Merge pull request #15509 from OpenNuvoton/nuvoton_fix_can_interrupt

NUVOTON: CAN: Fix Rx interrupt and filter mask
pull/15511/head
Martin Kojtal 2024-04-23 19:20:05 +02:00 committed by GitHub
commit 8502c74d9c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 175 additions and 41 deletions

View File

@ -27,13 +27,25 @@
#include "nu_miscutil.h" #include "nu_miscutil.h"
#include "nu_bitutil.h" #include "nu_bitutil.h"
#include "mbed_critical.h" #include "mbed_critical.h"
#include "mbed_error.h"
#define NU_CAN_DEBUG 0 #define NU_CAN_DEBUG 0
#define CAN_NUM 1 #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 uintptr_t can_irq_contexts[CAN_NUM] = {0};
static can_irq_handler can0_irq_handler; static can_irq_handler can0_irq_handler;
extern void CAN_CLR_INT_PENDING_ONLY_BIT(CAN_T *tCAN, uint32_t u32MsgNum);
static const struct nu_modinit_s can_modinit_tab[] = { static const struct nu_modinit_s can_modinit_tab[] = {
{CAN_0, CAN0_MODULE, 0, 0, CAN0_RST, CAN0_IRQn, NULL}, {CAN_0, CAN0_MODULE, 0, 0, CAN0_RST, CAN0_IRQn, NULL},
@ -125,12 +137,10 @@ static void can_irq(CANName name, int id)
/**************************/ /**************************/
if(can->STATUS & CAN_STATUS_RXOK_Msk) { if(can->STATUS & CAN_STATUS_RXOK_Msk) {
can->STATUS &= ~CAN_STATUS_RXOK_Msk; /* Clear Rx Ok status*/ can->STATUS &= ~CAN_STATUS_RXOK_Msk; /* Clear Rx Ok status*/
can0_irq_handler(can_irq_contexts[id], IRQ_RX);
} }
if(can->STATUS & CAN_STATUS_TXOK_Msk) { if(can->STATUS & CAN_STATUS_TXOK_Msk) {
can->STATUS &= ~CAN_STATUS_TXOK_Msk; /* Clear Tx Ok status*/ can->STATUS &= ~CAN_STATUS_TXOK_Msk; /* Clear Tx Ok status*/
can0_irq_handler(can_irq_contexts[id], IRQ_TX);
} }
/**************************/ /**************************/
@ -143,6 +153,14 @@ static void can_irq(CANName name, int id)
if(can->STATUS & CAN_STATUS_BOFF_Msk) { if(can->STATUS & CAN_STATUS_BOFF_Msk) {
can0_irq_handler(can_irq_contexts[id], IRQ_BUS); can0_irq_handler(can_irq_contexts[id], IRQ_BUS);
} }
} else if (u8IIDRstatus >= 1 && u8IIDRstatus <= 32) {
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 {
can0_irq_handler(can_irq_contexts[id], IRQ_TX);
CAN_CLR_INT_PENDING_BIT(can, (u8IIDRstatus -1));
}
} else if (u8IIDRstatus!=0) { } else if (u8IIDRstatus!=0) {
can0_irq_handler(can_irq_contexts[id], IRQ_OVERRUN); can0_irq_handler(can_irq_contexts[id], IRQ_OVERRUN);
@ -213,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) int can_write(can_t *obj, CAN_Message msg, int cc)
{ {
/* Unused */
(void) cc;
STR_CANMSG_T CMsg; STR_CANMSG_T CMsg;
CMsg.IdType = (uint32_t)msg.format; CMsg.IdType = (uint32_t)msg.format;
@ -221,7 +242,7 @@ int can_write(can_t *obj, CAN_Message msg, int cc)
CMsg.DLC = msg.len; CMsg.DLC = msg.len;
memcpy((void *)&CMsg.Data[0],(const void *)&msg.data[0], (unsigned int)8); 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) int can_read(can_t *obj, CAN_Message *msg, int handle)
@ -285,16 +306,19 @@ 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) int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle)
{ {
uint32_t numask = mask; /* Check validity of filter handle */
if( numask == 0x0000 ) if (handle < 0 || handle >= NU_CAN_MAXNUM_HNDL) {
{ /* NOTE: 0 is ambiguous, error or filter handle 0. */
return CAN_SetRxMsg((CAN_T *)NU_MODBASE(obj->can), handle, (uint32_t)format, id); error("Support max " NU_STR(NU_CAN_MAXNUM_HNDL) " CAN filters");
return 0;
} }
uint32_t numask = mask;
if( format == CANStandard ) if( format == CANStandard )
{ {
numask = (mask << 18); numask = (mask << 18);
} }
numask = (numask | CAN_IF_MASK2_MDIR_Msk | CAN_IF_MASK2_MXTD_Msk); numask = (numask | ((CAN_IF_MASK2_MDIR_Msk | CAN_IF_MASK2_MXTD_Msk) << 16));
return CAN_SetRxMsgAndMsk((CAN_T *)NU_MODBASE(obj->can), handle, (uint32_t)format, id, numask); return CAN_SetRxMsgAndMsk((CAN_T *)NU_MODBASE(obj->can), handle, (uint32_t)format, id, numask);
} }

