Skip to content

Commit

Permalink
NUVOTON: CAN: Fix Message Object number for Tx and recognition of Rx …
Browse files Browse the repository at this point in the history
…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).
  • Loading branch information
ccli8 committed Apr 18, 2024
1 parent bfd4ceb commit 989a694
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 8 deletions.
26 changes: 23 additions & 3 deletions targets/TARGET_NUVOTON/TARGET_M451/can_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -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[] = {
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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;
Expand All @@ -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)
Expand Down Expand Up @@ -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 )
{
Expand Down
25 changes: 23 additions & 2 deletions targets/TARGET_NUVOTON/TARGET_M480/can_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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;
Expand All @@ -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)
Expand Down Expand Up @@ -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 )
{
Expand Down
26 changes: 23 additions & 3 deletions targets/TARGET_NUVOTON/TARGET_NUC472/can_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -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[] = {
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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;
Expand All @@ -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)
Expand Down Expand Up @@ -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);
}

Expand Down

0 comments on commit 989a694

Please sign in to comment.