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