26 static uint8_t gu8LockCanIf[3ul][2ul] = {0ul};
28 static uint8_t gu8LockCanIf[2ul][2ul] = {0ul};
29 #elif defined(CAN0) || defined(CAN) 30 static uint8_t gu8LockCanIf[1ul][2ul] = {0ul};
33 #define RETRY_COUNTS (0x10000000ul) 36 #define TSEG1_MAX 16ul 40 #define BRP_MAX 1024ul 45 #define DEBUG_PRINTF(...) 47 static uint32_t LockIF(
CAN_T *tCAN);
48 static uint32_t LockIF_TL(
CAN_T *tCAN);
49 static void ReleaseIF(
CAN_T *tCAN, uint32_t u32IfNo);
50 static int can_update_spt(
int sampl_pt,
int tseg,
int *tseg1,
int *tseg2);
61 static 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;
140 static 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)
166 static 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;
200 static 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);
318 uint32_t u32Tseg1, u32Tseg2;
325 return (
SystemCoreClock / (u32Bpr + 1ul) / (u32Tseg1 + u32Tseg2 + 3ul));
344 tCAN->
TEST = u8TestMask;
371 return (u8MsgObj < 16ul ? tCAN->NDAT1 & (1ul << u8MsgObj) : tCAN->
NDAT2 & (1ul << (u8MsgObj - 16ul)));
400 tCAN->
IF[0].
ARB2 = (((pCanMsg->
Id) & 0x7FFul) << 2ul) ;
405 tCAN->
IF[0].
ARB1 = (pCanMsg->
Id) & 0xFFFFul;
420 tCAN->
IF[0].
DAT_A1 = (uint16_t)((uint16_t)((uint16_t)pCanMsg->
Data[1] << 8) | pCanMsg->
Data[0]);
421 tCAN->
IF[0].
DAT_A2 = (uint16_t)((uint16_t)((uint16_t)pCanMsg->
Data[3] << 8) | pCanMsg->
Data[2]);
422 tCAN->
IF[0].
DAT_B1 = (uint16_t)((uint16_t)((uint16_t)pCanMsg->
Data[5] << 8) | pCanMsg->
Data[4]);
423 tCAN->
IF[0].
DAT_B2 = (uint16_t)((uint16_t)((uint16_t)pCanMsg->
Data[7] << 8) | pCanMsg->
Data[6]);
436 for(i = 0ul; i < 0xFFFFFul; i++)
493 pCanMsg->
Id = (tCAN->
IF[1].
ARB2 >> 2) & 0x07FFul;
500 pCanMsg->
Id = (tCAN->
IF[1].
ARB2 & 0x1FFFul) << 16;
501 pCanMsg->
Id |= (uint32_t)tCAN->
IF[1].
ARB1;
538 int32_t
CAN_SetRxMsgObjAndMsk(
CAN_T *tCAN, uint8_t u8MsgObj, uint8_t u8idType, uint32_t u32id, uint32_t u32idmask, uint8_t u8singleOrFifoLast)
541 uint32_t u32MsgIfNum;
544 if((u32MsgIfNum = LockIF_TL(tCAN)) == 2ul)
556 tCAN->
IF[u32MsgIfNum].
ARB1 = 0ul;
561 tCAN->
IF[u32MsgIfNum].
ARB1 = u32id & 0xFFFFul;
565 tCAN->
IF[u32MsgIfNum].
MASK1 = (u32idmask & 0xFFFFul);
566 tCAN->
IF[u32MsgIfNum].
MASK2 = (u32idmask >> 16) & 0xFFFFul;
570 if(u8singleOrFifoLast)
584 tCAN->
IF[u32MsgIfNum].
CREQ = 1ul + u8MsgObj;
585 ReleaseIF(tCAN, u32MsgIfNum);
608 int32_t
CAN_SetRxMsgObj(
CAN_T *tCAN, uint8_t u8MsgObj, uint8_t u8idType, uint32_t u32id, uint8_t u8singleOrFifoLast)
611 uint32_t u32MsgIfNum;
614 if((u32MsgIfNum = LockIF_TL(tCAN)) == 2ul)
626 tCAN->
IF[u32MsgIfNum].
ARB1 = 0ul;
631 tCAN->
IF[u32MsgIfNum].
ARB1 = u32id & 0xFFFFul;
637 if(u8singleOrFifoLast)
651 tCAN->
IF[u32MsgIfNum].
CREQ = 1ul + u8MsgObj;
652 ReleaseIF(tCAN, u32MsgIfNum);
674 uint32_t u32MsgIfNum;
683 if((u32MsgIfNum = LockIF_TL(tCAN)) == 2ul)
700 tCAN->
IF[u32MsgIfNum].
CREQ = 1ul + u8MsgObj;
717 pCanMsg->
Id = (((tCAN->
IF[u32MsgIfNum].
ARB2) & 0x1FFFul) << 16) | tCAN->
IF[u32MsgIfNum].
ARB1;
730 ReleaseIF(tCAN, u32MsgIfNum);
751 long best_error = 1000000000, error = 0;
752 int best_tseg = 0, best_brp = 0, brp = 0;
753 int tsegall, tseg = 0, tseg1 = 0, tseg2 = 0;
754 int spt_error = 1000, spt = 0, sampl_pt;
755 uint64_t clock_freq = (uint64_t)0, u64PCLK_DIV = (uint64_t)1;
756 uint32_t sjw = (uint32_t)1;
761 if((tCAN ==
CAN0) || (tCAN ==
CAN2))
764 u64PCLK_DIV = (uint64_t)(1 << u64PCLK_DIV);
766 else if(tCAN ==
CAN1)
769 u64PCLK_DIV = (uint64_t)(1 << u64PCLK_DIV);
774 if(u32BaudRate >= (uint32_t)1000000)
776 u32BaudRate = (uint32_t)1000000;
780 if (u32BaudRate > (uint32_t)800000)
784 else if (u32BaudRate > (uint32_t)500000)
794 for (tseg = (TSEG1_MAX + TSEG2_MAX) * 2ul + 1ul; tseg >= (TSEG1_MIN + TSEG2_MIN) * 2ul; tseg--)
796 tsegall = 1ul + tseg / 2ul;
798 brp = clock_freq / (tsegall * u32BaudRate) + tseg % 2;
800 brp = (brp / BRP_INC) * BRP_INC;
802 if ((brp < BRP_MIN) || (brp > BRP_MAX))
806 rate = clock_freq / (brp * tsegall);
808 error = u32BaudRate - rate;
815 if (error > best_error)
822 spt = can_update_spt(sampl_pt, tseg / 2, &tseg1, &tseg2);
823 error = sampl_pt - spt;
828 if (error > spt_error)
834 best_tseg = tseg / 2;
843 spt = can_update_spt(sampl_pt, best_tseg, &tseg1, &tseg2);
858 u32BaudRate = clock_freq / (best_brp * (tseg1 + tseg2 + 1));
862 tCAN->
BRPE = ((uint32_t)(best_brp - 1ul) >> 6) & 0x0Ful;
900 uint32_t u32CurrentBitRate;
912 return u32CurrentBitRate;
931 uint32_t u32MsgIfNum;
933 if((u32MsgIfNum = LockIF_TL(tCAN)) == 2ul)
946 tCAN->
IF[u32MsgIfNum].
ARB1 = 0ul;
952 tCAN->
IF[u32MsgIfNum].
ARB1 = (pCanMsg->
Id) & 0xFFFFul;
953 tCAN->
IF[u32MsgIfNum].
ARB2 = ((pCanMsg->
Id) & 0x1FFF0000ul) >> 16 |
966 tCAN->
IF[u32MsgIfNum].
DAT_A1 = (uint16_t)((uint16_t)(((uint16_t)pCanMsg->
Data[1] << 8)) | pCanMsg->
Data[0]);
967 tCAN->
IF[u32MsgIfNum].
DAT_A2 = (uint16_t)((uint16_t)(((uint16_t)pCanMsg->
Data[3] << 8)) | pCanMsg->
Data[2]);
968 tCAN->
IF[u32MsgIfNum].
DAT_B1 = (uint16_t)((uint16_t)(((uint16_t)pCanMsg->
Data[5] << 8)) | pCanMsg->
Data[4]);
969 tCAN->
IF[u32MsgIfNum].
DAT_B2 = (uint16_t)((uint16_t)(((uint16_t)pCanMsg->
Data[7] << 8)) | pCanMsg->
Data[6]);
972 tCAN->
IF[u32MsgIfNum].
CREQ = 1ul + u32MsgNum;
974 ReleaseIF(tCAN, u32MsgIfNum);
993 uint32_t u32MsgIfNum;
995 if((u32MsgIfNum = LockIF_TL(tCAN)) == 2ul)
1007 tCAN->
IF[u32MsgIfNum].
CREQ = 1ul + u32MsgNum;
1014 tCAN->
IF[u32MsgIfNum].
CREQ = 1ul + u32MsgNum;
1016 ReleaseIF(tCAN, u32MsgIfNum);
1076 int32_t rev = (int32_t)
TRUE;
1077 uint32_t u32TimeOutCount = 0ul;
1081 if(++u32TimeOutCount >= RETRY_COUNTS)
1083 rev = (int32_t)(
FALSE);
1113 int32_t rev = (int32_t)
TRUE;
1114 uint32_t u32TimeOutCount = 0ul;
1118 if(++u32TimeOutCount >= RETRY_COUNTS)
1120 rev = (int32_t)
FALSE;
1150 int32_t rev = (int32_t)
TRUE;
1152 uint32_t u32TimeOutCount;
1153 uint32_t u32EOB_Flag = 0ul;
1155 for(i = 1ul; i < u32MsgCount; i++)
1157 u32TimeOutCount = 0ul;
1159 u32MsgNum += (i - 1ul);
1161 if(i == u32MsgCount)
1169 while(
CAN_SetRxMsgObj(tCAN, (uint8_t)u32MsgNum, (uint8_t)u32IDType, u32ID, (uint8_t)u32EOB_Flag) == (int32_t)
FALSE)
1171 if(++u32TimeOutCount >= RETRY_COUNTS)
1173 rev = (int32_t)
FALSE;
1201 int32_t rev = (int32_t)
TRUE;
1214 rev = (int32_t)
FALSE;
1240 int32_t rev = (int32_t)
TRUE;
1268 uint32_t u32MsgIfNum;
1270 if((u32MsgIfNum = LockIF_TL(tCAN)) == 2ul)
1279 tCAN->
IF[u32MsgIfNum].
CREQ = 1ul + u32MsgNum;
1281 ReleaseIF(tCAN, u32MsgIfNum);
#define CAN_IF_CMASK_DATAB_Msk
#define CAN_IF_DAT_B1_DATA4_Msk
#define CAN_IF_CMASK_ARB_Msk
#define CAN_IF_MCON_DLC_Msk
#define CLK_PCLKDIV_APB1DIV_Msk
#define CAN_IF_DAT_B2_DATA6_Msk
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.
#define CAN_TEST_SILENT_Msk
int32_t CAN_Receive(CAN_T *tCAN, uint32_t u32MsgNum, STR_CANMSG_T *pCanMsg)
Gets the message, if received.
#define CAN_IF_MCON_RXIE_Msk
#define CAN_IF_DAT_A2_DATA2_Msk
#define CAN_IF_CMASK_DATAA_Msk
void CAN_DisableInt(CAN_T *tCAN, uint32_t u32Mask)
Disable CAN interrupt.
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_SetRxMsgObj(CAN_T *tCAN, uint8_t u8MsgObj, uint8_t u8idType, uint32_t u32id, uint8_t u8singleOrFifoLast)
Set Rx message object.
#define CAN_STATUS_RXOK_Msk
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.
#define CAN_IF_MCON_EOB_Msk
#define CAN_IF_CMASK_CLRINTPND_Msk
int32_t CAN_Transmit(CAN_T *tCAN, uint32_t u32MsgNum, STR_CANMSG_T *pCanMsg)
Send CAN message.
void CAN_EnterInitMode(CAN_T *tCAN, uint8_t u8Mask)
Enter initialization mode.
#define TRUE
Boolean true, define to use in API parameters or return value.
#define CLK_PCLKDIV_APB0DIV_Msk
void CAN_CLR_INT_PENDING_BIT(CAN_T *tCAN, uint8_t u32MsgNum)
Clear interrupt pending bit.
int32_t CAN_SetTxMsg(CAN_T *tCAN, uint32_t u32MsgNum, STR_CANMSG_T *pCanMsg)
The function is used to configure a transmit object.
NuMicro peripheral access layer header file.
#define CAN_IF_ARB2_MSGVAL_Msk
#define CAN_BTIME_TSEG1_Pos
int32_t CAN_BasicSendMsg(CAN_T *tCAN, STR_CANMSG_T *pCanMsg)
Send CAN message in BASIC mode of test mode.
void CAN_Close(CAN_T *tCAN)
The function is used to disable all CAN interrupt.
#define FALSE
Boolean false, define to use in API parameters or return value.
#define CAN_IF_CMASK_TXRQSTNEWDAT_Msk
#define CAN_IF_ARB2_ID_Msk
#define CAN_BTIME_TSEG2_Pos
uint32_t CAN_Open(CAN_T *tCAN, uint32_t u32BaudRate, uint32_t u32Mode)
Set CAN operation mode and target baud-rate.
#define CAN_IF_CMASK_WRRD_Msk
#define CAN_BTIME_SJW_Pos
#define CAN_TEST_LBACK_Msk
void CAN_LeaveInitMode(CAN_T *tCAN)
Leave initialization mode.
#define CAN_IF_ARB2_DIR_Msk
#define CAN_BTIME_TSEG2_Msk
void CAN_LeaveTestMode(CAN_T *tCAN)
Leave the test mode.
#define CAN_IF_DAT_A1_DATA1_Pos
int32_t CAN_TriggerTxMsg(CAN_T *tCAN, uint32_t u32MsgNum)
Set transmit request bit.
#define CAN_IF_DAT_A1_DATA1_Msk
#define CAN_IF_DAT_A2_DATA3_Pos
#define CAN_IF_DAT_B2_DATA7_Pos
#define CAN_IF_ARB2_XTD_Msk
#define CLK_PCLKDIV_APB1DIV_Pos
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.
void SystemCoreClockUpdate(void)
Updates the SystemCoreClock with current core Clock retrieved from cpu registers.
#define CAN_IF_CREQ_BUSY_Msk
uint32_t CAN_IsNewDataReceived(CAN_T *tCAN, uint8_t u8MsgObj)
Get the waiting status of a received message.
#define CAN_IF_MCON_NEWDAT_Msk
#define CAN_IF_MCON_UMASK_Msk
#define CAN_IF_DAT_A2_DATA3_Msk
void CAN_EnableInt(CAN_T *tCAN, uint32_t u32Mask)
Enable CAN interrupt.
void CAN_EnterTestMode(CAN_T *tCAN, uint8_t u8TestMask)
Switch the CAN into test mode.
#define CAN_IF_CMASK_CONTROL_Msk
void CAN_WaitMsg(CAN_T *tCAN)
Wait message into message buffer in basic mode.
#define CAN_IF_DAT_B1_DATA5_Msk
uint32_t CAN_SetBaudRate(CAN_T *tCAN, uint32_t u32BaudRate)
Set bus baud-rate.
#define CAN_STATUS_LEC_Msk
#define CAN_BTIME_BRP_Msk
int32_t CAN_BasicReceiveMsg(CAN_T *tCAN, STR_CANMSG_T *pCanMsg)
Get a message information in BASIC mode.
uint32_t CAN_GetCANBitRate(CAN_T *tCAN)
Get current bit rate.
#define CAN_IF_CMASK_MASK_Msk
#define CAN_IF_DAT_B1_DATA5_Pos
#define CAN_IF_ARB2_DIR_Pos
#define CAN_IF_MCON_TXIE_Msk
#define CAN_TEST_BASIC_Msk
#define CAN_STATUS_TXOK_Msk
int32_t CAN_ReadMsgObj(CAN_T *tCAN, uint8_t u8MsgObj, uint8_t u8Release, STR_CANMSG_T *pCanMsg)
Gets the message.
#define CAN_IF_DAT_B2_DATA7_Msk
#define CAN_IF_DAT_A1_DATA0_Msk
#define CAN_BTIME_TSEG1_Msk