aboutsummaryrefslogtreecommitdiff
path: root/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_STM32F4/stm32f4xx_hal_dac_ex.c
blob: 65918291d435bc713a172ef1b3fe5b50736f87c6 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
/**
  ******************************************************************************
  * @file    stm32f4xx_hal_dac_ex.c
  * @author  MCD Application Team
  * @version V1.4.1
  * @date    09-October-2015
  * @brief   DAC HAL module driver.
  *         This file provides firmware functions to manage the following 
  *         functionalities of DAC extension peripheral:
  *           + Extended features functions
  *     
  *
  @verbatim      
  ==============================================================================
                      ##### How to use this driver #####
  ==============================================================================
    [..]          
      (+) When Dual mode is enabled (i.e DAC Channel1 and Channel2 are used simultaneously) :
          Use HAL_DACEx_DualGetValue() to get digital data to be converted and use
          HAL_DACEx_DualSetValue() to set digital value to converted simultaneously in Channel 1 and Channel 2.  
      (+) Use HAL_DACEx_TriangleWaveGenerate() to generate Triangle signal.
      (+) Use HAL_DACEx_NoiseWaveGenerate() to generate Noise signal.
   
 @endverbatim    
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
  *
  * Redistribution and use in source and binary forms, with or without modification,
  * are permitted provided that the following conditions are met:
  *   1. Redistributions of source code must retain the above copyright notice,
  *      this list of conditions and the following disclaimer.
  *   2. Redistributions in binary form must reproduce the above copyright notice,
  *      this list of conditions and the following disclaimer in the documentation
  *      and/or other materials provided with the distribution.
  *   3. Neither the name of STMicroelectronics nor the names of its contributors
  *      may be used to endorse or promote products derived from this software
  *      without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  ******************************************************************************
  */ 


/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx_hal.h"

/** @addtogroup STM32F4xx_HAL_Driver
  * @{
  */

/** @defgroup DACEx DACEx
  * @brief DAC driver modules
  * @{
  */ 

#ifdef HAL_DAC_MODULE_ENABLED

#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) ||\
    defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\
    defined(STM32F410Tx) || defined(STM32F410Cx) || defined(STM32F410Rx) || defined(STM32F446xx) ||\
    defined(STM32F469xx) || defined(STM32F479xx)
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
/** @defgroup DACEx_Exported_Functions DAC Exported Functions
  * @{
  */

/** @defgroup DACEx_Exported_Functions_Group1 Extended features functions
 *  @brief    Extended features functions 
 *
@verbatim   
  ==============================================================================
                 ##### Extended features functions #####
  ==============================================================================  
    [..]  This section provides functions allowing to:
      (+) Start conversion.
      (+) Stop conversion.
      (+) Start conversion and enable DMA transfer.
      (+) Stop conversion and disable DMA transfer.
      (+) Get result of conversion.
      (+) Get result of dual mode conversion.
                     
@endverbatim
  * @{
  */

/**
  * @brief  Returns the last data output value of the selected DAC channel.
  * @param  hdac: pointer to a DAC_HandleTypeDef structure that contains
  *         the configuration information for the specified DAC.
  * @retval The selected DAC channel data output value.
  */
uint32_t HAL_DACEx_DualGetValue(DAC_HandleTypeDef* hdac)
{
  uint32_t tmp = 0;
  
  tmp |= hdac->Instance->DOR1;
  
  tmp |= hdac->Instance->DOR2 << 16;
  
  /* Returns the DAC channel data output register value */
  return tmp;
}

/**
  * @brief  Enables or disables the selected DAC channel wave generation.
  * @param  hdac: pointer to a DAC_HandleTypeDef structure that contains
  *         the configuration information for the specified DAC.
  * @param  Channel: The selected DAC channel. 
  *          This parameter can be one of the following values:
  *            DAC_CHANNEL_1 / DAC_CHANNEL_2
  * @param  Amplitude: Select max triangle amplitude. 
  *          This parameter can be one of the following values:
  *            @arg DAC_TRIANGLEAMPLITUDE_1: Select max triangle amplitude of 1
  *            @arg DAC_TRIANGLEAMPLITUDE_3: Select max triangle amplitude of 3
  *            @arg DAC_TRIANGLEAMPLITUDE_7: Select max triangle amplitude of 7
  *            @arg DAC_TRIANGLEAMPLITUDE_15: Select max triangle amplitude of 15
  *            @arg DAC_TRIANGLEAMPLITUDE_31: Select max triangle amplitude of 31
  *            @arg DAC_TRIANGLEAMPLITUDE_63: Select max triangle amplitude of 63
  *            @arg DAC_TRIANGLEAMPLITUDE_127: Select max triangle amplitude of 127
  *            @arg DAC_TRIANGLEAMPLITUDE_255: Select max triangle amplitude of 255
  *            @arg DAC_TRIANGLEAMPLITUDE_511: Select max triangle amplitude of 511
  *            @arg DAC_TRIANGLEAMPLITUDE_1023: Select max triangle amplitude of 1023
  *            @arg DAC_TRIANGLEAMPLITUDE_2047: Select max triangle amplitude of 2047
  *            @arg DAC_TRIANGLEAMPLITUDE_4095: Select max triangle amplitude of 4095                               
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DACEx_TriangleWaveGenerate(DAC_HandleTypeDef* hdac, uint32_t Channel, uint32_t Amplitude)
{  
  /* Check the parameters */
  assert_param(IS_DAC_CHANNEL(Channel));
  assert_param(IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(Amplitude));
  
  /* Process locked */
  __HAL_LOCK(hdac);
  
  /* Change DAC state */
  hdac->State = HAL_DAC_STATE_BUSY;
  
  /* Enable the selected wave generation for the selected DAC channel */
  MODIFY_REG(hdac->Instance->CR, (DAC_CR_WAVE1 | DAC_CR_MAMP1) << Channel, (DAC_CR_WAVE1_1 | Amplitude) << Channel);
  
  /* Change DAC state */
  hdac->State = HAL_DAC_STATE_READY;
  
  /* Process unlocked */
  __HAL_UNLOCK(hdac);
  
  /* Return function status */
  return HAL_OK;
}

