/**
 *******************************************************************************
 * @file    dpm32m0xx_uart.h
 *
 * @brief   Header file for UART firmware driver.
 *
 * @author  DPM
 *
 * @version V1.0.0
 *
 * @date    2023-11-01
 *
 *******************************************************************************/

#ifndef __DPM32M0XX_UART_H__
#define __DPM32M0XX_UART_H__


#ifdef __cplusplus
extern "C" {
#endif

#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wpadded"
#endif

#include "dpm32m0xx.h"


/**
 ******************************************************************************
 * @brief UART mode enumeration.
 *****************************************************************************/
typedef enum
{
  UART_MODE_RX              = UART_CR_RX_EN_Msk,        /*!< UART enable Receive mode. */
  UART_MODE_TX              = UART_CR_TX_EN_Msk,        /*!< UART enable Transmit mode. */
  UART_MODE_RX_TX           = 0x06UL                    /*!< UART enable Receive and Transmit mode. */
} UART_ModeTypeEnum;

/**
 ******************************************************************************
 * @brief UART data length enumeration.
 *****************************************************************************/
typedef enum
{
  UART_DATA_LEN_6           = 0x00UL,                   /*!< 6 data bits transmitted or received in a frame. */
  UART_DATA_LEN_7           = 0x08UL,                   /*!< 7 data bits transmitted or received in a frame. */
  UART_DATA_LEN_8           = 0x10UL,                   /*!< 8 data bits transmitted or received in a frame.Default param. */
  UART_DATA_LEN_9           = UART_CR_DATA_LEN_Msk      /*!< 9 data bits transmitted or received in a frame. */
} UART_DataLenEnum;

/**
 ******************************************************************************
 * @brief UART stop bits length enumeration.
 *****************************************************************************/
typedef enum
{
  UART_STOP_BITS_1          = 0x00UL,                   /*!< 1 stop bits transmitted. */
  UART_STOP_BITS_2          = UART_CR_STOP_LEN_Msk      /*!< 2 stop bits transmitted.*/
} UART_StopBitsEnum;

/**
 ******************************************************************************
 * @brief UART parity mode enumeration.
 *****************************************************************************/
typedef enum
{
  UART_PARITY_NO            = 0x00UL,                   /*!< no parity check. */
  UART_PARITY_EVEN          = UART_CR_PARITY_EN_Msk,    /*!< even parity check .*/
  UART_PARITY_ODD           = 0xC0UL                    /*!< odd parity check .*/
} UART_ParityEnum;

#if defined (DPM32M08x) || defined (DPM32M05x)
/**
 ******************************************************************************
 * @brief UART DMA request enumeration.
 *****************************************************************************/
typedef enum
{
  UART_DMA_REQ_RX           = UART_CR_RX_DMAEN_Msk,   /*!< Rx DMA request. */
  UART_DMA_REQ_TX           = UART_CR_TX_DMAEN_Msk    /*!< Tx DMA request. */
} UART_DMAReqEnum;
#endif /* DPM32M08x || DPM32M05x */

/**
 ******************************************************************************
 * @brief UART data is transmitted/received with the LSB/MSB first enumeration.
 *****************************************************************************/
typedef enum
{
  UART_DATA_LSB           = 0x00,   /*!< LSB first */
  UART_DATA_MSB           = 0x01    /*!< MSB first. */
} UART_FirstDataEnum;

/**
 ******************************************************************************
 * @brief UART interrupt enable enumeration.
 *****************************************************************************/
typedef enum
{
  UART_INT_RXNE_IE          = UART_CR_RXNE_IE_Msk,    /*!< Reception buffer interrupt. */
  UART_INT_TXC_IE           = UART_CR_TXC_IE_Msk,     /*!< Transmission complete interrupt. */
  UART_INT_TXE_IE           = UART_CR_TXE_IE_Msk,     /*!< Transmission buffer empty interrupt. */
  UART_INT_ERR_IE           = UART_CR_ERR_IE_Msk,     /*!< Error interrupt,(Error includes PE, FE and ORE). */
  UART_INT_IDLE_IE          = UART_CR_IDLE_IE_Msk     /*!< Idle frame interrupt. */
} UART_IntTypeEnum;

/**
 ******************************************************************************
 * @brief UART interrupt flag enumeration.
 *****************************************************************************/
typedef enum
{
  UART_INT_FLAG_RXNE        = UART_ISR_RXNE_Msk,         /*!< Reception buffer not empty flag. */
  UART_INT_FLAG_TXC         = UART_ISR_TXC_Msk,          /*!< Transmission complete flag. */
  UART_INT_FLAG_TXE         = UART_ISR_TXE_Msk,          /*!< Transmission buffer empty flag. */
  UART_INT_FLAG_PARITY_ERR  = UART_ISR_PARITY_ERR_Msk,   /*!< Parity error flag. */
  UART_INT_FLAG_FRAME_ERR   = UART_ISR_FRAME_ERR_Msk,    /*!< Framing error flag. */
  UART_INT_FLAG_OVERR_ERR   = UART_ISR_OVRR_ERR_Msk,   /*!< Over run error flag. */
  UART_INT_FLAG_IDLE        = UART_ISR_IDLE_Msk          /*!< Idle frame flag. */
} UART_IntFlagEnum;

/**
 ******************************************************************************
 * @brief UART initialization structure definition.
 *****************************************************************************/
typedef struct
{
  uint32_t            UART_BaudRate;      /*!< This member configures the UART communication baud rate.
                                               The baud rate is computed using the following formula:
                                               IntegerDivider = ((PCLK) / (UART_InitTypeStruct->UART_BaudRate)))
                                               FractionalDivider = UART_GetBaudRateFraDiv((IntegerDivider - ((u32) IntegerDivider)))*/
  UART_DataLenEnum    UART_DataLen;       /*!< Specifies the number of data bits transmitted or received in a frame.
                                               This parameter can be a value of @ref UART_DataLenEnum. */
  UART_StopBitsEnum   UART_StopBits;      /*!< Specifies the number of stop bits transmitted.
                                               This parameter can be a value of @ref UART_StopBitsEnum. */
  UART_ParityEnum     UART_Parity;        /*!< Specifies the parity mode.
                                               This parameter can be a value of @ref UART_ParityEnum. */
  UART_ModeTypeEnum   UART_Mode;          /*!< Specifies whether the Receive or Transmit mode is enabled or disabled.
                                               This parameter can be a value of @ref UART_ModeTypeEnum. */
} UART_InitTypeStruct;


/* UART Param Check. */
#if defined (DPM32M08x) || defined (DPM32M05x)
#define IS_UART_PERIPH(x) (((x) == UART0) || \
                           ((x) == UART1) || \
                           ((x) == UART2))
