30
30
#include "nu_miscutil.h"
31
31
#include "nu_bitutil.h"
32
32
#include "mbed_critical.h"
33
+ #include "mbed_error.h"
33
34
34
35
#define NU_CAN_DEBUG 0
35
36
#define CAN_NUM 2
36
37
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
+
37
48
static uintptr_t can_irq_contexts [CAN_NUM ] = {0 };
38
49
static can_irq_handler can0_irq_handler ;
39
50
static can_irq_handler can1_irq_handler ;
@@ -43,6 +54,7 @@ extern void CAN_EnterInitMode(CAN_T *tCAN, uint8_t u8Mask);
43
54
extern void CAN_LeaveInitMode (CAN_T * tCAN );
44
55
extern void CAN_LeaveTestMode (CAN_T * tCAN );
45
56
extern void CAN_EnterTestMode (CAN_T * tCAN , uint8_t u8TestMask );
57
+ extern void CAN_CLR_INT_PENDING_ONLY_BIT (CAN_T * tCAN , uint32_t u32MsgNum );
46
58
47
59
static const struct nu_modinit_s can_modinit_tab [] = {
48
60
{CAN_0 , CAN0_MODULE , 0 , 0 , CAN0_RST , CAN0_IRQn , NULL },
@@ -139,19 +151,10 @@ static void can_irq(CANName name, int id)
139
151
/**************************/
140
152
if (can -> STATUS & CAN_STATUS_RXOK_Msk ) {
141
153
can -> STATUS &= ~CAN_STATUS_RXOK_Msk ; /* Clear Rx Ok status*/
142
- if (id )
143
- can1_irq_handler (can_irq_contexts [id ], IRQ_RX );
144
- else
145
- can0_irq_handler (can_irq_contexts [id ], IRQ_RX );
146
154
}
147
155
148
156
if (can -> STATUS & CAN_STATUS_TXOK_Msk ) {
149
157
can -> STATUS &= ~CAN_STATUS_TXOK_Msk ; /* Clear Tx Ok status*/
150
- if (id )
151
- can1_irq_handler (can_irq_contexts [id ], IRQ_TX );
152
- else
153
- can0_irq_handler (can_irq_contexts [id ], IRQ_TX );
154
-
155
158
}
156
159
157
160
/**************************/
@@ -170,6 +173,24 @@ static void can_irq(CANName name, int id)
170
173
else
171
174
can0_irq_handler (can_irq_contexts [id ], IRQ_BUS );
172
175
}
176
+ } else if (u8IIDRstatus >= 1 && u8IIDRstatus <= 32 ) {
177
+ if ((u8IIDRstatus - 1 ) != NU_CAN_MSG_OBJ_NUM_TX ) {
178
+ if (id ) {
179
+ can1_irq_handler (can_irq_contexts [id ], IRQ_RX );
180
+ }
181
+ else {
182
+ can0_irq_handler (can_irq_contexts [id ], IRQ_RX );
183
+ }
184
+ CAN_CLR_INT_PENDING_ONLY_BIT (can , (u8IIDRstatus - 1 ));
185
+ } else {
186
+ if (id ) {
187
+ can1_irq_handler (can_irq_contexts [id ], IRQ_TX );
188
+ }
189
+ else {
190
+ can0_irq_handler (can_irq_contexts [id ], IRQ_TX );
191
+ }
192
+ CAN_CLR_INT_PENDING_BIT (can , (u8IIDRstatus - 1 ));
193
+ }
173
194
} else if (u8IIDRstatus != 0 ) {
174
195
175
196
if (id )
@@ -178,7 +199,6 @@ static void can_irq(CANName name, int id)
178
199
can0_irq_handler (can_irq_contexts [id ], IRQ_OVERRUN );
179
200
180
201
CAN_CLR_INT_PENDING_BIT (can , ((can -> IIDR ) - 1 )); /* Clear Interrupt Pending */
181
-
182
202
} else if (can -> WU_STATUS == 1 ) {
183
203
184
204
can -> WU_STATUS = 0 ; /* Write '0' to clear */
@@ -263,6 +283,9 @@ void can_irq_set(can_t *obj, CanIrqType irq, uint32_t enable)
263
283
264
284
int can_write (can_t * obj , CAN_Message msg , int cc )
265
285
{
286
+ /* Unused */
287
+ (void ) cc ;
288
+
266
289
STR_CANMSG_T CMsg ;
267
290
268
291
CMsg .IdType = (uint32_t )msg .format ;
@@ -271,7 +294,7 @@ int can_write(can_t *obj, CAN_Message msg, int cc)
271
294
CMsg .DLC = msg .len ;
272
295
memcpy ((void * )& CMsg .Data [0 ],(const void * )& msg .data [0 ], (unsigned int )8 );
273
296
274
- 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 );
275
298
}
276
299
277
300
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)
293
316
int can_mode (can_t * obj , CanMode mode )
294
317
{
295
318
int success = 0 ;
319
+
296
320
switch (mode ) {
297
321
case MODE_RESET :
298
322
CAN_LeaveTestMode ((CAN_T * )NU_MODBASE (obj -> can ));
@@ -326,22 +350,24 @@ int can_mode(can_t *obj, CanMode mode)
326
350
327
351
}
328
352
329
-
330
353
return success ;
331
354
}
332
355
333
356
int can_filter (can_t * obj , uint32_t id , uint32_t mask , CANFormat format , int32_t handle )
334
357
{
335
- uint32_t numask = mask ;
336
- if ( numask == 0x0000 )
337
- {
338
- return CAN_SetRxMsg ((CAN_T * )NU_MODBASE (obj -> can ), handle , (uint32_t )format , id );
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 ;
339
363
}
364
+
365
+ uint32_t numask = mask ;
340
366
if ( format == CANStandard )
341
367
{
342
368
numask = (mask << 18 );
343
369
}
344
- numask = (numask | CAN_IF_MASK2_MDIR_Msk | CAN_IF_MASK2_MXTD_Msk );
370
+ numask = (numask | (( CAN_IF_MASK2_MDIR_Msk | CAN_IF_MASK2_MXTD_Msk ) << 16 ) );
345
371
return CAN_SetRxMsgAndMsk ((CAN_T * )NU_MODBASE (obj -> can ), handle , (uint32_t )format , id , numask );
346
372
}
347
373
0 commit comments