/******************************************************************************
*@file  : spl_uart.h
*@brief : Header file of UART SPL module.
******************************************************************************/

#ifndef __SPL_UART_H__
#define __SPL_UART_H__

#ifdef __cplusplus
 extern "C" {
#endif

#include "acm32g103_spl_conf.h"

/** 
  * @brief  UART Init Structure definition  
  */ 
  
typedef struct
{
  uint32_t BaudRate;            /*!< This member configures the UART communication baud rate. */

  uint32_t WordLength;          /*!< Specifies the number of data bits transmitted or received in a frame.
                                      This parameter can be a value of @ref UART_Word_Length */

  uint32_t StopBits;            /*!< Specifies the number of stop bits transmitted.
                                      This parameter can be a value of @ref UART_Stop_Bits */

  uint32_t Parity;              /*!< Specifies the parity mode.
                                      This parameter can be a value of @ref UART_Parity */
 
  uint32_t Mode;                /*!< Specifies whether the Receive or Transmit mode is enabled or disabled.
                                      This parameter can be a value of @ref UART_Mode */

  uint32_t HwFlowCtl;           /*!< Specifies wether the hardware flow control mode is enabled or disabled.
                                      This parameter can be a value of @ref UART_Hardware_Flow_Control */
} UART_InitTypeDef;

/** @defgroup UART_Exported_Constants
  * @{
  */ 

/** @defgroup UART_Word_Length 
  * @{
  */
#define UART_WORDLENGTH_5B                  (0x00000000U)    /*!< 5-bit Word Length */
#define UART_WORDLENGTH_6B                  (0x00000040U)    /*!< 6-bit Word Length */
#define UART_WORDLENGTH_7B                  (0x00000080U)    /*!< 7-bit Word Length */
#define UART_WORDLENGTH_8B                  (0x000000C0U)    /*!< 8-bit Word Length */
#define UART_WORDLENGTH_9B                  (0x00000100U)    /*!< 9-bit Word Length */
#define IS_UART_WORDLENGTH(__WORDLENGTH__)    (((__WORDLENGTH__) == UART_WORDLENGTH_5B) || \
                                               ((__WORDLENGTH__) == UART_WORDLENGTH_6B) || \
                                               ((__WORDLENGTH__) == UART_WORDLENGTH_7B) || \
                                               ((__WORDLENGTH__) == UART_WORDLENGTH_8B) || \
                                               ((__WORDLENGTH__) == UART_WORDLENGTH_9B))
/**
  * @}
  */


/** @defgroup UART_Parity
  * @{
  */
#define UART_PARITY_NONE                    (0x00000000U)    /*!< No parity   */
#define UART_PARITY_EVEN                    (0x00000006U)    /*!< Even parity */
#define UART_PARITY_ODD                     (0x00000002U)    /*!< Odd parity  */
#define UART_PARITY_0                       (0x00000206U)    /*!< 0 parity  */
#define UART_PARITY_1                       (0x00000202U)    /*!< 1 parity  */
#define IS_UART_PARITY(__PARITY__)        (((__PARITY__) == UART_PARITY_NONE) || \
                                           ((__PARITY__) == UART_PARITY_EVEN) || \
                                           ((__PARITY__) == UART_PARITY_ODD))
/**
  * @}
  */


/** @defgroup UART_Stop_Bits   UART Number of Stop Bits
  * @{
  */
#define UART_STOPBITS_1                     (0x00000000U)    /*!< UART frame with 1 stop bit    */
#define UART_STOPBITS_2                     (0x00000008U)    /*!< UART frame with 2 stop bits   */
#define IS_UART_STOPBITS(__STOPBITS__)    (((__STOPBITS__) == UART_STOPBITS_1) || \
                                           ((__STOPBITS__) == UART_STOPBITS_2))
/**
  * @}
  */


/** @defgroup UART_Hardware_Flow_Control
  * @{
  */
