Skip to content

Commit cbfb21e

Browse files
committed
support CAN FD for STM32 L5,G0,G4,H5,H7 and U5
1 parent 7fd6fdd commit cbfb21e

File tree

11 files changed

+506
-40
lines changed

11 files changed

+506
-40
lines changed

drivers/include/drivers/CAN.h

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,9 @@ class CAN
9494
* @param rd the read pin
9595
* @param td the transmit pin
9696
* @param hz the bus frequency in hertz
97+
* @param data_hz the data frequency in hertz(CAN FD only)
9798
*/
98-
CAN(PinName rd, PinName td, int hz);
99+
CAN(PinName rd, PinName td, int hz, int data_hz = 0);
99100

100101
/** Initialize CAN interface
101102
*
@@ -108,21 +109,23 @@ class CAN
108109
*
109110
* @param pinmap reference to structure which holds static pinmap
110111
* @param hz the bus frequency in hertz
112+
* @param data_hz the data frequency in hertz(CAN FD only)
111113
*/
112-
CAN(const can_pinmap_t &pinmap, int hz);
114+
CAN(const can_pinmap_t &pinmap, int hz, int data_hz = 0);
113115
CAN(const can_pinmap_t &&, int) = delete; // prevent passing of temporary objects
114116

115117
virtual ~CAN();
116118

117119
/** Set the frequency of the CAN interface
118120
*
119121
* @param hz The bus frequency in hertz
122+
* @param data_hz the data frequency in hertz(CAN FD only)
120123
*
121124
* @returns
122125
* 1 if successful,
123126
* 0 otherwise
124127
*/
125-
int frequency(int hz);
128+
int frequency(int hz, int data_hz = 0);
126129

127130
/** Write a CANMessage to the bus.
128131
*
@@ -145,6 +148,31 @@ class CAN
145148
*/
146149
int read(CANMessage &msg, int handle = 0);
147150

151+
#ifdef DEVICE_CAN_FD
152+
153+
/** Write a CANFDMessage to the bus.
154+
*
155+
* @param msg The CANFDMessage to write.
156+
*
157+
* @returns
158+
* 0 if write failed,
159+
* 1 if write was successful
160+
*/
161+
int write(CANFDMessage msg);
162+
163+
/** Read a CANFDMessage from the bus.
164+
*
165+
* @param msg A CANFDMessage to read to.
166+
* @param handle message filter handle (0 for any message)
167+
*
168+
* @returns
169+
* 0 if no message arrived,
170+
* 1 if message arrived
171+
*/
172+
int read(CANFDMessage &msg, int handle = 0);
173+
174+
#endif
175+
148176
/** Reset CAN interface.
149177
*
150178
* To use after error overflow.

drivers/include/drivers/interfaces/InterfaceCAN.h

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,107 @@ class CANMessage : public CAN_Message {
140140
}
141141
};
142142

143+
#ifdef DEVICE_CAN_FD
144+
145+
/** CANFDMessage class
146+
*
147+
* @note Synchronization level: Thread safe
148+
*/
149+
class CANFDMessage : public CANFD_Message {
150+
151+
public:
152+
/** Creates empty CANFD message.
153+
*/
154+
CANFDMessage() : CANFD_Message()
155+
{
156+
len = 64U;
157+
type = CANData;
158+
format = CANStandard;
159+
id = 0U;
160+
memset(data, 0, 64);
161+
}
162+
163+
/** Creates CANFD message with specific content.
164+
*
165+
* @param _id Message ID
166+
* @param _data Mesaage Data
167+
* @param _len Message Data length
168+
* @param _type Type of Data: Use enum CANType for valid parameter values
169+
* @param _format Data Format: Use enum CANFormat for valid parameter values
170+
*/
171+
CANFDMessage(unsigned int _id, const unsigned char *_data, unsigned char _len = 64, CANType _type = CANData, CANFormat _format = CANStandard)
172+
{
173+
len = (_len > 64) ? 64 : _len;
174+
type = _type;
175+
format = _format;
176+
id = _id;
177+
memcpy(data, _data, len);
178+
}
179+
180+
181+
/** Creates CANFD message with specific content.
182+
*
183+
* @param _id Message ID
184+
* @param _data Mesaage Data
185+
* @param _len Message Data length
186+
* @param _type Type of Data: Use enum CANType for valid parameter values
187+
* @param _format Data Format: Use enum CANFormat for valid parameter values
188+
*/
189+
CANFDMessage(unsigned int _id, const char *_data, unsigned char _len = 64, CANType _type = CANData, CANFormat _format = CANStandard)
190+
{
191+
len = (_len > 64) ? 64 : _len;
192+
type = _type;
193+
format = _format;
194+
id = _id;
195+
memcpy(data, _data, len);
196+
}
197+
198+
/** Creates CANFD remote message.
199+
*
200+
* @param _id Message ID
201+
* @param _format Data Format: Use enum CANType for valid parameter values
202+
*/
203+
CANFDMessage(unsigned int _id, CANFormat _format = CANStandard)
204+
{
205+
len = 0;
206+
type = CANRemote;
207+
format = _format;
208+
id = _id;
209+
memset(data, 0, 64);
210+
}
211+
212+
/**
213+
* "Deep" comparison operator (ie: compare value of each data member)
214+
*/
215+
bool operator ==(const CANFDMessage &b) const
216+
{
217+
if (id != b.id) {
218+
return false;
219+
}
220+
if (len != b.len) {
221+
return false;
222+
}
223+
if (format != b.format) {
224+
return false;
225+
}
226+
if (type != b.type) {
227+
return false;
228+
}
229+
if (memcmp(data, b.data, len) != 0) {
230+
return false;
231+
}
232+
233+
return true;
234+
}
235+
236+
bool operator !=(const CANFDMessage &b) const
237+
{
238+
return !(*this == b);
239+
}
240+
};
241+
242+
#endif
243+
143244
/** @}*/
144245

