Subversion Repositories DashDisplay

Rev

Rev 2 | Details | Compare with Previous | 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 mjames 5
  * @version V1.0.4
6
  * @date    29-April-2016
2 mjames 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
  *
5 mjames 76
  * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
2 mjames 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
{
5 mjames 479
  /* Prevent unused argument(s) compilation warning */
480
  UNUSED(hcan);
2 mjames 481
  /* NOTE : This function Should not be modified, when the callback is needed,
482
            the HAL_CAN_MspInit can be implemented in the user file
483
   */
484
}
485
 
486
/**
487
  * @brief  DeInitializes the CAN MSP.
488
  * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
489
  *         the configuration information for the specified CAN.  
490
  * @retval None
491
  */
492
__weak void HAL_CAN_MspDeInit(CAN_HandleTypeDef* hcan)
493
{
5 mjames 494
  /* Prevent unused argument(s) compilation warning */
495
  UNUSED(hcan);
2 mjames 496
  /* NOTE : This function Should not be modified, when the callback is needed,
497
            the HAL_CAN_MspDeInit can be implemented in the user file
498
   */
499
}
500
 
501
/**
502
  * @}
503
  */
504
 
505
/** @defgroup CAN_Exported_Functions_Group2 Input and Output operation functions
506
 *  @brief    I/O operation functions
507
 *
508
@verbatim  
509
  ==============================================================================
510
                      ##### IO operation functions #####
511
  ==============================================================================
512
    [..]  This section provides functions allowing to:
513
      (+) Transmit a CAN frame message.
514
      (+) Receive a CAN frame message.
515
      (+) Enter CAN peripheral in sleep mode.
516
      (+) Wake up the CAN peripheral from sleep mode.
517
 
518
@endverbatim
519
  * @{
520
  */
521
 
522
/**
523
  * @brief  Initiates and transmits a CAN frame message.
524
  * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
525
  *         the configuration information for the specified CAN.  
526
  * @param  Timeout: Specify Timeout value  
527
  * @retval HAL status
528
  */
529
HAL_StatusTypeDef HAL_CAN_Transmit(CAN_HandleTypeDef* hcan, uint32_t Timeout)
530
{
531
  uint32_t transmitmailbox = CAN_TXSTATUS_NOMAILBOX;
532
  uint32_t tickstart = 0;
533
 
534
  /* Check the parameters */
535
  assert_param(IS_CAN_IDTYPE(hcan->pTxMsg->IDE));
536
  assert_param(IS_CAN_RTR(hcan->pTxMsg->RTR));
537
  assert_param(IS_CAN_DLC(hcan->pTxMsg->DLC));
538
 
539
  /* Process locked */
540
  __HAL_LOCK(hcan);
541
 
542
  if(hcan->State == HAL_CAN_STATE_BUSY_RX)
543
  {
544
    /* Change CAN state */
545
    hcan->State = HAL_CAN_STATE_BUSY_TX_RX;
546
  }
547
  else
548
  {
549
    /* Change CAN state */
550
    hcan->State = HAL_CAN_STATE_BUSY_TX;
551
  }
552
 
553
  /* Select one empty transmit mailbox */
554
  if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME0))
555
  {
556
    transmitmailbox = 0;
557
  }
558
  else if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME1))
559
  {
560
    transmitmailbox = 1;
561
  }
562
  else if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME2))
563
  {
564
    transmitmailbox = 2;
565
  }
566
  else
567
  {
568
    transmitmailbox = CAN_TXSTATUS_NOMAILBOX;
569
  }
570
 
571
  if (transmitmailbox != CAN_TXSTATUS_NOMAILBOX)
572
  {
573
    /* Set up the Id */
574
    hcan->Instance->sTxMailBox[transmitmailbox].TIR &= CAN_TI0R_TXRQ;
575
    if (hcan->pTxMsg->IDE == CAN_ID_STD)
576
    {
577
      assert_param(IS_CAN_STDID(hcan->pTxMsg->StdId));  
578
      hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->StdId << CAN_TI0R_STID_BIT_POSITION) |
579
                                                           hcan->pTxMsg->RTR);
580
    }
581
    else
582
    {
583
      assert_param(IS_CAN_EXTID(hcan->pTxMsg->ExtId));
584
      hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->ExtId << CAN_TI0R_EXID_BIT_POSITION) |
585
                                                           hcan->pTxMsg->IDE |
586
                                                           hcan->pTxMsg->RTR);
587
    }
588
 
589
    /* Set up the DLC */
590
    hcan->pTxMsg->DLC &= (uint8_t)0x0000000F;
591
    hcan->Instance->sTxMailBox[transmitmailbox].TDTR &= (uint32_t)0xFFFFFFF0;
592
    hcan->Instance->sTxMailBox[transmitmailbox].TDTR |= hcan->pTxMsg->DLC;
