stm32f3xx_hal_can.c 44 KB

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