source: asp3_wo_tecs/trunk/arch/arm_m_gcc/stm32f4xx_stm32cube/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_can.c@ 303

Last change on this file since 303 was 303, checked in by ertl-honda, 7 years ago

nucleo_f401re依存部の追加

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