@@ -646,8 +646,12 @@ void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable)
646
646
#include <string.h>
647
647
#include <inttypes.h>
648
648
649
+ #define ENABLED true
650
+ #define DISABLED false
651
+
649
652
static uint32_t can_irq_ids [CAN_NUM ] = {0 };
650
653
static can_irq_handler irq_handler ;
654
+ static uint32_t rx_irq_status = DISABLED ;
651
655
652
656
static void can_registers_init (can_t * obj )
653
657
{
@@ -767,6 +771,7 @@ void can_irq_free(can_t *obj)
767
771
can -> IER &= ~(CAN_IT_FMP0 | CAN_IT_FMP1 | CAN_IT_TME | \
768
772
CAN_IT_ERR | CAN_IT_EPV | CAN_IT_BOF );
769
773
can_irq_ids [obj -> index ] = 0 ;
774
+ rx_irq_status = DISABLED ;
770
775
}
771
776
772
777
void can_free (can_t * obj )
@@ -998,6 +1003,10 @@ int can_read(can_t *obj, CAN_Message *msg, int handle)
998
1003
can -> RF1R |= CAN_RF1R_RFOM1 ;
999
1004
}
1000
1005
1006
+ if (rx_irq_status == ENABLED ) {
1007
+ __HAL_CAN_ENABLE_IT (& obj -> CanHandle , CAN_IT_FMP0 );
1008
+ }
1009
+
1001
1010
return 1 ;
1002
1011
}
1003
1012
@@ -1011,6 +1020,7 @@ void can_reset(can_t *obj)
1011
1020
1012
1021
/* restore registers state as saved in obj context */
1013
1022
can_registers_init (obj );
1023
+ rx_irq_status = DISABLED ;
1014
1024
}
1015
1025
1016
1026
unsigned char can_rderror (can_t * obj )
@@ -1162,6 +1172,11 @@ static void can_irq(CANName name, int id)
1162
1172
tmp1 = __HAL_CAN_MSG_PENDING (& CanHandle , CAN_FIFO0 );
1163
1173
tmp2 = __HAL_CAN_GET_IT_SOURCE (& CanHandle , CAN_IT_FMP0 );
1164
1174
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
+
1165
1180
if ((tmp1 != 0 ) && tmp2 ) {
1166
1181
irq_handler (can_irq_ids [id ], IRQ_RX );
1167
1182
}
@@ -1261,6 +1276,7 @@ void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable)
1261
1276
ier = CAN_IT_FMP0 ;
1262
1277
irq_n = CAN1_IRQ_RX_IRQN ;
1263
1278
vector = (uint32_t )& CAN1_IRQ_RX_VECT ;
1279
+ rx_irq_status = ENABLED ;
1264
1280
break ;
1265
1281
case IRQ_TX :
1266
1282
ier = CAN_IT_TME ;
@@ -1293,6 +1309,7 @@ void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable)
1293
1309
ier = CAN_IT_FMP0 ;
1294
1310
irq_n = CAN2_IRQ_RX_IRQN ;
1295
1311
vector = (uint32_t )& CAN2_IRQ_RX_VECT ;
1312
+ rx_irq_status = ENABLED ;
1296
1313
break ;
1297
1314
case IRQ_TX :
1298
1315
ier = CAN_IT_TME ;
@@ -1326,6 +1343,7 @@ void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable)
1326
1343
ier = CAN_IT_FMP0 ;
1327
1344
irq_n = CAN3_IRQ_RX_IRQN ;
1328
1345
vector = (uint32_t )& CAN3_IRQ_RX_VECT ;
1346
+ rx_irq_status = ENABLED ;
1329
1347
break ;
1330
1348
case IRQ_TX :
1331
1349
ier = CAN_IT_TME ;
0 commit comments