1 /**
2 ******************************************************************************
3 * @file stm32f3xx_hal_can.c
4 * @author MCD Application Team
5 * @brief This file provides firmware functions to manage the following
6 * functionalities of the Controller Area Network (CAN) peripheral:
7 * + Initialization and de-initialization functions
8 * + IO operation functions
9 * + Peripheral Control functions
10 * + Peripheral State and Error functions
11 *
12 ******************************************************************************
13 * @attention
14 *
15 * Copyright (c) 2016 STMicroelectronics.
16 * All rights reserved.
17 *
18 * This software is licensed under terms that can be found in the LICENSE file
19 * in the root directory of this software component.
20 * If no LICENSE file comes with this software, it is provided AS-IS.
21 *
22 ******************************************************************************
23 @verbatim
24 ==============================================================================
25 ##### User NOTE #####
26 ==============================================================================
27 [..]
28 (#) This HAL CAN driver is deprecated, it contains some CAN Tx/Rx FIFO management limitations.
29 Another HAL CAN driver version has been designed with new API's, to fix these limitations.
30
31 ==============================================================================
32 ##### How to use this driver #####
33 ==============================================================================
34 [..]
35 (#) Enable the CAN controller interface clock using __HAL_RCC_CAN1_CLK_ENABLE();
36
37 (#) CAN pins configuration
38 (++) Enable the clock for the CAN GPIOs using the following function:
39 __HAL_RCC_GPIOx_CLK_ENABLE();
40 (++) Connect and configure the involved CAN pins to AF9 using the
41 following function HAL_GPIO_Init();
42
43 (#) Initialise and configure the CAN using HAL_CAN_Init() function.
44
45 (#) Transmit the desired CAN frame using HAL_CAN_Transmit() function.
46
47 (#) Or transmit the desired CAN frame using HAL_CAN_Transmit_IT() function.
48
49 (#) Receive a CAN frame using HAL_CAN_Receive() function.
50
51 (#) Or receive a CAN frame using HAL_CAN_Receive_IT() function.
52
53 *** Polling mode IO operation ***
54 =================================
55 [..]
56 (+) Start the CAN peripheral transmission and wait the end of this operation
57 using HAL_CAN_Transmit(), at this stage user can specify the value of timeout
58 according to his end application
59 (+) Start the CAN peripheral reception and wait the end of this operation
60 using HAL_CAN_Receive(), at this stage user can specify the value of timeout
61 according to his end application
62
63 *** Interrupt mode IO operation ***
64 ===================================
65 [..]
66 (+) Start the CAN peripheral transmission using HAL_CAN_Transmit_IT()
67 (+) Start the CAN peripheral reception using HAL_CAN_Receive_IT()
68 (+) Use HAL_CAN_IRQHandler() called under the used CAN Interrupt subroutine
69 (+) At CAN end of transmission HAL_CAN_TxCpltCallback() function is executed and user can
70 add his own code by customization of function pointer HAL_CAN_TxCpltCallback
71 (+) In case of CAN Error, HAL_CAN_ErrorCallback() function is executed and user can
72 add his own code by customization of function pointer HAL_CAN_ErrorCallback
73
74 *** CAN HAL driver macros list ***
75 =============================================
76 [..]
77 Below the list of most used macros in CAN HAL driver.
78
79 (+) __HAL_CAN_ENABLE_IT: Enable the specified CAN interrupts
80 (+) __HAL_CAN_DISABLE_IT: Disable the specified CAN interrupts
81 (+) __HAL_CAN_GET_IT_SOURCE: Check if the specified CAN interrupt source is enabled or disabled
82 (+) __HAL_CAN_CLEAR_FLAG: Clear the CAN's pending flags
83 (+) __HAL_CAN_GET_FLAG: Get the selected CAN's flag status
84
85 [..]
86 (@) You can refer to the CAN Legacy HAL driver header file for more useful macros
87
88 @endverbatim
89
90 ******************************************************************************
91 */
92
93 /* Includes ------------------------------------------------------------------*/
94 #include "stm32f3xx_hal.h"
95
96 /** @addtogroup STM32F3xx_HAL_Driver
97 * @{
98 */
99
100 /** @defgroup CAN CAN
101 * @brief CAN driver modules
102 * @{
103 */
104
105 #ifdef HAL_CAN_LEGACY_MODULE_ENABLED
106
107 #if defined(STM32F302xE) || defined(STM32F303xE) || defined(STM32F398xx) || \
108 defined(STM32F302xC) || defined(STM32F303xC) || defined(STM32F358xx) || \
109 defined(STM32F303x8) || defined(STM32F334x8) || defined(STM32F328xx) || \
110 defined(STM32F302x8) || \
111 defined(STM32F373xC) || defined(STM32F378xx)
112 #ifdef HAL_CAN_MODULE_ENABLED
113 /* Select HAL CAN module in stm32f3xx_hal_conf.h file:
114 (#) HAL_CAN_MODULE_ENABLED for new HAL CAN driver fixing FIFO limitations
115 (#) HAL_CAN_LEGACY_MODULE_ENABLED for legacy HAL CAN driver */
116 #error 'The HAL CAN driver cannot be used with its legacy, Please ensure to enable only one HAL CAN module at once in stm32f3xx_hal_conf.h file'
117 #endif /* HAL_CAN_MODULE_ENABLED */
118
119 #warning 'Legacy HAL CAN driver is enabled! It can be used with known limitations, refer to the release notes. However it is recommended to use rather the new HAL CAN driver'
120
121 /* Private typedef -----------------------------------------------------------*/
122 /* Private define ------------------------------------------------------------*/
123 /** @defgroup CAN_Private_Constants CAN Private Constants
124 * @{
125 */
126 #define CAN_TIMEOUT_VALUE 10U
127 /**
128 * @}
129 */
130 /* Private macro -------------------------------------------------------------*/
131 /* Private variables ---------------------------------------------------------*/
132 /* Private function prototypes -----------------------------------------------*/
133 /** @defgroup CAN_Private_Functions CAN Private Functions
134 * @{
135 */
136 static HAL_StatusTypeDef CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber);
137 static HAL_StatusTypeDef CAN_Transmit_IT(CAN_HandleTypeDef* hcan);
138 /**
139 * @}
140 */
141
142 /* Exported functions ---------------------------------------------------------*/
143
144 /** @defgroup CAN_Exported_Functions CAN Exported Functions
145 * @{
146 */
147
148 /** @defgroup CAN_Exported_Functions_Group1 Initialization and de-initialization functions
149 * @brief Initialization and Configuration functions
150 *
151 @verbatim
152 ==============================================================================
153 ##### Initialization and de-initialization functions #####
154 ==============================================================================
155 [..] This section provides functions allowing to:
156 (+) Initialize and configure the CAN.
157 (+) De-initialize the CAN.
158
159 @endverbatim
160 * @{
161 */
162
163 /**
164 * @brief Initializes the CAN peripheral according to the specified
165 * parameters in the CAN_InitStruct.
166 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
167 * the configuration information for the specified CAN.
168 * @retval HAL status
169 */
HAL_CAN_Init(CAN_HandleTypeDef * hcan)170 HAL_StatusTypeDef HAL_CAN_Init(CAN_HandleTypeDef* hcan)
171 {
172 uint32_t status = CAN_INITSTATUS_FAILED; /* Default init status */
173 uint32_t tickstart = 0U;
174
175 /* Check CAN handle */
176 if(hcan == NULL)
177 {
178 return HAL_ERROR;
179 }
180
181 /* Check the parameters */
182 assert_param(IS_CAN_ALL_INSTANCE(hcan->Instance));
183 assert_param(IS_FUNCTIONAL_STATE(hcan->Init.TTCM));
184 assert_param(IS_FUNCTIONAL_STATE(hcan->Init.ABOM));
185 assert_param(IS_FUNCTIONAL_STATE(hcan->Init.AWUM));
186 assert_param(IS_FUNCTIONAL_STATE(hcan->Init.NART));
187 assert_param(IS_FUNCTIONAL_STATE(hcan->Init.RFLM));
188 assert_param(IS_FUNCTIONAL_STATE(hcan->Init.TXFP));
189 assert_param(IS_CAN_MODE(hcan->Init.Mode));
190 assert_param(IS_CAN_SJW(hcan->Init.SJW));
191 assert_param(IS_CAN_BS1(hcan->Init.BS1));
192 assert_param(IS_CAN_BS2(hcan->Init.BS2));
193 assert_param(IS_CAN_PRESCALER(hcan->Init.Prescaler));
194
195 if(hcan->State == HAL_CAN_STATE_RESET)
196 {
197 /* Allocate lock resource and initialize it */
198 hcan->Lock = HAL_UNLOCKED;
199 /* Init the low level hardware */
200 HAL_CAN_MspInit(hcan);
201 }
202
203 /* Initialize the CAN state*/
204 hcan->State = HAL_CAN_STATE_BUSY;
205
206 /* Exit from sleep mode */
207 CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_SLEEP);
208
209 /* Request initialisation */
210 SET_BIT(hcan->Instance->MCR, CAN_MCR_INRQ);
211
212 /* Get tick */
213 tickstart = HAL_GetTick();
214
215 /* Wait the acknowledge */
216 while(HAL_IS_BIT_CLR(hcan->Instance->MSR, CAN_MSR_INAK))
217 {
218 if((HAL_GetTick()-tickstart) > CAN_TIMEOUT_VALUE)
219 {
220 hcan->State= HAL_CAN_STATE_TIMEOUT;
221 /* Process unlocked */
222 __HAL_UNLOCK(hcan);
223 return HAL_TIMEOUT;
224 }
225 }
226
227 /* Check acknowledge */
228 if (HAL_IS_BIT_SET(hcan->Instance->MSR, CAN_MSR_INAK))
229 {
230 /* Set the time triggered communication mode */
231 if (hcan->Init.TTCM == ENABLE)
232 {
233 SET_BIT(hcan->Instance->MCR, CAN_MCR_TTCM);
234 }
235 else
236 {
237 CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_TTCM);
238 }
239
240 /* Set the automatic bus-off management */
241 if (hcan->Init.ABOM == ENABLE)
242 {
243 SET_BIT(hcan->Instance->MCR, CAN_MCR_ABOM);
244 }
245 else
246 {
247 CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_ABOM);
248 }
249
250 /* Set the automatic wake-up mode */
251 if (hcan->Init.AWUM == ENABLE)
252 {
253 SET_BIT(hcan->Instance->MCR, CAN_MCR_AWUM);
254 }
255 else
256 {
257 CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_AWUM);
258 }
259
260 /* Set the no automatic retransmission */
261 if (hcan->Init.NART == ENABLE)
262 {
263 SET_BIT(hcan->Instance->MCR, CAN_MCR_NART);
264 }
265 else
266 {
267 CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_NART);
268 }
269
270 /* Set the receive FIFO locked mode */
271 if (hcan->Init.RFLM == ENABLE)
272 {
273 SET_BIT(hcan->Instance->MCR, CAN_MCR_RFLM);
274 }
275 else
276 {
277 CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_RFLM);
278 }
279
280 /* Set the transmit FIFO priority */
281 if (hcan->Init.TXFP == ENABLE)
282 {
283 SET_BIT(hcan->Instance->MCR, CAN_MCR_TXFP);
284 }
285 else
286 {
287 CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_TXFP);
288 }
289
290 /* Set the bit timing register */
291 WRITE_REG(hcan->Instance->BTR, (uint32_t)(hcan->Init.Mode |
292 hcan->Init.SJW |
293 hcan->Init.BS1 |
294 hcan->Init.BS2 |
295 (hcan->Init.Prescaler - 1U) ));
296
297 /* Request leave initialisation */
298 CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_INRQ);
299
300 /* Get tick */
301 tickstart = HAL_GetTick();
302
303 /* Wait the acknowledge */
304 while(HAL_IS_BIT_SET(hcan->Instance->MSR, CAN_MSR_INAK))
305 {
306 if((HAL_GetTick()-tickstart) > CAN_TIMEOUT_VALUE)
307 {
308 hcan->State= HAL_CAN_STATE_TIMEOUT;
309
310 /* Process unlocked */
311 __HAL_UNLOCK(hcan);
312
313 return HAL_TIMEOUT;
314 }
315 }
316
317 /* Check acknowledged */
318 if(HAL_IS_BIT_CLR(hcan->Instance->MSR, CAN_MSR_INAK))
319 {
320 status = CAN_INITSTATUS_SUCCESS;
321 }
322 }
323
324 if(status == CAN_INITSTATUS_SUCCESS)
325 {
326 /* Set CAN error code to none */
327 hcan->ErrorCode = HAL_CAN_ERROR_NONE;
328
329 /* Initialize the CAN state */
330 hcan->State = HAL_CAN_STATE_READY;
331
332 /* Return function status */
333 return HAL_OK;
334 }
335 else
336 {
337 /* Initialize the CAN state */
338 hcan->State = HAL_CAN_STATE_ERROR;
339
340 /* Return function status */
341 return HAL_ERROR;
342 }
343 }
344
345 /**
346 * @brief Configures the CAN reception filter according to the specified
347 * parameters in the CAN_FilterInitStruct.
348 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
349 * the configuration information for the specified CAN.
350 * @param sFilterConfig pointer to a CAN_FilterConfTypeDef structure that
351 * contains the filter configuration information.
352 * @retval None
353 */
HAL_CAN_ConfigFilter(CAN_HandleTypeDef * hcan,CAN_FilterConfTypeDef * sFilterConfig)354 HAL_StatusTypeDef HAL_CAN_ConfigFilter(CAN_HandleTypeDef* hcan, CAN_FilterConfTypeDef* sFilterConfig)
355 {
356 uint32_t filternbrbitpos = 0U;
357
358 /* Check the parameters */
359 assert_param(IS_CAN_FILTER_NUMBER(sFilterConfig->FilterNumber));
360 assert_param(IS_CAN_FILTER_MODE(sFilterConfig->FilterMode));
361 assert_param(IS_CAN_FILTER_SCALE(sFilterConfig->FilterScale));
362 assert_param(IS_CAN_FILTER_FIFO(sFilterConfig->FilterFIFOAssignment));
363 assert_param(IS_FUNCTIONAL_STATE(sFilterConfig->FilterActivation));
364
365 filternbrbitpos = (1U) << sFilterConfig->FilterNumber;
366
367 /* Initialisation mode for the filter */
368 SET_BIT(hcan->Instance->FMR, CAN_FMR_FINIT);
369
370 /* Filter Deactivation */
371 CLEAR_BIT(hcan->Instance->FA1R, filternbrbitpos);
372
373 /* Filter Scale */
374 if (sFilterConfig->FilterScale == CAN_FILTERSCALE_16BIT)
375 {
376 /* 16-bit scale for the filter */
377 CLEAR_BIT(hcan->Instance->FS1R, filternbrbitpos);
378
379 /* First 16-bit identifier and First 16-bit mask */
380 /* Or First 16-bit identifier and Second 16-bit identifier */
381 hcan->Instance->sFilterRegister[sFilterConfig->FilterNumber].FR1 =
382 ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdLow) << 16U) |
383 (0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdLow);
384
385 /* Second 16-bit identifier and Second 16-bit mask */
386 /* Or Third 16-bit identifier and Fourth 16-bit identifier */
387 hcan->Instance->sFilterRegister[sFilterConfig->FilterNumber].FR2 =
388 ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdHigh) << 16U) |
389 (0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdHigh);
390 }
391
392 if (sFilterConfig->FilterScale == CAN_FILTERSCALE_32BIT)
393 {
394 /* 32-bit scale for the filter */
395 SET_BIT(hcan->Instance->FS1R, filternbrbitpos);
396
397 /* 32-bit identifier or First 32-bit identifier */
398 hcan->Instance->sFilterRegister[sFilterConfig->FilterNumber].FR1 =
399 ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdHigh) << 16U) |
400 (0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdLow);
401
402 /* 32-bit mask or Second 32-bit identifier */
403 hcan->Instance->sFilterRegister[sFilterConfig->FilterNumber].FR2 =
404 ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdHigh) << 16U) |
405 (0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdLow);
406 }
407
408 /* Filter Mode */
409 if (sFilterConfig->FilterMode == CAN_FILTERMODE_IDMASK)
410 {
411 /*Id/Mask mode for the filter*/
412 CLEAR_BIT(hcan->Instance->FM1R, filternbrbitpos);
413 }
414 else /* CAN_FilterInitStruct->CAN_FilterMode == CAN_FilterMode_IdList */
415 {
416 /*Identifier list mode for the filter*/
417 SET_BIT(hcan->Instance->FM1R, filternbrbitpos);
418 }
419
420 /* Filter FIFO assignment */
421 if (sFilterConfig->FilterFIFOAssignment == CAN_FILTER_FIFO0)
422 {
423 /* FIFO 0 assignation for the filter */
424 CLEAR_BIT(hcan->Instance->FFA1R, filternbrbitpos);
425 }
426 else
427 {
428 /* FIFO 1 assignation for the filter */
429 SET_BIT(hcan->Instance->FFA1R, filternbrbitpos);
430 }
431
432 /* Filter activation */
433 if (sFilterConfig->FilterActivation == ENABLE)
434 {
435 SET_BIT(hcan->Instance->FA1R, filternbrbitpos);
436 }
437
438 /* Leave the initialisation mode for the filter */
439 CLEAR_BIT(hcan->Instance->FMR, ((uint32_t)CAN_FMR_FINIT));
440
441 /* Return function status */
442 return HAL_OK;
443 }
444
445 /**
446 * @brief Deinitializes the CANx peripheral registers to their default reset values.
447 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
448 * the configuration information for the specified CAN.
449 * @retval HAL status
450 */
HAL_CAN_DeInit(CAN_HandleTypeDef * hcan)451 HAL_StatusTypeDef HAL_CAN_DeInit(CAN_HandleTypeDef* hcan)
452 {
453 /* Check CAN handle */
454 if(hcan == NULL)
455 {
456 return HAL_ERROR;
457 }
458
459 /* Check the parameters */
460 assert_param(IS_CAN_ALL_INSTANCE(hcan->Instance));
461
462 /* Change CAN state */
463 hcan->State = HAL_CAN_STATE_BUSY;
464
465 /* DeInit the low level hardware */
466 HAL_CAN_MspDeInit(hcan);
467
468 /* Change CAN state */
469 hcan->State = HAL_CAN_STATE_RESET;
470
471 /* Release Lock */
472 __HAL_UNLOCK(hcan);
473
474 /* Return function status */
475 return HAL_OK;
476 }
477
478 /**
479 * @brief Initializes the CAN MSP.
480 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
481 * the configuration information for the specified CAN.
482 * @retval None
483 */
HAL_CAN_MspInit(CAN_HandleTypeDef * hcan)484 __weak void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan)
485 {
486 /* Prevent unused argument(s) compilation warning */
487 UNUSED(hcan);
488
489 /* NOTE : This function Should not be modified, when the callback is needed,
490 the HAL_CAN_MspInit could be implemented in the user file
491 */
492 }
493
494 /**
495 * @brief DeInitializes the CAN MSP.
496 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
497 * the configuration information for the specified CAN.
498 * @retval None
499 */
HAL_CAN_MspDeInit(CAN_HandleTypeDef * hcan)500 __weak void HAL_CAN_MspDeInit(CAN_HandleTypeDef* hcan)
501 {
502 /* Prevent unused argument(s) compilation warning */
503 UNUSED(hcan);
504
505 /* NOTE : This function Should not be modified, when the callback is needed,
506 the HAL_CAN_MspDeInit could be implemented in the user file
507 */
508 }
509
510 /**
511 * @}
512 */
513
514 /** @defgroup CAN_Exported_Functions_Group2 Input and Output operation functions
515 * @brief IO operation functions
516 *
517 @verbatim
518 ==============================================================================
519 ##### IO operation functions #####
520 ==============================================================================
521 [..] This section provides functions allowing to:
522 (+) Transmit a CAN frame message.
523 (+) Receive a CAN frame message.
524 (+) Enter CAN peripheral in sleep mode.
525 (+) Wake up the CAN peripheral from sleep mode.
526
527 @endverbatim
528 * @{
529 */
530
531 /**
532 * @brief Initiates and transmits a CAN frame message.
533 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
534 * the configuration information for the specified CAN.
535 * @param Timeout Timeout duration.
536 * @retval HAL status
537 */
HAL_CAN_Transmit(CAN_HandleTypeDef * hcan,uint32_t Timeout)538 HAL_StatusTypeDef HAL_CAN_Transmit(CAN_HandleTypeDef* hcan, uint32_t Timeout)
539 {
540 uint32_t transmitmailbox = CAN_TXSTATUS_NOMAILBOX;
541 uint32_t tickstart = 0U;
542
543 /* Check the parameters */
544 assert_param(IS_CAN_IDTYPE(hcan->pTxMsg->IDE));
545 assert_param(IS_CAN_RTR(hcan->pTxMsg->RTR));
546 assert_param(IS_CAN_DLC(hcan->pTxMsg->DLC));
547
548 if(((hcan->Instance->TSR&CAN_TSR_TME0) == CAN_TSR_TME0) || \
549 ((hcan->Instance->TSR&CAN_TSR_TME1) == CAN_TSR_TME1) || \
550 ((hcan->Instance->TSR&CAN_TSR_TME2) == CAN_TSR_TME2))
551 {
552 /* Process locked */
553 __HAL_LOCK(hcan);
554
555 /* Change CAN state */
556 switch(hcan->State)
557 {
558 case(HAL_CAN_STATE_BUSY_RX0):
559 hcan->State = HAL_CAN_STATE_BUSY_TX_RX0;
560 break;
561 case(HAL_CAN_STATE_BUSY_RX1):
562 hcan->State = HAL_CAN_STATE_BUSY_TX_RX1;
563 break;
564 case(HAL_CAN_STATE_BUSY_RX0_RX1):
565 hcan->State = HAL_CAN_STATE_BUSY_TX_RX0_RX1;
566 break;
567 default: /* HAL_CAN_STATE_READY */
568 hcan->State = HAL_CAN_STATE_BUSY_TX;
569 break;
570 }
571
572 /* Select one empty transmit mailbox */
573 if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME0))
574 {
575 transmitmailbox = CAN_TXMAILBOX_0;
576 }
577 else if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME1))
578 {
579 transmitmailbox = CAN_TXMAILBOX_1;
580 }
581 else
582 {
583 transmitmailbox = CAN_TXMAILBOX_2;
584 }
585
586 /* Set up the Id */
587 hcan->Instance->sTxMailBox[transmitmailbox].TIR &= CAN_TI0R_TXRQ;
588 if (hcan->pTxMsg->IDE == CAN_ID_STD)
589 {
590 assert_param(IS_CAN_STDID(hcan->pTxMsg->StdId));
591 hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->StdId << CAN_TI0R_STID_Pos) | \
592 hcan->pTxMsg->RTR);
593 }
594 else
595 {
596 assert_param(IS_CAN_EXTID(hcan->pTxMsg->ExtId));
597 hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->ExtId << CAN_TI0R_EXID_Pos) | \
598 hcan->pTxMsg->IDE | \
599 hcan->pTxMsg->RTR);
600 }
601
602 /* Set up the DLC */
603 hcan->pTxMsg->DLC &= (uint8_t)0x0000000FU;
604 hcan->Instance->sTxMailBox[transmitmailbox].TDTR &= 0xFFFFFFF0U;
605 hcan->Instance->sTxMailBox[transmitmailbox].TDTR |= hcan->pTxMsg->DLC;
606
607 /* Set up the data field */
608 WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDLR, ((uint32_t)hcan->pTxMsg->Data[3] << CAN_TDL0R_DATA3_Pos) |
609 ((uint32_t)hcan->pTxMsg->Data[2] << CAN_TDL0R_DATA2_Pos) |
610 ((uint32_t)hcan->pTxMsg->Data[1] << CAN_TDL0R_DATA1_Pos) |
611 ((uint32_t)hcan->pTxMsg->Data[0] << CAN_TDL0R_DATA0_Pos));
612 WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDHR, ((uint32_t)hcan->pTxMsg->Data[7] << CAN_TDL0R_DATA3_Pos) |
613 ((uint32_t)hcan->pTxMsg->Data[6] << CAN_TDL0R_DATA2_Pos) |
614 ((uint32_t)hcan->pTxMsg->Data[5] << CAN_TDL0R_DATA1_Pos) |
615 ((uint32_t)hcan->pTxMsg->Data[4] << CAN_TDL0R_DATA0_Pos));
616
617 /* Request transmission */
618 SET_BIT(hcan->Instance->sTxMailBox[transmitmailbox].TIR, CAN_TI0R_TXRQ);
619
620 /* Get tick */
621 tickstart = HAL_GetTick();
622
623 /* Check End of transmission flag */
624 while(!(__HAL_CAN_TRANSMIT_STATUS(hcan, transmitmailbox)))
625 {
626 /* Check for the Timeout */
627 if(Timeout != HAL_MAX_DELAY)
628 {
629 if((Timeout == 0U) || ((HAL_GetTick()-tickstart) > Timeout))
630 {
631 hcan->State = HAL_CAN_STATE_TIMEOUT;
632
633 /* Cancel transmission */
634 __HAL_CAN_CANCEL_TRANSMIT(hcan, transmitmailbox);
635
636 /* Process unlocked */
637 __HAL_UNLOCK(hcan);
638 return HAL_TIMEOUT;
639 }
640 }
641 }
642
643 /* Change CAN state */
644 switch(hcan->State)
645 {
646 case(HAL_CAN_STATE_BUSY_TX_RX0):
647 hcan->State = HAL_CAN_STATE_BUSY_RX0;
648 break;
649 case(HAL_CAN_STATE_BUSY_TX_RX1):
650 hcan->State = HAL_CAN_STATE_BUSY_RX1;
651 break;
652 case(HAL_CAN_STATE_BUSY_TX_RX0_RX1):
653 hcan->State = HAL_CAN_STATE_BUSY_RX0_RX1;
654 break;
655 default: /* HAL_CAN_STATE_BUSY_TX */
656 hcan->State = HAL_CAN_STATE_READY;
657 break;
658 }
659
660 /* Process unlocked */
661 __HAL_UNLOCK(hcan);
662
663 /* Return function status */
664 return HAL_OK;
665 }
666 else
667 {
668 /* Change CAN state */
669 hcan->State = HAL_CAN_STATE_ERROR;
670
671 /* Return function status */
672 return HAL_ERROR;
673 }
674 }
675
676 /**
677 * @brief Initiates and transmits a CAN frame message.
678 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
679 * the configuration information for the specified CAN.
680 * @retval HAL status
681 */
HAL_CAN_Transmit_IT(CAN_HandleTypeDef * hcan)682 HAL_StatusTypeDef HAL_CAN_Transmit_IT(CAN_HandleTypeDef* hcan)
683 {
684 uint32_t transmitmailbox = CAN_TXSTATUS_NOMAILBOX;
685
686 /* Check the parameters */
687 assert_param(IS_CAN_IDTYPE(hcan->pTxMsg->IDE));
688 assert_param(IS_CAN_RTR(hcan->pTxMsg->RTR));
689 assert_param(IS_CAN_DLC(hcan->pTxMsg->DLC));
690
691 if(((hcan->Instance->TSR&CAN_TSR_TME0) == CAN_TSR_TME0) || \
692 ((hcan->Instance->TSR&CAN_TSR_TME1) == CAN_TSR_TME1) || \
693 ((hcan->Instance->TSR&CAN_TSR_TME2) == CAN_TSR_TME2))
694 {
695 /* Process Locked */
696 __HAL_LOCK(hcan);
697
698 /* Select one empty transmit mailbox */
699 if(HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME0))
700 {
701 transmitmailbox = CAN_TXMAILBOX_0;
702 }
703 else if(HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME1))
704 {
705 transmitmailbox = CAN_TXMAILBOX_1;
706 }
707 else
708 {
709 transmitmailbox = CAN_TXMAILBOX_2;
710 }
711
712 /* Set up the Id */
713 hcan->Instance->sTxMailBox[transmitmailbox].TIR &= CAN_TI0R_TXRQ;
714 if(hcan->pTxMsg->IDE == CAN_ID_STD)
715 {
716 assert_param(IS_CAN_STDID(hcan->pTxMsg->StdId));
717 hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->StdId << CAN_TI0R_STID_Pos) | \
718 hcan->pTxMsg->RTR);
719 }
720 else
721 {
722 assert_param(IS_CAN_EXTID(hcan->pTxMsg->ExtId));
723 hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->ExtId << CAN_TI0R_EXID_Pos) | \
724 hcan->pTxMsg->IDE | \
725 hcan->pTxMsg->RTR);
726 }
727
728 /* Set up the DLC */
729 hcan->pTxMsg->DLC &= (uint8_t)0x0000000FU;
730 hcan->Instance->sTxMailBox[transmitmailbox].TDTR &= 0xFFFFFFF0U;
731 hcan->Instance->sTxMailBox[transmitmailbox].TDTR |= hcan->pTxMsg->DLC;
732
733 /* Set up the data field */
734 WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDLR, ((uint32_t)hcan->pTxMsg->Data[3] << CAN_TDL0R_DATA3_Pos) |
735 ((uint32_t)hcan->pTxMsg->Data[2] << CAN_TDL0R_DATA2_Pos) |
736 ((uint32_t)hcan->pTxMsg->Data[1] << CAN_TDL0R_DATA1_Pos) |
737 ((uint32_t)hcan->pTxMsg->Data[0] << CAN_TDL0R_DATA0_Pos));
738 WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDHR, ((uint32_t)hcan->pTxMsg->Data[7] << CAN_TDL0R_DATA3_Pos) |
739 ((uint32_t)hcan->pTxMsg->Data[6] << CAN_TDL0R_DATA2_Pos) |
740 ((uint32_t)hcan->pTxMsg->Data[5] << CAN_TDL0R_DATA1_Pos) |
741 ((uint32_t)hcan->pTxMsg->Data[4] << CAN_TDL0R_DATA0_Pos));
742
743 /* Change CAN state */
744 switch(hcan->State)
745 {
746 case(HAL_CAN_STATE_BUSY_RX0):
747 hcan->State = HAL_CAN_STATE_BUSY_TX_RX0;
748 break;
749 case(HAL_CAN_STATE_BUSY_RX1):
750 hcan->State = HAL_CAN_STATE_BUSY_TX_RX1;
751 break;
752 case(HAL_CAN_STATE_BUSY_RX0_RX1):
753 hcan->State = HAL_CAN_STATE_BUSY_TX_RX0_RX1;
754 break;
755 default: /* HAL_CAN_STATE_READY */
756 hcan->State = HAL_CAN_STATE_BUSY_TX;
757 break;
758 }
759
760 /* Set CAN error code to none */
761 hcan->ErrorCode = HAL_CAN_ERROR_NONE;
762
763 /* Process Unlocked */
764 __HAL_UNLOCK(hcan);
765
766 /* Request transmission */
767 hcan->Instance->sTxMailBox[transmitmailbox].TIR |= CAN_TI0R_TXRQ;
768
769 /* Enable interrupts: */
770 /* - Enable Error warning Interrupt */
771 /* - Enable Error passive Interrupt */
772 /* - Enable Bus-off Interrupt */
773 /* - Enable Last error code Interrupt */
774 /* - Enable Error Interrupt */
775 /* - Enable Transmit mailbox empty Interrupt */
776 __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EWG |
777 CAN_IT_EPV |
778 CAN_IT_BOF |
779 CAN_IT_LEC |
780 CAN_IT_ERR |
781 CAN_IT_TME );
782 }
783 else
784 {
785 /* Change CAN state */
786 hcan->State = HAL_CAN_STATE_ERROR;
787
788 /* Return function status */
789 return HAL_ERROR;
790 }
791
792 return HAL_OK;
793 }
794
795 /**
796 * @brief Receives a correct CAN frame.
797 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
798 * the configuration information for the specified CAN.
799 * @param FIFONumber FIFO number.
800 * @param Timeout Timeout duration.
801 * @retval HAL status
802 */
HAL_CAN_Receive(CAN_HandleTypeDef * hcan,uint8_t FIFONumber,uint32_t Timeout)803 HAL_StatusTypeDef HAL_CAN_Receive(CAN_HandleTypeDef* hcan, uint8_t FIFONumber, uint32_t Timeout)
804 {
805 uint32_t tickstart = 0U;
806 CanRxMsgTypeDef* pRxMsg = NULL;
807
808 /* Check the parameters */
809 assert_param(IS_CAN_FIFO(FIFONumber));
810
811 /* Process locked */
812 __HAL_LOCK(hcan);
813
814 /* Check if CAN state is not busy for RX FIFO0 */
815 if ((FIFONumber == CAN_FIFO0) && ((hcan->State == HAL_CAN_STATE_BUSY_RX0) || \
816 (hcan->State == HAL_CAN_STATE_BUSY_TX_RX0) || \
817 (hcan->State == HAL_CAN_STATE_BUSY_RX0_RX1) || \
818 (hcan->State == HAL_CAN_STATE_BUSY_TX_RX0_RX1)))
819 {
820 /* Process unlocked */
821 __HAL_UNLOCK(hcan);
822
823 return HAL_BUSY;
824 }
825
826 /* Check if CAN state is not busy for RX FIFO1 */
827 if ((FIFONumber == CAN_FIFO1) && ((hcan->State == HAL_CAN_STATE_BUSY_RX1) || \
828 (hcan->State == HAL_CAN_STATE_BUSY_TX_RX1) || \
829 (hcan->State == HAL_CAN_STATE_BUSY_RX0_RX1) || \
830 (hcan->State == HAL_CAN_STATE_BUSY_TX_RX0_RX1)))
831 {
832 /* Process unlocked */
833 __HAL_UNLOCK(hcan);
834
835 return HAL_BUSY;
836 }
837
838 /* Change CAN state */
839 if (FIFONumber == CAN_FIFO0)
840 {
841 switch(hcan->State)
842 {
843 case(HAL_CAN_STATE_BUSY_TX):
844 hcan->State = HAL_CAN_STATE_BUSY_TX_RX0;
845 break;
846 case(HAL_CAN_STATE_BUSY_RX1):
847 hcan->State = HAL_CAN_STATE_BUSY_RX0_RX1;
848 break;
849 case(HAL_CAN_STATE_BUSY_TX_RX1):
850 hcan->State = HAL_CAN_STATE_BUSY_TX_RX0_RX1;
851 break;
852 default: /* HAL_CAN_STATE_READY */
853 hcan->State = HAL_CAN_STATE_BUSY_RX0;
854 break;
855 }
856 }
857 else /* FIFONumber == CAN_FIFO1 */
858 {
859 switch(hcan->State)
860 {
861 case(HAL_CAN_STATE_BUSY_TX):
862 hcan->State = HAL_CAN_STATE_BUSY_TX_RX1;
863 break;
864 case(HAL_CAN_STATE_BUSY_RX0):
865 hcan->State = HAL_CAN_STATE_BUSY_RX0_RX1;
866 break;
867 case(HAL_CAN_STATE_BUSY_TX_RX0):
868 hcan->State = HAL_CAN_STATE_BUSY_TX_RX0_RX1;
869 break;
870 default: /* HAL_CAN_STATE_READY */
871 hcan->State = HAL_CAN_STATE_BUSY_RX1;
872 break;
873 }
874 }
875
876 /* Get tick */
877 tickstart = HAL_GetTick();
878
879 /* Check pending message */
880 while(__HAL_CAN_MSG_PENDING(hcan, FIFONumber) == 0U)
881 {
882 /* Check for the Timeout */
883 if(Timeout != HAL_MAX_DELAY)
884 {
885 if((Timeout == 0U) || ((HAL_GetTick()-tickstart) > Timeout))
886 {
887 hcan->State = HAL_CAN_STATE_TIMEOUT;
888
889 /* Process unlocked */
890 __HAL_UNLOCK(hcan);
891
892 return HAL_TIMEOUT;
893 }
894 }
895 }
896
897 /* Set RxMsg pointer */
898 if(FIFONumber == CAN_FIFO0)
899 {
900 pRxMsg = hcan->pRxMsg;
901 }
902 else /* FIFONumber == CAN_FIFO1 */
903 {
904 pRxMsg = hcan->pRx1Msg;
905 }
906
907 /* Get the Id */
908 pRxMsg->IDE = CAN_RI0R_IDE & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
909 if (pRxMsg->IDE == CAN_ID_STD)
910 {
911 pRxMsg->StdId = (CAN_RI0R_STID & hcan->Instance->sFIFOMailBox[FIFONumber].RIR) >> CAN_TI0R_STID_Pos;
912 }
913 else
914 {
915 pRxMsg->ExtId = (0xFFFFFFF8U & hcan->Instance->sFIFOMailBox[FIFONumber].RIR) >> CAN_RI0R_EXID_Pos;
916 }
917 pRxMsg->RTR = (CAN_RI0R_RTR & hcan->Instance->sFIFOMailBox[FIFONumber].RIR) >> CAN_RI0R_RTR_Pos;
918 /* Get the DLC */
919 pRxMsg->DLC = (CAN_RDT0R_DLC & hcan->Instance->sFIFOMailBox[FIFONumber].RDTR) >> CAN_RDT0R_DLC_Pos;
920 /* Get the FMI */
921 pRxMsg->FMI = (CAN_RDT0R_FMI & hcan->Instance->sFIFOMailBox[FIFONumber].RDTR) >> CAN_RDT0R_FMI_Pos;
922 /* Get the FIFONumber */
923 pRxMsg->FIFONumber = FIFONumber;
924 /* Get the data field */
925 pRxMsg->Data[0] = (CAN_RDL0R_DATA0 & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR) >> CAN_RDL0R_DATA0_Pos;
926 pRxMsg->Data[1] = (CAN_RDL0R_DATA1 & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR) >> CAN_RDL0R_DATA1_Pos;
927 pRxMsg->Data[2] = (CAN_RDL0R_DATA2 & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR) >> CAN_RDL0R_DATA2_Pos;
928 pRxMsg->Data[3] = (CAN_RDL0R_DATA3 & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR) >> CAN_RDL0R_DATA3_Pos;
929 pRxMsg->Data[4] = (CAN_RDH0R_DATA4 & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR) >> CAN_RDH0R_DATA4_Pos;
930 pRxMsg->Data[5] = (CAN_RDH0R_DATA5 & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR) >> CAN_RDH0R_DATA5_Pos;
931 pRxMsg->Data[6] = (CAN_RDH0R_DATA6 & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR) >> CAN_RDH0R_DATA6_Pos;
932 pRxMsg->Data[7] = (CAN_RDH0R_DATA7 & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR) >> CAN_RDH0R_DATA7_Pos;
933
934 /* Release the FIFO */
935 if(FIFONumber == CAN_FIFO0)
936 {
937 /* Release FIFO0 */
938 __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO0);
939 }
940 else /* FIFONumber == CAN_FIFO1 */
941 {
942 /* Release FIFO1 */
943 __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO1);
944 }
945
946 /* Change CAN state */
947 if (FIFONumber == CAN_FIFO0)
948 {
949 switch(hcan->State)
950 {
951 case(HAL_CAN_STATE_BUSY_TX_RX0):
952 hcan->State = HAL_CAN_STATE_BUSY_TX;
953 break;
954 case(HAL_CAN_STATE_BUSY_RX0_RX1):
955 hcan->State = HAL_CAN_STATE_BUSY_RX1;
956 break;
957 case(HAL_CAN_STATE_BUSY_TX_RX0_RX1):
958 hcan->State = HAL_CAN_STATE_BUSY_TX_RX1;
959 break;
960 default: /* HAL_CAN_STATE_BUSY_RX0 */
961 hcan->State = HAL_CAN_STATE_READY;
962 break;
963 }
964 }
965 else /* FIFONumber == CAN_FIFO1 */
966 {
967 switch(hcan->State)
968 {
969 case(HAL_CAN_STATE_BUSY_TX_RX1):
970 hcan->State = HAL_CAN_STATE_BUSY_TX;
971 break;
972 case(HAL_CAN_STATE_BUSY_RX0_RX1):
973 hcan->State = HAL_CAN_STATE_BUSY_RX0;
974 break;
975 case(HAL_CAN_STATE_BUSY_TX_RX0_RX1):
976 hcan->State = HAL_CAN_STATE_BUSY_TX_RX0;
977 break;
978 default: /* HAL_CAN_STATE_BUSY_RX1 */
979 hcan->State = HAL_CAN_STATE_READY;
980 break;
981 }
982 }
983
984 /* Process unlocked */
985 __HAL_UNLOCK(hcan);
986
987 /* Return function status */
988 return HAL_OK;
989 }
990
991 /**
992 * @brief Receives a correct CAN frame.
993 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
994 * the configuration information for the specified CAN.
995 * @param FIFONumber FIFO number.
996 * @retval HAL status
997 */
HAL_CAN_Receive_IT(CAN_HandleTypeDef * hcan,uint8_t FIFONumber)998 HAL_StatusTypeDef HAL_CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber)
999 {
1000 /* Check the parameters */
1001 assert_param(IS_CAN_FIFO(FIFONumber));
1002
1003 /* Process locked */
1004 __HAL_LOCK(hcan);
1005
1006 /* Check if CAN state is not busy for RX FIFO0 */
1007 if ((FIFONumber == CAN_FIFO0) && ((hcan->State == HAL_CAN_STATE_BUSY_RX0) || \
1008 (hcan->State == HAL_CAN_STATE_BUSY_TX_RX0) || \
1009 (hcan->State == HAL_CAN_STATE_BUSY_RX0_RX1) || \
1010 (hcan->State == HAL_CAN_STATE_BUSY_TX_RX0_RX1)))
1011 {
1012 /* Process unlocked */
1013 __HAL_UNLOCK(hcan);
1014
1015 return HAL_BUSY;
1016 }
1017
1018 /* Check if CAN state is not busy for RX FIFO1 */
1019 if ((FIFONumber == CAN_FIFO1) && ((hcan->State == HAL_CAN_STATE_BUSY_RX1) || \
1020 (hcan->State == HAL_CAN_STATE_BUSY_TX_RX1) || \
1021 (hcan->State == HAL_CAN_STATE_BUSY_RX0_RX1) || \
1022 (hcan->State == HAL_CAN_STATE_BUSY_TX_RX0_RX1)))
1023 {
1024 /* Process unlocked */
1025 __HAL_UNLOCK(hcan);
1026
1027 return HAL_BUSY;
1028 }
1029
1030 /* Change CAN state */
1031 if (FIFONumber == CAN_FIFO0)
1032 {
1033 switch(hcan->State)
1034 {
1035 case(HAL_CAN_STATE_BUSY_TX):
1036 hcan->State = HAL_CAN_STATE_BUSY_TX_RX0;
1037 break;
1038 case(HAL_CAN_STATE_BUSY_RX1):
1039 hcan->State = HAL_CAN_STATE_BUSY_RX0_RX1;
1040 break;
1041 case(HAL_CAN_STATE_BUSY_TX_RX1):
1042 hcan->State = HAL_CAN_STATE_BUSY_TX_RX0_RX1;
1043 break;
1044 default: /* HAL_CAN_STATE_READY */
1045 hcan->State = HAL_CAN_STATE_BUSY_RX0;
1046 break;
1047 }
1048 }
1049 else /* FIFONumber == CAN_FIFO1 */
1050 {
1051 switch(hcan->State)
1052 {
1053 case(HAL_CAN_STATE_BUSY_TX):
1054 hcan->State = HAL_CAN_STATE_BUSY_TX_RX1;
1055 break;
1056 case(HAL_CAN_STATE_BUSY_RX0):
1057 hcan->State = HAL_CAN_STATE_BUSY_RX0_RX1;
1058 break;
1059 case(HAL_CAN_STATE_BUSY_TX_RX0):
1060 hcan->State = HAL_CAN_STATE_BUSY_TX_RX0_RX1;
1061 break;
1062 default: /* HAL_CAN_STATE_READY */
1063 hcan->State = HAL_CAN_STATE_BUSY_RX1;
1064 break;
1065 }
1066 }
1067
1068 /* Set CAN error code to none */
1069 hcan->ErrorCode = HAL_CAN_ERROR_NONE;
1070
1071 /* Enable interrupts: */
1072 /* - Enable Error warning Interrupt */
1073 /* - Enable Error passive Interrupt */
1074 /* - Enable Bus-off Interrupt */
1075 /* - Enable Last error code Interrupt */
1076 /* - Enable Error Interrupt */
1077 __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EWG |
1078 CAN_IT_EPV |
1079 CAN_IT_BOF |
1080 CAN_IT_LEC |
1081 CAN_IT_ERR);
1082
1083 /* Process unlocked */
1084 __HAL_UNLOCK(hcan);
1085
1086 if(FIFONumber == CAN_FIFO0)
1087 {
1088 /* Enable FIFO 0 overrun and message pending Interrupt */
1089 __HAL_CAN_ENABLE_IT(hcan, CAN_IT_FOV0 | CAN_IT_FMP0);
1090 }
1091 else
1092 {
1093 /* Enable FIFO 1 overrun and message pending Interrupt */
1094 __HAL_CAN_ENABLE_IT(hcan, CAN_IT_FOV1 | CAN_IT_FMP1);
1095 }
1096
1097 /* Return function status */
1098 return HAL_OK;
1099 }
1100
1101 /**
1102 * @brief Enters the Sleep (low power) mode.
1103 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
1104 * the configuration information for the specified CAN.
1105 * @retval HAL status.
1106 */
HAL_CAN_Sleep(CAN_HandleTypeDef * hcan)1107 HAL_StatusTypeDef HAL_CAN_Sleep(CAN_HandleTypeDef* hcan)
1108 {
1109 uint32_t tickstart = 0U;
1110
1111 /* Process locked */
1112 __HAL_LOCK(hcan);
1113
1114 /* Change CAN state */
1115 hcan->State = HAL_CAN_STATE_BUSY;
1116
1117 /* Request Sleep mode */
1118 MODIFY_REG(hcan->Instance->MCR,
1119 CAN_MCR_INRQ ,
1120 CAN_MCR_SLEEP );
1121
1122 /* Sleep mode status */
1123 if (HAL_IS_BIT_CLR(hcan->Instance->MSR, CAN_MSR_SLAK) ||
1124 HAL_IS_BIT_SET(hcan->Instance->MSR, CAN_MSR_INAK) )
1125 {
1126 /* Process unlocked */
1127 __HAL_UNLOCK(hcan);
1128
1129 /* Return function status */
1130 return HAL_ERROR;
1131 }
1132
1133 /* Get tick */
1134 tickstart = HAL_GetTick();
1135
1136 /* Wait the acknowledge */
1137 while (HAL_IS_BIT_CLR(hcan->Instance->MSR, CAN_MSR_SLAK) ||
1138 HAL_IS_BIT_SET(hcan->Instance->MSR, CAN_MSR_INAK) )
1139 {
1140 if((HAL_GetTick() - tickstart) > CAN_TIMEOUT_VALUE)
1141 {
1142 hcan->State = HAL_CAN_STATE_TIMEOUT;
1143 /* Process unlocked */
1144 __HAL_UNLOCK(hcan);
1145 return HAL_TIMEOUT;
1146 }
1147 }
1148
1149 /* Change CAN state */
1150 hcan->State = HAL_CAN_STATE_READY;
1151
1152 /* Process unlocked */
1153 __HAL_UNLOCK(hcan);
1154
1155 /* Return function status */
1156 return HAL_OK;
1157 }
1158
1159 /**
1160 * @brief Wakes up the CAN peripheral from sleep mode, after that the CAN peripheral
1161 * is in the normal mode.
1162 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
1163 * the configuration information for the specified CAN.
1164 * @retval HAL status.
1165 */
HAL_CAN_WakeUp(CAN_HandleTypeDef * hcan)1166 HAL_StatusTypeDef HAL_CAN_WakeUp(CAN_HandleTypeDef* hcan)
1167 {
1168 uint32_t tickstart = 0U;
1169
1170 /* Process locked */
1171 __HAL_LOCK(hcan);
1172
1173 /* Change CAN state */
1174 hcan->State = HAL_CAN_STATE_BUSY;
1175
1176 /* Wake up request */
1177 CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_SLEEP);
1178
1179 /* Get tick */
1180 tickstart = HAL_GetTick();
1181
1182 /* Sleep mode status */
1183 while(HAL_IS_BIT_SET(hcan->Instance->MSR, CAN_MSR_SLAK))
1184 {
1185 if((HAL_GetTick() - tickstart) > CAN_TIMEOUT_VALUE)
1186 {
1187 hcan->State= HAL_CAN_STATE_TIMEOUT;
1188
1189 /* Process unlocked */
1190 __HAL_UNLOCK(hcan);
1191
1192 return HAL_TIMEOUT;
1193 }
1194 }
1195
1196 if(HAL_IS_BIT_SET(hcan->Instance->MSR, CAN_MSR_SLAK))
1197 {
1198 /* Process unlocked */
1199 __HAL_UNLOCK(hcan);
1200
1201 /* Return function status */
1202 return HAL_ERROR;
1203 }
1204
1205 /* Change CAN state */
1206 hcan->State = HAL_CAN_STATE_READY;
1207
1208 /* Process unlocked */
1209 __HAL_UNLOCK(hcan);
1210
1211 /* Return function status */
1212 return HAL_OK;
1213 }
1214
1215 /**
1216 * @brief Handles CAN interrupt request
1217 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
1218 * the configuration information for the specified CAN.
1219 * @retval None
1220 */
HAL_CAN_IRQHandler(CAN_HandleTypeDef * hcan)1221 void HAL_CAN_IRQHandler(CAN_HandleTypeDef* hcan)
1222 {
1223 uint32_t errorcode = HAL_CAN_ERROR_NONE;
1224
1225 /* Check Overrun flag for FIFO0 */
1226 if((__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_FOV0)) &&
1227 (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FOV0)))
1228 {
1229 /* Set CAN error code to FOV0 error */
1230 errorcode |= HAL_CAN_ERROR_FOV0;
1231
1232 /* Clear FIFO0 Overrun Flag */
1233 __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FOV0);
1234 }
1235
1236 /* Check Overrun flag for FIFO1 */
1237 if((__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_FOV1)) &&
1238 (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FOV1)))
1239 {
1240 /* Set CAN error code to FOV1 error */
1241 errorcode |= HAL_CAN_ERROR_FOV1;
1242
1243 /* Clear FIFO1 Overrun Flag */
1244 __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FOV1);
1245 }
1246
1247 /* Check End of transmission flag */
1248 if(__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_TME))
1249 {
1250 /* Check Transmit request completion status */
1251 if((__HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_0)) ||
1252 (__HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_1)) ||
1253 (__HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_2)))
1254 {
1255 /* Check Transmit success */
1256 if((__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TXOK0)) ||
1257 (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TXOK1)) ||
1258 (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TXOK2)))
1259 {
1260 /* Call transmit function */
1261 CAN_Transmit_IT(hcan);
1262 }
1263 else /* Transmit failure */
1264 {
1265 /* Set CAN error code to TXFAIL error */
1266 errorcode |= HAL_CAN_ERROR_TXFAIL;
1267 }
1268
1269 /* Clear transmission status flags (RQCPx and TXOKx) */
1270 SET_BIT(hcan->Instance->TSR, CAN_TSR_RQCP0 | CAN_TSR_RQCP1 | CAN_TSR_RQCP2 | \
1271 CAN_FLAG_TXOK0 | CAN_FLAG_TXOK1 | CAN_FLAG_TXOK2);
1272 }
1273 }
1274
1275 /* Check End of reception flag for FIFO0 */
1276 if((__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FMP0)) &&
1277 (__HAL_CAN_MSG_PENDING(hcan, CAN_FIFO0) != 0U))
1278 {
1279 /* Call receive function */
1280 CAN_Receive_IT(hcan, CAN_FIFO0);
1281 }
1282
1283 /* Check End of reception flag for FIFO1 */
1284 if((__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FMP1)) &&
1285 (__HAL_CAN_MSG_PENDING(hcan, CAN_FIFO1) != 0U))
1286 {
1287 /* Call receive function */
1288 CAN_Receive_IT(hcan, CAN_FIFO1);
1289 }
1290
1291 /* Set error code in handle */
1292 hcan->ErrorCode |= errorcode;
1293
1294 /* Check Error Warning Flag */
1295 if((__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_EWG)) &&
1296 (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_EWG)) &&
1297 (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR)))
1298 {
1299 /* Set CAN error code to EWG error */
1300 hcan->ErrorCode |= HAL_CAN_ERROR_EWG;
1301 /* No need for clear of Error Warning Flag as read-only */
1302 }
1303
1304 /* Check Error Passive Flag */
1305 if((__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_EPV)) &&
1306 (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_EPV)) &&
1307 (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR)))
1308 {
1309 /* Set CAN error code to EPV error */
1310 hcan->ErrorCode |= HAL_CAN_ERROR_EPV;
1311 /* No need for clear of Error Passive Flag as read-only */
1312 }
1313
1314 /* Check Bus-Off Flag */
1315 if((__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_BOF)) &&
1316 (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_BOF)) &&
1317 (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR)))
1318 {
1319 /* Set CAN error code to BOF error */
1320 hcan->ErrorCode |= HAL_CAN_ERROR_BOF;
1321 /* No need for clear of Bus-Off Flag as read-only */
1322 }
1323
1324 /* Check Last error code Flag */
1325 if((!HAL_IS_BIT_CLR(hcan->Instance->ESR, CAN_ESR_LEC)) &&
1326 (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_LEC)) &&
1327 (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR)))
1328 {
1329 switch(hcan->Instance->ESR & CAN_ESR_LEC)
1330 {
1331 case(CAN_ESR_LEC_0):
1332 /* Set CAN error code to STF error */
1333 hcan->ErrorCode |= HAL_CAN_ERROR_STF;
1334 break;
1335 case(CAN_ESR_LEC_1):
1336 /* Set CAN error code to FOR error */
1337 hcan->ErrorCode |= HAL_CAN_ERROR_FOR;
1338 break;
1339 case(CAN_ESR_LEC_1 | CAN_ESR_LEC_0):
1340 /* Set CAN error code to ACK error */
1341 hcan->ErrorCode |= HAL_CAN_ERROR_ACK;
1342 break;
1343 case(CAN_ESR_LEC_2):
1344 /* Set CAN error code to BR error */
1345 hcan->ErrorCode |= HAL_CAN_ERROR_BR;
1346 break;
1347 case(CAN_ESR_LEC_2 | CAN_ESR_LEC_0):
1348 /* Set CAN error code to BD error */
1349 hcan->ErrorCode |= HAL_CAN_ERROR_BD;
1350 break;
1351 case(CAN_ESR_LEC_2 | CAN_ESR_LEC_1):
1352 /* Set CAN error code to CRC error */
1353 hcan->ErrorCode |= HAL_CAN_ERROR_CRC;
1354 break;
1355 default:
1356 break;
1357 }
1358
1359 /* Clear Last error code Flag */
1360 CLEAR_BIT(hcan->Instance->ESR, CAN_ESR_LEC);
1361 }
1362
1363 /* Call the Error call Back in case of Errors */
1364 if(hcan->ErrorCode != HAL_CAN_ERROR_NONE)
1365 {
1366 /* Clear ERRI Flag */
1367 SET_BIT(hcan->Instance->MSR, CAN_MSR_ERRI);
1368
1369 /* Set the CAN state ready to be able to start again the process */
1370 hcan->State = HAL_CAN_STATE_READY;
1371
1372 /* Disable interrupts: */
1373 /* - Disable Error warning Interrupt */
1374 /* - Disable Error passive Interrupt */
1375 /* - Disable Bus-off Interrupt */
1376 /* - Disable Last error code Interrupt */
1377 /* - Disable Error Interrupt */
1378 /* - Disable FIFO 0 message pending Interrupt */
1379 /* - Disable FIFO 0 Overrun Interrupt */
1380 /* - Disable FIFO 1 message pending Interrupt */
1381 /* - Disable FIFO 1 Overrun Interrupt */
1382 /* - Disable Transmit mailbox empty Interrupt */
1383 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EWG |
1384 CAN_IT_EPV |
1385 CAN_IT_BOF |
1386 CAN_IT_LEC |
1387 CAN_IT_ERR |
1388 CAN_IT_FMP0|
1389 CAN_IT_FOV0|
1390 CAN_IT_FMP1|
1391 CAN_IT_FOV1|
1392 CAN_IT_TME );
1393
1394 /* Call Error callback function */
1395 HAL_CAN_ErrorCallback(hcan);
1396 }
1397 }
1398
1399 /**
1400 * @brief Transmission complete callback in non blocking mode
1401 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
1402 * the configuration information for the specified CAN.
1403 * @retval None
1404 */
HAL_CAN_TxCpltCallback(CAN_HandleTypeDef * hcan)1405 __weak void HAL_CAN_TxCpltCallback(CAN_HandleTypeDef* hcan)
1406 {
1407 /* Prevent unused argument(s) compilation warning */
1408 UNUSED(hcan);
1409
1410 /* NOTE : This function Should not be modified, when the callback is needed,
1411 the HAL_CAN_TxCpltCallback could be implemented in the user file
1412 */
1413 }
1414
1415 /**
1416 * @brief Transmission complete callback in non blocking mode
1417 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
1418 * the configuration information for the specified CAN.
1419 * @retval None
1420 */
HAL_CAN_RxCpltCallback(CAN_HandleTypeDef * hcan)1421 __weak void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* hcan)
1422 {
1423 /* Prevent unused argument(s) compilation warning */
1424 UNUSED(hcan);
1425
1426 /* NOTE : This function Should not be modified, when the callback is needed,
1427 the HAL_CAN_RxCpltCallback could be implemented in the user file
1428 */
1429 }
1430
1431 /**
1432 * @brief Error CAN callback.
1433 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
1434 * the configuration information for the specified CAN.
1435 * @retval None
1436 */
HAL_CAN_ErrorCallback(CAN_HandleTypeDef * hcan)1437 __weak void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan)
1438 {
1439 /* Prevent unused argument(s) compilation warning */
1440 UNUSED(hcan);
1441
1442 /* NOTE : This function Should not be modified, when the callback is needed,
1443 the HAL_CAN_ErrorCallback could be implemented in the user file
1444 */
1445 }
1446
1447 /**
1448 * @}
1449 */
1450
1451 /** @defgroup CAN_Exported_Functions_Group3 Peripheral State and Error functions
1452 * @brief CAN Peripheral State functions
1453 *
1454 @verbatim
1455 ==============================================================================
1456 ##### Peripheral State and Error functions #####
1457 ==============================================================================
1458 [..]
1459 This subsection provides functions allowing to :
1460 (+) Check the CAN state.
1461 (+) Check CAN Errors detected during interrupt process
1462
1463 @endverbatim
1464 * @{
1465 */
1466
1467 /**
1468 * @brief return the CAN state
1469 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
1470 * the configuration information for the specified CAN.
1471 * @retval HAL state
1472 */
HAL_CAN_GetState(CAN_HandleTypeDef * hcan)1473 HAL_CAN_StateTypeDef HAL_CAN_GetState(CAN_HandleTypeDef* hcan)
1474 {
1475 /* Return CAN state */
1476 return hcan->State;
1477 }
1478
1479 /**
1480 * @brief Return the CAN error code
1481 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
1482 * the configuration information for the specified CAN.
1483 * @retval CAN Error Code
1484 */
HAL_CAN_GetError(CAN_HandleTypeDef * hcan)1485 uint32_t HAL_CAN_GetError(CAN_HandleTypeDef *hcan)
1486 {
1487 return hcan->ErrorCode;
1488 }
1489
1490 /**
1491 * @}
1492 */
1493
1494 /**
1495 * @}
1496 */
1497
1498 /** @addtogroup CAN_Private_Functions CAN Private Functions
1499 * @brief CAN Frame message Rx/Tx functions
1500 *
1501 * @{
1502 */
1503
1504 /**
1505 * @brief Initiates and transmits a CAN frame message.
1506 * @param hcan pointer to a CAN_HandleTypeDef structure that contains
1507 * the configuration information for the specified CAN.
1508 * @retval HAL status
1509 */
CAN_Transmit_IT(CAN_HandleTypeDef * hcan)1510 static HAL_StatusTypeDef CAN_Transmit_IT(CAN_HandleTypeDef* hcan)
1511 {
1512 /* Disable Transmit mailbox empty Interrupt */
1513 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_TME);
1514
1515 if(hcan->State == HAL_CAN_STATE_BUSY_TX)
1516 {
1517 /* Disable interrupts: */
1518 /* - Disable Error warning Interrupt */
1519 /* - Disable Error passive Interrupt */
1520 /* - Disable Bus-off Interrupt */
1521 /* - Disable Last error code Interrupt */
1522 /* - Disable Error Interrupt */
1523 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EWG |
1524 CAN_IT_EPV |
1525 CAN_IT_BOF |
1526 CAN_IT_LEC |
1527 CAN_IT_ERR );
1528 }
1529
1530 /* Change CAN state */
1531 switch(hcan->State)
1532 {
1533 case(HAL_CAN_STATE_BUSY_TX_RX0):
1534 hcan->State = HAL_CAN_STATE_BUSY_RX0;
1535 break;
1536 case(HAL_CAN_STATE_BUSY_TX_RX1):
1537 hcan->State = HAL_CAN_STATE_BUSY_RX1;
1538 break;
1539 case(HAL_CAN_STATE_BUSY_TX_RX0_RX1):
1540 hcan->State = HAL_CAN_STATE_BUSY_RX0_RX1;
1541 break;
1542 default: /* HAL_CAN_STATE_BUSY_TX */
1543 hcan->State = HAL_CAN_STATE_READY;
1544 break;
1545 }
1546
1547 /* Transmission complete callback */
1548 HAL_CAN_TxCpltCallback(hcan);
1549
1550 return HAL_OK;
1551 }
1552
1553 /**
1554 * @brief Receives a correct CAN frame.
1555 * @param hcan Pointer to a CAN_HandleTypeDef structure that contains
1556 * the configuration information for the specified CAN.
1557 * @param FIFONumber Specify the FIFO number
1558 * @retval HAL status
1559 * @retval None
1560 */
CAN_Receive_IT(CAN_HandleTypeDef * hcan,uint8_t FIFONumber)1561 static HAL_StatusTypeDef CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber)
1562 {
1563 CanRxMsgTypeDef* pRxMsg = NULL;
1564
1565 /* Set RxMsg pointer */
1566 if(FIFONumber == CAN_FIFO0)
1567 {
1568 pRxMsg = hcan->pRxMsg;
1569 }
1570 else /* FIFONumber == CAN_FIFO1 */
1571 {
1572 pRxMsg = hcan->pRx1Msg;
1573 }
1574
1575 /* Get the Id */
1576 pRxMsg->IDE = CAN_RI0R_IDE & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
1577 if (pRxMsg->IDE == CAN_ID_STD)
1578 {
1579 pRxMsg->StdId = (CAN_RI0R_STID & hcan->Instance->sFIFOMailBox[FIFONumber].RIR) >> CAN_TI0R_STID_Pos;
1580 }
1581 else
1582 {
1583 pRxMsg->ExtId = (0xFFFFFFF8U & hcan->Instance->sFIFOMailBox[FIFONumber].RIR) >> CAN_RI0R_EXID_Pos;
1584 }
1585 pRxMsg->RTR = (CAN_RI0R_RTR & hcan->Instance->sFIFOMailBox[FIFONumber].RIR) >> CAN_RI0R_RTR_Pos;
1586 /* Get the DLC */
1587 pRxMsg->DLC = (CAN_RDT0R_DLC & hcan->Instance->sFIFOMailBox[FIFONumber].RDTR) >> CAN_RDT0R_DLC_Pos;
1588 /* Get the FMI */
1589 pRxMsg->FMI = (CAN_RDT0R_FMI & hcan->Instance->sFIFOMailBox[FIFONumber].RDTR) >> CAN_RDT0R_FMI_Pos;
1590 /* Get the FIFONumber */
1591 pRxMsg->FIFONumber = FIFONumber;
1592 /* Get the data field */
1593 pRxMsg->Data[0] = (CAN_RDL0R_DATA0 & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR) >> CAN_RDL0R_DATA0_Pos;
1594 pRxMsg->Data[1] = (CAN_RDL0R_DATA1 & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR) >> CAN_RDL0R_DATA1_Pos;
1595 pRxMsg->Data[2] = (CAN_RDL0R_DATA2 & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR) >> CAN_RDL0R_DATA2_Pos;
1596 pRxMsg->Data[3] = (CAN_RDL0R_DATA3 & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR) >> CAN_RDL0R_DATA3_Pos;
1597 pRxMsg->Data[4] = (CAN_RDH0R_DATA4 & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR) >> CAN_RDH0R_DATA4_Pos;
1598 pRxMsg->Data[5] = (CAN_RDH0R_DATA5 & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR) >> CAN_RDH0R_DATA5_Pos;
1599 pRxMsg->Data[6] = (CAN_RDH0R_DATA6 & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR) >> CAN_RDH0R_DATA6_Pos;
1600 pRxMsg->Data[7] = (CAN_RDH0R_DATA7 & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR) >> CAN_RDH0R_DATA7_Pos;
1601
1602 /* Release the FIFO */
1603 /* Release FIFO0 */
1604 if (FIFONumber == CAN_FIFO0)
1605 {
1606 __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO0);
1607
1608 /* Disable FIFO 0 overrun and message pending Interrupt */
1609 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_FOV0 | CAN_IT_FMP0);
1610 }
1611 /* Release FIFO1 */
1612 else /* FIFONumber == CAN_FIFO1 */
1613 {
1614 __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO1);
1615
1616 /* Disable FIFO 1 overrun and message pending Interrupt */
1617 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_FOV1 | CAN_IT_FMP1);
1618 }
1619
1620 if((hcan->State == HAL_CAN_STATE_BUSY_RX0) || (hcan->State == HAL_CAN_STATE_BUSY_RX1))
1621 {
1622 /* Disable interrupts: */
1623 /* - Disable Error warning Interrupt */
1624 /* - Disable Error passive Interrupt */
1625 /* - Disable Bus-off Interrupt */
1626 /* - Disable Last error code Interrupt */
1627 /* - Disable Error Interrupt */
1628 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EWG |
1629 CAN_IT_EPV |
1630 CAN_IT_BOF |
1631 CAN_IT_LEC |
1632 CAN_IT_ERR );
1633 }
1634
1635 /* Change CAN state */
1636 if (FIFONumber == CAN_FIFO0)
1637 {
1638 switch(hcan->State)
1639 {
1640 case(HAL_CAN_STATE_BUSY_TX_RX0):
1641 hcan->State = HAL_CAN_STATE_BUSY_TX;
1642 break;
1643 case(HAL_CAN_STATE_BUSY_RX0_RX1):
1644 hcan->State = HAL_CAN_STATE_BUSY_RX1;
1645 break;
1646 case(HAL_CAN_STATE_BUSY_TX_RX0_RX1):
1647 hcan->State = HAL_CAN_STATE_BUSY_TX_RX1;
1648 break;
1649 default: /* HAL_CAN_STATE_BUSY_RX0 */
1650 hcan->State = HAL_CAN_STATE_READY;
1651 break;
1652 }
1653 }
1654 else /* FIFONumber == CAN_FIFO1 */
1655 {
1656 switch(hcan->State)
1657 {
1658 case(HAL_CAN_STATE_BUSY_TX_RX1):
1659 hcan->State = HAL_CAN_STATE_BUSY_TX;
1660 break;
1661 case(HAL_CAN_STATE_BUSY_RX0_RX1):
1662 hcan->State = HAL_CAN_STATE_BUSY_RX0;
1663 break;
1664 case(HAL_CAN_STATE_BUSY_TX_RX0_RX1):
1665 hcan->State = HAL_CAN_STATE_BUSY_TX_RX0;
1666 break;
1667 default: /* HAL_CAN_STATE_BUSY_RX1 */
1668 hcan->State = HAL_CAN_STATE_READY;
1669 break;
1670 }
1671 }
1672
1673 /* Receive complete callback */
1674 HAL_CAN_RxCpltCallback(hcan);
1675
1676 /* Return function status */
1677 return HAL_OK;
1678 }
1679
1680 /**
1681 * @}
1682 */
1683 #endif /* STM32F302xE || STM32F303xE || STM32F398xx || */
1684 /* STM32F302xC || STM32F303xC || STM32F358xx || */
1685 /* STM32F303x8 || STM32F334x8 || STM32F328xx || */
1686 /* STM32F302x8 || */
1687 /* STM32F373xC || STM32F378xx */
1688
1689 #endif /* HAL_CAN_LEGACY_MODULE_ENABLED */
1690 /**
1691 * @}
1692 */
1693
1694 /**
1695 * @}
1696 */
1697