View File

@ -981,7 +981,7 @@ int32_t CAN_Receive(CAN_T *tCAN, uint32_t u32MsgNum , STR_CANMSG_T* pCanMsg)
* *
* @details An interrupt remains pending until the application software has cleared it. * @details An interrupt remains pending until the application software has cleared it.
*/ */
void CAN_CLR_INT_PENDING_BIT(CAN_T *tCAN, uint8_t u32MsgNum) void CAN_CLR_INT_PENDING_BIT(CAN_T *tCAN, uint32_t u32MsgNum)
{ {
uint32_t u32MsgIfNum; uint32_t u32MsgIfNum;
@ -994,6 +994,19 @@ void CAN_CLR_INT_PENDING_BIT(CAN_T *tCAN, uint8_t u32MsgNum)
ReleaseIF(tCAN, u32MsgIfNum); ReleaseIF(tCAN, u32MsgIfNum);
} }
/* Clone of CAN_CLR_INT_PENDING_BIT() with NewDat not cleared */
void CAN_CLR_INT_PENDING_ONLY_BIT(CAN_T *tCAN, uint32_t u32MsgNum)
{
uint32_t u32MsgIfNum;
if((u32MsgIfNum = LockIF_TL(tCAN)) == 2)
u32MsgIfNum = 0;
tCAN->IF[u32MsgIfNum].CMASK = CAN_IF_CMASK_CLRINTPND_Msk;
tCAN->IF[u32MsgIfNum].CREQ = 1 + u32MsgNum;
ReleaseIF(tCAN, u32MsgIfNum);
}
/*@}*/ /* end of group CAN_EXPORTED_FUNCTIONS */ /*@}*/ /* end of group CAN_EXPORTED_FUNCTIONS */

View File

@ -148,7 +148,7 @@ typedef struct
uint32_t CAN_SetBaudRate(CAN_T *tCAN, uint32_t u32BaudRate); uint32_t CAN_SetBaudRate(CAN_T *tCAN, uint32_t u32BaudRate);
uint32_t CAN_Open(CAN_T *tCAN, uint32_t u32BaudRate, uint32_t u32Mode); uint32_t CAN_Open(CAN_T *tCAN, uint32_t u32BaudRate, uint32_t u32Mode);
void CAN_Close(CAN_T *tCAN); void CAN_Close(CAN_T *tCAN);
void CAN_CLR_INT_PENDING_BIT(CAN_T *tCAN, uint8_t u32MsgNum); void CAN_CLR_INT_PENDING_BIT(CAN_T *tCAN, uint32_t u32MsgNum);
void CAN_EnableInt(CAN_T *tCAN, uint32_t u32Mask); void CAN_EnableInt(CAN_T *tCAN, uint32_t u32Mask);
void CAN_DisableInt(CAN_T *tCAN, uint32_t u32Mask); void CAN_DisableInt(CAN_T *tCAN, uint32_t u32Mask);
int32_t CAN_Transmit(CAN_T *tCAN, uint32_t u32MsgNum , STR_CANMSG_T* pCanMsg); int32_t CAN_Transmit(CAN_T *tCAN, uint32_t u32MsgNum , STR_CANMSG_T* pCanMsg);

