comparison Common/Drivers/STM32F4xx_HAL_DRIVER_v120/Src/stm32f4xx_hal_can.c @ 38:5f11787b4f42

include in ostc4 repository
author heinrichsweikamp
date Sat, 28 Apr 2018 11:52:34 +0200
parents
children
comparison
equal deleted inserted replaced
37:ccc45c0e1ea2 38:5f11787b4f42
1 /**
2 ******************************************************************************
3 * @file stm32f4xx_hal_can.c
4 * @author MCD Application Team
5 * @version V1.2.0
6 * @date 26-December-2014
7 * @brief This file provides firmware functions to manage the following
8 * functionalities of the Controller Area Network (CAN) peripheral:
9 * + Initialization and de-initialization functions
10 * + IO operation functions
11 * + Peripheral Control functions
12 * + Peripheral State and Error functions
13 *
14 @verbatim
15 ==============================================================================
16 ##### How to use this driver #####
17 ==============================================================================
18 [..]
19 (#) Enable the CAN controller interface clock using
20 __HAL_RCC_CAN1_CLK_ENABLE() for CAN1 and __HAL_RCC_CAN1_CLK_ENABLE() for CAN2
21 -@- In case you are using CAN2 only, you have to enable the CAN1 clock.
22
23 (#) CAN pins configuration
24 (++) Enable the clock for the CAN GPIOs using the following function:
25 __GPIOx_CLK_ENABLE()
26 (++) Connect and configure the involved CAN pins to AF9 using the
27 following function HAL_GPIO_Init()
28
29 (#) Initialize and configure the CAN using CAN_Init() function.
30
31 (#) Transmit the desired CAN frame using HAL_CAN_Transmit() function.
32
33 (#) Receive a CAN frame using HAL_CAN_Receive() function.
34
35 *** Polling mode IO operation ***
36 =================================
37 [..]
38 (+) Start the CAN peripheral transmission and wait the end of this operation
39 using HAL_CAN_Transmit(), at this stage user can specify the value of timeout
40 according to his end application
41 (+) Start the CAN peripheral reception and wait the end of this operation
42 using HAL_CAN_Receive(), at this stage user can specify the value of timeout
43 according to his end application
44
45 *** Interrupt mode IO operation ***
46 ===================================
47 [..]
48 (+) Start the CAN peripheral transmission using HAL_CAN_Transmit_IT()
49 (+) Start the CAN peripheral reception using HAL_CAN_Receive_IT()
50 (+) Use HAL_CAN_IRQHandler() called under the used CAN Interrupt subroutine
51 (+) At CAN end of transmission HAL_CAN_TxCpltCallback() function is executed and user can
52 add his own code by customization of function pointer HAL_CAN_TxCpltCallback
53 (+) In case of CAN Error, HAL_CAN_ErrorCallback() function is executed and user can
54 add his own code by customization of function pointer HAL_CAN_ErrorCallback
55
56 *** CAN HAL driver macros list ***
57 =============================================
58 [..]
59 Below the list of most used macros in CAN HAL driver.
60
61 (+) __HAL_CAN_ENABLE_IT: Enable the specified CAN interrupts
62 (+) __HAL_CAN_DISABLE_IT: Disable the specified CAN interrupts
63 (+) __HAL_CAN_GET_IT_SOURCE: Check if the specified CAN interrupt source is enabled or disabled
64 (+) __HAL_CAN_CLEAR_FLAG: Clear the CAN's pending flags
65 (+) __HAL_CAN_GET_FLAG: Get the selected CAN's flag status
66
67 [..]
68 (@) You can refer to the CAN HAL driver header file for more useful macros
69
70 @endverbatim
71
72 ******************************************************************************
73 * @attention
74 *
75 * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
76 *
77 * Redistribution and use in source and binary forms, with or without modification,
78 * are permitted provided that the following conditions are met:
79 * 1. Redistributions of source code must retain the above copyright notice,
80 * this list of conditions and the following disclaimer.
81 * 2. Redistributions in binary form must reproduce the above copyright notice,
82 * this list of conditions and the following disclaimer in the documentation
83 * and/or other materials provided with the distribution.
84 * 3. Neither the name of STMicroelectronics nor the names of its contributors
85 * may be used to endorse or promote products derived from this software
86 * without specific prior written permission.
87 *
88 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
89 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
90 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
91 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
92 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
93 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
94 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
95 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
96 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
97 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
98 *
99 ******************************************************************************
100 */
101
102 /* Includes ------------------------------------------------------------------*/
103 #include "stm32f4xx_hal.h"
104
105 /** @addtogroup STM32F4xx_HAL_Driver
106 * @{
107 */
108
109 /** @defgroup CAN CAN
110 * @brief CAN driver modules
111 * @{
112 */
113
114 #ifdef HAL_CAN_MODULE_ENABLED
115
116 #if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) || defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)
117
118 /* Private typedef -----------------------------------------------------------*/
119 /* Private define ------------------------------------------------------------*/
120 /** @addtogroup CAN_Private_Constants
121 * @{
122 */
123 #define CAN_TIMEOUT_VALUE 10
124 /**
125 * @}
126 */
127 /* Private macro -------------------------------------------------------------*/
128 /* Private variables ---------------------------------------------------------*/
129 /* Private function prototypes -----------------------------------------------*/
130 /** @addtogroup CAN_Private_Functions
131 * @{
132 */
133 static HAL_StatusTypeDef CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber);
134 static HAL_StatusTypeDef CAN_Transmit_IT(CAN_HandleTypeDef* hcan);
135 /**
136 * @}
137 */
138
139 /* Exported functions --------------------------------------------------------*/
140 /** @defgroup CAN_Exported_Functions CAN Exported Functions
141 * @{
142 */
143
144 /** @defgroup CAN_Exported_Functions_Group1 Initialization and de-initialization functions
145 * @brief Initialization and Configuration functions
146 *
147 @verbatim
148 ==============================================================================
149 ##### Initialization and de-initialization functions #####
150 ==============================================================================
151 [..] This section provides functions allowing to:
152 (+) Initialize and configure the CAN.
153 (+) De-initialize the CAN.
154
155 @endverbatim
156 * @{
157 */
158
159 /**
160 * @brief Initializes the CAN peripheral according to the specified
161 * parameters in the CAN_InitStruct.
162 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
163 * the configuration information for the specified CAN.
164 * @retval HAL status
165 */
166 HAL_StatusTypeDef HAL_CAN_Init(CAN_HandleTypeDef* hcan)
167 {
168 uint32_t InitStatus = 3;
169 uint32_t tickstart = 0;
170
171 /* Check CAN handle */
172 if(hcan == NULL)
173 {
174 return HAL_ERROR;
175 }
176
177 /* Check the parameters */
178 assert_param(IS_CAN_ALL_INSTANCE(hcan->Instance));
179 assert_param(IS_FUNCTIONAL_STATE(hcan->Init.TTCM));
180 assert_param(IS_FUNCTIONAL_STATE(hcan->Init.ABOM));
181 assert_param(IS_FUNCTIONAL_STATE(hcan->Init.AWUM));
182 assert_param(IS_FUNCTIONAL_STATE(hcan->Init.NART));
183 assert_param(IS_FUNCTIONAL_STATE(hcan->Init.RFLM));
184 assert_param(IS_FUNCTIONAL_STATE(hcan->Init.TXFP));
185 assert_param(IS_CAN_MODE(hcan->Init.Mode));
186 assert_param(IS_CAN_SJW(hcan->Init.SJW));
187 assert_param(IS_CAN_BS1(hcan->Init.BS1));
188 assert_param(IS_CAN_BS2(hcan->Init.BS2));
189 assert_param(IS_CAN_PRESCALER(hcan->Init.Prescaler));
190
191
192 if(hcan->State == HAL_CAN_STATE_RESET)
193 {
194 /* Init the low level hardware */
195 HAL_CAN_MspInit(hcan);
196 }
197
198 /* Initialize the CAN state*/
199 hcan->State = HAL_CAN_STATE_BUSY;
200
201 /* Exit from sleep mode */
202 hcan->Instance->MCR &= (~(uint32_t)CAN_MCR_SLEEP);
203
204 /* Request initialisation */
205 hcan->Instance->MCR |= CAN_MCR_INRQ ;
206
207 /* Get tick */
208 tickstart = HAL_GetTick();
209
210 /* Wait the acknowledge */
211 while((hcan->Instance->MSR & CAN_MSR_INAK) != CAN_MSR_INAK)
212 {
213 if((HAL_GetTick() - tickstart ) > CAN_TIMEOUT_VALUE)
214 {
215 hcan->State= HAL_CAN_STATE_TIMEOUT;
216 /* Process unlocked */
217 __HAL_UNLOCK(hcan);
218 return HAL_TIMEOUT;
219 }
220 }
221
222 /* Check acknowledge */
223 if ((hcan->Instance->MSR & CAN_MSR_INAK) != CAN_MSR_INAK)
224 {
225 InitStatus = CAN_INITSTATUS_FAILED;
226 }
227 else
228 {
229 /* Set the time triggered communication mode */
230 if (hcan->Init.TTCM == ENABLE)
231 {
232 hcan->Instance->MCR |= CAN_MCR_TTCM;
233 }
234 else
235 {
236 hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_TTCM;
237 }
238
239 /* Set the automatic bus-off management */
240 if (hcan->Init.ABOM == ENABLE)
241 {
242 hcan->Instance->MCR |= CAN_MCR_ABOM;
243 }
244 else
245 {
246 hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_ABOM;
247 }
248
249 /* Set the automatic wake-up mode */
250 if (hcan->Init.AWUM == ENABLE)
251 {
252 hcan->Instance->MCR |= CAN_MCR_AWUM;
253 }
254 else
255 {
256 hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_AWUM;
257 }
258
259 /* Set the no automatic retransmission */
260 if (hcan->Init.NART == ENABLE)
261 {
262 hcan->Instance->MCR |= CAN_MCR_NART;
263 }
264 else
265 {
266 hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_NART;
267 }
268
269 /* Set the receive FIFO locked mode */
270 if (hcan->Init.RFLM == ENABLE)
271 {
272 hcan->Instance->MCR |= CAN_MCR_RFLM;
273 }
274 else
275 {
276 hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_RFLM;
277 }
278
279 /* Set the transmit FIFO priority */
280 if (hcan->Init.TXFP == ENABLE)
281 {
282 hcan->Instance->MCR |= CAN_MCR_TXFP;
283 }
284 else
285 {
286 hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_TXFP;
287 }
288
289 /* Set the bit timing register */
290 hcan->Instance->BTR = (uint32_t)((uint32_t)hcan->Init.Mode) | \
291 ((uint32_t)hcan->Init.SJW) | \
292 ((uint32_t)hcan->Init.BS1) | \
293 ((uint32_t)hcan->Init.BS2) | \
294 ((uint32_t)hcan->Init.Prescaler - 1);
295
296 /* Request leave initialisation */
297 hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_INRQ;
298
299 /* Get tick */
300 tickstart = HAL_GetTick();
301
302 /* Wait the acknowledge */
303 while((hcan->Instance->MSR & CAN_MSR_INAK) == CAN_MSR_INAK)
304 {
305 if((HAL_GetTick() - tickstart ) > CAN_TIMEOUT_VALUE)
306 {
307 hcan->State= HAL_CAN_STATE_TIMEOUT;
308 /* Process unlocked */
309 __HAL_UNLOCK(hcan);
310 return HAL_TIMEOUT;
311 }
312 }
313
314 /* Check acknowledged */
315 if ((hcan->Instance->MSR & CAN_MSR_INAK) == CAN_MSR_INAK)
316 {
317 InitStatus = CAN_INITSTATUS_FAILED;
318 }
319 else
320 {
321 InitStatus = CAN_INITSTATUS_SUCCESS;
322 }
323 }
324
325 if(InitStatus == CAN_INITSTATUS_SUCCESS)
326 {
327 /* Set CAN error code to none */
328 hcan->ErrorCode = HAL_CAN_ERROR_NONE;
329
330 /* Initialize the CAN state */
331 hcan->State = HAL_CAN_STATE_READY;
332
333 /* Return function status */
334 return HAL_OK;
335 }
336 else
337 {
338 /* Initialize the CAN state */
339 hcan->State = HAL_CAN_STATE_ERROR;
340
341 /* Return function status */
342 return HAL_ERROR;
343 }
344 }
345
346 /**
347 * @brief Configures the CAN reception filter according to the specified
348 * parameters in the CAN_FilterInitStruct.
349 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
350 * the configuration information for the specified CAN.
351 * @param sFilterConfig: pointer to a CAN_FilterConfTypeDef structure that
352 * contains the filter configuration information.
353 * @retval None
354 */
355 HAL_StatusTypeDef HAL_CAN_ConfigFilter(CAN_HandleTypeDef* hcan, CAN_FilterConfTypeDef* sFilterConfig)
356 {
357 uint32_t filternbrbitpos = 0;
358
359 /* Check the parameters */
360 assert_param(IS_CAN_FILTER_NUMBER(sFilterConfig->FilterNumber));
361 assert_param(IS_CAN_FILTER_MODE(sFilterConfig->FilterMode));
362 assert_param(IS_CAN_FILTER_SCALE(sFilterConfig->FilterScale));
363 assert_param(IS_CAN_FILTER_FIFO(sFilterConfig->FilterFIFOAssignment));
364 assert_param(IS_FUNCTIONAL_STATE(sFilterConfig->FilterActivation));
365 assert_param(IS_CAN_BANKNUMBER(sFilterConfig->BankNumber));
366
367 filternbrbitpos = ((uint32_t)1) << sFilterConfig->FilterNumber;
368
369 /* Initialisation mode for the filter */
370 CAN1->FMR |= (uint32_t)CAN_FMR_FINIT;
371
372 /* Select the start slave bank */
373 CAN1->FMR &= ~((uint32_t)CAN_FMR_CAN2SB);
374 CAN1->FMR |= (uint32_t)(sFilterConfig->BankNumber << 8);
375
376 /* Filter Deactivation */
377 CAN1->FA1R &= ~(uint32_t)filternbrbitpos;
378
379 /* Filter Scale */
380 if (sFilterConfig->FilterScale == CAN_FILTERSCALE_16BIT)
381 {
382 /* 16-bit scale for the filter */
383 CAN1->FS1R &= ~(uint32_t)filternbrbitpos;
384
385 /* First 16-bit identifier and First 16-bit mask */
386 /* Or First 16-bit identifier and Second 16-bit identifier */
387 CAN1->sFilterRegister[sFilterConfig->FilterNumber].FR1 =
388 ((0x0000FFFF & (uint32_t)sFilterConfig->FilterMaskIdLow) << 16) |
389 (0x0000FFFF & (uint32_t)sFilterConfig->FilterIdLow);
390
391 /* Second 16-bit identifier and Second 16-bit mask */
392 /* Or Third 16-bit identifier and Fourth 16-bit identifier */
393 CAN1->sFilterRegister[sFilterConfig->FilterNumber].FR2 =
394 ((0x0000FFFF & (uint32_t)sFilterConfig->FilterMaskIdHigh) << 16) |
395 (0x0000FFFF & (uint32_t)sFilterConfig->FilterIdHigh);
396 }
397
398 if (sFilterConfig->FilterScale == CAN_FILTERSCALE_32BIT)
399 {
400 /* 32-bit scale for the filter */
401 CAN1->FS1R |= filternbrbitpos;
402 /* 32-bit identifier or First 32-bit identifier */
403 CAN1->sFilterRegister[sFilterConfig->FilterNumber].FR1 =
404 ((0x0000FFFF & (uint32_t)sFilterConfig->FilterIdHigh) << 16) |
405 (0x0000FFFF & (uint32_t)sFilterConfig->FilterIdLow);
406 /* 32-bit mask or Second 32-bit identifier */
407 CAN1->sFilterRegister[sFilterConfig->FilterNumber].FR2 =
408 ((0x0000FFFF & (uint32_t)sFilterConfig->FilterMaskIdHigh) << 16) |
409 (0x0000FFFF & (uint32_t)sFilterConfig->FilterMaskIdLow);
410 }
411
412 /* Filter Mode */
413 if (sFilterConfig->FilterMode == CAN_FILTERMODE_IDMASK)
414 {
415 /*Id/Mask mode for the filter*/
416 CAN1->FM1R &= ~(uint32_t)filternbrbitpos;
417 }
418 else /* CAN_FilterInitStruct->CAN_FilterMode == CAN_FilterMode_IdList */
419 {
420 /*Identifier list mode for the filter*/
421 CAN1->FM1R |= (uint32_t)filternbrbitpos;
422 }
423
424 /* Filter FIFO assignment */
425 if (sFilterConfig->FilterFIFOAssignment == CAN_FILTER_FIFO0)
426 {
427 /* FIFO 0 assignation for the filter */
428 CAN1->FFA1R &= ~(uint32_t)filternbrbitpos;
429 }
430
431 if (sFilterConfig->FilterFIFOAssignment == CAN_FILTER_FIFO1)
432 {
433 /* FIFO 1 assignation for the filter */
434 CAN1->FFA1R |= (uint32_t)filternbrbitpos;
435 }
436
437 /* Filter activation */
438 if (sFilterConfig->FilterActivation == ENABLE)
439 {
440 CAN1->FA1R |= filternbrbitpos;
441 }
442
443 /* Leave the initialisation mode for the filter */
444 CAN1->FMR &= ~((uint32_t)CAN_FMR_FINIT);
445
446 /* Return function status */
447 return HAL_OK;
448 }
449
450 /**
451 * @brief Deinitializes the CANx peripheral registers to their default reset values.
452 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
453 * the configuration information for the specified CAN.
454 * @retval HAL status
455 */
456 HAL_StatusTypeDef HAL_CAN_DeInit(CAN_HandleTypeDef* hcan)
457 {
458 /* Check CAN handle */
459 if(hcan == NULL)
460 {
461 return HAL_ERROR;
462 }
463
464 /* Check the parameters */
465 assert_param(IS_CAN_ALL_INSTANCE(hcan->Instance));
466
467 /* Change CAN state */
468 hcan->State = HAL_CAN_STATE_BUSY;
469
470 /* DeInit the low level hardware */
471 HAL_CAN_MspDeInit(hcan);
472
473 /* Change CAN state */
474 hcan->State = HAL_CAN_STATE_RESET;
475
476 /* Release Lock */
477 __HAL_UNLOCK(hcan);
478
479 /* Return function status */
480 return HAL_OK;
481 }
482
483 /**
484 * @brief Initializes the CAN MSP.
485 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
486 * the configuration information for the specified CAN.
487 * @retval None
488 */
489 __weak void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan)
490 {
491 /* NOTE : This function Should not be modified, when the callback is needed,
492 the HAL_CAN_MspInit could be implemented in the user file
493 */
494 }
495
496 /**
497 * @brief DeInitializes the CAN MSP.
498 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
499 * the configuration information for the specified CAN.
500 * @retval None
501 */
502 __weak void HAL_CAN_MspDeInit(CAN_HandleTypeDef* hcan)
503 {
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 */
537 HAL_StatusTypeDef HAL_CAN_Transmit(CAN_HandleTypeDef* hcan, uint32_t Timeout)
538 {
539 uint32_t transmitmailbox = 5;
540 uint32_t tickstart = 0;
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 /* Process locked */
548 __HAL_LOCK(hcan);
549
550 if(hcan->State == HAL_CAN_STATE_BUSY_RX)
551 {
552 /* Change CAN state */
553 hcan->State = HAL_CAN_STATE_BUSY_TX_RX;
554 }
555 else
556 {
557 /* Change CAN state */
558 hcan->State = HAL_CAN_STATE_BUSY_TX;
559 }
560
561 /* Select one empty transmit mailbox */
562 if ((hcan->Instance->TSR&CAN_TSR_TME0) == CAN_TSR_TME0)
563 {
564 transmitmailbox = 0;
565 }
566 else if ((hcan->Instance->TSR&CAN_TSR_TME1) == CAN_TSR_TME1)
567 {
568 transmitmailbox = 1;
569 }
570 else if ((hcan->Instance->TSR&CAN_TSR_TME2) == CAN_TSR_TME2)
571 {
572 transmitmailbox = 2;
573 }
574 else
575 {
576 transmitmailbox = CAN_TXSTATUS_NOMAILBOX;
577 }
578
579 if (transmitmailbox != CAN_TXSTATUS_NOMAILBOX)
580 {
581 /* Set up the Id */
582 hcan->Instance->sTxMailBox[transmitmailbox].TIR &= CAN_TI0R_TXRQ;
583 if (hcan->pTxMsg->IDE == CAN_ID_STD)
584 {
585 assert_param(IS_CAN_STDID(hcan->pTxMsg->StdId));
586 hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->StdId << 21) | \
587 hcan->pTxMsg->RTR);
588 }
589 else
590 {
591 assert_param(IS_CAN_EXTID(hcan->pTxMsg->ExtId));
592 hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->ExtId << 3) | \
593 hcan->pTxMsg->IDE | \
594 hcan->pTxMsg->RTR);
595 }
596
597 /* Set up the DLC */
598 hcan->pTxMsg->DLC &= (uint8_t)0x0000000F;
599 hcan->Instance->sTxMailBox[transmitmailbox].TDTR &= (uint32_t)0xFFFFFFF0;
600 hcan->Instance->sTxMailBox[transmitmailbox].TDTR |= hcan->pTxMsg->DLC;
601
602 /* Set up the data field */
603 hcan->Instance->sTxMailBox[transmitmailbox].TDLR = (((uint32_t)hcan->pTxMsg->Data[3] << 24) |
604 ((uint32_t)hcan->pTxMsg->Data[2] << 16) |
605 ((uint32_t)hcan->pTxMsg->Data[1] << 8) |
606 ((uint32_t)hcan->pTxMsg->Data[0]));
607 hcan->Instance->sTxMailBox[transmitmailbox].TDHR = (((uint32_t)hcan->pTxMsg->Data[7] << 24) |
608 ((uint32_t)hcan->pTxMsg->Data[6] << 16) |
609 ((uint32_t)hcan->pTxMsg->Data[5] << 8) |
610 ((uint32_t)hcan->pTxMsg->Data[4]));
611 /* Request transmission */
612 hcan->Instance->sTxMailBox[transmitmailbox].TIR |= CAN_TI0R_TXRQ;
613
614 /* Get tick */
615 tickstart = HAL_GetTick();
616
617 /* Check End of transmission flag */
618 while(!(__HAL_CAN_TRANSMIT_STATUS(hcan, transmitmailbox)))
619 {
620 /* Check for the Timeout */
621 if(Timeout != HAL_MAX_DELAY)
622 {
623 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
624 {
625 hcan->State = HAL_CAN_STATE_TIMEOUT;
626 /* Process unlocked */
627 __HAL_UNLOCK(hcan);
628 return HAL_TIMEOUT;
629 }
630 }
631 }
632 if(hcan->State == HAL_CAN_STATE_BUSY_TX_RX)
633 {
634 /* Change CAN state */
635 hcan->State = HAL_CAN_STATE_BUSY_RX;
636
637 /* Process unlocked */
638 __HAL_UNLOCK(hcan);
639 }
640 else
641 {
642 /* Change CAN state */
643 hcan->State = HAL_CAN_STATE_READY;
644
645 /* Process unlocked */
646 __HAL_UNLOCK(hcan);
647 }
648
649 /* Return function status */
650 return HAL_OK;
651 }
652 else
653 {
654 /* Change CAN state */
655 hcan->State = HAL_CAN_STATE_ERROR;
656
657 /* Process unlocked */
658 __HAL_UNLOCK(hcan);
659
660 /* Return function status */
661 return HAL_ERROR;
662 }
663 }
664
665 /**
666 * @brief Initiates and transmits a CAN frame message.
667 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
668 * the configuration information for the specified CAN.
669 * @retval HAL status
670 */
671 HAL_StatusTypeDef HAL_CAN_Transmit_IT(CAN_HandleTypeDef* hcan)
672 {
673 uint32_t transmitmailbox = 5;
674 uint32_t tmp = 0;
675
676 /* Check the parameters */
677 assert_param(IS_CAN_IDTYPE(hcan->pTxMsg->IDE));
678 assert_param(IS_CAN_RTR(hcan->pTxMsg->RTR));
679 assert_param(IS_CAN_DLC(hcan->pTxMsg->DLC));
680
681 tmp = hcan->State;
682 if((tmp == HAL_CAN_STATE_READY) || (tmp == HAL_CAN_STATE_BUSY_RX))
683 {
684 /* Process Locked */
685 __HAL_LOCK(hcan);
686
687 /* Select one empty transmit mailbox */
688 if((hcan->Instance->TSR&CAN_TSR_TME0) == CAN_TSR_TME0)
689 {
690 transmitmailbox = 0;
691 }
692 else if((hcan->Instance->TSR&CAN_TSR_TME1) == CAN_TSR_TME1)
693 {
694 transmitmailbox = 1;
695 }
696 else if((hcan->Instance->TSR&CAN_TSR_TME2) == CAN_TSR_TME2)
697 {
698 transmitmailbox = 2;
699 }
700 else
701 {
702 transmitmailbox = CAN_TXSTATUS_NOMAILBOX;
703 }
704
705 if(transmitmailbox != CAN_TXSTATUS_NOMAILBOX)
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 << 21) | \
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 << 3) | \
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 &= (uint32_t)0xFFFFFFF0;
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[3] << 24) |
730 ((uint32_t)hcan->pTxMsg->Data[2] << 16) |
731 ((uint32_t)hcan->pTxMsg->Data[1] << 8) |
732 ((uint32_t)hcan->pTxMsg->Data[0]));
733 hcan->Instance->sTxMailBox[transmitmailbox].TDHR = (((uint32_t)hcan->pTxMsg->Data[7] << 24) |
734 ((uint32_t)hcan->pTxMsg->Data[6] << 16) |
735 ((uint32_t)hcan->pTxMsg->Data[5] << 8) |
736 ((uint32_t)hcan->pTxMsg->Data[4]));
737
738 if(hcan->State == HAL_CAN_STATE_BUSY_RX)
739 {
740 /* Change CAN state */
741 hcan->State = HAL_CAN_STATE_BUSY_TX_RX;
742 }
743 else
744 {
745 /* Change CAN state */
746 hcan->State = HAL_CAN_STATE_BUSY_TX;
747 }
748
749 /* Set CAN error code to none */
750 hcan->ErrorCode = HAL_CAN_ERROR_NONE;
751
752 /* Process Unlocked */
753 __HAL_UNLOCK(hcan);
754
755 /* Enable Error warning Interrupt */
756 __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EWG);
757
758 /* Enable Error passive Interrupt */
759 __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EPV);
760
761 /* Enable Bus-off Interrupt */
762 __HAL_CAN_ENABLE_IT(hcan, CAN_IT_BOF);
763
764 /* Enable Last error code Interrupt */
765 __HAL_CAN_ENABLE_IT(hcan, CAN_IT_LEC);
766
767 /* Enable Error Interrupt */
768 __HAL_CAN_ENABLE_IT(hcan, CAN_IT_ERR);
769
770 /* Enable Transmit mailbox empty Interrupt */
771 __HAL_CAN_ENABLE_IT(hcan, CAN_IT_TME);
772
773 /* Request transmission */
774 hcan->Instance->sTxMailBox[transmitmailbox].TIR |= CAN_TI0R_TXRQ;
775 }
776 }
777 else
778 {
779 return HAL_BUSY;
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 */
793 HAL_StatusTypeDef HAL_CAN_Receive(CAN_HandleTypeDef* hcan, uint8_t FIFONumber, uint32_t Timeout)
794 {
795 uint32_t tickstart = 0;
796
797 /* Check the parameters */
798 assert_param(IS_CAN_FIFO(FIFONumber));
799
800 /* Process locked */
801 __HAL_LOCK(hcan);
802
803 if(hcan->State == HAL_CAN_STATE_BUSY_TX)
804 {
805 /* Change CAN state */
806 hcan->State = HAL_CAN_STATE_BUSY_TX_RX;
807 }
808 else
809 {
810 /* Change CAN state */
811 hcan->State = HAL_CAN_STATE_BUSY_RX;
812 }
813
814 /* Get tick */
815 tickstart = HAL_GetTick();
816
817 /* Check pending message */
818 while(__HAL_CAN_MSG_PENDING(hcan, FIFONumber) == 0)
819 {
820 /* Check for the Timeout */
821 if(Timeout != HAL_MAX_DELAY)
822 {
823 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
824 {
825 hcan->State = HAL_CAN_STATE_TIMEOUT;
826 /* Process unlocked */
827 __HAL_UNLOCK(hcan);
828 return HAL_TIMEOUT;
829 }
830 }
831 }
832
833 /* Get the Id */
834 hcan->pRxMsg->IDE = (uint8_t)0x04 & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
835 if (hcan->pRxMsg->IDE == CAN_ID_STD)
836 {
837 hcan->pRxMsg->StdId = (uint32_t)0x000007FF & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 21);
838 }
839 else
840 {
841 hcan->pRxMsg->ExtId = (uint32_t)0x1FFFFFFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 3);
842 }
843
844 hcan->pRxMsg->RTR = (uint8_t)0x02 & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
845 /* Get the DLC */
846 hcan->pRxMsg->DLC = (uint8_t)0x0F & hcan->Instance->sFIFOMailBox[FIFONumber].RDTR;
847 /* Get the FMI */
848 hcan->pRxMsg->FMI = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDTR >> 8);
849 /* Get the data field */
850 hcan->pRxMsg->Data[0] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR;
851 hcan->pRxMsg->Data[1] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 8);
852 hcan->pRxMsg->Data[2] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 16);
853 hcan->pRxMsg->Data[3] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 24);
854 hcan->pRxMsg->Data[4] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR;
855 hcan->pRxMsg->Data[5] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 8);
856 hcan->pRxMsg->Data[6] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 16);
857 hcan->pRxMsg->Data[7] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 24);
858
859 /* Release the FIFO */
860 if(FIFONumber == CAN_FIFO0)
861 {
862 /* Release FIFO0 */
863 __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO0);
864 }
865 else /* FIFONumber == CAN_FIFO1 */
866 {
867 /* Release FIFO1 */
868 __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO1);
869 }
870
871 if(hcan->State == HAL_CAN_STATE_BUSY_TX_RX)
872 {
873 /* Change CAN state */
874 hcan->State = HAL_CAN_STATE_BUSY_TX;
875
876 /* Process unlocked */
877 __HAL_UNLOCK(hcan);
878 }
879 else
880 {
881 /* Change CAN state */
882 hcan->State = HAL_CAN_STATE_READY;
883
884 /* Process unlocked */
885 __HAL_UNLOCK(hcan);
886 }
887
888 /* Return function status */
889 return HAL_OK;
890 }
891
892 /**
893 * @brief Receives a correct CAN frame.
894 * @param hcan: Pointer to a CAN_HandleTypeDef structure that contains
895 * the configuration information for the specified CAN.
896 * @param FIFONumber: Specify the FIFO number
897 * @retval HAL status
898 */
899 HAL_StatusTypeDef HAL_CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber)
900 {
901 uint32_t tmp = 0;
902
903 /* Check the parameters */
904 assert_param(IS_CAN_FIFO(FIFONumber));
905
906 tmp = hcan->State;
907 if((tmp == HAL_CAN_STATE_READY) || (tmp == HAL_CAN_STATE_BUSY_TX))
908 {
909 /* Process locked */
910 __HAL_LOCK(hcan);
911
912 if(hcan->State == HAL_CAN_STATE_BUSY_TX)
913 {
914 /* Change CAN state */
915 hcan->State = HAL_CAN_STATE_BUSY_TX_RX;
916 }
917 else
918 {
919 /* Change CAN state */
920 hcan->State = HAL_CAN_STATE_BUSY_RX;
921 }
922
923 /* Set CAN error code to none */
924 hcan->ErrorCode = HAL_CAN_ERROR_NONE;
925
926 /* Enable Error warning Interrupt */
927 __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EWG);
928
929 /* Enable Error passive Interrupt */
930 __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EPV);
931
932 /* Enable Bus-off Interrupt */
933 __HAL_CAN_ENABLE_IT(hcan, CAN_IT_BOF);
934
935 /* Enable Last error code Interrupt */
936 __HAL_CAN_ENABLE_IT(hcan, CAN_IT_LEC);
937
938 /* Enable Error Interrupt */
939 __HAL_CAN_ENABLE_IT(hcan, CAN_IT_ERR);
940
941 /* Process unlocked */
942 __HAL_UNLOCK(hcan);
943
944 if(FIFONumber == CAN_FIFO0)
945 {
946 /* Enable FIFO 0 message pending Interrupt */
947 __HAL_CAN_ENABLE_IT(hcan, CAN_IT_FMP0);
948 }
949 else
950 {
951 /* Enable FIFO 1 message pending Interrupt */
952 __HAL_CAN_ENABLE_IT(hcan, CAN_IT_FMP1);
953 }
954
955 }
956 else
957 {
958 return HAL_BUSY;
959 }
960
961 /* Return function status */
962 return HAL_OK;
963 }
964
965 /**
966 * @brief Enters the Sleep (low power) mode.
967 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
968 * the configuration information for the specified CAN.
969 * @retval HAL status.
970 */
971 HAL_StatusTypeDef HAL_CAN_Sleep(CAN_HandleTypeDef* hcan)
972 {
973 uint32_t tickstart = 0;
974
975 /* Process locked */
976 __HAL_LOCK(hcan);
977
978 /* Change CAN state */
979 hcan->State = HAL_CAN_STATE_BUSY;
980
981 /* Request Sleep mode */
982 hcan->Instance->MCR = (((hcan->Instance->MCR) & (uint32_t)(~(uint32_t)CAN_MCR_INRQ)) | CAN_MCR_SLEEP);
983
984 /* Sleep mode status */
985 if ((hcan->Instance->MSR & (CAN_MSR_SLAK|CAN_MSR_INAK)) != CAN_MSR_SLAK)
986 {
987 /* Process unlocked */
988 __HAL_UNLOCK(hcan);
989
990 /* Return function status */
991 return HAL_ERROR;
992 }
993
994 /* Get tick */
995 tickstart = HAL_GetTick();
996
997 /* Wait the acknowledge */
998 while((hcan->Instance->MSR & (CAN_MSR_SLAK|CAN_MSR_INAK)) != CAN_MSR_SLAK)
999 {
1000 if((HAL_GetTick() - tickstart) > CAN_TIMEOUT_VALUE)
1001 {
1002 hcan->State = HAL_CAN_STATE_TIMEOUT;
1003 /* Process unlocked */
1004 __HAL_UNLOCK(hcan);
1005 return HAL_TIMEOUT;
1006 }
1007 }
1008
1009 /* Change CAN state */
1010 hcan->State = HAL_CAN_STATE_READY;
1011
1012 /* Process unlocked */
1013 __HAL_UNLOCK(hcan);
1014
1015 /* Return function status */
1016 return HAL_OK;
1017 }
1018
1019 /**
1020 * @brief Wakes up the CAN peripheral from sleep mode, after that the CAN peripheral
1021 * is in the normal mode.
1022 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
1023 * the configuration information for the specified CAN.
1024 * @retval HAL status.
1025 */
1026 HAL_StatusTypeDef HAL_CAN_WakeUp(CAN_HandleTypeDef* hcan)
1027 {
1028 uint32_t tickstart = 0;
1029
1030 /* Process locked */
1031 __HAL_LOCK(hcan);
1032
1033 /* Change CAN state */
1034 hcan->State = HAL_CAN_STATE_BUSY;
1035
1036 /* Wake up request */
1037 hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_SLEEP;
1038
1039 /* Get tick */
1040 tickstart = HAL_GetTick();
1041
1042 /* Sleep mode status */
1043 while((hcan->Instance->MSR & CAN_MSR_SLAK) == CAN_MSR_SLAK)
1044 {
1045 if((HAL_GetTick() - tickstart) > CAN_TIMEOUT_VALUE)
1046 {
1047 hcan->State= HAL_CAN_STATE_TIMEOUT;
1048 /* Process unlocked */
1049 __HAL_UNLOCK(hcan);
1050 return HAL_TIMEOUT;
1051 }
1052 }
1053 if((hcan->Instance->MSR & CAN_MSR_SLAK) == CAN_MSR_SLAK)
1054 {
1055 /* Process unlocked */
1056 __HAL_UNLOCK(hcan);
1057
1058 /* Return function status */
1059 return HAL_ERROR;
1060 }
1061
1062 /* Change CAN state */
1063 hcan->State = HAL_CAN_STATE_READY;
1064
1065 /* Process unlocked */
1066 __HAL_UNLOCK(hcan);
1067
1068 /* Return function status */
1069 return HAL_OK;
1070 }
1071
1072 /**
1073 * @brief Handles CAN interrupt request
1074 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
1075 * the configuration information for the specified CAN.
1076 * @retval None
1077 */
1078 void HAL_CAN_IRQHandler(CAN_HandleTypeDef* hcan)
1079 {
1080 uint32_t tmp1 = 0, tmp2 = 0, tmp3 = 0;
1081
1082 /* Check End of transmission flag */
1083 if(__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_TME))
1084 {
1085 tmp1 = __HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_0);
1086 tmp2 = __HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_1);
1087 tmp3 = __HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_2);
1088 if(tmp1 || tmp2 || tmp3)
1089 {
1090 /* Call transmit function */
1091 CAN_Transmit_IT(hcan);
1092 }
1093 }
1094
1095 tmp1 = __HAL_CAN_MSG_PENDING(hcan, CAN_FIFO0);
1096 tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FMP0);
1097 /* Check End of reception flag for FIFO0 */
1098 if((tmp1 != 0) && tmp2)
1099 {
1100 /* Call receive function */
1101 CAN_Receive_IT(hcan, CAN_FIFO0);
1102 }
1103
1104 tmp1 = __HAL_CAN_MSG_PENDING(hcan, CAN_FIFO1);
1105 tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FMP1);
1106 /* Check End of reception flag for FIFO1 */
1107 if((tmp1 != 0) && tmp2)
1108 {
1109 /* Call receive function */
1110 CAN_Receive_IT(hcan, CAN_FIFO1);
1111 }
1112
1113 tmp1 = __HAL_CAN_GET_FLAG(hcan, CAN_FLAG_EWG);
1114 tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_EWG);
1115 tmp3 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR);
1116 /* Check Error Warning Flag */
1117 if(tmp1 && tmp2 && tmp3)
1118 {
1119 /* Set CAN error code to EWG error */
1120 hcan->ErrorCode |= HAL_CAN_ERROR_EWG;
1121 /* Clear Error Warning Flag */
1122 __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_EWG);
1123 }
1124
1125 tmp1 = __HAL_CAN_GET_FLAG(hcan, CAN_FLAG_EPV);
1126 tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_EPV);
1127 tmp3 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR);
1128 /* Check Error Passive Flag */
1129 if(tmp1 && tmp2 && tmp3)
1130 {
1131 /* Set CAN error code to EPV error */
1132 hcan->ErrorCode |= HAL_CAN_ERROR_EPV;
1133 /* Clear Error Passive Flag */
1134 __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_EPV);
1135 }
1136
1137 tmp1 = __HAL_CAN_GET_FLAG(hcan, CAN_FLAG_BOF);
1138 tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_BOF);
1139 tmp3 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR);
1140 /* Check Bus-Off Flag */
1141 if(tmp1 && tmp2 && tmp3)
1142 {
1143 /* Set CAN error code to BOF error */
1144 hcan->ErrorCode |= HAL_CAN_ERROR_BOF;
1145 /* Clear Bus-Off Flag */
1146 __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_BOF);
1147 }
1148
1149 tmp1 = HAL_IS_BIT_CLR(hcan->Instance->ESR, CAN_ESR_LEC);
1150 tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_LEC);
1151 tmp3 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR);
1152 /* Check Last error code Flag */
1153 if((!tmp1) && tmp2 && tmp3)
1154 {
1155 tmp1 = (hcan->Instance->ESR) & CAN_ESR_LEC;
1156 switch(tmp1)
1157 {
1158 case(CAN_ESR_LEC_0):
1159 /* Set CAN error code to STF error */
1160 hcan->ErrorCode |= HAL_CAN_ERROR_STF;
1161 break;
1162 case(CAN_ESR_LEC_1):
1163 /* Set CAN error code to FOR error */
1164 hcan->ErrorCode |= HAL_CAN_ERROR_FOR;
1165 break;
1166 case(CAN_ESR_LEC_1 | CAN_ESR_LEC_0):
1167 /* Set CAN error code to ACK error */
1168 hcan->ErrorCode |= HAL_CAN_ERROR_ACK;
1169 break;
1170 case(CAN_ESR_LEC_2):
1171 /* Set CAN error code to BR error */
1172 hcan->ErrorCode |= HAL_CAN_ERROR_BR;
1173 break;
1174 case(CAN_ESR_LEC_2 | CAN_ESR_LEC_0):
1175 /* Set CAN error code to BD error */
1176 hcan->ErrorCode |= HAL_CAN_ERROR_BD;
1177 break;
1178 case(CAN_ESR_LEC_2 | CAN_ESR_LEC_1):
1179 /* Set CAN error code to CRC error */
1180 hcan->ErrorCode |= HAL_CAN_ERROR_CRC;
1181 break;
1182 default:
1183 break;
1184 }
1185
1186 /* Clear Last error code Flag */
1187 hcan->Instance->ESR &= ~(CAN_ESR_LEC);
1188 }
1189
1190 /* Call the Error call Back in case of Errors */
1191 if(hcan->ErrorCode != HAL_CAN_ERROR_NONE)
1192 {
1193 /* Set the CAN state ready to be able to start again the process */
1194 hcan->State = HAL_CAN_STATE_READY;
1195 /* Call Error callback function */
1196 HAL_CAN_ErrorCallback(hcan);
1197 }
1198 }
1199
1200 /**
1201 * @brief Transmission complete callback in non blocking mode
1202 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
1203 * the configuration information for the specified CAN.
1204 * @retval None
1205 */
1206 __weak void HAL_CAN_TxCpltCallback(CAN_HandleTypeDef* hcan)
1207 {
1208 /* NOTE : This function Should not be modified, when the callback is needed,
1209 the HAL_CAN_TxCpltCallback could be implemented in the user file
1210 */
1211 }
1212
1213 /**
1214 * @brief Transmission complete callback in non blocking mode
1215 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
1216 * the configuration information for the specified CAN.
1217 * @retval None
1218 */
1219 __weak void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* hcan)
1220 {
1221 /* NOTE : This function Should not be modified, when the callback is needed,
1222 the HAL_CAN_RxCpltCallback could be implemented in the user file
1223 */
1224 }
1225
1226 /**
1227 * @brief Error CAN callback.
1228 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
1229 * the configuration information for the specified CAN.
1230 * @retval None
1231 */
1232 __weak void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan)
1233 {
1234 /* NOTE : This function Should not be modified, when the callback is needed,
1235 the HAL_CAN_ErrorCallback could be implemented in the user file
1236 */
1237 }
1238
1239 /**
1240 * @}
1241 */
1242
1243 /** @defgroup CAN_Exported_Functions_Group3 Peripheral State and Error functions
1244 * @brief CAN Peripheral State functions
1245 *
1246 @verbatim
1247 ==============================================================================
1248 ##### Peripheral State and Error functions #####
1249 ==============================================================================
1250 [..]
1251 This subsection provides functions allowing to :
1252 (+) Check the CAN state.
1253 (+) Check CAN Errors detected during interrupt process
1254
1255 @endverbatim
1256 * @{
1257 */
1258
1259 /**
1260 * @brief return the CAN state
1261 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
1262 * the configuration information for the specified CAN.
1263 * @retval HAL state
1264 */
1265 HAL_CAN_StateTypeDef HAL_CAN_GetState(CAN_HandleTypeDef* hcan)
1266 {
1267 /* Return CAN state */
1268 return hcan->State;
1269 }
1270
1271 /**
1272 * @brief Return the CAN error code
1273 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
1274 * the configuration information for the specified CAN.
1275 * @retval CAN Error Code
1276 */
1277 uint32_t HAL_CAN_GetError(CAN_HandleTypeDef *hcan)
1278 {
1279 return hcan->ErrorCode;
1280 }
1281
1282 /**
1283 * @}
1284 */
1285 /**
1286 * @brief Initiates and transmits a CAN frame message.
1287 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
1288 * the configuration information for the specified CAN.
1289 * @retval HAL status
1290 */
1291 static HAL_StatusTypeDef CAN_Transmit_IT(CAN_HandleTypeDef* hcan)
1292 {
1293 /* Disable Transmit mailbox empty Interrupt */
1294 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_TME);
1295
1296 if(hcan->State == HAL_CAN_STATE_BUSY_TX)
1297 {
1298 /* Disable Error warning Interrupt */
1299 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EWG);
1300
1301 /* Disable Error passive Interrupt */
1302 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EPV);
1303
1304 /* Disable Bus-off Interrupt */
1305 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_BOF);
1306
1307 /* Disable Last error code Interrupt */
1308 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_LEC);
1309
1310 /* Disable Error Interrupt */
1311 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_ERR);
1312 }
1313
1314 if(hcan->State == HAL_CAN_STATE_BUSY_TX_RX)
1315 {
1316 /* Change CAN state */
1317 hcan->State = HAL_CAN_STATE_BUSY_RX;
1318 }
1319 else
1320 {
1321 /* Change CAN state */
1322 hcan->State = HAL_CAN_STATE_READY;
1323 }
1324
1325 /* Transmission complete callback */
1326 HAL_CAN_TxCpltCallback(hcan);
1327
1328 return HAL_OK;
1329 }
1330
1331 /**
1332 * @brief Receives a correct CAN frame.
1333 * @param hcan: Pointer to a CAN_HandleTypeDef structure that contains
1334 * the configuration information for the specified CAN.
1335 * @param FIFONumber: Specify the FIFO number
1336 * @retval HAL status
1337 * @retval None
1338 */
1339 static HAL_StatusTypeDef CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber)
1340 {
1341 /* Get the Id */
1342 hcan->pRxMsg->IDE = (uint8_t)0x04 & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
1343 if (hcan->pRxMsg->IDE == CAN_ID_STD)
1344 {
1345 hcan->pRxMsg->StdId = (uint32_t)0x000007FF & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 21);
1346 }
1347 else
1348 {
1349 hcan->pRxMsg->ExtId = (uint32_t)0x1FFFFFFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 3);
1350 }
1351
1352 hcan->pRxMsg->RTR = (uint8_t)0x02 & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
1353 /* Get the DLC */
1354 hcan->pRxMsg->DLC = (uint8_t)0x0F & hcan->Instance->sFIFOMailBox[FIFONumber].RDTR;
1355 /* Get the FMI */
1356 hcan->pRxMsg->FMI = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDTR >> 8);
1357 /* Get the data field */
1358 hcan->pRxMsg->Data[0] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR;
1359 hcan->pRxMsg->Data[1] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 8);
1360 hcan->pRxMsg->Data[2] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 16);
1361 hcan->pRxMsg->Data[3] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 24);
1362 hcan->pRxMsg->Data[4] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR;
1363 hcan->pRxMsg->Data[5] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 8);
1364 hcan->pRxMsg->Data[6] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 16);
1365 hcan->pRxMsg->Data[7] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 24);
1366 /* Release the FIFO */
1367 /* Release FIFO0 */
1368 if (FIFONumber == CAN_FIFO0)
1369 {
1370 __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO0);
1371
1372 /* Disable FIFO 0 message pending Interrupt */
1373 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_FMP0);
1374 }
1375 /* Release FIFO1 */
1376 else /* FIFONumber == CAN_FIFO1 */
1377 {
1378 __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO1);
1379
1380 /* Disable FIFO 1 message pending Interrupt */
1381 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_FMP1);
1382 }
1383
1384 if(hcan->State == HAL_CAN_STATE_BUSY_RX)
1385 {
1386 /* Disable Error warning Interrupt */
1387 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EWG);
1388
1389 /* Disable Error passive Interrupt */
1390 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EPV);
1391
1392 /* Disable Bus-off Interrupt */
1393 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_BOF);
1394
1395 /* Disable Last error code Interrupt */
1396 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_LEC);
1397
1398 /* Disable Error Interrupt */
1399 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_ERR);
1400 }
1401
1402 if(hcan->State == HAL_CAN_STATE_BUSY_TX_RX)
1403 {
1404 /* Disable CAN state */
1405 hcan->State = HAL_CAN_STATE_BUSY_TX;
1406 }
1407 else
1408 {
1409 /* Change CAN state */
1410 hcan->State = HAL_CAN_STATE_READY;
1411 }
1412
1413 /* Receive complete callback */
1414 HAL_CAN_RxCpltCallback(hcan);
1415
1416 /* Return function status */
1417 return HAL_OK;
1418 }
1419
1420 /**
1421 * @}
1422 */
1423 #endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */
1424
1425 #endif /* HAL_CAN_MODULE_ENABLED */
1426 /**
1427 * @}
1428 */
1429
1430 /**
1431 * @}
1432 */
1433
1434 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/