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