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_smartcard.c
4
  * @author  MCD Application Team
5
  * @version V1.0.1
6
  * @date    31-July-2015
7
  * @brief   SMARTCARD HAL module driver.
8
  *          This file provides firmware functions to manage the following
9
  *          functionalities of the SMARTCARD peripheral:
10
  *           + Initialization and de-initialization functions
11
  *           + IO operation functions
12
  *           + Peripheral State and Errors functions
13
  *           + Peripheral Control functions
14
  *
15
  @verbatim
16
  ==============================================================================
17
                        ##### How to use this driver #####
18
  ==============================================================================
19
  [..]
20
    The SMARTCARD HAL driver can be used as follows:
21
 
22
    (#) Declare a SMARTCARD_HandleTypeDef handle structure.
23
    (#) Initialize the SMARTCARD low level resources by implementing the HAL_SMARTCARD_MspInit() API:
24
        (##) Enable the interface clock of the USARTx associated to the SMARTCARD.
25
        (##) SMARTCARD pins configuration:
26
            (+++) Enable the clock for the SMARTCARD GPIOs.
27
             (+++) Configure the USART pins (TX as alternate function pull-up, RX as alternate function Input).
28
        (##) NVIC configuration if you need to use interrupt process (HAL_SMARTCARD_Transmit_IT()
29
             and HAL_SMARTCARD_Receive_IT() APIs):
30
            (+++) Configure the USARTx interrupt priority.
31
            (+++) Enable the NVIC USART IRQ handle.
32
        (##) DMA Configuration if you need to use DMA process (HAL_SMARTCARD_Transmit_DMA()
33
             and HAL_SMARTCARD_Receive_DMA() APIs):
34
            (+++) Declare a DMA handle structure for the Tx/Rx channel.
35
            (+++) Enable the DMAx interface clock.
36
            (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.
37
            (+++) Configure the DMA Tx/Rx channel.
38
            (+++) Associate the initilalized DMA handle to the SMARTCARD DMA Tx/Rx handle.
39
            (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx channel.
40
            (+++) Configure the USARTx interrupt priority and enable the NVIC USART IRQ handle
41
                  (used for last byte sending completion detection in DMA non circular mode)
42
 
43
    (#) Program the Baud Rate, Word Length , Stop Bit, Parity, Hardware
44
        flow control and Mode(Receiver/Transmitter) in the SMARTCARD Init structure.
45
 
46
    (#) Initialize the SMARTCARD registers by calling the HAL_SMARTCARD_Init() API:
47
        (++) This API configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
48
             by calling the customed HAL_SMARTCARD_MspInit(&hsc) API.
49
 
50
        -@@- The specific SMARTCARD interrupts (Transmission complete interrupt,
51
             RXNE interrupt and Error Interrupts) will be managed using the macros
52
             __HAL_SMARTCARD_ENABLE_IT() and __HAL_SMARTCARD_DISABLE_IT() inside the transmit and receive process.
53
 
54
    (#) Three operation modes are available within this driver :
55
 
56
     *** Polling mode IO operation ***
57
     =================================
58
     [..]    
59
       (+) Send an amount of data in blocking mode using HAL_SMARTCARD_Transmit()
60
       (+) Receive an amount of data in blocking mode using HAL_SMARTCARD_Receive()
61
 
62
     *** Interrupt mode IO operation ***    
63
     ===================================
64
     [..]    
65
       (+) Send an amount of data in non blocking mode using HAL_SMARTCARD_Transmit_IT()
66
       (+) At transmission end of transfer HAL_SMARTCARD_TxCpltCallback is executed and user can
67
            add his own code by customization of function pointer HAL_SMARTCARD_TxCpltCallback
68
       (+) Receive an amount of data in non blocking mode using HAL_SMARTCARD_Receive_IT()
69
       (+) At reception end of transfer HAL_SMARTCARD_RxCpltCallback is executed and user can
70
            add his own code by customization of function pointer HAL_SMARTCARD_RxCpltCallback                                      
71
       (+) In case of transfer Error, HAL_SMARTCARD_ErrorCallback() function is executed and user can
72
            add his own code by customization of function pointer HAL_SMARTCARD_ErrorCallback
73
 
74
     *** DMA mode IO operation ***    
75
     ==============================
76
     [..]
77
       (+) Send an amount of data in non blocking mode (DMA) using HAL_SMARTCARD_Transmit_DMA()
78
       (+) At transmission end of transfer HAL_SMARTCARD_TxCpltCallback is executed and user can
79
            add his own code by customization of function pointer HAL_SMARTCARD_TxCpltCallback
80
       (+) Receive an amount of data in non blocking mode (DMA) using HAL_SMARTCARD_Receive_DMA()
81
       (+) At reception end of transfer HAL_SMARTCARD_RxCpltCallback is executed and user can
82
            add his own code by customization of function pointer HAL_SMARTCARD_RxCpltCallback                                      
83
       (+) In case of transfer Error, HAL_SMARTCARD_ErrorCallback() function is executed and user can
84
            add his own code by customization of function pointer HAL_SMARTCARD_ErrorCallback
85
 
86
     *** SMARTCARD HAL driver macros list ***
87
     ========================================
88
     [..]
89
       Below the list of most used macros in SMARTCARD HAL driver.
90
 
91
       (+) __HAL_SMARTCARD_ENABLE: Enable the SMARTCARD peripheral
92
       (+) __HAL_SMARTCARD_DISABLE: Disable the SMARTCARD peripheral    
93
       (+) __HAL_SMARTCARD_GET_FLAG : Check whether the specified SMARTCARD flag is set or not
94
       (+) __HAL_SMARTCARD_CLEAR_FLAG : Clear the specified SMARTCARD pending flag
95
       (+) __HAL_SMARTCARD_ENABLE_IT: Enable the specified SMARTCARD interrupt
96
       (+) __HAL_SMARTCARD_DISABLE_IT: Disable the specified SMARTCARD interrupt
97
       (+) __HAL_SMARTCARD_GET_IT_SOURCE: Check whether the specified SMARTCARD interrupt has occurred or not
98
 
99
     [..]
100
       (@) You can refer to the SMARTCARD HAL driver header file for more useful macros
101
 
102
  @endverbatim
103
  ******************************************************************************
104
  * @attention
105
  *
106
  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
107
  *
108
  * Redistribution and use in source and binary forms, with or without modification,
109
  * are permitted provided that the following conditions are met:
110
  *   1. Redistributions of source code must retain the above copyright notice,
111
  *      this list of conditions and the following disclaimer.
112
  *   2. Redistributions in binary form must reproduce the above copyright notice,
113
  *      this list of conditions and the following disclaimer in the documentation
114
  *      and/or other materials provided with the distribution.
115
  *   3. Neither the name of STMicroelectronics nor the names of its contributors
116
  *      may be used to endorse or promote products derived from this software
117
  *      without specific prior written permission.
118
  *
119
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
120
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
121
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
122
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
123
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
124
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
125
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
126
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
127
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
128
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
129
  *
130
  ******************************************************************************
131
  */
132
 
133
/* Includes ------------------------------------------------------------------*/
134
#include "stm32f1xx_hal.h"
135
 
136
/** @addtogroup STM32F1xx_HAL_Driver
137
  * @{
138
  */
139
 
140
/** @defgroup SMARTCARD SMARTCARD
141
  * @brief HAL SMARTCARD module driver
142
  * @{
143
  */
144
 
145
#ifdef HAL_SMARTCARD_MODULE_ENABLED
146
 
147
/* Private typedef -----------------------------------------------------------*/
148
/* Private define ------------------------------------------------------------*/
149
/* Private macros --------------------------------------------------------*/
150
/* Private variables ---------------------------------------------------------*/
151
/* Private function prototypes -----------------------------------------------*/
152
/** @addtogroup SMARTCARD_Private_Functions   SMARTCARD Private Functions
153
  * @{
154
  */
155
static HAL_StatusTypeDef SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef *hsc);
156
static HAL_StatusTypeDef SMARTCARD_EndTransmit_IT(SMARTCARD_HandleTypeDef *hsmartcard);
157
static HAL_StatusTypeDef SMARTCARD_Receive_IT(SMARTCARD_HandleTypeDef *hsc);
158
static void SMARTCARD_SetConfig (SMARTCARD_HandleTypeDef *hsc);
159
static void SMARTCARD_DMATransmitCplt(DMA_HandleTypeDef *hdma);
160
static void SMARTCARD_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
161
static void SMARTCARD_DMAError(DMA_HandleTypeDef *hdma);
162
static HAL_StatusTypeDef SMARTCARD_WaitOnFlagUntilTimeout(SMARTCARD_HandleTypeDef *hsc, uint32_t Flag, FlagStatus Status, uint32_t Timeout);
163
/**
164
  * @}
165
  */
166
 
167
/* Exported functions ---------------------------------------------------------*/
168
 
169
/** @defgroup SMARTCARD_Exported_Functions SMARTCARD Exported Functions
170
  * @{
171
  */
172
 
173
/** @defgroup SMARTCARD_Exported_Functions_Group1 Initialization and de-initialization functions
174
  *  @brief    Initialization and Configuration functions
175
  *
176
@verbatim
177
 
178
  ==============================================================================
179
              ##### Initialization and Configuration functions #####
180
  ==============================================================================
181
  [..]
182
  This subsection provides a set of functions allowing to initialize the USART
183
  in Smartcard mode.
184
  [..]
185
  The Smartcard interface is designed to support asynchronous protocol Smartcards as
186
  defined in the ISO 7816-3 standard.
187
  [..]
188
  The USART can provide a clock to the smartcard through the SCLK output.
189
  In smartcard mode, SCLK is not associated to the communication but is simply derived
190
  from the internal peripheral input clock through a 5-bit prescaler.
191
  [..]
192
  (+) For the Smartcard mode only these parameters can be configured:
193
      (++) Baud Rate
194
      (++) Word Length => Should be 9 bits (8 bits + parity)
195
      (++) Stop Bit
196
      (++) Parity: => Should be enabled
197
   +-------------------------------------------------------------+
198
   |   M bit |  PCE bit  |        SMARTCARD frame                |
199
   |---------------------|---------------------------------------|
200
   |    1    |    1      |    | SB | 8 bit data | PB | STB |     |
201
   +-------------------------------------------------------------+
202
      (++) USART polarity
203
      (++) USART phase
204
      (++) USART LastBit
205
      (++) Receiver/transmitter modes
206
      (++) Prescaler
207
      (++) GuardTime
208
      (++) NACKState: The Smartcard NACK state
209
 
210
     (+) Recommended SmartCard interface configuration to get the Answer to Reset from the Card:
211
        (++) Word Length = 9 Bits
212
        (++) 1.5 Stop Bit
213
        (++) Even parity
214
        (++) BaudRate = 12096 baud
215
        (++) Tx and Rx enabled
216
  [..]
217
  Please refer to the ISO 7816-3 specification for more details.
218
 
219
    (@) It is also possible to choose 0.5 stop bit for receiving but it is recommended
220
        to use 1.5 stop bits for both transmitting and receiving to avoid switching
221
        between the two configurations.
222
  [..]
223
  The HAL_SMARTCARD_Init() function follows the USART  SmartCard configuration
224
  procedure (details for the procedure are available in reference manuals
225
  (RM0008 for STM32F10Xxx MCUs and RM0041 for STM32F100xx MCUs)).
226
 
227
@endverbatim
228
  * @{
229
  */
230
 
231
/**
232
  * @brief  Initializes the SmartCard mode according to the specified
233
  *         parameters in the SMARTCARD_HandleTypeDef and create the associated handle.
234
  * @param  hsc: Pointer to a SMARTCARD_HandleTypeDef structure that contains
235
  *              the configuration information for the specified SMARTCARD module.
236
  * @retval HAL status
237
  */
238
HAL_StatusTypeDef HAL_SMARTCARD_Init(SMARTCARD_HandleTypeDef *hsc)
239
{
240
  /* Check the SMARTCARD handle allocation */
241
  if(hsc == NULL)
242
  {
243
    return HAL_ERROR;
244
  }
245
 
246
  /* Check Wordlength, Parity and Stop bits parameters */
247
  if (  (!(IS_SMARTCARD_WORD_LENGTH(hsc->Init.WordLength)))
248
      ||(!(IS_SMARTCARD_STOPBITS(hsc->Init.StopBits)))
249
      ||(!(IS_SMARTCARD_PARITY(hsc->Init.Parity)))  )
250
  {
251
    return HAL_ERROR;
252
  }
253
 
254
  /* Check the parameters */
255
  assert_param(IS_SMARTCARD_INSTANCE(hsc->Instance));
256
  assert_param(IS_SMARTCARD_NACK_STATE(hsc->Init.NACKState));
257
  assert_param(IS_SMARTCARD_PRESCALER(hsc->Init.Prescaler));
258
 
259
  if(hsc->State == HAL_SMARTCARD_STATE_RESET)
260
  {  
261
    /* Allocate lock resource and initialize it */
262
    hsc->Lock = HAL_UNLOCKED;
263
 
264
    /* Init the low level hardware */
265
    HAL_SMARTCARD_MspInit(hsc);
266
  }
267
 
268
  hsc->State = HAL_SMARTCARD_STATE_BUSY;
269
 
270
  /* Disable the Peripheral */
271
  __HAL_SMARTCARD_DISABLE(hsc);
272
 
273
  /* Set the Prescaler */
274
  MODIFY_REG(hsc->Instance->GTPR, USART_GTPR_PSC, hsc->Init.Prescaler);
275
 
276
  /* Set the Guard Time */
277
  MODIFY_REG(hsc->Instance->GTPR, USART_GTPR_GT, ((hsc->Init.GuardTime)<<8));
278
 
279
  /* Set the Smartcard Communication parameters */
280
  SMARTCARD_SetConfig(hsc);
281
 
282
  /* In SmartCard mode, the following bits must be kept cleared:
283
  - LINEN bit in the USART_CR2 register
284
  - HDSEL and IREN bits in the USART_CR3 register.*/
285
  CLEAR_BIT(hsc->Instance->CR2, USART_CR2_LINEN);
286
  CLEAR_BIT(hsc->Instance->CR3, (USART_CR3_IREN | USART_CR3_HDSEL));
287
 
288
  /* Enable the Peripharal */
289
  __HAL_SMARTCARD_ENABLE(hsc);
290
 
291
  /* Configure the Smartcard NACK state */
292
  MODIFY_REG(hsc->Instance->CR3, USART_CR3_NACK, hsc->Init.NACKState);
293
 
294
  /* Enable the SC mode by setting the SCEN bit in the CR3 register */
295
  SET_BIT(hsc->Instance->CR3, USART_CR3_SCEN);
296
 
297
  /* Initialize the SMARTCARD state*/
298
  hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
299
  hsc->State= HAL_SMARTCARD_STATE_READY;
300
 
301
  return HAL_OK;
302
}
303
 
304
/**
305
  * @brief  DeInitializes the SMARTCARD peripheral
306
  * @param  hsc: Pointer to a SMARTCARD_HandleTypeDef structure that contains
307
  *              the configuration information for the specified SMARTCARD module.
308
  * @retval HAL status
309
  */
310
HAL_StatusTypeDef HAL_SMARTCARD_DeInit(SMARTCARD_HandleTypeDef *hsc)
311
{
312
  /* Check the SMARTCARD handle allocation */
313
  if(hsc == NULL)
314
  {
315
    return HAL_ERROR;
316
  }
317
 
318
  /* Check the parameters */
319
  assert_param(IS_SMARTCARD_INSTANCE(hsc->Instance));
320
 
321
  hsc->State = HAL_SMARTCARD_STATE_BUSY;
322
 
323
  /* Disable the Peripheral */
324
  __HAL_SMARTCARD_DISABLE(hsc);
325
 
326
  hsc->Instance->CR1 = 0x0;
327
  hsc->Instance->CR2 = 0x0;
328
  hsc->Instance->CR3 = 0x0;
329
  hsc->Instance->BRR = 0x0;
330
  hsc->Instance->GTPR = 0x0;
331
 
332
  /* DeInit the low level hardware */
333
  HAL_SMARTCARD_MspDeInit(hsc);
334
 
335
  hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
336
  hsc->State = HAL_SMARTCARD_STATE_RESET;
337
 
338
  /* Release Lock */
339
  __HAL_UNLOCK(hsc);
340
 
341
  return HAL_OK;
342
}
343
 
344
/**
345
  * @brief  SMARTCARD MSP Init.
346
  * @param  hsc: Pointer to a SMARTCARD_HandleTypeDef structure that contains
347
  *                the configuration information for the specified SMARTCARD module.
348
  * @retval None
349
  */
350
 __weak void HAL_SMARTCARD_MspInit(SMARTCARD_HandleTypeDef *hsc)
351
{
352
  /* NOTE: This function should not be modified, when the callback is needed,
353
           the HAL_SMARTCARD_MspInit can be implemented in the user file
354
   */
355
}
356
 
357
/**
358
  * @brief  SMARTCARD MSP DeInit.
359
  * @param  hsc: Pointer to a SMARTCARD_HandleTypeDef structure that contains
360
  *                the configuration information for the specified SMARTCARD module.
361
  * @retval None
362
  */
363
 __weak void HAL_SMARTCARD_MspDeInit(SMARTCARD_HandleTypeDef *hsc)
364
{
365
  /* NOTE: This function should not be modified, when the callback is needed,
366
           the HAL_SMARTCARD_MspDeInit can be implemented in the user file
367
   */
368
}
369
 
370
/**
371
  * @}
372
  */
373
 
374
/** @defgroup SMARTCARD_Exported_Functions_Group2 IO operation functions
375
  *  @brief   SMARTCARD Transmit and Receive functions
376
  *
377
@verbatim
378
  ==============================================================================
379
                         ##### IO operation functions #####
380
  ==============================================================================
381
  [..]
382
    This subsection provides a set of functions allowing to manage the SMARTCARD data transfers.
383
 
384
  [..]
385
    (#) Smartcard is a single wire half duplex communication protocol.
386
    The Smartcard interface is designed to support asynchronous protocol Smartcards as
387
    defined in the ISO 7816-3 standard.
388
    (#) The USART should be configured as:
389
        (++) 8 bits plus parity: where M=1 and PCE=1 in the USART_CR1 register
390
        (++) 1.5 stop bits when transmitting and receiving: where STOP=11 in the USART_CR2 register.
391
 
392
    (#) There are two modes of transfer:
393
        (++) Blocking mode: The communication is performed in polling mode.
394
             The HAL status of all data processing is returned by the same function
395
             after finishing transfer.  
396
        (++) No-Blocking mode: The communication is performed using Interrupts
397
             or DMA, the relevant API's return the HAL status.
398
             The end of the data processing will be indicated through the
399
             dedicated SMARTCARD IRQ when using Interrupt mode or the DMA IRQ when
400
             using DMA mode.
401
             The HAL_SMARTCARD_TxCpltCallback(), HAL_SMARTCARD_RxCpltCallback() user callbacks
402
             will be executed respectively at the end of the Transmit or Receive process
403
             The HAL_SMARTCARD_ErrorCallback() user callback will be executed when a communication
404
             error is detected.
405
 
406
    (#) Blocking mode APIs are :
407
        (++) HAL_SMARTCARD_Transmit()
408
        (++) HAL_SMARTCARD_Receive()
409
 
410
    (#) Non Blocking mode APIs with Interrupt are :
411
        (++) HAL_SMARTCARD_Transmit_IT()
412
        (++) HAL_SMARTCARD_Receive_IT()
413
        (++) HAL_SMARTCARD_IRQHandler()
414
 
415
    (#) Non Blocking mode functions with DMA are :
416
        (++) HAL_SMARTCARD_Transmit_DMA()
417
        (++) HAL_SMARTCARD_Receive_DMA()
418
 
419
    (#) A set of Transfer Complete Callbacks are provided in non Blocking mode:
420
        (++) HAL_SMARTCARD_TxCpltCallback()
421
        (++) HAL_SMARTCARD_RxCpltCallback()
422
        (++) HAL_SMARTCARD_ErrorCallback()
423
 
424
@endverbatim
425
  * @{
426
  */
427
 
428
/**
429
  * @brief  Sends an amount of data in blocking mode.
430
  * @param  hsc: Pointer to a SMARTCARD_HandleTypeDef structure that contains
431
  *                the configuration information for the specified SMARTCARD module.
432
  * @param  pData: Pointer to data buffer
433
  * @param  Size: Amount of data to be sent
434
  * @param  Timeout: Specify timeout value  
435
  * @retval HAL status
436
  */
437
HAL_StatusTypeDef HAL_SMARTCARD_Transmit(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size, uint32_t Timeout)
438
{
439
  uint32_t tmp_state = 0;
440
 
441
  tmp_state = hsc->State;
442
  if((tmp_state == HAL_SMARTCARD_STATE_READY) || (tmp_state == HAL_SMARTCARD_STATE_BUSY_RX))
443
  {
444
    if((pData == NULL) || (Size == 0))
445
    {
446
      return  HAL_ERROR;
447
    }
448
 
449
    /* Process Locked */
450
    __HAL_LOCK(hsc);
451
 
452
    hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
453
    /* Check if a non-blocking receive process is ongoing or not */
454
    if(hsc->State == HAL_SMARTCARD_STATE_BUSY_RX)
455
    {
456
      hsc->State = HAL_SMARTCARD_STATE_BUSY_TX_RX;
457
    }
458
    else
459
    {
460
      hsc->State = HAL_SMARTCARD_STATE_BUSY_TX;
461
    }
462
 
463
    hsc->TxXferSize = Size;
464
    hsc->TxXferCount = Size;
465
    while(hsc->TxXferCount > 0)
466
    {
467
      if(SMARTCARD_WaitOnFlagUntilTimeout(hsc, SMARTCARD_FLAG_TXE, RESET, Timeout) != HAL_OK)
468
      {
469
        return HAL_TIMEOUT;
470
      }
471
      WRITE_REG(hsc->Instance->DR, (*pData++ & (uint8_t)0xFF));
472
      hsc->TxXferCount--;
473
    }
474
 
475
    if(SMARTCARD_WaitOnFlagUntilTimeout(hsc, SMARTCARD_FLAG_TC, RESET, Timeout) != HAL_OK)
476
    {
477
      return HAL_TIMEOUT;
478
    }
479
 
480
    /* Check if a non-blocking receive process is ongoing or not */
481
    if(hsc->State == HAL_SMARTCARD_STATE_BUSY_TX_RX)
482
    {
483
      hsc->State = HAL_SMARTCARD_STATE_BUSY_RX;
484
    }
485
    else
486
    {
487
      hsc->State = HAL_SMARTCARD_STATE_READY;
488
    }
489
    /* Process Unlocked */
490
    __HAL_UNLOCK(hsc);
491
 
492
    return HAL_OK;
493
  }
494
  else
495
  {
496
    return HAL_BUSY;
497
  }
498
}
499
 
500
/**
501
  * @brief  Receive an amount of data in blocking mode.
502
  * @param  hsc: Pointer to a SMARTCARD_HandleTypeDef structure that contains
503
  *                the configuration information for the specified SMARTCARD module.
504
  * @param  pData: Pointer to data buffer
505
  * @param  Size: Amount of data to be received
506
  * @param  Timeout: Specify timeout value    
507
  * @retval HAL status
508
  */
509
HAL_StatusTypeDef HAL_SMARTCARD_Receive(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size, uint32_t Timeout)
510
{
511
  uint32_t tmp_state = 0;
512
 
513
  tmp_state = hsc->State;
514
  if((tmp_state == HAL_SMARTCARD_STATE_READY) || (tmp_state == HAL_SMARTCARD_STATE_BUSY_TX))
515
  {
516
    if((pData == NULL) || (Size == 0))
517
    {
518
      return  HAL_ERROR;
519
    }
520
 
521
    /* Process Locked */
522
    __HAL_LOCK(hsc);
523
 
524
    hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
525
 
526
    /* Check if a non-blocking transmit process is ongoing or not */
527
    if(hsc->State == HAL_SMARTCARD_STATE_BUSY_TX)
528
    {
529
      hsc->State = HAL_SMARTCARD_STATE_BUSY_TX_RX;
530
    }
531
    else
532
    {
533
      hsc->State = HAL_SMARTCARD_STATE_BUSY_RX;
534
    }
535
 
536
    hsc->RxXferSize = Size;
537
    hsc->RxXferCount = Size;
538
    /* Check the remain data to be received */
539
    while(hsc->RxXferCount > 0)
540
    {
541
      if(SMARTCARD_WaitOnFlagUntilTimeout(hsc, SMARTCARD_FLAG_RXNE, RESET, Timeout) != HAL_OK)
542
      {
543
        return HAL_TIMEOUT;
544
      }
545
      *pData++ = (uint8_t)(hsc->Instance->DR & (uint8_t)0x00FF);              
546
      hsc->RxXferCount--;
547
    }
548
 
549
    /* Check if a non-blocking transmit process is ongoing or not */
550
    if(hsc->State == HAL_SMARTCARD_STATE_BUSY_TX_RX)
551
    {
552
      hsc->State = HAL_SMARTCARD_STATE_BUSY_TX;
553
    }
554
    else
555
    {
556
      hsc->State = HAL_SMARTCARD_STATE_READY;
557
    }
558
 
559
    /* Process Unlocked */
560
    __HAL_UNLOCK(hsc);
561
 
562
    return HAL_OK;
563
  }
564
  else
565
  {
566
    return HAL_BUSY;
567
  }
568
}
569
 
570
/**
571
  * @brief  Sends an amount of data in non-blocking mode.
572
  * @param  hsc: Pointer to a SMARTCARD_HandleTypeDef structure that contains
573
  *                the configuration information for the specified SMARTCARD module.
574
  * @param  pData: Pointer to data buffer
575
  * @param  Size: Amount of data to be sent
576
  * @retval HAL status
577
  */
578
HAL_StatusTypeDef HAL_SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size)
579
{
580
  uint32_t tmp_state = 0;
581
 
582
  tmp_state = hsc->State;
583
  if((tmp_state == HAL_SMARTCARD_STATE_READY) || (tmp_state == HAL_SMARTCARD_STATE_BUSY_RX))
584
  {
585
    if((pData == NULL) || (Size == 0))
586
    {
587
      return HAL_ERROR;
588
    }
589
 
590
    /* Process Locked */
591
    __HAL_LOCK(hsc);
592
 
593
    hsc->pTxBuffPtr = pData;
594
    hsc->TxXferSize = Size;
595
    hsc->TxXferCount = Size;
596
 
597
    hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
598
    /* Check if a non-blocking receive process is ongoing or not */
599
    if(hsc->State == HAL_SMARTCARD_STATE_BUSY_RX)
600
    {
601
      hsc->State = HAL_SMARTCARD_STATE_BUSY_TX_RX;
602
    }
603
    else
604
    {
605
      hsc->State = HAL_SMARTCARD_STATE_BUSY_TX;
606
    }
607
 
608
    /* Process Unlocked */
609
    __HAL_UNLOCK(hsc);
610
 
611
    /* Enable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */
612
    __HAL_SMARTCARD_ENABLE_IT(hsc, SMARTCARD_IT_ERR);
613
 
614
    /* Enable the SMARTCARD Transmit data register empty Interrupt */
615
    __HAL_SMARTCARD_ENABLE_IT(hsc, SMARTCARD_IT_TXE);
616
 
617
    return HAL_OK;
618
  }
619
  else
620
  {
621
    return HAL_BUSY;
622
  }
623
}
624
 
625
/**
626
  * @brief  Receives an amount of data in non-blocking mode.
627
  * @param  hsc: Pointer to a SMARTCARD_HandleTypeDef structure that contains
628
  *                the configuration information for the specified SMARTCARD module.
629
  * @param  pData: Pointer to data buffer
630
  * @param  Size: Amount of data to be received
631
  * @retval HAL status
632
  */
633
HAL_StatusTypeDef HAL_SMARTCARD_Receive_IT(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size)
634
{
635
  uint32_t tmp_state = 0;
636
 
637
  tmp_state = hsc->State;
638
  if((tmp_state == HAL_SMARTCARD_STATE_READY) || (tmp_state == HAL_SMARTCARD_STATE_BUSY_TX))
639
  {
640
    if((pData == NULL) || (Size == 0))
641
    {
642
      return HAL_ERROR;
643
    }
644
 
645
    /* Process Locked */
646
    __HAL_LOCK(hsc);
647
 
648
    hsc->pRxBuffPtr = pData;
649
    hsc->RxXferSize = Size;
650
    hsc->RxXferCount = Size;
651
 
652
    hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
653
    /* Check if a non-blocking transmit process is ongoing or not */
654
    if(hsc->State == HAL_SMARTCARD_STATE_BUSY_TX)
655
    {
656
      hsc->State = HAL_SMARTCARD_STATE_BUSY_TX_RX;
657
    }
658
    else
659
    {
660
      hsc->State = HAL_SMARTCARD_STATE_BUSY_RX;
661
    }
662
 
663
    /* Process Unlocked */
664
    __HAL_UNLOCK(hsc);
665
 
666
    /* Enable the SMARTCARD Data Register not empty Interrupt */
667
    __HAL_SMARTCARD_ENABLE_IT(hsc, SMARTCARD_IT_RXNE);
668
 
669
    /* Enable the SMARTCARD Parity Error Interrupt */
670
    __HAL_SMARTCARD_ENABLE_IT(hsc, SMARTCARD_IT_PE);
671
 
672
    /* Enable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */
673
    __HAL_SMARTCARD_ENABLE_IT(hsc, SMARTCARD_IT_ERR);
674
 
675
    return HAL_OK;
676
  }
677
  else
678
  {
679
    return HAL_BUSY;
680
  }
681
}
682
 
683
/**
684
  * @brief  Sends an amount of data in non-blocking mode.
685
  * @param  hsc: Pointer to a SMARTCARD_HandleTypeDef structure that contains
686
  *                the configuration information for the specified SMARTCARD module.
687
  * @param  pData: Pointer to data buffer
688
  * @param  Size: Amount of data to be sent
689
  * @retval HAL status
690
  */
691
HAL_StatusTypeDef HAL_SMARTCARD_Transmit_DMA(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size)
692
{
693
  uint32_t *tmp = 0;
694
  uint32_t tmp_state = 0;
695
 
696
  tmp_state = hsc->State;
697
  if((tmp_state == HAL_SMARTCARD_STATE_READY) || (tmp_state == HAL_SMARTCARD_STATE_BUSY_RX))
698
  {
699
    if((pData == NULL) || (Size == 0))
700
    {
701
      return HAL_ERROR;
702
    }
703
 
704
    /* Process Locked */
705
    __HAL_LOCK(hsc);
706
 
707
    hsc->pTxBuffPtr = pData;
708
    hsc->TxXferSize = Size;
709
    hsc->TxXferCount = Size;
710
 
711
    hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
712
    /* Check if a non-blocking receive process is ongoing or not */
713
    if(hsc->State == HAL_SMARTCARD_STATE_BUSY_RX)
714
    {
715
      hsc->State = HAL_SMARTCARD_STATE_BUSY_TX_RX;
716
    }
717
    else
718
    {
719
      hsc->State = HAL_SMARTCARD_STATE_BUSY_TX;
720
    }
721
 
722
    /* Set the SMARTCARD DMA transfer complete callback */
723
    hsc->hdmatx->XferCpltCallback = SMARTCARD_DMATransmitCplt;
724
 
725
    /* Set the DMA error callback */
726
    hsc->hdmatx->XferErrorCallback = SMARTCARD_DMAError;
727
 
728
    /* Enable the SMARTCARD transmit DMA channel */
729
    tmp = (uint32_t*)&pData;
730
    HAL_DMA_Start_IT(hsc->hdmatx, *(uint32_t*)tmp, (uint32_t)&hsc->Instance->DR, Size);
731
 
732
     /* Clear the TC flag in the SR register by writing 0 to it */
733
    __HAL_SMARTCARD_CLEAR_FLAG(hsc, SMARTCARD_FLAG_TC);
734
 
735
    /* Enable the DMA transfer for transmit request by setting the DMAT bit
736
    in the SMARTCARD CR3 register */
737
    SET_BIT(hsc->Instance->CR3,USART_CR3_DMAT);
738
 
739
    /* Process Unlocked */
740
    __HAL_UNLOCK(hsc);
741
 
742
    return HAL_OK;
743
  }
744
  else
745
  {
746
    return HAL_BUSY;
747
  }
748
}
749
 
750
/**
751
  * @brief  Receive an amount of data in non-blocking mode.
752
  * @param  hsc: Pointer to a SMARTCARD_HandleTypeDef structure that contains
753
  *                the configuration information for the specified SMARTCARD module.
754
  * @param  pData: Pointer to data buffer
755
  * @param  Size: Amount of data to be received
756
  * @note   When the SMARTCARD parity is enabled (PCE = 1) the data received contain the parity bit.
757
  * @retval HAL status
758
  */
759
HAL_StatusTypeDef HAL_SMARTCARD_Receive_DMA(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size)
760
{
761
  uint32_t *tmp = 0;
762
  uint32_t tmp_state = 0;
763
 
764
  tmp_state = hsc->State;
765
  if((tmp_state == HAL_SMARTCARD_STATE_READY) || (tmp_state == HAL_SMARTCARD_STATE_BUSY_TX))
766
  {
767
    if((pData == NULL) || (Size == 0))
768
    {
769
      return HAL_ERROR;
770
    }
771
 
772
    /* Process Locked */
773
    __HAL_LOCK(hsc);
774
 
775
    hsc->pRxBuffPtr = pData;
776
    hsc->RxXferSize = Size;
777
 
778
    hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
779
    /* Check if a non-blocking transmit process is ongoing or not */
780
    if(hsc->State == HAL_SMARTCARD_STATE_BUSY_TX)
781
    {
782
      hsc->State = HAL_SMARTCARD_STATE_BUSY_TX_RX;
783
    }
784
    else
785
    {
786
      hsc->State = HAL_SMARTCARD_STATE_BUSY_RX;
787
    }
788
 
789
    /* Set the SMARTCARD DMA transfer complete callback */
790
    hsc->hdmarx->XferCpltCallback = SMARTCARD_DMAReceiveCplt;
791
 
792
    /* Set the DMA error callback */
793
    hsc->hdmarx->XferErrorCallback = SMARTCARD_DMAError;
794
 
795
    /* Enable the DMA channel */
796
    tmp = (uint32_t*)&pData;
797
    HAL_DMA_Start_IT(hsc->hdmarx, (uint32_t)&hsc->Instance->DR, *(uint32_t*)tmp, Size);
798
 
799
    /* Enable the DMA transfer for the receiver request by setting the DMAR bit
800
    in the SMARTCARD CR3 register */
801
    SET_BIT(hsc->Instance->CR3,USART_CR3_DMAR);
802
 
803
    /* Process Unlocked */
804
    __HAL_UNLOCK(hsc);
805
 
806
    return HAL_OK;
807
  }
808
  else
809
  {
810
    return HAL_BUSY;
811
  }
812
}
813
 
814
/**
815
  * @brief  This function handles SMARTCARD interrupt request.
816
  * @param  hsc: Pointer to a SMARTCARD_HandleTypeDef structure that contains
817
  *                the configuration information for the specified SMARTCARD module.
818
  * @retval None
819
  */
820
void HAL_SMARTCARD_IRQHandler(SMARTCARD_HandleTypeDef *hsc)
821
{
822
  uint32_t  tmp_flag = 0, tmp_it_source = 0;
823
 
824
  tmp_flag = __HAL_SMARTCARD_GET_FLAG(hsc, SMARTCARD_FLAG_PE);
825
  tmp_it_source = __HAL_SMARTCARD_GET_IT_SOURCE(hsc, SMARTCARD_IT_PE);
826
  /* SMARTCARD parity error interrupt occurred -----------------------------------*/
827
  if((tmp_flag != RESET) && (tmp_it_source != RESET))
828
  {
829
    __HAL_SMARTCARD_CLEAR_PEFLAG(hsc);
830
    hsc->ErrorCode |= HAL_SMARTCARD_ERROR_PE;
831
  }
832
 
833
  tmp_flag = __HAL_SMARTCARD_GET_FLAG(hsc, SMARTCARD_FLAG_FE);
834
  tmp_it_source = __HAL_SMARTCARD_GET_IT_SOURCE(hsc, SMARTCARD_IT_ERR);
835
  /* SMARTCARD frame error interrupt occurred ------------------------------------*/
836
  if((tmp_flag != RESET) && (tmp_it_source != RESET))
837
  {
838
    __HAL_SMARTCARD_CLEAR_FEFLAG(hsc);
839
    hsc->ErrorCode |= HAL_SMARTCARD_ERROR_FE;
840
  }
841
 
842
  tmp_flag = __HAL_SMARTCARD_GET_FLAG(hsc, SMARTCARD_FLAG_NE);
843
  /* SMARTCARD noise error interrupt occurred ------------------------------------*/
844
  if((tmp_flag != RESET) && (tmp_it_source != RESET))
845
  {
846
    __HAL_SMARTCARD_CLEAR_NEFLAG(hsc);
847
    hsc->ErrorCode |= HAL_SMARTCARD_ERROR_NE;
848
  }
849
 
850
  tmp_flag = __HAL_SMARTCARD_GET_FLAG(hsc, SMARTCARD_FLAG_ORE);
851
  /* SMARTCARD Over-Run interrupt occurred ---------------------------------------*/
852
  if((tmp_flag != RESET) && (tmp_it_source != RESET))
853
  {
854
    __HAL_SMARTCARD_CLEAR_OREFLAG(hsc);
855
    hsc->ErrorCode |= HAL_SMARTCARD_ERROR_ORE;
856
  }
857
 
858
  tmp_flag = __HAL_SMARTCARD_GET_FLAG(hsc, SMARTCARD_FLAG_RXNE);
859
  tmp_it_source = __HAL_SMARTCARD_GET_IT_SOURCE(hsc, SMARTCARD_IT_RXNE);
860
  /* SMARTCARD in mode Receiver --------------------------------------------------*/
861
  if((tmp_flag != RESET) && (tmp_it_source != RESET))
862
  {
863
    SMARTCARD_Receive_IT(hsc);
864
  }
865
 
866
  tmp_flag = __HAL_SMARTCARD_GET_FLAG(hsc, SMARTCARD_FLAG_TXE);
867
  tmp_it_source = __HAL_SMARTCARD_GET_IT_SOURCE(hsc, SMARTCARD_IT_TXE);
868
  /* SMARTCARD in mode Transmitter -----------------------------------------------*/
869
  if((tmp_flag != RESET) && (tmp_it_source != RESET))
870
  {
871
    SMARTCARD_Transmit_IT(hsc);
872
  }
873
 
874
  tmp_flag = __HAL_SMARTCARD_GET_FLAG(hsc, SMARTCARD_FLAG_TC);
875
  tmp_it_source = __HAL_SMARTCARD_GET_IT_SOURCE(hsc, SMARTCARD_IT_TC);
876
  /* SMARTCARD in mode Transmitter (transmission end) ------------------------*/
877
  if((tmp_flag != RESET) && (tmp_it_source != RESET))
878
  {
879
    SMARTCARD_EndTransmit_IT(hsc);
880
  }
881
 
882
  /* Call the Error call Back in case of Errors */
883
  if(hsc->ErrorCode != HAL_SMARTCARD_ERROR_NONE)
884
  {
885
    /* Set the SMARTCARD state ready to be able to start again the process */
886
    hsc->State= HAL_SMARTCARD_STATE_READY;
887
    HAL_SMARTCARD_ErrorCallback(hsc);
888
  }
889
}
890
 
891
/**
892
  * @brief  Tx Transfer completed callback.
893
  * @param  hsc: Pointer to a SMARTCARD_HandleTypeDef structure that contains
894
  *                the configuration information for the specified SMARTCARD module.
895
  * @retval None
896
  */
897
 __weak void HAL_SMARTCARD_TxCpltCallback(SMARTCARD_HandleTypeDef *hsc)
898
{
899
  /* NOTE: This function should not be modified, when the callback is needed,
900
           the HAL_SMARTCARD_TxCpltCallback can be implemented in the user file
901
   */
902
}
903
 
904
/**
905
  * @brief  Rx Transfer completed callback.
906
  * @param  hsc: Pointer to a SMARTCARD_HandleTypeDef structure that contains
907
  *                the configuration information for the specified SMARTCARD module.
908
  * @retval None
909
  */
910
__weak void HAL_SMARTCARD_RxCpltCallback(SMARTCARD_HandleTypeDef *hsc)
911
{
912
  /* NOTE: This function should not be modified, when the callback is needed,
913
           the HAL_SMARTCARD_RxCpltCallback can be implemented in the user file
914
   */
915
}
916
 
917
/**
918
  * @brief  SMARTCARD error callback.
919
  * @param  hsc: Pointer to a SMARTCARD_HandleTypeDef structure that contains
920
  *                the configuration information for the specified SMARTCARD module.
921
  * @retval None
922
  */
923
 __weak void HAL_SMARTCARD_ErrorCallback(SMARTCARD_HandleTypeDef *hsc)
924
{
925
  /* NOTE: This function should not be modified, when the callback is needed,
926
           the HAL_SMARTCARD_ErrorCallback can be implemented in the user file
927
   */
928
}
929
 
930
/**
931
  * @}
932
  */
933
 
934
/** @defgroup SMARTCARD_Exported_Functions_Group3 Peripheral State and Errors functions
935
  *  @brief   SMARTCARD State and Errors functions
936
  *
937
@verbatim  
938
  ==============================================================================
939
                  ##### Peripheral State and Errors functions #####
940
  ==============================================================================  
941
  [..]
942
    This subsection provides a set of functions allowing to return the State of SmartCard
943
    communication process and also return Peripheral Errors occurred during communication process
944
     (+) HAL_SMARTCARD_GetState() API can be helpful to check in run-time the state
945
         of the SMARTCARD peripheral.
946
     (+) HAL_SMARTCARD_GetError() check in run-time errors that could be occurred during
947
         communication.
948
 
949
@endverbatim
950
  * @{
951
  */
952
 
953
/**
954
  * @brief  Returns the SMARTCARD state.
955
  * @param  hsc: Pointer to a SMARTCARD_HandleTypeDef structure that contains
956
  *                the configuration information for the specified SMARTCARD module.
957
  * @retval HAL state
958
  */
959
HAL_SMARTCARD_StateTypeDef HAL_SMARTCARD_GetState(SMARTCARD_HandleTypeDef *hsc)
960
{
961
  return hsc->State;
962
}
963
 
964
/**
965
  * @brief  Return the SMARTCARD error code
966
  * @param  hsc: Pointer to a SMARTCARD_HandleTypeDef structure that contains
967
  *                the configuration information for the specified SMARTCARD module.
968
  * @retval SMARTCARD Error Code
969
  */
970
uint32_t HAL_SMARTCARD_GetError(SMARTCARD_HandleTypeDef *hsc)
971
{
972
  return hsc->ErrorCode;
973
}
974
 
975
/**
976
  * @}
977
  */
978
 
979
/**
980
  * @}
981
  */
982
 
983
/** @defgroup SMARTCARD_Private_Functions   SMARTCARD Private Functions
984
  *  @brief   SMARTCARD Private functions
985
  * @{
986
  */
987
/**
988
  * @brief  DMA SMARTCARD transmit process complete callback.
989
  * @param  hdma: Pointer to a DMA_HandleTypeDef structure that contains
990
  *               the configuration information for the specified DMA module.
991
  * @retval None
992
  */
993
static void SMARTCARD_DMATransmitCplt(DMA_HandleTypeDef *hdma)
994
{
995
  SMARTCARD_HandleTypeDef* hsc = ( SMARTCARD_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
996
 
997
  hsc->TxXferCount = 0;
998
 
999
  /* Disable the DMA transfer for transmit request by setting the DMAT bit
1000
     in the SMARTCARD CR3 register */
1001
  CLEAR_BIT(hsc->Instance->CR3, USART_CR3_DMAT);
1002
 
1003
  /* Enable the SMARTCARD Transmit Complete Interrupt */    
1004
  __HAL_SMARTCARD_ENABLE_IT(hsc, SMARTCARD_IT_TC);
1005
}
1006
 
1007
/**
1008
  * @brief  DMA SMARTCARD receive process complete callback.
1009
  * @param  hdma: Pointer to a DMA_HandleTypeDef structure that contains
1010
  *               the configuration information for the specified DMA module.
1011
  * @retval None
1012
  */
1013
static void SMARTCARD_DMAReceiveCplt(DMA_HandleTypeDef *hdma)  
1014
{
1015
  SMARTCARD_HandleTypeDef* hsc = ( SMARTCARD_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1016
 
1017
  hsc->RxXferCount = 0;
1018
 
1019
  /* Disable the DMA transfer for the receiver request by setting the DMAR bit
1020
     in the USART CR3 register */
1021
  CLEAR_BIT(hsc->Instance->CR3, USART_CR3_DMAR);
1022
 
1023
  /* Check if a non-blocking transmit process is ongoing or not */
1024
  if(hsc->State == HAL_SMARTCARD_STATE_BUSY_TX_RX)
1025
  {
1026
    hsc->State = HAL_SMARTCARD_STATE_BUSY_TX;
1027
  }
1028
  else
1029
  {
1030
    hsc->State = HAL_SMARTCARD_STATE_READY;
1031
  }
1032
 
1033
  HAL_SMARTCARD_RxCpltCallback(hsc);
1034
}
1035
 
1036
/**
1037
  * @brief  DMA SMARTCARD communication error callback.
1038
  * @param  hdma: Pointer to a DMA_HandleTypeDef structure that contains
1039
  *               the configuration information for the specified DMA module.
1040
  * @retval None
1041
  */
1042
static void SMARTCARD_DMAError(DMA_HandleTypeDef *hdma)  
1043
{
1044
  SMARTCARD_HandleTypeDef* hsc = ( SMARTCARD_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1045
 
1046
  hsc->RxXferCount = 0;
1047
  hsc->TxXferCount = 0;
1048
  hsc->ErrorCode = HAL_SMARTCARD_ERROR_DMA;
1049
  hsc->State= HAL_SMARTCARD_STATE_READY;
1050
 
1051
  HAL_SMARTCARD_ErrorCallback(hsc);
1052
}
1053
 
1054
/**
1055
  * @brief  This function handles SMARTCARD Communication Timeout.
1056
  * @param  hsc: Pointer to a SMARTCARD_HandleTypeDef structure that contains
1057
  *                the configuration information for the specified SMARTCARD module.
1058
  * @param  Flag: specifies the SMARTCARD flag to check.
1059
  * @param  Status: The new Flag status (SET or RESET).
1060
  * @param  Timeout: Timeout duration
1061
  * @retval HAL status
1062
  */
1063
static HAL_StatusTypeDef SMARTCARD_WaitOnFlagUntilTimeout(SMARTCARD_HandleTypeDef *hsc, uint32_t Flag, FlagStatus Status, uint32_t Timeout)
1064
{
1065
  uint32_t tickstart = 0;
1066
 
1067
  /* Get tick */
1068
  tickstart = HAL_GetTick();
1069
 
1070
  /* Wait until flag is set */
1071
  if(Status == RESET)
1072
  {
1073
    while(__HAL_SMARTCARD_GET_FLAG(hsc, Flag) == RESET)
1074
    {
1075
      /* Check for the Timeout */
1076
      if(Timeout != HAL_MAX_DELAY)
1077
      {
1078
        if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
1079
        {
1080
          /* Disable TXE and RXNE interrupts for the interrupt process */
1081
          __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_TXE);
1082
          __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_RXNE);
1083
 
1084
          hsc->State= HAL_SMARTCARD_STATE_READY;
1085
 
1086
          /* Process Unlocked */
1087
          __HAL_UNLOCK(hsc);
1088
 
1089
          return HAL_TIMEOUT;
1090
        }
1091
      }
1092
    }
1093
  }
1094
  else
1095
  {
1096
    while(__HAL_SMARTCARD_GET_FLAG(hsc, Flag) != RESET)
1097
    {
1098
      /* Check for the Timeout */
1099
      if(Timeout != HAL_MAX_DELAY)
1100
      {
1101
        if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
1102
        {
1103
          /* Disable TXE and RXNE interrupts for the interrupt process */
1104
          __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_TXE);
1105
          __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_RXNE);
1106
 
1107
          hsc->State= HAL_SMARTCARD_STATE_READY;
1108
 
1109
          /* Process Unlocked */
1110
          __HAL_UNLOCK(hsc);
1111
 
1112
          return HAL_TIMEOUT;
1113
        }
1114
      }
1115
    }
1116
  }
1117
  return HAL_OK;
1118
}
1119
 
1120
/**
1121
  * @brief  Send an amount of data in non-blocking mode.
1122
  * @param  hsc: Pointer to a SMARTCARD_HandleTypeDef structure that contains
1123
  *                the configuration information for the specified SMARTCARD module.
1124
  *         Function called under interruption only, once
1125
  *         interruptions have been enabled by HAL_SMARTCARD_Transmit_IT()      
1126
  * @retval HAL status
1127
  */
1128
static HAL_StatusTypeDef SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef *hsc)
1129
{
1130
  uint32_t tmp_state = 0;
1131
 
1132
  tmp_state = hsc->State;
1133
  if((tmp_state == HAL_SMARTCARD_STATE_BUSY_TX) || (tmp_state == HAL_SMARTCARD_STATE_BUSY_TX_RX))
1134
  {
1135
    WRITE_REG(hsc->Instance->DR, (*hsc->pTxBuffPtr++ & (uint8_t)0xFF));
1136
 
1137
    if(--hsc->TxXferCount == 0)
1138
    {
1139
      /* Disable the SMARTCARD Transmit Data Register Empty Interrupt */
1140
      __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_TXE);
1141
 
1142
      /* Enable the SMARTCARD Transmit Complete Interrupt */    
1143
      __HAL_SMARTCARD_ENABLE_IT(hsc, SMARTCARD_IT_TC);
1144
    }
1145
 
1146
    return HAL_OK;
1147
  }
1148
  else
1149
  {
1150
    return HAL_BUSY;
1151
  }
1152
}
1153
 
1154
 
1155
/**
1156
  * @brief  Wraps up transmission in non blocking mode.
1157
  * @param  hsmartcard: pointer to a SMARTCARD_HandleTypeDef structure that contains
1158
  *                the configuration information for the specified SMARTCARD module.
1159
  * @retval HAL status
1160
  */
1161
static HAL_StatusTypeDef SMARTCARD_EndTransmit_IT(SMARTCARD_HandleTypeDef *hsmartcard)
1162
{
1163
  /* Disable the SMARTCARD Transmit Complete Interrupt */    
1164
  __HAL_SMARTCARD_DISABLE_IT(hsmartcard, SMARTCARD_IT_TC);
1165
 
1166
  /* Check if a receive process is ongoing or not */
1167
  if(hsmartcard->State == HAL_SMARTCARD_STATE_BUSY_TX_RX)
1168
  {
1169
    hsmartcard->State = HAL_SMARTCARD_STATE_BUSY_RX;
1170
  }
1171
  else
1172
  {
1173
    /* Disable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */
1174
    __HAL_SMARTCARD_DISABLE_IT(hsmartcard, SMARTCARD_IT_ERR);
1175
 
1176
    hsmartcard->State = HAL_SMARTCARD_STATE_READY;
1177
  }
1178
 
1179
  HAL_SMARTCARD_TxCpltCallback(hsmartcard);
1180
 
1181
  return HAL_OK;
1182
}
1183
 
1184
 
1185
/**
1186
  * @brief  Receive an amount of data in non-blocking mode.
1187
  * @param  hsc: Pointer to a SMARTCARD_HandleTypeDef structure that contains
1188
  *                the configuration information for the specified SMARTCARD module.
1189
  * @retval HAL status
1190
  */
1191
static HAL_StatusTypeDef SMARTCARD_Receive_IT(SMARTCARD_HandleTypeDef *hsc)
1192
{
1193
  uint32_t tmp_state = 0;
1194
 
1195
  tmp_state = hsc->State;
1196
  if((tmp_state == HAL_SMARTCARD_STATE_BUSY_RX) || (tmp_state == HAL_SMARTCARD_STATE_BUSY_TX_RX))
1197
  {
1198
    *hsc->pRxBuffPtr++ = (uint8_t)(hsc->Instance->DR & (uint8_t)0xFF);
1199
 
1200
    if(--hsc->RxXferCount == 0)
1201
    {
1202
      __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_RXNE);
1203
 
1204
      /* Disable the SMARTCARD Parity Error Interrupt */
1205
      __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_PE);
1206
 
1207
      /* Disable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */
1208
      __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_ERR);
1209
 
1210
      /* Check if a non-blocking transmit process is ongoing or not */
1211
      if(hsc->State == HAL_SMARTCARD_STATE_BUSY_TX_RX)
1212
      {
1213
        hsc->State = HAL_SMARTCARD_STATE_BUSY_TX;
1214
      }
1215
      else
1216
      {
1217
        hsc->State = HAL_SMARTCARD_STATE_READY;
1218
      }
1219
 
1220
      HAL_SMARTCARD_RxCpltCallback(hsc);
1221
 
1222
      return HAL_OK;
1223
    }
1224
    return HAL_OK;
1225
  }
1226
  else
1227
  {
1228
    return HAL_BUSY;
1229
  }
1230
}
1231
 
1232
/**
1233
  * @brief  Configures the SMARTCARD peripheral.
1234
  * @param  hsc: Pointer to a SMARTCARD_HandleTypeDef structure that contains
1235
  *                the configuration information for the specified SMARTCARD module.
1236
  * @retval None
1237
  */
1238
static void SMARTCARD_SetConfig(SMARTCARD_HandleTypeDef *hsc)
1239
{
1240
  /* Check the parameters */
1241
  assert_param(IS_SMARTCARD_POLARITY(hsc->Init.CLKPolarity));
1242
  assert_param(IS_SMARTCARD_PHASE(hsc->Init.CLKPhase));
1243
  assert_param(IS_SMARTCARD_LASTBIT(hsc->Init.CLKLastBit));
1244
  assert_param(IS_SMARTCARD_BAUDRATE(hsc->Init.BaudRate));  
1245
  assert_param(IS_SMARTCARD_WORD_LENGTH(hsc->Init.WordLength));
1246
  assert_param(IS_SMARTCARD_STOPBITS(hsc->Init.StopBits));
1247
  assert_param(IS_SMARTCARD_PARITY(hsc->Init.Parity));
1248
  assert_param(IS_SMARTCARD_MODE(hsc->Init.Mode));
1249
  assert_param(IS_SMARTCARD_NACK_STATE(hsc->Init.NACKState));
1250
 
1251
  /* The LBCL, CPOL and CPHA bits have to be selected when both the transmitter and the
1252
     receiver are disabled (TE=RE=0) to ensure that the clock pulses function correctly. */
1253
  CLEAR_BIT(hsc->Instance->CR1, (uint32_t)(USART_CR1_TE | USART_CR1_RE));
1254
 
1255
  /*------ SMARTCARD-associated USART registers setting : CR2 Configuration ------*/
1256
  /* Clear CLKEN, CPOL, CPHA and LBCL bits */
1257
  /* Configure the SMARTCARD Clock, CPOL, CPHA and LastBit -----------------------*/
1258
  /* Set CPOL bit according to hsc->Init.CLKPolarity value */
1259
  /* Set CPHA bit according to hsc->Init.CLKPhase value */
1260
  /* Set LBCL bit according to hsc->Init.CLKLastBit value */
1261
  MODIFY_REG(hsc->Instance->CR2,
1262
             ((uint32_t)(USART_CR2_CPHA | USART_CR2_CPOL | USART_CR2_CLKEN | USART_CR2_LBCL)),
1263
             ((uint32_t)(USART_CR2_CLKEN | hsc->Init.CLKPolarity | hsc->Init.CLKPhase| hsc->Init.CLKLastBit)) );
1264
 
1265
  /* Set Stop Bits: Set STOP[13:12] bits according to hsc->Init.StopBits value */
1266
  MODIFY_REG(hsc->Instance->CR2, USART_CR2_STOP,(uint32_t)(hsc->Init.StopBits));
1267
 
1268
  /*------ SMARTCARD-associated USART registers setting : CR1 Configuration ------*/
1269
  /* Clear M, PCE, PS, TE and RE bits */
1270
  /* Configure the SMARTCARD Word Length, Parity and mode:
1271
     Set the M according to hsc->Init.WordLength value (forced to 1 as 9B data frame should be selected)
1272
     Set PCE and PS bits according to hsc->Init.Parity value (PCE bit forced to 1 as parity control should always be enabled)
1273
     Set TE and RE bits according to hsc->Init.Mode value */
1274
  MODIFY_REG(hsc->Instance->CR1,
1275
             ((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE)),
1276
             ((uint32_t)(USART_CR1_M | USART_CR1_PCE | hsc->Init.Parity | hsc->Init.Mode)) );
1277
 
1278
  /*------ SMARTCARD-associated USART registers setting : CR3 Configuration ------*/
1279
  /* Clear CTSE and RTSE bits */
1280
  CLEAR_BIT(hsc->Instance->CR3, (USART_CR3_RTSE | USART_CR3_CTSE));
1281
 
1282
  /*------ SMARTCARD-associated USART registers setting : BRR Configuration ------*/
1283
  if(hsc->Instance == USART1)
1284
  {
1285
    hsc->Instance->BRR = SMARTCARD_BRR(HAL_RCC_GetPCLK2Freq(), hsc->Init.BaudRate);
1286
  }
1287
  else
1288
  {
1289
    hsc->Instance->BRR = SMARTCARD_BRR(HAL_RCC_GetPCLK1Freq(), hsc->Init.BaudRate);
1290
  }
1291
}
1292
 
1293
/**
1294
  * @}
1295
  */
1296
 
1297
#endif /* HAL_SMARTCARD_MODULE_ENABLED */
1298
/**
1299
  * @}
1300
  */
1301
 
1302
/**
1303
  * @}
1304
  */
1305
 
1306
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/