mbed library sources. Supersedes mbed-src.

Fork of mbed-dev by mbed official

Committer:
<>
Date:
Fri Oct 28 11:17:30 2016 +0100
Revision:
149:156823d33999
This updates the lib to the mbed lib v128

NOTE: This release includes a restructuring of the file and directory locations and thus some
include paths in your code may need updating accordingly.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
<> 149:156823d33999 1 /**************************************************************************//**
<> 149:156823d33999 2 * @file can.c
<> 149:156823d33999 3 * @version V2.00
<> 149:156823d33999 4 * $Revision: 8 $
<> 149:156823d33999 5 * $Date: 15/08/11 10:26a $
<> 149:156823d33999 6 * @brief M451 series CAN driver source file
<> 149:156823d33999 7 *
<> 149:156823d33999 8 * @note
<> 149:156823d33999 9 * Copyright (C) 2014~2015 Nuvoton Technology Corp. All rights reserved.
<> 149:156823d33999 10 *****************************************************************************/
<> 149:156823d33999 11 #include "M451Series.h"
<> 149:156823d33999 12
<> 149:156823d33999 13 /** @addtogroup Standard_Driver Standard Driver
<> 149:156823d33999 14 @{
<> 149:156823d33999 15 */
<> 149:156823d33999 16
<> 149:156823d33999 17 /** @addtogroup CAN_Driver CAN Driver
<> 149:156823d33999 18 @{
<> 149:156823d33999 19 */
<> 149:156823d33999 20
<> 149:156823d33999 21 /** @addtogroup CAN_EXPORTED_FUNCTIONS CAN Exported Functions
<> 149:156823d33999 22 @{
<> 149:156823d33999 23 */
<> 149:156823d33999 24
<> 149:156823d33999 25 /// @cond HIDDEN_SYMBOLS
<> 149:156823d33999 26
<> 149:156823d33999 27 #if defined(CAN1)
<> 149:156823d33999 28 static uint8_t gu8LockCanIf[2][2] = {0}; // The chip has two CANs.
<> 149:156823d33999 29 #elif defined(CAN0) || defined(CAN)
<> 149:156823d33999 30 static uint8_t gu8LockCanIf[1][2] = {0}; // The chip only has one CAN.
<> 149:156823d33999 31 #endif
<> 149:156823d33999 32
<> 149:156823d33999 33 #define RETRY_COUNTS (0x10000000)
<> 149:156823d33999 34
<> 149:156823d33999 35 //#define DEBUG_PRINTF printf
<> 149:156823d33999 36 #define DEBUG_PRINTF(...)
<> 149:156823d33999 37
<> 149:156823d33999 38 /**
<> 149:156823d33999 39 * @brief Check if any interface is available then lock it for usage.
<> 149:156823d33999 40 * @param[in] tCAN The pointer to CAN module base address.
<> 149:156823d33999 41 * @retval 0 IF0 is free
<> 149:156823d33999 42 * @retval 1 IF1 is free
<> 149:156823d33999 43 * @retval 2 No IF is free
<> 149:156823d33999 44 * @details Search the first free message interface, starting from 0. If a interface is
<> 149:156823d33999 45 * available, set a flag to lock the interface.
<> 149:156823d33999 46 */
<> 149:156823d33999 47 static uint32_t LockIF(CAN_T *tCAN)
<> 149:156823d33999 48 {
<> 149:156823d33999 49 uint32_t u32CanNo;
<> 149:156823d33999 50 uint32_t u32FreeIfNo;
<> 149:156823d33999 51 uint32_t u32IntMask;
<> 149:156823d33999 52
<> 149:156823d33999 53 #if defined(CAN1)
<> 149:156823d33999 54 u32CanNo = (tCAN == CAN1) ? 1 : 0;
<> 149:156823d33999 55 #else // defined(CAN0) || defined(CAN)
<> 149:156823d33999 56 u32CanNo = 0;
<> 149:156823d33999 57 #endif
<> 149:156823d33999 58
<> 149:156823d33999 59 u32FreeIfNo = 2;
<> 149:156823d33999 60
<> 149:156823d33999 61 /* Disable CAN interrupt */
<> 149:156823d33999 62 u32IntMask = tCAN->CON & (CAN_CON_IE_Msk | CAN_CON_SIE_Msk | CAN_CON_EIE_Msk);
<> 149:156823d33999 63 tCAN->CON = tCAN->CON & ~(CAN_CON_IE_Msk | CAN_CON_SIE_Msk | CAN_CON_EIE_Msk);
<> 149:156823d33999 64
<> 149:156823d33999 65 /* Check interface 1 is available or not */
<> 149:156823d33999 66 if((tCAN->IF[0].CREQ & CAN_IF_CREQ_BUSY_Msk) == 0)
<> 149:156823d33999 67 {
<> 149:156823d33999 68 if(gu8LockCanIf[u32CanNo][0] == FALSE)
<> 149:156823d33999 69 {
<> 149:156823d33999 70 gu8LockCanIf[u32CanNo][0] = TRUE;
<> 149:156823d33999 71 u32FreeIfNo = 0;
<> 149:156823d33999 72 }
<> 149:156823d33999 73 }
<> 149:156823d33999 74
<> 149:156823d33999 75 /* Or check interface 2 is available or not */
<> 149:156823d33999 76 if(u32FreeIfNo == 2 && (tCAN->IF[1].CREQ & CAN_IF_CREQ_BUSY_Msk) == 0)
<> 149:156823d33999 77 {
<> 149:156823d33999 78 if(gu8LockCanIf[u32CanNo][1] == FALSE)
<> 149:156823d33999 79 {
<> 149:156823d33999 80 gu8LockCanIf[u32CanNo][1] = TRUE;
<> 149:156823d33999 81 u32FreeIfNo = 1;
<> 149:156823d33999 82 }
<> 149:156823d33999 83 }
<> 149:156823d33999 84
<> 149:156823d33999 85 /* Enable CAN interrupt */
<> 149:156823d33999 86 tCAN->CON |= u32IntMask;
<> 149:156823d33999 87
<> 149:156823d33999 88 return u32FreeIfNo;
<> 149:156823d33999 89 }
<> 149:156823d33999 90
<> 149:156823d33999 91 /**
<> 149:156823d33999 92 * @brief Check if any interface is available in a time limitation then lock it for usage.
<> 149:156823d33999 93 * @param[in] tCAN The pointer to CAN module base address.
<> 149:156823d33999 94 * @retval 0 IF0 is free
<> 149:156823d33999 95 * @retval 1 IF1 is free
<> 149:156823d33999 96 * @retval 2 No IF is free
<> 149:156823d33999 97 * @details Search the first free message interface, starting from 0. If no interface is
<> 149:156823d33999 98 * it will try again until time out. If a interface is available, set a flag to
<> 149:156823d33999 99 * lock the interface.
<> 149:156823d33999 100 */
<> 149:156823d33999 101 static uint32_t LockIF_TL(CAN_T *tCAN)
<> 149:156823d33999 102 {
<> 149:156823d33999 103 uint32_t u32Count;
<> 149:156823d33999 104 uint32_t u32FreeIfNo;
<> 149:156823d33999 105
<> 149:156823d33999 106 for(u32Count = 0; u32Count < RETRY_COUNTS; u32Count++)
<> 149:156823d33999 107 {
<> 149:156823d33999 108 if((u32FreeIfNo = LockIF(tCAN)) != 2)
<> 149:156823d33999 109 return u32FreeIfNo;
<> 149:156823d33999 110 }
<> 149:156823d33999 111
<> 149:156823d33999 112 return u32FreeIfNo;
<> 149:156823d33999 113 }
<> 149:156823d33999 114
<> 149:156823d33999 115 /**
<> 149:156823d33999 116 * @brief Release locked interface.
<> 149:156823d33999 117 * @param[in] tCAN The pointer to CAN module base address.
<> 149:156823d33999 118 * @param[in] u32Info The interface number, 0 or 1.
<> 149:156823d33999 119 * @return none
<> 149:156823d33999 120 * @details Release the locked interface.
<> 149:156823d33999 121 */
<> 149:156823d33999 122 static void ReleaseIF(CAN_T *tCAN, uint32_t u32IfNo)
<> 149:156823d33999 123 {
<> 149:156823d33999 124 uint32_t u32IntMask;
<> 149:156823d33999 125 uint32_t u32CanNo;
<> 149:156823d33999 126
<> 149:156823d33999 127 if(u32IfNo >= 2)
<> 149:156823d33999 128 return;
<> 149:156823d33999 129
<> 149:156823d33999 130 #if defined(CAN1)
<> 149:156823d33999 131 u32CanNo = (tCAN == CAN1) ? 1 : 0;
<> 149:156823d33999 132 #else // defined(CAN0) || defined(CAN)
<> 149:156823d33999 133 u32CanNo = 0;
<> 149:156823d33999 134 #endif
<> 149:156823d33999 135
<> 149:156823d33999 136 /* Disable CAN interrupt */
<> 149:156823d33999 137 u32IntMask = tCAN->CON & (CAN_CON_IE_Msk | CAN_CON_SIE_Msk | CAN_CON_EIE_Msk);
<> 149:156823d33999 138 tCAN->CON = tCAN->CON & ~(CAN_CON_IE_Msk | CAN_CON_SIE_Msk | CAN_CON_EIE_Msk);
<> 149:156823d33999 139
<> 149:156823d33999 140 gu8LockCanIf[u32CanNo][u32IfNo] = FALSE;
<> 149:156823d33999 141
<> 149:156823d33999 142 /* Enable CAN interrupt */
<> 149:156823d33999 143 tCAN->CON |= u32IntMask;
<> 149:156823d33999 144 }
<> 149:156823d33999 145
<> 149:156823d33999 146 /**
<> 149:156823d33999 147 * @brief Enter initialization mode
<> 149:156823d33999 148 * @param[in] tCAN The pointer to CAN module base address.
<> 149:156823d33999 149 * @param[in] Following values can be used.
<> 149:156823d33999 150 * \ref CAN_CON_DAR_Msk Disable automatic retransmission.
<> 149:156823d33999 151 * \ref CAN_CON_EIE_Msk Enable error interrupt.
<> 149:156823d33999 152 * \ref CAN_CON_SIE_Msk Enable status interrupt.
<> 149:156823d33999 153 * \ref CAN_CON_IE_Msk CAN interrupt.
<> 149:156823d33999 154 * @return None
<> 149:156823d33999 155 * @details This function is used to set CAN to enter initialization mode and enable access bit timing
<> 149:156823d33999 156 * register. After bit timing configuration ready, user must call CAN_LeaveInitMode()
<> 149:156823d33999 157 * to leave initialization mode and lock bit timing register to let new configuration
<> 149:156823d33999 158 * take effect.
<> 149:156823d33999 159 */
<> 149:156823d33999 160 void CAN_EnterInitMode(CAN_T *tCAN, uint8_t u8Mask)
<> 149:156823d33999 161 {
<> 149:156823d33999 162 tCAN->CON = u8Mask | (CAN_CON_INIT_Msk | CAN_CON_CCE_Msk);
<> 149:156823d33999 163 }
<> 149:156823d33999 164
<> 149:156823d33999 165
<> 149:156823d33999 166 /**
<> 149:156823d33999 167 * @brief Leave initialization mode
<> 149:156823d33999 168 * @param[in] tCAN The pointer to CAN module base address.
<> 149:156823d33999 169 * @return None
<> 149:156823d33999 170 * @details This function is used to set CAN to leave initialization mode to let
<> 149:156823d33999 171 * bit timing configuration take effect after configuration ready.
<> 149:156823d33999 172 */
<> 149:156823d33999 173 void CAN_LeaveInitMode(CAN_T *tCAN)
<> 149:156823d33999 174 {
<> 149:156823d33999 175 tCAN->CON &= (~(CAN_CON_INIT_Msk | CAN_CON_CCE_Msk));
<> 149:156823d33999 176 while(tCAN->CON & CAN_CON_INIT_Msk); /* Check INIT bit is released */
<> 149:156823d33999 177 }
<> 149:156823d33999 178
<> 149:156823d33999 179 /**
<> 149:156823d33999 180 * @brief Wait message into message buffer in basic mode.
<> 149:156823d33999 181 * @param[in] tCAN The pointer to CAN module base address.
<> 149:156823d33999 182 * @return None
<> 149:156823d33999 183 * @details This function is used to wait message into message buffer in basic mode. Please notice the
<> 149:156823d33999 184 * function is polling NEWDAT bit of MCON register by while loop and it is used in basic mode.
<> 149:156823d33999 185 */
<> 149:156823d33999 186 void CAN_WaitMsg(CAN_T *tCAN)
<> 149:156823d33999 187 {
<> 149:156823d33999 188 tCAN->STATUS = 0x0; /* clr status */
<> 149:156823d33999 189
<> 149:156823d33999 190 while(1)
<> 149:156823d33999 191 {
<> 149:156823d33999 192 if(tCAN->IF[1].MCON & CAN_IF_MCON_NEWDAT_Msk) /* check new data */
<> 149:156823d33999 193 {
<> 149:156823d33999 194 DEBUG_PRINTF("New Data IN\n");
<> 149:156823d33999 195 break;
<> 149:156823d33999 196 }
<> 149:156823d33999 197
<> 149:156823d33999 198 if(tCAN->STATUS & CAN_STATUS_RXOK_Msk)
<> 149:156823d33999 199 DEBUG_PRINTF("Rx OK\n");
<> 149:156823d33999 200
<> 149:156823d33999 201 if(tCAN->STATUS & CAN_STATUS_LEC_Msk)
<> 149:156823d33999 202 {
<> 149:156823d33999 203 DEBUG_PRINTF("Error\n");
<> 149:156823d33999 204 }
<> 149:156823d33999 205 }
<> 149:156823d33999 206 }
<> 149:156823d33999 207
<> 149:156823d33999 208 /**
<> 149:156823d33999 209 * @brief Get current bit rate
<> 149:156823d33999 210 * @param[in] tCAN The pointer to CAN module base address.
<> 149:156823d33999 211 * @return Current Bit-Rate (kilo bit per second)
<> 149:156823d33999 212 * @details Return current CAN bit rate according to the user bit-timing parameter settings
<> 149:156823d33999 213 */
<> 149:156823d33999 214 uint32_t CAN_GetCANBitRate(CAN_T *tCAN)
<> 149:156823d33999 215 {
<> 149:156823d33999 216 uint8_t u8Tseg1, u8Tseg2;
<> 149:156823d33999 217 uint32_t u32Bpr;
<> 149:156823d33999 218
<> 149:156823d33999 219 u8Tseg1 = (tCAN->BTIME & CAN_BTIME_TSEG1_Msk) >> CAN_BTIME_TSEG1_Pos;
<> 149:156823d33999 220 u8Tseg2 = (tCAN->BTIME & CAN_BTIME_TSEG2_Msk) >> CAN_BTIME_TSEG2_Pos;
<> 149:156823d33999 221 u32Bpr = (tCAN->BTIME & CAN_BTIME_BRP_Msk) | (tCAN->BRPE << 6);
<> 149:156823d33999 222
<> 149:156823d33999 223 return (SystemCoreClock / (u32Bpr + 1) / (u8Tseg1 + u8Tseg2 + 3));
<> 149:156823d33999 224 }
<> 149:156823d33999 225
<> 149:156823d33999 226 /**
<> 149:156823d33999 227 * @brief Switch the CAN into test mode.
<> 149:156823d33999 228 * @param[in] tCAN The pointer to CAN module base address.
<> 149:156823d33999 229 * @param[in] u8TestMask Specifies the configuration in test modes
<> 149:156823d33999 230 * \ref CAN_TEST_BASIC_Msk Enable basic mode of test mode
<> 149:156823d33999 231 * \ref CAN_TEST_SILENT_Msk Enable silent mode of test mode
<> 149:156823d33999 232 * \ref CAN_TEST_LBACK_Msk Enable Loop Back Mode of test mode
<> 149:156823d33999 233 * \ref CAN_TEST_TX0_Msk / \ref CAN_TEST_TX1_Msk Control CAN_TX pin bit field
<> 149:156823d33999 234 * @return None
<> 149:156823d33999 235 * @details Switch the CAN into test mode. There are four test mode (BASIC/SILENT/LOOPBACK/
<> 149:156823d33999 236 * LOOPBACK combined SILENT/CONTROL_TX_PIN)could be selected. After setting test mode,user
<> 149:156823d33999 237 * must call CAN_LeaveInitMode() to let the setting take effect.
<> 149:156823d33999 238 */
<> 149:156823d33999 239 void CAN_EnterTestMode(CAN_T *tCAN, uint8_t u8TestMask)
<> 149:156823d33999 240 {
<> 149:156823d33999 241 tCAN->CON |= CAN_CON_TEST_Msk;
<> 149:156823d33999 242 tCAN->TEST = u8TestMask;
<> 149:156823d33999 243 }
<> 149:156823d33999 244
<> 149:156823d33999 245
<> 149:156823d33999 246 /**
<> 149:156823d33999 247 * @brief Leave the test mode
<> 149:156823d33999 248 * @param[in] tCAN The pointer to CAN module base address.
<> 149:156823d33999 249 * @return None
<> 149:156823d33999 250 * @details This function is used to Leave the test mode (switch into normal mode).
<> 149:156823d33999 251 */
<> 149:156823d33999 252 void CAN_LeaveTestMode(CAN_T *tCAN)
<> 149:156823d33999 253 {
<> 149:156823d33999 254 tCAN->CON |= CAN_CON_TEST_Msk;
<> 149:156823d33999 255 tCAN->TEST &= ~(CAN_TEST_LBACK_Msk | CAN_TEST_SILENT_Msk | CAN_TEST_BASIC_Msk);
<> 149:156823d33999 256 tCAN->CON &= (~CAN_CON_TEST_Msk);
<> 149:156823d33999 257 }
<> 149:156823d33999 258
<> 149:156823d33999 259 /**
<> 149:156823d33999 260 * @brief Get the waiting status of a received message.
<> 149:156823d33999 261 * @param[in] tCAN The pointer to CAN module base address.
<> 149:156823d33999 262 * @param[in] u8MsgObj Specifies the Message object number, from 0 to 31.
<> 149:156823d33999 263 * @retval non-zero The corresponding message object has a new data bit is set.
<> 149:156823d33999 264 * @retval 0 No message object has new data.
<> 149:156823d33999 265 * @details This function is used to get the waiting status of a received message.
<> 149:156823d33999 266 */
<> 149:156823d33999 267 uint32_t CAN_IsNewDataReceived(CAN_T *tCAN, uint8_t u8MsgObj)
<> 149:156823d33999 268 {
<> 149:156823d33999 269 return (u8MsgObj < 16 ? tCAN->NDAT1 & (1 << u8MsgObj) : tCAN->NDAT2 & (1 << (u8MsgObj - 16)));
<> 149:156823d33999 270 }
<> 149:156823d33999 271
<> 149:156823d33999 272
<> 149:156823d33999 273 /**
<> 149:156823d33999 274 * @brief Send CAN message in BASIC mode of test mode
<> 149:156823d33999 275 * @param[in] tCAN The pointer to CAN module base address.
<> 149:156823d33999 276 * @param[in] pCanMsg Pointer to the message structure containing data to transmit.
<> 149:156823d33999 277 * @return TRUE: Transmission OK
<> 149:156823d33999 278 * FALSE: Check busy flag of interface 0 is timeout
<> 149:156823d33999 279 * @details The function is used to send CAN message in BASIC mode of test mode. Before call the API,
<> 149:156823d33999 280 * the user should be call CAN_EnterTestMode(CAN_TEST_BASIC) and let CAN controller enter
<> 149:156823d33999 281 * basic mode of test mode. Please notice IF1 Registers used as Tx Buffer in basic mode.
<> 149:156823d33999 282 */
<> 149:156823d33999 283 int32_t CAN_BasicSendMsg(CAN_T *tCAN, STR_CANMSG_T* pCanMsg)
<> 149:156823d33999 284 {
<> 149:156823d33999 285 uint32_t i = 0;
<> 149:156823d33999 286 while(tCAN->IF[0].CREQ & CAN_IF_CREQ_BUSY_Msk);
<> 149:156823d33999 287
<> 149:156823d33999 288 tCAN->STATUS &= (~CAN_STATUS_TXOK_Msk);
<> 149:156823d33999 289
<> 149:156823d33999 290 if(pCanMsg->IdType == CAN_STD_ID)
<> 149:156823d33999 291 {
<> 149:156823d33999 292 /* standard ID*/
<> 149:156823d33999 293 tCAN->IF[0].ARB1 = 0;
<> 149:156823d33999 294 tCAN->IF[0].ARB2 = (((pCanMsg->Id) & 0x7FF) << 2) ;
<> 149:156823d33999 295 }
<> 149:156823d33999 296 else
<> 149:156823d33999 297 {
<> 149:156823d33999 298 /* extended ID*/
<> 149:156823d33999 299 tCAN->IF[0].ARB1 = (pCanMsg->Id) & 0xFFFF;
<> 149:156823d33999 300 tCAN->IF[0].ARB2 = ((pCanMsg->Id) & 0x1FFF0000) >> 16 | CAN_IF_ARB2_XTD_Msk;
<> 149:156823d33999 301
<> 149:156823d33999 302 }
<> 149:156823d33999 303
<> 149:156823d33999 304 if(pCanMsg->FrameType)
<> 149:156823d33999 305 tCAN->IF[0].ARB2 |= CAN_IF_ARB2_DIR_Msk;
<> 149:156823d33999 306 else
<> 149:156823d33999 307 tCAN->IF[0].ARB2 &= (~CAN_IF_ARB2_DIR_Msk);
<> 149:156823d33999 308
<> 149:156823d33999 309 tCAN->IF[0].MCON = (tCAN->IF[0].MCON & (~CAN_IF_MCON_DLC_Msk)) | pCanMsg->DLC;
<> 149:156823d33999 310 tCAN->IF[0].DAT_A1 = ((uint16_t)pCanMsg->Data[1] << 8) | pCanMsg->Data[0];
<> 149:156823d33999 311 tCAN->IF[0].DAT_A2 = ((uint16_t)pCanMsg->Data[3] << 8) | pCanMsg->Data[2];
<> 149:156823d33999 312 tCAN->IF[0].DAT_B1 = ((uint16_t)pCanMsg->Data[5] << 8) | pCanMsg->Data[4];
<> 149:156823d33999 313 tCAN->IF[0].DAT_B2 = ((uint16_t)pCanMsg->Data[7] << 8) | pCanMsg->Data[6];
<> 149:156823d33999 314
<> 149:156823d33999 315 /* request transmission*/
<> 149:156823d33999 316 tCAN->IF[0].CREQ &= (~CAN_IF_CREQ_BUSY_Msk);
<> 149:156823d33999 317 if(tCAN->IF[0].CREQ & CAN_IF_CREQ_BUSY_Msk)
<> 149:156823d33999 318 {
<> 149:156823d33999 319 DEBUG_PRINTF("Cannot clear busy for sending ...\n");
<> 149:156823d33999 320 return FALSE;
<> 149:156823d33999 321 }
<> 149:156823d33999 322
<> 149:156823d33999 323 tCAN->IF[0].CREQ |= CAN_IF_CREQ_BUSY_Msk; // sending
<> 149:156823d33999 324
<> 149:156823d33999 325 for(i = 0; i < 0xFFFFF; i++)
<> 149:156823d33999 326 {
<> 149:156823d33999 327 if((tCAN->IF[0].CREQ & CAN_IF_CREQ_BUSY_Msk) == 0)
<> 149:156823d33999 328 break;
<> 149:156823d33999 329 }
<> 149:156823d33999 330
<> 149:156823d33999 331 if(i >= 0xFFFFF)
<> 149:156823d33999 332 {
<> 149:156823d33999 333 DEBUG_PRINTF("Cannot send out...\n");
<> 149:156823d33999 334 return FALSE;
<> 149:156823d33999 335 }
<> 149:156823d33999 336
<> 149:156823d33999 337 return TRUE;
<> 149:156823d33999 338 }
<> 149:156823d33999 339
<> 149:156823d33999 340 /**
<> 149:156823d33999 341 * @brief Get a message information in BASIC mode.
<> 149:156823d33999 342 *
<> 149:156823d33999 343 * @param[in] tCAN The pointer to CAN module base address.
<> 149:156823d33999 344 * @param[in] pCanMsg Pointer to the message structure where received data is copied.
<> 149:156823d33999 345 *
<> 149:156823d33999 346 * @return FALSE No any message received.
<> 149:156823d33999 347 * TRUE Receive a message success.
<> 149:156823d33999 348 *
<> 149:156823d33999 349 */
<> 149:156823d33999 350 int32_t CAN_BasicReceiveMsg(CAN_T *tCAN, STR_CANMSG_T* pCanMsg)
<> 149:156823d33999 351 {
<> 149:156823d33999 352
<> 149:156823d33999 353 if((tCAN->IF[1].MCON & CAN_IF_MCON_NEWDAT_Msk) == 0) /* In basic mode, receive data always save in IF2 */
<> 149:156823d33999 354 {
<> 149:156823d33999 355 return FALSE;
<> 149:156823d33999 356 }
<> 149:156823d33999 357
<> 149:156823d33999 358 tCAN->STATUS &= (~CAN_STATUS_RXOK_Msk);
<> 149:156823d33999 359
<> 149:156823d33999 360 tCAN->IF[1].CMASK = CAN_IF_CMASK_ARB_Msk
<> 149:156823d33999 361 | CAN_IF_CMASK_CONTROL_Msk
<> 149:156823d33999 362 | CAN_IF_CMASK_DATAA_Msk
<> 149:156823d33999 363 | CAN_IF_CMASK_DATAB_Msk;
<> 149:156823d33999 364
<> 149:156823d33999 365 if((tCAN->IF[1].ARB2 & CAN_IF_ARB2_XTD_Msk) == 0)
<> 149:156823d33999 366 {
<> 149:156823d33999 367 /* standard ID*/
<> 149:156823d33999 368 pCanMsg->IdType = CAN_STD_ID;
<> 149:156823d33999 369 pCanMsg->Id = (tCAN->IF[1].ARB2 >> 2) & 0x07FF;
<> 149:156823d33999 370
<> 149:156823d33999 371 }
<> 149:156823d33999 372 else
<> 149:156823d33999 373 {
<> 149:156823d33999 374 /* extended ID*/
<> 149:156823d33999 375 pCanMsg->IdType = CAN_EXT_ID;
<> 149:156823d33999 376 pCanMsg->Id = (tCAN->IF[1].ARB2 & 0x1FFF) << 16;
<> 149:156823d33999 377 pCanMsg->Id |= (uint32_t)tCAN->IF[1].ARB1;
<> 149:156823d33999 378 }
<> 149:156823d33999 379
<> 149:156823d33999 380 pCanMsg->FrameType = !((tCAN->IF[1].ARB2 & CAN_IF_ARB2_DIR_Msk) >> CAN_IF_ARB2_DIR_Pos);
<> 149:156823d33999 381
<> 149:156823d33999 382 pCanMsg->DLC = tCAN->IF[1].MCON & CAN_IF_MCON_DLC_Msk;
<> 149:156823d33999 383 pCanMsg->Data[0] = tCAN->IF[1].DAT_A1 & CAN_IF_DAT_A1_DATA0_Msk;
<> 149:156823d33999 384 pCanMsg->Data[1] = (tCAN->IF[1].DAT_A1 & CAN_IF_DAT_A1_DATA1_Msk) >> CAN_IF_DAT_A1_DATA1_Pos;
<> 149:156823d33999 385 pCanMsg->Data[2] = tCAN->IF[1].DAT_A2 & CAN_IF_DAT_A2_DATA2_Msk;
<> 149:156823d33999 386 pCanMsg->Data[3] = (tCAN->IF[1].DAT_A2 & CAN_IF_DAT_A2_DATA3_Msk) >> CAN_IF_DAT_A2_DATA3_Pos;
<> 149:156823d33999 387 pCanMsg->Data[4] = tCAN->IF[1].DAT_B1 & CAN_IF_DAT_B1_DATA4_Msk;
<> 149:156823d33999 388 pCanMsg->Data[5] = (tCAN->IF[1].DAT_B1 & CAN_IF_DAT_B1_DATA5_Msk) >> CAN_IF_DAT_B1_DATA5_Pos;
<> 149:156823d33999 389 pCanMsg->Data[6] = tCAN->IF[1].DAT_B2 & CAN_IF_DAT_B2_DATA6_Msk;
<> 149:156823d33999 390 pCanMsg->Data[7] = (tCAN->IF[1].DAT_B2 & CAN_IF_DAT_B2_DATA7_Msk) >> CAN_IF_DAT_B2_DATA7_Pos;
<> 149:156823d33999 391
<> 149:156823d33999 392 return TRUE;
<> 149:156823d33999 393 }
<> 149:156823d33999 394
<> 149:156823d33999 395 /**
<> 149:156823d33999 396 * @brief Set Rx message object, include ID mask.
<> 149:156823d33999 397 * @param[in] u8MsgObj Specifies the Message object number, from 0 to 31.
<> 149:156823d33999 398 * @param[in] u8idType Specifies the identifier type of the frames that will be transmitted
<> 149:156823d33999 399 * This parameter can be one of the following values:
<> 149:156823d33999 400 * \ref CAN_STD_ID (standard ID, 11-bit)
<> 149:156823d33999 401 * \ref CAN_EXT_ID (extended ID, 29-bit)
<> 149:156823d33999 402 * @param[in] u32id Specifies the identifier used for acceptance filtering.
<> 149:156823d33999 403 * @param[in] u8singleOrFifoLast Specifies the end-of-buffer indicator.
<> 149:156823d33999 404 * This parameter can be one of the following values:
<> 149:156823d33999 405 * TRUE: for a single receive object or a FIFO receive object that is the last one of the FIFO.
<> 149:156823d33999 406 * FALSE: for a FIFO receive object that is not the last one.
<> 149:156823d33999 407 * @retval TRUE SUCCESS
<> 149:156823d33999 408 * @retval FALSE No useful interface
<> 149:156823d33999 409 * @details The function is used to configure a receive message object.
<> 149:156823d33999 410 */
<> 149:156823d33999 411 int32_t CAN_SetRxMsgObjAndMsk(CAN_T *tCAN, uint8_t u8MsgObj, uint8_t u8idType, uint32_t u32id, uint32_t u32idmask, uint8_t u8singleOrFifoLast)
<> 149:156823d33999 412 {
<> 149:156823d33999 413 uint8_t u8MsgIfNum;
<> 149:156823d33999 414
<> 149:156823d33999 415 /* Get and lock a free interface */
<> 149:156823d33999 416 if((u8MsgIfNum = LockIF_TL(tCAN)) == 2)
<> 149:156823d33999 417 return FALSE;
<> 149:156823d33999 418
<> 149:156823d33999 419 /* Command Setting */
<> 149:156823d33999 420 tCAN->IF[u8MsgIfNum].CMASK = CAN_IF_CMASK_WRRD_Msk | CAN_IF_CMASK_MASK_Msk | CAN_IF_CMASK_ARB_Msk |
<> 149:156823d33999 421 CAN_IF_CMASK_CONTROL_Msk | CAN_IF_CMASK_DATAA_Msk | CAN_IF_CMASK_DATAB_Msk;
<> 149:156823d33999 422
<> 149:156823d33999 423 if(u8idType == CAN_STD_ID) /* According STD/EXT ID format,Configure Mask and Arbitration register */
<> 149:156823d33999 424 {
<> 149:156823d33999 425 tCAN->IF[u8MsgIfNum].ARB1 = 0;
<> 149:156823d33999 426 tCAN->IF[u8MsgIfNum].ARB2 = CAN_IF_ARB2_MSGVAL_Msk | (u32id & 0x7FF) << 2;
<> 149:156823d33999 427 }
<> 149:156823d33999 428 else
<> 149:156823d33999 429 {
<> 149:156823d33999 430 tCAN->IF[u8MsgIfNum].ARB1 = u32id & 0xFFFF;
<> 149:156823d33999 431 tCAN->IF[u8MsgIfNum].ARB2 = CAN_IF_ARB2_MSGVAL_Msk | CAN_IF_ARB2_XTD_Msk | (u32id & 0x1FFF0000) >> 16;
<> 149:156823d33999 432 }
<> 149:156823d33999 433
<> 149:156823d33999 434 tCAN->IF[u8MsgIfNum].MASK1 = (u32idmask & 0xFFFF);
<> 149:156823d33999 435 tCAN->IF[u8MsgIfNum].MASK2 = (u32idmask >> 16) & 0xFFFF;
<> 149:156823d33999 436
<> 149:156823d33999 437 //tCAN->IF[u8MsgIfNum].MCON |= CAN_IF_MCON_UMASK_Msk | CAN_IF_MCON_RXIE_Msk;
<> 149:156823d33999 438 tCAN->IF[u8MsgIfNum].MCON = CAN_IF_MCON_UMASK_Msk | CAN_IF_MCON_RXIE_Msk;
<> 149:156823d33999 439 if(u8singleOrFifoLast)
<> 149:156823d33999 440 tCAN->IF[u8MsgIfNum].MCON |= CAN_IF_MCON_EOB_Msk;
<> 149:156823d33999 441 else
<> 149:156823d33999 442 tCAN->IF[u8MsgIfNum].MCON &= (~CAN_IF_MCON_EOB_Msk);
<> 149:156823d33999 443
<> 149:156823d33999 444 tCAN->IF[u8MsgIfNum].DAT_A1 = 0;
<> 149:156823d33999 445 tCAN->IF[u8MsgIfNum].DAT_A2 = 0;
<> 149:156823d33999 446 tCAN->IF[u8MsgIfNum].DAT_B1 = 0;
<> 149:156823d33999 447 tCAN->IF[u8MsgIfNum].DAT_B2 = 0;
<> 149:156823d33999 448
<> 149:156823d33999 449 tCAN->IF[u8MsgIfNum].CREQ = 1 + u8MsgObj;
<> 149:156823d33999 450 ReleaseIF(tCAN, u8MsgIfNum);
<> 149:156823d33999 451
<> 149:156823d33999 452 return TRUE;
<> 149:156823d33999 453 }
<> 149:156823d33999 454
<> 149:156823d33999 455 /**
<> 149:156823d33999 456 * @brief Set Rx message object
<> 149:156823d33999 457 * @param[in] u8MsgObj Specifies the Message object number, from 0 to 31.
<> 149:156823d33999 458 * @param[in] u8idType Specifies the identifier type of the frames that will be transmitted
<> 149:156823d33999 459 * This parameter can be one of the following values:
<> 149:156823d33999 460 * \ref CAN_STD_ID (standard ID, 11-bit)
<> 149:156823d33999 461 * \ref CAN_EXT_ID (extended ID, 29-bit)
<> 149:156823d33999 462 * @param[in] u32id Specifies the identifier used for acceptance filtering.
<> 149:156823d33999 463 * @param[in] u8singleOrFifoLast Specifies the end-of-buffer indicator.
<> 149:156823d33999 464 * This parameter can be one of the following values:
<> 149:156823d33999 465 * TRUE: for a single receive object or a FIFO receive object that is the last one of the FIFO.
<> 149:156823d33999 466 * FALSE: for a FIFO receive object that is not the last one.
<> 149:156823d33999 467 * @retval TRUE SUCCESS
<> 149:156823d33999 468 * @retval FALSE No useful interface
<> 149:156823d33999 469 * @details The function is used to configure a receive message object.
<> 149:156823d33999 470 */
<> 149:156823d33999 471 int32_t CAN_SetRxMsgObj(CAN_T *tCAN, uint8_t u8MsgObj, uint8_t u8idType, uint32_t u32id, uint8_t u8singleOrFifoLast)
<> 149:156823d33999 472 {
<> 149:156823d33999 473 uint8_t u8MsgIfNum;
<> 149:156823d33999 474
<> 149:156823d33999 475 /* Get and lock a free interface */
<> 149:156823d33999 476 if((u8MsgIfNum = LockIF_TL(tCAN)) == 2)
<> 149:156823d33999 477 return FALSE;
<> 149:156823d33999 478
<> 149:156823d33999 479 /* Command Setting */
<> 149:156823d33999 480 tCAN->IF[u8MsgIfNum].CMASK = CAN_IF_CMASK_WRRD_Msk | CAN_IF_CMASK_MASK_Msk | CAN_IF_CMASK_ARB_Msk |
<> 149:156823d33999 481 CAN_IF_CMASK_CONTROL_Msk | CAN_IF_CMASK_DATAA_Msk | CAN_IF_CMASK_DATAB_Msk;
<> 149:156823d33999 482
<> 149:156823d33999 483 if(u8idType == CAN_STD_ID) /* According STD/EXT ID format,Configure Mask and Arbitration register */
<> 149:156823d33999 484 {
<> 149:156823d33999 485 tCAN->IF[u8MsgIfNum].ARB1 = 0;
<> 149:156823d33999 486 tCAN->IF[u8MsgIfNum].ARB2 = CAN_IF_ARB2_MSGVAL_Msk | (u32id & 0x7FF) << 2;
<> 149:156823d33999 487 }
<> 149:156823d33999 488 else
<> 149:156823d33999 489 {
<> 149:156823d33999 490 tCAN->IF[u8MsgIfNum].ARB1 = u32id & 0xFFFF;
<> 149:156823d33999 491 tCAN->IF[u8MsgIfNum].ARB2 = CAN_IF_ARB2_MSGVAL_Msk | CAN_IF_ARB2_XTD_Msk | (u32id & 0x1FFF0000) >> 16;
<> 149:156823d33999 492 }
<> 149:156823d33999 493
<> 149:156823d33999 494 //tCAN->IF[u8MsgIfNum].MCON |= CAN_IF_MCON_UMASK_Msk | CAN_IF_MCON_RXIE_Msk;
<> 149:156823d33999 495 tCAN->IF[u8MsgIfNum].MCON = CAN_IF_MCON_UMASK_Msk | CAN_IF_MCON_RXIE_Msk;
<> 149:156823d33999 496 if(u8singleOrFifoLast)
<> 149:156823d33999 497 tCAN->IF[u8MsgIfNum].MCON |= CAN_IF_MCON_EOB_Msk;
<> 149:156823d33999 498 else
<> 149:156823d33999 499 tCAN->IF[u8MsgIfNum].MCON &= (~CAN_IF_MCON_EOB_Msk);
<> 149:156823d33999 500
<> 149:156823d33999 501 tCAN->IF[u8MsgIfNum].DAT_A1 = 0;
<> 149:156823d33999 502 tCAN->IF[u8MsgIfNum].DAT_A2 = 0;
<> 149:156823d33999 503 tCAN->IF[u8MsgIfNum].DAT_B1 = 0;
<> 149:156823d33999 504 tCAN->IF[u8MsgIfNum].DAT_B2 = 0;
<> 149:156823d33999 505
<> 149:156823d33999 506 tCAN->IF[u8MsgIfNum].CREQ = 1 + u8MsgObj;
<> 149:156823d33999 507 ReleaseIF(tCAN, u8MsgIfNum);
<> 149:156823d33999 508
<> 149:156823d33999 509 return TRUE;
<> 149:156823d33999 510 }
<> 149:156823d33999 511
<> 149:156823d33999 512 /**
<> 149:156823d33999 513 * @brief Gets the message
<> 149:156823d33999 514 * @param[in] u8MsgObj Specifies the Message object number, from 0 to 31.
<> 149:156823d33999 515 * @param[in] u8Release Specifies the message release indicator.
<> 149:156823d33999 516 * This parameter can be one of the following values:
<> 149:156823d33999 517 * TRUE: the message object is released when getting the data.
<> 149:156823d33999 518 * FALSE:the message object is not released.
<> 149:156823d33999 519 * @param[in] pCanMsg Pointer to the message structure where received data is copied.
<> 149:156823d33999 520 * @retval TRUE Success
<> 149:156823d33999 521 * @retval FALSE No any message received
<> 149:156823d33999 522 * @details Gets the message, if received.
<> 149:156823d33999 523 */
<> 149:156823d33999 524 int32_t CAN_ReadMsgObj(CAN_T *tCAN, uint8_t u8MsgObj, uint8_t u8Release, STR_CANMSG_T* pCanMsg)
<> 149:156823d33999 525 {
<> 149:156823d33999 526 uint8_t u8MsgIfNum;
<> 149:156823d33999 527
<> 149:156823d33999 528 if(!CAN_IsNewDataReceived(tCAN, u8MsgObj))
<> 149:156823d33999 529 return FALSE;
<> 149:156823d33999 530
<> 149:156823d33999 531 /* Get and lock a free interface */
<> 149:156823d33999 532 if((u8MsgIfNum = LockIF_TL(tCAN)) == 2)
<> 149:156823d33999 533 return FALSE;
<> 149:156823d33999 534
<> 149:156823d33999 535 tCAN->STATUS &= (~CAN_STATUS_RXOK_Msk);
<> 149:156823d33999 536
<> 149:156823d33999 537 /* read the message contents*/
<> 149:156823d33999 538 tCAN->IF[u8MsgIfNum].CMASK = CAN_IF_CMASK_MASK_Msk
<> 149:156823d33999 539 | CAN_IF_CMASK_ARB_Msk
<> 149:156823d33999 540 | CAN_IF_CMASK_CONTROL_Msk
<> 149:156823d33999 541 | CAN_IF_CMASK_CLRINTPND_Msk
<> 149:156823d33999 542 | (u8Release ? CAN_IF_CMASK_TXRQSTNEWDAT_Msk : 0)
<> 149:156823d33999 543 | CAN_IF_CMASK_DATAA_Msk
<> 149:156823d33999 544 | CAN_IF_CMASK_DATAB_Msk;
<> 149:156823d33999 545
<> 149:156823d33999 546 tCAN->IF[u8MsgIfNum].CREQ = 1 + u8MsgObj;
<> 149:156823d33999 547
<> 149:156823d33999 548 while(tCAN->IF[u8MsgIfNum].CREQ & CAN_IF_CREQ_BUSY_Msk)
<> 149:156823d33999 549 {
<> 149:156823d33999 550 /*Wait*/
<> 149:156823d33999 551 }
<> 149:156823d33999 552
<> 149:156823d33999 553 if((tCAN->IF[u8MsgIfNum].ARB2 & CAN_IF_ARB2_XTD_Msk) == 0)
<> 149:156823d33999 554 {
<> 149:156823d33999 555 /* standard ID*/
<> 149:156823d33999 556 pCanMsg->IdType = CAN_STD_ID;
<> 149:156823d33999 557 pCanMsg->Id = (tCAN->IF[u8MsgIfNum].ARB2 & CAN_IF_ARB2_ID_Msk) >> 2;
<> 149:156823d33999 558 }
<> 149:156823d33999 559 else
<> 149:156823d33999 560 {
<> 149:156823d33999 561 /* extended ID*/
<> 149:156823d33999 562 pCanMsg->IdType = CAN_EXT_ID;
<> 149:156823d33999 563 pCanMsg->Id = (((tCAN->IF[u8MsgIfNum].ARB2) & 0x1FFF) << 16) | tCAN->IF[u8MsgIfNum].ARB1;
<> 149:156823d33999 564 }
<> 149:156823d33999 565
<> 149:156823d33999 566 pCanMsg->DLC = tCAN->IF[u8MsgIfNum].MCON & CAN_IF_MCON_DLC_Msk;
<> 149:156823d33999 567 pCanMsg->Data[0] = tCAN->IF[u8MsgIfNum].DAT_A1 & CAN_IF_DAT_A1_DATA0_Msk;
<> 149:156823d33999 568 pCanMsg->Data[1] = (tCAN->IF[u8MsgIfNum].DAT_A1 & CAN_IF_DAT_A1_DATA1_Msk) >> CAN_IF_DAT_A1_DATA1_Pos;
<> 149:156823d33999 569 pCanMsg->Data[2] = tCAN->IF[u8MsgIfNum].DAT_A2 & CAN_IF_DAT_A2_DATA2_Msk;
<> 149:156823d33999 570 pCanMsg->Data[3] = (tCAN->IF[u8MsgIfNum].DAT_A2 & CAN_IF_DAT_A2_DATA3_Msk) >> CAN_IF_DAT_A2_DATA3_Pos;
<> 149:156823d33999 571 pCanMsg->Data[4] = tCAN->IF[u8MsgIfNum].DAT_B1 & CAN_IF_DAT_B1_DATA4_Msk;
<> 149:156823d33999 572 pCanMsg->Data[5] = (tCAN->IF[u8MsgIfNum].DAT_B1 & CAN_IF_DAT_B1_DATA5_Msk) >> CAN_IF_DAT_B1_DATA5_Pos;
<> 149:156823d33999 573 pCanMsg->Data[6] = tCAN->IF[u8MsgIfNum].DAT_B2 & CAN_IF_DAT_B2_DATA6_Msk;
<> 149:156823d33999 574 pCanMsg->Data[7] = (tCAN->IF[u8MsgIfNum].DAT_B2 & CAN_IF_DAT_B2_DATA7_Msk) >> CAN_IF_DAT_B2_DATA7_Pos;
<> 149:156823d33999 575
<> 149:156823d33999 576 ReleaseIF(tCAN, u8MsgIfNum);
<> 149:156823d33999 577 return TRUE;
<> 149:156823d33999 578 }
<> 149:156823d33999 579
<> 149:156823d33999 580 /// @endcond HIDDEN_SYMBOLS
<> 149:156823d33999 581
<> 149:156823d33999 582
<> 149:156823d33999 583 /**
<> 149:156823d33999 584 * @brief Set bus baud-rate.
<> 149:156823d33999 585 *
<> 149:156823d33999 586 * @param[in] tCAN The pointer to CAN module base address.
<> 149:156823d33999 587 * @param[in] u32BaudRate The target CAN baud-rate. The range of u32BaudRate is 1~1000KHz.
<> 149:156823d33999 588 *
<> 149:156823d33999 589 * @return u32CurrentBitRate Real baud-rate value.
<> 149:156823d33999 590 *
<> 149:156823d33999 591 * @details The function is used to set bus timing parameter according current clock and target baud-rate.
<> 149:156823d33999 592 */
<> 149:156823d33999 593 uint32_t CAN_SetBaudRate(CAN_T *tCAN, uint32_t u32BaudRate)
<> 149:156823d33999 594 {
<> 149:156823d33999 595 uint8_t u8Tseg1, u8Tseg2;
<> 149:156823d33999 596 uint32_t u32Brp;
<> 149:156823d33999 597 uint32_t u32Value;
<> 149:156823d33999 598
<> 149:156823d33999 599 CAN_EnterInitMode(tCAN, 0);
<> 149:156823d33999 600 SystemCoreClockUpdate();
<> 149:156823d33999 601 u32Value = SystemCoreClock / u32BaudRate;
<> 149:156823d33999 602
<> 149:156823d33999 603 #if 0
<> 149:156823d33999 604 u8Tseg1 = 2;
<> 149:156823d33999 605 u8Tseg2 = 1;
<> 149:156823d33999 606 while(1)
<> 149:156823d33999 607 {
<> 149:156823d33999 608 if(((u32Value % (u8Tseg1 + u8Tseg2 + 3)) == 0))
<> 149:156823d33999 609 break;
<> 149:156823d33999 610 if(u8Tseg1 < 7)
<> 149:156823d33999 611 u8Tseg2++;
<> 149:156823d33999 612
<> 149:156823d33999 613 if((u32Value % (u8Tseg1 + u8Tseg2 + 3)) == 0)
<> 149:156823d33999 614 break;
<> 149:156823d33999 615 if(u8Tseg1 < 15)
<> 149:156823d33999 616 u8Tseg1++;
<> 149:156823d33999 617 else
<> 149:156823d33999 618 {
<> 149:156823d33999 619 u8Tseg1 = 2;
<> 149:156823d33999 620 u8Tseg2 = 1;
<> 149:156823d33999 621 break;
<> 149:156823d33999 622 }
<> 149:156823d33999 623 }
<> 149:156823d33999 624 #else
<> 149:156823d33999 625
<> 149:156823d33999 626 /* Fix for most standard baud rates, include 125K */
<> 149:156823d33999 627
<> 149:156823d33999 628 u8Tseg1 = 3;
<> 149:156823d33999 629 u8Tseg2 = 2;
<> 149:156823d33999 630 while(1)
<> 149:156823d33999 631 {
<> 149:156823d33999 632 if(((u32Value % (u8Tseg1 + u8Tseg2 + 3)) == 0) | (u8Tseg1 >= 15))
<> 149:156823d33999 633 break;
<> 149:156823d33999 634
<> 149:156823d33999 635 u8Tseg1++;
<> 149:156823d33999 636
<> 149:156823d33999 637 if((u32Value % (u8Tseg1 + u8Tseg2 + 3)) == 0)
<> 149:156823d33999 638 break;
<> 149:156823d33999 639
<> 149:156823d33999 640 if(u8Tseg2 < 7)
<> 149:156823d33999 641 u8Tseg2++;
<> 149:156823d33999 642 }
<> 149:156823d33999 643 #endif
<> 149:156823d33999 644 u32Brp = SystemCoreClock / (u32BaudRate) / (u8Tseg1 + u8Tseg2 + 3) - 1;
<> 149:156823d33999 645
<> 149:156823d33999 646 u32Value = ((uint32_t)u8Tseg2 << CAN_BTIME_TSEG2_Pos) | ((uint32_t)u8Tseg1 << CAN_BTIME_TSEG1_Pos) |
<> 149:156823d33999 647 (u32Brp & CAN_BTIME_BRP_Msk) | (tCAN->BTIME & CAN_BTIME_SJW_Msk);
<> 149:156823d33999 648 tCAN->BTIME = u32Value;
<> 149:156823d33999 649 tCAN->BRPE = (u32Brp >> 6) & 0x0F;
<> 149:156823d33999 650
<> 149:156823d33999 651 CAN_LeaveInitMode(tCAN);
<> 149:156823d33999 652
<> 149:156823d33999 653 return (CAN_GetCANBitRate(tCAN));
<> 149:156823d33999 654 }
<> 149:156823d33999 655
<> 149:156823d33999 656 /**
<> 149:156823d33999 657 * @brief The function is used to disable all CAN interrupt.
<> 149:156823d33999 658 *
<> 149:156823d33999 659 * @param[in] tCAN The pointer to CAN module base address.
<> 149:156823d33999 660 *
<> 149:156823d33999 661 * @return None
<> 149:156823d33999 662 *
<> 149:156823d33999 663 * @details No Status Change Interrupt and Error Status Interrupt will be generated.
<> 149:156823d33999 664 */
<> 149:156823d33999 665 void CAN_Close(CAN_T *tCAN)
<> 149:156823d33999 666 {
<> 149:156823d33999 667 CAN_DisableInt(tCAN, (CAN_CON_IE_Msk | CAN_CON_SIE_Msk | CAN_CON_EIE_Msk));
<> 149:156823d33999 668 }
<> 149:156823d33999 669
<> 149:156823d33999 670 /**
<> 149:156823d33999 671 * @brief Set CAN operation mode and target baud-rate.
<> 149:156823d33999 672 *
<> 149:156823d33999 673 * @param[in] tCAN The pointer to CAN module base address.
<> 149:156823d33999 674 * @param[in] u32BaudRate The target CAN baud-rate. The range of u32BaudRate is 1~1000KHz.
<> 149:156823d33999 675 * @param[in] u32Mode The CAN operation mode. Valid values are:
<> 149:156823d33999 676 * - \ref CAN_NORMAL_MODE Normal operation.
<> 149:156823d33999 677 * - \ref CAN_BASIC_MODE Basic mode.
<> 149:156823d33999 678 * @return u32CurrentBitRate Real baud-rate value.
<> 149:156823d33999 679 *
<> 149:156823d33999 680 * @details Set bus timing parameter according current clock and target baud-rate.
<> 149:156823d33999 681 * In Basic mode, IF1 Registers used as Tx Buffer, IF2 Registers used as Rx Buffer.
<> 149:156823d33999 682 */
<> 149:156823d33999 683 uint32_t CAN_Open(CAN_T *tCAN, uint32_t u32BaudRate, uint32_t u32Mode)
<> 149:156823d33999 684 {
<> 149:156823d33999 685 uint32_t u32CurrentBitRate;
<> 149:156823d33999 686
<> 149:156823d33999 687 u32CurrentBitRate = CAN_SetBaudRate(tCAN, u32BaudRate);
<> 149:156823d33999 688
<> 149:156823d33999 689 if(u32Mode == CAN_BASIC_MODE)
<> 149:156823d33999 690 CAN_EnterTestMode(tCAN, CAN_TEST_BASIC_Msk);
<> 149:156823d33999 691
<> 149:156823d33999 692 return u32CurrentBitRate;
<> 149:156823d33999 693 }
<> 149:156823d33999 694
<> 149:156823d33999 695 /**
<> 149:156823d33999 696 * @brief The function is used to configure a transmit object.
<> 149:156823d33999 697 *
<> 149:156823d33999 698 * @param[in] tCAN The pointer to CAN module base address.
<> 149:156823d33999 699 * @param[in] u32MsgNum Specifies the Message object number, from 0 to 31.
<> 149:156823d33999 700 * @param[in] pCanMsg Pointer to the message structure where received data is copied.
<> 149:156823d33999 701 *
<> 149:156823d33999 702 * @retval FALSE No useful interface.
<> 149:156823d33999 703 * @retval TRUE Config message object success.
<> 149:156823d33999 704 *
<> 149:156823d33999 705 * @details The two sets of interface registers (IF1 and IF2) control the software access to the Message RAM.
<> 149:156823d33999 706 * They buffer the data to be transferred to and from the RAM, avoiding conflicts between software accesses and message reception/transmission.
<> 149:156823d33999 707 */
<> 149:156823d33999 708 int32_t CAN_SetTxMsg(CAN_T *tCAN, uint32_t u32MsgNum , STR_CANMSG_T* pCanMsg)
<> 149:156823d33999 709 {
<> 149:156823d33999 710 uint8_t u8MsgIfNum;
<> 149:156823d33999 711
<> 149:156823d33999 712 if((u8MsgIfNum = LockIF_TL(tCAN)) == 2)
<> 149:156823d33999 713 return FALSE;
<> 149:156823d33999 714
<> 149:156823d33999 715 /* update the contents needed for transmission*/
<> 149:156823d33999 716 tCAN->IF[u8MsgIfNum].CMASK = CAN_IF_CMASK_WRRD_Msk | CAN_IF_CMASK_MASK_Msk | CAN_IF_CMASK_ARB_Msk |
<> 149:156823d33999 717 CAN_IF_CMASK_CONTROL_Msk | CAN_IF_CMASK_DATAA_Msk | CAN_IF_CMASK_DATAB_Msk;
<> 149:156823d33999 718
<> 149:156823d33999 719 if(pCanMsg->IdType == CAN_STD_ID)
<> 149:156823d33999 720 {
<> 149:156823d33999 721 /* standard ID*/
<> 149:156823d33999 722 tCAN->IF[u8MsgIfNum].ARB1 = 0;
<> 149:156823d33999 723 tCAN->IF[u8MsgIfNum].ARB2 = (((pCanMsg->Id) & 0x7FF) << 2) | CAN_IF_ARB2_DIR_Msk | CAN_IF_ARB2_MSGVAL_Msk;
<> 149:156823d33999 724 }
<> 149:156823d33999 725 else
<> 149:156823d33999 726 {
<> 149:156823d33999 727 /* extended ID*/
<> 149:156823d33999 728 tCAN->IF[u8MsgIfNum].ARB1 = (pCanMsg->Id) & 0xFFFF;
<> 149:156823d33999 729 tCAN->IF[u8MsgIfNum].ARB2 = ((pCanMsg->Id) & 0x1FFF0000) >> 16 |
<> 149:156823d33999 730 CAN_IF_ARB2_DIR_Msk | CAN_IF_ARB2_XTD_Msk | CAN_IF_ARB2_MSGVAL_Msk;
<> 149:156823d33999 731 }
<> 149:156823d33999 732
<> 149:156823d33999 733 if(pCanMsg->FrameType)
<> 149:156823d33999 734 tCAN->IF[u8MsgIfNum].ARB2 |= CAN_IF_ARB2_DIR_Msk;
<> 149:156823d33999 735 else
<> 149:156823d33999 736 tCAN->IF[u8MsgIfNum].ARB2 &= (~CAN_IF_ARB2_DIR_Msk);
<> 149:156823d33999 737
<> 149:156823d33999 738 tCAN->IF[u8MsgIfNum].DAT_A1 = ((uint16_t)pCanMsg->Data[1] << 8) | pCanMsg->Data[0];
<> 149:156823d33999 739 tCAN->IF[u8MsgIfNum].DAT_A2 = ((uint16_t)pCanMsg->Data[3] << 8) | pCanMsg->Data[2];
<> 149:156823d33999 740 tCAN->IF[u8MsgIfNum].DAT_B1 = ((uint16_t)pCanMsg->Data[5] << 8) | pCanMsg->Data[4];
<> 149:156823d33999 741 tCAN->IF[u8MsgIfNum].DAT_B2 = ((uint16_t)pCanMsg->Data[7] << 8) | pCanMsg->Data[6];
<> 149:156823d33999 742
<> 149:156823d33999 743 tCAN->IF[u8MsgIfNum].MCON = CAN_IF_MCON_NEWDAT_Msk | pCanMsg->DLC | CAN_IF_MCON_TXIE_Msk | CAN_IF_MCON_EOB_Msk;
<> 149:156823d33999 744 tCAN->IF[u8MsgIfNum].CREQ = 1 + u32MsgNum;
<> 149:156823d33999 745
<> 149:156823d33999 746 ReleaseIF(tCAN, u8MsgIfNum);
<> 149:156823d33999 747 return TRUE;
<> 149:156823d33999 748 }
<> 149:156823d33999 749
<> 149:156823d33999 750 /**
<> 149:156823d33999 751 * @brief Set transmit request bit.
<> 149:156823d33999 752 *
<> 149:156823d33999 753 * @param[in] tCAN The pointer to CAN module base address.
<> 149:156823d33999 754 * @param[in] u32MsgNum Specifies the Message object number, from 0 to 31.
<> 149:156823d33999 755 *
<> 149:156823d33999 756 * @return TRUE: Start transmit message.
<> 149:156823d33999 757 *
<> 149:156823d33999 758 * @details If a transmission is requested by programming bit TxRqst/NewDat (IFn_CMASK[2]), the TxRqst (IFn_MCON[8]) will be ignored.
<> 149:156823d33999 759 */
<> 149:156823d33999 760 int32_t CAN_TriggerTxMsg(CAN_T *tCAN, uint32_t u32MsgNum)
<> 149:156823d33999 761 {
<> 149:156823d33999 762 uint8_t u8MsgIfNum;
<> 149:156823d33999 763
<> 149:156823d33999 764 if((u8MsgIfNum = LockIF_TL(tCAN)) == 2)
<> 149:156823d33999 765 return FALSE;
<> 149:156823d33999 766
<> 149:156823d33999 767 tCAN->STATUS &= (~CAN_STATUS_TXOK_Msk);
<> 149:156823d33999 768
<> 149:156823d33999 769 /* read the message contents*/
<> 149:156823d33999 770 tCAN->IF[u8MsgIfNum].CMASK = CAN_IF_CMASK_CLRINTPND_Msk
<> 149:156823d33999 771 | CAN_IF_CMASK_TXRQSTNEWDAT_Msk;
<> 149:156823d33999 772
<> 149:156823d33999 773 tCAN->IF[u8MsgIfNum].CREQ = 1 + u32MsgNum;
<> 149:156823d33999 774
<> 149:156823d33999 775 while(tCAN->IF[u8MsgIfNum].CREQ & CAN_IF_CREQ_BUSY_Msk)
<> 149:156823d33999 776 {
<> 149:156823d33999 777 /*Wait*/
<> 149:156823d33999 778 }
<> 149:156823d33999 779 tCAN->IF[u8MsgIfNum].CMASK = CAN_IF_CMASK_WRRD_Msk | CAN_IF_CMASK_TXRQSTNEWDAT_Msk;
<> 149:156823d33999 780 tCAN->IF[u8MsgIfNum].CREQ = 1 + u32MsgNum;
<> 149:156823d33999 781
<> 149:156823d33999 782 ReleaseIF(tCAN, u8MsgIfNum);
<> 149:156823d33999 783 return TRUE;
<> 149:156823d33999 784 }
<> 149:156823d33999 785
<> 149:156823d33999 786 /**
<> 149:156823d33999 787 * @brief Enable CAN interrupt.
<> 149:156823d33999 788 *
<> 149:156823d33999 789 * @param[in] tCAN The pointer to CAN module base address.
<> 149:156823d33999 790 * @param[in] u32Mask Interrupt Mask. Valid values are:
<> 149:156823d33999 791 * - \ref CAN_CON_IE_Msk Module interrupt enable.
<> 149:156823d33999 792 * - \ref CAN_CON_SIE_Msk Status change interrupt enable.
<> 149:156823d33999 793 * - \ref CAN_CON_EIE_Msk Error interrupt enable.
<> 149:156823d33999 794 *
<> 149:156823d33999 795 * @return None
<> 149:156823d33999 796 *
<> 149:156823d33999 797 * @details The application software has two possibilities to follow the source of a message interrupt.
<> 149:156823d33999 798 * First, it can follow the IntId in the Interrupt Register and second it can poll the Interrupt Pending Register.
<> 149:156823d33999 799 */
<> 149:156823d33999 800 void CAN_EnableInt(CAN_T *tCAN, uint32_t u32Mask)
<> 149:156823d33999 801 {
<> 149:156823d33999 802 tCAN->CON = (tCAN->CON & ~(CAN_CON_IE_Msk | CAN_CON_SIE_Msk | CAN_CON_EIE_Msk)) |
<> 149:156823d33999 803 (u32Mask & (CAN_CON_IE_Msk | CAN_CON_SIE_Msk | CAN_CON_EIE_Msk));
<> 149:156823d33999 804 }
<> 149:156823d33999 805
<> 149:156823d33999 806 /**
<> 149:156823d33999 807 * @brief Disable CAN interrupt.
<> 149:156823d33999 808 *
<> 149:156823d33999 809 * @param[in] tCAN The pointer to CAN module base address.
<> 149:156823d33999 810 * @param[in] u32Mask Interrupt Mask. (CAN_CON_IE_Msk / CAN_CON_SIE_Msk / CAN_CON_EIE_Msk).
<> 149:156823d33999 811 *
<> 149:156823d33999 812 * @return None
<> 149:156823d33999 813 *
<> 149:156823d33999 814 * @details The interrupt remains active until the Interrupt Register is back to value zero (the cause of the interrupt is reset) or until IE is reset.
<> 149:156823d33999 815 */
<> 149:156823d33999 816 void CAN_DisableInt(CAN_T *tCAN, uint32_t u32Mask)
<> 149:156823d33999 817 {
<> 149:156823d33999 818 tCAN->CON = tCAN->CON & ~((u32Mask & (CAN_CON_IE_Msk | CAN_CON_SIE_Msk | CAN_CON_EIE_Msk)));
<> 149:156823d33999 819 }
<> 149:156823d33999 820
<> 149:156823d33999 821
<> 149:156823d33999 822 /**
<> 149:156823d33999 823 * @brief The function is used to configure a receive message object.
<> 149:156823d33999 824 *
<> 149:156823d33999 825 * @param[in] tCAN The pointer to CAN module base address.
<> 149:156823d33999 826 * @param[in] u32MsgNum Specifies the Message object number, from 0 to 31.
<> 149:156823d33999 827 * @param[in] u32IDType Specifies the identifier type of the frames that will be transmitted. Valid values are:
<> 149:156823d33999 828 * - \ref CAN_STD_ID The 11-bit identifier.
<> 149:156823d33999 829 * - \ref CAN_EXT_ID The 29-bit identifier.
<> 149:156823d33999 830 * @param[in] u32ID Specifies the identifier used for acceptance filtering.
<> 149:156823d33999 831 *
<> 149:156823d33999 832 * @retval FALSE No useful interface.
<> 149:156823d33999 833 * @retval TRUE Configure a receive message object success.
<> 149:156823d33999 834 *
<> 149:156823d33999 835 * @details If the RxIE bit (CAN_IFn_MCON[10]) is set, the IntPnd bit (CAN_IFn_MCON[13])
<> 149:156823d33999 836 * will be set when a received Data Frame is accepted and stored in the Message Object.
<> 149:156823d33999 837 */
<> 149:156823d33999 838 int32_t CAN_SetRxMsg(CAN_T *tCAN, uint32_t u32MsgNum , uint32_t u32IDType, uint32_t u32ID)
<> 149:156823d33999 839 {
<> 149:156823d33999 840 uint32_t u32TimeOutCount = 0;
<> 149:156823d33999 841
<> 149:156823d33999 842 while(CAN_SetRxMsgObj(tCAN, u32MsgNum, u32IDType, u32ID, TRUE) == FALSE)
<> 149:156823d33999 843 {
<> 149:156823d33999 844 if(++u32TimeOutCount >= RETRY_COUNTS) return FALSE;
<> 149:156823d33999 845 }
<> 149:156823d33999 846
<> 149:156823d33999 847 return TRUE;
<> 149:156823d33999 848 }
<> 149:156823d33999 849
<> 149:156823d33999 850 /**
<> 149:156823d33999 851 * @brief The function is used to configure a receive message object.
<> 149:156823d33999 852 *
<> 149:156823d33999 853 * @param[in] tCAN The pointer to CAN module base address.
<> 149:156823d33999 854 * @param[in] u32MsgNum Specifies the Message object number, from 0 to 31.
<> 149:156823d33999 855 * @param[in] u32IDType Specifies the identifier type of the frames that will be transmitted. Valid values are:
<> 149:156823d33999 856 * - \ref CAN_STD_ID The 11-bit identifier.
<> 149:156823d33999 857 * - \ref CAN_EXT_ID The 29-bit identifier.
<> 149:156823d33999 858 * @param[in] u32ID Specifies the identifier used for acceptance filtering.
<> 149:156823d33999 859 * @param[in] u32IDMask Specifies the identifier mask used for acceptance filtering.
<> 149:156823d33999 860 *
<> 149:156823d33999 861 * @retval FALSE No useful interface.
<> 149:156823d33999 862 * @retval TRUE Configure a receive message object success.
<> 149:156823d33999 863 *
<> 149:156823d33999 864 * @details If the RxIE bit (CAN_IFn_MCON[10]) is set, the IntPnd bit (CAN_IFn_MCON[13])
<> 149:156823d33999 865 * will be set when a received Data Frame is accepted and stored in the Message Object.
<> 149:156823d33999 866 */
<> 149:156823d33999 867 int32_t CAN_SetRxMsgAndMsk(CAN_T *tCAN, uint32_t u32MsgNum , uint32_t u32IDType, uint32_t u32ID, uint32_t u32IDMask)
<> 149:156823d33999 868 {
<> 149:156823d33999 869 uint32_t u32TimeOutCount = 0;
<> 149:156823d33999 870
<> 149:156823d33999 871 while(CAN_SetRxMsgObjAndMsk(tCAN, u32MsgNum, u32IDType, u32ID, u32IDMask, TRUE) == FALSE)
<> 149:156823d33999 872 {
<> 149:156823d33999 873 if(++u32TimeOutCount >= RETRY_COUNTS) return FALSE;
<> 149:156823d33999 874 }
<> 149:156823d33999 875
<> 149:156823d33999 876 return TRUE;
<> 149:156823d33999 877 }
<> 149:156823d33999 878
<> 149:156823d33999 879 /**
<> 149:156823d33999 880 * @brief The function is used to configure several receive message objects.
<> 149:156823d33999 881 *
<> 149:156823d33999 882 * @param[in] tCAN The pointer to CAN module base address.
<> 149:156823d33999 883 * @param[in] u32MsgNum The starting MSG RAM number(0 ~ 31).
<> 149:156823d33999 884 * @param[in] u32MsgCount the number of MSG RAM of the FIFO.
<> 149:156823d33999 885 * @param[in] u32IDType Specifies the identifier type of the frames that will be transmitted. Valid values are:
<> 149:156823d33999 886 * - \ref CAN_STD_ID The 11-bit identifier.
<> 149:156823d33999 887 * - \ref CAN_EXT_ID The 29-bit identifier.
<> 149:156823d33999 888 * @param[in] u32ID Specifies the identifier used for acceptance filtering.
<> 149:156823d33999 889 *
<> 149:156823d33999 890 * @retval FALSE No useful interface.
<> 149:156823d33999 891 * @retval TRUE Configure receive message objects success.
<> 149:156823d33999 892 *
<> 149:156823d33999 893 * @details The Interface Registers avoid conflict between the CPU accesses to the Message RAM and CAN message reception
<> 149:156823d33999 894 * and transmission by buffering the data to be transferred.
<> 149:156823d33999 895 */
<> 149:156823d33999 896 int32_t CAN_SetMultiRxMsg(CAN_T *tCAN, uint32_t u32MsgNum , uint32_t u32MsgCount, uint32_t u32IDType, uint32_t u32ID)
<> 149:156823d33999 897 {
<> 149:156823d33999 898 uint32_t i = 0;
<> 149:156823d33999 899 uint32_t u32TimeOutCount;
<> 149:156823d33999 900 uint32_t u32EOB_Flag = 0;
<> 149:156823d33999 901
<> 149:156823d33999 902 for(i = 1; i < u32MsgCount; i++)
<> 149:156823d33999 903 {
<> 149:156823d33999 904 u32TimeOutCount = 0;
<> 149:156823d33999 905
<> 149:156823d33999 906 u32MsgNum += (i - 1);
<> 149:156823d33999 907
<> 149:156823d33999 908 if(i == u32MsgCount) u32EOB_Flag = 1;
<> 149:156823d33999 909
<> 149:156823d33999 910 while(CAN_SetRxMsgObj(tCAN, u32MsgNum, u32IDType, u32ID, u32EOB_Flag) == FALSE)
<> 149:156823d33999 911 {
<> 149:156823d33999 912 if(++u32TimeOutCount >= RETRY_COUNTS) return FALSE;
<> 149:156823d33999 913 }
<> 149:156823d33999 914 }
<> 149:156823d33999 915
<> 149:156823d33999 916 return TRUE;
<> 149:156823d33999 917 }
<> 149:156823d33999 918
<> 149:156823d33999 919
<> 149:156823d33999 920 /**
<> 149:156823d33999 921 * @brief Send CAN message.
<> 149:156823d33999 922 * @param[in] tCAN The pointer to CAN module base address.
<> 149:156823d33999 923 * @param[in] u32MsgNum Specifies the Message object number, from 0 to 31.
<> 149:156823d33999 924 * @param[in] pCanMsg Pointer to the message structure where received data is copied.
<> 149:156823d33999 925 *
<> 149:156823d33999 926 * @retval FALSE 1. When operation in basic mode: Transmit message time out. \n
<> 149:156823d33999 927 * 2. When operation in normal mode: No useful interface. \n
<> 149:156823d33999 928 * @retval TRUE Transmit Message success.
<> 149:156823d33999 929 *
<> 149:156823d33999 930 * @details The receive/transmit priority for the Message Objects is attached to the message number.
<> 149:156823d33999 931 * Message Object 1 has the highest priority, while Message Object 32 has the lowest priority.
<> 149:156823d33999 932 */
<> 149:156823d33999 933 int32_t CAN_Transmit(CAN_T *tCAN, uint32_t u32MsgNum , STR_CANMSG_T* pCanMsg)
<> 149:156823d33999 934 {
<> 149:156823d33999 935 if((tCAN->CON & CAN_CON_TEST_Msk) && (tCAN->TEST & CAN_TEST_BASIC_Msk))
<> 149:156823d33999 936 {
<> 149:156823d33999 937 return (CAN_BasicSendMsg(tCAN, pCanMsg));
<> 149:156823d33999 938 }
<> 149:156823d33999 939 else
<> 149:156823d33999 940 {
<> 149:156823d33999 941 if(CAN_SetTxMsg(tCAN, u32MsgNum, pCanMsg) == FALSE)
<> 149:156823d33999 942 return FALSE;
<> 149:156823d33999 943 CAN_TriggerTxMsg(tCAN, u32MsgNum);
<> 149:156823d33999 944 }
<> 149:156823d33999 945
<> 149:156823d33999 946 return TRUE;
<> 149:156823d33999 947 }
<> 149:156823d33999 948
<> 149:156823d33999 949
<> 149:156823d33999 950 /**
<> 149:156823d33999 951 * @brief Gets the message, if received.
<> 149:156823d33999 952 * @param[in] tCAN The pointer to CAN module base address.
<> 149:156823d33999 953 * @param[in] u32MsgNum Specifies the Message object number, from 0 to 31.
<> 149:156823d33999 954 * @param[in] pCanMsg Pointer to the message structure where received data is copied.
<> 149:156823d33999 955 *
<> 149:156823d33999 956 * @retval FALSE No any message received.
<> 149:156823d33999 957 * @retval TRUE Receive Message success.
<> 149:156823d33999 958 *
<> 149:156823d33999 959 * @details The Interface Registers avoid conflict between the CPU accesses to the Message RAM and CAN message reception
<> 149:156823d33999 960 * and transmission by buffering the data to be transferred.
<> 149:156823d33999 961 */
<> 149:156823d33999 962 int32_t CAN_Receive(CAN_T *tCAN, uint32_t u32MsgNum , STR_CANMSG_T* pCanMsg)
<> 149:156823d33999 963 {
<> 149:156823d33999 964 if((tCAN->CON & CAN_CON_TEST_Msk) && (tCAN->TEST & CAN_TEST_BASIC_Msk))
<> 149:156823d33999 965 {
<> 149:156823d33999 966 return (CAN_BasicReceiveMsg(tCAN, pCanMsg));
<> 149:156823d33999 967 }
<> 149:156823d33999 968 else
<> 149:156823d33999 969 {
<> 149:156823d33999 970 return CAN_ReadMsgObj(tCAN, u32MsgNum, TRUE, pCanMsg);
<> 149:156823d33999 971 }
<> 149:156823d33999 972 }
<> 149:156823d33999 973
<> 149:156823d33999 974 /**
<> 149:156823d33999 975 * @brief Clear interrupt pending bit.
<> 149:156823d33999 976 * @param[in] tCAN The pointer to CAN module base address.
<> 149:156823d33999 977 * @param[in] u32MsgNum Specifies the Message object number, from 0 to 31.
<> 149:156823d33999 978 *
<> 149:156823d33999 979 * @return None
<> 149:156823d33999 980 *
<> 149:156823d33999 981 * @details An interrupt remains pending until the application software has cleared it.
<> 149:156823d33999 982 */
<> 149:156823d33999 983 void CAN_CLR_INT_PENDING_BIT(CAN_T *tCAN, uint8_t u32MsgNum)
<> 149:156823d33999 984 {
<> 149:156823d33999 985 uint32_t u32MsgIfNum;
<> 149:156823d33999 986
<> 149:156823d33999 987 if((u32MsgIfNum = LockIF_TL(tCAN)) == 2)
<> 149:156823d33999 988 u32MsgIfNum = 0;
<> 149:156823d33999 989
<> 149:156823d33999 990 tCAN->IF[u32MsgIfNum].CMASK = CAN_IF_CMASK_CLRINTPND_Msk | CAN_IF_CMASK_TXRQSTNEWDAT_Msk;
<> 149:156823d33999 991 tCAN->IF[u32MsgIfNum].CREQ = 1 + u32MsgNum;
<> 149:156823d33999 992
<> 149:156823d33999 993 ReleaseIF(tCAN, u32MsgIfNum);
<> 149:156823d33999 994 }
<> 149:156823d33999 995
<> 149:156823d33999 996
<> 149:156823d33999 997 /*@}*/ /* end of group CAN_EXPORTED_FUNCTIONS */
<> 149:156823d33999 998
<> 149:156823d33999 999 /*@}*/ /* end of group CAN_Driver */
<> 149:156823d33999 1000
<> 149:156823d33999 1001 /*@}*/ /* end of group Standard_Driver */
<> 149:156823d33999 1002
<> 149:156823d33999 1003 /*** (C) COPYRIGHT 2014~2015 Nuvoton Technology Corp. ***/
<> 149:156823d33999 1004