View File

@ -30,10 +30,21 @@
#include "nu_miscutil.h" #include "nu_miscutil.h"
#include "nu_bitutil.h" #include "nu_bitutil.h"
#include "mbed_critical.h" #include "mbed_critical.h"
#include "mbed_error.h"
#define NU_CAN_DEBUG 0 #define NU_CAN_DEBUG 0
#define CAN_NUM 2 #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 uintptr_t can_irq_contexts[CAN_NUM] = {0};
static can_irq_handler can0_irq_handler; static can_irq_handler can0_irq_handler;
static can_irq_handler can1_irq_handler; static can_irq_handler can1_irq_handler;
@ -43,6 +54,7 @@ extern void CAN_EnterInitMode(CAN_T *tCAN, uint8_t u8Mask);
extern void CAN_LeaveInitMode(CAN_T *tCAN); extern void CAN_LeaveInitMode(CAN_T *tCAN);
extern void CAN_LeaveTestMode(CAN_T *tCAN); extern void CAN_LeaveTestMode(CAN_T *tCAN);
extern void CAN_EnterTestMode(CAN_T *tCAN, uint8_t u8TestMask); extern void CAN_EnterTestMode(CAN_T *tCAN, uint8_t u8TestMask);
extern void CAN_CLR_INT_PENDING_ONLY_BIT(CAN_T *tCAN, uint32_t u32MsgNum);
static const struct nu_modinit_s can_modinit_tab[] = { static const struct nu_modinit_s can_modinit_tab[] = {
{CAN_0, CAN0_MODULE, 0, 0, CAN0_RST, CAN0_IRQn, NULL}, {CAN_0, CAN0_MODULE, 0, 0, CAN0_RST, CAN0_IRQn, NULL},
@ -139,19 +151,10 @@ static void can_irq(CANName name, int id)
/**************************/ /**************************/
if(can->STATUS & CAN_STATUS_RXOK_Msk) { if(can->STATUS & CAN_STATUS_RXOK_Msk) {
can->STATUS &= ~CAN_STATUS_RXOK_Msk; /* Clear Rx Ok status*/ can->STATUS &= ~CAN_STATUS_RXOK_Msk; /* Clear Rx Ok status*/
if(id)
can1_irq_handler(can_irq_contexts[id], IRQ_RX);
else
can0_irq_handler(can_irq_contexts[id], IRQ_RX);
} }
if(can->STATUS & CAN_STATUS_TXOK_Msk) { if(can->STATUS & CAN_STATUS_TXOK_Msk) {
can->STATUS &= ~CAN_STATUS_TXOK_Msk; /* Clear Tx Ok status*/ can->STATUS &= ~CAN_STATUS_TXOK_Msk; /* Clear Tx Ok status*/
if(id)
can1_irq_handler(can_irq_contexts[id], IRQ_TX);
else
can0_irq_handler(can_irq_contexts[id], IRQ_TX);
} }
/**************************/ /**************************/
@ -170,6 +173,24 @@ static void can_irq(CANName name, int id)
else else
can0_irq_handler(can_irq_contexts[id], IRQ_BUS); can0_irq_handler(can_irq_contexts[id], IRQ_BUS);
} }
} else if (u8IIDRstatus >= 1 && u8IIDRstatus <= 32) {
if ((u8IIDRstatus - 1) != NU_CAN_MSG_OBJ_NUM_TX) {
if (id) {
can1_irq_handler(can_irq_contexts[id], IRQ_RX);
}
else {
can0_irq_handler(can_irq_contexts[id], IRQ_RX);
}
CAN_CLR_INT_PENDING_ONLY_BIT(can, (u8IIDRstatus -1));
} else {
if (id) {
can1_irq_handler(can_irq_contexts[id], IRQ_TX);
}
else {
can0_irq_handler(can_irq_contexts[id], IRQ_TX);
}
CAN_CLR_INT_PENDING_BIT(can, (u8IIDRstatus -1));
}
} else if (u8IIDRstatus!=0) { } else if (u8IIDRstatus!=0) {
if(id) if(id)
@ -178,7 +199,6 @@ static void can_irq(CANName name, int id)
can0_irq_handler(can_irq_contexts[id], IRQ_OVERRUN); can0_irq_handler(can_irq_contexts[id], IRQ_OVERRUN);
CAN_CLR_INT_PENDING_BIT(can, ((can->IIDR) -1)); /* Clear Interrupt Pending */ CAN_CLR_INT_PENDING_BIT(can, ((can->IIDR) -1)); /* Clear Interrupt Pending */
} else if(can->WU_STATUS == 1) { } else if(can->WU_STATUS == 1) {
can->WU_STATUS = 0; /* Write '0' to clear */ can->WU_STATUS = 0; /* Write '0' to clear */
@ -263,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) int can_write(can_t *obj, CAN_Message msg, int cc)
{ {
/* Unused */
(void) cc;
STR_CANMSG_T CMsg; STR_CANMSG_T CMsg;
CMsg.IdType = (uint32_t)msg.format; CMsg.IdType = (uint32_t)msg.format;
@ -271,7 +294,7 @@ int can_write(can_t *obj, CAN_Message msg, int cc)
CMsg.DLC = msg.len; CMsg.DLC = msg.len;
memcpy((void *)&CMsg.Data[0],(const void *)&msg.data[0], (unsigned int)8); 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) int can_read(can_t *obj, CAN_Message *msg, int handle)
@ -293,6 +316,7 @@ int can_read(can_t *obj, CAN_Message *msg, int handle)
int can_mode(can_t *obj, CanMode mode) int can_mode(can_t *obj, CanMode mode)
{ {
int success = 0; int success = 0;
switch (mode) { switch (mode) {
case MODE_RESET: case MODE_RESET:
CAN_LeaveTestMode((CAN_T*)NU_MODBASE(obj->can)); CAN_LeaveTestMode((CAN_T*)NU_MODBASE(obj->can));
@ -326,22 +350,24 @@ int can_mode(can_t *obj, CanMode mode)
} }
return success; return success;
} }
int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle) int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle)
{ {
uint32_t numask = mask; /* Check validity of filter handle */
if( numask == 0x0000 ) if (handle < 0 || handle >= NU_CAN_MAXNUM_HNDL) {
{ /* NOTE: 0 is ambiguous, error or filter handle 0. */
return CAN_SetRxMsg((CAN_T *)NU_MODBASE(obj->can), handle, (uint32_t)format, id); error("Support max " NU_STR(NU_CAN_MAXNUM_HNDL) " CAN filters");
return 0;
} }
uint32_t numask = mask;
if( format == CANStandard ) if( format == CANStandard )
{ {
numask = (mask << 18); numask = (mask << 18);
} }
numask = (numask | CAN_IF_MASK2_MDIR_Msk | CAN_IF_MASK2_MXTD_Msk); numask = (numask | ((CAN_IF_MASK2_MDIR_Msk | CAN_IF_MASK2_MXTD_Msk) << 16));
return CAN_SetRxMsgAndMsk((CAN_T *)NU_MODBASE(obj->can), handle, (uint32_t)format, id, numask); return CAN_SetRxMsgAndMsk((CAN_T *)NU_MODBASE(obj->can), handle, (uint32_t)format, id, numask);
} }

