2 ******************************************************************************
\r
3 * @file stm32f7xx_hal_can.c
\r
4 * @author MCD Application Team
\r
6 * @date 06-March-2015
\r
7 * @brief CAN HAL module driver.
\r
9 * This file provides firmware functions to manage the following
\r
10 * functionalities of the Controller Area Network (CAN) peripheral:
\r
11 * + Initialization and de-initialization functions
\r
12 * + IO operation functions
\r
13 * + Peripheral Control functions
\r
14 * + Peripheral State and Error functions
\r
17 ==============================================================================
\r
18 ##### How to use this driver #####
\r
19 ==============================================================================
\r
21 (#) Enable the CAN controller interface clock using
\r
22 __HAL_RCC_CAN1_CLK_ENABLE() for CAN1 and __HAL_RCC_CAN1_CLK_ENABLE() for CAN2
\r
23 -@- In case you are using CAN2 only, you have to enable the CAN1 clock.
\r
25 (#) CAN pins configuration
\r
26 (++) Enable the clock for the CAN GPIOs using the following function:
\r
27 __HAL_RCC_GPIOx_CLK_ENABLE()
\r
28 (++) Connect and configure the involved CAN pins to AF9 using the
\r
29 following function HAL_GPIO_Init()
\r
31 (#) Initialize and configure the CAN using HAL_CAN_Init() function.
\r
33 (#) Transmit the desired CAN frame using HAL_CAN_Transmit() function.
\r
35 (#) Receive a CAN frame using HAL_CAN_Receive() function.
\r
37 *** Polling mode IO operation ***
\r
38 =================================
\r
40 (+) Start the CAN peripheral transmission and wait the end of this operation
\r
41 using HAL_CAN_Transmit(), at this stage user can specify the value of timeout
\r
42 according to his end application
\r
43 (+) Start the CAN peripheral reception and wait the end of this operation
\r
44 using HAL_CAN_Receive(), at this stage user can specify the value of timeout
\r
45 according to his end application
\r
47 *** Interrupt mode IO operation ***
\r
48 ===================================
\r
50 (+) Start the CAN peripheral transmission using HAL_CAN_Transmit_IT()
\r
51 (+) Start the CAN peripheral reception using HAL_CAN_Receive_IT()
\r
52 (+) Use HAL_CAN_IRQHandler() called under the used CAN Interrupt subroutine
\r
53 (+) At CAN end of transmission HAL_CAN_TxCpltCallback() function is executed and user can
\r
54 add his own code by customization of function pointer HAL_CAN_TxCpltCallback
\r
55 (+) In case of CAN Error, HAL_CAN_ErrorCallback() function is executed and user can
\r
56 add his own code by customization of function pointer HAL_CAN_ErrorCallback
\r
58 *** CAN HAL driver macros list ***
\r
59 =============================================
\r
61 Below the list of most used macros in CAN HAL driver.
\r
63 (+) __HAL_CAN_ENABLE_IT: Enable the specified CAN interrupts
\r
64 (+) __HAL_CAN_DISABLE_IT: Disable the specified CAN interrupts
\r
65 (+) __HAL_CAN_GET_IT_SOURCE: Check if the specified CAN interrupt source is enabled or disabled
\r
66 (+) __HAL_CAN_CLEAR_FLAG: Clear the CAN's pending flags
\r
67 (+) __HAL_CAN_GET_FLAG: Get the selected CAN's flag status
\r
70 (@) You can refer to the CAN HAL driver header file for more useful macros
\r
74 ******************************************************************************
\r
77 * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
\r
79 * Redistribution and use in source and binary forms, with or without modification,
\r
80 * are permitted provided that the following conditions are met:
\r
81 * 1. Redistributions of source code must retain the above copyright notice,
\r
82 * this list of conditions and the following disclaimer.
\r
83 * 2. Redistributions in binary form must reproduce the above copyright notice,
\r
84 * this list of conditions and the following disclaimer in the documentation
\r
85 * and/or other materials provided with the distribution.
\r
86 * 3. Neither the name of STMicroelectronics nor the names of its contributors
\r
87 * may be used to endorse or promote products derived from this software
\r
88 * without specific prior written permission.
\r
90 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
\r
91 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
\r
92 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
\r
93 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
\r
94 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
\r
95 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
\r
96 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
\r
97 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
\r
98 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
\r
99 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\r
101 ******************************************************************************
\r
104 /* Includes ------------------------------------------------------------------*/
\r
105 #include "stm32f7xx_hal.h"
\r
107 /** @addtogroup STM32F7xx_HAL_Driver
\r
111 /** @defgroup CAN CAN
\r
112 * @brief CAN driver modules
\r
116 #ifdef HAL_CAN_MODULE_ENABLED
\r
119 /* Private typedef -----------------------------------------------------------*/
\r
120 /* Private define ------------------------------------------------------------*/
\r
121 /** @addtogroup CAN_Private_Constants
\r
124 #define CAN_TIMEOUT_VALUE 10
\r
128 /* Private macro -------------------------------------------------------------*/
\r
129 /* Private variables ---------------------------------------------------------*/
\r
130 /* Private function prototypes -----------------------------------------------*/
\r
131 /** @addtogroup CAN_Private_Functions
\r
134 static HAL_StatusTypeDef CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber);
\r
135 static HAL_StatusTypeDef CAN_Transmit_IT(CAN_HandleTypeDef* hcan);
\r
140 /* Exported functions --------------------------------------------------------*/
\r
141 /** @defgroup CAN_Exported_Functions CAN Exported Functions
\r
145 /** @defgroup CAN_Exported_Functions_Group1 Initialization and de-initialization functions
\r
146 * @brief Initialization and Configuration functions
\r
149 ==============================================================================
\r
150 ##### Initialization and de-initialization functions #####
\r
151 ==============================================================================
\r
152 [..] This section provides functions allowing to:
\r
153 (+) Initialize and configure the CAN.
\r
154 (+) De-initialize the CAN.
\r
161 * @brief Initializes the CAN peripheral according to the specified
\r
162 * parameters in the CAN_InitStruct.
\r
163 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
\r
164 * the configuration information for the specified CAN.
\r
165 * @retval HAL status
\r
167 HAL_StatusTypeDef HAL_CAN_Init(CAN_HandleTypeDef* hcan)
\r
169 uint32_t InitStatus = 3;
\r
170 uint32_t tickstart = 0;
\r
172 /* Check CAN handle */
\r
178 /* Check the parameters */
\r
179 assert_param(IS_CAN_ALL_INSTANCE(hcan->Instance));
\r
180 assert_param(IS_FUNCTIONAL_STATE(hcan->Init.TTCM));
\r
181 assert_param(IS_FUNCTIONAL_STATE(hcan->Init.ABOM));
\r
182 assert_param(IS_FUNCTIONAL_STATE(hcan->Init.AWUM));
\r
183 assert_param(IS_FUNCTIONAL_STATE(hcan->Init.NART));
\r
184 assert_param(IS_FUNCTIONAL_STATE(hcan->Init.RFLM));
\r
185 assert_param(IS_FUNCTIONAL_STATE(hcan->Init.TXFP));
\r
186 assert_param(IS_CAN_MODE(hcan->Init.Mode));
\r
187 assert_param(IS_CAN_SJW(hcan->Init.SJW));
\r
188 assert_param(IS_CAN_BS1(hcan->Init.BS1));
\r
189 assert_param(IS_CAN_BS2(hcan->Init.BS2));
\r
190 assert_param(IS_CAN_PRESCALER(hcan->Init.Prescaler));
\r
193 if(hcan->State == HAL_CAN_STATE_RESET)
\r
195 /* Init the low level hardware */
\r
196 HAL_CAN_MspInit(hcan);
\r
199 /* Initialize the CAN state*/
\r
200 hcan->State = HAL_CAN_STATE_BUSY;
\r
202 /* Exit from sleep mode */
\r
203 hcan->Instance->MCR &= (~(uint32_t)CAN_MCR_SLEEP);
\r
205 /* Request initialisation */
\r
206 hcan->Instance->MCR |= CAN_MCR_INRQ ;
\r
209 tickstart = HAL_GetTick();
\r
211 /* Wait the acknowledge */
\r
212 while((hcan->Instance->MSR & CAN_MSR_INAK) != CAN_MSR_INAK)
\r
214 if((HAL_GetTick() - tickstart ) > CAN_TIMEOUT_VALUE)
\r
216 hcan->State= HAL_CAN_STATE_TIMEOUT;
\r
217 /* Process unlocked */
\r
218 __HAL_UNLOCK(hcan);
\r
219 return HAL_TIMEOUT;
\r
223 /* Check acknowledge */
\r
224 if ((hcan->Instance->MSR & CAN_MSR_INAK) != CAN_MSR_INAK)
\r
226 InitStatus = CAN_INITSTATUS_FAILED;
\r
230 /* Set the time triggered communication mode */
\r
231 if (hcan->Init.TTCM == ENABLE)
\r
233 hcan->Instance->MCR |= CAN_MCR_TTCM;
\r
237 hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_TTCM;
\r
240 /* Set the automatic bus-off management */
\r
241 if (hcan->Init.ABOM == ENABLE)
\r
243 hcan->Instance->MCR |= CAN_MCR_ABOM;
\r
247 hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_ABOM;
\r
250 /* Set the automatic wake-up mode */
\r
251 if (hcan->Init.AWUM == ENABLE)
\r
253 hcan->Instance->MCR |= CAN_MCR_AWUM;
\r
257 hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_AWUM;
\r
260 /* Set the no automatic retransmission */
\r
261 if (hcan->Init.NART == ENABLE)
\r
263 hcan->Instance->MCR |= CAN_MCR_NART;
\r
267 hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_NART;
\r
270 /* Set the receive FIFO locked mode */
\r
271 if (hcan->Init.RFLM == ENABLE)
\r
273 hcan->Instance->MCR |= CAN_MCR_RFLM;
\r
277 hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_RFLM;
\r
280 /* Set the transmit FIFO priority */
\r
281 if (hcan->Init.TXFP == ENABLE)
\r
283 hcan->Instance->MCR |= CAN_MCR_TXFP;
\r
287 hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_TXFP;
\r
290 /* Set the bit timing register */
\r
291 hcan->Instance->BTR = (uint32_t)((uint32_t)hcan->Init.Mode) | \
\r
292 ((uint32_t)hcan->Init.SJW) | \
\r
293 ((uint32_t)hcan->Init.BS1) | \
\r
294 ((uint32_t)hcan->Init.BS2) | \
\r
295 ((uint32_t)hcan->Init.Prescaler - 1);
\r
297 /* Request leave initialisation */
\r
298 hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_INRQ;
\r
301 tickstart = HAL_GetTick();
\r
303 /* Wait the acknowledge */
\r
304 while((hcan->Instance->MSR & CAN_MSR_INAK) == CAN_MSR_INAK)
\r
306 if((HAL_GetTick() - tickstart ) > CAN_TIMEOUT_VALUE)
\r
308 hcan->State= HAL_CAN_STATE_TIMEOUT;
\r
309 /* Process unlocked */
\r
310 __HAL_UNLOCK(hcan);
\r
311 return HAL_TIMEOUT;
\r
315 /* Check acknowledged */
\r
316 if ((hcan->Instance->MSR & CAN_MSR_INAK) == CAN_MSR_INAK)
\r
318 InitStatus = CAN_INITSTATUS_FAILED;
\r
322 InitStatus = CAN_INITSTATUS_SUCCESS;
\r
326 if(InitStatus == CAN_INITSTATUS_SUCCESS)
\r
328 /* Set CAN error code to none */
\r
329 hcan->ErrorCode = HAL_CAN_ERROR_NONE;
\r
331 /* Initialize the CAN state */
\r
332 hcan->State = HAL_CAN_STATE_READY;
\r
334 /* Return function status */
\r
339 /* Initialize the CAN state */
\r
340 hcan->State = HAL_CAN_STATE_ERROR;
\r
342 /* Return function status */
\r
348 * @brief Configures the CAN reception filter according to the specified
\r
349 * parameters in the CAN_FilterInitStruct.
\r
350 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
\r
351 * the configuration information for the specified CAN.
\r
352 * @param sFilterConfig: pointer to a CAN_FilterConfTypeDef structure that
\r
353 * contains the filter configuration information.
\r
356 HAL_StatusTypeDef HAL_CAN_ConfigFilter(CAN_HandleTypeDef* hcan, CAN_FilterConfTypeDef* sFilterConfig)
\r
358 uint32_t filternbrbitpos = 0;
\r
360 /* Check the parameters */
\r
361 assert_param(IS_CAN_FILTER_NUMBER(sFilterConfig->FilterNumber));
\r
362 assert_param(IS_CAN_FILTER_MODE(sFilterConfig->FilterMode));
\r
363 assert_param(IS_CAN_FILTER_SCALE(sFilterConfig->FilterScale));
\r
364 assert_param(IS_CAN_FILTER_FIFO(sFilterConfig->FilterFIFOAssignment));
\r
365 assert_param(IS_FUNCTIONAL_STATE(sFilterConfig->FilterActivation));
\r
366 assert_param(IS_CAN_BANKNUMBER(sFilterConfig->BankNumber));
\r
368 filternbrbitpos = ((uint32_t)1) << sFilterConfig->FilterNumber;
\r
370 /* Initialisation mode for the filter */
\r
371 CAN1->FMR |= (uint32_t)CAN_FMR_FINIT;
\r
373 /* Select the start slave bank */
\r
374 CAN1->FMR &= ~((uint32_t)CAN_FMR_CAN2SB);
\r
375 CAN1->FMR |= (uint32_t)(sFilterConfig->BankNumber << 8);
\r
377 /* Filter Deactivation */
\r
378 CAN1->FA1R &= ~(uint32_t)filternbrbitpos;
\r
381 if (sFilterConfig->FilterScale == CAN_FILTERSCALE_16BIT)
\r
383 /* 16-bit scale for the filter */
\r
384 CAN1->FS1R &= ~(uint32_t)filternbrbitpos;
\r
386 /* First 16-bit identifier and First 16-bit mask */
\r
387 /* Or First 16-bit identifier and Second 16-bit identifier */
\r
388 CAN1->sFilterRegister[sFilterConfig->FilterNumber].FR1 =
\r
389 ((0x0000FFFF & (uint32_t)sFilterConfig->FilterMaskIdLow) << 16) |
\r
390 (0x0000FFFF & (uint32_t)sFilterConfig->FilterIdLow);
\r
392 /* Second 16-bit identifier and Second 16-bit mask */
\r
393 /* Or Third 16-bit identifier and Fourth 16-bit identifier */
\r
394 CAN1->sFilterRegister[sFilterConfig->FilterNumber].FR2 =
\r
395 ((0x0000FFFF & (uint32_t)sFilterConfig->FilterMaskIdHigh) << 16) |
\r
396 (0x0000FFFF & (uint32_t)sFilterConfig->FilterIdHigh);
\r
399 if (sFilterConfig->FilterScale == CAN_FILTERSCALE_32BIT)
\r
401 /* 32-bit scale for the filter */
\r
402 CAN1->FS1R |= filternbrbitpos;
\r
403 /* 32-bit identifier or First 32-bit identifier */
\r
404 CAN1->sFilterRegister[sFilterConfig->FilterNumber].FR1 =
\r
405 ((0x0000FFFF & (uint32_t)sFilterConfig->FilterIdHigh) << 16) |
\r
406 (0x0000FFFF & (uint32_t)sFilterConfig->FilterIdLow);
\r
407 /* 32-bit mask or Second 32-bit identifier */
\r
408 CAN1->sFilterRegister[sFilterConfig->FilterNumber].FR2 =
\r
409 ((0x0000FFFF & (uint32_t)sFilterConfig->FilterMaskIdHigh) << 16) |
\r
410 (0x0000FFFF & (uint32_t)sFilterConfig->FilterMaskIdLow);
\r
414 if (sFilterConfig->FilterMode == CAN_FILTERMODE_IDMASK)
\r
416 /*Id/Mask mode for the filter*/
\r
417 CAN1->FM1R &= ~(uint32_t)filternbrbitpos;
\r
419 else /* CAN_FilterInitStruct->CAN_FilterMode == CAN_FilterMode_IdList */
\r
421 /*Identifier list mode for the filter*/
\r
422 CAN1->FM1R |= (uint32_t)filternbrbitpos;
\r
425 /* Filter FIFO assignment */
\r
426 if (sFilterConfig->FilterFIFOAssignment == CAN_FILTER_FIFO0)
\r
428 /* FIFO 0 assignation for the filter */
\r
429 CAN1->FFA1R &= ~(uint32_t)filternbrbitpos;
\r
432 if (sFilterConfig->FilterFIFOAssignment == CAN_FILTER_FIFO1)
\r
434 /* FIFO 1 assignation for the filter */
\r
435 CAN1->FFA1R |= (uint32_t)filternbrbitpos;
\r
438 /* Filter activation */
\r
439 if (sFilterConfig->FilterActivation == ENABLE)
\r
441 CAN1->FA1R |= filternbrbitpos;
\r
444 /* Leave the initialisation mode for the filter */
\r
445 CAN1->FMR &= ~((uint32_t)CAN_FMR_FINIT);
\r
447 /* Return function status */
\r
452 * @brief Deinitializes the CANx peripheral registers to their default reset values.
\r
453 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
\r
454 * the configuration information for the specified CAN.
\r
455 * @retval HAL status
\r
457 HAL_StatusTypeDef HAL_CAN_DeInit(CAN_HandleTypeDef* hcan)
\r
459 /* Check CAN handle */
\r
465 /* Check the parameters */
\r
466 assert_param(IS_CAN_ALL_INSTANCE(hcan->Instance));
\r
468 /* Change CAN state */
\r
469 hcan->State = HAL_CAN_STATE_BUSY;
\r
471 /* DeInit the low level hardware */
\r
472 HAL_CAN_MspDeInit(hcan);
\r
474 /* Change CAN state */
\r
475 hcan->State = HAL_CAN_STATE_RESET;
\r
478 __HAL_UNLOCK(hcan);
\r
480 /* Return function status */
\r
485 * @brief Initializes the CAN MSP.
\r
486 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
\r
487 * the configuration information for the specified CAN.
\r
490 __weak void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan)
\r
492 /* NOTE : This function Should not be modified, when the callback is needed,
\r
493 the HAL_CAN_MspInit could be implemented in the user file
\r
498 * @brief DeInitializes the CAN MSP.
\r
499 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
\r
500 * the configuration information for the specified CAN.
\r
503 __weak void HAL_CAN_MspDeInit(CAN_HandleTypeDef* hcan)
\r
505 /* NOTE : This function Should not be modified, when the callback is needed,
\r
506 the HAL_CAN_MspDeInit could be implemented in the user file
\r
514 /** @defgroup CAN_Exported_Functions_Group2 IO operation functions
\r
515 * @brief IO operation functions
\r
518 ==============================================================================
\r
519 ##### IO operation functions #####
\r
520 ==============================================================================
\r
521 [..] This section provides functions allowing to:
\r
522 (+) Transmit a CAN frame message.
\r
523 (+) Receive a CAN frame message.
\r
524 (+) Enter CAN peripheral in sleep mode.
\r
525 (+) Wake up the CAN peripheral from sleep mode.
\r
532 * @brief Initiates and transmits a CAN frame message.
\r
533 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
\r
534 * the configuration information for the specified CAN.
\r
535 * @param Timeout: Specify Timeout value
\r
536 * @retval HAL status
\r
538 HAL_StatusTypeDef HAL_CAN_Transmit(CAN_HandleTypeDef* hcan, uint32_t Timeout)
\r
540 uint32_t transmitmailbox = 5;
\r
541 uint32_t tickstart = 0;
\r
543 /* Check the parameters */
\r
544 assert_param(IS_CAN_IDTYPE(hcan->pTxMsg->IDE));
\r
545 assert_param(IS_CAN_RTR(hcan->pTxMsg->RTR));
\r
546 assert_param(IS_CAN_DLC(hcan->pTxMsg->DLC));
\r
548 /* Process locked */
\r
551 if(hcan->State == HAL_CAN_STATE_BUSY_RX)
\r
553 /* Change CAN state */
\r
554 hcan->State = HAL_CAN_STATE_BUSY_TX_RX;
\r
558 /* Change CAN state */
\r
559 hcan->State = HAL_CAN_STATE_BUSY_TX;
\r
562 /* Select one empty transmit mailbox */
\r
563 if ((hcan->Instance->TSR&CAN_TSR_TME0) == CAN_TSR_TME0)
\r
565 transmitmailbox = 0;
\r
567 else if ((hcan->Instance->TSR&CAN_TSR_TME1) == CAN_TSR_TME1)
\r
569 transmitmailbox = 1;
\r
571 else if ((hcan->Instance->TSR&CAN_TSR_TME2) == CAN_TSR_TME2)
\r
573 transmitmailbox = 2;
\r
577 transmitmailbox = CAN_TXSTATUS_NOMAILBOX;
\r
580 if (transmitmailbox != CAN_TXSTATUS_NOMAILBOX)
\r
582 /* Set up the Id */
\r
583 hcan->Instance->sTxMailBox[transmitmailbox].TIR &= CAN_TI0R_TXRQ;
\r
584 if (hcan->pTxMsg->IDE == CAN_ID_STD)
\r
586 assert_param(IS_CAN_STDID(hcan->pTxMsg->StdId));
\r
587 hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->StdId << 21) | \
\r
588 hcan->pTxMsg->RTR);
\r
592 assert_param(IS_CAN_EXTID(hcan->pTxMsg->ExtId));
\r
593 hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->ExtId << 3) | \
\r
594 hcan->pTxMsg->IDE | \
\r
595 hcan->pTxMsg->RTR);
\r
598 /* Set up the DLC */
\r
599 hcan->pTxMsg->DLC &= (uint8_t)0x0000000F;
\r
600 hcan->Instance->sTxMailBox[transmitmailbox].TDTR &= (uint32_t)0xFFFFFFF0;
\r
601 hcan->Instance->sTxMailBox[transmitmailbox].TDTR |= hcan->pTxMsg->DLC;
\r
603 /* Set up the data field */
\r
604 hcan->Instance->sTxMailBox[transmitmailbox].TDLR = (((uint32_t)hcan->pTxMsg->Data[3] << 24) |
\r
605 ((uint32_t)hcan->pTxMsg->Data[2] << 16) |
\r
606 ((uint32_t)hcan->pTxMsg->Data[1] << 8) |
\r
607 ((uint32_t)hcan->pTxMsg->Data[0]));
\r
608 hcan->Instance->sTxMailBox[transmitmailbox].TDHR = (((uint32_t)hcan->pTxMsg->Data[7] << 24) |
\r
609 ((uint32_t)hcan->pTxMsg->Data[6] << 16) |
\r
610 ((uint32_t)hcan->pTxMsg->Data[5] << 8) |
\r
611 ((uint32_t)hcan->pTxMsg->Data[4]));
\r
612 /* Request transmission */
\r
613 hcan->Instance->sTxMailBox[transmitmailbox].TIR |= CAN_TI0R_TXRQ;
\r
616 tickstart = HAL_GetTick();
\r
618 /* Check End of transmission flag */
\r
619 while(!(__HAL_CAN_TRANSMIT_STATUS(hcan, transmitmailbox)))
\r
621 /* Check for the Timeout */
\r
622 if(Timeout != HAL_MAX_DELAY)
\r
624 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
\r
626 hcan->State = HAL_CAN_STATE_TIMEOUT;
\r
627 /* Process unlocked */
\r
628 __HAL_UNLOCK(hcan);
\r
629 return HAL_TIMEOUT;
\r
633 if(hcan->State == HAL_CAN_STATE_BUSY_TX_RX)
\r
635 /* Change CAN state */
\r
636 hcan->State = HAL_CAN_STATE_BUSY_RX;
\r
638 /* Process unlocked */
\r
639 __HAL_UNLOCK(hcan);
\r
643 /* Change CAN state */
\r
644 hcan->State = HAL_CAN_STATE_READY;
\r
646 /* Process unlocked */
\r
647 __HAL_UNLOCK(hcan);
\r
650 /* Return function status */
\r
655 /* Change CAN state */
\r
656 hcan->State = HAL_CAN_STATE_ERROR;
\r
658 /* Process unlocked */
\r
659 __HAL_UNLOCK(hcan);
\r
661 /* Return function status */
\r
667 * @brief Initiates and transmits a CAN frame message.
\r
668 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
\r
669 * the configuration information for the specified CAN.
\r
670 * @retval HAL status
\r
672 HAL_StatusTypeDef HAL_CAN_Transmit_IT(CAN_HandleTypeDef* hcan)
\r
674 uint32_t transmitmailbox = 5;
\r
677 /* Check the parameters */
\r
678 assert_param(IS_CAN_IDTYPE(hcan->pTxMsg->IDE));
\r
679 assert_param(IS_CAN_RTR(hcan->pTxMsg->RTR));
\r
680 assert_param(IS_CAN_DLC(hcan->pTxMsg->DLC));
\r
683 if((tmp == HAL_CAN_STATE_READY) || (tmp == HAL_CAN_STATE_BUSY_RX))
\r
685 /* Process Locked */
\r
688 /* Select one empty transmit mailbox */
\r
689 if((hcan->Instance->TSR&CAN_TSR_TME0) == CAN_TSR_TME0)
\r
691 transmitmailbox = 0;
\r
693 else if((hcan->Instance->TSR&CAN_TSR_TME1) == CAN_TSR_TME1)
\r
695 transmitmailbox = 1;
\r
697 else if((hcan->Instance->TSR&CAN_TSR_TME2) == CAN_TSR_TME2)
\r
699 transmitmailbox = 2;
\r
703 transmitmailbox = CAN_TXSTATUS_NOMAILBOX;
\r
706 if(transmitmailbox != CAN_TXSTATUS_NOMAILBOX)
\r
708 /* Set up the Id */
\r
709 hcan->Instance->sTxMailBox[transmitmailbox].TIR &= CAN_TI0R_TXRQ;
\r
710 if(hcan->pTxMsg->IDE == CAN_ID_STD)
\r
712 assert_param(IS_CAN_STDID(hcan->pTxMsg->StdId));
\r
713 hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->StdId << 21) | \
\r
714 hcan->pTxMsg->RTR);
\r
718 assert_param(IS_CAN_EXTID(hcan->pTxMsg->ExtId));
\r
719 hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->ExtId << 3) | \
\r
720 hcan->pTxMsg->IDE | \
\r
721 hcan->pTxMsg->RTR);
\r
724 /* Set up the DLC */
\r
725 hcan->pTxMsg->DLC &= (uint8_t)0x0000000F;
\r
726 hcan->Instance->sTxMailBox[transmitmailbox].TDTR &= (uint32_t)0xFFFFFFF0;
\r
727 hcan->Instance->sTxMailBox[transmitmailbox].TDTR |= hcan->pTxMsg->DLC;
\r
729 /* Set up the data field */
\r
730 hcan->Instance->sTxMailBox[transmitmailbox].TDLR = (((uint32_t)hcan->pTxMsg->Data[3] << 24) |
\r
731 ((uint32_t)hcan->pTxMsg->Data[2] << 16) |
\r
732 ((uint32_t)hcan->pTxMsg->Data[1] << 8) |
\r
733 ((uint32_t)hcan->pTxMsg->Data[0]));
\r
734 hcan->Instance->sTxMailBox[transmitmailbox].TDHR = (((uint32_t)hcan->pTxMsg->Data[7] << 24) |
\r
735 ((uint32_t)hcan->pTxMsg->Data[6] << 16) |
\r
736 ((uint32_t)hcan->pTxMsg->Data[5] << 8) |
\r
737 ((uint32_t)hcan->pTxMsg->Data[4]));
\r
739 if(hcan->State == HAL_CAN_STATE_BUSY_RX)
\r
741 /* Change CAN state */
\r
742 hcan->State = HAL_CAN_STATE_BUSY_TX_RX;
\r
746 /* Change CAN state */
\r
747 hcan->State = HAL_CAN_STATE_BUSY_TX;
\r
750 /* Set CAN error code to none */
\r
751 hcan->ErrorCode = HAL_CAN_ERROR_NONE;
\r
753 /* Process Unlocked */
\r
754 __HAL_UNLOCK(hcan);
\r
756 /* Enable Error warning Interrupt */
\r
757 __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EWG);
\r
759 /* Enable Error passive Interrupt */
\r
760 __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EPV);
\r
762 /* Enable Bus-off Interrupt */
\r
763 __HAL_CAN_ENABLE_IT(hcan, CAN_IT_BOF);
\r
765 /* Enable Last error code Interrupt */
\r
766 __HAL_CAN_ENABLE_IT(hcan, CAN_IT_LEC);
\r
768 /* Enable Error Interrupt */
\r
769 __HAL_CAN_ENABLE_IT(hcan, CAN_IT_ERR);
\r
771 /* Enable Transmit mailbox empty Interrupt */
\r
772 __HAL_CAN_ENABLE_IT(hcan, CAN_IT_TME);
\r
774 /* Request transmission */
\r
775 hcan->Instance->sTxMailBox[transmitmailbox].TIR |= CAN_TI0R_TXRQ;
\r
787 * @brief Receives a correct CAN frame.
\r
788 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
\r
789 * the configuration information for the specified CAN.
\r
790 * @param FIFONumber: FIFO Number value
\r
791 * @param Timeout: Specify Timeout value
\r
792 * @retval HAL status
\r
794 HAL_StatusTypeDef HAL_CAN_Receive(CAN_HandleTypeDef* hcan, uint8_t FIFONumber, uint32_t Timeout)
\r
796 uint32_t tickstart = 0;
\r
798 /* Check the parameters */
\r
799 assert_param(IS_CAN_FIFO(FIFONumber));
\r
801 /* Process locked */
\r
804 if(hcan->State == HAL_CAN_STATE_BUSY_TX)
\r
806 /* Change CAN state */
\r
807 hcan->State = HAL_CAN_STATE_BUSY_TX_RX;
\r
811 /* Change CAN state */
\r
812 hcan->State = HAL_CAN_STATE_BUSY_RX;
\r
816 tickstart = HAL_GetTick();
\r
818 /* Check pending message */
\r
819 while(__HAL_CAN_MSG_PENDING(hcan, FIFONumber) == 0)
\r
821 /* Check for the Timeout */
\r
822 if(Timeout != HAL_MAX_DELAY)
\r
824 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
\r
826 hcan->State = HAL_CAN_STATE_TIMEOUT;
\r
827 /* Process unlocked */
\r
828 __HAL_UNLOCK(hcan);
\r
829 return HAL_TIMEOUT;
\r
835 hcan->pRxMsg->IDE = (uint8_t)0x04 & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
\r
836 if (hcan->pRxMsg->IDE == CAN_ID_STD)
\r
838 hcan->pRxMsg->StdId = (uint32_t)0x000007FF & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 21);
\r
842 hcan->pRxMsg->ExtId = (uint32_t)0x1FFFFFFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 3);
\r
845 hcan->pRxMsg->RTR = (uint8_t)0x02 & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
\r
847 hcan->pRxMsg->DLC = (uint8_t)0x0F & hcan->Instance->sFIFOMailBox[FIFONumber].RDTR;
\r
849 hcan->pRxMsg->FMI = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDTR >> 8);
\r
850 /* Get the data field */
\r
851 hcan->pRxMsg->Data[0] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR;
\r
852 hcan->pRxMsg->Data[1] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 8);
\r
853 hcan->pRxMsg->Data[2] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 16);
\r
854 hcan->pRxMsg->Data[3] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 24);
\r
855 hcan->pRxMsg->Data[4] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR;
\r
856 hcan->pRxMsg->Data[5] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 8);
\r
857 hcan->pRxMsg->Data[6] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 16);
\r
858 hcan->pRxMsg->Data[7] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 24);
\r
860 /* Release the FIFO */
\r
861 if(FIFONumber == CAN_FIFO0)
\r
863 /* Release FIFO0 */
\r
864 __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO0);
\r
866 else /* FIFONumber == CAN_FIFO1 */
\r
868 /* Release FIFO1 */
\r
869 __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO1);
\r
872 if(hcan->State == HAL_CAN_STATE_BUSY_TX_RX)
\r
874 /* Change CAN state */
\r
875 hcan->State = HAL_CAN_STATE_BUSY_TX;
\r
877 /* Process unlocked */
\r
878 __HAL_UNLOCK(hcan);
\r
882 /* Change CAN state */
\r
883 hcan->State = HAL_CAN_STATE_READY;
\r
885 /* Process unlocked */
\r
886 __HAL_UNLOCK(hcan);
\r
889 /* Return function status */
\r
894 * @brief Receives a correct CAN frame.
\r
895 * @param hcan: Pointer to a CAN_HandleTypeDef structure that contains
\r
896 * the configuration information for the specified CAN.
\r
897 * @param FIFONumber: Specify the FIFO number
\r
898 * @retval HAL status
\r
900 HAL_StatusTypeDef HAL_CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber)
\r
904 /* Check the parameters */
\r
905 assert_param(IS_CAN_FIFO(FIFONumber));
\r
908 if((tmp == HAL_CAN_STATE_READY) || (tmp == HAL_CAN_STATE_BUSY_TX))
\r
910 /* Process locked */
\r
913 if(hcan->State == HAL_CAN_STATE_BUSY_TX)
\r
915 /* Change CAN state */
\r
916 hcan->State = HAL_CAN_STATE_BUSY_TX_RX;
\r
920 /* Change CAN state */
\r
921 hcan->State = HAL_CAN_STATE_BUSY_RX;
\r
924 /* Set CAN error code to none */
\r
925 hcan->ErrorCode = HAL_CAN_ERROR_NONE;
\r
927 /* Enable Error warning Interrupt */
\r
928 __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EWG);
\r
930 /* Enable Error passive Interrupt */
\r
931 __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EPV);
\r
933 /* Enable Bus-off Interrupt */
\r
934 __HAL_CAN_ENABLE_IT(hcan, CAN_IT_BOF);
\r
936 /* Enable Last error code Interrupt */
\r
937 __HAL_CAN_ENABLE_IT(hcan, CAN_IT_LEC);
\r
939 /* Enable Error Interrupt */
\r
940 __HAL_CAN_ENABLE_IT(hcan, CAN_IT_ERR);
\r
942 /* Process unlocked */
\r
943 __HAL_UNLOCK(hcan);
\r
945 if(FIFONumber == CAN_FIFO0)
\r
947 /* Enable FIFO 0 message pending Interrupt */
\r
948 __HAL_CAN_ENABLE_IT(hcan, CAN_IT_FMP0);
\r
952 /* Enable FIFO 1 message pending Interrupt */
\r
953 __HAL_CAN_ENABLE_IT(hcan, CAN_IT_FMP1);
\r
962 /* Return function status */
\r
967 * @brief Enters the Sleep (low power) mode.
\r
968 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
\r
969 * the configuration information for the specified CAN.
\r
970 * @retval HAL status.
\r
972 HAL_StatusTypeDef HAL_CAN_Sleep(CAN_HandleTypeDef* hcan)
\r
974 uint32_t tickstart = 0;
\r
976 /* Process locked */
\r
979 /* Change CAN state */
\r
980 hcan->State = HAL_CAN_STATE_BUSY;
\r
982 /* Request Sleep mode */
\r
983 hcan->Instance->MCR = (((hcan->Instance->MCR) & (uint32_t)(~(uint32_t)CAN_MCR_INRQ)) | CAN_MCR_SLEEP);
\r
985 /* Sleep mode status */
\r
986 if ((hcan->Instance->MSR & (CAN_MSR_SLAK|CAN_MSR_INAK)) != CAN_MSR_SLAK)
\r
988 /* Process unlocked */
\r
989 __HAL_UNLOCK(hcan);
\r
991 /* Return function status */
\r
996 tickstart = HAL_GetTick();
\r
998 /* Wait the acknowledge */
\r
999 while((hcan->Instance->MSR & (CAN_MSR_SLAK|CAN_MSR_INAK)) != CAN_MSR_SLAK)
\r
1001 if((HAL_GetTick() - tickstart) > CAN_TIMEOUT_VALUE)
\r
1003 hcan->State = HAL_CAN_STATE_TIMEOUT;
\r
1004 /* Process unlocked */
\r
1005 __HAL_UNLOCK(hcan);
\r
1006 return HAL_TIMEOUT;
\r
1010 /* Change CAN state */
\r
1011 hcan->State = HAL_CAN_STATE_READY;
\r
1013 /* Process unlocked */
\r
1014 __HAL_UNLOCK(hcan);
\r
1016 /* Return function status */
\r
1021 * @brief Wakes up the CAN peripheral from sleep mode, after that the CAN peripheral
\r
1022 * is in the normal mode.
\r
1023 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
\r
1024 * the configuration information for the specified CAN.
\r
1025 * @retval HAL status.
\r
1027 HAL_StatusTypeDef HAL_CAN_WakeUp(CAN_HandleTypeDef* hcan)
\r
1029 uint32_t tickstart = 0;
\r
1031 /* Process locked */
\r
1034 /* Change CAN state */
\r
1035 hcan->State = HAL_CAN_STATE_BUSY;
\r
1037 /* Wake up request */
\r
1038 hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_SLEEP;
\r
1041 tickstart = HAL_GetTick();
\r
1043 /* Sleep mode status */
\r
1044 while((hcan->Instance->MSR & CAN_MSR_SLAK) == CAN_MSR_SLAK)
\r
1046 if((HAL_GetTick() - tickstart) > CAN_TIMEOUT_VALUE)
\r
1048 hcan->State= HAL_CAN_STATE_TIMEOUT;
\r
1049 /* Process unlocked */
\r
1050 __HAL_UNLOCK(hcan);
\r
1051 return HAL_TIMEOUT;
\r
1054 if((hcan->Instance->MSR & CAN_MSR_SLAK) == CAN_MSR_SLAK)
\r
1056 /* Process unlocked */
\r
1057 __HAL_UNLOCK(hcan);
\r
1059 /* Return function status */
\r
1063 /* Change CAN state */
\r
1064 hcan->State = HAL_CAN_STATE_READY;
\r
1066 /* Process unlocked */
\r
1067 __HAL_UNLOCK(hcan);
\r
1069 /* Return function status */
\r
1074 * @brief Handles CAN interrupt request
\r
1075 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
\r
1076 * the configuration information for the specified CAN.
\r
1079 void HAL_CAN_IRQHandler(CAN_HandleTypeDef* hcan)
\r
1081 uint32_t tmp1 = 0, tmp2 = 0, tmp3 = 0;
\r
1083 /* Check End of transmission flag */
\r
1084 if(__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_TME))
\r
1086 tmp1 = __HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_0);
\r
1087 tmp2 = __HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_1);
\r
1088 tmp3 = __HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_2);
\r
1089 if(tmp1 || tmp2 || tmp3)
\r
1091 /* Call transmit function */
\r
1092 CAN_Transmit_IT(hcan);
\r
1096 tmp1 = __HAL_CAN_MSG_PENDING(hcan, CAN_FIFO0);
\r
1097 tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FMP0);
\r
1098 /* Check End of reception flag for FIFO0 */
\r
1099 if((tmp1 != 0) && tmp2)
\r
1101 /* Call receive function */
\r
1102 CAN_Receive_IT(hcan, CAN_FIFO0);
\r
1105 tmp1 = __HAL_CAN_MSG_PENDING(hcan, CAN_FIFO1);
\r
1106 tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FMP1);
\r
1107 /* Check End of reception flag for FIFO1 */
\r
1108 if((tmp1 != 0) && tmp2)
\r
1110 /* Call receive function */
\r
1111 CAN_Receive_IT(hcan, CAN_FIFO1);
\r
1114 tmp1 = __HAL_CAN_GET_FLAG(hcan, CAN_FLAG_EWG);
\r
1115 tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_EWG);
\r
1116 tmp3 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR);
\r
1117 /* Check Error Warning Flag */
\r
1118 if(tmp1 && tmp2 && tmp3)
\r
1120 /* Set CAN error code to EWG error */
\r
1121 hcan->ErrorCode |= HAL_CAN_ERROR_EWG;
\r
1122 /* Clear Error Warning Flag */
\r
1123 __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_EWG);
\r
1126 tmp1 = __HAL_CAN_GET_FLAG(hcan, CAN_FLAG_EPV);
\r
1127 tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_EPV);
\r
1128 tmp3 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR);
\r
1129 /* Check Error Passive Flag */
\r
1130 if(tmp1 && tmp2 && tmp3)
\r
1132 /* Set CAN error code to EPV error */
\r
1133 hcan->ErrorCode |= HAL_CAN_ERROR_EPV;
\r
1134 /* Clear Error Passive Flag */
\r
1135 __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_EPV);
\r
1138 tmp1 = __HAL_CAN_GET_FLAG(hcan, CAN_FLAG_BOF);
\r
1139 tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_BOF);
\r
1140 tmp3 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR);
\r
1141 /* Check Bus-Off Flag */
\r
1142 if(tmp1 && tmp2 && tmp3)
\r
1144 /* Set CAN error code to BOF error */
\r
1145 hcan->ErrorCode |= HAL_CAN_ERROR_BOF;
\r
1146 /* Clear Bus-Off Flag */
\r
1147 __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_BOF);
\r
1150 tmp1 = HAL_IS_BIT_CLR(hcan->Instance->ESR, CAN_ESR_LEC);
\r
1151 tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_LEC);
\r
1152 tmp3 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR);
\r
1153 /* Check Last error code Flag */
\r
1154 if((!tmp1) && tmp2 && tmp3)
\r
1156 tmp1 = (hcan->Instance->ESR) & CAN_ESR_LEC;
\r
1159 case(CAN_ESR_LEC_0):
\r
1160 /* Set CAN error code to STF error */
\r
1161 hcan->ErrorCode |= HAL_CAN_ERROR_STF;
\r
1163 case(CAN_ESR_LEC_1):
\r
1164 /* Set CAN error code to FOR error */
\r
1165 hcan->ErrorCode |= HAL_CAN_ERROR_FOR;
\r
1167 case(CAN_ESR_LEC_1 | CAN_ESR_LEC_0):
\r
1168 /* Set CAN error code to ACK error */
\r
1169 hcan->ErrorCode |= HAL_CAN_ERROR_ACK;
\r
1171 case(CAN_ESR_LEC_2):
\r
1172 /* Set CAN error code to BR error */
\r
1173 hcan->ErrorCode |= HAL_CAN_ERROR_BR;
\r
1175 case(CAN_ESR_LEC_2 | CAN_ESR_LEC_0):
\r
1176 /* Set CAN error code to BD error */
\r
1177 hcan->ErrorCode |= HAL_CAN_ERROR_BD;
\r
1179 case(CAN_ESR_LEC_2 | CAN_ESR_LEC_1):
\r
1180 /* Set CAN error code to CRC error */
\r
1181 hcan->ErrorCode |= HAL_CAN_ERROR_CRC;
\r
1187 /* Clear Last error code Flag */
\r
1188 hcan->Instance->ESR &= ~(CAN_ESR_LEC);
\r
1191 /* Call the Error call Back in case of Errors */
\r
1192 if(hcan->ErrorCode != HAL_CAN_ERROR_NONE)
\r
1194 /* Set the CAN state ready to be able to start again the process */
\r
1195 hcan->State = HAL_CAN_STATE_READY;
\r
1196 /* Call Error callback function */
\r
1197 HAL_CAN_ErrorCallback(hcan);
\r
1202 * @brief Transmission complete callback in non blocking mode
\r
1203 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
\r
1204 * the configuration information for the specified CAN.
\r
1207 __weak void HAL_CAN_TxCpltCallback(CAN_HandleTypeDef* hcan)
\r
1209 /* NOTE : This function Should not be modified, when the callback is needed,
\r
1210 the HAL_CAN_TxCpltCallback could be implemented in the user file
\r
1215 * @brief Transmission complete callback in non blocking mode
\r
1216 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
\r
1217 * the configuration information for the specified CAN.
\r
1220 __weak void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* hcan)
\r
1222 /* NOTE : This function Should not be modified, when the callback is needed,
\r
1223 the HAL_CAN_RxCpltCallback could be implemented in the user file
\r
1228 * @brief Error CAN callback.
\r
1229 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
\r
1230 * the configuration information for the specified CAN.
\r
1233 __weak void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan)
\r
1235 /* NOTE : This function Should not be modified, when the callback is needed,
\r
1236 the HAL_CAN_ErrorCallback could be implemented in the user file
\r
1244 /** @defgroup CAN_Exported_Functions_Group3 Peripheral State and Error functions
\r
1245 * @brief CAN Peripheral State functions
\r
1248 ==============================================================================
\r
1249 ##### Peripheral State and Error functions #####
\r
1250 ==============================================================================
\r
1252 This subsection provides functions allowing to :
\r
1253 (+) Check the CAN state.
\r
1254 (+) Check CAN Errors detected during interrupt process
\r
1261 * @brief return the CAN state
\r
1262 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
\r
1263 * the configuration information for the specified CAN.
\r
1264 * @retval HAL state
\r
1266 HAL_CAN_StateTypeDef HAL_CAN_GetState(CAN_HandleTypeDef* hcan)
\r
1268 /* Return CAN state */
\r
1269 return hcan->State;
\r
1273 * @brief Return the CAN error code
\r
1274 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
\r
1275 * the configuration information for the specified CAN.
\r
1276 * @retval CAN Error Code
\r
1278 uint32_t HAL_CAN_GetError(CAN_HandleTypeDef *hcan)
\r
1280 return hcan->ErrorCode;
\r
1287 * @brief Initiates and transmits a CAN frame message.
\r
1288 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
\r
1289 * the configuration information for the specified CAN.
\r
1290 * @retval HAL status
\r
1292 static HAL_StatusTypeDef CAN_Transmit_IT(CAN_HandleTypeDef* hcan)
\r
1294 /* Disable Transmit mailbox empty Interrupt */
\r
1295 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_TME);
\r
1297 if(hcan->State == HAL_CAN_STATE_BUSY_TX)
\r
1299 /* Disable Error warning Interrupt */
\r
1300 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EWG);
\r
1302 /* Disable Error passive Interrupt */
\r
1303 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EPV);
\r
1305 /* Disable Bus-off Interrupt */
\r
1306 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_BOF);
\r
1308 /* Disable Last error code Interrupt */
\r
1309 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_LEC);
\r
1311 /* Disable Error Interrupt */
\r
1312 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_ERR);
\r
1315 if(hcan->State == HAL_CAN_STATE_BUSY_TX_RX)
\r
1317 /* Change CAN state */
\r
1318 hcan->State = HAL_CAN_STATE_BUSY_RX;
\r
1322 /* Change CAN state */
\r
1323 hcan->State = HAL_CAN_STATE_READY;
\r
1326 /* Transmission complete callback */
\r
1327 HAL_CAN_TxCpltCallback(hcan);
\r
1333 * @brief Receives a correct CAN frame.
\r
1334 * @param hcan: Pointer to a CAN_HandleTypeDef structure that contains
\r
1335 * the configuration information for the specified CAN.
\r
1336 * @param FIFONumber: Specify the FIFO number
\r
1337 * @retval HAL status
\r
1340 static HAL_StatusTypeDef CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber)
\r
1343 hcan->pRxMsg->IDE = (uint8_t)0x04 & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
\r
1344 if (hcan->pRxMsg->IDE == CAN_ID_STD)
\r
1346 hcan->pRxMsg->StdId = (uint32_t)0x000007FF & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 21);
\r
1350 hcan->pRxMsg->ExtId = (uint32_t)0x1FFFFFFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 3);
\r
1353 hcan->pRxMsg->RTR = (uint8_t)0x02 & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
\r
1355 hcan->pRxMsg->DLC = (uint8_t)0x0F & hcan->Instance->sFIFOMailBox[FIFONumber].RDTR;
\r
1357 hcan->pRxMsg->FMI = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDTR >> 8);
\r
1358 /* Get the data field */
\r
1359 hcan->pRxMsg->Data[0] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR;
\r
1360 hcan->pRxMsg->Data[1] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 8);
\r
1361 hcan->pRxMsg->Data[2] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 16);
\r
1362 hcan->pRxMsg->Data[3] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 24);
\r
1363 hcan->pRxMsg->Data[4] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR;
\r
1364 hcan->pRxMsg->Data[5] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 8);
\r
1365 hcan->pRxMsg->Data[6] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 16);
\r
1366 hcan->pRxMsg->Data[7] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 24);
\r
1367 /* Release the FIFO */
\r
1368 /* Release FIFO0 */
\r
1369 if (FIFONumber == CAN_FIFO0)
\r
1371 __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO0);
\r
1373 /* Disable FIFO 0 message pending Interrupt */
\r
1374 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_FMP0);
\r
1376 /* Release FIFO1 */
\r
1377 else /* FIFONumber == CAN_FIFO1 */
\r
1379 __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO1);
\r
1381 /* Disable FIFO 1 message pending Interrupt */
\r
1382 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_FMP1);
\r
1385 if(hcan->State == HAL_CAN_STATE_BUSY_RX)
\r
1387 /* Disable Error warning Interrupt */
\r
1388 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EWG);
\r
1390 /* Disable Error passive Interrupt */
\r
1391 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EPV);
\r
1393 /* Disable Bus-off Interrupt */
\r
1394 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_BOF);
\r
1396 /* Disable Last error code Interrupt */
\r
1397 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_LEC);
\r
1399 /* Disable Error Interrupt */
\r
1400 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_ERR);
\r
1403 if(hcan->State == HAL_CAN_STATE_BUSY_TX_RX)
\r
1405 /* Disable CAN state */
\r
1406 hcan->State = HAL_CAN_STATE_BUSY_TX;
\r
1410 /* Change CAN state */
\r
1411 hcan->State = HAL_CAN_STATE_READY;
\r
1414 /* Receive complete callback */
\r
1415 HAL_CAN_RxCpltCallback(hcan);
\r
1417 /* Return function status */
\r
1425 #endif /* HAL_CAN_MODULE_ENABLED */
\r
1434 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
\r