1 /**
2   ******************************************************************************
3   * @file    stm32l4xx_hal_smartcard_ex.c
4   * @author  MCD Application Team
5   * @brief   SMARTCARD HAL module driver.
6   *          This file provides extended firmware functions to manage the following
7   *          functionalities of the SmartCard.
8   *           + Initialization and de-initialization functions
9   *           + Peripheral Control functions
10   *
11   ******************************************************************************
12   * @attention
13   *
14   * Copyright (c) 2017 STMicroelectronics.
15   * All rights reserved.
16   *
17   * This software is licensed under terms that can be found in the LICENSE file
18   * in the root directory of this software component.
19   * If no LICENSE file comes with this software, it is provided AS-IS.
20   *
21   ******************************************************************************
22   @verbatim
23   =============================================================================
24                ##### SMARTCARD peripheral extended features  #####
25   =============================================================================
26   [..]
27   The Extended SMARTCARD HAL driver can be used as follows:
28 
29     (#) After having configured the SMARTCARD basic features with HAL_SMARTCARD_Init(),
30         then program SMARTCARD advanced features if required (TX/RX pins swap, TimeOut,
31         auto-retry counter,...) in the hsmartcard AdvancedInit structure.
32 
33     (#) FIFO mode enabling/disabling and RX/TX FIFO threshold programming.
34 
35         -@- When SMARTCARD operates in FIFO mode, FIFO mode must be enabled prior
36             starting RX/TX transfers. Also RX/TX FIFO thresholds must be
37             configured prior starting RX/TX transfers.
38 
39   @endverbatim
40   ******************************************************************************
41   */
42 
43 /* Includes ------------------------------------------------------------------*/
44 #include "stm32l4xx_hal.h"
45 
46 /** @addtogroup STM32L4xx_HAL_Driver
47   * @{
48   */
49 
50 /** @defgroup SMARTCARDEx SMARTCARDEx
51   * @brief SMARTCARD Extended HAL module driver
52   * @{
53   */
54 #ifdef HAL_SMARTCARD_MODULE_ENABLED
55 
56 /* Private typedef -----------------------------------------------------------*/
57 /* Private define ------------------------------------------------------------*/
58 /** @defgroup SMARTCARDEx_Private_Constants SMARTCARD Extended Private Constants
59   * @{
60   */
61 /* UART RX FIFO depth */
62 #define RX_FIFO_DEPTH 8U
63 
64 /* UART TX FIFO depth */
65 #define TX_FIFO_DEPTH 8U
66 /**
67   * @}
68   */
69 
70 /* Private macros ------------------------------------------------------------*/
71 /* Private variables ---------------------------------------------------------*/
72 /* Private function prototypes -----------------------------------------------*/
73 #if defined(USART_CR1_FIFOEN)
74 static void SMARTCARDEx_SetNbDataToProcess(SMARTCARD_HandleTypeDef *hsmartcard);
75 
76 #endif /* USART_CR1_FIFOEN */
77 /* Exported functions --------------------------------------------------------*/
78 /** @defgroup SMARTCARDEx_Exported_Functions  SMARTCARD Extended Exported Functions
79   * @{
80   */
81 
82 /** @defgroup SMARTCARDEx_Exported_Functions_Group1 Extended Peripheral Control functions
83   * @brief    Extended control functions
84   *
85 @verbatim
86   ===============================================================================
87                       ##### Peripheral Control functions #####
88   ===============================================================================
89   [..]
90   This subsection provides a set of functions allowing to initialize the SMARTCARD.
91      (+) HAL_SMARTCARDEx_BlockLength_Config() API allows to configure the Block Length on the fly
92      (+) HAL_SMARTCARDEx_TimeOut_Config() API allows to configure the receiver timeout value on the fly
93      (+) HAL_SMARTCARDEx_EnableReceiverTimeOut() API enables the receiver timeout feature
94      (+) HAL_SMARTCARDEx_DisableReceiverTimeOut() API disables the receiver timeout feature
95 
96 @endverbatim
97   * @{
98   */
99 
100 /** @brief Update on the fly the SMARTCARD block length in RTOR register.
101   * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains
102   *                    the configuration information for the specified SMARTCARD module.
103   * @param BlockLength SMARTCARD block length (8-bit long at most)
104   * @retval None
105   */
HAL_SMARTCARDEx_BlockLength_Config(SMARTCARD_HandleTypeDef * hsmartcard,uint8_t BlockLength)106 void HAL_SMARTCARDEx_BlockLength_Config(SMARTCARD_HandleTypeDef *hsmartcard, uint8_t BlockLength)
107 {
108   MODIFY_REG(hsmartcard->Instance->RTOR, USART_RTOR_BLEN, ((uint32_t)BlockLength << USART_RTOR_BLEN_Pos));
109 }
110 
111 /** @brief Update on the fly the receiver timeout value in RTOR register.
112   * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains
113   *                    the configuration information for the specified SMARTCARD module.
114   * @param TimeOutValue receiver timeout value in number of baud blocks. The timeout
115   *                     value must be less or equal to 0x0FFFFFFFF.
116   * @retval None
117   */
HAL_SMARTCARDEx_TimeOut_Config(SMARTCARD_HandleTypeDef * hsmartcard,uint32_t TimeOutValue)118 void HAL_SMARTCARDEx_TimeOut_Config(SMARTCARD_HandleTypeDef *hsmartcard, uint32_t TimeOutValue)
119 {
120   assert_param(IS_SMARTCARD_TIMEOUT_VALUE(hsmartcard->Init.TimeOutValue));
121   MODIFY_REG(hsmartcard->Instance->RTOR, USART_RTOR_RTO, TimeOutValue);
122 }
123 
124 /** @brief Enable the SMARTCARD receiver timeout feature.
125   * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains
126   *                    the configuration information for the specified SMARTCARD module.
127   * @retval HAL status
128   */
HAL_SMARTCARDEx_EnableReceiverTimeOut(SMARTCARD_HandleTypeDef * hsmartcard)129 HAL_StatusTypeDef HAL_SMARTCARDEx_EnableReceiverTimeOut(SMARTCARD_HandleTypeDef *hsmartcard)
130 {
131   if (hsmartcard->gState == HAL_SMARTCARD_STATE_READY)
132   {
133     /* Process Locked */
134     __HAL_LOCK(hsmartcard);
135 
136     hsmartcard->gState = HAL_SMARTCARD_STATE_BUSY;
137 
138     /* Set the USART RTOEN bit */
139     SET_BIT(hsmartcard->Instance->CR2, USART_CR2_RTOEN);
140 
141     hsmartcard->gState = HAL_SMARTCARD_STATE_READY;
142 
143     /* Process Unlocked */
144     __HAL_UNLOCK(hsmartcard);
145 
146     return HAL_OK;
147   }
148   else
149   {
150     return HAL_BUSY;
151   }
152 }
153 
154 /** @brief Disable the SMARTCARD receiver timeout feature.
155   * @param hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains
156   *                    the configuration information for the specified SMARTCARD module.
157   * @retval HAL status
158   */
HAL_SMARTCARDEx_DisableReceiverTimeOut(SMARTCARD_HandleTypeDef * hsmartcard)159 HAL_StatusTypeDef HAL_SMARTCARDEx_DisableReceiverTimeOut(SMARTCARD_HandleTypeDef *hsmartcard)
160 {
161   if (hsmartcard->gState == HAL_SMARTCARD_STATE_READY)
162   {
163     /* Process Locked */
164     __HAL_LOCK(hsmartcard);
165 
166     hsmartcard->gState = HAL_SMARTCARD_STATE_BUSY;
167 
168     /* Clear the USART RTOEN bit */
169     CLEAR_BIT(hsmartcard->Instance->CR2, USART_CR2_RTOEN);
170 
171     hsmartcard->gState = HAL_SMARTCARD_STATE_READY;
172 
173     /* Process Unlocked */
174     __HAL_UNLOCK(hsmartcard);
175 
176     return HAL_OK;
177   }
178   else
179   {
180     return HAL_BUSY;
181   }
182 }
183 
184 /**
185   * @}
186   */
187 
188 /** @defgroup SMARTCARDEx_Exported_Functions_Group2 Extended Peripheral IO operation functions
189   * @brief   SMARTCARD Transmit and Receive functions
190   *
191 @verbatim
192  ===============================================================================
193                       ##### IO operation functions #####
194  ===============================================================================
195     [..]
196     This subsection provides a set of FIFO mode related callback functions.
197 
198     (#) TX/RX Fifos Callbacks:
199         (++) HAL_SMARTCARDEx_RxFifoFullCallback()
200         (++) HAL_SMARTCARDEx_TxFifoEmptyCallback()
201 
202 @endverbatim
203   * @{
204   */
205 
206 #if defined(USART_CR1_FIFOEN)
207 /**
208   * @brief  SMARTCARD RX Fifo full callback.
209   * @param  hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains
210   *                   the configuration information for the specified SMARTCARD module.
211   * @retval None
212   */
HAL_SMARTCARDEx_RxFifoFullCallback(SMARTCARD_HandleTypeDef * hsmartcard)213 __weak void HAL_SMARTCARDEx_RxFifoFullCallback(SMARTCARD_HandleTypeDef *hsmartcard)
214 {
215   /* Prevent unused argument(s) compilation warning */
216   UNUSED(hsmartcard);
217 
218   /* NOTE : This function should not be modified, when the callback is needed,
219             the HAL_SMARTCARDEx_RxFifoFullCallback can be implemented in the user file.
220    */
221 }
222 
223 /**
224   * @brief  SMARTCARD TX Fifo empty callback.
225   * @param  hsmartcard Pointer to a SMARTCARD_HandleTypeDef structure that contains
226   *                   the configuration information for the specified SMARTCARD module.
227   * @retval None
228   */
HAL_SMARTCARDEx_TxFifoEmptyCallback(SMARTCARD_HandleTypeDef * hsmartcard)229 __weak void HAL_SMARTCARDEx_TxFifoEmptyCallback(SMARTCARD_HandleTypeDef *hsmartcard)
230 {
231   /* Prevent unused argument(s) compilation warning */
232   UNUSED(hsmartcard);
233 
234   /* NOTE : This function should not be modified, when the callback is needed,
235             the HAL_SMARTCARDEx_TxFifoEmptyCallback can be implemented in the user file.
236    */
237 }
238 
239 #endif /* USART_CR1_FIFOEN */
240 /**
241   * @}
242   */
243 
244 /** @defgroup SMARTCARDEx_Exported_Functions_Group3 Extended Peripheral FIFO Control functions
245   *  @brief   SMARTCARD control functions
246   *
247 @verbatim
248  ===============================================================================
249                   ##### Peripheral FIFO Control functions #####
250  ===============================================================================
251     [..]
252     This subsection provides a set of functions allowing to control the SMARTCARD
253     FIFO feature.
254      (+) HAL_SMARTCARDEx_EnableFifoMode() API enables the FIFO mode
255      (+) HAL_SMARTCARDEx_DisableFifoMode() API disables the FIFO mode
256      (+) HAL_SMARTCARDEx_SetTxFifoThreshold() API sets the TX FIFO threshold
257      (+) HAL_SMARTCARDEx_SetRxFifoThreshold() API sets the RX FIFO threshold
258 @endverbatim
259   * @{
260   */
261 
262 #if defined(USART_CR1_FIFOEN)
263 /**
264   * @brief  Enable the FIFO mode.
265   * @param hsmartcard SMARTCARD handle.
266   * @retval HAL status
267   */
HAL_SMARTCARDEx_EnableFifoMode(SMARTCARD_HandleTypeDef * hsmartcard)268 HAL_StatusTypeDef HAL_SMARTCARDEx_EnableFifoMode(SMARTCARD_HandleTypeDef *hsmartcard)
269 {
270   uint32_t tmpcr1;
271 
272   /* Check parameters */
273   assert_param(IS_UART_FIFO_INSTANCE(hsmartcard->Instance));
274 
275   /* Process Locked */
276   __HAL_LOCK(hsmartcard);
277 
278   hsmartcard->gState = HAL_SMARTCARD_STATE_BUSY;
279 
280   /* Save actual SMARTCARD configuration */
281   tmpcr1 = READ_REG(hsmartcard->Instance->CR1);
282 
283   /* Disable SMARTCARD */
284   __HAL_SMARTCARD_DISABLE(hsmartcard);
285 
286   /* Enable FIFO mode */
287   SET_BIT(tmpcr1, USART_CR1_FIFOEN);
288   hsmartcard->FifoMode = SMARTCARD_FIFOMODE_ENABLE;
289 
290   /* Restore SMARTCARD configuration */
291   WRITE_REG(hsmartcard->Instance->CR1, tmpcr1);
292 
293   /* Determine the number of data to process during RX/TX ISR execution */
294   SMARTCARDEx_SetNbDataToProcess(hsmartcard);
295 
296   hsmartcard->gState = HAL_SMARTCARD_STATE_READY;
297 
298   /* Process Unlocked */
299   __HAL_UNLOCK(hsmartcard);
300 
301   return HAL_OK;
302 }
303 
304 /**
305   * @brief  Disable the FIFO mode.
306   * @param hsmartcard SMARTCARD handle.
307   * @retval HAL status
308   */
HAL_SMARTCARDEx_DisableFifoMode(SMARTCARD_HandleTypeDef * hsmartcard)309 HAL_StatusTypeDef HAL_SMARTCARDEx_DisableFifoMode(SMARTCARD_HandleTypeDef *hsmartcard)
310 {
311   uint32_t tmpcr1;
312 
313   /* Check parameters */
314   assert_param(IS_UART_FIFO_INSTANCE(hsmartcard->Instance));
315 
316   /* Process Locked */
317   __HAL_LOCK(hsmartcard);
318 
319   hsmartcard->gState = HAL_SMARTCARD_STATE_BUSY;
320 
321   /* Save actual SMARTCARD configuration */
322   tmpcr1 = READ_REG(hsmartcard->Instance->CR1);
323 
324   /* Disable SMARTCARD */
325   __HAL_SMARTCARD_DISABLE(hsmartcard);
326 
327   /* Enable FIFO mode */
328   CLEAR_BIT(tmpcr1, USART_CR1_FIFOEN);
329   hsmartcard->FifoMode = SMARTCARD_FIFOMODE_DISABLE;
330 
331   /* Restore SMARTCARD configuration */
332   WRITE_REG(hsmartcard->Instance->CR1, tmpcr1);
333 
334   hsmartcard->gState = HAL_SMARTCARD_STATE_READY;
335 
336   /* Process Unlocked */
337   __HAL_UNLOCK(hsmartcard);
338 
339   return HAL_OK;
340 }
341 
342 /**
343   * @brief  Set the TXFIFO threshold.
344   * @param hsmartcard      SMARTCARD handle.
345   * @param Threshold  TX FIFO threshold value
346   *          This parameter can be one of the following values:
347   *            @arg @ref SMARTCARD_TXFIFO_THRESHOLD_1_8
348   *            @arg @ref SMARTCARD_TXFIFO_THRESHOLD_1_4
349   *            @arg @ref SMARTCARD_TXFIFO_THRESHOLD_1_2
350   *            @arg @ref SMARTCARD_TXFIFO_THRESHOLD_3_4
351   *            @arg @ref SMARTCARD_TXFIFO_THRESHOLD_7_8
352   *            @arg @ref SMARTCARD_TXFIFO_THRESHOLD_8_8
353   * @retval HAL status
354   */
HAL_SMARTCARDEx_SetTxFifoThreshold(SMARTCARD_HandleTypeDef * hsmartcard,uint32_t Threshold)355 HAL_StatusTypeDef HAL_SMARTCARDEx_SetTxFifoThreshold(SMARTCARD_HandleTypeDef *hsmartcard, uint32_t Threshold)
356 {
357   uint32_t tmpcr1;
358 
359   /* Check parameters */
360   assert_param(IS_UART_FIFO_INSTANCE(hsmartcard->Instance));
361   assert_param(IS_SMARTCARD_TXFIFO_THRESHOLD(Threshold));
362 
363   /* Process Locked */
364   __HAL_LOCK(hsmartcard);
365 
366   hsmartcard->gState = HAL_SMARTCARD_STATE_BUSY;
367 
368   /* Save actual SMARTCARD configuration */
369   tmpcr1 = READ_REG(hsmartcard->Instance->CR1);
370 
371   /* Disable SMARTCARD */
372   __HAL_SMARTCARD_DISABLE(hsmartcard);
373 
374   /* Update TX threshold configuration */
375   MODIFY_REG(hsmartcard->Instance->CR3, USART_CR3_TXFTCFG, Threshold);
376 
377   /* Determine the number of data to process during RX/TX ISR execution */
378   SMARTCARDEx_SetNbDataToProcess(hsmartcard);
379 
380   /* Restore SMARTCARD configuration */
381   MODIFY_REG(hsmartcard->Instance->CR1, USART_CR1_UE, tmpcr1);
382 
383   hsmartcard->gState = HAL_SMARTCARD_STATE_READY;
384 
385   /* Process Unlocked */
386   __HAL_UNLOCK(hsmartcard);
387 
388   return HAL_OK;
389 }
390 
391 /**
392   * @brief  Set the RXFIFO threshold.
393   * @param hsmartcard      SMARTCARD handle.
394   * @param Threshold  RX FIFO threshold value
395   *          This parameter can be one of the following values:
396   *            @arg @ref SMARTCARD_RXFIFO_THRESHOLD_1_8
397   *            @arg @ref SMARTCARD_RXFIFO_THRESHOLD_1_4
398   *            @arg @ref SMARTCARD_RXFIFO_THRESHOLD_1_2
399   *            @arg @ref SMARTCARD_RXFIFO_THRESHOLD_3_4
400   *            @arg @ref SMARTCARD_RXFIFO_THRESHOLD_7_8
401   *            @arg @ref SMARTCARD_RXFIFO_THRESHOLD_8_8
402   * @retval HAL status
403   */
HAL_SMARTCARDEx_SetRxFifoThreshold(SMARTCARD_HandleTypeDef * hsmartcard,uint32_t Threshold)404 HAL_StatusTypeDef HAL_SMARTCARDEx_SetRxFifoThreshold(SMARTCARD_HandleTypeDef *hsmartcard, uint32_t Threshold)
405 {
406   uint32_t tmpcr1;
407 
408   /* Check parameters */
409   assert_param(IS_UART_FIFO_INSTANCE(hsmartcard->Instance));
410   assert_param(IS_SMARTCARD_RXFIFO_THRESHOLD(Threshold));
411 
412   /* Process Locked */
413   __HAL_LOCK(hsmartcard);
414 
415   hsmartcard->gState = HAL_SMARTCARD_STATE_BUSY;
416 
417   /* Save actual SMARTCARD configuration */
418   tmpcr1 = READ_REG(hsmartcard->Instance->CR1);
419 
420   /* Disable SMARTCARD */
421   __HAL_SMARTCARD_DISABLE(hsmartcard);
422 
423   /* Update RX threshold configuration */
424   MODIFY_REG(hsmartcard->Instance->CR3, USART_CR3_RXFTCFG, Threshold);
425 
426   /* Determine the number of data to process during RX/TX ISR execution */
427   SMARTCARDEx_SetNbDataToProcess(hsmartcard);
428 
429   /* Restore SMARTCARD configuration */
430   MODIFY_REG(hsmartcard->Instance->CR1, USART_CR1_UE, tmpcr1);
431 
432   hsmartcard->gState = HAL_SMARTCARD_STATE_READY;
433 
434   /* Process Unlocked */
435   __HAL_UNLOCK(hsmartcard);
436 
437   return HAL_OK;
438 }
439 #endif /* USART_CR1_FIFOEN */
440 
441 /**
442   * @}
443   */
444 
445 /**
446   * @}
447   */
448 
449 /** @defgroup SMARTCARDEx_Private_Functions  SMARTCARD Extended Private Functions
450   * @{
451   */
452 
453 #if defined(USART_CR1_FIFOEN)
454 /**
455   * @brief Calculate the number of data to process in RX/TX ISR.
456   * @note The RX FIFO depth and the TX FIFO depth is extracted from
457   *       the USART configuration registers.
458   * @param hsmartcard SMARTCARD handle.
459   * @retval None
460   */
SMARTCARDEx_SetNbDataToProcess(SMARTCARD_HandleTypeDef * hsmartcard)461 static void SMARTCARDEx_SetNbDataToProcess(SMARTCARD_HandleTypeDef *hsmartcard)
462 {
463   uint8_t rx_fifo_depth;
464   uint8_t tx_fifo_depth;
465   uint8_t rx_fifo_threshold;
466   uint8_t tx_fifo_threshold;
467   /* 2 0U/1U added for MISRAC2012-Rule-18.1_b and MISRAC2012-Rule-18.1_d */
468   static const uint8_t numerator[]   = {1U, 1U, 1U, 3U, 7U, 1U, 0U, 0U};
469   static const uint8_t denominator[] = {8U, 4U, 2U, 4U, 8U, 1U, 1U, 1U};
470 
471   if (hsmartcard->FifoMode == SMARTCARD_FIFOMODE_DISABLE)
472   {
473     hsmartcard->NbTxDataToProcess = 1U;
474     hsmartcard->NbRxDataToProcess = 1U;
475   }
476   else
477   {
478     rx_fifo_depth = RX_FIFO_DEPTH;
479     tx_fifo_depth = TX_FIFO_DEPTH;
480     rx_fifo_threshold = (uint8_t)(READ_BIT(hsmartcard->Instance->CR3, USART_CR3_RXFTCFG) >> USART_CR3_RXFTCFG_Pos);
481     tx_fifo_threshold = (uint8_t)(READ_BIT(hsmartcard->Instance->CR3, USART_CR3_TXFTCFG) >> USART_CR3_TXFTCFG_Pos);
482     hsmartcard->NbTxDataToProcess = ((uint16_t)tx_fifo_depth * numerator[tx_fifo_threshold]) / \
483                                     (uint16_t)denominator[tx_fifo_threshold];
484     hsmartcard->NbRxDataToProcess = ((uint16_t)rx_fifo_depth * numerator[rx_fifo_threshold]) / \
485                                     (uint16_t)denominator[rx_fifo_threshold];
486   }
487 }
488 
489 #endif /* USART_CR1_FIFOEN */
490 /**
491   * @}
492   */
493 
494 #endif /* HAL_SMARTCARD_MODULE_ENABLED */
495 
496 /**
497   * @}
498   */
499 
500 /**
501   * @}
502   */
503 
504