View File

@ -155,7 +155,7 @@ typedef struct
uint32_t CAN_SetBaudRate(CAN_T *tCAN, uint32_t u32BaudRate); uint32_t CAN_SetBaudRate(CAN_T *tCAN, uint32_t u32BaudRate);
uint32_t CAN_Open(CAN_T *tCAN, uint32_t u32BaudRate, uint32_t u32Mode); uint32_t CAN_Open(CAN_T *tCAN, uint32_t u32BaudRate, uint32_t u32Mode);
void CAN_Close(CAN_T *tCAN); void CAN_Close(CAN_T *tCAN);
void CAN_CLR_INT_PENDING_BIT(CAN_T *tCAN, uint8_t u32MsgNum); void CAN_CLR_INT_PENDING_BIT(CAN_T *tCAN, uint32_t u32MsgNum);
void CAN_EnableInt(CAN_T *tCAN, uint32_t u32Mask); void CAN_EnableInt(CAN_T *tCAN, uint32_t u32Mask);
void CAN_DisableInt(CAN_T *tCAN, uint32_t u32Mask); void CAN_DisableInt(CAN_T *tCAN, uint32_t u32Mask);
int32_t CAN_Transmit(CAN_T *tCAN, uint32_t u32MsgNum, STR_CANMSG_T* pCanMsg); int32_t CAN_Transmit(CAN_T *tCAN, uint32_t u32MsgNum, STR_CANMSG_T* pCanMsg);

