stm32f1xx_hal_can.c 33 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012
  1. /**
  2. ******************************************************************************
  3. * @file stm32f1xx_hal_can.c
  4. * @author MCD Application Team
  5. * @version V1.0.4
  6. * @date 29-April-2016
  7. * @brief CAN HAL module driver.
  8. * This file provides firmware functions to manage the following
  9. * functionalities of the Controller Area Network (CAN) peripheral:
  10. * + Initialization and de-initialization functions
  11. * + IO operation functions
  12. * + Peripheral Control functions
  13. * + Peripheral State and Error functions
  14. *
  15. @verbatim
  16. ==============================================================================
  17. ##### How to use this driver #####
  18. ==============================================================================
  19. [..]
  20. (#) Enable the CAN controller interface clock using
  21. __HAL_RCC_CAN1_CLK_ENABLE() for CAN1 and __HAL_RCC_CAN2_CLK_ENABLE() for CAN2
  22. -@- In case you are using CAN2 only, you have to enable the CAN1 clock.
  23. (#) CAN pins configuration
  24. (++) Enable the clock for the CAN GPIOs using the following function:
  25. __HAL_RCC_GPIOx_CLK_ENABLE();
  26. (++) Connect and configure the involved CAN pins using the
  27. following function HAL_GPIO_Init();
  28. (#) Initialise and configure the CAN using HAL_CAN_Init() function.
  29. (#) Transmit the desired CAN frame using HAL_CAN_Transmit() function.
  30. (#) Receive a CAN frame using HAL_CAN_Receive() function.
  31. *** Polling mode IO operation ***
  32. =================================
  33. [..]
  34. (+) Start the CAN peripheral transmission and wait the end of this operation
  35. using HAL_CAN_Transmit(), at this stage user can specify the value of timeout
  36. according to his end application
  37. (+) Start the CAN peripheral reception and wait the end of this operation
  38. using HAL_CAN_Receive(), at this stage user can specify the value of timeout
  39. according to his end application
  40. *** Interrupt mode IO operation ***
  41. ===================================
  42. [..]
  43. (+) Start the CAN peripheral transmission using HAL_CAN_Transmit_IT()
  44. (+) Start the CAN peripheral reception using HAL_CAN_Receive_IT()
  45. (+) Use HAL_CAN_IRQHandler() called under the used CAN Interrupt subroutine
  46. (+) At CAN end of transmission HAL_CAN_TxCpltCallback() function is executed and user can
  47. add his own code by customization of function pointer HAL_CAN_TxCpltCallback
  48. (+) In case of CAN Error, HAL_CAN_ErrorCallback() function is executed and user can
  49. add his own code by customization of function pointer HAL_CAN_ErrorCallback
  50. *** CAN HAL driver macros list ***
  51. =============================================
  52. [..]
  53. Below the list of most used macros in CAN HAL driver.
  54. (+) __HAL_CAN_ENABLE_IT: Enable the specified CAN interrupts
  55. (+) __HAL_CAN_DISABLE_IT: Disable the specified CAN interrupts
  56. (+) __HAL_CAN_GET_IT_SOURCE: Check if the specified CAN interrupt source is enabled or disabled
  57. (+) __HAL_CAN_CLEAR_FLAG: Clear the CAN's pending flags
  58. (+) __HAL_CAN_GET_FLAG: Get the selected CAN's flag status
  59. [..]
  60. (@) You can refer to the CAN HAL driver header file for more useful macros
  61. @endverbatim
  62. ******************************************************************************
  63. * @attention
  64. *
  65. * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
  66. *
  67. * Redistribution and use in source and binary forms, with or without modification,
  68. * are permitted provided that the following conditions are met:
  69. * 1. Redistributions of source code must retain the above copyright notice,
  70. * this list of conditions and the following disclaimer.
  71. * 2. Redistributions in binary form must reproduce the above copyright notice,
  72. * this list of conditions and the following disclaimer in the documentation
  73. * and/or other materials provided with the distribution.
  74. * 3. Neither the name of STMicroelectronics nor the names of its contributors
  75. * may be used to endorse or promote products derived from this software
  76. * without specific prior written permission.
  77. *
  78. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  79. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  80. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  81. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  82. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  83. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  84. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  85. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  86. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  87. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  88. *
  89. ******************************************************************************
  90. */
  91. /* Includes ------------------------------------------------------------------*/
  92. #include "stm32f3xx_hal.h"
  93. /** @addtogroup STM32F1xx_HAL_Driver
  94. * @{
  95. */
  96. /** @defgroup CAN CAN
  97. * @brief CAN driver modules
  98. * @{
  99. */
  100. /* Private typedef -----------------------------------------------------------*/
  101. /* Private define ------------------------------------------------------------*/
  102. /** @defgroup CAN_Private_Constants CAN Private Constants
  103. * @{
  104. */
  105. #define CAN_TIMEOUT_VALUE 10
  106. #define CAN_TI0R_STID_BIT_POSITION ((uint32_t)21) /* Position of LSB bits STID in register CAN_TI0R */
  107. #define CAN_TI0R_EXID_BIT_POSITION ((uint32_t) 3) /* Position of LSB bits EXID in register CAN_TI0R */
  108. #define CAN_TDL0R_DATA0_BIT_POSITION ((uint32_t) 0) /* Position of LSB bits DATA0 in register CAN_TDL0R */
  109. #define CAN_TDL0R_DATA1_BIT_POSITION ((uint32_t) 8) /* Position of LSB bits DATA1 in register CAN_TDL0R */
  110. #define CAN_TDL0R_DATA2_BIT_POSITION ((uint32_t)16) /* Position of LSB bits DATA2 in register CAN_TDL0R */
  111. #define CAN_TDL0R_DATA3_BIT_POSITION ((uint32_t)24) /* Position of LSB bits DATA3 in register CAN_TDL0R */
  112. /**
  113. * @}
  114. */
  115. /* Private macro -------------------------------------------------------------*/
  116. /* Private variables ---------------------------------------------------------*/
  117. /* Private function prototypes -----------------------------------------------*/
  118. static HAL_StatusTypeDef CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber);
  119. static HAL_StatusTypeDef CAN_Transmit_IT(CAN_HandleTypeDef* hcan);
  120. /* Exported functions ---------------------------------------------------------*/
  121. /** @defgroup CAN_Exported_Functions CAN Exported Functions
  122. * @{
  123. */
  124. /** @defgroup CAN_Exported_Functions_Group1 Initialization and de-initialization functions
  125. * @brief Initialization and Configuration functions
  126. *
  127. @verbatim
  128. ==============================================================================
  129. ##### Initialization and de-initialization functions #####
  130. ==============================================================================
  131. [..] This section provides functions allowing to:
  132. (+) Initialize and configure the CAN.
  133. (+) De-initialize the CAN.
  134. @endverbatim
  135. * @{
  136. */
  137. /**
  138. * @brief Initializes the CAN peripheral according to the specified
  139. * parameters in the CAN_InitStruct.
  140. * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
  141. * the configuration information for the specified CAN.
  142. * @retval HAL status
  143. */
  144. HAL_StatusTypeDef HAL_CAN_Init(CAN_HandleTypeDef* hcan)
  145. {
  146. uint32_t status = CAN_INITSTATUS_FAILED; /* Default init status */
  147. uint32_t tickstart = 0;
  148. uint32_t tmp_mcr = 0;
  149. /* Check CAN handle */
  150. if(hcan == NULL)
  151. {
  152. return HAL_ERROR;
  153. }
  154. /* Check the parameters */
  155. assert_param(IS_CAN_ALL_INSTANCE(hcan->Instance));
  156. assert_param(IS_FUNCTIONAL_STATE(hcan->Init.TTCM));
  157. assert_param(IS_FUNCTIONAL_STATE(hcan->Init.ABOM));
  158. assert_param(IS_FUNCTIONAL_STATE(hcan->Init.AWUM));
  159. assert_param(IS_FUNCTIONAL_STATE(hcan->Init.NART));
  160. assert_param(IS_FUNCTIONAL_STATE(hcan->Init.RFLM));
  161. assert_param(IS_FUNCTIONAL_STATE(hcan->Init.TXFP));
  162. assert_param(IS_CAN_MODE(hcan->Init.Mode));
  163. assert_param(IS_CAN_SJW(hcan->Init.SJW));
  164. assert_param(IS_CAN_BS1(hcan->Init.BS1));
  165. assert_param(IS_CAN_BS2(hcan->Init.BS2));
  166. assert_param(IS_CAN_PRESCALER(hcan->Init.Prescaler));
  167. if(hcan->State == HAL_CAN_STATE_RESET)
  168. {
  169. /* Allocate lock resource and initialize it */
  170. hcan->Lock = HAL_UNLOCKED;
  171. /* Init the low level hardware */
  172. HAL_CAN_MspInit(hcan);
  173. }
  174. /* Initialize the CAN state*/
  175. hcan->State = HAL_CAN_STATE_BUSY;
  176. /* Exit from sleep mode */
  177. CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_SLEEP);
  178. /* Request initialisation */
  179. SET_BIT(hcan->Instance->MCR, CAN_MCR_INRQ);
  180. /* Get timeout */
  181. tickstart = HAL_GetTick();
  182. /* Wait the acknowledge */
  183. while(HAL_IS_BIT_CLR(hcan->Instance->MSR, CAN_MSR_INAK))
  184. {
  185. if((HAL_GetTick()-tickstart) > CAN_TIMEOUT_VALUE)
  186. {
  187. hcan->State= HAL_CAN_STATE_TIMEOUT;
  188. /* Process unlocked */
  189. __HAL_UNLOCK(hcan);
  190. return HAL_TIMEOUT;
  191. }
  192. }
  193. /* Check acknowledge */
  194. if ((hcan->Instance->MSR & CAN_MSR_INAK) == CAN_MSR_INAK)
  195. {
  196. /* Set the time triggered communication mode */
  197. if (hcan->Init.TTCM == ENABLE)
  198. {
  199. SET_BIT(tmp_mcr, CAN_MCR_TTCM);
  200. }
  201. /* Set the automatic bus-off management */
  202. if (hcan->Init.ABOM == ENABLE)
  203. {
  204. SET_BIT(tmp_mcr, CAN_MCR_ABOM);
  205. }
  206. /* Set the automatic wake-up mode */
  207. if (hcan->Init.AWUM == ENABLE)
  208. {
  209. SET_BIT(tmp_mcr, CAN_MCR_AWUM);
  210. }
  211. /* Set the no automatic retransmission */
  212. if (hcan->Init.NART == ENABLE)
  213. {
  214. SET_BIT(tmp_mcr, CAN_MCR_NART);
  215. }
  216. /* Set the receive FIFO locked mode */
  217. if (hcan->Init.RFLM == ENABLE)
  218. {
  219. SET_BIT(tmp_mcr, CAN_MCR_RFLM);
  220. }
  221. /* Set the transmit FIFO priority */
  222. if (hcan->Init.TXFP == ENABLE)
  223. {
  224. SET_BIT(tmp_mcr, CAN_MCR_TXFP);
  225. }
  226. /* Update register MCR */
  227. MODIFY_REG(hcan->Instance->MCR,
  228. CAN_MCR_TTCM |
  229. CAN_MCR_ABOM |
  230. CAN_MCR_AWUM |
  231. CAN_MCR_NART |
  232. CAN_MCR_RFLM |
  233. CAN_MCR_TXFP,
  234. tmp_mcr);
  235. /* Set the bit timing register */
  236. WRITE_REG(hcan->Instance->BTR, (uint32_t)(hcan->Init.Mode |
  237. hcan->Init.SJW |
  238. hcan->Init.BS1 |
  239. hcan->Init.BS2 |
  240. (hcan->Init.Prescaler - 1) ));
  241. /* Request leave initialisation */
  242. CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_INRQ);
  243. /* Get timeout */
  244. tickstart = HAL_GetTick();
  245. /* Wait the acknowledge */
  246. while(HAL_IS_BIT_SET(hcan->Instance->MSR, CAN_MSR_INAK))
  247. {
  248. if((HAL_GetTick()-tickstart) > CAN_TIMEOUT_VALUE)
  249. {
  250. hcan->State= HAL_CAN_STATE_TIMEOUT;
  251. /* Process unlocked */
  252. __HAL_UNLOCK(hcan);
  253. return HAL_TIMEOUT;
  254. }
  255. }
  256. /* Check acknowledged */
  257. if (HAL_IS_BIT_CLR(hcan->Instance->MSR, CAN_MSR_INAK))
  258. {
  259. status = CAN_INITSTATUS_SUCCESS;
  260. }
  261. }
  262. if(status == CAN_INITSTATUS_SUCCESS)
  263. {
  264. /* Set CAN error code to none */
  265. hcan->ErrorCode = HAL_CAN_ERROR_NONE;
  266. /* Initialize the CAN state */
  267. hcan->State = HAL_CAN_STATE_READY;
  268. /* Return function status */
  269. return HAL_OK;
  270. }
  271. else
  272. {
  273. /* Initialize the CAN state */
  274. hcan->State = HAL_CAN_STATE_ERROR;
  275. /* Return function status */
  276. return HAL_ERROR;
  277. }
  278. }
  279. /**
  280. * @brief Configures the CAN reception filter according to the specified
  281. * parameters in the CAN_FilterInitStruct.
  282. * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
  283. * the configuration information for the specified CAN.
  284. * @param sFilterConfig: pointer to a CAN_FilterConfTypeDef structure that
  285. * contains the filter configuration information.
  286. * @retval None
  287. */
  288. HAL_StatusTypeDef HAL_CAN_ConfigFilter(CAN_HandleTypeDef* hcan, CAN_FilterConfTypeDef* sFilterConfig)
  289. {
  290. uint32_t filternbrbitpos = 0;
  291. /* Check the parameters */
  292. assert_param(IS_CAN_FILTER_NUMBER(sFilterConfig->FilterNumber));
  293. assert_param(IS_CAN_FILTER_MODE(sFilterConfig->FilterMode));
  294. assert_param(IS_CAN_FILTER_SCALE(sFilterConfig->FilterScale));
  295. assert_param(IS_CAN_FILTER_FIFO(sFilterConfig->FilterFIFOAssignment));
  296. assert_param(IS_FUNCTIONAL_STATE(sFilterConfig->FilterActivation));
  297. assert_param(IS_CAN_BANKNUMBER(sFilterConfig->BankNumber));
  298. filternbrbitpos = ((uint32_t)1) << sFilterConfig->FilterNumber;
  299. /* Initialisation mode for the filter */
  300. /* Select the start slave bank */
  301. MODIFY_REG(hcan->Instance->FMR ,
  302. CAN_FMR_CAN2SB ,
  303. CAN_FMR_FINIT |
  304. (uint32_t)(sFilterConfig->BankNumber << 8) );
  305. /* Filter Deactivation */
  306. CLEAR_BIT(hcan->Instance->FA1R, filternbrbitpos);
  307. /* Filter Scale */
  308. if (sFilterConfig->FilterScale == CAN_FILTERSCALE_16BIT)
  309. {
  310. /* 16-bit scale for the filter */
  311. CLEAR_BIT(hcan->Instance->FS1R, filternbrbitpos);
  312. /* First 16-bit identifier and First 16-bit mask */
  313. /* Or First 16-bit identifier and Second 16-bit identifier */
  314. hcan->Instance->sFilterRegister[sFilterConfig->FilterNumber].FR1 =
  315. ((0x0000FFFF & (uint32_t)sFilterConfig->FilterMaskIdLow) << 16) |
  316. (0x0000FFFF & (uint32_t)sFilterConfig->FilterIdLow);
  317. /* Second 16-bit identifier and Second 16-bit mask */
  318. /* Or Third 16-bit identifier and Fourth 16-bit identifier */
  319. hcan->Instance->sFilterRegister[sFilterConfig->FilterNumber].FR2 =
  320. ((0x0000FFFF & (uint32_t)sFilterConfig->FilterMaskIdHigh) << 16) |
  321. (0x0000FFFF & (uint32_t)sFilterConfig->FilterIdHigh);
  322. }
  323. if (sFilterConfig->FilterScale == CAN_FILTERSCALE_32BIT)
  324. {
  325. /* 32-bit scale for the filter */
  326. SET_BIT(hcan->Instance->FS1R, filternbrbitpos);
  327. /* 32-bit identifier or First 32-bit identifier */
  328. hcan->Instance->sFilterRegister[sFilterConfig->FilterNumber].FR1 =
  329. ((0x0000FFFF & (uint32_t)sFilterConfig->FilterIdHigh) << 16) |
  330. (0x0000FFFF & (uint32_t)sFilterConfig->FilterIdLow);
  331. /* 32-bit mask or Second 32-bit identifier */
  332. hcan->Instance->sFilterRegister[sFilterConfig->FilterNumber].FR2 =
  333. ((0x0000FFFF & (uint32_t)sFilterConfig->FilterMaskIdHigh) << 16) |
  334. (0x0000FFFF & (uint32_t)sFilterConfig->FilterMaskIdLow);
  335. }
  336. /* Filter Mode */
  337. if (sFilterConfig->FilterMode == CAN_FILTERMODE_IDMASK)
  338. {
  339. /*Id/Mask mode for the filter*/
  340. CLEAR_BIT(hcan->Instance->FM1R, filternbrbitpos);
  341. }
  342. else /* CAN_FilterInitStruct->CAN_FilterMode == CAN_FilterMode_IdList */
  343. {
  344. /*Identifier list mode for the filter*/
  345. SET_BIT(hcan->Instance->FM1R, filternbrbitpos);
  346. }
  347. /* Filter FIFO assignment */
  348. if (sFilterConfig->FilterFIFOAssignment == CAN_FILTER_FIFO0)
  349. {
  350. /* FIFO 0 assignation for the filter */
  351. CLEAR_BIT(hcan->Instance->FFA1R, filternbrbitpos);
  352. }
  353. else
  354. {
  355. /* FIFO 1 assignation for the filter */
  356. SET_BIT(hcan->Instance->FFA1R, filternbrbitpos);
  357. }
  358. /* Filter activation */
  359. if (sFilterConfig->FilterActivation == ENABLE)
  360. {
  361. SET_BIT(hcan->Instance->FA1R, filternbrbitpos);
  362. }
  363. /* Leave the initialisation mode for the filter */
  364. CLEAR_BIT(hcan->Instance->FMR, ((uint32_t)CAN_FMR_FINIT));
  365. /* Return function status */
  366. return HAL_OK;
  367. }
  368. /**
  369. * @brief Deinitializes the CANx peripheral registers to their default reset values.
  370. * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
  371. * the configuration information for the specified CAN.
  372. * @retval HAL status
  373. */
  374. HAL_StatusTypeDef HAL_CAN_DeInit(CAN_HandleTypeDef* hcan)
  375. {
  376. /* Check CAN handle */
  377. if(hcan == NULL)
  378. {
  379. return HAL_ERROR;
  380. }
  381. /* Check the parameters */
  382. assert_param(IS_CAN_ALL_INSTANCE(hcan->Instance));
  383. /* Change CAN state */
  384. hcan->State = HAL_CAN_STATE_BUSY;
  385. /* DeInit the low level hardware */
  386. HAL_CAN_MspDeInit(hcan);
  387. /* Change CAN state */
  388. hcan->State = HAL_CAN_STATE_RESET;
  389. /* Release Lock */
  390. __HAL_UNLOCK(hcan);
  391. /* Return function status */
  392. return HAL_OK;
  393. }
  394. /**
  395. * @brief Initializes the CAN MSP.
  396. * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
  397. * the configuration information for the specified CAN.
  398. * @retval None
  399. */
  400. __weak void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan)
  401. {
  402. /* Prevent unused argument(s) compilation warning */
  403. UNUSED(hcan);
  404. /* NOTE : This function Should not be modified, when the callback is needed,
  405. the HAL_CAN_MspInit can be implemented in the user file
  406. */
  407. }
  408. /**
  409. * @brief DeInitializes the CAN MSP.
  410. * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
  411. * the configuration information for the specified CAN.
  412. * @retval None
  413. */
  414. __weak void HAL_CAN_MspDeInit(CAN_HandleTypeDef* hcan)
  415. {
  416. /* Prevent unused argument(s) compilation warning */
  417. UNUSED(hcan);
  418. /* NOTE : This function Should not be modified, when the callback is needed,
  419. the HAL_CAN_MspDeInit can be implemented in the user file
  420. */
  421. }
  422. /**
  423. * @}
  424. */
  425. /** @defgroup CAN_Exported_Functions_Group2 Input and Output operation functions
  426. * @brief I/O operation functions
  427. *
  428. @verbatim
  429. ==============================================================================
  430. ##### IO operation functions #####
  431. ==============================================================================
  432. [..] This section provides functions allowing to:
  433. (+) Transmit a CAN frame message.
  434. (+) Receive a CAN frame message.
  435. (+) Enter CAN peripheral in sleep mode.
  436. (+) Wake up the CAN peripheral from sleep mode.
  437. @endverbatim
  438. * @{
  439. */
  440. /**
  441. * @brief Initiates and transmits a CAN frame message.
  442. * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
  443. * the configuration information for the specified CAN.
  444. * @param Timeout: Specify Timeout value
  445. * @retval HAL status
  446. */
  447. HAL_StatusTypeDef HAL_CAN_Transmit(CAN_HandleTypeDef* hcan, uint32_t Timeout)
  448. {
  449. uint32_t transmitmailbox = CAN_TXSTATUS_NOMAILBOX;
  450. uint32_t tickstart = 0;
  451. /* Check the parameters */
  452. assert_param(IS_CAN_IDTYPE(hcan->pTxMsg->IDE));
  453. assert_param(IS_CAN_RTR(hcan->pTxMsg->RTR));
  454. assert_param(IS_CAN_DLC(hcan->pTxMsg->DLC));
  455. /* Process locked */
  456. __HAL_LOCK(hcan);
  457. if(hcan->State == HAL_CAN_STATE_BUSY_RX)
  458. {
  459. /* Change CAN state */
  460. hcan->State = HAL_CAN_STATE_BUSY_TX_RX;
  461. }
  462. else
  463. {
  464. /* Change CAN state */
  465. hcan->State = HAL_CAN_STATE_BUSY_TX;
  466. }
  467. /* Select one empty transmit mailbox */
  468. if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME0))
  469. {
  470. transmitmailbox = 0;
  471. }
  472. else if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME1))
  473. {
  474. transmitmailbox = 1;
  475. }
  476. else if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME2))
  477. {
  478. transmitmailbox = 2;
  479. }
  480. else
  481. {
  482. transmitmailbox = CAN_TXSTATUS_NOMAILBOX;
  483. }
  484. if (transmitmailbox != CAN_TXSTATUS_NOMAILBOX)
  485. {
  486. /* Set up the Id */
  487. hcan->Instance->sTxMailBox[transmitmailbox].TIR &= CAN_TI0R_TXRQ;
  488. if (hcan->pTxMsg->IDE == CAN_ID_STD)
  489. {
  490. assert_param(IS_CAN_STDID(hcan->pTxMsg->StdId));
  491. hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->StdId << CAN_TI0R_STID_BIT_POSITION) |
  492. hcan->pTxMsg->RTR);
  493. }
  494. else
  495. {
  496. assert_param(IS_CAN_EXTID(hcan->pTxMsg->ExtId));
  497. hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->ExtId << CAN_TI0R_EXID_BIT_POSITION) |
  498. hcan->pTxMsg->IDE |
  499. hcan->pTxMsg->RTR);
  500. }
  501. /* Set up the DLC */
  502. hcan->pTxMsg->DLC &= (uint8_t)0x0000000F;
  503. hcan->Instance->sTxMailBox[transmitmailbox].TDTR &= (uint32_t)0xFFFFFFF0;
  504. hcan->Instance->sTxMailBox[transmitmailbox].TDTR |= hcan->pTxMsg->DLC;
  505. /* Set up the data field */
  506. WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDLR, ((uint32_t)hcan->pTxMsg->Data[3] << CAN_TDL0R_DATA3_BIT_POSITION) |
  507. ((uint32_t)hcan->pTxMsg->Data[2] << CAN_TDL0R_DATA2_BIT_POSITION) |
  508. ((uint32_t)hcan->pTxMsg->Data[1] << CAN_TDL0R_DATA1_BIT_POSITION) |
  509. ((uint32_t)hcan->pTxMsg->Data[0] << CAN_TDL0R_DATA0_BIT_POSITION) );
  510. WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDHR, ((uint32_t)hcan->pTxMsg->Data[7] << CAN_TDL0R_DATA3_BIT_POSITION) |
  511. ((uint32_t)hcan->pTxMsg->Data[6] << CAN_TDL0R_DATA2_BIT_POSITION) |
  512. ((uint32_t)hcan->pTxMsg->Data[5] << CAN_TDL0R_DATA1_BIT_POSITION) |
  513. ((uint32_t)hcan->pTxMsg->Data[4] << CAN_TDL0R_DATA0_BIT_POSITION) );
  514. /* Request transmission */
  515. SET_BIT(hcan->Instance->sTxMailBox[transmitmailbox].TIR, CAN_TI0R_TXRQ);
  516. /* Get timeout */
  517. tickstart = HAL_GetTick();
  518. /* Check End of transmission flag */
  519. while(!(__HAL_CAN_TRANSMIT_STATUS(hcan, transmitmailbox)))
  520. {
  521. /* Check for the Timeout */
  522. if(Timeout != HAL_MAX_DELAY)
  523. {
  524. if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
  525. {
  526. hcan->State = HAL_CAN_STATE_TIMEOUT;
  527. /* Process unlocked */
  528. __HAL_UNLOCK(hcan);
  529. return HAL_TIMEOUT;
  530. }
  531. }
  532. }
  533. if(hcan->State == HAL_CAN_STATE_BUSY_TX_RX)
  534. {
  535. /* Change CAN state */
  536. hcan->State = HAL_CAN_STATE_BUSY_RX;
  537. /* Process unlocked */
  538. __HAL_UNLOCK(hcan);
  539. }
  540. else
  541. {
  542. /* Change CAN state */
  543. hcan->State = HAL_CAN_STATE_READY;
  544. }
  545. /* Process unlocked */
  546. __HAL_UNLOCK(hcan);
  547. /* Return function status */
  548. return HAL_OK;
  549. }
  550. else
  551. {
  552. /* Change CAN state */
  553. hcan->State = HAL_CAN_STATE_ERROR;
  554. /* Process unlocked */
  555. __HAL_UNLOCK(hcan);
  556. /* Return function status */
  557. return HAL_ERROR;
  558. }
  559. }
  560. /**
  561. * @brief Handles CAN interrupt request
  562. * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
  563. * the configuration information for the specified CAN.
  564. * @retval None
  565. */
  566. void HAL_CAN_IRQHandler(CAN_HandleTypeDef* hcan)
  567. {
  568. /* Check End of transmission flag */
  569. if(__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_TME))
  570. {
  571. if((__HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_0)) ||
  572. (__HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_1)) ||
  573. (__HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_2)))
  574. {
  575. /* Call transmit function */
  576. CAN_Transmit_IT(hcan);
  577. }
  578. }
  579. /* Check End of reception flag for FIFO0 */
  580. if((__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FMP0)) &&
  581. (__HAL_CAN_MSG_PENDING(hcan, CAN_FIFO0) != 0))
  582. {
  583. /* Call receive function */
  584. CAN_Receive_IT(hcan, CAN_FIFO0);
  585. }
  586. /* Check End of reception flag for FIFO1 */
  587. if((__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FMP1)) &&
  588. (__HAL_CAN_MSG_PENDING(hcan, CAN_FIFO1) != 0))
  589. {
  590. /* Call receive function */
  591. CAN_Receive_IT(hcan, CAN_FIFO1);
  592. }
  593. /* Check Error Warning Flag */
  594. if((__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_EWG)) &&
  595. (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_EWG)) &&
  596. (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR)))
  597. {
  598. /* Set CAN error code to EWG error */
  599. hcan->ErrorCode |= HAL_CAN_ERROR_EWG;
  600. /* No need for clear of Error Warning Flag as read-only */
  601. }
  602. /* Check Error Passive Flag */
  603. if((__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_EPV)) &&
  604. (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_EPV)) &&
  605. (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR)))
  606. {
  607. /* Set CAN error code to EPV error */
  608. hcan->ErrorCode |= HAL_CAN_ERROR_EPV;
  609. /* No need for clear of Error Passive Flag as read-only */
  610. }
  611. /* Check Bus-Off Flag */
  612. if((__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_BOF)) &&
  613. (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_BOF)) &&
  614. (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR)))
  615. {
  616. /* Set CAN error code to BOF error */
  617. hcan->ErrorCode |= HAL_CAN_ERROR_BOF;
  618. /* No need for clear of Bus-Off Flag as read-only */
  619. }
  620. /* Check Last error code Flag */
  621. if((!HAL_IS_BIT_CLR(hcan->Instance->ESR, CAN_ESR_LEC)) &&
  622. (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_LEC)) &&
  623. (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR)))
  624. {
  625. switch(hcan->Instance->ESR & CAN_ESR_LEC)
  626. {
  627. case(CAN_ESR_LEC_0):
  628. /* Set CAN error code to STF error */
  629. hcan->ErrorCode |= HAL_CAN_ERROR_STF;
  630. break;
  631. case(CAN_ESR_LEC_1):
  632. /* Set CAN error code to FOR error */
  633. hcan->ErrorCode |= HAL_CAN_ERROR_FOR;
  634. break;
  635. case(CAN_ESR_LEC_1 | CAN_ESR_LEC_0):
  636. /* Set CAN error code to ACK error */
  637. hcan->ErrorCode |= HAL_CAN_ERROR_ACK;
  638. break;
  639. case(CAN_ESR_LEC_2):
  640. /* Set CAN error code to BR error */
  641. hcan->ErrorCode |= HAL_CAN_ERROR_BR;
  642. break;
  643. case(CAN_ESR_LEC_2 | CAN_ESR_LEC_0):
  644. /* Set CAN error code to BD error */
  645. hcan->ErrorCode |= HAL_CAN_ERROR_BD;
  646. break;
  647. case(CAN_ESR_LEC_2 | CAN_ESR_LEC_1):
  648. /* Set CAN error code to CRC error */
  649. hcan->ErrorCode |= HAL_CAN_ERROR_CRC;
  650. break;
  651. default:
  652. break;
  653. }
  654. /* Clear Last error code Flag */
  655. CLEAR_BIT(hcan->Instance->ESR, CAN_ESR_LEC);
  656. }
  657. /* Call the Error call Back in case of Errors */
  658. if(hcan->ErrorCode != HAL_CAN_ERROR_NONE)
  659. {
  660. /* Clear ERRI Flag */
  661. hcan->Instance->MSR |= CAN_MSR_ERRI;
  662. /* Set the CAN state ready to be able to start again the process */
  663. hcan->State = HAL_CAN_STATE_READY;
  664. /* Call Error callback function */
  665. HAL_CAN_ErrorCallback(hcan);
  666. }
  667. }
  668. /**
  669. * @brief Transmission complete callback in non blocking mode
  670. * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
  671. * the configuration information for the specified CAN.
  672. * @retval None
  673. */
  674. __weak void HAL_CAN_TxCpltCallback(CAN_HandleTypeDef* hcan)
  675. {
  676. /* Prevent unused argument(s) compilation warning */
  677. UNUSED(hcan);
  678. /* NOTE : This function Should not be modified, when the callback is needed,
  679. the HAL_CAN_TxCpltCallback can be implemented in the user file
  680. */
  681. }
  682. /**
  683. * @brief Transmission complete callback in non blocking mode
  684. * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
  685. * the configuration information for the specified CAN.
  686. * @retval None
  687. */
  688. __weak void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* hcan)
  689. {
  690. /* Prevent unused argument(s) compilation warning */
  691. UNUSED(hcan);
  692. /* NOTE : This function Should not be modified, when the callback is needed,
  693. the HAL_CAN_RxCpltCallback can be implemented in the user file
  694. */
  695. }
  696. /**
  697. * @brief Error CAN callback.
  698. * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
  699. * the configuration information for the specified CAN.
  700. * @retval None
  701. */
  702. __weak void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan)
  703. {
  704. /* Prevent unused argument(s) compilation warning */
  705. UNUSED(hcan);
  706. /* NOTE : This function Should not be modified, when the callback is needed,
  707. the HAL_CAN_ErrorCallback can be implemented in the user file
  708. */
  709. }
  710. /**
  711. * @}
  712. */
  713. /** @defgroup CAN_Exported_Functions_Group3 Peripheral State and Error functions
  714. * @brief CAN Peripheral State functions
  715. *
  716. @verbatim
  717. ==============================================================================
  718. ##### Peripheral State and Error functions #####
  719. ==============================================================================
  720. [..]
  721. This subsection provides functions allowing to :
  722. (+) Check the CAN state.
  723. (+) Check CAN Errors detected during interrupt process
  724. @endverbatim
  725. * @{
  726. */
  727. /**
  728. * @brief return the CAN state
  729. * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
  730. * the configuration information for the specified CAN.
  731. * @retval HAL state
  732. */
  733. HAL_CAN_StateTypeDef HAL_CAN_GetState(CAN_HandleTypeDef* hcan)
  734. {
  735. /* Return CAN state */
  736. return hcan->State;
  737. }
  738. /**
  739. * @brief Return the CAN error code
  740. * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
  741. * the configuration information for the specified CAN.
  742. * @retval CAN Error Code
  743. */
  744. uint32_t HAL_CAN_GetError(CAN_HandleTypeDef *hcan)
  745. {
  746. return hcan->ErrorCode;
  747. }
  748. /**
  749. * @}
  750. */
  751. /**
  752. * @}
  753. */
  754. /** @defgroup CAN_Private_Functions CAN Private Functions
  755. * @{
  756. */
  757. /**
  758. * @brief Initiates and transmits a CAN frame message.
  759. * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
  760. * the configuration information for the specified CAN.
  761. * @retval HAL status
  762. */
  763. static HAL_StatusTypeDef CAN_Transmit_IT(CAN_HandleTypeDef* hcan)
  764. {
  765. /* Disable Transmit mailbox empty Interrupt */
  766. __HAL_CAN_DISABLE_IT(hcan, CAN_IT_TME);
  767. if(hcan->State == HAL_CAN_STATE_BUSY_TX)
  768. {
  769. /* Disable interrupts: */
  770. /* - Disable Error warning Interrupt */
  771. /* - Disable Error passive Interrupt */
  772. /* - Disable Bus-off Interrupt */
  773. /* - Disable Last error code Interrupt */
  774. /* - Disable Error Interrupt */
  775. __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EWG |
  776. CAN_IT_EPV |
  777. CAN_IT_BOF |
  778. CAN_IT_LEC |
  779. CAN_IT_ERR );
  780. }
  781. if(hcan->State == HAL_CAN_STATE_BUSY_TX_RX)
  782. {
  783. /* Change CAN state */
  784. hcan->State = HAL_CAN_STATE_BUSY_RX;
  785. }
  786. else
  787. {
  788. /* Change CAN state */
  789. hcan->State = HAL_CAN_STATE_READY;
  790. }
  791. /* Transmission complete callback */
  792. HAL_CAN_TxCpltCallback(hcan);
  793. return HAL_OK;
  794. }
  795. /**
  796. * @brief Receives a correct CAN frame.
  797. * @param hcan: Pointer to a CAN_HandleTypeDef structure that contains
  798. * the configuration information for the specified CAN.
  799. * @param FIFONumber: Specify the FIFO number
  800. * @retval HAL status
  801. * @retval None
  802. */
  803. static HAL_StatusTypeDef CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber)
  804. {
  805. /* Get the Id */
  806. hcan->pRxMsg->IDE = (uint8_t)0x04 & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
  807. if (hcan->pRxMsg->IDE == CAN_ID_STD)
  808. {
  809. hcan->pRxMsg->StdId = (uint32_t)0x000007FF & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 21);
  810. }
  811. else
  812. {
  813. hcan->pRxMsg->ExtId = (uint32_t)0x1FFFFFFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 3);
  814. }
  815. hcan->pRxMsg->RTR = (uint8_t)0x02 & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
  816. /* Get the DLC */
  817. hcan->pRxMsg->DLC = (uint8_t)0x0F & hcan->Instance->sFIFOMailBox[FIFONumber].RDTR;
  818. /* Get the FMI */
  819. hcan->pRxMsg->FMI = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDTR >> 8);
  820. /* Get the data field */
  821. hcan->pRxMsg->Data[0] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR;
  822. hcan->pRxMsg->Data[1] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 8);
  823. hcan->pRxMsg->Data[2] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 16);
  824. hcan->pRxMsg->Data[3] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 24);
  825. hcan->pRxMsg->Data[4] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR;
  826. hcan->pRxMsg->Data[5] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 8);
  827. hcan->pRxMsg->Data[6] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 16);
  828. hcan->pRxMsg->Data[7] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 24);
  829. /* Release the FIFO */
  830. /* Release FIFO0 */
  831. if (FIFONumber == CAN_FIFO0)
  832. {
  833. __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO0);
  834. /* Disable FIFO 0 message pending Interrupt */
  835. __HAL_CAN_DISABLE_IT(hcan, CAN_IT_FMP0);
  836. }
  837. /* Release FIFO1 */
  838. else /* FIFONumber == CAN_FIFO1 */
  839. {
  840. __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO1);
  841. /* Disable FIFO 1 message pending Interrupt */
  842. __HAL_CAN_DISABLE_IT(hcan, CAN_IT_FMP1);
  843. }
  844. if(hcan->State == HAL_CAN_STATE_BUSY_RX)
  845. {
  846. /* Disable interrupts: */
  847. /* - Disable Error warning Interrupt */
  848. /* - Disable Error passive Interrupt */
  849. /* - Disable Bus-off Interrupt */
  850. /* - Disable Last error code Interrupt */
  851. /* - Disable Error Interrupt */
  852. __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EWG |
  853. CAN_IT_EPV |
  854. CAN_IT_BOF |
  855. CAN_IT_LEC |
  856. CAN_IT_ERR );
  857. }
  858. if(hcan->State == HAL_CAN_STATE_BUSY_TX_RX)
  859. {
  860. /* Disable CAN state */
  861. hcan->State = HAL_CAN_STATE_BUSY_TX;
  862. }
  863. else
  864. {
  865. /* Change CAN state */
  866. hcan->State = HAL_CAN_STATE_READY;
  867. }
  868. /* Receive complete callback */
  869. HAL_CAN_RxCpltCallback(hcan);
  870. /* Return function status */
  871. return HAL_OK;
  872. }
  873. /**
  874. * @}
  875. */
  876. /**
  877. * @}
  878. */
  879. /**
  880. * @}
  881. */
  882. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/