Subversion Repositories DashDisplay

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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