stm32l4xx_hal_can_legacy.c 46 KB

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