F1 and F3 HAL / LL libraries
[betaflight.git] / lib / main / STM32F3 / Drivers / STM32F3xx_HAL_Driver / Src / stm32f3xx_hal_can.c
blobac192d589b20290129906ed3f8c017ee2838bc21
1 /**
2 ******************************************************************************
3 * @file stm32f3xx_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
13 @verbatim
14 ==============================================================================
15 ##### How to use this driver #####
16 ==============================================================================
17 [..]
18 (#) Enable the CAN controller interface clock using __HAL_RCC_CAN1_CLK_ENABLE();
20 (#) CAN pins configuration
21 (++) Enable the clock for the CAN GPIOs using the following function:
22 __HAL_RCC_GPIOx_CLK_ENABLE();
23 (++) Connect and configure the involved CAN pins to AF9 using the
24 following function HAL_GPIO_Init();
26 (#) Initialise and configure the CAN using HAL_CAN_Init() function.
28 (#) Transmit the desired CAN frame using HAL_CAN_Transmit() function.
30 (#) Or transmit the desired CAN frame using HAL_CAN_Transmit_IT() function.
32 (#) Receive a CAN frame using HAL_CAN_Receive() function.
34 (#) Or receive a CAN frame using HAL_CAN_Receive_IT() function.
36 *** Polling mode IO operation ***
37 =================================
38 [..]
39 (+) Start the CAN peripheral transmission and wait the end of this operation
40 using HAL_CAN_Transmit(), at this stage user can specify the value of timeout
41 according to his end application
42 (+) Start the CAN peripheral reception and wait the end of this operation
43 using HAL_CAN_Receive(), at this stage user can specify the value of timeout
44 according to his end application
46 *** Interrupt mode IO operation ***
47 ===================================
48 [..]
49 (+) Start the CAN peripheral transmission using HAL_CAN_Transmit_IT()
50 (+) Start the CAN peripheral reception using HAL_CAN_Receive_IT()
51 (+) Use HAL_CAN_IRQHandler() called under the used CAN Interrupt subroutine
52 (+) At CAN end of transmission HAL_CAN_TxCpltCallback() function is executed and user can
53 add his own code by customization of function pointer HAL_CAN_TxCpltCallback
54 (+) In case of CAN Error, HAL_CAN_ErrorCallback() function is executed and user can
55 add his own code by customization of function pointer HAL_CAN_ErrorCallback
57 *** CAN HAL driver macros list ***
58 =============================================
59 [..]
60 Below the list of most used macros in CAN HAL driver.
62 (+) __HAL_CAN_ENABLE_IT: Enable the specified CAN interrupts
63 (+) __HAL_CAN_DISABLE_IT: Disable the specified CAN interrupts
64 (+) __HAL_CAN_GET_IT_SOURCE: Check if the specified CAN interrupt source is enabled or disabled
65 (+) __HAL_CAN_CLEAR_FLAG: Clear the CAN's pending flags
66 (+) __HAL_CAN_GET_FLAG: Get the selected CAN's flag status
68 [..]
69 (@) You can refer to the CAN HAL driver header file for more useful macros
71 @endverbatim
73 ******************************************************************************
74 * @attention
76 * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
78 * Redistribution and use in source and binary forms, with or without modification,
79 * are permitted provided that the following conditions are met:
80 * 1. Redistributions of source code must retain the above copyright notice,
81 * this list of conditions and the following disclaimer.
82 * 2. Redistributions in binary form must reproduce the above copyright notice,
83 * this list of conditions and the following disclaimer in the documentation
84 * and/or other materials provided with the distribution.
85 * 3. Neither the name of STMicroelectronics nor the names of its contributors
86 * may be used to endorse or promote products derived from this software
87 * without specific prior written permission.
89 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
90 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
91 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
92 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
93 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
94 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
95 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
96 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
97 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
98 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
100 ******************************************************************************
103 /* Includes ------------------------------------------------------------------*/
104 #include "stm32f3xx_hal.h"
106 /** @addtogroup STM32F3xx_HAL_Driver
107 * @{
110 /** @defgroup CAN CAN
111 * @brief CAN driver modules
112 * @{
115 #ifdef HAL_CAN_MODULE_ENABLED
117 #if defined(STM32F302xE) || defined(STM32F303xE) || defined(STM32F398xx) || \
118 defined(STM32F302xC) || defined(STM32F303xC) || defined(STM32F358xx) || \
119 defined(STM32F303x8) || defined(STM32F334x8) || defined(STM32F328xx) || \
120 defined(STM32F302x8) || \
121 defined(STM32F373xC) || defined(STM32F378xx)
123 /* Private typedef -----------------------------------------------------------*/
124 /* Private define ------------------------------------------------------------*/
125 /** @defgroup CAN_Private_Constants CAN Private Constants
126 * @{
128 #define CAN_TIMEOUT_VALUE 10U
130 * @}
132 /* Private macro -------------------------------------------------------------*/
133 /* Private variables ---------------------------------------------------------*/
134 /* Private function prototypes -----------------------------------------------*/
135 /** @defgroup CAN_Private_Functions CAN Private Functions
136 * @{
138 static HAL_StatusTypeDef CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber);
139 static HAL_StatusTypeDef CAN_Transmit_IT(CAN_HandleTypeDef* hcan);
141 * @}
144 /* Exported functions ---------------------------------------------------------*/
146 /** @defgroup CAN_Exported_Functions CAN Exported Functions
147 * @{
150 /** @defgroup CAN_Exported_Functions_Group1 Initialization and de-initialization functions
151 * @brief Initialization and Configuration functions
153 @verbatim
154 ==============================================================================
155 ##### Initialization and de-initialization functions #####
156 ==============================================================================
157 [..] This section provides functions allowing to:
158 (+) Initialize and configure the CAN.
159 (+) De-initialize the CAN.
161 @endverbatim
162 * @{
166 * @brief Initializes the CAN peripheral according to the specified
167 * parameters in the CAN_InitStruct.
168 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
169 * the configuration information for the specified CAN.
170 * @retval HAL status
172 HAL_StatusTypeDef HAL_CAN_Init(CAN_HandleTypeDef* hcan)
174 uint32_t status = CAN_INITSTATUS_FAILED; /* Default init status */
175 uint32_t tickstart = 0U;
177 /* Check CAN handle */
178 if(hcan == NULL)
180 return HAL_ERROR;
183 /* Check the parameters */
184 assert_param(IS_CAN_ALL_INSTANCE(hcan->Instance));
185 assert_param(IS_FUNCTIONAL_STATE(hcan->Init.TTCM));
186 assert_param(IS_FUNCTIONAL_STATE(hcan->Init.ABOM));
187 assert_param(IS_FUNCTIONAL_STATE(hcan->Init.AWUM));
188 assert_param(IS_FUNCTIONAL_STATE(hcan->Init.NART));
189 assert_param(IS_FUNCTIONAL_STATE(hcan->Init.RFLM));
190 assert_param(IS_FUNCTIONAL_STATE(hcan->Init.TXFP));
191 assert_param(IS_CAN_MODE(hcan->Init.Mode));
192 assert_param(IS_CAN_SJW(hcan->Init.SJW));
193 assert_param(IS_CAN_BS1(hcan->Init.BS1));
194 assert_param(IS_CAN_BS2(hcan->Init.BS2));
195 assert_param(IS_CAN_PRESCALER(hcan->Init.Prescaler));
197 if(hcan->State == HAL_CAN_STATE_RESET)
199 /* Allocate lock resource and initialize it */
200 hcan->Lock = HAL_UNLOCKED;
201 /* Init the low level hardware */
202 HAL_CAN_MspInit(hcan);
205 /* Initialize the CAN state*/
206 hcan->State = HAL_CAN_STATE_BUSY;
208 /* Exit from sleep mode */
209 CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_SLEEP);
211 /* Request initialisation */
212 SET_BIT(hcan->Instance->MCR, CAN_MCR_INRQ);
214 /* Get tick */
215 tickstart = HAL_GetTick();
217 /* Wait the acknowledge */
218 while(HAL_IS_BIT_CLR(hcan->Instance->MSR, CAN_MSR_INAK))
220 if((HAL_GetTick()-tickstart) > CAN_TIMEOUT_VALUE)
222 hcan->State= HAL_CAN_STATE_TIMEOUT;
223 /* Process unlocked */
224 __HAL_UNLOCK(hcan);
225 return HAL_TIMEOUT;
229 /* Check acknowledge */
230 if (HAL_IS_BIT_SET(hcan->Instance->MSR, CAN_MSR_INAK))
232 /* Set the time triggered communication mode */
233 if (hcan->Init.TTCM == ENABLE)
235 SET_BIT(hcan->Instance->MCR, CAN_MCR_TTCM);
237 else
239 CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_TTCM);
242 /* Set the automatic bus-off management */
243 if (hcan->Init.ABOM == ENABLE)
245 SET_BIT(hcan->Instance->MCR, CAN_MCR_ABOM);
247 else
249 CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_ABOM);
252 /* Set the automatic wake-up mode */
253 if (hcan->Init.AWUM == ENABLE)
255 SET_BIT(hcan->Instance->MCR, CAN_MCR_AWUM);
257 else
259 CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_AWUM);
262 /* Set the no automatic retransmission */
263 if (hcan->Init.NART == ENABLE)
265 SET_BIT(hcan->Instance->MCR, CAN_MCR_NART);
267 else
269 CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_NART);
272 /* Set the receive FIFO locked mode */
273 if (hcan->Init.RFLM == ENABLE)
275 SET_BIT(hcan->Instance->MCR, CAN_MCR_RFLM);
277 else
279 CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_RFLM);
282 /* Set the transmit FIFO priority */
283 if (hcan->Init.TXFP == ENABLE)
285 SET_BIT(hcan->Instance->MCR, CAN_MCR_TXFP);
287 else
289 CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_TXFP);
292 /* Set the bit timing register */
293 WRITE_REG(hcan->Instance->BTR, (uint32_t)(hcan->Init.Mode |
294 hcan->Init.SJW |
295 hcan->Init.BS1 |
296 hcan->Init.BS2 |
297 (hcan->Init.Prescaler - 1U) ));
299 /* Request leave initialisation */
300 CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_INRQ);
302 /* Get tick */
303 tickstart = HAL_GetTick();
305 /* Wait the acknowledge */
306 while(HAL_IS_BIT_SET(hcan->Instance->MSR, CAN_MSR_INAK))
308 if((HAL_GetTick()-tickstart) > CAN_TIMEOUT_VALUE)
310 hcan->State= HAL_CAN_STATE_TIMEOUT;
312 /* Process unlocked */
313 __HAL_UNLOCK(hcan);
315 return HAL_TIMEOUT;
319 /* Check acknowledged */
320 if(HAL_IS_BIT_CLR(hcan->Instance->MSR, CAN_MSR_INAK))
322 status = CAN_INITSTATUS_SUCCESS;
326 if(status == CAN_INITSTATUS_SUCCESS)
328 /* Set CAN error code to none */
329 hcan->ErrorCode = HAL_CAN_ERROR_NONE;
331 /* Initialize the CAN state */
332 hcan->State = HAL_CAN_STATE_READY;
334 /* Return function status */
335 return HAL_OK;
337 else
339 /* Initialize the CAN state */
340 hcan->State = HAL_CAN_STATE_ERROR;
342 /* Return function status */
343 return HAL_ERROR;
348 * @brief Configures the CAN reception filter according to the specified
349 * parameters in the CAN_FilterInitStruct.
350 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
351 * the configuration information for the specified CAN.
352 * @param sFilterConfig pointer to a CAN_FilterConfTypeDef structure that
353 * contains the filter configuration information.
354 * @retval None
356 HAL_StatusTypeDef HAL_CAN_ConfigFilter(CAN_HandleTypeDef* hcan, CAN_FilterConfTypeDef* sFilterConfig)
358 uint32_t filternbrbitpos = 0U;
360 /* Check the parameters */
361 assert_param(IS_CAN_FILTER_NUMBER(sFilterConfig->FilterNumber));
362 assert_param(IS_CAN_FILTER_MODE(sFilterConfig->FilterMode));
363 assert_param(IS_CAN_FILTER_SCALE(sFilterConfig->FilterScale));
364 assert_param(IS_CAN_FILTER_FIFO(sFilterConfig->FilterFIFOAssignment));
365 assert_param(IS_FUNCTIONAL_STATE(sFilterConfig->FilterActivation));
367 filternbrbitpos = (1U) << sFilterConfig->FilterNumber;
369 /* Initialisation mode for the filter */
370 SET_BIT(hcan->Instance->FMR, CAN_FMR_FINIT);
372 /* Filter Deactivation */
373 CLEAR_BIT(hcan->Instance->FA1R, filternbrbitpos);
375 /* Filter Scale */
376 if (sFilterConfig->FilterScale == CAN_FILTERSCALE_16BIT)
378 /* 16-bit scale for the filter */
379 CLEAR_BIT(hcan->Instance->FS1R, filternbrbitpos);
381 /* First 16-bit identifier and First 16-bit mask */
382 /* Or First 16-bit identifier and Second 16-bit identifier */
383 hcan->Instance->sFilterRegister[sFilterConfig->FilterNumber].FR1 =
384 ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdLow) << 16U) |
385 (0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdLow);
387 /* Second 16-bit identifier and Second 16-bit mask */
388 /* Or Third 16-bit identifier and Fourth 16-bit identifier */
389 hcan->Instance->sFilterRegister[sFilterConfig->FilterNumber].FR2 =
390 ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdHigh) << 16U) |
391 (0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdHigh);
394 if (sFilterConfig->FilterScale == CAN_FILTERSCALE_32BIT)
396 /* 32-bit scale for the filter */
397 SET_BIT(hcan->Instance->FS1R, filternbrbitpos);
399 /* 32-bit identifier or First 32-bit identifier */
400 hcan->Instance->sFilterRegister[sFilterConfig->FilterNumber].FR1 =
401 ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdHigh) << 16U) |
402 (0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdLow);
404 /* 32-bit mask or Second 32-bit identifier */
405 hcan->Instance->sFilterRegister[sFilterConfig->FilterNumber].FR2 =
406 ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdHigh) << 16U) |
407 (0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdLow);
410 /* Filter Mode */
411 if (sFilterConfig->FilterMode == CAN_FILTERMODE_IDMASK)
413 /*Id/Mask mode for the filter*/
414 CLEAR_BIT(hcan->Instance->FM1R, filternbrbitpos);
416 else /* CAN_FilterInitStruct->CAN_FilterMode == CAN_FilterMode_IdList */
418 /*Identifier list mode for the filter*/
419 SET_BIT(hcan->Instance->FM1R, filternbrbitpos);
422 /* Filter FIFO assignment */
423 if (sFilterConfig->FilterFIFOAssignment == CAN_FILTER_FIFO0)
425 /* FIFO 0 assignation for the filter */
426 CLEAR_BIT(hcan->Instance->FFA1R, filternbrbitpos);
428 else
430 /* FIFO 1 assignation for the filter */
431 SET_BIT(hcan->Instance->FFA1R, filternbrbitpos);
434 /* Filter activation */
435 if (sFilterConfig->FilterActivation == ENABLE)
437 SET_BIT(hcan->Instance->FA1R, filternbrbitpos);
440 /* Leave the initialisation mode for the filter */
441 CLEAR_BIT(hcan->Instance->FMR, ((uint32_t)CAN_FMR_FINIT));
443 /* Return function status */
444 return HAL_OK;
448 * @brief Deinitializes the CANx peripheral registers to their default reset values.
449 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
450 * the configuration information for the specified CAN.
451 * @retval HAL status
453 HAL_StatusTypeDef HAL_CAN_DeInit(CAN_HandleTypeDef* hcan)
455 /* Check CAN handle */
456 if(hcan == NULL)
458 return HAL_ERROR;
461 /* Check the parameters */
462 assert_param(IS_CAN_ALL_INSTANCE(hcan->Instance));
464 /* Change CAN state */
465 hcan->State = HAL_CAN_STATE_BUSY;
467 /* DeInit the low level hardware */
468 HAL_CAN_MspDeInit(hcan);
470 /* Change CAN state */
471 hcan->State = HAL_CAN_STATE_RESET;
473 /* Release Lock */
474 __HAL_UNLOCK(hcan);
476 /* Return function status */
477 return HAL_OK;
481 * @brief Initializes the CAN MSP.
482 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
483 * the configuration information for the specified CAN.
484 * @retval None
486 __weak void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan)
488 /* Prevent unused argument(s) compilation warning */
489 UNUSED(hcan);
491 /* NOTE : This function Should not be modified, when the callback is needed,
492 the HAL_CAN_MspInit could be implemented in the user file
497 * @brief DeInitializes the CAN MSP.
498 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
499 * the configuration information for the specified CAN.
500 * @retval None
502 __weak void HAL_CAN_MspDeInit(CAN_HandleTypeDef* hcan)
504 /* Prevent unused argument(s) compilation warning */
505 UNUSED(hcan);
507 /* NOTE : This function Should not be modified, when the callback is needed,
508 the HAL_CAN_MspDeInit could be implemented in the user file
513 * @}
516 /** @defgroup CAN_Exported_Functions_Group2 Input and Output operation functions
517 * @brief IO operation functions
519 @verbatim
520 ==============================================================================
521 ##### IO operation functions #####
522 ==============================================================================
523 [..] This section provides functions allowing to:
524 (+) Transmit a CAN frame message.
525 (+) Receive a CAN frame message.
526 (+) Enter CAN peripheral in sleep mode.
527 (+) Wake up the CAN peripheral from sleep mode.
529 @endverbatim
530 * @{
534 * @brief Initiates and transmits a CAN frame message.
535 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
536 * the configuration information for the specified CAN.
537 * @param Timeout Timeout duration.
538 * @retval HAL status
540 HAL_StatusTypeDef HAL_CAN_Transmit(CAN_HandleTypeDef* hcan, uint32_t Timeout)
542 uint32_t transmitmailbox = CAN_TXSTATUS_NOMAILBOX;
543 uint32_t tickstart = 0U;
545 /* Check the parameters */
546 assert_param(IS_CAN_IDTYPE(hcan->pTxMsg->IDE));
547 assert_param(IS_CAN_RTR(hcan->pTxMsg->RTR));
548 assert_param(IS_CAN_DLC(hcan->pTxMsg->DLC));
550 if(((hcan->Instance->TSR&CAN_TSR_TME0) == CAN_TSR_TME0) || \
551 ((hcan->Instance->TSR&CAN_TSR_TME1) == CAN_TSR_TME1) || \
552 ((hcan->Instance->TSR&CAN_TSR_TME2) == CAN_TSR_TME2))
554 /* Process locked */
555 __HAL_LOCK(hcan);
557 /* Change CAN state */
558 switch(hcan->State)
560 case(HAL_CAN_STATE_BUSY_RX0):
561 hcan->State = HAL_CAN_STATE_BUSY_TX_RX0;
562 break;
563 case(HAL_CAN_STATE_BUSY_RX1):
564 hcan->State = HAL_CAN_STATE_BUSY_TX_RX1;
565 break;
566 case(HAL_CAN_STATE_BUSY_RX0_RX1):
567 hcan->State = HAL_CAN_STATE_BUSY_TX_RX0_RX1;
568 break;
569 default: /* HAL_CAN_STATE_READY */
570 hcan->State = HAL_CAN_STATE_BUSY_TX;
571 break;
574 /* Select one empty transmit mailbox */
575 if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME0))
577 transmitmailbox = CAN_TXMAILBOX_0;
579 else if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME1))
581 transmitmailbox = CAN_TXMAILBOX_1;
583 else
585 transmitmailbox = CAN_TXMAILBOX_2;
588 /* Set up the Id */
589 hcan->Instance->sTxMailBox[transmitmailbox].TIR &= CAN_TI0R_TXRQ;
590 if (hcan->pTxMsg->IDE == CAN_ID_STD)
592 assert_param(IS_CAN_STDID(hcan->pTxMsg->StdId));
593 hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->StdId << CAN_TI0R_STID_Pos) | \
594 hcan->pTxMsg->RTR);
596 else
598 assert_param(IS_CAN_EXTID(hcan->pTxMsg->ExtId));
599 hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->ExtId << CAN_TI0R_EXID_Pos) | \
600 hcan->pTxMsg->IDE | \
601 hcan->pTxMsg->RTR);
604 /* Set up the DLC */
605 hcan->pTxMsg->DLC &= (uint8_t)0x0000000FU;
606 hcan->Instance->sTxMailBox[transmitmailbox].TDTR &= 0xFFFFFFF0U;
607 hcan->Instance->sTxMailBox[transmitmailbox].TDTR |= hcan->pTxMsg->DLC;
609 /* Set up the data field */
610 WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDLR, ((uint32_t)hcan->pTxMsg->Data[3] << CAN_TDL0R_DATA3_Pos) |
611 ((uint32_t)hcan->pTxMsg->Data[2] << CAN_TDL0R_DATA2_Pos) |
612 ((uint32_t)hcan->pTxMsg->Data[1] << CAN_TDL0R_DATA1_Pos) |
613 ((uint32_t)hcan->pTxMsg->Data[0] << CAN_TDL0R_DATA0_Pos));
614 WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDHR, ((uint32_t)hcan->pTxMsg->Data[7] << CAN_TDL0R_DATA3_Pos) |
615 ((uint32_t)hcan->pTxMsg->Data[6] << CAN_TDL0R_DATA2_Pos) |
616 ((uint32_t)hcan->pTxMsg->Data[5] << CAN_TDL0R_DATA1_Pos) |
617 ((uint32_t)hcan->pTxMsg->Data[4] << CAN_TDL0R_DATA0_Pos));
619 /* Request transmission */
620 SET_BIT(hcan->Instance->sTxMailBox[transmitmailbox].TIR, CAN_TI0R_TXRQ);
622 /* Get tick */
623 tickstart = HAL_GetTick();
625 /* Check End of transmission flag */
626 while(!(__HAL_CAN_TRANSMIT_STATUS(hcan, transmitmailbox)))
628 /* Check for the Timeout */
629 if(Timeout != HAL_MAX_DELAY)
631 if((Timeout == 0U) || ((HAL_GetTick()-tickstart) > Timeout))
633 hcan->State = HAL_CAN_STATE_TIMEOUT;
635 /* Cancel transmission */
636 __HAL_CAN_CANCEL_TRANSMIT(hcan, transmitmailbox);
638 /* Process unlocked */
639 __HAL_UNLOCK(hcan);
640 return HAL_TIMEOUT;
645 /* Change CAN state */
646 switch(hcan->State)
648 case(HAL_CAN_STATE_BUSY_TX_RX0):
649 hcan->State = HAL_CAN_STATE_BUSY_RX0;
650 break;
651 case(HAL_CAN_STATE_BUSY_TX_RX1):
652 hcan->State = HAL_CAN_STATE_BUSY_RX1;
653 break;
654 case(HAL_CAN_STATE_BUSY_TX_RX0_RX1):
655 hcan->State = HAL_CAN_STATE_BUSY_RX0_RX1;
656 break;
657 default: /* HAL_CAN_STATE_BUSY_TX */
658 hcan->State = HAL_CAN_STATE_READY;
659 break;
662 /* Process unlocked */
663 __HAL_UNLOCK(hcan);
665 /* Return function status */
666 return HAL_OK;
668 else
670 /* Change CAN state */
671 hcan->State = HAL_CAN_STATE_ERROR;
673 /* Return function status */
674 return HAL_ERROR;
679 * @brief Initiates and transmits a CAN frame message.
680 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
681 * the configuration information for the specified CAN.
682 * @retval HAL status
684 HAL_StatusTypeDef HAL_CAN_Transmit_IT(CAN_HandleTypeDef* hcan)
686 uint32_t transmitmailbox = CAN_TXSTATUS_NOMAILBOX;
688 /* Check the parameters */
689 assert_param(IS_CAN_IDTYPE(hcan->pTxMsg->IDE));
690 assert_param(IS_CAN_RTR(hcan->pTxMsg->RTR));
691 assert_param(IS_CAN_DLC(hcan->pTxMsg->DLC));
693 if(((hcan->Instance->TSR&CAN_TSR_TME0) == CAN_TSR_TME0) || \
694 ((hcan->Instance->TSR&CAN_TSR_TME1) == CAN_TSR_TME1) || \
695 ((hcan->Instance->TSR&CAN_TSR_TME2) == CAN_TSR_TME2))
697 /* Process Locked */
698 __HAL_LOCK(hcan);
700 /* Select one empty transmit mailbox */
701 if(HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME0))
703 transmitmailbox = CAN_TXMAILBOX_0;
705 else if(HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME1))
707 transmitmailbox = CAN_TXMAILBOX_1;
709 else
711 transmitmailbox = CAN_TXMAILBOX_2;
714 /* Set up the Id */
715 hcan->Instance->sTxMailBox[transmitmailbox].TIR &= CAN_TI0R_TXRQ;
716 if(hcan->pTxMsg->IDE == CAN_ID_STD)
718 assert_param(IS_CAN_STDID(hcan->pTxMsg->StdId));
719 hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->StdId << CAN_TI0R_STID_Pos) | \
720 hcan->pTxMsg->RTR);
722 else
724 assert_param(IS_CAN_EXTID(hcan->pTxMsg->ExtId));
725 hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->ExtId << CAN_TI0R_EXID_Pos) | \
726 hcan->pTxMsg->IDE | \
727 hcan->pTxMsg->RTR);
730 /* Set up the DLC */
731 hcan->pTxMsg->DLC &= (uint8_t)0x0000000FU;
732 hcan->Instance->sTxMailBox[transmitmailbox].TDTR &= 0xFFFFFFF0U;
733 hcan->Instance->sTxMailBox[transmitmailbox].TDTR |= hcan->pTxMsg->DLC;
735 /* Set up the data field */
736 WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDLR, ((uint32_t)hcan->pTxMsg->Data[3] << CAN_TDL0R_DATA3_Pos) |
737 ((uint32_t)hcan->pTxMsg->Data[2] << CAN_TDL0R_DATA2_Pos) |
738 ((uint32_t)hcan->pTxMsg->Data[1] << CAN_TDL0R_DATA1_Pos) |
739 ((uint32_t)hcan->pTxMsg->Data[0] << CAN_TDL0R_DATA0_Pos));
740 WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDHR, ((uint32_t)hcan->pTxMsg->Data[7] << CAN_TDL0R_DATA3_Pos) |
741 ((uint32_t)hcan->pTxMsg->Data[6] << CAN_TDL0R_DATA2_Pos) |
742 ((uint32_t)hcan->pTxMsg->Data[5] << CAN_TDL0R_DATA1_Pos) |
743 ((uint32_t)hcan->pTxMsg->Data[4] << CAN_TDL0R_DATA0_Pos));
745 /* Change CAN state */
746 switch(hcan->State)
748 case(HAL_CAN_STATE_BUSY_RX0):
749 hcan->State = HAL_CAN_STATE_BUSY_TX_RX0;
750 break;
751 case(HAL_CAN_STATE_BUSY_RX1):
752 hcan->State = HAL_CAN_STATE_BUSY_TX_RX1;
753 break;
754 case(HAL_CAN_STATE_BUSY_RX0_RX1):
755 hcan->State = HAL_CAN_STATE_BUSY_TX_RX0_RX1;
756 break;
757 default: /* HAL_CAN_STATE_READY */
758 hcan->State = HAL_CAN_STATE_BUSY_TX;
759 break;
762 /* Set CAN error code to none */
763 hcan->ErrorCode = HAL_CAN_ERROR_NONE;
765 /* Process Unlocked */
766 __HAL_UNLOCK(hcan);
768 /* Request transmission */
769 hcan->Instance->sTxMailBox[transmitmailbox].TIR |= CAN_TI0R_TXRQ;
771 /* Enable interrupts: */
772 /* - Enable Error warning Interrupt */
773 /* - Enable Error passive Interrupt */
774 /* - Enable Bus-off Interrupt */
775 /* - Enable Last error code Interrupt */
776 /* - Enable Error Interrupt */
777 /* - Enable Transmit mailbox empty Interrupt */
778 __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EWG |
779 CAN_IT_EPV |
780 CAN_IT_BOF |
781 CAN_IT_LEC |
782 CAN_IT_ERR |
783 CAN_IT_TME );
785 else
787 /* Change CAN state */
788 hcan->State = HAL_CAN_STATE_ERROR;
790 /* Return function status */
791 return HAL_ERROR;
794 return HAL_OK;
798 * @brief Receives a correct CAN frame.
799 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
800 * the configuration information for the specified CAN.
801 * @param FIFONumber FIFO number.
802 * @param Timeout Timeout duration.
803 * @retval HAL status
805 HAL_StatusTypeDef HAL_CAN_Receive(CAN_HandleTypeDef* hcan, uint8_t FIFONumber, uint32_t Timeout)
807 uint32_t tickstart = 0U;
808 CanRxMsgTypeDef* pRxMsg = NULL;
810 /* Check the parameters */
811 assert_param(IS_CAN_FIFO(FIFONumber));
813 /* Process locked */
814 __HAL_LOCK(hcan);
816 /* Check if CAN state is not busy for RX FIFO0 */
817 if ((FIFONumber == CAN_FIFO0) && ((hcan->State == HAL_CAN_STATE_BUSY_RX0) || \
818 (hcan->State == HAL_CAN_STATE_BUSY_TX_RX0) || \
819 (hcan->State == HAL_CAN_STATE_BUSY_RX0_RX1) || \
820 (hcan->State == HAL_CAN_STATE_BUSY_TX_RX0_RX1)))
822 /* Process unlocked */
823 __HAL_UNLOCK(hcan);
825 return HAL_BUSY;
828 /* Check if CAN state is not busy for RX FIFO1 */
829 if ((FIFONumber == CAN_FIFO1) && ((hcan->State == HAL_CAN_STATE_BUSY_RX1) || \
830 (hcan->State == HAL_CAN_STATE_BUSY_TX_RX1) || \
831 (hcan->State == HAL_CAN_STATE_BUSY_RX0_RX1) || \
832 (hcan->State == HAL_CAN_STATE_BUSY_TX_RX0_RX1)))
834 /* Process unlocked */
835 __HAL_UNLOCK(hcan);
837 return HAL_BUSY;
840 /* Change CAN state */
841 if (FIFONumber == CAN_FIFO0)
843 switch(hcan->State)
845 case(HAL_CAN_STATE_BUSY_TX):
846 hcan->State = HAL_CAN_STATE_BUSY_TX_RX0;
847 break;
848 case(HAL_CAN_STATE_BUSY_RX1):
849 hcan->State = HAL_CAN_STATE_BUSY_RX0_RX1;
850 break;
851 case(HAL_CAN_STATE_BUSY_TX_RX1):
852 hcan->State = HAL_CAN_STATE_BUSY_TX_RX0_RX1;
853 break;
854 default: /* HAL_CAN_STATE_READY */
855 hcan->State = HAL_CAN_STATE_BUSY_RX0;
856 break;
859 else /* FIFONumber == CAN_FIFO1 */
861 switch(hcan->State)
863 case(HAL_CAN_STATE_BUSY_TX):
864 hcan->State = HAL_CAN_STATE_BUSY_TX_RX1;
865 break;
866 case(HAL_CAN_STATE_BUSY_RX0):
867 hcan->State = HAL_CAN_STATE_BUSY_RX0_RX1;
868 break;
869 case(HAL_CAN_STATE_BUSY_TX_RX0):
870 hcan->State = HAL_CAN_STATE_BUSY_TX_RX0_RX1;
871 break;
872 default: /* HAL_CAN_STATE_READY */
873 hcan->State = HAL_CAN_STATE_BUSY_RX1;
874 break;
878 /* Get tick */
879 tickstart = HAL_GetTick();
881 /* Check pending message */
882 while(__HAL_CAN_MSG_PENDING(hcan, FIFONumber) == 0U)
884 /* Check for the Timeout */
885 if(Timeout != HAL_MAX_DELAY)
887 if((Timeout == 0U) || ((HAL_GetTick()-tickstart) > Timeout))
889 hcan->State = HAL_CAN_STATE_TIMEOUT;
891 /* Process unlocked */
892 __HAL_UNLOCK(hcan);
894 return HAL_TIMEOUT;
899 /* Set RxMsg pointer */
900 if(FIFONumber == CAN_FIFO0)
902 pRxMsg = hcan->pRxMsg;
904 else /* FIFONumber == CAN_FIFO1 */
906 pRxMsg = hcan->pRx1Msg;
909 /* Get the Id */
910 pRxMsg->IDE = CAN_RI0R_IDE & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
911 if (pRxMsg->IDE == CAN_ID_STD)
913 pRxMsg->StdId = (CAN_RI0R_STID & hcan->Instance->sFIFOMailBox[FIFONumber].RIR) >> CAN_TI0R_STID_Pos;
915 else
917 pRxMsg->ExtId = (0xFFFFFFF8U & hcan->Instance->sFIFOMailBox[FIFONumber].RIR) >> CAN_RI0R_EXID_Pos;
919 pRxMsg->RTR = (CAN_RI0R_RTR & hcan->Instance->sFIFOMailBox[FIFONumber].RIR) >> CAN_RI0R_RTR_Pos;
920 /* Get the DLC */
921 pRxMsg->DLC = (CAN_RDT0R_DLC & hcan->Instance->sFIFOMailBox[FIFONumber].RDTR) >> CAN_RDT0R_DLC_Pos;
922 /* Get the FMI */
923 pRxMsg->FMI = (CAN_RDT0R_FMI & hcan->Instance->sFIFOMailBox[FIFONumber].RDTR) >> CAN_RDT0R_FMI_Pos;
924 /* Get the FIFONumber */
925 pRxMsg->FIFONumber = FIFONumber;
926 /* Get the data field */
927 pRxMsg->Data[0] = (CAN_RDL0R_DATA0 & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR) >> CAN_RDL0R_DATA0_Pos;
928 pRxMsg->Data[1] = (CAN_RDL0R_DATA1 & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR) >> CAN_RDL0R_DATA1_Pos;
929 pRxMsg->Data[2] = (CAN_RDL0R_DATA2 & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR) >> CAN_RDL0R_DATA2_Pos;
930 pRxMsg->Data[3] = (CAN_RDL0R_DATA3 & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR) >> CAN_RDL0R_DATA3_Pos;
931 pRxMsg->Data[4] = (CAN_RDH0R_DATA4 & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR) >> CAN_RDH0R_DATA4_Pos;
932 pRxMsg->Data[5] = (CAN_RDH0R_DATA5 & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR) >> CAN_RDH0R_DATA5_Pos;
933 pRxMsg->Data[6] = (CAN_RDH0R_DATA6 & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR) >> CAN_RDH0R_DATA6_Pos;
934 pRxMsg->Data[7] = (CAN_RDH0R_DATA7 & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR) >> CAN_RDH0R_DATA7_Pos;
936 /* Release the FIFO */
937 if(FIFONumber == CAN_FIFO0)
939 /* Release FIFO0 */
940 __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO0);
942 else /* FIFONumber == CAN_FIFO1 */
944 /* Release FIFO1 */
945 __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO1);
948 /* Change CAN state */
949 if (FIFONumber == CAN_FIFO0)
951 switch(hcan->State)
953 case(HAL_CAN_STATE_BUSY_TX_RX0):
954 hcan->State = HAL_CAN_STATE_BUSY_TX;
955 break;
956 case(HAL_CAN_STATE_BUSY_RX0_RX1):
957 hcan->State = HAL_CAN_STATE_BUSY_RX1;
958 break;
959 case(HAL_CAN_STATE_BUSY_TX_RX0_RX1):
960 hcan->State = HAL_CAN_STATE_BUSY_TX_RX1;
961 break;
962 default: /* HAL_CAN_STATE_BUSY_RX0 */
963 hcan->State = HAL_CAN_STATE_READY;
964 break;
967 else /* FIFONumber == CAN_FIFO1 */
969 switch(hcan->State)
971 case(HAL_CAN_STATE_BUSY_TX_RX1):
972 hcan->State = HAL_CAN_STATE_BUSY_TX;
973 break;
974 case(HAL_CAN_STATE_BUSY_RX0_RX1):
975 hcan->State = HAL_CAN_STATE_BUSY_RX0;
976 break;
977 case(HAL_CAN_STATE_BUSY_TX_RX0_RX1):
978 hcan->State = HAL_CAN_STATE_BUSY_TX_RX0;
979 break;
980 default: /* HAL_CAN_STATE_BUSY_RX1 */
981 hcan->State = HAL_CAN_STATE_READY;
982 break;
986 /* Process unlocked */
987 __HAL_UNLOCK(hcan);
989 /* Return function status */
990 return HAL_OK;
994 * @brief Receives a correct CAN frame.
995 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
996 * the configuration information for the specified CAN.
997 * @param FIFONumber FIFO number.
998 * @retval HAL status
1000 HAL_StatusTypeDef HAL_CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber)
1002 /* Check the parameters */
1003 assert_param(IS_CAN_FIFO(FIFONumber));
1005 /* Process locked */
1006 __HAL_LOCK(hcan);
1008 /* Check if CAN state is not busy for RX FIFO0 */
1009 if ((FIFONumber == CAN_FIFO0) && ((hcan->State == HAL_CAN_STATE_BUSY_RX0) || \
1010 (hcan->State == HAL_CAN_STATE_BUSY_TX_RX0) || \
1011 (hcan->State == HAL_CAN_STATE_BUSY_RX0_RX1) || \
1012 (hcan->State == HAL_CAN_STATE_BUSY_TX_RX0_RX1)))
1014 /* Process unlocked */
1015 __HAL_UNLOCK(hcan);
1017 return HAL_BUSY;
1020 /* Check if CAN state is not busy for RX FIFO1 */
1021 if ((FIFONumber == CAN_FIFO1) && ((hcan->State == HAL_CAN_STATE_BUSY_RX1) || \
1022 (hcan->State == HAL_CAN_STATE_BUSY_TX_RX1) || \
1023 (hcan->State == HAL_CAN_STATE_BUSY_RX0_RX1) || \
1024 (hcan->State == HAL_CAN_STATE_BUSY_TX_RX0_RX1)))
1026 /* Process unlocked */
1027 __HAL_UNLOCK(hcan);
1029 return HAL_BUSY;
1032 /* Change CAN state */
1033 if (FIFONumber == CAN_FIFO0)
1035 switch(hcan->State)
1037 case(HAL_CAN_STATE_BUSY_TX):
1038 hcan->State = HAL_CAN_STATE_BUSY_TX_RX0;
1039 break;
1040 case(HAL_CAN_STATE_BUSY_RX1):
1041 hcan->State = HAL_CAN_STATE_BUSY_RX0_RX1;
1042 break;
1043 case(HAL_CAN_STATE_BUSY_TX_RX1):
1044 hcan->State = HAL_CAN_STATE_BUSY_TX_RX0_RX1;
1045 break;
1046 default: /* HAL_CAN_STATE_READY */
1047 hcan->State = HAL_CAN_STATE_BUSY_RX0;
1048 break;
1051 else /* FIFONumber == CAN_FIFO1 */
1053 switch(hcan->State)
1055 case(HAL_CAN_STATE_BUSY_TX):
1056 hcan->State = HAL_CAN_STATE_BUSY_TX_RX1;
1057 break;
1058 case(HAL_CAN_STATE_BUSY_RX0):
1059 hcan->State = HAL_CAN_STATE_BUSY_RX0_RX1;
1060 break;
1061 case(HAL_CAN_STATE_BUSY_TX_RX0):
1062 hcan->State = HAL_CAN_STATE_BUSY_TX_RX0_RX1;
1063 break;
1064 default: /* HAL_CAN_STATE_READY */
1065 hcan->State = HAL_CAN_STATE_BUSY_RX1;
1066 break;
1070 /* Set CAN error code to none */
1071 hcan->ErrorCode = HAL_CAN_ERROR_NONE;
1073 /* Enable interrupts: */
1074 /* - Enable Error warning Interrupt */
1075 /* - Enable Error passive Interrupt */
1076 /* - Enable Bus-off Interrupt */
1077 /* - Enable Last error code Interrupt */
1078 /* - Enable Error Interrupt */
1079 __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EWG |
1080 CAN_IT_EPV |
1081 CAN_IT_BOF |
1082 CAN_IT_LEC |
1083 CAN_IT_ERR);
1085 /* Process unlocked */
1086 __HAL_UNLOCK(hcan);
1088 if(FIFONumber == CAN_FIFO0)
1090 /* Enable FIFO 0 overrun and message pending Interrupt */
1091 __HAL_CAN_ENABLE_IT(hcan, CAN_IT_FOV0 | CAN_IT_FMP0);
1093 else
1095 /* Enable FIFO 1 overrun and message pending Interrupt */
1096 __HAL_CAN_ENABLE_IT(hcan, CAN_IT_FOV1 | CAN_IT_FMP1);
1099 /* Return function status */
1100 return HAL_OK;
1104 * @brief Enters the Sleep (low power) mode.
1105 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
1106 * the configuration information for the specified CAN.
1107 * @retval HAL status.
1109 HAL_StatusTypeDef HAL_CAN_Sleep(CAN_HandleTypeDef* hcan)
1111 uint32_t tickstart = 0U;
1113 /* Process locked */
1114 __HAL_LOCK(hcan);
1116 /* Change CAN state */
1117 hcan->State = HAL_CAN_STATE_BUSY;
1119 /* Request Sleep mode */
1120 MODIFY_REG(hcan->Instance->MCR,
1121 CAN_MCR_INRQ ,
1122 CAN_MCR_SLEEP );
1124 /* Sleep mode status */
1125 if (HAL_IS_BIT_CLR(hcan->Instance->MSR, CAN_MSR_SLAK) ||
1126 HAL_IS_BIT_SET(hcan->Instance->MSR, CAN_MSR_INAK) )
1128 /* Process unlocked */
1129 __HAL_UNLOCK(hcan);
1131 /* Return function status */
1132 return HAL_ERROR;
1135 /* Get tick */
1136 tickstart = HAL_GetTick();
1138 /* Wait the acknowledge */
1139 while (HAL_IS_BIT_CLR(hcan->Instance->MSR, CAN_MSR_SLAK) ||
1140 HAL_IS_BIT_SET(hcan->Instance->MSR, CAN_MSR_INAK) )
1142 if((HAL_GetTick() - tickstart) > CAN_TIMEOUT_VALUE)
1144 hcan->State = HAL_CAN_STATE_TIMEOUT;
1145 /* Process unlocked */
1146 __HAL_UNLOCK(hcan);
1147 return HAL_TIMEOUT;
1151 /* Change CAN state */
1152 hcan->State = HAL_CAN_STATE_READY;
1154 /* Process unlocked */
1155 __HAL_UNLOCK(hcan);
1157 /* Return function status */
1158 return HAL_OK;
1162 * @brief Wakes up the CAN peripheral from sleep mode, after that the CAN peripheral
1163 * is in the normal mode.
1164 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
1165 * the configuration information for the specified CAN.
1166 * @retval HAL status.
1168 HAL_StatusTypeDef HAL_CAN_WakeUp(CAN_HandleTypeDef* hcan)
1170 uint32_t tickstart = 0U;
1172 /* Process locked */
1173 __HAL_LOCK(hcan);
1175 /* Change CAN state */
1176 hcan->State = HAL_CAN_STATE_BUSY;
1178 /* Wake up request */
1179 CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_SLEEP);
1181 /* Get tick */
1182 tickstart = HAL_GetTick();
1184 /* Sleep mode status */
1185 while(HAL_IS_BIT_SET(hcan->Instance->MSR, CAN_MSR_SLAK))
1187 if((HAL_GetTick() - tickstart) > CAN_TIMEOUT_VALUE)
1189 hcan->State= HAL_CAN_STATE_TIMEOUT;
1191 /* Process unlocked */
1192 __HAL_UNLOCK(hcan);
1194 return HAL_TIMEOUT;
1198 if(HAL_IS_BIT_SET(hcan->Instance->MSR, CAN_MSR_SLAK))
1200 /* Process unlocked */
1201 __HAL_UNLOCK(hcan);
1203 /* Return function status */
1204 return HAL_ERROR;
1207 /* Change CAN state */
1208 hcan->State = HAL_CAN_STATE_READY;
1210 /* Process unlocked */
1211 __HAL_UNLOCK(hcan);
1213 /* Return function status */
1214 return HAL_OK;
1218 * @brief Handles CAN interrupt request
1219 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
1220 * the configuration information for the specified CAN.
1221 * @retval None
1223 void HAL_CAN_IRQHandler(CAN_HandleTypeDef* hcan)
1225 uint32_t errorcode = HAL_CAN_ERROR_NONE;
1227 /* Check Overrun flag for FIFO0 */
1228 if((__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_FOV0)) &&
1229 (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FOV0)))
1231 /* Set CAN error code to FOV0 error */
1232 errorcode |= HAL_CAN_ERROR_FOV0;
1234 /* Clear FIFO0 Overrun Flag */
1235 __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FOV0);
1238 /* Check Overrun flag for FIFO1 */
1239 if((__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_FOV1)) &&
1240 (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FOV1)))
1242 /* Set CAN error code to FOV1 error */
1243 errorcode |= HAL_CAN_ERROR_FOV1;
1245 /* Clear FIFO1 Overrun Flag */
1246 __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FOV1);
1249 /* Check End of transmission flag */
1250 if(__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_TME))
1252 /* Check Transmit request completion status */
1253 if((__HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_0)) ||
1254 (__HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_1)) ||
1255 (__HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_2)))
1257 /* Check Transmit success */
1258 if((__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TXOK0)) ||
1259 (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TXOK1)) ||
1260 (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TXOK2)))
1262 /* Call transmit function */
1263 CAN_Transmit_IT(hcan);
1265 else /* Transmit failure */
1267 /* Set CAN error code to TXFAIL error */
1268 errorcode |= HAL_CAN_ERROR_TXFAIL;
1271 /* Clear transmission status flags (RQCPx and TXOKx) */
1272 SET_BIT(hcan->Instance->TSR, CAN_TSR_RQCP0 | CAN_TSR_RQCP1 | CAN_TSR_RQCP2 | \
1273 CAN_FLAG_TXOK0 | CAN_FLAG_TXOK1 | CAN_FLAG_TXOK2);
1277 /* Check End of reception flag for FIFO0 */
1278 if((__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FMP0)) &&
1279 (__HAL_CAN_MSG_PENDING(hcan, CAN_FIFO0) != 0U))
1281 /* Call receive function */
1282 CAN_Receive_IT(hcan, CAN_FIFO0);
1285 /* Check End of reception flag for FIFO1 */
1286 if((__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FMP1)) &&
1287 (__HAL_CAN_MSG_PENDING(hcan, CAN_FIFO1) != 0U))
1289 /* Call receive function */
1290 CAN_Receive_IT(hcan, CAN_FIFO1);
1293 /* Set error code in handle */
1294 hcan->ErrorCode |= errorcode;
1296 /* Check Error Warning Flag */
1297 if((__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_EWG)) &&
1298 (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_EWG)) &&
1299 (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR)))
1301 /* Set CAN error code to EWG error */
1302 hcan->ErrorCode |= HAL_CAN_ERROR_EWG;
1303 /* No need for clear of Error Warning Flag as read-only */
1306 /* Check Error Passive Flag */
1307 if((__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_EPV)) &&
1308 (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_EPV)) &&
1309 (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR)))
1311 /* Set CAN error code to EPV error */
1312 hcan->ErrorCode |= HAL_CAN_ERROR_EPV;
1313 /* No need for clear of Error Passive Flag as read-only */
1316 /* Check Bus-Off Flag */
1317 if((__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_BOF)) &&
1318 (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_BOF)) &&
1319 (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR)))
1321 /* Set CAN error code to BOF error */
1322 hcan->ErrorCode |= HAL_CAN_ERROR_BOF;
1323 /* No need for clear of Bus-Off Flag as read-only */
1326 /* Check Last error code Flag */
1327 if((!HAL_IS_BIT_CLR(hcan->Instance->ESR, CAN_ESR_LEC)) &&
1328 (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_LEC)) &&
1329 (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR)))
1331 switch(hcan->Instance->ESR & CAN_ESR_LEC)
1333 case(CAN_ESR_LEC_0):
1334 /* Set CAN error code to STF error */
1335 hcan->ErrorCode |= HAL_CAN_ERROR_STF;
1336 break;
1337 case(CAN_ESR_LEC_1):
1338 /* Set CAN error code to FOR error */
1339 hcan->ErrorCode |= HAL_CAN_ERROR_FOR;
1340 break;
1341 case(CAN_ESR_LEC_1 | CAN_ESR_LEC_0):
1342 /* Set CAN error code to ACK error */
1343 hcan->ErrorCode |= HAL_CAN_ERROR_ACK;
1344 break;
1345 case(CAN_ESR_LEC_2):
1346 /* Set CAN error code to BR error */
1347 hcan->ErrorCode |= HAL_CAN_ERROR_BR;
1348 break;
1349 case(CAN_ESR_LEC_2 | CAN_ESR_LEC_0):
1350 /* Set CAN error code to BD error */
1351 hcan->ErrorCode |= HAL_CAN_ERROR_BD;
1352 break;
1353 case(CAN_ESR_LEC_2 | CAN_ESR_LEC_1):
1354 /* Set CAN error code to CRC error */
1355 hcan->ErrorCode |= HAL_CAN_ERROR_CRC;
1356 break;
1357 default:
1358 break;
1361 /* Clear Last error code Flag */
1362 CLEAR_BIT(hcan->Instance->ESR, CAN_ESR_LEC);
1365 /* Call the Error call Back in case of Errors */
1366 if(hcan->ErrorCode != HAL_CAN_ERROR_NONE)
1368 /* Clear ERRI Flag */
1369 SET_BIT(hcan->Instance->MSR, CAN_MSR_ERRI);
1371 /* Set the CAN state ready to be able to start again the process */
1372 hcan->State = HAL_CAN_STATE_READY;
1374 /* Disable interrupts: */
1375 /* - Disable Error warning Interrupt */
1376 /* - Disable Error passive Interrupt */
1377 /* - Disable Bus-off Interrupt */
1378 /* - Disable Last error code Interrupt */
1379 /* - Disable Error Interrupt */
1380 /* - Disable FIFO 0 message pending Interrupt */
1381 /* - Disable FIFO 0 Overrun Interrupt */
1382 /* - Disable FIFO 1 message pending Interrupt */
1383 /* - Disable FIFO 1 Overrun Interrupt */
1384 /* - Disable Transmit mailbox empty Interrupt */
1385 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EWG |
1386 CAN_IT_EPV |
1387 CAN_IT_BOF |
1388 CAN_IT_LEC |
1389 CAN_IT_ERR |
1390 CAN_IT_FMP0|
1391 CAN_IT_FOV0|
1392 CAN_IT_FMP1|
1393 CAN_IT_FOV1|
1394 CAN_IT_TME );
1396 /* Call Error callback function */
1397 HAL_CAN_ErrorCallback(hcan);
1402 * @brief Transmission complete callback in non blocking mode
1403 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
1404 * the configuration information for the specified CAN.
1405 * @retval None
1407 __weak void HAL_CAN_TxCpltCallback(CAN_HandleTypeDef* hcan)
1409 /* Prevent unused argument(s) compilation warning */
1410 UNUSED(hcan);
1412 /* NOTE : This function Should not be modified, when the callback is needed,
1413 the HAL_CAN_TxCpltCallback could be implemented in the user file
1418 * @brief Transmission complete callback in non blocking mode
1419 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
1420 * the configuration information for the specified CAN.
1421 * @retval None
1423 __weak void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* hcan)
1425 /* Prevent unused argument(s) compilation warning */
1426 UNUSED(hcan);
1428 /* NOTE : This function Should not be modified, when the callback is needed,
1429 the HAL_CAN_RxCpltCallback could be implemented in the user file
1434 * @brief Error CAN callback.
1435 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
1436 * the configuration information for the specified CAN.
1437 * @retval None
1439 __weak void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan)
1441 /* Prevent unused argument(s) compilation warning */
1442 UNUSED(hcan);
1444 /* NOTE : This function Should not be modified, when the callback is needed,
1445 the HAL_CAN_ErrorCallback could be implemented in the user file
1450 * @}
1453 /** @defgroup CAN_Exported_Functions_Group3 Peripheral State and Error functions
1454 * @brief CAN Peripheral State functions
1456 @verbatim
1457 ==============================================================================
1458 ##### Peripheral State and Error functions #####
1459 ==============================================================================
1460 [..]
1461 This subsection provides functions allowing to :
1462 (+) Check the CAN state.
1463 (+) Check CAN Errors detected during interrupt process
1465 @endverbatim
1466 * @{
1470 * @brief return the CAN state
1471 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
1472 * the configuration information for the specified CAN.
1473 * @retval HAL state
1475 HAL_CAN_StateTypeDef HAL_CAN_GetState(CAN_HandleTypeDef* hcan)
1477 /* Return CAN state */
1478 return hcan->State;
1482 * @brief Return the CAN error code
1483 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
1484 * the configuration information for the specified CAN.
1485 * @retval CAN Error Code
1487 uint32_t HAL_CAN_GetError(CAN_HandleTypeDef *hcan)
1489 return hcan->ErrorCode;
1493 * @}
1497 * @}
1500 /** @addtogroup CAN_Private_Functions CAN Private Functions
1501 * @brief CAN Frame message Rx/Tx functions
1503 * @{
1507 * @brief Initiates and transmits a CAN frame message.
1508 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
1509 * the configuration information for the specified CAN.
1510 * @retval HAL status
1512 static HAL_StatusTypeDef CAN_Transmit_IT(CAN_HandleTypeDef* hcan)
1514 /* Disable Transmit mailbox empty Interrupt */
1515 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_TME);
1517 if(hcan->State == HAL_CAN_STATE_BUSY_TX)
1519 /* Disable interrupts: */
1520 /* - Disable Error warning Interrupt */
1521 /* - Disable Error passive Interrupt */
1522 /* - Disable Bus-off Interrupt */
1523 /* - Disable Last error code Interrupt */
1524 /* - Disable Error Interrupt */
1525 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EWG |
1526 CAN_IT_EPV |
1527 CAN_IT_BOF |
1528 CAN_IT_LEC |
1529 CAN_IT_ERR );
1532 /* Change CAN state */
1533 switch(hcan->State)
1535 case(HAL_CAN_STATE_BUSY_TX_RX0):
1536 hcan->State = HAL_CAN_STATE_BUSY_RX0;
1537 break;
1538 case(HAL_CAN_STATE_BUSY_TX_RX1):
1539 hcan->State = HAL_CAN_STATE_BUSY_RX1;
1540 break;
1541 case(HAL_CAN_STATE_BUSY_TX_RX0_RX1):
1542 hcan->State = HAL_CAN_STATE_BUSY_RX0_RX1;
1543 break;
1544 default: /* HAL_CAN_STATE_BUSY_TX */
1545 hcan->State = HAL_CAN_STATE_READY;
1546 break;
1549 /* Transmission complete callback */
1550 HAL_CAN_TxCpltCallback(hcan);
1552 return HAL_OK;
1556 * @brief Receives a correct CAN frame.
1557 * @param hcan Pointer to a CAN_HandleTypeDef structure that contains
1558 * the configuration information for the specified CAN.
1559 * @param FIFONumber Specify the FIFO number
1560 * @retval HAL status
1561 * @retval None
1563 static HAL_StatusTypeDef CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber)
1565 CanRxMsgTypeDef* pRxMsg = NULL;
1567 /* Set RxMsg pointer */
1568 if(FIFONumber == CAN_FIFO0)
1570 pRxMsg = hcan->pRxMsg;
1572 else /* FIFONumber == CAN_FIFO1 */
1574 pRxMsg = hcan->pRx1Msg;
1577 /* Get the Id */
1578 pRxMsg->IDE = CAN_RI0R_IDE & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
1579 if (pRxMsg->IDE == CAN_ID_STD)
1581 pRxMsg->StdId = (CAN_RI0R_STID & hcan->Instance->sFIFOMailBox[FIFONumber].RIR) >> CAN_TI0R_STID_Pos;
1583 else
1585 pRxMsg->ExtId = (0xFFFFFFF8U & hcan->Instance->sFIFOMailBox[FIFONumber].RIR) >> CAN_RI0R_EXID_Pos;
1587 pRxMsg->RTR = (CAN_RI0R_RTR & hcan->Instance->sFIFOMailBox[FIFONumber].RIR) >> CAN_RI0R_RTR_Pos;
1588 /* Get the DLC */
1589 pRxMsg->DLC = (CAN_RDT0R_DLC & hcan->Instance->sFIFOMailBox[FIFONumber].RDTR) >> CAN_RDT0R_DLC_Pos;
1590 /* Get the FMI */
1591 pRxMsg->FMI = (CAN_RDT0R_FMI & hcan->Instance->sFIFOMailBox[FIFONumber].RDTR) >> CAN_RDT0R_FMI_Pos;
1592 /* Get the FIFONumber */
1593 pRxMsg->FIFONumber = FIFONumber;
1594 /* Get the data field */
1595 pRxMsg->Data[0] = (CAN_RDL0R_DATA0 & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR) >> CAN_RDL0R_DATA0_Pos;
1596 pRxMsg->Data[1] = (CAN_RDL0R_DATA1 & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR) >> CAN_RDL0R_DATA1_Pos;
1597 pRxMsg->Data[2] = (CAN_RDL0R_DATA2 & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR) >> CAN_RDL0R_DATA2_Pos;
1598 pRxMsg->Data[3] = (CAN_RDL0R_DATA3 & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR) >> CAN_RDL0R_DATA3_Pos;
1599 pRxMsg->Data[4] = (CAN_RDH0R_DATA4 & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR) >> CAN_RDH0R_DATA4_Pos;
1600 pRxMsg->Data[5] = (CAN_RDH0R_DATA5 & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR) >> CAN_RDH0R_DATA5_Pos;
1601 pRxMsg->Data[6] = (CAN_RDH0R_DATA6 & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR) >> CAN_RDH0R_DATA6_Pos;
1602 pRxMsg->Data[7] = (CAN_RDH0R_DATA7 & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR) >> CAN_RDH0R_DATA7_Pos;
1604 /* Release the FIFO */
1605 /* Release FIFO0 */
1606 if (FIFONumber == CAN_FIFO0)
1608 __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO0);
1610 /* Disable FIFO 0 overrun and message pending Interrupt */
1611 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_FOV0 | CAN_IT_FMP0);
1613 /* Release FIFO1 */
1614 else /* FIFONumber == CAN_FIFO1 */
1616 __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO1);
1618 /* Disable FIFO 1 overrun and message pending Interrupt */
1619 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_FOV1 | CAN_IT_FMP1);
1622 if((hcan->State == HAL_CAN_STATE_BUSY_RX0) || (hcan->State == HAL_CAN_STATE_BUSY_RX1))
1624 /* Disable interrupts: */
1625 /* - Disable Error warning Interrupt */
1626 /* - Disable Error passive Interrupt */
1627 /* - Disable Bus-off Interrupt */
1628 /* - Disable Last error code Interrupt */
1629 /* - Disable Error Interrupt */
1630 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EWG |
1631 CAN_IT_EPV |
1632 CAN_IT_BOF |
1633 CAN_IT_LEC |
1634 CAN_IT_ERR );
1637 /* Change CAN state */
1638 if (FIFONumber == CAN_FIFO0)
1640 switch(hcan->State)
1642 case(HAL_CAN_STATE_BUSY_TX_RX0):
1643 hcan->State = HAL_CAN_STATE_BUSY_TX;
1644 break;
1645 case(HAL_CAN_STATE_BUSY_RX0_RX1):
1646 hcan->State = HAL_CAN_STATE_BUSY_RX1;
1647 break;
1648 case(HAL_CAN_STATE_BUSY_TX_RX0_RX1):
1649 hcan->State = HAL_CAN_STATE_BUSY_TX_RX1;
1650 break;
1651 default: /* HAL_CAN_STATE_BUSY_RX0 */
1652 hcan->State = HAL_CAN_STATE_READY;
1653 break;
1656 else /* FIFONumber == CAN_FIFO1 */
1658 switch(hcan->State)
1660 case(HAL_CAN_STATE_BUSY_TX_RX1):
1661 hcan->State = HAL_CAN_STATE_BUSY_TX;
1662 break;
1663 case(HAL_CAN_STATE_BUSY_RX0_RX1):
1664 hcan->State = HAL_CAN_STATE_BUSY_RX0;
1665 break;
1666 case(HAL_CAN_STATE_BUSY_TX_RX0_RX1):
1667 hcan->State = HAL_CAN_STATE_BUSY_TX_RX0;
1668 break;
1669 default: /* HAL_CAN_STATE_BUSY_RX1 */
1670 hcan->State = HAL_CAN_STATE_READY;
1671 break;
1675 /* Receive complete callback */
1676 HAL_CAN_RxCpltCallback(hcan);
1678 /* Return function status */
1679 return HAL_OK;
1683 * @}
1685 #endif /* STM32F302xE || STM32F303xE || STM32F398xx || */
1686 /* STM32F302xC || STM32F303xC || STM32F358xx || */
1687 /* STM32F303x8 || STM32F334x8 || STM32F328xx || */
1688 /* STM32F302x8 || */
1689 /* STM32F373xC || STM32F378xx */
1691 #endif /* HAL_CAN_MODULE_ENABLED */
1693 * @}
1697 * @}
1700 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/