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