sidestep
[mTask.git] / int / com / lib / STM32F7xx_HAL_Driver / Src / stm32f7xx_hal_smartcard.c
1 /**
2 ******************************************************************************
3 * @file stm32f7xx_hal_smartcard.c
4 * @author MCD Application Team
5 * @version V1.1.0
6 * @date 22-April-2016
7 * @brief SMARTCARD HAL module driver.
8 * This file provides firmware functions to manage the following
9 * functionalities of the SMARTCARD peripheral:
10 * + Initialization and de-initialization functions
11 * + IO operation functions
12 * + Peripheral State and Errors functions
13 *
14 @verbatim
15 ==============================================================================
16 ##### How to use this driver #####
17 ==============================================================================
18 [..]
19 The SMARTCARD HAL driver can be used as follow:
20
21 (#) Declare a SMARTCARD_HandleTypeDef handle structure.
22 (#) Associate a USART to the SMARTCARD handle hsc.
23 (#) Initialize the SMARTCARD low level resources by implementing the HAL_SMARTCARD_MspInit() API:
24 (##) Enable the USARTx interface clock.
25 (##) SMARTCARD pins configuration:
26 (+++) Enable the clock for the SMARTCARD GPIOs.
27 (+++) Configure these SMARTCARD pins as alternate function pull-up.
28 (##) NVIC configuration if you need to use interrupt process (HAL_SMARTCARD_Transmit_IT()
29 and HAL_SMARTCARD_Receive_IT() APIs):
30 (+++) Configure the USARTx interrupt priority.
31 (+++) Enable the NVIC USART IRQ handle.
32 (+++) The specific USART interrupts (Transmission complete interrupt,
33 RXNE interrupt and Error Interrupts) will be managed using the macros
34 __HAL_SMARTCARD_ENABLE_IT() and __HAL_SMARTCARD_DISABLE_IT() inside the transmit and receive process.
35 (##) DMA Configuration if you need to use DMA process (HAL_SMARTCARD_Transmit_DMA()
36 and HAL_SMARTCARD_Receive_DMA() APIs):
37 (+++) Declare a DMA handle structure for the Tx/Rx stream.
38 (+++) Enable the DMAx interface clock.
39 (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.
40 (+++) Configure the DMA Tx/Rx Stream.
41 (+++) Associate the initialized DMA handle to the SMARTCARD DMA Tx/Rx handle.
42 (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx Stream.
43
44 (#) Program the Baud Rate, Parity, Mode(Receiver/Transmitter), clock enabling/disabling and accordingly,
45 the clock parameters (parity, phase, last bit), prescaler value, guard time and NACK on transmission
46 error enabling or disabling in the hsc Init structure.
47
48 (#) If required, program SMARTCARD advanced features (TX/RX pins swap, TimeOut, auto-retry counter,...)
49 in the hsc AdvancedInit structure.
50
51 (#) Initialize the SMARTCARD associated USART registers by calling
52 the HAL_SMARTCARD_Init() API.
53
54 [..]
55 (@) HAL_SMARTCARD_Init() API also configure also the low level Hardware GPIO, CLOCK, CORTEX...etc) by
56 calling the customized HAL_SMARTCARD_MspInit() API.
57
58 @endverbatim
59 ******************************************************************************
60 * @attention
61 *
62 * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
63 *
64 * Redistribution and use in source and binary forms, with or without modification,
65 * are permitted provided that the following conditions are met:
66 * 1. Redistributions of source code must retain the above copyright notice,
67 * this list of conditions and the following disclaimer.
68 * 2. Redistributions in binary form must reproduce the above copyright notice,
69 * this list of conditions and the following disclaimer in the documentation
70 * and/or other materials provided with the distribution.
71 * 3. Neither the name of STMicroelectronics nor the names of its contributors
72 * may be used to endorse or promote products derived from this software
73 * without specific prior written permission.
74 *
75 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
76 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
77 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
78 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
79 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
80 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
81 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
82 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
83 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
84 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
85 *
86 ******************************************************************************
87 */
88
89 /* Includes ------------------------------------------------------------------*/
90 #include "stm32f7xx_hal.h"
91
92 /** @addtogroup STM32F7xx_HAL_Driver
93 * @{
94 */
95
96 /** @defgroup SMARTCARD SMARTCARD
97 * @brief HAL USART SMARTCARD module driver
98 * @{
99 */
100 #ifdef HAL_SMARTCARD_MODULE_ENABLED
101 /* Private typedef -----------------------------------------------------------*/
102 /* Private define ------------------------------------------------------------*/
103 /** @defgroup SMARTCARD_Private_Constants SMARTCARD Private Constants
104 * @{
105 */
106 #define TEACK_REACK_TIMEOUT 1000U
107 #define HAL_SMARTCARD_TXDMA_TIMEOUTVALUE 22000U
108 #define USART_CR1_FIELDS ((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | \
109 USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8))
110 #define USART_CR2_CLK_FIELDS ((uint32_t)(USART_CR2_CLKEN|USART_CR2_CPOL|USART_CR2_CPHA|USART_CR2_LBCL))
111 #define USART_CR2_FIELDS ((uint32_t)(USART_CR2_RTOEN|USART_CR2_CLK_FIELDS|USART_CR2_STOP))
112 #define USART_CR3_FIELDS ((uint32_t)(USART_CR3_ONEBIT|USART_CR3_NACK|USART_CR3_SCARCNT))
113 /**
114 * @}
115 */
116 /* Private macros -------------------------------------------------------------*/
117 /* Private variables ---------------------------------------------------------*/
118 /* Private function prototypes -----------------------------------------------*/
119 /** @addtogroup SMARTCARD_Private_Functions
120 * @{
121 */
122 static void SMARTCARD_DMATransmitCplt(DMA_HandleTypeDef *hdma);
123 static void SMARTCARD_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
124 static void SMARTCARD_DMAError(DMA_HandleTypeDef *hdma);
125 static void SMARTCARD_DMAAbortOnError(DMA_HandleTypeDef *hdma);
126 static void SMARTCARD_SetConfig(SMARTCARD_HandleTypeDef *hsc);
127 static HAL_StatusTypeDef SMARTCARD_WaitOnFlagUntilTimeout(SMARTCARD_HandleTypeDef *hsc, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout);
128 static HAL_StatusTypeDef SMARTCARD_CheckIdleState(SMARTCARD_HandleTypeDef *hsc);
129 static HAL_StatusTypeDef SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef *hsc);
130 static HAL_StatusTypeDef SMARTCARD_Receive_IT(SMARTCARD_HandleTypeDef *hsc);
131 static void SMARTCARD_EndTxTransfer(SMARTCARD_HandleTypeDef *hsc);
132 static void SMARTCARD_EndRxTransfer(SMARTCARD_HandleTypeDef *hsc);
133 static void SMARTCARD_AdvFeatureConfig(SMARTCARD_HandleTypeDef *hsc);
134 /**
135 * @}
136 */
137 /* Exported functions --------------------------------------------------------*/
138 /** @defgroup SMARTCARD_Exported_Functions SMARTCARD Exported Functions
139 * @{
140 */
141
142 /** @defgroup SMARTCARD_Exported_Functions_Group1 SmartCard Initialization and de-initialization functions
143 * @brief Initialization and Configuration functions
144 *
145 @verbatim
146 ===============================================================================
147 ##### Initialization and Configuration functions #####
148 ===============================================================================
149 [..]
150 This subsection provides a set of functions allowing to initialize the USART
151 associated to the SmartCard.
152 (+) These parameters can be configured:
153 (++) Baud Rate
154 (++) Parity: parity should be enabled,
155 Frame Length is fixed to 8 bits plus parity.
156 (++) Receiver/transmitter modes
157 (++) Synchronous mode (and if enabled, phase, polarity and last bit parameters)
158 (++) Prescaler value
159 (++) Guard bit time
160 (++) NACK enabling or disabling on transmission error
161
162 (+) The following advanced features can be configured as well:
163 (++) TX and/or RX pin level inversion
164 (++) data logical level inversion
165 (++) RX and TX pins swap
166 (++) RX overrun detection disabling
167 (++) DMA disabling on RX error
168 (++) MSB first on communication line
169 (++) Time out enabling (and if activated, timeout value)
170 (++) Block length
171 (++) Auto-retry counter
172
173 [..]
174 The HAL_SMARTCARD_Init() API follow respectively the USART (a)synchronous configuration procedures
175 (details for the procedures are available in reference manual).
176
177 @endverbatim
178
179 The USART frame format is given in the following table:
180
181 +---------------------------------------------------------------+
182 | M1M0 bits | PCE bit | USART frame |
183 |-----------------------|---------------------------------------|
184 | 01 | 1 | | SB | 8 bit data | PB | STB | |
185 +---------------------------------------------------------------+
186
187 * @{
188 */
189
190 /**
191 * @brief Initializes the SMARTCARD mode according to the specified
192 * parameters in the SMARTCARD_InitTypeDef and create the associated handle .
193 * @param hsc: SMARTCARD handle
194 * @retval HAL status
195 */
196 HAL_StatusTypeDef HAL_SMARTCARD_Init(SMARTCARD_HandleTypeDef *hsc)
197 {
198 /* Check the SMARTCARD handle allocation */
199 if(hsc == NULL)
200 {
201 return HAL_ERROR;
202 }
203
204 /* Check the parameters */
205 assert_param(IS_SMARTCARD_INSTANCE(hsc->Instance));
206
207 if(hsc->gState == HAL_SMARTCARD_STATE_RESET)
208 {
209 /* Allocate lock resource and initialize it */
210 hsc->Lock = HAL_UNLOCKED;
211 /* Init the low level hardware : GPIO, CLOCK, CORTEX */
212 HAL_SMARTCARD_MspInit(hsc);
213 }
214
215 hsc->gState = HAL_SMARTCARD_STATE_BUSY;
216
217 /* Disable the Peripheral */
218 __HAL_SMARTCARD_DISABLE(hsc);
219
220 /* Set the SMARTCARD Communication parameters */
221 SMARTCARD_SetConfig(hsc);
222
223 if(hsc->AdvancedInit.AdvFeatureInit != SMARTCARD_ADVFEATURE_NO_INIT)
224 {
225 SMARTCARD_AdvFeatureConfig(hsc);
226 }
227
228 /* In SmartCard mode, the following bits must be kept cleared:
229 - LINEN in the USART_CR2 register,
230 - HDSEL and IREN bits in the USART_CR3 register.*/
231 CLEAR_BIT(hsc->Instance->CR2, USART_CR2_LINEN);
232 CLEAR_BIT(hsc->Instance->CR3, (USART_CR3_IREN | USART_CR3_HDSEL));
233
234 /* set the USART in SMARTCARD mode */
235 SET_BIT(hsc->Instance->CR3, USART_CR3_SCEN);
236
237 /* Enable the Peripheral */
238 __HAL_SMARTCARD_ENABLE(hsc);
239
240 /* TEACK and/or REACK to check before moving hsc->State to Ready */
241 return (SMARTCARD_CheckIdleState(hsc));
242 }
243
244 /**
245 * @brief DeInitializes the SMARTCARD peripheral
246 * @param hsc: SMARTCARD handle
247 * @retval HAL status
248 */
249 HAL_StatusTypeDef HAL_SMARTCARD_DeInit(SMARTCARD_HandleTypeDef *hsc)
250 {
251 /* Check the SMARTCARD handle allocation */
252 if(hsc == NULL)
253 {
254 return HAL_ERROR;
255 }
256
257 /* Check the parameters */
258 assert_param(IS_SMARTCARD_INSTANCE(hsc->Instance));
259
260 hsc->gState = HAL_SMARTCARD_STATE_BUSY;
261
262 /* DeInit the low level hardware */
263 HAL_SMARTCARD_MspDeInit(hsc);
264
265 hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
266 hsc->gState = HAL_SMARTCARD_STATE_RESET;
267 hsc->RxState = HAL_SMARTCARD_STATE_RESET;
268
269 /* Release Lock */
270 __HAL_UNLOCK(hsc);
271
272 return HAL_OK;
273 }
274
275 /**
276 * @brief SMARTCARD MSP Init
277 * @param hsc: SMARTCARD handle
278 * @retval None
279 */
280 __weak void HAL_SMARTCARD_MspInit(SMARTCARD_HandleTypeDef *hsc)
281 {
282 /* Prevent unused argument(s) compilation warning */
283 UNUSED(hsc);
284
285 /* NOTE : This function Should not be modified, when the callback is needed,
286 the HAL_SMARTCARD_MspInit could be implemented in the user file
287 */
288 }
289
290 /**
291 * @brief SMARTCARD MSP DeInit
292 * @param hsc: SMARTCARD handle
293 * @retval None
294 */
295 __weak void HAL_SMARTCARD_MspDeInit(SMARTCARD_HandleTypeDef *hsc)
296 {
297 /* Prevent unused argument(s) compilation warning */
298 UNUSED(hsc);
299
300 /* NOTE : This function Should not be modified, when the callback is needed,
301 the HAL_SMARTCARD_MspDeInit could be implemented in the user file
302 */
303 }
304
305 /**
306 * @}
307 */
308
309 /** @defgroup SMARTCARD_Exported_Functions_Group2 IO operation functions
310 * @brief SMARTCARD Transmit and Receive functions
311 *
312 @verbatim
313 ===============================================================================
314 ##### IO operation functions #####
315 ===============================================================================
316 This subsection provides a set of functions allowing to manage the SMARTCARD data transfers.
317
318 (#) There are two modes of transfer:
319 (+) Blocking mode: The communication is performed in polling mode.
320 The HAL status of all data processing is returned by the same function
321 after finishing transfer.
322 (+) No-Blocking mode: The communication is performed using Interrupts
323 or DMA, These API's return the HAL status.
324 The end of the data processing will be indicated through the
325 dedicated SMARTCARD IRQ when using Interrupt mode or the DMA IRQ when
326 using DMA mode.
327 The HAL_SMARTCARD_TxCpltCallback(), HAL_SMARTCARD_RxCpltCallback() user callbacks
328 will be executed respectively at the end of the Transmit or Receive process
329 The HAL_SMARTCARD_ErrorCallback()user callback will be executed when a communication error is detected
330
331 (#) Blocking mode API's are :
332 (+) HAL_SMARTCARD_Transmit()
333 (+) HAL_SMARTCARD_Receive()
334
335 (#) Non-Blocking mode API's with Interrupt are :
336 (+) HAL_SMARTCARD_Transmit_IT()
337 (+) HAL_SMARTCARD_Receive_IT()
338 (+) HAL_SMARTCARD_IRQHandler()
339 (+) SMARTCARD_Transmit_IT()
340 (+) SMARTCARD_Receive_IT()
341
342 (#) No-Blocking mode functions with DMA are :
343 (+) HAL_SMARTCARD_Transmit_DMA()
344 (+) HAL_SMARTCARD_Receive_DMA()
345
346 (#) A set of Transfer Complete Callbacks are provided in No_Blocking mode:
347 (+) HAL_SMARTCARD_TxCpltCallback()
348 (+) HAL_SMARTCARD_RxCpltCallback()
349 (+) HAL_SMARTCARD_ErrorCallback()
350
351 @endverbatim
352 * @{
353 */
354
355 /**
356 * @brief Send an amount of data in blocking mode
357 * @param hsc: SMARTCARD handle
358 * @param pData: pointer to data buffer
359 * @param Size: amount of data to be sent
360 * @param Timeout: Timeout duration
361 * @retval HAL status
362 */
363 HAL_StatusTypeDef HAL_SMARTCARD_Transmit(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size, uint32_t Timeout)
364 {
365 uint32_t tickstart = 0U;
366
367 if(hsc->gState == HAL_SMARTCARD_STATE_READY)
368 {
369 if((pData == NULL) || (Size == 0U))
370 {
371 return HAL_ERROR;
372 }
373
374 /* Process Locked */
375 __HAL_LOCK(hsc);
376 hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
377 hsc->gState = HAL_SMARTCARD_STATE_BUSY_TX;
378
379 /* Init tickstart for timeout managment*/
380 tickstart = HAL_GetTick();
381
382 hsc->TxXferSize = Size;
383 hsc->TxXferCount = Size;
384 while(hsc->TxXferCount > 0U)
385 {
386 hsc->TxXferCount--;
387 if(SMARTCARD_WaitOnFlagUntilTimeout(hsc, SMARTCARD_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
388 {
389 return HAL_TIMEOUT;
390 }
391 hsc->Instance->TDR = (*pData++ & (uint8_t)0xFFU);
392 }
393 if(SMARTCARD_WaitOnFlagUntilTimeout(hsc, SMARTCARD_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
394 {
395 return HAL_TIMEOUT;
396 }
397
398 /* At end of Tx process, restore hsc->gState to Ready */
399 hsc->gState = HAL_SMARTCARD_STATE_READY;
400
401 /* Process Unlocked */
402 __HAL_UNLOCK(hsc);
403
404 return HAL_OK;
405 }
406 else
407 {
408 return HAL_BUSY;
409 }
410 }
411
412 /**
413 * @brief Receive an amount of data in blocking mode
414 * @param hsc: SMARTCARD handle
415 * @param pData: pointer to data buffer
416 * @param Size: amount of data to be received
417 * @param Timeout: Timeout duration
418 * @retval HAL status
419 */
420 HAL_StatusTypeDef HAL_SMARTCARD_Receive(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size, uint32_t Timeout)
421 {
422 uint32_t tickstart = 0U;
423
424 if(hsc->RxState == HAL_SMARTCARD_STATE_READY)
425 {
426 if((pData == NULL) || (Size == 0U))
427 {
428 return HAL_ERROR;
429 }
430
431 /* Process Locked */
432 __HAL_LOCK(hsc);
433
434 hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
435 hsc->RxState = HAL_SMARTCARD_STATE_BUSY_RX;
436
437 /* Init tickstart for timeout managment*/
438 tickstart = HAL_GetTick();
439
440 hsc->RxXferSize = Size;
441 hsc->RxXferCount = Size;
442 /* Check the remain data to be received */
443 while(hsc->RxXferCount > 0U)
444 {
445 hsc->RxXferCount--;
446 if(SMARTCARD_WaitOnFlagUntilTimeout(hsc, SMARTCARD_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
447 {
448 return HAL_TIMEOUT;
449 }
450 *pData++ = (uint8_t)(hsc->Instance->RDR & (uint8_t)0x00FFU);
451 }
452
453 /* At end of Rx process, restore hsc->RxState to Ready */
454 hsc->RxState = HAL_SMARTCARD_STATE_READY;
455
456 /* Process Unlocked */
457 __HAL_UNLOCK(hsc);
458
459 return HAL_OK;
460 }
461 else
462 {
463 return HAL_BUSY;
464 }
465 }
466
467 /**
468 * @brief Send an amount of data in interrupt mode
469 * @param hsc: SMARTCARD handle
470 * @param pData: pointer to data buffer
471 * @param Size: amount of data to be sent
472 * @retval HAL status
473 */
474 HAL_StatusTypeDef HAL_SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size)
475 {
476 /* Check that a Tx process is not already ongoing */
477 if(hsc->gState == HAL_SMARTCARD_STATE_READY)
478 {
479 if((pData == NULL) || (Size == 0U))
480 {
481 return HAL_ERROR;
482 }
483
484 /* Process Locked */
485 __HAL_LOCK(hsc);
486
487 hsc->pTxBuffPtr = pData;
488 hsc->TxXferSize = Size;
489 hsc->TxXferCount = Size;
490
491 hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
492 hsc->gState = HAL_SMARTCARD_STATE_BUSY_TX;
493
494 /* Process Unlocked */
495 __HAL_UNLOCK(hsc);
496
497 /* Enable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */
498 CLEAR_BIT(hsc->Instance->CR3, USART_CR3_EIE);
499
500 /* Enable the SMARTCARD Transmit Complete Interrupt */
501 CLEAR_BIT(hsc->Instance->CR1, USART_CR1_TCIE);
502
503 return HAL_OK;
504 }
505 else
506 {
507 return HAL_BUSY;
508 }
509 }
510
511 /**
512 * @brief Receive an amount of data in interrupt mode
513 * @param hsc: SMARTCARD handle
514 * @param pData: pointer to data buffer
515 * @param Size: amount of data to be received
516 * @retval HAL status
517 */
518 HAL_StatusTypeDef HAL_SMARTCARD_Receive_IT(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size)
519 {
520 /* Check that a Rx process is not already ongoing */
521 if(hsc->RxState == HAL_SMARTCARD_STATE_READY)
522 {
523 if((pData == NULL) || (Size == 0U))
524 {
525 return HAL_ERROR;
526 }
527
528 /* Process Locked */
529 __HAL_LOCK(hsc);
530
531 hsc->pRxBuffPtr = pData;
532 hsc->RxXferSize = Size;
533 hsc->RxXferCount = Size;
534
535 hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
536 hsc->RxState = HAL_SMARTCARD_STATE_BUSY_RX;
537
538 /* Process Unlocked */
539 __HAL_UNLOCK(hsc);
540
541 /* Enable the SMARTCARD Parity Error Interrupt */
542 SET_BIT(hsc->Instance->CR1, USART_CR1_PEIE);
543
544 /* Enable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */
545 SET_BIT(hsc->Instance->CR3, USART_CR3_EIE);
546
547 /* Enable the SMARTCARD Data Register not empty Interrupt */
548 SET_BIT(hsc->Instance->CR1, USART_CR1_RXNEIE);
549
550 return HAL_OK;
551 }
552 else
553 {
554 return HAL_BUSY;
555 }
556 }
557
558 /**
559 * @brief Send an amount of data in DMA mode
560 * @param hsc: SMARTCARD handle
561 * @param pData: pointer to data buffer
562 * @param Size: amount of data to be sent
563 * @retval HAL status
564 */
565 HAL_StatusTypeDef HAL_SMARTCARD_Transmit_DMA(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size)
566 {
567 uint32_t *tmp;
568
569 /* Check that a Tx process is not already ongoing */
570 if(hsc->gState == HAL_SMARTCARD_STATE_READY)
571 {
572 if((pData == NULL) || (Size == 0U))
573 {
574 return HAL_ERROR;
575 }
576
577 /* Process Locked */
578 __HAL_LOCK(hsc);
579
580 hsc->pTxBuffPtr = pData;
581 hsc->TxXferSize = Size;
582 hsc->TxXferCount = Size;
583
584 hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
585 hsc->gState = HAL_SMARTCARD_STATE_BUSY_TX;
586
587 /* Set the SMARTCARD DMA transfer complete callback */
588 hsc->hdmatx->XferCpltCallback = SMARTCARD_DMATransmitCplt;
589
590 /* Set the SMARTCARD error callback */
591 hsc->hdmatx->XferErrorCallback = SMARTCARD_DMAError;
592
593 /* Set the DMA abort callback */
594 hsc->hdmatx->XferAbortCallback = NULL;
595
596 /* Enable the SMARTCARD transmit DMA Stream */
597 tmp = (uint32_t*)&pData;
598 HAL_DMA_Start_IT(hsc->hdmatx, *(uint32_t*)tmp, (uint32_t)&hsc->Instance->TDR, Size);
599
600 /* Clear the TC flag in the SR register by writing 0 to it */
601 __HAL_SMARTCARD_CLEAR_IT(hsc, SMARTCARD_FLAG_TC);
602
603 /* Process Unlocked */
604 __HAL_UNLOCK(hsc);
605
606 /* Enable the DMA transfer for transmit request by setting the DMAT bit
607 in the SMARTCARD associated USART CR3 register */
608 SET_BIT(hsc->Instance->CR3, USART_CR3_DMAT);
609
610 return HAL_OK;
611 }
612 else
613 {
614 return HAL_BUSY;
615 }
616 }
617
618 /**
619 * @brief Receive an amount of data in DMA mode
620 * @param hsc: SMARTCARD handle
621 * @param pData: pointer to data buffer
622 * @param Size: amount of data to be received
623 * @note The SMARTCARD-associated USART parity is enabled (PCE = 1),
624 * the received data contain the parity bit (MSB position)
625 * @retval HAL status
626 */
627 HAL_StatusTypeDef HAL_SMARTCARD_Receive_DMA(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size)
628 {
629 uint32_t *tmp;
630
631 /* Check that a Rx process is not already ongoing */
632 if(hsc->RxState == HAL_SMARTCARD_STATE_READY)
633 {
634 if((pData == NULL) || (Size == 0U))
635 {
636 return HAL_ERROR;
637 }
638
639 /* Process Locked */
640 __HAL_LOCK(hsc);
641
642 hsc->pRxBuffPtr = pData;
643 hsc->RxXferSize = Size;
644
645 hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
646 hsc->RxState = HAL_SMARTCARD_STATE_BUSY_RX;
647
648 /* Set the SMARTCARD DMA transfer complete callback */
649 hsc->hdmarx->XferCpltCallback = SMARTCARD_DMAReceiveCplt;
650
651 /* Set the SMARTCARD DMA error callback */
652 hsc->hdmarx->XferErrorCallback = SMARTCARD_DMAError;
653
654 /* Set the DMA abort callback */
655 hsc->hdmatx->XferAbortCallback = NULL;
656
657 /* Enable the DMA Stream */
658 tmp = (uint32_t*)&pData;
659 HAL_DMA_Start_IT(hsc->hdmarx, (uint32_t)&hsc->Instance->RDR, *(uint32_t*)tmp, Size);
660
661 /* Process Unlocked */
662 __HAL_UNLOCK(hsc);
663
664 /* Enable the SMARTCARD Parity Error Interrupt */
665 SET_BIT(hsc->Instance->CR1, USART_CR1_PEIE);
666
667 /* Enable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */
668 SET_BIT(hsc->Instance->CR3, USART_CR3_EIE);
669
670 /* Enable the DMA transfer for the receiver request by setting the DMAR bit
671 in the SMARTCARD associated USART CR3 register */
672 SET_BIT(hsc->Instance->CR3, USART_CR3_DMAR);
673
674 return HAL_OK;
675 }
676 else
677 {
678 return HAL_BUSY;
679 }
680 }
681
682 /**
683 * @brief SMARTCARD interrupt requests handling.
684 * @param hsc: SMARTCARD handle
685 * @retval None
686 */
687 void HAL_SMARTCARD_IRQHandler(SMARTCARD_HandleTypeDef *hsc)
688 {
689 uint32_t isrflags = READ_REG(hsc->Instance->ISR);
690 uint32_t cr1its = READ_REG(hsc->Instance->CR1);
691 uint32_t cr3its = READ_REG(hsc->Instance->CR3);
692 uint32_t dmarequest = 0x00U;
693 uint32_t errorflags = 0x00U;
694
695 /* If no error occurs */
696 errorflags = (isrflags & (uint32_t)(USART_ISR_PE | USART_ISR_FE | USART_ISR_ORE | USART_ISR_NE));
697 if(errorflags == RESET)
698 {
699 /* SMARTCARD in mode Receiver -------------------------------------------------*/
700 if(((isrflags & USART_ISR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
701 {
702 SMARTCARD_Receive_IT(hsc);
703 return;
704 }
705 }
706
707 /* If some errors occur */
708 if((errorflags != RESET) && ((cr3its & (USART_CR3_EIE | USART_CR1_PEIE)) != RESET))
709 {
710 /* SMARTCARD parity error interrupt occurred ---------------------------*/
711 if(((isrflags & SMARTCARD_FLAG_PE) != RESET) && ((cr1its & USART_CR1_PEIE) != RESET))
712 {
713 hsc->ErrorCode |= HAL_SMARTCARD_ERROR_PE;
714 }
715
716 /* SMARTCARD frame error interrupt occurred ----------------------------*/
717 if(((isrflags & SMARTCARD_FLAG_FE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
718 {
719 hsc->ErrorCode |= HAL_SMARTCARD_ERROR_FE;
720 }
721
722 /* SMARTCARD noise error interrupt occurred ----------------------------*/
723 if(((isrflags & SMARTCARD_FLAG_NE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
724 {
725 hsc->ErrorCode |= HAL_SMARTCARD_ERROR_NE;
726 }
727
728 /* SMARTCARD Over-Run interrupt occurred -------------------------------*/
729 if(((isrflags & SMARTCARD_FLAG_ORE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
730 {
731 hsc->ErrorCode |= HAL_SMARTCARD_ERROR_ORE;
732 }
733 /* Call the Error call Back in case of Errors */
734 if(hsc->ErrorCode != HAL_SMARTCARD_ERROR_NONE)
735 {
736 /* SMARTCARD in mode Receiver -----------------------------------------------*/
737 if(((isrflags & USART_ISR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
738 {
739 SMARTCARD_Receive_IT(hsc);
740 }
741
742 /* If Overrun error occurs, or if any error occurs in DMA mode reception,
743 consider error as blocking */
744 dmarequest = HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAR);
745 if(((hsc->ErrorCode & HAL_SMARTCARD_ERROR_ORE) != RESET) || dmarequest)
746 {
747 /* Blocking error : transfer is aborted
748 Set the SMARTCARD state ready to be able to start again the process,
749 Disable Rx Interrupts, and disable Rx DMA request, if ongoing */
750 SMARTCARD_EndRxTransfer(hsc);
751 /* Disable the SMARTCARD DMA Rx request if enabled */
752 if (HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAR))
753 {
754 CLEAR_BIT(hsc->Instance->CR3, USART_CR3_DMAR);
755
756 /* Abort the SMARTCARD DMA Rx channel */
757 if(hsc->hdmarx != NULL)
758 {
759 /* Set the SMARTCARD DMA Abort callback :
760 will lead to call HAL_SMARTCARD_ErrorCallback() at end of DMA abort procedure */
761 hsc->hdmarx->XferAbortCallback = SMARTCARD_DMAAbortOnError;
762
763 if(HAL_DMA_Abort_IT(hsc->hdmarx) != HAL_OK)
764 {
765 /* Call Directly XferAbortCallback function in case of error */
766 hsc->hdmarx->XferAbortCallback(hsc->hdmarx);
767 }
768 }
769 else
770 {
771 /* Call user error callback */
772 HAL_SMARTCARD_ErrorCallback(hsc);
773 }
774 }
775 else
776 {
777 /* Call user error callback */
778 HAL_SMARTCARD_ErrorCallback(hsc);
779 }
780 }
781 else
782 {
783 /* Call user error callback */
784 HAL_SMARTCARD_ErrorCallback(hsc);
785 hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
786 }
787 }
788 return;
789 } /* End if some error occurs */
790
791 /* SMARTCARD in mode Transmitter -------------------------------------------*/
792 if(((isrflags & SMARTCARD_FLAG_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET))
793 {
794 SMARTCARD_Transmit_IT(hsc);
795 return;
796 }
797
798 /* SMARTCARD in mode Transmitter (transmission end) ------------------------*/
799 if(((isrflags & SMARTCARD_FLAG_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET))
800 {
801 /* Disable the SMARTCARD Transmit Complete Interrupt */
802 CLEAR_BIT(hsc->Instance->CR1, USART_CR1_TCIE);
803
804 /* Disable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */
805 CLEAR_BIT(hsc->Instance->CR3, USART_CR3_EIE);
806
807 /* Tx process is ended, restore hsmartcard->gState to Ready */
808 hsc->gState = HAL_SMARTCARD_STATE_READY;
809
810 HAL_SMARTCARD_TxCpltCallback(hsc);
811
812 return;
813 }
814 }
815
816 /**
817 * @brief Tx Transfer completed callbacks
818 * @param hsc: SMARTCARD handle
819 * @retval None
820 */
821 __weak void HAL_SMARTCARD_TxCpltCallback(SMARTCARD_HandleTypeDef *hsc)
822 {
823 /* Prevent unused argument(s) compilation warning */
824 UNUSED(hsc);
825
826 /* NOTE : This function Should not be modified, when the callback is needed,
827 the HAL_SMARTCARD_TxCpltCallback could be implemented in the user file
828 */
829 }
830
831 /**
832 * @brief Rx Transfer completed callbacks
833 * @param hsc: SMARTCARD handle
834 * @retval None
835 */
836 __weak void HAL_SMARTCARD_RxCpltCallback(SMARTCARD_HandleTypeDef *hsc)
837 {
838 /* Prevent unused argument(s) compilation warning */
839 UNUSED(hsc);
840
841 /* NOTE : This function Should not be modified, when the callback is needed,
842 the HAL_SMARTCARD_TxCpltCallback could be implemented in the user file
843 */
844 }
845
846 /**
847 * @brief SMARTCARD error callbacks
848 * @param hsc: SMARTCARD handle
849 * @retval None
850 */
851 __weak void HAL_SMARTCARD_ErrorCallback(SMARTCARD_HandleTypeDef *hsc)
852 {
853 /* Prevent unused argument(s) compilation warning */
854 UNUSED(hsc);
855
856 /* NOTE : This function Should not be modified, when the callback is needed,
857 the HAL_SMARTCARD_ErrorCallback could be implemented in the user file
858 */
859 }
860
861 /**
862 * @}
863 */
864
865 /** @defgroup SMARTCARD_Exported_Functions_Group3 Peripheral State functions
866 * @brief SMARTCARD State functions
867 *
868 @verbatim
869 ===============================================================================
870 ##### Peripheral State and Errors functions #####
871 ===============================================================================
872 [..]
873 This subsection provides a set of functions allowing to initialize the SMARTCARD.
874 (+) HAL_SMARTCARD_GetState() API is helpful to check in run-time the state of the SMARTCARD peripheral
875 (+) SMARTCARD_SetConfig() API configures the SMARTCARD peripheral
876 (+) SMARTCARD_CheckIdleState() API ensures that TEACK and/or REACK are set after initialization
877
878 @endverbatim
879 * @{
880 */
881
882
883 /**
884 * @brief return the SMARTCARD state
885 * @param hsc: SMARTCARD handle
886 * @retval HAL state
887 */
888 HAL_SMARTCARD_StateTypeDef HAL_SMARTCARD_GetState(SMARTCARD_HandleTypeDef *hsc)
889 {
890 uint32_t temp1= 0x00U, temp2 = 0x00U;
891 temp1 = hsc->gState;
892 temp2 = hsc->RxState;
893
894 return (HAL_SMARTCARD_StateTypeDef)(temp1 | temp2);
895 }
896
897 /**
898 * @brief Return the SMARTCARD error code
899 * @param hsc : pointer to a SMARTCARD_HandleTypeDef structure that contains
900 * the configuration information for the specified SMARTCARD.
901 * @retval SMARTCARD Error Code
902 */
903 uint32_t HAL_SMARTCARD_GetError(SMARTCARD_HandleTypeDef *hsc)
904 {
905 return hsc->ErrorCode;
906 }
907
908 /**
909 * @}
910 */
911
912 /**
913 * @brief Send an amount of data in non blocking mode
914 * @param hsc: SMARTCARD handle.
915 * Function called under interruption only, once
916 * interruptions have been enabled by HAL_SMARTCARD_Transmit_IT()
917 * @retval HAL status
918 */
919 static HAL_StatusTypeDef SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef *hsc)
920 {
921 if(hsc->gState == HAL_SMARTCARD_STATE_BUSY_TX)
922 {
923 if(hsc->TxXferCount == 0)
924 {
925 /* Disable the SMARTCARD Transmit Complete Interrupt */
926 CLEAR_BIT(hsc->Instance->CR1, USART_CR1_TXEIE);
927
928 /* Disable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */
929 CLEAR_BIT(hsc->Instance->CR3, USART_CR3_EIE);
930
931 /* Tx process is ended, restore hsmartcard->gState to Ready */
932 hsc->gState = HAL_SMARTCARD_STATE_READY;
933 }
934
935 HAL_SMARTCARD_TxCpltCallback(hsc);
936
937 return HAL_OK;
938 }
939 else
940 {
941 hsc->Instance->TDR = (*hsc->pTxBuffPtr++ & (uint8_t)0xFFU);
942 hsc->TxXferCount--;
943
944 return HAL_OK;
945 }
946 }
947
948 /**
949 * @brief Receive an amount of data in non blocking mode
950 * @param hsc: SMARTCARD handle.
951 * Function called under interruption only, once
952 * interruptions have been enabled by HAL_SMARTCARD_Receive_IT()
953 * @retval HAL status
954 */
955 static HAL_StatusTypeDef SMARTCARD_Receive_IT(SMARTCARD_HandleTypeDef *hsc)
956 {
957 /* Check that a Rx process is ongoing */
958 if(hsc->RxState == HAL_SMARTCARD_STATE_BUSY_RX)
959 {
960 *hsc->pRxBuffPtr++ = (uint8_t)(hsc->Instance->RDR & (uint8_t)0xFFU);
961
962 if(--hsc->RxXferCount == 0)
963 {
964 CLEAR_BIT(hsc->Instance->CR1, USART_CR1_RXNEIE);
965
966 /* Disable the SMARTCARD Parity Error Interrupt */
967 CLEAR_BIT(hsc->Instance->CR1, USART_CR1_PEIE);
968
969 /* Disable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */
970 CLEAR_BIT(hsc->Instance->CR3, USART_CR3_EIE);
971
972 hsc->RxState = HAL_SMARTCARD_STATE_READY;
973
974 HAL_SMARTCARD_RxCpltCallback(hsc);
975
976 return HAL_OK;
977 }
978
979 return HAL_OK;
980 }
981 else
982 {
983 return HAL_BUSY;
984 }
985 }
986
987 /**
988 * @brief Configure the SMARTCARD associated USART peripheral
989 * @param hsc: SMARTCARD handle
990 * @retval None
991 */
992 static void SMARTCARD_SetConfig(SMARTCARD_HandleTypeDef *hsc)
993 {
994 uint32_t tmpreg = 0x00000000U;
995 uint32_t clocksource = 0x00000000U;
996
997 /* Check the parameters */
998 assert_param(IS_SMARTCARD_INSTANCE(hsc->Instance));
999 assert_param(IS_SMARTCARD_BAUDRATE(hsc->Init.BaudRate));
1000 assert_param(IS_SMARTCARD_WORD_LENGTH(hsc->Init.WordLength));
1001 assert_param(IS_SMARTCARD_STOPBITS(hsc->Init.StopBits));
1002 assert_param(IS_SMARTCARD_PARITY(hsc->Init.Parity));
1003 assert_param(IS_SMARTCARD_MODE(hsc->Init.Mode));
1004 assert_param(IS_SMARTCARD_POLARITY(hsc->Init.CLKPolarity));
1005 assert_param(IS_SMARTCARD_PHASE(hsc->Init.CLKPhase));
1006 assert_param(IS_SMARTCARD_LASTBIT(hsc->Init.CLKLastBit));
1007 assert_param(IS_SMARTCARD_ONE_BIT_SAMPLE(hsc->Init.OneBitSampling));
1008 assert_param(IS_SMARTCARD_NACK(hsc->Init.NACKState));
1009 assert_param(IS_SMARTCARD_TIMEOUT(hsc->Init.TimeOutEnable));
1010 assert_param(IS_SMARTCARD_AUTORETRY_COUNT(hsc->Init.AutoRetryCount));
1011
1012 /*-------------------------- USART CR1 Configuration -----------------------*/
1013 /* In SmartCard mode, M and PCE are forced to 1 (8 bits + parity).
1014 * Oversampling is forced to 16 (OVER8 = 0).
1015 * Configure the Parity and Mode:
1016 * set PS bit according to hsc->Init.Parity value
1017 * set TE and RE bits according to hsc->Init.Mode value */
1018 tmpreg = (uint32_t) hsc->Init.Parity | hsc->Init.Mode;
1019 /* in case of TX-only mode, if NACK is enabled, the USART must be able to monitor
1020 the bidirectional line to detect a NACK signal in case of parity error.
1021 Therefore, the receiver block must be enabled as well (RE bit must be set). */
1022 if((hsc->Init.Mode == SMARTCARD_MODE_TX) && (hsc->Init.NACKState == SMARTCARD_NACK_ENABLE))
1023 {
1024 tmpreg |= USART_CR1_RE;
1025 }
1026 tmpreg |= (uint32_t) hsc->Init.WordLength;
1027 MODIFY_REG(hsc->Instance->CR1, USART_CR1_FIELDS, tmpreg);
1028
1029 /*-------------------------- USART CR2 Configuration -----------------------*/
1030 /* Stop bits are forced to 1.5 (STOP = 11) */
1031 tmpreg = hsc->Init.StopBits;
1032 /* Synchronous mode is activated by default */
1033 tmpreg |= (uint32_t) USART_CR2_CLKEN | hsc->Init.CLKPolarity;
1034 tmpreg |= (uint32_t) hsc->Init.CLKPhase | hsc->Init.CLKLastBit;
1035 tmpreg |= (uint32_t) hsc->Init.TimeOutEnable;
1036 MODIFY_REG(hsc->Instance->CR2, USART_CR2_FIELDS, tmpreg);
1037
1038 /*-------------------------- USART CR3 Configuration -----------------------*/
1039 /* Configure
1040 * - one-bit sampling method versus three samples' majority rule
1041 * according to hsc->Init.OneBitSampling
1042 * - NACK transmission in case of parity error according
1043 * to hsc->Init.NACKEnable
1044 * - autoretry counter according to hsc->Init.AutoRetryCount */
1045 tmpreg = (uint32_t) hsc->Init.OneBitSampling | hsc->Init.NACKState;
1046 tmpreg |= (uint32_t) (hsc->Init.AutoRetryCount << SMARTCARD_CR3_SCARCNT_LSB_POS);
1047 MODIFY_REG(hsc->Instance-> CR3,USART_CR3_FIELDS, tmpreg);
1048
1049 /*-------------------------- USART GTPR Configuration ----------------------*/
1050 tmpreg = (uint32_t) (hsc->Init.Prescaler | (hsc->Init.GuardTime << SMARTCARD_GTPR_GT_LSB_POS));
1051 MODIFY_REG(hsc->Instance->GTPR, (uint32_t)(USART_GTPR_GT|USART_GTPR_PSC), tmpreg);
1052
1053 /*-------------------------- USART RTOR Configuration ----------------------*/
1054 tmpreg = (uint32_t) (hsc->Init.BlockLength << SMARTCARD_RTOR_BLEN_LSB_POS);
1055 if(hsc->Init.TimeOutEnable == SMARTCARD_TIMEOUT_ENABLE)
1056 {
1057 assert_param(IS_SMARTCARD_TIMEOUT_VALUE(hsc->Init.TimeOutValue));
1058 tmpreg |= (uint32_t) hsc->Init.TimeOutValue;
1059 }
1060 MODIFY_REG(hsc->Instance->RTOR, (USART_RTOR_RTO|USART_RTOR_BLEN), tmpreg);
1061
1062 /*-------------------------- USART BRR Configuration -----------------------*/
1063 SMARTCARD_GETCLOCKSOURCE(hsc, clocksource);
1064 switch (clocksource)
1065 {
1066 case SMARTCARD_CLOCKSOURCE_PCLK1:
1067 hsc->Instance->BRR = (uint16_t)((HAL_RCC_GetPCLK1Freq() + (hsc->Init.BaudRate/2))/ hsc->Init.BaudRate);
1068 break;
1069 case SMARTCARD_CLOCKSOURCE_PCLK2:
1070 hsc->Instance->BRR = (uint16_t)((HAL_RCC_GetPCLK2Freq() + (hsc->Init.BaudRate/2))/ hsc->Init.BaudRate);
1071 break;
1072 case SMARTCARD_CLOCKSOURCE_HSI:
1073 hsc->Instance->BRR = (uint16_t)((HSI_VALUE + (hsc->Init.BaudRate/2))/ hsc->Init.BaudRate);
1074 break;
1075 case SMARTCARD_CLOCKSOURCE_SYSCLK:
1076 hsc->Instance->BRR = (uint16_t)((HAL_RCC_GetSysClockFreq() + (hsc->Init.BaudRate/2))/ hsc->Init.BaudRate);
1077 break;
1078 case SMARTCARD_CLOCKSOURCE_LSE:
1079 hsc->Instance->BRR = (uint16_t)((LSE_VALUE + (hsc->Init.BaudRate/2))/ hsc->Init.BaudRate);
1080 break;
1081 default:
1082 break;
1083 }
1084 }
1085
1086 /**
1087 * @brief Check the SMARTCARD Idle State
1088 * @param hsc: SMARTCARD handle
1089 * @retval HAL status
1090 */
1091 static HAL_StatusTypeDef SMARTCARD_CheckIdleState(SMARTCARD_HandleTypeDef *hsc)
1092 {
1093 uint32_t tickstart = 0U;
1094
1095 /* Initialize the SMARTCARD ErrorCode */
1096 hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
1097
1098 /* Init tickstart for timeout managment*/
1099 tickstart = HAL_GetTick();
1100
1101 /* Check if the Transmitter is enabled */
1102 if((hsc->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE)
1103 {
1104 /* Wait until TEACK flag is set */
1105 if(SMARTCARD_WaitOnFlagUntilTimeout(hsc, USART_ISR_TEACK, RESET, tickstart, TEACK_REACK_TIMEOUT) != HAL_OK)
1106 {
1107 return HAL_TIMEOUT;
1108 }
1109 }
1110 /* Check if the Receiver is enabled */
1111 if((hsc->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE)
1112 {
1113 /* Wait until REACK flag is set */
1114 if(SMARTCARD_WaitOnFlagUntilTimeout(hsc, USART_ISR_REACK, RESET, tickstart, TEACK_REACK_TIMEOUT) != HAL_OK)
1115 {
1116 return HAL_TIMEOUT;
1117 }
1118 }
1119
1120 /* Process Unlocked */
1121 __HAL_UNLOCK(hsc);
1122
1123 /* Initialize the SMARTCARD state*/
1124 hsc->gState= HAL_SMARTCARD_STATE_READY;
1125 hsc->RxState= HAL_SMARTCARD_STATE_READY;
1126
1127 return HAL_OK;
1128 }
1129
1130 /**
1131 * @brief Configure the SMARTCARD associated USART peripheral advanced features
1132 * @param hsc: SMARTCARD handle
1133 * @retval None
1134 */
1135 static void SMARTCARD_AdvFeatureConfig(SMARTCARD_HandleTypeDef *hsc)
1136 {
1137 /* Check whether the set of advanced features to configure is properly set */
1138 assert_param(IS_SMARTCARD_ADVFEATURE_INIT(hsc->AdvancedInit.AdvFeatureInit));
1139
1140 /* if required, configure TX pin active level inversion */
1141 if(HAL_IS_BIT_SET(hsc->AdvancedInit.AdvFeatureInit, SMARTCARD_ADVFEATURE_TXINVERT_INIT))
1142 {
1143 assert_param(IS_SMARTCARD_ADVFEATURE_TXINV(hsc->AdvancedInit.TxPinLevelInvert));
1144 MODIFY_REG(hsc->Instance->CR2, USART_CR2_TXINV, hsc->AdvancedInit.TxPinLevelInvert);
1145 }
1146
1147 /* if required, configure RX pin active level inversion */
1148 if(HAL_IS_BIT_SET(hsc->AdvancedInit.AdvFeatureInit, SMARTCARD_ADVFEATURE_RXINVERT_INIT))
1149 {
1150 assert_param(IS_SMARTCARD_ADVFEATURE_RXINV(hsc->AdvancedInit.RxPinLevelInvert));
1151 MODIFY_REG(hsc->Instance->CR2, USART_CR2_RXINV, hsc->AdvancedInit.RxPinLevelInvert);
1152 }
1153
1154 /* if required, configure data inversion */
1155 if(HAL_IS_BIT_SET(hsc->AdvancedInit.AdvFeatureInit, SMARTCARD_ADVFEATURE_DATAINVERT_INIT))
1156 {
1157 assert_param(IS_SMARTCARD_ADVFEATURE_DATAINV(hsc->AdvancedInit.DataInvert));
1158 MODIFY_REG(hsc->Instance->CR2, USART_CR2_DATAINV, hsc->AdvancedInit.DataInvert);
1159 }
1160
1161 /* if required, configure RX/TX pins swap */
1162 if(HAL_IS_BIT_SET(hsc->AdvancedInit.AdvFeatureInit, SMARTCARD_ADVFEATURE_SWAP_INIT))
1163 {
1164 assert_param(IS_SMARTCARD_ADVFEATURE_SWAP(hsc->AdvancedInit.Swap));
1165 MODIFY_REG(hsc->Instance->CR2, USART_CR2_SWAP, hsc->AdvancedInit.Swap);
1166 }
1167
1168 /* if required, configure RX overrun detection disabling */
1169 if(HAL_IS_BIT_SET(hsc->AdvancedInit.AdvFeatureInit, SMARTCARD_ADVFEATURE_RXOVERRUNDISABLE_INIT))
1170 {
1171 assert_param(IS_SMARTCARD_OVERRUN(hsc->AdvancedInit.OverrunDisable));
1172 MODIFY_REG(hsc->Instance->CR3, USART_CR3_OVRDIS, hsc->AdvancedInit.OverrunDisable);
1173 }
1174
1175 /* if required, configure DMA disabling on reception error */
1176 if(HAL_IS_BIT_SET(hsc->AdvancedInit.AdvFeatureInit, SMARTCARD_ADVFEATURE_DMADISABLEONERROR_INIT))
1177 {
1178 assert_param(IS_SMARTCARD_ADVFEATURE_DMAONRXERROR(hsc->AdvancedInit.DMADisableonRxError));
1179 MODIFY_REG(hsc->Instance->CR3, USART_CR3_DDRE, hsc->AdvancedInit.DMADisableonRxError);
1180 }
1181
1182 /* if required, configure MSB first on communication line */
1183 if(HAL_IS_BIT_SET(hsc->AdvancedInit.AdvFeatureInit, SMARTCARD_ADVFEATURE_MSBFIRST_INIT))
1184 {
1185 assert_param(IS_SMARTCARD_ADVFEATURE_MSBFIRST(hsc->AdvancedInit.MSBFirst));
1186 MODIFY_REG(hsc->Instance->CR2, USART_CR2_MSBFIRST, hsc->AdvancedInit.MSBFirst);
1187 }
1188 }
1189
1190 /**
1191 * @brief This function handles SMARTCARD Communication Timeout.
1192 * @param hsc SMARTCARD handle
1193 * @param Flag specifies the SMARTCARD flag to check.
1194 * @param Status The new Flag status (SET or RESET).
1195 * @param Tickstart Tick start value
1196 * @param Timeout Timeout duration
1197 * @retval HAL status
1198 */
1199 static HAL_StatusTypeDef SMARTCARD_WaitOnFlagUntilTimeout(SMARTCARD_HandleTypeDef *hsc, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout)
1200 {
1201 /* Wait until flag is set */
1202 while((__HAL_SMARTCARD_GET_FLAG(hsc, Flag) ? SET : RESET) == Status)
1203 {
1204 /* Check for the Timeout */
1205 if(Timeout != HAL_MAX_DELAY)
1206 {
1207 if((Timeout == 0U)||((HAL_GetTick() - Tickstart ) > Timeout))
1208 {
1209 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
1210 CLEAR_BIT(hsc->Instance->CR1, USART_CR1_TXEIE);
1211 CLEAR_BIT(hsc->Instance->CR1, USART_CR1_RXNEIE);
1212 __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_PE);
1213 __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_ERR);
1214 CLEAR_BIT(hsc->Instance->CR1, USART_CR1_PEIE);
1215 CLEAR_BIT(hsc->Instance->CR3, USART_CR3_EIE);
1216
1217 hsc->gState= HAL_SMARTCARD_STATE_READY;
1218 hsc->RxState= HAL_SMARTCARD_STATE_READY;
1219
1220 /* Process Unlocked */
1221 __HAL_UNLOCK(hsc);
1222
1223 return HAL_TIMEOUT;
1224 }
1225 }
1226 }
1227 return HAL_OK;
1228 }
1229
1230 /*
1231 * @brief End ongoing Tx transfer on SMARTCARD peripheral (following error detection or Transmit completion).
1232 * @param hsc: SMARTCARD handle.
1233 * @retval None
1234 */
1235 static void SMARTCARD_EndTxTransfer(SMARTCARD_HandleTypeDef *hsc)
1236 {
1237 /* Disable TXEIE and TCIE interrupts */
1238 CLEAR_BIT(hsc->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
1239
1240 /* At end of Tx process, restore hsc->gState to Ready */
1241 hsc->gState = HAL_SMARTCARD_STATE_READY;
1242 }
1243
1244
1245 /**
1246 * @brief End ongoing Rx transfer on SMARTCARD peripheral (following error detection or Reception completion).
1247 * @param hsc: SMARTCARD handle.
1248 * @retval None
1249 */
1250 static void SMARTCARD_EndRxTransfer(SMARTCARD_HandleTypeDef *hsc)
1251 {
1252 /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
1253 CLEAR_BIT(hsc->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
1254 CLEAR_BIT(hsc->Instance->CR3, USART_CR3_EIE);
1255
1256 /* At end of Rx process, restore hsc->RxState to Ready */
1257 hsc->RxState = HAL_SMARTCARD_STATE_READY;
1258 }
1259
1260 /**
1261 * @brief DMA SMARTCARD transmit process complete callback
1262 * @param hdma: DMA handle
1263 * @retval None
1264 */
1265 static void SMARTCARD_DMATransmitCplt(DMA_HandleTypeDef *hdma)
1266 {
1267 SMARTCARD_HandleTypeDef* hsc = ( SMARTCARD_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1268 hsc->TxXferCount = 0;
1269
1270 /* Disable the DMA transfer for transmit request by setting the DMAT bit
1271 in the USART CR3 register */
1272 CLEAR_BIT(hsc->Instance->CR3, USART_CR3_DMAT);
1273
1274 /* Enable the SMARTCARD Transmit Complete Interrupt */
1275 SET_BIT(hsc->Instance->CR1, USART_CR1_TCIE);
1276 }
1277
1278 /**
1279 * @brief DMA SMARTCARD receive process complete callback
1280 * @param hdma: DMA handle
1281 * @retval None
1282 */
1283 static void SMARTCARD_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
1284 {
1285 SMARTCARD_HandleTypeDef* hsc = ( SMARTCARD_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1286 hsc->RxXferCount = 0;
1287
1288 /* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
1289 CLEAR_BIT(hsc->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
1290 CLEAR_BIT(hsc->Instance->CR3, USART_CR3_EIE);
1291
1292 /* Disable the DMA transfer for the receiver request by setting the DMAR bit
1293 in the SMARTCARD associated USART CR3 register */
1294 CLEAR_BIT(hsc->Instance->CR3, USART_CR3_DMAR);
1295
1296 /* At end of Rx process, restore hsc->RxState to Ready */
1297 hsc->RxState = HAL_SMARTCARD_STATE_READY;
1298
1299 HAL_SMARTCARD_RxCpltCallback(hsc);
1300 }
1301
1302 /**
1303 * @brief DMA SMARTCARD communication error callback
1304 * @param hdma: DMA handle
1305 * @retval None
1306 */
1307 static void SMARTCARD_DMAError(DMA_HandleTypeDef *hdma)
1308 {
1309 SMARTCARD_HandleTypeDef* hsc = ( SMARTCARD_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1310 hsc->RxXferCount = 0U;
1311 hsc->TxXferCount = 0U;
1312 hsc->ErrorCode = HAL_SMARTCARD_ERROR_DMA;
1313
1314 /* Stop SMARTCARD DMA Tx request if ongoing */
1315 if ( (hsc->gState == HAL_SMARTCARD_STATE_BUSY_TX)
1316 &&(HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAT)) )
1317 {
1318 SMARTCARD_EndTxTransfer(hsc);
1319 }
1320
1321 /* Stop SMARTCARD DMA Rx request if ongoing */
1322 if ( (hsc->RxState == HAL_SMARTCARD_STATE_BUSY_RX)
1323 &&(HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAR)) )
1324 {
1325 SMARTCARD_EndRxTransfer(hsc);
1326 }
1327
1328 HAL_SMARTCARD_ErrorCallback(hsc);
1329 }
1330
1331 /**
1332 * @brief DMA SMARTCARD communication abort callback, when call by HAL services on Error
1333 * (To be called at end of DMA Abort procedure following error occurrence).
1334 * @param hdma: DMA handle.
1335 * @retval None
1336 */
1337 static void SMARTCARD_DMAAbortOnError(DMA_HandleTypeDef *hdma)
1338 {
1339 SMARTCARD_HandleTypeDef* hsc = ( SMARTCARD_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1340 hsc->RxXferCount = 0U;
1341 hsc->TxXferCount = 0U;
1342
1343 HAL_SMARTCARD_ErrorCallback(hsc);
1344 }
1345
1346 /**
1347 * @}
1348 */
1349
1350 #endif /* HAL_SMARTCARD_MODULE_ENABLED */
1351 /**
1352 * @}
1353 */
1354
1355 /**
1356 * @}
1357 */
1358
1359 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/