593
 
594
    /* Set up the data field */
595
    WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDLR, ((uint32_t)hcan->pTxMsg->Data[3] << CAN_TDL0R_DATA3_BIT_POSITION) |
596
                                                                ((uint32_t)hcan->pTxMsg->Data[2] << CAN_TDL0R_DATA2_BIT_POSITION) |
597
                                                                ((uint32_t)hcan->pTxMsg->Data[1] << CAN_TDL0R_DATA1_BIT_POSITION) |
598
                                                                ((uint32_t)hcan->pTxMsg->Data[0] << CAN_TDL0R_DATA0_BIT_POSITION)  );
599
    WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDHR, ((uint32_t)hcan->pTxMsg->Data[7] << CAN_TDL0R_DATA3_BIT_POSITION) |
600
                                                                ((uint32_t)hcan->pTxMsg->Data[6] << CAN_TDL0R_DATA2_BIT_POSITION) |
601
                                                                ((uint32_t)hcan->pTxMsg->Data[5] << CAN_TDL0R_DATA1_BIT_POSITION) |
602
                                                                ((uint32_t)hcan->pTxMsg->Data[4] << CAN_TDL0R_DATA0_BIT_POSITION)  );
603
    /* Request transmission */
604
    SET_BIT(hcan->Instance->sTxMailBox[transmitmailbox].TIR, CAN_TI0R_TXRQ);
605
 
606
    /* Get timeout */
607
    tickstart = HAL_GetTick();  
608
 
609
    /* Check End of transmission flag */
610
    while(!(__HAL_CAN_TRANSMIT_STATUS(hcan, transmitmailbox)))
611
    {
612
      /* Check for the Timeout */
613
      if(Timeout != HAL_MAX_DELAY)
614
      {
615
        if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
616
        {
617
          hcan->State = HAL_CAN_STATE_TIMEOUT;
618
 
619
          /* Process unlocked */
620
          __HAL_UNLOCK(hcan);
621
 
622
          return HAL_TIMEOUT;
623
        }
624
      }
625
    }
626
    if(hcan->State == HAL_CAN_STATE_BUSY_TX_RX)
627
    {
628
      /* Change CAN state */
629
      hcan->State = HAL_CAN_STATE_BUSY_RX;
630
 
631
      /* Process unlocked */
632
      __HAL_UNLOCK(hcan);
633
    }
634
    else
635
    {
636
      /* Change CAN state */
637
      hcan->State = HAL_CAN_STATE_READY;
638
    }
639
 
640
    /* Process unlocked */
641
    __HAL_UNLOCK(hcan);
642
 
643
    /* Return function status */
644
    return HAL_OK;
645
  }
646
  else
647
  {
648
    /* Change CAN state */
649
    hcan->State = HAL_CAN_STATE_ERROR;
650
 
651
    /* Process unlocked */
652
    __HAL_UNLOCK(hcan);
653
 
654
    /* Return function status */
655
    return HAL_ERROR;
656
  }
657
}
658
 
659
/**
660
  * @brief  Initiates and transmits a CAN frame message.
661
  * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
662
  *         the configuration information for the specified CAN.  
663
  * @retval HAL status
664
  */
665
HAL_StatusTypeDef HAL_CAN_Transmit_IT(CAN_HandleTypeDef* hcan)
666
{
667
  uint32_t transmitmailbox = CAN_TXSTATUS_NOMAILBOX;
668
 
669
  /* Check the parameters */
670
  assert_param(IS_CAN_IDTYPE(hcan->pTxMsg->IDE));
671
  assert_param(IS_CAN_RTR(hcan->pTxMsg->RTR));
672
  assert_param(IS_CAN_DLC(hcan->pTxMsg->DLC));
673
 
674
  if((hcan->State == HAL_CAN_STATE_READY) || (hcan->State == HAL_CAN_STATE_BUSY_RX))
675
  {
676
    /* Process Locked */
677
    __HAL_LOCK(hcan);
678
 
679
    /* Select one empty transmit mailbox */
680
    if(HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME0))
681
    {
682
      transmitmailbox = 0;
683
    }
684
    else if(HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME1))
685
    {
686
      transmitmailbox = 1;
687
    }
688
    else if(HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME2))
689
    {
690
      transmitmailbox = 2;
691
    }
692
    else
693
    {
694
      transmitmailbox = CAN_TXSTATUS_NOMAILBOX;
695
    }
696
 
697
    if(transmitmailbox != CAN_TXSTATUS_NOMAILBOX)
698
    {
699
      /* Set up the Id */
700
      hcan->Instance->sTxMailBox[transmitmailbox].TIR &= CAN_TI0R_TXRQ;
701
      if (hcan->pTxMsg->IDE == CAN_ID_STD)
702
      {
703
        assert_param(IS_CAN_STDID(hcan->pTxMsg->StdId));  
704
        hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->StdId << CAN_TI0R_STID_BIT_POSITION) |
705
                                                             hcan->pTxMsg->RTR);