#endif /* DPM32M08x || DPM32M05x */

#if defined (DPM32M03x) || defined (DPM32M036) || defined (DPM32M030) || defined (DPM32M015) 
#define IS_UART_PERIPH(x) (((x) == UART0) || \
                           ((x) == UART1))
#endif /* DPM32M03x || DPM32M036 || DPM32M030 || DPM32M015 */

#define IS_UART_BAUDRATE(x) (((x) > 0u) && ((x) < 7500001u))

#define IS_UART_DATALEN(x) (((x) == UART_DATA_LEN_6) || \
                            ((x) == UART_DATA_LEN_7) || \
                            ((x) == UART_DATA_LEN_8) || \
                            ((x) == UART_DATA_LEN_9))

#define IS_UART_STOPBITs(x) (((x) == UART_STOP_BITS_1) || \
                             ((x) == UART_STOP_BITS_2))

#define IS_UART_PARITY(x) (((x) == UART_PARITY_NO) || \
                           ((x) == UART_PARITY_EVEN) || \
                           ((x) == UART_PARITY_ODD))

#define IS_UART_MODE(x) (((x) == UART_MODE_RX) || \
                         ((x) == UART_MODE_TX) || \
                         ((x) == UART_MODE_RX_TX))



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

/* Initialization and Configuration functions. */
void                    UART_Init(UART_Type *UARTx, UART_InitTypeStruct *UART_InitType);
void                    UART_StructInit(UART_InitTypeStruct *UART_InitType);
void                    UART_Cmd(UART_Type* UARTx, FunctionalState NewState);

/* Data transfers functions. */
void                    UART_SendData(UART_Type* UARTx, uint16_t UART_Data);
uint16_t                UART_ReceiveData(UART_Type* UARTx);

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

/* LSB/MSB send first function. */
void                    UART_DataFirstConfig(UART_Type* UARTx, UART_FirstDataEnum UART_FirstData);

#if defined (DPM32M08x) || defined (DPM32M05x)
/* DMA transfers management functions. */
void                    UART_DMACmd(UART_Type* UARTx, UART_DMAReqEnum UART_DMAReq, FunctionalState NewState);
#endif  /* DPM32M08x || DPM32M05x */

/* Interrupts enable bit management functions. */
void                    UART_IntCmd(UART_Type* UARTx, uint16_t UART_IntType, FunctionalState NewState);
FunctionalState         UART_GetIntCmdStatus(UART_Type* UARTx, UART_IntTypeEnum UART_IntType);
FlagState               UART_GetIntFlagStatus(UART_Type* UARTx, UART_IntFlagEnum UART_IntFlag);
void                    UART_ClearIntFlag(UART_Type* UARTx, UART_IntFlagEnum UART_IntFlag);

#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#pragma clang diagnostic pop
#endif

#ifdef __cplusplus
}

#endif

#endif /* __DPM32M0XX_UART_H__ */
