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