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