View File

@ -1264,7 +1264,7 @@ int32_t CAN_Receive(CAN_T *tCAN, uint32_t u32MsgNum, STR_CANMSG_T* pCanMsg)
* *
* @details An interrupt remains pending until the application software has cleared it. * @details An interrupt remains pending until the application software has cleared it.
*/ */
void CAN_CLR_INT_PENDING_BIT(CAN_T *tCAN, uint8_t u32MsgNum) void CAN_CLR_INT_PENDING_BIT(CAN_T *tCAN, uint32_t u32MsgNum)
{ {
uint32_t u32MsgIfNum; uint32_t u32MsgIfNum;
@ -1282,6 +1282,24 @@ void CAN_CLR_INT_PENDING_BIT(CAN_T *tCAN, uint8_t u32MsgNum)
ReleaseIF(tCAN, u32MsgIfNum); ReleaseIF(tCAN, u32MsgIfNum);
} }
/* Clone of CAN_CLR_INT_PENDING_BIT() with NewDat not cleared */
void CAN_CLR_INT_PENDING_ONLY_BIT(CAN_T *tCAN, uint32_t u32MsgNum)
{
uint32_t u32MsgIfNum;
if((u32MsgIfNum = LockIF_TL(tCAN)) == 2ul)
{
u32MsgIfNum = 0ul;
}
else
{
}
tCAN->IF[u32MsgIfNum].CMASK = CAN_IF_CMASK_CLRINTPND_Msk;
tCAN->IF[u32MsgIfNum].CREQ = 1ul + u32MsgNum;
ReleaseIF(tCAN, u32MsgIfNum);
}
/*@}*/ /* end of group CAN_EXPORTED_FUNCTIONS */ /*@}*/ /* end of group CAN_EXPORTED_FUNCTIONS */

View File

