Open FFBoard
Open source force feedback firmware
CAN.h
Go to the documentation of this file.
1/*
2 * CAN.h
3 *
4 * Created on: 21.06.2021
5 * Author: Yannick
6 */
7
8#ifndef SRC_CAN_H_
9#define SRC_CAN_H_
10#include "target_constants.h"
11#ifdef CANBUS
12//#include "CanHandler.h"
13#include "main.h"
14#include <vector>
15#include "semaphore.hpp"
16#include <GPIOPin.h>
17#include "PersistentStorage.h"
18#include "CommandHandler.h"
19#include <span>
20
21
22class CANPort;
23
24#if defined(CAN1)
25#define CANTYPE_2B
26#define CAN_INITTYPE uint32_t
27#define CAN_MSGBUFSIZE 8
28#elif defined(FDCAN1)
29#define CANTYPE_FDCAN
30#define CAN_INITTYPE FDCAN_InitTypeDef&
31#define CAN_MSGBUFSIZE 64
32const uint8_t DLCtoBytes[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 12, 16, 20, 24, 32, 48, 64};
33#endif
34
35//class CANPort;
36
37
39public:
40 struct PresetEntry{// Helper for preset entries
41 const CAN_INITTYPE init;
42 const uint32_t speed;
43 const char* name;
44 };
45 constexpr CANPortHardwareConfig(const bool canChangeSpeed,std::span<const PresetEntry> presets_list)
46 : canChangeSpeed(canChangeSpeed),presets(presets_list){}
47
48 // Values
49 const bool canChangeSpeed;
50 constexpr PresetEntry getPreset(uint8_t idx) const {return PresetEntry(presets[std::min<uint8_t>(idx,presets.size())]);}
51 constexpr uint32_t speedToPreset(uint32_t speed) const {
52 auto it = std::find_if( presets.begin(), presets.end(), [&speed](const PresetEntry &e){return e.speed == speed;});
53 return it == presets.end() ? 255 : std::distance(presets.begin(),it);
54 }
55 constexpr uint32_t presetToSpeed(uint8_t preset) const {return presets[preset].speed;}
56 const std::span<const PresetEntry> presets; // Name for listing and init types for setup
57};
58
59typedef struct {
60 uint32_t id = 0;
61 uint32_t length = 0;
62 bool extId = false;
63 bool rtr = false;
64 bool fdcan = false; // Placeholder
65// bool fdcan_rateswitch = false;
67
69public:
70 uint32_t id = 0;
71 uint32_t length = 0;
72 bool extId = false;
73 bool rtr = false;
74 uint32_t filter = 0;
75 uint32_t timestamp = 0;
76 bool fdcan = false;
77// bool fdcan_rateswitch = false;
79#if defined(CANTYPE_2B)
80#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
81 CAN_msg_header_rx(CAN_RxHeaderTypeDef* hdr) : id(hdr->IDE==CAN_ID_STD ? hdr->StdId : hdr->ExtId),length(hdr->DLC),extId(hdr->IDE==CAN_ID_EXT),rtr(hdr->RTR == CAN_RTR_REMOTE),filter(hdr->FilterMatchIndex),timestamp(hdr->Timestamp),fdcan(false) {};
82#elif defined(CANTYPE_FDCAN)
83#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
84 CAN_msg_header_rx(FDCAN_RxHeaderTypeDef* hdr) : id(hdr->Identifier),length(DLCtoBytes[hdr->DataLength >> 16]),extId(hdr->FDFormat),rtr(hdr->RxFrameType == FDCAN_REMOTE_FRAME),filter(hdr->FilterIndex),timestamp(hdr->RxTimestamp),fdcan(hdr->FDFormat == FDCAN_FD_CAN) {};
85#endif
86 virtual ~CAN_msg_header_rx(){};
87};
88
89typedef struct{
90 uint8_t data[CAN_MSGBUFSIZE] = {0};
91 //CAN_TxHeaderTypeDef header = {0,0,0,CAN_RTR_DATA,8,(FunctionalState)0};
94
95// Unused?
96typedef struct{
97 uint8_t data[CAN_MSGBUFSIZE] = {0};
98 //CAN_RxHeaderTypeDef header = {0,0,0,0,0,0};
100 uint8_t fifo = 0;
101 uint32_t size(){return header.length;}
102} CAN_rx_msg;
103
107typedef struct {
108 uint32_t filter_id = 0;
109 uint32_t filter_mask = 0;
110 uint32_t buffer = 0; // FIFO index or fdcan buffer mode
111 bool active = true;
112 bool extid = false;
113// bool dedicated_buffer = false; // Not yet supported
114} CAN_filter;
115
116
117
118//template<class INIT>
119class CANPort : public PersistentStorage { // : public CanHandler if interrupt callbacks needed
120 static std::vector<CANPort*> canPorts;
121public:
122
123 CANPort(const CANPortHardwareConfig& presets,uint8_t instance = 0);
124 virtual ~CANPort();
125
126 // ---- Implement these in the CAN port ---
130 virtual bool start() = 0;
131
135 virtual bool stop() = 0;
136
137 virtual bool sendMessage(CAN_tx_msg& msg) = 0;
138 virtual bool sendMessage(CAN_msg_header_tx *pHeader, uint8_t aData[],uint32_t *pTxMailbox = nullptr) = 0;
142 virtual void abortTxRequests() = 0;
143
144 virtual int32_t addCanFilter(CAN_filter filter) = 0;
145 virtual void removeCanFilter(uint8_t filterId) = 0;
146
147 virtual void setSpeed(uint32_t speed) = 0;
148 virtual void setSpeedPreset(uint8_t preset) = 0;
149 virtual uint32_t getSpeed() = 0;
150 virtual uint8_t getSpeedPreset() = 0;
151
152 virtual void setSilentMode(bool silent) = 0;
153
154
155 // ---------------------------------------------
156
157 // Common implementations
158 virtual int32_t getPortUsers(){return portUsers;}
159 virtual void takePort(){
160 if(portUsers++ == 0){
161 start();
162 }
163 }
164 virtual void freePort(){
165 if(portUsers>0){
166 portUsers--;
167 }
168
169 if(portUsers == 0){
170 stop();
171 }
172 }
173 virtual void giveSemaphore(){
174 bool isIsr = inIsr();
175 BaseType_t taskWoken = 0;
176 if(isIsr)
177 this->semaphore.GiveFromISR(&taskWoken);
178 else
179 this->semaphore.Give();
180 isWaitingFlag = false;
181 portYIELD_FROM_ISR(taskWoken);
182 }
183 virtual bool takeSemaphore(uint32_t delay = portMAX_DELAY){
184 bool isIsr = inIsr();
185 BaseType_t taskWoken = 0;
186 bool success;
187 if(isIsr)
188 success = this->semaphore.TakeFromISR(&taskWoken);
189 else{
190 success = this->semaphore.Take(delay);
191 }
192 //isTakenFlag = true;
193 portYIELD_FROM_ISR(taskWoken);
194 return success;
195 }
196 static CANPort* handleToPort(void* handle);
197 virtual uint8_t speedToPreset(uint32_t speed){return presets.speedToPreset(speed);}
198 virtual uint32_t presetToSpeed(uint8_t preset){return presets.presetToSpeed(preset);}
199
200protected:
204 bool isWaitingFlag = false;
205 int32_t portUsers = 0;
206 virtual void* getHandle() = 0;
207};
208
209
210
211
212#endif /* SRC_CAN_H_ */
213#endif
const uint8_t DLCtoBytes[]
Definition: CAN.h:32
uint8_t header
CAN_msg_header_rx(CAN_RxHeaderTypeDef *hdr)
Definition: CAN.h:81
CAN_msg_header_rx()
Definition: CAN.h:78
uint32_t timestamp
Definition: CAN.h:75
uint32_t filter
Definition: CAN.h:74
virtual ~CAN_msg_header_rx()
Definition: CAN.h:86
bool rtr
Definition: CAN.h:73
bool extId
Definition: CAN.h:72
uint32_t id
Definition: CAN.h:70
CAN_msg_header_rx(FDCAN_RxHeaderTypeDef *hdr)
Definition: CAN.h:84
bool fdcan
Definition: CAN.h:76
uint32_t length
Definition: CAN.h:71
constexpr CANPortHardwareConfig(const bool canChangeSpeed, std::span< const PresetEntry > presets_list)
Definition: CAN.h:45
const bool canChangeSpeed
Definition: CAN.h:49
constexpr uint32_t presetToSpeed(uint8_t preset) const
Definition: CAN.h:55
constexpr uint32_t speedToPreset(uint32_t speed) const
Definition: CAN.h:51
constexpr PresetEntry getPreset(uint8_t idx) const
Definition: CAN.h:50
const std::span< const PresetEntry > presets
Definition: CAN.h:56
Definition: CAN.h:119
virtual void * getHandle()=0
virtual void giveSemaphore()
Definition: CAN.h:173
virtual uint8_t speedToPreset(uint32_t speed)
Gets preset index for a speed.
Definition: CAN.h:197
virtual ~CANPort()
Definition: CAN.cpp:19
virtual void freePort()
Definition: CAN.h:164
virtual uint8_t getSpeedPreset()=0
cpp_freertos::BinarySemaphore configSem
Definition: CAN.h:202
static CANPort * handleToPort(void *handle)
Definition: CAN.cpp:23
virtual bool takeSemaphore(uint32_t delay=portMAX_DELAY)
Definition: CAN.h:183
virtual void takePort()
Definition: CAN.h:159
virtual bool start()=0
virtual void setSpeedPreset(uint8_t preset)=0
virtual int32_t getPortUsers()
Definition: CAN.h:158
cpp_freertos::BinarySemaphore semaphore
Definition: CAN.h:201
const CANPortHardwareConfig & presets
CAN port presets for different speeds. Hardware dependent.
Definition: CAN.h:203
virtual uint32_t getSpeed()=0
CANPort(const CANPortHardwareConfig &presets, uint8_t instance=0)
Definition: CAN.cpp:16
bool isWaitingFlag
Definition: CAN.h:204
virtual int32_t addCanFilter(CAN_filter filter)=0
virtual bool sendMessage(CAN_tx_msg &msg)=0
virtual void setSpeed(uint32_t speed)=0
int32_t portUsers
Definition: CAN.h:205
virtual bool stop()=0
static std::vector< CANPort * > canPorts
Definition: CAN.h:120
virtual void abortTxRequests()=0
virtual uint32_t presetToSpeed(uint8_t preset)
Gets speed for a preset index.
Definition: CAN.h:198
virtual void removeCanFilter(uint8_t filterId)=0
virtual bool sendMessage(CAN_msg_header_tx *pHeader, uint8_t aData[], uint32_t *pTxMailbox=nullptr)=0
virtual void setSilentMode(bool silent)=0
bool GiveFromISR(BaseType_t *pxHigherPriorityTaskWoken)
Definition: csemaphore.cpp:76
bool TakeFromISR(BaseType_t *pxHigherPriorityTaskWoken)
Definition: csemaphore.cpp:56
bool Take(TickType_t Timeout=portMAX_DELAY)
Definition: csemaphore.cpp:46
static bool inIsr()
Definition: cppmain.h:41
static struct @612 data
uint8_t const * buffer
Definition: midi_device.h:100
Definition: CAN.h:96
uint32_t size()
Definition: CAN.h:101
CAN_msg_header_rx header
Definition: CAN.h:99
Definition: CAN.h:89
CAN_msg_header_tx header
Definition: CAN.h:92
Definition: CAN.h:40
const char * name
Definition: CAN.h:43
const uint32_t speed
Definition: CAN.h:42
const CAN_INITTYPE init
Definition: CAN.h:41