99
1010#include <stdbool.h>
1111#include <stdint.h>
12+ #include <string.h>
1213#include <stm32f3xx_hal.h>
1314
1415#include "can.h"
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
3740static 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
93103void 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