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