706
      }
707
      else
708
      {
709
        assert_param(IS_CAN_EXTID(hcan->pTxMsg->ExtId));
710
        hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->ExtId << CAN_TI0R_EXID_BIT_POSITION) |
711
                                                             hcan->pTxMsg->IDE |
712
                                                             hcan->pTxMsg->RTR);
713
      }
714
 
715
      /* Set up the DLC */
716
      hcan->pTxMsg->DLC &= (uint8_t)0x0000000F;
717
      hcan->Instance->sTxMailBox[transmitmailbox].TDTR &= (uint32_t)0xFFFFFFF0;
718
      hcan->Instance->sTxMailBox[transmitmailbox].TDTR |= hcan->pTxMsg->DLC;
719
 
720
      /* Set up the data field */
721
      WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDLR, ((uint32_t)hcan->pTxMsg->Data[3] << CAN_TDL0R_DATA3_BIT_POSITION) |
722
                                                                  ((uint32_t)hcan->pTxMsg->Data[2] << CAN_TDL0R_DATA2_BIT_POSITION) |
723
                                                                  ((uint32_t)hcan->pTxMsg->Data[1] << CAN_TDL0R_DATA1_BIT_POSITION) |
724
                                                                  ((uint32_t)hcan->pTxMsg->Data[0] << CAN_TDL0R_DATA0_BIT_POSITION)  );
725
      WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDHR, ((uint32_t)hcan->pTxMsg->Data[7] << CAN_TDL0R_DATA3_BIT_POSITION) |
726
                                                                  ((uint32_t)hcan->pTxMsg->Data[6] << CAN_TDL0R_DATA2_BIT_POSITION) |
727
                                                                  ((uint32_t)hcan->pTxMsg->Data[5] << CAN_TDL0R_DATA1_BIT_POSITION) |
728
                                                                  ((uint32_t)hcan->pTxMsg->Data[4] << CAN_TDL0R_DATA0_BIT_POSITION)  );
729
 
730
      if(hcan->State == HAL_CAN_STATE_BUSY_RX)
731
      {
732
        /* Change CAN state */
733
        hcan->State = HAL_CAN_STATE_BUSY_TX_RX;
734
      }
735
      else
736
      {
737
        /* Change CAN state */
738
        hcan->State = HAL_CAN_STATE_BUSY_TX;
739
      }
740
 
741
      /* Set CAN error code to none */
742
      hcan->ErrorCode = HAL_CAN_ERROR_NONE;
743
 
744
      /* Process Unlocked */
745
      __HAL_UNLOCK(hcan);
746
 
747
      /* Enable interrupts: */
748
      /*  - Enable Error warning Interrupt */
749
      /*  - Enable Error passive Interrupt */
750
      /*  - Enable Bus-off Interrupt */
751
      /*  - Enable Last error code Interrupt */
752
      /*  - Enable Error Interrupt */
753
      /*  - Enable Transmit mailbox empty Interrupt */
754
      __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EWG |
755
                                CAN_IT_EPV |
756
                                CAN_IT_BOF |
757
                                CAN_IT_LEC |
758
                                CAN_IT_ERR |
759
                                CAN_IT_TME  );
760
 
761
      /* Request transmission */
762
      hcan->Instance->sTxMailBox[transmitmailbox].TIR |= CAN_TI0R_TXRQ;
763
    }
764
  }
765
  else
766
  {
767
    return HAL_BUSY;
768
  }
769
 
770
  return HAL_OK;
771
}
772
 
773
/**
774
  * @brief  Receives a correct CAN frame.
775
  * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
776
  *         the configuration information for the specified CAN.  
777
  * @param  FIFONumber: FIFO Number value
778
  * @param  Timeout: Specify Timeout value
779
  * @retval HAL status
780
  * @retval None
781
  */