145246
namespace interface {

drivers/source/CAN.cpp

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,14 @@ CAN::CAN(PinName rd, PinName td) : _can(), _irq()
3030
can_irq_init(&_can, (&CAN::_irq_handler), reinterpret_cast<uintptr_t>(this));
3131
}
3232

33-
CAN::CAN(PinName rd, PinName td, int hz) : _can(), _irq()
33+
CAN::CAN(PinName rd, PinName td, int hz, int data_hz) : _can(), _irq()
3434
{
3535
// No lock needed in constructor
36+
#ifdef DEVICE_CAN_FD
37+
canfd_init_freq(&_can, rd, td, hz, data_hz);
38+
#else
3639
can_init_freq(&_can, rd, td, hz);
40+
#endif
3741
can_irq_init(&_can, (&CAN::_irq_handler), reinterpret_cast<uintptr_t>(this));
3842
}
3943

@@ -44,10 +48,14 @@ CAN::CAN(const can_pinmap_t &pinmap) : _can(), _irq()
4448
can_irq_init(&_can, (&CAN::_irq_handler), reinterpret_cast<uintptr_t>(this));
4549
}
4650

47-
CAN::CAN(const can_pinmap_t &pinmap, int hz) : _can(), _irq()
51+
CAN::CAN(const can_pinmap_t &pinmap, int hz, int data_hz) : _can(), _irq()
4852
{
4953
// No lock needed in constructor
54+
#ifdef DEVICE_CAN_FD
55+
canfd_init_freq_direct(&_can, &pinmap, hz, data_hz);
56+
#else
5057
can_init_freq_direct(&_can, &pinmap, hz);
58+
#endif
5159
can_irq_init(&_can, (&CAN::_irq_handler), reinterpret_cast<uintptr_t>(this));
5260
}
5361

@@ -63,10 +71,14 @@ CAN::~CAN()
6371
can_free(&_can);
6472
}
6573

66-
int CAN::frequency(int f)
74+
int CAN::frequency(int f, int data_f)
6775
{
6876
lock();
77+
#ifdef DEVICE_CAN_FD
78+
int ret = canfd_frequency(&_can, f, data_f);
79+
#else
6980
int ret = can_frequency(&_can, f);
81+
#endif
7082
unlock();
7183
return ret;
7284
}
@@ -90,6 +102,29 @@ int CAN::read(CANMessage &msg, int handle)
90102
return ret;
91103
}
92104

105+
#ifdef DEVICE_CAN_FD
106+
107+
int CAN::write(CANFDMessage msg)
108+
{
109+
lock();
110+
int ret = canfd_write(&_can, msg, 0);
111+
unlock();
112+
return ret;
113+
}
114+
115+
int CAN::read(CANFDMessage &msg, int handle)
116+
{
117+
lock();
118+
int ret = canfd_read(&_can, &msg, handle);
119+
if (msg.len > 64) {
120+
MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_DRIVER_CAN, MBED_ERROR_CODE_READ_FAILED), "Read tried to write more than 64 bytes");
121+
}
122+
unlock();
123+
return ret;
124+
}
125+
126+
#endif
127+
93128
void CAN::reset()
94129
{
95130
lock();

targets/TARGET_STM/TARGET_STM32G0/objects.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,15 @@ struct analogin_s {
7575
uint8_t channel;
7676
};
7777

78+
#if DEVICE_CAN
79+
struct can_s {
80+
FDCAN_HandleTypeDef CanHandle;
81+
int index;
82+
int hz;
83+
int data_hz;
84+
};
85+
#endif
86+
7887
#include "gpio_object.h"
7988

8089
#if DEVICE_ANALOGOUT

targets/TARGET_STM/TARGET_STM32G4/objects.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ struct can_s {
8888
FDCAN_HandleTypeDef CanHandle;
8989
int index;
9090
int hz;
91+
int data_hz;
9192
};
9293
#endif
9394

targets/TARGET_STM/TARGET_STM32H5/objects.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ struct can_s {
133133
FDCAN_HandleTypeDef CanHandle;
134134
int index;
135135
int hz;
136+
int data_hz;
136137
};
137138
#endif
138139

targets/TARGET_STM/TARGET_STM32H7/objects.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ struct can_s {
177177
FDCAN_HandleTypeDef CanHandle;
178178
int index;
179179
int hz;
180+
int data_hz;
180181
};
181182
#endif
182183

targets/TARGET_STM/TARGET_STM32L5/objects.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ struct can_s {
106106
FDCAN_HandleTypeDef CanHandle;
107107
int index;
108108
int hz;
109+
int data_hz;
109110
};
110111
#endif
111112

targets/TARGET_STM/TARGET_STM32U5/objects.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ struct can_s {
106106
FDCAN_HandleTypeDef CanHandle;
107107
int index;
108108
int hz;
109+
int data_hz;
109110
};
110111
#endif
111112

0 commit comments

Comments
 (0)