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