782
HAL_StatusTypeDef HAL_CAN_Receive(CAN_HandleTypeDef* hcan, uint8_t FIFONumber, uint32_t Timeout)
783
{
784
  uint32_t tickstart = 0;
785
 
786
  /* Check the parameters */
787
  assert_param(IS_CAN_FIFO(FIFONumber));
788
 
789
  /* Process locked */
790
  __HAL_LOCK(hcan);
791
 
792
  if(hcan->State == HAL_CAN_STATE_BUSY_TX)
793
  {
794
    /* Change CAN state */
795
    hcan->State = HAL_CAN_STATE_BUSY_TX_RX;
796
  }
797
  else
798
  {
799
    /* Change CAN state */
800
    hcan->State = HAL_CAN_STATE_BUSY_RX;
801
  }
802
 
803
  /* Get tick */
804
  tickstart = HAL_GetTick();
805
 
806
  /* Check pending message */
807
  while(__HAL_CAN_MSG_PENDING(hcan, FIFONumber) == 0)
808
  {
809
    /* Check for the Timeout */
810
    if(Timeout != HAL_MAX_DELAY)
811
    {
812
      if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
813
      {
814
        hcan->State = HAL_CAN_STATE_TIMEOUT;
815
 
816
        /* Process unlocked */
817
        __HAL_UNLOCK(hcan);
818
 
819
        return HAL_TIMEOUT;
820
      }
821
    }
822
  }
823
 
824
  /* Get the Id */
825
  hcan->pRxMsg->IDE = (uint8_t)CAN_ID_EXT & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
826
  if (hcan->pRxMsg->IDE == CAN_ID_STD)
827
  {
828
    hcan->pRxMsg->StdId = (uint32_t)0x000007FF & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 21);
829
  }
830
  else
831
  {
832
    hcan->pRxMsg->ExtId = (uint32_t)0x1FFFFFFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 3);
833
  }
834
 
835
  hcan->pRxMsg->RTR = (uint8_t)CAN_RTR_REMOTE & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
836
  /* Get the DLC */
837
  hcan->pRxMsg->DLC = (uint8_t)0x0F & hcan->Instance->sFIFOMailBox[FIFONumber].RDTR;
838
  /* Get the FMI */
839
  hcan->pRxMsg->FMI = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDTR >> 8);
840
  /* Get the data field */
841
  hcan->pRxMsg->Data[0] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR;
842
  hcan->pRxMsg->Data[1] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 8);
843
  hcan->pRxMsg->Data[2] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 16);
844
  hcan->pRxMsg->Data[3] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 24);
845
  hcan->pRxMsg->Data[4] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR;
846
  hcan->pRxMsg->Data[5] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 8);
847
  hcan->pRxMsg->Data[6] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 16);
848
  hcan->pRxMsg->Data[7] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 24);
849
 
850
  /* Release the FIFO */
851
  if(FIFONumber == CAN_FIFO0)
852
  {
853
    /* Release FIFO0 */
854
    __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO0);
855
  }
856
  else /* FIFONumber == CAN_FIFO1 */
857
  {
858
    /* Release FIFO1 */
859
    __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO1);
860
  }
861
 
862
  if(hcan->State == HAL_CAN_STATE_BUSY_TX_RX)
863
  {
864
    /* Change CAN state */
865
    hcan->State = HAL_CAN_STATE_BUSY_TX;
866
  }
867
  else
868
  {
869
    /* Change CAN state */
870
    hcan->State = HAL_CAN_STATE_READY;
871
  }
872
 
873
  /* Process unlocked */
874
  __HAL_UNLOCK(hcan);
875
 
876
  /* Return function status */
877
  return HAL_OK;
878
}
879
 
880
/**
881
  * @brief  Receives a correct CAN frame.
882
  * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
883
  *         the configuration information for the specified CAN.  
884
  * @param  FIFONumber: Specify the FIFO number    
885
  * @retval HAL status
886
  * @retval None
887
  */
888
HAL_StatusTypeDef HAL_CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber)
889
{
890
  /* Check the parameters */
891
  assert_param(IS_CAN_FIFO(FIFONumber));
892
 
893
  if((hcan->State == HAL_CAN_STATE_READY) || (hcan->State == HAL_CAN_STATE_BUSY_TX))
894
  {
895
    /* Process locked */
896
    __HAL_LOCK(hcan);
897
 
898
    if(hcan->State == HAL_CAN_STATE_BUSY_TX)
899
    {
900
      /* Change CAN state */
901
      hcan->State = HAL_CAN_STATE_BUSY_TX_RX;
902
    }
903
    else
904
    {
905
      /* Change CAN state */
906
      hcan->State = HAL_CAN_STATE_BUSY_RX;
907
    }
908
 
909
    /* Set CAN error code to none */
910
    hcan->ErrorCode = HAL_CAN_ERROR_NONE;
911
 
912
    /* Enable interrupts: */
913
    /*  - Enable Error warning Interrupt */
914
    /*  - Enable Error passive Interrupt */
915
    /*  - Enable Bus-off Interrupt */
916
    /*  - Enable Last error code Interrupt */
917
    /*  - Enable Error Interrupt */
918
    /*  - Enable Transmit mailbox empty Interrupt */
919
    __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EWG |
920
                              CAN_IT_EPV |
921
                              CAN_IT_BOF |
922
                              CAN_IT_LEC |
923
                              CAN_IT_ERR |
924
                              CAN_IT_TME  );
925
 
926
    /* Process unlocked */
927
    __HAL_UNLOCK(hcan);
928
 
929
    if(FIFONumber == CAN_FIFO0)
930
    {
931
      /* Enable FIFO 0 message pending Interrupt */
932
      __HAL_CAN_ENABLE_IT(hcan, CAN_IT_FMP0);
933
    }
934
    else
935
    {
936
      /* Enable FIFO 1 message pending Interrupt */
937
      __HAL_CAN_ENABLE_IT(hcan, CAN_IT_FMP1);
938
    }
939
 
940
  }
