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