stm32f1xx_hal_can.c 55 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716
  1. /**
  2. ******************************************************************************
  3. * @file stm32f1xx_hal_can.c
  4. * @author MCD Application Team
  5. * @brief CAN HAL module driver.
  6. * This file provides firmware functions to manage the following
  7. * functionalities of the Controller Area Network (CAN) peripheral:
  8. * + Initialization and de-initialization functions
  9. * + IO operation functions
  10. * + Peripheral Control functions
  11. * + Peripheral State and Error functions
  12. *
  13. @verbatim
  14. ==============================================================================
  15. ##### How to use this driver #####
  16. ==============================================================================
  17. [..]
  18. (#) Enable the CAN controller interface clock using
  19. __HAL_RCC_CAN1_CLK_ENABLE() for CAN1 and __HAL_RCC_CAN2_CLK_ENABLE() for CAN2
  20. -@- In case you are using CAN2 only, you have to enable the CAN1 clock.
  21. (#) CAN pins configuration
  22. (++) Enable the clock for the CAN GPIOs using the following function:
  23. __HAL_RCC_GPIOx_CLK_ENABLE();
  24. (++) Connect and configure the involved CAN pins using the
  25. following function HAL_GPIO_Init();
  26. (#) Initialize and configure the CAN using HAL_CAN_Init() function.
  27. (#) Transmit the desired CAN frame using HAL_CAN_Transmit() function.
  28. (#) Or transmit the desired CAN frame using HAL_CAN_Transmit_IT() function.
  29. (#) Receive a CAN frame using HAL_CAN_Receive() function.
  30. (#) Or receive a CAN frame using HAL_CAN_Receive_IT() function.
  31. *** Polling mode IO operation ***
  32. =================================
  33. [..]
  34. (+) Start the CAN peripheral transmission and wait the end of this operation
  35. using HAL_CAN_Transmit(), at this stage user can specify the value of timeout
  36. according to his end application
  37. (+) Start the CAN peripheral reception and wait the end of this operation
  38. using HAL_CAN_Receive(), at this stage user can specify the value of timeout
  39. according to his end application
  40. *** Interrupt mode IO operation ***
  41. ===================================
  42. [..]
  43. (+) Start the CAN peripheral transmission using HAL_CAN_Transmit_IT()
  44. (+) Start the CAN peripheral reception using HAL_CAN_Receive_IT()
  45. (+) Use HAL_CAN_IRQHandler() called under the used CAN Interrupt subroutine
  46. (+) At CAN end of transmission HAL_CAN_TxCpltCallback() function is executed and user can
  47. add his own code by customization of function pointer HAL_CAN_TxCpltCallback
  48. (+) In case of CAN Error, HAL_CAN_ErrorCallback() function is executed and user can
  49. add his own code by customization of function pointer HAL_CAN_ErrorCallback
  50. *** CAN HAL driver macros list ***
  51. =============================================
  52. [..]
  53. Below the list of most used macros in CAN HAL driver.
  54. (+) __HAL_CAN_ENABLE_IT: Enable the specified CAN interrupts
  55. (+) __HAL_CAN_DISABLE_IT: Disable the specified CAN interrupts
  56. (+) __HAL_CAN_GET_IT_SOURCE: Check if the specified CAN interrupt source is enabled or disabled
  57. (+) __HAL_CAN_CLEAR_FLAG: Clear the CAN's pending flags
  58. (+) __HAL_CAN_GET_FLAG: Get the selected CAN's flag status
  59. [..]
  60. (@) You can refer to the CAN HAL driver header file for more useful macros
  61. @endverbatim
  62. ******************************************************************************
  63. * @attention
  64. *
  65. * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
  66. *
  67. * Redistribution and use in source and binary forms, with or without modification,
  68. * are permitted provided that the following conditions are met:
  69. * 1. Redistributions of source code must retain the above copyright notice,
  70. * this list of conditions and the following disclaimer.
  71. * 2. Redistributions in binary form must reproduce the above copyright notice,
  72. * this list of conditions and the following disclaimer in the documentation
  73. * and/or other materials provided with the distribution.
  74. * 3. Neither the name of STMicroelectronics nor the names of its contributors
  75. * may be used to endorse or promote products derived from this software
  76. * without specific prior written permission.
  77. *
  78. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  79. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  80. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  81. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  82. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  83. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  84. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  85. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  86. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  87. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  88. *
  89. ******************************************************************************
  90. */
  91. /* Includes ------------------------------------------------------------------*/
  92. #include "stm32f1xx_hal.h"
  93. /** @addtogroup STM32F1xx_HAL_Driver
  94. * @{
  95. */
  96. /** @defgroup CAN CAN
  97. * @brief CAN driver modules
  98. * @{
  99. */
  100. #ifdef HAL_CAN_MODULE_ENABLED
  101. #if defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || \
  102. defined(STM32F103xG) || defined(STM32F105xC) || defined(STM32F107xC)
  103. /* Private typedef -----------------------------------------------------------*/
  104. /* Private define ------------------------------------------------------------*/
  105. /** @defgroup CAN_Private_Constants CAN Private Constants
  106. * @{
  107. */
  108. #define CAN_TIMEOUT_VALUE 10U
  109. /**
  110. * @}
  111. */
  112. /* Private macro -------------------------------------------------------------*/
  113. /* Private variables ---------------------------------------------------------*/
  114. /* Private function prototypes -----------------------------------------------*/
  115. /** @defgroup CAN_Private_Functions CAN Private Functions
  116. * @{
  117. */
  118. static HAL_StatusTypeDef CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber);
  119. static HAL_StatusTypeDef CAN_Transmit_IT(CAN_HandleTypeDef* hcan);
  120. /**
  121. * @}
  122. */
  123. /* Exported functions --------------------------------------------------------*/
  124. /** @defgroup CAN_Exported_Functions CAN Exported Functions
  125. * @{
  126. */
  127. /** @defgroup CAN_Exported_Functions_Group1 Initialization and de-initialization functions
  128. * @brief Initialization and Configuration functions
  129. *
  130. @verbatim
  131. ==============================================================================
  132. ##### Initialization and de-initialization functions #####
  133. ==============================================================================
  134. [..] This section provides functions allowing to:
  135. (+) Initialize and configure the CAN.
  136. (+) De-initialize the CAN.
  137. @endverbatim
  138. * @{
  139. */
  140. /**
  141. * @brief Initializes the CAN peripheral according to the specified
  142. * parameters in the CAN_InitStruct.
  143. * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
  144. * the configuration information for the specified CAN.
  145. * @retval HAL status
  146. */
  147. HAL_StatusTypeDef HAL_CAN_Init(CAN_HandleTypeDef* hcan)
  148. {
  149. uint32_t status = CAN_INITSTATUS_FAILED; /* Default init status */
  150. uint32_t tickstart = 0U;
  151. uint32_t tmp_mcr = 0U;
  152. /* Check CAN handle */
  153. if(hcan == NULL)
  154. {
  155. return HAL_ERROR;
  156. }
  157. /* Check the parameters */
  158. assert_param(IS_CAN_ALL_INSTANCE(hcan->Instance));
  159. assert_param(IS_FUNCTIONAL_STATE(hcan->Init.TTCM));
  160. assert_param(IS_FUNCTIONAL_STATE(hcan->Init.ABOM));
  161. assert_param(IS_FUNCTIONAL_STATE(hcan->Init.AWUM));
  162. assert_param(IS_FUNCTIONAL_STATE(hcan->Init.NART));
  163. assert_param(IS_FUNCTIONAL_STATE(hcan->Init.RFLM));
  164. assert_param(IS_FUNCTIONAL_STATE(hcan->Init.TXFP));
  165. assert_param(IS_CAN_MODE(hcan->Init.Mode));
  166. assert_param(IS_CAN_SJW(hcan->Init.SJW));
  167. assert_param(IS_CAN_BS1(hcan->Init.BS1));
  168. assert_param(IS_CAN_BS2(hcan->Init.BS2));
  169. assert_param(IS_CAN_PRESCALER(hcan->Init.Prescaler));
  170. if(hcan->State == HAL_CAN_STATE_RESET)
  171. {
  172. /* Allocate lock resource and initialize it */
  173. hcan->Lock = HAL_UNLOCKED;
  174. /* Init the low level hardware */
  175. HAL_CAN_MspInit(hcan);
  176. }
  177. /* Initialize the CAN state*/
  178. hcan->State = HAL_CAN_STATE_BUSY;
  179. /* Exit from sleep mode */
  180. CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_SLEEP);
  181. /* Request initialisation */
  182. SET_BIT(hcan->Instance->MCR, CAN_MCR_INRQ);
  183. /* Get timeout */
  184. tickstart = HAL_GetTick();
  185. /* Wait the acknowledge */
  186. while(HAL_IS_BIT_CLR(hcan->Instance->MSR, CAN_MSR_INAK))
  187. {
  188. if((HAL_GetTick()-tickstart) > CAN_TIMEOUT_VALUE)
  189. {
  190. hcan->State= HAL_CAN_STATE_TIMEOUT;
  191. /* Process unlocked */
  192. __HAL_UNLOCK(hcan);
  193. return HAL_TIMEOUT;
  194. }
  195. }
  196. /* Check acknowledge */
  197. if ((hcan->Instance->MSR & CAN_MSR_INAK) == CAN_MSR_INAK)
  198. {
  199. /* Set the time triggered communication mode */
  200. if (hcan->Init.TTCM == ENABLE)
  201. {
  202. SET_BIT(tmp_mcr, CAN_MCR_TTCM);
  203. }
  204. else
  205. {
  206. CLEAR_BIT(tmp_mcr, CAN_MCR_TTCM);
  207. }
  208. /* Set the automatic bus-off management */
  209. if (hcan->Init.ABOM == ENABLE)
  210. {
  211. SET_BIT(tmp_mcr, CAN_MCR_ABOM);
  212. }
  213. else
  214. {
  215. CLEAR_BIT(tmp_mcr, CAN_MCR_ABOM);
  216. }
  217. /* Set the automatic wake-up mode */
  218. if (hcan->Init.AWUM == ENABLE)
  219. {
  220. SET_BIT(tmp_mcr, CAN_MCR_AWUM);
  221. }
  222. else
  223. {
  224. CLEAR_BIT(tmp_mcr, CAN_MCR_AWUM);
  225. }
  226. /* Set the no automatic retransmission */
  227. if (hcan->Init.NART == ENABLE)
  228. {
  229. SET_BIT(tmp_mcr, CAN_MCR_NART);
  230. }
  231. else
  232. {
  233. CLEAR_BIT(tmp_mcr, CAN_MCR_NART);
  234. }
  235. /* Set the receive FIFO locked mode */
  236. if (hcan->Init.RFLM == ENABLE)
  237. {
  238. SET_BIT(tmp_mcr, CAN_MCR_RFLM);
  239. }
  240. else
  241. {
  242. CLEAR_BIT(tmp_mcr, CAN_MCR_RFLM);
  243. }
  244. /* Set the transmit FIFO priority */
  245. if (hcan->Init.TXFP == ENABLE)
  246. {
  247. SET_BIT(tmp_mcr, CAN_MCR_TXFP);
  248. }
  249. else
  250. {
  251. CLEAR_BIT(tmp_mcr, CAN_MCR_TXFP);
  252. }
  253. /* Update register MCR */
  254. MODIFY_REG(hcan->Instance->MCR,
  255. CAN_MCR_TTCM |
  256. CAN_MCR_ABOM |
  257. CAN_MCR_AWUM |
  258. CAN_MCR_NART |
  259. CAN_MCR_RFLM |
  260. CAN_MCR_TXFP,
  261. tmp_mcr);
  262. /* Set the bit timing register */
  263. WRITE_REG(hcan->Instance->BTR, (uint32_t)(hcan->Init.Mode |
  264. hcan->Init.SJW |
  265. hcan->Init.BS1 |
  266. hcan->Init.BS2 |
  267. (hcan->Init.Prescaler - 1U)));
  268. /* Request leave initialisation */
  269. CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_INRQ);
  270. /* Get timeout */
  271. tickstart = HAL_GetTick();
  272. /* Wait the acknowledge */
  273. while(HAL_IS_BIT_SET(hcan->Instance->MSR, CAN_MSR_INAK))
  274. {
  275. if((HAL_GetTick()-tickstart) > CAN_TIMEOUT_VALUE)
  276. {
  277. hcan->State= HAL_CAN_STATE_TIMEOUT;
  278. /* Process unlocked */
  279. __HAL_UNLOCK(hcan);
  280. return HAL_TIMEOUT;
  281. }
  282. }
  283. /* Check acknowledged */
  284. if(HAL_IS_BIT_CLR(hcan->Instance->MSR, CAN_MSR_INAK))
  285. {
  286. status = CAN_INITSTATUS_SUCCESS;
  287. }
  288. }
  289. if(status == CAN_INITSTATUS_SUCCESS)
  290. {
  291. /* Set CAN error code to none */
  292. hcan->ErrorCode = HAL_CAN_ERROR_NONE;
  293. /* Initialize the CAN state */
  294. hcan->State = HAL_CAN_STATE_READY;
  295. /* Return function status */
  296. return HAL_OK;
  297. }
  298. else
  299. {
  300. /* Initialize the CAN state */
  301. hcan->State = HAL_CAN_STATE_ERROR;
  302. /* Return function status */
  303. return HAL_ERROR;
  304. }
  305. }
  306. /**
  307. * @brief Configures the CAN reception filter according to the specified
  308. * parameters in the CAN_FilterInitStruct.
  309. * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
  310. * the configuration information for the specified CAN.
  311. * @param sFilterConfig: pointer to a CAN_FilterConfTypeDef structure that
  312. * contains the filter configuration information.
  313. * @retval None
  314. */
  315. HAL_StatusTypeDef HAL_CAN_ConfigFilter(CAN_HandleTypeDef* hcan, CAN_FilterConfTypeDef* sFilterConfig)
  316. {
  317. uint32_t filternbrbitpos = 0U;
  318. /* Prevent unused argument(s) compilation warning */
  319. UNUSED(hcan);
  320. /* Check the parameters */
  321. assert_param(IS_CAN_FILTER_NUMBER(sFilterConfig->FilterNumber));
  322. assert_param(IS_CAN_FILTER_MODE(sFilterConfig->FilterMode));
  323. assert_param(IS_CAN_FILTER_SCALE(sFilterConfig->FilterScale));
  324. assert_param(IS_CAN_FILTER_FIFO(sFilterConfig->FilterFIFOAssignment));
  325. assert_param(IS_FUNCTIONAL_STATE(sFilterConfig->FilterActivation));
  326. assert_param(IS_CAN_BANKNUMBER(sFilterConfig->BankNumber));
  327. filternbrbitpos = (1U) << sFilterConfig->FilterNumber;
  328. /* Initialisation mode for the filter */
  329. /* Select the start slave bank */
  330. MODIFY_REG(hcan->Instance->FMR ,
  331. CAN_FMR_CAN2SB ,
  332. CAN_FMR_FINIT |
  333. (uint32_t)(sFilterConfig->BankNumber << 8U) );
  334. /* Filter Deactivation */
  335. CLEAR_BIT(hcan->Instance->FA1R, filternbrbitpos);
  336. /* Filter Scale */
  337. if (sFilterConfig->FilterScale == CAN_FILTERSCALE_16BIT)
  338. {
  339. /* 16-bit scale for the filter */
  340. CLEAR_BIT(hcan->Instance->FS1R, filternbrbitpos);
  341. /* First 16-bit identifier and First 16-bit mask */
  342. /* Or First 16-bit identifier and Second 16-bit identifier */
  343. hcan->Instance->sFilterRegister[sFilterConfig->FilterNumber].FR1 =
  344. ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdLow) << 16U) |
  345. (0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdLow);
  346. /* Second 16-bit identifier and Second 16-bit mask */
  347. /* Or Third 16-bit identifier and Fourth 16-bit identifier */
  348. hcan->Instance->sFilterRegister[sFilterConfig->FilterNumber].FR2 =
  349. ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdHigh) << 16U) |
  350. (0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdHigh);
  351. }
  352. if (sFilterConfig->FilterScale == CAN_FILTERSCALE_32BIT)
  353. {
  354. /* 32-bit scale for the filter */
  355. SET_BIT(hcan->Instance->FS1R, filternbrbitpos);
  356. /* 32-bit identifier or First 32-bit identifier */
  357. hcan->Instance->sFilterRegister[sFilterConfig->FilterNumber].FR1 =
  358. ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdHigh) << 16U) |
  359. (0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdLow);
  360. /* 32-bit mask or Second 32-bit identifier */
  361. hcan->Instance->sFilterRegister[sFilterConfig->FilterNumber].FR2 =
  362. ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdHigh) << 16U) |
  363. (0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdLow);
  364. }
  365. /* Filter Mode */
  366. if (sFilterConfig->FilterMode == CAN_FILTERMODE_IDMASK)
  367. {
  368. /*Id/Mask mode for the filter*/
  369. CLEAR_BIT(hcan->Instance->FM1R, filternbrbitpos);
  370. }
  371. else /* CAN_FilterInitStruct->CAN_FilterMode == CAN_FilterMode_IdList */
  372. {
  373. /*Identifier list mode for the filter*/
  374. SET_BIT(hcan->Instance->FM1R, filternbrbitpos);
  375. }
  376. /* Filter FIFO assignment */
  377. if (sFilterConfig->FilterFIFOAssignment == CAN_FILTER_FIFO0)
  378. {
  379. /* FIFO 0 assignation for the filter */
  380. CLEAR_BIT(hcan->Instance->FFA1R, filternbrbitpos);
  381. }
  382. else
  383. {
  384. /* FIFO 1 assignation for the filter */
  385. SET_BIT(hcan->Instance->FFA1R, filternbrbitpos);
  386. }
  387. /* Filter activation */
  388. if (sFilterConfig->FilterActivation == ENABLE)
  389. {
  390. SET_BIT(hcan->Instance->FA1R, filternbrbitpos);
  391. }
  392. /* Leave the initialisation mode for the filter */
  393. CLEAR_BIT(hcan->Instance->FMR, ((uint32_t)CAN_FMR_FINIT));
  394. /* Return function status */
  395. return HAL_OK;
  396. }
  397. /**
  398. * @brief Deinitializes the CANx peripheral registers to their default reset values.
  399. * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
  400. * the configuration information for the specified CAN.
  401. * @retval HAL status
  402. */
  403. HAL_StatusTypeDef HAL_CAN_DeInit(CAN_HandleTypeDef* hcan)
  404. {
  405. /* Check CAN handle */
  406. if(hcan == NULL)
  407. {
  408. return HAL_ERROR;
  409. }
  410. /* Check the parameters */
  411. assert_param(IS_CAN_ALL_INSTANCE(hcan->Instance));
  412. /* Change CAN state */
  413. hcan->State = HAL_CAN_STATE_BUSY;
  414. /* DeInit the low level hardware */
  415. HAL_CAN_MspDeInit(hcan);
  416. /* Change CAN state */
  417. hcan->State = HAL_CAN_STATE_RESET;
  418. /* Release Lock */
  419. __HAL_UNLOCK(hcan);
  420. /* Return function status */
  421. return HAL_OK;
  422. }
  423. /**
  424. * @brief Initializes the CAN MSP.
  425. * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
  426. * the configuration information for the specified CAN.
  427. * @retval None
  428. */
  429. __weak void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan)
  430. {
  431. /* Prevent unused argument(s) compilation warning */
  432. UNUSED(hcan);
  433. /* NOTE : This function Should not be modified, when the callback is needed,
  434. the HAL_CAN_MspInit can be implemented in the user file
  435. */
  436. }
  437. /**
  438. * @brief DeInitializes the CAN MSP.
  439. * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
  440. * the configuration information for the specified CAN.
  441. * @retval None
  442. */
  443. __weak void HAL_CAN_MspDeInit(CAN_HandleTypeDef* hcan)
  444. {
  445. /* Prevent unused argument(s) compilation warning */
  446. UNUSED(hcan);
  447. /* NOTE : This function Should not be modified, when the callback is needed,
  448. the HAL_CAN_MspDeInit can be implemented in the user file
  449. */
  450. }
  451. /**
  452. * @}
  453. */
  454. /** @defgroup CAN_Exported_Functions_Group2 Input and Output operation functions
  455. * @brief I/O operation functions
  456. *
  457. @verbatim
  458. ==============================================================================
  459. ##### IO operation functions #####
  460. ==============================================================================
  461. [..] This section provides functions allowing to:
  462. (+) Transmit a CAN frame message.
  463. (+) Receive a CAN frame message.
  464. (+) Enter CAN peripheral in sleep mode.
  465. (+) Wake up the CAN peripheral from sleep mode.
  466. @endverbatim
  467. * @{
  468. */
  469. /**
  470. * @brief Initiates and transmits a CAN frame message.
  471. * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
  472. * the configuration information for the specified CAN.
  473. * @param Timeout: Specify Timeout value
  474. * @retval HAL status
  475. */
  476. HAL_StatusTypeDef HAL_CAN_Transmit(CAN_HandleTypeDef* hcan, uint32_t Timeout)
  477. {
  478. uint32_t transmitmailbox = CAN_TXSTATUS_NOMAILBOX;
  479. uint32_t tickstart = 0U;
  480. /* Check the parameters */
  481. assert_param(IS_CAN_IDTYPE(hcan->pTxMsg->IDE));
  482. assert_param(IS_CAN_RTR(hcan->pTxMsg->RTR));
  483. assert_param(IS_CAN_DLC(hcan->pTxMsg->DLC));
  484. if(((hcan->Instance->TSR&CAN_TSR_TME0) == CAN_TSR_TME0) || \
  485. ((hcan->Instance->TSR&CAN_TSR_TME1) == CAN_TSR_TME1) || \
  486. ((hcan->Instance->TSR&CAN_TSR_TME2) == CAN_TSR_TME2))
  487. {
  488. /* Process locked */
  489. __HAL_LOCK(hcan);
  490. /* Change CAN state */
  491. switch(hcan->State)
  492. {
  493. case(HAL_CAN_STATE_BUSY_RX0):
  494. hcan->State = HAL_CAN_STATE_BUSY_TX_RX0;
  495. break;
  496. case(HAL_CAN_STATE_BUSY_RX1):
  497. hcan->State = HAL_CAN_STATE_BUSY_TX_RX1;
  498. break;
  499. case(HAL_CAN_STATE_BUSY_RX0_RX1):
  500. hcan->State = HAL_CAN_STATE_BUSY_TX_RX0_RX1;
  501. break;
  502. default: /* HAL_CAN_STATE_READY */
  503. hcan->State = HAL_CAN_STATE_BUSY_TX;
  504. break;
  505. }
  506. /* Select one empty transmit mailbox */
  507. if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME0))
  508. {
  509. transmitmailbox = CAN_TXMAILBOX_0;
  510. }
  511. else if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME1))
  512. {
  513. transmitmailbox = CAN_TXMAILBOX_1;
  514. }
  515. else
  516. {
  517. transmitmailbox = CAN_TXMAILBOX_2;
  518. }
  519. /* Set up the Id */
  520. hcan->Instance->sTxMailBox[transmitmailbox].TIR &= CAN_TI0R_TXRQ;
  521. if (hcan->pTxMsg->IDE == CAN_ID_STD)
  522. {
  523. assert_param(IS_CAN_STDID(hcan->pTxMsg->StdId));
  524. hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->StdId << CAN_TI0R_STID_Pos) |
  525. hcan->pTxMsg->RTR);
  526. }
  527. else
  528. {
  529. assert_param(IS_CAN_EXTID(hcan->pTxMsg->ExtId));
  530. hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->ExtId << CAN_TI0R_EXID_Pos) |
  531. hcan->pTxMsg->IDE |
  532. hcan->pTxMsg->RTR);
  533. }
  534. /* Set up the DLC */
  535. hcan->pTxMsg->DLC &= (uint8_t)0x0000000F;
  536. hcan->Instance->sTxMailBox[transmitmailbox].TDTR &= 0xFFFFFFF0U;
  537. hcan->Instance->sTxMailBox[transmitmailbox].TDTR |= hcan->pTxMsg->DLC;
  538. /* Set up the data field */
  539. WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDLR, ((uint32_t)hcan->pTxMsg->Data[3] << CAN_TDL0R_DATA3_Pos) |
  540. ((uint32_t)hcan->pTxMsg->Data[2] << CAN_TDL0R_DATA2_Pos) |
  541. ((uint32_t)hcan->pTxMsg->Data[1] << CAN_TDL0R_DATA1_Pos) |
  542. ((uint32_t)hcan->pTxMsg->Data[0] << CAN_TDL0R_DATA0_Pos));
  543. WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDHR, ((uint32_t)hcan->pTxMsg->Data[7] << CAN_TDL0R_DATA3_Pos) |
  544. ((uint32_t)hcan->pTxMsg->Data[6] << CAN_TDL0R_DATA2_Pos) |
  545. ((uint32_t)hcan->pTxMsg->Data[5] << CAN_TDL0R_DATA1_Pos) |
  546. ((uint32_t)hcan->pTxMsg->Data[4] << CAN_TDL0R_DATA0_Pos));
  547. /* Request transmission */
  548. SET_BIT(hcan->Instance->sTxMailBox[transmitmailbox].TIR, CAN_TI0R_TXRQ);
  549. /* Get tick */
  550. tickstart = HAL_GetTick();
  551. /* Check End of transmission flag */
  552. while(!(__HAL_CAN_TRANSMIT_STATUS(hcan, transmitmailbox)))
  553. {
  554. /* Check for the Timeout */
  555. if(Timeout != HAL_MAX_DELAY)
  556. {
  557. if((Timeout == 0U) || ((HAL_GetTick()-tickstart) > Timeout))
  558. {
  559. hcan->State = HAL_CAN_STATE_TIMEOUT;
  560. /* Cancel transmission */
  561. __HAL_CAN_CANCEL_TRANSMIT(hcan, transmitmailbox);
  562. /* Process unlocked */
  563. __HAL_UNLOCK(hcan);
  564. return HAL_TIMEOUT;
  565. }
  566. }
  567. }
  568. /* Change CAN state */
  569. switch(hcan->State)
  570. {
  571. case(HAL_CAN_STATE_BUSY_TX_RX0):
  572. hcan->State = HAL_CAN_STATE_BUSY_RX0;
  573. break;
  574. case(HAL_CAN_STATE_BUSY_TX_RX1):
  575. hcan->State = HAL_CAN_STATE_BUSY_RX1;
  576. break;
  577. case(HAL_CAN_STATE_BUSY_TX_RX0_RX1):
  578. hcan->State = HAL_CAN_STATE_BUSY_RX0_RX1;
  579. break;
  580. default: /* HAL_CAN_STATE_BUSY_TX */
  581. hcan->State = HAL_CAN_STATE_READY;
  582. break;
  583. }
  584. /* Process unlocked */
  585. __HAL_UNLOCK(hcan);
  586. /* Return function status */
  587. return HAL_OK;
  588. }
  589. else
  590. {
  591. /* Change CAN state */
  592. hcan->State = HAL_CAN_STATE_ERROR;
  593. /* Return function status */
  594. return HAL_ERROR;
  595. }
  596. }
  597. /**
  598. * @brief Initiates and transmits a CAN frame message.
  599. * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
  600. * the configuration information for the specified CAN.
  601. * @retval HAL status
  602. */
  603. HAL_StatusTypeDef HAL_CAN_Transmit_IT(CAN_HandleTypeDef* hcan)
  604. {
  605. uint32_t transmitmailbox = CAN_TXSTATUS_NOMAILBOX;
  606. /* Check the parameters */
  607. assert_param(IS_CAN_IDTYPE(hcan->pTxMsg->IDE));
  608. assert_param(IS_CAN_RTR(hcan->pTxMsg->RTR));
  609. assert_param(IS_CAN_DLC(hcan->pTxMsg->DLC));
  610. if(((hcan->Instance->TSR&CAN_TSR_TME0) == CAN_TSR_TME0) || \
  611. ((hcan->Instance->TSR&CAN_TSR_TME1) == CAN_TSR_TME1) || \
  612. ((hcan->Instance->TSR&CAN_TSR_TME2) == CAN_TSR_TME2))
  613. {
  614. /* Process Locked */
  615. __HAL_LOCK(hcan);
  616. /* Select one empty transmit mailbox */
  617. if(HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME0))
  618. {
  619. transmitmailbox = CAN_TXMAILBOX_0;
  620. }
  621. else if(HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME1))
  622. {
  623. transmitmailbox = CAN_TXMAILBOX_1;
  624. }
  625. else
  626. {
  627. transmitmailbox = CAN_TXMAILBOX_2;
  628. }
  629. /* Set up the Id */
  630. hcan->Instance->sTxMailBox[transmitmailbox].TIR &= CAN_TI0R_TXRQ;
  631. if(hcan->pTxMsg->IDE == CAN_ID_STD)
  632. {
  633. assert_param(IS_CAN_STDID(hcan->pTxMsg->StdId));
  634. hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->StdId << CAN_TI0R_STID_Pos) | \
  635. hcan->pTxMsg->RTR);
  636. }
  637. else
  638. {
  639. assert_param(IS_CAN_EXTID(hcan->pTxMsg->ExtId));
  640. hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->ExtId << CAN_TI0R_EXID_Pos) | \
  641. hcan->pTxMsg->IDE |
  642. hcan->pTxMsg->RTR);
  643. }
  644. /* Set up the DLC */
  645. hcan->pTxMsg->DLC &= (uint8_t)0x0000000FU;
  646. hcan->Instance->sTxMailBox[transmitmailbox].TDTR &= 0xFFFFFFF0U;
  647. hcan->Instance->sTxMailBox[transmitmailbox].TDTR |= hcan->pTxMsg->DLC;
  648. /* Set up the data field */
  649. WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDLR, ((uint32_t)hcan->pTxMsg->Data[3U] << CAN_TDL0R_DATA3_Pos) |
  650. ((uint32_t)hcan->pTxMsg->Data[2U] << CAN_TDL0R_DATA2_Pos) |
  651. ((uint32_t)hcan->pTxMsg->Data[1U] << CAN_TDL0R_DATA1_Pos) |
  652. ((uint32_t)hcan->pTxMsg->Data[0U] << CAN_TDL0R_DATA0_Pos));
  653. WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDHR, ((uint32_t)hcan->pTxMsg->Data[7U] << CAN_TDL0R_DATA3_Pos) |
  654. ((uint32_t)hcan->pTxMsg->Data[6U] << CAN_TDL0R_DATA2_Pos) |
  655. ((uint32_t)hcan->pTxMsg->Data[5U] << CAN_TDL0R_DATA1_Pos) |
  656. ((uint32_t)hcan->pTxMsg->Data[4U] << CAN_TDL0R_DATA0_Pos));
  657. /* Change CAN state */
  658. switch(hcan->State)
  659. {
  660. case(HAL_CAN_STATE_BUSY_RX0):
  661. hcan->State = HAL_CAN_STATE_BUSY_TX_RX0;
  662. break;
  663. case(HAL_CAN_STATE_BUSY_RX1):
  664. hcan->State = HAL_CAN_STATE_BUSY_TX_RX1;
  665. break;
  666. case(HAL_CAN_STATE_BUSY_RX0_RX1):
  667. hcan->State = HAL_CAN_STATE_BUSY_TX_RX0_RX1;
  668. break;
  669. default: /* HAL_CAN_STATE_READY */
  670. hcan->State = HAL_CAN_STATE_BUSY_TX;
  671. break;
  672. }
  673. /* Set CAN error code to none */
  674. hcan->ErrorCode = HAL_CAN_ERROR_NONE;
  675. /* Process Unlocked */
  676. __HAL_UNLOCK(hcan);
  677. /* Request transmission */
  678. hcan->Instance->sTxMailBox[transmitmailbox].TIR |= CAN_TI0R_TXRQ;
  679. /* Enable interrupts: */
  680. /* - Enable Error warning Interrupt */
  681. /* - Enable Error passive Interrupt */
  682. /* - Enable Bus-off Interrupt */
  683. /* - Enable Last error code Interrupt */
  684. /* - Enable Error Interrupt */
  685. /* - Enable Transmit mailbox empty Interrupt */
  686. __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EWG |
  687. CAN_IT_EPV |
  688. CAN_IT_BOF |
  689. CAN_IT_LEC |
  690. CAN_IT_ERR |
  691. CAN_IT_TME );
  692. }
  693. else
  694. {
  695. /* Change CAN state */
  696. hcan->State = HAL_CAN_STATE_ERROR;
  697. /* Return function status */
  698. return HAL_ERROR;
  699. }
  700. return HAL_OK;
  701. }
  702. /**
  703. * @brief Receives a correct CAN frame.
  704. * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
  705. * the configuration information for the specified CAN.
  706. * @param FIFONumber: FIFO Number value
  707. * @param Timeout: Specify Timeout value
  708. * @retval HAL status
  709. */
  710. HAL_StatusTypeDef HAL_CAN_Receive(CAN_HandleTypeDef* hcan, uint8_t FIFONumber, uint32_t Timeout)
  711. {
  712. uint32_t tickstart = 0U;
  713. CanRxMsgTypeDef* pRxMsg = NULL;
  714. /* Check the parameters */
  715. assert_param(IS_CAN_FIFO(FIFONumber));
  716. /* Check if CAN state is not busy for RX FIFO0 */
  717. if ((FIFONumber == CAN_FIFO0) && ((hcan->State == HAL_CAN_STATE_BUSY_RX0) || \
  718. (hcan->State == HAL_CAN_STATE_BUSY_TX_RX0) || \
  719. (hcan->State == HAL_CAN_STATE_BUSY_RX0_RX1) || \
  720. (hcan->State == HAL_CAN_STATE_BUSY_TX_RX0_RX1)))
  721. {
  722. return HAL_BUSY;
  723. }
  724. /* Check if CAN state is not busy for RX FIFO1 */
  725. if ((FIFONumber == CAN_FIFO1) && ((hcan->State == HAL_CAN_STATE_BUSY_RX1) || \
  726. (hcan->State == HAL_CAN_STATE_BUSY_TX_RX1) || \
  727. (hcan->State == HAL_CAN_STATE_BUSY_RX0_RX1) || \
  728. (hcan->State == HAL_CAN_STATE_BUSY_TX_RX0_RX1)))
  729. {
  730. return HAL_BUSY;
  731. }
  732. /* Process locked */
  733. __HAL_LOCK(hcan);
  734. /* Change CAN state */
  735. if (FIFONumber == CAN_FIFO0)
  736. {
  737. switch(hcan->State)
  738. {
  739. case(HAL_CAN_STATE_BUSY_TX):
  740. hcan->State = HAL_CAN_STATE_BUSY_TX_RX0;
  741. break;
  742. case(HAL_CAN_STATE_BUSY_RX1):
  743. hcan->State = HAL_CAN_STATE_BUSY_RX0_RX1;
  744. break;
  745. case(HAL_CAN_STATE_BUSY_TX_RX1):
  746. hcan->State = HAL_CAN_STATE_BUSY_TX_RX0_RX1;
  747. break;
  748. default: /* HAL_CAN_STATE_READY */
  749. hcan->State = HAL_CAN_STATE_BUSY_RX0;
  750. break;
  751. }
  752. }
  753. else /* FIFONumber == CAN_FIFO1 */
  754. {
  755. switch(hcan->State)
  756. {
  757. case(HAL_CAN_STATE_BUSY_TX):
  758. hcan->State = HAL_CAN_STATE_BUSY_TX_RX1;
  759. break;
  760. case(HAL_CAN_STATE_BUSY_RX0):
  761. hcan->State = HAL_CAN_STATE_BUSY_RX0_RX1;
  762. break;
  763. case(HAL_CAN_STATE_BUSY_TX_RX0):
  764. hcan->State = HAL_CAN_STATE_BUSY_TX_RX0_RX1;
  765. break;
  766. default: /* HAL_CAN_STATE_READY */
  767. hcan->State = HAL_CAN_STATE_BUSY_RX1;
  768. break;
  769. }
  770. }
  771. /* Get tick */
  772. tickstart = HAL_GetTick();
  773. /* Check pending message */
  774. while(__HAL_CAN_MSG_PENDING(hcan, FIFONumber) == 0U)
  775. {
  776. /* Check for the Timeout */
  777. if(Timeout != HAL_MAX_DELAY)
  778. {
  779. if((Timeout == 0U) || ((HAL_GetTick()-tickstart) > Timeout))
  780. {
  781. hcan->State = HAL_CAN_STATE_TIMEOUT;
  782. /* Process unlocked */
  783. __HAL_UNLOCK(hcan);
  784. return HAL_TIMEOUT;
  785. }
  786. }
  787. }
  788. /* Set RxMsg pointer */
  789. if(FIFONumber == CAN_FIFO0)
  790. {
  791. pRxMsg = hcan->pRxMsg;
  792. }
  793. else /* FIFONumber == CAN_FIFO1 */
  794. {
  795. pRxMsg = hcan->pRx1Msg;
  796. }
  797. /* Get the Id */
  798. pRxMsg->IDE = (uint8_t)CAN_ID_EXT & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
  799. if (pRxMsg->IDE == CAN_ID_STD)
  800. {
  801. pRxMsg->StdId = 0x000007FFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 21U);
  802. }
  803. else
  804. {
  805. pRxMsg->ExtId = 0x1FFFFFFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 3U);
  806. }
  807. pRxMsg->RTR = (uint8_t)CAN_RTR_REMOTE & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
  808. /* Get the DLC */
  809. pRxMsg->DLC = (uint8_t)0x0FU & hcan->Instance->sFIFOMailBox[FIFONumber].RDTR;
  810. /* Get the FMI */
  811. pRxMsg->FMI = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RDTR >> 8U);
  812. /* Get the FIFONumber */
  813. pRxMsg->FIFONumber = FIFONumber;
  814. /* Get the data field */
  815. pRxMsg->Data[0] = (uint8_t)0xFFU & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR;
  816. pRxMsg->Data[1] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 8U);
  817. pRxMsg->Data[2] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 16U);
  818. pRxMsg->Data[3] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 24U);
  819. pRxMsg->Data[4] = (uint8_t)0xFFU & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR;
  820. pRxMsg->Data[5] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 8U);
  821. pRxMsg->Data[6] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 16U);
  822. pRxMsg->Data[7] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 24U);
  823. /* Release the FIFO */
  824. if(FIFONumber == CAN_FIFO0)
  825. {
  826. /* Release FIFO0 */
  827. __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO0);
  828. }
  829. else /* FIFONumber == CAN_FIFO1 */
  830. {
  831. /* Release FIFO1 */
  832. __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO1);
  833. }
  834. /* Change CAN state */
  835. if (FIFONumber == CAN_FIFO0)
  836. {
  837. switch(hcan->State)
  838. {
  839. case(HAL_CAN_STATE_BUSY_TX_RX0):
  840. hcan->State = HAL_CAN_STATE_BUSY_TX;
  841. break;
  842. case(HAL_CAN_STATE_BUSY_RX0_RX1):
  843. hcan->State = HAL_CAN_STATE_BUSY_RX1;
  844. break;
  845. case(HAL_CAN_STATE_BUSY_TX_RX0_RX1):
  846. hcan->State = HAL_CAN_STATE_BUSY_TX_RX1;
  847. break;
  848. default: /* HAL_CAN_STATE_BUSY_RX0 */
  849. hcan->State = HAL_CAN_STATE_READY;
  850. break;
  851. }
  852. }
  853. else /* FIFONumber == CAN_FIFO1 */
  854. {
  855. switch(hcan->State)
  856. {
  857. case(HAL_CAN_STATE_BUSY_TX_RX1):
  858. hcan->State = HAL_CAN_STATE_BUSY_TX;
  859. break;
  860. case(HAL_CAN_STATE_BUSY_RX0_RX1):
  861. hcan->State = HAL_CAN_STATE_BUSY_RX0;
  862. break;
  863. case(HAL_CAN_STATE_BUSY_TX_RX0_RX1):
  864. hcan->State = HAL_CAN_STATE_BUSY_TX_RX0;
  865. break;
  866. default: /* HAL_CAN_STATE_BUSY_RX1 */
  867. hcan->State = HAL_CAN_STATE_READY;
  868. break;
  869. }
  870. }
  871. /* Process unlocked */
  872. __HAL_UNLOCK(hcan);
  873. /* Return function status */
  874. return HAL_OK;
  875. }
  876. /**
  877. * @brief Receives a correct CAN frame.
  878. * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
  879. * the configuration information for the specified CAN.
  880. * @param FIFONumber: Specify the FIFO number
  881. * @retval HAL status
  882. */
  883. HAL_StatusTypeDef HAL_CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber)
  884. {
  885. /* Check the parameters */
  886. assert_param(IS_CAN_FIFO(FIFONumber));
  887. /* Check if CAN state is not busy for RX FIFO0 */
  888. if((FIFONumber == CAN_FIFO0) && ((hcan->State == HAL_CAN_STATE_BUSY_RX0) || \
  889. (hcan->State == HAL_CAN_STATE_BUSY_TX_RX0) || \
  890. (hcan->State == HAL_CAN_STATE_BUSY_RX0_RX1) || \
  891. (hcan->State == HAL_CAN_STATE_BUSY_TX_RX0_RX1)))
  892. {
  893. return HAL_BUSY;
  894. }
  895. /* Check if CAN state is not busy for RX FIFO1 */
  896. if((FIFONumber == CAN_FIFO1) && ((hcan->State == HAL_CAN_STATE_BUSY_RX1) || \
  897. (hcan->State == HAL_CAN_STATE_BUSY_TX_RX1) || \
  898. (hcan->State == HAL_CAN_STATE_BUSY_RX0_RX1) || \
  899. (hcan->State == HAL_CAN_STATE_BUSY_TX_RX0_RX1)))
  900. {
  901. return HAL_BUSY;
  902. }
  903. /* Process locked */
  904. __HAL_LOCK(hcan);
  905. /* Change CAN state */
  906. if(FIFONumber == CAN_FIFO0)
  907. {
  908. switch(hcan->State)
  909. {
  910. case(HAL_CAN_STATE_BUSY_TX):
  911. hcan->State = HAL_CAN_STATE_BUSY_TX_RX0;
  912. break;
  913. case(HAL_CAN_STATE_BUSY_RX1):
  914. hcan->State = HAL_CAN_STATE_BUSY_RX0_RX1;
  915. break;
  916. case(HAL_CAN_STATE_BUSY_TX_RX1):
  917. hcan->State = HAL_CAN_STATE_BUSY_TX_RX0_RX1;
  918. break;
  919. default: /* HAL_CAN_STATE_READY */
  920. hcan->State = HAL_CAN_STATE_BUSY_RX0;
  921. break;
  922. }
  923. }
  924. else /* FIFONumber == CAN_FIFO1 */
  925. {
  926. switch(hcan->State)
  927. {
  928. case(HAL_CAN_STATE_BUSY_TX):
  929. hcan->State = HAL_CAN_STATE_BUSY_TX_RX1;
  930. break;
  931. case(HAL_CAN_STATE_BUSY_RX0):
  932. hcan->State = HAL_CAN_STATE_BUSY_RX0_RX1;
  933. break;
  934. case(HAL_CAN_STATE_BUSY_TX_RX0):
  935. hcan->State = HAL_CAN_STATE_BUSY_TX_RX0_RX1;
  936. break;
  937. default: /* HAL_CAN_STATE_READY */
  938. hcan->State = HAL_CAN_STATE_BUSY_RX1;
  939. break;
  940. }
  941. }
  942. /* Set CAN error code to none */
  943. hcan->ErrorCode = HAL_CAN_ERROR_NONE;
  944. /* Enable interrupts: */
  945. /* - Enable Error warning Interrupt */
  946. /* - Enable Error passive Interrupt */
  947. /* - Enable Bus-off Interrupt */
  948. /* - Enable Last error code Interrupt */
  949. /* - Enable Error Interrupt */
  950. /* - Enable Transmit mailbox empty Interrupt */
  951. __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EWG |
  952. CAN_IT_EPV |
  953. CAN_IT_BOF |
  954. CAN_IT_LEC |
  955. CAN_IT_ERR |
  956. CAN_IT_TME );
  957. /* Process unlocked */
  958. __HAL_UNLOCK(hcan);
  959. if(FIFONumber == CAN_FIFO0)
  960. {
  961. /* Enable FIFO 0 overrun and message pending Interrupt */
  962. __HAL_CAN_ENABLE_IT(hcan, CAN_IT_FOV0 | CAN_IT_FMP0);
  963. }
  964. else
  965. {
  966. /* Enable FIFO 1 overrun and message pending Interrupt */
  967. __HAL_CAN_ENABLE_IT(hcan, CAN_IT_FOV1 | CAN_IT_FMP1);
  968. }
  969. /* Return function status */
  970. return HAL_OK;
  971. }
  972. /**
  973. * @brief Enters the Sleep (low power) mode.
  974. * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
  975. * the configuration information for the specified CAN.
  976. * @retval HAL status.
  977. */
  978. HAL_StatusTypeDef HAL_CAN_Sleep(CAN_HandleTypeDef* hcan)
  979. {
  980. uint32_t tickstart = 0U;
  981. /* Process locked */
  982. __HAL_LOCK(hcan);
  983. /* Change CAN state */
  984. hcan->State = HAL_CAN_STATE_BUSY;
  985. /* Request Sleep mode */
  986. MODIFY_REG(hcan->Instance->MCR,
  987. CAN_MCR_INRQ ,
  988. CAN_MCR_SLEEP );
  989. /* Sleep mode status */
  990. if (HAL_IS_BIT_CLR(hcan->Instance->MSR, CAN_MSR_SLAK) ||
  991. HAL_IS_BIT_SET(hcan->Instance->MSR, CAN_MSR_INAK) )
  992. {
  993. /* Process unlocked */
  994. __HAL_UNLOCK(hcan);
  995. /* Return function status */
  996. return HAL_ERROR;
  997. }
  998. /* Get tick */
  999. tickstart = HAL_GetTick();
  1000. /* Wait the acknowledge */
  1001. while (HAL_IS_BIT_CLR(hcan->Instance->MSR, CAN_MSR_SLAK) ||
  1002. HAL_IS_BIT_SET(hcan->Instance->MSR, CAN_MSR_INAK))
  1003. {
  1004. if((HAL_GetTick()-tickstart) > CAN_TIMEOUT_VALUE)
  1005. {
  1006. hcan->State = HAL_CAN_STATE_TIMEOUT;
  1007. /* Process unlocked */
  1008. __HAL_UNLOCK(hcan);
  1009. return HAL_TIMEOUT;
  1010. }
  1011. }
  1012. /* Change CAN state */
  1013. hcan->State = HAL_CAN_STATE_READY;
  1014. /* Process unlocked */
  1015. __HAL_UNLOCK(hcan);
  1016. /* Return function status */
  1017. return HAL_OK;
  1018. }
  1019. /**
  1020. * @brief Wakes up the CAN peripheral from sleep mode, after that the CAN peripheral
  1021. * is in the normal mode.
  1022. * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
  1023. * the configuration information for the specified CAN.
  1024. * @retval HAL status.
  1025. */
  1026. HAL_StatusTypeDef HAL_CAN_WakeUp(CAN_HandleTypeDef* hcan)
  1027. {
  1028. uint32_t tickstart = 0U;
  1029. /* Process locked */
  1030. __HAL_LOCK(hcan);
  1031. /* Change CAN state */
  1032. hcan->State = HAL_CAN_STATE_BUSY;
  1033. /* Wake up request */
  1034. CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_SLEEP);
  1035. /* Get timeout */
  1036. tickstart = HAL_GetTick();
  1037. /* Sleep mode status */
  1038. while((hcan->Instance->MSR & CAN_MSR_SLAK) == CAN_MSR_SLAK)
  1039. {
  1040. if((HAL_GetTick()-tickstart) > CAN_TIMEOUT_VALUE)
  1041. {
  1042. hcan->State= HAL_CAN_STATE_TIMEOUT;
  1043. /* Process unlocked */
  1044. __HAL_UNLOCK(hcan);
  1045. return HAL_TIMEOUT;
  1046. }
  1047. }
  1048. if(HAL_IS_BIT_SET(hcan->Instance->MSR, CAN_MSR_SLAK))
  1049. {
  1050. /* Process unlocked */
  1051. __HAL_UNLOCK(hcan);
  1052. /* Return function status */
  1053. return HAL_ERROR;
  1054. }
  1055. /* Change CAN state */
  1056. hcan->State = HAL_CAN_STATE_READY;
  1057. /* Process unlocked */
  1058. __HAL_UNLOCK(hcan);
  1059. /* Return function status */
  1060. return HAL_OK;
  1061. }
  1062. /**
  1063. * @brief Handles CAN interrupt request
  1064. * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
  1065. * the configuration information for the specified CAN.
  1066. * @retval None
  1067. */
  1068. void HAL_CAN_IRQHandler(CAN_HandleTypeDef* hcan)
  1069. {
  1070. uint32_t tmp1 = 0U, tmp2 = 0U, tmp3 = 0U;
  1071. uint32_t errorcode = HAL_CAN_ERROR_NONE;
  1072. /* Check Overrun flag for FIFO0 */
  1073. tmp1 = __HAL_CAN_GET_FLAG(hcan, CAN_FLAG_FOV0);
  1074. tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FOV0);
  1075. if((tmp1 != 0U) && tmp2)
  1076. {
  1077. /* Set CAN error code to FOV0 error */
  1078. errorcode |= HAL_CAN_ERROR_FOV0;
  1079. /* Clear FIFO0 Overrun Flag */
  1080. __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FOV0);
  1081. }
  1082. /* Check Overrun flag for FIFO1 */
  1083. tmp1 = __HAL_CAN_GET_FLAG(hcan, CAN_FLAG_FOV1);
  1084. tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FOV1);
  1085. if((tmp1 != 0U) && tmp2)
  1086. {
  1087. /* Set CAN error code to FOV1 error */
  1088. errorcode |= HAL_CAN_ERROR_FOV1;
  1089. /* Clear FIFO1 Overrun Flag */
  1090. __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FOV1);
  1091. }
  1092. /* Check End of transmission flag */
  1093. if(__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_TME))
  1094. {
  1095. /* Check Transmit request completion status */
  1096. tmp1 = __HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_0);
  1097. tmp2 = __HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_1);
  1098. tmp3 = __HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_2);
  1099. if(tmp1 || tmp2 || tmp3)
  1100. {
  1101. tmp1 = __HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TXOK0);
  1102. tmp2 = __HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TXOK1);
  1103. tmp3 = __HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TXOK2);
  1104. /* Check Transmit success */
  1105. if((tmp1) || (tmp2) || (tmp3))
  1106. {
  1107. /* Call transmit function */
  1108. CAN_Transmit_IT(hcan);
  1109. }
  1110. else /* Transmit failure */
  1111. {
  1112. /* Set CAN error code to TXFAIL error */
  1113. errorcode |= HAL_CAN_ERROR_TXFAIL;
  1114. }
  1115. /* Clear transmission status flags (RQCPx and TXOKx) */
  1116. SET_BIT(hcan->Instance->TSR, CAN_TSR_RQCP0 | CAN_TSR_RQCP1 | CAN_TSR_RQCP2 | \
  1117. CAN_FLAG_TXOK0 | CAN_FLAG_TXOK1 | CAN_FLAG_TXOK2);
  1118. }
  1119. }
  1120. tmp1 = __HAL_CAN_MSG_PENDING(hcan, CAN_FIFO0);
  1121. tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FMP0);
  1122. /* Check End of reception flag for FIFO0 */
  1123. if((tmp1 != 0U) && tmp2)
  1124. {
  1125. /* Call receive function */
  1126. CAN_Receive_IT(hcan, CAN_FIFO0);
  1127. }
  1128. tmp1 = __HAL_CAN_MSG_PENDING(hcan, CAN_FIFO1);
  1129. tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FMP1);
  1130. /* Check End of reception flag for FIFO1 */
  1131. if((tmp1 != 0U) && tmp2)
  1132. {
  1133. /* Call receive function */
  1134. CAN_Receive_IT(hcan, CAN_FIFO1);
  1135. }
  1136. /* Set error code in handle */
  1137. hcan->ErrorCode |= errorcode;
  1138. tmp1 = __HAL_CAN_GET_FLAG(hcan, CAN_FLAG_EWG);
  1139. tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_EWG);
  1140. tmp3 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR);
  1141. /* Check Error Warning Flag */
  1142. if(tmp1 && tmp2 && tmp3)
  1143. {
  1144. /* Set CAN error code to EWG error */
  1145. hcan->ErrorCode |= HAL_CAN_ERROR_EWG;
  1146. /* No need for clear of Error Warning Flag as read-only */
  1147. }
  1148. tmp1 = __HAL_CAN_GET_FLAG(hcan, CAN_FLAG_EPV);
  1149. tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_EPV);
  1150. tmp3 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR);
  1151. /* Check Error Passive Flag */
  1152. if(tmp1 && tmp2 && tmp3)
  1153. {
  1154. /* Set CAN error code to EPV error */
  1155. hcan->ErrorCode |= HAL_CAN_ERROR_EPV;
  1156. /* No need for clear of Error Passive Flag as read-only */
  1157. }
  1158. tmp1 = __HAL_CAN_GET_FLAG(hcan, CAN_FLAG_BOF);
  1159. tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_BOF);
  1160. tmp3 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR);
  1161. /* Check Bus-Off Flag */
  1162. if(tmp1 && tmp2 && tmp3)
  1163. {
  1164. /* Set CAN error code to BOF error */
  1165. hcan->ErrorCode |= HAL_CAN_ERROR_BOF;
  1166. /* No need for clear of Bus-Off Flag as read-only */
  1167. }
  1168. tmp1 = HAL_IS_BIT_CLR(hcan->Instance->ESR, CAN_ESR_LEC);
  1169. tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_LEC);
  1170. tmp3 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR);
  1171. /* Check Last error code Flag */
  1172. if((!tmp1) && tmp2 && tmp3)
  1173. {
  1174. tmp1 = (hcan->Instance->ESR & CAN_ESR_LEC);
  1175. switch(tmp1)
  1176. {
  1177. case(CAN_ESR_LEC_0):
  1178. /* Set CAN error code to STF error */
  1179. hcan->ErrorCode |= HAL_CAN_ERROR_STF;
  1180. break;
  1181. case(CAN_ESR_LEC_1):
  1182. /* Set CAN error code to FOR error */
  1183. hcan->ErrorCode |= HAL_CAN_ERROR_FOR;
  1184. break;
  1185. case(CAN_ESR_LEC_1 | CAN_ESR_LEC_0):
  1186. /* Set CAN error code to ACK error */
  1187. hcan->ErrorCode |= HAL_CAN_ERROR_ACK;
  1188. break;
  1189. case(CAN_ESR_LEC_2):
  1190. /* Set CAN error code to BR error */
  1191. hcan->ErrorCode |= HAL_CAN_ERROR_BR;
  1192. break;
  1193. case(CAN_ESR_LEC_2 | CAN_ESR_LEC_0):
  1194. /* Set CAN error code to BD error */
  1195. hcan->ErrorCode |= HAL_CAN_ERROR_BD;
  1196. break;
  1197. case(CAN_ESR_LEC_2 | CAN_ESR_LEC_1):
  1198. /* Set CAN error code to CRC error */
  1199. hcan->ErrorCode |= HAL_CAN_ERROR_CRC;
  1200. break;
  1201. default:
  1202. break;
  1203. }
  1204. /* Clear Last error code Flag */
  1205. CLEAR_BIT(hcan->Instance->ESR, CAN_ESR_LEC);
  1206. }
  1207. /* Call the Error call Back in case of Errors */
  1208. if(hcan->ErrorCode != HAL_CAN_ERROR_NONE)
  1209. {
  1210. /* Clear ERRI Flag */
  1211. hcan->Instance->MSR = CAN_MSR_ERRI;
  1212. /* Set the CAN state ready to be able to start again the process */
  1213. hcan->State = HAL_CAN_STATE_READY;
  1214. /* Disable interrupts: */
  1215. /* - Disable Error warning Interrupt */
  1216. /* - Disable Error passive Interrupt */
  1217. /* - Disable Bus-off Interrupt */
  1218. /* - Disable Last error code Interrupt */
  1219. /* - Disable Error Interrupt */
  1220. /* - Disable FIFO 0 message pending Interrupt */
  1221. /* - Disable FIFO 0 Overrun Interrupt */
  1222. /* - Disable FIFO 1 message pending Interrupt */
  1223. /* - Disable FIFO 1 Overrun Interrupt */
  1224. /* - Disable Transmit mailbox empty Interrupt */
  1225. __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EWG |
  1226. CAN_IT_EPV |
  1227. CAN_IT_BOF |
  1228. CAN_IT_LEC |
  1229. CAN_IT_ERR |
  1230. CAN_IT_FMP0|
  1231. CAN_IT_FOV0|
  1232. CAN_IT_FMP1|
  1233. CAN_IT_FOV1|
  1234. CAN_IT_TME );
  1235. /* Call Error callback function */
  1236. HAL_CAN_ErrorCallback(hcan);
  1237. }
  1238. }
  1239. /**
  1240. * @brief Transmission complete callback in non blocking mode
  1241. * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
  1242. * the configuration information for the specified CAN.
  1243. * @retval None
  1244. */
  1245. __weak void HAL_CAN_TxCpltCallback(CAN_HandleTypeDef* hcan)
  1246. {
  1247. /* Prevent unused argument(s) compilation warning */
  1248. UNUSED(hcan);
  1249. /* NOTE : This function Should not be modified, when the callback is needed,
  1250. the HAL_CAN_TxCpltCallback can be implemented in the user file
  1251. */
  1252. }
  1253. /**
  1254. * @brief Transmission complete callback in non blocking mode
  1255. * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
  1256. * the configuration information for the specified CAN.
  1257. * @retval None
  1258. */
  1259. __weak void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* hcan)
  1260. {
  1261. /* Prevent unused argument(s) compilation warning */
  1262. UNUSED(hcan);
  1263. /* NOTE : This function Should not be modified, when the callback is needed,
  1264. the HAL_CAN_RxCpltCallback can be implemented in the user file
  1265. */
  1266. }
  1267. /**
  1268. * @brief Transmission complete callback in non blocking mode
  1269. * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
  1270. * the configuration information for the specified CAN.
  1271. * @retval None
  1272. */
  1273. __weak void HAL_CAN_Rx1CpltCallback(CAN_HandleTypeDef* hcan)
  1274. {
  1275. /* Prevent unused argument(s) compilation warning */
  1276. UNUSED(hcan);
  1277. /* NOTE : This function Should not be modified, when the callback is needed,
  1278. the HAL_CAN_Rx1CpltCallback can be implemented in the user file
  1279. */
  1280. }
  1281. /**
  1282. * @brief Error CAN callback.
  1283. * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
  1284. * the configuration information for the specified CAN.
  1285. * @retval None
  1286. */
  1287. __weak void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan)
  1288. {
  1289. /* Prevent unused argument(s) compilation warning */
  1290. UNUSED(hcan);
  1291. /* NOTE : This function Should not be modified, when the callback is needed,
  1292. the HAL_CAN_ErrorCallback can be implemented in the user file
  1293. */
  1294. }
  1295. /**
  1296. * @}
  1297. */
  1298. /** @defgroup CAN_Exported_Functions_Group3 Peripheral State and Error functions
  1299. * @brief CAN Peripheral State functions
  1300. *
  1301. @verbatim
  1302. ==============================================================================
  1303. ##### Peripheral State and Error functions #####
  1304. ==============================================================================
  1305. [..]
  1306. This subsection provides functions allowing to :
  1307. (+) Check the CAN state.
  1308. (+) Check CAN Errors detected during interrupt process
  1309. @endverbatim
  1310. * @{
  1311. */
  1312. /**
  1313. * @brief return the CAN state
  1314. * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
  1315. * the configuration information for the specified CAN.
  1316. * @retval HAL state
  1317. */
  1318. HAL_CAN_StateTypeDef HAL_CAN_GetState(CAN_HandleTypeDef* hcan)
  1319. {
  1320. /* Return CAN state */
  1321. return hcan->State;
  1322. }
  1323. /**
  1324. * @brief Return the CAN error code
  1325. * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
  1326. * the configuration information for the specified CAN.
  1327. * @retval CAN Error Code
  1328. */
  1329. uint32_t HAL_CAN_GetError(CAN_HandleTypeDef *hcan)
  1330. {
  1331. return hcan->ErrorCode;
  1332. }
  1333. /**
  1334. * @}
  1335. */
  1336. /**
  1337. * @}
  1338. */
  1339. /** @addtogroup CAN_Private_Functions
  1340. * @{
  1341. */
  1342. /**
  1343. * @brief Initiates and transmits a CAN frame message.
  1344. * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
  1345. * the configuration information for the specified CAN.
  1346. * @retval HAL status
  1347. */
  1348. static HAL_StatusTypeDef CAN_Transmit_IT(CAN_HandleTypeDef* hcan)
  1349. {
  1350. /* Disable Transmit mailbox empty Interrupt */
  1351. __HAL_CAN_DISABLE_IT(hcan, CAN_IT_TME);
  1352. if(hcan->State == HAL_CAN_STATE_BUSY_TX)
  1353. {
  1354. /* Disable interrupts: */
  1355. /* - Disable Error warning Interrupt */
  1356. /* - Disable Error passive Interrupt */
  1357. /* - Disable Bus-off Interrupt */
  1358. /* - Disable Last error code Interrupt */
  1359. /* - Disable Error Interrupt */
  1360. __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EWG |
  1361. CAN_IT_EPV |
  1362. CAN_IT_BOF |
  1363. CAN_IT_LEC |
  1364. CAN_IT_ERR);
  1365. }
  1366. /* Change CAN state */
  1367. switch(hcan->State)
  1368. {
  1369. case(HAL_CAN_STATE_BUSY_TX_RX0):
  1370. hcan->State = HAL_CAN_STATE_BUSY_RX0;
  1371. break;
  1372. case(HAL_CAN_STATE_BUSY_TX_RX1):
  1373. hcan->State = HAL_CAN_STATE_BUSY_RX1;
  1374. break;
  1375. case(HAL_CAN_STATE_BUSY_TX_RX0_RX1):
  1376. hcan->State = HAL_CAN_STATE_BUSY_RX0_RX1;
  1377. break;
  1378. default: /* HAL_CAN_STATE_BUSY_TX */
  1379. hcan->State = HAL_CAN_STATE_READY;
  1380. break;
  1381. }
  1382. /* Transmission complete callback */
  1383. HAL_CAN_TxCpltCallback(hcan);
  1384. return HAL_OK;
  1385. }
  1386. /**
  1387. * @brief Receives a correct CAN frame.
  1388. * @param hcan: Pointer to a CAN_HandleTypeDef structure that contains
  1389. * the configuration information for the specified CAN.
  1390. * @param FIFONumber: Specify the FIFO number
  1391. * @retval HAL status
  1392. * @retval None
  1393. */
  1394. static HAL_StatusTypeDef CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber)
  1395. {
  1396. uint32_t tmp1 = 0U;
  1397. CanRxMsgTypeDef* pRxMsg = NULL;
  1398. /* Set RxMsg pointer */
  1399. if(FIFONumber == CAN_FIFO0)
  1400. {
  1401. pRxMsg = hcan->pRxMsg;
  1402. }
  1403. else /* FIFONumber == CAN_FIFO1 */
  1404. {
  1405. pRxMsg = hcan->pRx1Msg;
  1406. }
  1407. /* Get the Id */
  1408. pRxMsg->IDE = (uint8_t)0x04U & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
  1409. if (pRxMsg->IDE == CAN_ID_STD)
  1410. {
  1411. pRxMsg->StdId = 0x000007FFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 21U);
  1412. }
  1413. else
  1414. {
  1415. pRxMsg->ExtId = 0x1FFFFFFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 3U);
  1416. }
  1417. pRxMsg->RTR = (uint8_t)0x02U & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
  1418. /* Get the DLC */
  1419. pRxMsg->DLC = (uint8_t)0x0FU & hcan->Instance->sFIFOMailBox[FIFONumber].RDTR;
  1420. /* Get the FIFONumber */
  1421. pRxMsg->FIFONumber = FIFONumber;
  1422. /* Get the FMI */
  1423. pRxMsg->FMI = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RDTR >> 8U);
  1424. /* Get the data field */
  1425. pRxMsg->Data[0] = (uint8_t)0xFFU & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR;
  1426. pRxMsg->Data[1] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 8U);
  1427. pRxMsg->Data[2] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 16U);
  1428. pRxMsg->Data[3] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 24U);
  1429. pRxMsg->Data[4] = (uint8_t)0xFFU & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR;
  1430. pRxMsg->Data[5] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 8U);
  1431. pRxMsg->Data[6] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 16U);
  1432. pRxMsg->Data[7] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 24U);
  1433. /* Release the FIFO */
  1434. /* Release FIFO0 */
  1435. if (FIFONumber == CAN_FIFO0)
  1436. {
  1437. __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO0);
  1438. /* Disable FIFO 0 overrun and message pending Interrupt */
  1439. __HAL_CAN_DISABLE_IT(hcan, CAN_IT_FOV0 | CAN_IT_FMP0);
  1440. }
  1441. /* Release FIFO1 */
  1442. else /* FIFONumber == CAN_FIFO1 */
  1443. {
  1444. __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO1);
  1445. /* Disable FIFO 1 overrun and message pending Interrupt */
  1446. __HAL_CAN_DISABLE_IT(hcan, CAN_IT_FOV1 | CAN_IT_FMP1);
  1447. }
  1448. tmp1 = hcan->State;
  1449. if((tmp1 == HAL_CAN_STATE_BUSY_RX0) || (tmp1 == HAL_CAN_STATE_BUSY_RX1))
  1450. {
  1451. /* Disable interrupts: */
  1452. /* - Disable Error warning Interrupt */
  1453. /* - Disable Error passive Interrupt */
  1454. /* - Disable Bus-off Interrupt */
  1455. /* - Disable Last error code Interrupt */
  1456. /* - Disable Error Interrupt */
  1457. __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EWG |
  1458. CAN_IT_EPV |
  1459. CAN_IT_BOF |
  1460. CAN_IT_LEC |
  1461. CAN_IT_ERR);
  1462. }
  1463. /* Change CAN state */
  1464. if (FIFONumber == CAN_FIFO0)
  1465. {
  1466. switch(hcan->State)
  1467. {
  1468. case(HAL_CAN_STATE_BUSY_TX_RX0):
  1469. hcan->State = HAL_CAN_STATE_BUSY_TX;
  1470. break;
  1471. case(HAL_CAN_STATE_BUSY_RX0_RX1):
  1472. hcan->State = HAL_CAN_STATE_BUSY_RX1;
  1473. break;
  1474. case(HAL_CAN_STATE_BUSY_TX_RX0_RX1):
  1475. hcan->State = HAL_CAN_STATE_BUSY_TX_RX1;
  1476. break;
  1477. default: /* HAL_CAN_STATE_BUSY_RX0 */
  1478. hcan->State = HAL_CAN_STATE_READY;
  1479. break;
  1480. }
  1481. /* Receive complete callback */
  1482. HAL_CAN_RxCpltCallback(hcan);
  1483. }
  1484. else /* FIFONumber == CAN_FIFO1 */
  1485. {
  1486. switch(hcan->State)
  1487. {
  1488. case(HAL_CAN_STATE_BUSY_TX_RX1):
  1489. hcan->State = HAL_CAN_STATE_BUSY_TX;
  1490. break;
  1491. case(HAL_CAN_STATE_BUSY_RX0_RX1):
  1492. hcan->State = HAL_CAN_STATE_BUSY_RX0;
  1493. break;
  1494. case(HAL_CAN_STATE_BUSY_TX_RX0_RX1):
  1495. hcan->State = HAL_CAN_STATE_BUSY_TX_RX0;
  1496. break;
  1497. default: /* HAL_CAN_STATE_BUSY_RX1 */
  1498. hcan->State = HAL_CAN_STATE_READY;
  1499. break;
  1500. }
  1501. /* Receive complete callback */
  1502. HAL_CAN_Rx1CpltCallback(hcan);
  1503. }
  1504. /* Return function status */
  1505. return HAL_OK;
  1506. }
  1507. /**
  1508. * @}
  1509. */
  1510. #endif /* STM32F103x6) || STM32F103xB || STM32F103xE || STM32F103xG) || STM32F105xC || STM32F107xC */
  1511. #endif /* HAL_CAN_MODULE_ENABLED */
  1512. /**
  1513. * @}
  1514. */
  1515. /**
  1516. * @}
  1517. */
  1518. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/