Skip to content
This repository was archived by the owner on Apr 13, 2024. It is now read-only.

Commit 3c1728a

Browse files
Add additional software buffering for CAN messages
1 parent 603c4d9 commit 3c1728a

File tree

1 file changed

+73
-17
lines changed

1 file changed

+73
-17
lines changed

src/can.c

Lines changed: 73 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#include <stdbool.h>
1111
#include <stdint.h>
12+
#include <string.h>
1213
#include <stm32f3xx_hal.h>
1314

1415
#include "can.h"
@@ -29,12 +30,17 @@
2930
#define CAN_PORT GPIOA
3031
#define CAN_PINS GPIO_PIN_12 | GPIO_PIN_11
3132

33+
#define CAN_BUF_SIZE 16
34+
3235

3336
//------------------------------------------------------------------------------
3437
// Private Variables
3538
//------------------------------------------------------------------------------
3639

3740
static CAN_HandleTypeDef hcan;
41+
static can_msg_t buffer[CAN_BUF_SIZE];
42+
static size_t buf_write_pos;
43+
static size_t buf_read_pos;
3844

3945

4046
//------------------------------------------------------------------------------
@@ -59,6 +65,10 @@ void can_init(void)
5965
gpio_config.Alternate = GPIO_AF9_CAN;
6066
HAL_GPIO_Init(CAN_PORT, &gpio_config);
6167

68+
// configure interrupts
69+
HAL_NVIC_SetPriority(USB_LP_CAN_RX0_IRQn, 1, 1);
70+
HAL_NVIC_EnableIRQ(USB_LP_CAN_RX0_IRQn);
71+
6272
// configure peripheral
6373
hcan.Instance = CAN;
6474
hcan.Init.Prescaler = 2;
@@ -92,12 +102,14 @@ void can_init(void)
92102
// Deinitialize CAN peripheral
93103
void can_deinit(void)
94104
{
105+
HAL_NVIC_EnableIRQ(USB_LP_CAN_RX0_IRQn);
95106
HAL_CAN_Stop(&hcan);
96107
HAL_GPIO_DeInit(CAN_PORT, CAN_PINS);
97108
}
98109

99110
// Send a CAN message
100-
void can_send(uint8_t id, can_cmd_t cmd, uint8_t *payload, uint8_t len) {
111+
void can_send(uint8_t id, can_cmd_t cmd, uint8_t *payload, uint8_t len)
112+
{
101113
CAN_TxHeaderTypeDef msg_header = {0};
102114
msg_header.ExtId = cmd << 8 | id;
103115
msg_header.IDE = CAN_ID_EXT;
@@ -121,25 +133,69 @@ void can_send(uint8_t id, can_cmd_t cmd, uint8_t *payload, uint8_t len) {
121133
}
122134

123135
// Receive a CAN message
124-
bool can_receive(can_msg_t *msg) {
125-
CAN_RxHeaderTypeDef msg_header;
126-
127-
if(HAL_CAN_GetRxFifoFillLevel(&hcan, CAN_RX_FIFO0) == 0) return false;
128-
129-
if(HAL_CAN_GetRxMessage(&hcan, CAN_RX_FIFO0, &msg_header, msg->payload) != HAL_OK)
136+
bool can_receive(can_msg_t *msg)
137+
{
138+
if(buf_read_pos != buf_write_pos)
130139
{
131-
debug_printf("Error receiving CAN message");
132-
return false;
140+
// copy message from buffer
141+
msg->cmd = buffer[buf_read_pos].cmd;
142+
msg->id = buffer[buf_read_pos].id;
143+
memcpy(msg->payload, buffer[buf_read_pos].payload, msg->len);
144+
msg->len = buffer[buf_read_pos].len;
145+
146+
// increment read position
147+
if(buf_read_pos == (CAN_BUF_SIZE - 1))
148+
buf_read_pos = 0;
149+
else
150+
buf_read_pos++;
151+
152+
// blink status LED on activity
153+
HAL_GPIO_WritePin(STATUS_PORT, STATUS_PIN, GPIO_PIN_RESET);
154+
HAL_Delay(STATUS_BLINK_TIME);
155+
HAL_GPIO_WritePin(STATUS_PORT, STATUS_PIN, GPIO_PIN_SET);
156+
157+
return true;
133158
}
134159

135-
msg->cmd = msg_header.ExtId >> 8;
136-
msg->id = msg_header.ExtId & 0xFF;
137-
msg->len = msg_header.DLC;
160+
return false;
161+
}
138162

139-
// blink status LED on activity
140-
HAL_GPIO_WritePin(STATUS_PORT, STATUS_PIN, GPIO_PIN_RESET);
141-
HAL_Delay(STATUS_BLINK_TIME);
142-
HAL_GPIO_WritePin(STATUS_PORT, STATUS_PIN, GPIO_PIN_SET);
143163

144-
return true;
164+
//------------------------------------------------------------------------------
165+
// ISRs
166+
//------------------------------------------------------------------------------
167+
168+
// CAN FIFO0 receive ISR
169+
void USB_LP_CAN_RX0_IRQHandler(void)
170+
{
171+
if(HAL_CAN_GetRxFifoFillLevel(&hcan, CAN_RX_FIFO0) > 0)
172+
{
173+
CAN_RxHeaderTypeDef msg_header;
174+
if(HAL_CAN_GetRxMessage(&hcan, CAN_RX_FIFO0, &msg_header, buffer[buf_write_pos].payload) == HAL_OK)
175+
{
176+
buffer[buf_write_pos].cmd = msg_header.ExtId >> 8;
177+
buffer[buf_write_pos].id = msg_header.ExtId & 0xFF;
178+
buffer[buf_write_pos].len = msg_header.DLC;
179+
180+
// increment write position
181+
if(buf_write_pos == (CAN_BUF_SIZE - 1))
182+
buf_write_pos = 0;
183+
else
184+
buf_write_pos++;
185+
186+
if(buf_read_pos == buf_write_pos)
187+
{
188+
if(buf_read_pos == (CAN_BUF_SIZE - 1))
189+
buf_read_pos = 0;
190+
else
191+
buf_read_pos++;
192+
}
193+
}
194+
else
195+
{
196+
//debug_printf("Error receiving CAN message");
197+
}
198+
}
199+
200+
HAL_CAN_IRQHandler(&hcan);
145201
}

0 commit comments

Comments
 (0)