Skip to content

Commit 989a694

Browse files
committed
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).
1 parent bfd4ceb commit 989a694

File tree

3 files changed

+69
-8
lines changed

3 files changed

+69
-8
lines changed

targets/TARGET_NUVOTON/TARGET_M451/can_api.c

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,24 @@
2727
#include "nu_miscutil.h"
2828
#include "nu_bitutil.h"
2929
#include "mbed_critical.h"
30+
#include "mbed_error.h"
3031

3132
#define NU_CAN_DEBUG 0
3233
#define CAN_NUM 1
3334

35+
/* Reserve Message Object number 31 for Tx */
36+
#define NU_CAN_MSG_OBJ_NUM_TX 31
37+
38+
/* Max number of message ID filter handle */
39+
#define NU_CAN_MAXNUM_HNDL NU_CAN_MSG_OBJ_NUM_TX
40+
41+
/* Convert to string literal */
42+
#define NU_STR_(X) #X
43+
#define NU_STR(X) NU_STR_(X)
44+
3445
static uintptr_t can_irq_contexts[CAN_NUM] = {0};
3546
static can_irq_handler can0_irq_handler;
3647

37-
extern uint32_t CAN_IsNewDataReceived(CAN_T *tCAN, uint8_t u8MsgObj);
3848
extern void CAN_CLR_INT_PENDING_ONLY_BIT(CAN_T *tCAN, uint32_t u32MsgNum);
3949

