Implementation for can_read to be deferred to thread context when rx

interrupt is enabled.
pull/14688/head
Mohammed Mubeen 2021-05-21 16:11:37 +05:30
parent 14e5d307bb
commit 033b08de19
1 changed files with 18 additions and 0 deletions

View File

@ -646,8 +646,12 @@ void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable)
#include <string.h>
#include <inttypes.h>
#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 @@ void can_irq_free(can_t *obj)
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 @@ int can_read(can_t *obj, CAN_Message *msg, int handle)
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 @@ void can_reset(can_t *obj)
/* 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 @@ static void can_irq(CANName name, int id)
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 @@ void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable)
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 @@ void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable)
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 @@ void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable)
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;