diff --git a/targets/TARGET_STM/can_api.c b/targets/TARGET_STM/can_api.c index abfff56..0843ba8 100644 --- a/targets/TARGET_STM/can_api.c +++ b/targets/TARGET_STM/can_api.c @@ -646,8 +646,12 @@ #include #include +#define ENABLED true +#define DISABLED false + static uint32_t can_irq_ids[CAN_NUM] = {0}; static can_irq_handler irq_handler; +static uint32_t rx_irq_status = DISABLED; static void can_registers_init(can_t *obj) { @@ -767,6 +771,7 @@ can->IER &= ~(CAN_IT_FMP0 | CAN_IT_FMP1 | CAN_IT_TME | \ CAN_IT_ERR | CAN_IT_EPV | CAN_IT_BOF); can_irq_ids[obj->index] = 0; + rx_irq_status = DISABLED; } void can_free(can_t *obj) @@ -998,6 +1003,10 @@ can->RF1R |= CAN_RF1R_RFOM1; } + if(rx_irq_status == ENABLED) { + __HAL_CAN_ENABLE_IT(&obj->CanHandle, CAN_IT_FMP0); + } + return 1; } @@ -1011,6 +1020,7 @@ /* restore registers state as saved in obj context */ can_registers_init(obj); + rx_irq_status = DISABLED; } unsigned char can_rderror(can_t *obj) @@ -1162,6 +1172,11 @@ tmp1 = __HAL_CAN_MSG_PENDING(&CanHandle, CAN_FIFO0); tmp2 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_FMP0); + // In legacy can, reading is the only way to clear rx interrupt. But can_read has mutex locks + // since mutexes cannot be used in ISR context, rx interrupt is masked here to temporary disable it + // rx interrupts will be unamsked in read operation. reads must be deffered to thread context. + __HAL_CAN_DISABLE_IT(&CanHandle, CAN_IT_FMP0); + if ((tmp1 != 0) && tmp2) { irq_handler(can_irq_ids[id], IRQ_RX); } @@ -1261,6 +1276,7 @@ ier = CAN_IT_FMP0; irq_n = CAN1_IRQ_RX_IRQN; vector = (uint32_t)&CAN1_IRQ_RX_VECT; + rx_irq_status = ENABLED; break; case IRQ_TX: ier = CAN_IT_TME; @@ -1293,6 +1309,7 @@ ier = CAN_IT_FMP0; irq_n = CAN2_IRQ_RX_IRQN; vector = (uint32_t)&CAN2_IRQ_RX_VECT; + rx_irq_status = ENABLED; break; case IRQ_TX: ier = CAN_IT_TME; @@ -1326,6 +1343,7 @@ ier = CAN_IT_FMP0; irq_n = CAN3_IRQ_RX_IRQN; vector = (uint32_t)&CAN3_IRQ_RX_VECT; + rx_irq_status = ENABLED; break; case IRQ_TX: ier = CAN_IT_TME;