941
  else
942
  {
943
    return HAL_BUSY;
944
  }
945
 
946
  /* Return function status */
947
  return HAL_OK;
948
}
949
 
950
/**
951
  * @brief  Enters the Sleep (low power) mode.
952
  * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
953
  *         the configuration information for the specified CAN.
954
  * @retval HAL status.
955
  */
956
HAL_StatusTypeDef HAL_CAN_Sleep(CAN_HandleTypeDef* hcan)
957
{
958
  uint32_t tickstart = 0;
959
 
960
  /* Process locked */
961
  __HAL_LOCK(hcan);
962
 
963
  /* Change CAN state */
964
  hcan->State = HAL_CAN_STATE_BUSY;
965
 
966
  /* Request Sleep mode */
967
  MODIFY_REG(hcan->Instance->MCR,
968
             CAN_MCR_INRQ       ,
969
             CAN_MCR_SLEEP       );
970
 
971
  /* Sleep mode status */
972
  if (HAL_IS_BIT_CLR(hcan->Instance->MSR, CAN_MSR_SLAK) ||
973
      HAL_IS_BIT_SET(hcan->Instance->MSR, CAN_MSR_INAK)   )
974
  {
975
    /* Process unlocked */
976
    __HAL_UNLOCK(hcan);
977
 
978
    /* Return function status */
979
    return HAL_ERROR;
980
  }
981
 
982
  /* Get tick */
983
  tickstart = HAL_GetTick();
984
 
985
  /* Wait the acknowledge */
986
  while (HAL_IS_BIT_CLR(hcan->Instance->MSR, CAN_MSR_SLAK) ||
987
         HAL_IS_BIT_SET(hcan->Instance->MSR, CAN_MSR_INAK)   )
988
  {
989
    if((HAL_GetTick()-tickstart) > CAN_TIMEOUT_VALUE)
990
    {
991
      hcan->State = HAL_CAN_STATE_TIMEOUT;
992
 
993
      /* Process unlocked */
994
      __HAL_UNLOCK(hcan);
995
 
996
      return HAL_TIMEOUT;
997
    }
998
  }
999
 
1000
  /* Change CAN state */
1001
  hcan->State = HAL_CAN_STATE_READY;
1002
 
1003
  /* Process unlocked */
1004
  __HAL_UNLOCK(hcan);
1005
 
1006
  /* Return function status */
1007
  return HAL_OK;
1008
}
1009
 
1010
/**
1011
  * @brief  Wakes up the CAN peripheral from sleep mode, after that the CAN peripheral
1012
  *         is in the normal mode.
1013
  * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
1014
  *         the configuration information for the specified CAN.
1015
  * @retval HAL status.
1016
  */
1017
HAL_StatusTypeDef HAL_CAN_WakeUp(CAN_HandleTypeDef* hcan)
1018
{
1019
  uint32_t tickstart = 0;
1020
 
1021
  /* Process locked */
1022
  __HAL_LOCK(hcan);
1023
 
1024
  /* Change CAN state */
1025
  hcan->State = HAL_CAN_STATE_BUSY;  
1026
 
1027
  /* Wake up request */
1028
  CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_SLEEP);
1029
 
1030
  /* Get timeout */
1031
  tickstart = HAL_GetTick();  
1032
 
1033
  /* Sleep mode status */
1034
  while((hcan->Instance->MSR & CAN_MSR_SLAK) == CAN_MSR_SLAK)
1035
  {
1036
    if((HAL_GetTick()-tickstart) > CAN_TIMEOUT_VALUE)
1037
    {
1038
      hcan->State= HAL_CAN_STATE_TIMEOUT;
1039
 
1040
      /* Process unlocked */
1041
      __HAL_UNLOCK(hcan);
1042
 
1043
      return HAL_TIMEOUT;
1044
    }
1045
  }
1046
  if(HAL_IS_BIT_SET(hcan->Instance->MSR, CAN_MSR_SLAK))
1047
  {
1048
    /* Process unlocked */
1049
    __HAL_UNLOCK(hcan);
1050
 
1051
    /* Return function status */
1052
    return HAL_ERROR;
1053
  }
1054
 
1055
  /* Change CAN state */
1056
  hcan->State = HAL_CAN_STATE_READY;
1057
 
1058
  /* Process unlocked */
1059
  __HAL_UNLOCK(hcan);
1060
 
