NUVOTON: CAN: Fix Message Object number for Tx and recognition of Rx interrupt

1.  The same Message Object number cannot use for both Tx and Rx simultaneously.
    For Tx, Message Object number 31 is reserved instead of 0.
    For Rx, Message Object numbers 0~30 are used and for filters.
2.  NewDat bit (CAN_IsNewDataReceived()) isn't exclusive to Rx.
    Recognize Rx interrupt by Message Object number other than 31.

NOTE: This fix only targets CAN (NUC472/M453/M487), not CAN-FD (M467).
pull/15508/head
Chun-Chieh Li 2024-04-12 13:41:20 +08:00
parent bfd4ceb20b
commit 989a694c5a
3 changed files with 69 additions and 8 deletions

View File

@ -27,14 +27,24 @@
#include "nu_miscutil.h"
#include "nu_bitutil.h"
#include "mbed_critical.h"
#include "mbed_error.h"
#define NU_CAN_DEBUG 0
#define CAN_NUM 1
/* Reserve Message Object number 31 for Tx */
#define NU_CAN_MSG_OBJ_NUM_TX 31
/* Max number of message ID filter handle */
#define NU_CAN_MAXNUM_HNDL NU_CAN_MSG_OBJ_NUM_TX
/* Convert to string literal */
#define NU_STR_(X) #X
#define NU_STR(X) NU_STR_(X)
static uintptr_t can_irq_contexts[CAN_NUM] = {0};
static can_irq_handler can0_irq_handler;
extern uint32_t CAN_IsNewDataReceived(CAN_T *tCAN, uint8_t u8MsgObj);
extern void CAN_CLR_INT_PENDING_ONLY_BIT(CAN_T *tCAN, uint32_t u32MsgNum);
static const struct nu_modinit_s can_modinit_tab[] = {
@ -144,7 +154,7 @@ static void can_irq(CANName name, int id)
can0_irq_handler(can_irq_contexts[id], IRQ_BUS);
}
} else if (u8IIDRstatus >= 1 && u8IIDRstatus <= 32) {
if (CAN_IsNewDataReceived(can, u8IIDRstatus - 1)) {
if ((u8IIDRstatus - 1) != NU_CAN_MSG_OBJ_NUM_TX) {
can0_irq_handler(can_irq_contexts[id], IRQ_RX);
CAN_CLR_INT_PENDING_ONLY_BIT(can, (u8IIDRstatus -1));
} else {
@ -221,6 +231,9 @@ void can_irq_set(can_t *obj, CanIrqType irq, uint32_t enable)
int can_write(can_t *obj, CAN_Message msg, int cc)
{
/* Unused */
(void) cc;
STR_CANMSG_T CMsg;
CMsg.IdType = (uint32_t)msg.format;
@ -229,7 +242,7 @@ int can_write(can_t *obj, CAN_Message msg, int cc)
CMsg.DLC = msg.len;
memcpy((void *)&CMsg.Data[0],(const void *)&msg.data[0], (unsigned int)8);
return CAN_Transmit((CAN_T *)NU_MODBASE(obj->can), cc, &CMsg);
return CAN_Transmit((CAN_T *)NU_MODBASE(obj->can), NU_CAN_MSG_OBJ_NUM_TX, &CMsg);
}
int can_read(can_t *obj, CAN_Message *msg, int handle)
@ -293,6 +306,13 @@ int can_mode(can_t *obj, CanMode mode)
int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle)
{
/* Check validity of filter handle */
if (handle < 0 || handle >= NU_CAN_MAXNUM_HNDL) {
/* NOTE: 0 is ambiguous, error or filter handle 0. */
error("Support max " NU_STR(NU_CAN_MAXNUM_HNDL) " CAN filters");
return 0;
}
uint32_t numask = mask;
if( numask == 0x0000 )
{

View File

@ -30,10 +30,21 @@
#include "nu_miscutil.h"
#include "nu_bitutil.h"
#include "mbed_critical.h"
#include "mbed_error.h"
#define NU_CAN_DEBUG 0
#define CAN_NUM 2
/* Reserve Message Object number 31 for Tx */
#define NU_CAN_MSG_OBJ_NUM_TX 31
/* Max number of message ID filter handle */
#define NU_CAN_MAXNUM_HNDL NU_CAN_MSG_OBJ_NUM_TX
/* Convert to string literal */
#define NU_STR_(X) #X
#define NU_STR(X) NU_STR_(X)
static uintptr_t can_irq_contexts[CAN_NUM] = {0};
static can_irq_handler can0_irq_handler;
static can_irq_handler can1_irq_handler;
@ -163,7 +174,7 @@ static void can_irq(CANName name, int id)
can0_irq_handler(can_irq_contexts[id], IRQ_BUS);
}
} else if (u8IIDRstatus >= 1 && u8IIDRstatus <= 32) {
if (CAN_IsNewDataReceived(can, u8IIDRstatus - 1)) {
if ((u8IIDRstatus - 1) != NU_CAN_MSG_OBJ_NUM_TX) {
if (id) {
can1_irq_handler(can_irq_contexts[id], IRQ_RX);
}
@ -272,6 +283,9 @@ void can_irq_set(can_t *obj, CanIrqType irq, uint32_t enable)
int can_write(can_t *obj, CAN_Message msg, int cc)
{
/* Unused */
(void) cc;
STR_CANMSG_T CMsg;
CMsg.IdType = (uint32_t)msg.format;
@ -280,7 +294,7 @@ int can_write(can_t *obj, CAN_Message msg, int cc)
CMsg.DLC = msg.len;
memcpy((void *)&CMsg.Data[0],(const void *)&msg.data[0], (unsigned int)8);
return CAN_Transmit((CAN_T *)(NU_MODBASE(obj->can)), cc, &CMsg);
return CAN_Transmit((CAN_T *)(NU_MODBASE(obj->can)), NU_CAN_MSG_OBJ_NUM_TX, &CMsg);
}
int can_read(can_t *obj, CAN_Message *msg, int handle)
@ -341,6 +355,13 @@ int can_mode(can_t *obj, CanMode mode)
int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle)
{
/* Check validity of filter handle */
if (handle < 0 || handle >= NU_CAN_MAXNUM_HNDL) {
/* NOTE: 0 is ambiguous, error or filter handle 0. */
error("Support max " NU_STR(NU_CAN_MAXNUM_HNDL) " CAN filters");
return 0;
}
uint32_t numask = mask;
if( numask == 0x0000 )
{

View File

@ -27,15 +27,25 @@
#include "nu_miscutil.h"
#include "nu_bitutil.h"
#include "mbed_critical.h"
#include "mbed_error.h"
#define NU_CAN_DEBUG 0
#define CAN_NUM 2
/* Reserve Message Object number 31 for Tx */
#define NU_CAN_MSG_OBJ_NUM_TX 31
/* Convert to string literal */
#define NU_STR_(X) #X
#define NU_STR(X) NU_STR_(X)
/* Max number of message ID filter handle */
#define NU_CAN_MAXNUM_HNDL NU_CAN_MSG_OBJ_NUM_TX
static uintptr_t can_irq_contexts[CAN_NUM] = {0};
static can_irq_handler can0_irq_handler;
static can_irq_handler can1_irq_handler;
extern uint32_t CAN_IsNewDataReceived(CAN_T *tCAN, uint8_t u8MsgObj);
extern void CAN_CLR_INT_PENDING_ONLY_BIT(CAN_T *tCAN, uint32_t u32MsgNum);
static const struct nu_modinit_s can_modinit_tab[] = {
@ -158,7 +168,7 @@ static void can_irq(CANName name, int id)
can0_irq_handler(can_irq_contexts[id], IRQ_BUS);
}
} else if (u8IIDRstatus >= 1 && u8IIDRstatus <= 32) {
if (CAN_IsNewDataReceived(can, u8IIDRstatus - 1)) {
if ((u8IIDRstatus - 1) != NU_CAN_MSG_OBJ_NUM_TX) {
if (id) {
can1_irq_handler(can_irq_contexts[id], IRQ_RX);
}
@ -274,6 +284,9 @@ void can_irq_set(can_t *obj, CanIrqType irq, uint32_t enable)
int can_write(can_t *obj, CAN_Message msg, int cc)
{
/* Unused */
(void) cc;
STR_CANMSG_T CMsg;
CMsg.IdType = (uint32_t)msg.format;
@ -282,7 +295,7 @@ int can_write(can_t *obj, CAN_Message msg, int cc)
CMsg.DLC = msg.len;
memcpy((void *)&CMsg.Data[0],(const void *)&msg.data[0], (unsigned int)8);
return CAN_Transmit((CAN_T *)NU_MODBASE(obj->can), cc, &CMsg);
return CAN_Transmit((CAN_T *)NU_MODBASE(obj->can), NU_CAN_MSG_OBJ_NUM_TX, &CMsg);
}
int can_read(can_t *obj, CAN_Message *msg, int handle)
@ -346,6 +359,13 @@ int can_mode(can_t *obj, CanMode mode)
int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle)
{
/* Check validity of filter handle */
if (handle < 0 || handle >= NU_CAN_MAXNUM_HNDL) {
/* NOTE: 0 is ambiguous, error or filter handle 0. */
error("Support max " NU_STR(NU_CAN_MAXNUM_HNDL) " CAN filters");
return 0;
}
return CAN_SetRxMsg((CAN_T *)NU_MODBASE(obj->can), handle , (uint32_t)format, id);
}