#define UART_HWCONTROL_NONE                  (0x00000000U)        /*!< No hardware control       */
#define UART_HWCONTROL_CTS                   (0x00008000U)        /*!< Clear To Send             */
#define UART_HWCONTROL_RTS                   (0x00004000U)        /*!< Request To Send           */
#define UART_HWCONTROL_CTS_RTS               (UART_HWCONTROL_CTS | UART_HWCONTROL_RTS)    /*!< Request and Clear To Send */
#define IS_UART_HARDWARE_FLOW_CONTROL(__CONTROL__)    (((__CONTROL__) == UART_HWCONTROL_NONE) || \
                                                       ((__CONTROL__) == UART_HWCONTROL_RTS)  || \
                                                       ((__CONTROL__) == UART_HWCONTROL_CTS)  || \
                                                       ((__CONTROL__) == UART_HWCONTROL_CTS_RTS))
/**
  * @}
  */


/** @defgroup UART_Mode
  * @{
  */
#define UART_MODE_RX                        (0x00000200)        /*!< RX mode        */
#define UART_MODE_TX                        (0x00000100)        /*!< TX mode        */
#define UART_MODE_TX_RX                     (0x00000300)        /*!< RX and TX mode */
#define UART_MODE_HALF_DUPLEX               (0x20000300)        /*!< Single half duplex */
#define IS_UART_MODE(__MODE__)            (((__MODE__) == UART_MODE_RX)          || \
                                           ((__MODE__) == UART_MODE_TX)          || \
                                           ((__MODE__) == UART_MODE_TX_RX)       || \
                                           ((__MODE__) == UART_MODE_HALF_DUPLEX))
/**
  * @}
  */
  
  
  
/** @defgroup UART_FIFO_Level
  * @{
  */
 
/* 
TXIFLSEL:  
TXI happened only at the point when the data quantity in TXFIFO changes to one of the values below.
*/
#define UART_TX_FIFO_1_16             (0x00001400)        /*!< TXI happen when 0 data   left in TXFIFO */
#define UART_TX_FIFO_1_8              (0x00000000)        /*!< TXI happen when 2 datas  left in TXFIFO */
#define UART_TX_FIFO_1_4              (0x00000400)        /*!< TXI happen when 4 datas  left in TXFIFO */
#define UART_TX_FIFO_1_2              (0x00000800)        /*!< TXI happen when 8 datas  left in TXFIFO */
#define UART_TX_FIFO_3_4              (0x00000C00)        /*!< TXI happen when 12 datas left in TXFIFO */
#define UART_TX_FIFO_7_8              (0x00001000)        /*!< TXI happen when 14 datas left in TXFIFO */

#define IS_UART_TX_FIFO_LEVEL(LEVEL)      (((LEVEL) == UART_TX_FIFO_1_16)  || \
                                           ((LEVEL) == UART_TX_FIFO_1_8)   || \
                                           ((LEVEL) == UART_TX_FIFO_1_4)   || \
                                           ((LEVEL) == UART_TX_FIFO_1_2)   || \
                                           ((LEVEL) == UART_TX_FIFO_3_4)   || \
                                           ((LEVEL) == UART_TX_FIFO_7_8))
/* 
RXIFLSEL:
RXI happened only at the point when the data quantity in RXFIFO changes to one of the values below.
*/ 
#define UART_RX_FIFO_1_16             (0x0000A000)        /*!< RXI happen when 1 data   in RXFIFO */
#define UART_RX_FIFO_1_8              (0x00000000)        /*!< RXI happen when 2 datas  in RXFIFO */
#define UART_RX_FIFO_1_4              (0x00002000)        /*!< RXI happen when 4 datas  in RXFIFO */
#define UART_RX_FIFO_1_2              (0x00004000)        /*!< RXI happen when 8 datas  in RXFIFO */
#define UART_RX_FIFO_3_4              (0x00006000)        /*!< RXI happen when 12 datas in RXFIFO */
#define UART_RX_FIFO_7_8              (0x00008000)        /*!< RXI happen when 14 datas in RXFIFO */

