CAN: Use uintptr_t for can_irq_ids

The HAL can_api stores an array of IDs in order to dispatch interrupts
to the correct CAN object. The drivers level CAN Class casts a pointer
to itself to an uint32_t, which is stored as the ID and then cast back
to a CAN * in order to call the correct handler. This results in
compilation failure when the size of an object pointer is greater than
uint32_t, for example when building on a PC for unit testing.

In order to allow Unit Testing of the CAN Class, we replace the use of
uint32_t with uintptr_t (type capable of holding a pointer), which
allows portability and expresses intentions more clearly. In aid of this
latter goal, we also replace the use of the name "id" with "context",
to improve clarity. These are addresses of the context related to that
callback.
pull/15077/head
Hari Limaye 2021-09-13 19:49:10 +01:00
parent 810adf9aa8
commit b493a15a53
13 changed files with 126 additions and 126 deletions

View File

@ -205,7 +205,7 @@ public:
*/
void attach(Callback<void()> func, IrqType type = IrqType::RxIrq);
static void _irq_handler(uint32_t id, CanIrqType type);
static void _irq_handler(uintptr_t context, CanIrqType type);
#if !defined(DOXYGEN_ONLY)
protected:

View File

@ -26,28 +26,28 @@ CAN::CAN(PinName rd, PinName td) : _can(), _irq()
{
// No lock needed in constructor
can_init(&_can, rd, td);
can_irq_init(&_can, (&CAN::_irq_handler), (uint32_t)this);
can_irq_init(&_can, (&CAN::_irq_handler), reinterpret_cast<uintptr_t>(this));
}
CAN::CAN(PinName rd, PinName td, int hz) : _can(), _irq()
{
// No lock needed in constructor
can_init_freq(&_can, rd, td, hz);
can_irq_init(&_can, (&CAN::_irq_handler), (uint32_t)this);
can_irq_init(&_can, (&CAN::_irq_handler), reinterpret_cast<uintptr_t>(this));
}
CAN::CAN(const can_pinmap_t &pinmap) : _can(), _irq()
{
// No lock needed in constructor
can_init_direct(&_can, &pinmap);
can_irq_init(&_can, (&CAN::_irq_handler), (uint32_t)this);
can_irq_init(&_can, (&CAN::_irq_handler), reinterpret_cast<uintptr_t>(this));
}
CAN::CAN(const can_pinmap_t &pinmap, int hz) : _can(), _irq()
{
// No lock needed in constructor
can_init_freq_direct(&_can, &pinmap, hz);
can_irq_init(&_can, (&CAN::_irq_handler), (uint32_t)this);
can_irq_init(&_can, (&CAN::_irq_handler), reinterpret_cast<uintptr_t>(this));
}
CAN::~CAN()
@ -153,9 +153,9 @@ void CAN::attach(Callback<void()> func, IrqType type)
unlock();
}
void CAN::_irq_handler(uint32_t id, CanIrqType type)
void CAN::_irq_handler(uintptr_t context, CanIrqType type)
{
CAN *handler = (CAN *)id;
CAN *handler = reinterpret_cast<CAN *>(context);
if (handler->_irq[type]) {
handler->_irq[type].call();
}

View File

@ -63,7 +63,7 @@ typedef struct {
int td_function;
} can_pinmap_t;
typedef void (*can_irq_handler)(uint32_t id, CanIrqType type);
typedef void (*can_irq_handler)(uintptr_t context, CanIrqType type);
typedef struct can_s can_t;
@ -74,7 +74,7 @@ void can_init_freq_direct(can_t *obj, const can_pinmap_t *pinmap, int h
void can_free(can_t *obj);
int can_frequency(can_t *obj, int hz);
void can_irq_init(can_t *obj, can_irq_handler handler, uint32_t id);
void can_irq_init(can_t *obj, can_irq_handler handler, uintptr_t context);
void can_irq_free(can_t *obj);
void can_irq_set(can_t *obj, CanIrqType irq, uint32_t enable);

View File

@ -38,7 +38,7 @@
/* CAN1 interrupt vector number */
#define CAN1_IRQ_BASE_NUM 63
static uint32_t can_irq_ids[2] = {0};
static uintptr_t can_irq_contexts[2] = {0};
static can_irq_handler irq_callback;
/** CAN interrupt handle .
@ -66,13 +66,13 @@ static void dev_can_irq_handle(uint32_t periph, int id)
/* CAN transmit complete interrupt handle */
if (flag0 || flag1 || flag2) {
irq_callback(can_irq_ids[id], IRQ_TX);
irq_callback(can_irq_contexts[id], IRQ_TX);
}
/* CAN receive complete interrupt handle */
if (CAN_INTEN_RFNEIE0 == (CAN_INTEN(periph) & CAN_INTEN_RFNEIE0)) {
if (0 != can_receive_message_length_get(periph, CAN_FIFO0)) {
irq_callback(can_irq_ids[id], IRQ_RX);
irq_callback(can_irq_contexts[id], IRQ_RX);
}
}
@ -81,18 +81,18 @@ static void dev_can_irq_handle(uint32_t periph, int id)
/* passive error interrupt handle */
if (CAN_INTEN_PERRIE == (CAN_INTEN(periph) & CAN_INTEN_PERRIE)) {
if (SET == can_flag_get(periph, CAN_FLAG_PERR)) {
irq_callback(can_irq_ids[id], IRQ_PASSIVE);
irq_callback(can_irq_contexts[id], IRQ_PASSIVE);
}
}
/* bus-off interrupt handle */
if (CAN_INTEN_BOIE == (CAN_INTEN(periph) & CAN_INTEN_BOIE)) {
if (SET == can_flag_get(periph, CAN_FLAG_BOERR)) {
irq_callback(can_irq_ids[id], IRQ_BUS);
irq_callback(can_irq_contexts[id], IRQ_BUS);
}
}
irq_callback(can_irq_ids[id], IRQ_ERROR);
irq_callback(can_irq_contexts[id], IRQ_ERROR);
}
}
@ -330,10 +330,10 @@ int can_frequency(can_t *obj, int hz)
* @param handler the interrupt callback.
* @param id the CANx index.
*/
void can_irq_init(can_t *obj, can_irq_handler handler, uint32_t id)
void can_irq_init(can_t *obj, can_irq_handler handler, uintptr_t context)
{
irq_callback = handler;
can_irq_ids[obj->index] = id;
can_irq_contexts[obj->index] = context;
}
/** disable the interrupt.
@ -351,7 +351,7 @@ void can_irq_free(can_t *obj)
CAN_INTEN_PERRIE | CAN_INTEN_BOIE | CAN_INTEN_ERRIE);
}
can_irq_ids[obj->index] = 0;
can_irq_contexts[obj->index] = 0;
}
/** Set the interrupt handle.

View File

@ -38,7 +38,7 @@
/* CAN1 interrupt vector number */
#define CAN1_IRQ_BASE_NUM 63
static uint32_t can_irq_ids[2] = {0};
static uintptr_t can_irq_contexts[2] = {0};
static can_irq_handler irq_callback;
/** CAN interrupt handle .
@ -66,13 +66,13 @@ static void dev_can_irq_handle(uint32_t periph, int id)
/* CAN transmit complete interrupt handle */
if (flag0 || flag1 || flag2) {
irq_callback(can_irq_ids[id], IRQ_TX);
irq_callback(can_irq_contexts[id], IRQ_TX);
}
/* CAN receive complete interrupt handle */
if (CAN_INTEN_RFNEIE0 == (CAN_INTEN(periph) & CAN_INTEN_RFNEIE0)) {
if (0 != can_receive_message_length_get(periph, CAN_FIFO0)) {
irq_callback(can_irq_ids[id], IRQ_RX);
irq_callback(can_irq_contexts[id], IRQ_RX);
}
}
@ -81,18 +81,18 @@ static void dev_can_irq_handle(uint32_t periph, int id)
/* passive error interrupt handle */
if (CAN_INTEN_PERRIE == (CAN_INTEN(periph) & CAN_INTEN_PERRIE)) {
if (SET == can_flag_get(periph, CAN_FLAG_PERR)) {
irq_callback(can_irq_ids[id], IRQ_PASSIVE);
irq_callback(can_irq_contexts[id], IRQ_PASSIVE);
}
}
/* bus-off interrupt handle */
if (CAN_INTEN_BOIE == (CAN_INTEN(periph) & CAN_INTEN_BOIE)) {
if (SET == can_flag_get(periph, CAN_FLAG_BOERR)) {
irq_callback(can_irq_ids[id], IRQ_BUS);
irq_callback(can_irq_contexts[id], IRQ_BUS);
}
}
irq_callback(can_irq_ids[id], IRQ_ERROR);
irq_callback(can_irq_contexts[id], IRQ_ERROR);
}
}
@ -331,10 +331,10 @@ int can_frequency(can_t *obj, int hz)
* @param handler the interrupt callback.
* @param id the CANx index.
*/
void can_irq_init(can_t *obj, can_irq_handler handler, uint32_t id)
void can_irq_init(can_t *obj, can_irq_handler handler, uintptr_t context)
{
irq_callback = handler;
can_irq_ids[obj->index] = id;
can_irq_contexts[obj->index] = context;
}
/** disable the interrupt.
@ -352,7 +352,7 @@ void can_irq_free(can_t *obj)
CAN_INTEN_PERRIE | CAN_INTEN_BOIE | CAN_INTEN_ERRIE);
}
can_irq_ids[obj->index] = 0;
can_irq_contexts[obj->index] = 0;
}
/** Set the interrupt handle.

View File

@ -31,7 +31,7 @@
#define NU_CAN_DEBUG 0
#define CAN_NUM 1
static uint32_t can_irq_ids[CAN_NUM] = {0};
static uintptr_t can_irq_contexts[CAN_NUM] = {0};
static can_irq_handler can0_irq_handler;
@ -125,34 +125,34 @@ static void can_irq(CANName name, int id)
/**************************/
if(can->STATUS & CAN_STATUS_RXOK_Msk) {
can->STATUS &= ~CAN_STATUS_RXOK_Msk; /* Clear Rx Ok status*/
can0_irq_handler(can_irq_ids[id], IRQ_RX);
can0_irq_handler(can_irq_contexts[id], IRQ_RX);
}
if(can->STATUS & CAN_STATUS_TXOK_Msk) {
can->STATUS &= ~CAN_STATUS_TXOK_Msk; /* Clear Tx Ok status*/
can0_irq_handler(can_irq_ids[id], IRQ_TX);
can0_irq_handler(can_irq_contexts[id], IRQ_TX);
}
/**************************/
/* Error Status interrupt */
/**************************/
if(can->STATUS & CAN_STATUS_EWARN_Msk) {
can0_irq_handler(can_irq_ids[id], IRQ_ERROR);
can0_irq_handler(can_irq_contexts[id], IRQ_ERROR);
}
if(can->STATUS & CAN_STATUS_BOFF_Msk) {
can0_irq_handler(can_irq_ids[id], IRQ_BUS);
can0_irq_handler(can_irq_contexts[id], IRQ_BUS);
}
} else if (u8IIDRstatus!=0) {
can0_irq_handler(can_irq_ids[id], IRQ_OVERRUN);
can0_irq_handler(can_irq_contexts[id], IRQ_OVERRUN);
CAN_CLR_INT_PENDING_BIT(can, ((can->IIDR) -1)); /* Clear Interrupt Pending */
} else if(can->WU_STATUS == 1) {
can->WU_STATUS = 0; /* Write '0' to clear */
can0_irq_handler(can_irq_ids[id], IRQ_WAKEUP);
can0_irq_handler(can_irq_contexts[id], IRQ_WAKEUP);
}
}
@ -161,17 +161,17 @@ void CAN0_IRQHandler(void)
can_irq(CAN_0, 0);
}
void can_irq_init(can_t *obj, can_irq_handler handler, uint32_t id)
void can_irq_init(can_t *obj, can_irq_handler handler, uintptr_t context)
{
can0_irq_handler = handler;
can_irq_ids[obj->index] = id;
can_irq_contexts[obj->index] = context;
}
void can_irq_free(can_t *obj)
{
CAN_DisableInt((CAN_T *)NU_MODBASE(obj->can), (CAN_CON_IE_Msk|CAN_CON_SIE_Msk|CAN_CON_EIE_Msk));
can_irq_ids[obj->index] = 0;
can_irq_contexts[obj->index] = 0;
NVIC_DisableIRQ(CAN0_IRQn);
}

