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