#define IS_UART_RX_FIFO_LEVEL(LEVEL)       (((LEVEL) == UART_RX_FIFO_1_16)  || \
                                            ((LEVEL) == UART_RX_FIFO_1_8)   || \
                                            ((LEVEL) == UART_RX_FIFO_1_4)   || \
                                            ((LEVEL) == UART_RX_FIFO_1_2)   || \
                                            ((LEVEL) == UART_RX_FIFO_3_4)   || \
                                            ((LEVEL) == UART_RX_FIFO_7_8))


/**
  * @}
  */  

  
#define IS_UART_ALL_PERIPH(PERIPH)  (((PERIPH) == UART1) || \
                                     ((PERIPH) == UART2) || \
                                     ((PERIPH) == UART3) || \
                                     ((PERIPH) == UART4)) 

/** @defgroup UART_Interrupt_definition 
  * @{
  */
  
#define UART_IT_ABRI               (UART_IE_ABRI )     
#define UART_IT_IDLEI              (UART_IE_IDLEI)     
#define UART_IT_BCNTI              (UART_IE_BCNTI)     
#define UART_IT_LBDI               (UART_IE_LBDI )     
#define UART_IT_OEI                (UART_IE_OEI  )      
#define UART_IT_BEI                (UART_IE_BEI  )     
#define UART_IT_PEI                (UART_IE_PEI  )     
#define UART_IT_FEI                (UART_IE_FEI  )     
#define UART_IT_TXI                (UART_IE_TXI  )     
#define UART_IT_RXI                (UART_IE_RXI  )     


#define IS_UART_CONFIG_IT(IT)  (((IT) == UART_IT_ABRI) || ((IT) == UART_IT_IDLEI) || \
                                ((IT) == UART_IT_BCNTI)|| ((IT) == UART_IT_LBDI) || \
                                ((IT) == UART_IT_OEI)  || ((IT) == UART_IT_BEI) || \
                                ((IT) == UART_IT_PEI)  || ((IT) == UART_IT_FEI)|| \
                                ((IT) == UART_IT_TXI)  || ((IT) == UART_IT_RXI))
                                
#define IS_UART_GET_IT(IT)     IS_UART_CONFIG_IT(IT) 
#define IS_UART_CLEAR_IT(IT)   IS_UART_CONFIG_IT(IT) 
/**
  * @}
  */

/** @defgroup UART_DMA_Requests 
  * @{
  */

#define UART_DMAReq_Tx                      (UART_CR1_TXDMAE)
#define UART_DMAReq_Rx                      (UART_CR1_RXDMAE)
#define IS_UART_DMAREQ(DMAREQ) ((((DMAREQ) & ~(UART_CR1_TXDMAE | UART_CR1_RXDMAE)) == 0x00) && ((DMAREQ) != (uint16_t)0x00))

/**
  * @}
  */ 

/** @defgroup UART_WakeUp_methods
  * @{
  */

#define UART_WakeUp_IdleLine                ((uint32_t)0x0)
#define UART_WakeUp_AddressMark             ((uint32_t)UART_CR2_WAKE)
#define IS_UART_WAKEUP(WAKEUP) (((WAKEUP) == UART_WakeUp_IdleLine) || \
                                 ((WAKEUP) == UART_WakeUp_AddressMark))
/**
  * @}
  */
  

/** @defgroup UART_IrDA_Low_Power 
  * @{
  */

#define UART_IrDAMode_LowPower              (UART_CR1_SIRLP)
#define UART_IrDAMode_Normal                (0x0)
#define IS_UART_IRDA_MODE(MODE) (((MODE) == UART_IrDAMode_LowPower) || \
                                  ((MODE) == UART_IrDAMode_Normal))
/**
  * @}
  */ 

/** @defgroup UART_Flags 
  * @{
  */

#define IS_UART_FLAG(FLAG)     (((FLAG) == UART_FR_BUSY) || ((FLAG) == UART_FR_CTS) || \
                                ((FLAG) == UART_FR_TXFE) || ((FLAG) == UART_FR_RXFF)|| \
                                ((FLAG) == UART_FR_TXFF) || ((FLAG) == UART_FR_RXFE)|| \
                                ((FLAG) == UART_FR_OE)   || ((FLAG) == UART_FR_BE)  || \
                                ((FLAG) == UART_FR_PE)   || ((FLAG) == UART_FR_FE))

