Skip to content

Commit 830fcfb

Browse files
committed
can_driver_stm32h7: add bus_off recovery support
1 parent bd4f1a4 commit 830fcfb

File tree

1 file changed

+20
-8
lines changed

1 file changed

+20
-8
lines changed

modules/can_driver_stm32/can_driver_stm32h7.c

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ struct can_driver_stm32_instance_s {
6060
FDCAN_GlobalTypeDef* can;
6161
};
6262

63+
static void stm32_can_tx_handler_I(struct can_driver_stm32_instance_s* instance);
64+
6365
static struct can_driver_stm32_instance_s can1_instance;
6466

6567
RUN_ON(CAN_INIT) {
@@ -277,10 +279,11 @@ static void can_driver_stm32_start(void* ctx, bool silent, bool auto_retransmit,
277279
FDCAN_IE_RF0NE | // RX FIFO 0 new message
278280
FDCAN_IE_RF0FE | // Rx FIFO 1 FIFO Full
279281
FDCAN_IE_RF1NE | // RX FIFO 1 new message
280-
FDCAN_IE_RF1FE; // Rx FIFO 1 FIFO Full
281-
instance->can->IE |= FDCAN_IE_TCFE | (1UL<<27); // Transmit Canceled interrupt enable, it doubles as
282+
FDCAN_IE_RF1FE | // Rx FIFO 1 FIFO Full
283+
FDCAN_IE_BOE; // bus off
284+
instance->can->IE |= FDCAN_IE_TCFE | FDCAN_IE_PEAE; // Transmit Canceled interrupt enable, it doubles as
282285
// transmit failed in Disabled AutoRetransmission mode.
283-
instance->can->ILS = FDCAN_ILS_TCL | FDCAN_ILS_TCFL | (1UL<<27); //Set Line 1 for Transmit Complete Event Interrupt
286+
instance->can->ILS = FDCAN_ILS_TCL | FDCAN_ILS_TCFL | FDCAN_ILS_PEAE | FDCAN_ILS_BOE; //Set Line 1 for Transmit Complete Event Interrupt
284287
instance->can->TXBTIE = (1 << NUM_TX_MAILBOXES) - 1;
285288
instance->can->ILE = 0x3; // Enable both interrupt handlers
286289

@@ -418,11 +421,9 @@ static void stm32_can_rx_handler(struct can_driver_stm32_instance_s* instance) {
418421
chSysUnlockFromISR();
419422
}
420423

421-
static void stm32_can_tx_handler(struct can_driver_stm32_instance_s* instance) {
424+
static void stm32_can_tx_handler_I(struct can_driver_stm32_instance_s* instance) {
422425
systime_t t_now = chVTGetSystemTimeX();
423426

424-
chSysLockFromISR();
425-
426427
for (uint8_t i = 0; i < NUM_TX_MAILBOXES; i++) {
427428
if (instance->tx_bits_processed & (1UL << i)) {
428429
continue;
@@ -442,7 +443,11 @@ static void stm32_can_tx_handler(struct can_driver_stm32_instance_s* instance) {
442443
can_driver_tx_request_complete_I(instance->frontend, i, false, t_now);
443444
}
444445
}
446+
}
445447

448+
static void stm32_can_tx_handler(struct can_driver_stm32_instance_s* instance) {
449+
chSysLockFromISR();
450+
stm32_can_tx_handler_I(instance);
446451
chSysUnlockFromISR();
447452
}
448453

@@ -458,15 +463,22 @@ static void stm32_can_interrupt_handler(struct can_driver_stm32_instance_s *inst
458463
if (instance->can->IR & FDCAN_IR_TC) {
459464
instance->can->IR = FDCAN_IR_TC;
460465
stm32_can_tx_handler(instance);
466+
461467
}
462468

463469
if (instance->can->IR & FDCAN_IR_TCF) {
464470
instance->can->IR = FDCAN_IR_TCF;
465471
stm32_can_tx_handler(instance);
466472
}
467473

468-
if (instance->can->IR & (1UL << 27)) {
469-
instance->can->IR = (1UL << 27);
474+
if (instance->can->IR & FDCAN_IR_PEA) {
475+
instance->can->IR = FDCAN_IR_PEA;
476+
stm32_can_tx_handler(instance);
477+
}
478+
479+
if (instance->can->IR & FDCAN_IR_BO) {
480+
instance->can->IR = FDCAN_IR_BO;
481+
instance->can->CCCR &= ~FDCAN_CCCR_INIT;
470482
stm32_can_tx_handler(instance);
471483
}
472484
}

0 commit comments

Comments
 (0)