View File

@ -34,7 +34,7 @@
#define NU_CAN_DEBUG 0
#define CAN_NUM 2
static uint32_t can_irq_ids[CAN_NUM] = {0};
static uintptr_t can_irq_contexts[CAN_NUM] = {0};
static can_irq_handler can0_irq_handler;
static can_irq_handler can1_irq_handler;
@ -140,17 +140,17 @@ static void can_irq(CANName name, int id)
if(can->STATUS & CAN_STATUS_RXOK_Msk) {
can->STATUS &= ~CAN_STATUS_RXOK_Msk; /* Clear Rx Ok status*/
if(id)
can1_irq_handler(can_irq_ids[id], IRQ_RX);
can1_irq_handler(can_irq_contexts[id], IRQ_RX);
else
can0_irq_handler(can_irq_ids[id], IRQ_RX);
can0_irq_handler(can_irq_contexts[id], IRQ_RX);
}
if(can->STATUS & CAN_STATUS_TXOK_Msk) {
can->STATUS &= ~CAN_STATUS_TXOK_Msk; /* Clear Tx Ok status*/
if(id)
can1_irq_handler(can_irq_ids[id], IRQ_TX);
can1_irq_handler(can_irq_contexts[id], IRQ_TX);
else
can0_irq_handler(can_irq_ids[id], IRQ_TX);
can0_irq_handler(can_irq_contexts[id], IRQ_TX);
}
@ -159,23 +159,23 @@ static void can_irq(CANName name, int id)
/**************************/
if(can->STATUS & CAN_STATUS_EWARN_Msk) {
if(id)
can1_irq_handler(can_irq_ids[id], IRQ_ERROR);
can1_irq_handler(can_irq_contexts[id], IRQ_ERROR);
else
can0_irq_handler(can_irq_ids[id], IRQ_ERROR);
can0_irq_handler(can_irq_contexts[id], IRQ_ERROR);
}
if(can->STATUS & CAN_STATUS_BOFF_Msk) {
if(id)
can1_irq_handler(can_irq_ids[id], IRQ_BUS);
can1_irq_handler(can_irq_contexts[id], IRQ_BUS);
else
can0_irq_handler(can_irq_ids[id], IRQ_BUS);
can0_irq_handler(can_irq_contexts[id], IRQ_BUS);
}
} else if (u8IIDRstatus!=0) {
if(id)
can1_irq_handler(can_irq_ids[id], IRQ_OVERRUN);
can1_irq_handler(can_irq_contexts[id], IRQ_OVERRUN);
else
can0_irq_handler(can_irq_ids[id], IRQ_OVERRUN);
can0_irq_handler(can_irq_contexts[id], IRQ_OVERRUN);
CAN_CLR_INT_PENDING_BIT(can, ((can->IIDR) -1)); /* Clear Interrupt Pending */
@ -183,9 +183,9 @@ static void can_irq(CANName name, int id)
can->WU_STATUS = 0; /* Write '0' to clear */
if(id)
can1_irq_handler(can_irq_ids[id], IRQ_WAKEUP);
can1_irq_handler(can_irq_contexts[id], IRQ_WAKEUP);
else
can0_irq_handler(can_irq_ids[id], IRQ_WAKEUP);
can0_irq_handler(can_irq_contexts[id], IRQ_WAKEUP);
}
}
@ -199,13 +199,13 @@ void CAN1_IRQHandler(void)
can_irq(CAN_1, 1);
}
void can_irq_init(can_t *obj, can_irq_handler handler, uint32_t id)
void can_irq_init(can_t *obj, can_irq_handler handler, uintptr_t context)
{
if(obj->index)
can1_irq_handler = handler;
else
can0_irq_handler = handler;
can_irq_ids[obj->index] = id;
can_irq_contexts[obj->index] = context;
}
@ -213,7 +213,7 @@ void can_irq_free(can_t *obj)
{
CAN_DisableInt((CAN_T *)NU_MODBASE(obj->can), (CAN_CON_IE_Msk|CAN_CON_SIE_Msk|CAN_CON_EIE_Msk));
can_irq_ids[obj->index] = 0;
can_irq_contexts[obj->index] = 0;
if(!obj->index)
NVIC_DisableIRQ(CAN0_IRQn);

View File

@ -31,7 +31,7 @@
#define NU_CAN_DEBUG 0
#define CAN_NUM 2
static uint32_t can_irq_ids[CAN_NUM] = {0};
static uintptr_t can_irq_contexts[CAN_NUM] = {0};
static can_irq_handler can0_irq_handler;
static can_irq_handler can1_irq_handler;
@ -134,17 +134,17 @@ static void can_irq(CANName name, int id)
if(can->STATUS & CAN_STATUS_RXOK_Msk) {
can->STATUS &= ~CAN_STATUS_RXOK_Msk; /* Clear Rx Ok status*/
if(id)
can1_irq_handler(can_irq_ids[id] , IRQ_RX);
can1_irq_handler(can_irq_contexts[id] , IRQ_RX);
else
can0_irq_handler(can_irq_ids[id], IRQ_RX);
can0_irq_handler(can_irq_contexts[id], IRQ_RX);
}
if(can->STATUS & CAN_STATUS_TXOK_Msk) {
can->STATUS &= ~CAN_STATUS_TXOK_Msk; /* Clear Tx Ok status*/
if(id)
can1_irq_handler(can_irq_ids[id] , IRQ_TX);
can1_irq_handler(can_irq_contexts[id] , IRQ_TX);
else
can0_irq_handler(can_irq_ids[id], IRQ_TX);
can0_irq_handler(can_irq_contexts[id], IRQ_TX);
}
@ -153,23 +153,23 @@ static void can_irq(CANName name, int id)
/**************************/
if(can->STATUS & CAN_STATUS_EWARN_Msk) {
if(id)
can1_irq_handler(can_irq_ids[id] , IRQ_ERROR);
can1_irq_handler(can_irq_contexts[id] , IRQ_ERROR);
else
can0_irq_handler(can_irq_ids[id], IRQ_ERROR);
can0_irq_handler(can_irq_contexts[id], IRQ_ERROR);
}
if(can->STATUS & CAN_STATUS_BOFF_Msk) {
if(id)
can1_irq_handler(can_irq_ids[id] , IRQ_BUS);
can1_irq_handler(can_irq_contexts[id] , IRQ_BUS);
else
can0_irq_handler(can_irq_ids[id], IRQ_BUS);
can0_irq_handler(can_irq_contexts[id], IRQ_BUS);
}
} else if (u8IIDRstatus!=0) {
if(id)
can1_irq_handler(can_irq_ids[id] , IRQ_OVERRUN);
can1_irq_handler(can_irq_contexts[id] , IRQ_OVERRUN);
else
can0_irq_handler(can_irq_ids[id], IRQ_OVERRUN);
can0_irq_handler(can_irq_contexts[id], IRQ_OVERRUN);
CAN_CLR_INT_PENDING_BIT(can, ((can->IIDR) -1)); /* Clear Interrupt Pending */
@ -177,9 +177,9 @@ static void can_irq(CANName name, int id)
can->WU_STATUS = 0; /* Write '0' to clear */
if(id)
can1_irq_handler(can_irq_ids[id] , IRQ_WAKEUP);
can1_irq_handler(can_irq_contexts[id] , IRQ_WAKEUP);
else
can0_irq_handler(can_irq_ids[id], IRQ_WAKEUP);
can0_irq_handler(can_irq_contexts[id], IRQ_WAKEUP);
}
}
@ -193,13 +193,13 @@ void CAN1_IRQHandler(void)
can_irq(CAN_1, 1);
}
void can_irq_init(can_t *obj, can_irq_handler handler, uint32_t id)
void can_irq_init(can_t *obj, can_irq_handler handler, uintptr_t context)
{
if(obj->index)
can1_irq_handler = handler;
else
can0_irq_handler = handler;
can_irq_ids[obj->index] = id;
can_irq_contexts[obj->index] = context;
}
@ -207,7 +207,7 @@ void can_irq_free(can_t *obj)
{
CAN_DisableInt((CAN_T *)NU_MODBASE(obj->can), (CAN_CON_IE_Msk|CAN_CON_SIE_Msk|CAN_CON_EIE_Msk));
can_irq_ids[obj->index] = 0;
can_irq_contexts[obj->index] = 0;
if(!obj->index)
NVIC_DisableIRQ(CAN0_IRQn);

View File

@ -64,7 +64,7 @@ struct CANMsg {
};
typedef struct CANMsg CANMsg;
static uint32_t can_irq_ids[CAN_NUM] = {0};
static uintptr_t can_irq_contexts[CAN_NUM] = {0};
static can_irq_handler irq_handler;
static uint32_t can_disable(can_t *obj) {
@ -130,18 +130,18 @@ static inline void can_irq(uint32_t icr, uint32_t index) {
for(i = 0; i < 8; i++)
{
if((can_irq_ids[index] != 0) && (icr & (1 << i)))
if((can_irq_contexts[index] != 0) && (icr & (1 << i)))
{
switch (i) {
case 0: irq_handler(can_irq_ids[index], IRQ_RX); break;
case 1: irq_handler(can_irq_ids[index], IRQ_TX); break;
case 2: irq_handler(can_irq_ids[index], IRQ_ERROR); break;
case 3: irq_handler(can_irq_ids[index], IRQ_OVERRUN); break;
case 4: irq_handler(can_irq_ids[index], IRQ_WAKEUP); break;
case 5: irq_handler(can_irq_ids[index], IRQ_PASSIVE); break;
case 6: irq_handler(can_irq_ids[index], IRQ_ARB); break;
case 7: irq_handler(can_irq_ids[index], IRQ_BUS); break;
case 8: irq_handler(can_irq_ids[index], IRQ_READY); break;
case 0: irq_handler(can_irq_contexts[index], IRQ_RX); break;
case 1: irq_handler(can_irq_contexts[index], IRQ_TX); break;
case 2: irq_handler(can_irq_contexts[index], IRQ_ERROR); break;
case 3: irq_handler(can_irq_contexts[index], IRQ_OVERRUN); break;
case 4: irq_handler(can_irq_contexts[index], IRQ_WAKEUP); break;
case 5: irq_handler(can_irq_contexts[index], IRQ_PASSIVE); break;
case 6: irq_handler(can_irq_contexts[index], IRQ_ARB); break;
case 7: irq_handler(can_irq_contexts[index], IRQ_BUS); break;
case 8: irq_handler(can_irq_contexts[index], IRQ_READY); break;
}
}
}
@ -164,17 +164,17 @@ void can_irq_n() {
}
// Register CAN object's irq handler
void can_irq_init(can_t *obj, can_irq_handler handler, uint32_t id) {
void can_irq_init(can_t *obj, can_irq_handler handler, uintptr_t context) {
irq_handler = handler;
can_irq_ids[obj->index] = id;
can_irq_contexts[obj->index] = context;
}
// Unregister CAN object's irq handler
void can_irq_free(can_t *obj) {
obj->dev->IER &= ~(1);
can_irq_ids[obj->index] = 0;
can_irq_contexts[obj->index] = 0;
if ((can_irq_ids[0] == 0) && (can_irq_ids[1] == 0)) {
if ((can_irq_contexts[0] == 0) && (can_irq_contexts[1] == 0)) {
NVIC_DisableIRQ(CAN_IRQn);
}
}

View File

@ -104,7 +104,7 @@ typedef struct {
} can_info_int_t;
static can_irq_handler irq_handler;
static uint32_t can_irq_id[CAN_NUM];
static uintptr_t can_irq_contexts[CAN_NUM];
static int can_initialized[CAN_NUM] = {0};
@ -310,13 +310,13 @@ static __IO uint32_t *dmy_gaflm = &RSCAN0GAFLM0;
static __IO uint32_t *dmy_gaflp0 = &RSCAN0GAFLP00;
static __IO uint32_t *dmy_gaflp1 = &RSCAN0GAFLP10;
void can_irq_init(can_t *obj, can_irq_handler handler, uint32_t id) {
void can_irq_init(can_t *obj, can_irq_handler handler, uintptr_t context) {
irq_handler = handler;
can_irq_id[obj->ch] = id;
can_irq_contexts[obj->ch] = context;
}
void can_irq_free(can_t *obj) {
can_irq_id[obj->ch] = 0;
can_irq_contexts[obj->ch] = 0;
}
void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable) {
@ -358,7 +358,7 @@ static void can_rec_irq(uint32_t ch) {
dmy_cfsts = CFSTS_TBL[ch][CAN_RECV];
*dmy_cfsts &= 0xFFFFFFF7; // Clear CFRXIF
irq_handler(can_irq_id[ch], IRQ_RX);
irq_handler(can_irq_contexts[ch], IRQ_RX);
}
static void can_trx_irq(uint32_t ch) {
@ -367,7 +367,7 @@ static void can_trx_irq(uint32_t ch) {
dmy_cfsts = CFSTS_TBL[ch][CAN_SEND];
*dmy_cfsts &= 0xFFFFFFEF; // Clear CFTXIF
irq_handler(can_irq_id[ch], IRQ_TX);
irq_handler(can_irq_contexts[ch], IRQ_TX);
}
static void can_err_irq(uint32_t ch, CanIrqType type) {
@ -400,7 +400,7 @@ static void can_err_irq(uint32_t ch, CanIrqType type) {
break;
}
if (val == 1) {
irq_handler(can_irq_id[ch], type);
irq_handler(can_irq_contexts[ch], type);
}
}

View File

@ -382,17 +382,17 @@ volatile int g_normal_bitrate[CHANNEL_MAX];
volatile int g_data_bitrate[CHANNEL_MAX] = {D_CH0_BITRATE, D_CH1_BITRATE};
uint32_t rx_buf[RX_BUFFER_MAX];
static can_irq_handler irq_handler[CHANNEL_MAX] = {NULL};
static uint32_t can_irq_id[CHANNEL_MAX] = {0};
static uintptr_t can_irq_contexts[CHANNEL_MAX] = {0};
void can_irq_init(can_t *obj, can_irq_handler handler, uint32_t id)
void can_irq_init(can_t *obj, can_irq_handler handler, uintptr_t context)
{
irq_handler[obj->ch] = handler;
can_irq_id[obj->ch] = id;
can_irq_contexts[obj->ch] = context;
}
void can_irq_free(can_t *obj)
{
can_irq_id[obj->ch] = 0;
can_irq_contexts[obj->ch] = 0;
*g_regtbl_cfcc[obj->ch][CAN_RX] &= ~CFCC_CFRXIE;
*g_regtbl_cfcc[obj->ch][CAN_TX] &= ~CFCC_CFTXIE;
*g_regtbl_ctr[obj->ch] &= ~(CTR_EWIE | CTR_OLIE | CTR_EPIE | CTR_ALIE | CTR_BEIE);
@ -454,13 +454,13 @@ void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable)
static void can_rec_irq(uint32_t ch)
{
*g_regtbl_cfsts[ch][CAN_RX] &= ~CFSTS_CFRXIF;
irq_handler[ch](can_irq_id[ch], IRQ_RX);
irq_handler[ch](can_irq_contexts[ch], IRQ_RX);
}
static void can_trx_irq(uint32_t ch)
{
*g_regtbl_cfsts[ch][CAN_TX] &= ~CFSTS_CFTXIF;
irq_handler[ch](can_irq_id[ch], IRQ_TX);
irq_handler[ch](can_irq_contexts[ch], IRQ_TX);
}
static void can_err_irq(uint32_t ch)
@ -468,32 +468,32 @@ static void can_err_irq(uint32_t ch)
/* error warning */
if (*g_regtbl_erfl[ch] & ERFL_EWF) {
*g_regtbl_erfl[ch] &= ~ERFL_EWF;
irq_handler[ch](can_irq_id[ch], IRQ_ERROR);
irq_handler[ch](can_irq_contexts[ch], IRQ_ERROR);
}
/* over load */
if (*g_regtbl_erfl[ch] & ERFL_OVLF) {
*g_regtbl_erfl[ch] &= ~ERFL_OVLF;
irq_handler[ch](can_irq_id[ch], IRQ_OVERRUN);
irq_handler[ch](can_irq_contexts[ch], IRQ_OVERRUN);
}
/* error passive */
if (*g_regtbl_erfl[ch] & ERFL_EPF) {
*g_regtbl_erfl[ch] &= ~ERFL_EPF;
irq_handler[ch](can_irq_id[ch], IRQ_PASSIVE);
irq_handler[ch](can_irq_contexts[ch], IRQ_PASSIVE);
}
/* arbitration lost */
if (*g_regtbl_erfl[ch] & ERFL_ALF) {
*g_regtbl_erfl[ch] &= ~ERFL_ALF;
irq_handler[ch](can_irq_id[ch], IRQ_ARB);
irq_handler[ch](can_irq_contexts[ch], IRQ_ARB);
}
/* bus error */
if (*g_regtbl_erfl[ch] & ERFL_ALLERR) {
*g_regtbl_erfl[ch] &= ~ERFL_ALLERR;
*g_regtbl_erfl[ch] &= ~ERFL_BEF;
irq_handler[ch](can_irq_id[ch], IRQ_BUS);
irq_handler[ch](can_irq_contexts[ch], IRQ_BUS);
}
}

View File

@ -24,7 +24,7 @@
#include "PeripheralPins.h"
#include "mbed_error.h"
static uint32_t can_irq_ids[2] = {0};
static uintptr_t can_irq_contexts[2] = {0};
static can_irq_handler irq_handler;
/** Call all the init functions
@ -222,10 +222,10 @@ void can_init(can_t *obj, PinName rd, PinName td)
can_init_freq(obj, rd, td, 100000);
}
void can_irq_init(can_t *obj, can_irq_handler handler, uint32_t id)
void can_irq_init(can_t *obj, can_irq_handler handler, uintptr_t context)
{
irq_handler = handler;
can_irq_ids[obj->index] = id;
can_irq_contexts[obj->index] = context;
}
void can_irq_free(can_t *obj)
@ -253,7 +253,7 @@ void can_irq_free(can_t *obj)
#ifndef TARGET_STM32G4
HAL_NVIC_DisableIRQ(FDCAN_CAL_IRQn);
#endif
can_irq_ids[obj->index] = 0;
can_irq_contexts[obj->index] = 0;
}
void can_free(can_t *obj)
@ -517,42 +517,42 @@ static void can_irq(CANName name, int id)
if (__HAL_FDCAN_GET_IT_SOURCE(&CanHandle, FDCAN_IT_TX_COMPLETE)) {
if (__HAL_FDCAN_GET_FLAG(&CanHandle, FDCAN_FLAG_TX_COMPLETE)) {
__HAL_FDCAN_CLEAR_FLAG(&CanHandle, FDCAN_FLAG_TX_COMPLETE);
irq_handler(can_irq_ids[id], IRQ_TX);
irq_handler(can_irq_contexts[id], IRQ_TX);
}
}
#ifndef TARGET_STM32G4
if (__HAL_FDCAN_GET_IT_SOURCE(&CanHandle, FDCAN_IT_RX_BUFFER_NEW_MESSAGE)) {
if (__HAL_FDCAN_GET_FLAG(&CanHandle, FDCAN_IT_RX_BUFFER_NEW_MESSAGE)) {
__HAL_FDCAN_CLEAR_FLAG(&CanHandle, FDCAN_IT_RX_BUFFER_NEW_MESSAGE);
irq_handler(can_irq_ids[id], IRQ_RX);
irq_handler(can_irq_contexts[id], IRQ_RX);
}
}
#else
if (__HAL_FDCAN_GET_IT_SOURCE(&CanHandle, FDCAN_IT_RX_FIFO0_NEW_MESSAGE)) {
if (__HAL_FDCAN_GET_FLAG(&CanHandle, FDCAN_IT_RX_FIFO0_NEW_MESSAGE)) {
__HAL_FDCAN_CLEAR_FLAG(&CanHandle, FDCAN_IT_RX_FIFO0_NEW_MESSAGE);
irq_handler(can_irq_ids[id], IRQ_RX);
irq_handler(can_irq_contexts[id], IRQ_RX);
}
}
#endif
if (__HAL_FDCAN_GET_IT_SOURCE(&CanHandle, FDCAN_IT_ERROR_WARNING)) {
if (__HAL_FDCAN_GET_FLAG(&CanHandle, FDCAN_FLAG_ERROR_WARNING)) {
__HAL_FDCAN_CLEAR_FLAG(&CanHandle, FDCAN_FLAG_ERROR_WARNING);
irq_handler(can_irq_ids[id], IRQ_ERROR);
irq_handler(can_irq_contexts[id], IRQ_ERROR);
}
}
if (__HAL_FDCAN_GET_IT_SOURCE(&CanHandle, FDCAN_IT_ERROR_PASSIVE)) {
if (__HAL_FDCAN_GET_FLAG(&CanHandle, FDCAN_FLAG_ERROR_PASSIVE)) {
__HAL_FDCAN_CLEAR_FLAG(&CanHandle, FDCAN_FLAG_ERROR_PASSIVE);
irq_handler(can_irq_ids[id], IRQ_PASSIVE);
irq_handler(can_irq_contexts[id], IRQ_PASSIVE);
}
}
if (__HAL_FDCAN_GET_IT_SOURCE(&CanHandle, FDCAN_IT_BUS_OFF)) {
if (__HAL_FDCAN_GET_FLAG(&CanHandle, FDCAN_FLAG_BUS_OFF)) {
__HAL_FDCAN_CLEAR_FLAG(&CanHandle, FDCAN_FLAG_BUS_OFF);
irq_handler(can_irq_ids[id], IRQ_BUS);
irq_handler(can_irq_contexts[id], IRQ_BUS);
}
}
}
@ -666,7 +666,7 @@ void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable)
#define DEFAULT_RXFIFO 0 // default rx fifo for can by hardware is FIFO0
static uint32_t can_irq_ids[CAN_NUM] = {0};
static uint32_t can_irq_contexts[CAN_NUM] = {0};
static can_irq_handler irq_handler;
static void can_registers_init(can_t *obj)
@ -774,10 +774,10 @@ void can_init(can_t *obj, PinName rd, PinName td)
can_init_freq(obj, rd, td, 100000);
}
void can_irq_init(can_t *obj, can_irq_handler handler, uint32_t id)
void can_irq_init(can_t *obj, can_irq_handler handler, uintptr_t context)
{
irq_handler = handler;
can_irq_ids[obj->index] = id;
can_irq_contexts[obj->index] = context;
obj->rxIrqEnabled = false;
}
@ -787,7 +787,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;
can_irq_contexts[obj->index] = 0;
obj->rxIrqEnabled = false;
}
@ -1177,7 +1177,7 @@ static void can_irq(CANName name, int id)
__HAL_CAN_CLEAR_FLAG(&CanHandle, CAN_FLAG_RQCP2);
}
if (tmp1 || tmp2 || tmp3) {
irq_handler(can_irq_ids[id], IRQ_TX);
irq_handler(can_irq_contexts[id], IRQ_TX);
}
}
@ -1191,7 +1191,7 @@ static void can_irq(CANName name, int id)
__HAL_CAN_DISABLE_IT(&CanHandle, CAN_IT_FMP0);
if ((tmp1 != 0) && tmp2) {
irq_handler(can_irq_ids[id], IRQ_RX);
irq_handler(can_irq_contexts[id], IRQ_RX);
}
tmp1 = __HAL_CAN_GET_FLAG(&CanHandle, CAN_FLAG_EPV);
@ -1199,19 +1199,19 @@ static void can_irq(CANName name, int id)
tmp3 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_ERR);
if (tmp1 && tmp2 && tmp3) {
irq_handler(can_irq_ids[id], IRQ_PASSIVE);
irq_handler(can_irq_contexts[id], IRQ_PASSIVE);
}
tmp1 = __HAL_CAN_GET_FLAG(&CanHandle, CAN_FLAG_BOF);
tmp2 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_BOF);
tmp3 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_ERR);
if (tmp1 && tmp2 && tmp3) {
irq_handler(can_irq_ids[id], IRQ_BUS);
irq_handler(can_irq_contexts[id], IRQ_BUS);
}
tmp3 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_ERR);
if (tmp1 && tmp2 && tmp3) {
irq_handler(can_irq_ids[id], IRQ_ERROR);
irq_handler(can_irq_contexts[id], IRQ_ERROR);
}
}

View File

@ -27,7 +27,7 @@
#include "em_cmu.h"
#include "em_can.h"
static uint32_t can_irq_ids[CAN_COUNT] = {0};
static uintptr_t can_irq_contexts[CAN_COUNT] = {0};
static can_irq_handler irq_handler;
// CAN bus interfaces
@ -104,7 +104,7 @@ void can_init_freq(can_t *obj, PinName rd, PinName td, int hz)
CAN_SetIdAndFilter(obj->instance, CAN_RX_IF, true, &receiver, true);
}
void can_irq_init(can_t *obj, can_irq_handler handler, uint32_t id)
void can_irq_init(can_t *obj, can_irq_handler handler, uintptr_t context)
{
int index = 0;
@ -122,7 +122,7 @@ void can_irq_init(can_t *obj, can_irq_handler handler, uint32_t id)
}
irq_handler = handler;
can_irq_ids[index] = id;
can_irq_contexts[index] = context;
}
void can_irq_free(can_t *obj)
@ -294,12 +294,12 @@ static void can_irq(CANName name, int id)
can = (CAN_TypeDef *)name;
if (can->STATUS & CAN_STATUS_RXOK) {
irq_handler(can_irq_ids[id], IRQ_RX);
irq_handler(can_irq_contexts[id], IRQ_RX);
CAN_MessageIntClear(can, 0xFFFFFFFF);
}
if (can->STATUS & CAN_STATUS_TXOK) {
irq_handler(can_irq_ids[id], IRQ_TX);
irq_handler(can_irq_contexts[id], IRQ_TX);
CAN_MessageIntClear(can, 0xFFFFFFFF);
}
}