1 /**
2 ******************************************************************************
3 * @file stm32f7xx_hal_smartcard.c
4 * @author MCD Application Team
5 * @version V1.0.1
6 * @date 25-June-2015
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>© COPYRIGHT(c) 2015 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 1000
107 #define HAL_SMARTCARD_TXDMA_TIMEOUTVALUE 22000
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_SetConfig(SMARTCARD_HandleTypeDef *hsc);
126 static HAL_StatusTypeDef SMARTCARD_WaitOnFlagUntilTimeout(SMARTCARD_HandleTypeDef *hsc, uint32_t Flag, FlagStatus Status, uint32_t Timeout);
127 static HAL_StatusTypeDef SMARTCARD_CheckIdleState(SMARTCARD_HandleTypeDef *hsc);
128 static HAL_StatusTypeDef SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef *hsc);
129 static HAL_StatusTypeDef SMARTCARD_Receive_IT(SMARTCARD_HandleTypeDef *hsc);
130 static void SMARTCARD_AdvFeatureConfig(SMARTCARD_HandleTypeDef *hsc);
131 /**
132 * @}
133 */
134 /* Exported functions --------------------------------------------------------*/
135 /** @defgroup SMARTCARD_Exported_Functions SMARTCARD Exported Functions
136 * @{
137 */
138
139 /** @defgroup SMARTCARD_Exported_Functions_Group1 SmartCard Initialization and de-initialization functions
140 * @brief Initialization and Configuration functions
141 *
142 @verbatim
143 ===============================================================================
144 ##### Initialization and Configuration functions #####
145 ===============================================================================
146 [..]
147 This subsection provides a set of functions allowing to initialize the USART
148 associated to the SmartCard.
149 (+) These parameters can be configured:
150 (++) Baud Rate
151 (++) Parity: parity should be enabled,
152 Frame Length is fixed to 8 bits plus parity:
153 the USART frame format is given in the following table:
154
155 (+++) +---------------------------------------------------------------+
156 (+++) | M1M0 bits | PCE bit | USART frame |
157 (+++) |-----------------------|---------------------------------------|
158 (+++) | 01 | 1 | | SB | 8 bit data | PB | STB | |
159 (+++) +---------------------------------------------------------------+
160
161 (++) Receiver/transmitter modes
162 (++) Synchronous mode (and if enabled, phase, polarity and last bit parameters)
163 (++) Prescaler value
164 (++) Guard bit time
165 (++) NACK enabling or disabling on transmission error
166
167 (+) The following advanced features can be configured as well:
168 (++) TX and/or RX pin level inversion
169 (++) data logical level inversion
170 (++) RX and TX pins swap
171 (++) RX overrun detection disabling
172 (++) DMA disabling on RX error
173 (++) MSB first on communication line
174 (++) Time out enabling (and if activated, timeout value)
175 (++) Block length
176 (++) Auto-retry counter
177
178 [..]
179 The HAL_SMARTCARD_Init() API follow respectively the USART (a)synchronous configuration procedures
180 (details for the procedures are available in reference manual).
181
182 @endverbatim
183 * @{
184 */
185
186 /**
187 * @brief Initializes the SMARTCARD mode according to the specified
188 * parameters in the SMARTCARD_InitTypeDef and create the associated handle .
189 * @param hsc: SMARTCARD handle
190 * @retval HAL status
191 */
HAL_SMARTCARD_Init(SMARTCARD_HandleTypeDef * hsc)192 HAL_StatusTypeDef HAL_SMARTCARD_Init(SMARTCARD_HandleTypeDef *hsc)
193 {
194 /* Check the SMARTCARD handle allocation */
195 if (hsc == NULL) {
196 return HAL_ERROR;
197 }
198
199 /* Check the parameters */
200 assert_param(IS_SMARTCARD_INSTANCE(hsc->Instance));
201
202 if (hsc->State == HAL_SMARTCARD_STATE_RESET) {
203 /* Allocate lock resource and initialize it */
204 hsc->Lock = HAL_UNLOCKED;
205 /* Init the low level hardware : GPIO, CLOCK, CORTEX */
206 HAL_SMARTCARD_MspInit(hsc);
207 }
208
209 hsc->State = HAL_SMARTCARD_STATE_BUSY;
210
211 /* Disable the Peripheral */
212 __HAL_SMARTCARD_DISABLE(hsc);
213
214 /* Set the SMARTCARD Communication parameters */
215 SMARTCARD_SetConfig(hsc);
216
217 if (hsc->AdvancedInit.AdvFeatureInit != SMARTCARD_ADVFEATURE_NO_INIT) {
218 SMARTCARD_AdvFeatureConfig(hsc);
219 }
220
221 /* In SmartCard mode, the following bits must be kept cleared:
222 - LINEN in the USART_CR2 register,
223 - HDSEL and IREN bits in the USART_CR3 register.*/
224 hsc->Instance->CR2 &= ~(USART_CR2_LINEN);
225 hsc->Instance->CR3 &= ~(USART_CR3_HDSEL | USART_CR3_IREN);
226
227 /* set the USART in SMARTCARD mode */
228 hsc->Instance->CR3 |= USART_CR3_SCEN;
229
230 /* Enable the Peripheral */
231 __HAL_SMARTCARD_ENABLE(hsc);
232
233 /* TEACK and/or REACK to check before moving hsc->State to Ready */
234 return (SMARTCARD_CheckIdleState(hsc));
235 }
236
237 /**
238 * @brief DeInitializes the SMARTCARD peripheral
239 * @param hsc: SMARTCARD handle
240 * @retval HAL status
241 */
HAL_SMARTCARD_DeInit(SMARTCARD_HandleTypeDef * hsc)242 HAL_StatusTypeDef HAL_SMARTCARD_DeInit(SMARTCARD_HandleTypeDef *hsc)
243 {
244 /* Check the SMARTCARD handle allocation */
245 if (hsc == NULL) {
246 return HAL_ERROR;
247 }
248
249 /* Check the parameters */
250 assert_param(IS_SMARTCARD_INSTANCE(hsc->Instance));
251
252 hsc->State = HAL_SMARTCARD_STATE_BUSY;
253
254 /* DeInit the low level hardware */
255 HAL_SMARTCARD_MspDeInit(hsc);
256
257 hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
258 hsc->State = HAL_SMARTCARD_STATE_RESET;
259
260 /* Release Lock */
261 __HAL_UNLOCK(hsc);
262
263 return HAL_OK;
264 }
265
266 /**
267 * @brief SMARTCARD MSP Init
268 * @param hsc: SMARTCARD handle
269 * @retval None
270 */
HAL_SMARTCARD_MspInit(SMARTCARD_HandleTypeDef * hsc)271 __weak void HAL_SMARTCARD_MspInit(SMARTCARD_HandleTypeDef *hsc)
272 {
273 /* NOTE : This function Should not be modified, when the callback is needed,
274 the HAL_SMARTCARD_MspInit could be implemented in the user file
275 */
276 }
277
278 /**
279 * @brief SMARTCARD MSP DeInit
280 * @param hsc: SMARTCARD handle
281 * @retval None
282 */
HAL_SMARTCARD_MspDeInit(SMARTCARD_HandleTypeDef * hsc)283 __weak void HAL_SMARTCARD_MspDeInit(SMARTCARD_HandleTypeDef *hsc)
284 {
285 /* NOTE : This function Should not be modified, when the callback is needed,
286 the HAL_SMARTCARD_MspDeInit could be implemented in the user file
287 */
288 }
289
290 /**
291 * @}
292 */
293
294 /** @defgroup SMARTCARD_Exported_Functions_Group2 IO operation functions
295 * @brief SMARTCARD Transmit and Receive functions
296 *
297 @verbatim
298 ===============================================================================
299 ##### IO operation functions #####
300 ===============================================================================
301 This subsection provides a set of functions allowing to manage the SMARTCARD data transfers.
302
303 (#) There are two modes of transfer:
304 (+) Blocking mode: The communication is performed in polling mode.
305 The HAL status of all data processing is returned by the same function
306 after finishing transfer.
307 (+) No-Blocking mode: The communication is performed using Interrupts
308 or DMA, These API's return the HAL status.
309 The end of the data processing will be indicated through the
310 dedicated SMARTCARD IRQ when using Interrupt mode or the DMA IRQ when
311 using DMA mode.
312 The HAL_SMARTCARD_TxCpltCallback(), HAL_SMARTCARD_RxCpltCallback() user callbacks
313 will be executed respectively at the end of the Transmit or Receive process
314 The HAL_SMARTCARD_ErrorCallback()user callback will be executed when a communication error is detected
315
316 (#) Blocking mode API's are :
317 (+) HAL_SMARTCARD_Transmit()
318 (+) HAL_SMARTCARD_Receive()
319
320 (#) Non-Blocking mode API's with Interrupt are :
321 (+) HAL_SMARTCARD_Transmit_IT()
322 (+) HAL_SMARTCARD_Receive_IT()
323 (+) HAL_SMARTCARD_IRQHandler()
324 (+) SMARTCARD_Transmit_IT()
325 (+) SMARTCARD_Receive_IT()
326
327 (#) No-Blocking mode functions with DMA are :
328 (+) HAL_SMARTCARD_Transmit_DMA()
329 (+) HAL_SMARTCARD_Receive_DMA()
330
331 (#) A set of Transfer Complete Callbacks are provided in No_Blocking mode:
332 (+) HAL_SMARTCARD_TxCpltCallback()
333 (+) HAL_SMARTCARD_RxCpltCallback()
334 (+) HAL_SMARTCARD_ErrorCallback()
335
336 @endverbatim
337 * @{
338 */
339
340 /**
341 * @brief Send an amount of data in blocking mode
342 * @param hsc: SMARTCARD handle
343 * @param pData: pointer to data buffer
344 * @param Size: amount of data to be sent
345 * @param Timeout: Timeout duration
346 * @retval HAL status
347 */
HAL_SMARTCARD_Transmit(SMARTCARD_HandleTypeDef * hsc,uint8_t * pData,uint16_t Size,uint32_t Timeout)348 HAL_StatusTypeDef HAL_SMARTCARD_Transmit(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size, uint32_t Timeout)
349 {
350 if ((hsc->State == HAL_SMARTCARD_STATE_READY) || (hsc->State == HAL_SMARTCARD_STATE_BUSY_RX)) {
351 if ((pData == NULL) || (Size == 0)) {
352 return HAL_ERROR;
353 }
354
355 /* Process Locked */
356 __HAL_LOCK(hsc);
357 hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
358 /* Check if a non-blocking receive process is ongoing or not */
359 if (hsc->State == HAL_SMARTCARD_STATE_BUSY_RX) {
360 hsc->State = HAL_SMARTCARD_STATE_BUSY_TX_RX;
361 } else {
362 hsc->State = HAL_SMARTCARD_STATE_BUSY_TX;
363 }
364
365 hsc->TxXferSize = Size;
366 hsc->TxXferCount = Size;
367 while (hsc->TxXferCount > 0) {
368 hsc->TxXferCount--;
369 if (SMARTCARD_WaitOnFlagUntilTimeout(hsc, SMARTCARD_FLAG_TXE, RESET, Timeout) != HAL_OK) {
370 return HAL_TIMEOUT;
371 }
372 hsc->Instance->TDR = (*pData++ & (uint8_t)0xFF);
373 }
374 if (SMARTCARD_WaitOnFlagUntilTimeout(hsc, SMARTCARD_FLAG_TC, RESET, Timeout) != HAL_OK) {
375 return HAL_TIMEOUT;
376 }
377 /* Check if a non-blocking receive Process is ongoing or not */
378 if (hsc->State == HAL_SMARTCARD_STATE_BUSY_TX_RX) {
379 hsc->State = HAL_SMARTCARD_STATE_BUSY_RX;
380 } else {
381 hsc->State = HAL_SMARTCARD_STATE_READY;
382 }
383 /* Process Unlocked */
384 __HAL_UNLOCK(hsc);
385
386 return HAL_OK;
387 } else {
388 return HAL_BUSY;
389 }
390 }
391
392 /**
393 * @brief Receive an amount of data in blocking mode
394 * @param hsc: SMARTCARD handle
395 * @param pData: pointer to data buffer
396 * @param Size: amount of data to be received
397 * @param Timeout: Timeout duration
398 * @retval HAL status
399 */
HAL_SMARTCARD_Receive(SMARTCARD_HandleTypeDef * hsc,uint8_t * pData,uint16_t Size,uint32_t Timeout)400 HAL_StatusTypeDef HAL_SMARTCARD_Receive(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size, uint32_t Timeout)
401 {
402 if ((hsc->State == HAL_SMARTCARD_STATE_READY) || (hsc->State == HAL_SMARTCARD_STATE_BUSY_TX)) {
403 if ((pData == NULL) || (Size == 0)) {
404 return HAL_ERROR;
405 }
406
407 /* Process Locked */
408 __HAL_LOCK(hsc);
409
410 hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
411 /* Check if a non-blocking transmit process is ongoing or not */
412 if (hsc->State == HAL_SMARTCARD_STATE_BUSY_TX) {
413 hsc->State = HAL_SMARTCARD_STATE_BUSY_TX_RX;
414 } else {
415 hsc->State = HAL_SMARTCARD_STATE_BUSY_RX;
416 }
417
418 hsc->RxXferSize = Size;
419 hsc->RxXferCount = Size;
420 /* Check the remain data to be received */
421 while (hsc->RxXferCount > 0) {
422 hsc->RxXferCount--;
423 if (SMARTCARD_WaitOnFlagUntilTimeout(hsc, SMARTCARD_FLAG_RXNE, RESET, Timeout) != HAL_OK) {
424 return HAL_TIMEOUT;
425 }
426 *pData++ = (uint8_t)(hsc->Instance->RDR & (uint8_t)0x00FF);
427 }
428
429 /* Check if a non-blocking transmit process is ongoing or not */
430 if (hsc->State == HAL_SMARTCARD_STATE_BUSY_TX_RX) {
431 hsc->State = HAL_SMARTCARD_STATE_BUSY_TX;
432 } else {
433 hsc->State = HAL_SMARTCARD_STATE_READY;
434 }
435
436 /* Process Unlocked */
437 __HAL_UNLOCK(hsc);
438
439 return HAL_OK;
440 } else {
441 return HAL_BUSY;
442 }
443 }
444
445 /**
446 * @brief Send an amount of data in interrupt mode
447 * @param hsc: SMARTCARD handle
448 * @param pData: pointer to data buffer
449 * @param Size: amount of data to be sent
450 * @retval HAL status
451 */
HAL_SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef * hsc,uint8_t * pData,uint16_t Size)452 HAL_StatusTypeDef HAL_SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size)
453 {
454 if ((hsc->State == HAL_SMARTCARD_STATE_READY) || (hsc->State == HAL_SMARTCARD_STATE_BUSY_RX)) {
455 if ((pData == NULL) || (Size == 0)) {
456 return HAL_ERROR;
457 }
458
459 /* Process Locked */
460 __HAL_LOCK(hsc);
461
462 hsc->pTxBuffPtr = pData;
463 hsc->TxXferSize = Size;
464 hsc->TxXferCount = Size;
465
466 hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
467 /* Check if a receive process is ongoing or not */
468 if (hsc->State == HAL_SMARTCARD_STATE_BUSY_RX) {
469 hsc->State = HAL_SMARTCARD_STATE_BUSY_TX_RX;
470 } else {
471 hsc->State = HAL_SMARTCARD_STATE_BUSY_TX;
472 }
473
474 /* Enable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */
475 __HAL_SMARTCARD_ENABLE_IT(hsc, SMARTCARD_IT_ERR);
476
477 /* Process Unlocked */
478 __HAL_UNLOCK(hsc);
479
480 /* Enable the SMARTCARD Transmit Complete Interrupt */
481 __HAL_SMARTCARD_ENABLE_IT(hsc, SMARTCARD_IT_TC);
482
483 return HAL_OK;
484 } else {
485 return HAL_BUSY;
486 }
487 }
488
489 /**
490 * @brief Receive an amount of data in interrupt mode
491 * @param hsc: SMARTCARD handle
492 * @param pData: pointer to data buffer
493 * @param Size: amount of data to be received
494 * @retval HAL status
495 */
HAL_SMARTCARD_Receive_IT(SMARTCARD_HandleTypeDef * hsc,uint8_t * pData,uint16_t Size)496 HAL_StatusTypeDef HAL_SMARTCARD_Receive_IT(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size)
497 {
498 if ((hsc->State == HAL_SMARTCARD_STATE_READY) || (hsc->State == HAL_SMARTCARD_STATE_BUSY_TX)) {
499 if ((pData == NULL) || (Size == 0)) {
500 return HAL_ERROR;
501 }
502
503 /* Process Locked */
504 __HAL_LOCK(hsc);
505
506 hsc->pRxBuffPtr = pData;
507 hsc->RxXferSize = Size;
508 hsc->RxXferCount = Size;
509
510 hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
511 /* Check if a transmit process is ongoing or not */
512 if (hsc->State == HAL_SMARTCARD_STATE_BUSY_TX) {
513 hsc->State = HAL_SMARTCARD_STATE_BUSY_TX_RX;
514 } else {
515 hsc->State = HAL_SMARTCARD_STATE_BUSY_RX;
516 }
517
518 /* Enable the SMARTCARD Parity Error Interrupt */
519 __HAL_SMARTCARD_ENABLE_IT(hsc, SMARTCARD_IT_PE);
520
521 /* Enable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */
522 __HAL_SMARTCARD_ENABLE_IT(hsc, SMARTCARD_IT_ERR);
523
524 /* Process Unlocked */
525 __HAL_UNLOCK(hsc);
526
527 /* Enable the SMARTCARD Data Register not empty Interrupt */
528 __HAL_SMARTCARD_ENABLE_IT(hsc, SMARTCARD_IT_RXNE);
529
530 return HAL_OK;
531 } else {
532 return HAL_BUSY;
533 }
534 }
535
536 /**
537 * @brief Send an amount of data in DMA mode
538 * @param hsc: SMARTCARD handle
539 * @param pData: pointer to data buffer
540 * @param Size: amount of data to be sent
541 * @retval HAL status
542 */
HAL_SMARTCARD_Transmit_DMA(SMARTCARD_HandleTypeDef * hsc,uint8_t * pData,uint16_t Size)543 HAL_StatusTypeDef HAL_SMARTCARD_Transmit_DMA(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size)
544 {
545 uint32_t *tmp;
546
547 if ((hsc->State == HAL_SMARTCARD_STATE_READY) || (hsc->State == HAL_SMARTCARD_STATE_BUSY_RX)) {
548 if ((pData == NULL) || (Size == 0)) {
549 return HAL_ERROR;
550 }
551
552 /* Process Locked */
553 __HAL_LOCK(hsc);
554
555 hsc->pTxBuffPtr = pData;
556 hsc->TxXferSize = Size;
557 hsc->TxXferCount = Size;
558
559 hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
560 /* Check if a receive process is ongoing or not */
561 if (hsc->State == HAL_SMARTCARD_STATE_BUSY_RX) {
562 hsc->State = HAL_SMARTCARD_STATE_BUSY_TX_RX;
563 } else {
564 hsc->State = HAL_SMARTCARD_STATE_BUSY_TX;
565 }
566
567 /* Set the SMARTCARD DMA transfer complete callback */
568 hsc->hdmatx->XferCpltCallback = SMARTCARD_DMATransmitCplt;
569
570 /* Set the SMARTCARD error callback */
571 hsc->hdmatx->XferErrorCallback = SMARTCARD_DMAError;
572
573 /* Enable the SMARTCARD transmit DMA Stream */
574 tmp = (uint32_t*)&pData;
575 HAL_DMA_Start_IT(hsc->hdmatx, *(uint32_t*)tmp, (uint32_t)&hsc->Instance->TDR, Size);
576
577 /* Clear the TC flag in the SR register by writing 0 to it */
578 __HAL_SMARTCARD_CLEAR_IT(hsc, SMARTCARD_FLAG_TC);
579
580 /* Enable the DMA transfer for transmit request by setting the DMAT bit
581 in the SMARTCARD associated USART CR3 register */
582 hsc->Instance->CR3 |= USART_CR3_DMAT;
583
584 /* Process Unlocked */
585 __HAL_UNLOCK(hsc);
586
587 return HAL_OK;
588 } else {
589 return HAL_BUSY;
590 }
591 }
592
593 /**
594 * @brief Receive an amount of data in DMA mode
595 * @param hsc: SMARTCARD handle
596 * @param pData: pointer to data buffer
597 * @param Size: amount of data to be received
598 * @note The SMARTCARD-associated USART parity is enabled (PCE = 1),
599 * the received data contain the parity bit (MSB position)
600 * @retval HAL status
601 */
HAL_SMARTCARD_Receive_DMA(SMARTCARD_HandleTypeDef * hsc,uint8_t * pData,uint16_t Size)602 HAL_StatusTypeDef HAL_SMARTCARD_Receive_DMA(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size)
603 {
604 uint32_t *tmp;
605
606 if ((hsc->State == HAL_SMARTCARD_STATE_READY) || (hsc->State == HAL_SMARTCARD_STATE_BUSY_TX)) {
607 if ((pData == NULL) || (Size == 0)) {
608 return HAL_ERROR;
609 }
610
611 /* Process Locked */
612 __HAL_LOCK(hsc);
613
614 hsc->pRxBuffPtr = pData;
615 hsc->RxXferSize = Size;
616
617 hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
618 /* Check if a transmit process is ongoing or not */
619 if (hsc->State == HAL_SMARTCARD_STATE_BUSY_TX) {
620 hsc->State = HAL_SMARTCARD_STATE_BUSY_TX_RX;
621 } else {
622 hsc->State = HAL_SMARTCARD_STATE_BUSY_RX;
623 }
624
625 /* Set the SMARTCARD DMA transfer complete callback */
626 hsc->hdmarx->XferCpltCallback = SMARTCARD_DMAReceiveCplt;
627
628 /* Set the SMARTCARD DMA error callback */
629 hsc->hdmarx->XferErrorCallback = SMARTCARD_DMAError;
630
631 /* Enable the DMA Stream */
632 tmp = (uint32_t*)&pData;
633 HAL_DMA_Start_IT(hsc->hdmarx, (uint32_t)&hsc->Instance->RDR, *(uint32_t*)tmp, Size);
634
635 /* Enable the DMA transfer for the receiver request by setting the DMAR bit
636 in the SMARTCARD associated USART CR3 register */
637 hsc->Instance->CR3 |= USART_CR3_DMAR;
638
639 /* Process Unlocked */
640 __HAL_UNLOCK(hsc);
641
642 return HAL_OK;
643 } else {
644 return HAL_BUSY;
645 }
646 }
647
648 /**
649 * @brief SMARTCARD interrupt requests handling.
650 * @param hsc: SMARTCARD handle
651 * @retval None
652 */
HAL_SMARTCARD_IRQHandler(SMARTCARD_HandleTypeDef * hsc)653 void HAL_SMARTCARD_IRQHandler(SMARTCARD_HandleTypeDef *hsc)
654 {
655 /* SMARTCARD parity error interrupt occurred -------------------------------*/
656 if ((__HAL_SMARTCARD_GET_IT(hsc, SMARTCARD_IT_PE) != RESET) && (__HAL_SMARTCARD_GET_IT_SOURCE(hsc, SMARTCARD_IT_PE) != RESET)) {
657 __HAL_SMARTCARD_CLEAR_IT(hsc, SMARTCARD_CLEAR_PEF);
658 hsc->ErrorCode |= HAL_SMARTCARD_ERROR_PE;
659 /* Set the SMARTCARD state ready to be able to start again the process */
660 hsc->State = HAL_SMARTCARD_STATE_READY;
661 }
662
663 /* SMARTCARD frame error interrupt occurred ---------------------------------*/
664 if ((__HAL_SMARTCARD_GET_IT(hsc, SMARTCARD_IT_FE) != RESET) && (__HAL_SMARTCARD_GET_IT_SOURCE(hsc, SMARTCARD_IT_ERR) != RESET)) {
665 __HAL_SMARTCARD_CLEAR_IT(hsc, SMARTCARD_CLEAR_FEF);
666 hsc->ErrorCode |= HAL_SMARTCARD_ERROR_FE;
667 /* Set the SMARTCARD state ready to be able to start again the process */
668 hsc->State = HAL_SMARTCARD_STATE_READY;
669 }
670
671 /* SMARTCARD noise error interrupt occurred ---------------------------------*/
672 if ((__HAL_SMARTCARD_GET_IT(hsc, SMARTCARD_IT_NE) != RESET) && (__HAL_SMARTCARD_GET_IT_SOURCE(hsc, SMARTCARD_IT_ERR) != RESET)) {
673 __HAL_SMARTCARD_CLEAR_IT(hsc, SMARTCARD_CLEAR_NEF);
674 hsc->ErrorCode |= HAL_SMARTCARD_ERROR_NE;
675 /* Set the SMARTCARD state ready to be able to start again the process */
676 hsc->State = HAL_SMARTCARD_STATE_READY;
677 }
678
679 /* SMARTCARD Over-Run interrupt occurred ------------------------------------*/
680 if ((__HAL_SMARTCARD_GET_IT(hsc, SMARTCARD_IT_ORE) != RESET) && (__HAL_SMARTCARD_GET_IT_SOURCE(hsc, SMARTCARD_IT_ERR) != RESET)) {
681 __HAL_SMARTCARD_CLEAR_IT(hsc, SMARTCARD_CLEAR_OREF);
682 hsc->ErrorCode |= HAL_SMARTCARD_ERROR_ORE;
683 /* Set the SMARTCARD state ready to be able to start again the process */
684 hsc->State = HAL_SMARTCARD_STATE_READY;
685 }
686
687 /* SMARTCARD receiver timeout interrupt occurred ----------------------------*/
688 if ((__HAL_SMARTCARD_GET_IT(hsc, SMARTCARD_IT_RTO) != RESET) && (__HAL_SMARTCARD_GET_IT_SOURCE(hsc, SMARTCARD_IT_RTO) != RESET)) {
689 __HAL_SMARTCARD_CLEAR_IT(hsc, SMARTCARD_CLEAR_RTOF);
690 hsc->ErrorCode |= HAL_SMARTCARD_ERROR_RTO;
691 /* Set the SMARTCARD state ready to be able to start again the process */
692 hsc->State = HAL_SMARTCARD_STATE_READY;
693 }
694
695 /* Call SMARTCARD Error Call back function if need be ----------------------*/
696 if (hsc->ErrorCode != HAL_SMARTCARD_ERROR_NONE) {
697 HAL_SMARTCARD_ErrorCallback(hsc);
698 }
699
700 /* SMARTCARD in mode Receiver ----------------------------------------------*/
701 if ((__HAL_SMARTCARD_GET_IT(hsc, SMARTCARD_IT_RXNE) != RESET) && (__HAL_SMARTCARD_GET_IT_SOURCE(hsc, SMARTCARD_IT_RXNE) != RESET)) {
702 SMARTCARD_Receive_IT(hsc);
703 /* Clear RXNE interrupt flag */
704 __HAL_SMARTCARD_SEND_REQ(hsc, SMARTCARD_RXDATA_FLUSH_REQUEST);
705 }
706
707 /* SMARTCARD in mode Receiver, end of block interruption -------------------*/
708 if ((__HAL_SMARTCARD_GET_IT(hsc, SMARTCARD_IT_EOB) != RESET) && (__HAL_SMARTCARD_GET_IT_SOURCE(hsc, SMARTCARD_IT_EOB) != RESET)) {
709 hsc->State = HAL_SMARTCARD_STATE_READY;
710 HAL_SMARTCARD_RxCpltCallback(hsc);
711 /* Clear EOBF interrupt after HAL_SMARTCARD_RxCpltCallback() call for the End of Block information
712 * to be available during HAL_SMARTCARD_RxCpltCallback() processing */
713 __HAL_SMARTCARD_CLEAR_IT(hsc, SMARTCARD_CLEAR_EOBF);
714 }
715
716 /* SMARTCARD in mode Transmitter -------------------------------------------*/
717 if ((__HAL_SMARTCARD_GET_IT(hsc, SMARTCARD_IT_TC) != RESET) && (__HAL_SMARTCARD_GET_IT_SOURCE(hsc, SMARTCARD_IT_TC) != RESET)) {
718 SMARTCARD_Transmit_IT(hsc);
719 }
720 }
721
722 /**
723 * @brief Tx Transfer completed callbacks
724 * @param hsc: SMARTCARD handle
725 * @retval None
726 */
HAL_SMARTCARD_TxCpltCallback(SMARTCARD_HandleTypeDef * hsc)727 __weak void HAL_SMARTCARD_TxCpltCallback(SMARTCARD_HandleTypeDef *hsc)
728 {
729 /* NOTE : This function Should not be modified, when the callback is needed,
730 the HAL_SMARTCARD_TxCpltCallback could be implemented in the user file
731 */
732 }
733
734 /**
735 * @brief Rx Transfer completed callbacks
736 * @param hsc: SMARTCARD handle
737 * @retval None
738 */
HAL_SMARTCARD_RxCpltCallback(SMARTCARD_HandleTypeDef * hsc)739 __weak void HAL_SMARTCARD_RxCpltCallback(SMARTCARD_HandleTypeDef *hsc)
740 {
741 /* NOTE : This function Should not be modified, when the callback is needed,
742 the HAL_SMARTCARD_TxCpltCallback could be implemented in the user file
743 */
744 }
745
746 /**
747 * @brief SMARTCARD error callbacks
748 * @param hsc: SMARTCARD handle
749 * @retval None
750 */
HAL_SMARTCARD_ErrorCallback(SMARTCARD_HandleTypeDef * hsc)751 __weak void HAL_SMARTCARD_ErrorCallback(SMARTCARD_HandleTypeDef *hsc)
752 {
753 /* NOTE : This function Should not be modified, when the callback is needed,
754 the HAL_SMARTCARD_ErrorCallback could be implemented in the user file
755 */
756 }
757
758 /**
759 * @}
760 */
761
762 /** @defgroup SMARTCARD_Exported_Functions_Group3 Peripheral State functions
763 * @brief SMARTCARD State functions
764 *
765 @verbatim
766 ===============================================================================
767 ##### Peripheral State and Errors functions #####
768 ===============================================================================
769 [..]
770 This subsection provides a set of functions allowing to initialize the SMARTCARD.
771 (+) HAL_SMARTCARD_GetState() API is helpful to check in run-time the state of the SMARTCARD peripheral
772 (+) SMARTCARD_SetConfig() API configures the SMARTCARD peripheral
773 (+) SMARTCARD_CheckIdleState() API ensures that TEACK and/or REACK are set after initialization
774
775 @endverbatim
776 * @{
777 */
778
779
780 /**
781 * @brief return the SMARTCARD state
782 * @param hsc: SMARTCARD handle
783 * @retval HAL state
784 */
HAL_SMARTCARD_GetState(SMARTCARD_HandleTypeDef * hsc)785 HAL_SMARTCARD_StateTypeDef HAL_SMARTCARD_GetState(SMARTCARD_HandleTypeDef *hsc)
786 {
787 return hsc->State;
788 }
789
790 /**
791 * @brief Return the SMARTCARD error code
792 * @param hsc : pointer to a SMARTCARD_HandleTypeDef structure that contains
793 * the configuration information for the specified SMARTCARD.
794 * @retval SMARTCARD Error Code
795 */
HAL_SMARTCARD_GetError(SMARTCARD_HandleTypeDef * hsc)796 uint32_t HAL_SMARTCARD_GetError(SMARTCARD_HandleTypeDef *hsc)
797 {
798 return hsc->ErrorCode;
799 }
800
801 /**
802 * @}
803 */
804
805 /**
806 * @brief Send an amount of data in non blocking mode
807 * @param hsc: SMARTCARD handle.
808 * Function called under interruption only, once
809 * interruptions have been enabled by HAL_SMARTCARD_Transmit_IT()
810 * @retval HAL status
811 */
SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef * hsc)812 static HAL_StatusTypeDef SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef *hsc)
813 {
814 if ((hsc->State == HAL_SMARTCARD_STATE_BUSY_TX) || (hsc->State == HAL_SMARTCARD_STATE_BUSY_TX_RX)) {
815 if (hsc->TxXferCount == 0) {
816 /* Disable the SMARTCARD Transmit Complete Interrupt */
817 __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_TC);
818
819 /* Check if a receive Process is ongoing or not */
820 if (hsc->State == HAL_SMARTCARD_STATE_BUSY_TX_RX) {
821 hsc->State = HAL_SMARTCARD_STATE_BUSY_RX;
822 } else {
823 /* Disable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */
824 __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_ERR);
825
826 hsc->State = HAL_SMARTCARD_STATE_READY;
827 }
828
829 HAL_SMARTCARD_TxCpltCallback(hsc);
830
831 return HAL_OK;
832 } else {
833 hsc->Instance->TDR = (*hsc->pTxBuffPtr++ & (uint8_t)0xFF);
834 hsc->TxXferCount--;
835
836 return HAL_OK;
837 }
838 } else {
839 return HAL_BUSY;
840 }
841 }
842
843 /**
844 * @brief Receive an amount of data in non blocking mode
845 * @param hsc: SMARTCARD handle.
846 * Function called under interruption only, once
847 * interruptions have been enabled by HAL_SMARTCARD_Receive_IT()
848 * @retval HAL status
849 */
SMARTCARD_Receive_IT(SMARTCARD_HandleTypeDef * hsc)850 static HAL_StatusTypeDef SMARTCARD_Receive_IT(SMARTCARD_HandleTypeDef *hsc)
851 {
852 if ((hsc->State == HAL_SMARTCARD_STATE_BUSY_RX) || (hsc->State == HAL_SMARTCARD_STATE_BUSY_TX_RX)) {
853 *hsc->pRxBuffPtr++ = (uint8_t)(hsc->Instance->RDR & (uint8_t)0xFF);
854
855 if (--hsc->RxXferCount == 0) {
856 while (HAL_IS_BIT_SET(hsc->Instance->ISR, SMARTCARD_FLAG_RXNE)) {
857 }
858 __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_RXNE);
859
860 /* Check if a transmit Process is ongoing or not */
861 if (hsc->State == HAL_SMARTCARD_STATE_BUSY_TX_RX) {
862 hsc->State = HAL_SMARTCARD_STATE_BUSY_TX;
863 } else {
864 /* Disable the SMARTCARD Parity Error Interrupt */
865 __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_PE);
866
867 /* Disable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */
868 __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_ERR);
869
870 hsc->State = HAL_SMARTCARD_STATE_READY;
871 }
872
873 HAL_SMARTCARD_RxCpltCallback(hsc);
874
875 return HAL_OK;
876 }
877 return HAL_OK;
878 } else {
879 return HAL_BUSY;
880 }
881 }
882
883 /**
884 * @brief Configure the SMARTCARD associated USART peripheral
885 * @param hsc: SMARTCARD handle
886 * @retval None
887 */
SMARTCARD_SetConfig(SMARTCARD_HandleTypeDef * hsc)888 static void SMARTCARD_SetConfig(SMARTCARD_HandleTypeDef *hsc)
889 {
890 uint32_t tmpreg = 0x00000000;
891 uint32_t clocksource = 0x00000000;
892
893 /* Check the parameters */
894 assert_param(IS_SMARTCARD_INSTANCE(hsc->Instance));
895 assert_param(IS_SMARTCARD_BAUDRATE(hsc->Init.BaudRate));
896 assert_param(IS_SMARTCARD_WORD_LENGTH(hsc->Init.WordLength));
897 assert_param(IS_SMARTCARD_STOPBITS(hsc->Init.StopBits));
898 assert_param(IS_SMARTCARD_PARITY(hsc->Init.Parity));
899 assert_param(IS_SMARTCARD_MODE(hsc->Init.Mode));
900 assert_param(IS_SMARTCARD_POLARITY(hsc->Init.CLKPolarity));
901 assert_param(IS_SMARTCARD_PHASE(hsc->Init.CLKPhase));
902 assert_param(IS_SMARTCARD_LASTBIT(hsc->Init.CLKLastBit));
903 assert_param(IS_SMARTCARD_ONE_BIT_SAMPLE(hsc->Init.OneBitSampling));
904 assert_param(IS_SMARTCARD_NACK(hsc->Init.NACKState));
905 assert_param(IS_SMARTCARD_TIMEOUT(hsc->Init.TimeOutEnable));
906 assert_param(IS_SMARTCARD_AUTORETRY_COUNT(hsc->Init.AutoRetryCount));
907
908 /*-------------------------- USART CR1 Configuration -----------------------*/
909 /* In SmartCard mode, M and PCE are forced to 1 (8 bits + parity).
910 * Oversampling is forced to 16 (OVER8 = 0).
911 * Configure the Parity and Mode:
912 * set PS bit according to hsc->Init.Parity value
913 * set TE and RE bits according to hsc->Init.Mode value */
914 tmpreg = (uint32_t) hsc->Init.Parity | hsc->Init.Mode;
915 /* in case of TX-only mode, if NACK is enabled, the USART must be able to monitor
916 the bidirectional line to detect a NACK signal in case of parity error.
917 Therefore, the receiver block must be enabled as well (RE bit must be set). */
918 if ((hsc->Init.Mode == SMARTCARD_MODE_TX) && (hsc->Init.NACKState == SMARTCARD_NACK_ENABLE)) {
919 tmpreg |= USART_CR1_RE;
920 }
921 tmpreg |= (uint32_t) hsc->Init.WordLength;
922 MODIFY_REG(hsc->Instance->CR1, USART_CR1_FIELDS, tmpreg);
923
924 /*-------------------------- USART CR2 Configuration -----------------------*/
925 /* Stop bits are forced to 1.5 (STOP = 11) */
926 tmpreg = hsc->Init.StopBits;
927 /* Synchronous mode is activated by default */
928 tmpreg |= (uint32_t) USART_CR2_CLKEN | hsc->Init.CLKPolarity;
929 tmpreg |= (uint32_t) hsc->Init.CLKPhase | hsc->Init.CLKLastBit;
930 tmpreg |= (uint32_t) hsc->Init.TimeOutEnable;
931 MODIFY_REG(hsc->Instance->CR2, USART_CR2_FIELDS, tmpreg);
932
933 /*-------------------------- USART CR3 Configuration -----------------------*/
934 /* Configure
935 * - one-bit sampling method versus three samples' majority rule
936 * according to hsc->Init.OneBitSampling
937 * - NACK transmission in case of parity error according
938 * to hsc->Init.NACKEnable
939 * - autoretry counter according to hsc->Init.AutoRetryCount */
940 tmpreg = (uint32_t) hsc->Init.OneBitSampling | hsc->Init.NACKState;
941 tmpreg |= (uint32_t) (hsc->Init.AutoRetryCount << SMARTCARD_CR3_SCARCNT_LSB_POS);
942 MODIFY_REG(hsc->Instance-> CR3,USART_CR3_FIELDS, tmpreg);
943
944 /*-------------------------- USART GTPR Configuration ----------------------*/
945 tmpreg = (uint32_t) (hsc->Init.Prescaler | (hsc->Init.GuardTime << SMARTCARD_GTPR_GT_LSB_POS));
946 MODIFY_REG(hsc->Instance->GTPR, (uint32_t)(USART_GTPR_GT|USART_GTPR_PSC), tmpreg);
947
948 /*-------------------------- USART RTOR Configuration ----------------------*/
949 tmpreg = (uint32_t) (hsc->Init.BlockLength << SMARTCARD_RTOR_BLEN_LSB_POS);
950 if (hsc->Init.TimeOutEnable == SMARTCARD_TIMEOUT_ENABLE) {
951 assert_param(IS_SMARTCARD_TIMEOUT_VALUE(hsc->Init.TimeOutValue));
952 tmpreg |= (uint32_t) hsc->Init.TimeOutValue;
953 }
954 MODIFY_REG(hsc->Instance->RTOR, (USART_RTOR_RTO|USART_RTOR_BLEN), tmpreg);
955
956 /*-------------------------- USART BRR Configuration -----------------------*/
957 SMARTCARD_GETCLOCKSOURCE(hsc, clocksource);
958 switch (clocksource) {
959 case SMARTCARD_CLOCKSOURCE_PCLK1:
960 hsc->Instance->BRR = (uint16_t)(HAL_RCC_GetPCLK1Freq() / hsc->Init.BaudRate);
961 break;
962 case SMARTCARD_CLOCKSOURCE_PCLK2:
963 hsc->Instance->BRR = (uint16_t)(HAL_RCC_GetPCLK2Freq() / hsc->Init.BaudRate);
964 break;
965 case SMARTCARD_CLOCKSOURCE_HSI:
966 hsc->Instance->BRR = (uint16_t)(HSI_VALUE / hsc->Init.BaudRate);
967 break;
968 case SMARTCARD_CLOCKSOURCE_SYSCLK:
969 hsc->Instance->BRR = (uint16_t)(HAL_RCC_GetSysClockFreq() / hsc->Init.BaudRate);
970 break;
971 case SMARTCARD_CLOCKSOURCE_LSE:
972 hsc->Instance->BRR = (uint16_t)(LSE_VALUE / hsc->Init.BaudRate);
973 break;
974 default:
975 break;
976 }
977 }
978
979 /**
980 * @brief Check the SMARTCARD Idle State
981 * @param hsc: SMARTCARD handle
982 * @retval HAL status
983 */
SMARTCARD_CheckIdleState(SMARTCARD_HandleTypeDef * hsc)984 static HAL_StatusTypeDef SMARTCARD_CheckIdleState(SMARTCARD_HandleTypeDef *hsc)
985 {
986
987 /* Initialize the SMARTCARD ErrorCode */
988 hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE;
989
990 /* Check if the Transmitter is enabled */
991 if ((hsc->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE) {
992 /* Wait until TEACK flag is set */
993 if (SMARTCARD_WaitOnFlagUntilTimeout(hsc, USART_ISR_TEACK, RESET, TEACK_REACK_TIMEOUT) != HAL_OK) {
994 return HAL_TIMEOUT;
995 }
996 }
997 /* Check if the Receiver is enabled */
998 if ((hsc->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE) {
999 /* Wait until REACK flag is set */
1000 if (SMARTCARD_WaitOnFlagUntilTimeout(hsc, USART_ISR_REACK, RESET, TEACK_REACK_TIMEOUT) != HAL_OK) {
1001 return HAL_TIMEOUT;
1002 }
1003 }
1004
1005 /* Process Unlocked */
1006 __HAL_UNLOCK(hsc);
1007
1008 /* Initialize the SMARTCARD state*/
1009 hsc->State= HAL_SMARTCARD_STATE_READY;
1010
1011 return HAL_OK;
1012 }
1013
1014 /**
1015 * @brief Configure the SMARTCARD associated USART peripheral advanced features
1016 * @param hsc: SMARTCARD handle
1017 * @retval None
1018 */
SMARTCARD_AdvFeatureConfig(SMARTCARD_HandleTypeDef * hsc)1019 static void SMARTCARD_AdvFeatureConfig(SMARTCARD_HandleTypeDef *hsc)
1020 {
1021 /* Check whether the set of advanced features to configure is properly set */
1022 assert_param(IS_SMARTCARD_ADVFEATURE_INIT(hsc->AdvancedInit.AdvFeatureInit));
1023
1024 /* if required, configure TX pin active level inversion */
1025 if (HAL_IS_BIT_SET(hsc->AdvancedInit.AdvFeatureInit, SMARTCARD_ADVFEATURE_TXINVERT_INIT)) {
1026 assert_param(IS_SMARTCARD_ADVFEATURE_TXINV(hsc->AdvancedInit.TxPinLevelInvert));
1027 MODIFY_REG(hsc->Instance->CR2, USART_CR2_TXINV, hsc->AdvancedInit.TxPinLevelInvert);
1028 }
1029
1030 /* if required, configure RX pin active level inversion */
1031 if (HAL_IS_BIT_SET(hsc->AdvancedInit.AdvFeatureInit, SMARTCARD_ADVFEATURE_RXINVERT_INIT)) {
1032 assert_param(IS_SMARTCARD_ADVFEATURE_RXINV(hsc->AdvancedInit.RxPinLevelInvert));
1033 MODIFY_REG(hsc->Instance->CR2, USART_CR2_RXINV, hsc->AdvancedInit.RxPinLevelInvert);
1034 }
1035
1036 /* if required, configure data inversion */
1037 if (HAL_IS_BIT_SET(hsc->AdvancedInit.AdvFeatureInit, SMARTCARD_ADVFEATURE_DATAINVERT_INIT)) {
1038 assert_param(IS_SMARTCARD_ADVFEATURE_DATAINV(hsc->AdvancedInit.DataInvert));
1039 MODIFY_REG(hsc->Instance->CR2, USART_CR2_DATAINV, hsc->AdvancedInit.DataInvert);
1040 }
1041
1042 /* if required, configure RX/TX pins swap */
1043 if (HAL_IS_BIT_SET(hsc->AdvancedInit.AdvFeatureInit, SMARTCARD_ADVFEATURE_SWAP_INIT)) {
1044 assert_param(IS_SMARTCARD_ADVFEATURE_SWAP(hsc->AdvancedInit.Swap));
1045 MODIFY_REG(hsc->Instance->CR2, USART_CR2_SWAP, hsc->AdvancedInit.Swap);
1046 }
1047
1048 /* if required, configure RX overrun detection disabling */
1049 if (HAL_IS_BIT_SET(hsc->AdvancedInit.AdvFeatureInit, SMARTCARD_ADVFEATURE_RXOVERRUNDISABLE_INIT)) {
1050 assert_param(IS_SMARTCARD_OVERRUN(hsc->AdvancedInit.OverrunDisable));
1051 MODIFY_REG(hsc->Instance->CR3, USART_CR3_OVRDIS, hsc->AdvancedInit.OverrunDisable);
1052 }
1053
1054 /* if required, configure DMA disabling on reception error */
1055 if (HAL_IS_BIT_SET(hsc->AdvancedInit.AdvFeatureInit, SMARTCARD_ADVFEATURE_DMADISABLEONERROR_INIT)) {
1056 assert_param(IS_SMARTCARD_ADVFEATURE_DMAONRXERROR(hsc->AdvancedInit.DMADisableonRxError));
1057 MODIFY_REG(hsc->Instance->CR3, USART_CR3_DDRE, hsc->AdvancedInit.DMADisableonRxError);
1058 }
1059
1060 /* if required, configure MSB first on communication line */
1061 if (HAL_IS_BIT_SET(hsc->AdvancedInit.AdvFeatureInit, SMARTCARD_ADVFEATURE_MSBFIRST_INIT)) {
1062 assert_param(IS_SMARTCARD_ADVFEATURE_MSBFIRST(hsc->AdvancedInit.MSBFirst));
1063 MODIFY_REG(hsc->Instance->CR2, USART_CR2_MSBFIRST, hsc->AdvancedInit.MSBFirst);
1064 }
1065 }
1066
1067 /**
1068 * @brief This function handles SMARTCARD Communication Timeout.
1069 * @param hsc: SMARTCARD handle
1070 * @param Flag: specifies the SMARTCARD flag to check.
1071 * @param Status: The new Flag status (SET or RESET).
1072 * @param Timeout: Timeout duration
1073 * @retval HAL status
1074 */
SMARTCARD_WaitOnFlagUntilTimeout(SMARTCARD_HandleTypeDef * hsc,uint32_t Flag,FlagStatus Status,uint32_t Timeout)1075 static HAL_StatusTypeDef SMARTCARD_WaitOnFlagUntilTimeout(SMARTCARD_HandleTypeDef *hsc, uint32_t Flag, FlagStatus Status, uint32_t Timeout)
1076 {
1077 uint32_t tickstart = 0x00;
1078
1079 /* Get tick */
1080 tickstart = HAL_GetTick();
1081
1082 /* Wait until flag is set */
1083 if (Status == RESET) {
1084 while (__HAL_SMARTCARD_GET_FLAG(hsc, Flag) == RESET) {
1085 /* Check for the Timeout */
1086 if (Timeout != HAL_MAX_DELAY) {
1087 if ((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) {
1088 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
1089 __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_TXE);
1090 __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_RXNE);
1091 __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_PE);
1092 __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_ERR);
1093
1094 hsc->State= HAL_SMARTCARD_STATE_READY;
1095
1096 /* Process Unlocked */
1097 __HAL_UNLOCK(hsc);
1098
1099 return HAL_TIMEOUT;
1100 }
1101 }
1102 }
1103 } else {
1104 while (__HAL_SMARTCARD_GET_FLAG(hsc, Flag) != RESET) {
1105 /* Check for the Timeout */
1106 if (Timeout != HAL_MAX_DELAY) {
1107 if ((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) {
1108 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
1109 __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_TXE);
1110 __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_RXNE);
1111 __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_PE);
1112 __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_ERR);
1113
1114 hsc->State= HAL_SMARTCARD_STATE_READY;
1115
1116 /* Process Unlocked */
1117 __HAL_UNLOCK(hsc);
1118
1119 return HAL_TIMEOUT;
1120 }
1121 }
1122 }
1123 }
1124 return HAL_OK;
1125 }
1126
1127 /**
1128 * @brief DMA SMARTCARD transmit process complete callback
1129 * @param hdma: DMA handle
1130 * @retval None
1131 */
SMARTCARD_DMATransmitCplt(DMA_HandleTypeDef * hdma)1132 static void SMARTCARD_DMATransmitCplt(DMA_HandleTypeDef *hdma)
1133 {
1134 SMARTCARD_HandleTypeDef* hsc = ( SMARTCARD_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1135 hsc->TxXferCount = 0;
1136
1137 /* Disable the DMA transfer for transmit request by setting the DMAT bit
1138 in the SMARTCARD associated USART CR3 register */
1139 hsc->Instance->CR3 &= (uint16_t)~((uint16_t)USART_CR3_DMAT);
1140
1141 /* Wait for SMARTCARD TC Flag */
1142 if (SMARTCARD_WaitOnFlagUntilTimeout(hsc, SMARTCARD_FLAG_TC, RESET, HAL_SMARTCARD_TXDMA_TIMEOUTVALUE) != HAL_OK) {
1143 /* Timeout Occurred */
1144 hsc->State = HAL_SMARTCARD_STATE_TIMEOUT;
1145 HAL_SMARTCARD_ErrorCallback(hsc);
1146 } else {
1147 /* No Timeout */
1148 /* Check if a receive Process is ongoing or not */
1149 if (hsc->State == HAL_SMARTCARD_STATE_BUSY_TX_RX) {
1150 hsc->State = HAL_SMARTCARD_STATE_BUSY_RX;
1151 } else {
1152 hsc->State = HAL_SMARTCARD_STATE_READY;
1153 }
1154 HAL_SMARTCARD_TxCpltCallback(hsc);
1155 }
1156 }
1157
1158 /**
1159 * @brief DMA SMARTCARD receive process complete callback
1160 * @param hdma: DMA handle
1161 * @retval None
1162 */
SMARTCARD_DMAReceiveCplt(DMA_HandleTypeDef * hdma)1163 static void SMARTCARD_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
1164 {
1165 SMARTCARD_HandleTypeDef* hsc = ( SMARTCARD_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1166 hsc->RxXferCount = 0;
1167
1168 /* Disable the DMA transfer for the receiver request by setting the DMAR bit
1169 in the SMARTCARD associated USART CR3 register */
1170 hsc->Instance->CR3 &= (uint16_t)~((uint16_t)USART_CR3_DMAR);
1171
1172 /* Check if a transmit Process is ongoing or not */
1173 if (hsc->State == HAL_SMARTCARD_STATE_BUSY_TX_RX) {
1174 hsc->State = HAL_SMARTCARD_STATE_BUSY_TX;
1175 } else {
1176 hsc->State = HAL_SMARTCARD_STATE_READY;
1177 }
1178
1179 HAL_SMARTCARD_RxCpltCallback(hsc);
1180 }
1181
1182 /**
1183 * @brief DMA SMARTCARD communication error callback
1184 * @param hdma: DMA handle
1185 * @retval None
1186 */
SMARTCARD_DMAError(DMA_HandleTypeDef * hdma)1187 static void SMARTCARD_DMAError(DMA_HandleTypeDef *hdma)
1188 {
1189 SMARTCARD_HandleTypeDef* hsc = ( SMARTCARD_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1190 hsc->RxXferCount = 0;
1191 hsc->TxXferCount = 0;
1192 hsc->State= HAL_SMARTCARD_STATE_READY;
1193 hsc->ErrorCode |= HAL_SMARTCARD_ERROR_DMA;
1194 HAL_SMARTCARD_ErrorCallback(hsc);
1195 }
1196 /**
1197 * @}
1198 */
1199
1200 #endif /* HAL_SMARTCARD_MODULE_ENABLED */
1201 /**
1202 * @}
1203 */
1204
1205 /**
1206 * @}
1207 */
1208
1209 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
1210