#define IS_UART_ADDRESS(ADDRESS) ((ADDRESS) <= 0x7F)
#define IS_UART_DATA(DATA) ((DATA) <= 0x1FF)

/**
  * @}
  */ 

/* Clear UART_FR_OE flag */
#define UART_CLEAR_FLAG_OE(UARTx)  (UARTx->FR = UART_FR_OE)

/* Function used to set the UART configuration to the default reset state ***/ 
void UART_DeInit(UART_TypeDef* UARTx);

/* Initialization and Configuration functions *********************************/
void UART_Init(UART_TypeDef* UARTx, UART_InitTypeDef* UART_InitStruct);
void UART_StructInit(UART_InitTypeDef* UART_InitStruct);

/* UART TX RX FIFO command ****************************************************/
void UART_FIFOCmd(UART_TypeDef* UARTx, FunctionalState NewState);
void UART_FIFO_Level_Set(UART_TypeDef* UARTx, uint32_t TXFIFO_Level, uint32_t RXFIFO_Level);
void UART_TX_FIFO_Level_Set(UART_TypeDef* UARTx, uint32_t TXFIFO_Level);
void UART_RX_FIFO_Level_Set(UART_TypeDef* UARTx, uint32_t RXFIFO_Level);

void UART_Cmd(UART_TypeDef* UARTx, FunctionalState NewState);
void UART_SetPrescaler(UART_TypeDef* UARTx, uint8_t UART_Prescaler);


/* Data transfers functions ***************************************************/ 
void UART_SendData(UART_TypeDef* UARTx, uint16_t Data);
uint16_t UART_ReceiveData(UART_TypeDef* UARTx);

/* Multi-Processor Communication functions ************************************/
void UART_SetAddress(UART_TypeDef* UARTx, uint8_t UART_Address);
void UART_WakeUpConfig(UART_TypeDef* UARTx, uint16_t UART_WakeUp);
void UART_ReceiverWakeUpCmd(UART_TypeDef* UARTx, FunctionalState NewState);

/* LIN mode functions *********************************************************/
void UART_SendBreak(UART_TypeDef* UARTx);

/* Half-duplex mode function **************************************************/
void UART_HalfDuplexCmd(UART_TypeDef* UARTx, FunctionalState NewState);

/* Smartcard mode functions ***************************************************/
void UART_SmartCardCmd(UART_TypeDef* UARTx, FunctionalState NewState);
void UART_SmartCardNACKCmd(UART_TypeDef* UARTx, FunctionalState NewState);
void UART_SetGuardTime(UART_TypeDef* UARTx, uint8_t UART_GuardTime);

/* IrDA mode functions ********************************************************/
void UART_IrDAConfig(UART_TypeDef* UARTx, uint32_t UART_IrDAMode);
void UART_IrDACmd(UART_TypeDef* UARTx, FunctionalState NewState);

/* DMA transfers management functions *****************************************/
void UART_DMACmd(UART_TypeDef* UARTx, uint32_t UART_DMAReq, FunctionalState NewState);

/* Interrupts and flags management functions **********************************/
FlagStatus UART_GetFlagStatus(UART_TypeDef* UARTx, uint32_t UART_FLAG);

void UART_ITConfig(UART_TypeDef* UARTx, uint32_t UART_IT, FunctionalState NewState);

ITStatus UART_GetITStatus(UART_TypeDef* UARTx, uint32_t UART_IT);
void UART_ClearITPendingBit(UART_TypeDef* UARTx, uint32_t UART_IT);

ITStatus UART_GetISRStatus(UART_TypeDef* UARTx, uint32_t UART_IT);
void UART_ClearISRStatus(UART_TypeDef* UARTx, uint32_t UART_IT);

/* UART for logging */
void UART_SetDebugUart(UART_TypeDef *UARTx);

#ifdef __cplusplus
}
#endif

#endif /* __SPL_UART_H__ */
