Skip to content

Commit 033b08d

Browse files
committed
Implementation for can_read to be deferred to thread context when rx
interrupt is enabled.
1 parent 14e5d30 commit 033b08d

File tree

1 file changed

+18
-0
lines changed

1 file changed

+18
-0
lines changed

targets/TARGET_STM/can_api.c

+18
Original file line numberDiff line numberDiff line change
@@ -646,8 +646,12 @@ void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable)
646646
#include <string.h>
647647
#include <inttypes.h>
648648

649+
#define ENABLED true
650+
#define DISABLED false
651+
649652
static uint32_t can_irq_ids[CAN_NUM] = {0};
650653
static can_irq_handler irq_handler;
654+
static uint32_t rx_irq_status = DISABLED;
651655

652656
static void can_registers_init(can_t *obj)
653657
{
@@ -767,6 +771,7 @@ void can_irq_free(can_t *obj)
767771
can->IER &= ~(CAN_IT_FMP0 | CAN_IT_FMP1 | CAN_IT_TME | \
768772
CAN_IT_ERR | CAN_IT_EPV | CAN_IT_BOF);
769773
can_irq_ids[obj->index] = 0;
774+
rx_irq_status = DISABLED;
770775
}
771776

772777
void can_free(can_t *obj)
@@ -998,6 +1003,10 @@ int can_read(can_t *obj, CAN_Message *msg, int handle)
9981003
can->RF1R |= CAN_RF1R_RFOM1;
9991004
}
10001005

1006+
if(rx_irq_status == ENABLED) {
1007+
__HAL_CAN_ENABLE_IT(&obj->CanHandle, CAN_IT_FMP0);
1008+
}
1009+
10011010
return 1;
10021011
}
10031012

@@ -1011,6 +1020,7 @@ void can_reset(can_t *obj)
10111020

10121021
/* restore registers state as saved in obj context */
10131022
can_registers_init(obj);
1023+
rx_irq_status = DISABLED;
10141024
}
10151025

10161026
unsigned char can_rderror(can_t *obj)
@@ -1162,6 +1172,11 @@ static void can_irq(CANName name, int id)
11621172
tmp1 = __HAL_CAN_MSG_PENDING(&CanHandle, CAN_FIFO0);
11631173
tmp2 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_FMP0);
11641174

1175+
// In legacy can, reading is the only way to clear rx interrupt. But can_read has mutex locks
1176+
// since mutexes cannot be used in ISR context, rx interrupt is masked here to temporary disable it
1177+
// rx interrupts will be unamsked in read operation. reads must be deffered to thread context.
1178+
__HAL_CAN_DISABLE_IT(&CanHandle, CAN_IT_FMP0);
1179+
11651180
if ((tmp1 != 0) && tmp2) {
11661181
irq_handler(can_irq_ids[id], IRQ_RX);
11671182
}
@@ -1261,6 +1276,7 @@ void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable)
12611276
ier = CAN_IT_FMP0;
12621277
irq_n = CAN1_IRQ_RX_IRQN;
12631278
vector = (uint32_t)&CAN1_IRQ_RX_VECT;
1279+
rx_irq_status = ENABLED;
12641280
break;
12651281
case IRQ_TX:
12661282
ier = CAN_IT_TME;
@@ -1293,6 +1309,7 @@ void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable)
12931309
ier = CAN_IT_FMP0;
12941310
irq_n = CAN2_IRQ_RX_IRQN;
12951311
vector = (uint32_t)&CAN2_IRQ_RX_VECT;
1312+
rx_irq_status = ENABLED;
12961313
break;
12971314
case IRQ_TX:
12981315
ier = CAN_IT_TME;
@@ -1326,6 +1343,7 @@ void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable)
13261343
ier = CAN_IT_FMP0;
13271344
irq_n = CAN3_IRQ_RX_IRQN;
13281345
vector = (uint32_t)&CAN3_IRQ_RX_VECT;
1346+
rx_irq_status = ENABLED;
13291347
break;
13301348
case IRQ_TX:
13311349
ier = CAN_IT_TME;

0 commit comments

Comments
 (0)