1 /**
2 ******************************************************************************
3 * @file stm32g0xx_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) 2018 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 "stm32g0xx_hal.h"
45
46 /** @addtogroup STM32G0xx_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