fsl_flexcan.c 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407
  1. /*
  2. * Copyright (c) 2015, 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_flexcan.h"
  31. /*******************************************************************************
  32. * Definitons
  33. ******************************************************************************/
  34. #define FLEXCAN_TIME_QUANTA_NUM (10)
  35. /*! @brief FlexCAN Internal State. */
  36. enum _flexcan_state
  37. {
  38. kFLEXCAN_StateIdle = 0x0, /*!< MB/RxFIFO idle.*/
  39. kFLEXCAN_StateRxData = 0x1, /*!< MB receiving.*/
  40. kFLEXCAN_StateRxRemote = 0x2, /*!< MB receiving remote reply.*/
  41. kFLEXCAN_StateTxData = 0x3, /*!< MB transmitting.*/
  42. kFLEXCAN_StateTxRemote = 0x4, /*!< MB transmitting remote request.*/
  43. kFLEXCAN_StateRxFifo = 0x5, /*!< RxFIFO receiving.*/
  44. };
  45. /*! @brief FlexCAN message buffer CODE for Rx buffers. */
  46. enum _flexcan_mb_code_rx
  47. {
  48. kFLEXCAN_RxMbInactive = 0x0, /*!< MB is not active.*/
  49. kFLEXCAN_RxMbFull = 0x2, /*!< MB is full.*/
  50. kFLEXCAN_RxMbEmpty = 0x4, /*!< MB is active and empty.*/
  51. kFLEXCAN_RxMbOverrun = 0x6, /*!< MB is overwritten into a full buffer.*/
  52. kFLEXCAN_RxMbBusy = 0x8, /*!< FlexCAN is updating the contents of the MB.*/
  53. /*! The CPU must not access the MB.*/
  54. kFLEXCAN_RxMbRanswer = 0xA, /*!< A frame was configured to recognize a Remote Request Frame */
  55. /*! and transmit a Response Frame in return.*/
  56. kFLEXCAN_RxMbNotUsed = 0xF, /*!< Not used.*/
  57. };
  58. /*! @brief FlexCAN message buffer CODE FOR Tx buffers. */
  59. enum _flexcan_mb_code_tx
  60. {
  61. kFLEXCAN_TxMbInactive = 0x8, /*!< MB is not active.*/
  62. kFLEXCAN_TxMbAbort = 0x9, /*!< MB is aborted.*/
  63. kFLEXCAN_TxMbDataOrRemote = 0xC, /*!< MB is a TX Data Frame(when MB RTR = 0) or */
  64. /*!< MB is a TX Remote Request Frame (when MB RTR = 1).*/
  65. kFLEXCAN_TxMbTanswer = 0xE, /*!< MB is a TX Response Request Frame from */
  66. /*! an incoming Remote Request Frame.*/
  67. kFLEXCAN_TxMbNotUsed = 0xF, /*!< Not used.*/
  68. };
  69. /* Typedef for interrupt handler. */
  70. typedef void (*flexcan_isr_t)(CAN_Type *base, flexcan_handle_t *handle);
  71. /*******************************************************************************
  72. * Prototypes
  73. ******************************************************************************/
  74. /*!
  75. * @brief Get the FlexCAN instance from peripheral base address.
  76. *
  77. * @param base FlexCAN peripheral base address.
  78. * @return FlexCAN instance.
  79. */
  80. uint32_t FLEXCAN_GetInstance(CAN_Type *base);
  81. /*!
  82. * @brief Enter FlexCAN Freeze Mode.
  83. *
  84. * This function makes the FlexCAN work under Freeze Mode.
  85. *
  86. * @param base FlexCAN peripheral base address.
  87. */
  88. static void FLEXCAN_EnterFreezeMode(CAN_Type *base);
  89. /*!
  90. * @brief Exit FlexCAN Freeze Mode.
  91. *
  92. * This function makes the FlexCAN leave Freeze Mode.
  93. *
  94. * @param base FlexCAN peripheral base address.
  95. */
  96. static void FLEXCAN_ExitFreezeMode(CAN_Type *base);
  97. #if !defined(NDEBUG)
  98. /*!
  99. * @brief Check if Message Buffer is occupied by Rx FIFO.
  100. *
  101. * This function check if Message Buffer is occupied by Rx FIFO.
  102. *
  103. * @param base FlexCAN peripheral base address.
  104. * @param mbIdx The FlexCAN Message Buffer index.
  105. */
  106. static bool FLEXCAN_IsMbOccupied(CAN_Type *base, uint8_t mbIdx);
  107. #endif
  108. #if (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641)
  109. /*!
  110. * @brief Get the first valid Message buffer ID of give FlexCAN instance.
  111. *
  112. * This function is a helper function for Errata 5641 workaround.
  113. *
  114. * @param base FlexCAN peripheral base address.
  115. * @return The first valid Message Buffer Number.
  116. */
  117. static uint32_t FLEXCAN_GetFirstValidMb(CAN_Type *base);
  118. #endif
  119. /*!
  120. * @brief Check if Message Buffer interrupt is enabled.
  121. *
  122. * This function check if Message Buffer interrupt is enabled.
  123. *
  124. * @param base FlexCAN peripheral base address.
  125. * @param mbIdx The FlexCAN Message Buffer index.
  126. */
  127. static bool FLEXCAN_IsMbIntEnabled(CAN_Type *base, uint8_t mbIdx);
  128. /*!
  129. * @brief Reset the FlexCAN Instance.
  130. *
  131. * Restores the FlexCAN module to reset state, notice that this function
  132. * will set all the registers to reset state so the FlexCAN module can not work
  133. * after calling this API.
  134. *
  135. * @param base FlexCAN peripheral base address.
  136. */
  137. static void FLEXCAN_Reset(CAN_Type *base);
  138. /*!
  139. * @brief Set Baud Rate of FlexCAN.
  140. *
  141. * This function set the baud rate of FlexCAN.
  142. *
  143. * @param base FlexCAN peripheral base address.
  144. * @param sourceClock_Hz Source Clock in Hz.
  145. * @param baudRate_Bps Baud Rate in Bps.
  146. */
  147. static void FLEXCAN_SetBaudRate(CAN_Type *base, uint32_t sourceClock_Hz, uint32_t baudRate_Bps);
  148. /*******************************************************************************
  149. * Variables
  150. ******************************************************************************/
  151. /* Array of FlexCAN peripheral base address. */
  152. static CAN_Type *const s_flexcanBases[] = CAN_BASE_PTRS;
  153. /* Array of FlexCAN IRQ number. */
  154. static const IRQn_Type s_flexcanRxWarningIRQ[] = CAN_Rx_Warning_IRQS;
  155. static const IRQn_Type s_flexcanTxWarningIRQ[] = CAN_Tx_Warning_IRQS;
  156. static const IRQn_Type s_flexcanWakeUpIRQ[] = CAN_Wake_Up_IRQS;
  157. static const IRQn_Type s_flexcanErrorIRQ[] = CAN_Error_IRQS;
  158. static const IRQn_Type s_flexcanBusOffIRQ[] = CAN_Bus_Off_IRQS;
  159. static const IRQn_Type s_flexcanMbIRQ[] = CAN_ORed_Message_buffer_IRQS;
  160. /* Array of FlexCAN handle. */
  161. static flexcan_handle_t *s_flexcanHandle[ARRAY_SIZE(s_flexcanBases)];
  162. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  163. /* Array of FlexCAN clock name. */
  164. static const clock_ip_name_t s_flexcanClock[] = FLEXCAN_CLOCKS;
  165. #if defined(FLEXCAN_PERIPH_CLOCKS)
  166. /* Array of FlexCAN serial clock name. */
  167. static const clock_ip_name_t s_flexcanPeriphClock[] = FLEXCAN_PERIPH_CLOCKS;
  168. #endif /* FLEXCAN_PERIPH_CLOCKS */
  169. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  170. /* FlexCAN ISR for transactional APIs. */
  171. static flexcan_isr_t s_flexcanIsr;
  172. /*******************************************************************************
  173. * Code
  174. ******************************************************************************/
  175. uint32_t FLEXCAN_GetInstance(CAN_Type *base)
  176. {
  177. uint32_t instance;
  178. /* Find the instance index from base address mappings. */
  179. for (instance = 0; instance < ARRAY_SIZE(s_flexcanBases); instance++)
  180. {
  181. if (s_flexcanBases[instance] == base)
  182. {
  183. break;
  184. }
  185. }
  186. assert(instance < ARRAY_SIZE(s_flexcanBases));
  187. return instance;
  188. }
  189. static void FLEXCAN_EnterFreezeMode(CAN_Type *base)
  190. {
  191. /* Set Freeze, Halt bits. */
  192. base->MCR |= CAN_MCR_HALT_MASK;
  193. /* Wait until the FlexCAN Module enter freeze mode. */
  194. while (!(base->MCR & CAN_MCR_FRZACK_MASK))
  195. {
  196. }
  197. }
  198. static void FLEXCAN_ExitFreezeMode(CAN_Type *base)
  199. {
  200. /* Clear Freeze, Halt bits. */
  201. base->MCR &= ~CAN_MCR_HALT_MASK;
  202. /* Wait until the FlexCAN Module exit freeze mode. */
  203. while (base->MCR & CAN_MCR_FRZACK_MASK)
  204. {
  205. }
  206. }
  207. #if !defined(NDEBUG)
  208. static bool FLEXCAN_IsMbOccupied(CAN_Type *base, uint8_t mbIdx)
  209. {
  210. uint8_t lastOccupiedMb;
  211. /* Is Rx FIFO enabled? */
  212. if (base->MCR & CAN_MCR_RFEN_MASK)
  213. {
  214. /* Get RFFN value. */
  215. lastOccupiedMb = ((base->CTRL2 & CAN_CTRL2_RFFN_MASK) >> CAN_CTRL2_RFFN_SHIFT);
  216. /* Calculate the number of last Message Buffer occupied by Rx FIFO. */
  217. lastOccupiedMb = ((lastOccupiedMb + 1) * 2) + 5;
  218. #if (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641)
  219. if (mbIdx <= (lastOccupiedMb + 1))
  220. #else
  221. if (mbIdx <= lastOccupiedMb)
  222. #endif
  223. {
  224. return true;
  225. }
  226. else
  227. {
  228. return false;
  229. }
  230. }
  231. else
  232. {
  233. #if (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641)
  234. if (0 == mbIdx)
  235. {
  236. return true;
  237. }
  238. else
  239. {
  240. return false;
  241. }
  242. #else
  243. return false;
  244. #endif
  245. }
  246. }
  247. #endif
  248. #if (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641)
  249. static uint32_t FLEXCAN_GetFirstValidMb(CAN_Type *base)
  250. {
  251. uint32_t firstValidMbNum;
  252. if (base->MCR & CAN_MCR_RFEN_MASK)
  253. {
  254. firstValidMbNum = ((base->CTRL2 & CAN_CTRL2_RFFN_MASK) >> CAN_CTRL2_RFFN_SHIFT);
  255. firstValidMbNum = ((firstValidMbNum + 1) * 2) + 6;
  256. }
  257. else
  258. {
  259. firstValidMbNum = 0;
  260. }
  261. return firstValidMbNum;
  262. }
  263. #endif
  264. static bool FLEXCAN_IsMbIntEnabled(CAN_Type *base, uint8_t mbIdx)
  265. {
  266. /* Assertion. */
  267. assert(mbIdx < FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base));
  268. #if (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
  269. if (mbIdx < 32)
  270. {
  271. #endif
  272. if (base->IMASK1 & ((uint32_t)(1 << mbIdx)))
  273. {
  274. return true;
  275. }
  276. else
  277. {
  278. return false;
  279. }
  280. #if (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
  281. }
  282. else
  283. {
  284. if (base->IMASK2 & ((uint32_t)(1 << (mbIdx - 32))))
  285. {
  286. return true;
  287. }
  288. else
  289. {
  290. return false;
  291. }
  292. }
  293. #endif
  294. }
  295. static void FLEXCAN_Reset(CAN_Type *base)
  296. {
  297. /* The module must should be first exit from low power
  298. * mode, and then soft reset can be applied.
  299. */
  300. assert(!(base->MCR & CAN_MCR_MDIS_MASK));
  301. uint8_t i;
  302. #if (FSL_FEATURE_FLEXCAN_HAS_DOZE_MODE_SUPPORT != 0)
  303. /* De-assert DOZE Enable Bit. */
  304. base->MCR &= ~CAN_MCR_DOZE_MASK;
  305. #endif
  306. /* Wait until FlexCAN exit from any Low Power Mode. */
  307. while (base->MCR & CAN_MCR_LPMACK_MASK)
  308. {
  309. }
  310. /* Assert Soft Reset Signal. */
  311. base->MCR |= CAN_MCR_SOFTRST_MASK;
  312. /* Wait until FlexCAN reset completes. */
  313. while (base->MCR & CAN_MCR_SOFTRST_MASK)
  314. {
  315. }
  316. /* Reset MCR rigister. */
  317. #if (defined(FSL_FEATURE_FLEXCAN_HAS_GLITCH_FILTER) && FSL_FEATURE_FLEXCAN_HAS_GLITCH_FILTER)
  318. base->MCR |= CAN_MCR_WRNEN_MASK | CAN_MCR_WAKSRC_MASK |
  319. CAN_MCR_MAXMB(FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base) - 1);
  320. #else
  321. base->MCR |= CAN_MCR_WRNEN_MASK | CAN_MCR_MAXMB(FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base) - 1);
  322. #endif
  323. /* Reset CTRL1 and CTRL2 rigister. */
  324. base->CTRL1 = CAN_CTRL1_SMP_MASK;
  325. base->CTRL2 = CAN_CTRL2_TASD(0x16) | CAN_CTRL2_RRS_MASK | CAN_CTRL2_EACEN_MASK;
  326. /* Clean all individual Rx Mask of Message Buffers. */
  327. for (i = 0; i < FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base); i++)
  328. {
  329. base->RXIMR[i] = 0x3FFFFFFF;
  330. }
  331. /* Clean Global Mask of Message Buffers. */
  332. base->RXMGMASK = 0x3FFFFFFF;
  333. /* Clean Global Mask of Message Buffer 14. */
  334. base->RX14MASK = 0x3FFFFFFF;
  335. /* Clean Global Mask of Message Buffer 15. */
  336. base->RX15MASK = 0x3FFFFFFF;
  337. /* Clean Global Mask of Rx FIFO. */
  338. base->RXFGMASK = 0x3FFFFFFF;
  339. /* Clean all Message Buffer CS fields. */
  340. for (i = 0; i < FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base); i++)
  341. {
  342. base->MB[i].CS = 0x0;
  343. }
  344. }
  345. static void FLEXCAN_SetBaudRate(CAN_Type *base, uint32_t sourceClock_Hz, uint32_t baudRate_Bps)
  346. {
  347. flexcan_timing_config_t timingConfig;
  348. uint32_t priDiv = baudRate_Bps * FLEXCAN_TIME_QUANTA_NUM;
  349. /* Assertion: Desired baud rate is too high. */
  350. assert(baudRate_Bps <= 1000000U);
  351. /* Assertion: Source clock should greater than baud rate * FLEXCAN_TIME_QUANTA_NUM. */
  352. assert(priDiv <= sourceClock_Hz);
  353. if (0 == priDiv)
  354. {
  355. priDiv = 1;
  356. }
  357. priDiv = (sourceClock_Hz / priDiv) - 1;
  358. /* Desired baud rate is too low. */
  359. if (priDiv > 0xFF)
  360. {
  361. priDiv = 0xFF;
  362. }
  363. /* FlexCAN timing setting formula:
  364. * FLEXCAN_TIME_QUANTA_NUM = 1 + (PSEG1 + 1) + (PSEG2 + 1) + (PROPSEG + 1);
  365. */
  366. timingConfig.preDivider = priDiv;
  367. timingConfig.phaseSeg1 = 3;
  368. timingConfig.phaseSeg2 = 2;
  369. timingConfig.propSeg = 1;
  370. timingConfig.rJumpwidth = 1;
  371. /* Update actual timing characteristic. */
  372. FLEXCAN_SetTimingConfig(base, &timingConfig);
  373. }
  374. void FLEXCAN_Init(CAN_Type *base, const flexcan_config_t *config, uint32_t sourceClock_Hz)
  375. {
  376. uint32_t mcrTemp;
  377. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  378. uint32_t instance;
  379. #endif
  380. /* Assertion. */
  381. assert(config);
  382. assert((config->maxMbNum > 0) && (config->maxMbNum <= FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base)));
  383. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  384. instance = FLEXCAN_GetInstance(base);
  385. /* Enable FlexCAN clock. */
  386. CLOCK_EnableClock(s_flexcanClock[instance]);
  387. #if defined(FLEXCAN_PERIPH_CLOCKS)
  388. /* Enable FlexCAN serial clock. */
  389. CLOCK_EnableClock(s_flexcanPeriphClock[instance]);
  390. #endif /* FLEXCAN_PERIPH_CLOCKS */
  391. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  392. #if (!defined(FSL_FEATURE_FLEXCAN_SUPPORT_ENGINE_CLK_SEL_REMOVE)) || !FSL_FEATURE_FLEXCAN_SUPPORT_ENGINE_CLK_SEL_REMOVE
  393. /* Disable FlexCAN Module. */
  394. FLEXCAN_Enable(base, false);
  395. /* Protocol-Engine clock source selection, This bit must be set
  396. * when FlexCAN Module in Disable Mode.
  397. */
  398. base->CTRL1 = (kFLEXCAN_ClkSrcOsc == config->clkSrc) ? base->CTRL1 & ~CAN_CTRL1_CLKSRC_MASK :
  399. base->CTRL1 | CAN_CTRL1_CLKSRC_MASK;
  400. #endif /* FSL_FEATURE_FLEXCAN_SUPPORT_ENGINE_CLK_SEL_REMOVE */
  401. /* Enable FlexCAN Module for configuartion. */
  402. FLEXCAN_Enable(base, true);
  403. /* Reset to known status. */
  404. FLEXCAN_Reset(base);
  405. /* Save current MCR value and enable to enter Freeze mode(enabled by default). */
  406. mcrTemp = base->MCR;
  407. /* Set the maximum number of Message Buffers */
  408. mcrTemp = (mcrTemp & ~CAN_MCR_MAXMB_MASK) | CAN_MCR_MAXMB(config->maxMbNum - 1);
  409. /* Enable Loop Back Mode? */
  410. base->CTRL1 = (config->enableLoopBack) ? base->CTRL1 | CAN_CTRL1_LPB_MASK : base->CTRL1 & ~CAN_CTRL1_LPB_MASK;
  411. /* Enable Self Wake Up Mode? */
  412. mcrTemp = (config->enableSelfWakeup) ? mcrTemp | CAN_MCR_SLFWAK_MASK : mcrTemp & ~CAN_MCR_SLFWAK_MASK;
  413. /* Enable Individual Rx Masking? */
  414. mcrTemp = (config->enableIndividMask) ? mcrTemp | CAN_MCR_IRMQ_MASK : mcrTemp & ~CAN_MCR_IRMQ_MASK;
  415. #if (defined(FSL_FEATURE_FLEXCAN_HAS_DOZE_MODE_SUPPORT) && FSL_FEATURE_FLEXCAN_HAS_DOZE_MODE_SUPPORT)
  416. /* Enable Doze Mode? */
  417. mcrTemp = (config->enableDoze) ? mcrTemp | CAN_MCR_DOZE_MASK : mcrTemp & ~CAN_MCR_DOZE_MASK;
  418. #endif
  419. /* Save MCR Configuation. */
  420. base->MCR = mcrTemp;
  421. /* Baud Rate Configuration.*/
  422. FLEXCAN_SetBaudRate(base, sourceClock_Hz, config->baudRate);
  423. }
  424. void FLEXCAN_Deinit(CAN_Type *base)
  425. {
  426. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  427. uint32_t instance;
  428. #endif
  429. /* Reset all Register Contents. */
  430. FLEXCAN_Reset(base);
  431. /* Disable FlexCAN module. */
  432. FLEXCAN_Enable(base, false);
  433. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  434. instance = FLEXCAN_GetInstance(base);
  435. #if defined(FLEXCAN_PERIPH_CLOCKS)
  436. /* Disable FlexCAN serial clock. */
  437. CLOCK_DisableClock(s_flexcanPeriphClock[instance]);
  438. #endif /* FLEXCAN_PERIPH_CLOCKS */
  439. /* Disable FlexCAN clock. */
  440. CLOCK_DisableClock(s_flexcanClock[instance]);
  441. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  442. }
  443. void FLEXCAN_GetDefaultConfig(flexcan_config_t *config)
  444. {
  445. /* Assertion. */
  446. assert(config);
  447. /* Initialize FlexCAN Module config struct with default value. */
  448. #if (!defined(FSL_FEATURE_FLEXCAN_SUPPORT_ENGINE_CLK_SEL_REMOVE)) || !FSL_FEATURE_FLEXCAN_SUPPORT_ENGINE_CLK_SEL_REMOVE
  449. config->clkSrc = kFLEXCAN_ClkSrcOsc;
  450. #endif /* FSL_FEATURE_FLEXCAN_SUPPORT_ENGINE_CLK_SEL_REMOVE */
  451. config->baudRate = 125000U;
  452. config->maxMbNum = 16;
  453. config->enableLoopBack = false;
  454. config->enableSelfWakeup = false;
  455. config->enableIndividMask = false;
  456. #if (defined(FSL_FEATURE_FLEXCAN_HAS_DOZE_MODE_SUPPORT) && FSL_FEATURE_FLEXCAN_HAS_DOZE_MODE_SUPPORT)
  457. config->enableDoze = false;
  458. #endif
  459. }
  460. void FLEXCAN_SetTimingConfig(CAN_Type *base, const flexcan_timing_config_t *config)
  461. {
  462. /* Assertion. */
  463. assert(config);
  464. /* Enter Freeze Mode. */
  465. FLEXCAN_EnterFreezeMode(base);
  466. /* Cleaning previous Timing Setting. */
  467. base->CTRL1 &= ~(CAN_CTRL1_PRESDIV_MASK | CAN_CTRL1_RJW_MASK | CAN_CTRL1_PSEG1_MASK | CAN_CTRL1_PSEG2_MASK |
  468. CAN_CTRL1_PROPSEG_MASK);
  469. /* Updating Timing Setting according to configuration structure. */
  470. base->CTRL1 |=
  471. (CAN_CTRL1_PRESDIV(config->preDivider) | CAN_CTRL1_RJW(config->rJumpwidth) |
  472. CAN_CTRL1_PSEG1(config->phaseSeg1) | CAN_CTRL1_PSEG2(config->phaseSeg2) | CAN_CTRL1_PROPSEG(config->propSeg));
  473. /* Exit Freeze Mode. */
  474. FLEXCAN_ExitFreezeMode(base);
  475. }
  476. void FLEXCAN_SetRxMbGlobalMask(CAN_Type *base, uint32_t mask)
  477. {
  478. /* Enter Freeze Mode. */
  479. FLEXCAN_EnterFreezeMode(base);
  480. /* Setting Rx Message Buffer Global Mask value. */
  481. base->RXMGMASK = mask;
  482. base->RX14MASK = mask;
  483. base->RX15MASK = mask;
  484. /* Exit Freeze Mode. */
  485. FLEXCAN_ExitFreezeMode(base);
  486. }
  487. void FLEXCAN_SetRxFifoGlobalMask(CAN_Type *base, uint32_t mask)
  488. {
  489. /* Enter Freeze Mode. */
  490. FLEXCAN_EnterFreezeMode(base);
  491. /* Setting Rx FIFO Global Mask value. */
  492. base->RXFGMASK = mask;
  493. /* Exit Freeze Mode. */
  494. FLEXCAN_ExitFreezeMode(base);
  495. }
  496. void FLEXCAN_SetRxIndividualMask(CAN_Type *base, uint8_t maskIdx, uint32_t mask)
  497. {
  498. assert(maskIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
  499. /* Enter Freeze Mode. */
  500. FLEXCAN_EnterFreezeMode(base);
  501. /* Setting Rx Individual Mask value. */
  502. base->RXIMR[maskIdx] = mask;
  503. /* Exit Freeze Mode. */
  504. FLEXCAN_ExitFreezeMode(base);
  505. }
  506. void FLEXCAN_SetTxMbConfig(CAN_Type *base, uint8_t mbIdx, bool enable)
  507. {
  508. /* Assertion. */
  509. assert(mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
  510. assert(!FLEXCAN_IsMbOccupied(base, mbIdx));
  511. /* Inactivate Message Buffer. */
  512. if (enable)
  513. {
  514. base->MB[mbIdx].CS = CAN_CS_CODE(kFLEXCAN_TxMbInactive);
  515. }
  516. else
  517. {
  518. base->MB[mbIdx].CS = 0;
  519. }
  520. /* Clean Message Buffer content. */
  521. base->MB[mbIdx].ID = 0x0;
  522. base->MB[mbIdx].WORD0 = 0x0;
  523. base->MB[mbIdx].WORD1 = 0x0;
  524. }
  525. void FLEXCAN_SetRxMbConfig(CAN_Type *base, uint8_t mbIdx, const flexcan_rx_mb_config_t *config, bool enable)
  526. {
  527. /* Assertion. */
  528. assert(mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
  529. assert(((config) || (false == enable)));
  530. assert(!FLEXCAN_IsMbOccupied(base, mbIdx));
  531. uint32_t cs_temp = 0;
  532. /* Inactivate Message Buffer. */
  533. base->MB[mbIdx].CS = 0;
  534. /* Clean Message Buffer content. */
  535. base->MB[mbIdx].ID = 0x0;
  536. base->MB[mbIdx].WORD0 = 0x0;
  537. base->MB[mbIdx].WORD1 = 0x0;
  538. if (enable)
  539. {
  540. /* Setup Message Buffer ID. */
  541. base->MB[mbIdx].ID = config->id;
  542. /* Setup Message Buffer format. */
  543. if (kFLEXCAN_FrameFormatExtend == config->format)
  544. {
  545. cs_temp |= CAN_CS_IDE_MASK;
  546. }
  547. /* Setup Message Buffer type. */
  548. if (kFLEXCAN_FrameTypeRemote == config->type)
  549. {
  550. cs_temp |= CAN_CS_RTR_MASK;
  551. }
  552. /* Activate Rx Message Buffer. */
  553. cs_temp |= CAN_CS_CODE(kFLEXCAN_RxMbEmpty);
  554. base->MB[mbIdx].CS = cs_temp;
  555. }
  556. }
  557. void FLEXCAN_SetRxFifoConfig(CAN_Type *base, const flexcan_rx_fifo_config_t *config, bool enable)
  558. {
  559. /* Assertion. */
  560. assert((config) || (false == enable));
  561. volatile uint32_t *idFilterRegion = (volatile uint32_t *)(&base->MB[6].CS);
  562. uint8_t setup_mb, i, rffn = 0;
  563. /* Enter Freeze Mode. */
  564. FLEXCAN_EnterFreezeMode(base);
  565. if (enable)
  566. {
  567. assert(config->idFilterNum <= 128);
  568. /* Get the setup_mb value. */
  569. setup_mb = (base->MCR & CAN_MCR_MAXMB_MASK) >> CAN_MCR_MAXMB_SHIFT;
  570. setup_mb = (setup_mb < FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base)) ?
  571. setup_mb :
  572. FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base);
  573. /* Determine RFFN value. */
  574. for (i = 0; i <= 0xF; i++)
  575. {
  576. if ((8 * (i + 1)) >= config->idFilterNum)
  577. {
  578. rffn = i;
  579. assert(((setup_mb - 8) - (2 * rffn)) > 0);
  580. base->CTRL2 = (base->CTRL2 & ~CAN_CTRL2_RFFN_MASK) | CAN_CTRL2_RFFN(rffn);
  581. break;
  582. }
  583. }
  584. }
  585. else
  586. {
  587. rffn = (base->CTRL2 & CAN_CTRL2_RFFN_MASK) >> CAN_CTRL2_RFFN_SHIFT;
  588. }
  589. /* Clean ID filter table occuyied Message Buffer Region. */
  590. rffn = (rffn + 1) * 8;
  591. for (i = 0; i < rffn; i++)
  592. {
  593. idFilterRegion[i] = 0x0;
  594. }
  595. if (enable)
  596. {
  597. /* Disable unused Rx FIFO Filter. */
  598. for (i = config->idFilterNum; i < rffn; i++)
  599. {
  600. idFilterRegion[i] = 0xFFFFFFFFU;
  601. }
  602. /* Copy ID filter table to Message Buffer Region. */
  603. for (i = 0; i < config->idFilterNum; i++)
  604. {
  605. idFilterRegion[i] = config->idFilterTable[i];
  606. }
  607. /* Setup ID Fitlter Type. */
  608. switch (config->idFilterType)
  609. {
  610. case kFLEXCAN_RxFifoFilterTypeA:
  611. base->MCR = (base->MCR & ~CAN_MCR_IDAM_MASK) | CAN_MCR_IDAM(0x0);
  612. break;
  613. case kFLEXCAN_RxFifoFilterTypeB:
  614. base->MCR = (base->MCR & ~CAN_MCR_IDAM_MASK) | CAN_MCR_IDAM(0x1);
  615. break;
  616. case kFLEXCAN_RxFifoFilterTypeC:
  617. base->MCR = (base->MCR & ~CAN_MCR_IDAM_MASK) | CAN_MCR_IDAM(0x2);
  618. break;
  619. case kFLEXCAN_RxFifoFilterTypeD:
  620. /* All frames rejected. */
  621. base->MCR = (base->MCR & ~CAN_MCR_IDAM_MASK) | CAN_MCR_IDAM(0x3);
  622. break;
  623. default:
  624. break;
  625. }
  626. /* Setting Message Reception Priority. */
  627. base->CTRL2 = (config->priority == kFLEXCAN_RxFifoPrioHigh) ? base->CTRL2 & ~CAN_CTRL2_MRP_MASK :
  628. base->CTRL2 | CAN_CTRL2_MRP_MASK;
  629. /* Enable Rx Message FIFO. */
  630. base->MCR |= CAN_MCR_RFEN_MASK;
  631. }
  632. else
  633. {
  634. /* Disable Rx Message FIFO. */
  635. base->MCR &= ~CAN_MCR_RFEN_MASK;
  636. /* Clean MB0 ~ MB5. */
  637. FLEXCAN_SetRxMbConfig(base, 0, NULL, false);
  638. FLEXCAN_SetRxMbConfig(base, 1, NULL, false);
  639. FLEXCAN_SetRxMbConfig(base, 2, NULL, false);
  640. FLEXCAN_SetRxMbConfig(base, 3, NULL, false);
  641. FLEXCAN_SetRxMbConfig(base, 4, NULL, false);
  642. FLEXCAN_SetRxMbConfig(base, 5, NULL, false);
  643. }
  644. /* Exit Freeze Mode. */
  645. FLEXCAN_ExitFreezeMode(base);
  646. }
  647. #if (defined(FSL_FEATURE_FLEXCAN_HAS_RX_FIFO_DMA) && FSL_FEATURE_FLEXCAN_HAS_RX_FIFO_DMA)
  648. void FLEXCAN_EnableRxFifoDMA(CAN_Type *base, bool enable)
  649. {
  650. if (enable)
  651. {
  652. /* Enter Freeze Mode. */
  653. FLEXCAN_EnterFreezeMode(base);
  654. /* Enable FlexCAN DMA. */
  655. base->MCR |= CAN_MCR_DMA_MASK;
  656. /* Exit Freeze Mode. */
  657. FLEXCAN_ExitFreezeMode(base);
  658. }
  659. else
  660. {
  661. /* Enter Freeze Mode. */
  662. FLEXCAN_EnterFreezeMode(base);
  663. /* Disable FlexCAN DMA. */
  664. base->MCR &= ~CAN_MCR_DMA_MASK;
  665. /* Exit Freeze Mode. */
  666. FLEXCAN_ExitFreezeMode(base);
  667. }
  668. }
  669. #endif /* FSL_FEATURE_FLEXCAN_HAS_RX_FIFO_DMA */
  670. status_t FLEXCAN_WriteTxMb(CAN_Type *base, uint8_t mbIdx, const flexcan_frame_t *txFrame)
  671. {
  672. /* Assertion. */
  673. assert(mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
  674. assert(txFrame);
  675. assert(txFrame->length <= 8);
  676. assert(!FLEXCAN_IsMbOccupied(base, mbIdx));
  677. uint32_t cs_temp = 0;
  678. /* Check if Message Buffer is available. */
  679. if (CAN_CS_CODE(kFLEXCAN_TxMbDataOrRemote) != (base->MB[mbIdx].CS & CAN_CS_CODE_MASK))
  680. {
  681. /* Inactive Tx Message Buffer. */
  682. base->MB[mbIdx].CS = (base->MB[mbIdx].CS & ~CAN_CS_CODE_MASK) | CAN_CS_CODE(kFLEXCAN_TxMbInactive);
  683. /* Fill Message ID field. */
  684. base->MB[mbIdx].ID = txFrame->id;
  685. /* Fill Message Format field. */
  686. if (kFLEXCAN_FrameFormatExtend == txFrame->format)
  687. {
  688. cs_temp |= CAN_CS_SRR_MASK | CAN_CS_IDE_MASK;
  689. }
  690. /* Fill Message Type field. */
  691. if (kFLEXCAN_FrameTypeRemote == txFrame->type)
  692. {
  693. cs_temp |= CAN_CS_RTR_MASK;
  694. }
  695. cs_temp |= CAN_CS_CODE(kFLEXCAN_TxMbDataOrRemote) | CAN_CS_DLC(txFrame->length);
  696. /* Load Message Payload. */
  697. base->MB[mbIdx].WORD0 = txFrame->dataWord0;
  698. base->MB[mbIdx].WORD1 = txFrame->dataWord1;
  699. /* Activate Tx Message Buffer. */
  700. base->MB[mbIdx].CS = cs_temp;
  701. #if (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641)
  702. base->MB[FLEXCAN_GetFirstValidMb(base)].CS = CAN_CS_CODE(kFLEXCAN_TxMbInactive);
  703. base->MB[FLEXCAN_GetFirstValidMb(base)].CS = CAN_CS_CODE(kFLEXCAN_TxMbInactive);
  704. #endif
  705. return kStatus_Success;
  706. }
  707. else
  708. {
  709. /* Tx Message Buffer is activated, return immediately. */
  710. return kStatus_Fail;
  711. }
  712. }
  713. status_t FLEXCAN_ReadRxMb(CAN_Type *base, uint8_t mbIdx, flexcan_frame_t *rxFrame)
  714. {
  715. /* Assertion. */
  716. assert(mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
  717. assert(rxFrame);
  718. assert(!FLEXCAN_IsMbOccupied(base, mbIdx));
  719. uint32_t cs_temp;
  720. uint8_t rx_code;
  721. /* Read CS field of Rx Message Buffer to lock Message Buffer. */
  722. cs_temp = base->MB[mbIdx].CS;
  723. /* Get Rx Message Buffer Code field. */
  724. rx_code = (cs_temp & CAN_CS_CODE_MASK) >> CAN_CS_CODE_SHIFT;
  725. /* Check to see if Rx Message Buffer is full. */
  726. if ((kFLEXCAN_RxMbFull == rx_code) || (kFLEXCAN_RxMbOverrun == rx_code))
  727. {
  728. /* Store Message ID. */
  729. rxFrame->id = base->MB[mbIdx].ID & (CAN_ID_EXT_MASK | CAN_ID_STD_MASK);
  730. /* Get the message ID and format. */
  731. rxFrame->format = (cs_temp & CAN_CS_IDE_MASK) ? kFLEXCAN_FrameFormatExtend : kFLEXCAN_FrameFormatStandard;
  732. /* Get the message type. */
  733. rxFrame->type = (cs_temp & CAN_CS_RTR_MASK) ? kFLEXCAN_FrameTypeRemote : kFLEXCAN_FrameTypeData;
  734. /* Get the message length. */
  735. rxFrame->length = (cs_temp & CAN_CS_DLC_MASK) >> CAN_CS_DLC_SHIFT;
  736. /* Store Message Payload. */
  737. rxFrame->dataWord0 = base->MB[mbIdx].WORD0;
  738. rxFrame->dataWord1 = base->MB[mbIdx].WORD1;
  739. /* Read free-running timer to unlock Rx Message Buffer. */
  740. (void)base->TIMER;
  741. if (kFLEXCAN_RxMbFull == rx_code)
  742. {
  743. return kStatus_Success;
  744. }
  745. else
  746. {
  747. return kStatus_FLEXCAN_RxOverflow;
  748. }
  749. }
  750. else
  751. {
  752. /* Read free-running timer to unlock Rx Message Buffer. */
  753. (void)base->TIMER;
  754. return kStatus_Fail;
  755. }
  756. }
  757. status_t FLEXCAN_ReadRxFifo(CAN_Type *base, flexcan_frame_t *rxFrame)
  758. {
  759. /* Assertion. */
  760. assert(rxFrame);
  761. uint32_t cs_temp;
  762. /* Check if Rx FIFO is Enabled. */
  763. if (base->MCR & CAN_MCR_RFEN_MASK)
  764. {
  765. /* Read CS field of Rx Message Buffer to lock Message Buffer. */
  766. cs_temp = base->MB[0].CS;
  767. /* Read data from Rx FIFO output port. */
  768. /* Store Message ID. */
  769. rxFrame->id = base->MB[0].ID & (CAN_ID_EXT_MASK | CAN_ID_STD_MASK);
  770. /* Get the message ID and format. */
  771. rxFrame->format = (cs_temp & CAN_CS_IDE_MASK) ? kFLEXCAN_FrameFormatExtend : kFLEXCAN_FrameFormatStandard;
  772. /* Get the message type. */
  773. rxFrame->type = (cs_temp & CAN_CS_RTR_MASK) ? kFLEXCAN_FrameTypeRemote : kFLEXCAN_FrameTypeData;
  774. /* Get the message length. */
  775. rxFrame->length = (cs_temp & CAN_CS_DLC_MASK) >> CAN_CS_DLC_SHIFT;
  776. /* Store Message Payload. */
  777. rxFrame->dataWord0 = base->MB[0].WORD0;
  778. rxFrame->dataWord1 = base->MB[0].WORD1;
  779. /* Store ID Filter Hit Index. */
  780. rxFrame->idhit = (uint8_t)(base->RXFIR & CAN_RXFIR_IDHIT_MASK);
  781. /* Read free-running timer to unlock Rx Message Buffer. */
  782. (void)base->TIMER;
  783. return kStatus_Success;
  784. }
  785. else
  786. {
  787. return kStatus_Fail;
  788. }
  789. }
  790. status_t FLEXCAN_TransferSendBlocking(CAN_Type *base, uint8_t mbIdx, flexcan_frame_t *txFrame)
  791. {
  792. /* Write Tx Message Buffer to initiate a data sending. */
  793. if (kStatus_Success == FLEXCAN_WriteTxMb(base, mbIdx, txFrame))
  794. {
  795. /* Wait until CAN Message send out. */
  796. while (!FLEXCAN_GetMbStatusFlags(base, 1 << mbIdx))
  797. {
  798. }
  799. /* Clean Tx Message Buffer Flag. */
  800. FLEXCAN_ClearMbStatusFlags(base, 1 << mbIdx);
  801. return kStatus_Success;
  802. }
  803. else
  804. {
  805. return kStatus_Fail;
  806. }
  807. }
  808. status_t FLEXCAN_TransferReceiveBlocking(CAN_Type *base, uint8_t mbIdx, flexcan_frame_t *rxFrame)
  809. {
  810. /* Wait until Rx Message Buffer non-empty. */
  811. while (!FLEXCAN_GetMbStatusFlags(base, 1 << mbIdx))
  812. {
  813. }
  814. /* Clean Rx Message Buffer Flag. */
  815. FLEXCAN_ClearMbStatusFlags(base, 1 << mbIdx);
  816. /* Read Received CAN Message. */
  817. return FLEXCAN_ReadRxMb(base, mbIdx, rxFrame);
  818. }
  819. status_t FLEXCAN_TransferReceiveFifoBlocking(CAN_Type *base, flexcan_frame_t *rxFrame)
  820. {
  821. status_t rxFifoStatus;
  822. /* Wait until Rx FIFO non-empty. */
  823. while (!FLEXCAN_GetMbStatusFlags(base, kFLEXCAN_RxFifoFrameAvlFlag))
  824. {
  825. }
  826. /* */
  827. rxFifoStatus = FLEXCAN_ReadRxFifo(base, rxFrame);
  828. /* Clean Rx Fifo available flag. */
  829. FLEXCAN_ClearMbStatusFlags(base, kFLEXCAN_RxFifoFrameAvlFlag);
  830. return rxFifoStatus;
  831. }
  832. void FLEXCAN_TransferCreateHandle(CAN_Type *base,
  833. flexcan_handle_t *handle,
  834. flexcan_transfer_callback_t callback,
  835. void *userData)
  836. {
  837. assert(handle);
  838. uint8_t instance;
  839. /* Clean FlexCAN transfer handle. */
  840. memset(handle, 0, sizeof(*handle));
  841. /* Get instance from peripheral base address. */
  842. instance = FLEXCAN_GetInstance(base);
  843. /* Save the context in global variables to support the double weak mechanism. */
  844. s_flexcanHandle[instance] = handle;
  845. /* Register Callback function. */
  846. handle->callback = callback;
  847. handle->userData = userData;
  848. s_flexcanIsr = FLEXCAN_TransferHandleIRQ;
  849. /* We Enable Error & Status interrupt here, because this interrupt just
  850. * report current status of FlexCAN module through Callback function.
  851. * It is insignificance without a available callback function.
  852. */
  853. if (handle->callback != NULL)
  854. {
  855. FLEXCAN_EnableInterrupts(base, kFLEXCAN_BusOffInterruptEnable | kFLEXCAN_ErrorInterruptEnable |
  856. kFLEXCAN_RxWarningInterruptEnable | kFLEXCAN_TxWarningInterruptEnable |
  857. kFLEXCAN_WakeUpInterruptEnable);
  858. }
  859. else
  860. {
  861. FLEXCAN_DisableInterrupts(base, kFLEXCAN_BusOffInterruptEnable | kFLEXCAN_ErrorInterruptEnable |
  862. kFLEXCAN_RxWarningInterruptEnable | kFLEXCAN_TxWarningInterruptEnable |
  863. kFLEXCAN_WakeUpInterruptEnable);
  864. }
  865. /* Enable interrupts in NVIC. */
  866. EnableIRQ((IRQn_Type)(s_flexcanRxWarningIRQ[instance]));
  867. EnableIRQ((IRQn_Type)(s_flexcanTxWarningIRQ[instance]));
  868. EnableIRQ((IRQn_Type)(s_flexcanWakeUpIRQ[instance]));
  869. EnableIRQ((IRQn_Type)(s_flexcanErrorIRQ[instance]));
  870. EnableIRQ((IRQn_Type)(s_flexcanBusOffIRQ[instance]));
  871. EnableIRQ((IRQn_Type)(s_flexcanMbIRQ[instance]));
  872. }
  873. status_t FLEXCAN_TransferSendNonBlocking(CAN_Type *base, flexcan_handle_t *handle, flexcan_mb_transfer_t *xfer)
  874. {
  875. /* Assertion. */
  876. assert(handle);
  877. assert(xfer);
  878. assert(xfer->mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
  879. assert(!FLEXCAN_IsMbOccupied(base, xfer->mbIdx));
  880. /* Check if Message Buffer is idle. */
  881. if (kFLEXCAN_StateIdle == handle->mbState[xfer->mbIdx])
  882. {
  883. /* Distinguish transmit type. */
  884. if (kFLEXCAN_FrameTypeRemote == xfer->frame->type)
  885. {
  886. handle->mbState[xfer->mbIdx] = kFLEXCAN_StateTxRemote;
  887. /* Register user Frame buffer to receive remote Frame. */
  888. handle->mbFrameBuf[xfer->mbIdx] = xfer->frame;
  889. }
  890. else
  891. {
  892. handle->mbState[xfer->mbIdx] = kFLEXCAN_StateTxData;
  893. }
  894. if (kStatus_Success == FLEXCAN_WriteTxMb(base, xfer->mbIdx, xfer->frame))
  895. {
  896. /* Enable Message Buffer Interrupt. */
  897. FLEXCAN_EnableMbInterrupts(base, 1 << xfer->mbIdx);
  898. return kStatus_Success;
  899. }
  900. else
  901. {
  902. handle->mbState[xfer->mbIdx] = kFLEXCAN_StateIdle;
  903. return kStatus_Fail;
  904. }
  905. }
  906. else
  907. {
  908. return kStatus_FLEXCAN_TxBusy;
  909. }
  910. }
  911. status_t FLEXCAN_TransferReceiveNonBlocking(CAN_Type *base, flexcan_handle_t *handle, flexcan_mb_transfer_t *xfer)
  912. {
  913. /* Assertion. */
  914. assert(handle);
  915. assert(xfer);
  916. assert(xfer->mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
  917. assert(!FLEXCAN_IsMbOccupied(base, xfer->mbIdx));
  918. /* Check if Message Buffer is idle. */
  919. if (kFLEXCAN_StateIdle == handle->mbState[xfer->mbIdx])
  920. {
  921. handle->mbState[xfer->mbIdx] = kFLEXCAN_StateRxData;
  922. /* Register Message Buffer. */
  923. handle->mbFrameBuf[xfer->mbIdx] = xfer->frame;
  924. /* Enable Message Buffer Interrupt. */
  925. FLEXCAN_EnableMbInterrupts(base, 1 << xfer->mbIdx);
  926. return kStatus_Success;
  927. }
  928. else
  929. {
  930. return kStatus_FLEXCAN_RxBusy;
  931. }
  932. }
  933. status_t FLEXCAN_TransferReceiveFifoNonBlocking(CAN_Type *base, flexcan_handle_t *handle, flexcan_fifo_transfer_t *xfer)
  934. {
  935. /* Assertion. */
  936. assert(handle);
  937. assert(xfer);
  938. /* Check if Message Buffer is idle. */
  939. if (kFLEXCAN_StateIdle == handle->rxFifoState)
  940. {
  941. handle->rxFifoState = kFLEXCAN_StateRxFifo;
  942. /* Register Message Buffer. */
  943. handle->rxFifoFrameBuf = xfer->frame;
  944. /* Enable Message Buffer Interrupt. */
  945. FLEXCAN_EnableMbInterrupts(
  946. base, kFLEXCAN_RxFifoOverflowFlag | kFLEXCAN_RxFifoWarningFlag | kFLEXCAN_RxFifoFrameAvlFlag);
  947. return kStatus_Success;
  948. }
  949. else
  950. {
  951. return kStatus_FLEXCAN_RxFifoBusy;
  952. }
  953. }
  954. void FLEXCAN_TransferAbortSend(CAN_Type *base, flexcan_handle_t *handle, uint8_t mbIdx)
  955. {
  956. /* Assertion. */
  957. assert(handle);
  958. assert(mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
  959. assert(!FLEXCAN_IsMbOccupied(base, mbIdx));
  960. /* Disable Message Buffer Interrupt. */
  961. FLEXCAN_DisableMbInterrupts(base, 1 << mbIdx);
  962. /* Un-register handle. */
  963. handle->mbFrameBuf[mbIdx] = 0x0;
  964. /* Clean Message Buffer. */
  965. FLEXCAN_SetTxMbConfig(base, mbIdx, true);
  966. handle->mbState[mbIdx] = kFLEXCAN_StateIdle;
  967. }
  968. void FLEXCAN_TransferAbortReceive(CAN_Type *base, flexcan_handle_t *handle, uint8_t mbIdx)
  969. {
  970. /* Assertion. */
  971. assert(handle);
  972. assert(mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
  973. assert(!FLEXCAN_IsMbOccupied(base, mbIdx));
  974. /* Disable Message Buffer Interrupt. */
  975. FLEXCAN_DisableMbInterrupts(base, 1 << mbIdx);
  976. /* Un-register handle. */
  977. handle->mbFrameBuf[mbIdx] = 0x0;
  978. handle->mbState[mbIdx] = kFLEXCAN_StateIdle;
  979. }
  980. void FLEXCAN_TransferAbortReceiveFifo(CAN_Type *base, flexcan_handle_t *handle)
  981. {
  982. /* Assertion. */
  983. assert(handle);
  984. /* Check if Rx FIFO is enabled. */
  985. if (base->MCR & CAN_MCR_RFEN_MASK)
  986. {
  987. /* Disable Rx Message FIFO Interrupts. */
  988. FLEXCAN_DisableMbInterrupts(
  989. base, kFLEXCAN_RxFifoOverflowFlag | kFLEXCAN_RxFifoWarningFlag | kFLEXCAN_RxFifoFrameAvlFlag);
  990. /* Un-register handle. */
  991. handle->rxFifoFrameBuf = 0x0;
  992. }
  993. handle->rxFifoState = kFLEXCAN_StateIdle;
  994. }
  995. void FLEXCAN_TransferHandleIRQ(CAN_Type *base, flexcan_handle_t *handle)
  996. {
  997. /* Assertion. */
  998. assert(handle);
  999. status_t status = kStatus_FLEXCAN_UnHandled;
  1000. uint32_t result;
  1001. /* Store Current FlexCAN Module Error and Status. */
  1002. result = base->ESR1;
  1003. do
  1004. {
  1005. /* Solve FlexCAN Error and Status Interrupt. */
  1006. if (result & (kFLEXCAN_TxWarningIntFlag | kFLEXCAN_RxWarningIntFlag | kFLEXCAN_BusOffIntFlag |
  1007. kFLEXCAN_ErrorIntFlag | kFLEXCAN_WakeUpIntFlag))
  1008. {
  1009. status = kStatus_FLEXCAN_ErrorStatus;
  1010. /* Clear FlexCAN Error and Status Interrupt. */
  1011. FLEXCAN_ClearStatusFlags(base, kFLEXCAN_TxWarningIntFlag | kFLEXCAN_RxWarningIntFlag |
  1012. kFLEXCAN_BusOffIntFlag | kFLEXCAN_ErrorIntFlag | kFLEXCAN_WakeUpIntFlag);
  1013. }
  1014. /* Solve FlexCAN Rx FIFO & Message Buffer Interrupt. */
  1015. else
  1016. {
  1017. /* For this implementation, we solve the Message with lowest MB index first. */
  1018. for (result = 0; result < FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base); result++)
  1019. {
  1020. /* Get the lowest unhandled Message Buffer */
  1021. if ((FLEXCAN_GetMbStatusFlags(base, 1 << result)) && (FLEXCAN_IsMbIntEnabled(base, result)))
  1022. {
  1023. break;
  1024. }
  1025. }
  1026. /* Does not find Message to deal with. */
  1027. if (result == FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base))
  1028. {
  1029. break;
  1030. }
  1031. /* Solve Rx FIFO interrupt. */
  1032. if ((kFLEXCAN_StateIdle != handle->rxFifoState) && ((1 << result) <= kFLEXCAN_RxFifoOverflowFlag))
  1033. {
  1034. switch (1 << result)
  1035. {
  1036. case kFLEXCAN_RxFifoOverflowFlag:
  1037. status = kStatus_FLEXCAN_RxFifoOverflow;
  1038. break;
  1039. case kFLEXCAN_RxFifoWarningFlag:
  1040. status = kStatus_FLEXCAN_RxFifoWarning;
  1041. break;
  1042. case kFLEXCAN_RxFifoFrameAvlFlag:
  1043. status = FLEXCAN_ReadRxFifo(base, handle->rxFifoFrameBuf);
  1044. if (kStatus_Success == status)
  1045. {
  1046. status = kStatus_FLEXCAN_RxFifoIdle;
  1047. }
  1048. FLEXCAN_TransferAbortReceiveFifo(base, handle);
  1049. break;
  1050. default:
  1051. status = kStatus_FLEXCAN_UnHandled;
  1052. break;
  1053. }
  1054. }
  1055. else
  1056. {
  1057. /* Get current State of Message Buffer. */
  1058. switch (handle->mbState[result])
  1059. {
  1060. /* Solve Rx Data Frame. */
  1061. case kFLEXCAN_StateRxData:
  1062. status = FLEXCAN_ReadRxMb(base, result, handle->mbFrameBuf[result]);
  1063. if (kStatus_Success == status)
  1064. {
  1065. status = kStatus_FLEXCAN_RxIdle;
  1066. }
  1067. FLEXCAN_TransferAbortReceive(base, handle, result);
  1068. break;
  1069. /* Solve Rx Remote Frame. */
  1070. case kFLEXCAN_StateRxRemote:
  1071. status = FLEXCAN_ReadRxMb(base, result, handle->mbFrameBuf[result]);
  1072. if (kStatus_Success == status)
  1073. {
  1074. status = kStatus_FLEXCAN_RxIdle;
  1075. }
  1076. FLEXCAN_TransferAbortReceive(base, handle, result);
  1077. break;
  1078. /* Solve Tx Data Frame. */
  1079. case kFLEXCAN_StateTxData:
  1080. status = kStatus_FLEXCAN_TxIdle;
  1081. FLEXCAN_TransferAbortSend(base, handle, result);
  1082. break;
  1083. /* Solve Tx Remote Frame. */
  1084. case kFLEXCAN_StateTxRemote:
  1085. handle->mbState[result] = kFLEXCAN_StateRxRemote;
  1086. status = kStatus_FLEXCAN_TxSwitchToRx;
  1087. break;
  1088. default:
  1089. status = kStatus_FLEXCAN_UnHandled;
  1090. break;
  1091. }
  1092. }
  1093. /* Clear resolved Message Buffer IRQ. */
  1094. FLEXCAN_ClearMbStatusFlags(base, 1 << result);
  1095. }
  1096. /* Calling Callback Function if has one. */
  1097. if (handle->callback != NULL)
  1098. {
  1099. handle->callback(base, handle, status, result, handle->userData);
  1100. }
  1101. /* Reset return status */
  1102. status = kStatus_FLEXCAN_UnHandled;
  1103. /* Store Current FlexCAN Module Error and Status. */
  1104. result = base->ESR1;
  1105. }
  1106. #if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
  1107. while ((0 != FLEXCAN_GetMbStatusFlags(base, 0xFFFFFFFFFFFFFFFFU)) ||
  1108. (0 != (result & (kFLEXCAN_TxWarningIntFlag | kFLEXCAN_RxWarningIntFlag | kFLEXCAN_BusOffIntFlag |
  1109. kFLEXCAN_ErrorIntFlag | kFLEXCAN_WakeUpIntFlag))));
  1110. #else
  1111. while ((0 != FLEXCAN_GetMbStatusFlags(base, 0xFFFFFFFFU)) ||
  1112. (0 != (result & (kFLEXCAN_TxWarningIntFlag | kFLEXCAN_RxWarningIntFlag | kFLEXCAN_BusOffIntFlag |
  1113. kFLEXCAN_ErrorIntFlag | kFLEXCAN_WakeUpIntFlag))));
  1114. #endif
  1115. }
  1116. #if defined(CAN0)
  1117. void CAN0_DriverIRQHandler(void)
  1118. {
  1119. assert(s_flexcanHandle[0]);
  1120. s_flexcanIsr(CAN0, s_flexcanHandle[0]);
  1121. }
  1122. #endif
  1123. #if defined(CAN1)
  1124. void CAN1_DriverIRQHandler(void)
  1125. {
  1126. assert(s_flexcanHandle[1]);
  1127. s_flexcanIsr(CAN1, s_flexcanHandle[1]);
  1128. }
  1129. #endif
  1130. #if defined(CAN2)
  1131. void CAN2_DriverIRQHandler(void)
  1132. {
  1133. assert(s_flexcanHandle[2]);
  1134. s_flexcanIsr(CAN2, s_flexcanHandle[2]);
  1135. }
  1136. #endif
  1137. #if defined(CAN3)
  1138. void CAN3_DriverIRQHandler(void)
  1139. {
  1140. assert(s_flexcanHandle[3]);
  1141. s_flexcanIsr(CAN3, s_flexcanHandle[3]);
  1142. }
  1143. #endif
  1144. #if defined(CAN4)
  1145. void CAN4_DriverIRQHandler(void)
  1146. {
  1147. assert(s_flexcanHandle[4]);
  1148. s_flexcanIsr(CAN4, s_flexcanHandle[4]);
  1149. }
  1150. #endif
  1151. #if defined(DMA_CAN0)
  1152. void DMA_FLEXCAN0_DriverIRQHandler(void)
  1153. {
  1154. assert(s_flexcanHandle[FLEXCAN_GetInstance(DMA_CAN0)]);
  1155. s_flexcanIsr(DMA_CAN0, s_flexcanHandle[FLEXCAN_GetInstance(DMA_CAN0)]);
  1156. }
  1157. #endif
  1158. #if defined(DMA_CAN1)
  1159. void DMA_FLEXCAN1_DriverIRQHandler(void)
  1160. {
  1161. assert(s_flexcanHandle[FLEXCAN_GetInstance(DMA_CAN1)]);
  1162. s_flexcanIsr(DMA_CAN0, s_flexcanHandle[FLEXCAN_GetInstance(DMA_CAN1)]);
  1163. }
  1164. #endif
  1165. #if defined(DMA_CAN2)
  1166. void DMA_FLEXCAN2_DriverIRQHandler(void)
  1167. {
  1168. assert(s_flexcanHandle[FLEXCAN_GetInstance(DMA_CAN2)]);
  1169. s_flexcanIsr(DMA_CAN2, s_flexcanHandle[FLEXCAN_GetInstance(DMA_CAN2)]);
  1170. }
  1171. #endif