@ -27,14 +27,26 @@
#include "nu_miscutil.h" #include "nu_miscutil.h"
#include "nu_bitutil.h" #include "nu_bitutil.h"
#include "mbed_critical.h" #include "mbed_critical.h"
#include "mbed_error.h"
#define NU_CAN_DEBUG 0 #define NU_CAN_DEBUG 0
#define CAN_NUM 2 #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 uintptr_t can_irq_contexts[CAN_NUM] = {0};
static can_irq_handler can0_irq_handler; static can_irq_handler can0_irq_handler;
static can_irq_handler can1_irq_handler; static can_irq_handler can1_irq_handler;
extern void CAN_CLR_INT_PENDING_ONLY_BIT(CAN_T *tCAN, uint32_t u32MsgNum);
static const struct nu_modinit_s can_modinit_tab[] = { static const struct nu_modinit_s can_modinit_tab[] = {
{CAN_0, CAN0_MODULE, 0, 0, CAN0_RST, CAN0_IRQn, NULL}, {CAN_0, CAN0_MODULE, 0, 0, CAN0_RST, CAN0_IRQn, NULL},
@ -133,19 +145,10 @@ static void can_irq(CANName name, int id)
/**************************/ /**************************/
if(can->STATUS & CAN_STATUS_RXOK_Msk) { if(can->STATUS & CAN_STATUS_RXOK_Msk) {
can->STATUS &= ~CAN_STATUS_RXOK_Msk; /* Clear Rx Ok status*/ can->STATUS &= ~CAN_STATUS_RXOK_Msk; /* Clear Rx Ok status*/
if(id)
can1_irq_handler(can_irq_contexts[id] , IRQ_RX);
else
can0_irq_handler(can_irq_contexts[id], IRQ_RX);
} }
if(can->STATUS & CAN_STATUS_TXOK_Msk) { if(can->STATUS & CAN_STATUS_TXOK_Msk) {
can->STATUS &= ~CAN_STATUS_TXOK_Msk; /* Clear Tx Ok status*/ can->STATUS &= ~CAN_STATUS_TXOK_Msk; /* Clear Tx Ok status*/
if(id)
can1_irq_handler(can_irq_contexts[id] , IRQ_TX);
else
can0_irq_handler(can_irq_contexts[id], IRQ_TX);
} }
/**************************/ /**************************/
@ -164,6 +167,24 @@ static void can_irq(CANName name, int id)
else else
can0_irq_handler(can_irq_contexts[id], IRQ_BUS); can0_irq_handler(can_irq_contexts[id], IRQ_BUS);
} }
} else if (u8IIDRstatus >= 1 && u8IIDRstatus <= 32) {
if ((u8IIDRstatus - 1) != NU_CAN_MSG_OBJ_NUM_TX) {
if (id) {
can1_irq_handler(can_irq_contexts[id], IRQ_RX);
}
else {
can0_irq_handler(can_irq_contexts[id], IRQ_RX);
}
CAN_CLR_INT_PENDING_ONLY_BIT(can, (u8IIDRstatus -1));
} else {
if (id) {
can1_irq_handler(can_irq_contexts[id], IRQ_TX);
}
else {
can0_irq_handler(can_irq_contexts[id], IRQ_TX);
}
CAN_CLR_INT_PENDING_BIT(can, (u8IIDRstatus -1));
}
} else if (u8IIDRstatus!=0) { } else if (u8IIDRstatus!=0) {
if(id) if(id)
@ -263,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) int can_write(can_t *obj, CAN_Message msg, int cc)
{ {
/* Unused */
(void) cc;
STR_CANMSG_T CMsg; STR_CANMSG_T CMsg;
CMsg.IdType = (uint32_t)msg.format; CMsg.IdType = (uint32_t)msg.format;
@ -271,7 +295,7 @@ int can_write(can_t *obj, CAN_Message msg, int cc)
CMsg.DLC = msg.len; CMsg.DLC = msg.len;
memcpy((void *)&CMsg.Data[0],(const void *)&msg.data[0], (unsigned int)8); 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) int can_read(can_t *obj, CAN_Message *msg, int handle)
@ -335,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) 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); return CAN_SetRxMsg((CAN_T *)NU_MODBASE(obj->can), handle , (uint32_t)format, id);
} }

