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