]> git.friedersdorff.com Git - max/tmk_keyboard.git/blob - tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_STM32F3/stm32f3xx_hal_usart.c
Merge commit '5a0132f1c1c9a14fd2941f0a5e29bbf5e31da20c' into master-core-pull
[max/tmk_keyboard.git] / tmk_core / tool / mbed / mbed-sdk / libraries / mbed / targets / cmsis / TARGET_STM / TARGET_STM32F3 / stm32f3xx_hal_usart.c
1 /**
2   ******************************************************************************
3   * @file    stm32f3xx_hal_usart.c
4   * @author  MCD Application Team
5   * @version V1.1.0
6   * @date    12-Sept-2014
7   * @brief   USART HAL module driver.
8   *
9   *          This file provides firmware functions to manage the following 
10   *          functionalities of the Universal Synchronous/Asynchronous Receiver Transmitter
11   *          Peripheral (USART).
12   *           + Initialization and de-initialization functions
13   *           + IO operation functions
14   *           + Peripheral Control functions
15   *           
16   @verbatim       
17  ===============================================================================
18                         ##### How to use this driver #####
19  ===============================================================================
20     [..]
21     The USART HAL driver can be used as follows:
22     
23     (#) Declare a USART_HandleTypeDef handle structure.
24     (#) Initialize the USART low level resources by implement the HAL_USART_MspInit ()API:
25         (##) Enable the USARTx interface clock.
26         (##) USART pins configuration:
27             (+) Enable the clock for the USART GPIOs.
28             (+) Configure these USART pins as alternate function pull-up.
29         (##) NVIC configuration if you need to use interrupt process (HAL_USART_Transmit_IT(),
30               HAL_USART_Receive_IT() and HAL_USART_TransmitReceive_IT() APIs):
31             (+) Configure the USARTx interrupt priority.
32             (+) Enable the NVIC USART IRQ handle.
33             (@) The specific USART interrupts (Transmission complete interrupt, 
34                 RXNE interrupt and Error Interrupts) will be managed using the macros
35                 __HAL_USART_ENABLE_IT() and __HAL_USART_DISABLE_IT() inside the transmit and receive process.
36         (##) DMA Configuration if you need to use DMA process (HAL_USART_Transmit_DMA()
37              HAL_USART_Receive_IT() and HAL_USART_TransmitReceive_IT() APIs):
38             (+) Declare a DMA handle structure for the Tx/Rx channel.
39             (+) Enable the DMAx interface clock.
40             (+) Configure the declared DMA handle structure with the required Tx/Rx parameters.                
41             (+) Configure the DMA Tx/Rx channel.
42             (+) Associate the initilalized DMA handle to the USART DMA Tx/Rx handle.
43             (+) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx channel.
44
45     (#) Program the Baud Rate, Word Length , Stop Bit, Parity, Hardware 
46         flow control and Mode(Receiver/Transmitter) in the husart Init structure.
47
48     (#) Initialize the USART registers by calling the HAL_USART_Init() API:
49         (+) These API's configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
50             by calling the customed HAL_USART_MspInit(&husart) API.
51            
52   @endverbatim
53   ******************************************************************************
54   * @attention
55   *
56   * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
57   *
58   * Redistribution and use in source and binary forms, with or without modification,
59   * are permitted provided that the following conditions are met:
60   *   1. Redistributions of source code must retain the above copyright notice,
61   *      this list of conditions and the following disclaimer.
62   *   2. Redistributions in binary form must reproduce the above copyright notice,
63   *      this list of conditions and the following disclaimer in the documentation
64   *      and/or other materials provided with the distribution.
65   *   3. Neither the name of STMicroelectronics nor the names of its contributors
66   *      may be used to endorse or promote products derived from this software
67   *      without specific prior written permission.
68   *
69   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
70   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
71   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
72   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
73   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
74   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
75   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
76   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
77   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
78   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
79   *
80   ******************************************************************************  
81   */
82
83 /* Includes ------------------------------------------------------------------*/
84 #include "stm32f3xx_hal.h"
85
86 /** @addtogroup STM32F3xx_HAL_Driver
87   * @{
88   */
89
90 /** @defgroup USART HAL USART Synchronous module driver
91   * @brief HAL USART Synchronous module driver
92   * @{
93   */
94 #ifdef HAL_USART_MODULE_ENABLED
95 /* Private typedef -----------------------------------------------------------*/
96 /* Private define ------------------------------------------------------------*/
97 /** @defgroup UASRT_Private_Constants USART Private Constants
98   * @{
99   */
100 #define DUMMY_DATA                  ((uint16_t) 0xFFFF)
101 #define TEACK_REACK_TIMEOUT         ((uint32_t) 1000)
102 #define USART_TXDMA_TIMEOUTVALUE            22000
103 #define USART_TIMEOUT_VALUE                 22000
104 #define USART_CR1_FIELDS  ((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | \
105                                       USART_CR1_TE | USART_CR1_RE))
106 #define USART_CR2_FIELDS  ((uint32_t)(USART_CR2_CPHA | USART_CR2_CPOL | \
107                                       USART_CR2_CLKEN | USART_CR2_LBCL | USART_CR2_STOP))
108 /**
109   * @}
110   */
111 /* Private macro -------------------------------------------------------------*/
112 /* Private variables ---------------------------------------------------------*/
113 /* Private function prototypes -----------------------------------------------*/
114 static void USART_DMATransmitCplt(DMA_HandleTypeDef *hdma);
115 static void USART_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
116 static void USART_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
117 static void USART_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
118 static void USART_DMAError(DMA_HandleTypeDef *hdma); 
119 static HAL_StatusTypeDef USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef *husart, uint32_t Flag, FlagStatus Status, uint32_t Timeout);
120 static HAL_StatusTypeDef USART_SetConfig(USART_HandleTypeDef *husart);
121 static HAL_StatusTypeDef USART_CheckIdleState(USART_HandleTypeDef *husart);
122 static HAL_StatusTypeDef USART_Transmit_IT(USART_HandleTypeDef *husart);
123 static HAL_StatusTypeDef USART_EndTransmit_IT(USART_HandleTypeDef *husart);
124 static HAL_StatusTypeDef USART_Receive_IT(USART_HandleTypeDef *husart);
125 static HAL_StatusTypeDef USART_TransmitReceive_IT(USART_HandleTypeDef *husart);
126 /* Exported functions --------------------------------------------------------*/
127
128
129 /** @defgroup USART_Exported_Functions USART Exported Functions
130   * @{
131   */
132
133 /** @defgroup USART_Exported_Functions_Group1 Initialization and de-initialization functions
134   *  @brief    Initialization and Configuration functions 
135   *
136 @verbatim   
137  ===============================================================================
138             ##### Initialization and Configuration functions #####
139  ===============================================================================  
140     [..]
141     This subsection provides a set of functions allowing to initialize the USART 
142     in asynchronous and in synchronous modes.
143       (+) For the asynchronous mode only these parameters can be configured: 
144         (++) Baud Rate
145         (++) Word Length 
146         (++) Stop Bit
147         (++) Parity: If the parity is enabled, then the MSB bit of the data written
148              in the data register is transmitted but is changed by the parity bit.
149              Depending on the frame length defined by the M bit (8-bits or 9-bits)
150              or by the M1 and M0 bits (7-bit, 8-bit or 9-bit),
151              the possible USART frame formats are as listed in the following table:
152    +---------------------------------------------------------------+     
153    |    M bit  |  PCE bit  |            USART frame                |
154    |-----------|-----------|---------------------------------------|             
155    |     0     |     0     |    | SB | 8-bit data | STB |          |
156    |-----------|-----------|---------------------------------------|  
157    |     0     |     1     |    | SB | 7-bit data | PB | STB |     |
158    |-----------|-----------|---------------------------------------|  
159    |     1     |     0     |    | SB | 9-bit data | STB |          |
160    |-----------|-----------|---------------------------------------|  
161    |     1     |     1     |    | SB | 8-bit data | PB | STB |     |
162    +---------------------------------------------------------------+     
163    | M1M0 bits |  PCE bit  |            USART frame                |
164    |-----------------------|---------------------------------------|             
165    |     10    |     0     |    | SB | 7-bit data | STB |          |
166    |-----------|-----------|---------------------------------------|  
167    |     10    |     1     |    | SB | 6-bit data | PB | STB |     |   
168    +---------------------------------------------------------------+          
169         (++) USART polarity
170         (++) USART phase
171         (++) USART LastBit
172         (++) Receiver/transmitter modes
173
174     [..]
175     The HAL_USART_Init() function follows the USART  synchronous configuration 
176     procedure (details for the procedure are available in reference manual).
177
178 @endverbatim
179   * @{
180   */
181
182 /**
183   * @brief Initializes the USART mode according to the specified
184   *         parameters in the USART_InitTypeDef and create the associated handle .
185   * @param husart: usart handle
186   * @retval HAL status
187   */
188 HAL_StatusTypeDef HAL_USART_Init(USART_HandleTypeDef *husart)
189 {
190   /* Check the USART handle allocation */
191   if(husart == HAL_NULL)
192   {
193     return HAL_ERROR;
194   }
195   
196   /* Check the parameters */
197   assert_param(IS_USART_INSTANCE(husart->Instance));
198   
199   if(husart->State == HAL_USART_STATE_RESET)
200   {   
201     /* Init the low level hardware : GPIO, CLOCK */
202     HAL_USART_MspInit(husart);
203   }
204   
205   husart->State = HAL_USART_STATE_BUSY;
206     
207   /* Disable the Peripheral */
208   __HAL_USART_DISABLE(husart);
209   
210   /* Set the Usart Communication parameters */
211   if (USART_SetConfig(husart) == HAL_ERROR)
212   {
213     return HAL_ERROR;
214   }
215   
216   /* In Synchronous mode, the following bits must be kept cleared: 
217   - LINEN bit in the USART_CR2 register
218   - HDSEL, SCEN and IREN bits in the USART_CR3 register.*/
219   husart->Instance->CR2 &= ~USART_CR2_LINEN;
220   husart->Instance->CR3 &= ~(USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN);
221   
222   /* Enable the Peripharal */
223   __HAL_USART_ENABLE(husart);
224   
225   /* TEACK and/or REACK to check before moving husart->State to Ready */
226   return (USART_CheckIdleState(husart));
227 }
228
229 /**
230   * @brief DeInitializes the USART peripheral 
231   * @param husart: usart handle
232   * @retval HAL status
233   */
234 HAL_StatusTypeDef HAL_USART_DeInit(USART_HandleTypeDef *husart)
235 {
236    /* Check the USART handle allocation */
237   if(husart == HAL_NULL)
238   {
239     return HAL_ERROR;
240   }
241   
242   /* Check the parameters */
243   assert_param(IS_USART_INSTANCE(husart->Instance));
244   
245   husart->State = HAL_USART_STATE_BUSY;
246   
247   husart->Instance->CR1 = 0x0;
248   husart->Instance->CR2 = 0x0;
249   husart->Instance->CR3 = 0x0;
250   
251   /* DeInit the low level hardware */
252   HAL_USART_MspDeInit(husart);
253   
254   husart->ErrorCode = HAL_USART_ERROR_NONE;
255   husart->State = HAL_USART_STATE_RESET;
256   
257   /* Process Unlock */
258   __HAL_UNLOCK(husart);
259   
260   return HAL_OK;
261 }
262
263 /**
264   * @brief USART MSP Init
265   * @param husart: usart handle
266   * @retval None
267   */
268  __weak void HAL_USART_MspInit(USART_HandleTypeDef *husart)
269 {
270   /* NOTE : This function should not be modified, when the callback is needed,
271             the HAL_USART_MspInit can be implemented in the user file
272    */ 
273 }
274
275 /**
276   * @brief USART MSP DeInit
277   * @param husart: usart handle
278   * @retval None
279   */
280  __weak void HAL_USART_MspDeInit(USART_HandleTypeDef *husart)
281 {
282   /* NOTE : This function should not be modified, when the callback is needed,
283             the HAL_USART_MspDeInit can be implemented in the user file
284    */ 
285 }
286
287 /**
288   * @}
289   */
290
291 /** @defgroup USART_Exported_Functions_Group2 Input and Output operation functions 
292   *  @brief   USART Transmit/Receive functions 
293   *
294 @verbatim   
295  ===============================================================================
296                       ##### I/O operation functions #####
297  ===============================================================================  
298     This subsection provides a set of functions allowing to manage the USART synchronous
299     data transfers.
300       
301     [..] The USART supports master mode only: it cannot receive or send data related to an input
302          clock (SCLK is always an output).
303
304     (#) There are two mode of transfer:
305        (+) Blocking mode: The communication is performed in polling mode. 
306             The HAL status of all data processing is returned by the same function 
307             after finishing transfer.  
308        (+) No-Blocking mode: The communication is performed using Interrupts 
309            or DMA, These API's return the HAL status.
310            The end of the data processing will be indicated through the 
311            dedicated USART IRQ when using Interrupt mode or the DMA IRQ when 
312            using DMA mode.
313            The HAL_USART_TxCpltCallback(), HAL_USART_RxCpltCallback() and HAL_USART_TxRxCpltCallback() user callbacks 
314            will be executed respectivelly at the end of the transmit or Receive process
315            The HAL_USART_ErrorCallback()user callback will be executed when a communication error is detected
316
317     (#) Blocking mode API's are :
318         (+) HAL_USART_Transmit()in simplex mode
319         (+) HAL_USART_Receive() in full duplex receive only
320         (+) HAL_USART_TransmitReceive() in full duplex mode         
321         
322     (#) Non-Blocking mode API's with Interrupt are :
323         (+) HAL_USART_Transmit_IT()in simplex mode
324         (+) HAL_USART_Receive_IT() in full duplex receive only
325         (+) HAL_USART_TransmitReceive_IT()in full duplex mode
326         (+) HAL_USART_IRQHandler()
327
328     (#) No-Blocking mode functions with DMA are :
329         (+) HAL_USART_Transmit_DMA()in simplex mode
330         (+) HAL_USART_Receive_DMA() in full duplex receive only
331         (+) HAL_USART_TransmitReceive_DMA() in full duplex mode
332         (+) HAL_USART_DMAPause()
333         (+) HAL_USART_DMAResume()
334         (+) HAL_USART_DMAStop()
335           
336     (#) A set of Transfer Complete Callbacks are provided in No_Blocking mode:
337         (+) HAL_USART_TxCpltCallback()
338         (+) HAL_USART_RxCpltCallback()
339         (+) HAL_USART_TxHalfCpltCallback()
340         (+) HAL_USART_RxHalfCpltCallback()
341         (+) HAL_USART_ErrorCallback()
342         (+) HAL_USART_TxRxCpltCallback()
343       
344 @endverbatim
345   * @{
346   */
347
348 /**
349   * @brief Simplex Send an amount of data in blocking mode 
350   * @param husart: USART handle
351   * @param pTxData: pointer to data buffer
352   * @param Size: amount of data to be sent
353   * @param Timeout : Timeout duration
354   * @retval HAL status
355   */
356 HAL_StatusTypeDef HAL_USART_Transmit(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size, uint32_t Timeout)
357 {
358    uint16_t* tmp; 
359     
360   if(husart->State == HAL_USART_STATE_READY)
361   { 
362     if((pTxData == HAL_NULL) || (Size == 0)) 
363     {
364       return  HAL_ERROR;                                    
365     }
366     
367     /* Process Locked */
368     __HAL_LOCK(husart);
369     
370     husart->ErrorCode = HAL_USART_ERROR_NONE;
371     husart->State = HAL_USART_STATE_BUSY_TX;
372     
373     husart->TxXferSize = Size;
374     husart->TxXferCount = Size;
375     
376     /* Check the remaining data to be sent */
377     while(husart->TxXferCount > 0)
378     {
379       husart->TxXferCount--;
380       if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TC, RESET, Timeout) != HAL_OK)
381         {
382           return HAL_TIMEOUT;
383         }
384       if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
385       {
386         tmp = (uint16_t*) pTxData;
387         husart->Instance->TDR = (*tmp & (uint16_t)0x01FF);
388         pTxData += 2;
389       } 
390       else
391       {
392         husart->Instance->TDR = (*pTxData++ & (uint8_t)0xFF);
393       }
394     }
395     
396     if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TC, RESET, Timeout) != HAL_OK)
397     { 
398       return HAL_TIMEOUT;
399     }
400     
401     husart->State = HAL_USART_STATE_READY;
402     
403     /* Process Unlocked */
404     __HAL_UNLOCK(husart);
405     
406     return HAL_OK;
407   }
408   else
409   {
410     return HAL_BUSY;   
411   }
412 }
413
414 /**
415   * @brief Receive an amount of data in blocking mode 
416   *        To receive synchronous data, dummy data are simultaneously transmitted  
417   * @param husart: USART handle
418   * @param pRxData: pointer to data buffer
419   * @param Size: amount of data to be received
420   * @param Timeout : Timeout duration
421   * @retval HAL status
422   */
423 HAL_StatusTypeDef HAL_USART_Receive(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size, uint32_t Timeout)
424
425   uint16_t* tmp;
426   uint16_t uhMask;  
427   
428   if(husart->State == HAL_USART_STATE_READY)
429   {
430     if((pRxData == HAL_NULL) || (Size == 0)) 
431     {
432       return  HAL_ERROR;                                    
433     }
434     /* Process Locked */
435     __HAL_LOCK(husart);
436     
437     husart->ErrorCode = HAL_USART_ERROR_NONE;
438     husart->State = HAL_USART_STATE_BUSY_RX;
439     
440     husart->RxXferSize = Size; 
441     husart->RxXferCount = Size;
442     
443     /* Computation of USART mask to apply to RDR register */
444     __HAL_USART_MASK_COMPUTATION(husart);
445     uhMask = husart->Mask;
446     
447     /* as long as data have to be received */
448     while(husart->RxXferCount > 0)
449     {
450       husart->RxXferCount--;
451       
452       /* Wait until TC flag is set to send dummy byte in order to generate the 
453       * clock for the slave to send data.
454        * Whatever the frame length (7, 8 or 9-bit long), the same dummy value 
455        * can be written for all the cases. */
456       if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TC, RESET, Timeout) != HAL_OK)
457       {            
458         return HAL_TIMEOUT;  
459       }
460       husart->Instance->TDR = (DUMMY_DATA & (uint16_t)0x0FF);         
461         
462       /* Wait for RXNE Flag */
463       if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, Timeout) != HAL_OK)
464       {            
465         return HAL_TIMEOUT;
466       }
467       
468       if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
469       {
470         tmp = (uint16_t*) pRxData ;
471         *tmp = (uint16_t)(husart->Instance->RDR & uhMask);
472         pRxData +=2;        
473       } 
474       else
475       {
476         *pRxData++ = (uint8_t)(husart->Instance->RDR & (uint8_t)uhMask);  
477       }
478     }
479     
480     husart->State = HAL_USART_STATE_READY;
481     
482     /* Process Unlocked */
483     __HAL_UNLOCK(husart);
484     
485     return HAL_OK;
486   }
487   else
488   {
489     return HAL_BUSY;   
490   }
491 }
492
493 /**
494   * @brief Full-Duplex Send and Receive an amount of data in blocking mode 
495   * @param husart: USART handle
496   * @param pTxData: pointer to TX data buffer
497   * @param pRxData: pointer to RX data buffer
498   * @param Size: amount of data to be sent (same amount to be received)
499   * @param Timeout : Timeout duration
500   * @retval HAL status
501   */
502 HAL_StatusTypeDef HAL_USART_TransmitReceive(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout)
503 {
504   uint16_t* tmp;
505   uint16_t uhMask;  
506   
507   if(husart->State == HAL_USART_STATE_READY)
508   {
509     if((pTxData == HAL_NULL) || (pRxData == HAL_NULL) || (Size == 0)) 
510     {
511       return  HAL_ERROR;                                    
512     }
513     /* Process Locked */
514     __HAL_LOCK(husart);
515     
516     husart->ErrorCode = HAL_USART_ERROR_NONE;
517     husart->State = HAL_USART_STATE_BUSY_RX;
518     
519     husart->RxXferSize = Size;
520     husart->TxXferSize = Size;
521     husart->TxXferCount = Size;
522     husart->RxXferCount = Size;
523
524     /* Computation of USART mask to apply to RDR register */
525     __HAL_USART_MASK_COMPUTATION(husart);
526     uhMask = husart->Mask;
527
528     /* Check the remain data to be sent */
529     while(husart->TxXferCount > 0)
530     {
531       husart->TxXferCount--;
532       husart->RxXferCount--;      
533       
534      /* Wait until TC flag is set to send data */
535       if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TC, RESET, Timeout) != HAL_OK)
536       {            
537         return HAL_TIMEOUT;
538       }
539       if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
540       {
541         tmp = (uint16_t*) pTxData;
542         husart->Instance->TDR = (*tmp & uhMask);
543         pTxData += 2;
544       }
545       else
546       {
547         husart->Instance->TDR = (*pTxData++ & (uint8_t)uhMask);         
548       }   
549         
550       /* Wait for RXNE Flag */
551       if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, Timeout) != HAL_OK)
552       {            
553           return HAL_TIMEOUT;
554       }
555       
556       if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
557       {
558         tmp = (uint16_t*) pRxData ;
559         *tmp = (uint16_t)(husart->Instance->RDR & uhMask);
560         pRxData +=2;        
561       } 
562       else
563       {
564         *pRxData++ = (uint8_t)(husart->Instance->RDR & (uint8_t)uhMask);  
565       }
566     }
567     
568     husart->State = HAL_USART_STATE_READY;
569     
570     /* Process Unlocked */
571     __HAL_UNLOCK(husart);
572     
573     return HAL_OK;
574   }
575   else
576   {
577     return HAL_BUSY;   
578   }
579 }
580
581 /**
582   * @brief Send an amount of data in interrupt mode 
583   * @param husart: USART handle
584   * @param pTxData: pointer to data buffer
585   * @param Size: amount of data to be sent
586   * @retval HAL status
587   */
588 HAL_StatusTypeDef HAL_USART_Transmit_IT(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size)
589 {  
590   if(husart->State == HAL_USART_STATE_READY)
591   {
592     if((pTxData == HAL_NULL) || (Size == 0)) 
593     {
594       return HAL_ERROR;                                    
595     }
596     
597     /* Process Locked */
598     __HAL_LOCK(husart);
599     
600     husart->pTxBuffPtr = pTxData;
601     husart->TxXferSize = Size;
602     husart->TxXferCount = Size;
603     
604     husart->ErrorCode = HAL_USART_ERROR_NONE;
605     husart->State = HAL_USART_STATE_BUSY_TX;
606     
607     /* The USART Error Interrupts: (Frame error, noise error, overrun error) 
608     are not managed by the USART Transmit Process to avoid the overrun interrupt
609     when the usart mode is configured for transmit and receive "USART_MODE_TX_RX"
610     to benefit for the frame error and noise interrupts the usart mode should be 
611     configured only for transmit "USART_MODE_TX" */
612     
613     /* Process Unlocked */
614     __HAL_UNLOCK(husart);
615     
616     /* Enable the USART Transmit Data Register Empty Interrupt */
617     __HAL_USART_ENABLE_IT(husart, USART_IT_TXE);
618     
619     return HAL_OK;
620   }
621   else
622   {
623     return HAL_BUSY;   
624   }
625 }
626
627 /**
628   * @brief Receive an amount of data in blocking mode 
629   *        To receive synchronous data, dummy data are simultaneously transmitted  
630   * @param husart: usart handle
631   * @param pRxData: pointer to data buffer
632   * @param Size: amount of data to be received
633   * @retval HAL status
634   */
635 HAL_StatusTypeDef HAL_USART_Receive_IT(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size)
636 {
637   if(husart->State == HAL_USART_STATE_READY)
638   {
639     if((pRxData == HAL_NULL) || (Size == 0)) 
640     {
641       return HAL_ERROR;                                    
642     }
643     /* Process Locked */
644     __HAL_LOCK(husart);
645     
646     husart->pRxBuffPtr = pRxData;
647     husart->RxXferSize = Size;
648     husart->RxXferCount = Size;
649
650     __HAL_USART_MASK_COMPUTATION(husart);
651
652     husart->ErrorCode = HAL_USART_ERROR_NONE;
653     husart->State = HAL_USART_STATE_BUSY_RX;
654     
655     /* Enable the USART Parity Error Interrupt */
656     __HAL_USART_ENABLE_IT(husart, USART_IT_PE);
657     
658     /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
659     __HAL_USART_ENABLE_IT(husart, USART_IT_ERR);
660     
661     /* Enable the USART Data Register not empty Interrupt */
662     __HAL_USART_ENABLE_IT(husart, USART_IT_RXNE);
663    
664     /* Process Unlocked */
665     __HAL_UNLOCK(husart);
666
667     
668     /* Send dummy byte in order to generate the clock for the Slave to send the next data */
669     if(husart->Init.WordLength == USART_WORDLENGTH_9B)
670     {
671       husart->Instance->TDR = (DUMMY_DATA & (uint16_t)0x01FF); 
672     } 
673     else
674     {
675       husart->Instance->TDR = (DUMMY_DATA & (uint16_t)0x00FF);
676     }
677     
678     return HAL_OK;
679   }
680   else
681   {
682     return HAL_BUSY; 
683   }
684 }
685
686 /**
687   * @brief Full-Duplex Send and Receive an amount of data in interrupt mode 
688   * @param husart: USART handle
689   * @param pTxData: pointer to TX data buffer
690   * @param pRxData: pointer to RX data buffer
691   * @param Size: amount of data to be sent (same amount to be received)   
692   * @retval HAL status
693   */
694 HAL_StatusTypeDef HAL_USART_TransmitReceive_IT(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData,  uint16_t Size)
695 {
696
697   if(husart->State == HAL_USART_STATE_READY)
698   {
699     if((pTxData == HAL_NULL) || (pRxData == HAL_NULL) || (Size == 0)) 
700     {
701       return HAL_ERROR;                                    
702     }
703     /* Process Locked */
704     __HAL_LOCK(husart);
705     
706     husart->pRxBuffPtr = pRxData;
707     husart->RxXferSize = Size;
708     husart->RxXferCount = Size;
709     husart->pTxBuffPtr = pTxData;
710     husart->TxXferSize = Size;
711     husart->TxXferCount = Size;
712     
713     /* Computation of USART mask to apply to RDR register */
714     __HAL_USART_MASK_COMPUTATION(husart);
715     
716     husart->ErrorCode = HAL_USART_ERROR_NONE;
717     husart->State = HAL_USART_STATE_BUSY_TX_RX;
718     
719     /* Enable the USART Data Register not empty Interrupt */
720     __HAL_USART_ENABLE_IT(husart, USART_IT_RXNE); 
721     
722     /* Enable the USART Parity Error Interrupt */
723     __HAL_USART_ENABLE_IT(husart, USART_IT_PE);
724     
725     /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
726     __HAL_USART_ENABLE_IT(husart, USART_IT_ERR);
727     
728     /* Process Unlocked */
729     __HAL_UNLOCK(husart);
730     
731     /* Enable the USART Transmit Data Register Empty Interrupt */
732     __HAL_USART_ENABLE_IT(husart, USART_IT_TXE);
733     
734     return HAL_OK;
735   }
736   else
737   {
738     return HAL_BUSY; 
739   }
740   
741 }
742
743 /**
744   * @brief Send an amount of data in DMA mode 
745   * @param husart: USART handle
746   * @param pTxData: pointer to data buffer
747   * @param Size: amount of data to be sent
748   * @retval HAL status
749   */
750 HAL_StatusTypeDef HAL_USART_Transmit_DMA(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size)
751 {
752   uint32_t *tmp;
753   
754   if(husart->State == HAL_USART_STATE_READY)
755   {
756     if((pTxData == HAL_NULL) || (Size == 0)) 
757     {
758       return HAL_ERROR; 
759     }
760     /* Process Locked */
761     __HAL_LOCK(husart);  
762     
763     husart->pTxBuffPtr = pTxData;
764     husart->TxXferSize = Size;
765     husart->TxXferCount = Size;
766     
767     husart->ErrorCode = HAL_USART_ERROR_NONE;
768     husart->State = HAL_USART_STATE_BUSY_TX;
769     
770     /* Set the USART DMA transfer complete callback */
771     husart->hdmatx->XferCpltCallback = USART_DMATransmitCplt;
772     
773     /* Set the USART DMA Half transfer complete callback */
774     husart->hdmatx->XferHalfCpltCallback = USART_DMATxHalfCplt;
775     
776     /* Set the DMA error callback */
777     husart->hdmatx->XferErrorCallback = USART_DMAError;
778
779     /* Enable the USART transmit DMA channel */
780     tmp = (uint32_t*)&pTxData;
781     HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t*)tmp, (uint32_t)&husart->Instance->TDR, Size);
782     
783     /* Enable the DMA transfer for transmit request by setting the DMAT bit
784        in the USART CR3 register */
785     husart->Instance->CR3 |= USART_CR3_DMAT;
786     
787     /* Process Unlocked */
788     __HAL_UNLOCK(husart);
789     
790     return HAL_OK;
791   }
792   else
793   {
794     return HAL_BUSY;   
795   }
796 }
797
798 /**
799   * @brief Receive an amount of data in DMA mode 
800   * @param husart: USART handle
801   * @param pRxData: pointer to data buffer
802   * @param Size: amount of data to be received
803   * @note   When the USART parity is enabled (PCE = 1), the received data contain 
804   *         the parity bit (MSB position)    
805   * @retval HAL status
806   * @note The USART DMA transmit channel must be configured in order to generate the clock for the slave.
807   */
808 HAL_StatusTypeDef HAL_USART_Receive_DMA(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size)
809 {
810   uint32_t *tmp;
811   
812   if(husart->State == HAL_USART_STATE_READY)
813   {
814     if((pRxData == HAL_NULL) || (Size == 0)) 
815     {
816       return HAL_ERROR;                                    
817     }
818     
819     /* Process Locked */
820     __HAL_LOCK(husart);
821     
822     husart->pRxBuffPtr = pRxData;
823     husart->RxXferSize = Size;
824     husart->pTxBuffPtr = pRxData;
825     husart->TxXferSize = Size;
826     
827     husart->ErrorCode = HAL_USART_ERROR_NONE;
828     husart->State = HAL_USART_STATE_BUSY_RX;
829     
830     /* Set the USART DMA Rx transfer complete callback */
831     husart->hdmarx->XferCpltCallback = USART_DMAReceiveCplt;
832     
833     /* Set the USART DMA Half transfer complete callback */
834     husart->hdmarx->XferHalfCpltCallback = USART_DMARxHalfCplt;    
835     
836     /* Set the USART DMA Rx transfer error callback */
837     husart->hdmarx->XferErrorCallback = USART_DMAError;
838     
839     /* Enable the USART receive DMA channel */
840     tmp = (uint32_t*)&pRxData;
841     HAL_DMA_Start_IT(husart->hdmarx, (uint32_t)&husart->Instance->RDR, *(uint32_t*)tmp, Size);
842     
843     /* Enable the USART transmit DMA channel: the transmit channel is used in order
844        to generate in the non-blocking mode the clock to the slave device, 
845        this mode isn't a simplex receive mode but a full-duplex receive mode */
846     tmp = (uint32_t*)&pRxData;
847     HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t*)tmp, (uint32_t)&husart->Instance->TDR, Size);
848
849     /* Enable the DMA transfer for the receiver request by setting the DMAR bit 
850     in the USART CR3 register */
851     husart->Instance->CR3 |= USART_CR3_DMAR;
852     
853     /* Enable the DMA transfer for transmit request by setting the DMAT bit
854        in the USART CR3 register */
855     husart->Instance->CR3 |= USART_CR3_DMAT;
856     
857     /* Process Unlocked */
858     __HAL_UNLOCK(husart);
859     
860     return HAL_OK;
861   }
862   else
863   {
864     return HAL_BUSY; 
865   }
866 }
867
868 /**
869   * @brief Full-Duplex Transmit Receive an amount of data in non blocking mode 
870   * @param husart: usart handle
871   * @param pTxData: pointer to TX data buffer
872   * @param pRxData: pointer to RX data buffer
873   * @param Size: amount of data to be received/sent
874   * @note   When the USART parity is enabled (PCE = 1) the data received contain the parity bit.
875   * @retval HAL status
876   */
877 HAL_StatusTypeDef HAL_USART_TransmitReceive_DMA(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size)
878 {
879   uint32_t *tmp;
880   
881   if(husart->State == HAL_USART_STATE_READY)
882   {
883     if((pTxData == HAL_NULL) || (pRxData == HAL_NULL) || (Size == 0)) 
884     {
885       return HAL_ERROR;                                    
886     }
887     /* Process Locked */
888     __HAL_LOCK(husart);
889     
890     husart->pRxBuffPtr = pRxData;
891     husart->RxXferSize = Size;
892     husart->pTxBuffPtr = pTxData;
893     husart->TxXferSize = Size;
894     
895     husart->ErrorCode = HAL_USART_ERROR_NONE;
896     husart->State = HAL_USART_STATE_BUSY_TX_RX;
897     
898     /* Set the USART DMA Rx transfer complete callback */
899     husart->hdmarx->XferCpltCallback = USART_DMAReceiveCplt;
900     
901     /* Set the USART DMA Half transfer complete callback */
902     husart->hdmarx->XferHalfCpltCallback = USART_DMARxHalfCplt;
903
904     /* Set the USART DMA Tx transfer complete callback */
905     husart->hdmatx->XferCpltCallback = USART_DMATransmitCplt;
906     
907     /* Set the USART DMA Half transfer complete callback */
908     husart->hdmatx->XferHalfCpltCallback = USART_DMATxHalfCplt;
909
910     /* Set the USART DMA Tx transfer error callback */
911     husart->hdmatx->XferErrorCallback = USART_DMAError;
912     
913     /* Set the USART DMA Rx transfer error callback */
914     husart->hdmarx->XferErrorCallback = USART_DMAError;
915     
916     /* Enable the USART receive DMA channel */
917     tmp = (uint32_t*)&pRxData;
918     HAL_DMA_Start_IT(husart->hdmarx, (uint32_t)&husart->Instance->RDR, *(uint32_t*)tmp, Size);
919     
920     /* Enable the USART transmit DMA channel */
921     tmp = (uint32_t*)&pTxData;
922     HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t*)tmp, (uint32_t)&husart->Instance->TDR, Size);
923
924     /* Enable the DMA transfer for the receiver request by setting the DMAR bit 
925     in the USART CR3 register */
926     husart->Instance->CR3 |= USART_CR3_DMAR;
927     
928     /* Enable the DMA transfer for transmit request by setting the DMAT bit
929        in the USART CR3 register */
930     husart->Instance->CR3 |= USART_CR3_DMAT;
931     
932     /* Process Unlocked */
933     __HAL_UNLOCK(husart);
934     
935     return HAL_OK;
936   }
937   else
938   {
939     return HAL_BUSY; 
940   }
941 }
942     
943 /**
944   * @brief Pauses the DMA Transfer.
945   * @param husart: USART handle
946   * @retval None
947   */
948 HAL_StatusTypeDef HAL_USART_DMAPause(USART_HandleTypeDef *husart)
949 {
950   /* Process Locked */
951   __HAL_LOCK(husart);
952
953   if(husart->State == HAL_USART_STATE_BUSY_TX)
954   {
955     /* Disable the USART DMA Tx request */
956     husart->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAT);
957   }
958   else if(husart->State == HAL_USART_STATE_BUSY_RX)
959   {
960     /* Disable the USART DMA Rx request */
961     husart->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAR);
962   }
963   else if(husart->State == HAL_USART_STATE_BUSY_TX_RX)
964   {
965     /* Disable the USART DMA Tx request */
966     husart->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAT);
967     /* Disable the USART DMA Rx request */
968     husart->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAR);
969   }
970
971   /* Process Unlocked */
972   __HAL_UNLOCK(husart);
973
974   return HAL_OK; 
975 }
976
977 /**
978   * @brief Resumes the DMA Transfer.
979   * @param husart: USART handle
980   * @retval None
981   */
982 HAL_StatusTypeDef HAL_USART_DMAResume(USART_HandleTypeDef *husart)
983 {
984   /* Process Locked */
985   __HAL_LOCK(husart);
986
987   if(husart->State == HAL_USART_STATE_BUSY_TX)
988   {
989     /* Enable the USART DMA Tx request */
990     husart->Instance->CR3 |= USART_CR3_DMAT;
991   }
992   else if(husart->State == HAL_USART_STATE_BUSY_RX)
993   {
994     /* Enable the USART DMA Rx request */
995     husart->Instance->CR3 |= USART_CR3_DMAR;
996   }
997   else if(husart->State == HAL_USART_STATE_BUSY_TX_RX)
998   {
999     /* Enable the USART DMA Rx request  before the DMA Tx request */
1000     husart->Instance->CR3 |= USART_CR3_DMAR;
1001     /* Enable the USART DMA Tx request */
1002     husart->Instance->CR3 |= USART_CR3_DMAT;
1003   }
1004
1005   /* If the USART peripheral is still not enabled, enable it */
1006   if ((husart->Instance->CR1 & USART_CR1_UE) == 0)
1007   {
1008     /* Enable USART peripheral */
1009     __HAL_USART_ENABLE(husart);
1010   }
1011
1012   /* Process Unlocked */
1013   __HAL_UNLOCK(husart);
1014
1015   return HAL_OK;
1016 }
1017
1018 /**
1019   * @brief Stops the DMA Transfer.
1020   * @param husart: USART handle
1021   * @retval None
1022   */
1023 HAL_StatusTypeDef HAL_USART_DMAStop(USART_HandleTypeDef *husart)
1024 {
1025   /* Process Locked */
1026   __HAL_LOCK(husart);
1027
1028   /* Disable the USART Tx/Rx DMA requests */
1029   husart->Instance->CR3 &= ~USART_CR3_DMAT;
1030   husart->Instance->CR3 &= ~USART_CR3_DMAR;
1031
1032   /* Abort the USART DMA tx channel */
1033   if(husart->hdmatx != HAL_NULL)
1034   {
1035     HAL_DMA_Abort(husart->hdmatx);
1036   }
1037   /* Abort the USART DMA rx channel */
1038   if(husart->hdmarx != HAL_NULL)
1039   {
1040     HAL_DMA_Abort(husart->hdmarx);
1041   }
1042
1043   /* Disable USART peripheral */
1044   __HAL_USART_DISABLE(husart);
1045
1046   husart->State = HAL_USART_STATE_READY;
1047
1048   /* Process Unlocked */
1049   __HAL_UNLOCK(husart);
1050
1051   return HAL_OK;
1052 }    
1053     
1054 /**
1055   * @brief This function handles USART interrupt request.
1056   * @param husart: USART handle
1057   * @retval None
1058   */
1059 void HAL_USART_IRQHandler(USART_HandleTypeDef *husart)
1060 {
1061   
1062   /* USART parity error interrupt occured ------------------------------------*/
1063   if((__HAL_USART_GET_IT(husart, USART_IT_PE) != RESET) && (__HAL_USART_GET_IT_SOURCE(husart, USART_IT_PE) != RESET))
1064   { 
1065     __HAL_USART_CLEAR_IT(husart, USART_IT_PE);
1066     husart->ErrorCode |= HAL_USART_ERROR_PE;
1067     /* Set the USART state ready to be able to start again the process */
1068     husart->State = HAL_USART_STATE_READY;
1069   }
1070   
1071   /* USART frame error interrupt occured -------------------------------------*/
1072   if((__HAL_USART_GET_IT(husart, USART_IT_FE) != RESET) && (__HAL_USART_GET_IT_SOURCE(husart, USART_IT_ERR) != RESET))
1073   { 
1074     __HAL_USART_CLEAR_IT(husart, USART_IT_FE);
1075     husart->ErrorCode |= HAL_USART_ERROR_FE;
1076     /* Set the USART state ready to be able to start again the process */
1077     husart->State = HAL_USART_STATE_READY;
1078   }
1079   
1080   /* USART noise error interrupt occured -------------------------------------*/
1081   if((__HAL_USART_GET_IT(husart, USART_IT_NE) != RESET) && (__HAL_USART_GET_IT_SOURCE(husart, USART_IT_ERR) != RESET))
1082   { 
1083     __HAL_USART_CLEAR_IT(husart, USART_IT_NE);
1084     husart->ErrorCode |= HAL_USART_ERROR_NE;
1085     /* Set the USART state ready to be able to start again the process */
1086     husart->State = HAL_USART_STATE_READY;
1087   }
1088   
1089   /* USART Over-Run interrupt occured ----------------------------------------*/
1090   if((__HAL_USART_GET_IT(husart, USART_IT_ORE) != RESET) && (__HAL_USART_GET_IT_SOURCE(husart, USART_IT_ERR) != RESET))
1091   { 
1092     __HAL_USART_CLEAR_IT(husart, USART_IT_ORE);
1093     husart->ErrorCode |= HAL_USART_ERROR_ORE;
1094     /* Set the USART state ready to be able to start again the process */
1095     husart->State = HAL_USART_STATE_READY;
1096   }
1097  
1098    /* Call USART Error Call back function if need be --------------------------*/
1099   if(husart->ErrorCode != HAL_USART_ERROR_NONE)
1100   {
1101     HAL_USART_ErrorCallback(husart);
1102   }  
1103  
1104   /* USART in mode Receiver --------------------------------------------------*/
1105   if((__HAL_USART_GET_IT(husart, USART_IT_RXNE) != RESET) && (__HAL_USART_GET_IT_SOURCE(husart, USART_IT_RXNE) != RESET))
1106   {
1107     if(husart->State == HAL_USART_STATE_BUSY_RX)
1108     {
1109       USART_Receive_IT(husart);
1110     }
1111     else
1112     {
1113       USART_TransmitReceive_IT(husart);
1114     }
1115   }
1116   
1117   /* USART in mode Transmitter -----------------------------------------------*/
1118   if((__HAL_USART_GET_IT(husart, USART_IT_TXE) != RESET) &&(__HAL_USART_GET_IT_SOURCE(husart, USART_IT_TXE) != RESET))
1119   {    
1120     if(husart->State == HAL_USART_STATE_BUSY_TX)
1121     {
1122       USART_Transmit_IT(husart);
1123     }
1124     else
1125     {
1126       USART_TransmitReceive_IT(husart);
1127     }
1128   }
1129   
1130   /* USART in mode Transmitter (transmission end) -----------------------------*/
1131   if((__HAL_USART_GET_IT(husart, USART_IT_TC) != RESET) &&(__HAL_USART_GET_IT_SOURCE(husart, USART_IT_TC) != RESET))
1132   {
1133     USART_EndTransmit_IT(husart);
1134   } 
1135
1136 }
1137
1138
1139 /**
1140   * @brief Tx Transfer completed callbacks
1141   * @param husart: usart handle
1142   * @retval None
1143   */
1144 __weak void HAL_USART_TxCpltCallback(USART_HandleTypeDef *husart)
1145 {
1146   /* NOTE : This function should not be modified, when the callback is needed,
1147             the HAL_USART_TxCpltCallback can be implemented in the user file
1148    */ 
1149 }
1150
1151 /**
1152   * @brief  Tx Half Transfer completed callbacks.
1153   * @param  husart: USART handle
1154   * @retval None
1155   */
1156  __weak void HAL_USART_TxHalfCpltCallback(USART_HandleTypeDef *husart)
1157 {
1158   /* NOTE: This function should not be modified, when the callback is needed,
1159            the HAL_USART_TxHalfCpltCallback can be implemented in the user file
1160    */
1161 }
1162
1163 /**
1164   * @brief  Rx Transfer completed callbacks.
1165   * @param  husart: USART handle
1166   * @retval None
1167   */
1168 __weak void HAL_USART_RxCpltCallback(USART_HandleTypeDef *husart)
1169 {
1170   /* NOTE: This function should not be modified, when the callback is needed,
1171            the HAL_USART_RxCpltCallback can be implemented in the user file
1172    */
1173 }
1174
1175 /**
1176   * @brief Rx Half Transfer completed callbacks
1177   * @param husart: usart handle
1178   * @retval None
1179   */
1180 __weak void HAL_USART_RxHalfCpltCallback(USART_HandleTypeDef *husart)
1181 {
1182   /* NOTE : This function should not be modified, when the callback is needed,
1183             the HAL_USART_RxHalfCpltCallback can be implemented in the user file
1184    */
1185 }
1186
1187 /**
1188   * @brief Tx/Rx Transfers completed callback for the non-blocking process
1189   * @param husart: usart handle
1190   * @retval None
1191   */
1192 __weak void HAL_USART_TxRxCpltCallback(USART_HandleTypeDef *husart)
1193 {
1194   /* NOTE : This function should not be modified, when the callback is needed,
1195             the HAL_USART_TxRxCpltCallback can be implemented in the user file
1196    */
1197 }
1198
1199 /**
1200   * @brief USART error callbacks
1201   * @param husart: usart handle
1202   * @retval None
1203   */
1204 __weak void HAL_USART_ErrorCallback(USART_HandleTypeDef *husart)
1205 {
1206   /* NOTE : This function should not be modified, when the callback is needed,
1207             the HAL_USART_ErrorCallback can be implemented in the user file
1208    */ 
1209 }
1210
1211 /**
1212   * @}
1213   */
1214
1215 /** @defgroup USART_Exported_Functions_Group3 Peripheral Control functions 
1216   *  @brief   USART control functions 
1217   *
1218 @verbatim   
1219  ===============================================================================
1220                       ##### Peripheral Control functions #####
1221  ===============================================================================  
1222     [..]
1223     This subsection provides a set of functions allowing to control the USART.
1224      (+) HAL_USART_GetState() API can be helpful to check in run-time the state of the USART peripheral. 
1225      (+) USART_CheckIdleState() APi ensures that TEACK and/or REACK bits are set after initialization
1226       
1227 @endverbatim
1228   * @{
1229   */
1230
1231
1232
1233 /**
1234   * @brief return the USART state
1235   * @param husart: USART handle
1236   * @retval HAL state
1237   */
1238 HAL_USART_StateTypeDef HAL_USART_GetState(USART_HandleTypeDef *husart)
1239 {
1240   return husart->State;
1241 }
1242
1243 /**
1244   * @brief  Return the USART error code
1245   * @param  husart : pointer to a USART_HandleTypeDef structure that contains
1246   *              the configuration information for the specified USART.
1247   * @retval USART Error Code
1248   */
1249 uint32_t HAL_USART_GetError(USART_HandleTypeDef *husart)
1250 {
1251   return husart->ErrorCode;
1252 }
1253
1254 /**
1255   * @}
1256   */
1257
1258 /**
1259   * @}
1260   */
1261   
1262 /** @defgroup USART_Private_Functions USART Private Functions
1263  * @{
1264  */
1265
1266 /**
1267   * @brief DMA USART transmit process complete callback 
1268   * @param hdma : DMA handle
1269   * @retval None
1270   */
1271 static void USART_DMATransmitCplt(DMA_HandleTypeDef *hdma)   
1272 {
1273   USART_HandleTypeDef* husart = ( USART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1274
1275   husart->TxXferCount = 0;
1276   
1277   if(husart->State == HAL_USART_STATE_BUSY_TX)
1278   {
1279     /* Wait for USART TC Flag */
1280     if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TC, RESET, USART_TXDMA_TIMEOUTVALUE) != HAL_OK)
1281     {
1282       /* Timeout Occured */ 
1283       HAL_USART_ErrorCallback(husart);
1284     }
1285     else
1286     {
1287       /* No Timeout */
1288       /* Disable the DMA transfer for transmit request by setting the DMAT bit
1289        in the USART CR3 register */
1290       husart->Instance->CR3 &= ~(USART_CR3_DMAT);
1291       husart->State= HAL_USART_STATE_READY;
1292     }
1293   }
1294   /* the usart state is HAL_USART_STATE_BUSY_TX_RX*/
1295   else
1296   {
1297     husart->State= HAL_USART_STATE_BUSY_RX;
1298     HAL_USART_TxCpltCallback(husart);
1299   }
1300 }
1301
1302
1303 /**
1304   * @brief DMA USART transmit process half complete callback 
1305   * @param hdma : DMA handle
1306   * @retval None
1307   */
1308 static void USART_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
1309 {
1310   USART_HandleTypeDef* husart = (USART_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
1311
1312   HAL_USART_TxHalfCpltCallback(husart);
1313 }
1314
1315 /**
1316   * @brief DMA USART receive process complete callback 
1317   * @param hdma : DMA handle
1318   * @retval None
1319   */
1320 static void USART_DMAReceiveCplt(DMA_HandleTypeDef *hdma)   
1321 {
1322   USART_HandleTypeDef* husart = ( USART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1323
1324   husart->RxXferCount = 0;
1325   
1326   /* Disable the DMA RX transfer for the receiver request by resetting the DMAR bit 
1327      in USART CR3 register */
1328   husart->Instance->CR3 &= (uint32_t)~((uint32_t)USART_CR3_DMAR);
1329   /* similarly, disable the DMA TX transfer that was started to provide the 
1330      clock to the slave device */
1331   husart->Instance->CR3 &= (uint32_t)~((uint32_t)USART_CR3_DMAT);
1332
1333   husart->State= HAL_USART_STATE_READY;
1334   
1335   HAL_USART_RxCpltCallback(husart);
1336 }
1337
1338 /**
1339   * @brief DMA USART receive process half complete callback 
1340   * @param hdma : DMA handle
1341   * @retval None
1342   */
1343 static void USART_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
1344 {
1345   USART_HandleTypeDef* husart = (USART_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
1346
1347   HAL_USART_RxHalfCpltCallback(husart); 
1348 }
1349
1350 /**
1351   * @brief DMA USART communication error callback 
1352   * @param hdma : DMA handle
1353   * @retval None
1354   */
1355 static void USART_DMAError(DMA_HandleTypeDef *hdma)   
1356 {
1357   USART_HandleTypeDef* husart = ( USART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1358
1359   husart->RxXferCount = 0;
1360   husart->TxXferCount = 0;
1361   husart->ErrorCode |= HAL_USART_ERROR_DMA;
1362   husart->State= HAL_USART_STATE_READY;
1363   
1364   HAL_USART_ErrorCallback(husart);
1365 }
1366
1367 /**
1368   * @brief  This function handles USART Communication Timeout.
1369   * @param  husart: USART handle
1370   * @param  Flag: specifies the USART flag to check.
1371   * @param  Status: The new Flag status (SET or RESET).
1372   * @param  Timeout: Timeout duration
1373   * @retval HAL status
1374   */
1375 static HAL_StatusTypeDef USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef *husart, uint32_t Flag, FlagStatus Status, uint32_t Timeout)  
1376 {
1377   uint32_t tickstart = HAL_GetTick();
1378   
1379   /* Wait until flag is set */
1380   if(Status == RESET)
1381   {    
1382     while(__HAL_USART_GET_FLAG(husart, Flag) == RESET)
1383     {
1384       /* Check for the Timeout */
1385       if(Timeout != HAL_MAX_DELAY)
1386       {
1387         if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
1388         {
1389           /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
1390           __HAL_USART_DISABLE_IT(husart, USART_IT_TXE);
1391           __HAL_USART_DISABLE_IT(husart, USART_IT_RXNE);
1392           __HAL_USART_DISABLE_IT(husart, USART_IT_PE);
1393           __HAL_USART_DISABLE_IT(husart, USART_IT_ERR);
1394           
1395           husart->State= HAL_USART_STATE_TIMEOUT;
1396           
1397           /* Process Unlocked */
1398           __HAL_UNLOCK(husart);
1399           
1400           return HAL_TIMEOUT;
1401         }
1402       }
1403     }
1404   }
1405   else
1406   {
1407     while(__HAL_USART_GET_FLAG(husart, Flag) != RESET)
1408     {
1409       /* Check for the Timeout */
1410       if(Timeout != HAL_MAX_DELAY)
1411       {
1412         if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
1413         {
1414           /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
1415           __HAL_USART_DISABLE_IT(husart, USART_IT_TXE);
1416           __HAL_USART_DISABLE_IT(husart, USART_IT_RXNE);
1417           __HAL_USART_DISABLE_IT(husart, USART_IT_PE);
1418           __HAL_USART_DISABLE_IT(husart, USART_IT_ERR);
1419     
1420           husart->State= HAL_USART_STATE_TIMEOUT;
1421           
1422           /* Process Unlocked */
1423           __HAL_UNLOCK(husart);
1424         
1425           return HAL_TIMEOUT;
1426         }
1427       }
1428     }
1429   }
1430   return HAL_OK;      
1431 }
1432
1433 /**
1434   * @brief Configure the USART peripheral 
1435   * @param husart: USART handle
1436   * @retval None
1437   */
1438 static HAL_StatusTypeDef USART_SetConfig(USART_HandleTypeDef *husart)
1439 {
1440   uint32_t tmpreg                      = 0x0;
1441   USART_ClockSourceTypeDef clocksource = USART_CLOCKSOURCE_UNDEFINED;
1442   HAL_StatusTypeDef ret                = HAL_OK;
1443   
1444   /* Check the parameters */
1445   assert_param(IS_USART_POLARITY(husart->Init.CLKPolarity));
1446   assert_param(IS_USART_PHASE(husart->Init.CLKPhase));
1447   assert_param(IS_USART_LASTBIT(husart->Init.CLKLastBit));
1448   assert_param(IS_USART_BAUDRATE(husart->Init.BaudRate));  
1449   assert_param(IS_USART_WORD_LENGTH(husart->Init.WordLength));
1450   assert_param(IS_USART_STOPBITS(husart->Init.StopBits));
1451   assert_param(IS_USART_PARITY(husart->Init.Parity));
1452   assert_param(IS_USART_MODE(husart->Init.Mode));
1453  
1454
1455   /*-------------------------- USART CR1 Configuration -----------------------*/
1456    /* Clear M, PCE, PS, TE and RE bits and configure       
1457    *  the USART Word Length, Parity and Mode: 
1458    *  set the M bits according to husart->Init.WordLength value 
1459    *  set PCE and PS bits according to husart->Init.Parity value
1460    *  set TE and RE bits according to husart->Init.Mode value */
1461   tmpreg = (uint32_t)husart->Init.WordLength | husart->Init.Parity | husart->Init.Mode;
1462   MODIFY_REG(husart->Instance->CR1, USART_CR1_FIELDS, tmpreg);
1463   
1464   /*---------------------------- USART CR2 Configuration ---------------------*/
1465   /* Clear and configure the USART Clock, CPOL, CPHA, LBCL and STOP bits:
1466    * set CPOL bit according to husart->Init.CLKPolarity value
1467    * set CPHA bit according to husart->Init.CLKPhase value
1468    * set LBCL bit according to husart->Init.CLKLastBit value
1469    * set STOP[13:12] bits according to husart->Init.StopBits value */
1470   tmpreg = (uint32_t)(USART_CLOCK_ENABLED); 
1471   tmpreg |= ((uint32_t)husart->Init.CLKPolarity | (uint32_t)husart->Init.CLKPhase);
1472   tmpreg |= ((uint32_t)husart->Init.CLKLastBit | (uint32_t)husart->Init.StopBits);
1473   MODIFY_REG(husart->Instance->CR2, USART_CR2_FIELDS, tmpreg);
1474
1475   /*-------------------------- USART CR3 Configuration -----------------------*/  
1476   /* no CR3 register configuration                                            */
1477
1478   /*-------------------------- USART BRR Configuration -----------------------*/
1479   __HAL_USART_GETCLOCKSOURCE(husart, clocksource);
1480   switch (clocksource)
1481   {
1482     case USART_CLOCKSOURCE_PCLK1: 
1483       husart->Instance->BRR = (uint16_t)(HAL_RCC_GetPCLK1Freq() / husart->Init.BaudRate);
1484       break;
1485     case USART_CLOCKSOURCE_PCLK2: 
1486       husart->Instance->BRR = (uint16_t)(HAL_RCC_GetPCLK2Freq() / husart->Init.BaudRate);
1487       break;
1488     case USART_CLOCKSOURCE_HSI: 
1489       husart->Instance->BRR = (uint16_t)(HSI_VALUE / husart->Init.BaudRate); 
1490       break; 
1491     case USART_CLOCKSOURCE_SYSCLK:  
1492       husart->Instance->BRR = (uint16_t)(HAL_RCC_GetSysClockFreq() / husart->Init.BaudRate);
1493       break;  
1494     case USART_CLOCKSOURCE_LSE:                
1495       husart->Instance->BRR = (uint16_t)(LSE_VALUE / husart->Init.BaudRate); 
1496       break;      
1497     case USART_CLOCKSOURCE_UNDEFINED:                
1498     default:                
1499       ret = HAL_ERROR; 
1500       break;          
1501   } 
1502   
1503   return ret; 
1504 }
1505
1506
1507
1508 /**
1509   * @brief Check the USART Idle State
1510   * @param husart: USART handle
1511   * @retval HAL status
1512   */
1513 static HAL_StatusTypeDef USART_CheckIdleState(USART_HandleTypeDef *husart)
1514 {
1515   /* Initialize the USART ErrorCode */
1516   husart->ErrorCode = HAL_USART_ERROR_NONE;
1517   
1518   /* Check if the Transmitter is enabled */
1519   if((husart->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE)
1520   {
1521     /* Wait until TEACK flag is set */
1522     if(USART_WaitOnFlagUntilTimeout(husart, USART_ISR_TEACK, RESET, TEACK_REACK_TIMEOUT) != HAL_OK)  
1523     { 
1524       /* Timeout Occured */ 
1525       return HAL_TIMEOUT;
1526     } 
1527   }
1528   /* Check if the Receiver is enabled */
1529   if((husart->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE)
1530   {
1531     /* Wait until REACK flag is set */
1532     if(USART_WaitOnFlagUntilTimeout(husart, USART_ISR_REACK, RESET, TEACK_REACK_TIMEOUT) != HAL_OK)  
1533     { 
1534       /* Timeout Occured */ 
1535       return HAL_TIMEOUT;
1536     }
1537   }
1538   
1539   /* Initialize the USART state*/
1540   husart->State= HAL_USART_STATE_READY;
1541     
1542   /* Process Unlocked */
1543   __HAL_UNLOCK(husart);
1544   
1545   return HAL_OK;  
1546 }
1547
1548 /**
1549   * @brief  Simplex Send an amount of data in non-blocking mode.
1550   *         Function called under interruption only, once
1551   *         interruptions have been enabled by HAL_USART_Transmit_IT()      
1552   * @param  husart: USART handle
1553   * @retval HAL status
1554   * @note   The USART errors are not managed to avoid the overrun error.
1555   */
1556 static HAL_StatusTypeDef USART_Transmit_IT(USART_HandleTypeDef *husart)
1557 {
1558   uint16_t* tmp;
1559
1560   if (husart->State == HAL_USART_STATE_BUSY_TX)
1561   {
1562     
1563      if(husart->TxXferCount == 0)
1564     {
1565       /* Disable the USART Transmit Complete Interrupt */
1566       __HAL_USART_DISABLE_IT(husart, USART_IT_TXE);
1567         
1568       /* Enable the USART Transmit Complete Interrupt */    
1569       __HAL_USART_ENABLE_IT(husart, USART_IT_TC);
1570       
1571       return HAL_OK;
1572     }
1573     else
1574     {
1575       if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1576       {
1577         tmp = (uint16_t*) husart->pTxBuffPtr;
1578         husart->Instance->TDR = (*tmp & (uint16_t)0x01FF);   
1579         husart->pTxBuffPtr += 2;
1580       } 
1581       else
1582       {
1583         husart->Instance->TDR = (uint8_t)(*husart->pTxBuffPtr++ & (uint8_t)0xFF);       
1584       }
1585
1586       husart->TxXferCount--;
1587     
1588       return HAL_OK;
1589     }
1590   }
1591   else
1592   {
1593     return HAL_BUSY;   
1594   }
1595 }
1596
1597
1598 /**
1599   * @brief  Wraps up transmission in non blocking mode.
1600   * @param  husart: pointer to a USART_HandleTypeDef structure that contains
1601   *                the configuration information for the specified USART module.
1602   * @retval HAL status
1603   */
1604 static HAL_StatusTypeDef USART_EndTransmit_IT(USART_HandleTypeDef *husart)
1605 {
1606   /* Disable the USART Transmit Complete Interrupt */    
1607   __HAL_USART_DISABLE_IT(husart, USART_IT_TC);
1608   
1609   /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1610   __HAL_USART_DISABLE_IT(husart, USART_IT_ERR);
1611     
1612   husart->State = HAL_USART_STATE_READY;
1613    
1614   HAL_USART_TxCpltCallback(husart);
1615   
1616   return HAL_OK;
1617 }
1618
1619
1620 /**
1621   * @brief  Simplex Receive an amount of data in non-blocking mode.
1622   *         Function called under interruption only, once
1623   *         interruptions have been enabled by HAL_USART_Receive_IT()    
1624   * @param  husart: USART handle
1625   * @retval HAL status
1626   */
1627 static HAL_StatusTypeDef USART_Receive_IT(USART_HandleTypeDef *husart)
1628 {
1629   uint16_t* tmp;
1630   uint16_t uhMask = husart->Mask;  
1631
1632   if(husart->State == HAL_USART_STATE_BUSY_RX)
1633   {
1634     
1635     if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1636     {
1637       tmp = (uint16_t*) husart->pRxBuffPtr;
1638       *tmp = (uint16_t)(husart->Instance->RDR & uhMask);
1639       husart->pRxBuffPtr += 2;
1640     } 
1641     else
1642     {
1643       *husart->pRxBuffPtr++ = (uint8_t)(husart->Instance->RDR & (uint8_t)uhMask);       
1644     }
1645       /* Send dummy byte in order to generate the clock for the Slave to Send the next data */
1646       husart->Instance->TDR = (DUMMY_DATA & (uint16_t)0x00FF);       
1647     
1648     if(--husart->RxXferCount == 0)
1649     { 
1650       __HAL_USART_DISABLE_IT(husart, USART_IT_RXNE);      
1651
1652       /* Disable the USART Parity Error Interrupt */
1653       __HAL_USART_DISABLE_IT(husart, USART_IT_PE);
1654         
1655       /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1656       __HAL_USART_DISABLE_IT(husart, USART_IT_ERR);
1657         
1658       husart->State = HAL_USART_STATE_READY;
1659       
1660       HAL_USART_RxCpltCallback(husart);
1661       
1662       return HAL_OK;
1663     }
1664     
1665     return HAL_OK;
1666   }
1667   else
1668   {
1669     return HAL_BUSY; 
1670   }
1671 }
1672
1673 /**
1674   * @brief  Full-Duplex Send receive an amount of data in full-duplex mode (non-blocking).
1675   *         Function called under interruption only, once
1676   *         interruptions have been enabled by HAL_USART_TransmitReceive_IT()     
1677   * @param  husart: USART handle
1678   * @retval HAL status
1679   */
1680 static HAL_StatusTypeDef USART_TransmitReceive_IT(USART_HandleTypeDef *husart)
1681 {
1682   uint16_t* tmp;
1683   uint16_t uhMask = husart->Mask;   
1684
1685   if(husart->State == HAL_USART_STATE_BUSY_TX_RX)
1686   {
1687
1688     if(husart->TxXferCount != 0x00)
1689     {
1690       if(__HAL_USART_GET_FLAG(husart, USART_FLAG_TXE) != RESET)
1691       {
1692         if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1693         {
1694           tmp = (uint16_t*) husart->pTxBuffPtr;
1695           husart->Instance->TDR = (uint16_t)(*tmp & uhMask);
1696           husart->pTxBuffPtr += 2;
1697         } 
1698         else
1699         {
1700           husart->Instance->TDR = (uint8_t)(*husart->pTxBuffPtr++ & (uint8_t)uhMask);       
1701         }
1702         husart->TxXferCount--;
1703         
1704         /* Check the latest data transmitted */
1705         if(husart->TxXferCount == 0)
1706         {
1707            __HAL_USART_DISABLE_IT(husart, USART_IT_TXE);
1708         }
1709       }
1710     }
1711     
1712     if(husart->RxXferCount != 0x00)
1713     {
1714       if(__HAL_USART_GET_FLAG(husart, USART_FLAG_RXNE) != RESET)
1715       {
1716         if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
1717         {
1718           tmp = (uint16_t*) husart->pRxBuffPtr;
1719           *tmp = (uint16_t)(husart->Instance->RDR & uhMask);
1720           husart->pRxBuffPtr += 2;          
1721         } 
1722         else
1723         {
1724           *husart->pRxBuffPtr++ = (uint8_t)(husart->Instance->RDR & (uint8_t)uhMask);         
1725         }
1726         husart->RxXferCount--;
1727       }
1728     }
1729     
1730     /* Check the latest data received */
1731     if(husart->RxXferCount == 0)
1732     {
1733       __HAL_USART_DISABLE_IT(husart, USART_IT_RXNE);
1734       
1735       /* Disable the USART Parity Error Interrupt */
1736       __HAL_USART_DISABLE_IT(husart, USART_IT_PE);
1737       
1738       /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
1739       __HAL_USART_DISABLE_IT(husart, USART_IT_ERR);
1740       
1741       husart->State = HAL_USART_STATE_READY;
1742       
1743       HAL_USART_TxRxCpltCallback(husart);
1744       
1745       return HAL_OK;
1746     }
1747     
1748     return HAL_OK;
1749   }
1750   else
1751   {
1752     return HAL_BUSY; 
1753   }
1754 }
1755
1756 /**
1757   * @}
1758   */
1759
1760 #endif /* HAL_USART_MODULE_ENABLED */
1761 /**
1762   * @}
1763   */
1764
1765 /**
1766   * @}
1767   */
1768
1769 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/