1061
  /* Return function status */
1062
  return HAL_OK;
1063
}
1064
 
1065
/**
1066
  * @brief  Handles CAN interrupt request  
1067
  * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
1068
  *         the configuration information for the specified CAN.
1069
  * @retval None
1070
  */
1071
void HAL_CAN_IRQHandler(CAN_HandleTypeDef* hcan)
1072
{
1073
  /* Check End of transmission flag */
1074
  if(__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_TME))
1075
  {
1076
    if((__HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_0)) ||
1077
       (__HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_1)) ||
1078
       (__HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_2)))
1079
    {
1080
      /* Call transmit function */
1081
      CAN_Transmit_IT(hcan);
1082
    }
1083
  }
1084
 
1085
  /* Check End of reception flag for FIFO0 */
1086
  if((__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FMP0)) &&
1087
     (__HAL_CAN_MSG_PENDING(hcan, CAN_FIFO0) != 0))
1088
  {
1089
    /* Call receive function */
1090
    CAN_Receive_IT(hcan, CAN_FIFO0);
1091
  }
1092
 
1093
  /* Check End of reception flag for FIFO1 */
1094
  if((__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FMP1)) &&
1095
     (__HAL_CAN_MSG_PENDING(hcan, CAN_FIFO1) != 0))
1096
  {
1097
    /* Call receive function */
1098
    CAN_Receive_IT(hcan, CAN_FIFO1);
1099
  }
1100
 
1101
  /* Check Error Warning Flag */
1102
  if((__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_EWG))    &&
1103
     (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_EWG)) &&
1104
     (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR)))
1105
  {
1106
    /* Set CAN error code to EWG error */
1107
    hcan->ErrorCode |= HAL_CAN_ERROR_EWG;
1108
    /* No need for clear of Error Warning Flag as read-only */
1109
  }
1110
 
1111
  /* Check Error Passive Flag */
1112
  if((__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_EPV))    &&
1113
     (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_EPV)) &&
1114
     (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR)))
1115
  {
1116
    /* Set CAN error code to EPV error */
1117
    hcan->ErrorCode |= HAL_CAN_ERROR_EPV;
1118
    /* No need for clear of Error Passive Flag as read-only */
1119
  }
1120
 
1121
  /* Check Bus-Off Flag */
1122
  if((__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_BOF))    &&
1123
     (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_BOF)) &&
1124
     (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR)))
1125
  {
1126
    /* Set CAN error code to BOF error */
1127
    hcan->ErrorCode |= HAL_CAN_ERROR_BOF;
1128
    /* No need for clear of Bus-Off Flag as read-only */
1129
  }
1130
 
1131
  /* Check Last error code Flag */
1132
  if((!HAL_IS_BIT_CLR(hcan->Instance->ESR, CAN_ESR_LEC)) &&
1133
     (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_LEC))         &&
1134
     (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR)))
1135
  {
1136
    switch(hcan->Instance->ESR & CAN_ESR_LEC)
1137
    {
1138
      case(CAN_ESR_LEC_0):
1139
          /* Set CAN error code to STF error */
1140
          hcan->ErrorCode |= HAL_CAN_ERROR_STF;
1141
          break;
1142
      case(CAN_ESR_LEC_1):
1143
          /* Set CAN error code to FOR error */
1144
          hcan->ErrorCode |= HAL_CAN_ERROR_FOR;
1145
          break;
1146
      case(CAN_ESR_LEC_1 | CAN_ESR_LEC_0):
1147
          /* Set CAN error code to ACK error */
1148
          hcan->ErrorCode |= HAL_CAN_ERROR_ACK;
1149
          break;
1150
      case(CAN_ESR_LEC_2):
1151
          /* Set CAN error code to BR error */
1152
          hcan->ErrorCode |= HAL_CAN_ERROR_BR;
1153
          break;
1154
      case(CAN_ESR_LEC_2 | CAN_ESR_LEC_0):
1155
          /* Set CAN error code to BD error */
1156
          hcan->ErrorCode |= HAL_CAN_ERROR_BD;
1157
          break;
1158
      case(CAN_ESR_LEC_2 | CAN_ESR_LEC_1):
1159
          /* Set CAN error code to CRC error */
1160
          hcan->ErrorCode |= HAL_CAN_ERROR_CRC;
1161
          break;
1162
      default:
1163
          break;
1164
    }
1165
 
1166
    /* Clear Last error code Flag */
1167
    CLEAR_BIT(hcan->Instance->ESR, CAN_ESR_LEC);
1168
  }
1169
 
1170
  /* Call the Error call Back in case of Errors */
1171
  if(hcan->ErrorCode != HAL_CAN_ERROR_NONE)
