You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

1405 lines
43 KiB

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