Skip to content

Commit

Permalink
Merge pull request #55 from arduino/fix/can
Browse files Browse the repository at this point in the history
Fix: synchronize received CAN frames within pre-defined timeout.
  • Loading branch information
MaxPayne86 authored Aug 6, 2024
2 parents d12371a + fc75b6c commit 4fad98a
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 21 deletions.
1 change: 1 addition & 0 deletions include/can.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ void can_deinit(FDCAN_HandleTypeDef * handle);
int can_set_bittiming(FDCAN_HandleTypeDef * handle, uint32_t const baud_rate_prescaler, uint32_t const time_segment_1, uint32_t const time_segment_2, uint32_t const sync_jump_width);

uint32_t can_tx_fifo_available(FDCAN_HandleTypeDef * handle);
uint32_t can_rx_fifo_available(FDCAN_HandleTypeDef * handle, uint32_t const rx_fifo);
int can_write(FDCAN_HandleTypeDef * handle, uint32_t const id, uint8_t const len, uint8_t const * data);
int can_read(FDCAN_HandleTypeDef * handle, uint32_t * id, uint8_t * len, uint8_t * data);
int can_filter(FDCAN_HandleTypeDef * handle, uint32_t const filter_index, uint32_t const id, uint32_t const mask, bool const is_extended_id);
Expand Down
10 changes: 8 additions & 2 deletions src/can.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,8 @@ int can_internal_init(FDCAN_HandleTypeDef * handle)
if (HAL_FDCAN_ActivateNotification(handle, FDCAN_IT_RX_FIFO0_FULL | FDCAN_IT_RX_FIFO0_WATERMARK, 0) != HAL_OK)
Error_Handler("HAL_FDCAN_ActivateNotification(FDCAN_IT_RX_FIFO0_NEW_MESSAGE) Error_Handler\n");

HAL_FDCAN_ConfigFifoWatermark(handle, 0, 32);
if (HAL_FDCAN_ConfigFifoWatermark(handle, FDCAN_CFG_RX_FIFO0, 32) != HAL_OK)
Error_Handler("HAL_FDCAN_ConfigFifoWatermark(...) Error_Handler\n");

if (HAL_FDCAN_Start(handle) != HAL_OK)
Error_Handler("HAL_FDCAN_Start Error_Handler\n");
Expand Down Expand Up @@ -239,6 +240,11 @@ uint32_t can_tx_fifo_available(FDCAN_HandleTypeDef * handle)
return HAL_FDCAN_GetTxFifoFreeLevel(handle);
}

uint32_t can_rx_fifo_available(FDCAN_HandleTypeDef * handle, uint32_t const rx_fifo)
{
return HAL_FDCAN_GetRxFifoFillLevel(handle, rx_fifo);
}

