26static uint8_t gu8LockCanIf[3ul][2ul] = {0ul};
28static uint8_t gu8LockCanIf[2ul][2ul] = {0ul};
29#elif defined(CAN0) || defined(CAN)
30static uint8_t gu8LockCanIf[1ul][2ul] = {0ul};
33#define RETRY_COUNTS (0x10000000ul)
45#define DEBUG_PRINTF(...)
47static uint32_t LockIF(
CAN_T *tCAN);
48static uint32_t LockIF_TL(
CAN_T *tCAN);
49static void ReleaseIF(
CAN_T *tCAN, uint32_t u32IfNo);
50static int can_update_spt(
int sampl_pt,
int tseg,
int *tseg1,
int *tseg2);
61static uint32_t LockIF(
CAN_T *tCAN)
89 if(gu8LockCanIf[u32CanNo][0ul] == 0ul)
91 gu8LockCanIf[u32CanNo][0ul] = 1u;
103 if(u32FreeIfNo == 2ul)
107 if(gu8LockCanIf[u32CanNo][1ul] == 0ul)
109 gu8LockCanIf[u32CanNo][1ul] = 1u;
125 tCAN->
CON |= u32IntMask;
140static uint32_t LockIF_TL(
CAN_T *tCAN)
143 uint32_t u32FreeIfNo;
145 for(u32Count = 0ul; u32Count < RETRY_COUNTS; u32Count++)
147 if((u32FreeIfNo = LockIF(tCAN)) != 2ul)
166static void ReleaseIF(
CAN_T *tCAN, uint32_t u32IfNo)
179 else if(tCAN ==
CAN1)
182 else if(tCAN ==
CAN2)
193 gu8LockCanIf[u32CanNo][u32IfNo] = 0u;
196 tCAN->
CON |= u32IntMask;
200static int can_update_spt(
int sampl_pt,
int tseg,
int *tseg1,
int *tseg2)
202 *tseg2 = tseg + 1 - (sampl_pt * (tseg + 1)) / 1000;
203 if (*tseg2 < TSEG2_MIN)
211 if (*tseg2 > TSEG2_MAX)
219 *tseg1 = tseg - *tseg2;
220 if (*tseg1 > TSEG1_MAX)
223 *tseg2 = tseg - *tseg1;
229 return 1000 * (tseg + 1 - *tseg2) / (tseg + 1);
267 if(u32TimeOutCount == 0)
break;
320 uint32_t u32Tseg1, u32Tseg2;
322 uint32_t u32Clock = (uint32_t)0;
325 if((tCAN ==
CAN0) || (tCAN ==
CAN2))
329 else if(tCAN ==
CAN1)
338 return (u32Clock / (u32Bpr + 1ul) / (u32Tseg1 + u32Tseg2 + 3ul));
357 tCAN->
TEST = u8TestMask;
371 tCAN->
CON &= (~CAN_CON_TEST_Msk);
384 return (u8MsgObj < 16ul ? tCAN->NDAT1 & (1ul << u8MsgObj) : tCAN->
NDAT2 & (1ul << (u8MsgObj - 16ul)));
408 if(i > u32TimeOutCount)
return -1;
411 tCAN->
STATUS &= (~CAN_STATUS_TXOK_Msk);
417 tCAN->
IF[0].
ARB2 = (((pCanMsg->
Id) & 0x7FFul) << 2ul) ;
422 tCAN->
IF[0].
ARB1 = (pCanMsg->
Id) & 0xFFFFul;
433 tCAN->
IF[0].
ARB2 &= (~CAN_IF_ARB2_DIR_Msk);
436 tCAN->
IF[0].
MCON = (tCAN->
IF[0].
MCON & (~CAN_IF_MCON_DLC_Msk)) | pCanMsg->
DLC;
437 tCAN->
IF[0].
DAT_A1 = (uint16_t)((uint16_t)((uint16_t)pCanMsg->
Data[1] << 8) | pCanMsg->
Data[0]);
438 tCAN->
IF[0].
DAT_A2 = (uint16_t)((uint16_t)((uint16_t)pCanMsg->
Data[3] << 8) | pCanMsg->
Data[2]);
439 tCAN->
IF[0].
DAT_B1 = (uint16_t)((uint16_t)((uint16_t)pCanMsg->
Data[5] << 8) | pCanMsg->
Data[4]);
440 tCAN->
IF[0].
DAT_B2 = (uint16_t)((uint16_t)((uint16_t)pCanMsg->
Data[7] << 8) | pCanMsg->
Data[6]);
443 tCAN->
IF[0].
CREQ &= (~CAN_IF_CREQ_BUSY_Msk);
453 for(i = 0ul; i < 0xFFFFFul; i++)
499 tCAN->
STATUS &= (~CAN_STATUS_RXOK_Msk);
510 pCanMsg->
Id = (tCAN->
IF[1].
ARB2 >> 2) & 0x07FFul;
517 pCanMsg->
Id = (tCAN->
IF[1].
ARB2 & 0x1FFFul) << 16;
518 pCanMsg->
Id |= (uint32_t)tCAN->
IF[1].
ARB1;
559int32_t
CAN_SetRxMsgObjAndMsk(
CAN_T *tCAN, uint8_t u8MsgObj, uint8_t u8idType, uint32_t u32id, uint32_t u32idmask, uint8_t u8singleOrFifoLast)
562 uint32_t u32MsgIfNum;
565 if((u32MsgIfNum = LockIF_TL(tCAN)) == 2ul)
577 tCAN->
IF[u32MsgIfNum].
ARB1 = 0ul;
582 tCAN->
IF[u32MsgIfNum].
ARB1 = u32id & 0xFFFFul;
586 tCAN->
IF[u32MsgIfNum].
MASK1 = (u32idmask & 0xFFFFul);
587 tCAN->
IF[u32MsgIfNum].
MASK2 = (u32idmask >> 16) & 0xFFFFul;
591 if(u8singleOrFifoLast)
597 tCAN->
IF[u32MsgIfNum].
MCON &= (~CAN_IF_MCON_EOB_Msk);
605 tCAN->
IF[u32MsgIfNum].
CREQ = 1ul + u8MsgObj;
606 ReleaseIF(tCAN, u32MsgIfNum);
629int32_t
CAN_SetRxMsgObj(
CAN_T *tCAN, uint8_t u8MsgObj, uint8_t u8idType, uint32_t u32id, uint8_t u8singleOrFifoLast)
632 uint32_t u32MsgIfNum;
635 if((u32MsgIfNum = LockIF_TL(tCAN)) == 2ul)
647 tCAN->
IF[u32MsgIfNum].
ARB1 = 0ul;
652 tCAN->
IF[u32MsgIfNum].
ARB1 = u32id & 0xFFFFul;
658 if(u8singleOrFifoLast)
664 tCAN->
IF[u32MsgIfNum].
MCON &= (~CAN_IF_MCON_EOB_Msk);
672 tCAN->
IF[u32MsgIfNum].
CREQ = 1ul + u8MsgObj;
673 ReleaseIF(tCAN, u32MsgIfNum);
696 uint32_t u32MsgIfNum;
706 if((u32MsgIfNum = LockIF_TL(tCAN)) == 2ul)
712 tCAN->
STATUS &= (~CAN_STATUS_RXOK_Msk);
723 tCAN->
IF[u32MsgIfNum].
CREQ = 1ul + u8MsgObj;
727 if(u32TimeOutCount == 0)
729 ReleaseIF(tCAN, u32MsgIfNum);
745 pCanMsg->
Id = (((tCAN->
IF[u32MsgIfNum].
ARB2) & 0x1FFFul) << 16) | tCAN->
IF[u32MsgIfNum].
ARB1;
758 ReleaseIF(tCAN, u32MsgIfNum);
779 long best_error = 1000000000, error = 0;
780 int best_tseg = 0, best_brp = 0, brp = 0;
781 int tsegall, tseg = 0, tseg1 = 0, tseg2 = 0;
782 int spt_error = 1000, spt = 0, sampl_pt;
783 uint64_t clock_freq = (uint64_t)0, u64PCLK_DIV = (uint64_t)1;
784 uint32_t sjw = (uint32_t)1;
789 if((tCAN ==
CAN0) || (tCAN ==
CAN2))
792 u64PCLK_DIV = (uint64_t)(1 << u64PCLK_DIV);
794 else if(tCAN ==
CAN1)
797 u64PCLK_DIV = (uint64_t)(1 << u64PCLK_DIV);
802 if(u32BaudRate >= (uint32_t)1000000)
804 u32BaudRate = (uint32_t)1000000;
808 if (u32BaudRate > (uint32_t)800000)
812 else if (u32BaudRate > (uint32_t)500000)
822 for (tseg = (TSEG1_MAX + TSEG2_MAX) * 2ul + 1ul; tseg >= (TSEG1_MIN + TSEG2_MIN) * 2ul; tseg--)
824 tsegall = 1ul + tseg / 2ul;
826 brp = clock_freq / (tsegall * u32BaudRate) + tseg % 2;
828 brp = (brp / BRP_INC) * BRP_INC;
830 if ((brp < BRP_MIN) || (brp > BRP_MAX))
834 rate = clock_freq / (brp * tsegall);
836 error = u32BaudRate - rate;
843 if (error > best_error)
850 spt = can_update_spt(sampl_pt, tseg / 2, &tseg1, &tseg2);
851 error = sampl_pt - spt;
856 if (error > spt_error)
862 best_tseg = tseg / 2;
871 spt = can_update_spt(sampl_pt, best_tseg, &tseg1, &tseg2);
886 u32BaudRate = clock_freq / (best_brp * (tseg1 + tseg2 + 1));
890 tCAN->
BRPE = ((uint32_t)(best_brp - 1ul) >> 6) & 0x0Ful;
928 uint32_t u32CurrentBitRate;
940 return u32CurrentBitRate;
959 uint32_t u32MsgIfNum;
961 if((u32MsgIfNum = LockIF_TL(tCAN)) == 2ul)
974 tCAN->
IF[u32MsgIfNum].
ARB1 = 0ul;
980 tCAN->
IF[u32MsgIfNum].
ARB1 = (pCanMsg->
Id) & 0xFFFFul;
981 tCAN->
IF[u32MsgIfNum].
ARB2 = ((pCanMsg->
Id) & 0x1FFF0000ul) >> 16 |
991 tCAN->
IF[u32MsgIfNum].
ARB2 &= (~CAN_IF_ARB2_DIR_Msk);
994 tCAN->
IF[u32MsgIfNum].
DAT_A1 = (uint16_t)((uint16_t)(((uint16_t)pCanMsg->
Data[1] << 8)) | pCanMsg->
Data[0]);
995 tCAN->
IF[u32MsgIfNum].
DAT_A2 = (uint16_t)((uint16_t)(((uint16_t)pCanMsg->
Data[3] << 8)) | pCanMsg->
Data[2]);
996 tCAN->
IF[u32MsgIfNum].
DAT_B1 = (uint16_t)((uint16_t)(((uint16_t)pCanMsg->
Data[5] << 8)) | pCanMsg->
Data[4]);
997 tCAN->
IF[u32MsgIfNum].
DAT_B2 = (uint16_t)((uint16_t)(((uint16_t)pCanMsg->
Data[7] << 8)) | pCanMsg->
Data[6]);
1000 tCAN->
IF[u32MsgIfNum].
CREQ = 1ul + u32MsgNum;
1002 ReleaseIF(tCAN, u32MsgIfNum);
1023 uint32_t u32MsgIfNum;
1026 if((u32MsgIfNum = LockIF_TL(tCAN)) == 2ul)
1032 tCAN->
STATUS &= (~CAN_STATUS_TXOK_Msk);
1038 tCAN->
IF[u32MsgIfNum].
CREQ = 1ul + u32MsgNum;
1042 if(u32TimeOutCount == 0)
1044 ReleaseIF(tCAN, u32MsgIfNum);
1050 tCAN->
IF[u32MsgIfNum].
CREQ = 1ul + u32MsgNum;
1052 ReleaseIF(tCAN, u32MsgIfNum);
1112 int32_t rev = (int32_t)
TRUE;
1113 uint32_t u32TimeOutCount = 0ul;
1117 if(++u32TimeOutCount >= RETRY_COUNTS)
1119 rev = (int32_t)(
FALSE);
1149 int32_t rev = (int32_t)
TRUE;
1150 uint32_t u32TimeOutCount = 0ul;
1154 if(++u32TimeOutCount >= RETRY_COUNTS)
1156 rev = (int32_t)
FALSE;
1186 int32_t rev = (int32_t)
TRUE;
1188 uint32_t u32TimeOutCount;
1189 uint32_t u32EOB_Flag = 0ul;
1191 for(i = 1ul; i < u32MsgCount; i++)
1193 u32TimeOutCount = 0ul;
1195 u32MsgNum += (i - 1ul);
1197 if(i == u32MsgCount)
1205 while(
CAN_SetRxMsgObj(tCAN, (uint8_t)u32MsgNum, (uint8_t)u32IDType, u32ID, (uint8_t)u32EOB_Flag) == (int32_t)
FALSE)
1207 if(++u32TimeOutCount >= RETRY_COUNTS)
1209 rev = (int32_t)
FALSE;
1237 int32_t rev = (int32_t)
TRUE;
1245 if(rev < 0) rev = 0;
1251 rev = (int32_t)
FALSE;
1277 int32_t rev = (int32_t)
TRUE;
1305 uint32_t u32MsgIfNum;
1307 if((u32MsgIfNum = LockIF_TL(tCAN)) == 2ul)
1316 tCAN->
IF[u32MsgIfNum].
CREQ = 1ul + u32MsgNum;
1318 ReleaseIF(tCAN, u32MsgIfNum);
NuMicro peripheral access layer header file.
void CAN_EnterTestMode(CAN_T *tCAN, uint8_t u8TestMask)
Switch the CAN into test mode.
void CAN_Close(CAN_T *tCAN)
The function is used to disable all CAN interrupt.
int32_t CAN_BasicSendMsg(CAN_T *tCAN, STR_CANMSG_T *pCanMsg)
Send CAN message in BASIC mode of test mode.
void CAN_LeaveInitMode(CAN_T *tCAN)
Leave initialization mode.
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.
void CAN_LeaveTestMode(CAN_T *tCAN)
Leave the test mode.
void CAN_WaitMsg(CAN_T *tCAN)
Wait message into message buffer in basic mode.
int32_t CAN_SetTxMsg(CAN_T *tCAN, uint32_t u32MsgNum, STR_CANMSG_T *pCanMsg)
The function is used to configure a transmit object.
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.
int32_t CAN_ReadMsgObj(CAN_T *tCAN, uint8_t u8MsgObj, uint8_t u8Release, STR_CANMSG_T *pCanMsg)
Gets the message.
int32_t CAN_BasicReceiveMsg(CAN_T *tCAN, STR_CANMSG_T *pCanMsg)
Get a message information in BASIC mode.
int32_t CAN_SetRxMsgObj(CAN_T *tCAN, uint8_t u8MsgObj, uint8_t u8idType, uint32_t u32id, uint8_t u8singleOrFifoLast)
Set Rx message object.
uint32_t CAN_GetCANBitRate(CAN_T *tCAN)
Get current bit rate.
int32_t CAN_SetRxMsgAndMsk(CAN_T *tCAN, uint32_t u32MsgNum, uint32_t u32IDType, uint32_t u32ID, uint32_t u32IDMask)
The function is used to configure a receive message object.
uint32_t CAN_IsNewDataReceived(CAN_T *tCAN, uint8_t u8MsgObj)
Get the waiting status of a received message.
uint32_t CAN_SetBaudRate(CAN_T *tCAN, uint32_t u32BaudRate)
Set bus baud-rate.
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)
Set CAN operation mode and target baud-rate.
int32_t CAN_SetRxMsgObjAndMsk(CAN_T *tCAN, uint8_t u8MsgObj, uint8_t u8idType, uint32_t u32id, uint32_t u32idmask, uint8_t u8singleOrFifoLast)
Set Rx message object, include ID mask.
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.
void CAN_EnterInitMode(CAN_T *tCAN, uint8_t u8Mask)
Enter initialization mode.
int32_t CAN_Transmit(CAN_T *tCAN, uint32_t u32MsgNum, STR_CANMSG_T *pCanMsg)
Send CAN message.
uint32_t CLK_GetPCLK1Freq(void)
Get PCLK1 frequency.
uint32_t CLK_GetPCLK0Freq(void)
Get PCLK0 frequency.
#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.
#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 CLK_PCLKDIV_APB1DIV_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 CLK_PCLKDIV_APB1DIV_Pos
#define CLK_PCLKDIV_APB0DIV_Msk
#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 SystemCoreClockUpdate(void)
Updates the SystemCoreClock with current core Clock retrieved from cpu registers.