1 /**
2   ******************************************************************************
3   * @file    stm32f4xx_hal_smartcard.c
4   * @author  MCD Application Team
5   * @brief   SMARTCARD HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the SMARTCARD peripheral:
8   *           + Initialization and de-initialization functions
9   *           + IO operation functions
10   *           + Peripheral Control functions
11   *           + Peripheral State and Error functions
12   *
13   ******************************************************************************
14   * @attention
15   *
16   * Copyright (c) 2016 STMicroelectronics.
17   * All rights reserved.
18   *
19   * This software is licensed under terms that can be found in the LICENSE file
20   * in the root directory of this software component.
21   * If no LICENSE file comes with this software, it is provided AS-IS.
22   *
23   ******************************************************************************
24   @verbatim
25   ==============================================================================
26                      ##### How to use this driver #####
27   ==============================================================================
28     [..]
29       The SMARTCARD HAL driver can be used as follows:
30 
31     (#) Declare a SMARTCARD_HandleTypeDef handle structure.
32     (#) Initialize the SMARTCARD low level resources by implementing the HAL_SMARTCARD_MspInit() API:
33         (##) Enable the interface clock of the USARTx associated to the SMARTCARD.
34         (##) SMARTCARD pins configuration:
35             (+++) Enable the clock for the SMARTCARD GPIOs.
36             (+++) Configure SMARTCARD pins as alternate function pull-up.
37         (##) NVIC configuration if you need to use interrupt process (HAL_SMARTCARD_Transmit_IT()
38              and HAL_SMARTCARD_Receive_IT() APIs):
39             (+++) Configure the USARTx interrupt priority.
40             (+++) Enable the NVIC USART IRQ handle.
41         (##) DMA Configuration if you need to use DMA process (HAL_SMARTCARD_Transmit_DMA()
42              and HAL_SMARTCARD_Receive_DMA() APIs):
43             (+++) Declare a DMA handle structure for the Tx/Rx stream.
44             (+++) Enable the DMAx interface clock.
45             (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.
46             (+++) Configure the DMA Tx/Rx stream.
47             (+++) Associate the initialized DMA handle to the SMARTCARD DMA Tx/Rx handle.
48             (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx stream.
49             (+++) Configure the USARTx interrupt priority and enable the NVIC USART IRQ handle
50                   (used for last byte sending completion detection in DMA non circular mode)
51 
52     (#) Program the Baud Rate, Word Length , Stop Bit, Parity, Hardware
53         flow control and Mode(Receiver/Transmitter) in the SMARTCARD Init structure.
54 
55     (#) Initialize the SMARTCARD registers by calling the HAL_SMARTCARD_Init() API:
56         (++) These APIs configure also the low level Hardware GPIO, CLOCK, CORTEX...etc)
57              by calling the customized HAL_SMARTCARD_MspInit() API.
58     [..]
59     (@) The specific SMARTCARD interrupts (Transmission complete interrupt,
60         RXNE interrupt and Error Interrupts) will be managed using the macros
61         __HAL_SMARTCARD_ENABLE_IT() and __HAL_SMARTCARD_DISABLE_IT() inside the transmit and receive process.
62 
63     [..]
64     Three operation modes are available within this driver :
65 
66     *** Polling mode IO operation ***
67     =================================
68     [..]
69       (+) Send an amount of data in blocking mode using HAL_SMARTCARD_Transmit()
70       (+) Receive an amount of data in blocking mode using HAL_SMARTCARD_Receive()
71 
72     *** Interrupt mode IO operation ***
73     ===================================
74     [..]
75       (+) Send an amount of data in non blocking mode using HAL_SMARTCARD_Transmit_IT()
76       (+) At transmission end of transfer HAL_SMARTCARD_TxCpltCallback is executed and user can
77           add his own code by customization of function pointer HAL_SMARTCARD_TxCpltCallback
78       (+) Receive an amount of data in non blocking mode using HAL_SMARTCARD_Receive_IT()
79       (+) At reception end of transfer HAL_SMARTCARD_RxCpltCallback is executed and user can
80           add his own code by customization of function pointer HAL_SMARTCARD_RxCpltCallback
81       (+) In case of transfer Error, HAL_SMARTCARD_ErrorCallback() function is executed and user can
82           add his own code by customization of function pointer HAL_SMARTCARD_ErrorCallback
83 
84     *** DMA mode IO operation ***
85     ==============================
86     [..]
87       (+) Send an amount of data in non blocking mode (DMA) using HAL_SMARTCARD_Transmit_DMA()
88       (+) At transmission end of transfer HAL_SMARTCARD_TxCpltCallback is executed and user can
89           add his own code by customization of function pointer HAL_SMARTCARD_TxCpltCallback
90       (+) Receive an amount of data in non blocking mode (DMA) using HAL_SMARTCARD_Receive_DMA()
91       (+) At reception end of transfer HAL_SMARTCARD_RxCpltCallback is executed and user can
92           add his own code by customization of function pointer HAL_SMARTCARD_RxCpltCallback
93       (+) In case of transfer Error, HAL_SMARTCARD_ErrorCallback() function is executed and user can
94           add his own code by customization of function pointer HAL_SMARTCARD_ErrorCallback
95 
96     *** SMARTCARD HAL driver macros list ***
97     ========================================
98     [..]
99       Below the list of most used macros in SMARTCARD HAL driver.
100 
101       (+) __HAL_SMARTCARD_ENABLE: Enable the SMARTCARD peripheral
102       (+) __HAL_SMARTCARD_DISABLE: Disable the SMARTCARD peripheral
103       (+) __HAL_SMARTCARD_GET_FLAG : Check whether the specified SMARTCARD flag is set or not
104       (+) __HAL_SMARTCARD_CLEAR_FLAG : Clear the specified SMARTCARD pending flag
105       (+) __HAL_SMARTCARD_ENABLE_IT: Enable the specified SMARTCARD interrupt
106       (+) __HAL_SMARTCARD_DISABLE_IT: Disable the specified SMARTCARD interrupt
107 
108     [..]
109       (@) You can refer to the SMARTCARD HAL driver header file for more useful macros
110 
111     ##### Callback registration #####
112     ==================================
113 
114     [..]
115     The compilation define USE_HAL_SMARTCARD_REGISTER_CALLBACKS when set to 1
116     allows the user to configure dynamically the driver callbacks.
117 
118     [..]
119     Use Function HAL_SMARTCARD_RegisterCallback() to register a user callback.
120     Function HAL_SMARTCARD_RegisterCallback() allows to register following callbacks:
121     (+) TxCpltCallback            : Tx Complete Callback.
122     (+) RxCpltCallback            : Rx Complete Callback.
123     (+) ErrorCallback             : Error Callback.
124     (+) AbortCpltCallback         : Abort Complete Callback.
125     (+) AbortTransmitCpltCallback : Abort Transmit Complete Callback.
126     (+) AbortReceiveCpltCallback  : Abort Receive Complete Callback.
127     (+) MspInitCallback           : SMARTCARD MspInit.
128     (+) MspDeInitCallback         : SMARTCARD MspDeInit.
129     This function takes as parameters the HAL peripheral handle, the Callback ID
130     and a pointer to the user callback function.
131 
132     [..]
133     Use function HAL_SMARTCARD_UnRegisterCallback() to reset a callback to the default
134     weak (surcharged) function.
135     HAL_SMARTCARD_UnRegisterCallback() takes as parameters the HAL peripheral handle,
136     and the Callback ID.
137     This function allows to reset following callbacks:
138     (+) TxCpltCallback            : Tx Complete Callback.
139     (+) RxCpltCallback            : Rx Complete Callback.
140     (+) ErrorCallback             : Error Callback.
141     (+) AbortCpltCallback         : Abort Complete Callback.
142     (+) AbortTransmitCpltCallback : Abort Transmit Complete Callback.
143     (+) AbortReceiveCpltCallback  : Abort Receive Complete Callback.
144     (+) MspInitCallback           : SMARTCARD MspInit.
145     (+) MspDeInitCallback         : SMARTCARD MspDeInit.
146 
147     [..]
148     By default, after the HAL_SMARTCARD_Init() and when the state is HAL_SMARTCARD_STATE_RESET
149     all callbacks are set to the corresponding weak (surcharged) functions:
150     examples HAL_SMARTCARD_TxCpltCallback(), HAL_SMARTCARD_RxCpltCallback().
151     Exception done for MspInit and MspDeInit functions that are respectively
152     reset to the legacy weak (surcharged) functions in the HAL_SMARTCARD_Init()
153     and HAL_SMARTCARD_DeInit() only when these callbacks are null (not registered beforehand).
154     If not, MspInit or MspDeInit are not null, the HAL_SMARTCARD_Init() and HAL_SMARTCARD_DeInit()
155     keep and use the user MspInit/MspDeInit callbacks (registered beforehand).
156 
157     [..]
158     Callbacks can be registered/unregistered in HAL_SMARTCARD_STATE_READY state only.
159     Exception done MspInit/MspDeInit that can be registered/unregistered
160     in HAL_SMARTCARD_STATE_READY or HAL_SMARTCARD_STATE_RESET state, thus registered (user)
161     MspInit/DeInit callbacks can be used during the Init/DeInit.
162     In that case first register the MspInit/MspDeInit user callbacks
163     using HAL_SMARTCARD_RegisterCallback() before calling HAL_SMARTCARD_DeInit()
164     or HAL_SMARTCARD_Init() function.
165 
166     [..]
167     When The compilation define USE_HAL_SMARTCARD_REGISTER_CALLBACKS is set to 0 or
168     not defined, the callback registration feature is not available
169     and weak (surcharged) callbacks are used.
170 
171   @endverbatim
172   ******************************************************************************
173   */
174 
175 /* Includes ------------------------------------------------------------------*/
176 #include "stm32f4xx_hal.h"
177 
178 /** @addtogroup STM32F4xx_HAL_Driver
179   * @{
180   */
181 
182 /** @defgroup SMARTCARD SMARTCARD
183   * @brief HAL SMARTCARD module driver
184   * @{
185   */
186 #ifdef HAL_SMARTCARD_MODULE_ENABLED
187 /* Private typedef -----------------------------------------------------------*/
188 /* Private define ------------------------------------------------------------*/
189 /** @addtogroup SMARTCARD_Private_Constants
190   * @{
191   */
192 /**
193   * @}
194   */
195 
196 /* Private macro -------------------------------------------------------------*/
197 /* Private variables ---------------------------------------------------------*/
198 /* Private function prototypes -----------------------------------------------*/
199 /** @addtogroup SMARTCARD_Private_Functions
200   * @{
201   */
202 #if (USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1)
203 void SMARTCARD_InitCallbacksToDefault(SMARTCARD_HandleTypeDef *hsc);
204 #endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACKS */
205 static void SMARTCARD_EndTxTransfer(SMARTCARD_HandleTypeDef *hsc);
206 static void SMARTCARD_EndRxTransfer(SMARTCARD_HandleTypeDef *hsc);
207 static void SMARTCARD_SetConfig (SMARTCARD_HandleTypeDef *hsc);
208 static HAL_StatusTypeDef SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef *hsc);
209 static HAL_StatusTypeDef SMARTCARD_EndTransmit_IT(SMARTCARD_HandleTypeDef *hsc);
210 static HAL_StatusTypeDef SMARTCARD_Receive_IT(SMARTCARD_HandleTypeDef *hsc);
211 static void SMARTCARD_DMATransmitCplt(DMA_HandleTypeDef *hdma);
212 static void SMARTCARD_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
213 static void SMARTCARD_DMAError(DMA_HandleTypeDef *hdma);
214 static void SMARTCARD_DMAAbortOnError(DMA_HandleTypeDef *hdma);
215 static void SMARTCARD_DMATxAbortCallback(DMA_HandleTypeDef *hdma);
216 static void SMARTCARD_DMARxAbortCallback(DMA_HandleTypeDef *hdma);
217 static void SMARTCARD_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma);
218 static void SMARTCARD_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma);
219 static HAL_StatusTypeDef SMARTCARD_WaitOnFlagUntilTimeout(SMARTCARD_HandleTypeDef *hsc, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout);
220 /**
221   * @}
222   */
223 
224 /* Exported functions --------------------------------------------------------*/
225 /** @defgroup SMARTCARD_Exported_Functions SMARTCARD Exported Functions
226   * @{
227   */
228 
229 /** @defgroup SMARTCARD_Exported_Functions_Group1 SmartCard Initialization and de-initialization functions
230   *  @brief    Initialization and Configuration functions
231   *
232 @verbatim
233   ==============================================================================
234               ##### Initialization and Configuration functions #####
235   ==============================================================================
236   [..]
237   This subsection provides a set of functions allowing to initialize the USART
238   in Smartcard mode.
239   [..]
240   The Smartcard interface is designed to support asynchronous protocol Smartcards as
241   defined in the ISO 7816-3 standard.
242   [..]
243   The USART can provide a clock to the smartcard through the SCLK output.
244   In smartcard mode, SCLK is not associated to the communication but is simply derived
245   from the internal peripheral input clock through a 5-bit prescaler.
246   [..]
247   (+) For the Smartcard mode only these parameters can be configured:
248       (++) Baud Rate
249       (++) Word Length => Should be 9 bits (8 bits + parity)
250       (++) Stop Bit
251       (++) Parity: => Should be enabled
252       (++) USART polarity
253       (++) USART phase
254       (++) USART LastBit
255       (++) Receiver/transmitter modes
256       (++) Prescaler
257       (++) GuardTime
258       (++) NACKState: The Smartcard NACK state
259 
260      (+) Recommended SmartCard interface configuration to get the Answer to Reset from the Card:
261         (++) Word Length = 9 Bits
262         (++) 1.5 Stop Bit
263         (++) Even parity
264         (++) BaudRate = 12096 baud
265         (++) Tx and Rx enabled
266   [..]
267   Please refer to the ISO 7816-3 specification for more details.
268 
269   [..]
270    (@) It is also possible to choose 0.5 stop bit for receiving but it is recommended
271        to use 1.5 stop bits for both transmitting and receiving to avoid switching
272        between the two configurations.
273   [..]
274     The HAL_SMARTCARD_Init() function follows the USART  SmartCard configuration
275     procedures (details for the procedures are available in reference manual
276     (RM0430 for STM32F4X3xx MCUs and RM0402 for STM32F412xx MCUs
277      RM0383 for STM32F411xC/E MCUs and RM0401 for STM32F410xx MCUs
278      RM0090 for STM32F4X5xx/STM32F4X7xx/STM32F429xx/STM32F439xx MCUs
279      RM0390 for STM32F446xx MCUs and RM0386 for STM32F469xx/STM32F479xx MCUs)).
280 
281 @endverbatim
282 
283   The SMARTCARD frame format is given in the following table:
284        +-------------------------------------------------------------+
285        |   M bit |  PCE bit  |        SMARTCARD frame                |
286        |---------------------|---------------------------------------|
287        |    1    |    1      |    | SB | 8 bit data | PB | STB |     |
288        +-------------------------------------------------------------+
289   * @{
290   */
291 
292 /**
293   * @brief  Initializes the SmartCard mode according to the specified
294   *         parameters in the SMARTCARD_InitTypeDef and create the associated handle.
295   * @param  hsc    Pointer to a SMARTCARD_HandleTypeDef structure that contains
296   *                the configuration information for SMARTCARD module.
297   * @retval HAL status
298   */
HAL_SMARTCARD_Init(SMARTCARD_HandleTypeDef * hsc)299 HAL_StatusTypeDef HAL_SMARTCARD_Init(SMARTCARD_HandleTypeDef *hsc)
300 {
301   /* Check the SMARTCARD handle allocation */
302   if(hsc == NULL)
303   {
304     return HAL_ERROR;
305   }
306 
307   /* Check the parameters */
308   assert_param(IS_SMARTCARD_INSTANCE(hsc->Instance));
309   assert_param(IS_SMARTCARD_NACK_STATE(hsc->Init.NACKState));
310 
311   if(hsc->gState == HAL_SMARTCARD_STATE_RESET)
312   {
313     /* Allocate lock resource and initialize it */
314     hsc->Lock = HAL_UNLOCKED;
315 
316 #if USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1
317     SMARTCARD_InitCallbacksToDefault(hsc);
318 
319     if (hsc->MspInitCallback == NULL)
320     {
321       hsc->MspInitCallback = HAL_SMARTCARD_MspInit;
322     }
323 
324     /* Init the low level hardware */
325     hsc->MspInitCallback(hsc);
326 #else
327     /* Init the low level hardware : GPIO, CLOCK */
328     HAL_SMARTCARD_MspInit(hsc);
329 #endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACKS */
330   }
331 
332   hsc->gState = HAL_SMARTCARD_STATE_BUSY;
333 
334   /* Set the Prescaler */
335   MODIFY_REG(hsc->Instance->GTPR, USART_GTPR_PSC, hsc->Init.Prescaler);
336 
337   /* Set the Guard Time */
338   MODIFY_REG(hsc->Instance->GTPR, USART_GTPR_GT, ((hsc->Init.GuardTime)<<8U));
339 
340   /* Set the Smartcard Communication parameters */
341   SMARTCARD_SetConfig(hsc);
342 
343   /* In SmartCard mode, the following bits must be kept cleared:
344   - LINEN bit in the USART_CR2 register
345   - HDSEL and IREN bits in the USART_CR3 register.*/
346   CLEAR_BIT(hsc->Instance->CR2, USART_CR2_LINEN);
347   CLEAR_BIT(hsc->Instance->CR3, (USART_CR3_IREN | USART_CR3_HDSEL));
348 
349   /* Enable the SMARTCARD Parity Error Interrupt */
350   SET_BIT(hsc->Instance->CR1, USART_CR1_PEIE);
351 
352   /* Enable the SMARTCARD Framing Error Interrupt */
353   SET_BIT(hsc->Instance->CR3, USART_CR3_EIE);
354 
355   /* Enable the Peripheral */
356   __HAL_SMARTCARD_ENABLE(hsc);
357 
358   /* Configure the Smartcard NACK state */
359   MODIFY_REG(hsc->Instance->CR3, USART_CR3_NACK, hsc->Init.NACKState);
360 
361   /* Enable the SC mode by setting the SCEN bit in the CR3 register */
362   hsc->Instance->CR3 |= (USART_CR3_SCEN);
363 
364   /* Initialize the SMARTCARD state*/
365   hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
366   hsc->gState= HAL_SMARTCARD_STATE_READY;
367   hsc->RxState= HAL_SMARTCARD_STATE_READY;
368 
369   return HAL_OK;
370 }
371 
372 /**
373   * @brief DeInitializes the USART SmartCard peripheral
374   * @param  hsc    Pointer to a SMARTCARD_HandleTypeDef structure that contains
375   *                the configuration information for SMARTCARD module.
376   * @retval HAL status
377   */
HAL_SMARTCARD_DeInit(SMARTCARD_HandleTypeDef * hsc)378 HAL_StatusTypeDef HAL_SMARTCARD_DeInit(SMARTCARD_HandleTypeDef *hsc)
379 {
380   /* Check the SMARTCARD handle allocation */
381   if(hsc == NULL)
382   {
383     return HAL_ERROR;
384   }
385 
386   /* Check the parameters */
387   assert_param(IS_SMARTCARD_INSTANCE(hsc->Instance));
388 
389   hsc->gState = HAL_SMARTCARD_STATE_BUSY;
390 
391   /* Disable the Peripheral */
392   __HAL_SMARTCARD_DISABLE(hsc);
393 
394   /* DeInit the low level hardware */
395 #if USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1
396   if (hsc->MspDeInitCallback == NULL)
397   {
398     hsc->MspDeInitCallback = HAL_SMARTCARD_MspDeInit;
399   }
400   /* DeInit the low level hardware */
401   hsc->MspDeInitCallback(hsc);
402 #else
403   HAL_SMARTCARD_MspDeInit(hsc);
404 #endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACKS */
405 
406   hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
407   hsc->gState = HAL_SMARTCARD_STATE_RESET;
408   hsc->RxState = HAL_SMARTCARD_STATE_RESET;
409 
410   /* Release Lock */
411   __HAL_UNLOCK(hsc);
412 
413   return HAL_OK;
414 }
415 
416 /**
417   * @brief  SMARTCARD MSP Init
418   * @param  hsc    Pointer to a SMARTCARD_HandleTypeDef structure that contains
419   *                the configuration information for SMARTCARD module.
420   * @retval None
421   */
HAL_SMARTCARD_MspInit(SMARTCARD_HandleTypeDef * hsc)422 __weak void HAL_SMARTCARD_MspInit(SMARTCARD_HandleTypeDef *hsc)
423 {
424   /* Prevent unused argument(s) compilation warning */
425   UNUSED(hsc);
426 
427   /* NOTE : This function should not be modified, when the callback is needed,
428             the HAL_SMARTCARD_MspInit can be implemented in the user file
429    */
430 }
431 
432 /**
433   * @brief SMARTCARD MSP DeInit
434   * @param  hsc    Pointer to a SMARTCARD_HandleTypeDef structure that contains
435   *                the configuration information for SMARTCARD module.
436   * @retval None
437   */
HAL_SMARTCARD_MspDeInit(SMARTCARD_HandleTypeDef * hsc)438 __weak void HAL_SMARTCARD_MspDeInit(SMARTCARD_HandleTypeDef *hsc)
439 {
440   /* Prevent unused argument(s) compilation warning */
441   UNUSED(hsc);
442 
443   /* NOTE : This function should not be modified, when the callback is needed,
444             the HAL_SMARTCARD_MspDeInit can be implemented in the user file
445    */
446 }
447 
448 #if (USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1)
449 /**
450   * @brief  Register a User SMARTCARD Callback
451   *         To be used instead of the weak predefined callback
452   * @note   The HAL_SMARTCARD_RegisterCallback() may be called before HAL_SMARTCARD_Init()
453   *         in HAL_SMARTCARD_STATE_RESET to register callbacks for HAL_SMARTCARD_MSPINIT_CB_ID
454   *         and HAL_SMARTCARD_MSPDEINIT_CB_ID
455   * @param  hsc smartcard handle
456   * @param  CallbackID ID of the callback to be registered
457   *         This parameter can be one of the following values:
458   *           @arg @ref HAL_SMARTCARD_TX_COMPLETE_CB_ID Tx Complete Callback ID
459   *           @arg @ref HAL_SMARTCARD_RX_COMPLETE_CB_ID Rx Complete Callback ID
460   *           @arg @ref HAL_SMARTCARD_ERROR_CB_ID Error Callback ID
461   *           @arg @ref HAL_SMARTCARD_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
462   *           @arg @ref HAL_SMARTCARD_ABORT_TRANSMIT_COMPLETE_CB_ID Abort Transmit Complete Callback ID
463   *           @arg @ref HAL_SMARTCARD_ABORT_RECEIVE_COMPLETE_CB_ID Abort Receive Complete Callback ID
464   *           @arg @ref HAL_SMARTCARD_MSPINIT_CB_ID MspInit Callback ID
465   *           @arg @ref HAL_SMARTCARD_MSPDEINIT_CB_ID MspDeInit Callback ID
466   * @param  pCallback pointer to the Callback function
467   * @retval HAL status
468   */
HAL_SMARTCARD_RegisterCallback(SMARTCARD_HandleTypeDef * hsc,HAL_SMARTCARD_CallbackIDTypeDef CallbackID,pSMARTCARD_CallbackTypeDef pCallback)469 HAL_StatusTypeDef HAL_SMARTCARD_RegisterCallback(SMARTCARD_HandleTypeDef *hsc, HAL_SMARTCARD_CallbackIDTypeDef CallbackID, pSMARTCARD_CallbackTypeDef pCallback)
470 {
471   HAL_StatusTypeDef status = HAL_OK;
472 
473   if (pCallback == NULL)
474   {
475     /* Update the error code */
476     hsc->ErrorCode |= HAL_SMARTCARD_ERROR_INVALID_CALLBACK;
477 
478     return HAL_ERROR;
479   }
480 
481   if (hsc->gState == HAL_SMARTCARD_STATE_READY)
482   {
483     switch (CallbackID)
484     {
485 
486       case HAL_SMARTCARD_TX_COMPLETE_CB_ID :
487         hsc->TxCpltCallback = pCallback;
488         break;
489 
490       case HAL_SMARTCARD_RX_COMPLETE_CB_ID :
491         hsc->RxCpltCallback = pCallback;
492         break;
493 
494       case HAL_SMARTCARD_ERROR_CB_ID :
495         hsc->ErrorCallback = pCallback;
496         break;
497 
498       case HAL_SMARTCARD_ABORT_COMPLETE_CB_ID :
499         hsc->AbortCpltCallback = pCallback;
500         break;
501 
502       case HAL_SMARTCARD_ABORT_TRANSMIT_COMPLETE_CB_ID :
503         hsc->AbortTransmitCpltCallback = pCallback;
504         break;
505 
506       case HAL_SMARTCARD_ABORT_RECEIVE_COMPLETE_CB_ID :
507         hsc->AbortReceiveCpltCallback = pCallback;
508         break;
509 
510 
511       case HAL_SMARTCARD_MSPINIT_CB_ID :
512         hsc->MspInitCallback = pCallback;
513         break;
514 
515       case HAL_SMARTCARD_MSPDEINIT_CB_ID :
516         hsc->MspDeInitCallback = pCallback;
517         break;
518 
519       default :
520         /* Update the error code */
521         hsc->ErrorCode |= HAL_SMARTCARD_ERROR_INVALID_CALLBACK;
522 
523         /* Return error status */
524         status =  HAL_ERROR;
525         break;
526     }
527   }
528   else if (hsc->gState == HAL_SMARTCARD_STATE_RESET)
529   {
530     switch (CallbackID)
531     {
532       case HAL_SMARTCARD_MSPINIT_CB_ID :
533         hsc->MspInitCallback = pCallback;
534         break;
535 
536       case HAL_SMARTCARD_MSPDEINIT_CB_ID :
537         hsc->MspDeInitCallback = pCallback;
538         break;
539 
540       default :
541         /* Update the error code */
542         hsc->ErrorCode |= HAL_SMARTCARD_ERROR_INVALID_CALLBACK;
543 
544         /* Return error status */
545         status =  HAL_ERROR;
546         break;
547     }
548   }
549   else
550   {
551     /* Update the error code */
552     hsc->ErrorCode |= HAL_SMARTCARD_ERROR_INVALID_CALLBACK;
553 
554     /* Return error status */
555     status =  HAL_ERROR;
556   }
557 
558   return status;
559 }
560 
561 /**
562   * @brief  Unregister an SMARTCARD callback
563   *         SMARTCARD callback is redirected to the weak predefined callback
564   * @note   The HAL_SMARTCARD_UnRegisterCallback() may be called before HAL_SMARTCARD_Init()
565   *         in HAL_SMARTCARD_STATE_RESET to un-register callbacks for HAL_SMARTCARD_MSPINIT_CB_ID
566   *         and HAL_SMARTCARD_MSPDEINIT_CB_ID
567   * @param  hsc smartcard handle
568   * @param  CallbackID ID of the callback to be unregistered
569   *         This parameter can be one of the following values:
570   *           @arg @ref HAL_SMARTCARD_TX_COMPLETE_CB_ID Tx Complete Callback ID
571   *           @arg @ref HAL_SMARTCARD_RX_COMPLETE_CB_ID Rx Complete Callback ID
572   *           @arg @ref HAL_SMARTCARD_ERROR_CB_ID Error Callback ID
573   *           @arg @ref HAL_SMARTCARD_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
574   *           @arg @ref HAL_SMARTCARD_ABORT_TRANSMIT_COMPLETE_CB_ID Abort Transmit Complete Callback ID
575   *           @arg @ref HAL_SMARTCARD_ABORT_RECEIVE_COMPLETE_CB_ID Abort Receive Complete Callback ID
576   *           @arg @ref HAL_SMARTCARD_MSPINIT_CB_ID MspInit Callback ID
577   *           @arg @ref HAL_SMARTCARD_MSPDEINIT_CB_ID MspDeInit Callback ID
578   * @retval HAL status
579   */
HAL_SMARTCARD_UnRegisterCallback(SMARTCARD_HandleTypeDef * hsc,HAL_SMARTCARD_CallbackIDTypeDef CallbackID)580 HAL_StatusTypeDef HAL_SMARTCARD_UnRegisterCallback(SMARTCARD_HandleTypeDef *hsc, HAL_SMARTCARD_CallbackIDTypeDef CallbackID)
581 {
582   HAL_StatusTypeDef status = HAL_OK;
583 
584   if (HAL_SMARTCARD_STATE_READY == hsc->gState)
585   {
586     switch (CallbackID)
587     {
588       case HAL_SMARTCARD_TX_COMPLETE_CB_ID :
589         hsc->TxCpltCallback = HAL_SMARTCARD_TxCpltCallback;                       /* Legacy weak TxCpltCallback            */
590         break;
591 
592       case HAL_SMARTCARD_RX_COMPLETE_CB_ID :
593         hsc->RxCpltCallback = HAL_SMARTCARD_RxCpltCallback;                       /* Legacy weak RxCpltCallback            */
594         break;
595 
596       case HAL_SMARTCARD_ERROR_CB_ID :
597         hsc->ErrorCallback = HAL_SMARTCARD_ErrorCallback;                         /* Legacy weak ErrorCallback             */
598         break;
599 
600       case HAL_SMARTCARD_ABORT_COMPLETE_CB_ID :
601         hsc->AbortCpltCallback = HAL_SMARTCARD_AbortCpltCallback;                 /* Legacy weak AbortCpltCallback         */
602         break;
603 
604       case HAL_SMARTCARD_ABORT_TRANSMIT_COMPLETE_CB_ID :
605         hsc->AbortTransmitCpltCallback = HAL_SMARTCARD_AbortTransmitCpltCallback; /* Legacy weak AbortTransmitCpltCallback */
606         break;
607 
608       case HAL_SMARTCARD_ABORT_RECEIVE_COMPLETE_CB_ID :
609         hsc->AbortReceiveCpltCallback = HAL_SMARTCARD_AbortReceiveCpltCallback;   /* Legacy weak AbortReceiveCpltCallback  */
610         break;
611 
612 
613       case HAL_SMARTCARD_MSPINIT_CB_ID :
614         hsc->MspInitCallback = HAL_SMARTCARD_MspInit;                             /* Legacy weak MspInitCallback           */
615         break;
616 
617       case HAL_SMARTCARD_MSPDEINIT_CB_ID :
618         hsc->MspDeInitCallback = HAL_SMARTCARD_MspDeInit;                         /* Legacy weak MspDeInitCallback         */
619         break;
620 
621       default :
622         /* Update the error code */
623         hsc->ErrorCode |= HAL_SMARTCARD_ERROR_INVALID_CALLBACK;
624 
625         /* Return error status */
626         status =  HAL_ERROR;
627         break;
628     }
629   }
630   else if (HAL_SMARTCARD_STATE_RESET == hsc->gState)
631   {
632     switch (CallbackID)
633     {
634       case HAL_SMARTCARD_MSPINIT_CB_ID :
635         hsc->MspInitCallback = HAL_SMARTCARD_MspInit;
636         break;
637 
638       case HAL_SMARTCARD_MSPDEINIT_CB_ID :
639         hsc->MspDeInitCallback = HAL_SMARTCARD_MspDeInit;
640         break;
641 
642       default :
643         /* Update the error code */
644         hsc->ErrorCode |= HAL_SMARTCARD_ERROR_INVALID_CALLBACK;
645 
646         /* Return error status */
647         status =  HAL_ERROR;
648         break;
649     }
650   }
651   else
652   {
653     /* Update the error code */
654     hsc->ErrorCode |= HAL_SMARTCARD_ERROR_INVALID_CALLBACK;
655 
656     /* Return error status */
657     status =  HAL_ERROR;
658   }
659 
660   return status;
661 }
662 #endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACKS */
663 
664 /**
665   * @}
666   */
667 
668 /** @defgroup SMARTCARD_Exported_Functions_Group2 IO operation functions
669   * @brief    SMARTCARD Transmit and Receive functions
670   *
671 @verbatim
672  ===============================================================================
673                       ##### IO operation functions #####
674  ===============================================================================
675  [..]
676    This subsection provides a set of functions allowing to manage the SMARTCARD data transfers.
677 
678  [..]
679     (#) Smartcard is a single wire half duplex communication protocol.
680     The Smartcard interface is designed to support asynchronous protocol Smartcards as
681     defined in the ISO 7816-3 standard.
682     (#) The USART should be configured as:
683        (++) 8 bits plus parity: where M=1 and PCE=1 in the USART_CR1 register
684        (++) 1.5 stop bits when transmitting and receiving: where STOP=11 in the USART_CR2 register.
685 
686     (#) There are two modes of transfer:
687        (++) Blocking mode: The communication is performed in polling mode.
688             The HAL status of all data processing is returned by the same function
689             after finishing transfer.
690        (++) Non Blocking mode: The communication is performed using Interrupts
691            or DMA, These APIs return the HAL status.
692            The end of the data processing will be indicated through the
693            dedicated SMARTCARD IRQ when using Interrupt mode or the DMA IRQ when
694            using DMA mode.
695            The HAL_SMARTCARD_TxCpltCallback(), HAL_SMARTCARD_RxCpltCallback() user callbacks
696            will be executed respectively at the end of the Transmit or Receive process
697            The HAL_SMARTCARD_ErrorCallback() user callback will be executed when a communication error is detected
698 
699     (#) Blocking mode APIs are :
700         (++) HAL_SMARTCARD_Transmit()
701         (++) HAL_SMARTCARD_Receive()
702 
703     (#) Non Blocking mode APIs with Interrupt are :
704         (++) HAL_SMARTCARD_Transmit_IT()
705         (++) HAL_SMARTCARD_Receive_IT()
706         (++) HAL_SMARTCARD_IRQHandler()
707 
708     (#) Non Blocking mode functions with DMA are :
709         (++) HAL_SMARTCARD_Transmit_DMA()
710         (++) HAL_SMARTCARD_Receive_DMA()
711 
712     (#) A set of Transfer Complete Callbacks are provided in non Blocking mode:
713         (++) HAL_SMARTCARD_TxCpltCallback()
714         (++) HAL_SMARTCARD_RxCpltCallback()
715         (++) HAL_SMARTCARD_ErrorCallback()
716 
717     (#) Non-Blocking mode transfers could be aborted using Abort API's :
718         (+) HAL_SMARTCARD_Abort()
719         (+) HAL_SMARTCARD_AbortTransmit()
720         (+) HAL_SMARTCARD_AbortReceive()
721         (+) HAL_SMARTCARD_Abort_IT()
722         (+) HAL_SMARTCARD_AbortTransmit_IT()
723         (+) HAL_SMARTCARD_AbortReceive_IT()
724 
725     (#) For Abort services based on interrupts (HAL_SMARTCARD_Abortxxx_IT), a set of Abort Complete Callbacks are provided:
726         (+) HAL_SMARTCARD_AbortCpltCallback()
727         (+) HAL_SMARTCARD_AbortTransmitCpltCallback()
728         (+) HAL_SMARTCARD_AbortReceiveCpltCallback()
729 
730     (#) In Non-Blocking mode transfers, possible errors are split into 2 categories.
731         Errors are handled as follows :
732        (+) Error is considered as Recoverable and non blocking : Transfer could go till end, but error severity is
733            to be evaluated by user : this concerns Frame Error, Parity Error or Noise Error in Interrupt mode reception .
734            Received character is then retrieved and stored in Rx buffer, Error code is set to allow user to identify error type,
735            and HAL_SMARTCARD_ErrorCallback() user callback is executed. Transfer is kept ongoing on SMARTCARD side.
736            If user wants to abort it, Abort services should be called by user.
737        (+) Error is considered as Blocking : Transfer could not be completed properly and is aborted.
738            This concerns Frame Error in Interrupt mode transmission, Overrun Error in Interrupt mode reception and all errors in DMA mode.
739            Error code is set to allow user to identify error type, and HAL_SMARTCARD_ErrorCallback() user callback is executed.
740 
741 @endverbatim
742   * @{
743   */
744 
745 /**
746   * @brief Send an amount of data in blocking mode
747   * @param  hsc    Pointer to a SMARTCARD_HandleTypeDef structure that contains
748   *                the configuration information for SMARTCARD module.
749   * @param  pData  Pointer to data buffer
750   * @param  Size   Amount of data to be sent
751   * @param  Timeout Timeout duration
752   * @retval HAL status
753   */
HAL_SMARTCARD_Transmit(SMARTCARD_HandleTypeDef * hsc,const uint8_t * pData,uint16_t Size,uint32_t Timeout)754 HAL_StatusTypeDef HAL_SMARTCARD_Transmit(SMARTCARD_HandleTypeDef *hsc, const uint8_t *pData, uint16_t Size, uint32_t Timeout)
755 {
756   const uint8_t *tmp = pData;
757   uint32_t tickstart = 0U;
758 
759   if(hsc->gState == HAL_SMARTCARD_STATE_READY)
760   {
761     if((pData == NULL) || (Size == 0U))
762     {
763       return  HAL_ERROR;
764     }
765 
766     /* Process Locked */
767     __HAL_LOCK(hsc);
768 
769     hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
770     hsc->gState = HAL_SMARTCARD_STATE_BUSY_TX;
771 
772     /* Init tickstart for timeout management */
773     tickstart = HAL_GetTick();
774 
775     hsc->TxXferSize = Size;
776     hsc->TxXferCount = Size;
777     while(hsc->TxXferCount > 0U)
778     {
779       hsc->TxXferCount--;
780       if(SMARTCARD_WaitOnFlagUntilTimeout(hsc, SMARTCARD_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
781       {
782         return HAL_TIMEOUT;
783       }
784       hsc->Instance->DR = (uint8_t)(*tmp & 0xFFU);
785       tmp++;
786     }
787 
788     if(SMARTCARD_WaitOnFlagUntilTimeout(hsc, SMARTCARD_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
789     {
790       return HAL_TIMEOUT;
791     }
792 
793 	/* At end of Tx process, restore hsc->gState to Ready */
794     hsc->gState = HAL_SMARTCARD_STATE_READY;
795 
796     /* Process Unlocked */
797     __HAL_UNLOCK(hsc);
798 
799     return HAL_OK;
800   }
801   else
802   {
803     return HAL_BUSY;
804   }
805 }
806 
807 /**
808   * @brief Receive an amount of data in blocking mode
809   * @param  hsc    Pointer to a SMARTCARD_HandleTypeDef structure that contains
810   *                the configuration information for SMARTCARD module.
811   * @param  pData  Pointer to data buffer
812   * @param  Size   Amount of data to be received
813   * @param  Timeout Timeout duration
814   * @retval HAL status
815   */
HAL_SMARTCARD_Receive(SMARTCARD_HandleTypeDef * hsc,uint8_t * pData,uint16_t Size,uint32_t Timeout)816 HAL_StatusTypeDef HAL_SMARTCARD_Receive(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size, uint32_t Timeout)
817 {
818   uint8_t  *tmp = pData;
819   uint32_t tickstart = 0U;
820 
821   if(hsc->RxState == HAL_SMARTCARD_STATE_READY)
822   {
823     if((pData == NULL) || (Size == 0U))
824     {
825       return  HAL_ERROR;
826     }
827 
828     /* Process Locked */
829     __HAL_LOCK(hsc);
830 
831     hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
832     hsc->RxState = HAL_SMARTCARD_STATE_BUSY_RX;
833 
834     /* Init tickstart for timeout management */
835     tickstart = HAL_GetTick();
836 
837     hsc->RxXferSize = Size;
838     hsc->RxXferCount = Size;
839 
840     /* Check the remain data to be received */
841     while(hsc->RxXferCount > 0U)
842     {
843       hsc->RxXferCount--;
844       if(SMARTCARD_WaitOnFlagUntilTimeout(hsc, SMARTCARD_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
845       {
846         return HAL_TIMEOUT;
847       }
848       *tmp = (uint8_t)(hsc->Instance->DR & (uint8_t)0xFFU);
849       tmp++;
850     }
851 
852     /* At end of Rx process, restore hsc->RxState to Ready */
853     hsc->RxState = HAL_SMARTCARD_STATE_READY;
854 
855     /* Process Unlocked */
856     __HAL_UNLOCK(hsc);
857 
858     return HAL_OK;
859   }
860   else
861   {
862     return HAL_BUSY;
863   }
864 }
865 
866 /**
867   * @brief Send an amount of data in non blocking mode
868   * @param  hsc    Pointer to a SMARTCARD_HandleTypeDef structure that contains
869   *                the configuration information for SMARTCARD module.
870   * @param  pData  Pointer to data buffer
871   * @param  Size   Amount of data to be sent
872   * @retval HAL status
873   */
HAL_SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef * hsc,const uint8_t * pData,uint16_t Size)874 HAL_StatusTypeDef HAL_SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef *hsc, const uint8_t *pData, uint16_t Size)
875 {
876   /* Check that a Tx process is not already ongoing */
877   if(hsc->gState == HAL_SMARTCARD_STATE_READY)
878   {
879     if((pData == NULL) || (Size == 0U))
880     {
881       return HAL_ERROR;
882     }
883 
884     /* Process Locked */
885     __HAL_LOCK(hsc);
886 
887     hsc->pTxBuffPtr = pData;
888     hsc->TxXferSize = Size;
889     hsc->TxXferCount = Size;
890 
891     hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
892     hsc->gState = HAL_SMARTCARD_STATE_BUSY_TX;
893 
894     /* Process Unlocked */
895     __HAL_UNLOCK(hsc);
896 
897     /* Enable the SMARTCARD Parity Error Interrupt */
898     SET_BIT(hsc->Instance->CR1, USART_CR1_PEIE);
899 
900     /* Disable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */
901     CLEAR_BIT(hsc->Instance->CR3, USART_CR3_EIE);
902 
903     /* Enable the SMARTCARD Transmit data register empty Interrupt */
904     SET_BIT(hsc->Instance->CR1, USART_CR1_TXEIE);
905 
906     return HAL_OK;
907   }
908   else
909   {
910     return HAL_BUSY;
911   }
912 }
913 
914 /**
915   * @brief Receive an amount of data in non blocking mode
916   * @param  hsc    Pointer to a SMARTCARD_HandleTypeDef structure that contains
917   *                the configuration information for SMARTCARD module.
918   * @param  pData  Pointer to data buffer
919   * @param  Size   Amount of data to be received
920   * @retval HAL status
921   */
HAL_SMARTCARD_Receive_IT(SMARTCARD_HandleTypeDef * hsc,uint8_t * pData,uint16_t Size)922 HAL_StatusTypeDef HAL_SMARTCARD_Receive_IT(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size)
923 {
924   /* Check that a Rx process is not already ongoing */
925   if(hsc->RxState == HAL_SMARTCARD_STATE_READY)
926   {
927     if((pData == NULL) || (Size == 0U))
928     {
929       return HAL_ERROR;
930     }
931 
932     /* Process Locked */
933     __HAL_LOCK(hsc);
934 
935     hsc->pRxBuffPtr = pData;
936     hsc->RxXferSize = Size;
937     hsc->RxXferCount = Size;
938 
939     hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
940     hsc->RxState = HAL_SMARTCARD_STATE_BUSY_RX;
941 
942     /* Process Unlocked */
943     __HAL_UNLOCK(hsc);
944 
945     /* Enable the SMARTCARD Parity Error and Data Register not empty Interrupts */
946     SET_BIT(hsc->Instance->CR1, USART_CR1_PEIE| USART_CR1_RXNEIE);
947 
948     /* Enable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */
949     SET_BIT(hsc->Instance->CR3, USART_CR3_EIE);
950 
951     return HAL_OK;
952   }
953   else
954   {
955     return HAL_BUSY;
956   }
957 }
958 
959 /**
960   * @brief Send an amount of data in non blocking mode
961   * @param  hsc    Pointer to a SMARTCARD_HandleTypeDef structure that contains
962   *                the configuration information for SMARTCARD module.
963   * @param  pData  Pointer to data buffer
964   * @param  Size   Amount of data to be sent
965   * @retval HAL status
966   */
HAL_SMARTCARD_Transmit_DMA(SMARTCARD_HandleTypeDef * hsc,const uint8_t * pData,uint16_t Size)967 HAL_StatusTypeDef HAL_SMARTCARD_Transmit_DMA(SMARTCARD_HandleTypeDef *hsc, const uint8_t *pData, uint16_t Size)
968 {
969   const uint32_t *tmp;
970 
971   /* Check that a Tx process is not already ongoing */
972   if(hsc->gState == HAL_SMARTCARD_STATE_READY)
973   {
974     if((pData == NULL) || (Size == 0U))
975     {
976       return HAL_ERROR;
977     }
978 
979     /* Process Locked */
980     __HAL_LOCK(hsc);
981 
982     hsc->pTxBuffPtr = pData;
983     hsc->TxXferSize = Size;
984     hsc->TxXferCount = Size;
985 
986     hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
987     hsc->gState = HAL_SMARTCARD_STATE_BUSY_TX;
988 
989     /* Set the SMARTCARD DMA transfer complete callback */
990     hsc->hdmatx->XferCpltCallback = SMARTCARD_DMATransmitCplt;
991 
992     /* Set the DMA error callback */
993     hsc->hdmatx->XferErrorCallback = SMARTCARD_DMAError;
994 
995     /* Set the DMA abort callback */
996     hsc->hdmatx->XferAbortCallback = NULL;
997 
998     /* Enable the SMARTCARD transmit DMA stream */
999     tmp = (const uint32_t*)&pData;
1000     HAL_DMA_Start_IT(hsc->hdmatx, *(const uint32_t*)tmp, (uint32_t)&hsc->Instance->DR, Size);
1001 
1002      /* Clear the TC flag in the SR register by writing 0 to it */
1003     __HAL_SMARTCARD_CLEAR_FLAG(hsc, SMARTCARD_FLAG_TC);
1004 
1005     /* Process Unlocked */
1006     __HAL_UNLOCK(hsc);
1007 
1008     /* Enable the DMA transfer for transmit request by setting the DMAT bit
1009     in the SMARTCARD CR3 register */
1010     SET_BIT(hsc->Instance->CR3, USART_CR3_DMAT);
1011 
1012     return HAL_OK;
1013   }
1014   else
1015   {
1016     return HAL_BUSY;
1017   }
1018 }
1019 
1020 /**
1021   * @brief Receive an amount of data in non blocking mode
1022   * @param  hsc    Pointer to a SMARTCARD_HandleTypeDef structure that contains
1023   *                the configuration information for SMARTCARD module.
1024   * @param  pData  Pointer to data buffer
1025   * @param  Size   Amount of data to be received
1026   * @note   When the SMARTCARD parity is enabled (PCE = 1) the data received contain the parity bit.s
1027   * @retval HAL status
1028   */
HAL_SMARTCARD_Receive_DMA(SMARTCARD_HandleTypeDef * hsc,uint8_t * pData,uint16_t Size)1029 HAL_StatusTypeDef HAL_SMARTCARD_Receive_DMA(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size)
1030 {
1031   uint32_t *tmp;
1032 
1033   /* Check that a Rx process is not already ongoing */
1034   if(hsc->RxState == HAL_SMARTCARD_STATE_READY)
1035   {
1036     if((pData == NULL) || (Size == 0U))
1037     {
1038       return HAL_ERROR;
1039     }
1040 
1041     /* Process Locked */
1042     __HAL_LOCK(hsc);
1043 
1044     hsc->pRxBuffPtr = pData;
1045     hsc->RxXferSize = Size;
1046 
1047     hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
1048     hsc->RxState = HAL_SMARTCARD_STATE_BUSY_RX;
1049 
1050     /* Set the SMARTCARD DMA transfer complete callback */
1051     hsc->hdmarx->XferCpltCallback = SMARTCARD_DMAReceiveCplt;
1052 
1053     /* Set the DMA error callback */
1054     hsc->hdmarx->XferErrorCallback = SMARTCARD_DMAError;
1055 
1056     /* Set the DMA abort callback */
1057     hsc->hdmatx->XferAbortCallback = NULL;
1058 
1059     /* Enable the DMA stream */
1060     tmp = (uint32_t*)&pData;
1061     HAL_DMA_Start_IT(hsc->hdmarx, (uint32_t)&hsc->Instance->DR, *(uint32_t*)tmp, Size);
1062 
1063     /* Clear the Overrun flag just before enabling the DMA Rx request: can be mandatory for the second transfer */
1064     __HAL_SMARTCARD_CLEAR_OREFLAG(hsc);
1065 
1066     /* Process Unlocked */
1067     __HAL_UNLOCK(hsc);
1068 
1069     /* Enable the SMARTCARD Parity Error Interrupt */
1070     SET_BIT(hsc->Instance->CR1, USART_CR1_PEIE);
1071 
1072     /* Enable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */
1073     SET_BIT(hsc->Instance->CR3, USART_CR3_EIE);
1074 
1075     /* Enable the DMA transfer for the receiver request by setting the DMAR bit
1076     in the SMARTCARD CR3 register */
1077     SET_BIT(hsc->Instance->CR3, USART_CR3_DMAR);
1078 
1079     return HAL_OK;
1080   }
1081   else
1082   {
1083     return HAL_BUSY;
1084   }
1085 }
1086 
1087 /**
1088   * @brief  Abort ongoing transfers (blocking mode).
1089   * @param  hsc SMARTCARD handle.
1090   * @note   This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
1091   *         This procedure performs following operations :
1092   *           - Disable PPP Interrupts
1093   *           - Disable the DMA transfer in the peripheral register (if enabled)
1094   *           - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
1095   *           - Set handle State to READY
1096   * @note   This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
1097   * @retval HAL status
1098 */
HAL_SMARTCARD_Abort(SMARTCARD_HandleTypeDef * hsc)1099 HAL_StatusTypeDef HAL_SMARTCARD_Abort(SMARTCARD_HandleTypeDef *hsc)
1100 {
1101   /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
1102   CLEAR_BIT(hsc->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
1103   CLEAR_BIT(hsc->Instance->CR3, USART_CR3_EIE);
1104 
1105   /* Disable the SMARTCARD DMA Tx request if enabled */
1106   if(HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAT))
1107   {
1108     CLEAR_BIT(hsc->Instance->CR3, USART_CR3_DMAT);
1109 
1110     /* Abort the SMARTCARD DMA Tx channel : use blocking DMA Abort API (no callback) */
1111     if(hsc->hdmatx != NULL)
1112     {
1113       /* Set the SMARTCARD DMA Abort callback to Null.
1114          No call back execution at end of DMA abort procedure */
1115       hsc->hdmatx->XferAbortCallback = NULL;
1116 
1117       HAL_DMA_Abort(hsc->hdmatx);
1118     }
1119   }
1120 
1121   /* Disable the SMARTCARD DMA Rx request if enabled */
1122   if(HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAR))
1123   {
1124     CLEAR_BIT(hsc->Instance->CR3, USART_CR3_DMAR);
1125 
1126     /* Abort the SMARTCARD DMA Rx channel : use blocking DMA Abort API (no callback) */
1127     if(hsc->hdmarx != NULL)
1128     {
1129       /* Set the SMARTCARD DMA Abort callback to Null.
1130          No call back execution at end of DMA abort procedure */
1131       hsc->hdmarx->XferAbortCallback = NULL;
1132 
1133       HAL_DMA_Abort(hsc->hdmarx);
1134     }
1135   }
1136 
1137   /* Reset Tx and Rx transfer counters */
1138   hsc->TxXferCount = 0x00U;
1139   hsc->RxXferCount = 0x00U;
1140 
1141   /* Reset ErrorCode */
1142   hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
1143 
1144   /* Restore hsc->RxState and hsc->gState to Ready */
1145   hsc->RxState = HAL_SMARTCARD_STATE_READY;
1146   hsc->gState = HAL_SMARTCARD_STATE_READY;
1147 
1148   return HAL_OK;
1149 }
1150 
1151 /**
1152   * @brief  Abort ongoing Transmit transfer (blocking mode).
1153   * @param  hsc SMARTCARD handle.
1154   * @note   This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
1155   *         This procedure performs following operations :
1156   *           - Disable SMARTCARD Interrupts (Tx)
1157   *           - Disable the DMA transfer in the peripheral register (if enabled)
1158   *           - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
1159   *           - Set handle State to READY
1160   * @note   This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
1161   * @retval HAL status
1162 */
HAL_SMARTCARD_AbortTransmit(SMARTCARD_HandleTypeDef * hsc)1163 HAL_StatusTypeDef HAL_SMARTCARD_AbortTransmit(SMARTCARD_HandleTypeDef *hsc)
1164 {
1165   /* Disable TXEIE and TCIE interrupts */
1166   CLEAR_BIT(hsc->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
1167 
1168   /* Disable the SMARTCARD DMA Tx request if enabled */
1169   if(HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAT))
1170   {
1171     CLEAR_BIT(hsc->Instance->CR3, USART_CR3_DMAT);
1172 
1173     /* Abort the SMARTCARD DMA Tx channel : use blocking DMA Abort API (no callback) */
1174     if(hsc->hdmatx != NULL)
1175     {
1176       /* Set the SMARTCARD DMA Abort callback to Null.
1177          No call back execution at end of DMA abort procedure */
1178       hsc->hdmatx->XferAbortCallback = NULL;
1179 
1180       HAL_DMA_Abort(hsc->hdmatx);
1181     }
1182   }
1183 
1184   /* Reset Tx transfer counter */
1185   hsc->TxXferCount = 0x00U;
1186 
1187   /* Restore hsc->gState to Ready */
1188   hsc->gState = HAL_SMARTCARD_STATE_READY;
1189 
1190   return HAL_OK;
1191 }
1192 
1193 /**
1194   * @brief  Abort ongoing Receive transfer (blocking mode).
1195   * @param  hsc SMARTCARD handle.
1196   * @note   This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
1197   *         This procedure performs following operations :
1198   *           - Disable PPP Interrupts
1199   *           - Disable the DMA transfer in the peripheral register (if enabled)
1200   *           - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
1201   *           - Set handle State to READY
1202   * @note   This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
1203   * @retval HAL status
1204 */
HAL_SMARTCARD_AbortReceive(SMARTCARD_HandleTypeDef * hsc)1205 HAL_StatusTypeDef HAL_SMARTCARD_AbortReceive(SMARTCARD_HandleTypeDef *hsc)
1206 {
1207   /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
1208   CLEAR_BIT(hsc->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
1209   CLEAR_BIT(hsc->Instance->CR3, USART_CR3_EIE);
1210 
1211   /* Disable the SMARTCARD DMA Rx request if enabled */
1212   if(HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAR))
1213   {
1214     CLEAR_BIT(hsc->Instance->CR3, USART_CR3_DMAR);
1215 
1216     /* Abort the SMARTCARD DMA Rx channel : use blocking DMA Abort API (no callback) */
1217     if(hsc->hdmarx != NULL)
1218     {
1219       /* Set the SMARTCARD DMA Abort callback to Null.
1220          No call back execution at end of DMA abort procedure */
1221       hsc->hdmarx->XferAbortCallback = NULL;
1222 
1223       HAL_DMA_Abort(hsc->hdmarx);
1224     }
1225   }
1226 
1227   /* Reset Rx transfer counter */
1228   hsc->RxXferCount = 0x00U;
1229 
1230   /* Restore hsc->RxState to Ready */
1231   hsc->RxState = HAL_SMARTCARD_STATE_READY;
1232 
1233   return HAL_OK;
1234 }
1235 
1236 /**
1237   * @brief  Abort ongoing transfers (Interrupt mode).
1238   * @param  hsc SMARTCARD handle.
1239   * @note   This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
1240   *         This procedure performs following operations :
1241   *           - Disable PPP Interrupts
1242   *           - Disable the DMA transfer in the peripheral register (if enabled)
1243   *           - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
1244   *           - Set handle State to READY
1245   *           - At abort completion, call user abort complete callback
1246   * @note   This procedure is executed in Interrupt mode, meaning that abort procedure could be
1247   *         considered as completed only when user abort complete callback is executed (not when exiting function).
1248   * @retval HAL status
1249 */
HAL_SMARTCARD_Abort_IT(SMARTCARD_HandleTypeDef * hsc)1250 HAL_StatusTypeDef HAL_SMARTCARD_Abort_IT(SMARTCARD_HandleTypeDef *hsc)
1251 {
1252   uint32_t AbortCplt = 0x01U;
1253 
1254   /* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
1255   CLEAR_BIT(hsc->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
1256   CLEAR_BIT(hsc->Instance->CR3, USART_CR3_EIE);
1257 
1258   /* If DMA Tx and/or DMA Rx Handles are associated to SMARTCARD Handle, DMA Abort complete callbacks should be initialised
1259      before any call to DMA Abort functions */
1260   /* DMA Tx Handle is valid */
1261   if(hsc->hdmatx != NULL)
1262   {
1263     /* Set DMA Abort Complete callback if SMARTCARD DMA Tx request if enabled.
1264        Otherwise, set it to NULL */
1265     if(HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAT))
1266     {
1267       hsc->hdmatx->XferAbortCallback = SMARTCARD_DMATxAbortCallback;
1268     }
1269     else
1270     {
1271       hsc->hdmatx->XferAbortCallback = NULL;
1272     }
1273   }
1274   /* DMA Rx Handle is valid */
1275   if(hsc->hdmarx != NULL)
1276   {
1277     /* Set DMA Abort Complete callback if SMARTCARD DMA Rx request if enabled.
1278        Otherwise, set it to NULL */
1279     if(HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAR))
1280     {
1281       hsc->hdmarx->XferAbortCallback = SMARTCARD_DMARxAbortCallback;
1282     }
1283     else
1284     {
1285       hsc->hdmarx->XferAbortCallback = NULL;
1286     }
1287   }
1288 
1289   /* Disable the SMARTCARD DMA Tx request if enabled */
1290   if(HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAT))
1291   {
1292     /* Disable DMA Tx at SMARTCARD level */
1293     CLEAR_BIT(hsc->Instance->CR3, USART_CR3_DMAT);
1294 
1295     /* Abort the SMARTCARD DMA Tx channel : use non blocking DMA Abort API (callback) */
1296     if(hsc->hdmatx != NULL)
1297     {
1298       /* SMARTCARD Tx DMA Abort callback has already been initialised :
1299          will lead to call HAL_SMARTCARD_AbortCpltCallback() at end of DMA abort procedure */
1300 
1301       /* Abort DMA TX */
1302       if(HAL_DMA_Abort_IT(hsc->hdmatx) != HAL_OK)
1303       {
1304         hsc->hdmatx->XferAbortCallback = NULL;
1305       }
1306       else
1307       {
1308         AbortCplt = 0x00U;
1309       }
1310     }
1311   }
1312 
1313   /* Disable the SMARTCARD DMA Rx request if enabled */
1314   if(HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAR))
1315   {
1316     CLEAR_BIT(hsc->Instance->CR3, USART_CR3_DMAR);
1317 
1318     /* Abort the SMARTCARD DMA Rx channel : use non blocking DMA Abort API (callback) */
1319     if(hsc->hdmarx != NULL)
1320     {
1321       /* SMARTCARD Rx DMA Abort callback has already been initialised :
1322          will lead to call HAL_SMARTCARD_AbortCpltCallback() at end of DMA abort procedure */
1323 
1324       /* Abort DMA RX */
1325       if(HAL_DMA_Abort_IT(hsc->hdmarx) != HAL_OK)
1326       {
1327         hsc->hdmarx->XferAbortCallback = NULL;
1328         AbortCplt = 0x01U;
1329       }
1330       else
1331       {
1332         AbortCplt = 0x00U;
1333       }
1334     }
1335   }
1336 
1337   /* if no DMA abort complete callback execution is required => call user Abort Complete callback */
1338   if(AbortCplt == 0x01U)
1339   {
1340     /* Reset Tx and Rx transfer counters */
1341     hsc->TxXferCount = 0x00U;
1342     hsc->RxXferCount = 0x00U;
1343 
1344     /* Reset ErrorCode */
1345     hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
1346 
1347     /* Restore hsc->gState and hsc->RxState to Ready */
1348     hsc->gState  = HAL_SMARTCARD_STATE_READY;
1349     hsc->RxState = HAL_SMARTCARD_STATE_READY;
1350 
1351     /* As no DMA to be aborted, call directly user Abort complete callback */
1352 #if (USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1)
1353     /* Call registered Abort complete callback */
1354     hsc->AbortCpltCallback(hsc);
1355 #else
1356     /* Call legacy weak Abort complete callback */
1357     HAL_SMARTCARD_AbortCpltCallback(hsc);
1358 #endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACK */
1359   }
1360   return HAL_OK;
1361 }
1362 
1363 /**
1364   * @brief  Abort ongoing Transmit transfer (Interrupt mode).
1365   * @param  hsc SMARTCARD handle.
1366   * @note   This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
1367   *         This procedure performs following operations :
1368   *           - Disable SMARTCARD Interrupts (Tx)
1369   *           - Disable the DMA transfer in the peripheral register (if enabled)
1370   *           - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
1371   *           - Set handle State to READY
1372   *           - At abort completion, call user abort complete callback
1373   * @note   This procedure is executed in Interrupt mode, meaning that abort procedure could be
1374   *         considered as completed only when user abort complete callback is executed (not when exiting function).
1375   * @retval HAL status
1376 */
HAL_SMARTCARD_AbortTransmit_IT(SMARTCARD_HandleTypeDef * hsc)1377 HAL_StatusTypeDef HAL_SMARTCARD_AbortTransmit_IT(SMARTCARD_HandleTypeDef *hsc)
1378 {
1379   /* Disable TXEIE and TCIE interrupts */
1380   CLEAR_BIT(hsc->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
1381 
1382   /* Disable the SMARTCARD DMA Tx request if enabled */
1383   if(HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAT))
1384   {
1385     CLEAR_BIT(hsc->Instance->CR3, USART_CR3_DMAT);
1386 
1387     /* Abort the SMARTCARD DMA Tx channel : use blocking DMA Abort API (no callback) */
1388     if(hsc->hdmatx != NULL)
1389     {
1390       /* Set the SMARTCARD DMA Abort callback :
1391          will lead to call HAL_SMARTCARD_AbortCpltCallback() at end of DMA abort procedure */
1392       hsc->hdmatx->XferAbortCallback = SMARTCARD_DMATxOnlyAbortCallback;
1393 
1394       /* Abort DMA TX */
1395       if(HAL_DMA_Abort_IT(hsc->hdmatx) != HAL_OK)
1396       {
1397         /* Call Directly hsc->hdmatx->XferAbortCallback function in case of error */
1398         hsc->hdmatx->XferAbortCallback(hsc->hdmatx);
1399       }
1400     }
1401     else
1402     {
1403       /* Reset Tx transfer counter */
1404       hsc->TxXferCount = 0x00U;
1405 
1406       /* Restore hsc->gState to Ready */
1407       hsc->gState = HAL_SMARTCARD_STATE_READY;
1408 
1409       /* As no DMA to be aborted, call directly user Abort complete callback */
1410 #if (USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1)
1411       /* Call registered Abort Transmit Complete Callback */
1412       hsc->AbortTransmitCpltCallback(hsc);
1413 #else
1414       /* Call legacy weak Abort Transmit Complete Callback */
1415       HAL_SMARTCARD_AbortTransmitCpltCallback(hsc);
1416 #endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACK */
1417     }
1418   }
1419   else
1420   {
1421     /* Reset Tx transfer counter */
1422     hsc->TxXferCount = 0x00U;
1423 
1424     /* Restore hsc->gState to Ready */
1425     hsc->gState = HAL_SMARTCARD_STATE_READY;
1426 
1427     /* As no DMA to be aborted, call directly user Abort complete callback */
1428 #if (USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1)
1429     /* Call registered Abort Transmit Complete Callback */
1430     hsc->AbortTransmitCpltCallback(hsc);
1431 #else
1432     /* Call legacy weak Abort Transmit Complete Callback */
1433     HAL_SMARTCARD_AbortTransmitCpltCallback(hsc);
1434 #endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACK */
1435   }
1436 
1437   return HAL_OK;
1438 }
1439 
1440 /**
1441   * @brief  Abort ongoing Receive transfer (Interrupt mode).
1442   * @param  hsc SMARTCARD handle.
1443   * @note   This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
1444   *         This procedure performs following operations :
1445   *           - Disable SMARTCARD Interrupts (Rx)
1446   *           - Disable the DMA transfer in the peripheral register (if enabled)
1447   *           - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
1448   *           - Set handle State to READY
1449   *           - At abort completion, call user abort complete callback
1450   * @note   This procedure is executed in Interrupt mode, meaning that abort procedure could be
1451   *         considered as completed only when user abort complete callback is executed (not when exiting function).
1452   * @retval HAL status
1453 */
HAL_SMARTCARD_AbortReceive_IT(SMARTCARD_HandleTypeDef * hsc)1454 HAL_StatusTypeDef HAL_SMARTCARD_AbortReceive_IT(SMARTCARD_HandleTypeDef *hsc)
1455 {
1456   /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
1457   CLEAR_BIT(hsc->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
1458   CLEAR_BIT(hsc->Instance->CR3, USART_CR3_EIE);
1459 
1460   /* Disable the SMARTCARD DMA Rx request if enabled */
1461   if(HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAR))
1462   {
1463     CLEAR_BIT(hsc->Instance->CR3, USART_CR3_DMAR);
1464 
1465     /* Abort the SMARTCARD DMA Rx channel : use blocking DMA Abort API (no callback) */
1466     if(hsc->hdmarx != NULL)
1467     {
1468       /* Set the SMARTCARD DMA Abort callback :
1469          will lead to call HAL_SMARTCARD_AbortCpltCallback() at end of DMA abort procedure */
1470       hsc->hdmarx->XferAbortCallback = SMARTCARD_DMARxOnlyAbortCallback;
1471 
1472       /* Abort DMA RX */
1473       if(HAL_DMA_Abort_IT(hsc->hdmarx) != HAL_OK)
1474       {
1475         /* Call Directly hsc->hdmarx->XferAbortCallback function in case of error */
1476         hsc->hdmarx->XferAbortCallback(hsc->hdmarx);
1477       }
1478     }
1479     else
1480     {
1481       /* Reset Rx transfer counter */
1482       hsc->RxXferCount = 0x00U;
1483 
1484       /* Restore hsc->RxState to Ready */
1485       hsc->RxState = HAL_SMARTCARD_STATE_READY;
1486 
1487       /* As no DMA to be aborted, call directly user Abort complete callback */
1488 #if (USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1)
1489       /* Call registered Abort Receive Complete Callback */
1490       hsc->AbortReceiveCpltCallback(hsc);
1491 #else
1492       /* Call legacy weak Abort Receive Complete Callback */
1493       HAL_SMARTCARD_AbortReceiveCpltCallback(hsc);
1494 #endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACK */
1495     }
1496   }
1497   else
1498   {
1499     /* Reset Rx transfer counter */
1500     hsc->RxXferCount = 0x00U;
1501 
1502     /* Restore hsc->RxState to Ready */
1503     hsc->RxState = HAL_SMARTCARD_STATE_READY;
1504 
1505     /* As no DMA to be aborted, call directly user Abort complete callback */
1506 #if (USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1)
1507     /* Call registered Abort Receive Complete Callback */
1508     hsc->AbortReceiveCpltCallback(hsc);
1509 #else
1510     /* Call legacy weak Abort Receive Complete Callback */
1511     HAL_SMARTCARD_AbortReceiveCpltCallback(hsc);
1512 #endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACK */
1513   }
1514 
1515   return HAL_OK;
1516 }
1517 
1518 /**
1519   * @brief This function handles SMARTCARD interrupt request.
1520   * @param  hsc    Pointer to a SMARTCARD_HandleTypeDef structure that contains
1521   *                the configuration information for SMARTCARD module.
1522   * @retval None
1523   */
HAL_SMARTCARD_IRQHandler(SMARTCARD_HandleTypeDef * hsc)1524 void HAL_SMARTCARD_IRQHandler(SMARTCARD_HandleTypeDef *hsc)
1525 {
1526   uint32_t isrflags   = READ_REG(hsc->Instance->SR);
1527   uint32_t cr1its     = READ_REG(hsc->Instance->CR1);
1528   uint32_t cr3its     = READ_REG(hsc->Instance->CR3);
1529   uint32_t dmarequest = 0x00U;
1530   uint32_t errorflags = 0x00U;
1531 
1532   /* If no error occurs */
1533   errorflags = (isrflags & (uint32_t)(USART_SR_PE | USART_SR_FE | USART_SR_ORE | USART_SR_NE));
1534   if(errorflags == RESET)
1535   {
1536     /* SMARTCARD in mode Receiver -------------------------------------------------*/
1537     if(((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
1538     {
1539       SMARTCARD_Receive_IT(hsc);
1540       return;
1541     }
1542   }
1543 
1544   /* If some errors occur */
1545   if((errorflags != RESET) && (((cr3its & USART_CR3_EIE) != RESET) || ((cr1its & (USART_CR1_RXNEIE | USART_CR1_PEIE)) != RESET)))
1546   {
1547     /* SMARTCARD parity error interrupt occurred ---------------------------*/
1548     if(((isrflags & SMARTCARD_FLAG_PE) != RESET) && ((cr1its & USART_CR1_PEIE) != RESET))
1549     {
1550       hsc->ErrorCode |= HAL_SMARTCARD_ERROR_PE;
1551     }
1552 
1553     /* SMARTCARD frame error interrupt occurred ----------------------------*/
1554     if(((isrflags & SMARTCARD_FLAG_FE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
1555     {
1556       hsc->ErrorCode |= HAL_SMARTCARD_ERROR_FE;
1557     }
1558 
1559     /* SMARTCARD noise error interrupt occurred ----------------------------*/
1560     if(((isrflags & SMARTCARD_FLAG_NE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
1561     {
1562       hsc->ErrorCode |= HAL_SMARTCARD_ERROR_NE;
1563     }
1564 
1565     /* SMARTCARD Over-Run interrupt occurred -------------------------------*/
1566     if(((isrflags & SMARTCARD_FLAG_ORE) != RESET) && (((cr1its & USART_CR1_RXNEIE) != RESET) || ((cr3its & USART_CR3_EIE) != RESET)))
1567     {
1568       hsc->ErrorCode |= HAL_SMARTCARD_ERROR_ORE;
1569     }
1570     /* Call the Error call Back in case of Errors --------------------------*/
1571     if(hsc->ErrorCode != HAL_SMARTCARD_ERROR_NONE)
1572     {
1573       /* SMARTCARD in mode Receiver ----------------------------------------*/
1574       if(((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
1575       {
1576         SMARTCARD_Receive_IT(hsc);
1577       }
1578 
1579       /* If Overrun error occurs, or if any error occurs in DMA mode reception,
1580          consider error as blocking */
1581       dmarequest = HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAR);
1582       if(((hsc->ErrorCode & HAL_SMARTCARD_ERROR_ORE) != RESET) || dmarequest)
1583       {
1584         /* Blocking error : transfer is aborted
1585           Set the SMARTCARD state ready to be able to start again the process,
1586           Disable Rx Interrupts, and disable Rx DMA request, if ongoing */
1587         SMARTCARD_EndRxTransfer(hsc);
1588         /* Disable the SMARTCARD DMA Rx request if enabled */
1589         if(HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAR))
1590         {
1591           CLEAR_BIT(hsc->Instance->CR3, USART_CR3_DMAR);
1592 
1593           /* Abort the SMARTCARD DMA Rx channel */
1594           if(hsc->hdmarx != NULL)
1595           {
1596             /* Set the SMARTCARD DMA Abort callback :
1597               will lead to call HAL_SMARTCARD_ErrorCallback() at end of DMA abort procedure */
1598             hsc->hdmarx->XferAbortCallback = SMARTCARD_DMAAbortOnError;
1599 
1600            if(HAL_DMA_Abort_IT(hsc->hdmarx) != HAL_OK)
1601             {
1602               /* Call Directly XferAbortCallback function in case of error */
1603               hsc->hdmarx->XferAbortCallback(hsc->hdmarx);
1604             }
1605           }
1606           else
1607           {
1608 #if (USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1)
1609             /* Call registered user error callback */
1610             hsc->ErrorCallback(hsc);
1611 #else
1612             /* Call legacy weak user error callback */
1613             HAL_SMARTCARD_ErrorCallback(hsc);
1614 #endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACK */
1615           }
1616         }
1617         else
1618         {
1619 #if (USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1)
1620           /* Call registered user error callback */
1621           hsc->ErrorCallback(hsc);
1622 #else
1623           /* Call legacy weak user error callback */
1624           HAL_SMARTCARD_ErrorCallback(hsc);
1625 #endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACK */
1626         }
1627       }
1628       else
1629       {
1630         /* Non Blocking error : transfer could go on.
1631            Error is notified to user through user error callback */
1632 #if (USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1)
1633         /* Call registered user error callback */
1634         hsc->ErrorCallback(hsc);
1635 #else
1636         /* Call legacy weak user error callback */
1637         HAL_SMARTCARD_ErrorCallback(hsc);
1638 #endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACK */
1639         hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
1640       }
1641     }
1642     return;
1643   } /* End if some error occurs */
1644 
1645   /* SMARTCARD in mode Transmitter ------------------------------------------*/
1646   if(((isrflags & SMARTCARD_FLAG_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET))
1647   {
1648     SMARTCARD_Transmit_IT(hsc);
1649     return;
1650   }
1651 
1652   /* SMARTCARD in mode Transmitter (transmission end) -----------------------*/
1653   if(((isrflags & SMARTCARD_FLAG_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET))
1654   {
1655     SMARTCARD_EndTransmit_IT(hsc);
1656     return;
1657   }
1658 }
1659 
1660 /**
1661   * @brief Tx Transfer completed callbacks
1662   * @param  hsc    Pointer to a SMARTCARD_HandleTypeDef structure that contains
1663   *                the configuration information for SMARTCARD module.
1664   * @retval None
1665   */
HAL_SMARTCARD_TxCpltCallback(SMARTCARD_HandleTypeDef * hsc)1666 __weak void HAL_SMARTCARD_TxCpltCallback(SMARTCARD_HandleTypeDef *hsc)
1667 {
1668   /* Prevent unused argument(s) compilation warning */
1669   UNUSED(hsc);
1670 
1671   /* NOTE : This function should not be modified, when the callback is needed,
1672             the HAL_SMARTCARD_TxCpltCallback can be implemented in the user file.
1673    */
1674 }
1675 
1676 /**
1677   * @brief Rx Transfer completed callback
1678   * @param  hsc    Pointer to a SMARTCARD_HandleTypeDef structure that contains
1679   *                the configuration information for SMARTCARD module.
1680   * @retval None
1681   */
HAL_SMARTCARD_RxCpltCallback(SMARTCARD_HandleTypeDef * hsc)1682 __weak void HAL_SMARTCARD_RxCpltCallback(SMARTCARD_HandleTypeDef *hsc)
1683 {
1684   /* Prevent unused argument(s) compilation warning */
1685   UNUSED(hsc);
1686 
1687   /* NOTE : This function should not be modified, when the callback is needed,
1688             the HAL_SMARTCARD_RxCpltCallback can be implemented in the user file.
1689    */
1690 }
1691 
1692 /**
1693   * @brief SMARTCARD error callback
1694   * @param  hsc    Pointer to a SMARTCARD_HandleTypeDef structure that contains
1695   *                the configuration information for SMARTCARD module.
1696   * @retval None
1697   */
HAL_SMARTCARD_ErrorCallback(SMARTCARD_HandleTypeDef * hsc)1698 __weak void HAL_SMARTCARD_ErrorCallback(SMARTCARD_HandleTypeDef *hsc)
1699 {
1700   /* Prevent unused argument(s) compilation warning */
1701   UNUSED(hsc);
1702 
1703   /* NOTE : This function should not be modified, when the callback is needed,
1704             the HAL_SMARTCARD_ErrorCallback can be implemented in the user file.
1705    */
1706 }
1707 
1708 /**
1709   * @brief  SMARTCARD Abort Complete callback.
1710   * @param  hsc SMARTCARD handle.
1711   * @retval None
1712   */
HAL_SMARTCARD_AbortCpltCallback(SMARTCARD_HandleTypeDef * hsc)1713 __weak void HAL_SMARTCARD_AbortCpltCallback (SMARTCARD_HandleTypeDef *hsc)
1714 {
1715   /* Prevent unused argument(s) compilation warning */
1716   UNUSED(hsc);
1717 
1718   /* NOTE : This function should not be modified, when the callback is needed,
1719             the HAL_SMARTCARD_AbortCpltCallback can be implemented in the user file.
1720    */
1721 }
1722 
1723 /**
1724   * @brief  SMARTCARD Abort Transmit Complete callback.
1725   * @param  hsc SMARTCARD handle.
1726   * @retval None
1727   */
HAL_SMARTCARD_AbortTransmitCpltCallback(SMARTCARD_HandleTypeDef * hsc)1728 __weak void HAL_SMARTCARD_AbortTransmitCpltCallback (SMARTCARD_HandleTypeDef *hsc)
1729 {
1730     /* Prevent unused argument(s) compilation warning */
1731     UNUSED(hsc);
1732 
1733   /* NOTE : This function should not be modified, when the callback is needed,
1734             the HAL_SMARTCARD_AbortTransmitCpltCallback can be implemented in the user file.
1735    */
1736 }
1737 
1738 /**
1739   * @brief  SMARTCARD Abort Receive Complete callback.
1740   * @param  hsc SMARTCARD handle.
1741   * @retval None
1742   */
HAL_SMARTCARD_AbortReceiveCpltCallback(SMARTCARD_HandleTypeDef * hsc)1743 __weak void HAL_SMARTCARD_AbortReceiveCpltCallback (SMARTCARD_HandleTypeDef *hsc)
1744 {
1745     /* Prevent unused argument(s) compilation warning */
1746     UNUSED(hsc);
1747 
1748   /* NOTE : This function should not be modified, when the callback is needed,
1749             the HAL_SMARTCARD_AbortReceiveCpltCallback can be implemented in the user file.
1750    */
1751 }
1752 
1753 /**
1754   * @}
1755   */
1756 
1757 /** @defgroup SMARTCARD_Exported_Functions_Group3 Peripheral State and Errors functions
1758   *  @brief   SMARTCARD State and Errors functions
1759   *
1760 @verbatim
1761  ===============================================================================
1762                 ##### Peripheral State and Errors functions #####
1763  ===============================================================================
1764     [..]
1765     This subsection provides a set of functions allowing to control the SmartCard.
1766      (+) HAL_SMARTCARD_GetState() API can be helpful to check in run-time the state of the SmartCard peripheral.
1767      (+) HAL_SMARTCARD_GetError() check in run-time errors that could be occurred during communication.
1768 @endverbatim
1769   * @{
1770   */
1771 
1772 /**
1773   * @brief Return the SMARTCARD handle state
1774   * @param  hsc    Pointer to a SMARTCARD_HandleTypeDef structure that contains
1775   *                the configuration information for SMARTCARD module.
1776   * @retval HAL state
1777   */
HAL_SMARTCARD_GetState(const SMARTCARD_HandleTypeDef * hsc)1778 HAL_SMARTCARD_StateTypeDef HAL_SMARTCARD_GetState(const SMARTCARD_HandleTypeDef *hsc)
1779 {
1780   uint32_t temp1= 0x00U, temp2 = 0x00U;
1781   temp1 = hsc->gState;
1782   temp2 = hsc->RxState;
1783 
1784   return (HAL_SMARTCARD_StateTypeDef)(temp1 | temp2);
1785 }
1786 
1787 /**
1788   * @brief  Return the SMARTCARD error code
1789   * @param  hsc  Pointer to a SMARTCARD_HandleTypeDef structure that contains
1790   *              the configuration information for the specified SMARTCARD.
1791   * @retval SMARTCARD Error Code
1792   */
HAL_SMARTCARD_GetError(const SMARTCARD_HandleTypeDef * hsc)1793 uint32_t HAL_SMARTCARD_GetError(const SMARTCARD_HandleTypeDef *hsc)
1794 {
1795   return hsc->ErrorCode;
1796 }
1797 
1798 /**
1799   * @}
1800   */
1801 
1802 /**
1803   * @}
1804   */
1805 
1806 /** @defgroup SMARTCARD_Private_Functions SMARTCARD Private Functions
1807   * @{
1808   */
1809 
1810 #if (USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1)
1811 /**
1812   * @brief  Initialize the callbacks to their default values.
1813   * @param  hsc SMARTCARD handle.
1814   * @retval none
1815   */
SMARTCARD_InitCallbacksToDefault(SMARTCARD_HandleTypeDef * hsc)1816 void SMARTCARD_InitCallbacksToDefault(SMARTCARD_HandleTypeDef *hsc)
1817 {
1818   /* Init the SMARTCARD Callback settings */
1819   hsc->TxCpltCallback            = HAL_SMARTCARD_TxCpltCallback;            /* Legacy weak TxCpltCallback            */
1820   hsc->RxCpltCallback            = HAL_SMARTCARD_RxCpltCallback;            /* Legacy weak RxCpltCallback            */
1821   hsc->ErrorCallback             = HAL_SMARTCARD_ErrorCallback;             /* Legacy weak ErrorCallback             */
1822   hsc->AbortCpltCallback         = HAL_SMARTCARD_AbortCpltCallback;         /* Legacy weak AbortCpltCallback         */
1823   hsc->AbortTransmitCpltCallback = HAL_SMARTCARD_AbortTransmitCpltCallback; /* Legacy weak AbortTransmitCpltCallback */
1824   hsc->AbortReceiveCpltCallback  = HAL_SMARTCARD_AbortReceiveCpltCallback;  /* Legacy weak AbortReceiveCpltCallback  */
1825 
1826 }
1827 #endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACKS */
1828 
1829 /**
1830   * @brief DMA SMARTCARD transmit process complete callback
1831   * @param  hdma   Pointer to a DMA_HandleTypeDef structure that contains
1832   *                the configuration information for the specified DMA module.
1833   * @retval None
1834   */
SMARTCARD_DMATransmitCplt(DMA_HandleTypeDef * hdma)1835 static void SMARTCARD_DMATransmitCplt(DMA_HandleTypeDef *hdma)
1836 {
1837   SMARTCARD_HandleTypeDef* hsc = ( SMARTCARD_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1838 
1839   hsc->TxXferCount = 0U;
1840 
1841   /* Disable the DMA transfer for transmit request by setting the DMAT bit
1842      in the USART CR3 register */
1843   CLEAR_BIT(hsc->Instance->CR3, USART_CR3_DMAT);
1844 
1845   /* Enable the SMARTCARD Transmit Complete Interrupt */
1846   SET_BIT(hsc->Instance->CR1, USART_CR1_TCIE);
1847 }
1848 
1849 /**
1850   * @brief DMA SMARTCARD receive process complete callback
1851   * @param  hdma   Pointer to a DMA_HandleTypeDef structure that contains
1852   *                the configuration information for the specified DMA module.
1853   * @retval None
1854   */
SMARTCARD_DMAReceiveCplt(DMA_HandleTypeDef * hdma)1855 static void SMARTCARD_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
1856 {
1857   SMARTCARD_HandleTypeDef* hsc = ( SMARTCARD_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1858 
1859   hsc->RxXferCount = 0U;
1860 
1861   /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
1862   CLEAR_BIT(hsc->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
1863   CLEAR_BIT(hsc->Instance->CR3, USART_CR3_EIE);
1864 
1865   /* Disable the DMA transfer for the receiver request by setting the DMAR bit
1866      in the USART CR3 register */
1867   CLEAR_BIT(hsc->Instance->CR3, USART_CR3_DMAR);
1868 
1869   /* At end of Rx process, restore hsc->RxState to Ready */
1870   hsc->RxState = HAL_SMARTCARD_STATE_READY;
1871 
1872 #if (USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1)
1873   /* Call registered Rx complete callback */
1874   hsc->RxCpltCallback(hsc);
1875 #else
1876   /* Call legacy weak Rx complete callback */
1877   HAL_SMARTCARD_RxCpltCallback(hsc);
1878 #endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACK */
1879 }
1880 
1881 /**
1882   * @brief DMA SMARTCARD communication error callback
1883   * @param  hdma   Pointer to a DMA_HandleTypeDef structure that contains
1884   *                the configuration information for the specified DMA module.
1885   * @retval None
1886   */
SMARTCARD_DMAError(DMA_HandleTypeDef * hdma)1887 static void SMARTCARD_DMAError(DMA_HandleTypeDef *hdma)
1888 {
1889   uint32_t dmarequest = 0x00U;
1890   SMARTCARD_HandleTypeDef* hsc = ( SMARTCARD_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1891   hsc->RxXferCount = 0U;
1892   hsc->TxXferCount = 0U;
1893   hsc->ErrorCode = HAL_SMARTCARD_ERROR_DMA;
1894 
1895   /* Stop SMARTCARD DMA Tx request if ongoing */
1896   dmarequest = HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAT);
1897   if((hsc->gState == HAL_SMARTCARD_STATE_BUSY_TX) && dmarequest)
1898   {
1899     SMARTCARD_EndTxTransfer(hsc);
1900   }
1901 
1902   /* Stop SMARTCARD DMA Rx request if ongoing */
1903   dmarequest = HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAR);
1904   if((hsc->RxState == HAL_SMARTCARD_STATE_BUSY_RX) && dmarequest)
1905   {
1906     SMARTCARD_EndRxTransfer(hsc);
1907   }
1908 
1909 #if (USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1)
1910   /* Call registered user error callback */
1911   hsc->ErrorCallback(hsc);
1912 #else
1913   /* Call legacy weak user error callback */
1914   HAL_SMARTCARD_ErrorCallback(hsc);
1915 #endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACK */
1916 }
1917 
1918 /**
1919   * @brief  This function handles SMARTCARD Communication Timeout. It waits
1920   *         until a flag is no longer in the specified status.
1921   * @param  hsc    Pointer to a SMARTCARD_HandleTypeDef structure that contains
1922   *                the configuration information for SMARTCARD module.
1923   * @param  Flag   Specifies the SMARTCARD flag to check.
1924   * @param  Status The actual Flag status (SET or RESET).
1925   * @param  Timeout Timeout duration
1926   * @param  Tickstart Tick start value
1927   * @retval HAL status
1928   */
SMARTCARD_WaitOnFlagUntilTimeout(SMARTCARD_HandleTypeDef * hsc,uint32_t Flag,FlagStatus Status,uint32_t Tickstart,uint32_t Timeout)1929 static HAL_StatusTypeDef SMARTCARD_WaitOnFlagUntilTimeout(SMARTCARD_HandleTypeDef *hsc, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout)
1930 {
1931   /* Wait until flag is set */
1932   while((__HAL_SMARTCARD_GET_FLAG(hsc, Flag) ? SET : RESET) == Status)
1933   {
1934     /* Check for the Timeout */
1935     if(Timeout != HAL_MAX_DELAY)
1936     {
1937       if((Timeout == 0U)||((HAL_GetTick() - Tickstart ) > Timeout))
1938       {
1939         /* Disable TXE and RXNE interrupts for the interrupt process */
1940         CLEAR_BIT(hsc->Instance->CR1, USART_CR1_TXEIE);
1941         CLEAR_BIT(hsc->Instance->CR1, USART_CR1_RXNEIE);
1942 
1943         hsc->gState= HAL_SMARTCARD_STATE_READY;
1944         hsc->RxState= HAL_SMARTCARD_STATE_READY;
1945 
1946         /* Process Unlocked */
1947         __HAL_UNLOCK(hsc);
1948 
1949         return HAL_TIMEOUT;
1950       }
1951     }
1952   }
1953   return HAL_OK;
1954 }
1955 
1956 /**
1957   * @brief  End ongoing Tx transfer on SMARTCARD peripheral (following error detection or Transmit completion).
1958   * @param  hsc    Pointer to a SMARTCARD_HandleTypeDef structure that contains
1959   *                the configuration information for SMARTCARD module.
1960   * @retval None
1961   */
SMARTCARD_EndTxTransfer(SMARTCARD_HandleTypeDef * hsc)1962 static void SMARTCARD_EndTxTransfer(SMARTCARD_HandleTypeDef *hsc)
1963 {
1964   /* At end of Tx process, restore hsc->gState to Ready */
1965   hsc->gState = HAL_SMARTCARD_STATE_READY;
1966 
1967   /* Disable TXEIE and TCIE interrupts */
1968   CLEAR_BIT(hsc->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
1969 }
1970 
1971 
1972 /**
1973   * @brief  End ongoing Rx transfer on SMARTCARD peripheral (following error detection or Reception completion).
1974   * @param  hsc    Pointer to a SMARTCARD_HandleTypeDef structure that contains
1975   *                the configuration information for SMARTCARD module.
1976   * @retval None
1977   */
SMARTCARD_EndRxTransfer(SMARTCARD_HandleTypeDef * hsc)1978 static void SMARTCARD_EndRxTransfer(SMARTCARD_HandleTypeDef *hsc)
1979 {
1980   /* At end of Rx process, restore hsc->RxState to Ready */
1981   hsc->RxState = HAL_SMARTCARD_STATE_READY;
1982 
1983   /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
1984   CLEAR_BIT(hsc->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
1985   CLEAR_BIT(hsc->Instance->CR3, USART_CR3_EIE);
1986 }
1987 
1988 /**
1989   * @brief Send an amount of data in non blocking mode
1990   * @param  hsc    Pointer to a SMARTCARD_HandleTypeDef structure that contains
1991   *                the configuration information for SMARTCARD module.
1992   * @retval HAL status
1993   */
SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef * hsc)1994 static HAL_StatusTypeDef SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef *hsc)
1995 {
1996 
1997   /* Check that a Tx process is ongoing */
1998   if(hsc->gState == HAL_SMARTCARD_STATE_BUSY_TX)
1999   {
2000     hsc->Instance->DR = (uint8_t)(*hsc->pTxBuffPtr & 0xFFU);
2001     hsc->pTxBuffPtr++;
2002 
2003     if(--hsc->TxXferCount == 0U)
2004     {
2005       /* Disable the SMARTCARD Transmit data register empty Interrupt */
2006       CLEAR_BIT(hsc->Instance->CR1, USART_CR1_TXEIE);
2007 
2008       /* Enable the SMARTCARD Transmit Complete Interrupt */
2009       SET_BIT(hsc->Instance->CR1, USART_CR1_TCIE);
2010     }
2011 
2012     return HAL_OK;
2013   }
2014   else
2015   {
2016     return HAL_BUSY;
2017   }
2018 }
2019 
2020 /**
2021   * @brief  Wraps up transmission in non blocking mode.
2022   * @param  hsc    Pointer to a SMARTCARD_HandleTypeDef structure that contains
2023   *                the configuration information for the specified SMARTCARD module.
2024   * @retval HAL status
2025   */
SMARTCARD_EndTransmit_IT(SMARTCARD_HandleTypeDef * hsc)2026 static HAL_StatusTypeDef SMARTCARD_EndTransmit_IT(SMARTCARD_HandleTypeDef *hsc)
2027 {
2028   /* Disable the SMARTCARD Transmit Complete Interrupt */
2029   CLEAR_BIT(hsc->Instance->CR1, USART_CR1_TCIE);
2030 
2031   /* Disable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */
2032   CLEAR_BIT(hsc->Instance->CR3, USART_CR3_EIE);
2033 
2034   /* Tx process is ended, restore hsc->gState to Ready */
2035   hsc->gState = HAL_SMARTCARD_STATE_READY;
2036 
2037 #if (USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1)
2038   /* Call registered Tx complete callback */
2039   hsc->TxCpltCallback(hsc);
2040 #else
2041   /* Call legacy weak Tx complete callback */
2042   HAL_SMARTCARD_TxCpltCallback(hsc);
2043 #endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACK */
2044 
2045   return HAL_OK;
2046 }
2047 
2048 /**
2049   * @brief Receive an amount of data in non blocking mode
2050   * @param  hsc    Pointer to a SMARTCARD_HandleTypeDef structure that contains
2051   *                the configuration information for SMARTCARD module.
2052   * @retval HAL status
2053   */
SMARTCARD_Receive_IT(SMARTCARD_HandleTypeDef * hsc)2054 static HAL_StatusTypeDef SMARTCARD_Receive_IT(SMARTCARD_HandleTypeDef *hsc)
2055 {
2056 
2057   /* Check that a Rx process is ongoing */
2058   if(hsc->RxState == HAL_SMARTCARD_STATE_BUSY_RX)
2059   {
2060     *hsc->pRxBuffPtr = (uint8_t)(hsc->Instance->DR & (uint8_t)0xFFU);
2061     hsc->pRxBuffPtr++;
2062 
2063     if(--hsc->RxXferCount == 0U)
2064     {
2065       CLEAR_BIT(hsc->Instance->CR1, USART_CR1_RXNEIE);
2066 
2067       /* Disable the SMARTCARD Parity Error Interrupt */
2068       CLEAR_BIT(hsc->Instance->CR1, USART_CR1_PEIE);
2069 
2070       /* Disable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */
2071       CLEAR_BIT(hsc->Instance->CR3, USART_CR3_EIE);
2072 
2073       /* Rx process is completed, restore hsc->RxState to Ready */
2074       hsc->RxState = HAL_SMARTCARD_STATE_READY;
2075 
2076 #if (USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1)
2077       /* Call registered Rx complete callback */
2078       hsc->RxCpltCallback(hsc);
2079 #else
2080       /* Call legacy weak Rx complete callback */
2081       HAL_SMARTCARD_RxCpltCallback(hsc);
2082 #endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACK */
2083 
2084       return HAL_OK;
2085     }
2086     return HAL_OK;
2087   }
2088   else
2089   {
2090     return HAL_BUSY;
2091   }
2092 }
2093 
2094 /**
2095   * @brief  DMA SMARTCARD communication abort callback, when initiated by HAL services on Error
2096   *         (To be called at end of DMA Abort procedure following error occurrence).
2097   * @param  hdma DMA handle.
2098   * @retval None
2099   */
SMARTCARD_DMAAbortOnError(DMA_HandleTypeDef * hdma)2100 static void SMARTCARD_DMAAbortOnError(DMA_HandleTypeDef *hdma)
2101 {
2102   SMARTCARD_HandleTypeDef* hsc = (SMARTCARD_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
2103   hsc->RxXferCount = 0x00U;
2104   hsc->TxXferCount = 0x00U;
2105 
2106 #if (USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1)
2107   /* Call registered user error callback */
2108   hsc->ErrorCallback(hsc);
2109 #else
2110   /* Call legacy weak user error callback */
2111   HAL_SMARTCARD_ErrorCallback(hsc);
2112 #endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACK */
2113 }
2114 
2115 /**
2116   * @brief  DMA SMARTCARD Tx communication abort callback, when initiated by user
2117   *         (To be called at end of DMA Tx Abort procedure following user abort request).
2118   * @note   When this callback is executed, User Abort complete call back is called only if no
2119   *         Abort still ongoing for Rx DMA Handle.
2120   * @param  hdma DMA handle.
2121   * @retval None
2122   */
SMARTCARD_DMATxAbortCallback(DMA_HandleTypeDef * hdma)2123 static void SMARTCARD_DMATxAbortCallback(DMA_HandleTypeDef *hdma)
2124 {
2125   SMARTCARD_HandleTypeDef* hsc = ( SMARTCARD_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
2126 
2127   hsc->hdmatx->XferAbortCallback = NULL;
2128 
2129   /* Check if an Abort process is still ongoing */
2130   if(hsc->hdmarx != NULL)
2131   {
2132     if(hsc->hdmarx->XferAbortCallback != NULL)
2133     {
2134       return;
2135     }
2136   }
2137 
2138   /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
2139   hsc->TxXferCount = 0x00U;
2140   hsc->RxXferCount = 0x00U;
2141 
2142   /* Reset ErrorCode */
2143   hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
2144 
2145   /* Restore hsc->gState and hsc->RxState to Ready */
2146   hsc->gState  = HAL_SMARTCARD_STATE_READY;
2147   hsc->RxState = HAL_SMARTCARD_STATE_READY;
2148 
2149 #if (USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1)
2150   /* Call registered Abort complete callback */
2151   hsc->AbortCpltCallback(hsc);
2152 #else
2153   /* Call legacy weak Abort complete callback */
2154   HAL_SMARTCARD_AbortCpltCallback(hsc);
2155 #endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACK */
2156 }
2157 
2158 /**
2159   * @brief  DMA SMARTCARD Rx communication abort callback, when initiated by user
2160   *         (To be called at end of DMA Rx Abort procedure following user abort request).
2161   * @note   When this callback is executed, User Abort complete call back is called only if no
2162   *         Abort still ongoing for Tx DMA Handle.
2163   * @param  hdma DMA handle.
2164   * @retval None
2165   */
SMARTCARD_DMARxAbortCallback(DMA_HandleTypeDef * hdma)2166 static void SMARTCARD_DMARxAbortCallback(DMA_HandleTypeDef *hdma)
2167 {
2168   SMARTCARD_HandleTypeDef* hsc = ( SMARTCARD_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
2169 
2170   hsc->hdmarx->XferAbortCallback = NULL;
2171 
2172   /* Check if an Abort process is still ongoing */
2173   if(hsc->hdmatx != NULL)
2174   {
2175     if(hsc->hdmatx->XferAbortCallback != NULL)
2176     {
2177       return;
2178     }
2179   }
2180 
2181   /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
2182   hsc->TxXferCount = 0x00U;
2183   hsc->RxXferCount = 0x00U;
2184 
2185   /* Reset ErrorCode */
2186   hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
2187 
2188   /* Restore hsc->gState and hsc->RxState to Ready */
2189   hsc->gState  = HAL_SMARTCARD_STATE_READY;
2190   hsc->RxState = HAL_SMARTCARD_STATE_READY;
2191 
2192 #if (USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1)
2193   /* Call registered Abort complete callback */
2194   hsc->AbortCpltCallback(hsc);
2195 #else
2196   /* Call legacy weak Abort complete callback */
2197   HAL_SMARTCARD_AbortCpltCallback(hsc);
2198 #endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACK */
2199 }
2200 
2201 /**
2202   * @brief  DMA SMARTCARD Tx communication abort callback, when initiated by user by a call to
2203   *         HAL_SMARTCARD_AbortTransmit_IT API (Abort only Tx transfer)
2204   *         (This callback is executed at end of DMA Tx Abort procedure following user abort request,
2205   *         and leads to user Tx Abort Complete callback execution).
2206   * @param  hdma DMA handle.
2207   * @retval None
2208   */
SMARTCARD_DMATxOnlyAbortCallback(DMA_HandleTypeDef * hdma)2209 static void SMARTCARD_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
2210 {
2211   SMARTCARD_HandleTypeDef* hsc = ( SMARTCARD_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
2212 
2213   hsc->TxXferCount = 0x00U;
2214 
2215   /* Restore hsc->gState to Ready */
2216   hsc->gState = HAL_SMARTCARD_STATE_READY;
2217 
2218 #if (USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1)
2219   /* Call registered Abort Transmit Complete Callback */
2220   hsc->AbortTransmitCpltCallback(hsc);
2221 #else
2222   /* Call legacy weak Abort Transmit Complete Callback */
2223   HAL_SMARTCARD_AbortTransmitCpltCallback(hsc);
2224 #endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACK */
2225 }
2226 
2227 /**
2228   * @brief  DMA SMARTCARD Rx communication abort callback, when initiated by user by a call to
2229   *         HAL_SMARTCARD_AbortReceive_IT API (Abort only Rx transfer)
2230   *         (This callback is executed at end of DMA Rx Abort procedure following user abort request,
2231   *         and leads to user Rx Abort Complete callback execution).
2232   * @param  hdma DMA handle.
2233   * @retval None
2234   */
SMARTCARD_DMARxOnlyAbortCallback(DMA_HandleTypeDef * hdma)2235 static void SMARTCARD_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
2236 {
2237   SMARTCARD_HandleTypeDef* hsc = ( SMARTCARD_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
2238 
2239   hsc->RxXferCount = 0x00U;
2240 
2241   /* Restore hsc->RxState to Ready */
2242   hsc->RxState = HAL_SMARTCARD_STATE_READY;
2243 
2244 #if (USE_HAL_SMARTCARD_REGISTER_CALLBACKS == 1)
2245   /* Call registered Abort Receive Complete Callback */
2246   hsc->AbortReceiveCpltCallback(hsc);
2247 #else
2248   /* Call legacy weak Abort Receive Complete Callback */
2249   HAL_SMARTCARD_AbortReceiveCpltCallback(hsc);
2250 #endif /* USE_HAL_SMARTCARD_REGISTER_CALLBACK */
2251 }
2252 
2253 /**
2254   * @brief Configure the SMARTCARD peripheral
2255   * @param  hsc    Pointer to a SMARTCARD_HandleTypeDef structure that contains
2256   *                the configuration information for SMARTCARD module.
2257   * @retval None
2258   */
SMARTCARD_SetConfig(SMARTCARD_HandleTypeDef * hsc)2259 static void SMARTCARD_SetConfig(SMARTCARD_HandleTypeDef *hsc)
2260 {
2261   uint32_t tmpreg = 0x00U;
2262   uint32_t pclk;
2263 
2264   /* Check the parameters */
2265   assert_param(IS_SMARTCARD_INSTANCE(hsc->Instance));
2266   assert_param(IS_SMARTCARD_POLARITY(hsc->Init.CLKPolarity));
2267   assert_param(IS_SMARTCARD_PHASE(hsc->Init.CLKPhase));
2268   assert_param(IS_SMARTCARD_LASTBIT(hsc->Init.CLKLastBit));
2269   assert_param(IS_SMARTCARD_BAUDRATE(hsc->Init.BaudRate));
2270   assert_param(IS_SMARTCARD_WORD_LENGTH(hsc->Init.WordLength));
2271   assert_param(IS_SMARTCARD_STOPBITS(hsc->Init.StopBits));
2272   assert_param(IS_SMARTCARD_PARITY(hsc->Init.Parity));
2273   assert_param(IS_SMARTCARD_MODE(hsc->Init.Mode));
2274   assert_param(IS_SMARTCARD_NACK_STATE(hsc->Init.NACKState));
2275 
2276   /* The LBCL, CPOL and CPHA bits have to be selected when both the transmitter and the
2277      receiver are disabled (TE=RE=0) to ensure that the clock pulses function correctly. */
2278   CLEAR_BIT(hsc->Instance->CR1, (USART_CR1_TE | USART_CR1_RE));
2279 
2280   /*---------------------------- USART CR2 Configuration ---------------------*/
2281   tmpreg = hsc->Instance->CR2;
2282   /* Clear CLKEN, CPOL, CPHA and LBCL bits */
2283   tmpreg &= (uint32_t)~((uint32_t)(USART_CR2_CPHA | USART_CR2_CPOL | USART_CR2_CLKEN | USART_CR2_LBCL));
2284   /* Configure the SMARTCARD Clock, CPOL, CPHA and LastBit -----------------------*/
2285   /* Set CPOL bit according to hsc->Init.CLKPolarity value */
2286   /* Set CPHA bit according to hsc->Init.CLKPhase value */
2287   /* Set LBCL bit according to hsc->Init.CLKLastBit value */
2288   /* Set Stop Bits: Set STOP[13:12] bits according to hsc->Init.StopBits value */
2289   tmpreg |= (uint32_t)(USART_CR2_CLKEN | hsc->Init.CLKPolarity |
2290                       hsc->Init.CLKPhase| hsc->Init.CLKLastBit | hsc->Init.StopBits);
2291   /* Write to USART CR2 */
2292   WRITE_REG(hsc->Instance->CR2, (uint32_t)tmpreg);
2293 
2294   tmpreg = hsc->Instance->CR2;
2295 
2296   /* Clear STOP[13:12] bits */
2297   tmpreg &= (uint32_t)~((uint32_t)USART_CR2_STOP);
2298 
2299   /* Set Stop Bits: Set STOP[13:12] bits according to hsc->Init.StopBits value */
2300   tmpreg |= (uint32_t)(hsc->Init.StopBits);
2301 
2302   /* Write to USART CR2 */
2303   WRITE_REG(hsc->Instance->CR2, (uint32_t)tmpreg);
2304 
2305   /*-------------------------- USART CR1 Configuration -----------------------*/
2306   tmpreg = hsc->Instance->CR1;
2307 
2308   /* Clear M, PCE, PS, TE and RE bits */
2309   tmpreg &= (uint32_t)~((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | \
2310                                    USART_CR1_RE));
2311 
2312   /* Configure the SMARTCARD Word Length, Parity and mode:
2313      Set the M bits according to hsc->Init.WordLength value
2314      Set PCE and PS bits according to hsc->Init.Parity value
2315      Set TE and RE bits according to hsc->Init.Mode value */
2316   tmpreg |= (uint32_t)hsc->Init.WordLength | hsc->Init.Parity | hsc->Init.Mode;
2317 
2318   /* Write to USART CR1 */
2319   WRITE_REG(hsc->Instance->CR1, (uint32_t)tmpreg);
2320 
2321   /*-------------------------- USART CR3 Configuration -----------------------*/
2322   /* Clear CTSE and RTSE bits */
2323   CLEAR_BIT(hsc->Instance->CR3, (USART_CR3_RTSE | USART_CR3_CTSE));
2324 
2325   /*-------------------------- USART BRR Configuration -----------------------*/
2326 #if defined(USART6)
2327   if((hsc->Instance == USART1) || (hsc->Instance == USART6))
2328   {
2329     pclk = HAL_RCC_GetPCLK2Freq();
2330     hsc->Instance->BRR = SMARTCARD_BRR(pclk, hsc->Init.BaudRate);
2331   }
2332 #else
2333   if(hsc->Instance == USART1)
2334   {
2335     pclk = HAL_RCC_GetPCLK2Freq();
2336     hsc->Instance->BRR = SMARTCARD_BRR(pclk, hsc->Init.BaudRate);
2337   }
2338 #endif /* USART6 */
2339   else
2340   {
2341     pclk = HAL_RCC_GetPCLK1Freq();
2342     hsc->Instance->BRR = SMARTCARD_BRR(pclk, hsc->Init.BaudRate);
2343   }
2344 }
2345 
2346 /**
2347   * @}
2348   */
2349 
2350 #endif /* HAL_SMARTCARD_MODULE_ENABLED */
2351 /**
2352   * @}
2353   */
2354 
2355 /**
2356   * @}
2357   */
2358 
2359