int can_write(FDCAN_HandleTypeDef * handle, uint32_t const id, uint8_t const len, uint8_t const * data)
{
FDCAN_TxHeaderTypeDef TxHeader = {0};
Expand Down Expand Up @@ -284,7 +290,7 @@ int can_write(FDCAN_HandleTypeDef * handle, uint32_t const id, uint8_t const len
if (HAL_FDCAN_AddMessageToTxFifoQ(handle, &TxHeader, (uint8_t *)data) != HAL_OK)
{
uint32_t const err_code = HAL_FDCAN_GetError(handle);
printf("HAL_FDCAN_AddMessageToTxFifoQ failed with %ld\n", err_code);
dbg_printf("HAL_FDCAN_AddMessageToTxFifoQ failed with %ld\n", err_code);
return -err_code;
}
return 0;
Expand Down
61 changes: 44 additions & 17 deletions src/can_handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ extern FDCAN_HandleTypeDef fdcan_2;

static bool is_can1_init = false;
static bool is_can2_init = false;
static uint32_t can_1_last_enqueue = 0;
static uint32_t can_2_last_enqueue = 0;

/**************************************************************************************
* FUNCTION DECLARATION
Expand Down Expand Up @@ -138,33 +140,52 @@ int can_handle_data()
*/
int rc_enq;

uint32_t const now = HAL_GetTick();
static uint32_t const RX_CAN_FRAME_SYNC_TIMEOUT = 10;

if (is_can1_init)
{
for (rc_enq = 0; can_read(&fdcan_1, &can_id, &can_len, can_data); bytes_enqueued += rc_enq)
bool const can_1_rx_fifo_frames_available = can_rx_fifo_available(&fdcan_1, FDCAN_RX_FIFO0) > 0;
bool const can_1_should_enqueue = (now - can_1_last_enqueue) > RX_CAN_FRAME_SYNC_TIMEOUT; /* At least every 10 ms CAN frames should be synced to the X8. */

if (can_1_rx_fifo_frames_available && can_1_should_enqueue)
{
union x8h7_can_frame_message x8h7_msg;
for (rc_enq = 0; can_read(&fdcan_1, &can_id, &can_len, can_data); bytes_enqueued += rc_enq)
{
union x8h7_can_frame_message x8h7_msg;

x8h7_msg.field.id = can_id;
x8h7_msg.field.len = can_len;
memcpy(x8h7_msg.field.data, can_data, x8h7_msg.field.len);
x8h7_msg.field.id = can_id;
x8h7_msg.field.len = can_len;
memcpy(x8h7_msg.field.data, can_data, x8h7_msg.field.len);

rc_enq = enqueue_packet(PERIPH_FDCAN1, CAN_RX_FRAME, X8H7_CAN_HEADER_SIZE + x8h7_msg.field.len, x8h7_msg.buf);
if (!rc_enq) break;

rc_enq = enqueue_packet(PERIPH_FDCAN1, CAN_RX_FRAME, X8H7_CAN_HEADER_SIZE + x8h7_msg.field.len, x8h7_msg.buf);
if (!rc_enq) break;
can_1_last_enqueue = now;
}
}
}

if (is_can2_init)
{
for (rc_enq = 0; can_read(&fdcan_2, &can_id, &can_len, can_data); bytes_enqueued += rc_enq)
bool const can_2_rx_fifo_frames_available = can_rx_fifo_available(&fdcan_2, FDCAN_RX_FIFO0) > 0;
bool const can_2_should_enqueue = (now - can_2_last_enqueue) > RX_CAN_FRAME_SYNC_TIMEOUT; /* At least every 10 ms CAN frames should be synced to the X8. */

if (can_2_rx_fifo_frames_available && can_2_should_enqueue)
{
union x8h7_can_frame_message x8h7_msg;
for (rc_enq = 0; can_read(&fdcan_2, &can_id, &can_len, can_data); bytes_enqueued += rc_enq)
{
union x8h7_can_frame_message x8h7_msg;

x8h7_msg.field.id = can_id;
x8h7_msg.field.len = can_len;
memcpy(x8h7_msg.field.data, can_data, x8h7_msg.field.len);
x8h7_msg.field.id = can_id;
x8h7_msg.field.len = can_len;
memcpy(x8h7_msg.field.data, can_data, x8h7_msg.field.len);

rc_enq = enqueue_packet(PERIPH_FDCAN2, CAN_RX_FRAME, X8H7_CAN_HEADER_SIZE + x8h7_msg.field.len, x8h7_msg.buf);
if (!rc_enq) break;

rc_enq = enqueue_packet(PERIPH_FDCAN2, CAN_RX_FRAME, X8H7_CAN_HEADER_SIZE + x8h7_msg.field.len, x8h7_msg.buf);
if (!rc_enq) break;
can_2_last_enqueue = now;
}
}
}

Expand Down Expand Up @@ -324,7 +345,6 @@ void HAL_FDCAN_TxFifoEmptyCallback(FDCAN_HandleTypeDef * handle)
{
uint8_t x8_msg[2] = {X8H7_CAN_STS_INT_TX_FIFO_EMPTY, can_tx_fifo_available(handle)};
enqueue_packet(handle == &fdcan_1 ? PERIPH_FDCAN1 : PERIPH_FDCAN2, CAN_STATUS, sizeof(x8_msg), x8_msg);

}

void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs)
Expand All @@ -335,15 +355,22 @@ void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs)

if(((RxFifo0ITs & FDCAN_IT_RX_FIFO0_FULL) || (RxFifo0ITs & FDCAN_IT_RX_FIFO0_WATERMARK)) != RESET)
{
while ((get_available_enqueue() >= 8) && can_read(hfdcan, &can_id, &can_len, can_data)) {
union x8h7_can_frame_message x8h7_msg;
union x8h7_can_frame_message x8h7_msg;

while ((get_available_enqueue() >= sizeof(x8h7_msg)) && can_read(hfdcan, &can_id, &can_len, can_data))
{
x8h7_msg.field.id = can_id;
x8h7_msg.field.len = can_len;
memcpy(x8h7_msg.field.data, can_data, x8h7_msg.field.len);

int ret = enqueue_packet(hfdcan == &fdcan_1 ? PERIPH_FDCAN1 : PERIPH_FDCAN2, CAN_RX_FRAME, X8H7_CAN_HEADER_SIZE + x8h7_msg.field.len, x8h7_msg.buf);
if (ret == 0) break;

/* Save the timestamp when we've last enqueued data using the RX FIFO watermark. */
if (hfdcan == &fdcan_1)
can_1_last_enqueue = HAL_GetTick();
else
can_2_last_enqueue = HAL_GetTick();
}

if (HAL_FDCAN_ActivateNotification(hfdcan, FDCAN_IT_RX_FIFO0_FULL | FDCAN_IT_RX_FIFO0_WATERMARK, 0) != HAL_OK)
Expand Down
2 changes: 1 addition & 1 deletion src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ void handle_data()
if (virtual_uart_data_available())
virtual_uart_handle_data();

//can_handle_data();
can_handle_data();
gpio_handle_data();
dma_handle_data();

Expand Down
2 changes: 1 addition & 1 deletion src/pwm.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ void configurePwm(uint8_t channel, bool enable, bool polarity, uint32_t duty_ns,
HRTIM_SimplePWMChannelCfgTypeDef sConfig_Channel = {0};
HRTIM_TimeBaseCfgTypeDef pTimeBaseCfg = {0};

// invert 0% and 100% duty cycle (HRTIM special behaviour)
// invert 0% and 100% duty cycle (HRTIM special behavior)
if (duty_ns == 0) {
duty_ns = period_ns;
} else if (duty_ns == period_ns) {
Expand Down

0 comments on commit 4fad98a

Please sign in to comment.