Skip to content

Commit 248dee6

Browse files
jmaralog0nz4I0
andauthored
Fixes on FDCAN for BCU (#490)
* configure CAN for use with SuperCaps * change bit setting for 500Kbit baudrate * Fix FDCAN consuming packets on interrupt instead of leaving them to application * move stuff into FDCAN::inscribe() * implementation of CAN with templated parameters, yet to be tested * fix warnings, for some reason STLIB alone compiles without -Werror flag * renamed MODE to format since MODE was overloaded, and now it supports LOOPBACK_EXTERNAL and NORMAL mode(hence the renaming to format of the other variable) * fix typo on CANBitRate Enum * fix type --------- Co-authored-by: Gonzalo Sanchez <gonzalosmoya24@gmail.com> Co-authored-by: Gonzalo <58850783+g0nz4I0@users.noreply.github.com>
1 parent ce53a8a commit 248dee6

3 files changed

Lines changed: 141 additions & 94 deletions

File tree

Lines changed: 31 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,48 @@
11
#pragma once
2-
#include "HALAL/Services/Communication/Ethernet/EthernetNode.hpp"
3-
#include "HALAL/Services/Communication/Ethernet/Ethernet.hpp"
42
#include "HALAL/Models/Packets/Packet.hpp"
3+
#include "HALAL/Services/Communication/Ethernet/Ethernet.hpp"
4+
#include "HALAL/Services/Communication/Ethernet/EthernetNode.hpp"
55

66
#ifdef HAL_ETH_MODULE_ENABLED
77
#define PBUF_POOL_MEMORY_DESC_POSITION 8
88

9-
class DatagramSocket{
10-
private:
11-
struct udp_pcb* udp_control_block;
12-
static void receive_callback(void *args, struct udp_pcb *udp_control_block, struct pbuf *packet_buffer, const ip_addr_t *remote_address, u16_t port);
13-
14-
public:
15-
IPV4 local_ip;
16-
uint32_t local_port;
17-
IPV4 remote_ip;
18-
uint32_t remote_port;
19-
bool is_disconnected = true;
20-
21-
DatagramSocket();
22-
DatagramSocket(DatagramSocket&& other);
23-
DatagramSocket(IPV4 local_ip, uint32_t local_port, IPV4 remote_ip, uint32_t remote_port);
24-
DatagramSocket(EthernetNode local_node, EthernetNode remote_node);
25-
~DatagramSocket();
9+
class DatagramSocket {
10+
public:
11+
struct udp_pcb* udp_control_block;
2612

27-
void operator=(DatagramSocket&&);
13+
IPV4 local_ip;
14+
uint32_t local_port;
15+
IPV4 remote_ip;
16+
uint32_t remote_port;
17+
bool is_disconnected = true;
18+
DatagramSocket();
19+
DatagramSocket(DatagramSocket&& other);
20+
DatagramSocket(IPV4 local_ip, uint32_t local_port, IPV4 remote_ip,
21+
uint32_t remote_port);
22+
DatagramSocket(EthernetNode local_node, EthernetNode remote_node);
23+
~DatagramSocket();
2824

29-
bool send_packet(Packet& packet){
30-
uint8_t* packet_buffer = packet.build();
25+
void operator=(DatagramSocket&&);
3126

32-
struct pbuf* tx_buffer = pbuf_alloc(PBUF_TRANSPORT, packet.size, PBUF_RAM);
33-
pbuf_take(tx_buffer, packet_buffer, packet.size);
34-
udp_send(udp_control_block, tx_buffer);
35-
pbuf_free(tx_buffer);
27+
void reconnect();
3628

37-
return true;
38-
}
39-
4029

41-
void reconnect();
30+
static void receive_callback(void* args, struct udp_pcb* udp_control_block,
31+
struct pbuf* packet_buffer,
32+
const ip_addr_t* remote_address, u16_t port);
33+
bool send_packet(Packet& packet) {
34+
uint8_t* packet_buffer = packet.build();
4235

43-
void close();
36+
struct pbuf* tx_buffer =
37+
pbuf_alloc(PBUF_TRANSPORT, packet.size, PBUF_RAM);
38+
pbuf_take(tx_buffer, packet_buffer, packet.size);
39+
udp_send(udp_control_block, tx_buffer);
40+
pbuf_free(tx_buffer);
4441

42+
return true;
43+
}
4544

45+
void close();
4646
};
4747

48-
4948
#endif

Inc/HALAL/Services/Communication/FDCAN/FDCAN.hpp

Lines changed: 106 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,25 @@ using std::unordered_map;
1717
using std::vector;
1818
using std::queue;
1919

20+
enum class CANBitRatesSpeed{
21+
CAN_125_kbit = 0,
22+
CAN_250_kbit = 1,
23+
CAN_500_kbit = 2,
24+
CAN_1_Mbit = 3
25+
};
2026

27+
enum class CANFormat{
28+
CAN_NORMAL_FORMAT = 0,
29+
CAN_FDCAN_FORMAT = 1
30+
};
31+
enum class CANIdentifier{
32+
CAN_11_BIT_IDENTIFIER = 0,
33+
CAN_29_BIT_IDENTIFIER = 1
34+
};
35+
enum class CANMode{
36+
CAN_MODE_NORMAL = 0,
37+
CAN_MODE_LOOPBACK = 4
38+
};
2139

2240
class FDCAN{
2341
public:
@@ -108,7 +126,7 @@ class FDCAN{
108126
static FDCAN::Instance instance1;
109127
static FDCAN::Instance instance2;
110128
static FDCAN::Instance instance3;
111-
129+
template<CANBitRatesSpeed Speed,CANFormat Format,CANIdentifier id,CANMode Mode>
112130
static uint8_t inscribe(FDCAN::Peripheral& fdcan);
113131

114132
static void start();
@@ -133,4 +151,91 @@ class FDCAN{
133151

134152
};
135153

154+
template<CANBitRatesSpeed Speed,CANFormat format,CANIdentifier message_id,CANMode mode>
155+
uint8_t FDCAN::inscribe(FDCAN::Peripheral& fdcan){
156+
if (!FDCAN::available_fdcans.contains(fdcan)) {
157+
ErrorHandler(" The FDCAN peripheral %d is already used or does not exists.", (uint16_t)fdcan);
158+
return 0;
159+
}
160+
161+
FDCAN::Instance* fdcan_instance = FDCAN::available_fdcans[fdcan];
162+
if constexpr(format == CANFormat::CAN_FDCAN_FORMAT){
163+
fdcan_instance->tx_header.FDFormat = FDCAN_FD_CAN;
164+
}else{
165+
fdcan_instance->tx_header.FDFormat = FDCAN_CLASSIC_CAN;
166+
}
167+
fdcan_instance->tx_header.DataLength = fdcan_instance->dlc;
168+
fdcan_instance->tx_header.TxFrameType = FDCAN_DATA_FRAME;
169+
fdcan_instance->tx_header.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
170+
fdcan_instance->tx_header.BitRateSwitch = FDCAN_BRS_OFF;
171+
172+
if constexpr(message_id == CANIdentifier::CAN_29_BIT_IDENTIFIER){
173+
fdcan_instance->tx_header.IdType = FDCAN_EXTENDED_ID;
174+
fdcan_instance->hfdcan->Init.FrameFormat = FDCAN_FRAME_FD_NO_BRS;
175+
}else{
176+
fdcan_instance->tx_header.IdType = FDCAN_STANDARD_ID;
177+
fdcan_instance->hfdcan->Init.FrameFormat = FDCAN_FRAME_CLASSIC;
178+
}
179+
fdcan_instance->tx_header.TxEventFifoControl = FDCAN_NO_TX_EVENTS;
180+
fdcan_instance->tx_header.MessageMarker = 0;
181+
fdcan_instance->tx_header.Identifier = 0x0;
182+
183+
fdcan_instance->hfdcan->Instance = fdcan_instance->instance;
184+
// use NORMAL or EXTERNAL_LOOPBACK mode
185+
fdcan_instance->hfdcan->Init.Mode = static_cast<uint32_t>(mode);
186+
fdcan_instance->hfdcan->Init.AutoRetransmission = DISABLE;
187+
fdcan_instance->hfdcan->Init.TransmitPause = DISABLE;
188+
fdcan_instance->hfdcan->Init.ProtocolException = DISABLE;
189+
///////////////////////////////////////////////////////////
190+
if constexpr(Speed == CANBitRatesSpeed::CAN_125_kbit){
191+
fdcan_instance->hfdcan->Init.NominalPrescaler = 20;
192+
fdcan_instance->hfdcan->Init.NominalSyncJumpWidth = 2;
193+
fdcan_instance->hfdcan->Init.NominalTimeSeg1 = 5;
194+
fdcan_instance->hfdcan->Init.NominalTimeSeg2 = 2;
195+
}else if constexpr(Speed == CANBitRatesSpeed::CAN_250_kbit){
196+
fdcan_instance->hfdcan->Init.NominalPrescaler = 10;
197+
fdcan_instance->hfdcan->Init.NominalSyncJumpWidth = 2;
198+
fdcan_instance->hfdcan->Init.NominalTimeSeg1 = 5;
199+
fdcan_instance->hfdcan->Init.NominalTimeSeg2 = 2;
200+
}else if constexpr(Speed == CANBitRatesSpeed::CAN_500_kbit){
201+
fdcan_instance->hfdcan->Init.NominalPrescaler = 5;
202+
fdcan_instance->hfdcan->Init.NominalSyncJumpWidth = 2;
203+
fdcan_instance->hfdcan->Init.NominalTimeSeg1 = 5;
204+
fdcan_instance->hfdcan->Init.NominalTimeSeg2 = 2;
205+
}else if constexpr(Speed == CANBitRatesSpeed::CAN_1_Mbit){
206+
fdcan_instance->hfdcan->Init.NominalPrescaler = 1;
207+
fdcan_instance->hfdcan->Init.NominalSyncJumpWidth = 4;
208+
fdcan_instance->hfdcan->Init.NominalTimeSeg1 = 15;
209+
fdcan_instance->hfdcan->Init.NominalTimeSeg2 = 4;
210+
}
211+
////////////////////////////////////////////////////////////
212+
fdcan_instance->hfdcan->Init.DataPrescaler = 11;
213+
fdcan_instance->hfdcan->Init.DataSyncJumpWidth = 4;
214+
fdcan_instance->hfdcan->Init.DataTimeSeg1 = 17;
215+
fdcan_instance->hfdcan->Init.DataTimeSeg2 = 8;
216+
fdcan_instance->hfdcan->Init.MessageRAMOffset = 0;
217+
fdcan_instance->hfdcan->Init.StdFiltersNbr = 0;
218+
fdcan_instance->hfdcan->Init.ExtFiltersNbr = 0;
219+
fdcan_instance->hfdcan->Init.RxFifo0ElmtsNbr = 16;
220+
fdcan_instance->hfdcan->Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_64;
221+
fdcan_instance->hfdcan->Init.RxFifo1ElmtsNbr = 0;
222+
fdcan_instance->hfdcan->Init.RxFifo1ElmtSize = FDCAN_DATA_BYTES_64;
223+
fdcan_instance->hfdcan->Init.RxBuffersNbr = 0;
224+
fdcan_instance->hfdcan->Init.RxBufferSize = FDCAN_DATA_BYTES_64;
225+
fdcan_instance->hfdcan->Init.TxEventsNbr = 0;
226+
fdcan_instance->hfdcan->Init.TxBuffersNbr = 0;
227+
fdcan_instance->hfdcan->Init.TxFifoQueueElmtsNbr = 16;
228+
fdcan_instance->hfdcan->Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
229+
fdcan_instance->hfdcan->Init.TxElmtSize = FDCAN_DATA_BYTES_8;
230+
231+
Pin::inscribe(fdcan_instance->TX, ALTERNATIVE);
232+
Pin::inscribe(fdcan_instance->RX, ALTERNATIVE);
233+
234+
uint8_t id = FDCAN::id_counter++;
235+
236+
FDCAN::registered_fdcan[id] = fdcan_instance;
237+
238+
return id;
239+
}
240+
136241
#endif

Src/HALAL/Services/Communication/FDCAN/FDCAN.cpp

Lines changed: 4 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -21,43 +21,14 @@ unordered_map<FDCAN::DLC, uint8_t> FDCAN::dlc_to_len = {{DLC::BYTES_0, 0}, {DLC:
2121
unordered_map<FDCAN_HandleTypeDef*,uint8_t> FDCAN::handle_to_id{};
2222
unordered_map<FDCAN::Instance*,uint8_t> FDCAN::instance_to_id{};
2323
FDCAN::Packet packet{.rx_data = array<uint8_t, 64>{},.data_length = FDCAN::BYTES_64};
24-
uint8_t FDCAN::inscribe(FDCAN::Peripheral& fdcan){
25-
if (!FDCAN::available_fdcans.contains(fdcan)) {
26-
ErrorHandler(" The FDCAN peripheral %d is already used or does not exists.", (uint16_t)fdcan);
27-
return 0;
28-
}
29-
30-
FDCAN::Instance* fdcan_instance = FDCAN::available_fdcans[fdcan];
31-
32-
Pin::inscribe(fdcan_instance->TX, ALTERNATIVE);
33-
Pin::inscribe(fdcan_instance->RX, ALTERNATIVE);
3424

35-
uint8_t id = FDCAN::id_counter++;
36-
37-
FDCAN::registered_fdcan[id] = fdcan_instance;
38-
39-
return id;
40-
}
4125

4226
void FDCAN::start(){
4327
for( std::pair<uint8_t, FDCAN::Instance*> inst: FDCAN::registered_fdcan){
4428
uint8_t id = inst.first;
4529
FDCAN::Instance* instance = inst.second;
4630
FDCAN::init(instance);
4731

48-
FDCAN_TxHeaderTypeDef header;
49-
header.FDFormat = FDCAN_FD_CAN;
50-
header.DataLength = instance->dlc;
51-
header.TxFrameType = FDCAN_DATA_FRAME;
52-
header.BitRateSwitch = FDCAN_BRS_ON;
53-
header.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
54-
header.IdType = FDCAN_STANDARD_ID;
55-
header.TxEventFifoControl = FDCAN_NO_TX_EVENTS;
56-
header.MessageMarker = 0;
57-
header.Identifier = 0x0;
58-
59-
instance->tx_header = header;
60-
6132
instance->rx_queue = queue<FDCAN::Packet>();
6233
instance->tx_data = vector<uint8_t>();
6334

@@ -106,10 +77,10 @@ bool FDCAN::transmit(uint8_t id, uint32_t message_id, const char* data, FDCAN::D
10677
}
10778

10879
void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs){
109-
FDCAN::read(FDCAN::handle_to_id[hfdcan],&packet);
110-
if(packet.identifier == FDCAN::ID::FAULT_ID){
111-
ErrorHandler("FAULT PROPAGATED via CAN");
112-
}
80+
// FDCAN::read(FDCAN::handle_to_id[hfdcan],&packet);
81+
// if(packet.identifier == FDCAN::ID::FAULT_ID){
82+
// ErrorHandler("FAULT PROPAGATED via CAN");
83+
// }
11384
}
11485

11586
bool FDCAN::read(uint8_t id, FDCAN::Packet* data){
@@ -142,34 +113,6 @@ bool FDCAN::received_test(uint8_t id){
142113
void FDCAN::init(FDCAN::Instance* fdcan){
143114
FDCAN_HandleTypeDef* handle = fdcan->hfdcan;
144115
handle_to_id[handle] = instance_to_id[fdcan];
145-
handle->Instance = fdcan->instance;
146-
handle->Init.FrameFormat = FDCAN_FRAME_FD_BRS;
147-
handle->Init.Mode = FDCAN_MODE_INTERNAL_LOOPBACK;
148-
handle->Init.AutoRetransmission = ENABLE;
149-
handle->Init.TransmitPause = DISABLE;
150-
handle->Init.ProtocolException = DISABLE;
151-
handle->Init.NominalPrescaler = 1;
152-
handle->Init.NominalSyncJumpWidth = 16;
153-
handle->Init.NominalTimeSeg1 = 59;
154-
handle->Init.NominalTimeSeg2 = 20;
155-
handle->Init.DataPrescaler = 1;
156-
handle->Init.DataSyncJumpWidth = 4;
157-
handle->Init.DataTimeSeg1 = 14;
158-
handle->Init.DataTimeSeg2 = 5;
159-
handle->Init.MessageRAMOffset = 0;
160-
handle->Init.StdFiltersNbr = 1;
161-
handle->Init.ExtFiltersNbr = 0;
162-
handle->Init.RxFifo0ElmtsNbr = 16;
163-
handle->Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_64;
164-
handle->Init.RxFifo1ElmtsNbr = 0;
165-
handle->Init.RxFifo1ElmtSize = FDCAN_DATA_BYTES_64;
166-
handle->Init.RxBuffersNbr = 0;
167-
handle->Init.RxBufferSize = FDCAN_DATA_BYTES_64;
168-
handle->Init.TxEventsNbr = 0;
169-
handle->Init.TxBuffersNbr = 0;
170-
handle->Init.TxFifoQueueElmtsNbr = 16;
171-
handle->Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
172-
handle->Init.TxElmtSize = FDCAN_DATA_BYTES_64;
173116

174117
if (HAL_FDCAN_Init(handle) != HAL_OK)
175118
{

0 commit comments

Comments
 (0)