4050
static const struct nu_modinit_s can_modinit_tab[] = {
@@ -144,7 +154,7 @@ static void can_irq(CANName name, int id)
144154
can0_irq_handler(can_irq_contexts[id], IRQ_BUS);
145155
}
146156
} else if (u8IIDRstatus >= 1 && u8IIDRstatus <= 32) {
147-
if (CAN_IsNewDataReceived(can, u8IIDRstatus - 1)) {
157+
if ((u8IIDRstatus - 1) != NU_CAN_MSG_OBJ_NUM_TX) {
148158
can0_irq_handler(can_irq_contexts[id], IRQ_RX);
149159
CAN_CLR_INT_PENDING_ONLY_BIT(can, (u8IIDRstatus -1));
150160
} else {
@@ -221,6 +231,9 @@ void can_irq_set(can_t *obj, CanIrqType irq, uint32_t enable)
221231

222232
int can_write(can_t *obj, CAN_Message msg, int cc)
223233
{
234+
/* Unused */
235+
(void) cc;
236+
224237
STR_CANMSG_T CMsg;
225238

226239
CMsg.IdType = (uint32_t)msg.format;
@@ -229,7 +242,7 @@ int can_write(can_t *obj, CAN_Message msg, int cc)
229242
CMsg.DLC = msg.len;
230243
memcpy((void *)&CMsg.Data[0],(const void *)&msg.data[0], (unsigned int)8);
231244

232-
return CAN_Transmit((CAN_T *)NU_MODBASE(obj->can), cc, &CMsg);
245+
return CAN_Transmit((CAN_T *)NU_MODBASE(obj->can), NU_CAN_MSG_OBJ_NUM_TX, &CMsg);
233246
}
234247

235248
int can_read(can_t *obj, CAN_Message *msg, int handle)
@@ -293,6 +306,13 @@ int can_mode(can_t *obj, CanMode mode)
293306

294307
int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle)
295308
{
309+
/* Check validity of filter handle */
310+
if (handle < 0 || handle >= NU_CAN_MAXNUM_HNDL) {
311+
/* NOTE: 0 is ambiguous, error or filter handle 0. */
312+
error("Support max " NU_STR(NU_CAN_MAXNUM_HNDL) " CAN filters");
313+
return 0;
314+
}
315+
296316
uint32_t numask = mask;
297317
if( numask == 0x0000 )
298318
{

targets/TARGET_NUVOTON/TARGET_M480/can_api.c

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,21 @@
3030
#include "nu_miscutil.h"
3131
#include "nu_bitutil.h"
3232
#include "mbed_critical.h"
33+
#include "mbed_error.h"
3334

3435
#define NU_CAN_DEBUG 0
3536
#define CAN_NUM 2
3637

38+
/* Reserve Message Object number 31 for Tx */
39+
#define NU_CAN_MSG_OBJ_NUM_TX 31
40+
41+
/* Max number of message ID filter handle */
42+
#define NU_CAN_MAXNUM_HNDL NU_CAN_MSG_OBJ_NUM_TX
43+
44+
/* Convert to string literal */
45+
#define NU_STR_(X) #X
46+
#define NU_STR(X) NU_STR_(X)
47+
3748
static uintptr_t can_irq_contexts[CAN_NUM] = {0};
3849
static can_irq_handler can0_irq_handler;
3950
static can_irq_handler can1_irq_handler;
@@ -163,7 +174,7 @@ static void can_irq(CANName name, int id)
163174
can0_irq_handler(can_irq_contexts[id], IRQ_BUS);
164175
}
165176
} else if (u8IIDRstatus >= 1 && u8IIDRstatus <= 32) {
166-
if (CAN_IsNewDataReceived(can, u8IIDRstatus - 1)) {
177+
if ((u8IIDRstatus - 1) != NU_CAN_MSG_OBJ_NUM_TX) {
167178
if (id) {
168179
can1_irq_handler(can_irq_contexts[id], IRQ_RX);
169180
}
@@ -272,6 +283,9 @@ void can_irq_set(can_t *obj, CanIrqType irq, uint32_t enable)
272283

273284
int can_write(can_t *obj, CAN_Message msg, int cc)
274285
{
286+
/* Unused */
287+
(void) cc;
288+
275289
STR_CANMSG_T CMsg;
276290

277291
CMsg.IdType = (uint32_t)msg.format;
@@ -280,7 +294,7 @@ int can_write(can_t *obj, CAN_Message msg, int cc)
280294
CMsg.DLC = msg.len;
281295
memcpy((void *)&CMsg.Data[0],(const void *)&msg.data[0], (unsigned int)8);
282296

283-
return CAN_Transmit((CAN_T *)(NU_MODBASE(obj->can)), cc, &CMsg);
297+
return CAN_Transmit((CAN_T *)(NU_MODBASE(obj->can)), NU_CAN_MSG_OBJ_NUM_TX, &CMsg);
284298
}
285299

286300
int can_read(can_t *obj, CAN_Message *msg, int handle)
@@ -341,6 +355,13 @@ int can_mode(can_t *obj, CanMode mode)
341355

342356
int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle)
343357
{
358+
/* Check validity of filter handle */
359+
if (handle < 0 || handle >= NU_CAN_MAXNUM_HNDL) {
360+
/* NOTE: 0 is ambiguous, error or filter handle 0. */
361+
error("Support max " NU_STR(NU_CAN_MAXNUM_HNDL) " CAN filters");
362+
return 0;
363+
}
364+
344365
uint32_t numask = mask;
345366
if( numask == 0x0000 )
346367
{

targets/TARGET_NUVOTON/TARGET_NUC472/can_api.c

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,25 @@
2727
#include "nu_miscutil.h"
2828
#include "nu_bitutil.h"
2929
#include "mbed_critical.h"
30+
#include "mbed_error.h"
3031

3132
#define NU_CAN_DEBUG 0
3233
#define CAN_NUM 2
3334

35+
/* Reserve Message Object number 31 for Tx */
36+
#define NU_CAN_MSG_OBJ_NUM_TX 31
37+
38+
/* Convert to string literal */
39+
#define NU_STR_(X) #X
40+
#define NU_STR(X) NU_STR_(X)
41+
42+
/* Max number of message ID filter handle */
43+
#define NU_CAN_MAXNUM_HNDL NU_CAN_MSG_OBJ_NUM_TX
44+
3445
static uintptr_t can_irq_contexts[CAN_NUM] = {0};
3546
static can_irq_handler can0_irq_handler;
3647
static can_irq_handler can1_irq_handler;
3748

38-
extern uint32_t CAN_IsNewDataReceived(CAN_T *tCAN, uint8_t u8MsgObj);
3949
extern void CAN_CLR_INT_PENDING_ONLY_BIT(CAN_T *tCAN, uint32_t u32MsgNum);
4050

4151
static const struct nu_modinit_s can_modinit_tab[] = {
@@ -158,7 +168,7 @@ static void can_irq(CANName name, int id)
158168
can0_irq_handler(can_irq_contexts[id], IRQ_BUS);
159169
}
160170
} else if (u8IIDRstatus >= 1 && u8IIDRstatus <= 32) {
161-
if (CAN_IsNewDataReceived(can, u8IIDRstatus - 1)) {
171+
if ((u8IIDRstatus - 1) != NU_CAN_MSG_OBJ_NUM_TX) {
162172
if (id) {
163173
can1_irq_handler(can_irq_contexts[id], IRQ_RX);
164174
}
@@ -274,6 +284,9 @@ void can_irq_set(can_t *obj, CanIrqType irq, uint32_t enable)
274284

275285
int can_write(can_t *obj, CAN_Message msg, int cc)
276286
{
287+
/* Unused */
288+
(void) cc;
289+
277290
STR_CANMSG_T CMsg;
278291

279292
CMsg.IdType = (uint32_t)msg.format;
@@ -282,7 +295,7 @@ int can_write(can_t *obj, CAN_Message msg, int cc)
282295
CMsg.DLC = msg.len;
283296
memcpy((void *)&CMsg.Data[0],(const void *)&msg.data[0], (unsigned int)8);
284297

285-
return CAN_Transmit((CAN_T *)NU_MODBASE(obj->can), cc, &CMsg);
298+
return CAN_Transmit((CAN_T *)NU_MODBASE(obj->can), NU_CAN_MSG_OBJ_NUM_TX, &CMsg);
286299
}
287300

288301
int can_read(can_t *obj, CAN_Message *msg, int handle)
@@ -346,6 +359,13 @@ int can_mode(can_t *obj, CanMode mode)
346359

347360
int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle)
348361
{
362+
/* Check validity of filter handle */
363+
if (handle < 0 || handle >= NU_CAN_MAXNUM_HNDL) {
364+
/* NOTE: 0 is ambiguous, error or filter handle 0. */
365+
error("Support max " NU_STR(NU_CAN_MAXNUM_HNDL) " CAN filters");
366+
return 0;
367+
}
368+
349369
return CAN_SetRxMsg((CAN_T *)NU_MODBASE(obj->can), handle , (uint32_t)format, id);
350370
}
351371

0 commit comments

Comments
 (0)