/**
  * @brief  Enables or disables the selected DAC channel wave generation.
  * @param  hdac: pointer to a DAC_HandleTypeDef structure that contains
  *         the configuration information for the specified DAC. 
  * @param  Channel: The selected DAC channel. 
  *          This parameter can be one of the following values:
  *            DAC_CHANNEL_1 / DAC_CHANNEL_2
  * @param  Amplitude: Unmask DAC channel LFSR for noise wave generation. 
  *          This parameter can be one of the following values: 
  *            @arg DAC_LFSRUNMASK_BIT0: Unmask DAC channel LFSR bit0 for noise wave generation
  *            @arg DAC_LFSRUNMASK_BITS1_0: Unmask DAC channel LFSR bit[1:0] for noise wave generation  
  *            @arg DAC_LFSRUNMASK_BITS2_0: Unmask DAC channel LFSR bit[2:0] for noise wave generation
  *            @arg DAC_LFSRUNMASK_BITS3_0: Unmask DAC channel LFSR bit[3:0] for noise wave generation 
  *            @arg DAC_LFSRUNMASK_BITS4_0: Unmask DAC channel LFSR bit[4:0] for noise wave generation 
  *            @arg DAC_LFSRUNMASK_BITS5_0: Unmask DAC channel LFSR bit[5:0] for noise wave generation 
  *            @arg DAC_LFSRUNMASK_BITS6_0: Unmask DAC channel LFSR bit[6:0] for noise wave generation 
  *            @arg DAC_LFSRUNMASK_BITS7_0: Unmask DAC channel LFSR bit[7:0] for noise wave generation 
  *            @arg DAC_LFSRUNMASK_BITS8_0: Unmask DAC channel LFSR bit[8:0] for noise wave generation 
  *            @arg DAC_LFSRUNMASK_BITS9_0: Unmask DAC channel LFSR bit[9:0] for noise wave generation 
  *            @arg DAC_LFSRUNMASK_BITS10_0: Unmask DAC channel LFSR bit[10:0] for noise wave generation 
  *            @arg DAC_LFSRUNMASK_BITS11_0: Unmask DAC channel LFSR bit[11:0] for noise wave generation 
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DACEx_NoiseWaveGenerate(DAC_HandleTypeDef* hdac, uint32_t Channel, uint32_t Amplitude)
{  
  /* Check the parameters */
  assert_param(IS_DAC_CHANNEL(Channel));
  assert_param(IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(Amplitude));
  
  /* Process locked */
  __HAL_LOCK(hdac);
  
  /* Change DAC state */
  hdac->State = HAL_DAC_STATE_BUSY;
  
  /* Enable the selected wave generation for the selected DAC channel */
  MODIFY_REG(hdac->Instance->CR, (DAC_CR_WAVE1 | DAC_CR_MAMP1) << Channel, (DAC_CR_WAVE1_0 | Amplitude) << Channel);
  
  /* Change DAC state */
  hdac->State = HAL_DAC_STATE_READY;
  
  /* Process unlocked */
  __HAL_UNLOCK(hdac);
  
  /* Return function status */
  return HAL_OK;
}

/**
  * @brief  Set the specified data holding register value for dual DAC channel.
  * @param  hdac: pointer to a DAC_HandleTypeDef structure that contains
  *               the configuration information for the specified DAC.
  * @param  Alignment: Specifies the data alignment for dual channel DAC.
  *          This parameter can be one of the following values:
  *            DAC_ALIGN_8B_R: 8bit right data alignment selected
  *            DAC_ALIGN_12B_L: 12bit left data alignment selected
  *            DAC_ALIGN_12B_R: 12bit right data alignment selected
  * @param  Data1: Data for DAC Channel2 to be loaded in the selected data holding register.
  * @param  Data2: Data for DAC Channel1 to be loaded in the selected data  holding register.
  * @note   In dual mode, a unique register access is required to write in both
  *          DAC channels at the same time.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DACEx_DualSetValue(DAC_HandleTypeDef* hdac, uint32_t Alignment, uint32_t Data1, uint32_t Data2)
{  
  uint32_t data = 0, tmp = 0;
  
  /* Check the parameters */
  assert_param(IS_DAC_ALIGN(Alignment));
  assert_param(IS_DAC_DATA(Data1));
  assert_param(IS_DAC_DATA(Data2));
  
  /* Calculate and set dual DAC data holding register value */
  if (Alignment == DAC_ALIGN_8B_R)
  {
    data = ((uint32_t)Data2 << 8) | Data1; 
  }
  else
  {
    data = ((uint32_t)Data2 << 16) | Data1;
  }
  
  tmp = (uint32_t)hdac->Instance;
  tmp += DAC_DHR12RD_ALIGNMENT(Alignment);

  /* Set the dual DAC selected data holding register */
  *(__IO uint32_t *)tmp = data;
  
  /* Return function status */
  return HAL_OK;
}

/**
  * @}
  */

/**
  * @brief  Conversion complete callback in non blocking mode for Channel2 
  * @param  hdac: pointer to a DAC_HandleTypeDef structure that contains
  *         the configuration information for the specified DAC.
  * @retval None
  */
__weak void HAL_DACEx_ConvCpltCallbackCh2(DAC_HandleTypeDef* hdac)
{
  /* NOTE : This function Should not be modified, when the callback is needed,
            the HAL_DAC_ConvCpltCallback could be implemented in the user file
   */
}

/**
  * @brief  Conversion half DMA transfer callback in non blocking mode for Channel2 
  * @param  hdac: pointer to a DAC_HandleTypeDef structure that contains
  *         the configuration information for the specified DAC.
  * @retval None
  */
__weak void HAL_DACEx_ConvHalfCpltCallbackCh2(DAC_HandleTypeDef* hdac)
{
  /* NOTE : This function Should not be modified, when the callback is needed,
            the HAL_DAC_ConvHalfCpltCallbackCh2 could be implemented in the user file
   */
}

/**
  * @brief  Error DAC callback for Channel2.
  * @param  hdac: pointer to a DAC_HandleTypeDef structure that contains
  *         the configuration information for the specified DAC.
  * @retval None
  */
__weak void HAL_DACEx_ErrorCallbackCh2(DAC_HandleTypeDef *hdac)
{
  /* NOTE : This function Should not be modified, when the callback is needed,
            the HAL_DAC_ErrorCallback could be implemented in the user file
   */
}

/**
  * @brief  DMA underrun DAC callback for channel2.
  * @param  hdac: pointer to a DAC_HandleTypeDef structure that contains
  *         the configuration information for the specified DAC.
  * @retval None
  */
__weak void HAL_DACEx_DMAUnderrunCallbackCh2(DAC_HandleTypeDef *hdac)
{
  /* NOTE : This function Should not be modified, when the callback is needed,
            the HAL_DAC_DMAUnderrunCallbackCh2 could be implemented in the user file
   */
}

/**
  * @brief  DMA conversion complete callback. 
  * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
  *                the configuration information for the specified DMA module.
  * @retval None
  */
