stm32f1xx_hal_can.c 46 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428
  1. /**
  2. ******************************************************************************
  3. * @file stm32f1xx_hal_can.c
  4. * @author MCD Application Team
  5. * @version V1.0.4
  6. * @date 29-April-2016
  7. * @brief CAN HAL module driver.
  8. * This file provides firmware functions to manage the following
  9. * functionalities of the Controller Area Network (CAN) peripheral:
  10. * + Initialization and de-initialization functions
  11. * + IO operation functions
  12. * + Peripheral Control functions
  13. * + Peripheral State and Error functions
  14. *
  15. @verbatim
  16. ==============================================================================
  17. ##### How to use this driver #####
  18. ==============================================================================
  19. [..]
  20. (#) Enable the CAN controller interface clock using
  21. __HAL_RCC_CAN1_CLK_ENABLE() for CAN1 and __HAL_RCC_CAN2_CLK_ENABLE() for CAN2
  22. -@- In case you are using CAN2 only, you have to enable the CAN1 clock.
  23. (#) CAN pins configuration
  24. (++) Enable the clock for the CAN GPIOs using the following function:
  25. __HAL_RCC_GPIOx_CLK_ENABLE();
  26. (++) Connect and configure the involved CAN pins using the
  27. following function HAL_GPIO_Init();
  28. (#) Initialise and configure the CAN using HAL_CAN_Init() function.
  29. (#) Transmit the desired CAN frame using HAL_CAN_Transmit() function.
  30. (#) Receive a CAN frame using HAL_CAN_Receive() 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) 2016 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. #ifdef HAL_CAN_MODULE_ENABLED
  94. #if defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || \
  95. defined(STM32F103xG) || defined(STM32F105xC) || defined(STM32F107xC)
  96. /** @addtogroup STM32F1xx_HAL_Driver
  97. * @{
  98. */
  99. /** @defgroup CAN CAN
  100. * @brief CAN driver modules
  101. * @{
  102. */
  103. /* Private typedef -----------------------------------------------------------*/
  104. /* Private define ------------------------------------------------------------*/
  105. /** @defgroup CAN_Private_Constants CAN Private Constants
  106. * @{
  107. */
  108. #define CAN_TIMEOUT_VALUE 10
  109. #define CAN_TI0R_STID_BIT_POSITION ((uint32_t)21) /* Position of LSB bits STID in register CAN_TI0R */
  110. #define CAN_TI0R_EXID_BIT_POSITION ((uint32_t) 3) /* Position of LSB bits EXID in register CAN_TI0R */
  111. #define CAN_TDL0R_DATA0_BIT_POSITION ((uint32_t) 0) /* Position of LSB bits DATA0 in register CAN_TDL0R */
  112. #define CAN_TDL0R_DATA1_BIT_POSITION ((uint32_t) 8) /* Position of LSB bits DATA1 in register CAN_TDL0R */
  113. #define CAN_TDL0R_DATA2_BIT_POSITION ((uint32_t)16) /* Position of LSB bits DATA2 in register CAN_TDL0R */
  114. #define CAN_TDL0R_DATA3_BIT_POSITION ((uint32_t)24) /* Position of LSB bits DATA3 in register CAN_TDL0R */
  115. /**
  116. * @}
  117. */
  118. /* Private macro -------------------------------------------------------------*/
  119. /* Private variables ---------------------------------------------------------*/
  120. /* Private function prototypes -----------------------------------------------*/
  121. static HAL_StatusTypeDef CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber);
  122. static HAL_StatusTypeDef CAN_Transmit_IT(CAN_HandleTypeDef* hcan);
  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 = 0;
  151. uint32_t tmp_mcr = 0;
  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. /* Set the automatic bus-off management */
  205. if (hcan->Init.ABOM == ENABLE)
  206. {
  207. SET_BIT(tmp_mcr, CAN_MCR_ABOM);
  208. }
  209. /* Set the automatic wake-up mode */
  210. if (hcan->Init.AWUM == ENABLE)
  211. {
  212. SET_BIT(tmp_mcr, CAN_MCR_AWUM);
  213. }
  214. /* Set the no automatic retransmission */
  215. if (hcan->Init.NART == ENABLE)
  216. {
  217. SET_BIT(tmp_mcr, CAN_MCR_NART);
  218. }
  219. /* Set the receive FIFO locked mode */
  220. if (hcan->Init.RFLM == ENABLE)
  221. {
  222. SET_BIT(tmp_mcr, CAN_MCR_RFLM);
  223. }
  224. /* Set the transmit FIFO priority */
  225. if (hcan->Init.TXFP == ENABLE)
  226. {
  227. SET_BIT(tmp_mcr, CAN_MCR_TXFP);
  228. }
  229. /* Update register MCR */
  230. MODIFY_REG(hcan->Instance->MCR,
  231. CAN_MCR_TTCM |
  232. CAN_MCR_ABOM |
  233. CAN_MCR_AWUM |
  234. CAN_MCR_NART |
  235. CAN_MCR_RFLM |
  236. CAN_MCR_TXFP,
  237. tmp_mcr);
  238. /* Set the bit timing register */
  239. WRITE_REG(hcan->Instance->BTR, (uint32_t)(hcan->Init.Mode |
  240. hcan->Init.SJW |
  241. hcan->Init.BS1 |
  242. hcan->Init.BS2 |
  243. (hcan->Init.Prescaler - 1) ));
  244. /* Request leave initialisation */
  245. CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_INRQ);
  246. /* Get timeout */
  247. tickstart = HAL_GetTick();
  248. /* Wait the acknowledge */
  249. while(HAL_IS_BIT_SET(hcan->Instance->MSR, CAN_MSR_INAK))
  250. {
  251. if((HAL_GetTick()-tickstart) > CAN_TIMEOUT_VALUE)
  252. {
  253. hcan->State= HAL_CAN_STATE_TIMEOUT;
  254. /* Process unlocked */
  255. __HAL_UNLOCK(hcan);
  256. return HAL_TIMEOUT;
  257. }
  258. }
  259. /* Check acknowledged */
  260. if (HAL_IS_BIT_CLR(hcan->Instance->MSR, CAN_MSR_INAK))
  261. {
  262. status = CAN_INITSTATUS_SUCCESS;
  263. }
  264. }
  265. if(status == CAN_INITSTATUS_SUCCESS)
  266. {
  267. /* Set CAN error code to none */
  268. hcan->ErrorCode = HAL_CAN_ERROR_NONE;
  269. /* Initialize the CAN state */
  270. hcan->State = HAL_CAN_STATE_READY;
  271. /* Return function status */
  272. return HAL_OK;
  273. }
  274. else
  275. {
  276. /* Initialize the CAN state */
  277. hcan->State = HAL_CAN_STATE_ERROR;
  278. /* Return function status */
  279. return HAL_ERROR;
  280. }
  281. }
  282. /**
  283. * @brief Configures the CAN reception filter according to the specified
  284. * parameters in the CAN_FilterInitStruct.
  285. * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
  286. * the configuration information for the specified CAN.
  287. * @param sFilterConfig: pointer to a CAN_FilterConfTypeDef structure that
  288. * contains the filter configuration information.
  289. * @retval None
  290. */
  291. HAL_StatusTypeDef HAL_CAN_ConfigFilter(CAN_HandleTypeDef* hcan, CAN_FilterConfTypeDef* sFilterConfig)
  292. {
  293. uint32_t filternbrbitpos = 0;
  294. /* Check the parameters */
  295. assert_param(IS_CAN_FILTER_NUMBER(sFilterConfig->FilterNumber));
  296. assert_param(IS_CAN_FILTER_MODE(sFilterConfig->FilterMode));
  297. assert_param(IS_CAN_FILTER_SCALE(sFilterConfig->FilterScale));
  298. assert_param(IS_CAN_FILTER_FIFO(sFilterConfig->FilterFIFOAssignment));
  299. assert_param(IS_FUNCTIONAL_STATE(sFilterConfig->FilterActivation));
  300. assert_param(IS_CAN_BANKNUMBER(sFilterConfig->BankNumber));
  301. filternbrbitpos = ((uint32_t)1) << sFilterConfig->FilterNumber;
  302. /* Initialisation mode for the filter */
  303. /* Select the start slave bank */
  304. MODIFY_REG(hcan->Instance->FMR ,
  305. CAN_FMR_CAN2SB ,
  306. CAN_FMR_FINIT |
  307. (uint32_t)(sFilterConfig->BankNumber << 8) );
  308. /* Filter Deactivation */
  309. CLEAR_BIT(hcan->Instance->FA1R, filternbrbitpos);
  310. /* Filter Scale */
  311. if (sFilterConfig->FilterScale == CAN_FILTERSCALE_16BIT)
  312. {
  313. /* 16-bit scale for the filter */
  314. CLEAR_BIT(hcan->Instance->FS1R, filternbrbitpos);
  315. /* First 16-bit identifier and First 16-bit mask */
  316. /* Or First 16-bit identifier and Second 16-bit identifier */
  317. hcan->Instance->sFilterRegister[sFilterConfig->FilterNumber].FR1 =
  318. ((0x0000FFFF & (uint32_t)sFilterConfig->FilterMaskIdLow) << 16) |
  319. (0x0000FFFF & (uint32_t)sFilterConfig->FilterIdLow);
  320. /* Second 16-bit identifier and Second 16-bit mask */
  321. /* Or Third 16-bit identifier and Fourth 16-bit identifier */
  322. hcan->Instance->sFilterRegister[sFilterConfig->FilterNumber].FR2 =
  323. ((0x0000FFFF & (uint32_t)sFilterConfig->FilterMaskIdHigh) << 16) |
  324. (0x0000FFFF & (uint32_t)sFilterConfig->FilterIdHigh);
  325. }
  326. if (sFilterConfig->FilterScale == CAN_FILTERSCALE_32BIT)
  327. {
  328. /* 32-bit scale for the filter */
  329. SET_BIT(hcan->Instance->FS1R, filternbrbitpos);
  330. /* 32-bit identifier or First 32-bit identifier */
  331. hcan->Instance->sFilterRegister[sFilterConfig->FilterNumber].FR1 =
  332. ((0x0000FFFF & (uint32_t)sFilterConfig->FilterIdHigh) << 16) |
  333. (0x0000FFFF & (uint32_t)sFilterConfig->FilterIdLow);
  334. /* 32-bit mask or Second 32-bit identifier */
  335. hcan->Instance->sFilterRegister[sFilterConfig->FilterNumber].FR2 =
  336. ((0x0000FFFF & (uint32_t)sFilterConfig->FilterMaskIdHigh) << 16) |
  337. (0x0000FFFF & (uint32_t)sFilterConfig->FilterMaskIdLow);
  338. }
  339. /* Filter Mode */
  340. if (sFilterConfig->FilterMode == CAN_FILTERMODE_IDMASK)
  341. {
  342. /*Id/Mask mode for the filter*/
  343. CLEAR_BIT(hcan->Instance->FM1R, filternbrbitpos);
  344. }
  345. else /* CAN_FilterInitStruct->CAN_FilterMode == CAN_FilterMode_IdList */
  346. {
  347. /*Identifier list mode for the filter*/
  348. SET_BIT(hcan->Instance->FM1R, filternbrbitpos);
  349. }
  350. /* Filter FIFO assignment */
  351. if (sFilterConfig->FilterFIFOAssignment == CAN_FILTER_FIFO0)
  352. {
  353. /* FIFO 0 assignation for the filter */
  354. CLEAR_BIT(hcan->Instance->FFA1R, filternbrbitpos);
  355. }
  356. else
  357. {
  358. /* FIFO 1 assignation for the filter */
  359. SET_BIT(hcan->Instance->FFA1R, filternbrbitpos);
  360. }
  361. /* Filter activation */
  362. if (sFilterConfig->FilterActivation == ENABLE)
  363. {
  364. SET_BIT(hcan->Instance->FA1R, filternbrbitpos);
  365. }
  366. /* Leave the initialisation mode for the filter */
  367. CLEAR_BIT(hcan->Instance->FMR, ((uint32_t)CAN_FMR_FINIT));
  368. /* Return function status */
  369. return HAL_OK;
  370. }
  371. /**
  372. * @brief Deinitializes the CANx peripheral registers to their default reset values.
  373. * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
  374. * the configuration information for the specified CAN.
  375. * @retval HAL status
  376. */
  377. HAL_StatusTypeDef HAL_CAN_DeInit(CAN_HandleTypeDef* hcan)
  378. {
  379. /* Check CAN handle */
  380. if(hcan == NULL)
  381. {
  382. return HAL_ERROR;
  383. }
  384. /* Check the parameters */
  385. assert_param(IS_CAN_ALL_INSTANCE(hcan->Instance));
  386. /* Change CAN state */
  387. hcan->State = HAL_CAN_STATE_BUSY;
  388. /* DeInit the low level hardware */
  389. HAL_CAN_MspDeInit(hcan);
  390. /* Change CAN state */
  391. hcan->State = HAL_CAN_STATE_RESET;
  392. /* Release Lock */
  393. __HAL_UNLOCK(hcan);
  394. /* Return function status */
  395. return HAL_OK;
  396. }
  397. /**
  398. * @brief Initializes the CAN MSP.
  399. * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
  400. * the configuration information for the specified CAN.
  401. * @retval None
  402. */
  403. __weak void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan)
  404. {
  405. /* Prevent unused argument(s) compilation warning */
  406. UNUSED(hcan);
  407. /* NOTE : This function Should not be modified, when the callback is needed,
  408. the HAL_CAN_MspInit can be implemented in the user file
  409. */
  410. }
  411. /**
  412. * @brief DeInitializes the CAN MSP.
  413. * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
  414. * the configuration information for the specified CAN.
  415. * @retval None
  416. */
  417. __weak void HAL_CAN_MspDeInit(CAN_HandleTypeDef* hcan)
  418. {
  419. /* Prevent unused argument(s) compilation warning */
  420. UNUSED(hcan);
  421. /* NOTE : This function Should not be modified, when the callback is needed,
  422. the HAL_CAN_MspDeInit can be implemented in the user file
  423. */
  424. }
  425. /**
  426. * @}
  427. */
  428. /** @defgroup CAN_Exported_Functions_Group2 Input and Output operation functions
  429. * @brief I/O operation functions
  430. *
  431. @verbatim
  432. ==============================================================================
  433. ##### IO operation functions #####
  434. ==============================================================================
  435. [..] This section provides functions allowing to:
  436. (+) Transmit a CAN frame message.
  437. (+) Receive a CAN frame message.
  438. (+) Enter CAN peripheral in sleep mode.
  439. (+) Wake up the CAN peripheral from sleep mode.
  440. @endverbatim
  441. * @{
  442. */
  443. /**
  444. * @brief Initiates and transmits a CAN frame message.
  445. * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
  446. * the configuration information for the specified CAN.
  447. * @param Timeout: Specify Timeout value
  448. * @retval HAL status
  449. */
  450. HAL_StatusTypeDef HAL_CAN_Transmit(CAN_HandleTypeDef* hcan, uint32_t Timeout)
  451. {
  452. uint32_t transmitmailbox = CAN_TXSTATUS_NOMAILBOX;
  453. uint32_t tickstart = 0;
  454. /* Check the parameters */
  455. assert_param(IS_CAN_IDTYPE(hcan->pTxMsg->IDE));
  456. assert_param(IS_CAN_RTR(hcan->pTxMsg->RTR));
  457. assert_param(IS_CAN_DLC(hcan->pTxMsg->DLC));
  458. /* Process locked */
  459. __HAL_LOCK(hcan);
  460. if(hcan->State == HAL_CAN_STATE_BUSY_RX)
  461. {
  462. /* Change CAN state */
  463. hcan->State = HAL_CAN_STATE_BUSY_TX_RX;
  464. }
  465. else
  466. {
  467. /* Change CAN state */
  468. hcan->State = HAL_CAN_STATE_BUSY_TX;
  469. }
  470. /* Select one empty transmit mailbox */
  471. if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME0))
  472. {
  473. transmitmailbox = 0;
  474. }
  475. else if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME1))
  476. {
  477. transmitmailbox = 1;
  478. }
  479. else if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME2))
  480. {
  481. transmitmailbox = 2;
  482. }
  483. else
  484. {
  485. transmitmailbox = CAN_TXSTATUS_NOMAILBOX;
  486. }
  487. if (transmitmailbox != CAN_TXSTATUS_NOMAILBOX)
  488. {
  489. /* Set up the Id */
  490. hcan->Instance->sTxMailBox[transmitmailbox].TIR &= CAN_TI0R_TXRQ;
  491. if (hcan->pTxMsg->IDE == CAN_ID_STD)
  492. {
  493. assert_param(IS_CAN_STDID(hcan->pTxMsg->StdId));
  494. hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->StdId << CAN_TI0R_STID_BIT_POSITION) |
  495. hcan->pTxMsg->RTR);
  496. }
  497. else
  498. {
  499. assert_param(IS_CAN_EXTID(hcan->pTxMsg->ExtId));
  500. hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->ExtId << CAN_TI0R_EXID_BIT_POSITION) |
  501. hcan->pTxMsg->IDE |
  502. hcan->pTxMsg->RTR);
  503. }
  504. /* Set up the DLC */
  505. hcan->pTxMsg->DLC &= (uint8_t)0x0000000F;
  506. hcan->Instance->sTxMailBox[transmitmailbox].TDTR &= (uint32_t)0xFFFFFFF0;
  507. hcan->Instance->sTxMailBox[transmitmailbox].TDTR |= hcan->pTxMsg->DLC;
  508. /* Set up the data field */
  509. WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDLR, ((uint32_t)hcan->pTxMsg->Data[3] << CAN_TDL0R_DATA3_BIT_POSITION) |
  510. ((uint32_t)hcan->pTxMsg->Data[2] << CAN_TDL0R_DATA2_BIT_POSITION) |
  511. ((uint32_t)hcan->pTxMsg->Data[1] << CAN_TDL0R_DATA1_BIT_POSITION) |
  512. ((uint32_t)hcan->pTxMsg->Data[0] << CAN_TDL0R_DATA0_BIT_POSITION) );
  513. WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDHR, ((uint32_t)hcan->pTxMsg->Data[7] << CAN_TDL0R_DATA3_BIT_POSITION) |
  514. ((uint32_t)hcan->pTxMsg->Data[6] << CAN_TDL0R_DATA2_BIT_POSITION) |
  515. ((uint32_t)hcan->pTxMsg->Data[5] << CAN_TDL0R_DATA1_BIT_POSITION) |
  516. ((uint32_t)hcan->pTxMsg->Data[4] << CAN_TDL0R_DATA0_BIT_POSITION) );
  517. /* Request transmission */
  518. SET_BIT(hcan->Instance->sTxMailBox[transmitmailbox].TIR, CAN_TI0R_TXRQ);
  519. /* Get timeout */
  520. tickstart = HAL_GetTick();
  521. /* Check End of transmission flag */
  522. while(!(__HAL_CAN_TRANSMIT_STATUS(hcan, transmitmailbox)))
  523. {
  524. /* Check for the Timeout */
  525. if(Timeout != HAL_MAX_DELAY)
  526. {
  527. if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
  528. {
  529. hcan->State = HAL_CAN_STATE_TIMEOUT;
  530. /* Process unlocked */
  531. __HAL_UNLOCK(hcan);
  532. return HAL_TIMEOUT;
  533. }
  534. }
  535. }
  536. if(hcan->State == HAL_CAN_STATE_BUSY_TX_RX)
  537. {
  538. /* Change CAN state */
  539. hcan->State = HAL_CAN_STATE_BUSY_RX;
  540. /* Process unlocked */
  541. __HAL_UNLOCK(hcan);
  542. }
  543. else
  544. {
  545. /* Change CAN state */
  546. hcan->State = HAL_CAN_STATE_READY;
  547. }
  548. /* Process unlocked */
  549. __HAL_UNLOCK(hcan);
  550. /* Return function status */
  551. return HAL_OK;
  552. }
  553. else
  554. {
  555. /* Change CAN state */
  556. hcan->State = HAL_CAN_STATE_ERROR;
  557. /* Process unlocked */
  558. __HAL_UNLOCK(hcan);
  559. /* Return function status */
  560. return HAL_ERROR;
  561. }
  562. }
  563. /**
  564. * @brief Initiates and transmits a CAN frame message.
  565. * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
  566. * the configuration information for the specified CAN.
  567. * @retval HAL status
  568. */
  569. HAL_StatusTypeDef HAL_CAN_Transmit_IT(CAN_HandleTypeDef* hcan)
  570. {
  571. uint32_t transmitmailbox = CAN_TXSTATUS_NOMAILBOX;
  572. /* Check the parameters */
  573. assert_param(IS_CAN_IDTYPE(hcan->pTxMsg->IDE));
  574. assert_param(IS_CAN_RTR(hcan->pTxMsg->RTR));
  575. assert_param(IS_CAN_DLC(hcan->pTxMsg->DLC));
  576. if((hcan->State == HAL_CAN_STATE_READY) || (hcan->State == HAL_CAN_STATE_BUSY_RX))
  577. {
  578. /* Process Locked */
  579. __HAL_LOCK(hcan);
  580. /* Select one empty transmit mailbox */
  581. if(HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME0))
  582. {
  583. transmitmailbox = 0;
  584. }
  585. else if(HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME1))
  586. {
  587. transmitmailbox = 1;
  588. }
  589. else if(HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME2))
  590. {
  591. transmitmailbox = 2;
  592. }
  593. else
  594. {
  595. transmitmailbox = CAN_TXSTATUS_NOMAILBOX;
  596. }
  597. if(transmitmailbox != CAN_TXSTATUS_NOMAILBOX)
  598. {
  599. /* Set up the Id */
  600. hcan->Instance->sTxMailBox[transmitmailbox].TIR &= CAN_TI0R_TXRQ;
  601. if (hcan->pTxMsg->IDE == CAN_ID_STD)
  602. {
  603. assert_param(IS_CAN_STDID(hcan->pTxMsg->StdId));
  604. hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->StdId << CAN_TI0R_STID_BIT_POSITION) |
  605. hcan->pTxMsg->RTR);
  606. }
  607. else
  608. {
  609. assert_param(IS_CAN_EXTID(hcan->pTxMsg->ExtId));
  610. hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->ExtId << CAN_TI0R_EXID_BIT_POSITION) |
  611. hcan->pTxMsg->IDE |
  612. hcan->pTxMsg->RTR);
  613. }
  614. /* Set up the DLC */
  615. hcan->pTxMsg->DLC &= (uint8_t)0x0000000F;
  616. hcan->Instance->sTxMailBox[transmitmailbox].TDTR &= (uint32_t)0xFFFFFFF0;
  617. hcan->Instance->sTxMailBox[transmitmailbox].TDTR |= hcan->pTxMsg->DLC;
  618. /* Set up the data field */
  619. WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDLR, ((uint32_t)hcan->pTxMsg->Data[3] << CAN_TDL0R_DATA3_BIT_POSITION) |
  620. ((uint32_t)hcan->pTxMsg->Data[2] << CAN_TDL0R_DATA2_BIT_POSITION) |
  621. ((uint32_t)hcan->pTxMsg->Data[1] << CAN_TDL0R_DATA1_BIT_POSITION) |
  622. ((uint32_t)hcan->pTxMsg->Data[0] << CAN_TDL0R_DATA0_BIT_POSITION) );
  623. WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDHR, ((uint32_t)hcan->pTxMsg->Data[7] << CAN_TDL0R_DATA3_BIT_POSITION) |
  624. ((uint32_t)hcan->pTxMsg->Data[6] << CAN_TDL0R_DATA2_BIT_POSITION) |
  625. ((uint32_t)hcan->pTxMsg->Data[5] << CAN_TDL0R_DATA1_BIT_POSITION) |
  626. ((uint32_t)hcan->pTxMsg->Data[4] << CAN_TDL0R_DATA0_BIT_POSITION) );
  627. if(hcan->State == HAL_CAN_STATE_BUSY_RX)
  628. {
  629. /* Change CAN state */
  630. hcan->State = HAL_CAN_STATE_BUSY_TX_RX;
  631. }
  632. else
  633. {
  634. /* Change CAN state */
  635. hcan->State = HAL_CAN_STATE_BUSY_TX;
  636. }
  637. /* Set CAN error code to none */
  638. hcan->ErrorCode = HAL_CAN_ERROR_NONE;
  639. /* Process Unlocked */
  640. __HAL_UNLOCK(hcan);
  641. /* Enable interrupts: */
  642. /* - Enable Error warning Interrupt */
  643. /* - Enable Error passive Interrupt */
  644. /* - Enable Bus-off Interrupt */
  645. /* - Enable Last error code Interrupt */
  646. /* - Enable Error Interrupt */
  647. /* - Enable Transmit mailbox empty Interrupt */
  648. __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EWG |
  649. CAN_IT_EPV |
  650. CAN_IT_BOF |
  651. CAN_IT_LEC |
  652. CAN_IT_ERR |
  653. CAN_IT_TME );
  654. /* Request transmission */
  655. hcan->Instance->sTxMailBox[transmitmailbox].TIR |= CAN_TI0R_TXRQ;
  656. }
  657. }
  658. else
  659. {
  660. return HAL_BUSY;
  661. }
  662. return HAL_OK;
  663. }
  664. /**
  665. * @brief Receives a correct CAN frame.
  666. * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
  667. * the configuration information for the specified CAN.
  668. * @param FIFONumber: FIFO Number value
  669. * @param Timeout: Specify Timeout value
  670. * @retval HAL status
  671. * @retval None
  672. */
  673. HAL_StatusTypeDef HAL_CAN_Receive(CAN_HandleTypeDef* hcan, uint8_t FIFONumber, uint32_t Timeout)
  674. {
  675. uint32_t tickstart = 0;
  676. /* Check the parameters */
  677. assert_param(IS_CAN_FIFO(FIFONumber));
  678. /* Process locked */
  679. __HAL_LOCK(hcan);
  680. if(hcan->State == HAL_CAN_STATE_BUSY_TX)
  681. {
  682. /* Change CAN state */
  683. hcan->State = HAL_CAN_STATE_BUSY_TX_RX;
  684. }
  685. else
  686. {
  687. /* Change CAN state */
  688. hcan->State = HAL_CAN_STATE_BUSY_RX;
  689. }
  690. /* Get tick */
  691. tickstart = HAL_GetTick();
  692. /* Check pending message */
  693. while(__HAL_CAN_MSG_PENDING(hcan, FIFONumber) == 0)
  694. {
  695. /* Check for the Timeout */
  696. if(Timeout != HAL_MAX_DELAY)
  697. {
  698. if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
  699. {
  700. hcan->State = HAL_CAN_STATE_TIMEOUT;
  701. /* Process unlocked */
  702. __HAL_UNLOCK(hcan);
  703. return HAL_TIMEOUT;
  704. }
  705. }
  706. }
  707. /* Get the Id */
  708. hcan->pRxMsg->IDE = (uint8_t)CAN_ID_EXT & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
  709. if (hcan->pRxMsg->IDE == CAN_ID_STD)
  710. {
  711. hcan->pRxMsg->StdId = (uint32_t)0x000007FF & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 21);
  712. }
  713. else
  714. {
  715. hcan->pRxMsg->ExtId = (uint32_t)0x1FFFFFFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 3);
  716. }
  717. hcan->pRxMsg->RTR = (uint8_t)CAN_RTR_REMOTE & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
  718. /* Get the DLC */
  719. hcan->pRxMsg->DLC = (uint8_t)0x0F & hcan->Instance->sFIFOMailBox[FIFONumber].RDTR;
  720. /* Get the FMI */
  721. hcan->pRxMsg->FMI = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDTR >> 8);
  722. /* Get the data field */
  723. hcan->pRxMsg->Data[0] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR;
  724. hcan->pRxMsg->Data[1] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 8);
  725. hcan->pRxMsg->Data[2] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 16);
  726. hcan->pRxMsg->Data[3] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 24);
  727. hcan->pRxMsg->Data[4] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR;
  728. hcan->pRxMsg->Data[5] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 8);
  729. hcan->pRxMsg->Data[6] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 16);
  730. hcan->pRxMsg->Data[7] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 24);
  731. /* Release the FIFO */
  732. if(FIFONumber == CAN_FIFO0)
  733. {
  734. /* Release FIFO0 */
  735. __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO0);
  736. }
  737. else /* FIFONumber == CAN_FIFO1 */
  738. {
  739. /* Release FIFO1 */
  740. __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO1);
  741. }
  742. if(hcan->State == HAL_CAN_STATE_BUSY_TX_RX)
  743. {
  744. /* Change CAN state */
  745. hcan->State = HAL_CAN_STATE_BUSY_TX;
  746. }
  747. else
  748. {
  749. /* Change CAN state */
  750. hcan->State = HAL_CAN_STATE_READY;
  751. }
  752. /* Process unlocked */
  753. __HAL_UNLOCK(hcan);
  754. /* Return function status */
  755. return HAL_OK;
  756. }
  757. /**
  758. * @brief Receives a correct CAN frame.
  759. * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
  760. * the configuration information for the specified CAN.
  761. * @param FIFONumber: Specify the FIFO number
  762. * @retval HAL status
  763. * @retval None
  764. */
  765. HAL_StatusTypeDef HAL_CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber)
  766. {
  767. /* Check the parameters */
  768. assert_param(IS_CAN_FIFO(FIFONumber));
  769. if((hcan->State == HAL_CAN_STATE_READY) || (hcan->State == HAL_CAN_STATE_BUSY_TX))
  770. {
  771. /* Process locked */
  772. __HAL_LOCK(hcan);
  773. if(hcan->State == HAL_CAN_STATE_BUSY_TX)
  774. {
  775. /* Change CAN state */
  776. hcan->State = HAL_CAN_STATE_BUSY_TX_RX;
  777. }
  778. else
  779. {
  780. /* Change CAN state */
  781. hcan->State = HAL_CAN_STATE_BUSY_RX;
  782. }
  783. /* Set CAN error code to none */
  784. hcan->ErrorCode = HAL_CAN_ERROR_NONE;
  785. /* Enable interrupts: */
  786. /* - Enable Error warning Interrupt */
  787. /* - Enable Error passive Interrupt */
  788. /* - Enable Bus-off Interrupt */
  789. /* - Enable Last error code Interrupt */
  790. /* - Enable Error Interrupt */
  791. /* - Enable Transmit mailbox empty Interrupt */
  792. __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EWG |
  793. CAN_IT_EPV |
  794. CAN_IT_BOF |
  795. CAN_IT_LEC |
  796. CAN_IT_ERR |
  797. CAN_IT_TME );
  798. /* Process unlocked */
  799. __HAL_UNLOCK(hcan);
  800. if(FIFONumber == CAN_FIFO0)
  801. {
  802. /* Enable FIFO 0 message pending Interrupt */
  803. __HAL_CAN_ENABLE_IT(hcan, CAN_IT_FMP0);
  804. }
  805. else
  806. {
  807. /* Enable FIFO 1 message pending Interrupt */
  808. __HAL_CAN_ENABLE_IT(hcan, CAN_IT_FMP1);
  809. }
  810. }
  811. else
  812. {
  813. return HAL_BUSY;
  814. }
  815. /* Return function status */
  816. return HAL_OK;
  817. }
  818. /**
  819. * @brief Enters the Sleep (low power) mode.
  820. * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
  821. * the configuration information for the specified CAN.
  822. * @retval HAL status.
  823. */
  824. HAL_StatusTypeDef HAL_CAN_Sleep(CAN_HandleTypeDef* hcan)
  825. {
  826. uint32_t tickstart = 0;
  827. /* Process locked */
  828. __HAL_LOCK(hcan);
  829. /* Change CAN state */
  830. hcan->State = HAL_CAN_STATE_BUSY;
  831. /* Request Sleep mode */
  832. MODIFY_REG(hcan->Instance->MCR,
  833. CAN_MCR_INRQ ,
  834. CAN_MCR_SLEEP );
  835. /* Sleep mode status */
  836. if (HAL_IS_BIT_CLR(hcan->Instance->MSR, CAN_MSR_SLAK) ||
  837. HAL_IS_BIT_SET(hcan->Instance->MSR, CAN_MSR_INAK) )
  838. {
  839. /* Process unlocked */
  840. __HAL_UNLOCK(hcan);
  841. /* Return function status */
  842. return HAL_ERROR;
  843. }
  844. /* Get tick */
  845. tickstart = HAL_GetTick();
  846. /* Wait the acknowledge */
  847. while (HAL_IS_BIT_CLR(hcan->Instance->MSR, CAN_MSR_SLAK) ||
  848. HAL_IS_BIT_SET(hcan->Instance->MSR, CAN_MSR_INAK) )
  849. {
  850. if((HAL_GetTick()-tickstart) > CAN_TIMEOUT_VALUE)
  851. {
  852. hcan->State = HAL_CAN_STATE_TIMEOUT;
  853. /* Process unlocked */
  854. __HAL_UNLOCK(hcan);
  855. return HAL_TIMEOUT;
  856. }
  857. }
  858. /* Change CAN state */
  859. hcan->State = HAL_CAN_STATE_READY;
  860. /* Process unlocked */
  861. __HAL_UNLOCK(hcan);
  862. /* Return function status */
  863. return HAL_OK;
  864. }
  865. /**
  866. * @brief Wakes up the CAN peripheral from sleep mode, after that the CAN peripheral
  867. * is in the normal mode.
  868. * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
  869. * the configuration information for the specified CAN.
  870. * @retval HAL status.
  871. */
  872. HAL_StatusTypeDef HAL_CAN_WakeUp(CAN_HandleTypeDef* hcan)
  873. {
  874. uint32_t tickstart = 0;
  875. /* Process locked */
  876. __HAL_LOCK(hcan);
  877. /* Change CAN state */
  878. hcan->State = HAL_CAN_STATE_BUSY;
  879. /* Wake up request */
  880. CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_SLEEP);
  881. /* Get timeout */
  882. tickstart = HAL_GetTick();
  883. /* Sleep mode status */
  884. while((hcan->Instance->MSR & CAN_MSR_SLAK) == CAN_MSR_SLAK)
  885. {
  886. if((HAL_GetTick()-tickstart) > CAN_TIMEOUT_VALUE)
  887. {
  888. hcan->State= HAL_CAN_STATE_TIMEOUT;
  889. /* Process unlocked */
  890. __HAL_UNLOCK(hcan);
  891. return HAL_TIMEOUT;
  892. }
  893. }
  894. if(HAL_IS_BIT_SET(hcan->Instance->MSR, CAN_MSR_SLAK))
  895. {
  896. /* Process unlocked */
  897. __HAL_UNLOCK(hcan);
  898. /* Return function status */
  899. return HAL_ERROR;
  900. }
  901. /* Change CAN state */
  902. hcan->State = HAL_CAN_STATE_READY;
  903. /* Process unlocked */
  904. __HAL_UNLOCK(hcan);
  905. /* Return function status */
  906. return HAL_OK;
  907. }
  908. /**
  909. * @brief Handles CAN interrupt request
  910. * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
  911. * the configuration information for the specified CAN.
  912. * @retval None
  913. */
  914. void HAL_CAN_IRQHandler(CAN_HandleTypeDef* hcan)
  915. {
  916. /* Check End of transmission flag */
  917. if(__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_TME))
  918. {
  919. if((__HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_0)) ||
  920. (__HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_1)) ||
  921. (__HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_2)))
  922. {
  923. /* Call transmit function */
  924. CAN_Transmit_IT(hcan);
  925. }
  926. }
  927. /* Check End of reception flag for FIFO0 */
  928. if((__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FMP0)) &&
  929. (__HAL_CAN_MSG_PENDING(hcan, CAN_FIFO0) != 0))
  930. {
  931. /* Call receive function */
  932. CAN_Receive_IT(hcan, CAN_FIFO0);
  933. }
  934. /* Check End of reception flag for FIFO1 */
  935. if((__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FMP1)) &&
  936. (__HAL_CAN_MSG_PENDING(hcan, CAN_FIFO1) != 0))
  937. {
  938. /* Call receive function */
  939. CAN_Receive_IT(hcan, CAN_FIFO1);
  940. }
  941. /* Check Error Warning Flag */
  942. if((__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_EWG)) &&
  943. (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_EWG)) &&
  944. (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR)))
  945. {
  946. /* Set CAN error code to EWG error */
  947. hcan->ErrorCode |= HAL_CAN_ERROR_EWG;
  948. /* No need for clear of Error Warning Flag as read-only */
  949. }
  950. /* Check Error Passive Flag */
  951. if((__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_EPV)) &&
  952. (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_EPV)) &&
  953. (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR)))
  954. {
  955. /* Set CAN error code to EPV error */
  956. hcan->ErrorCode |= HAL_CAN_ERROR_EPV;
  957. /* No need for clear of Error Passive Flag as read-only */
  958. }
  959. /* Check Bus-Off Flag */
  960. if((__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_BOF)) &&
  961. (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_BOF)) &&
  962. (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR)))
  963. {
  964. /* Set CAN error code to BOF error */
  965. hcan->ErrorCode |= HAL_CAN_ERROR_BOF;
  966. /* No need for clear of Bus-Off Flag as read-only */
  967. }
  968. /* Check Last error code Flag */
  969. if((!HAL_IS_BIT_CLR(hcan->Instance->ESR, CAN_ESR_LEC)) &&
  970. (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_LEC)) &&
  971. (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR)))
  972. {
  973. switch(hcan->Instance->ESR & CAN_ESR_LEC)
  974. {
  975. case(CAN_ESR_LEC_0):
  976. /* Set CAN error code to STF error */
  977. hcan->ErrorCode |= HAL_CAN_ERROR_STF;
  978. break;
  979. case(CAN_ESR_LEC_1):
  980. /* Set CAN error code to FOR error */
  981. hcan->ErrorCode |= HAL_CAN_ERROR_FOR;
  982. break;
  983. case(CAN_ESR_LEC_1 | CAN_ESR_LEC_0):
  984. /* Set CAN error code to ACK error */
  985. hcan->ErrorCode |= HAL_CAN_ERROR_ACK;
  986. break;
  987. case(CAN_ESR_LEC_2):
  988. /* Set CAN error code to BR error */
  989. hcan->ErrorCode |= HAL_CAN_ERROR_BR;
  990. break;
  991. case(CAN_ESR_LEC_2 | CAN_ESR_LEC_0):
  992. /* Set CAN error code to BD error */
  993. hcan->ErrorCode |= HAL_CAN_ERROR_BD;
  994. break;
  995. case(CAN_ESR_LEC_2 | CAN_ESR_LEC_1):
  996. /* Set CAN error code to CRC error */
  997. hcan->ErrorCode |= HAL_CAN_ERROR_CRC;
  998. break;
  999. default:
  1000. break;
  1001. }
  1002. /* Clear Last error code Flag */
  1003. CLEAR_BIT(hcan->Instance->ESR, CAN_ESR_LEC);
  1004. }
  1005. /* Call the Error call Back in case of Errors */
  1006. if(hcan->ErrorCode != HAL_CAN_ERROR_NONE)
  1007. {
  1008. /* Clear ERRI Flag */
  1009. hcan->Instance->MSR |= CAN_MSR_ERRI;
  1010. /* Set the CAN state ready to be able to start again the process */
  1011. hcan->State = HAL_CAN_STATE_READY;
  1012. /* Call Error callback function */
  1013. HAL_CAN_ErrorCallback(hcan);
  1014. }
  1015. }
  1016. /**
  1017. * @brief Transmission complete callback in non blocking mode
  1018. * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
  1019. * the configuration information for the specified CAN.
  1020. * @retval None
  1021. */
  1022. __weak void HAL_CAN_TxCpltCallback(CAN_HandleTypeDef* hcan)
  1023. {
  1024. /* Prevent unused argument(s) compilation warning */
  1025. UNUSED(hcan);
  1026. /* NOTE : This function Should not be modified, when the callback is needed,
  1027. the HAL_CAN_TxCpltCallback can be implemented in the user file
  1028. */
  1029. }
  1030. /**
  1031. * @brief Transmission complete callback in non blocking mode
  1032. * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
  1033. * the configuration information for the specified CAN.
  1034. * @retval None
  1035. */
  1036. __weak void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* hcan)
  1037. {
  1038. /* Prevent unused argument(s) compilation warning */
  1039. UNUSED(hcan);
  1040. /* NOTE : This function Should not be modified, when the callback is needed,
  1041. the HAL_CAN_RxCpltCallback can be implemented in the user file
  1042. */
  1043. }
  1044. /**
  1045. * @brief Error CAN callback.
  1046. * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
  1047. * the configuration information for the specified CAN.
  1048. * @retval None
  1049. */
  1050. __weak void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan)
  1051. {
  1052. /* Prevent unused argument(s) compilation warning */
  1053. UNUSED(hcan);
  1054. /* NOTE : This function Should not be modified, when the callback is needed,
  1055. the HAL_CAN_ErrorCallback can be implemented in the user file
  1056. */
  1057. }
  1058. /**
  1059. * @}
  1060. */
  1061. /** @defgroup CAN_Exported_Functions_Group3 Peripheral State and Error functions
  1062. * @brief CAN Peripheral State functions
  1063. *
  1064. @verbatim
  1065. ==============================================================================
  1066. ##### Peripheral State and Error functions #####
  1067. ==============================================================================
  1068. [..]
  1069. This subsection provides functions allowing to :
  1070. (+) Check the CAN state.
  1071. (+) Check CAN Errors detected during interrupt process
  1072. @endverbatim
  1073. * @{
  1074. */
  1075. /**
  1076. * @brief return the CAN state
  1077. * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
  1078. * the configuration information for the specified CAN.
  1079. * @retval HAL state
  1080. */
  1081. HAL_CAN_StateTypeDef HAL_CAN_GetState(CAN_HandleTypeDef* hcan)
  1082. {
  1083. /* Return CAN state */
  1084. return hcan->State;
  1085. }
  1086. /**
  1087. * @brief Return the CAN error code
  1088. * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
  1089. * the configuration information for the specified CAN.
  1090. * @retval CAN Error Code
  1091. */
  1092. uint32_t HAL_CAN_GetError(CAN_HandleTypeDef *hcan)
  1093. {
  1094. return hcan->ErrorCode;
  1095. }
  1096. /**
  1097. * @}
  1098. */
  1099. /**
  1100. * @}
  1101. */
  1102. /** @defgroup CAN_Private_Functions CAN Private Functions
  1103. * @{
  1104. */
  1105. /**
  1106. * @brief Initiates and transmits a CAN frame message.
  1107. * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
  1108. * the configuration information for the specified CAN.
  1109. * @retval HAL status
  1110. */
  1111. static HAL_StatusTypeDef CAN_Transmit_IT(CAN_HandleTypeDef* hcan)
  1112. {
  1113. /* Disable Transmit mailbox empty Interrupt */
  1114. __HAL_CAN_DISABLE_IT(hcan, CAN_IT_TME);
  1115. if(hcan->State == HAL_CAN_STATE_BUSY_TX)
  1116. {
  1117. /* Disable interrupts: */
  1118. /* - Disable Error warning Interrupt */
  1119. /* - Disable Error passive Interrupt */
  1120. /* - Disable Bus-off Interrupt */
  1121. /* - Disable Last error code Interrupt */
  1122. /* - Disable Error Interrupt */
  1123. __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EWG |
  1124. CAN_IT_EPV |
  1125. CAN_IT_BOF |
  1126. CAN_IT_LEC |
  1127. CAN_IT_ERR );
  1128. }
  1129. if(hcan->State == HAL_CAN_STATE_BUSY_TX_RX)
  1130. {
  1131. /* Change CAN state */
  1132. hcan->State = HAL_CAN_STATE_BUSY_RX;
  1133. }
  1134. else
  1135. {
  1136. /* Change CAN state */
  1137. hcan->State = HAL_CAN_STATE_READY;
  1138. }
  1139. /* Transmission complete callback */
  1140. HAL_CAN_TxCpltCallback(hcan);
  1141. return HAL_OK;
  1142. }
  1143. /**
  1144. * @brief Receives a correct CAN frame.
  1145. * @param hcan: Pointer to a CAN_HandleTypeDef structure that contains
  1146. * the configuration information for the specified CAN.
  1147. * @param FIFONumber: Specify the FIFO number
  1148. * @retval HAL status
  1149. * @retval None
  1150. */
  1151. static HAL_StatusTypeDef CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber)
  1152. {
  1153. /* Get the Id */
  1154. hcan->pRxMsg->IDE = (uint8_t)0x04 & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
  1155. if (hcan->pRxMsg->IDE == CAN_ID_STD)
  1156. {
  1157. hcan->pRxMsg->StdId = (uint32_t)0x000007FF & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 21);
  1158. }
  1159. else
  1160. {
  1161. hcan->pRxMsg->ExtId = (uint32_t)0x1FFFFFFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 3);
  1162. }
  1163. hcan->pRxMsg->RTR = (uint8_t)0x02 & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
  1164. /* Get the DLC */
  1165. hcan->pRxMsg->DLC = (uint8_t)0x0F & hcan->Instance->sFIFOMailBox[FIFONumber].RDTR;
  1166. /* Get the FMI */
  1167. hcan->pRxMsg->FMI = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDTR >> 8);
  1168. /* Get the data field */
  1169. hcan->pRxMsg->Data[0] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR;
  1170. hcan->pRxMsg->Data[1] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 8);
  1171. hcan->pRxMsg->Data[2] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 16);
  1172. hcan->pRxMsg->Data[3] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 24);
  1173. hcan->pRxMsg->Data[4] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR;
  1174. hcan->pRxMsg->Data[5] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 8);
  1175. hcan->pRxMsg->Data[6] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 16);
  1176. hcan->pRxMsg->Data[7] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 24);
  1177. /* Release the FIFO */
  1178. /* Release FIFO0 */
  1179. if (FIFONumber == CAN_FIFO0)
  1180. {
  1181. __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO0);
  1182. /* Disable FIFO 0 message pending Interrupt */
  1183. __HAL_CAN_DISABLE_IT(hcan, CAN_IT_FMP0);
  1184. }
  1185. /* Release FIFO1 */
  1186. else /* FIFONumber == CAN_FIFO1 */
  1187. {
  1188. __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO1);
  1189. /* Disable FIFO 1 message pending Interrupt */
  1190. __HAL_CAN_DISABLE_IT(hcan, CAN_IT_FMP1);
  1191. }
  1192. if(hcan->State == HAL_CAN_STATE_BUSY_RX)
  1193. {
  1194. /* Disable interrupts: */
  1195. /* - Disable Error warning Interrupt */
  1196. /* - Disable Error passive Interrupt */
  1197. /* - Disable Bus-off Interrupt */
  1198. /* - Disable Last error code Interrupt */
  1199. /* - Disable Error Interrupt */
  1200. __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EWG |
  1201. CAN_IT_EPV |
  1202. CAN_IT_BOF |
  1203. CAN_IT_LEC |
  1204. CAN_IT_ERR );
  1205. }
  1206. if(hcan->State == HAL_CAN_STATE_BUSY_TX_RX)
  1207. {
  1208. /* Disable CAN state */
  1209. hcan->State = HAL_CAN_STATE_BUSY_TX;
  1210. }
  1211. else
  1212. {
  1213. /* Change CAN state */
  1214. hcan->State = HAL_CAN_STATE_READY;
  1215. }
  1216. /* Receive complete callback */
  1217. HAL_CAN_RxCpltCallback(hcan);
  1218. /* Return function status */
  1219. return HAL_OK;
  1220. }
  1221. /**
  1222. * @}
  1223. */
  1224. /**
  1225. * @}
  1226. */
  1227. #endif /* STM32F103x6) || STM32F103xB || STM32F103xE || */
  1228. /* STM32F103xG) || STM32F105xC || STM32F107xC */
  1229. #endif /* HAL_CAN_MODULE_ENABLED */
  1230. /**
  1231. * @}
  1232. */
  1233. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/