1172
  {
5 mjames 1173
    /* Clear ERRI Flag */
1174
    hcan->Instance->MSR |= CAN_MSR_ERRI;
2 mjames 1175
    /* Set the CAN state ready to be able to start again the process */
1176
    hcan->State = HAL_CAN_STATE_READY;
1177
 
1178
    /* Call Error callback function */
1179
    HAL_CAN_ErrorCallback(hcan);
1180
  }  
1181
}
1182
 
1183
/**
1184
  * @brief  Transmission  complete callback in non blocking mode
1185
  * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
1186
  *         the configuration information for the specified CAN.
1187
  * @retval None
1188
  */
1189
__weak void HAL_CAN_TxCpltCallback(CAN_HandleTypeDef* hcan)
1190
{
5 mjames 1191
  /* Prevent unused argument(s) compilation warning */
1192
  UNUSED(hcan);
2 mjames 1193
  /* NOTE : This function Should not be modified, when the callback is needed,
1194
            the HAL_CAN_TxCpltCallback can be implemented in the user file
1195
   */
1196
}
1197
 
1198
/**
1199
  * @brief  Transmission  complete callback in non blocking mode
1200
  * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
1201
  *         the configuration information for the specified CAN.
1202
  * @retval None
1203
  */
1204
__weak void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* hcan)
1205
{
5 mjames 1206
  /* Prevent unused argument(s) compilation warning */
1207
  UNUSED(hcan);
2 mjames 1208
  /* NOTE : This function Should not be modified, when the callback is needed,
1209
            the HAL_CAN_RxCpltCallback can be implemented in the user file
1210
   */
1211
}
1212
 
1213
/**
1214
  * @brief  Error CAN callback.
1215
  * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
1216
  *         the configuration information for the specified CAN.
1217
  * @retval None
1218
  */
1219
__weak void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan)
1220
{
5 mjames 1221
  /* Prevent unused argument(s) compilation warning */
1222
  UNUSED(hcan);
2 mjames 1223
  /* NOTE : This function Should not be modified, when the callback is needed,
1224
            the HAL_CAN_ErrorCallback can be implemented in the user file
1225
   */
1226
}
1227
 
1228
/**
1229
  * @}
1230
  */
1231
 
1232
/** @defgroup CAN_Exported_Functions_Group3 Peripheral State and Error functions
1233
 *  @brief   CAN Peripheral State functions
1234
 *
1235
@verbatim  
1236
  ==============================================================================
1237
            ##### Peripheral State and Error functions #####
1238
  ==============================================================================
1239
    [..]
1240
    This subsection provides functions allowing to :
1241
      (+) Check the CAN state.
1242
      (+) Check CAN Errors detected during interrupt process
1243
 
1244
@endverbatim
1245
  * @{
1246
  */
1247
 
1248
/**
1249
  * @brief  return the CAN state
1250
  * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
1251
  *         the configuration information for the specified CAN.
1252
  * @retval HAL state
1253
  */
1254
HAL_CAN_StateTypeDef HAL_CAN_GetState(CAN_HandleTypeDef* hcan)
1255
{
1256
  /* Return CAN state */
1257
  return hcan->State;
1258
}
1259
 
1260
/**
1261
  * @brief  Return the CAN error code
1262
  * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
1263
  *         the configuration information for the specified CAN.
1264
  * @retval CAN Error Code
1265
  */
1266
uint32_t HAL_CAN_GetError(CAN_HandleTypeDef *hcan)
1267
{
1268
  return hcan->ErrorCode;
1269
}
1270
 
1271
/**
1272
  * @}
1273
  */
1274
 
1275
/**
1276
  * @}
1277
  */
1278
 
1279
/** @defgroup CAN_Private_Functions CAN Private Functions
1280
 * @{
1281
 */
1282
/**
1283
  * @brief  Initiates and transmits a CAN frame message.
1284
  * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
1285
  *         the configuration information for the specified CAN.  
1286
  * @retval HAL status
1287
  */
1288
static HAL_StatusTypeDef CAN_Transmit_IT(CAN_HandleTypeDef* hcan)
1289
{
1290
  /* Disable Transmit mailbox empty Interrupt */
1291
  __HAL_CAN_DISABLE_IT(hcan, CAN_IT_TME);
1292
 
1293
  if(hcan->State == HAL_CAN_STATE_BUSY_TX)
1294
  {  
1295
    /* Disable interrupts: */
1296
    /*  - Disable Error warning Interrupt */
1297
    /*  - Disable Error passive Interrupt */
1298
    /*  - Disable Bus-off Interrupt */
1299
    /*  - Disable Last error code Interrupt */
1300
    /*  - Disable Error Interrupt */
1301
    __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EWG |
1302
                               CAN_IT_EPV |
1303
                               CAN_IT_BOF |
1304
                               CAN_IT_LEC |
1305
                               CAN_IT_ERR  );
1306
  }
1307
 