View File

@ -716,7 +716,7 @@ int32_t CAN_Receive(CAN_T *tCAN, uint32_t u32MsgNum , STR_CANMSG_T* pCanMsg)
* @return None * @return None
* *
*/ */
void CAN_CLR_INT_PENDING_BIT(CAN_T *tCAN, uint8_t u32MsgNum) void CAN_CLR_INT_PENDING_BIT(CAN_T *tCAN, uint32_t u32MsgNum)
{ {
uint32_t u32MsgIfNum = 0; uint32_t u32MsgIfNum = 0;
uint32_t u32IFBusyCount = 0; uint32_t u32IFBusyCount = 0;
@ -738,6 +738,28 @@ void CAN_CLR_INT_PENDING_BIT(CAN_T *tCAN, uint8_t u32MsgNum)
} }
/* Clone of CAN_CLR_INT_PENDING_BIT() with NewDat not cleared */
void CAN_CLR_INT_PENDING_ONLY_BIT(CAN_T *tCAN, uint32_t u32MsgNum)
{
uint32_t u32MsgIfNum = 0;
uint32_t u32IFBusyCount = 0;
while(u32IFBusyCount < 0x10000000) {
if((tCAN->IF[0].CREQ & CAN_IF_CREQ_BUSY_Msk) == 0) {
u32MsgIfNum = 0;
break;
} else if((tCAN->IF[1].CREQ & CAN_IF_CREQ_BUSY_Msk) == 0) {
u32MsgIfNum = 1;
break;
}
u32IFBusyCount++;
}
tCAN->IF[u32MsgIfNum].CMASK = CAN_IF_CMASK_CLRINTPND_Msk;
tCAN->IF[u32MsgIfNum].CREQ = 1 + u32MsgNum;
}
/*@}*/ /* end of group NUC472_442_CAN_EXPORTED_FUNCTIONS */ /*@}*/ /* end of group NUC472_442_CAN_EXPORTED_FUNCTIONS */

View File

@ -143,7 +143,7 @@ uint32_t CAN_SetBaudRate(CAN_T *tCAN, uint32_t u32BaudRate);
uint32_t CAN_Open(CAN_T *tCAN, uint32_t u32BaudRate, uint32_t u32Mode); uint32_t CAN_Open(CAN_T *tCAN, uint32_t u32BaudRate, uint32_t u32Mode);
int32_t CAN_Transmit(CAN_T *tCAN, uint32_t u32MsgNum , STR_CANMSG_T* pCanMsg); int32_t CAN_Transmit(CAN_T *tCAN, uint32_t u32MsgNum , STR_CANMSG_T* pCanMsg);
int32_t CAN_Receive(CAN_T *tCAN, uint32_t u32MsgNum , STR_CANMSG_T* pCanMsg); int32_t CAN_Receive(CAN_T *tCAN, uint32_t u32MsgNum , STR_CANMSG_T* pCanMsg);
void CAN_CLR_INT_PENDING_BIT(CAN_T *tCAN, uint8_t u32MsgNum); void CAN_CLR_INT_PENDING_BIT(CAN_T *tCAN, uint32_t u32MsgNum);
void CAN_EnableInt(CAN_T *tCAN, uint32_t u32Mask); void CAN_EnableInt(CAN_T *tCAN, uint32_t u32Mask);
void CAN_DisableInt(CAN_T *tCAN, uint32_t u32Mask); void CAN_DisableInt(CAN_T *tCAN, uint32_t u32Mask);
int32_t CAN_SetMultiRxMsg(CAN_T *tCAN, uint32_t u32MsgNum , uint32_t u32MsgCount, uint32_t u32IDType, uint32_t u32ID); int32_t CAN_SetMultiRxMsg(CAN_T *tCAN, uint32_t u32MsgNum , uint32_t u32MsgCount, uint32_t u32IDType, uint32_t u32ID);