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