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 constexpr PresetEntry(const CAN_INITTYPE init,const uint32_t speed,const char* name):init(init),speed(speed),name(name){}
45 };
46 constexpr CANPortHardwareConfig(const bool canChangeSpeed,std::span<const PresetEntry> presets_list)
47 : canChangeSpeed(canChangeSpeed),presets(presets_list){}
48
49 // Values
50 const bool canChangeSpeed;
51 constexpr PresetEntry getPreset(uint8_t idx) const {return PresetEntry(presets[std::min<uint8_t>(idx,presets.size())]);}
52 constexpr uint32_t speedToPreset(uint32_t speed) const {
53 auto it = std::find_if( presets.begin(), presets.end(), [&speed](const PresetEntry &e){return e.speed == speed;});
54 return it == presets.end() ? 255 : std::distance(presets.begin(),it);
55 }
56 constexpr uint32_t presetToSpeed(uint8_t preset) const {return presets[preset].speed;}
57 const std::span<const PresetEntry> presets; // Name for listing and init types for setup
58};
59
60typedef struct {
61 uint32_t id = 0;
62 uint32_t length = 0;
63 bool extId = false;
64 bool rtr = false;
65 bool fdcan = false; // Placeholder
66// bool fdcan_rateswitch = false;
68
70public:
71 uint32_t id = 0;
72 uint32_t length = 0;
73 bool extId = false;
74 bool rtr = false;
75 uint32_t filter = 0;
76 uint32_t timestamp = 0;
77 bool fdcan = false;
78// bool fdcan_rateswitch = false;
80#if defined(CANTYPE_2B)
81#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
82 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) {};
83#elif defined(CANTYPE_FDCAN)
84#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
85 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) {};
86#endif
87 virtual ~CAN_msg_header_rx(){};
88};
89
90typedef struct{
91 uint8_t data[CAN_MSGBUFSIZE] = {0};
92 //CAN_TxHeaderTypeDef header = {0,0,0,CAN_RTR_DATA,8,(FunctionalState)0};
95
96// Unused?
97typedef struct{
98 uint8_t data[CAN_MSGBUFSIZE] = {0};
99 //CAN_RxHeaderTypeDef header = {0,0,0,0,0,0};
101 uint8_t fifo = 0;
102 uint32_t size(){return header.length;}
103} CAN_rx_msg;
104
108typedef struct {
109 uint32_t filter_id = 0;
110 uint32_t filter_mask = 0;
111 uint32_t buffer = 0; // FIFO index or fdcan buffer mode
112 bool active = true;
113 bool extid = false;
114// bool dedicated_buffer = false; // Not yet supported
115} CAN_filter;
116
117
118
119//template<class INIT>
120class CANPort : public PersistentStorage { // : public CanHandler if interrupt callbacks needed
121 static std::vector<CANPort*> canPorts;
122public:
123
124 CANPort(const CANPortHardwareConfig& presets,uint8_t instance = 0);
125 virtual ~CANPort();
126
127 // ---- Implement these in the CAN port ---
131 virtual bool start() = 0;
132
136 virtual bool stop() = 0;
137
138 virtual bool sendMessage(CAN_tx_msg& msg) = 0;
139 virtual bool sendMessage(CAN_msg_header_tx *pHeader, uint8_t aData[],uint32_t *pTxMailbox = nullptr) = 0;
143 virtual void abortTxRequests() = 0;
144
145 virtual int32_t addCanFilter(CAN_filter filter) = 0;
146 virtual void removeCanFilter(uint8_t filterId) = 0;
147
148 virtual void setSpeed(uint32_t speed) = 0;
149 virtual void setSpeedPreset(uint8_t preset) = 0;
150 virtual uint32_t getSpeed() = 0;
151 virtual uint8_t getSpeedPreset() = 0;
152
153 virtual void setSilentMode(bool silent) = 0;
154
155
156 // ---------------------------------------------
157
158 // Common implementations
159 virtual int32_t getPortUsers(){return portUsers;}
160 virtual void takePort(){
161 if(portUsers++ == 0){
162 start();
163 }
164 }
165 virtual void freePort(){
166 if(portUsers>0){
167 portUsers--;
168 }
169
170 if(portUsers == 0){
171 stop();
172 }
173 }
174 virtual void giveSemaphore(){
175 bool isIsr = inIsr();
176 BaseType_t taskWoken = 0;
177 if(isIsr)
178 this->semaphore.GiveFromISR(&taskWoken);
179 else
180 this->semaphore.Give();
181 isWaitingFlag = false;
182 portYIELD_FROM_ISR(taskWoken);
183 }
184 virtual bool takeSemaphore(uint32_t delay = portMAX_DELAY){
185 bool isIsr = inIsr();
186 BaseType_t taskWoken = 0;
187 bool success;
188 if(isIsr)
189 success = this->semaphore.TakeFromISR(&taskWoken);
190 else{
191 success = this->semaphore.Take(delay);
192 }
193 //isTakenFlag = true;
194 portYIELD_FROM_ISR(taskWoken);
195 return success;
196 }
197 static CANPort* handleToPort(void* handle);
198 virtual uint8_t speedToPreset(uint32_t speed){return presets.speedToPreset(speed);}
199 virtual uint32_t presetToSpeed(uint8_t preset){return presets.presetToSpeed(preset);}
200
201protected:
205 bool isWaitingFlag = false;
206 int32_t portUsers = 0;
207 virtual void* getHandle() = 0;
208};
209
210
211
212
213#endif /* SRC_CAN_H_ */
214#endif
const uint8_t DLCtoBytes[]
Definition: CAN.h:32
uint8_t header
CAN_msg_header_rx(CAN_RxHeaderTypeDef *hdr)
Definition: CAN.h:82
CAN_msg_header_rx()
Definition: CAN.h:79
uint32_t timestamp
Definition: CAN.h:76
uint32_t filter
Definition: CAN.h:75
virtual ~CAN_msg_header_rx()
Definition: CAN.h:87
bool rtr
Definition: CAN.h:74
bool extId
Definition: CAN.h:73
uint32_t id
Definition: CAN.h:71
CAN_msg_header_rx(FDCAN_RxHeaderTypeDef *hdr)
Definition: CAN.h:85
bool fdcan
Definition: CAN.h:77
uint32_t length
Definition: CAN.h:72
constexpr CANPortHardwareConfig(const bool canChangeSpeed, std::span< const PresetEntry > presets_list)
Definition: CAN.h:46
const bool canChangeSpeed
Definition: CAN.h:50
constexpr uint32_t presetToSpeed(uint8_t preset) const
Definition: CAN.h:56
constexpr uint32_t speedToPreset(uint32_t speed) const
Definition: CAN.h:52
constexpr PresetEntry getPreset(uint8_t idx) const
Definition: CAN.h:51
const std::span< const PresetEntry > presets
Definition: CAN.h:57
Definition: CAN.h:120
virtual void * getHandle()=0
virtual void giveSemaphore()
Definition: CAN.h:174
virtual uint8_t speedToPreset(uint32_t speed)
Gets preset index for a speed.
Definition: CAN.h:198
virtual ~CANPort()
Definition: CAN.cpp:19
virtual void freePort()
Definition: CAN.h:165
virtual uint8_t getSpeedPreset()=0
cpp_freertos::BinarySemaphore configSem
Definition: CAN.h:203
static CANPort * handleToPort(void *handle)
Definition: CAN.cpp:23
virtual bool takeSemaphore(uint32_t delay=portMAX_DELAY)
Definition: CAN.h:184
virtual void takePort()
Definition: CAN.h:160
virtual bool start()=0
virtual void setSpeedPreset(uint8_t preset)=0
virtual int32_t getPortUsers()
Definition: CAN.h:159
cpp_freertos::BinarySemaphore semaphore
Definition: CAN.h:202
const CANPortHardwareConfig & presets
CAN port presets for different speeds. Hardware dependent.
Definition: CAN.h:204
virtual uint32_t getSpeed()=0
CANPort(const CANPortHardwareConfig &presets, uint8_t instance=0)
Definition: CAN.cpp:16
bool isWaitingFlag
Definition: CAN.h:205
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:206
virtual bool stop()=0
static std::vector< CANPort * > canPorts
Definition: CAN.h:121
virtual void abortTxRequests()=0
virtual uint32_t presetToSpeed(uint8_t preset)
Gets speed for a preset index.
Definition: CAN.h:199
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:97
uint32_t size()
Definition: CAN.h:102
CAN_msg_header_rx header
Definition: CAN.h:100
Definition: CAN.h:90
CAN_msg_header_tx header
Definition: CAN.h:93
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
constexpr PresetEntry(const CAN_INITTYPE init, const uint32_t speed, const char *name)
Definition: CAN.h:44