| NUC472_NUC442_BSP V3.04.000 The Board Support Package for NUC472/NUC442

can.c
Go to the documentation of this file.
1/**************************************************************************/
13#include "NUC472_442.h"
27#include <stdio.h>
28
29
31
32#define TSEG1_MIN 2
33#define TSEG1_MAX 16
34#define TSEG2_MIN 1
35#define TSEG2_MAX 8
36#define BRP_MIN 1
37#define BRP_MAX 1024 /* 6-bit BRP field + 4-bit BRPE field*/
38#define SJW_MAX 4
39#define BRP_INC 1
40
41static uint32_t GetFreeIF(CAN_T *tCAN);
42
43
44//#define DEBUG_PRINTF printf
45#define DEBUG_PRINTF(...)
46
55static uint32_t GetFreeIF(CAN_T *tCAN)
56{
57 if((tCAN->IF[0].CREQ & CAN_IF_CREQ_BUSY_Msk) == 0)
58 return 0;
59 else if((tCAN->IF[1].CREQ & CAN_IF_CREQ_BUSY_Msk) == 0)
60 return 1;
61 else
62 return 2;
63}
64
74void CAN_EnterInitMode(CAN_T *tCAN)
75{
76 tCAN->CON |= CAN_CON_INIT_Msk;
77 tCAN->CON |= CAN_CON_CCE_Msk;
78}
79
80
88void CAN_LeaveInitMode(CAN_T *tCAN)
89{
90 uint32_t u32TimeOutCount = SystemCoreClock; // 1 second timeout
91 tCAN->CON &= (~(CAN_CON_INIT_Msk | CAN_CON_CCE_Msk));
92
93 while(tCAN->CON & CAN_CON_INIT_Msk) /* Check INIT bit is released */
94 {
95 if(u32TimeOutCount == 0) break;
96 u32TimeOutCount--;
97 }
98}
99
107void CAN_WaitMsg(CAN_T *tCAN)
108{
109 tCAN->STATUS = 0x0; /* clr status */
110
111 while (1)
112 {
113 if(tCAN->IF[1].MCON & CAN_IF_MCON_NEWDAT_Msk) /* check new data */
114 {
115 DEBUG_PRINTF("New Data IN\n");
116 break;
117 }
118 if(tCAN->STATUS & CAN_STATUS_RXOK_Msk)
119 DEBUG_PRINTF("Rx OK\n");
120
121 if(tCAN->STATUS & CAN_STATUS_LEC_Msk)
122 {
123 DEBUG_PRINTF("Error\n");
124 }
125 }
126}
127
134uint32_t CAN_GetCANBitRate(CAN_T *tCAN)
135{
136 uint8_t u8Tseg1,u8Tseg2;
137 uint32_t u32Bpr;
138
139 u8Tseg1 = (tCAN->BTIME & CAN_BTIME_TSEG1_Msk) >> CAN_BTIME_TSEG1_Pos;
140 u8Tseg2 = (tCAN->BTIME & CAN_BTIME_TSEG2_Msk) >> CAN_BTIME_TSEG2_Pos;
141 u32Bpr = (tCAN->BTIME & CAN_BTIME_BRP_Msk) | (tCAN->BRPE << 6);
142
143 return (CLK_GetPCLKFreq()/(u32Bpr+1)/(u8Tseg1 + u8Tseg2 + 3));
144}
145
159void CAN_EnterTestMode(CAN_T *tCAN, uint8_t u8TestMask)
160{
161 tCAN->CON |= CAN_CON_TEST_Msk;
162 tCAN->TEST = u8TestMask;
163}
164
165
172void CAN_LeaveTestMode(CAN_T *tCAN)
173{
174 tCAN->CON |= CAN_CON_TEST_Msk;
175 tCAN->TEST &= ~(CAN_TEST_LBACK_Msk | CAN_TEST_SILENT_Msk | CAN_TEST_BASIC_Msk);
176 tCAN->CON &= (~CAN_CON_TEST_Msk);
177}
178
187uint32_t CAN_IsNewDataReceived(CAN_T *tCAN, uint8_t u8MsgObj)
188{
189 return (u8MsgObj < 16 ? tCAN->NDAT1 & (1 << u8MsgObj) : tCAN->NDAT2 & (1 << (u8MsgObj-16)));
190}
191
192
204int32_t CAN_BasicSendMsg(CAN_T *tCAN, STR_CANMSG_T* pCanMsg)
205{
206 uint32_t i=0;
207 uint32_t u32TimeOutCount = SystemCoreClock; // 1 second timeout
208
209 while(tCAN->IF[0].CREQ & CAN_IF_CREQ_BUSY_Msk)
210 {
211 i++;
212 if(i > u32TimeOutCount) return -1;
213 }
214
215 tCAN->STATUS &= (~CAN_STATUS_TXOK_Msk);
216
217 tCAN->IF[0].CMASK = CAN_IF_CMASK_WRRD_Msk;
218
219 if (pCanMsg->IdType == CAN_STD_ID)
220 {
221 /* standard ID*/
222 tCAN->IF[0].ARB1 = 0;
223 tCAN->IF[0].ARB2 = (((pCanMsg->Id)&0x7FF)<<2) ;
224 }
225 else
226 {
227 /* extended ID*/
228 tCAN->IF[0].ARB1 = (pCanMsg->Id)&0xFFFF;
229 tCAN->IF[0].ARB2 = ((pCanMsg->Id)&0x1FFF0000)>>16 | CAN_IF_ARB2_XTD_Msk;
230
231 }
232
233 if(pCanMsg->FrameType)
234 tCAN->IF[0].ARB2 |= CAN_IF_ARB2_DIR_Msk;
235 else
236 tCAN->IF[0].ARB2 &= (~CAN_IF_ARB2_DIR_Msk);
237
238 tCAN->IF[0].MCON = (tCAN->IF[0].MCON & (~CAN_IF_MCON_DLC_Msk)) | pCanMsg->DLC;
239 tCAN->IF[0].DAT_A1 = ((uint16_t)pCanMsg->Data[1]<<8) | pCanMsg->Data[0];
240 tCAN->IF[0].DAT_A2 = ((uint16_t)pCanMsg->Data[3]<<8) | pCanMsg->Data[2];
241 tCAN->IF[0].DAT_B1 = ((uint16_t)pCanMsg->Data[5]<<8) | pCanMsg->Data[4];
242 tCAN->IF[0].DAT_B2 = ((uint16_t)pCanMsg->Data[7]<<8) | pCanMsg->Data[6];
243
244 /* request transmission*/
245 tCAN->IF[0].CREQ &= (~CAN_IF_CREQ_BUSY_Msk);
246 if(tCAN->IF[0].CREQ & CAN_IF_CREQ_BUSY_Msk)
247 {
248 DEBUG_PRINTF("Cannot clear busy for sending ...\n");
249 return FALSE;
250 }
251
252 tCAN->IF[0].CREQ |= CAN_IF_CREQ_BUSY_Msk; // sending
253
254 for ( i=0; i<0xFFFFF; i++)
255 {
256 if((tCAN->IF[0].CREQ & CAN_IF_CREQ_BUSY_Msk) == 0) break;
257 }
258
259 if ( i >= 0xFFFFF )
260 {
261 DEBUG_PRINTF("Cannot send out...\n");
262 return FALSE;
263 }
264
265 return TRUE;
266}
267
268
279int32_t CAN_BasicReceiveMsg(CAN_T *tCAN, STR_CANMSG_T* pCanMsg)
280{
281 if((tCAN->IF[1].MCON & CAN_IF_MCON_NEWDAT_Msk) == 0) /* In basic mode, receive data always save in IF2 */
282 {
283 return FALSE;
284 }
285
286 tCAN->STATUS &= (~CAN_STATUS_RXOK_Msk);
287
288 tCAN->IF[1].CMASK = CAN_IF_CMASK_ARB_Msk
289 | CAN_IF_CMASK_CONTROL_Msk
290 | CAN_IF_CMASK_DATAA_Msk
291 | CAN_IF_CMASK_DATAB_Msk;
292
293 if((tCAN->IF[1].ARB2 & CAN_IF_ARB2_XTD_Msk) == 0)
294 {
295 /* standard ID*/
296 pCanMsg->IdType = CAN_STD_ID;
297 pCanMsg->Id = (tCAN->IF[1].ARB2 >> 2) & 0x07FF;
298
299 }
300 else
301 {
302 /* extended ID*/
303 pCanMsg->IdType = CAN_EXT_ID;
304 pCanMsg->Id = (tCAN->IF[1].ARB2 & 0x1FFF)<<16;
305 pCanMsg->Id |= (uint32_t)tCAN->IF[1].ARB1;
306 }
307
308 pCanMsg->FrameType = !((tCAN->IF[1].ARB2 & CAN_IF_ARB2_DIR_Msk) >> CAN_IF_ARB2_DIR_Pos);
309
310 pCanMsg->DLC = tCAN->IF[1].MCON & CAN_IF_MCON_DLC_Msk;
311 pCanMsg->Data[0] = tCAN->IF[1].DAT_A1 & CAN_IF_DAT_A1_DATA0_Msk;
312 pCanMsg->Data[1] = (tCAN->IF[1].DAT_A1 & CAN_IF_DAT_A1_DATA1_Msk) >> CAN_IF_DAT_A1_DATA1_Pos;
313 pCanMsg->Data[2] = tCAN->IF[1].DAT_A2 & CAN_IF_DAT_A2_DATA2_Msk;
314 pCanMsg->Data[3] = (tCAN->IF[1].DAT_A2 & CAN_IF_DAT_A2_DATA3_Msk) >> CAN_IF_DAT_A2_DATA3_Pos;
315 pCanMsg->Data[4] = tCAN->IF[1].DAT_B1 & CAN_IF_DAT_B1_DATA4_Msk;
316 pCanMsg->Data[5] = (tCAN->IF[1].DAT_B1 & CAN_IF_DAT_B1_DATA5_Msk) >> CAN_IF_DAT_B1_DATA5_Pos;
317 pCanMsg->Data[6] = tCAN->IF[1].DAT_B2 & CAN_IF_DAT_B2_DATA6_Msk;
318 pCanMsg->Data[7] = (tCAN->IF[1].DAT_B2 & CAN_IF_DAT_B2_DATA7_Msk) >> CAN_IF_DAT_B2_DATA7_Pos;
319
320 return TRUE;
321}
322
340int32_t CAN_SetRxMsgObj(CAN_T *tCAN, uint8_t u8MsgObj, uint8_t u8idType, uint32_t u32id, uint8_t u8singleOrFifoLast)
341{
342 uint8_t u8MsgIfNum=0;
343
344 if ((u8MsgIfNum = GetFreeIF(tCAN)) == 2) /* Check Free Interface for configure */
345 {
346 return FALSE;
347 }
348 /* Command Setting */
349 tCAN->IF[u8MsgIfNum].CMASK = CAN_IF_CMASK_WRRD_Msk | CAN_IF_CMASK_MASK_Msk | CAN_IF_CMASK_ARB_Msk |
350 CAN_IF_CMASK_CONTROL_Msk | CAN_IF_CMASK_DATAA_Msk | CAN_IF_CMASK_DATAB_Msk;
351
352 if (u8idType == CAN_STD_ID) /* According STD/EXT ID format,Configure Mask and Arbitration register */
353 {
354 tCAN->IF[u8MsgIfNum].ARB1 = 0;
355 tCAN->IF[u8MsgIfNum].ARB2 = CAN_IF_ARB2_MSGVAL_Msk | (u32id & 0x7FF)<< 2;
356 }
357 else
358 {
359 tCAN->IF[u8MsgIfNum].ARB1 = u32id & 0xFFFF;
360 tCAN->IF[u8MsgIfNum].ARB2 = CAN_IF_ARB2_MSGVAL_Msk | CAN_IF_ARB2_XTD_Msk | (u32id & 0x1FFF0000)>>16;
361 }
362
363 tCAN->IF[u8MsgIfNum].MCON |= CAN_IF_MCON_UMASK_Msk | CAN_IF_MCON_RXIE_Msk;
364 if(u8singleOrFifoLast)
365 tCAN->IF[u8MsgIfNum].MCON |= CAN_IF_MCON_EOB_Msk;
366 else
367 tCAN->IF[u8MsgIfNum].MCON &= (~CAN_IF_MCON_EOB_Msk);
368
369 tCAN->IF[u8MsgIfNum].DAT_A1 = 0;
370 tCAN->IF[u8MsgIfNum].DAT_A2 = 0;
371 tCAN->IF[u8MsgIfNum].DAT_B1 = 0;
372 tCAN->IF[u8MsgIfNum].DAT_B2 = 0;
373
374 tCAN->IF[u8MsgIfNum].CREQ = 1 + u8MsgObj;
375
376 return TRUE;
377}
378
379
394int32_t CAN_ReadMsgObj(CAN_T *tCAN, uint8_t u8MsgObj, uint8_t u8Release, STR_CANMSG_T* pCanMsg)
395{
396 int32_t rev = 1l;
397 uint32_t u32TimeOutCount = SystemCoreClock * 2; // 2 second timeout
398
399 if (!CAN_IsNewDataReceived(tCAN, u8MsgObj))
400 {
401 rev = 0;
402 }
403
404 tCAN->STATUS &= (~CAN_STATUS_RXOK_Msk);
405
406 /* read the message contents*/
407 tCAN->IF[1].CMASK = CAN_IF_CMASK_MASK_Msk
408 | CAN_IF_CMASK_ARB_Msk
409 | CAN_IF_CMASK_CONTROL_Msk
410 | CAN_IF_CMASK_CLRINTPND_Msk
411 | (u8Release ? CAN_IF_CMASK_TXRQSTNEWDAT_Msk : 0)
412 | CAN_IF_CMASK_DATAA_Msk
413 | CAN_IF_CMASK_DATAB_Msk;
414
415 tCAN->IF[1].CREQ = 1 + u8MsgObj;
416
417 while (tCAN->IF[1].CREQ & CAN_IF_CREQ_BUSY_Msk)
418 {
419 if(u32TimeOutCount == 0)
420 {
421 return -1;
422 }
423 u32TimeOutCount--;
424 }
425
426 if ((tCAN->IF[1].ARB2 & CAN_IF_ARB2_XTD_Msk) == 0)
427 {
428 /* standard ID*/
429 pCanMsg->IdType = CAN_STD_ID;
430 pCanMsg->Id = (tCAN->IF[1].ARB2 & CAN_IF_ARB2_ID_Msk) >> 2;
431 }
432 else
433 {
434 /* extended ID*/
435 pCanMsg->IdType = CAN_EXT_ID;
436 pCanMsg->Id = (((tCAN->IF[1].ARB2) & 0x1FFF)<<16) | tCAN->IF[1].ARB1;
437 }
438
439 pCanMsg->DLC = tCAN->IF[1].MCON & CAN_IF_MCON_DLC_Msk;
440 pCanMsg->Data[0] = tCAN->IF[1].DAT_A1 & CAN_IF_DAT_A1_DATA0_Msk;
441 pCanMsg->Data[1] = (tCAN->IF[1].DAT_A1 & CAN_IF_DAT_A1_DATA1_Msk) >> CAN_IF_DAT_A1_DATA1_Pos;
442 pCanMsg->Data[2] = tCAN->IF[1].DAT_A2 & CAN_IF_DAT_A2_DATA2_Msk;
443 pCanMsg->Data[3] = (tCAN->IF[1].DAT_A2 & CAN_IF_DAT_A2_DATA3_Msk) >> CAN_IF_DAT_A2_DATA3_Pos;
444 pCanMsg->Data[4] = tCAN->IF[1].DAT_B1 & CAN_IF_DAT_B1_DATA4_Msk;
445 pCanMsg->Data[5] = (tCAN->IF[1].DAT_B1 & CAN_IF_DAT_B1_DATA5_Msk) >> CAN_IF_DAT_B1_DATA5_Pos;
446 pCanMsg->Data[6] = tCAN->IF[1].DAT_B2 & CAN_IF_DAT_B2_DATA6_Msk;
447 pCanMsg->Data[7] = (tCAN->IF[1].DAT_B2 & CAN_IF_DAT_B2_DATA7_Msk) >> CAN_IF_DAT_B2_DATA7_Pos;
448
449 return rev;
450}
451
452static int can_update_spt(int sampl_pt, int tseg, int *tseg1, int *tseg2)
453{
454 *tseg2 = tseg + 1 - (sampl_pt * (tseg + 1)) / 1000;
455 if (*tseg2 < TSEG2_MIN)
456 *tseg2 = TSEG2_MIN;
457 if (*tseg2 > TSEG2_MAX)
458 *tseg2 = TSEG2_MAX;
459 *tseg1 = tseg - *tseg2;
460 if (*tseg1 > TSEG1_MAX)
461 {
462 *tseg1 = TSEG1_MAX;
463 *tseg2 = tseg - *tseg1;
464 }
465 return 1000 * (tseg + 1 - *tseg2) / (tseg + 1);
466}
467
469
470
479uint32_t CAN_SetBaudRate(CAN_T *tCAN, uint32_t u32BaudRate)
480{
481 long rate;
482 long best_error = 1000000000, error = 0;
483 int best_tseg = 0, best_brp = 0, brp = 0;
484 int tsegall, tseg = 0, tseg1 = 0, tseg2 = 0;
485 int spt_error = 1000, spt = 0, sampl_pt;
486 uint64_t clock_freq = 0;
487 uint32_t sjw = 1;
488
489 CAN_EnterInitMode(tCAN);
490
491 SystemCoreClockUpdate();
492
493 clock_freq = CLK_GetPCLKFreq();
494
495 if(u32BaudRate >= 1000000)
496 u32BaudRate = 1000000;
497
498 /* Use CIA recommended sample points */
499 if (u32BaudRate > 800000)
500 sampl_pt = 750;
501 else if (u32BaudRate > 500000)
502 sampl_pt = 800;
503 else
504 sampl_pt = 875;
505
506 /* tseg even = round down, odd = round up */
507 for (tseg = (TSEG1_MAX + TSEG2_MAX) * 2 + 1; tseg >= (TSEG1_MIN + TSEG2_MIN) * 2; tseg--)
508 {
509 tsegall = 1 + tseg / 2;
510 /* Compute all possible tseg choices (tseg=tseg1+tseg2) */
511 brp = clock_freq / (tsegall * u32BaudRate) + tseg % 2;
512 /* chose brp step which is possible in system */
513 brp = (brp / BRP_INC) * BRP_INC;
514
515 if ((brp < BRP_MIN) || (brp > BRP_MAX))
516 continue;
517 rate = clock_freq / (brp * tsegall);
518
519 error = u32BaudRate - rate;
520
521 /* tseg brp biterror */
522 if (error < 0)
523 error = -error;
524 if (error > best_error)
525 continue;
526 best_error = error;
527 if (error == 0)
528 {
529 spt = can_update_spt(sampl_pt, tseg / 2, &tseg1, &tseg2);
530 error = sampl_pt - spt;
531 if (error < 0)
532 error = -error;
533 if (error > spt_error)
534 continue;
535 spt_error = error;
536 }
537 best_tseg = tseg / 2;
538 best_brp = brp;
539
540 if (error == 0)
541 break;
542 }
543
544 spt = can_update_spt(sampl_pt, best_tseg, &tseg1, &tseg2);
545
546 /* check for sjw user settings */
547 /* bt->sjw is at least 1 -> sanitize upper bound to sjw_max */
548 if (sjw > SJW_MAX)
549 sjw = SJW_MAX;
550 /* bt->sjw must not be higher than tseg2 */
551 if (tseg2 < sjw)
552 sjw = tseg2;
553
554 /* real bit-rate */
555 u32BaudRate = clock_freq / (best_brp * (tseg1 + tseg2 + 1));
556
557 tCAN->BTIME = ((uint32_t)(tseg2 - 1) << CAN_BTIME_TSEG2_Pos) | ((uint32_t)(tseg1 - 1) << CAN_BTIME_TSEG1_Pos) |
558 ((best_brp - 1) & CAN_BTIME_BRP_Msk) | (sjw << CAN_BTIME_SJW_Pos);
559 tCAN->BRPE = ((best_brp - 1) >> 6) & 0x0F;
560
561 //printf("\n bitrate = %d \n", CAN_GetCANBitRate(tCAN));
562
563 CAN_LeaveInitMode(tCAN);
564
565 return u32BaudRate;
566}
567
575 void CAN_Close(CAN_T *tCAN)
576{
577 CAN_DisableInt(tCAN, (CAN_CON_IE_Msk|CAN_CON_SIE_Msk|CAN_CON_EIE_Msk));
578}
579
589uint32_t CAN_Open(CAN_T *tCAN, uint32_t u32BaudRate, uint32_t u32Mode)
590{
591 uint32_t u32CurrentBitRate;
592
593 u32CurrentBitRate = CAN_SetBaudRate(tCAN, u32BaudRate);
594
595 if(u32Mode == CAN_BASIC_MODE)
596 CAN_EnterTestMode(tCAN, CAN_TEST_BASIC_Msk);
597 else
598 tCAN->CON &= ~CAN_CON_TEST_Msk;
599
600 return u32CurrentBitRate;
601}
602
614int32_t CAN_SetTxMsg(CAN_T *tCAN, uint32_t u32MsgNum, STR_CANMSG_T* pCanMsg)
615{
616 uint8_t u8MsgIfNum=0;
617 uint32_t u32TimeOutCount = SystemCoreClock; // 1 second timeout
618
619 while((u8MsgIfNum = GetFreeIF(tCAN)) == 2)
620 {
621 if(u32TimeOutCount == 0)
622 {
623 return FALSE;
624 }
625 u32TimeOutCount--;
626 }
627
628 /* update the contents needed for transmission*/
629 tCAN->IF[u8MsgIfNum].CMASK = 0xF3; /*CAN_CMASK_WRRD_Msk | CAN_CMASK_MASK_Msk | CAN_CMASK_ARB_Msk
630 | CAN_CMASK_CONTROL_Msk | CAN_CMASK_DATAA_Msk | CAN_CMASK_DATAB_Msk ; */
631
632 if (pCanMsg->IdType == CAN_STD_ID)
633 {
634 /* standard ID*/
635 tCAN->IF[u8MsgIfNum].ARB1 = 0;
636 tCAN->IF[u8MsgIfNum].ARB2 = (((pCanMsg->Id)&0x7FF)<<2) | CAN_IF_ARB2_DIR_Msk | CAN_IF_ARB2_MSGVAL_Msk;
637 }
638 else
639 {
640 /* extended ID*/
641 tCAN->IF[u8MsgIfNum].ARB1 = (pCanMsg->Id)&0xFFFF;
642 tCAN->IF[u8MsgIfNum].ARB2 = ((pCanMsg->Id)&0x1FFF0000)>>16 | CAN_IF_ARB2_DIR_Msk
643 | CAN_IF_ARB2_XTD_Msk | CAN_IF_ARB2_MSGVAL_Msk;
644 }
645
646 if(pCanMsg->FrameType)
647 tCAN->IF[u8MsgIfNum].ARB2 |= CAN_IF_ARB2_DIR_Msk;
648 else
649 tCAN->IF[u8MsgIfNum].ARB2 &= (~CAN_IF_ARB2_DIR_Msk);
650
651 tCAN->IF[u8MsgIfNum].DAT_A1 = ((uint16_t)pCanMsg->Data[1]<<8) | pCanMsg->Data[0];
652 tCAN->IF[u8MsgIfNum].DAT_A2 = ((uint16_t)pCanMsg->Data[3]<<8) | pCanMsg->Data[2];
653 tCAN->IF[u8MsgIfNum].DAT_B1 = ((uint16_t)pCanMsg->Data[5]<<8) | pCanMsg->Data[4];
654 tCAN->IF[u8MsgIfNum].DAT_B2 = ((uint16_t)pCanMsg->Data[7]<<8) | pCanMsg->Data[6];
655
656 tCAN->IF[u8MsgIfNum].MCON = CAN_IF_MCON_NEWDAT_Msk | pCanMsg->DLC |CAN_IF_MCON_TXIE_Msk | CAN_IF_MCON_EOB_Msk;
657 tCAN->IF[u8MsgIfNum].CREQ = 1 + u32MsgNum;
658
659 return TRUE;
660}
661
670int32_t CAN_TriggerTxMsg(CAN_T *tCAN, uint32_t u32MsgNum)
671{
672 STR_CANMSG_T rMsg;
673 CAN_ReadMsgObj(tCAN, u32MsgNum,TRUE, &rMsg);
674 tCAN->IF[0].CMASK = CAN_IF_CMASK_WRRD_Msk |CAN_IF_CMASK_TXRQSTNEWDAT_Msk;
675 tCAN->IF[0].CREQ = 1 + u32MsgNum;
676
677 return TRUE;
678}
679
688 void CAN_EnableInt(CAN_T *tCAN, uint32_t u32Mask)
689{
690 CAN_EnterInitMode(tCAN);
691
692 tCAN->CON = (tCAN->CON & ~(CAN_CON_IE_Msk | CAN_CON_SIE_Msk | CAN_CON_EIE_Msk)) |
693 (u32Mask & (CAN_CON_IE_Msk | CAN_CON_SIE_Msk | CAN_CON_EIE_Msk));
694
695
696 CAN_LeaveInitMode(tCAN);
697}
698
707 void CAN_DisableInt(CAN_T *tCAN, uint32_t u32Mask)
708{
709 CAN_EnterInitMode(tCAN);
710
711 tCAN->CON = tCAN->CON & ~((u32Mask & (CAN_CON_IE_Msk | CAN_CON_SIE_Msk | CAN_CON_EIE_Msk)));
712
713 CAN_LeaveInitMode(tCAN);
714}
715
716
729int32_t CAN_SetRxMsg(CAN_T *tCAN, uint32_t u32MsgNum, uint32_t u32IDType, uint32_t u32ID)
730{
731 uint32_t u32TimeOutCount = SystemCoreClock; // 1 second timeout
732
733 while(CAN_SetRxMsgObj(tCAN, u32MsgNum, u32IDType, u32ID, TRUE) == FALSE)
734 {
735 if(u32TimeOutCount == 0)
736 {
737 return FALSE;
738 }
739 u32TimeOutCount--;
740 }
741
742 return TRUE;
743}
744
758int32_t CAN_SetMultiRxMsg(CAN_T *tCAN, uint32_t u32MsgNum, uint32_t u32MsgCount, uint32_t u32IDType, uint32_t u32ID)
759{
760 uint32_t i = 0;
761 uint32_t u32TimeOutCount = SystemCoreClock; // 1 second timeout
762 uint32_t u32EOB_Flag = 0;
763
764 for(i= 1; i <= u32MsgCount; i++)
765 {
766 if(i == u32MsgCount) u32EOB_Flag = 1;
767
768 while(CAN_SetRxMsgObj(tCAN, u32MsgNum, u32IDType, u32ID, u32EOB_Flag) == FALSE)
769 {
770 if(u32TimeOutCount == 0)
771 {
772 return FALSE;
773 }
774 u32TimeOutCount--;
775 }
776
777 u32MsgNum++;
778 }
779
780 return TRUE;
781}
782
783
793int32_t CAN_Transmit(CAN_T *tCAN, uint32_t u32MsgNum, STR_CANMSG_T* pCanMsg)
794{
795 if((tCAN->CON & CAN_CON_TEST_Msk) && (tCAN->TEST & CAN_TEST_BASIC_Msk))
796 {
797 return (CAN_BasicSendMsg(tCAN, pCanMsg));
798 }
799 else
800 {
801 if(CAN_SetTxMsg(tCAN, u32MsgNum, pCanMsg) == FALSE)
802 return FALSE;
803 CAN_TriggerTxMsg(tCAN, u32MsgNum);
804 }
805
806 return TRUE;
807}
808
809
819int32_t CAN_Receive(CAN_T *tCAN, uint32_t u32MsgNum, STR_CANMSG_T* pCanMsg)
820{
821 if((tCAN->CON & CAN_CON_TEST_Msk) && (tCAN->TEST & CAN_TEST_BASIC_Msk))
822 {
823 return (CAN_BasicReceiveMsg(tCAN, pCanMsg));
824 }
825 else
826 {
827 return CAN_ReadMsgObj(tCAN, u32MsgNum, TRUE, pCanMsg);
828 }
829}
830
839 void CAN_CLR_INT_PENDING_BIT(CAN_T *tCAN, uint8_t u32MsgNum)
840{
841 uint32_t u32MsgIfNum = 0;
842 uint32_t u32TimeOutCount = SystemCoreClock; // 1 second timeout
843
844 while(u32TimeOutCount > 0)
845 {
846 if((tCAN->IF[0].CREQ & CAN_IF_CREQ_BUSY_Msk) == 0)
847 {
848 u32MsgIfNum = 0;
849 break;
850 }
851 else if((tCAN->IF[1].CREQ & CAN_IF_CREQ_BUSY_Msk) == 0)
852 {
853 u32MsgIfNum = 1;
854 break;
855 }
856
857 u32TimeOutCount--;
858 }
859
860 tCAN->IF[u32MsgIfNum].CMASK = CAN_IF_CMASK_CLRINTPND_Msk | CAN_IF_CMASK_TXRQSTNEWDAT_Msk;
861 tCAN->IF[u32MsgIfNum].CREQ = 1 + u32MsgNum;
862
863}
864
865 /* end of group NUC472_442_CAN_EXPORTED_FUNCTIONS */
867 /* end of group NUC472_442_CAN_Driver */
869 /* end of group NUC472_442_Device_Driver */
871
872/*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/
873
874
NUC472_442.h
NUC472/NUC442 peripheral access layer header file. This file contains all the peripheral register's d...
CAN_CON_CCE_Msk
#define CAN_CON_CCE_Msk
Definition: NUC472_442.h:1454
CAN_CON_IE_Msk
#define CAN_CON_IE_Msk
Definition: NUC472_442.h:1466
CAN_IF_CMASK_DATAB_Msk
#define CAN_IF_CMASK_DATAB_Msk
Definition: NUC472_442.h:1559
CAN_IF_DAT_B2_DATA7_Msk
#define CAN_IF_DAT_B2_DATA7_Msk
Definition: NUC472_442.h:1637
CAN_TEST_SILENT_Msk
#define CAN_TEST_SILENT_Msk
Definition: NUC472_442.h:1523
CAN_IF_CREQ_BUSY_Msk
#define CAN_IF_CREQ_BUSY_Msk
Definition: NUC472_442.h:1532
CAN_IF_MCON_EOB_Msk
#define CAN_IF_MCON_EOB_Msk
Definition: NUC472_442.h:1613
CAN_CON_SIE_Msk
#define CAN_CON_SIE_Msk
Definition: NUC472_442.h:1463
CAN_IF_DAT_B2_DATA6_Msk
#define CAN_IF_DAT_B2_DATA6_Msk
Definition: NUC472_442.h:1640
CAN_BTIME_TSEG1_Msk
#define CAN_BTIME_TSEG1_Msk
Definition: NUC472_442.h:1502
CAN_CON_EIE_Msk
#define CAN_CON_EIE_Msk
Definition: NUC472_442.h:1460
CAN_IF_MCON_NEWDAT_Msk
#define CAN_IF_MCON_NEWDAT_Msk
Definition: NUC472_442.h:1589
CAN_IF_DAT_A1_DATA1_Pos
#define CAN_IF_DAT_A1_DATA1_Pos
Definition: NUC472_442.h:1618
CAN_IF_MCON_DLC_Msk
#define CAN_IF_MCON_DLC_Msk
Definition: NUC472_442.h:1616
CAN_IF_ARB2_DIR_Msk
#define CAN_IF_ARB2_DIR_Msk
Definition: NUC472_442.h:1583
CAN_IF_CMASK_CLRINTPND_Msk
#define CAN_IF_CMASK_CLRINTPND_Msk
Definition: NUC472_442.h:1550
CAN_IF_MCON_TXIE_Msk
#define CAN_IF_MCON_TXIE_Msk
Definition: NUC472_442.h:1601
CAN_TEST_LBACK_Msk
#define CAN_TEST_LBACK_Msk
Definition: NUC472_442.h:1520
CAN_BTIME_BRP_Msk
#define CAN_BTIME_BRP_Msk
Definition: NUC472_442.h:1508
CAN_IF_MCON_UMASK_Msk
#define CAN_IF_MCON_UMASK_Msk
Definition: NUC472_442.h:1598
CAN_BTIME_SJW_Pos
#define CAN_BTIME_SJW_Pos
Definition: NUC472_442.h:1504
CAN_STATUS_LEC_Msk
#define CAN_STATUS_LEC_Msk
Definition: NUC472_442.h:1487
CAN_IF_ARB2_XTD_Msk
#define CAN_IF_ARB2_XTD_Msk
Definition: NUC472_442.h:1580
CAN_IF_CMASK_CONTROL_Msk
#define CAN_IF_CMASK_CONTROL_Msk
Definition: NUC472_442.h:1547
CAN_IF_CMASK_ARB_Msk
#define CAN_IF_CMASK_ARB_Msk
Definition: NUC472_442.h:1544
CAN_IF_DAT_B1_DATA4_Msk
#define CAN_IF_DAT_B1_DATA4_Msk
Definition: NUC472_442.h:1634
CAN_IF_DAT_B2_DATA7_Pos
#define CAN_IF_DAT_B2_DATA7_Pos
Definition: NUC472_442.h:1636
CAN_CON_INIT_Msk
#define CAN_CON_INIT_Msk
Definition: NUC472_442.h:1469
CAN_IF_ARB2_ID_Msk
#define CAN_IF_ARB2_ID_Msk
Definition: NUC472_442.h:1586
CAN_STATUS_RXOK_Msk
#define CAN_STATUS_RXOK_Msk
Definition: NUC472_442.h:1481
CAN_IF_DAT_A1_DATA1_Msk
#define CAN_IF_DAT_A1_DATA1_Msk
Definition: NUC472_442.h:1619
CAN_TEST_BASIC_Msk
#define CAN_TEST_BASIC_Msk
Definition: NUC472_442.h:1526
CAN_IF_DAT_B1_DATA5_Pos
#define CAN_IF_DAT_B1_DATA5_Pos
Definition: NUC472_442.h:1630
CAN_IF_DAT_A1_DATA0_Msk
#define CAN_IF_DAT_A1_DATA0_Msk
Definition: NUC472_442.h:1622
CAN_IF_ARB2_DIR_Pos
#define CAN_IF_ARB2_DIR_Pos
Definition: NUC472_442.h:1582
CAN_IF_DAT_A2_DATA3_Pos
#define CAN_IF_DAT_A2_DATA3_Pos
Definition: NUC472_442.h:1624
CAN_IF_CMASK_TXRQSTNEWDAT_Msk
#define CAN_IF_CMASK_TXRQSTNEWDAT_Msk
Definition: NUC472_442.h:1553
CAN_BTIME_TSEG2_Pos
#define CAN_BTIME_TSEG2_Pos
Definition: NUC472_442.h:1498
CAN_IF_DAT_A2_DATA3_Msk
#define CAN_IF_DAT_A2_DATA3_Msk
Definition: NUC472_442.h:1625
CAN_BTIME_TSEG1_Pos
#define CAN_BTIME_TSEG1_Pos
Definition: NUC472_442.h:1501
CAN_CON_TEST_Msk
#define CAN_CON_TEST_Msk
Definition: NUC472_442.h:1451
CAN_IF_MCON_RXIE_Msk
#define CAN_IF_MCON_RXIE_Msk
Definition: NUC472_442.h:1604
CAN_IF_DAT_B1_DATA5_Msk
#define CAN_IF_DAT_B1_DATA5_Msk
Definition: NUC472_442.h:1631
CAN_BTIME_TSEG2_Msk
#define CAN_BTIME_TSEG2_Msk
Definition: NUC472_442.h:1499
CAN_IF_ARB2_MSGVAL_Msk
#define CAN_IF_ARB2_MSGVAL_Msk
Definition: NUC472_442.h:1577
CAN_IF_CMASK_WRRD_Msk
#define CAN_IF_CMASK_WRRD_Msk
Definition: NUC472_442.h:1538
CAN_IF_CMASK_MASK_Msk
#define CAN_IF_CMASK_MASK_Msk
Definition: NUC472_442.h:1541
CAN_IF_DAT_A2_DATA2_Msk
#define CAN_IF_DAT_A2_DATA2_Msk
Definition: NUC472_442.h:1628
CAN_IF_CMASK_DATAA_Msk
#define CAN_IF_CMASK_DATAA_Msk
Definition: NUC472_442.h:1556
CAN_Close
void CAN_Close(CAN_T *tCAN)
The function is used to disable all CAN interrupt.
Definition: can.c:575
CAN_SetRxMsg
int32_t CAN_SetRxMsg(CAN_T *tCAN, uint32_t u32MsgNum, uint32_t u32IDType, uint32_t u32ID)
The function is used to configure a receive message object.
Definition: can.c:729
STR_CANMSG_T::Data
uint8_t Data[8]
Definition: can.h:59
CAN_SetTxMsg
int32_t CAN_SetTxMsg(CAN_T *tCAN, uint32_t u32MsgNum, STR_CANMSG_T *pCanMsg)
The function is used to configure a transmit object.
Definition: can.c:614
CAN_SetBaudRate
uint32_t CAN_SetBaudRate(CAN_T *tCAN, uint32_t u32BaudRate)
The function is used to set bus timing parameter according current clock and target baud-rate.
Definition: can.c:479
CAN_TriggerTxMsg
int32_t CAN_TriggerTxMsg(CAN_T *tCAN, uint32_t u32MsgNum)
Set transmit request bit.
Definition: can.c:670
CAN_Receive
int32_t CAN_Receive(CAN_T *tCAN, uint32_t u32MsgNum, STR_CANMSG_T *pCanMsg)
Gets the message, if received.
Definition: can.c:819
STR_CANMSG_T::DLC
uint8_t DLC
Definition: can.h:58
STR_CANMSG_T::FrameType
uint32_t FrameType
Definition: can.h:56
CAN_DisableInt
void CAN_DisableInt(CAN_T *tCAN, uint32_t u32Mask)
Disable CAN interrupt.
Definition: can.c:707
CAN_EnableInt
void CAN_EnableInt(CAN_T *tCAN, uint32_t u32Mask)
Enable CAN interrupt.
Definition: can.c:688
CAN_CLR_INT_PENDING_BIT
void CAN_CLR_INT_PENDING_BIT(CAN_T *tCAN, uint8_t u32MsgNum)
Clear interrupt pending bit.
Definition: can.c:839
CAN_Open
uint32_t CAN_Open(CAN_T *tCAN, uint32_t u32BaudRate, uint32_t u32Mode)
The function is sets bus timing parameter according current clock and target baud-rate....
Definition: can.c:589
CAN_SetMultiRxMsg
int32_t CAN_SetMultiRxMsg(CAN_T *tCAN, uint32_t u32MsgNum, uint32_t u32MsgCount, uint32_t u32IDType, uint32_t u32ID)
The function is used to configure several receive message objects.
Definition: can.c:758
STR_CANMSG_T::Id
uint32_t Id
Definition: can.h:57
STR_CANMSG_T::IdType
uint32_t IdType
Definition: can.h:55
CAN_Transmit
int32_t CAN_Transmit(CAN_T *tCAN, uint32_t u32MsgNum, STR_CANMSG_T *pCanMsg)
Send CAN message.
Definition: can.c:793
CAN_BASIC_MODE
@ CAN_BASIC_MODE
Definition: can.h:79
CAN_EXT_ID
@ CAN_EXT_ID
Definition: can.h:38
CAN_STD_ID
@ CAN_STD_ID
Definition: can.h:37
CLK_GetPCLKFreq
uint32_t CLK_GetPCLKFreq(void)
This function get PCLK frequency. The frequency unit is Hz.
Definition: clk.c:104
CAN_IF_T::DAT_B1
__IO uint32_t DAT_B1
Definition: NUC472_442.h:1105
CAN_T::NDAT2
__IO uint32_t NDAT2
Definition: NUC472_442.h:1353
CAN_IF_T::DAT_B2
__IO uint32_t DAT_B2
Definition: NUC472_442.h:1119
CAN_IF_T::DAT_A2
__IO uint32_t DAT_A2
Definition: NUC472_442.h:1091
CAN_T::IF
__IO CAN_IF_T IF[2]
Definition: NUC472_442.h:1295
CAN_IF_T::CREQ
__IO uint32_t CREQ
Definition: NUC472_442.h:868
CAN_IF_T::CMASK
__IO uint32_t CMASK
Definition: NUC472_442.h:931
TRUE
#define TRUE
Boolean true, define to use in API parameters or return value.
Definition: NUC472_442.h:29021
FALSE
#define FALSE
Boolean false, define to use in API parameters or return value.
Definition: NUC472_442.h:29022
CAN_T::CON
__IO uint32_t CON
Definition: NUC472_442.h:1156
CAN_IF_T::MCON
__IO uint32_t MCON
Definition: NUC472_442.h:1063
CAN_T::BTIME
__IO uint32_t BTIME
Definition: NUC472_442.h:1229
CAN_IF_T::ARB1
__IO uint32_t ARB1
Definition: NUC472_442.h:978
CAN_IF_T::ARB2
__IO uint32_t ARB2
Definition: NUC472_442.h:1006
CAN_T::TEST
__IO uint32_t TEST
Definition: NUC472_442.h:1278
CAN_T::BRPE
__IO uint32_t BRPE
Definition: NUC472_442.h:1291
CAN_T::STATUS
__IO uint32_t STATUS
Definition: NUC472_442.h:1188
CAN_IF_T::DAT_A1
__IO uint32_t DAT_A1
Definition: NUC472_442.h:1077
CAN_T
Definition: NUC472_442.h:1125
STR_CANMSG_T
Definition: can.h:54
SystemCoreClock
uint32_t SystemCoreClock
Definition: system_NUC472_442.c:17
SystemCoreClockUpdate
void SystemCoreClockUpdate(void)
Updates the SystemCoreClock with current core Clock retrieved from CPU registers.
Definition: system_NUC472_442.c:26