fsl_flexcan.c 69 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127
  1. /*
  2. * The Clear BSD License
  3. * Copyright (c) 2015, Freescale Semiconductor, Inc.
  4. * Copyright 2016-2017 NXP
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without modification,
  8. * are permitted (subject to the limitations in the disclaimer below) provided
  9. * that the following conditions are met:
  10. *
  11. * o Redistributions of source code must retain the above copyright notice, this list
  12. * of conditions and the following disclaimer.
  13. *
  14. * o Redistributions in binary form must reproduce the above copyright notice, this
  15. * list of conditions and the following disclaimer in the documentation and/or
  16. * other materials provided with the distribution.
  17. *
  18. * o Neither the name of the copyright holder nor the names of its
  19. * contributors may be used to endorse or promote products derived from this
  20. * software without specific prior written permission.
  21. *
  22. * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
  23. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  24. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  25. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  26. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
  27. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  28. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  29. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  30. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  31. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  32. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  33. */
  34. #include "fsl_flexcan.h"
  35. /*******************************************************************************
  36. * Definitions
  37. ******************************************************************************/
  38. /* Component ID definition, used by tools. */
  39. #ifndef FSL_COMPONENT_ID
  40. #define FSL_COMPONENT_ID "platform.drivers.flexcan"
  41. #endif
  42. /*! @brief FlexCAN Internal State. */
  43. enum _flexcan_state
  44. {
  45. kFLEXCAN_StateIdle = 0x0, /*!< MB/RxFIFO idle.*/
  46. kFLEXCAN_StateRxData = 0x1, /*!< MB receiving.*/
  47. kFLEXCAN_StateRxRemote = 0x2, /*!< MB receiving remote reply.*/
  48. kFLEXCAN_StateTxData = 0x3, /*!< MB transmitting.*/
  49. kFLEXCAN_StateTxRemote = 0x4, /*!< MB transmitting remote request.*/
  50. kFLEXCAN_StateRxFifo = 0x5, /*!< RxFIFO receiving.*/
  51. };
  52. /*! @brief FlexCAN message buffer CODE for Rx buffers. */
  53. enum _flexcan_mb_code_rx
  54. {
  55. kFLEXCAN_RxMbInactive = 0x0, /*!< MB is not active.*/
  56. kFLEXCAN_RxMbFull = 0x2, /*!< MB is full.*/
  57. kFLEXCAN_RxMbEmpty = 0x4, /*!< MB is active and empty.*/
  58. kFLEXCAN_RxMbOverrun = 0x6, /*!< MB is overwritten into a full buffer.*/
  59. kFLEXCAN_RxMbBusy = 0x8, /*!< FlexCAN is updating the contents of the MB.*/
  60. /*! The CPU must not access the MB.*/
  61. kFLEXCAN_RxMbRanswer = 0xA, /*!< A frame was configured to recognize a Remote Request Frame */
  62. /*! and transmit a Response Frame in return.*/
  63. kFLEXCAN_RxMbNotUsed = 0xF, /*!< Not used.*/
  64. };
  65. /*! @brief FlexCAN message buffer CODE FOR Tx buffers. */
  66. enum _flexcan_mb_code_tx
  67. {
  68. kFLEXCAN_TxMbInactive = 0x8, /*!< MB is not active.*/
  69. kFLEXCAN_TxMbAbort = 0x9, /*!< MB is aborted.*/
  70. kFLEXCAN_TxMbDataOrRemote = 0xC, /*!< MB is a TX Data Frame(when MB RTR = 0) or */
  71. /*!< MB is a TX Remote Request Frame (when MB RTR = 1).*/
  72. kFLEXCAN_TxMbTanswer = 0xE, /*!< MB is a TX Response Request Frame from */
  73. /*! an incoming Remote Request Frame.*/
  74. kFLEXCAN_TxMbNotUsed = 0xF, /*!< Not used.*/
  75. };
  76. /* Typedef for interrupt handler. */
  77. typedef void (*flexcan_isr_t)(CAN_Type *base, flexcan_handle_t *handle);
  78. /*******************************************************************************
  79. * Prototypes
  80. ******************************************************************************/
  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. * @param timingConfig FlexCAN timingConfig.
  147. */
  148. static void FLEXCAN_SetBaudRate(CAN_Type *base,
  149. uint32_t sourceClock_Hz,
  150. uint32_t baudRate_Bps,
  151. flexcan_timing_config_t timingConfig);
  152. #if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE)
  153. /*!
  154. * @brief Set Baud Rate of FlexCAN FD frame.
  155. *
  156. * This function set the baud rate of FlexCAN FD frame.
  157. *
  158. * @param base FlexCAN peripheral base address.
  159. * @param sourceClock_Hz Source Clock in Hz.
  160. * @param baudRateFD_Bps FD frame Baud Rate in Bps.
  161. * @param timingConfig FlexCAN timingConfig.
  162. */
  163. static void FLEXCAN_SetFDBaudRate(CAN_Type *base, uint32_t sourceClock_Hz, uint32_t baudRateFD_Bps, flexcan_timing_config_t timingConfig);
  164. /*!
  165. * @brief Get Mailbox offset number by dword.
  166. *
  167. * This function gets the offset number of the specified mailbox.
  168. * Mailbox is not consecutive between memory regions when payload is not 8 bytes
  169. * so need to calculate the specified mailbox address.
  170. * For example, in the first memory region, MB[0].CS address is 0x4002_4080. For 32 bytes
  171. * payload frame, the second mailbox is ((1/12)*512 + 1%12*40)/4 = 10, meaning 10 dword
  172. * after the 0x4002_4080, which is actually the address of mailbox MB[1].CS.
  173. *
  174. * @param base FlexCAN peripheral base address.
  175. * @param mbIdx Mailbox index.
  176. */
  177. static uint32_t FLEXCAN_GetFDMailboxOffset(CAN_Type *base, uint8_t mbIdx);
  178. #endif
  179. /*******************************************************************************
  180. * Variables
  181. ******************************************************************************/
  182. /* Array of FlexCAN peripheral base address. */
  183. static CAN_Type *const s_flexcanBases[] = CAN_BASE_PTRS;
  184. /* Array of FlexCAN IRQ number. */
  185. static const IRQn_Type s_flexcanRxWarningIRQ[] = CAN_Rx_Warning_IRQS;
  186. static const IRQn_Type s_flexcanTxWarningIRQ[] = CAN_Tx_Warning_IRQS;
  187. static const IRQn_Type s_flexcanWakeUpIRQ[] = CAN_Wake_Up_IRQS;
  188. static const IRQn_Type s_flexcanErrorIRQ[] = CAN_Error_IRQS;
  189. static const IRQn_Type s_flexcanBusOffIRQ[] = CAN_Bus_Off_IRQS;
  190. static const IRQn_Type s_flexcanMbIRQ[] = CAN_ORed_Message_buffer_IRQS;
  191. /* Array of FlexCAN handle. */
  192. static flexcan_handle_t *s_flexcanHandle[ARRAY_SIZE(s_flexcanBases)];
  193. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  194. /* Array of FlexCAN clock name. */
  195. static const clock_ip_name_t s_flexcanClock[] = FLEXCAN_CLOCKS;
  196. #if defined(FLEXCAN_PERIPH_CLOCKS)
  197. /* Array of FlexCAN serial clock name. */
  198. static const clock_ip_name_t s_flexcanPeriphClock[] = FLEXCAN_PERIPH_CLOCKS;
  199. #endif /* FLEXCAN_PERIPH_CLOCKS */
  200. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  201. /* FlexCAN ISR for transactional APIs. */
  202. static flexcan_isr_t s_flexcanIsr;
  203. /*******************************************************************************
  204. * Code
  205. ******************************************************************************/
  206. uint32_t FLEXCAN_GetInstance(CAN_Type *base)
  207. {
  208. uint32_t instance;
  209. /* Find the instance index from base address mappings. */
  210. for (instance = 0; instance < ARRAY_SIZE(s_flexcanBases); instance++)
  211. {
  212. if (s_flexcanBases[instance] == base)
  213. {
  214. break;
  215. }
  216. }
  217. assert(instance < ARRAY_SIZE(s_flexcanBases));
  218. return instance;
  219. }
  220. static void FLEXCAN_EnterFreezeMode(CAN_Type *base)
  221. {
  222. /* Set Freeze, Halt bits. */
  223. base->MCR |= CAN_MCR_FRZ_MASK;
  224. base->MCR |= CAN_MCR_HALT_MASK;
  225. /* Wait until the FlexCAN Module enter freeze mode. */
  226. while (!(base->MCR & CAN_MCR_FRZACK_MASK))
  227. {
  228. }
  229. }
  230. static void FLEXCAN_ExitFreezeMode(CAN_Type *base)
  231. {
  232. /* Clear Freeze, Halt bits. */
  233. base->MCR &= ~CAN_MCR_HALT_MASK;
  234. base->MCR &= ~CAN_MCR_FRZ_MASK;
  235. /* Wait until the FlexCAN Module exit freeze mode. */
  236. while (base->MCR & CAN_MCR_FRZACK_MASK)
  237. {
  238. }
  239. }
  240. #if !defined(NDEBUG)
  241. static bool FLEXCAN_IsMbOccupied(CAN_Type *base, uint8_t mbIdx)
  242. {
  243. uint8_t lastOccupiedMb;
  244. /* Is Rx FIFO enabled? */
  245. if (base->MCR & CAN_MCR_RFEN_MASK)
  246. {
  247. /* Get RFFN value. */
  248. lastOccupiedMb = ((base->CTRL2 & CAN_CTRL2_RFFN_MASK) >> CAN_CTRL2_RFFN_SHIFT);
  249. /* Calculate the number of last Message Buffer occupied by Rx FIFO. */
  250. lastOccupiedMb = ((lastOccupiedMb + 1) * 2) + 5;
  251. #if (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641)
  252. if (mbIdx <= (lastOccupiedMb + 1))
  253. #else
  254. if (mbIdx <= lastOccupiedMb)
  255. #endif
  256. {
  257. return true;
  258. }
  259. else
  260. {
  261. return false;
  262. }
  263. }
  264. else
  265. {
  266. #if (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641)
  267. if (0 == mbIdx)
  268. {
  269. return true;
  270. }
  271. else
  272. {
  273. return false;
  274. }
  275. #else
  276. return false;
  277. #endif
  278. }
  279. }
  280. #endif
  281. #if (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641)
  282. static uint32_t FLEXCAN_GetFirstValidMb(CAN_Type *base)
  283. {
  284. uint32_t firstValidMbNum;
  285. if (base->MCR & CAN_MCR_RFEN_MASK)
  286. {
  287. firstValidMbNum = ((base->CTRL2 & CAN_CTRL2_RFFN_MASK) >> CAN_CTRL2_RFFN_SHIFT);
  288. firstValidMbNum = ((firstValidMbNum + 1) * 2) + 6;
  289. }
  290. else
  291. {
  292. firstValidMbNum = 0;
  293. }
  294. return firstValidMbNum;
  295. }
  296. #endif
  297. static bool FLEXCAN_IsMbIntEnabled(CAN_Type *base, uint8_t mbIdx)
  298. {
  299. /* Assertion. */
  300. assert(mbIdx < FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base));
  301. #if (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
  302. if (mbIdx < 32)
  303. {
  304. #endif
  305. if (base->IMASK1 & ((uint32_t)(1 << mbIdx)))
  306. {
  307. return true;
  308. }
  309. else
  310. {
  311. return false;
  312. }
  313. #if (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
  314. }
  315. else
  316. {
  317. if (base->IMASK2 & ((uint32_t)(1 << (mbIdx - 32))))
  318. {
  319. return true;
  320. }
  321. else
  322. {
  323. return false;
  324. }
  325. }
  326. #endif
  327. }
  328. static void FLEXCAN_Reset(CAN_Type *base)
  329. {
  330. /* The module must should be first exit from low power
  331. * mode, and then soft reset can be applied.
  332. */
  333. assert(!(base->MCR & CAN_MCR_MDIS_MASK));
  334. uint8_t i;
  335. #if (FSL_FEATURE_FLEXCAN_HAS_DOZE_MODE_SUPPORT != 0)
  336. /* De-assert DOZE Enable Bit. */
  337. base->MCR &= ~CAN_MCR_DOZE_MASK;
  338. #endif
  339. /* Wait until FlexCAN exit from any Low Power Mode. */
  340. while (base->MCR & CAN_MCR_LPMACK_MASK)
  341. {
  342. }
  343. /* Assert Soft Reset Signal. */
  344. base->MCR |= CAN_MCR_SOFTRST_MASK;
  345. /* Wait until FlexCAN reset completes. */
  346. while (base->MCR & CAN_MCR_SOFTRST_MASK)
  347. {
  348. }
  349. /* Reset MCR rigister. */
  350. #if (defined(FSL_FEATURE_FLEXCAN_HAS_GLITCH_FILTER) && FSL_FEATURE_FLEXCAN_HAS_GLITCH_FILTER)
  351. base->MCR |= CAN_MCR_WRNEN_MASK | CAN_MCR_WAKSRC_MASK |
  352. CAN_MCR_MAXMB(FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base) - 1);
  353. #else
  354. base->MCR |= CAN_MCR_WRNEN_MASK | CAN_MCR_MAXMB(FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base) - 1);
  355. #endif
  356. /* Reset CTRL1 and CTRL2 rigister. */
  357. base->CTRL1 = CAN_CTRL1_SMP_MASK;
  358. base->CTRL2 = CAN_CTRL2_TASD(0x16) | CAN_CTRL2_RRS_MASK | CAN_CTRL2_EACEN_MASK;
  359. /* Clean all individual Rx Mask of Message Buffers. */
  360. for (i = 0; i < FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base); i++)
  361. {
  362. base->RXIMR[i] = 0x3FFFFFFF;
  363. }
  364. /* Clean Global Mask of Message Buffers. */
  365. base->RXMGMASK = 0x3FFFFFFF;
  366. /* Clean Global Mask of Message Buffer 14. */
  367. base->RX14MASK = 0x3FFFFFFF;
  368. /* Clean Global Mask of Message Buffer 15. */
  369. base->RX15MASK = 0x3FFFFFFF;
  370. /* Clean Global Mask of Rx FIFO. */
  371. base->RXFGMASK = 0x3FFFFFFF;
  372. /* Clean all Message Buffer CS fields. */
  373. for (i = 0; i < FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base); i++)
  374. {
  375. base->MB[i].CS = 0x0;
  376. }
  377. }
  378. static void FLEXCAN_SetBaudRate(CAN_Type *base,
  379. uint32_t sourceClock_Hz,
  380. uint32_t baudRate_Bps,
  381. flexcan_timing_config_t timingConfig)
  382. {
  383. /* FlexCAN timing setting formula:
  384. * quantum = 1 + (PSEG1 + 1) + (PSEG2 + 1) + (PROPSEG + 1);
  385. */
  386. uint32_t quantum = 1 + (timingConfig.phaseSeg1 + 1) + (timingConfig.phaseSeg2 + 1) + (timingConfig.propSeg + 1);
  387. uint32_t priDiv = baudRate_Bps * quantum;
  388. /* Assertion: Desired baud rate is too high. */
  389. assert(baudRate_Bps <= 1000000U);
  390. /* Assertion: Source clock should greater than baud rate * quantum. */
  391. assert(priDiv <= sourceClock_Hz);
  392. if (0 == priDiv)
  393. {
  394. priDiv = 1;
  395. }
  396. priDiv = (sourceClock_Hz / priDiv) - 1;
  397. /* Desired baud rate is too low. */
  398. if (priDiv > 0xFF)
  399. {
  400. priDiv = 0xFF;
  401. }
  402. timingConfig.preDivider = priDiv;
  403. /* Update actual timing characteristic. */
  404. FLEXCAN_SetTimingConfig(base, &timingConfig);
  405. }
  406. #if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE)
  407. static void FLEXCAN_SetFDBaudRate(CAN_Type *base,
  408. uint32_t sourceClock_Hz,
  409. uint32_t baudRateFD_Bps,
  410. flexcan_timing_config_t timingConfig)
  411. {
  412. /* FlexCAN FD timing setting formula:
  413. * quantum = 1 + (FPSEG1 + 1) + (FPSEG2 + 1) + FPROPSEG;
  414. */
  415. uint32_t quantum = 1 + (timingConfig.fphaseSeg1 + 1) + (timingConfig.fphaseSeg2 + 1) + timingConfig.fpropSeg;
  416. uint32_t priDiv = baudRateFD_Bps * quantum;
  417. /* Assertion: Desired baud rate is too high. */
  418. assert(baudRateFD_Bps <= 8000000U);
  419. /* Assertion: Source clock should greater than baud rate * FLEXCAN_TIME_QUANTA_NUM. */
  420. assert(priDiv <= sourceClock_Hz);
  421. if (0 == priDiv)
  422. {
  423. priDiv = 1;
  424. }
  425. priDiv = (sourceClock_Hz / priDiv) - 1;
  426. /* Desired baud rate is too low. */
  427. if (priDiv > 0xFF)
  428. {
  429. priDiv = 0xFF;
  430. }
  431. timingConfig.fpreDivider = priDiv;
  432. /* Update actual timing characteristic. */
  433. FLEXCAN_SetFDTimingConfig(base, &timingConfig);
  434. }
  435. #endif
  436. void FLEXCAN_Init(CAN_Type *base, const flexcan_config_t *config, uint32_t sourceClock_Hz)
  437. {
  438. uint32_t mcrTemp;
  439. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  440. uint32_t instance;
  441. #endif
  442. /* Assertion. */
  443. assert(config);
  444. assert((config->maxMbNum > 0) && (config->maxMbNum <= FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base)));
  445. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  446. instance = FLEXCAN_GetInstance(base);
  447. /* Enable FlexCAN clock. */
  448. CLOCK_EnableClock(s_flexcanClock[instance]);
  449. #if defined(FLEXCAN_PERIPH_CLOCKS)
  450. /* Enable FlexCAN serial clock. */
  451. CLOCK_EnableClock(s_flexcanPeriphClock[instance]);
  452. #endif /* FLEXCAN_PERIPH_CLOCKS */
  453. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  454. #if (!defined(FSL_FEATURE_FLEXCAN_SUPPORT_ENGINE_CLK_SEL_REMOVE)) || !FSL_FEATURE_FLEXCAN_SUPPORT_ENGINE_CLK_SEL_REMOVE
  455. /* Disable FlexCAN Module. */
  456. FLEXCAN_Enable(base, false);
  457. /* Protocol-Engine clock source selection, This bit must be set
  458. * when FlexCAN Module in Disable Mode.
  459. */
  460. base->CTRL1 = (kFLEXCAN_ClkSrcOsc == config->clkSrc) ? base->CTRL1 & ~CAN_CTRL1_CLKSRC_MASK :
  461. base->CTRL1 | CAN_CTRL1_CLKSRC_MASK;
  462. #endif /* FSL_FEATURE_FLEXCAN_SUPPORT_ENGINE_CLK_SEL_REMOVE */
  463. /* Enable FlexCAN Module for configuartion. */
  464. FLEXCAN_Enable(base, true);
  465. /* Reset to known status. */
  466. FLEXCAN_Reset(base);
  467. /* Save current MCR value and enable to enter Freeze mode(enabled by default). */
  468. mcrTemp = base->MCR;
  469. /* Set the maximum number of Message Buffers */
  470. mcrTemp = (mcrTemp & ~CAN_MCR_MAXMB_MASK) | CAN_MCR_MAXMB(config->maxMbNum - 1);
  471. /* Enable Loop Back Mode? */
  472. base->CTRL1 = (config->enableLoopBack) ? base->CTRL1 | CAN_CTRL1_LPB_MASK : base->CTRL1 & ~CAN_CTRL1_LPB_MASK;
  473. /* Enable Self Wake Up Mode? */
  474. mcrTemp = (config->enableSelfWakeup) ? mcrTemp | CAN_MCR_SLFWAK_MASK : mcrTemp & ~CAN_MCR_SLFWAK_MASK;
  475. /* Enable Individual Rx Masking? */
  476. mcrTemp = (config->enableIndividMask) ? mcrTemp | CAN_MCR_IRMQ_MASK : mcrTemp & ~CAN_MCR_IRMQ_MASK;
  477. #if (defined(FSL_FEATURE_FLEXCAN_HAS_DOZE_MODE_SUPPORT) && FSL_FEATURE_FLEXCAN_HAS_DOZE_MODE_SUPPORT)
  478. /* Enable Doze Mode? */
  479. mcrTemp = (config->enableDoze) ? mcrTemp | CAN_MCR_DOZE_MASK : mcrTemp & ~CAN_MCR_DOZE_MASK;
  480. #endif
  481. /* Save MCR Configuation. */
  482. base->MCR = mcrTemp;
  483. /* Baud Rate Configuration.*/
  484. FLEXCAN_SetBaudRate(base, sourceClock_Hz, config->baudRate, config->timingConfig);
  485. #if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE)
  486. FLEXCAN_SetFDBaudRate(base, sourceClock_Hz, config->baudRateFD, config->timingConfig);
  487. #endif
  488. }
  489. void FLEXCAN_Deinit(CAN_Type *base)
  490. {
  491. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  492. uint32_t instance;
  493. #endif
  494. /* Reset all Register Contents. */
  495. FLEXCAN_Reset(base);
  496. /* Disable FlexCAN module. */
  497. FLEXCAN_Enable(base, false);
  498. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  499. instance = FLEXCAN_GetInstance(base);
  500. #if defined(FLEXCAN_PERIPH_CLOCKS)
  501. /* Disable FlexCAN serial clock. */
  502. CLOCK_DisableClock(s_flexcanPeriphClock[instance]);
  503. #endif /* FLEXCAN_PERIPH_CLOCKS */
  504. /* Disable FlexCAN clock. */
  505. CLOCK_DisableClock(s_flexcanClock[instance]);
  506. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  507. }
  508. void FLEXCAN_GetDefaultConfig(flexcan_config_t *config)
  509. {
  510. /* Assertion. */
  511. assert(config);
  512. /* Initialize FlexCAN Module config struct with default value. */
  513. #if (!defined(FSL_FEATURE_FLEXCAN_SUPPORT_ENGINE_CLK_SEL_REMOVE)) || !FSL_FEATURE_FLEXCAN_SUPPORT_ENGINE_CLK_SEL_REMOVE
  514. config->clkSrc = kFLEXCAN_ClkSrcOsc;
  515. #endif /* FSL_FEATURE_FLEXCAN_SUPPORT_ENGINE_CLK_SEL_REMOVE */
  516. config->baudRate = 1000000U;
  517. #if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE)
  518. config->baudRateFD = 1000000U;
  519. #endif
  520. config->maxMbNum = 16;
  521. config->enableLoopBack = false;
  522. config->enableSelfWakeup = false;
  523. config->enableIndividMask = false;
  524. #if (defined(FSL_FEATURE_FLEXCAN_HAS_DOZE_MODE_SUPPORT) && FSL_FEATURE_FLEXCAN_HAS_DOZE_MODE_SUPPORT)
  525. config->enableDoze = false;
  526. #endif
  527. /* Default protocol timing configuration, time quantum is 10. */
  528. config->timingConfig.phaseSeg1 = 3;
  529. config->timingConfig.phaseSeg2 = 2;
  530. config->timingConfig.propSeg = 1;
  531. config->timingConfig.rJumpwidth = 1;
  532. #if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE)
  533. config->timingConfig.fphaseSeg1 = 3;
  534. config->timingConfig.fphaseSeg2 = 3;
  535. config->timingConfig.fpropSeg = 1;
  536. config->timingConfig.frJumpwidth = 1;
  537. #endif
  538. }
  539. #if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE)
  540. void FLEXCAN_FDEnable(CAN_Type *base, flexcan_mb_size_t dataSize, bool brs)
  541. {
  542. if (brs)
  543. {
  544. base->FDCTRL &= CAN_FDCTRL_FDRATE_MASK;
  545. }
  546. else
  547. {
  548. base->FDCTRL &= ~CAN_FDCTRL_FDRATE_MASK;
  549. }
  550. /* Enter Freeze Mode. */
  551. FLEXCAN_EnterFreezeMode(base);
  552. base->MCR |= CAN_MCR_FDEN_MASK;
  553. base->FDCTRL |= CAN_FDCTRL_MBDSR0(dataSize);
  554. #if defined(CAN_FDCTRL_MBDSR1_MASK)
  555. base->FDCTRL |= CAN_FDCTRL_MBDSR1(dataSize);
  556. #endif
  557. #if defined(CAN_FDCTRL_MBDSR2_MASK)
  558. base->FDCTRL |= CAN_FDCTRL_MBDSR2(dataSize);
  559. #endif
  560. #if defined(CAN_FDCTRL_MBDSR3_MASK)
  561. base->FDCTRL |= CAN_FDCTRL_MBDSR3(dataSize);
  562. #endif
  563. /* Exit Freeze Mode. */
  564. FLEXCAN_ExitFreezeMode(base);
  565. }
  566. #endif
  567. void FLEXCAN_SetTimingConfig(CAN_Type *base, const flexcan_timing_config_t *config)
  568. {
  569. /* Assertion. */
  570. assert(config);
  571. /* Enter Freeze Mode. */
  572. FLEXCAN_EnterFreezeMode(base);
  573. #if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE)
  574. /* Cleaning previous Timing Setting. */
  575. base->CBT &= ~(CAN_CBT_EPRESDIV_MASK | CAN_CBT_ERJW_MASK | CAN_CBT_EPSEG1_MASK | CAN_CBT_EPSEG2_MASK |
  576. CAN_CBT_EPROPSEG_MASK);
  577. /* Updating Timing Setting according to configuration structure. */
  578. base->CBT |=
  579. (CAN_CBT_EPRESDIV(config->preDivider) | CAN_CBT_ERJW(config->rJumpwidth) | CAN_CBT_EPSEG1(config->phaseSeg1) |
  580. CAN_CBT_EPSEG2(config->phaseSeg2) | CAN_CBT_EPROPSEG(config->propSeg));
  581. #else
  582. /* Cleaning previous Timing Setting. */
  583. base->CTRL1 &= ~(CAN_CTRL1_PRESDIV_MASK | CAN_CTRL1_RJW_MASK | CAN_CTRL1_PSEG1_MASK | CAN_CTRL1_PSEG2_MASK |
  584. CAN_CTRL1_PROPSEG_MASK);
  585. /* Updating Timing Setting according to configuration structure. */
  586. base->CTRL1 |=
  587. (CAN_CTRL1_PRESDIV(config->preDivider) | CAN_CTRL1_RJW(config->rJumpwidth) |
  588. CAN_CTRL1_PSEG1(config->phaseSeg1) | CAN_CTRL1_PSEG2(config->phaseSeg2) | CAN_CTRL1_PROPSEG(config->propSeg));
  589. #endif
  590. /* Exit Freeze Mode. */
  591. FLEXCAN_ExitFreezeMode(base);
  592. }
  593. #if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE)
  594. void FLEXCAN_SetFDTimingConfig(CAN_Type *base, const flexcan_timing_config_t *config)
  595. {
  596. /* Assertion. */
  597. assert(config);
  598. /* Enter Freeze Mode. */
  599. FLEXCAN_EnterFreezeMode(base);
  600. base->CBT |= CAN_CBT_BTF(1);
  601. /* Cleaning previous Timing Setting. */
  602. base->FDCBT &= ~(CAN_FDCBT_FPRESDIV_MASK | CAN_FDCBT_FRJW_MASK | CAN_FDCBT_FPSEG1_MASK | CAN_FDCBT_FPSEG2_MASK |
  603. CAN_FDCBT_FPROPSEG_MASK);
  604. /* Updating Timing Setting according to configuration structure. */
  605. base->FDCBT |= (CAN_FDCBT_FPRESDIV(config->fpreDivider) | CAN_FDCBT_FRJW(config->frJumpwidth) |
  606. CAN_FDCBT_FPSEG1(config->fphaseSeg1) | CAN_FDCBT_FPSEG2(config->fphaseSeg2) |
  607. CAN_FDCBT_FPROPSEG(config->fpropSeg));
  608. /* Exit Freeze Mode. */
  609. FLEXCAN_ExitFreezeMode(base);
  610. }
  611. #endif
  612. void FLEXCAN_SetRxMbGlobalMask(CAN_Type *base, uint32_t mask)
  613. {
  614. /* Enter Freeze Mode. */
  615. FLEXCAN_EnterFreezeMode(base);
  616. /* Setting Rx Message Buffer Global Mask value. */
  617. base->RXMGMASK = mask;
  618. base->RX14MASK = mask;
  619. base->RX15MASK = mask;
  620. /* Exit Freeze Mode. */
  621. FLEXCAN_ExitFreezeMode(base);
  622. }
  623. void FLEXCAN_SetRxFifoGlobalMask(CAN_Type *base, uint32_t mask)
  624. {
  625. /* Enter Freeze Mode. */
  626. FLEXCAN_EnterFreezeMode(base);
  627. /* Setting Rx FIFO Global Mask value. */
  628. base->RXFGMASK = mask;
  629. /* Exit Freeze Mode. */
  630. FLEXCAN_ExitFreezeMode(base);
  631. }
  632. void FLEXCAN_SetRxIndividualMask(CAN_Type *base, uint8_t maskIdx, uint32_t mask)
  633. {
  634. assert(maskIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
  635. /* Enter Freeze Mode. */
  636. FLEXCAN_EnterFreezeMode(base);
  637. /* Setting Rx Individual Mask value. */
  638. base->RXIMR[maskIdx] = mask;
  639. /* Exit Freeze Mode. */
  640. FLEXCAN_ExitFreezeMode(base);
  641. }
  642. void FLEXCAN_SetTxMbConfig(CAN_Type *base, uint8_t mbIdx, bool enable)
  643. {
  644. /* Assertion. */
  645. assert(mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
  646. assert(!FLEXCAN_IsMbOccupied(base, mbIdx));
  647. /* Inactivate Message Buffer. */
  648. if (enable)
  649. {
  650. base->MB[mbIdx].CS = CAN_CS_CODE(kFLEXCAN_TxMbInactive);
  651. }
  652. else
  653. {
  654. base->MB[mbIdx].CS = 0;
  655. }
  656. /* Clean Message Buffer content. */
  657. base->MB[mbIdx].ID = 0x0;
  658. base->MB[mbIdx].WORD0 = 0x0;
  659. base->MB[mbIdx].WORD1 = 0x0;
  660. }
  661. #if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE)
  662. static uint32_t FLEXCAN_GetFDMailboxOffset(CAN_Type *base, uint8_t mbIdx)
  663. {
  664. uint32_t dataSize;
  665. uint32_t offset = 0;
  666. dataSize = (base->FDCTRL & CAN_FDCTRL_MBDSR0_MASK) >> CAN_FDCTRL_MBDSR0_SHIFT;
  667. switch (dataSize)
  668. {
  669. case kFLEXCAN_8BperMB:
  670. offset = (mbIdx / 32) * 512 + mbIdx % 32 * 16;
  671. break;
  672. case kFLEXCAN_16BperMB:
  673. offset = (mbIdx / 21) * 512 + mbIdx % 21 * 24;
  674. break;
  675. case kFLEXCAN_32BperMB:
  676. offset = (mbIdx / 12) * 512 + mbIdx % 12 * 40;
  677. break;
  678. case kFLEXCAN_64BperMB:
  679. offset = (mbIdx / 7) * 512 + mbIdx % 7 * 72;
  680. break;
  681. default:
  682. break;
  683. }
  684. /* To get the dword aligned offset, need to divide by 4. */
  685. offset = offset / 4;
  686. return offset;
  687. }
  688. #endif
  689. #if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE)
  690. void FLEXCAN_SetFDTxMbConfig(CAN_Type *base, uint8_t mbIdx, bool enable)
  691. {
  692. /* Assertion. */
  693. assert(mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
  694. assert(!FLEXCAN_IsMbOccupied(base, mbIdx));
  695. uint8_t cnt = 0;
  696. uint8_t payload_dword = 1;
  697. uint32_t dataSize;
  698. dataSize = (base->FDCTRL & CAN_FDCTRL_MBDSR0_MASK) >> CAN_FDCTRL_MBDSR0_SHIFT;
  699. volatile uint32_t *mbAddr = &(base->MB[0].CS);
  700. uint32_t offset = FLEXCAN_GetFDMailboxOffset(base, mbIdx);
  701. #if (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641)
  702. uint32_t availoffset = FLEXCAN_GetFDMailboxOffset(base, FLEXCAN_GetFirstValidMb(base));
  703. #endif
  704. /* Inactivate Message Buffer. */
  705. if (enable)
  706. {
  707. /* Inactivate by writing CS. */
  708. mbAddr[offset] = CAN_CS_CODE(kFLEXCAN_TxMbInactive);
  709. }
  710. else
  711. {
  712. mbAddr[offset] = 0x0;
  713. }
  714. /* Calculate the DWORD number, dataSize 0/1/2/3 corresponds to 8/16/32/64
  715. Bytes payload. */
  716. for (cnt = 0; cnt < dataSize + 1; cnt++)
  717. {
  718. payload_dword *= 2;
  719. }
  720. /* Clean ID. */
  721. mbAddr[offset + 1] = 0x0;
  722. /* Clean Message Buffer content, DWORD by DWORD. */
  723. for (cnt = 0; cnt < payload_dword; cnt++)
  724. {
  725. mbAddr[offset + 2 + cnt] = 0x0;
  726. }
  727. #if (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641)
  728. mbAddr[availoffset] = CAN_CS_CODE(kFLEXCAN_TxMbInactive);
  729. #endif
  730. }
  731. #endif
  732. void FLEXCAN_SetRxMbConfig(CAN_Type *base, uint8_t mbIdx, const flexcan_rx_mb_config_t *config, bool enable)
  733. {
  734. /* Assertion. */
  735. assert(mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
  736. assert(((config) || (false == enable)));
  737. assert(!FLEXCAN_IsMbOccupied(base, mbIdx));
  738. uint32_t cs_temp = 0;
  739. /* Inactivate Message Buffer. */
  740. base->MB[mbIdx].CS = 0;
  741. /* Clean Message Buffer content. */
  742. base->MB[mbIdx].ID = 0x0;
  743. base->MB[mbIdx].WORD0 = 0x0;
  744. base->MB[mbIdx].WORD1 = 0x0;
  745. if (enable)
  746. {
  747. /* Setup Message Buffer ID. */
  748. base->MB[mbIdx].ID = config->id;
  749. /* Setup Message Buffer format. */
  750. if (kFLEXCAN_FrameFormatExtend == config->format)
  751. {
  752. cs_temp |= CAN_CS_IDE_MASK;
  753. }
  754. /* Setup Message Buffer type. */
  755. if (kFLEXCAN_FrameTypeRemote == config->type)
  756. {
  757. cs_temp |= CAN_CS_RTR_MASK;
  758. }
  759. /* Activate Rx Message Buffer. */
  760. cs_temp |= CAN_CS_CODE(kFLEXCAN_RxMbEmpty);
  761. base->MB[mbIdx].CS = cs_temp;
  762. }
  763. }
  764. #if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE)
  765. void FLEXCAN_SetFDRxMbConfig(CAN_Type *base, uint8_t mbIdx, const flexcan_rx_mb_config_t *config, bool enable)
  766. {
  767. /* Assertion. */
  768. assert(mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
  769. assert(((config) || (false == enable)));
  770. assert(!FLEXCAN_IsMbOccupied(base, mbIdx));
  771. uint32_t cs_temp = 0;
  772. uint8_t cnt = 0;
  773. volatile uint32_t *mbAddr = &(base->MB[0].CS);
  774. uint32_t offset = FLEXCAN_GetFDMailboxOffset(base, mbIdx);
  775. /* Inactivate all mailboxes first, clean ID and Message Buffer content. */
  776. for (cnt = 0; cnt < FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base); cnt++)
  777. {
  778. base->MB[cnt].CS = 0;
  779. base->MB[cnt].ID = 0;
  780. base->MB[cnt].WORD0 = 0;
  781. base->MB[cnt].WORD1 = 0;
  782. }
  783. if (enable)
  784. {
  785. /* Setup Message Buffer ID. */
  786. mbAddr[offset + 1] = config->id;
  787. /* Setup Message Buffer format. */
  788. if (kFLEXCAN_FrameFormatExtend == config->format)
  789. {
  790. cs_temp |= CAN_CS_IDE_MASK;
  791. }
  792. /* Activate Rx Message Buffer. */
  793. cs_temp |= CAN_CS_CODE(kFLEXCAN_RxMbEmpty);
  794. mbAddr[offset] = cs_temp;
  795. }
  796. }
  797. #endif
  798. void FLEXCAN_SetRxFifoConfig(CAN_Type *base, const flexcan_rx_fifo_config_t *config, bool enable)
  799. {
  800. /* Assertion. */
  801. assert((config) || (false == enable));
  802. volatile uint32_t *idFilterRegion = (volatile uint32_t *)(&base->MB[6].CS);
  803. uint8_t setup_mb, i, rffn = 0;
  804. /* Enter Freeze Mode. */
  805. FLEXCAN_EnterFreezeMode(base);
  806. if (enable)
  807. {
  808. assert(config->idFilterNum <= 128);
  809. /* Get the setup_mb value. */
  810. setup_mb = (base->MCR & CAN_MCR_MAXMB_MASK) >> CAN_MCR_MAXMB_SHIFT;
  811. setup_mb = (setup_mb < FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base)) ?
  812. setup_mb :
  813. FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base);
  814. /* Determine RFFN value. */
  815. for (i = 0; i <= 0xF; i++)
  816. {
  817. if ((8 * (i + 1)) >= config->idFilterNum)
  818. {
  819. rffn = i;
  820. assert(((setup_mb - 8) - (2 * rffn)) > 0);
  821. base->CTRL2 = (base->CTRL2 & ~CAN_CTRL2_RFFN_MASK) | CAN_CTRL2_RFFN(rffn);
  822. break;
  823. }
  824. }
  825. }
  826. else
  827. {
  828. rffn = (base->CTRL2 & CAN_CTRL2_RFFN_MASK) >> CAN_CTRL2_RFFN_SHIFT;
  829. }
  830. /* Clean ID filter table occuyied Message Buffer Region. */
  831. rffn = (rffn + 1) * 8;
  832. for (i = 0; i < rffn; i++)
  833. {
  834. idFilterRegion[i] = 0x0;
  835. }
  836. if (enable)
  837. {
  838. /* Disable unused Rx FIFO Filter. */
  839. for (i = config->idFilterNum; i < rffn; i++)
  840. {
  841. idFilterRegion[i] = 0xFFFFFFFFU;
  842. }
  843. /* Copy ID filter table to Message Buffer Region. */
  844. for (i = 0; i < config->idFilterNum; i++)
  845. {
  846. idFilterRegion[i] = config->idFilterTable[i];
  847. }
  848. /* Setup ID Fitlter Type. */
  849. switch (config->idFilterType)
  850. {
  851. case kFLEXCAN_RxFifoFilterTypeA:
  852. base->MCR = (base->MCR & ~CAN_MCR_IDAM_MASK) | CAN_MCR_IDAM(0x0);
  853. break;
  854. case kFLEXCAN_RxFifoFilterTypeB:
  855. base->MCR = (base->MCR & ~CAN_MCR_IDAM_MASK) | CAN_MCR_IDAM(0x1);
  856. break;
  857. case kFLEXCAN_RxFifoFilterTypeC:
  858. base->MCR = (base->MCR & ~CAN_MCR_IDAM_MASK) | CAN_MCR_IDAM(0x2);
  859. break;
  860. case kFLEXCAN_RxFifoFilterTypeD:
  861. /* All frames rejected. */
  862. base->MCR = (base->MCR & ~CAN_MCR_IDAM_MASK) | CAN_MCR_IDAM(0x3);
  863. break;
  864. default:
  865. break;
  866. }
  867. /* Setting Message Reception Priority. */
  868. base->CTRL2 = (config->priority == kFLEXCAN_RxFifoPrioHigh) ? base->CTRL2 & ~CAN_CTRL2_MRP_MASK :
  869. base->CTRL2 | CAN_CTRL2_MRP_MASK;
  870. /* Enable Rx Message FIFO. */
  871. base->MCR |= CAN_MCR_RFEN_MASK;
  872. }
  873. else
  874. {
  875. /* Disable Rx Message FIFO. */
  876. base->MCR &= ~CAN_MCR_RFEN_MASK;
  877. /* Clean MB0 ~ MB5. */
  878. FLEXCAN_SetRxMbConfig(base, 0, NULL, false);
  879. FLEXCAN_SetRxMbConfig(base, 1, NULL, false);
  880. FLEXCAN_SetRxMbConfig(base, 2, NULL, false);
  881. FLEXCAN_SetRxMbConfig(base, 3, NULL, false);
  882. FLEXCAN_SetRxMbConfig(base, 4, NULL, false);
  883. FLEXCAN_SetRxMbConfig(base, 5, NULL, false);
  884. }
  885. /* Exit Freeze Mode. */
  886. FLEXCAN_ExitFreezeMode(base);
  887. }
  888. #if (defined(FSL_FEATURE_FLEXCAN_HAS_RX_FIFO_DMA) && FSL_FEATURE_FLEXCAN_HAS_RX_FIFO_DMA)
  889. void FLEXCAN_EnableRxFifoDMA(CAN_Type *base, bool enable)
  890. {
  891. if (enable)
  892. {
  893. /* Enter Freeze Mode. */
  894. FLEXCAN_EnterFreezeMode(base);
  895. /* Enable FlexCAN DMA. */
  896. base->MCR |= CAN_MCR_DMA_MASK;
  897. /* Exit Freeze Mode. */
  898. FLEXCAN_ExitFreezeMode(base);
  899. }
  900. else
  901. {
  902. /* Enter Freeze Mode. */
  903. FLEXCAN_EnterFreezeMode(base);
  904. /* Disable FlexCAN DMA. */
  905. base->MCR &= ~CAN_MCR_DMA_MASK;
  906. /* Exit Freeze Mode. */
  907. FLEXCAN_ExitFreezeMode(base);
  908. }
  909. }
  910. #endif /* FSL_FEATURE_FLEXCAN_HAS_RX_FIFO_DMA */
  911. status_t FLEXCAN_WriteTxMb(CAN_Type *base, uint8_t mbIdx, const flexcan_frame_t *txFrame)
  912. {
  913. /* Assertion. */
  914. assert(mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
  915. assert(txFrame);
  916. assert(txFrame->length <= 8);
  917. assert(!FLEXCAN_IsMbOccupied(base, mbIdx));
  918. uint32_t cs_temp = 0;
  919. /* Check if Message Buffer is available. */
  920. if (CAN_CS_CODE(kFLEXCAN_TxMbDataOrRemote) != (base->MB[mbIdx].CS & CAN_CS_CODE_MASK))
  921. {
  922. /* Inactive Tx Message Buffer. */
  923. base->MB[mbIdx].CS = (base->MB[mbIdx].CS & ~CAN_CS_CODE_MASK) | CAN_CS_CODE(kFLEXCAN_TxMbInactive);
  924. /* Fill Message ID field. */
  925. base->MB[mbIdx].ID = txFrame->id;
  926. /* Fill Message Format field. */
  927. if (kFLEXCAN_FrameFormatExtend == txFrame->format)
  928. {
  929. cs_temp |= CAN_CS_SRR_MASK | CAN_CS_IDE_MASK;
  930. }
  931. /* Fill Message Type field. */
  932. if (kFLEXCAN_FrameTypeRemote == txFrame->type)
  933. {
  934. cs_temp |= CAN_CS_RTR_MASK;
  935. }
  936. cs_temp |= CAN_CS_CODE(kFLEXCAN_TxMbDataOrRemote) | CAN_CS_DLC(txFrame->length);
  937. /* Load Message Payload. */
  938. base->MB[mbIdx].WORD0 = txFrame->dataWord0;
  939. base->MB[mbIdx].WORD1 = txFrame->dataWord1;
  940. /* Activate Tx Message Buffer. */
  941. base->MB[mbIdx].CS = cs_temp;
  942. #if (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641)
  943. base->MB[FLEXCAN_GetFirstValidMb(base)].CS = CAN_CS_CODE(kFLEXCAN_TxMbInactive);
  944. base->MB[FLEXCAN_GetFirstValidMb(base)].CS = CAN_CS_CODE(kFLEXCAN_TxMbInactive);
  945. #endif
  946. return kStatus_Success;
  947. }
  948. else
  949. {
  950. /* Tx Message Buffer is activated, return immediately. */
  951. return kStatus_Fail;
  952. }
  953. }
  954. #if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE)
  955. status_t FLEXCAN_WriteFDTxMb(CAN_Type *base, uint8_t mbIdx, const flexcan_fd_frame_t *txFrame)
  956. {
  957. /* Assertion. */
  958. assert(mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
  959. assert(txFrame);
  960. assert(!FLEXCAN_IsMbOccupied(base, mbIdx));
  961. uint32_t cs_temp = 0;
  962. uint8_t cnt = 0;
  963. uint32_t can_cs = 0;
  964. uint8_t payload_dword = 1;
  965. uint32_t dataSize;
  966. dataSize = (base->FDCTRL & CAN_FDCTRL_MBDSR0_MASK) >> CAN_FDCTRL_MBDSR0_SHIFT;
  967. #if (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641)
  968. uint32_t availoffset = FLEXCAN_GetFDMailboxOffset(base, FLEXCAN_GetFirstValidMb(base));
  969. #endif
  970. volatile uint32_t *mbAddr = &(base->MB[0].CS);
  971. uint32_t offset = FLEXCAN_GetFDMailboxOffset(base, mbIdx);
  972. can_cs = mbAddr[0];
  973. /* Check if Message Buffer is available. */
  974. if (CAN_CS_CODE(kFLEXCAN_TxMbDataOrRemote) != (can_cs & CAN_CS_CODE_MASK))
  975. {
  976. /* Inactive Tx Message Buffer and Fill Message ID field. */
  977. mbAddr[offset] = (can_cs & ~CAN_CS_CODE_MASK) | CAN_CS_CODE(kFLEXCAN_TxMbInactive);
  978. mbAddr[offset + 1] = txFrame->id;
  979. /* Fill Message Format field. */
  980. if (kFLEXCAN_FrameFormatExtend == txFrame->format)
  981. {
  982. cs_temp |= CAN_CS_SRR_MASK | CAN_CS_IDE_MASK;
  983. }
  984. cs_temp |= CAN_CS_CODE(kFLEXCAN_TxMbDataOrRemote) | CAN_CS_DLC(txFrame->length) | CAN_CS_EDL(1);
  985. /* Calculate the DWORD number, dataSize 0/1/2/3 corresponds to 8/16/32/64
  986. Bytes payload. */
  987. for (cnt = 0; cnt < dataSize + 1; cnt++)
  988. {
  989. payload_dword *= 2;
  990. }
  991. /* Load Message Payload and Activate Tx Message Buffer. */
  992. for (cnt = 0; cnt < payload_dword; cnt++)
  993. {
  994. mbAddr[offset + 2 + cnt] = txFrame->dataWord[cnt];
  995. }
  996. mbAddr[offset] = cs_temp;
  997. #if (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641)
  998. mbAddr[availoffset] = CAN_CS_CODE(kFLEXCAN_TxMbInactive);
  999. mbAddr[availoffset] = CAN_CS_CODE(kFLEXCAN_TxMbInactive);
  1000. #endif
  1001. return kStatus_Success;
  1002. }
  1003. else
  1004. {
  1005. /* Tx Message Buffer is activated, return immediately. */
  1006. return kStatus_Fail;
  1007. }
  1008. }
  1009. #endif
  1010. status_t FLEXCAN_ReadRxMb(CAN_Type *base, uint8_t mbIdx, flexcan_frame_t *rxFrame)
  1011. {
  1012. /* Assertion. */
  1013. assert(mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
  1014. assert(rxFrame);
  1015. assert(!FLEXCAN_IsMbOccupied(base, mbIdx));
  1016. uint32_t cs_temp;
  1017. uint8_t rx_code;
  1018. /* Read CS field of Rx Message Buffer to lock Message Buffer. */
  1019. cs_temp = base->MB[mbIdx].CS;
  1020. /* Get Rx Message Buffer Code field. */
  1021. rx_code = (cs_temp & CAN_CS_CODE_MASK) >> CAN_CS_CODE_SHIFT;
  1022. /* Check to see if Rx Message Buffer is full. */
  1023. if ((kFLEXCAN_RxMbFull == rx_code) || (kFLEXCAN_RxMbOverrun == rx_code))
  1024. {
  1025. /* Store Message ID. */
  1026. rxFrame->id = base->MB[mbIdx].ID & (CAN_ID_EXT_MASK | CAN_ID_STD_MASK);
  1027. /* Get the message ID and format. */
  1028. rxFrame->format = (cs_temp & CAN_CS_IDE_MASK) ? kFLEXCAN_FrameFormatExtend : kFLEXCAN_FrameFormatStandard;
  1029. /* Get the message type. */
  1030. rxFrame->type = (cs_temp & CAN_CS_RTR_MASK) ? kFLEXCAN_FrameTypeRemote : kFLEXCAN_FrameTypeData;
  1031. /* Get the message length. */
  1032. rxFrame->length = (cs_temp & CAN_CS_DLC_MASK) >> CAN_CS_DLC_SHIFT;
  1033. /* Store Message Payload. */
  1034. rxFrame->dataWord0 = base->MB[mbIdx].WORD0;
  1035. rxFrame->dataWord1 = base->MB[mbIdx].WORD1;
  1036. /* Read free-running timer to unlock Rx Message Buffer. */
  1037. (void)base->TIMER;
  1038. if (kFLEXCAN_RxMbFull == rx_code)
  1039. {
  1040. return kStatus_Success;
  1041. }
  1042. else
  1043. {
  1044. return kStatus_FLEXCAN_RxOverflow;
  1045. }
  1046. }
  1047. else
  1048. {
  1049. /* Read free-running timer to unlock Rx Message Buffer. */
  1050. (void)base->TIMER;
  1051. return kStatus_Fail;
  1052. }
  1053. }
  1054. #if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE)
  1055. status_t FLEXCAN_ReadFDRxMb(CAN_Type *base, uint8_t mbIdx, flexcan_fd_frame_t *rxFrame)
  1056. {
  1057. /* Assertion. */
  1058. assert(mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
  1059. assert(rxFrame);
  1060. assert(!FLEXCAN_IsMbOccupied(base, mbIdx));
  1061. uint32_t cs_temp;
  1062. uint8_t rx_code;
  1063. uint8_t cnt = 0;
  1064. uint32_t can_id = 0;
  1065. uint32_t dataSize;
  1066. dataSize = (base->FDCTRL & CAN_FDCTRL_MBDSR0_MASK) >> CAN_FDCTRL_MBDSR0_SHIFT;
  1067. uint8_t payload_dword = 1;
  1068. volatile uint32_t *mbAddr = &(base->MB[0].CS);
  1069. uint32_t offset = FLEXCAN_GetFDMailboxOffset(base, mbIdx);
  1070. /* Read CS field of Rx Message Buffer to lock Message Buffer. */
  1071. cs_temp = mbAddr[offset];
  1072. can_id = mbAddr[offset + 1];
  1073. /* Get Rx Message Buffer Code field. */
  1074. rx_code = (cs_temp & CAN_CS_CODE_MASK) >> CAN_CS_CODE_SHIFT;
  1075. /* Check to see if Rx Message Buffer is full. */
  1076. if ((kFLEXCAN_RxMbFull == rx_code) || (kFLEXCAN_RxMbOverrun == rx_code))
  1077. {
  1078. /* Store Message ID. */
  1079. rxFrame->id = can_id & (CAN_ID_EXT_MASK | CAN_ID_STD_MASK);
  1080. /* Get the message ID and format. */
  1081. rxFrame->format = (cs_temp & CAN_CS_IDE_MASK) ? kFLEXCAN_FrameFormatExtend : kFLEXCAN_FrameFormatStandard;
  1082. /* Get the message type. */
  1083. rxFrame->type = (cs_temp & CAN_CS_RTR_MASK) ? kFLEXCAN_FrameTypeRemote : kFLEXCAN_FrameTypeData;
  1084. /* Get the message length. */
  1085. rxFrame->length = (cs_temp & CAN_CS_DLC_MASK) >> CAN_CS_DLC_SHIFT;
  1086. /* Calculate the DWORD number, dataSize 0/1/2/3 corresponds to 8/16/32/64
  1087. Bytes payload. */
  1088. for (cnt = 0; cnt < dataSize + 1; cnt++)
  1089. {
  1090. payload_dword *= 2;
  1091. }
  1092. /* Store Message Payload. */
  1093. for (cnt = 0; cnt < payload_dword; cnt++)
  1094. {
  1095. rxFrame->dataWord[cnt] = mbAddr[offset + 2 + cnt];
  1096. }
  1097. /* Read free-running timer to unlock Rx Message Buffer. */
  1098. (void)base->TIMER;
  1099. if (kFLEXCAN_RxMbFull == rx_code)
  1100. {
  1101. return kStatus_Success;
  1102. }
  1103. else
  1104. {
  1105. return kStatus_FLEXCAN_RxOverflow;
  1106. }
  1107. }
  1108. else
  1109. {
  1110. /* Read free-running timer to unlock Rx Message Buffer. */
  1111. (void)base->TIMER;
  1112. return kStatus_Fail;
  1113. }
  1114. }
  1115. #endif
  1116. status_t FLEXCAN_ReadRxFifo(CAN_Type *base, flexcan_frame_t *rxFrame)
  1117. {
  1118. /* Assertion. */
  1119. assert(rxFrame);
  1120. uint32_t cs_temp;
  1121. /* Check if Rx FIFO is Enabled. */
  1122. if (base->MCR & CAN_MCR_RFEN_MASK)
  1123. {
  1124. /* Read CS field of Rx Message Buffer to lock Message Buffer. */
  1125. cs_temp = base->MB[0].CS;
  1126. /* Read data from Rx FIFO output port. */
  1127. /* Store Message ID. */
  1128. rxFrame->id = base->MB[0].ID & (CAN_ID_EXT_MASK | CAN_ID_STD_MASK);
  1129. /* Get the message ID and format. */
  1130. rxFrame->format = (cs_temp & CAN_CS_IDE_MASK) ? kFLEXCAN_FrameFormatExtend : kFLEXCAN_FrameFormatStandard;
  1131. /* Get the message type. */
  1132. rxFrame->type = (cs_temp & CAN_CS_RTR_MASK) ? kFLEXCAN_FrameTypeRemote : kFLEXCAN_FrameTypeData;
  1133. /* Get the message length. */
  1134. rxFrame->length = (cs_temp & CAN_CS_DLC_MASK) >> CAN_CS_DLC_SHIFT;
  1135. /* Store Message Payload. */
  1136. rxFrame->dataWord0 = base->MB[0].WORD0;
  1137. rxFrame->dataWord1 = base->MB[0].WORD1;
  1138. /* Store ID Filter Hit Index. */
  1139. rxFrame->idhit = (uint8_t)(base->RXFIR & CAN_RXFIR_IDHIT_MASK);
  1140. /* Read free-running timer to unlock Rx Message Buffer. */
  1141. (void)base->TIMER;
  1142. return kStatus_Success;
  1143. }
  1144. else
  1145. {
  1146. return kStatus_Fail;
  1147. }
  1148. }
  1149. status_t FLEXCAN_TransferSendBlocking(CAN_Type *base, uint8_t mbIdx, flexcan_frame_t *txFrame)
  1150. {
  1151. /* Write Tx Message Buffer to initiate a data sending. */
  1152. if (kStatus_Success == FLEXCAN_WriteTxMb(base, mbIdx, txFrame))
  1153. {
  1154. /* Wait until CAN Message send out. */
  1155. #if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
  1156. while (!FLEXCAN_GetMbStatusFlags(base, (uint64_t)1 << mbIdx))
  1157. #else
  1158. while (!FLEXCAN_GetMbStatusFlags(base, 1 << mbIdx))
  1159. #endif
  1160. {
  1161. }
  1162. /* Clean Tx Message Buffer Flag. */
  1163. #if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
  1164. FLEXCAN_ClearMbStatusFlags(base, (uint64_t)1 << mbIdx);
  1165. #else
  1166. FLEXCAN_ClearMbStatusFlags(base, 1 << mbIdx);
  1167. #endif
  1168. return kStatus_Success;
  1169. }
  1170. else
  1171. {
  1172. return kStatus_Fail;
  1173. }
  1174. }
  1175. status_t FLEXCAN_TransferReceiveBlocking(CAN_Type *base, uint8_t mbIdx, flexcan_frame_t *rxFrame)
  1176. {
  1177. /* Wait until Rx Message Buffer non-empty. */
  1178. #if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
  1179. while (!FLEXCAN_GetMbStatusFlags(base, (uint64_t)1 << mbIdx))
  1180. #else
  1181. while (!FLEXCAN_GetMbStatusFlags(base, 1 << mbIdx))
  1182. #endif
  1183. {
  1184. }
  1185. /* Clean Rx Message Buffer Flag. */
  1186. #if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
  1187. FLEXCAN_ClearMbStatusFlags(base, (uint64_t)1 << mbIdx);
  1188. #else
  1189. FLEXCAN_ClearMbStatusFlags(base, 1 << mbIdx);
  1190. #endif
  1191. /* Read Received CAN Message. */
  1192. return FLEXCAN_ReadRxMb(base, mbIdx, rxFrame);
  1193. }
  1194. #if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE)
  1195. status_t FLEXCAN_TransferFDSendBlocking(CAN_Type *base, uint8_t mbIdx, flexcan_fd_frame_t *txFrame)
  1196. {
  1197. /* Write Tx Message Buffer to initiate a data sending. */
  1198. if (kStatus_Success == FLEXCAN_WriteFDTxMb(base, mbIdx, txFrame))
  1199. {
  1200. /* Wait until CAN Message send out. */
  1201. #if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
  1202. while (!FLEXCAN_GetMbStatusFlags(base, (uint64_t)1 << mbIdx))
  1203. #else
  1204. while (!FLEXCAN_GetMbStatusFlags(base, 1 << mbIdx))
  1205. #endif
  1206. {
  1207. }
  1208. /* Clean Tx Message Buffer Flag. */
  1209. #if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
  1210. FLEXCAN_ClearMbStatusFlags(base, (uint64_t)1 << mbIdx);
  1211. #else
  1212. FLEXCAN_ClearMbStatusFlags(base, 1 << mbIdx);
  1213. #endif
  1214. return kStatus_Success;
  1215. }
  1216. else
  1217. {
  1218. return kStatus_Fail;
  1219. }
  1220. }
  1221. status_t FLEXCAN_TransferFDReceiveBlocking(CAN_Type *base, uint8_t mbIdx, flexcan_fd_frame_t *rxFrame)
  1222. {
  1223. /* Wait until Rx Message Buffer non-empty. */
  1224. #if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
  1225. while (!FLEXCAN_GetMbStatusFlags(base, (uint64_t)1 << mbIdx))
  1226. #else
  1227. while (!FLEXCAN_GetMbStatusFlags(base, 1 << mbIdx))
  1228. #endif
  1229. {
  1230. }
  1231. /* Clean Rx Message Buffer Flag. */
  1232. #if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
  1233. FLEXCAN_ClearMbStatusFlags(base, (uint64_t)1 << mbIdx);
  1234. #else
  1235. FLEXCAN_ClearMbStatusFlags(base, 1 << mbIdx);
  1236. #endif
  1237. /* Read Received CAN Message. */
  1238. return FLEXCAN_ReadFDRxMb(base, mbIdx, rxFrame);
  1239. }
  1240. #endif
  1241. status_t FLEXCAN_TransferReceiveFifoBlocking(CAN_Type *base, flexcan_frame_t *rxFrame)
  1242. {
  1243. status_t rxFifoStatus;
  1244. /* Wait until Rx FIFO non-empty. */
  1245. while (!FLEXCAN_GetMbStatusFlags(base, kFLEXCAN_RxFifoFrameAvlFlag))
  1246. {
  1247. }
  1248. /* */
  1249. rxFifoStatus = FLEXCAN_ReadRxFifo(base, rxFrame);
  1250. /* Clean Rx Fifo available flag. */
  1251. FLEXCAN_ClearMbStatusFlags(base, kFLEXCAN_RxFifoFrameAvlFlag);
  1252. return rxFifoStatus;
  1253. }
  1254. void FLEXCAN_TransferCreateHandle(CAN_Type *base,
  1255. flexcan_handle_t *handle,
  1256. flexcan_transfer_callback_t callback,
  1257. void *userData)
  1258. {
  1259. assert(handle);
  1260. uint8_t instance;
  1261. /* Clean FlexCAN transfer handle. */
  1262. memset(handle, 0, sizeof(*handle));
  1263. /* Get instance from peripheral base address. */
  1264. instance = FLEXCAN_GetInstance(base);
  1265. /* Save the context in global variables to support the double weak mechanism. */
  1266. s_flexcanHandle[instance] = handle;
  1267. /* Register Callback function. */
  1268. handle->callback = callback;
  1269. handle->userData = userData;
  1270. s_flexcanIsr = FLEXCAN_TransferHandleIRQ;
  1271. /* We Enable Error & Status interrupt here, because this interrupt just
  1272. * report current status of FlexCAN module through Callback function.
  1273. * It is insignificance without a available callback function.
  1274. */
  1275. if (handle->callback != NULL)
  1276. {
  1277. FLEXCAN_EnableInterrupts(base, kFLEXCAN_BusOffInterruptEnable | kFLEXCAN_ErrorInterruptEnable |
  1278. kFLEXCAN_RxWarningInterruptEnable | kFLEXCAN_TxWarningInterruptEnable |
  1279. kFLEXCAN_WakeUpInterruptEnable);
  1280. }
  1281. else
  1282. {
  1283. FLEXCAN_DisableInterrupts(base, kFLEXCAN_BusOffInterruptEnable | kFLEXCAN_ErrorInterruptEnable |
  1284. kFLEXCAN_RxWarningInterruptEnable | kFLEXCAN_TxWarningInterruptEnable |
  1285. kFLEXCAN_WakeUpInterruptEnable);
  1286. }
  1287. /* Enable interrupts in NVIC. */
  1288. EnableIRQ((IRQn_Type)(s_flexcanRxWarningIRQ[instance]));
  1289. EnableIRQ((IRQn_Type)(s_flexcanTxWarningIRQ[instance]));
  1290. EnableIRQ((IRQn_Type)(s_flexcanWakeUpIRQ[instance]));
  1291. EnableIRQ((IRQn_Type)(s_flexcanErrorIRQ[instance]));
  1292. EnableIRQ((IRQn_Type)(s_flexcanBusOffIRQ[instance]));
  1293. EnableIRQ((IRQn_Type)(s_flexcanMbIRQ[instance]));
  1294. }
  1295. status_t FLEXCAN_TransferSendNonBlocking(CAN_Type *base, flexcan_handle_t *handle, flexcan_mb_transfer_t *xfer)
  1296. {
  1297. /* Assertion. */
  1298. assert(handle);
  1299. assert(xfer);
  1300. assert(xfer->mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
  1301. assert(!FLEXCAN_IsMbOccupied(base, xfer->mbIdx));
  1302. /* Check if Message Buffer is idle. */
  1303. if (kFLEXCAN_StateIdle == handle->mbState[xfer->mbIdx])
  1304. {
  1305. /* Distinguish transmit type. */
  1306. if (kFLEXCAN_FrameTypeRemote == xfer->frame->type)
  1307. {
  1308. handle->mbState[xfer->mbIdx] = kFLEXCAN_StateTxRemote;
  1309. /* Register user Frame buffer to receive remote Frame. */
  1310. handle->mbFrameBuf[xfer->mbIdx] = xfer->frame;
  1311. }
  1312. else
  1313. {
  1314. handle->mbState[xfer->mbIdx] = kFLEXCAN_StateTxData;
  1315. }
  1316. if (kStatus_Success == FLEXCAN_WriteTxMb(base, xfer->mbIdx, xfer->frame))
  1317. {
  1318. /* Enable Message Buffer Interrupt. */
  1319. #if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
  1320. FLEXCAN_EnableMbInterrupts(base, (uint64_t)1 << xfer->mbIdx);
  1321. #else
  1322. FLEXCAN_EnableMbInterrupts(base, 1 << xfer->mbIdx);
  1323. #endif
  1324. return kStatus_Success;
  1325. }
  1326. else
  1327. {
  1328. handle->mbState[xfer->mbIdx] = kFLEXCAN_StateIdle;
  1329. return kStatus_Fail;
  1330. }
  1331. }
  1332. else
  1333. {
  1334. return kStatus_FLEXCAN_TxBusy;
  1335. }
  1336. }
  1337. status_t FLEXCAN_TransferReceiveNonBlocking(CAN_Type *base, flexcan_handle_t *handle, flexcan_mb_transfer_t *xfer)
  1338. {
  1339. /* Assertion. */
  1340. assert(handle);
  1341. assert(xfer);
  1342. assert(xfer->mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
  1343. assert(!FLEXCAN_IsMbOccupied(base, xfer->mbIdx));
  1344. /* Check if Message Buffer is idle. */
  1345. if (kFLEXCAN_StateIdle == handle->mbState[xfer->mbIdx])
  1346. {
  1347. handle->mbState[xfer->mbIdx] = kFLEXCAN_StateRxData;
  1348. /* Register Message Buffer. */
  1349. handle->mbFrameBuf[xfer->mbIdx] = xfer->frame;
  1350. /* Enable Message Buffer Interrupt. */
  1351. #if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
  1352. FLEXCAN_EnableMbInterrupts(base, (uint64_t)1 << xfer->mbIdx);
  1353. #else
  1354. FLEXCAN_EnableMbInterrupts(base, 1 << xfer->mbIdx);
  1355. #endif
  1356. return kStatus_Success;
  1357. }
  1358. else
  1359. {
  1360. return kStatus_FLEXCAN_RxBusy;
  1361. }
  1362. }
  1363. #if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE)
  1364. status_t FLEXCAN_TransferFDSendNonBlocking(CAN_Type *base, flexcan_handle_t *handle, flexcan_mb_transfer_t *xfer)
  1365. {
  1366. /* Assertion. */
  1367. assert(handle);
  1368. assert(xfer);
  1369. assert(xfer->mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
  1370. assert(!FLEXCAN_IsMbOccupied(base, xfer->mbIdx));
  1371. /* Check if Message Buffer is idle. */
  1372. if (kFLEXCAN_StateIdle == handle->mbState[xfer->mbIdx])
  1373. {
  1374. /* Distinguish transmit type. */
  1375. if (kFLEXCAN_FrameTypeRemote == xfer->frame->type)
  1376. {
  1377. handle->mbState[xfer->mbIdx] = kFLEXCAN_StateTxRemote;
  1378. /* Register user Frame buffer to receive remote Frame. */
  1379. handle->mbFDFrameBuf[xfer->mbIdx] = xfer->framefd;
  1380. }
  1381. else
  1382. {
  1383. handle->mbState[xfer->mbIdx] = kFLEXCAN_StateTxData;
  1384. }
  1385. if (kStatus_Success == FLEXCAN_WriteFDTxMb(base, xfer->mbIdx, xfer->framefd))
  1386. {
  1387. /* Enable Message Buffer Interrupt. */
  1388. #if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
  1389. FLEXCAN_EnableMbInterrupts(base, (uint64_t)1 << xfer->mbIdx);
  1390. #else
  1391. FLEXCAN_EnableMbInterrupts(base, 1 << xfer->mbIdx);
  1392. #endif
  1393. return kStatus_Success;
  1394. }
  1395. else
  1396. {
  1397. handle->mbState[xfer->mbIdx] = kFLEXCAN_StateIdle;
  1398. return kStatus_Fail;
  1399. }
  1400. }
  1401. else
  1402. {
  1403. return kStatus_FLEXCAN_TxBusy;
  1404. }
  1405. }
  1406. status_t FLEXCAN_TransferFDReceiveNonBlocking(CAN_Type *base, flexcan_handle_t *handle, flexcan_mb_transfer_t *xfer)
  1407. {
  1408. /* Assertion. */
  1409. assert(handle);
  1410. assert(xfer);
  1411. assert(xfer->mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
  1412. assert(!FLEXCAN_IsMbOccupied(base, xfer->mbIdx));
  1413. /* Check if Message Buffer is idle. */
  1414. if (kFLEXCAN_StateIdle == handle->mbState[xfer->mbIdx])
  1415. {
  1416. handle->mbState[xfer->mbIdx] = kFLEXCAN_StateRxData;
  1417. /* Register Message Buffer. */
  1418. handle->mbFDFrameBuf[xfer->mbIdx] = xfer->framefd;
  1419. /* Enable Message Buffer Interrupt. */
  1420. #if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
  1421. FLEXCAN_EnableMbInterrupts(base, (uint64_t)1 << xfer->mbIdx);
  1422. #else
  1423. FLEXCAN_EnableMbInterrupts(base, 1 << xfer->mbIdx);
  1424. #endif
  1425. return kStatus_Success;
  1426. }
  1427. else
  1428. {
  1429. return kStatus_FLEXCAN_RxBusy;
  1430. }
  1431. }
  1432. #endif
  1433. status_t FLEXCAN_TransferReceiveFifoNonBlocking(CAN_Type *base, flexcan_handle_t *handle, flexcan_fifo_transfer_t *xfer)
  1434. {
  1435. /* Assertion. */
  1436. assert(handle);
  1437. assert(xfer);
  1438. /* Check if Message Buffer is idle. */
  1439. if (kFLEXCAN_StateIdle == handle->rxFifoState)
  1440. {
  1441. handle->rxFifoState = kFLEXCAN_StateRxFifo;
  1442. /* Register Message Buffer. */
  1443. handle->rxFifoFrameBuf = xfer->frame;
  1444. /* Enable Message Buffer Interrupt. */
  1445. FLEXCAN_EnableMbInterrupts(
  1446. base, kFLEXCAN_RxFifoOverflowFlag | kFLEXCAN_RxFifoWarningFlag | kFLEXCAN_RxFifoFrameAvlFlag);
  1447. return kStatus_Success;
  1448. }
  1449. else
  1450. {
  1451. return kStatus_FLEXCAN_RxFifoBusy;
  1452. }
  1453. }
  1454. void FLEXCAN_TransferAbortSend(CAN_Type *base, flexcan_handle_t *handle, uint8_t mbIdx)
  1455. {
  1456. /* Assertion. */
  1457. assert(handle);
  1458. assert(mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
  1459. assert(!FLEXCAN_IsMbOccupied(base, mbIdx));
  1460. /* Disable Message Buffer Interrupt. */
  1461. #if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
  1462. FLEXCAN_DisableMbInterrupts(base, (uint64_t)1 << mbIdx);
  1463. #else
  1464. FLEXCAN_DisableMbInterrupts(base, 1 << mbIdx);
  1465. #endif
  1466. /* Un-register handle. */
  1467. handle->mbFrameBuf[mbIdx] = 0x0;
  1468. /* Clean Message Buffer. */
  1469. FLEXCAN_SetTxMbConfig(base, mbIdx, true);
  1470. handle->mbState[mbIdx] = kFLEXCAN_StateIdle;
  1471. }
  1472. #if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE)
  1473. void FLEXCAN_TransferFDAbortSend(CAN_Type *base, flexcan_handle_t *handle, uint8_t mbIdx)
  1474. {
  1475. /* Assertion. */
  1476. assert(handle);
  1477. assert(mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
  1478. assert(!FLEXCAN_IsMbOccupied(base, mbIdx));
  1479. /* Disable Message Buffer Interrupt. */
  1480. #if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
  1481. FLEXCAN_DisableMbInterrupts(base, (uint64_t)1 << mbIdx);
  1482. #else
  1483. FLEXCAN_DisableMbInterrupts(base, 1 << mbIdx);
  1484. #endif
  1485. /* Un-register handle. */
  1486. handle->mbFDFrameBuf[mbIdx] = 0x0;
  1487. /* Clean Message Buffer. */
  1488. FLEXCAN_SetFDTxMbConfig(base, mbIdx, true);
  1489. handle->mbState[mbIdx] = kFLEXCAN_StateIdle;
  1490. }
  1491. void FLEXCAN_TransferFDAbortReceive(CAN_Type *base, flexcan_handle_t *handle, uint8_t mbIdx)
  1492. {
  1493. /* Assertion. */
  1494. assert(handle);
  1495. assert(mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
  1496. assert(!FLEXCAN_IsMbOccupied(base, mbIdx));
  1497. /* Disable Message Buffer Interrupt. */
  1498. #if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
  1499. FLEXCAN_DisableMbInterrupts(base, (uint64_t)1 << mbIdx);
  1500. #else
  1501. FLEXCAN_DisableMbInterrupts(base, 1 << mbIdx);
  1502. #endif
  1503. /* Un-register handle. */
  1504. handle->mbFDFrameBuf[mbIdx] = 0x0;
  1505. handle->mbState[mbIdx] = kFLEXCAN_StateIdle;
  1506. }
  1507. #endif
  1508. void FLEXCAN_TransferAbortReceive(CAN_Type *base, flexcan_handle_t *handle, uint8_t mbIdx)
  1509. {
  1510. /* Assertion. */
  1511. assert(handle);
  1512. assert(mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
  1513. assert(!FLEXCAN_IsMbOccupied(base, mbIdx));
  1514. /* Disable Message Buffer Interrupt. */
  1515. #if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
  1516. FLEXCAN_DisableMbInterrupts(base, (uint64_t)1 << mbIdx);
  1517. #else
  1518. FLEXCAN_DisableMbInterrupts(base, 1 << mbIdx);
  1519. #endif
  1520. /* Un-register handle. */
  1521. handle->mbFrameBuf[mbIdx] = 0x0;
  1522. handle->mbState[mbIdx] = kFLEXCAN_StateIdle;
  1523. }
  1524. void FLEXCAN_TransferAbortReceiveFifo(CAN_Type *base, flexcan_handle_t *handle)
  1525. {
  1526. /* Assertion. */
  1527. assert(handle);
  1528. /* Check if Rx FIFO is enabled. */
  1529. if (base->MCR & CAN_MCR_RFEN_MASK)
  1530. {
  1531. /* Disable Rx Message FIFO Interrupts. */
  1532. FLEXCAN_DisableMbInterrupts(
  1533. base, kFLEXCAN_RxFifoOverflowFlag | kFLEXCAN_RxFifoWarningFlag | kFLEXCAN_RxFifoFrameAvlFlag);
  1534. /* Un-register handle. */
  1535. handle->rxFifoFrameBuf = 0x0;
  1536. }
  1537. handle->rxFifoState = kFLEXCAN_StateIdle;
  1538. }
  1539. void FLEXCAN_TransferHandleIRQ(CAN_Type *base, flexcan_handle_t *handle)
  1540. {
  1541. /* Assertion. */
  1542. assert(handle);
  1543. status_t status = kStatus_FLEXCAN_UnHandled;
  1544. uint32_t result;
  1545. /* Store Current FlexCAN Module Error and Status. */
  1546. result = base->ESR1;
  1547. do
  1548. {
  1549. /* Solve FlexCAN Error and Status Interrupt. */
  1550. if (result & (kFLEXCAN_TxWarningIntFlag | kFLEXCAN_RxWarningIntFlag | kFLEXCAN_BusOffIntFlag |
  1551. kFLEXCAN_ErrorIntFlag | kFLEXCAN_WakeUpIntFlag))
  1552. {
  1553. status = kStatus_FLEXCAN_ErrorStatus;
  1554. /* Clear FlexCAN Error and Status Interrupt. */
  1555. FLEXCAN_ClearStatusFlags(base, kFLEXCAN_TxWarningIntFlag | kFLEXCAN_RxWarningIntFlag |
  1556. kFLEXCAN_BusOffIntFlag | kFLEXCAN_ErrorIntFlag | kFLEXCAN_WakeUpIntFlag);
  1557. }
  1558. /* Solve FlexCAN Rx FIFO & Message Buffer Interrupt. */
  1559. else
  1560. {
  1561. /* For this implementation, we solve the Message with lowest MB index first. */
  1562. for (result = 0; result < FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base); result++)
  1563. {
  1564. /* Get the lowest unhandled Message Buffer */
  1565. #if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
  1566. if ((FLEXCAN_GetMbStatusFlags(base, (uint64_t)1 << result)) && (FLEXCAN_IsMbIntEnabled(base, result)))
  1567. #else
  1568. if ((FLEXCAN_GetMbStatusFlags(base, 1 << result)) && (FLEXCAN_IsMbIntEnabled(base, result)))
  1569. #endif
  1570. {
  1571. break;
  1572. }
  1573. }
  1574. /* Does not find Message to deal with. */
  1575. if (result == FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base))
  1576. {
  1577. break;
  1578. }
  1579. /* Solve Rx FIFO interrupt. */
  1580. if ((kFLEXCAN_StateIdle != handle->rxFifoState) && ((1 << result) <= kFLEXCAN_RxFifoOverflowFlag))
  1581. {
  1582. switch (1 << result)
  1583. {
  1584. case kFLEXCAN_RxFifoOverflowFlag:
  1585. status = kStatus_FLEXCAN_RxFifoOverflow;
  1586. break;
  1587. case kFLEXCAN_RxFifoWarningFlag:
  1588. status = kStatus_FLEXCAN_RxFifoWarning;
  1589. break;
  1590. case kFLEXCAN_RxFifoFrameAvlFlag:
  1591. status = FLEXCAN_ReadRxFifo(base, handle->rxFifoFrameBuf);
  1592. if (kStatus_Success == status)
  1593. {
  1594. status = kStatus_FLEXCAN_RxFifoIdle;
  1595. }
  1596. FLEXCAN_TransferAbortReceiveFifo(base, handle);
  1597. break;
  1598. default:
  1599. status = kStatus_FLEXCAN_UnHandled;
  1600. break;
  1601. }
  1602. }
  1603. else
  1604. {
  1605. /* Get current State of Message Buffer. */
  1606. switch (handle->mbState[result])
  1607. {
  1608. /* Solve Rx Data Frame. */
  1609. case kFLEXCAN_StateRxData:
  1610. #if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE)
  1611. status = FLEXCAN_ReadFDRxMb(base, result, handle->mbFDFrameBuf[result]);
  1612. #else
  1613. status = FLEXCAN_ReadRxMb(base, result, handle->mbFrameBuf[result]);
  1614. #endif
  1615. if (kStatus_Success == status)
  1616. {
  1617. status = kStatus_FLEXCAN_RxIdle;
  1618. }
  1619. #if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE)
  1620. FLEXCAN_TransferFDAbortReceive(base, handle, result);
  1621. #else
  1622. FLEXCAN_TransferAbortReceive(base, handle, result);
  1623. #endif
  1624. break;
  1625. /* Solve Rx Remote Frame. */
  1626. case kFLEXCAN_StateRxRemote:
  1627. status = FLEXCAN_ReadRxMb(base, result, handle->mbFrameBuf[result]);
  1628. if (kStatus_Success == status)
  1629. {
  1630. status = kStatus_FLEXCAN_RxIdle;
  1631. }
  1632. FLEXCAN_TransferAbortReceive(base, handle, result);
  1633. break;
  1634. /* Solve Tx Data Frame. */
  1635. case kFLEXCAN_StateTxData:
  1636. status = kStatus_FLEXCAN_TxIdle;
  1637. #if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE)
  1638. FLEXCAN_TransferFDAbortSend(base, handle, result);
  1639. #else
  1640. FLEXCAN_TransferAbortSend(base, handle, result);
  1641. #endif
  1642. break;
  1643. /* Solve Tx Remote Frame. */
  1644. case kFLEXCAN_StateTxRemote:
  1645. handle->mbState[result] = kFLEXCAN_StateRxRemote;
  1646. status = kStatus_FLEXCAN_TxSwitchToRx;
  1647. break;
  1648. default:
  1649. status = kStatus_FLEXCAN_UnHandled;
  1650. break;
  1651. }
  1652. }
  1653. /* Clear resolved Message Buffer IRQ. */
  1654. #if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
  1655. FLEXCAN_ClearMbStatusFlags(base, (uint64_t)1 << result);
  1656. #else
  1657. FLEXCAN_ClearMbStatusFlags(base, 1 << result);
  1658. #endif
  1659. }
  1660. /* Calling Callback Function if has one. */
  1661. if (handle->callback != NULL)
  1662. {
  1663. handle->callback(base, handle, status, result, handle->userData);
  1664. }
  1665. /* Reset return status */
  1666. status = kStatus_FLEXCAN_UnHandled;
  1667. /* Store Current FlexCAN Module Error and Status. */
  1668. result = base->ESR1;
  1669. }
  1670. #if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
  1671. while ((0 != FLEXCAN_GetMbStatusFlags(base, 0xFFFFFFFFFFFFFFFFU)) ||
  1672. (0 != (result & (kFLEXCAN_TxWarningIntFlag | kFLEXCAN_RxWarningIntFlag | kFLEXCAN_BusOffIntFlag |
  1673. kFLEXCAN_ErrorIntFlag | kFLEXCAN_WakeUpIntFlag))));
  1674. #else
  1675. while ((0 != FLEXCAN_GetMbStatusFlags(base, 0xFFFFFFFFU)) ||
  1676. (0 != (result & (kFLEXCAN_TxWarningIntFlag | kFLEXCAN_RxWarningIntFlag | kFLEXCAN_BusOffIntFlag |
  1677. kFLEXCAN_ErrorIntFlag | kFLEXCAN_WakeUpIntFlag))));
  1678. #endif
  1679. }
  1680. #if defined(CAN0)
  1681. void CAN0_DriverIRQHandler(void)
  1682. {
  1683. assert(s_flexcanHandle[0]);
  1684. s_flexcanIsr(CAN0, s_flexcanHandle[0]);
  1685. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  1686. exception return operation might vector to incorrect interrupt */
  1687. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  1688. __DSB();
  1689. #endif
  1690. }
  1691. #endif
  1692. #if defined(CAN1)
  1693. void CAN1_DriverIRQHandler(void)
  1694. {
  1695. assert(s_flexcanHandle[1]);
  1696. s_flexcanIsr(CAN1, s_flexcanHandle[1]);
  1697. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  1698. exception return operation might vector to incorrect interrupt */
  1699. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  1700. __DSB();
  1701. #endif
  1702. }
  1703. #endif
  1704. #if defined(CAN2)
  1705. void CAN2_DriverIRQHandler(void)
  1706. {
  1707. assert(s_flexcanHandle[2]);
  1708. s_flexcanIsr(CAN2, s_flexcanHandle[2]);
  1709. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  1710. exception return operation might vector to incorrect interrupt */
  1711. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  1712. __DSB();
  1713. #endif
  1714. }
  1715. #endif
  1716. #if defined(CAN3)
  1717. void CAN3_DriverIRQHandler(void)
  1718. {
  1719. assert(s_flexcanHandle[3]);
  1720. s_flexcanIsr(CAN3, s_flexcanHandle[3]);
  1721. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  1722. exception return operation might vector to incorrect interrupt */
  1723. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  1724. __DSB();
  1725. #endif
  1726. }
  1727. #endif
  1728. #if defined(CAN4)
  1729. void CAN4_DriverIRQHandler(void)
  1730. {
  1731. assert(s_flexcanHandle[4]);
  1732. s_flexcanIsr(CAN4, s_flexcanHandle[4]);
  1733. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  1734. exception return operation might vector to incorrect interrupt */
  1735. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  1736. __DSB();
  1737. #endif
  1738. }
  1739. #endif
  1740. #if defined(DMA__CAN0)
  1741. void DMA_FLEXCAN0_INT_DriverIRQHandler(void)
  1742. {
  1743. assert(s_flexcanHandle[FLEXCAN_GetInstance(DMA__CAN0)]);
  1744. s_flexcanIsr(DMA__CAN0, s_flexcanHandle[FLEXCAN_GetInstance(DMA__CAN0)]);
  1745. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  1746. exception return operation might vector to incorrect interrupt */
  1747. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  1748. __DSB();
  1749. #endif
  1750. }
  1751. #endif
  1752. #if defined(DMA__CAN1)
  1753. void DMA_FLEXCAN1_INT_DriverIRQHandler(void)
  1754. {
  1755. assert(s_flexcanHandle[FLEXCAN_GetInstance(DMA__CAN1)]);
  1756. s_flexcanIsr(DMA__CAN1, s_flexcanHandle[FLEXCAN_GetInstance(DMA__CAN1)]);
  1757. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  1758. exception return operation might vector to incorrect interrupt */
  1759. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  1760. __DSB();
  1761. #endif
  1762. }
  1763. #endif
  1764. #if defined(DMA__CAN2)
  1765. void DMA_FLEXCAN2_INT_DriverIRQHandler(void)
  1766. {
  1767. assert(s_flexcanHandle[FLEXCAN_GetInstance(DMA__CAN2)]);
  1768. s_flexcanIsr(DMA__CAN2, s_flexcanHandle[FLEXCAN_GetInstance(DMA__CAN2)]);
  1769. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  1770. exception return operation might vector to incorrect interrupt */
  1771. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  1772. __DSB();
  1773. #endif
  1774. }
  1775. #endif
  1776. #if defined(ADMA__CAN0)
  1777. void ADMA_FLEXCAN0_INT_DriverIRQHandler(void)
  1778. {
  1779. assert(s_flexcanHandle[FLEXCAN_GetInstance(ADMA__CAN0)]);
  1780. s_flexcanIsr(ADMA__CAN0, s_flexcanHandle[FLEXCAN_GetInstance(ADMA__CAN0)]);
  1781. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  1782. exception return operation might vector to incorrect interrupt */
  1783. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  1784. __DSB();
  1785. #endif
  1786. }
  1787. #endif
  1788. #if defined(ADMA__CAN1)
  1789. void ADMA_FLEXCAN1_INT_DriverIRQHandler(void)
  1790. {
  1791. assert(s_flexcanHandle[FLEXCAN_GetInstance(ADMA__CAN1)]);
  1792. s_flexcanIsr(ADMA__CAN1, s_flexcanHandle[FLEXCAN_GetInstance(ADMA__CAN1)]);
  1793. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  1794. exception return operation might vector to incorrect interrupt */
  1795. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  1796. __DSB();
  1797. #endif
  1798. }
  1799. #endif
  1800. #if defined(ADMA__CAN2)
  1801. void ADMA_FLEXCAN2_INT_DriverIRQHandler(void)
  1802. {
  1803. assert(s_flexcanHandle[FLEXCAN_GetInstance(ADMA__CAN2)]);
  1804. s_flexcanIsr(ADMA__CAN2, s_flexcanHandle[FLEXCAN_GetInstance(ADMA__CAN2)]);
  1805. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  1806. exception return operation might vector to incorrect interrupt */
  1807. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  1808. __DSB();
  1809. #endif
  1810. }
  1811. #endif