fsl_mcan.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862
  1. /*
  2. * Copyright (c) 2016, Freescale Semiconductor, Inc.
  3. * Copyright 2016-2017 NXP
  4. *
  5. * Redistribution and use in source and binary forms, with or without modification,
  6. * are permitted provided that the following conditions are met:
  7. *
  8. * o Redistributions of source code must retain the above copyright notice, this list
  9. * of conditions and the following disclaimer.
  10. *
  11. * o Redistributions in binary form must reproduce the above copyright notice, this
  12. * list of conditions and the following disclaimer in the documentation and/or
  13. * other materials provided with the distribution.
  14. *
  15. * o Neither the name of the copyright holder nor the names of its
  16. * contributors may be used to endorse or promote products derived from this
  17. * software without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  20. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  21. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  22. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
  23. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  24. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  25. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  26. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  28. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. */
  30. #include "fsl_mcan.h"
  31. /*******************************************************************************
  32. * Definitons
  33. ******************************************************************************/
  34. #define MCAN_TIME_QUANTA_NUM (16U)
  35. /*! @brief MCAN Internal State. */
  36. enum _mcan_state
  37. {
  38. kMCAN_StateIdle = 0x0, /*!< MB/RxFIFO idle.*/
  39. kMCAN_StateRxData = 0x1, /*!< MB receiving.*/
  40. kMCAN_StateRxRemote = 0x2, /*!< MB receiving remote reply.*/
  41. kMCAN_StateTxData = 0x3, /*!< MB transmitting.*/
  42. kMCAN_StateTxRemote = 0x4, /*!< MB transmitting remote request.*/
  43. kMCAN_StateRxFifo = 0x5, /*!< RxFIFO receiving.*/
  44. };
  45. /* Typedef for interrupt handler. */
  46. typedef void (*mcan_isr_t)(CAN_Type *base, mcan_handle_t *handle);
  47. /*******************************************************************************
  48. * Prototypes
  49. ******************************************************************************/
  50. /*!
  51. * @brief Get the MCAN instance from peripheral base address.
  52. *
  53. * @param base MCAN peripheral base address.
  54. * @return MCAN instance.
  55. */
  56. uint32_t MCAN_GetInstance(CAN_Type *base);
  57. /*!
  58. * @brief Reset the MCAN instance.
  59. *
  60. * @param base MCAN peripheral base address.
  61. */
  62. static void MCAN_Reset(CAN_Type *base);
  63. /*!
  64. * @brief Set Baud Rate of MCAN.
  65. *
  66. * This function set the baud rate of MCAN.
  67. *
  68. * @param base MCAN peripheral base address.
  69. * @param sourceClock_Hz Source Clock in Hz.
  70. * @param baudRate_Bps Baud Rate in Bps.
  71. */
  72. static void MCAN_SetBaudRate(CAN_Type *base, uint32_t sourceClock_Hz, uint32_t baudRateA_Bps);
  73. #if (defined(FSL_FEATURE_CAN_SUPPORT_CANFD) && FSL_FEATURE_CAN_SUPPORT_CANFD)
  74. /*!
  75. * @brief Set Baud Rate of MCAN FD.
  76. *
  77. * This function set the baud rate of MCAN FD.
  78. *
  79. * @param base MCAN peripheral base address.
  80. * @param sourceClock_Hz Source Clock in Hz.
  81. * @param baudRateD_Bps Baud Rate in Bps.
  82. */
  83. static void MCAN_SetBaudRateFD(CAN_Type *base, uint32_t sourceClock_Hz, uint32_t baudRateD_Bps);
  84. #endif /* FSL_FEATURE_CAN_SUPPORT_CANFD */
  85. /*!
  86. * @brief Get the element's address when read receive fifo 0.
  87. *
  88. * @param base MCAN peripheral base address.
  89. * @return Address of the element in receive fifo 0.
  90. */
  91. static uint32_t MCAN_GetRxFifo0ElementAddress(CAN_Type *base);
  92. /*!
  93. * @brief Get the element's address when read receive fifo 1.
  94. *
  95. * @param base MCAN peripheral base address.
  96. * @return Address of the element in receive fifo 1.
  97. */
  98. static uint32_t MCAN_GetRxFifo1ElementAddress(CAN_Type *base);
  99. /*!
  100. * @brief Get the element's address when read receive buffer.
  101. *
  102. * @param base MCAN peripheral base address.
  103. * @param idx Number of the erceive buffer element.
  104. * @return Address of the element in receive buffer.
  105. */
  106. static uint32_t MCAN_GetRxBufferElementAddress(CAN_Type *base, uint8_t idx);
  107. /*!
  108. * @brief Get the element's address when read transmit buffer.
  109. *
  110. * @param base MCAN peripheral base address.
  111. * @param idx Number of the transmit buffer element.
  112. * @return Address of the element in transmit buffer.
  113. */
  114. static uint32_t MCAN_GetTxBufferElementAddress(CAN_Type *base, uint8_t idx);
  115. /*******************************************************************************
  116. * Variables
  117. ******************************************************************************/
  118. /* Array of MCAN handle. */
  119. static mcan_handle_t *s_mcanHandle[FSL_FEATURE_SOC_LPC_CAN_COUNT];
  120. /* Array of MCAN peripheral base address. */
  121. static CAN_Type *const s_mcanBases[] = CAN_BASE_PTRS;
  122. /* Array of MCAN IRQ number. */
  123. static const IRQn_Type s_mcanIRQ[][2] = CAN_IRQS;
  124. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  125. /* Array of MCAN clock name. */
  126. static const clock_ip_name_t s_mcanClock[] = MCAN_CLOCKS;
  127. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  128. /* MCAN ISR for transactional APIs. */
  129. static mcan_isr_t s_mcanIsr;
  130. /*******************************************************************************
  131. * Code
  132. ******************************************************************************/
  133. uint32_t MCAN_GetInstance(CAN_Type *base)
  134. {
  135. uint32_t instance;
  136. /* Find the instance index from base address mappings. */
  137. for (instance = 0; instance < ARRAY_SIZE(s_mcanBases); instance++)
  138. {
  139. if (s_mcanBases[instance] == base)
  140. {
  141. break;
  142. }
  143. }
  144. assert(instance < ARRAY_SIZE(s_mcanBases));
  145. return instance;
  146. }
  147. static void MCAN_Reset(CAN_Type *base)
  148. {
  149. /* Set INIT bit. */
  150. base->CCCR |= CAN_CCCR_INIT_MASK;
  151. /* Confirm the value has been accepted. */
  152. while (!((base->CCCR & CAN_CCCR_INIT_MASK) >> CAN_CCCR_INIT_SHIFT))
  153. {
  154. }
  155. /* Set CCE bit to have access to the protected configuration registers,
  156. and clear some status registers. */
  157. base->CCCR |= CAN_CCCR_CCE_MASK;
  158. }
  159. static void MCAN_SetBaudRate(CAN_Type *base, uint32_t sourceClock_Hz, uint32_t baudRateA_Bps)
  160. {
  161. mcan_timing_config_t timingConfigA;
  162. uint32_t preDivA = baudRateA_Bps * MCAN_TIME_QUANTA_NUM;
  163. if (0 == preDivA)
  164. {
  165. preDivA = 1U;
  166. }
  167. preDivA = (sourceClock_Hz / preDivA) - 1U;
  168. /* Desired baud rate is too low. */
  169. if (preDivA > 0x1FFU)
  170. {
  171. preDivA = 0x1FFU;
  172. }
  173. /* MCAN timing setting formula:
  174. * MCAN_TIME_QUANTA_NUM = 1 + (xTSEG1 + 1) + (xTSEG2 + 1));
  175. */
  176. timingConfigA.preDivider = preDivA;
  177. timingConfigA.seg1 = 0xAU;
  178. timingConfigA.seg2 = 0x3U;
  179. timingConfigA.rJumpwidth = 0x3U;
  180. /* Update actual timing characteristic. */
  181. MCAN_SetArbitrationTimingConfig(base, &timingConfigA);
  182. }
  183. #if (defined(FSL_FEATURE_CAN_SUPPORT_CANFD) && FSL_FEATURE_CAN_SUPPORT_CANFD)
  184. static void MCAN_SetBaudRateFD(CAN_Type *base, uint32_t sourceClock_Hz, uint32_t baudRateD_Bps)
  185. {
  186. mcan_timing_config_t timingConfigD;
  187. uint32_t preDivD = baudRateD_Bps * MCAN_TIME_QUANTA_NUM;
  188. if (0 == preDivD)
  189. {
  190. preDivD = 1U;
  191. }
  192. preDivD = (sourceClock_Hz / preDivD) - 1U;
  193. /* Desired baud rate is too low. */
  194. if (preDivD > 0x1FU)
  195. {
  196. preDivD = 0x1FU;
  197. }
  198. /* MCAN timing setting formula:
  199. * MCAN_TIME_QUANTA_NUM = 1 + (xTSEG1 + 1) + (xTSEG2 + 1));
  200. */
  201. timingConfigD.preDivider = preDivD;
  202. timingConfigD.seg1 = 0xAU;
  203. timingConfigD.seg2 = 0x3U;
  204. timingConfigD.rJumpwidth = 0x3U;
  205. /* Update actual timing characteristic. */
  206. MCAN_SetDataTimingConfig(base, &timingConfigD);
  207. }
  208. #endif
  209. void MCAN_Init(CAN_Type *base, const mcan_config_t *config, uint32_t sourceClock_Hz)
  210. {
  211. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  212. /* Enable MCAN clock. */
  213. CLOCK_EnableClock(s_mcanClock[MCAN_GetInstance(base)]);
  214. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  215. MCAN_Reset(base);
  216. if (config->enableLoopBackInt)
  217. {
  218. base->CCCR |= CAN_CCCR_TEST_MASK | CAN_CCCR_MON_MASK;
  219. base->TEST |= CAN_TEST_LBCK_MASK;
  220. }
  221. if (config->enableLoopBackExt)
  222. {
  223. base->CCCR |= CAN_CCCR_TEST_MASK;
  224. base->TEST |= CAN_TEST_LBCK_MASK;
  225. }
  226. if (config->enableBusMon)
  227. {
  228. base->CCCR |= CAN_CCCR_MON_MASK;
  229. }
  230. #if (defined(FSL_FEATURE_CAN_SUPPORT_CANFD) && FSL_FEATURE_CAN_SUPPORT_CANFD)
  231. if (config->enableCanfdNormal)
  232. {
  233. base->CCCR |= CAN_CCCR_FDOE_MASK;
  234. }
  235. if (config->enableCanfdSwitch)
  236. {
  237. base->CCCR |= CAN_CCCR_FDOE_MASK | CAN_CCCR_BRSE_MASK;
  238. }
  239. #endif
  240. /* Set baud rate of arbitration and data phase. */
  241. MCAN_SetBaudRate(base, sourceClock_Hz, config->baudRateA);
  242. #if (defined(FSL_FEATURE_CAN_SUPPORT_CANFD) && FSL_FEATURE_CAN_SUPPORT_CANFD)
  243. MCAN_SetBaudRateFD(base, sourceClock_Hz, config->baudRateD);
  244. #endif
  245. }
  246. void MCAN_Deinit(CAN_Type *base)
  247. {
  248. /* Reset all Register Contents. */
  249. MCAN_Reset(base);
  250. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  251. /* Disable MCAN clock. */
  252. CLOCK_DisableClock(s_mcanClock[MCAN_GetInstance(base)]);
  253. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  254. }
  255. void MCAN_EnterNormalMode(CAN_Type *base)
  256. {
  257. /* Reset INIT bit to enter normal mode. */
  258. base->CCCR &= ~CAN_CCCR_INIT_MASK;
  259. while (((base->CCCR & CAN_CCCR_INIT_MASK) >> CAN_CCCR_INIT_SHIFT))
  260. {
  261. }
  262. }
  263. void MCAN_GetDefaultConfig(mcan_config_t *config)
  264. {
  265. /* Assertion. */
  266. assert(config);
  267. /* Initialize MCAN Module config struct with default value. */
  268. config->baudRateA = 500000U;
  269. config->baudRateD = 500000U;
  270. config->enableCanfdNormal = false;
  271. config->enableCanfdSwitch = false;
  272. config->enableLoopBackInt = false;
  273. config->enableLoopBackExt = false;
  274. config->enableBusMon = false;
  275. }
  276. #if (defined(FSL_FEATURE_CAN_SUPPORT_CANFD) && FSL_FEATURE_CAN_SUPPORT_CANFD)
  277. void MCAN_SetDataTimingConfig(CAN_Type *base, const mcan_timing_config_t *config)
  278. {
  279. /* Assertion. */
  280. assert(config);
  281. /* Cleaning previous Timing Setting. */
  282. base->DBTP &= ~(CAN_DBTP_DSJW_MASK | CAN_DBTP_DTSEG2_MASK | CAN_DBTP_DTSEG1_MASK | CAN_DBTP_DBRP_MASK);
  283. /* Updating Timing Setting according to configuration structure. */
  284. base->DBTP |= (CAN_DBTP_DBRP(config->preDivider) | CAN_DBTP_DSJW(config->rJumpwidth) |
  285. CAN_DBTP_DTSEG1(config->seg1) | CAN_DBTP_DTSEG2(config->seg2));
  286. }
  287. #endif /* FSL_FEATURE_CAN_SUPPORT_CANFD */
  288. void MCAN_SetArbitrationTimingConfig(CAN_Type *base, const mcan_timing_config_t *config)
  289. {
  290. /* Assertion. */
  291. assert(config);
  292. /* Cleaning previous Timing Setting. */
  293. base->NBTP &= ~(CAN_NBTP_NSJW_MASK | CAN_NBTP_NTSEG2_MASK | CAN_NBTP_NTSEG1_MASK | CAN_NBTP_NBRP_MASK);
  294. /* Updating Timing Setting according to configuration structure. */
  295. base->NBTP |= (CAN_NBTP_NBRP(config->preDivider) | CAN_NBTP_NSJW(config->rJumpwidth) |
  296. CAN_NBTP_NTSEG1(config->seg1) | CAN_NBTP_NTSEG2(config->seg2));
  297. }
  298. void MCAN_SetFilterConfig(CAN_Type *base, const mcan_frame_filter_config_t *config)
  299. {
  300. /* Set global configuration of remote/nonmasking frames, set filter address and list size. */
  301. if (config->idFormat == kMCAN_FrameIDStandard)
  302. {
  303. base->GFC |= CAN_GFC_RRFS(config->remFrame) | CAN_GFC_ANFS(config->nmFrame);
  304. base->SIDFC |= CAN_SIDFC_FLSSA(config->address >> CAN_SIDFC_FLSSA_SHIFT) | CAN_SIDFC_LSS(config->listSize);
  305. }
  306. else
  307. {
  308. base->GFC |= CAN_GFC_RRFE(config->remFrame) | CAN_GFC_ANFE(config->nmFrame);
  309. base->XIDFC |= CAN_XIDFC_FLESA(config->address >> CAN_XIDFC_FLESA_SHIFT) | CAN_XIDFC_LSE(config->listSize);
  310. }
  311. }
  312. void MCAN_SetRxFifo0Config(CAN_Type *base, const mcan_rx_fifo_config_t *config)
  313. {
  314. /* Set Rx FIFO 0 start address, element size, watermark, operation mode. */
  315. base->RXF0C |= CAN_RXF0C_F0SA(config->address >> CAN_RXF0C_F0SA_SHIFT) | CAN_RXF0C_F0S(config->elementSize) |
  316. CAN_RXF0C_F0WM(config->watermark) | CAN_RXF0C_F0OM(config->opmode);
  317. /* Set Rx FIFO 0 data field size */
  318. base->RXESC |= CAN_RXESC_F0DS(config->datafieldSize);
  319. }
  320. void MCAN_SetRxFifo1Config(CAN_Type *base, const mcan_rx_fifo_config_t *config)
  321. {
  322. /* Set Rx FIFO 1 start address, element size, watermark, operation mode. */
  323. base->RXF1C |= CAN_RXF1C_F1SA(config->address >> CAN_RXF1C_F1SA_SHIFT) | CAN_RXF1C_F1S(config->elementSize) |
  324. CAN_RXF1C_F1WM(config->watermark) | CAN_RXF1C_F1OM(config->opmode);
  325. /* Set Rx FIFO 1 data field size */
  326. base->RXESC |= CAN_RXESC_F1DS(config->datafieldSize);
  327. }
  328. void MCAN_SetRxBufferConfig(CAN_Type *base, const mcan_rx_buffer_config_t *config)
  329. {
  330. /* Set Rx Buffer start address. */
  331. base->RXBC |= CAN_RXBC_RBSA(config->address >> CAN_RXBC_RBSA_SHIFT);
  332. /* Set Rx Buffer data field size */
  333. base->RXESC |= CAN_RXESC_RBDS(config->datafieldSize);
  334. }
  335. void MCAN_SetTxEventFifoConfig(CAN_Type *base, const mcan_tx_fifo_config_t *config)
  336. {
  337. /* Set TX Event FIFO start address, element size, watermark. */
  338. base->TXEFC |= CAN_TXEFC_EFSA(config->address >> CAN_TXEFC_EFSA_SHIFT) | CAN_TXEFC_EFS(config->elementSize) |
  339. CAN_TXEFC_EFWM(config->watermark);
  340. }
  341. void MCAN_SetTxBufferConfig(CAN_Type *base, const mcan_tx_buffer_config_t *config)
  342. {
  343. assert((config->dedicatedSize + config->fqSize) <= 32U);
  344. /* Set Tx Buffer start address, size, fifo/queue mode. */
  345. base->TXBC |= CAN_TXBC_TBSA(config->address >> CAN_TXBC_TBSA_SHIFT) | CAN_TXBC_NDTB(config->dedicatedSize) |
  346. CAN_TXBC_TFQS(config->fqSize) | CAN_TXBC_TFQM(config->mode);
  347. /* Set Tx Buffer data field size */
  348. base->TXESC |= CAN_TXESC_TBDS(config->datafieldSize);
  349. }
  350. void MCAN_SetSTDFilterElement(CAN_Type *base,
  351. const mcan_frame_filter_config_t *config,
  352. const mcan_std_filter_element_config_t *filter,
  353. uint8_t idx)
  354. {
  355. uint8_t *elementAddress = 0;
  356. elementAddress = (uint8_t *)(MCAN_GetMsgRAMBase(base) + config->address + idx * 4U);
  357. memcpy(elementAddress, filter, sizeof(*filter));
  358. }
  359. void MCAN_SetEXTFilterElement(CAN_Type *base,
  360. const mcan_frame_filter_config_t *config,
  361. const mcan_ext_filter_element_config_t *filter,
  362. uint8_t idx)
  363. {
  364. uint8_t *elementAddress = 0;
  365. elementAddress = (uint8_t *)(MCAN_GetMsgRAMBase(base) + config->address + idx * 8U);
  366. memcpy(elementAddress, filter, sizeof(*filter));
  367. }
  368. static uint32_t MCAN_GetRxFifo0ElementAddress(CAN_Type *base)
  369. {
  370. uint32_t eSize;
  371. eSize = (base->RXESC & CAN_RXESC_F0DS_MASK) >> CAN_RXESC_F0DS_SHIFT;
  372. if (eSize < 5U)
  373. {
  374. eSize += 4U;
  375. }
  376. else
  377. {
  378. eSize = eSize * 4U - 10U;
  379. }
  380. return (base->RXF0C & CAN_RXF0C_F0SA_MASK) +
  381. ((base->RXF0S & CAN_RXF0S_F0GI_MASK) >> CAN_RXF0S_F0GI_SHIFT) * eSize * 4U;
  382. }
  383. static uint32_t MCAN_GetRxFifo1ElementAddress(CAN_Type *base)
  384. {
  385. uint32_t eSize;
  386. eSize = (base->RXESC & CAN_RXESC_F1DS_MASK) >> CAN_RXESC_F1DS_SHIFT;
  387. if (eSize < 5U)
  388. {
  389. eSize += 4U;
  390. }
  391. else
  392. {
  393. eSize = eSize * 4U - 10U;
  394. }
  395. return (base->RXF1C & CAN_RXF1C_F1SA_MASK) +
  396. ((base->RXF1S & CAN_RXF1S_F1GI_MASK) >> CAN_RXF1S_F1GI_SHIFT) * eSize * 4U;
  397. }
  398. static uint32_t MCAN_GetRxBufferElementAddress(CAN_Type *base, uint8_t idx)
  399. {
  400. assert(idx <= 63U);
  401. uint32_t eSize;
  402. eSize = (base->RXESC & CAN_RXESC_RBDS_MASK) >> CAN_RXESC_RBDS_SHIFT;
  403. if (eSize < 5U)
  404. {
  405. eSize += 4U;
  406. }
  407. else
  408. {
  409. eSize = eSize * 4U - 10U;
  410. }
  411. return (base->RXBC & CAN_RXBC_RBSA_MASK) + idx * eSize * 4U;
  412. }
  413. static uint32_t MCAN_GetTxBufferElementAddress(CAN_Type *base, uint8_t idx)
  414. {
  415. assert(idx <= 31U);
  416. uint32_t eSize;
  417. eSize = (base->TXESC & CAN_TXESC_TBDS_MASK) >> CAN_TXESC_TBDS_SHIFT;
  418. if (eSize < 5U)
  419. {
  420. eSize += 4U;
  421. }
  422. else
  423. {
  424. eSize = eSize * 4U - 10U;
  425. }
  426. return (base->TXBC & CAN_TXBC_TBSA_MASK) + idx * eSize * 4U;
  427. }
  428. uint32_t MCAN_IsTransmitRequestPending(CAN_Type *base, uint8_t idx)
  429. {
  430. return (base->TXBRP & (uint32_t)(1U << idx)) >> (uint32_t)idx;
  431. }
  432. uint32_t MCAN_IsTransmitOccurred(CAN_Type *base, uint8_t idx)
  433. {
  434. return (base->TXBTO & (uint32_t)(1U << idx)) >> (uint32_t)idx;
  435. }
  436. status_t MCAN_WriteTxBuffer(CAN_Type *base, uint8_t idx, const mcan_tx_buffer_frame_t *txFrame)
  437. {
  438. if (!MCAN_IsTransmitRequestPending(base, idx))
  439. {
  440. uint8_t *elementAddress = 0;
  441. elementAddress = (uint8_t *)(MCAN_GetMsgRAMBase(base) + MCAN_GetTxBufferElementAddress(base, idx));
  442. /* Write 2 words configuration field. */
  443. memcpy(elementAddress, (uint8_t *)txFrame, 8U);
  444. /* Write data field. */
  445. memcpy(elementAddress + 8U, txFrame->data, txFrame->size);
  446. return kStatus_Success;
  447. }
  448. else
  449. {
  450. return kStatus_Fail;
  451. }
  452. }
  453. status_t MCAN_ReadRxBuffer(CAN_Type *base, uint8_t idx, mcan_rx_buffer_frame_t *rxFrame)
  454. {
  455. mcan_rx_buffer_frame_t *elementAddress = 0;
  456. elementAddress = (mcan_rx_buffer_frame_t *)(MCAN_GetMsgRAMBase(base) + MCAN_GetRxBufferElementAddress(base, idx));
  457. memcpy(rxFrame, elementAddress, (rxFrame->size + 8U) * 4U);
  458. return kStatus_Success;
  459. }
  460. status_t MCAN_ReadRxFifo(CAN_Type *base, uint8_t fifoBlock, mcan_rx_buffer_frame_t *rxFrame)
  461. {
  462. assert((fifoBlock == 0) || (fifoBlock == 1U));
  463. mcan_rx_buffer_frame_t *elementAddress = 0;
  464. if (0 == fifoBlock)
  465. {
  466. elementAddress = (mcan_rx_buffer_frame_t *)(MCAN_GetMsgRAMBase(base) + MCAN_GetRxFifo0ElementAddress(base));
  467. }
  468. else
  469. {
  470. elementAddress = (mcan_rx_buffer_frame_t *)(MCAN_GetMsgRAMBase(base) + MCAN_GetRxFifo1ElementAddress(base));
  471. }
  472. memcpy(rxFrame, elementAddress, 8U);
  473. rxFrame->data = (uint8_t *)elementAddress + 8U;
  474. /* Acknowledge the read. */
  475. if (0 == fifoBlock)
  476. {
  477. base->RXF0A = (base->RXF0S & CAN_RXF0S_F0GI_MASK) >> CAN_RXF0S_F0GI_SHIFT;
  478. }
  479. else
  480. {
  481. base->RXF1A = (base->RXF1S & CAN_RXF1S_F1GI_MASK) >> CAN_RXF1S_F1GI_SHIFT;
  482. }
  483. return kStatus_Success;
  484. }
  485. status_t MCAN_TransferSendBlocking(CAN_Type *base, uint8_t idx, mcan_tx_buffer_frame_t *txFrame)
  486. {
  487. if (kStatus_Success == MCAN_WriteTxBuffer(base, idx, txFrame))
  488. {
  489. MCAN_TransmitAddRequest(base, idx);
  490. /* Wait until message sent out. */
  491. while (!MCAN_IsTransmitOccurred(base, idx))
  492. {
  493. }
  494. return kStatus_Success;
  495. }
  496. else
  497. {
  498. return kStatus_Fail;
  499. }
  500. }
  501. status_t MCAN_TransferReceiveBlocking(CAN_Type *base, uint8_t bufferIdx, mcan_rx_buffer_frame_t *rxFrame)
  502. {
  503. assert(bufferIdx <= 63U);
  504. while (!MCAN_GetRxBufferStatusFlag(base, bufferIdx))
  505. {
  506. }
  507. MCAN_ClearRxBufferStatusFlag(base, bufferIdx);
  508. return MCAN_ReadRxBuffer(base, bufferIdx, rxFrame);
  509. }
  510. status_t MCAN_TransferReceiveFifoBlocking(CAN_Type *base, uint8_t fifoBlock, mcan_rx_buffer_frame_t *rxFrame)
  511. {
  512. assert((fifoBlock == 0) || (fifoBlock == 1U));
  513. if (0 == fifoBlock)
  514. {
  515. while (!MCAN_GetStatusFlag(base, CAN_IR_RF0N_MASK))
  516. {
  517. }
  518. MCAN_ClearStatusFlag(base, CAN_IR_RF0N_MASK);
  519. }
  520. else
  521. {
  522. while (!MCAN_GetStatusFlag(base, CAN_IR_RF1N_MASK))
  523. {
  524. }
  525. MCAN_ClearStatusFlag(base, CAN_IR_RF1N_MASK);
  526. }
  527. return MCAN_ReadRxFifo(base, fifoBlock, rxFrame);
  528. }
  529. void MCAN_TransferCreateHandle(CAN_Type *base, mcan_handle_t *handle, mcan_transfer_callback_t callback, void *userData)
  530. {
  531. assert(handle);
  532. uint8_t instance;
  533. /* Clean MCAN transfer handle. */
  534. memset(handle, 0, sizeof(*handle));
  535. /* Get instance from peripheral base address. */
  536. instance = MCAN_GetInstance(base);
  537. /* Save the context in global variables to support the double weak mechanism. */
  538. s_mcanHandle[instance] = handle;
  539. /* Register Callback function. */
  540. handle->callback = callback;
  541. handle->userData = userData;
  542. s_mcanIsr = MCAN_TransferHandleIRQ;
  543. /* We Enable Error & Status interrupt here, because this interrupt just
  544. * report current status of MCAN module through Callback function.
  545. * It is insignificance without a available callback function.
  546. */
  547. if (handle->callback != NULL)
  548. {
  549. MCAN_EnableInterrupts(base, 0,
  550. kMCAN_BusOffInterruptEnable | kMCAN_ErrorInterruptEnable | kMCAN_WarningInterruptEnable);
  551. }
  552. else
  553. {
  554. MCAN_DisableInterrupts(base,
  555. kMCAN_BusOffInterruptEnable | kMCAN_ErrorInterruptEnable | kMCAN_WarningInterruptEnable);
  556. }
  557. /* Enable interrupts in NVIC. */
  558. EnableIRQ((IRQn_Type)(s_mcanIRQ[instance][0]));
  559. EnableIRQ((IRQn_Type)(s_mcanIRQ[instance][1]));
  560. }
  561. status_t MCAN_TransferSendNonBlocking(CAN_Type *base, mcan_handle_t *handle, mcan_buffer_transfer_t *xfer)
  562. {
  563. /* Assertion. */
  564. assert(handle);
  565. assert(xfer);
  566. assert(xfer->bufferIdx <= 63U);
  567. /* Check if Tx Buffer is idle. */
  568. if (kMCAN_StateIdle == handle->bufferState[xfer->bufferIdx])
  569. {
  570. handle->txbufferIdx = xfer->bufferIdx;
  571. /* Distinguish transmit type. */
  572. if (kMCAN_FrameTypeRemote == xfer->frame->xtd)
  573. {
  574. handle->bufferState[xfer->bufferIdx] = kMCAN_StateTxRemote;
  575. /* Register user Frame buffer to receive remote Frame. */
  576. handle->bufferFrameBuf[xfer->bufferIdx] = xfer->frame;
  577. }
  578. else
  579. {
  580. handle->bufferState[xfer->bufferIdx] = kMCAN_StateTxData;
  581. }
  582. if (kStatus_Success == MCAN_WriteTxBuffer(base, xfer->bufferIdx, xfer->frame))
  583. {
  584. /* Enable Buffer Interrupt. */
  585. MCAN_EnableTransmitBufferInterrupts(base, xfer->bufferIdx);
  586. MCAN_EnableInterrupts(base, 0, CAN_IE_TCE_MASK);
  587. MCAN_TransmitAddRequest(base, xfer->bufferIdx);
  588. return kStatus_Success;
  589. }
  590. else
  591. {
  592. handle->bufferState[xfer->bufferIdx] = kMCAN_StateIdle;
  593. return kStatus_Fail;
  594. }
  595. }
  596. else
  597. {
  598. return kStatus_MCAN_TxBusy;
  599. }
  600. }
  601. status_t MCAN_TransferReceiveFifoNonBlocking(CAN_Type *base,
  602. uint8_t fifoBlock,
  603. mcan_handle_t *handle,
  604. mcan_fifo_transfer_t *xfer)
  605. {
  606. /* Assertion. */
  607. assert((fifoBlock == 0) || (fifoBlock == 1U));
  608. assert(handle);
  609. assert(xfer);
  610. /* Check if Message Buffer is idle. */
  611. if (kMCAN_StateIdle == handle->rxFifoState)
  612. {
  613. handle->rxFifoState = kMCAN_StateRxFifo;
  614. /* Register Message Buffer. */
  615. handle->rxFifoFrameBuf = xfer->frame;
  616. /* Enable FIFO Interrupt. */
  617. if (fifoBlock)
  618. {
  619. MCAN_EnableInterrupts(base, 0, CAN_IE_RF1NE_MASK);
  620. }
  621. else
  622. {
  623. MCAN_EnableInterrupts(base, 0, CAN_IE_RF0NE_MASK);
  624. }
  625. return kStatus_Success;
  626. }
  627. else
  628. {
  629. return fifoBlock ? kStatus_MCAN_RxFifo1Busy : kStatus_MCAN_RxFifo0Busy;
  630. }
  631. }
  632. void MCAN_TransferAbortSend(CAN_Type *base, mcan_handle_t *handle, uint8_t bufferIdx)
  633. {
  634. /* Assertion. */
  635. assert(handle);
  636. assert(bufferIdx <= 63U);
  637. /* Disable Buffer Interrupt. */
  638. MCAN_DisableTransmitBufferInterrupts(base, bufferIdx);
  639. MCAN_DisableInterrupts(base, CAN_IE_TCE_MASK);
  640. /* Cancel send request. */
  641. MCAN_TransmitCancelRequest(base, bufferIdx);
  642. /* Un-register handle. */
  643. handle->bufferFrameBuf[bufferIdx] = 0x0;
  644. handle->bufferState[bufferIdx] = kMCAN_StateIdle;
  645. }
  646. void MCAN_TransferAbortReceiveFifo(CAN_Type *base, uint8_t fifoBlock, mcan_handle_t *handle)
  647. {
  648. /* Assertion. */
  649. assert(handle);
  650. assert((fifoBlock == 0) || (fifoBlock == 1));
  651. /* Check if Rx FIFO is enabled. */
  652. if (fifoBlock)
  653. {
  654. /* Disable Rx Message FIFO Interrupts. */
  655. MCAN_DisableInterrupts(base, CAN_IE_RF1NE_MASK);
  656. }
  657. else
  658. {
  659. MCAN_DisableInterrupts(base, CAN_IE_RF0NE_MASK);
  660. }
  661. /* Un-register handle. */
  662. handle->rxFifoFrameBuf = 0x0;
  663. handle->rxFifoState = kMCAN_StateIdle;
  664. }
  665. void MCAN_TransferHandleIRQ(CAN_Type *base, mcan_handle_t *handle)
  666. {
  667. /* Assertion. */
  668. assert(handle);
  669. status_t status = kStatus_MCAN_UnHandled;
  670. uint32_t result;
  671. /* Store Current MCAN Module Error and Status. */
  672. result = base->IR;
  673. do
  674. {
  675. /* Solve Rx FIFO, Tx interrupt. */
  676. if (result & kMCAN_TxTransmitCompleteFlag)
  677. {
  678. status = kStatus_MCAN_TxIdle;
  679. MCAN_TransferAbortSend(base, handle, handle->txbufferIdx);
  680. }
  681. else if (result & kMCAN_RxFifo0NewFlag)
  682. {
  683. MCAN_ReadRxFifo(base, 0, handle->rxFifoFrameBuf);
  684. status = kStatus_MCAN_RxFifo0Idle;
  685. MCAN_TransferAbortReceiveFifo(base, 0, handle);
  686. }
  687. else if (result & kMCAN_RxFifo0LostFlag)
  688. {
  689. status = kStatus_MCAN_RxFifo0Lost;
  690. }
  691. else if (result & kMCAN_RxFifo1NewFlag)
  692. {
  693. MCAN_ReadRxFifo(base, 1, handle->rxFifoFrameBuf);
  694. status = kStatus_MCAN_RxFifo1Idle;
  695. MCAN_TransferAbortReceiveFifo(base, 1, handle);
  696. }
  697. else if (result & kMCAN_RxFifo1LostFlag)
  698. {
  699. status = kStatus_MCAN_RxFifo0Lost;
  700. }
  701. else
  702. {
  703. ;
  704. }
  705. /* Clear resolved Rx FIFO, Tx Buffer IRQ. */
  706. MCAN_ClearStatusFlag(base, result);
  707. /* Calling Callback Function if has one. */
  708. if (handle->callback != NULL)
  709. {
  710. handle->callback(base, handle, status, result, handle->userData);
  711. }
  712. /* Reset return status */
  713. status = kStatus_MCAN_UnHandled;
  714. /* Store Current MCAN Module Error and Status. */
  715. result = base->IR;
  716. } while ((0 != MCAN_GetStatusFlag(base, 0xFFFFFFFFU)) ||
  717. (0 != (result & (kMCAN_ErrorWarningIntFlag | kMCAN_BusOffIntFlag | kMCAN_ErrorPassiveIntFlag))));
  718. }
  719. #if defined(CAN0)
  720. void CAN0_IRQ0_DriverIRQHandler(void)
  721. {
  722. assert(s_mcanHandle[0]);
  723. s_mcanIsr(CAN0, s_mcanHandle[0]);
  724. }
  725. void CAN0_IRQ1_DriverIRQHandler(void)
  726. {
  727. assert(s_mcanHandle[0]);
  728. s_mcanIsr(CAN0, s_mcanHandle[0]);
  729. }
  730. #endif
  731. #if defined(CAN1)
  732. void CAN1_IRQ0_DriverIRQHandler(void)
  733. {
  734. assert(s_mcanHandle[1]);
  735. s_mcanIsr(CAN1, s_mcanHandle[1]);
  736. }
  737. void CAN1_IRQ1_DriverIRQHandler(void)
  738. {
  739. assert(s_mcanHandle[1]);
  740. s_mcanIsr(CAN1, s_mcanHandle[1]);
  741. }
  742. #endif