void DAC_DMAConvCpltCh2(DMA_HandleTypeDef *hdma)   
{
  DAC_HandleTypeDef* hdac = ( DAC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
  
  HAL_DACEx_ConvCpltCallbackCh2(hdac); 
  
  hdac->State= HAL_DAC_STATE_READY;
}

/**
  * @brief  DMA half transfer complete callback. 
  * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
  *                the configuration information for the specified DMA module.
  * @retval None
  */
void DAC_DMAHalfConvCpltCh2(DMA_HandleTypeDef *hdma)   
{
    DAC_HandleTypeDef* hdac = ( DAC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
    /* Conversion complete callback */
    HAL_DACEx_ConvHalfCpltCallbackCh2(hdac); 
}

/**
  * @brief  DMA error callback 
  * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
  *                the configuration information for the specified DMA module.
  * @retval None
  */
void DAC_DMAErrorCh2(DMA_HandleTypeDef *hdma)   
{
  DAC_HandleTypeDef* hdac = ( DAC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
    
  /* Set DAC error code to DMA error */
  hdac->ErrorCode |= HAL_DAC_ERROR_DMA;
    
  HAL_DACEx_ErrorCallbackCh2(hdac); 
    
  hdac->State= HAL_DAC_STATE_READY;
}

/**
  * @}
  */

#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx ||\
          STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx ||\
          STM32F410xx || STM32F446xx || STM32F469xx || STM32F479xx */

#endif /* HAL_DAC_MODULE_ENABLED */

/**
  * @}
  */

/**
  * @}
  */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
span class="cm"> ============================== [..] (+) Send an amount of data in non blocking mode (DMA) using HAL_SMARTCARD_Transmit_DMA() (+) At transmission end of transfer HAL_SMARTCARD_TxCpltCallback is executed and user can add his own code by customization of function pointer HAL_SMARTCARD_TxCpltCallback (+) Receive an amount of data in non blocking mode (DMA) using HAL_SMARTCARD_Receive_DMA() (+) At reception end of transfer HAL_SMARTCARD_RxCpltCallback is executed and user can add his own code by customization of function pointer HAL_SMARTCARD_RxCpltCallback (+) In case of transfer Error, HAL_SMARTCARD_ErrorCallback() function is executed and user can add his own code by customization of function pointer HAL_SMARTCARD_ErrorCallback *** SMARTCARD HAL driver macros list *** ============================================= [..] Below the list of most used macros in SMARTCARD HAL driver. (+) __HAL_SMARTCARD_ENABLE: Enable the SMARTCARD peripheral (+) __HAL_SMARTCARD_DISABLE: Disable the SMARTCARD peripheral (+) __HAL_SMARTCARD_GET_FLAG : Check whether the specified SMARTCARD flag is set or not (+) __HAL_SMARTCARD_CLEAR_FLAG : Clear the specified SMARTCARD pending flag (+) __HAL_SMARTCARD_ENABLE_IT: Enable the specified SMARTCARD interrupt (+) __HAL_SMARTCARD_DISABLE_IT: Disable the specified SMARTCARD interrupt [..] (@) You can refer to the SMARTCARD HAL driver header file for more useful macros @endverbatim ****************************************************************************** * @attention * * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2> * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. Neither the name of STMicroelectronics nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include "stm32f4xx_hal.h" /** @addtogroup STM32F4xx_HAL_Driver * @{ */ /** @defgroup SMARTCARD SMARTCARD * @brief HAL USART SMARTCARD module driver * @{ */ #ifdef HAL_SMARTCARD_MODULE_ENABLED /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ /** @addtogroup SMARTCARD_Private_Constants * @{ */ #define SMARTCARD_TIMEOUT_VALUE 22000 /** * @} */ /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/ /** @addtogroup SMARTCARD_Private_Functions * @{ */ static void SMARTCARD_SetConfig (SMARTCARD_HandleTypeDef *hsc); static HAL_StatusTypeDef SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef *hsc); static HAL_StatusTypeDef SMARTCARD_EndTransmit_IT(SMARTCARD_HandleTypeDef *hsmartcard); static HAL_StatusTypeDef SMARTCARD_Receive_IT(SMARTCARD_HandleTypeDef *hsc); static void SMARTCARD_DMATransmitCplt(DMA_HandleTypeDef *hdma); static void SMARTCARD_DMAReceiveCplt(DMA_HandleTypeDef *hdma); static void SMARTCARD_DMAError(DMA_HandleTypeDef *hdma); static HAL_StatusTypeDef SMARTCARD_WaitOnFlagUntilTimeout(SMARTCARD_HandleTypeDef *hsc, uint32_t Flag, FlagStatus Status, uint32_t Timeout); /** * @} */ /* Exported functions --------------------------------------------------------*/ /** @defgroup SMARTCARD_Exported_Functions SMARTCARD Exported Functions * @{ */ /** @defgroup SMARTCARD_Exported_Functions_Group1 SmartCard Initialization and de-initialization functions * @brief Initialization and Configuration functions * @verbatim ============================================================================== ##### Initialization and Configuration functions ##### ============================================================================== [..] This subsection provides a set of functions allowing to initialize the USART in Smartcard mode. [..] The Smartcard interface is designed to support asynchronous protocol Smartcards as defined in the ISO 7816-3 standard. [..] The USART can provide a clock to the smartcard through the SCLK output. In smartcard mode, SCLK is not associated to the communication but is simply derived from the internal peripheral input clock through a 5-bit prescaler. [..] (+) For the Smartcard mode only these parameters can be configured: (++) Baud Rate (++) Word Length => Should be 9 bits (8 bits + parity) (++) Stop Bit (++) Parity: => Should be enabled +-------------------------------------------------------------+ | M bit | PCE bit | SMARTCARD frame | |---------------------|---------------------------------------| | 1 | 1 | | SB | 8 bit data | PB | STB | | +-------------------------------------------------------------+ (++) USART polarity (++) USART phase (++) USART LastBit (++) Receiver/transmitter modes (++) Prescaler (++) GuardTime (++) NACKState: The Smartcard NACK state (+) Recommended SmartCard interface configuration to get the Answer to Reset from the Card: (++) Word Length = 9 Bits (++) 1.5 Stop Bit (++) Even parity (++) BaudRate = 12096 baud (++) Tx and Rx enabled [..] Please refer to the ISO 7816-3 specification for more details. -@- It is also possible to choose 0.5 stop bit for receiving but it is recommended to use 1.5 stop bits for both transmitting and receiving to avoid switching between the two configurations. [..] The HAL_SMARTCARD_Init() function follows the USART SmartCard configuration procedure (details for the procedure are available in reference manual (RM0329)). @endverbatim * @{ */ /** * @brief Initializes the SmartCard mode according to the specified * parameters in the SMARTCARD_InitTypeDef and create the associated handle . * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains * the configuration information for SMARTCARD module. * @retval HAL status */ HAL_StatusTypeDef HAL_SMARTCARD_Init(SMARTCARD_HandleTypeDef *hsc) { /* Check the SMARTCARD handle allocation */ if(hsc == NULL) { return HAL_ERROR; } /* Check the parameters */ assert_param(IS_SMARTCARD_INSTANCE(hsc->Instance)); assert_param(IS_SMARTCARD_NACK_STATE(hsc->Init.NACKState)); if(hsc->State == HAL_SMARTCARD_STATE_RESET) { /* Allocate lock resource and initialize it */ hsc->Lock = HAL_UNLOCKED; /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */ HAL_SMARTCARD_MspInit(hsc); } hsc->State = HAL_SMARTCARD_STATE_BUSY; /* Set the Prescaler */ MODIFY_REG(hsc->Instance->GTPR, USART_GTPR_PSC, hsc->Init.Prescaler); /* Set the Guard Time */ MODIFY_REG(hsc->Instance->GTPR, USART_GTPR_GT, ((hsc->Init.GuardTime)<<8)); /* Set the Smartcard Communication parameters */ SMARTCARD_SetConfig(hsc); /* In SmartCard mode, the following bits must be kept cleared: - LINEN bit in the USART_CR2 register - HDSEL and IREN bits in the USART_CR3 register.*/ hsc->Instance->CR2 &= ~USART_CR2_LINEN; hsc->Instance->CR3 &= ~(USART_CR3_IREN | USART_CR3_HDSEL); /* Enable the SMARTCARD Parity Error Interrupt */ __HAL_SMARTCARD_ENABLE_IT(hsc, SMARTCARD_IT_PE); /* Enable the SMARTCARD Framing Error Interrupt */ __HAL_SMARTCARD_ENABLE_IT(hsc, SMARTCARD_IT_ERR); /* Enable the Peripheral */ __HAL_SMARTCARD_ENABLE(hsc); /* Configure the Smartcard NACK state */ MODIFY_REG(hsc->Instance->CR3, USART_CR3_NACK, hsc->Init.NACKState); /* Enable the SC mode by setting the SCEN bit in the CR3 register */ hsc->Instance->CR3 |= (USART_CR3_SCEN); /* Initialize the SMARTCARD state*/ hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE; hsc->State= HAL_SMARTCARD_STATE_READY; return HAL_OK; } /** * @brief DeInitializes the USART SmartCard peripheral * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains * the configuration information for SMARTCARD module. * @retval HAL status */ HAL_StatusTypeDef HAL_SMARTCARD_DeInit(SMARTCARD_HandleTypeDef *hsc) { /* Check the SMARTCARD handle allocation */ if(hsc == NULL) { return HAL_ERROR; } /* Check the parameters */ assert_param(IS_SMARTCARD_INSTANCE(hsc->Instance)); hsc->State = HAL_SMARTCARD_STATE_BUSY; /* Disable the Peripheral */ __HAL_SMARTCARD_DISABLE(hsc); /* DeInit the low level hardware */ HAL_SMARTCARD_MspDeInit(hsc); hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE; hsc->State = HAL_SMARTCARD_STATE_RESET; /* Release Lock */ __HAL_UNLOCK(hsc); return HAL_OK; } /** * @brief SMARTCARD MSP Init * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains * the configuration information for SMARTCARD module. * @retval None */ __weak void HAL_SMARTCARD_MspInit(SMARTCARD_HandleTypeDef *hsc) { /* NOTE : This function Should not be modified, when the callback is needed, the HAL_SMARTCARD_MspInit could be implemented in the user file */ } /** * @brief SMARTCARD MSP DeInit * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains * the configuration information for SMARTCARD module. * @retval None */ __weak void HAL_SMARTCARD_MspDeInit(SMARTCARD_HandleTypeDef *hsc) { /* NOTE : This function Should not be modified, when the callback is needed, the HAL_SMARTCARD_MspDeInit could be implemented in the user file */ } /** * @} */ /** @defgroup SMARTCARD_Exported_Functions_Group2 IO operation functions * @brief SMARTCARD Transmit and Receive functions * @verbatim =============================================================================== ##### IO operation functions ##### =============================================================================== This subsection provides a set of functions allowing to manage the SMARTCARD data transfers. [..] Smartcard is a single wire half duplex communication protocol. The Smartcard interface is designed to support asynchronous protocol Smartcards as defined in the ISO 7816-3 standard. The USART should be configured as: (+) 8 bits plus parity: where M=1 and PCE=1 in the USART_CR1 register (+) 1.5 stop bits when transmitting and receiving: where STOP=11 in the USART_CR2 register. (#) There are two modes of transfer: (++) Blocking mode: The communication is performed in polling mode. The HAL status of all data processing is returned by the same function after finishing transfer. (++) Non Blocking mode: The communication is performed using Interrupts or DMA, These APIs return the HAL status. The end of the data processing will be indicated through the dedicated SMARTCARD IRQ when using Interrupt mode or the DMA IRQ when using DMA mode. The HAL_SMARTCARD_TxCpltCallback(), HAL_SMARTCARD_RxCpltCallback() user callbacks will be executed respectively at the end of the Transmit or Receive process The HAL_SMARTCARD_ErrorCallback() user callback will be executed when a communication error is detected (#) Blocking mode APIs are : (++) HAL_SMARTCARD_Transmit() (++) HAL_SMARTCARD_Receive() (#) Non Blocking mode APIs with Interrupt are : (++) HAL_SMARTCARD_Transmit_IT() (++) HAL_SMARTCARD_Receive_IT() (++) HAL_SMARTCARD_IRQHandler() (#) Non Blocking mode functions with DMA are : (++) HAL_SMARTCARD_Transmit_DMA() (++) HAL_SMARTCARD_Receive_DMA() (#) A set of Transfer Complete Callbacks are provided in non Blocking mode: (++) HAL_SMARTCARD_TxCpltCallback() (++) HAL_SMARTCARD_RxCpltCallback() (++) HAL_SMARTCARD_ErrorCallback() @endverbatim * @{ */ /** * @brief Send an amount of data in blocking mode * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains * the configuration information for SMARTCARD module. * @param pData: pointer to data buffer * @param Size: amount of data to be sent * @param Timeout: Timeout duration * @retval HAL status */ HAL_StatusTypeDef HAL_SMARTCARD_Transmit(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size, uint32_t Timeout) { uint16_t* tmp; uint32_t tmp1 = 0; tmp1 = hsc->State; if((tmp1 == HAL_SMARTCARD_STATE_READY) || (tmp1 == HAL_SMARTCARD_STATE_BUSY_RX)) { if((pData == NULL) || (Size == 0)) { return HAL_ERROR; } /* Process Locked */ __HAL_LOCK(hsc); hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE; /* Check if a non-blocking receive process is ongoing or not */ if(hsc->State == HAL_SMARTCARD_STATE_BUSY_RX) { hsc->State = HAL_SMARTCARD_STATE_BUSY_TX_RX; } else { hsc->State = HAL_SMARTCARD_STATE_BUSY_TX; } hsc->TxXferSize = Size; hsc->TxXferCount = Size; while(hsc->TxXferCount > 0) { hsc->TxXferCount--; if(SMARTCARD_WaitOnFlagUntilTimeout(hsc, SMARTCARD_FLAG_TXE, RESET, Timeout) != HAL_OK) { return HAL_TIMEOUT; } tmp = (uint16_t*) pData; hsc->Instance->DR = (*tmp & (uint16_t)0x01FF); pData +=1; } if(SMARTCARD_WaitOnFlagUntilTimeout(hsc, SMARTCARD_FLAG_TC, RESET, Timeout) != HAL_OK) { return HAL_TIMEOUT; } /* Check if a non-blocking receive process is ongoing or not */ if(hsc->State == HAL_SMARTCARD_STATE_BUSY_TX_RX) { hsc->State = HAL_SMARTCARD_STATE_BUSY_RX; } else { hsc->State = HAL_SMARTCARD_STATE_READY; } /* Process Unlocked */ __HAL_UNLOCK(hsc); return HAL_OK; } else { return HAL_BUSY; } } /** * @brief Receive an amount of data in blocking mode * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains * the configuration information for SMARTCARD module. * @param pData: pointer to data buffer * @param Size: amount of data to be received * @param Timeout: Timeout duration * @retval HAL status */ HAL_StatusTypeDef HAL_SMARTCARD_Receive(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size, uint32_t Timeout) { uint16_t* tmp; uint32_t tmp1 = 0; tmp1 = hsc->State; if((tmp1 == HAL_SMARTCARD_STATE_READY) || (tmp1 == HAL_SMARTCARD_STATE_BUSY_TX)) { if((pData == NULL) || (Size == 0)) { return HAL_ERROR; } /* Process Locked */ __HAL_LOCK(hsc); hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE; /* Check if a non-blocking transmit process is ongoing or not */ if(hsc->State == HAL_SMARTCARD_STATE_BUSY_TX) { hsc->State = HAL_SMARTCARD_STATE_BUSY_TX_RX; } else { hsc->State = HAL_SMARTCARD_STATE_BUSY_RX; } hsc->RxXferSize = Size; hsc->RxXferCount = Size; /* Check the remain data to be received */ while(hsc->RxXferCount > 0) { hsc->RxXferCount--; if(SMARTCARD_WaitOnFlagUntilTimeout(hsc, SMARTCARD_FLAG_RXNE, RESET, Timeout) != HAL_OK) { return HAL_TIMEOUT; } tmp = (uint16_t*) pData; *tmp = (uint16_t)(hsc->Instance->DR & (uint16_t)0x00FF); pData +=1; } /* Check if a non-blocking transmit process is ongoing or not */ if(hsc->State == HAL_SMARTCARD_STATE_BUSY_TX_RX) { hsc->State = HAL_SMARTCARD_STATE_BUSY_TX; } else { hsc->State = HAL_SMARTCARD_STATE_READY; } /* Process Unlocked */ __HAL_UNLOCK(hsc); return HAL_OK; } else { return HAL_BUSY; } } /** * @brief Send an amount of data in non blocking mode * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains * the configuration information for SMARTCARD module. * @param pData: pointer to data buffer * @param Size: amount of data to be sent * @retval HAL status */ HAL_StatusTypeDef HAL_SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size) { uint32_t tmp1 = 0; tmp1 = hsc->State; if((tmp1 == HAL_SMARTCARD_STATE_READY) || (tmp1 == HAL_SMARTCARD_STATE_BUSY_RX)) { if((pData == NULL) || (Size == 0)) { return HAL_ERROR; } /* Process Locked */ __HAL_LOCK(hsc); hsc->pTxBuffPtr = pData; hsc->TxXferSize = Size; hsc->TxXferCount = Size; hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE; /* Check if a non-blocking receive process is ongoing or not */ if(hsc->State == HAL_SMARTCARD_STATE_BUSY_RX) { hsc->State = HAL_SMARTCARD_STATE_BUSY_TX_RX; } else { hsc->State = HAL_SMARTCARD_STATE_BUSY_TX; } /* Process Unlocked */ __HAL_UNLOCK(hsc); /* Enable the SMARTCARD Parity Error Interrupt */ __HAL_SMARTCARD_ENABLE_IT(hsc, SMARTCARD_IT_PE); /* Disable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */ __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_ERR); /* Enable the SMARTCARD Transmit data register empty Interrupt */ __HAL_SMARTCARD_ENABLE_IT(hsc, SMARTCARD_IT_TXE); return HAL_OK; } else { return HAL_BUSY; } } /** * @brief Receive an amount of data in non blocking mode * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains * the configuration information for SMARTCARD module. * @param pData: pointer to data buffer * @param Size: amount of data to be received * @retval HAL status */ HAL_StatusTypeDef HAL_SMARTCARD_Receive_IT(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size) { uint32_t tmp1 = 0; tmp1 = hsc->State; if((tmp1 == HAL_SMARTCARD_STATE_READY) || (tmp1 == HAL_SMARTCARD_STATE_BUSY_TX)) { if((pData == NULL) || (Size == 0)) { return HAL_ERROR; } /* Process Locked */ __HAL_LOCK(hsc); hsc->pRxBuffPtr = pData; hsc->RxXferSize = Size; hsc->RxXferCount = Size; hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE; /* Check if a non-blocking transmit process is ongoing or not */ if(hsc->State == HAL_SMARTCARD_STATE_BUSY_TX) { hsc->State = HAL_SMARTCARD_STATE_BUSY_TX_RX; } else { hsc->State = HAL_SMARTCARD_STATE_BUSY_RX; } /* Process Unlocked */ __HAL_UNLOCK(hsc); /* Enable the SMARTCARD Data Register not empty Interrupt */ __HAL_SMARTCARD_ENABLE_IT(hsc, SMARTCARD_IT_RXNE); /* Enable the SMARTCARD Parity Error Interrupt */ __HAL_SMARTCARD_ENABLE_IT(hsc, SMARTCARD_IT_PE); /* Enable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */ __HAL_SMARTCARD_ENABLE_IT(hsc, SMARTCARD_IT_ERR); return HAL_OK; } else { return HAL_BUSY; } } /** * @brief Send an amount of data in non blocking mode * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains * the configuration information for SMARTCARD module. * @param pData: pointer to data buffer * @param Size: amount of data to be sent * @retval HAL status */ HAL_StatusTypeDef HAL_SMARTCARD_Transmit_DMA(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size) { uint32_t *tmp; uint32_t tmp1 = 0; tmp1 = hsc->State; if((tmp1 == HAL_SMARTCARD_STATE_READY) || (tmp1 == HAL_SMARTCARD_STATE_BUSY_RX)) { if((pData == NULL) || (Size == 0)) { return HAL_ERROR; } /* Process Locked */ __HAL_LOCK(hsc); hsc->pTxBuffPtr = pData; hsc->TxXferSize = Size; hsc->TxXferCount = Size; hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE; /* Check if a non-blocking receive process is ongoing or not */ if(hsc->State == HAL_SMARTCARD_STATE_BUSY_RX) { hsc->State = HAL_SMARTCARD_STATE_BUSY_TX_RX; } else { hsc->State = HAL_SMARTCARD_STATE_BUSY_TX; } /* Set the SMARTCARD DMA transfer complete callback */ hsc->hdmatx->XferCpltCallback = SMARTCARD_DMATransmitCplt; /* Set the DMA error callback */ hsc->hdmatx->XferErrorCallback = SMARTCARD_DMAError; /* Enable the SMARTCARD transmit DMA Stream */ tmp = (uint32_t*)&pData; HAL_DMA_Start_IT(hsc->hdmatx, *(uint32_t*)tmp, (uint32_t)&hsc->Instance->DR, Size); /* Clear the TC flag in the SR register by writing 0 to it */ __HAL_SMARTCARD_CLEAR_FLAG(hsc, SMARTCARD_FLAG_TC); /* Enable the DMA transfer for transmit request by setting the DMAT bit in the SMARTCARD CR3 register */ hsc->Instance->CR3 |= USART_CR3_DMAT; /* Process Unlocked */ __HAL_UNLOCK(hsc); return HAL_OK; } else { return HAL_BUSY; } } /** * @brief Receive an amount of data in non blocking mode * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains * the configuration information for SMARTCARD module. * @param pData: pointer to data buffer * @param Size: amount of data to be received * @note When the SMARTCARD parity is enabled (PCE = 1) the data received contain the parity bit.s * @retval HAL status */ HAL_StatusTypeDef HAL_SMARTCARD_Receive_DMA(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size) { uint32_t *tmp; uint32_t tmp1 = 0; tmp1 = hsc->State; if((tmp1 == HAL_SMARTCARD_STATE_READY) || (tmp1 == HAL_SMARTCARD_STATE_BUSY_TX)) { if((pData == NULL) || (Size == 0)) { return HAL_ERROR; } /* Process Locked */ __HAL_LOCK(hsc); hsc->pRxBuffPtr = pData; hsc->RxXferSize = Size; hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE; /* Check if a non-blocking transmit process is ongoing or not */ if(hsc->State == HAL_SMARTCARD_STATE_BUSY_TX) { hsc->State = HAL_SMARTCARD_STATE_BUSY_TX_RX; } else { hsc->State = HAL_SMARTCARD_STATE_BUSY_RX; } /* Set the SMARTCARD DMA transfer complete callback */ hsc->hdmarx->XferCpltCallback = SMARTCARD_DMAReceiveCplt; /* Set the DMA error callback */ hsc->hdmarx->XferErrorCallback = SMARTCARD_DMAError; /* Enable the DMA Stream */ tmp = (uint32_t*)&pData; HAL_DMA_Start_IT(hsc->hdmarx, (uint32_t)&hsc->Instance->DR, *(uint32_t*)tmp, Size); /* Enable the DMA transfer for the receiver request by setting the DMAR bit in the SMARTCARD CR3 register */ hsc->Instance->CR3 |= USART_CR3_DMAR; /* Process Unlocked */ __HAL_UNLOCK(hsc); return HAL_OK; } else { return HAL_BUSY; } } /** * @brief This function handles SMARTCARD interrupt request. * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains * the configuration information for SMARTCARD module. * @retval None */ void HAL_SMARTCARD_IRQHandler(SMARTCARD_HandleTypeDef *hsc) { uint32_t tmp1 = 0, tmp2 = 0; tmp1 = hsc->Instance->SR; tmp2 = __HAL_SMARTCARD_GET_IT_SOURCE(hsc, SMARTCARD_IT_PE); /* SMARTCARD parity error interrupt occurred --------------------------------*/ if(((tmp1 & SMARTCARD_FLAG_PE) != RESET) && (tmp2 != RESET)) { __HAL_SMARTCARD_CLEAR_PEFLAG(hsc); hsc->ErrorCode |= HAL_SMARTCARD_ERROR_PE; } tmp2 = __HAL_SMARTCARD_GET_IT_SOURCE(hsc, SMARTCARD_IT_ERR); /* SMARTCARD frame error interrupt occurred ---------------------------------*/ if(((tmp1 & SMARTCARD_FLAG_FE) != RESET) && (tmp2 != RESET)) { __HAL_SMARTCARD_CLEAR_FEFLAG(hsc); hsc->ErrorCode |= HAL_SMARTCARD_ERROR_FE; } tmp2 = __HAL_SMARTCARD_GET_IT_SOURCE(hsc, SMARTCARD_IT_ERR); /* SMARTCARD noise error interrupt occurred ---------------------------------*/ if(((tmp1 & SMARTCARD_FLAG_NE) != RESET) && (tmp2 != RESET)) { __HAL_SMARTCARD_CLEAR_NEFLAG(hsc); hsc->ErrorCode |= HAL_SMARTCARD_ERROR_NE; } tmp2 = __HAL_SMARTCARD_GET_IT_SOURCE(hsc, SMARTCARD_IT_ERR); /* SMARTCARD Over-Run interrupt occurred ------------------------------------*/ if(((tmp1 & SMARTCARD_FLAG_ORE) != RESET) && (tmp2 != RESET)) { __HAL_SMARTCARD_CLEAR_OREFLAG(hsc); hsc->ErrorCode |= HAL_SMARTCARD_ERROR_ORE; } tmp2 = __HAL_SMARTCARD_GET_IT_SOURCE(hsc, SMARTCARD_IT_RXNE); /* SMARTCARD in mode Receiver ----------------------------------------------*/ if(((tmp1 & SMARTCARD_FLAG_RXNE) != RESET) && (tmp2 != RESET)) { SMARTCARD_Receive_IT(hsc); } tmp2 = __HAL_SMARTCARD_GET_IT_SOURCE(hsc, SMARTCARD_IT_TXE); /* SMARTCARD in mode Transmitter -------------------------------------------*/ if(((tmp1 & SMARTCARD_FLAG_TXE) != RESET) && (tmp2 != RESET)) { SMARTCARD_Transmit_IT(hsc); } tmp2 = __HAL_SMARTCARD_GET_IT_SOURCE(hsc, SMARTCARD_IT_TC); /* SMARTCARD in mode Transmitter (transmission end) ------------------------*/ if(((tmp1 & SMARTCARD_FLAG_TC) != RESET) && (tmp2 != RESET)) { SMARTCARD_EndTransmit_IT(hsc); } /* Call the Error call Back in case of Errors */ if(hsc->ErrorCode != HAL_SMARTCARD_ERROR_NONE) { /* Set the SMARTCARD state ready to be able to start again the process */ hsc->State= HAL_SMARTCARD_STATE_READY; HAL_SMARTCARD_ErrorCallback(hsc); } } /** * @brief Tx Transfer completed callbacks * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains * the configuration information for SMARTCARD module. * @retval None */ __weak void HAL_SMARTCARD_TxCpltCallback(SMARTCARD_HandleTypeDef *hsc) { /* NOTE : This function Should not be modified, when the callback is needed, the HAL_SMARTCARD_TxCpltCallback could be implemented in the user file */ } /** * @brief Rx Transfer completed callbacks * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains * the configuration information for SMARTCARD module. * @retval None */ __weak void HAL_SMARTCARD_RxCpltCallback(SMARTCARD_HandleTypeDef *hsc) { /* NOTE : This function Should not be modified, when the callback is needed, the HAL_SMARTCARD_TxCpltCallback could be implemented in the user file */ } /** * @brief SMARTCARD error callbacks * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains * the configuration information for SMARTCARD module. * @retval None */ __weak void HAL_SMARTCARD_ErrorCallback(SMARTCARD_HandleTypeDef *hsc) { /* NOTE : This function Should not be modified, when the callback is needed, the HAL_SMARTCARD_ErrorCallback could be implemented in the user file */ } /** * @} */ /** @defgroup SMARTCARD_Exported_Functions_Group3 Peripheral State and Errors functions * @brief SMARTCARD State and Errors functions * @verbatim =============================================================================== ##### Peripheral State and Errors functions ##### =============================================================================== [..] This subsection provides a set of functions allowing to control the SmartCard. (+) HAL_SMARTCARD_GetState() API can be helpful to check in run-time the state of the SmartCard peripheral. (+) HAL_SMARTCARD_GetError() check in run-time errors that could be occurred during communication. @endverbatim * @{ */ /** * @brief return the SMARTCARD state * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains * the configuration information for SMARTCARD module. * @retval HAL state */ HAL_SMARTCARD_StateTypeDef HAL_SMARTCARD_GetState(SMARTCARD_HandleTypeDef *hsc) { return hsc->State; } /** * @brief Return the SMARTCARD error code * @param hsc : pointer to a SMARTCARD_HandleTypeDef structure that contains * the configuration information for the specified SMARTCARD. * @retval SMARTCARD Error Code */ uint32_t HAL_SMARTCARD_GetError(SMARTCARD_HandleTypeDef *hsc) { return hsc->ErrorCode; } /** * @} */ /** * @brief DMA SMARTCARD transmit process complete callback * @param hdma: pointer to a DMA_HandleTypeDef structure that contains * the configuration information for the specified DMA module. * @retval None */ static void SMARTCARD_DMATransmitCplt(DMA_HandleTypeDef *hdma) { SMARTCARD_HandleTypeDef* hsc = ( SMARTCARD_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; hsc->TxXferCount = 0; /* Disable the DMA transfer for transmit request by setting the DMAT bit in the USART CR3 register */ hsc->Instance->CR3 &= (uint32_t)~((uint32_t)USART_CR3_DMAT); /* Enable the SMARTCARD Transmit Complete Interrupt */ __HAL_SMARTCARD_ENABLE_IT(hsc, SMARTCARD_IT_TC); } /** * @brief DMA SMARTCARD receive process complete callback * @param hdma: pointer to a DMA_HandleTypeDef structure that contains * the configuration information for the specified DMA module. * @retval None */ static void SMARTCARD_DMAReceiveCplt(DMA_HandleTypeDef *hdma) { SMARTCARD_HandleTypeDef* hsc = ( SMARTCARD_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; hsc->RxXferCount = 0; /* Disable the DMA transfer for the receiver request by setting the DMAR bit in the USART CR3 register */ hsc->Instance->CR3 &= (uint32_t)~((uint32_t)USART_CR3_DMAR); /* Check if a non-blocking transmit process is ongoing or not */ if(hsc->State == HAL_SMARTCARD_STATE_BUSY_TX_RX) { hsc->State = HAL_SMARTCARD_STATE_BUSY_TX; } else { hsc->State = HAL_SMARTCARD_STATE_READY; } HAL_SMARTCARD_RxCpltCallback(hsc); } /** * @brief DMA SMARTCARD communication error callback * @param hdma: pointer to a DMA_HandleTypeDef structure that contains * the configuration information for the specified DMA module. * @retval None */ static void SMARTCARD_DMAError(DMA_HandleTypeDef *hdma) { SMARTCARD_HandleTypeDef* hsc = ( SMARTCARD_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; hsc->RxXferCount = 0; hsc->TxXferCount = 0; hsc->ErrorCode = HAL_SMARTCARD_ERROR_DMA; hsc->State= HAL_SMARTCARD_STATE_READY; HAL_SMARTCARD_ErrorCallback(hsc); } /** * @brief This function handles SMARTCARD Communication Timeout. * @param hsc: SMARTCARD handle * @param Flag: specifies the SMARTCARD flag to check. * @param Status: The new Flag status (SET or RESET). * @param Timeout: Timeout duration * @retval HAL status */ static HAL_StatusTypeDef SMARTCARD_WaitOnFlagUntilTimeout(SMARTCARD_HandleTypeDef *hsc, uint32_t Flag, FlagStatus Status, uint32_t Timeout) { uint32_t tickstart = 0; /* Get tick */ tickstart = HAL_GetTick(); /* Wait until flag is set */ if(Status == RESET) { while(__HAL_SMARTCARD_GET_FLAG(hsc, Flag) == RESET) { /* Check for the Timeout */ if(Timeout != HAL_MAX_DELAY) { if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) { /* Disable TXE and RXNE interrupts for the interrupt process */ __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_TXE); __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_RXNE); hsc->State= HAL_SMARTCARD_STATE_READY; /* Process Unlocked */ __HAL_UNLOCK(hsc); return HAL_TIMEOUT; } } } } else { while(__HAL_SMARTCARD_GET_FLAG(hsc, Flag) != RESET) { /* Check for the Timeout */ if(Timeout != HAL_MAX_DELAY) { if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) { /* Disable TXE and RXNE interrupts for the interrupt process */ __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_TXE); __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_RXNE); hsc->State= HAL_SMARTCARD_STATE_READY; /* Process Unlocked */ __HAL_UNLOCK(hsc); return HAL_TIMEOUT; } } } } return HAL_OK; } /** * @brief Send an amount of data in non blocking mode * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains * the configuration information for SMARTCARD module. * @retval HAL status */ static HAL_StatusTypeDef SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef *hsc) { uint16_t* tmp; uint32_t tmp1 = 0; tmp1 = hsc->State; if((tmp1 == HAL_SMARTCARD_STATE_BUSY_TX) || (tmp1 == HAL_SMARTCARD_STATE_BUSY_TX_RX)) { tmp = (uint16_t*) hsc->pTxBuffPtr; hsc->Instance->DR = (uint16_t)(*tmp & (uint16_t)0x01FF); hsc->pTxBuffPtr += 1; if(--hsc->TxXferCount == 0) { /* Disable the SMARTCARD Transmit data register empty Interrupt */ __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_TXE); /* Enable the SMARTCARD Transmit Complete Interrupt */ __HAL_SMARTCARD_ENABLE_IT(hsc, SMARTCARD_IT_TC); } return HAL_OK; } else { return HAL_BUSY; } } /** * @brief Wraps up transmission in non blocking mode. * @param hsmartcard: pointer to a SMARTCARD_HandleTypeDef structure that contains * the configuration information for the specified SMARTCARD module. * @retval HAL status */ static HAL_StatusTypeDef SMARTCARD_EndTransmit_IT(SMARTCARD_HandleTypeDef *hsmartcard) { /* Disable the SMARTCARD Transmit Complete Interrupt */ __HAL_SMARTCARD_DISABLE_IT(hsmartcard, SMARTCARD_IT_TC); /* Check if a receive process is ongoing or not */ if(hsmartcard->State == HAL_SMARTCARD_STATE_BUSY_TX_RX) { hsmartcard->State = HAL_SMARTCARD_STATE_BUSY_RX; } else { /* Disable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */ __HAL_SMARTCARD_DISABLE_IT(hsmartcard, SMARTCARD_IT_ERR); hsmartcard->State = HAL_SMARTCARD_STATE_READY; } HAL_SMARTCARD_TxCpltCallback(hsmartcard); return HAL_OK; } /** * @brief Receive an amount of data in non blocking mode * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains * the configuration information for SMARTCARD module. * @retval HAL status */ static HAL_StatusTypeDef SMARTCARD_Receive_IT(SMARTCARD_HandleTypeDef *hsc) { uint16_t* tmp; uint32_t tmp1 = 0; tmp1 = hsc->State; if((tmp1 == HAL_SMARTCARD_STATE_BUSY_RX) || (tmp1 == HAL_SMARTCARD_STATE_BUSY_TX_RX)) { tmp = (uint16_t*) hsc->pRxBuffPtr; *tmp = (uint16_t)(hsc->Instance->DR & (uint16_t)0x00FF); hsc->pRxBuffPtr += 1; if(--hsc->RxXferCount == 0) { __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_RXNE); /* Disable the SMARTCARD Parity Error Interrupt */ __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_PE); /* Disable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */ __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_ERR); /* Check if a non-blocking transmit process is ongoing or not */ if(hsc->State == HAL_SMARTCARD_STATE_BUSY_TX_RX) { hsc->State = HAL_SMARTCARD_STATE_BUSY_TX; } else { hsc->State = HAL_SMARTCARD_STATE_READY; } HAL_SMARTCARD_RxCpltCallback(hsc); return HAL_OK; } return HAL_OK; } else { return HAL_BUSY; } } /** * @brief Configure the SMARTCARD peripheral * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains * the configuration information for SMARTCARD module. * @retval None */ static void SMARTCARD_SetConfig(SMARTCARD_HandleTypeDef *hsc) { uint32_t tmpreg = 0x00; /* Check the parameters */ assert_param(IS_SMARTCARD_INSTANCE(hsc->Instance)); assert_param(IS_SMARTCARD_POLARITY(hsc->Init.CLKPolarity)); assert_param(IS_SMARTCARD_PHASE(hsc->Init.CLKPhase)); assert_param(IS_SMARTCARD_LASTBIT(hsc->Init.CLKLastBit)); assert_param(IS_SMARTCARD_BAUDRATE(hsc->Init.BaudRate)); assert_param(IS_SMARTCARD_WORD_LENGTH(hsc->Init.WordLength)); assert_param(IS_SMARTCARD_STOPBITS(hsc->Init.StopBits)); assert_param(IS_SMARTCARD_PARITY(hsc->Init.Parity)); assert_param(IS_SMARTCARD_MODE(hsc->Init.Mode)); assert_param(IS_SMARTCARD_NACK_STATE(hsc->Init.NACKState)); /* The LBCL, CPOL and CPHA bits have to be selected when both the transmitter and the receiver are disabled (TE=RE=0) to ensure that the clock pulses function correctly. */ hsc->Instance->CR1 &= (uint32_t)~((uint32_t)(USART_CR1_TE | USART_CR1_RE)); /*---------------------------- USART CR2 Configuration ---------------------*/ tmpreg = hsc->Instance->CR2; /* Clear CLKEN, CPOL, CPHA and LBCL bits */ tmpreg &= (uint32_t)~((uint32_t)(USART_CR2_CPHA | USART_CR2_CPOL | USART_CR2_CLKEN | USART_CR2_LBCL)); /* Configure the SMARTCARD Clock, CPOL, CPHA and LastBit -----------------------*/ /* Set CPOL bit according to hsc->Init.CLKPolarity value */ /* Set CPHA bit according to hsc->Init.CLKPhase value */ /* Set LBCL bit according to hsc->Init.CLKLastBit value */ /* Set Stop Bits: Set STOP[13:12] bits according to hsc->Init.StopBits value */ tmpreg |= (uint32_t)(USART_CR2_CLKEN | hsc->Init.CLKPolarity | hsc->Init.CLKPhase| hsc->Init.CLKLastBit | hsc->Init.StopBits); /* Write to USART CR2 */ hsc->Instance->CR2 = (uint32_t)tmpreg; tmpreg = hsc->Instance->CR2; /* Clear STOP[13:12] bits */ tmpreg &= (uint32_t)~((uint32_t)USART_CR2_STOP); /* Set Stop Bits: Set STOP[13:12] bits according to hsc->Init.StopBits value */ tmpreg |= (uint32_t)(hsc->Init.StopBits); /* Write to USART CR2 */ hsc->Instance->CR2 = (uint32_t)tmpreg; /*-------------------------- USART CR1 Configuration -----------------------*/ tmpreg = hsc->Instance->CR1; /* Clear M, PCE, PS, TE and RE bits */ tmpreg &= (uint32_t)~((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | \ USART_CR1_RE)); /* Configure the SMARTCARD Word Length, Parity and mode: Set the M bits according to hsc->Init.WordLength value Set PCE and PS bits according to hsc->Init.Parity value Set TE and RE bits according to hsc->Init.Mode value */ tmpreg |= (uint32_t)hsc->Init.WordLength | hsc->Init.Parity | hsc->Init.Mode; /* Write to USART CR1 */ hsc->Instance->CR1 = (uint32_t)tmpreg; /*-------------------------- USART CR3 Configuration -----------------------*/ /* Clear CTSE and RTSE bits */ hsc->Instance->CR3 &= (uint32_t)~((uint32_t)(USART_CR3_RTSE | USART_CR3_CTSE)); /*-------------------------- USART BRR Configuration -----------------------*/ if((hsc->Instance == USART1) || (hsc->Instance == USART6)) { hsc->Instance->BRR = SMARTCARD_BRR(HAL_RCC_GetPCLK2Freq(), hsc->Init.BaudRate); } else { hsc->Instance->BRR = SMARTCARD_BRR(HAL_RCC_GetPCLK1Freq(), hsc->Init.BaudRate); } } /** * @} */ #endif /* HAL_SMARTCARD_MODULE_ENABLED */ /** * @} */ /** * @} */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/