41static uint32_t GetFreeIF(
CAN_T *tCAN);
45#define DEBUG_PRINTF(...)
55static uint32_t GetFreeIF(
CAN_T *tCAN)
74void CAN_EnterInitMode(
CAN_T *tCAN)
88void CAN_LeaveInitMode(
CAN_T *tCAN)
95 if(u32TimeOutCount == 0)
break;
107void CAN_WaitMsg(
CAN_T *tCAN)
115 DEBUG_PRINTF(
"New Data IN\n");
119 DEBUG_PRINTF(
"Rx OK\n");
123 DEBUG_PRINTF(
"Error\n");
134uint32_t CAN_GetCANBitRate(
CAN_T *tCAN)
136 uint8_t u8Tseg1,u8Tseg2;
159void CAN_EnterTestMode(
CAN_T *tCAN, uint8_t u8TestMask)
162 tCAN->
TEST = u8TestMask;
172void CAN_LeaveTestMode(
CAN_T *tCAN)
176 tCAN->
CON &= (~CAN_CON_TEST_Msk);
187uint32_t CAN_IsNewDataReceived(
CAN_T *tCAN, uint8_t u8MsgObj)
189 return (u8MsgObj < 16 ? tCAN->NDAT1 & (1 << u8MsgObj) : tCAN->
NDAT2 & (1 << (u8MsgObj-16)));
212 if(i > u32TimeOutCount)
return -1;
215 tCAN->
STATUS &= (~CAN_STATUS_TXOK_Msk);
223 tCAN->
IF[0].
ARB2 = (((pCanMsg->
Id)&0x7FF)<<2) ;
228 tCAN->
IF[0].
ARB1 = (pCanMsg->
Id)&0xFFFF;
236 tCAN->
IF[0].
ARB2 &= (~CAN_IF_ARB2_DIR_Msk);
238 tCAN->
IF[0].
MCON = (tCAN->
IF[0].
MCON & (~CAN_IF_MCON_DLC_Msk)) | pCanMsg->
DLC;
245 tCAN->
IF[0].
CREQ &= (~CAN_IF_CREQ_BUSY_Msk);
248 DEBUG_PRINTF(
"Cannot clear busy for sending ...\n");
254 for ( i=0; i<0xFFFFF; i++)
261 DEBUG_PRINTF(
"Cannot send out...\n");
286 tCAN->
STATUS &= (~CAN_STATUS_RXOK_Msk);
297 pCanMsg->
Id = (tCAN->
IF[1].
ARB2 >> 2) & 0x07FF;
304 pCanMsg->
Id = (tCAN->
IF[1].
ARB2 & 0x1FFF)<<16;
305 pCanMsg->
Id |= (uint32_t)tCAN->
IF[1].
ARB1;
340int32_t CAN_SetRxMsgObj(
CAN_T *tCAN, uint8_t u8MsgObj, uint8_t u8idType, uint32_t u32id, uint8_t u8singleOrFifoLast)
342 uint8_t u8MsgIfNum=0;
344 if ((u8MsgIfNum = GetFreeIF(tCAN)) == 2)
354 tCAN->
IF[u8MsgIfNum].
ARB1 = 0;
359 tCAN->
IF[u8MsgIfNum].
ARB1 = u32id & 0xFFFF;
364 if(u8singleOrFifoLast)
367 tCAN->
IF[u8MsgIfNum].
MCON &= (~CAN_IF_MCON_EOB_Msk);
374 tCAN->
IF[u8MsgIfNum].
CREQ = 1 + u8MsgObj;
394int32_t CAN_ReadMsgObj(
CAN_T *tCAN, uint8_t u8MsgObj, uint8_t u8Release,
STR_CANMSG_T* pCanMsg)
399 if (!CAN_IsNewDataReceived(tCAN, u8MsgObj))
404 tCAN->
STATUS &= (~CAN_STATUS_RXOK_Msk);
415 tCAN->
IF[1].
CREQ = 1 + u8MsgObj;
419 if(u32TimeOutCount == 0)
436 pCanMsg->
Id = (((tCAN->
IF[1].
ARB2) & 0x1FFF)<<16) | tCAN->
IF[1].
ARB1;
452static int can_update_spt(
int sampl_pt,
int tseg,
int *tseg1,
int *tseg2)
454 *tseg2 = tseg + 1 - (sampl_pt * (tseg + 1)) / 1000;
455 if (*tseg2 < TSEG2_MIN)
457 if (*tseg2 > TSEG2_MAX)
459 *tseg1 = tseg - *tseg2;
460 if (*tseg1 > TSEG1_MAX)
463 *tseg2 = tseg - *tseg1;
465 return 1000 * (tseg + 1 - *tseg2) / (tseg + 1);
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;
489 CAN_EnterInitMode(tCAN);
495 if(u32BaudRate >= 1000000)
496 u32BaudRate = 1000000;
499 if (u32BaudRate > 800000)
501 else if (u32BaudRate > 500000)
507 for (tseg = (TSEG1_MAX + TSEG2_MAX) * 2 + 1; tseg >= (TSEG1_MIN + TSEG2_MIN) * 2; tseg--)
509 tsegall = 1 + tseg / 2;
511 brp = clock_freq / (tsegall * u32BaudRate) + tseg % 2;
513 brp = (brp / BRP_INC) * BRP_INC;
515 if ((brp < BRP_MIN) || (brp > BRP_MAX))
517 rate = clock_freq / (brp * tsegall);
519 error = u32BaudRate - rate;
524 if (error > best_error)
529 spt = can_update_spt(sampl_pt, tseg / 2, &tseg1, &tseg2);
530 error = sampl_pt - spt;
533 if (error > spt_error)
537 best_tseg = tseg / 2;
544 spt = can_update_spt(sampl_pt, best_tseg, &tseg1, &tseg2);
555 u32BaudRate = clock_freq / (best_brp * (tseg1 + tseg2 + 1));
559 tCAN->
BRPE = ((best_brp - 1) >> 6) & 0x0F;
563 CAN_LeaveInitMode(tCAN);
591 uint32_t u32CurrentBitRate;
598 tCAN->
CON &= ~CAN_CON_TEST_Msk;
600 return u32CurrentBitRate;
616 uint8_t u8MsgIfNum=0;
619 while((u8MsgIfNum = GetFreeIF(tCAN)) == 2)
621 if(u32TimeOutCount == 0)
629 tCAN->
IF[u8MsgIfNum].
CMASK = 0xF3;
635 tCAN->
IF[u8MsgIfNum].
ARB1 = 0;
641 tCAN->
IF[u8MsgIfNum].
ARB1 = (pCanMsg->
Id)&0xFFFF;
649 tCAN->
IF[u8MsgIfNum].
ARB2 &= (~CAN_IF_ARB2_DIR_Msk);
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];
657 tCAN->
IF[u8MsgIfNum].
CREQ = 1 + u32MsgNum;
673 CAN_ReadMsgObj(tCAN, u32MsgNum,
TRUE, &rMsg);
675 tCAN->
IF[0].
CREQ = 1 + u32MsgNum;
690 CAN_EnterInitMode(tCAN);
696 CAN_LeaveInitMode(tCAN);
709 CAN_EnterInitMode(tCAN);
713 CAN_LeaveInitMode(tCAN);
733 while(CAN_SetRxMsgObj(tCAN, u32MsgNum, u32IDType, u32ID,
TRUE) ==
FALSE)
735 if(u32TimeOutCount == 0)
762 uint32_t u32EOB_Flag = 0;
764 for(i= 1; i <= u32MsgCount; i++)
766 if(i == u32MsgCount) u32EOB_Flag = 1;
768 while(CAN_SetRxMsgObj(tCAN, u32MsgNum, u32IDType, u32ID, u32EOB_Flag) ==
FALSE)
770 if(u32TimeOutCount == 0)
797 return (CAN_BasicSendMsg(tCAN, pCanMsg));
823 return (CAN_BasicReceiveMsg(tCAN, pCanMsg));
827 return CAN_ReadMsgObj(tCAN, u32MsgNum,
TRUE, pCanMsg);
841 uint32_t u32MsgIfNum = 0;
844 while(u32TimeOutCount > 0)
861 tCAN->
IF[u32MsgIfNum].
CREQ = 1 + u32MsgNum;
NUC472/NUC442 peripheral access layer header file. This file contains all the peripheral register's d...
#define CAN_IF_CMASK_DATAB_Msk
#define CAN_IF_DAT_B2_DATA7_Msk
#define CAN_TEST_SILENT_Msk
#define CAN_IF_CREQ_BUSY_Msk
#define CAN_IF_MCON_EOB_Msk
#define CAN_IF_DAT_B2_DATA6_Msk
#define CAN_BTIME_TSEG1_Msk
#define CAN_IF_MCON_NEWDAT_Msk
#define CAN_IF_DAT_A1_DATA1_Pos
#define CAN_IF_MCON_DLC_Msk
#define CAN_IF_ARB2_DIR_Msk
#define CAN_IF_CMASK_CLRINTPND_Msk
#define CAN_IF_MCON_TXIE_Msk
#define CAN_TEST_LBACK_Msk
#define CAN_BTIME_BRP_Msk
#define CAN_IF_MCON_UMASK_Msk
#define CAN_BTIME_SJW_Pos
#define CAN_STATUS_LEC_Msk
#define CAN_IF_ARB2_XTD_Msk
#define CAN_IF_CMASK_CONTROL_Msk
#define CAN_IF_CMASK_ARB_Msk
#define CAN_IF_DAT_B1_DATA4_Msk
#define CAN_IF_DAT_B2_DATA7_Pos
#define CAN_IF_ARB2_ID_Msk
#define CAN_STATUS_RXOK_Msk
#define CAN_IF_DAT_A1_DATA1_Msk
#define CAN_TEST_BASIC_Msk
#define CAN_IF_DAT_B1_DATA5_Pos
#define CAN_IF_DAT_A1_DATA0_Msk
#define CAN_IF_ARB2_DIR_Pos
#define CAN_IF_DAT_A2_DATA3_Pos
#define CAN_IF_CMASK_TXRQSTNEWDAT_Msk
#define CAN_BTIME_TSEG2_Pos
#define CAN_IF_DAT_A2_DATA3_Msk
#define CAN_BTIME_TSEG1_Pos
#define CAN_IF_MCON_RXIE_Msk
#define CAN_IF_DAT_B1_DATA5_Msk
#define CAN_BTIME_TSEG2_Msk
#define CAN_IF_ARB2_MSGVAL_Msk
#define CAN_IF_CMASK_WRRD_Msk
#define CAN_IF_CMASK_MASK_Msk
#define CAN_IF_DAT_A2_DATA2_Msk
#define CAN_IF_CMASK_DATAA_Msk
void CAN_Close(CAN_T *tCAN)
The function is used to disable all CAN interrupt.
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.
int32_t CAN_SetTxMsg(CAN_T *tCAN, uint32_t u32MsgNum, STR_CANMSG_T *pCanMsg)
The function is used to configure a transmit object.
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.
int32_t CAN_TriggerTxMsg(CAN_T *tCAN, uint32_t u32MsgNum)
Set transmit request bit.
int32_t CAN_Receive(CAN_T *tCAN, uint32_t u32MsgNum, STR_CANMSG_T *pCanMsg)
Gets the message, if received.
void CAN_DisableInt(CAN_T *tCAN, uint32_t u32Mask)
Disable CAN interrupt.
void CAN_EnableInt(CAN_T *tCAN, uint32_t u32Mask)
Enable CAN interrupt.
void CAN_CLR_INT_PENDING_BIT(CAN_T *tCAN, uint8_t u32MsgNum)
Clear interrupt pending bit.
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....
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.
int32_t CAN_Transmit(CAN_T *tCAN, uint32_t u32MsgNum, STR_CANMSG_T *pCanMsg)
Send CAN message.
uint32_t CLK_GetPCLKFreq(void)
This function get PCLK frequency. The frequency unit is Hz.
#define TRUE
Boolean true, define to use in API parameters or return value.
#define FALSE
Boolean false, define to use in API parameters or return value.
void SystemCoreClockUpdate(void)
Updates the SystemCoreClock with current core Clock retrieved from CPU registers.