2 ******************************************************************************
3 * @file stm32f4xx_hal_can.c
4 * @author MCD Application Team
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
15 ==============================================================================
16 ##### How to use this driver #####
17 ==============================================================================
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:
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 =================================
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 ===================================
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 =============================================
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
73 (@) You can refer to the CAN HAL driver header file for more useful macros
77 ******************************************************************************
80 * <h2><center>© 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
114 /** @defgroup CAN CAN
115 * @brief CAN driver modules
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) ||\
127 /* Private typedef -----------------------------------------------------------*/
128 /* Private define ------------------------------------------------------------*/
129 /** @addtogroup CAN_Private_Constants
132 #define CAN_TIMEOUT_VALUE 10U
136 /* Private macro -------------------------------------------------------------*/
137 /* Private variables ---------------------------------------------------------*/
138 /* Private function prototypes -----------------------------------------------*/
139 /** @addtogroup CAN_Private_Functions
142 static HAL_StatusTypeDef
CAN_Receive_IT(CAN_HandleTypeDef
* hcan
, uint8_t FIFONumber
);
143 static HAL_StatusTypeDef
CAN_Transmit_IT(CAN_HandleTypeDef
* hcan
);
148 /* Exported functions --------------------------------------------------------*/
149 /** @defgroup CAN_Exported_Functions CAN Exported Functions
153 /** @defgroup CAN_Exported_Functions_Group1 Initialization and de-initialization functions
154 * @brief Initialization and Configuration functions
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.
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.
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 */
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
;
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 */
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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 */
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 */
341 /* Initialize the CAN state */
342 hcan
->State
= HAL_CAN_STATE_ERROR
;
344 /* Return function status */
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.
358 HAL_StatusTypeDef
HAL_CAN_ConfigFilter(CAN_HandleTypeDef
* hcan
, CAN_FilterConfTypeDef
* sFilterConfig
)
360 uint32_t filternbrbitpos
= 0U;
363 /* Prevent unused argument(s) compilation warning */
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
;
376 /* Check the CAN instance */
377 if(hcan
->Instance
== CAN3
)
389 /* Initialisation mode for the filter */
390 can_ip
->FMR
|= (uint32_t)CAN_FMR_FINIT
;
393 /* Select the start slave bank */
394 can_ip
->FMR
&= ~((uint32_t)CAN_FMR_CAN2SB
);
395 can_ip
->FMR
|= (uint32_t)(sFilterConfig
->BankNumber
<< 8U);
398 /* Filter Deactivation */
399 can_ip
->FA1R
&= ~(uint32_t)filternbrbitpos
;
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
);
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 */
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.
479 HAL_StatusTypeDef
HAL_CAN_DeInit(CAN_HandleTypeDef
* hcan
)
481 /* Check CAN handle */
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
;
502 /* Return function status */
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.
512 __weak
void HAL_CAN_MspInit(CAN_HandleTypeDef
* hcan
)
514 /* Prevent unused argument(s) compilation warning */
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.
527 __weak
void HAL_CAN_MspDeInit(CAN_HandleTypeDef
* hcan
)
529 /* Prevent unused argument(s) compilation warning */
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
540 /** @defgroup CAN_Exported_Functions_Group2 IO operation functions
541 * @brief IO operation functions
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.
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
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
))
581 /* Change CAN state */
584 case(HAL_CAN_STATE_BUSY_RX0
):
585 hcan
->State
= HAL_CAN_STATE_BUSY_TX_RX0
;
587 case(HAL_CAN_STATE_BUSY_RX1
):
588 hcan
->State
= HAL_CAN_STATE_BUSY_TX_RX1
;
590 case(HAL_CAN_STATE_BUSY_RX0_RX1
):
591 hcan
->State
= HAL_CAN_STATE_BUSY_TX_RX0_RX1
;
593 default: /* HAL_CAN_STATE_READY */
594 hcan
->State
= HAL_CAN_STATE_BUSY_TX
;
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
;
609 transmitmailbox
= CAN_TXMAILBOX_2
;
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) | \
622 assert_param(IS_CAN_EXTID(hcan
->pTxMsg
->ExtId
));
623 hcan
->Instance
->sTxMailBox
[transmitmailbox
].TIR
|= ((hcan
->pTxMsg
->ExtId
<< 3U) | \
624 hcan
->pTxMsg
->IDE
| \
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
;
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 */
667 /* Change CAN state */
670 case(HAL_CAN_STATE_BUSY_TX_RX0
):
671 hcan
->State
= HAL_CAN_STATE_BUSY_RX0
;
673 case(HAL_CAN_STATE_BUSY_TX_RX1
):
674 hcan
->State
= HAL_CAN_STATE_BUSY_RX1
;
676 case(HAL_CAN_STATE_BUSY_TX_RX0_RX1
):
677 hcan
->State
= HAL_CAN_STATE_BUSY_RX0_RX1
;
679 default: /* HAL_CAN_STATE_BUSY_TX */
680 hcan
->State
= HAL_CAN_STATE_READY
;
684 /* Process unlocked */
687 /* Return function status */
692 /* Change CAN state */
693 hcan
->State
= HAL_CAN_STATE_ERROR
;
695 /* Return function status */
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.
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
))
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
;
733 transmitmailbox
= CAN_TXMAILBOX_2
;
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) | \
746 assert_param(IS_CAN_EXTID(hcan
->pTxMsg
->ExtId
));
747 hcan
->Instance
->sTxMailBox
[transmitmailbox
].TIR
|= ((hcan
->pTxMsg
->ExtId
<< 3U) | \
748 hcan
->pTxMsg
->IDE
| \
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 */
770 case(HAL_CAN_STATE_BUSY_RX0
):
771 hcan
->State
= HAL_CAN_STATE_BUSY_TX_RX0
;
773 case(HAL_CAN_STATE_BUSY_RX1
):
774 hcan
->State
= HAL_CAN_STATE_BUSY_TX_RX1
;
776 case(HAL_CAN_STATE_BUSY_RX0_RX1
):
777 hcan
->State
= HAL_CAN_STATE_BUSY_TX_RX0_RX1
;
779 default: /* HAL_CAN_STATE_READY */
780 hcan
->State
= HAL_CAN_STATE_BUSY_TX
;
784 /* Set CAN error code to none */
785 hcan
->ErrorCode
= HAL_CAN_ERROR_NONE
;
787 /* Process Unlocked */
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
|
804 /* Change CAN state */
805 hcan
->State
= HAL_CAN_STATE_ERROR
;
807 /* Return function status */
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
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
)))
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
)))
851 /* Change CAN state */
852 if (FIFONumber
== CAN_FIFO0
)
856 case(HAL_CAN_STATE_BUSY_TX
):
857 hcan
->State
= HAL_CAN_STATE_BUSY_TX_RX0
;
859 case(HAL_CAN_STATE_BUSY_RX1
):
860 hcan
->State
= HAL_CAN_STATE_BUSY_RX0_RX1
;
862 case(HAL_CAN_STATE_BUSY_TX_RX1
):
863 hcan
->State
= HAL_CAN_STATE_BUSY_TX_RX0_RX1
;
865 default: /* HAL_CAN_STATE_READY */
866 hcan
->State
= HAL_CAN_STATE_BUSY_RX0
;
870 else /* FIFONumber == CAN_FIFO1 */
874 case(HAL_CAN_STATE_BUSY_TX
):
875 hcan
->State
= HAL_CAN_STATE_BUSY_TX_RX1
;
877 case(HAL_CAN_STATE_BUSY_RX0
):
878 hcan
->State
= HAL_CAN_STATE_BUSY_RX0_RX1
;
880 case(HAL_CAN_STATE_BUSY_TX_RX0
):
881 hcan
->State
= HAL_CAN_STATE_BUSY_TX_RX0_RX1
;
883 default: /* HAL_CAN_STATE_READY */
884 hcan
->State
= HAL_CAN_STATE_BUSY_RX1
;
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 */
908 /* Set RxMsg pointer */
909 if(FIFONumber
== CAN_FIFO0
)
911 pRxMsg
= hcan
->pRxMsg
;
913 else /* FIFONumber == CAN_FIFO1 */
915 pRxMsg
= hcan
->pRx1Msg
;
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);
926 pRxMsg
->ExtId
= 0x1FFFFFFFU
& (hcan
->Instance
->sFIFOMailBox
[FIFONumber
].RIR
>> 3U);
929 pRxMsg
->RTR
= (uint8_t)0x02 & hcan
->Instance
->sFIFOMailBox
[FIFONumber
].RIR
;
931 pRxMsg
->DLC
= (uint8_t)0x0F & hcan
->Instance
->sFIFOMailBox
[FIFONumber
].RDTR
;
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
)
950 __HAL_CAN_FIFO_RELEASE(hcan
, CAN_FIFO0
);
952 else /* FIFONumber == CAN_FIFO1 */
955 __HAL_CAN_FIFO_RELEASE(hcan
, CAN_FIFO1
);
958 /* Change CAN state */
959 if (FIFONumber
== CAN_FIFO0
)
963 case(HAL_CAN_STATE_BUSY_TX_RX0
):
964 hcan
->State
= HAL_CAN_STATE_BUSY_TX
;
966 case(HAL_CAN_STATE_BUSY_RX0_RX1
):
967 hcan
->State
= HAL_CAN_STATE_BUSY_RX1
;
969 case(HAL_CAN_STATE_BUSY_TX_RX0_RX1
):
970 hcan
->State
= HAL_CAN_STATE_BUSY_TX_RX1
;
972 default: /* HAL_CAN_STATE_BUSY_RX0 */
973 hcan
->State
= HAL_CAN_STATE_READY
;
977 else /* FIFONumber == CAN_FIFO1 */
981 case(HAL_CAN_STATE_BUSY_TX_RX1
):
982 hcan
->State
= HAL_CAN_STATE_BUSY_TX
;
984 case(HAL_CAN_STATE_BUSY_RX0_RX1
):
985 hcan
->State
= HAL_CAN_STATE_BUSY_RX0
;
987 case(HAL_CAN_STATE_BUSY_TX_RX0_RX1
):
988 hcan
->State
= HAL_CAN_STATE_BUSY_TX_RX0
;
990 default: /* HAL_CAN_STATE_BUSY_RX1 */
991 hcan
->State
= HAL_CAN_STATE_READY
;
996 /* Process unlocked */
999 /* Return function status */
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
)))
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
)))
1033 /* Process locked */
1036 /* Change CAN state */
1037 if(FIFONumber
== CAN_FIFO0
)
1041 case(HAL_CAN_STATE_BUSY_TX
):
1042 hcan
->State
= HAL_CAN_STATE_BUSY_TX_RX0
;
1044 case(HAL_CAN_STATE_BUSY_RX1
):
1045 hcan
->State
= HAL_CAN_STATE_BUSY_RX0_RX1
;
1047 case(HAL_CAN_STATE_BUSY_TX_RX1
):
1048 hcan
->State
= HAL_CAN_STATE_BUSY_TX_RX0_RX1
;
1050 default: /* HAL_CAN_STATE_READY */
1051 hcan
->State
= HAL_CAN_STATE_BUSY_RX0
;
1055 else /* FIFONumber == CAN_FIFO1 */
1059 case(HAL_CAN_STATE_BUSY_TX
):
1060 hcan
->State
= HAL_CAN_STATE_BUSY_TX_RX1
;
1062 case(HAL_CAN_STATE_BUSY_RX0
):
1063 hcan
->State
= HAL_CAN_STATE_BUSY_RX0_RX1
;
1065 case(HAL_CAN_STATE_BUSY_TX_RX0
):
1066 hcan
->State
= HAL_CAN_STATE_BUSY_TX_RX0_RX1
;
1068 default: /* HAL_CAN_STATE_READY */
1069 hcan
->State
= HAL_CAN_STATE_BUSY_RX1
;
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
|
1090 /* Process unlocked */
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
);
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 */
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 */
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 */
1133 /* Return function status */
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 */
1152 /* Change CAN state */
1153 hcan
->State
= HAL_CAN_STATE_READY
;
1155 /* Process unlocked */
1158 /* Return function status */
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 */
1176 /* Change CAN state */
1177 hcan
->State
= HAL_CAN_STATE_BUSY
;
1179 /* Wake up request */
1180 hcan
->Instance
->MCR
&= ~(uint32_t)CAN_MCR_SLEEP
;
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 */
1196 if((hcan
->Instance
->MSR
& CAN_MSR_SLAK
) == CAN_MSR_SLAK
)
1198 /* Process unlocked */
1201 /* Return function status */
1205 /* Change CAN state */
1206 hcan
->State
= HAL_CAN_STATE_READY
;
1208 /* Process unlocked */
1211 /* Return function status */
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.
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
);
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
);
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
;
1339 case(CAN_ESR_LEC_0
):
1340 /* Set CAN error code to STF error */
1341 hcan
->ErrorCode
|= HAL_CAN_ERROR_STF
;
1343 case(CAN_ESR_LEC_1
):
1344 /* Set CAN error code to FOR error */
1345 hcan
->ErrorCode
|= HAL_CAN_ERROR_FOR
;
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
;
1351 case(CAN_ESR_LEC_2
):
1352 /* Set CAN error code to BR error */
1353 hcan
->ErrorCode
|= HAL_CAN_ERROR_BR
;
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
;
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
;
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
|
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.
1412 __weak
void HAL_CAN_TxCpltCallback(CAN_HandleTypeDef
* hcan
)
1414 /* Prevent unused argument(s) compilation warning */
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.
1427 __weak
void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef
* hcan
)
1429 /* Prevent unused argument(s) compilation warning */
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.
1442 __weak
void HAL_CAN_ErrorCallback(CAN_HandleTypeDef
*hcan
)
1444 /* Prevent unused argument(s) compilation warning */
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
1455 /** @defgroup CAN_Exported_Functions_Group3 Peripheral State and Error functions
1456 * @brief CAN Peripheral State functions
1459 ==============================================================================
1460 ##### Peripheral State and Error functions #####
1461 ==============================================================================
1463 This subsection provides functions allowing to :
1464 (+) Check the CAN state.
1465 (+) Check CAN Errors detected during interrupt process
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.
1477 HAL_CAN_StateTypeDef
HAL_CAN_GetState(CAN_HandleTypeDef
* hcan
)
1479 /* Return CAN 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
;
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
|
1519 /* Change CAN state */
1522 case(HAL_CAN_STATE_BUSY_TX_RX0
):
1523 hcan
->State
= HAL_CAN_STATE_BUSY_RX0
;
1525 case(HAL_CAN_STATE_BUSY_TX_RX1
):
1526 hcan
->State
= HAL_CAN_STATE_BUSY_RX1
;
1528 case(HAL_CAN_STATE_BUSY_TX_RX0_RX1
):
1529 hcan
->State
= HAL_CAN_STATE_BUSY_RX0_RX1
;
1531 default: /* HAL_CAN_STATE_BUSY_TX */
1532 hcan
->State
= HAL_CAN_STATE_READY
;
1536 /* Transmission complete callback */
1537 HAL_CAN_TxCpltCallback(hcan
);
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
1550 static HAL_StatusTypeDef
CAN_Receive_IT(CAN_HandleTypeDef
* hcan
, uint8_t FIFONumber
)
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
;
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);
1573 pRxMsg
->ExtId
= 0x1FFFFFFFU
& (hcan
->Instance
->sFIFOMailBox
[FIFONumber
].RIR
>> 3U);
1576 pRxMsg
->RTR
= (uint8_t)0x02 & hcan
->Instance
->sFIFOMailBox
[FIFONumber
].RIR
;
1578 pRxMsg
->DLC
= (uint8_t)0x0F & hcan
->Instance
->sFIFOMailBox
[FIFONumber
].RDTR
;
1579 /* Get the FIFONumber */
1580 pRxMsg
->FIFONumber
= FIFONumber
;
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 */
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
);
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
);
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
|
1622 /* Change CAN state */
1623 if (FIFONumber
== CAN_FIFO0
)
1627 case(HAL_CAN_STATE_BUSY_TX_RX0
):
1628 hcan
->State
= HAL_CAN_STATE_BUSY_TX
;
1630 case(HAL_CAN_STATE_BUSY_RX0_RX1
):
1631 hcan
->State
= HAL_CAN_STATE_BUSY_RX1
;
1633 case(HAL_CAN_STATE_BUSY_TX_RX0_RX1
):
1634 hcan
->State
= HAL_CAN_STATE_BUSY_TX_RX1
;
1636 default: /* HAL_CAN_STATE_BUSY_RX0 */
1637 hcan
->State
= HAL_CAN_STATE_READY
;
1641 else /* FIFONumber == CAN_FIFO1 */
1645 case(HAL_CAN_STATE_BUSY_TX_RX1
):
1646 hcan
->State
= HAL_CAN_STATE_BUSY_TX
;
1648 case(HAL_CAN_STATE_BUSY_RX0_RX1
):
1649 hcan
->State
= HAL_CAN_STATE_BUSY_RX0
;
1651 case(HAL_CAN_STATE_BUSY_TX_RX0_RX1
):
1652 hcan
->State
= HAL_CAN_STATE_BUSY_TX_RX0
;
1654 default: /* HAL_CAN_STATE_BUSY_RX1 */
1655 hcan
->State
= HAL_CAN_STATE_READY
;
1660 /* Receive complete callback */
1661 HAL_CAN_RxCpltCallback(hcan
);
1663 /* Return function status */
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 */
1683 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/