1308
  if(hcan->State == HAL_CAN_STATE_BUSY_TX_RX)
1309
  {
1310
    /* Change CAN state */
1311
    hcan->State = HAL_CAN_STATE_BUSY_RX;
1312
  }
1313
  else
1314
  {
1315
    /* Change CAN state */
1316
    hcan->State = HAL_CAN_STATE_READY;
1317
  }
1318
 
1319
  /* Transmission complete callback */
1320
  HAL_CAN_TxCpltCallback(hcan);
1321
 
1322
  return HAL_OK;
1323
}
1324
 
1325
/**
1326
  * @brief  Receives a correct CAN frame.
1327
  * @param  hcan:       Pointer to a CAN_HandleTypeDef structure that contains
1328
  *         the configuration information for the specified CAN.  
1329
  * @param  FIFONumber: Specify the FIFO number    
1330
  * @retval HAL status
1331
  * @retval None
1332
  */
1333
static HAL_StatusTypeDef CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber)
1334
{
1335
  /* Get the Id */
1336
  hcan->pRxMsg->IDE = (uint8_t)0x04 & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
1337
  if (hcan->pRxMsg->IDE == CAN_ID_STD)
1338
  {
1339
    hcan->pRxMsg->StdId = (uint32_t)0x000007FF & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 21);
1340
  }
1341
  else
1342
  {
1343
    hcan->pRxMsg->ExtId = (uint32_t)0x1FFFFFFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 3);
1344
  }
1345
 
1346
  hcan->pRxMsg->RTR = (uint8_t)0x02 & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
1347
  /* Get the DLC */
1348
  hcan->pRxMsg->DLC = (uint8_t)0x0F & hcan->Instance->sFIFOMailBox[FIFONumber].RDTR;
1349
  /* Get the FMI */
1350
  hcan->pRxMsg->FMI = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDTR >> 8);
1351
  /* Get the data field */
1352
  hcan->pRxMsg->Data[0] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR;
1353
  hcan->pRxMsg->Data[1] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 8);
1354
  hcan->pRxMsg->Data[2] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 16);
1355
  hcan->pRxMsg->Data[3] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 24);
1356
  hcan->pRxMsg->Data[4] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR;
1357
  hcan->pRxMsg->Data[5] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 8);
1358
  hcan->pRxMsg->Data[6] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 16);
1359
  hcan->pRxMsg->Data[7] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 24);
1360
  /* Release the FIFO */
1361
  /* Release FIFO0 */
1362
  if (FIFONumber == CAN_FIFO0)
1363
  {
1364
    __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO0);
1365
 
1366
    /* Disable FIFO 0 message pending Interrupt */
1367
    __HAL_CAN_DISABLE_IT(hcan, CAN_IT_FMP0);
1368
  }
1369
  /* Release FIFO1 */
1370
  else /* FIFONumber == CAN_FIFO1 */
1371
  {
1372
    __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO1);
1373
 
1374
    /* Disable FIFO 1 message pending Interrupt */
1375
    __HAL_CAN_DISABLE_IT(hcan, CAN_IT_FMP1);
1376
  }
1377
 
1378
  if(hcan->State == HAL_CAN_STATE_BUSY_RX)
1379
  {
1380
    /* Disable interrupts: */
1381
    /*  - Disable Error warning Interrupt */
1382
    /*  - Disable Error passive Interrupt */
1383
    /*  - Disable Bus-off Interrupt */
1384
    /*  - Disable Last error code Interrupt */
1385
    /*  - Disable Error Interrupt */
1386
    __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EWG |
1387
                               CAN_IT_EPV |
1388
                               CAN_IT_BOF |
1389
                               CAN_IT_LEC |
1390
                               CAN_IT_ERR  );
1391
  }
1392
 
1393
  if(hcan->State == HAL_CAN_STATE_BUSY_TX_RX)
1394
  {
1395
    /* Disable CAN state */
1396
    hcan->State = HAL_CAN_STATE_BUSY_TX;
1397
  }
1398
  else
1399
  {
1400
    /* Change CAN state */
1401
    hcan->State = HAL_CAN_STATE_READY;
1402
  }
1403
 
1404
  /* Receive complete callback */
1405
  HAL_CAN_RxCpltCallback(hcan);
1406
 
1407
  /* Return function status */
1408
  return HAL_OK;
1409
}
1410
 
1411
/**
1412
 * @}
1413
 */
1414
 
1415
/**
1416
  * @}
1417
  */
1418
 
1419
#endif /* STM32F103x6) || STM32F103xB || STM32F103xE || */
1420
       /* STM32F103xG) || STM32F105xC || STM32F107xC    */
1421
 
1422
#endif /* HAL_CAN_MODULE_ENABLED */
1423
 
1424
/**
1425
  * @}
1426
  */
1427
 
1428
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/