]> git.gir.st - tmk_keyboard.git/blob - tool/mbed/mbed-sdk/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_STM32F1/stm32f1xx_hal_can.c
Squashed 'tmk_core/' changes from 7967731..b9e0ea0
[tmk_keyboard.git] / tool / mbed / mbed-sdk / libraries / mbed / targets / cmsis / TARGET_STM / TARGET_STM32F1 / stm32f1xx_hal_can.c
1 /**
2 ******************************************************************************
3 * @file stm32f1xx_hal_can.c
4 * @author MCD Application Team
5 * @version V1.0.0
6 * @date 15-December-2014
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 using the
28 following function HAL_GPIO_Init();
29
30 (#) Initialise 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>&copy; COPYRIGHT(c) 2014 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 "stm32f1xx_hal.h"
105
106 #ifdef HAL_CAN_MODULE_ENABLED
107
108 #if defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || \
109 defined(STM32F103xG) || defined(STM32F105xC) || defined(STM32F107xC)
110
111 /** @addtogroup STM32F1xx_HAL_Driver
112 * @{
113 */
114
115 /** @defgroup CAN CAN
116 * @brief CAN driver modules
117 * @{
118 */
119
120 /* Private typedef -----------------------------------------------------------*/
121 /* Private define ------------------------------------------------------------*/
122 /** @defgroup CAN_Private_Constants CAN Private Constants
123 * @{
124 */
125 #define CAN_TIMEOUT_VALUE 10
126
127 #define CAN_TI0R_STID_BIT_POSITION ((uint32_t)21) /* Position of LSB bits STID in register CAN_TI0R */
128 #define CAN_TI0R_EXID_BIT_POSITION ((uint32_t) 3) /* Position of LSB bits EXID in register CAN_TI0R */
129 #define CAN_TDL0R_DATA0_BIT_POSITION ((uint32_t) 0) /* Position of LSB bits DATA0 in register CAN_TDL0R */
130 #define CAN_TDL0R_DATA1_BIT_POSITION ((uint32_t) 8) /* Position of LSB bits DATA1 in register CAN_TDL0R */
131 #define CAN_TDL0R_DATA2_BIT_POSITION ((uint32_t)16) /* Position of LSB bits DATA2 in register CAN_TDL0R */
132 #define CAN_TDL0R_DATA3_BIT_POSITION ((uint32_t)24) /* Position of LSB bits DATA3 in register CAN_TDL0R */
133
134 /**
135 * @}
136 */
137
138 /* Private macro -------------------------------------------------------------*/
139 /* Private variables ---------------------------------------------------------*/
140 /* Private function prototypes -----------------------------------------------*/
141 static HAL_StatusTypeDef CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber);
142 static HAL_StatusTypeDef CAN_Transmit_IT(CAN_HandleTypeDef* hcan);
143 /* Exported functions ---------------------------------------------------------*/
144
145 /** @defgroup CAN_Exported_Functions CAN Exported Functions
146 * @{
147 */
148
149 /** @defgroup CAN_Exported_Functions_Group1 Initialization and de-initialization functions
150 * @brief Initialization and Configuration functions
151 *
152 @verbatim
153 ==============================================================================
154 ##### Initialization and de-initialization functions #####
155 ==============================================================================
156 [..] This section provides functions allowing to:
157 (+) Initialize and configure the CAN.
158 (+) De-initialize the CAN.
159
160 @endverbatim
161 * @{
162 */
163
164 /**
165 * @brief Initializes the CAN peripheral according to the specified
166 * parameters in the CAN_InitStruct.
167 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
168 * the configuration information for the specified CAN.
169 * @retval HAL status
170 */
171 HAL_StatusTypeDef HAL_CAN_Init(CAN_HandleTypeDef* hcan)
172 {
173 uint32_t status = CAN_INITSTATUS_FAILED; /* Default init status */
174 uint32_t tickstart = 0;
175 uint32_t tmp_mcr = 0;
176
177 /* Check CAN handle */
178 if(hcan == NULL)
179 {
180 return HAL_ERROR;
181 }
182
183 /* Check the parameters */
184 assert_param(IS_CAN_ALL_INSTANCE(hcan->Instance));
185 assert_param(IS_FUNCTIONAL_STATE(hcan->Init.TTCM));
186 assert_param(IS_FUNCTIONAL_STATE(hcan->Init.ABOM));
187 assert_param(IS_FUNCTIONAL_STATE(hcan->Init.AWUM));
188 assert_param(IS_FUNCTIONAL_STATE(hcan->Init.NART));
189 assert_param(IS_FUNCTIONAL_STATE(hcan->Init.RFLM));
190 assert_param(IS_FUNCTIONAL_STATE(hcan->Init.TXFP));
191 assert_param(IS_CAN_MODE(hcan->Init.Mode));
192 assert_param(IS_CAN_SJW(hcan->Init.SJW));
193 assert_param(IS_CAN_BS1(hcan->Init.BS1));
194 assert_param(IS_CAN_BS2(hcan->Init.BS2));
195 assert_param(IS_CAN_PRESCALER(hcan->Init.Prescaler));
196
197 if(hcan->State == HAL_CAN_STATE_RESET)
198 {
199 /* Allocate lock resource and initialize it */
200 hcan-> Lock = HAL_UNLOCKED;
201 /* Init the low level hardware */
202 HAL_CAN_MspInit(hcan);
203 }
204
205 /* Initialize the CAN state*/
206 hcan->State = HAL_CAN_STATE_BUSY;
207
208 /* Exit from sleep mode */
209 CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_SLEEP);
210
211 /* Request initialisation */
212 SET_BIT(hcan->Instance->MCR, CAN_MCR_INRQ);
213
214 /* Get timeout */
215 tickstart = HAL_GetTick();
216
217 /* Wait the acknowledge */
218 while(HAL_IS_BIT_CLR(hcan->Instance->MSR, CAN_MSR_INAK))
219 {
220 if((HAL_GetTick()-tickstart) > CAN_TIMEOUT_VALUE)
221 {
222 hcan->State= HAL_CAN_STATE_TIMEOUT;
223
224 /* Process unlocked */
225 __HAL_UNLOCK(hcan);
226
227 return HAL_TIMEOUT;
228 }
229 }
230
231 /* Check acknowledge */
232 if ((hcan->Instance->MSR & CAN_MSR_INAK) == CAN_MSR_INAK)
233 {
234 /* Set the time triggered communication mode */
235 if (hcan->Init.TTCM == ENABLE)
236 {
237 SET_BIT(tmp_mcr, CAN_MCR_TTCM);
238 }
239
240 /* Set the automatic bus-off management */
241 if (hcan->Init.ABOM == ENABLE)
242 {
243 SET_BIT(tmp_mcr, CAN_MCR_ABOM);
244 }
245
246 /* Set the automatic wake-up mode */
247 if (hcan->Init.AWUM == ENABLE)
248 {
249 SET_BIT(tmp_mcr, CAN_MCR_AWUM);
250 }
251
252 /* Set the no automatic retransmission */
253 if (hcan->Init.NART == ENABLE)
254 {
255 SET_BIT(tmp_mcr, CAN_MCR_NART);
256 }
257
258 /* Set the receive FIFO locked mode */
259 if (hcan->Init.RFLM == ENABLE)
260 {
261 SET_BIT(tmp_mcr, CAN_MCR_RFLM);
262 }
263
264 /* Set the transmit FIFO priority */
265 if (hcan->Init.TXFP == ENABLE)
266 {
267 SET_BIT(tmp_mcr, CAN_MCR_TXFP);
268 }
269
270 /* Update register MCR */
271 MODIFY_REG(hcan->Instance->MCR,
272 CAN_MCR_TTCM |
273 CAN_MCR_ABOM |
274 CAN_MCR_AWUM |
275 CAN_MCR_NART |
276 CAN_MCR_RFLM |
277 CAN_MCR_TXFP,
278 tmp_mcr);
279
280 /* Set the bit timing register */
281 WRITE_REG(hcan->Instance->BTR, (uint32_t)(hcan->Init.Mode |
282 hcan->Init.SJW |
283 hcan->Init.BS1 |
284 hcan->Init.BS2 |
285 (hcan->Init.Prescaler - 1) ));
286
287 /* Request leave initialisation */
288 CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_INRQ);
289
290 /* Get timeout */
291 tickstart = HAL_GetTick();
292
293 /* Wait the acknowledge */
294 while(HAL_IS_BIT_CLR(hcan->Instance->MSR, CAN_MSR_INAK))
295 {
296 if((HAL_GetTick()-tickstart) > CAN_TIMEOUT_VALUE)
297 {
298 hcan->State= HAL_CAN_STATE_TIMEOUT;
299
300 /* Process unlocked */
301 __HAL_UNLOCK(hcan);
302
303 return HAL_TIMEOUT;
304 }
305 }
306
307 /* Check acknowledged */
308 if (HAL_IS_BIT_SET(hcan->Instance->MSR, CAN_MSR_INAK))
309 {
310 status = CAN_INITSTATUS_SUCCESS;
311 }
312 }
313
314 if(status == CAN_INITSTATUS_SUCCESS)
315 {
316 /* Set CAN error code to none */
317 hcan->ErrorCode = HAL_CAN_ERROR_NONE;
318
319 /* Initialize the CAN state */
320 hcan->State = HAL_CAN_STATE_READY;
321
322 /* Return function status */
323 return HAL_OK;
324 }
325 else
326 {
327 /* Initialize the CAN state */
328 hcan->State = HAL_CAN_STATE_ERROR;
329
330 /* Return function status */
331 return HAL_ERROR;
332 }
333 }
334
335 /**
336 * @brief Configures the CAN reception filter according to the specified
337 * parameters in the CAN_FilterInitStruct.
338 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
339 * the configuration information for the specified CAN.
340 * @param sFilterConfig: pointer to a CAN_FilterConfTypeDef structure that
341 * contains the filter configuration information.
342 * @retval None
343 */
344 HAL_StatusTypeDef HAL_CAN_ConfigFilter(CAN_HandleTypeDef* hcan, CAN_FilterConfTypeDef* sFilterConfig)
345 {
346 uint32_t filternbrbitpos = 0;
347
348 /* Check the parameters */
349 assert_param(IS_CAN_FILTER_NUMBER(sFilterConfig->FilterNumber));
350 assert_param(IS_CAN_FILTER_MODE(sFilterConfig->FilterMode));
351 assert_param(IS_CAN_FILTER_SCALE(sFilterConfig->FilterScale));
352 assert_param(IS_CAN_FILTER_FIFO(sFilterConfig->FilterFIFOAssignment));
353 assert_param(IS_FUNCTIONAL_STATE(sFilterConfig->FilterActivation));
354 assert_param(IS_CAN_BANKNUMBER(sFilterConfig->BankNumber));
355
356 filternbrbitpos = ((uint32_t)1) << sFilterConfig->FilterNumber;
357
358 /* Initialisation mode for the filter */
359 /* Select the start slave bank */
360 MODIFY_REG(hcan->Instance->FMR ,
361 CAN_FMR_CAN2SB ,
362 CAN_FMR_FINIT |
363 (uint32_t)(sFilterConfig->BankNumber << 8) );
364
365 /* Filter Deactivation */
366 CLEAR_BIT(hcan->Instance->FA1R, filternbrbitpos);
367
368 /* Filter Scale */
369 if (sFilterConfig->FilterScale == CAN_FILTERSCALE_16BIT)
370 {
371 /* 16-bit scale for the filter */
372 CLEAR_BIT(hcan->Instance->FS1R, filternbrbitpos);
373
374 /* First 16-bit identifier and First 16-bit mask */
375 /* Or First 16-bit identifier and Second 16-bit identifier */
376 hcan->Instance->sFilterRegister[sFilterConfig->FilterNumber].FR1 =
377 ((0x0000FFFF & (uint32_t)sFilterConfig->FilterMaskIdLow) << 16) |
378 (0x0000FFFF & (uint32_t)sFilterConfig->FilterIdLow);
379
380 /* Second 16-bit identifier and Second 16-bit mask */
381 /* Or Third 16-bit identifier and Fourth 16-bit identifier */
382 hcan->Instance->sFilterRegister[sFilterConfig->FilterNumber].FR2 =
383 ((0x0000FFFF & (uint32_t)sFilterConfig->FilterMaskIdHigh) << 16) |
384 (0x0000FFFF & (uint32_t)sFilterConfig->FilterIdHigh);
385 }
386
387 if (sFilterConfig->FilterScale == CAN_FILTERSCALE_32BIT)
388 {
389 /* 32-bit scale for the filter */
390 SET_BIT(hcan->Instance->FS1R, filternbrbitpos);
391 /* 32-bit identifier or First 32-bit identifier */
392 hcan->Instance->sFilterRegister[sFilterConfig->FilterNumber].FR1 =
393 ((0x0000FFFF & (uint32_t)sFilterConfig->FilterIdHigh) << 16) |
394 (0x0000FFFF & (uint32_t)sFilterConfig->FilterIdLow);
395 /* 32-bit mask or Second 32-bit identifier */
396 hcan->Instance->sFilterRegister[sFilterConfig->FilterNumber].FR2 =
397 ((0x0000FFFF & (uint32_t)sFilterConfig->FilterMaskIdHigh) << 16) |
398 (0x0000FFFF & (uint32_t)sFilterConfig->FilterMaskIdLow);
399 }
400
401 /* Filter Mode */
402 if (sFilterConfig->FilterMode == CAN_FILTERMODE_IDMASK)
403 {
404 /*Id/Mask mode for the filter*/
405 CLEAR_BIT(hcan->Instance->FM1R, filternbrbitpos);
406 }
407 else /* CAN_FilterInitStruct->CAN_FilterMode == CAN_FilterMode_IdList */
408 {
409 /*Identifier list mode for the filter*/
410 SET_BIT(hcan->Instance->FM1R, filternbrbitpos);
411 }
412
413 /* Filter FIFO assignment */
414 if (sFilterConfig->FilterFIFOAssignment == CAN_FILTER_FIFO0)
415 {
416 /* FIFO 0 assignation for the filter */
417 CLEAR_BIT(hcan->Instance->FFA1R, filternbrbitpos);
418 }
419 else
420 {
421 /* FIFO 1 assignation for the filter */
422 SET_BIT(hcan->Instance->FFA1R, filternbrbitpos);
423 }
424
425 /* Filter activation */
426 if (sFilterConfig->FilterActivation == ENABLE)
427 {
428 SET_BIT(hcan->Instance->FA1R, filternbrbitpos);
429 }
430
431 /* Leave the initialisation mode for the filter */
432 CLEAR_BIT(hcan->Instance->FMR, ((uint32_t)CAN_FMR_FINIT));
433
434 /* Return function status */
435 return HAL_OK;
436 }
437
438 /**
439 * @brief Deinitializes the CANx peripheral registers to their default reset values.
440 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
441 * the configuration information for the specified CAN.
442 * @retval HAL status
443 */
444 HAL_StatusTypeDef HAL_CAN_DeInit(CAN_HandleTypeDef* hcan)
445 {
446 /* Check CAN handle */
447 if(hcan == NULL)
448 {
449 return HAL_ERROR;
450 }
451
452 /* Check the parameters */
453 assert_param(IS_CAN_ALL_INSTANCE(hcan->Instance));
454
455 /* Change CAN state */
456 hcan->State = HAL_CAN_STATE_BUSY;
457
458 /* DeInit the low level hardware */
459 HAL_CAN_MspDeInit(hcan);
460
461 /* Change CAN state */
462 hcan->State = HAL_CAN_STATE_RESET;
463
464 /* Release Lock */
465 __HAL_UNLOCK(hcan);
466
467 /* Return function status */
468 return HAL_OK;
469 }
470
471 /**
472 * @brief Initializes the CAN MSP.
473 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
474 * the configuration information for the specified CAN.
475 * @retval None
476 */
477 __weak void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan)
478 {
479 /* NOTE : This function Should not be modified, when the callback is needed,
480 the HAL_CAN_MspInit can be implemented in the user file
481 */
482 }
483
484 /**
485 * @brief DeInitializes the CAN MSP.
486 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
487 * the configuration information for the specified CAN.
488 * @retval None
489 */
490 __weak void HAL_CAN_MspDeInit(CAN_HandleTypeDef* hcan)
491 {
492 /* NOTE : This function Should not be modified, when the callback is needed,
493 the HAL_CAN_MspDeInit can be implemented in the user file
494 */
495 }
496
497 /**
498 * @}
499 */
500
501 /** @defgroup CAN_Exported_Functions_Group2 Input and Output operation functions
502 * @brief I/O operation functions
503 *
504 @verbatim
505 ==============================================================================
506 ##### IO operation functions #####
507 ==============================================================================
508 [..] This section provides functions allowing to:
509 (+) Transmit a CAN frame message.
510 (+) Receive a CAN frame message.
511 (+) Enter CAN peripheral in sleep mode.
512 (+) Wake up the CAN peripheral from sleep mode.
513
514 @endverbatim
515 * @{
516 */
517
518 /**
519 * @brief Initiates and transmits a CAN frame message.
520 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
521 * the configuration information for the specified CAN.
522 * @param Timeout: Specify Timeout value
523 * @retval HAL status
524 */
525 HAL_StatusTypeDef HAL_CAN_Transmit(CAN_HandleTypeDef* hcan, uint32_t Timeout)
526 {
527 uint32_t transmitmailbox = CAN_TXSTATUS_NOMAILBOX;
528 uint32_t tickstart = 0;
529
530 /* Check the parameters */
531 assert_param(IS_CAN_IDTYPE(hcan->pTxMsg->IDE));
532 assert_param(IS_CAN_RTR(hcan->pTxMsg->RTR));
533 assert_param(IS_CAN_DLC(hcan->pTxMsg->DLC));
534
535 /* Process locked */
536 __HAL_LOCK(hcan);
537
538 if(hcan->State == HAL_CAN_STATE_BUSY_RX)
539 {
540 /* Change CAN state */
541 hcan->State = HAL_CAN_STATE_BUSY_TX_RX;
542 }
543 else
544 {
545 /* Change CAN state */
546 hcan->State = HAL_CAN_STATE_BUSY_TX;
547 }
548
549 /* Select one empty transmit mailbox */
550 if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME0))
551 {
552 transmitmailbox = 0;
553 }
554 else if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME1))
555 {
556 transmitmailbox = 1;
557 }
558 else if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME2))
559 {
560 transmitmailbox = 2;
561 }
562 else
563 {
564 transmitmailbox = CAN_TXSTATUS_NOMAILBOX;
565 }
566
567 if (transmitmailbox != CAN_TXSTATUS_NOMAILBOX)
568 {
569 /* Set up the Id */
570 hcan->Instance->sTxMailBox[transmitmailbox].TIR &= CAN_TI0R_TXRQ;
571 if (hcan->pTxMsg->IDE == CAN_ID_STD)
572 {
573 assert_param(IS_CAN_STDID(hcan->pTxMsg->StdId));
574 hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->StdId << CAN_TI0R_STID_BIT_POSITION) |
575 hcan->pTxMsg->RTR);
576 }
577 else
578 {
579 assert_param(IS_CAN_EXTID(hcan->pTxMsg->ExtId));
580 hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->ExtId << CAN_TI0R_EXID_BIT_POSITION) |
581 hcan->pTxMsg->IDE |
582 hcan->pTxMsg->RTR);
583 }
584
585 /* Set up the DLC */
586 hcan->pTxMsg->DLC &= (uint8_t)0x0000000F;
587 hcan->Instance->sTxMailBox[transmitmailbox].TDTR &= (uint32_t)0xFFFFFFF0;
588 hcan->Instance->sTxMailBox[transmitmailbox].TDTR |= hcan->pTxMsg->DLC;
589
590 /* Set up the data field */
591 WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDLR, ((uint32_t)hcan->pTxMsg->Data[3] << CAN_TDL0R_DATA3_BIT_POSITION) |
592 ((uint32_t)hcan->pTxMsg->Data[2] << CAN_TDL0R_DATA2_BIT_POSITION) |
593 ((uint32_t)hcan->pTxMsg->Data[1] << CAN_TDL0R_DATA1_BIT_POSITION) |
594 ((uint32_t)hcan->pTxMsg->Data[0] << CAN_TDL0R_DATA0_BIT_POSITION) );
595 WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDHR, ((uint32_t)hcan->pTxMsg->Data[7] << CAN_TDL0R_DATA3_BIT_POSITION) |
596 ((uint32_t)hcan->pTxMsg->Data[6] << CAN_TDL0R_DATA2_BIT_POSITION) |
597 ((uint32_t)hcan->pTxMsg->Data[5] << CAN_TDL0R_DATA1_BIT_POSITION) |
598 ((uint32_t)hcan->pTxMsg->Data[4] << CAN_TDL0R_DATA0_BIT_POSITION) );
599 /* Request transmission */
600 SET_BIT(hcan->Instance->sTxMailBox[transmitmailbox].TIR, CAN_TI0R_TXRQ);
601
602 /* Get timeout */
603 tickstart = HAL_GetTick();
604
605 /* Check End of transmission flag */
606 while(!(__HAL_CAN_TRANSMIT_STATUS(hcan, transmitmailbox)))
607 {
608 /* Check for the Timeout */
609 if(Timeout != HAL_MAX_DELAY)
610 {
611 if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
612 {
613 hcan->State = HAL_CAN_STATE_TIMEOUT;
614
615 /* Process unlocked */
616 __HAL_UNLOCK(hcan);
617
618 return HAL_TIMEOUT;
619 }
620 }
621 }
622 if(hcan->State == HAL_CAN_STATE_BUSY_TX_RX)
623 {
624 /* Change CAN state */
625 hcan->State = HAL_CAN_STATE_BUSY_RX;
626
627 /* Process unlocked */
628 __HAL_UNLOCK(hcan);
629 }
630 else
631 {
632 /* Change CAN state */
633 hcan->State = HAL_CAN_STATE_READY;
634 }
635
636 /* Process unlocked */
637 __HAL_UNLOCK(hcan);
638
639 /* Return function status */
640 return HAL_OK;
641 }
642 else
643 {
644 /* Change CAN state */
645 hcan->State = HAL_CAN_STATE_ERROR;
646
647 /* Process unlocked */
648 __HAL_UNLOCK(hcan);
649
650 /* Return function status */
651 return HAL_ERROR;
652 }
653 }
654
655 /**
656 * @brief Initiates and transmits a CAN frame message.
657 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
658 * the configuration information for the specified CAN.
659 * @retval HAL status
660 */
661 HAL_StatusTypeDef HAL_CAN_Transmit_IT(CAN_HandleTypeDef* hcan)
662 {
663 uint32_t transmitmailbox = CAN_TXSTATUS_NOMAILBOX;
664
665 /* Check the parameters */
666 assert_param(IS_CAN_IDTYPE(hcan->pTxMsg->IDE));
667 assert_param(IS_CAN_RTR(hcan->pTxMsg->RTR));
668 assert_param(IS_CAN_DLC(hcan->pTxMsg->DLC));
669
670 if((hcan->State == HAL_CAN_STATE_READY) || (hcan->State == HAL_CAN_STATE_BUSY_RX))
671 {
672 /* Process Locked */
673 __HAL_LOCK(hcan);
674
675 /* Select one empty transmit mailbox */
676 if(HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME0))
677 {
678 transmitmailbox = 0;
679 }
680 else if(HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME1))
681 {
682 transmitmailbox = 1;
683 }
684 else if(HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME2))
685 {
686 transmitmailbox = 2;
687 }
688 else
689 {
690 transmitmailbox = CAN_TXSTATUS_NOMAILBOX;
691 }
692
693 if(transmitmailbox != CAN_TXSTATUS_NOMAILBOX)
694 {
695 /* Set up the Id */
696 hcan->Instance->sTxMailBox[transmitmailbox].TIR &= CAN_TI0R_TXRQ;
697 if (hcan->pTxMsg->IDE == CAN_ID_STD)
698 {
699 assert_param(IS_CAN_STDID(hcan->pTxMsg->StdId));
700 hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->StdId << CAN_TI0R_STID_BIT_POSITION) |
701 hcan->pTxMsg->RTR);
702 }
703 else
704 {
705 assert_param(IS_CAN_EXTID(hcan->pTxMsg->ExtId));
706 hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->ExtId << CAN_TI0R_EXID_BIT_POSITION) |
707 hcan->pTxMsg->IDE |
708 hcan->pTxMsg->RTR);
709 }
710
711 /* Set up the DLC */
712 hcan->pTxMsg->DLC &= (uint8_t)0x0000000F;
713 hcan->Instance->sTxMailBox[transmitmailbox].TDTR &= (uint32_t)0xFFFFFFF0;
714 hcan->Instance->sTxMailBox[transmitmailbox].TDTR |= hcan->pTxMsg->DLC;
715
716 /* Set up the data field */
717 WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDLR, ((uint32_t)hcan->pTxMsg->Data[3] << CAN_TDL0R_DATA3_BIT_POSITION) |
718 ((uint32_t)hcan->pTxMsg->Data[2] << CAN_TDL0R_DATA2_BIT_POSITION) |
719 ((uint32_t)hcan->pTxMsg->Data[1] << CAN_TDL0R_DATA1_BIT_POSITION) |
720 ((uint32_t)hcan->pTxMsg->Data[0] << CAN_TDL0R_DATA0_BIT_POSITION) );
721 WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDHR, ((uint32_t)hcan->pTxMsg->Data[7] << CAN_TDL0R_DATA3_BIT_POSITION) |
722 ((uint32_t)hcan->pTxMsg->Data[6] << CAN_TDL0R_DATA2_BIT_POSITION) |
723 ((uint32_t)hcan->pTxMsg->Data[5] << CAN_TDL0R_DATA1_BIT_POSITION) |
724 ((uint32_t)hcan->pTxMsg->Data[4] << CAN_TDL0R_DATA0_BIT_POSITION) );
725
726 if(hcan->State == HAL_CAN_STATE_BUSY_RX)
727 {
728 /* Change CAN state */
729 hcan->State = HAL_CAN_STATE_BUSY_TX_RX;
730 }
731 else
732 {
733 /* Change CAN state */
734 hcan->State = HAL_CAN_STATE_BUSY_TX;
735 }
736
737 /* Set CAN error code to none */
738 hcan->ErrorCode = HAL_CAN_ERROR_NONE;
739
740 /* Process Unlocked */
741 __HAL_UNLOCK(hcan);
742
743 /* Enable interrupts: */
744 /* - Enable Error warning Interrupt */
745 /* - Enable Error passive Interrupt */
746 /* - Enable Bus-off Interrupt */
747 /* - Enable Last error code Interrupt */
748 /* - Enable Error Interrupt */
749 /* - Enable Transmit mailbox empty Interrupt */
750 __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EWG |
751 CAN_IT_EPV |
752 CAN_IT_BOF |
753 CAN_IT_LEC |
754 CAN_IT_ERR |
755 CAN_IT_TME );
756
757 /* Request transmission */
758 hcan->Instance->sTxMailBox[transmitmailbox].TIR |= CAN_TI0R_TXRQ;
759 }
760 }
761 else
762 {
763 return HAL_BUSY;
764 }
765
766 return HAL_OK;
767 }
768
769 /**
770 * @brief Receives a correct CAN frame.
771 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
772 * the configuration information for the specified CAN.
773 * @param FIFONumber: FIFO Number value
774 * @param Timeout: Specify Timeout value
775 * @retval HAL status
776 * @retval None
777 */
778 HAL_StatusTypeDef HAL_CAN_Receive(CAN_HandleTypeDef* hcan, uint8_t FIFONumber, uint32_t Timeout)
779 {
780 uint32_t tickstart = 0;
781
782 /* Check the parameters */
783 assert_param(IS_CAN_FIFO(FIFONumber));
784
785 /* Process locked */
786 __HAL_LOCK(hcan);
787
788 if(hcan->State == HAL_CAN_STATE_BUSY_TX)
789 {
790 /* Change CAN state */
791 hcan->State = HAL_CAN_STATE_BUSY_TX_RX;
792 }
793 else
794 {
795 /* Change CAN state */
796 hcan->State = HAL_CAN_STATE_BUSY_RX;
797 }
798
799 /* Get tick */
800 tickstart = HAL_GetTick();
801
802 /* Check pending message */
803 while(__HAL_CAN_MSG_PENDING(hcan, FIFONumber) == 0)
804 {
805 /* Check for the Timeout */
806 if(Timeout != HAL_MAX_DELAY)
807 {
808 if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
809 {
810 hcan->State = HAL_CAN_STATE_TIMEOUT;
811
812 /* Process unlocked */
813 __HAL_UNLOCK(hcan);
814
815 return HAL_TIMEOUT;
816 }
817 }
818 }
819
820 /* Get the Id */
821 hcan->pRxMsg->IDE = (uint8_t)CAN_ID_EXT & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
822 if (hcan->pRxMsg->IDE == CAN_ID_STD)
823 {
824 hcan->pRxMsg->StdId = (uint32_t)0x000007FF & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 21);
825 }
826 else
827 {
828 hcan->pRxMsg->ExtId = (uint32_t)0x1FFFFFFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 3);
829 }
830
831 hcan->pRxMsg->RTR = (uint8_t)CAN_RTR_REMOTE & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
832 /* Get the DLC */
833 hcan->pRxMsg->DLC = (uint8_t)0x0F & hcan->Instance->sFIFOMailBox[FIFONumber].RDTR;
834 /* Get the FMI */
835 hcan->pRxMsg->FMI = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDTR >> 8);
836 /* Get the data field */
837 hcan->pRxMsg->Data[0] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR;
838 hcan->pRxMsg->Data[1] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 8);
839 hcan->pRxMsg->Data[2] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 16);
840 hcan->pRxMsg->Data[3] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 24);
841 hcan->pRxMsg->Data[4] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR;
842 hcan->pRxMsg->Data[5] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 8);
843 hcan->pRxMsg->Data[6] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 16);
844 hcan->pRxMsg->Data[7] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 24);
845
846 /* Release the FIFO */
847 if(FIFONumber == CAN_FIFO0)
848 {
849 /* Release FIFO0 */
850 __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO0);
851 }
852 else /* FIFONumber == CAN_FIFO1 */
853 {
854 /* Release FIFO1 */
855 __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO1);
856 }
857
858 if(hcan->State == HAL_CAN_STATE_BUSY_TX_RX)
859 {
860 /* Change CAN state */
861 hcan->State = HAL_CAN_STATE_BUSY_TX;
862 }
863 else
864 {
865 /* Change CAN state */
866 hcan->State = HAL_CAN_STATE_READY;
867 }
868
869 /* Process unlocked */
870 __HAL_UNLOCK(hcan);
871
872 /* Return function status */
873 return HAL_OK;
874 }
875
876 /**
877 * @brief Receives a correct CAN frame.
878 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
879 * the configuration information for the specified CAN.
880 * @param FIFONumber: Specify the FIFO number
881 * @retval HAL status
882 * @retval None
883 */
884 HAL_StatusTypeDef HAL_CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber)
885 {
886 /* Check the parameters */
887 assert_param(IS_CAN_FIFO(FIFONumber));
888
889 if((hcan->State == HAL_CAN_STATE_READY) || (hcan->State == HAL_CAN_STATE_BUSY_TX))
890 {
891 /* Process locked */
892 __HAL_LOCK(hcan);
893
894 if(hcan->State == HAL_CAN_STATE_BUSY_TX)
895 {
896 /* Change CAN state */
897 hcan->State = HAL_CAN_STATE_BUSY_TX_RX;
898 }
899 else
900 {
901 /* Change CAN state */
902 hcan->State = HAL_CAN_STATE_BUSY_RX;
903 }
904
905 /* Set CAN error code to none */
906 hcan->ErrorCode = HAL_CAN_ERROR_NONE;
907
908 /* Enable interrupts: */
909 /* - Enable Error warning Interrupt */
910 /* - Enable Error passive Interrupt */
911 /* - Enable Bus-off Interrupt */
912 /* - Enable Last error code Interrupt */
913 /* - Enable Error Interrupt */
914 /* - Enable Transmit mailbox empty Interrupt */
915 __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EWG |
916 CAN_IT_EPV |
917 CAN_IT_BOF |
918 CAN_IT_LEC |
919 CAN_IT_ERR |
920 CAN_IT_TME );
921
922 /* Process unlocked */
923 __HAL_UNLOCK(hcan);
924
925 if(FIFONumber == CAN_FIFO0)
926 {
927 /* Enable FIFO 0 message pending Interrupt */
928 __HAL_CAN_ENABLE_IT(hcan, CAN_IT_FMP0);
929 }
930 else
931 {
932 /* Enable FIFO 1 message pending Interrupt */
933 __HAL_CAN_ENABLE_IT(hcan, CAN_IT_FMP1);
934 }
935
936 }
937 else
938 {
939 return HAL_BUSY;
940 }
941
942 /* Return function status */
943 return HAL_OK;
944 }
945
946 /**
947 * @brief Enters the Sleep (low power) mode.
948 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
949 * the configuration information for the specified CAN.
950 * @retval HAL status.
951 */
952 HAL_StatusTypeDef HAL_CAN_Sleep(CAN_HandleTypeDef* hcan)
953 {
954 uint32_t tickstart = 0;
955
956 /* Process locked */
957 __HAL_LOCK(hcan);
958
959 /* Change CAN state */
960 hcan->State = HAL_CAN_STATE_BUSY;
961
962 /* Request Sleep mode */
963 MODIFY_REG(hcan->Instance->MCR,
964 CAN_MCR_INRQ ,
965 CAN_MCR_SLEEP );
966
967 /* Sleep mode status */
968 if (HAL_IS_BIT_CLR(hcan->Instance->MSR, CAN_MSR_SLAK) ||
969 HAL_IS_BIT_SET(hcan->Instance->MSR, CAN_MSR_INAK) )
970 {
971 /* Process unlocked */
972 __HAL_UNLOCK(hcan);
973
974 /* Return function status */
975 return HAL_ERROR;
976 }
977
978 /* Get tick */
979 tickstart = HAL_GetTick();
980
981 /* Wait the acknowledge */
982 while (HAL_IS_BIT_CLR(hcan->Instance->MSR, CAN_MSR_SLAK) ||
983 HAL_IS_BIT_SET(hcan->Instance->MSR, CAN_MSR_INAK) )
984 {
985 if((HAL_GetTick()-tickstart) > CAN_TIMEOUT_VALUE)
986 {
987 hcan->State = HAL_CAN_STATE_TIMEOUT;
988
989 /* Process unlocked */
990 __HAL_UNLOCK(hcan);
991
992 return HAL_TIMEOUT;
993 }
994 }
995
996 /* Change CAN state */
997 hcan->State = HAL_CAN_STATE_READY;
998
999 /* Process unlocked */
1000 __HAL_UNLOCK(hcan);
1001
1002 /* Return function status */
1003 return HAL_OK;
1004 }
1005
1006 /**
1007 * @brief Wakes up the CAN peripheral from sleep mode, after that the CAN peripheral
1008 * is in the normal mode.
1009 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
1010 * the configuration information for the specified CAN.
1011 * @retval HAL status.
1012 */
1013 HAL_StatusTypeDef HAL_CAN_WakeUp(CAN_HandleTypeDef* hcan)
1014 {
1015 uint32_t tickstart = 0;
1016
1017 /* Process locked */
1018 __HAL_LOCK(hcan);
1019
1020 /* Change CAN state */
1021 hcan->State = HAL_CAN_STATE_BUSY;
1022
1023 /* Wake up request */
1024 CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_SLEEP);
1025
1026 /* Get timeout */
1027 tickstart = HAL_GetTick();
1028
1029 /* Sleep mode status */
1030 while((hcan->Instance->MSR & CAN_MSR_SLAK) == CAN_MSR_SLAK)
1031 {
1032 if((HAL_GetTick()-tickstart) > CAN_TIMEOUT_VALUE)
1033 {
1034 hcan->State= HAL_CAN_STATE_TIMEOUT;
1035
1036 /* Process unlocked */
1037 __HAL_UNLOCK(hcan);
1038
1039 return HAL_TIMEOUT;
1040 }
1041 }
1042 if(HAL_IS_BIT_SET(hcan->Instance->MSR, CAN_MSR_SLAK))
1043 {
1044 /* Process unlocked */
1045 __HAL_UNLOCK(hcan);
1046
1047 /* Return function status */
1048 return HAL_ERROR;
1049 }
1050
1051 /* Change CAN state */
1052 hcan->State = HAL_CAN_STATE_READY;
1053
1054 /* Process unlocked */
1055 __HAL_UNLOCK(hcan);
1056
1057 /* Return function status */
1058 return HAL_OK;
1059 }
1060
1061 /**
1062 * @brief Handles CAN interrupt request
1063 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
1064 * the configuration information for the specified CAN.
1065 * @retval None
1066 */
1067 void HAL_CAN_IRQHandler(CAN_HandleTypeDef* hcan)
1068 {
1069 /* Check End of transmission flag */
1070 if(__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_TME))
1071 {
1072 if((__HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_0)) ||
1073 (__HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_1)) ||
1074 (__HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_2)))
1075 {
1076 /* Call transmit function */
1077 CAN_Transmit_IT(hcan);
1078 }
1079 }
1080
1081 /* Check End of reception flag for FIFO0 */
1082 if((__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FMP0)) &&
1083 (__HAL_CAN_MSG_PENDING(hcan, CAN_FIFO0) != 0))
1084 {
1085 /* Call receive function */
1086 CAN_Receive_IT(hcan, CAN_FIFO0);
1087 }
1088
1089 /* Check End of reception flag for FIFO1 */
1090 if((__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FMP1)) &&
1091 (__HAL_CAN_MSG_PENDING(hcan, CAN_FIFO1) != 0))
1092 {
1093 /* Call receive function */
1094 CAN_Receive_IT(hcan, CAN_FIFO1);
1095 }
1096
1097 /* Check Error Warning Flag */
1098 if((__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_EWG)) &&
1099 (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_EWG)) &&
1100 (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR)))
1101 {
1102 /* Set CAN error code to EWG error */
1103 hcan->ErrorCode |= HAL_CAN_ERROR_EWG;
1104 /* No need for clear of Error Warning Flag as read-only */
1105 }
1106
1107 /* Check Error Passive Flag */
1108 if((__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_EPV)) &&
1109 (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_EPV)) &&
1110 (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR)))
1111 {
1112 /* Set CAN error code to EPV error */
1113 hcan->ErrorCode |= HAL_CAN_ERROR_EPV;
1114 /* No need for clear of Error Passive Flag as read-only */
1115 }
1116
1117 /* Check Bus-Off Flag */
1118 if((__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_BOF)) &&
1119 (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_BOF)) &&
1120 (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR)))
1121 {
1122 /* Set CAN error code to BOF error */
1123 hcan->ErrorCode |= HAL_CAN_ERROR_BOF;
1124 /* No need for clear of Bus-Off Flag as read-only */
1125 }
1126
1127 /* Check Last error code Flag */
1128 if((!HAL_IS_BIT_CLR(hcan->Instance->ESR, CAN_ESR_LEC)) &&
1129 (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_LEC)) &&
1130 (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR)))
1131 {
1132 switch(hcan->Instance->ESR & CAN_ESR_LEC)
1133 {
1134 case(CAN_ESR_LEC_0):
1135 /* Set CAN error code to STF error */
1136 hcan->ErrorCode |= HAL_CAN_ERROR_STF;
1137 break;
1138 case(CAN_ESR_LEC_1):
1139 /* Set CAN error code to FOR error */
1140 hcan->ErrorCode |= HAL_CAN_ERROR_FOR;
1141 break;
1142 case(CAN_ESR_LEC_1 | CAN_ESR_LEC_0):
1143 /* Set CAN error code to ACK error */
1144 hcan->ErrorCode |= HAL_CAN_ERROR_ACK;
1145 break;
1146 case(CAN_ESR_LEC_2):
1147 /* Set CAN error code to BR error */
1148 hcan->ErrorCode |= HAL_CAN_ERROR_BR;
1149 break;
1150 case(CAN_ESR_LEC_2 | CAN_ESR_LEC_0):
1151 /* Set CAN error code to BD error */
1152 hcan->ErrorCode |= HAL_CAN_ERROR_BD;
1153 break;
1154 case(CAN_ESR_LEC_2 | CAN_ESR_LEC_1):
1155 /* Set CAN error code to CRC error */
1156 hcan->ErrorCode |= HAL_CAN_ERROR_CRC;
1157 break;
1158 default:
1159 break;
1160 }
1161
1162 /* Clear Last error code Flag */
1163 CLEAR_BIT(hcan->Instance->ESR, CAN_ESR_LEC);
1164 }
1165
1166 /* Call the Error call Back in case of Errors */
1167 if(hcan->ErrorCode != HAL_CAN_ERROR_NONE)
1168 {
1169 /* Set the CAN state ready to be able to start again the process */
1170 hcan->State = HAL_CAN_STATE_READY;
1171
1172 /* Call Error callback function */
1173 HAL_CAN_ErrorCallback(hcan);
1174 }
1175 }
1176
1177 /**
1178 * @brief Transmission complete callback in non blocking mode
1179 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
1180 * the configuration information for the specified CAN.
1181 * @retval None
1182 */
1183 __weak void HAL_CAN_TxCpltCallback(CAN_HandleTypeDef* hcan)
1184 {
1185 /* NOTE : This function Should not be modified, when the callback is needed,
1186 the HAL_CAN_TxCpltCallback can be implemented in the user file
1187 */
1188 }
1189
1190 /**
1191 * @brief Transmission complete callback in non blocking mode
1192 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
1193 * the configuration information for the specified CAN.
1194 * @retval None
1195 */
1196 __weak void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* hcan)
1197 {
1198 /* NOTE : This function Should not be modified, when the callback is needed,
1199 the HAL_CAN_RxCpltCallback can be implemented in the user file
1200 */
1201 }
1202
1203 /**
1204 * @brief Error CAN callback.
1205 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
1206 * the configuration information for the specified CAN.
1207 * @retval None
1208 */
1209 __weak void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan)
1210 {
1211 /* NOTE : This function Should not be modified, when the callback is needed,
1212 the HAL_CAN_ErrorCallback can be implemented in the user file
1213 */
1214 }
1215
1216 /**
1217 * @}
1218 */
1219
1220 /** @defgroup CAN_Exported_Functions_Group3 Peripheral State and Error functions
1221 * @brief CAN Peripheral State functions
1222 *
1223 @verbatim
1224 ==============================================================================
1225 ##### Peripheral State and Error functions #####
1226 ==============================================================================
1227 [..]
1228 This subsection provides functions allowing to :
1229 (+) Check the CAN state.
1230 (+) Check CAN Errors detected during interrupt process
1231
1232 @endverbatim
1233 * @{
1234 */
1235
1236 /**
1237 * @brief return the CAN state
1238 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
1239 * the configuration information for the specified CAN.
1240 * @retval HAL state
1241 */
1242 HAL_CAN_StateTypeDef HAL_CAN_GetState(CAN_HandleTypeDef* hcan)
1243 {
1244 /* Return CAN state */
1245 return hcan->State;
1246 }
1247
1248 /**
1249 * @brief Return the CAN error code
1250 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
1251 * the configuration information for the specified CAN.
1252 * @retval CAN Error Code
1253 */
1254 uint32_t HAL_CAN_GetError(CAN_HandleTypeDef *hcan)
1255 {
1256 return hcan->ErrorCode;
1257 }
1258
1259 /**
1260 * @}
1261 */
1262
1263 /**
1264 * @}
1265 */
1266
1267 /** @defgroup CAN_Private_Functions CAN Private Functions
1268 * @{
1269 */
1270 /**
1271 * @brief Initiates and transmits a CAN frame message.
1272 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
1273 * the configuration information for the specified CAN.
1274 * @retval HAL status
1275 */
1276 static HAL_StatusTypeDef CAN_Transmit_IT(CAN_HandleTypeDef* hcan)
1277 {
1278 /* Disable Transmit mailbox empty Interrupt */
1279 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_TME);
1280
1281 if(hcan->State == HAL_CAN_STATE_BUSY_TX)
1282 {
1283 /* Disable interrupts: */
1284 /* - Disable Error warning Interrupt */
1285 /* - Disable Error passive Interrupt */
1286 /* - Disable Bus-off Interrupt */
1287 /* - Disable Last error code Interrupt */
1288 /* - Disable Error Interrupt */
1289 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EWG |
1290 CAN_IT_EPV |
1291 CAN_IT_BOF |
1292 CAN_IT_LEC |
1293 CAN_IT_ERR );
1294 }
1295
1296 if(hcan->State == HAL_CAN_STATE_BUSY_TX_RX)
1297 {
1298 /* Change CAN state */
1299 hcan->State = HAL_CAN_STATE_BUSY_RX;
1300 }
1301 else
1302 {
1303 /* Change CAN state */
1304 hcan->State = HAL_CAN_STATE_READY;
1305 }
1306
1307 /* Transmission complete callback */
1308 HAL_CAN_TxCpltCallback(hcan);
1309
1310 return HAL_OK;
1311 }
1312
1313 /**
1314 * @brief Receives a correct CAN frame.
1315 * @param hcan: Pointer to a CAN_HandleTypeDef structure that contains
1316 * the configuration information for the specified CAN.
1317 * @param FIFONumber: Specify the FIFO number
1318 * @retval HAL status
1319 * @retval None
1320 */
1321 static HAL_StatusTypeDef CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber)
1322 {
1323 /* Get the Id */
1324 hcan->pRxMsg->IDE = (uint8_t)0x04 & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
1325 if (hcan->pRxMsg->IDE == CAN_ID_STD)
1326 {
1327 hcan->pRxMsg->StdId = (uint32_t)0x000007FF & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 21);
1328 }
1329 else
1330 {
1331 hcan->pRxMsg->ExtId = (uint32_t)0x1FFFFFFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 3);
1332 }
1333
1334 hcan->pRxMsg->RTR = (uint8_t)0x02 & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
1335 /* Get the DLC */
1336 hcan->pRxMsg->DLC = (uint8_t)0x0F & hcan->Instance->sFIFOMailBox[FIFONumber].RDTR;
1337 /* Get the FMI */
1338 hcan->pRxMsg->FMI = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDTR >> 8);
1339 /* Get the data field */
1340 hcan->pRxMsg->Data[0] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR;
1341 hcan->pRxMsg->Data[1] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 8);
1342 hcan->pRxMsg->Data[2] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 16);
1343 hcan->pRxMsg->Data[3] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 24);
1344 hcan->pRxMsg->Data[4] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR;
1345 hcan->pRxMsg->Data[5] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 8);
1346 hcan->pRxMsg->Data[6] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 16);
1347 hcan->pRxMsg->Data[7] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 24);
1348 /* Release the FIFO */
1349 /* Release FIFO0 */
1350 if (FIFONumber == CAN_FIFO0)
1351 {
1352 __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO0);
1353
1354 /* Disable FIFO 0 message pending Interrupt */
1355 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_FMP0);
1356 }
1357 /* Release FIFO1 */
1358 else /* FIFONumber == CAN_FIFO1 */
1359 {
1360 __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO1);
1361
1362 /* Disable FIFO 1 message pending Interrupt */
1363 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_FMP1);
1364 }
1365
1366 if(hcan->State == HAL_CAN_STATE_BUSY_RX)
1367 {
1368 /* Disable interrupts: */
1369 /* - Disable Error warning Interrupt */
1370 /* - Disable Error passive Interrupt */
1371 /* - Disable Bus-off Interrupt */
1372 /* - Disable Last error code Interrupt */
1373 /* - Disable Error Interrupt */
1374 __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EWG |
1375 CAN_IT_EPV |
1376 CAN_IT_BOF |
1377 CAN_IT_LEC |
1378 CAN_IT_ERR );
1379 }
1380
1381 if(hcan->State == HAL_CAN_STATE_BUSY_TX_RX)
1382 {
1383 /* Disable CAN state */
1384 hcan->State = HAL_CAN_STATE_BUSY_TX;
1385 }
1386 else
1387 {
1388 /* Change CAN state */
1389 hcan->State = HAL_CAN_STATE_READY;
1390 }
1391
1392 /* Receive complete callback */
1393 HAL_CAN_RxCpltCallback(hcan);
1394
1395 /* Return function status */
1396 return HAL_OK;
1397 }
1398
1399 /**
1400 * @}
1401 */
1402
1403 /**
1404 * @}
1405 */
1406
1407 #endif /* STM32F103x6) || STM32F103xB || STM32F103xE || */
1408 /* STM32F103xG) || STM32F105xC || STM32F107xC */
1409
1410 #endif /* HAL_CAN_MODULE_ENABLED */
1411
1412 /**
1413 * @}
1414 */
1415
1416 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Imprint / Impressum