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