Merge pull request #11198 from SteveCEvans/sce_rc2
[betaflight.git] / lib / main / STM32F4 / Drivers / STM32F4xx_HAL_Driver / Src / stm32f4xx_hal_can.c
blobd6aa756d16dfbe4cd527a15660f06b10a11a241c
1 /**
2 ******************************************************************************
3 * @file stm32f4xx_hal_can.c
4 * @author MCD Application Team
5 * @version V1.7.1
6 * @date 14-April-2017
7 * @brief This file provides firmware functions to manage the following
8 * functionalities of the Controller Area Network (CAN) peripheral:
9 * + Initialization and de-initialization functions
10 * + IO operation functions
11 * + Peripheral Control functions
12 * + Peripheral State and Error functions
14 @verbatim
15 ==============================================================================
16 ##### How to use this driver #####
17 ==============================================================================
18 [..]
19 (#) Enable the CAN controller interface clock using
20 __HAL_RCC_CAN1_CLK_ENABLE() for CAN1, __HAL_RCC_CAN2_CLK_ENABLE() for CAN2
21 and __HAL_RCC_CAN3_CLK_ENABLE() for CAN3
22 -@- In case you are using CAN2 only, you have to enable the CAN1 clock.
24 (#) CAN pins configuration
25 (++) Enable the clock for the CAN GPIOs using the following function:
26 __GPIOx_CLK_ENABLE()
27 (++) Connect and configure the involved CAN pins to AF9 using the
28 following function HAL_GPIO_Init()
30 (#) Initialize and configure the CAN using CAN_Init() function.
32 (#) Transmit the desired CAN frame using HAL_CAN_Transmit() function.
34 (#) Or transmit the desired CAN frame using HAL_CAN_Transmit_IT() function.
36 (#) Receive a CAN frame using HAL_CAN_Receive() function.
38 (#) Or receive a CAN frame using HAL_CAN_Receive_IT() function.
40 *** Polling mode IO operation ***
41 =================================
42 [..]
43 (+) Start the CAN peripheral transmission and wait the end of this operation
44 using HAL_CAN_Transmit(), at this stage user can specify the value of timeout
45 according to his end application
46 (+) Start the CAN peripheral reception and wait the end of this operation
47 using HAL_CAN_Receive(), at this stage user can specify the value of timeout
48 according to his end application
50 *** Interrupt mode IO operation ***
51 ===================================
52 [..]
53 (+) Start the CAN peripheral transmission using HAL_CAN_Transmit_IT()
54 (+) Start the CAN peripheral reception using HAL_CAN_Receive_IT()
55 (+) Use HAL_CAN_IRQHandler() called under the used CAN Interrupt subroutine
56 (+) At CAN end of transmission HAL_CAN_TxCpltCallback() function is executed and user can
57 add his own code by customization of function pointer HAL_CAN_TxCpltCallback
58 (+) In case of CAN Error, HAL_CAN_ErrorCallback() function is executed and user can
59 add his own code by customization of function pointer HAL_CAN_ErrorCallback
61 *** CAN HAL driver macros list ***
62 =============================================
63 [..]
64 Below the list of most used macros in CAN HAL driver.
66 (+) __HAL_CAN_ENABLE_IT: Enable the specified CAN interrupts
67 (+) __HAL_CAN_DISABLE_IT: Disable the specified CAN interrupts
68 (+) __HAL_CAN_GET_IT_SOURCE: Check if the specified CAN interrupt source is enabled or disabled
69 (+) __HAL_CAN_CLEAR_FLAG: Clear the CAN's pending flags
70 (+) __HAL_CAN_GET_FLAG: Get the selected CAN's flag status
72 [..]
73 (@) You can refer to the CAN HAL driver header file for more useful macros
75 @endverbatim
77 ******************************************************************************
78 * @attention
80 * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
82 * Redistribution and use in source and binary forms, with or without modification,
83 * are permitted provided that the following conditions are met:
84 * 1. Redistributions of source code must retain the above copyright notice,
85 * this list of conditions and the following disclaimer.
86 * 2. Redistributions in binary form must reproduce the above copyright notice,
87 * this list of conditions and the following disclaimer in the documentation
88 * and/or other materials provided with the distribution.
89 * 3. Neither the name of STMicroelectronics nor the names of its contributors
90 * may be used to endorse or promote products derived from this software
91 * without specific prior written permission.
93 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
94 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
95 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
96 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
97 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
98 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
99 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
100 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
101 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
102 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
104 ******************************************************************************
107 /* Includes ------------------------------------------------------------------*/
108 #include "stm32f4xx_hal.h"
110 /** @addtogroup STM32F4xx_HAL_Driver
111 * @{
114 /** @defgroup CAN CAN
115 * @brief CAN driver modules
116 * @{
119 #ifdef HAL_CAN_MODULE_ENABLED
121 #if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) ||\
122 defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\
123 defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) ||\
124 defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) ||\
125 defined(STM32F423xx)
127 /* Private typedef -----------------------------------------------------------*/
128 /* Private define ------------------------------------------------------------*/
129 /** @addtogroup CAN_Private_Constants
130 * @{
132 #define CAN_TIMEOUT_VALUE 10U
134 * @}
136 /* Private macro -------------------------------------------------------------*/
137 /* Private variables ---------------------------------------------------------*/
138 /* Private function prototypes -----------------------------------------------*/
139 /** @addtogroup CAN_Private_Functions
140 * @{
142 static HAL_StatusTypeDef CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber);
143 static HAL_StatusTypeDef CAN_Transmit_IT(CAN_HandleTypeDef* hcan);
145 * @}
148 /* Exported functions --------------------------------------------------------*/
149 /** @defgroup CAN_Exported_Functions CAN Exported Functions
150 * @{
153 /** @defgroup CAN_Exported_Functions_Group1 Initialization and de-initialization functions
154 * @brief Initialization and Configuration functions
156 @verbatim
157 ==============================================================================
158 ##### Initialization and de-initialization functions #####
159 ==============================================================================
160 [..] This section provides functions allowing to:
161 (+) Initialize and configure the CAN.
162 (+) De-initialize the CAN.
164 @endverbatim
165 * @{
169 * @brief Initializes the CAN peripheral according to the specified
170 * parameters in the CAN_InitStruct.
171 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
172 * the configuration information for the specified CAN.
173 * @retval HAL status
175 HAL_StatusTypeDef HAL_CAN_Init(CAN_HandleTypeDef* hcan)
177 uint32_t InitStatus = CAN_INITSTATUS_FAILED;
178 uint32_t tickstart = 0U;
180 /* Check CAN handle */
181 if(hcan == NULL)
183 return HAL_ERROR;
186 /* Check the parameters */
187 assert_param(IS_CAN_ALL_INSTANCE(hcan->Instance));
188 assert_param(IS_FUNCTIONAL_STATE(hcan->Init.TTCM));
189 assert_param(IS_FUNCTIONAL_STATE(hcan->Init.ABOM));
190 assert_param(IS_FUNCTIONAL_STATE(hcan->Init.AWUM));
191 assert_param(IS_FUNCTIONAL_STATE(hcan->Init.NART));
192 assert_param(IS_FUNCTIONAL_STATE(hcan->Init.RFLM));
193 assert_param(IS_FUNCTIONAL_STATE(hcan->Init.TXFP));
194 assert_param(IS_CAN_MODE(hcan->Init.Mode));
195 assert_param(IS_CAN_SJW(hcan->Init.SJW));
196 assert_param(IS_CAN_BS1(hcan->Init.BS1));
197 assert_param(IS_CAN_BS2(hcan->Init.BS2));
198 assert_param(IS_CAN_PRESCALER(hcan->Init.Prescaler));
201 if(hcan->State == HAL_CAN_STATE_RESET)
203 /* Allocate lock resource and initialize it */
204 hcan->Lock = HAL_UNLOCKED;
205 /* Init the low level hardware */
206 HAL_CAN_MspInit(hcan);
209 /* Initialize the CAN state*/
210 hcan->State = HAL_CAN_STATE_BUSY;
212 /* Exit from sleep mode */
213 hcan->Instance->MCR &= (~(uint32_t)CAN_MCR_SLEEP);
215 /* Request initialisation */
216 hcan->Instance->MCR |= CAN_MCR_INRQ ;
218 /* Get tick */
219 tickstart = HAL_GetTick();
221 /* Wait the acknowledge */
222 while((hcan->Instance->MSR & CAN_MSR_INAK) != CAN_MSR_INAK)
224 if((HAL_GetTick() - tickstart ) > CAN_TIMEOUT_VALUE)
226 hcan->State= HAL_CAN_STATE_TIMEOUT;
227 /* Process unlocked */
228 __HAL_UNLOCK(hcan);
229 return HAL_TIMEOUT;
233 /* Check acknowledge */
234 if ((hcan->Instance->MSR & CAN_MSR_INAK) == CAN_MSR_INAK)
236 /* Set the time triggered communication mode */
237 if (hcan->Init.TTCM == ENABLE)
239 hcan->Instance->MCR |= CAN_MCR_TTCM;
241 else
243 hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_TTCM;
246 /* Set the automatic bus-off management */
247 if (hcan->Init.ABOM == ENABLE)
249 hcan->Instance->MCR |= CAN_MCR_ABOM;
251 else
253 hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_ABOM;
256 /* Set the automatic wake-up mode */
257 if (hcan->Init.AWUM == ENABLE)
259 hcan->Instance->MCR |= CAN_MCR_AWUM;
261 else
263 hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_AWUM;
266 /* Set the no automatic retransmission */
267 if (hcan->Init.NART == ENABLE)
269 hcan->Instance->MCR |= CAN_MCR_NART;
271 else
273 hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_NART;
276 /* Set the receive FIFO locked mode */
277 if (hcan->Init.RFLM == ENABLE)
279 hcan->Instance->MCR |= CAN_MCR_RFLM;
281 else
283 hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_RFLM;
286 /* Set the transmit FIFO priority */
287 if (hcan->Init.TXFP == ENABLE)
289 hcan->Instance->MCR |= CAN_MCR_TXFP;
291 else
293 hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_TXFP;
296 /* Set the bit timing register */
297 hcan->Instance->BTR = (uint32_t)((uint32_t)hcan->Init.Mode) | \
298 ((uint32_t)hcan->Init.SJW) | \
299 ((uint32_t)hcan->Init.BS1) | \
300 ((uint32_t)hcan->Init.BS2) | \
301 ((uint32_t)hcan->Init.Prescaler - 1U);
303 /* Request leave initialisation */
304 hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_INRQ;
306 /* Get tick */
307 tickstart = HAL_GetTick();
309 /* Wait the acknowledge */
310 while((hcan->Instance->MSR & CAN_MSR_INAK) == CAN_MSR_INAK)
312 if((HAL_GetTick() - tickstart ) > CAN_TIMEOUT_VALUE)
314 hcan->State= HAL_CAN_STATE_TIMEOUT;
315 /* Process unlocked */
316 __HAL_UNLOCK(hcan);
317 return HAL_TIMEOUT;
321 /* Check acknowledged */
322 if ((hcan->Instance->MSR & CAN_MSR_INAK) != CAN_MSR_INAK)
324 InitStatus = CAN_INITSTATUS_SUCCESS;
328 if(InitStatus == CAN_INITSTATUS_SUCCESS)
330 /* Set CAN error code to none */
331 hcan->ErrorCode = HAL_CAN_ERROR_NONE;
333 /* Initialize the CAN state */
334 hcan->State = HAL_CAN_STATE_READY;
336 /* Return function status */
337 return HAL_OK;
339 else
341 /* Initialize the CAN state */
342 hcan->State = HAL_CAN_STATE_ERROR;
344 /* Return function status */
345 return HAL_ERROR;
350 * @brief Configures the CAN reception filter according to the specified
351 * parameters in the CAN_FilterInitStruct.
352 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
353 * the configuration information for the specified CAN.
354 * @param sFilterConfig: pointer to a CAN_FilterConfTypeDef structure that
355 * contains the filter configuration information.
356 * @retval None
358 HAL_StatusTypeDef HAL_CAN_ConfigFilter(CAN_HandleTypeDef* hcan, CAN_FilterConfTypeDef* sFilterConfig)
360 uint32_t filternbrbitpos = 0U;
361 CAN_TypeDef *can_ip;
363 /* Prevent unused argument(s) compilation warning */
364 UNUSED(hcan);
366 /* Check the parameters */
367 assert_param(IS_CAN_FILTER_NUMBER(sFilterConfig->FilterNumber));
368 assert_param(IS_CAN_FILTER_MODE(sFilterConfig->FilterMode));
369 assert_param(IS_CAN_FILTER_SCALE(sFilterConfig->FilterScale));
370 assert_param(IS_CAN_FILTER_FIFO(sFilterConfig->FilterFIFOAssignment));
371 assert_param(IS_FUNCTIONAL_STATE(sFilterConfig->FilterActivation));
372 assert_param(IS_CAN_BANKNUMBER(sFilterConfig->BankNumber));
374 filternbrbitpos = 1U << sFilterConfig->FilterNumber;
375 #if defined (CAN3)
376 /* Check the CAN instance */
377 if(hcan->Instance == CAN3)
379 can_ip = CAN3;
381 else
383 can_ip = CAN1;
385 #else
386 can_ip = CAN1;
387 #endif
389 /* Initialisation mode for the filter */
390 can_ip->FMR |= (uint32_t)CAN_FMR_FINIT;
392 #if defined (CAN2)
393 /* Select the start slave bank */
394 can_ip->FMR &= ~((uint32_t)CAN_FMR_CAN2SB);
395 can_ip->FMR |= (uint32_t)(sFilterConfig->BankNumber << 8U);
396 #endif
398 /* Filter Deactivation */
399 can_ip->FA1R &= ~(uint32_t)filternbrbitpos;
401 /* Filter Scale */
402 if (sFilterConfig->FilterScale == CAN_FILTERSCALE_16BIT)
404 /* 16-bit scale for the filter */
405 can_ip->FS1R &= ~(uint32_t)filternbrbitpos;
407 /* First 16-bit identifier and First 16-bit mask */
408 /* Or First 16-bit identifier and Second 16-bit identifier */
409 can_ip->sFilterRegister[sFilterConfig->FilterNumber].FR1 =
410 ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdLow) << 16U) |
411 (0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdLow);
413 /* Second 16-bit identifier and Second 16-bit mask */
414 /* Or Third 16-bit identifier and Fourth 16-bit identifier */
415 can_ip->sFilterRegister[sFilterConfig->FilterNumber].FR2 =
416 ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdHigh) << 16U) |
417 (0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdHigh);
420 if (sFilterConfig->FilterScale == CAN_FILTERSCALE_32BIT)
422 /* 32-bit scale for the filter */
423 can_ip->FS1R |= filternbrbitpos;
425 /* 32-bit identifier or First 32-bit identifier */
426 can_ip->sFilterRegister[sFilterConfig->FilterNumber].FR1 =
427 ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdHigh) << 16U) |
428 (0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdLow);
429 /* 32-bit mask or Second 32-bit identifier */
430 can_ip->sFilterRegister[sFilterConfig->FilterNumber].FR2 =
431 ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdHigh) << 16U) |
432 (0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdLow);
435 /* Filter Mode */
436 if (sFilterConfig->FilterMode == CAN_FILTERMODE_IDMASK)
438 /*Id/Mask mode for the filter*/
439 can_ip->FM1R &= ~(uint32_t)filternbrbitpos;
441 else /* CAN_FilterInitStruct->CAN_FilterMode == CAN_FilterMode_IdList */
443 /*Identifier list mode for the filter*/
444 can_ip->FM1R |= (uint32_t)filternbrbitpos;
447 /* Filter FIFO assignment */
448 if (sFilterConfig->FilterFIFOAssignment == CAN_FILTER_FIFO0)
450 /* FIFO 0 assignation for the filter */
451 can_ip->FFA1R &= ~(uint32_t)filternbrbitpos;
454 if (sFilterConfig->FilterFIFOAssignment == CAN_FILTER_FIFO1)
456 /* FIFO 1 assignation for the filter */
457 can_ip->FFA1R |= (uint32_t)filternbrbitpos;
460 /* Filter activation */
461 if (sFilterConfig->FilterActivation == ENABLE)
463 can_ip->FA1R |= filternbrbitpos;
466 /* Leave the initialisation mode for the filter */
467 can_ip->FMR &= ~((uint32_t)CAN_FMR_FINIT);
469 /* Return function status */
470 return HAL_OK;
474 * @brief Deinitializes the CANx peripheral registers to their default reset values.
475 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
476 * the configuration information for the specified CAN.
477 * @retval HAL status
479 HAL_StatusTypeDef HAL_CAN_DeInit(CAN_HandleTypeDef* hcan)
481 /* Check CAN handle */
482 if(hcan == NULL)
484 return HAL_ERROR;
487 /* Check the parameters */
488 assert_param(IS_CAN_ALL_INSTANCE(hcan->Instance));
490 /* Change CAN state */
491 hcan->State = HAL_CAN_STATE_BUSY;
493 /* DeInit the low level hardware */
494 HAL_CAN_MspDeInit(hcan);
496 /* Change CAN state */
497 hcan->State = HAL_CAN_STATE_RESET;
499 /* Release Lock */
500 __HAL_UNLOCK(hcan);
502 /* Return function status */
503 return HAL_OK;
507 * @brief Initializes the CAN MSP.
508 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
509 * the configuration information for the specified CAN.
510 * @retval None
512 __weak void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan)
514 /* Prevent unused argument(s) compilation warning */
515 UNUSED(hcan);
516 /* NOTE : This function Should not be modified, when the callback is needed,
517 the HAL_CAN_MspInit could be implemented in the user file
522 * @brief DeInitializes the CAN MSP.
523 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
524 * the configuration information for the specified CAN.
525 * @retval None
527 __weak void HAL_CAN_MspDeInit(CAN_HandleTypeDef* hcan)
529 /* Prevent unused argument(s) compilation warning */
530 UNUSED(hcan);
531 /* NOTE : This function Should not be modified, when the callback is needed,
532 the HAL_CAN_MspDeInit could be implemented in the user file
537 * @}
540 /** @defgroup CAN_Exported_Functions_Group2 IO operation functions
541 * @brief IO operation functions
543 @verbatim
544 ==============================================================================
545 ##### IO operation functions #####
546 ==============================================================================
547 [..] This section provides functions allowing to:
548 (+) Transmit a CAN frame message.
549 (+) Receive a CAN frame message.
550 (+) Enter CAN peripheral in sleep mode.
551 (+) Wake up the CAN peripheral from sleep mode.
553 @endverbatim
554 * @{
558 * @brief Initiates and transmits a CAN frame message.
559 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
560 * the configuration information for the specified CAN.
561 * @param Timeout: Specify Timeout value
562 * @retval HAL status
564 HAL_StatusTypeDef HAL_CAN_Transmit(CAN_HandleTypeDef* hcan, uint32_t Timeout)
566 uint32_t transmitmailbox = CAN_TXSTATUS_NOMAILBOX;
567 uint32_t tickstart = 0U;
569 /* Check the parameters */
570 assert_param(IS_CAN_IDTYPE(hcan->pTxMsg->IDE));
571 assert_param(IS_CAN_RTR(hcan->pTxMsg->RTR));
572 assert_param(IS_CAN_DLC(hcan->pTxMsg->DLC));
574 if(((hcan->Instance->TSR&CAN_TSR_TME0) == CAN_TSR_TME0) || \
575 ((hcan->Instance->TSR&CAN_TSR_TME1) == CAN_TSR_TME1) || \
576 ((hcan->Instance->TSR&CAN_TSR_TME2) == CAN_TSR_TME2))
578 /* Process locked */
579 __HAL_LOCK(hcan);
581 /* Change CAN state */
582 switch(hcan->State)
584 case(HAL_CAN_STATE_BUSY_RX0):
585 hcan->State = HAL_CAN_STATE_BUSY_TX_RX0;
586 break;
587 case(HAL_CAN_STATE_BUSY_RX1):
588 hcan->State = HAL_CAN_STATE_BUSY_TX_RX1;
589 break;
590 case(HAL_CAN_STATE_BUSY_RX0_RX1):
591 hcan->State = HAL_CAN_STATE_BUSY_TX_RX0_RX1;
592 break;
593 default: /* HAL_CAN_STATE_READY */
594 hcan->State = HAL_CAN_STATE_BUSY_TX;
595 break;
598 /* Select one empty transmit mailbox */
599 if ((hcan->Instance->TSR&CAN_TSR_TME0) == CAN_TSR_TME0)
601 transmitmailbox = CAN_TXMAILBOX_0;
603 else if ((hcan->Instance->TSR&CAN_TSR_TME1) == CAN_TSR_TME1)
605 transmitmailbox = CAN_TXMAILBOX_1;
607 else
609 transmitmailbox = CAN_TXMAILBOX_2;
612 /* Set up the Id */
613 hcan->Instance->sTxMailBox[transmitmailbox].TIR &= CAN_TI0R_TXRQ;
614 if (hcan->pTxMsg->IDE == CAN_ID_STD)
616 assert_param(IS_CAN_STDID(hcan->pTxMsg->StdId));
617 hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->StdId << 21U) | \
618 hcan->pTxMsg->RTR);
620 else
622 assert_param(IS_CAN_EXTID(hcan->pTxMsg->ExtId));
623 hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->ExtId << 3U) | \
624 hcan->pTxMsg->IDE | \
625 hcan->pTxMsg->RTR);
628 /* Set up the DLC */
629 hcan->pTxMsg->DLC &= (uint8_t)0x0000000F;
630 hcan->Instance->sTxMailBox[transmitmailbox].TDTR &= (uint32_t)0xFFFFFFF0U;
631 hcan->Instance->sTxMailBox[transmitmailbox].TDTR |= hcan->pTxMsg->DLC;
633 /* Set up the data field */
634 hcan->Instance->sTxMailBox[transmitmailbox].TDLR = (((uint32_t)hcan->pTxMsg->Data[3U] << 24U) |
635 ((uint32_t)hcan->pTxMsg->Data[2U] << 16U) |
636 ((uint32_t)hcan->pTxMsg->Data[1U] << 8U) |
637 ((uint32_t)hcan->pTxMsg->Data[0U]));
638 hcan->Instance->sTxMailBox[transmitmailbox].TDHR = (((uint32_t)hcan->pTxMsg->Data[7U] << 24U) |
639 ((uint32_t)hcan->pTxMsg->Data[6U] << 16U) |
640 ((uint32_t)hcan->pTxMsg->Data[5U] << 8U) |
641 ((uint32_t)hcan->pTxMsg->Data[4U]));
642 /* Request transmission */
643 hcan->Instance->sTxMailBox[transmitmailbox].TIR |= CAN_TI0R_TXRQ;
645 /* Get tick */
646 tickstart = HAL_GetTick();
648 /* Check End of transmission flag */
649 while(!(__HAL_CAN_TRANSMIT_STATUS(hcan, transmitmailbox)))
651 /* Check for the Timeout */
652 if(Timeout != HAL_MAX_DELAY)
654 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
656 hcan->State = HAL_CAN_STATE_TIMEOUT;
658 __HAL_CAN_CANCEL_TRANSMIT(hcan, transmitmailbox);
660 /* Process unlocked */
661 __HAL_UNLOCK(hcan);
662 return HAL_TIMEOUT;
667 /* Change CAN state */
668 switch(hcan->State)
670 case(HAL_CAN_STATE_BUSY_TX_RX0):
671 hcan->State = HAL_CAN_STATE_BUSY_RX0;
672 break;
673 case(HAL_CAN_STATE_BUSY_TX_RX1):
674 hcan->State = HAL_CAN_STATE_BUSY_RX1;
675 break;
676 case(HAL_CAN_STATE_BUSY_TX_RX0_RX1):
677 hcan->State = HAL_CAN_STATE_BUSY_RX0_RX1;
678 break;
679 default: /* HAL_CAN_STATE_BUSY_TX */
680 hcan->State = HAL_CAN_STATE_READY;
681 break;
684 /* Process unlocked */
685 __HAL_UNLOCK(hcan);
687 /* Return function status */
688 return HAL_OK;
690 else
692 /* Change CAN state */
693 hcan->State = HAL_CAN_STATE_ERROR;
695 /* Return function status */
696 return HAL_ERROR;
701 * @brief Initiates and transmits a CAN frame message.
702 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
703 * the configuration information for the specified CAN.
704 * @retval HAL status
706 HAL_StatusTypeDef HAL_CAN_Transmit_IT(CAN_HandleTypeDef* hcan)
708 uint32_t transmitmailbox = CAN_TXSTATUS_NOMAILBOX;
710 /* Check the parameters */
711 assert_param(IS_CAN_IDTYPE(hcan->pTxMsg->IDE));
712 assert_param(IS_CAN_RTR(hcan->pTxMsg->RTR));
713 assert_param(IS_CAN_DLC(hcan->pTxMsg->DLC));
715 if(((hcan->Instance->TSR&CAN_TSR_TME0) == CAN_TSR_TME0) || \
716 ((hcan->Instance->TSR&CAN_TSR_TME1) == CAN_TSR_TME1) || \
717 ((hcan->Instance->TSR&CAN_TSR_TME2) == CAN_TSR_TME2))
719 /* Process Locked */
720 __HAL_LOCK(hcan);
722 /* Select one empty transmit mailbox */
723 if((hcan->Instance->TSR&CAN_TSR_TME0) == CAN_TSR_TME0)
725 transmitmailbox = CAN_TXMAILBOX_0;
727 else if((hcan->Instance->TSR&CAN_TSR_TME1) == CAN_TSR_TME1)
729 transmitmailbox = CAN_TXMAILBOX_1;
731 else
733 transmitmailbox = CAN_TXMAILBOX_2;
736 /* Set up the Id */
737 hcan->Instance->sTxMailBox[transmitmailbox].TIR &= CAN_TI0R_TXRQ;
738 if(hcan->pTxMsg->IDE == CAN_ID_STD)
740 assert_param(IS_CAN_STDID(hcan->pTxMsg->StdId));
741 hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->StdId << 21U) | \
742 hcan->pTxMsg->RTR);
744 else
746 assert_param(IS_CAN_EXTID(hcan->pTxMsg->ExtId));
747 hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->ExtId << 3U) | \
748 hcan->pTxMsg->IDE | \
749 hcan->pTxMsg->RTR);
752 /* Set up the DLC */
753 hcan->pTxMsg->DLC &= (uint8_t)0x0000000F;
754 hcan->Instance->sTxMailBox[transmitmailbox].TDTR &= (uint32_t)0xFFFFFFF0U;
755 hcan->Instance->sTxMailBox[transmitmailbox].TDTR |= hcan->pTxMsg->DLC;
757 /* Set up the data field */
758 hcan->Instance->sTxMailBox[transmitmailbox].TDLR = (((uint32_t)hcan->pTxMsg->Data[3U] << 24U) |
759 ((uint32_t)hcan->pTxMsg->Data[2U] << 16U) |
760 ((uint32_t)hcan->pTxMsg->Data[1U] << 8U) |
761 ((uint32_t)hcan->pTxMsg->Data[0U]));
762 hcan->Instance->sTxMailBox[transmitmailbox].TDHR = (((uint32_t)hcan->pTxMsg->Data[7U] << 24U) |
763 ((uint32_t)hcan->pTxMsg->Data[6U] << 16U) |
764 ((uint32_t)hcan->pTxMsg->Data[5U] << 8U) |
765 ((uint32_t)hcan->pTxMsg->Data[4U]));
767 /* Change CAN state */
768 switch(hcan->State)
770 case(HAL_CAN_STATE_BUSY_RX0):
771 hcan->State = HAL_CAN_STATE_BUSY_TX_RX0;
772 break;
773 case(HAL_CAN_STATE_BUSY_RX1):
774 hcan->State = HAL_CAN_STATE_BUSY_TX_RX1;
775 break;
776 case(HAL_CAN_STATE_BUSY_RX0_RX1):
777 hcan->State = HAL_CAN_STATE_BUSY_TX_RX0_RX1;
778 break;
779 default: /* HAL_CAN_STATE_READY */
780 hcan->State = HAL_CAN_STATE_BUSY_TX;
781 break;
784 /* Set CAN error code to none */
785 hcan->ErrorCode = HAL_CAN_ERROR_NONE;
787 /* Process Unlocked */
788 __HAL_UNLOCK(hcan);
790 /* Request transmission */
791 hcan->Instance->sTxMailBox[transmitmailbox].TIR |= CAN_TI0R_TXRQ;
793 /* Enable Error warning, Error passive, Bus-off,
794 Last error and Error Interrupts */
795 __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EWG |
796 CAN_IT_EPV |
797 CAN_IT_BOF |
798 CAN_IT_LEC |
799 CAN_IT_ERR |
800 CAN_IT_TME);
802 else
804 /* Change CAN state */
805 hcan->State = HAL_CAN_STATE_ERROR;
807 /* Return function status */
808 return HAL_ERROR;
811 return HAL_OK;
815 * @brief Receives a correct CAN frame.
816 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
817 * the configuration information for the specified CAN.
818 * @param FIFONumber: FIFO Number value
819 * @param Timeout: Specify Timeout value
820 * @retval HAL status
822 HAL_StatusTypeDef HAL_CAN_Receive(CAN_HandleTypeDef* hcan, uint8_t FIFONumber, uint32_t Timeout)
824 uint32_t tickstart = 0U;
825 CanRxMsgTypeDef* pRxMsg = NULL;
827 /* Check the parameters */
828 assert_param(IS_CAN_FIFO(FIFONumber));
830 /* Check if CAN state is not busy for RX FIFO0 */
831 if ((FIFONumber == CAN_FIFO0) && ((hcan->State == HAL_CAN_STATE_BUSY_RX0) || \
832 (hcan->State == HAL_CAN_STATE_BUSY_TX_RX0) || \
833 (hcan->State == HAL_CAN_STATE_BUSY_RX0_RX1) || \
834 (hcan->State == HAL_CAN_STATE_BUSY_TX_RX0_RX1)))
836 return HAL_BUSY;
839 /* Check if CAN state is not busy for RX FIFO1 */
840 if ((FIFONumber == CAN_FIFO1) && ((hcan->State == HAL_CAN_STATE_BUSY_RX1) || \
841 (hcan->State == HAL_CAN_STATE_BUSY_TX_RX1) || \
842 (hcan->State == HAL_CAN_STATE_BUSY_RX0_RX1) || \
843 (hcan->State == HAL_CAN_STATE_BUSY_TX_RX0_RX1)))
845 return HAL_BUSY;
848 /* Process locked */
849 __HAL_LOCK(hcan);
851 /* Change CAN state */
852 if (FIFONumber == CAN_FIFO0)
854 switch(hcan->State)
856 case(HAL_CAN_STATE_BUSY_TX):
857 hcan->State = HAL_CAN_STATE_BUSY_TX_RX0;
858 break;
859 case(HAL_CAN_STATE_BUSY_RX1):
860 hcan->State = HAL_CAN_STATE_BUSY_RX0_RX1;
861 break;
862 case(HAL_CAN_STATE_BUSY_TX_RX1):
863 hcan->State = HAL_CAN_STATE_BUSY_TX_RX0_RX1;
864 break;
865 default: /* HAL_CAN_STATE_READY */
866 hcan->State = HAL_CAN_STATE_BUSY_RX0;
867 break;
870 else /* FIFONumber == CAN_FIFO1 */
872 switch(hcan->State)
874 case(HAL_CAN_STATE_BUSY_TX):
875 hcan->State = HAL_CAN_STATE_BUSY_TX_RX1;
876 break;
877 case(HAL_CAN_STATE_BUSY_RX0):
878 hcan->State = HAL_CAN_STATE_BUSY_RX0_RX1;
879 break;
880 case(HAL_CAN_STATE_BUSY_TX_RX0):
881 hcan->State = HAL_CAN_STATE_BUSY_TX_RX0_RX1;
882 break;
883 default: /* HAL_CAN_STATE_READY */
884 hcan->State = HAL_CAN_STATE_BUSY_RX1;
885 break;
889 /* Get tick */
890 tickstart = HAL_GetTick();
892 /* Check pending message */
893 while(__HAL_CAN_MSG_PENDING(hcan, FIFONumber) == 0U)
895 /* Check for the Timeout */
896 if(Timeout != HAL_MAX_DELAY)
898 if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
900 hcan->State = HAL_CAN_STATE_TIMEOUT;
901 /* Process unlocked */
902 __HAL_UNLOCK(hcan);
903 return HAL_TIMEOUT;
908 /* Set RxMsg pointer */
909 if(FIFONumber == CAN_FIFO0)
911 pRxMsg = hcan->pRxMsg;
913 else /* FIFONumber == CAN_FIFO1 */
915 pRxMsg = hcan->pRx1Msg;
918 /* Get the Id */
919 pRxMsg->IDE = (uint8_t)0x04 & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
920 if (pRxMsg->IDE == CAN_ID_STD)
922 pRxMsg->StdId = 0x000007FFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 21U);
924 else
926 pRxMsg->ExtId = 0x1FFFFFFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 3U);
929 pRxMsg->RTR = (uint8_t)0x02 & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
930 /* Get the DLC */
931 pRxMsg->DLC = (uint8_t)0x0F & hcan->Instance->sFIFOMailBox[FIFONumber].RDTR;
932 /* Get the FMI */
933 pRxMsg->FMI = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDTR >> 8U);
934 /* Get the FIFONumber */
935 pRxMsg->FIFONumber = FIFONumber;
936 /* Get the data field */
937 pRxMsg->Data[0] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR;
938 pRxMsg->Data[1] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 8U);
939 pRxMsg->Data[2] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 16U);
940 pRxMsg->Data[3] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 24U);
941 pRxMsg->Data[4] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR;
942 pRxMsg->Data[5] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 8U);
943 pRxMsg->Data[6] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 16U);
944 pRxMsg->Data[7] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 24U);
946 /* Release the FIFO */
947 if(FIFONumber == CAN_FIFO0)
949 /* Release FIFO0 */
950 __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO0);
952 else /* FIFONumber == CAN_FIFO1 */
954 /* Release FIFO1 */
955 __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO1);
958 /* Change CAN state */
959 if (FIFONumber == CAN_FIFO0)
961 switch(hcan->State)
963 case(HAL_CAN_STATE_BUSY_TX_RX0):
964 hcan->State = HAL_CAN_STATE_BUSY_TX;
965 break;
966 case(HAL_CAN_STATE_BUSY_RX0_RX1):
967 hcan->State = HAL_CAN_STATE_BUSY_RX1;
968 break;
969 case(HAL_CAN_STATE_BUSY_TX_RX0_RX1):
970 hcan->State = HAL_CAN_STATE_BUSY_TX_RX1;
971 break;
972 default: /* HAL_CAN_STATE_BUSY_RX0 */
973 hcan->State = HAL_CAN_STATE_READY;
974 break;
977 else /* FIFONumber == CAN_FIFO1 */
979 switch(hcan->State)
981 case(HAL_CAN_STATE_BUSY_TX_RX1):
982 hcan->State = HAL_CAN_STATE_BUSY_TX;
983 break;
984 case(HAL_CAN_STATE_BUSY_RX0_RX1):
985 hcan->State = HAL_CAN_STATE_BUSY_RX0;
986 break;
987 case(HAL_CAN_STATE_BUSY_TX_RX0_RX1):
988 hcan->State = HAL_CAN_STATE_BUSY_TX_RX0;
989 break;
990 default: /* HAL_CAN_STATE_BUSY_RX1 */
991 hcan->State = HAL_CAN_STATE_READY;
992 break;
996 /* Process unlocked */
997 __HAL_UNLOCK(hcan);
999 /* Return function status */
1000 return HAL_OK;
1004 * @brief Receives a correct CAN frame.
1005 * @param hcan: Pointer to a CAN_HandleTypeDef structure that contains
1006 * the configuration information for the specified CAN.
1007 * @param FIFONumber: Specify the FIFO number
1008 * @retval HAL status
1010 HAL_StatusTypeDef HAL_CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber)
1012 /* Check the parameters */
1013 assert_param(IS_CAN_FIFO(FIFONumber));
1015 /* Check if CAN state is not busy for RX FIFO0 */
1016 if((FIFONumber == CAN_FIFO0) && ((hcan->State == HAL_CAN_STATE_BUSY_RX0) || \
1017 (hcan->State == HAL_CAN_STATE_BUSY_TX_RX0) || \
1018 (hcan->State == HAL_CAN_STATE_BUSY_RX0_RX1) || \
1019 (hcan->State == HAL_CAN_STATE_BUSY_TX_RX0_RX1)))
1021 return HAL_BUSY;
1024 /* Check if CAN state is not busy for RX FIFO1 */
1025 if((FIFONumber == CAN_FIFO1) && ((hcan->State == HAL_CAN_STATE_BUSY_RX1) || \
1026 (hcan->State == HAL_CAN_STATE_BUSY_TX_RX1) || \
1027 (hcan->State == HAL_CAN_STATE_BUSY_RX0_RX1) || \
1028 (hcan->State == HAL_CAN_STATE_BUSY_TX_RX0_RX1)))
1030 return HAL_BUSY;
1033 /* Process locked */
1034 __HAL_LOCK(hcan);
1036 /* Change CAN state */
1037 if(FIFONumber == CAN_FIFO0)
1039 switch(hcan->State)
1041 case(HAL_CAN_STATE_BUSY_TX):
1042 hcan->State = HAL_CAN_STATE_BUSY_TX_RX0;
1043 break;
1044 case(HAL_CAN_STATE_BUSY_RX1):
1045 hcan->State = HAL_CAN_STATE_BUSY_RX0_RX1;
1046 break;
1047 case(HAL_CAN_STATE_BUSY_TX_RX1):
1048 hcan->State = HAL_CAN_STATE_BUSY_TX_RX0_RX1;
1049 break;
1050 default: /* HAL_CAN_STATE_READY */
1051 hcan->State = HAL_CAN_STATE_BUSY_RX0;
1052 break;
1055 else /* FIFONumber == CAN_FIFO1 */
1057 switch(hcan->State)
1059 case(HAL_CAN_STATE_BUSY_TX):
1060 hcan->State = HAL_CAN_STATE_BUSY_TX_RX1;
1061 break;
1062 case(HAL_CAN_STATE_BUSY_RX0):
1063 hcan->State = HAL_CAN_STATE_BUSY_RX0_RX1;
1064 break;
1065 case(HAL_CAN_STATE_BUSY_TX_RX0):
1066 hcan->State = HAL_CAN_STATE_BUSY_TX_RX0_RX1;
1067 break;
1068 default: /* HAL_CAN_STATE_READY */
1069 hcan->State = HAL_CAN_STATE_BUSY_RX1;
1070 break;
1073 /* Set CAN error code to none */
1074 hcan->ErrorCode = HAL_CAN_ERROR_NONE;
1076 /* Enable interrupts: */
1077 /* - Enable Error warning Interrupt */
1078 /* - Enable Error passive Interrupt */
1079 /* - Enable Bus-off Interrupt */
1080 /* - Enable Last error code Interrupt */
1081 /* - Enable Error Interrupt */
1082 /* - Enable Transmit mailbox empty Interrupt */
1083 __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EWG |
1084 CAN_IT_EPV |
1085 CAN_IT_BOF |
1086 CAN_IT_LEC |
1087 CAN_IT_ERR |
1088 CAN_IT_TME);
1090 /* Process unlocked */
1091 __HAL_UNLOCK(hcan);
1093 if(FIFONumber == CAN_FIFO0)
1095 /* Enable FIFO 0 overrun and message pending Interrupt */
1096 __HAL_CAN_ENABLE_IT(hcan, CAN_IT_FOV0 | CAN_IT_FMP0);
1098 else
1100 /* Enable FIFO 1 overrun and message pending Interrupt */
1101 __HAL_CAN_ENABLE_IT(hcan, CAN_IT_FOV1 | CAN_IT_FMP1);
1104 /* Return function status */
1105 return HAL_OK;
1109 * @brief Enters the Sleep (low power) mode.
1110 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
1111 * the configuration information for the specified CAN.
1112 * @retval HAL status.
1114 HAL_StatusTypeDef HAL_CAN_Sleep(CAN_HandleTypeDef* hcan)
1116 uint32_t tickstart = 0U;
1118 /* Process locked */
1119 __HAL_LOCK(hcan);
1121 /* Change CAN state */
1122 hcan->State = HAL_CAN_STATE_BUSY;
1124 /* Request Sleep mode */
1125 hcan->Instance->MCR = (((hcan->Instance->MCR) & (uint32_t)(~(uint32_t)CAN_MCR_INRQ)) | CAN_MCR_SLEEP);
1127 /* Sleep mode status */
1128 if ((hcan->Instance->MSR & (CAN_MSR_SLAK|CAN_MSR_INAK)) != CAN_MSR_SLAK)
1130 /* Process unlocked */
1131 __HAL_UNLOCK(hcan);
1133 /* Return function status */
1134 return HAL_ERROR;
1137 /* Get tick */
1138 tickstart = HAL_GetTick();
1140 /* Wait the acknowledge */
1141 while((hcan->Instance->MSR & (CAN_MSR_SLAK|CAN_MSR_INAK)) != CAN_MSR_SLAK)
1143 if((HAL_GetTick() - tickstart) > CAN_TIMEOUT_VALUE)
1145 hcan->State = HAL_CAN_STATE_TIMEOUT;
1146 /* Process unlocked */
1147 __HAL_UNLOCK(hcan);
1148 return HAL_TIMEOUT;
1152 /* Change CAN state */
1153 hcan->State = HAL_CAN_STATE_READY;
1155 /* Process unlocked */
1156 __HAL_UNLOCK(hcan);
1158 /* Return function status */
1159 return HAL_OK;
1163 * @brief Wakes up the CAN peripheral from sleep mode, after that the CAN peripheral
1164 * is in the normal mode.
1165 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
1166 * the configuration information for the specified CAN.
1167 * @retval HAL status.
1169 HAL_StatusTypeDef HAL_CAN_WakeUp(CAN_HandleTypeDef* hcan)
1171 uint32_t tickstart = 0U;
1173 /* Process locked */
1174 __HAL_LOCK(hcan);
1176 /* Change CAN state */
1177 hcan->State = HAL_CAN_STATE_BUSY;
1179 /* Wake up request */
1180 hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_SLEEP;
1182 /* Get tick */
1183 tickstart = HAL_GetTick();
1185 /* Sleep mode status */
1186 while((hcan->Instance->MSR & CAN_MSR_SLAK) == CAN_MSR_SLAK)
1188 if((HAL_GetTick() - tickstart) > CAN_TIMEOUT_VALUE)
1190 hcan->State= HAL_CAN_STATE_TIMEOUT;
1191 /* Process unlocked */
1192 __HAL_UNLOCK(hcan);
1193 return HAL_TIMEOUT;
1196 if((hcan->Instance->MSR & CAN_MSR_SLAK) == CAN_MSR_SLAK)
1198 /* Process unlocked */
1199 __HAL_UNLOCK(hcan);
1201 /* Return function status */
1202 return HAL_ERROR;
1205 /* Change CAN state */
1206 hcan->State = HAL_CAN_STATE_READY;
1208 /* Process unlocked */
1209 __HAL_UNLOCK(hcan);
1211 /* Return function status */
1212 return HAL_OK;
1216 * @brief Handles CAN interrupt request
1217 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
1218 * the configuration information for the specified CAN.
1219 * @retval None
1221 void HAL_CAN_IRQHandler(CAN_HandleTypeDef* hcan)
1223 uint32_t tmp1 = 0U, tmp2 = 0U, tmp3 = 0U;
1224 uint32_t errorcode = HAL_CAN_ERROR_NONE;
1226 /* Check Overrun flag for FIFO0 */
1227 tmp1 = __HAL_CAN_GET_FLAG(hcan, CAN_FLAG_FOV0);
1228 tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FOV0);
1229 if(tmp1 && tmp2)
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);
1237 /* Check Overrun flag for FIFO1 */
1238 tmp1 = __HAL_CAN_GET_FLAG(hcan, CAN_FLAG_FOV1);
1239 tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FOV1);
1241 if(tmp1 && tmp2)
1243 /* Set CAN error code to FOV1 error */
1244 errorcode |= HAL_CAN_ERROR_FOV1;
1246 /* Clear FIFO1 Overrun Flag */
1247 __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FOV1);
1250 /* Check End of transmission flag */
1251 if(__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_TME))
1253 tmp1 = __HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_0);
1254 tmp2 = __HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_1);
1255 tmp3 = __HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_2);
1256 if(tmp1 || tmp2 || tmp3)
1258 tmp1 = __HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TXOK0);
1259 tmp2 = __HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TXOK1);
1260 tmp3 = __HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TXOK2);
1261 /* Check Transmit success */
1262 if(tmp1 || tmp2 || tmp3)
1264 /* Call transmit function */
1265 CAN_Transmit_IT(hcan);
1267 else /* Transmit failure */
1269 /* Set CAN error code to TXFAIL error */
1270 errorcode |= HAL_CAN_ERROR_TXFAIL;
1273 /* Clear transmission status flags (RQCPx and TXOKx) */
1274 SET_BIT(hcan->Instance->TSR, CAN_TSR_RQCP0 | CAN_TSR_RQCP1 | CAN_TSR_RQCP2 | \
1275 CAN_FLAG_TXOK0 | CAN_FLAG_TXOK1 | CAN_FLAG_TXOK2);
1279 tmp1 = __HAL_CAN_MSG_PENDING(hcan, CAN_FIFO0);
1280 tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FMP0);
1281 /* Check End of reception flag for FIFO0 */
1282 if((tmp1 != 0U) && tmp2)
1284 /* Call receive function */
1285 CAN_Receive_IT(hcan, CAN_FIFO0);
1288 tmp1 = __HAL_CAN_MSG_PENDING(hcan, CAN_FIFO1);
1289 tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FMP1);
1290 /* Check End of reception flag for FIFO1 */
1291 if((tmp1 != 0U) && tmp2)
1293 /* Call receive function */
1294 CAN_Receive_IT(hcan, CAN_FIFO1);
1297 /* Set error code in handle */
1298 hcan->ErrorCode |= errorcode;
1300 tmp1 = __HAL_CAN_GET_FLAG(hcan, CAN_FLAG_EWG);
1301 tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_EWG);
1302 tmp3 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR);
1303 /* Check Error Warning Flag */
1304 if(tmp1 && tmp2 && tmp3)
1306 /* Set CAN error code to EWG error */
1307 hcan->ErrorCode |= HAL_CAN_ERROR_EWG;
1310 tmp1 = __HAL_CAN_GET_FLAG(hcan, CAN_FLAG_EPV);
1311 tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_EPV);
1312 tmp3 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR);
1313 /* Check Error Passive Flag */
1314 if(tmp1 && tmp2 && tmp3)
1316 /* Set CAN error code to EPV error */
1317 hcan->ErrorCode |= HAL_CAN_ERROR_EPV;
1320 tmp1 = __HAL_CAN_GET_FLAG(hcan, CAN_FLAG_BOF);
1321 tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_BOF);
1322 tmp3 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR);
1323 /* Check Bus-Off Flag */
1324 if(tmp1 && tmp2 && tmp3)
1326 /* Set CAN error code to BOF error */
1327 hcan->ErrorCode |= HAL_CAN_ERROR_BOF;
1330 tmp1 = HAL_IS_BIT_CLR(hcan->Instance->ESR, CAN_ESR_LEC);
1331 tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_LEC);
1332 tmp3 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR);
1333 /* Check Last error code Flag */
1334 if((!tmp1) && tmp2 && tmp3)
1336 tmp1 = (hcan->Instance->ESR) & CAN_ESR_LEC;
1337 switch(tmp1)
1339 case(CAN_ESR_LEC_0):
1340 /* Set CAN error code to STF error */
1341 hcan->ErrorCode |= HAL_CAN_ERROR_STF;
1342 break;
1343 case(CAN_ESR_LEC_1):
1344 /* Set CAN error code to FOR error */
1345 hcan->ErrorCode |= HAL_CAN_ERROR_FOR;
1346 break;
1347 case(CAN_ESR_LEC_1 | CAN_ESR_LEC_0):
1348 /* Set CAN error code to ACK error */
1349 hcan->ErrorCode |= HAL_CAN_ERROR_ACK;
1350 break;
1351 case(CAN_ESR_LEC_2):
1352 /* Set CAN error code to BR error */
1353 hcan->ErrorCode |= HAL_CAN_ERROR_BR;
1354 break;
1355 case(CAN_ESR_LEC_2 | CAN_ESR_LEC_0):
1356 /* Set CAN error code to BD error */
1357 hcan->ErrorCode |= HAL_CAN_ERROR_BD;
1358 break;
1359 case(CAN_ESR_LEC_2 | CAN_ESR_LEC_1):
1360 /* Set CAN error code to CRC error */
1361 hcan->ErrorCode |= HAL_CAN_ERROR_CRC;
1362 break;
1363 default:
1364 break;
1367 /* Clear Last error code Flag */
1368 hcan->Instance->ESR &= ~(CAN_ESR_LEC);
1371 /* Call the Error call Back in case of Errors */
1372 if(hcan->ErrorCode != HAL_CAN_ERROR_NONE)
1374 /* Clear ERRI Flag */
1375 hcan->Instance->MSR = CAN_MSR_ERRI;
1376 /* Set the CAN state ready to be able to start again the process */
1377 hcan->State = HAL_CAN_STATE_READY;
1379 /* Disable interrupts: */
1380 /* - Disable Error warning Interrupt */
1381 /* - Disable Error passive Interrupt */
1382 /* - Disable Bus-off Interrupt */
1383 /* - Disable Last error code Interrupt */
1384 /* - Disable Error Interrupt */
1385 /* - Disable FIFO 0 message pending Interrupt */
1386 /* - Disable FIFO 0 Overrun Interrupt */
1387 /* - Disable FIFO 1 message pending Interrupt */
1388 /* - Disable FIFO 1 Overrun Interrupt */
1389 /* - Disable Transmit mailbox empty Interrupt */
1390 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EWG |
1391 CAN_IT_EPV |
1392 CAN_IT_BOF |
1393 CAN_IT_LEC |
1394 CAN_IT_ERR |
1395 CAN_IT_FMP0|
1396 CAN_IT_FOV0|
1397 CAN_IT_FMP1|
1398 CAN_IT_FOV1|
1399 CAN_IT_TME);
1401 /* Call Error callback function */
1402 HAL_CAN_ErrorCallback(hcan);
1407 * @brief Transmission complete callback in non blocking mode
1408 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
1409 * the configuration information for the specified CAN.
1410 * @retval None
1412 __weak void HAL_CAN_TxCpltCallback(CAN_HandleTypeDef* hcan)
1414 /* Prevent unused argument(s) compilation warning */
1415 UNUSED(hcan);
1416 /* NOTE : This function Should not be modified, when the callback is needed,
1417 the HAL_CAN_TxCpltCallback could be implemented in the user file
1422 * @brief Transmission complete callback in non blocking mode
1423 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
1424 * the configuration information for the specified CAN.
1425 * @retval None
1427 __weak void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* hcan)
1429 /* Prevent unused argument(s) compilation warning */
1430 UNUSED(hcan);
1431 /* NOTE : This function Should not be modified, when the callback is needed,
1432 the HAL_CAN_RxCpltCallback could be implemented in the user file
1437 * @brief Error CAN callback.
1438 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
1439 * the configuration information for the specified CAN.
1440 * @retval None
1442 __weak void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan)
1444 /* Prevent unused argument(s) compilation warning */
1445 UNUSED(hcan);
1446 /* NOTE : This function Should not be modified, when the callback is needed,
1447 the HAL_CAN_ErrorCallback could be implemented in the user file
1452 * @}
1455 /** @defgroup CAN_Exported_Functions_Group3 Peripheral State and Error functions
1456 * @brief CAN Peripheral State functions
1458 @verbatim
1459 ==============================================================================
1460 ##### Peripheral State and Error functions #####
1461 ==============================================================================
1462 [..]
1463 This subsection provides functions allowing to :
1464 (+) Check the CAN state.
1465 (+) Check CAN Errors detected during interrupt process
1467 @endverbatim
1468 * @{
1472 * @brief return the CAN state
1473 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
1474 * the configuration information for the specified CAN.
1475 * @retval HAL state
1477 HAL_CAN_StateTypeDef HAL_CAN_GetState(CAN_HandleTypeDef* hcan)
1479 /* Return CAN state */
1480 return hcan->State;
1484 * @brief Return the CAN error code
1485 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
1486 * the configuration information for the specified CAN.
1487 * @retval CAN Error Code
1489 uint32_t HAL_CAN_GetError(CAN_HandleTypeDef *hcan)
1491 return hcan->ErrorCode;
1495 * @}
1498 * @brief Initiates and transmits a CAN frame message.
1499 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
1500 * the configuration information for the specified CAN.
1501 * @retval HAL status
1503 static HAL_StatusTypeDef CAN_Transmit_IT(CAN_HandleTypeDef* hcan)
1505 /* Disable Transmit mailbox empty Interrupt */
1506 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_TME);
1508 if(hcan->State == HAL_CAN_STATE_BUSY_TX)
1510 /* Disable Error warning, Error passive, Bus-off, Last error code
1511 and Error Interrupts */
1512 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EWG |
1513 CAN_IT_EPV |
1514 CAN_IT_BOF |
1515 CAN_IT_LEC |
1516 CAN_IT_ERR );
1519 /* Change CAN state */
1520 switch(hcan->State)
1522 case(HAL_CAN_STATE_BUSY_TX_RX0):
1523 hcan->State = HAL_CAN_STATE_BUSY_RX0;
1524 break;
1525 case(HAL_CAN_STATE_BUSY_TX_RX1):
1526 hcan->State = HAL_CAN_STATE_BUSY_RX1;
1527 break;
1528 case(HAL_CAN_STATE_BUSY_TX_RX0_RX1):
1529 hcan->State = HAL_CAN_STATE_BUSY_RX0_RX1;
1530 break;
1531 default: /* HAL_CAN_STATE_BUSY_TX */
1532 hcan->State = HAL_CAN_STATE_READY;
1533 break;
1536 /* Transmission complete callback */
1537 HAL_CAN_TxCpltCallback(hcan);
1539 return HAL_OK;
1543 * @brief Receives a correct CAN frame.
1544 * @param hcan: Pointer to a CAN_HandleTypeDef structure that contains
1545 * the configuration information for the specified CAN.
1546 * @param FIFONumber: Specify the FIFO number
1547 * @retval HAL status
1548 * @retval None
1550 static HAL_StatusTypeDef CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber)
1552 uint32_t tmp1 = 0U;
1553 CanRxMsgTypeDef* pRxMsg = NULL;
1555 /* Set RxMsg pointer */
1556 if(FIFONumber == CAN_FIFO0)
1558 pRxMsg = hcan->pRxMsg;
1560 else /* FIFONumber == CAN_FIFO1 */
1562 pRxMsg = hcan->pRx1Msg;
1565 /* Get the Id */
1566 pRxMsg->IDE = (uint8_t)0x04 & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
1567 if (pRxMsg->IDE == CAN_ID_STD)
1569 pRxMsg->StdId = 0x000007FFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 21U);
1571 else
1573 pRxMsg->ExtId = 0x1FFFFFFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 3U);
1576 pRxMsg->RTR = (uint8_t)0x02 & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
1577 /* Get the DLC */
1578 pRxMsg->DLC = (uint8_t)0x0F & hcan->Instance->sFIFOMailBox[FIFONumber].RDTR;
1579 /* Get the FIFONumber */
1580 pRxMsg->FIFONumber = FIFONumber;
1581 /* Get the FMI */
1582 pRxMsg->FMI = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDTR >> 8U);
1583 /* Get the data field */
1584 pRxMsg->Data[0] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR;
1585 pRxMsg->Data[1] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 8U);
1586 pRxMsg->Data[2] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 16U);
1587 pRxMsg->Data[3] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 24U);
1588 pRxMsg->Data[4] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR;
1589 pRxMsg->Data[5] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 8U);
1590 pRxMsg->Data[6] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 16U);
1591 pRxMsg->Data[7] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 24U);
1592 /* Release the FIFO */
1593 /* Release FIFO0 */
1594 if (FIFONumber == CAN_FIFO0)
1596 __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO0);
1598 /* Disable FIFO 0 overrun and message pending Interrupt */
1599 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_FOV0 | CAN_IT_FMP0);
1601 /* Release FIFO1 */
1602 else /* FIFONumber == CAN_FIFO1 */
1604 __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO1);
1606 /* Disable FIFO 1 overrun and message pending Interrupt */
1607 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_FOV1 | CAN_IT_FMP1);
1610 tmp1 = hcan->State;
1611 if((tmp1 == HAL_CAN_STATE_BUSY_RX0) || (tmp1 == HAL_CAN_STATE_BUSY_RX1))
1613 /* Disable Error warning, Error passive, Bus-off, Last error code
1614 and Error Interrupts */
1615 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EWG |
1616 CAN_IT_EPV |
1617 CAN_IT_BOF |
1618 CAN_IT_LEC |
1619 CAN_IT_ERR);
1622 /* Change CAN state */
1623 if (FIFONumber == CAN_FIFO0)
1625 switch(hcan->State)
1627 case(HAL_CAN_STATE_BUSY_TX_RX0):
1628 hcan->State = HAL_CAN_STATE_BUSY_TX;
1629 break;
1630 case(HAL_CAN_STATE_BUSY_RX0_RX1):
1631 hcan->State = HAL_CAN_STATE_BUSY_RX1;
1632 break;
1633 case(HAL_CAN_STATE_BUSY_TX_RX0_RX1):
1634 hcan->State = HAL_CAN_STATE_BUSY_TX_RX1;
1635 break;
1636 default: /* HAL_CAN_STATE_BUSY_RX0 */
1637 hcan->State = HAL_CAN_STATE_READY;
1638 break;
1641 else /* FIFONumber == CAN_FIFO1 */
1643 switch(hcan->State)
1645 case(HAL_CAN_STATE_BUSY_TX_RX1):
1646 hcan->State = HAL_CAN_STATE_BUSY_TX;
1647 break;
1648 case(HAL_CAN_STATE_BUSY_RX0_RX1):
1649 hcan->State = HAL_CAN_STATE_BUSY_RX0;
1650 break;
1651 case(HAL_CAN_STATE_BUSY_TX_RX0_RX1):
1652 hcan->State = HAL_CAN_STATE_BUSY_TX_RX0;
1653 break;
1654 default: /* HAL_CAN_STATE_BUSY_RX1 */
1655 hcan->State = HAL_CAN_STATE_READY;
1656 break;
1660 /* Receive complete callback */
1661 HAL_CAN_RxCpltCallback(hcan);
1663 /* Return function status */
1664 return HAL_OK;
1668 * @}
1670 #endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F427xx || STM32F437xx ||\
1671 STM32F429xx || STM32F439xx || STM32F446xx || STM32F469xx || STM32F479xx || STM32F412Zx ||\
1672 STM32F412Vx || STM32F412Rx || STM32F412Cx || STM32F413xx || STM32F423xx */
1674 #endif /* HAL_CAN_MODULE_ENABLED */
1676 * @}
1680 * @}
1683 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/