mirror of https://github.com/ARMmbed/mbed-os.git
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
parent
810adf9aa8
commit
b493a15a53
|
@ -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:
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue