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