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