/*!
 * @file        bmp561_uart.c
 *
 * @brief       This file provides all the UART firmware functions
 *
 * @version     V1.0.0
 *
 * @date        2025-01-01
 *
 * @attention
 *
 *  Copyright (C) 2025 Geehy Semiconductor
 *
 *  You may not use this file except in compliance with the
 *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
 *
 *  The program is only for reference, which is distributed in the hope
 *  that it will be useful and instructional for customers to develop
 *  their software. Unless required by applicable law or agreed to in
 *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
 *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
 *  and limitations under the License.
 */

#include "bmp561_uart.h"
#include "bmp561_sysctrl.h"

/** @addtogroup Peripherals_Library Standard Peripheral Library
  @{
*/

/** @addtogroup UART_Driver UART Driver
  @{
*/

/** @addtogroup UART_Functions Functions
  @{
*/

/*!
 * @brief     Resets the UART peripheral registers to their default reset values.
 *
 * @param     None
 *
 * @retval    None
 *
 */
void UART_Reset(void)
{
    SYSCTRL_Unlock();
    SYSCTRL_EnableAPBPeriphReset(SYSCTRL_APB_UART);
    SYSCTRL_DisableAPBPeriphReset(SYSCTRL_APB_UART);
    SYSCTRL_Lock();
}

/*!
 * @brief     Configures the UART peripheral according to the specified parameters in the uartConfig.
 *
 * @param     uartConfig: pointer to a UART_Config_T structure.
 *
 * @retval    None
 *
 */
void UART_Config(UART_Config_T* uartConfig)
{
    UART->BDR = uartConfig->baudrate;
    UART->CR_B.STOPBIT = (uint32_t)uartConfig->stopbit;
    UART->CR_B.PARITYE = uartConfig->parityen;
    UART->CR_B.PARITYSEL = (uint32_t)uartConfig->parity;
    UART->CR_B.TXSEQSEL = (uint32_t)uartConfig->sequence;
    UART->CR_B.RXE = uartConfig->rxen;
    UART->CR_B.TXE = uartConfig->txen;
}

/*!
 * @brief     Fills each UART_Config_T member with its default value.
 *
 * @param     uartConfig: pointer to a UART_Config_T structure which will be initialized.
 *
 * @retval    None
 *
 */
void UART_ConfigStructInit(UART_Config_T* uartConfig)
{
    uartConfig->baudrate = 0x23;
    uartConfig->stopbit = UART_STOPBIT_1B;
    uartConfig->parityen = DISABLE;
    uartConfig->parity = UART_PARITY_EVEN;
    uartConfig->sequence = UART_TXSEQ_LSB;
    uartConfig->rxen = DISABLE;
    uartConfig->txen = DISABLE;
}

/*!
 * @brief     Configures the UART baud rate divisor.
 *
 * @param     Baudrate: specifies baud rate divisor.
 *
 * @retval    None
 *
 * @note      BaudRate = (UART_PCLK)/bauddiv.
 *            The default value is UART_PCLK = 4MHz, bauddiv = 0x23, BaudRate = 115200bps.
 *
 */
void UART_ConfigBaudRateDiv(uint16_t bauddiv)
{
    UART->BDR = bauddiv;
}

/*!
 * @brief     Enables the UART transmit.
 *
 * @param     None
 *
 * @retval    None
 *
 */
void UART_EnableTransmit(void)
{
    UART->CR_B.TXE = BIT_SET;
}

/*!
 * @brief     Disables the UART transmit.
 *
 * @param     None
 *
 * @retval    None
 *
 */
void UART_DisableTransmit(void)
{
    UART->CR_B.TXE = BIT_RESET;
}

/*!
 * @brief     Enables the UART receive.
 *
 * @param     None
 *
 * @retval    None
 *
 */
void UART_EnableReceive(void)
{
    UART->CR_B.RXE = BIT_SET;
}

/*!
 * @brief     Disables the UART receive.
 *
 * @param     None
 *
 * @retval    None
 *
 */
void UART_DisableReceive(void)
{
    UART->CR_B.RXE = BIT_RESET;
}

/*!
 * @brief     Configures the UART stop bit.
 *
 * @param     bit: specifies UART stop bit.
 *                 This parameter can be one of the following values:
 *                 @arg UART_STOPBIT_1B: 1 bit stop bit
 *                 @arg UART_STOPBIT_2B: 2 bit stop bit
 *
 * @retval    None
 *
 */
void UART_ConfigStopBit(UART_STOPBIT_T bit)
{
    UART->CR_B.STOPBIT = bit;
}

/*!
 * @brief     Enables the UART parity.
 *
 * @param     None
 *
 * @retval    None
 *
 */
void UART_EnableParity(void)
{
    UART->CR_B.PARITYE = BIT_SET;
}

/*!
 * @brief     Disables the UART parity.
 *
 * @param     None
 *
 * @retval    None
 *
 */
void UART_DisableParity(void)
{
    UART->CR_B.PARITYE = BIT_RESET;
}

/*!
 * @brief     Configures the UART parity.
 *
 * @param     parity: specifies UART parity.
 *                    This parameter can be one of the following values:
 *                    @arg UART_PARITY_EVEN: Even verification
 *                    @arg UART_PARITY_ODD : Odd verification
 *
 * @retval    None
 *
 */
void UART_ConfigParity(UART_PARITY_T parity)
{
    UART->CR_B.PARITYSEL = parity;
}

/*!
 * @brief     Configures the UART transmit sequence.
 *
 * @param     sequence: specifies UART transmit sequence.
 *                    This parameter can be one of the following values:
 *                    @arg UART_TXSEQ_LSB: LSB order
 *                    @arg UART_TXSEQ_MSB: MSB order
 *
 * @retval    None
 *
 */
void UART_ConfigTransmitSequence(UART_TXSEQ_T sequence)
{
    UART->CR_B.TXSEQSEL = sequence;
}

/*!
 * @brief     Enables the UART auto baud rate.
 *
 * @param     None
 *
 * @retval    None
 *
 */
void UART_EnableAutoBaudRate(void)
{
    UART->CR_B.ABE = BIT_SET;
}

/*!
 * @brief     Disables the UART auto baud rate.
 *
 * @param     None
 *
 * @retval    None
 *
 */
void UART_DisableAutoBaudRate(void)
{
    UART->CR_B.ABE = BIT_RESET;
}

/*!
 * @brief     UART send one byte.
 *
 * @param     data: the 8 bit data to be transmitted.
 *
 * @retval    None
 *
 */
void UART_SendData(uint8_t data)
{
    UART->TDR = data;
}

/*!
 * @brief     UART receive one byte.
 *
 * @param     None
 *
 * @retval    The 8 bit received data.
 *
 */
uint8_t UART_RecieveData(void)
{
    return (uint8_t)UART->RDR;
}

/*!
 * @brief     Enables the specifies UART inetrrupt.
 *
 * @param     interrupt : specifies the UART inetrrupt flag.
 *                        This parameter can be one of the following value:
 *                        @arg UART_INT_TX       : Transmit interrupt
 *                        @arg UART_INT_RX       : Receive interrupt
 *                        @arg UART_INT_TXOE     : Transmit overflow error interrupt
 *                        @arg UART_INT_RXOE     : Receive overflow error interrupt
 *                        @arg UART_INT_PE       : Parity error interrupt
 *                        @arg UART_INT_FE       : Frame error interrupt
 *                        @arg UART_INT_TXBUFFU  : Transmit buffer full interrupt
 *                        @arg UART_INT_RXBUFFU  : Receive buffer full interrupt
 *                        @arg UART_INT_TXBUFEM  : Transmit buffer empty interrupt
 *                        @arg UART_INT_RXBUFEM  : Receive buffer empty interrupt
 *                        @arg UART_INT_TXBUFHAFU: Transmit buffer half full interrupt
 *                        @arg UART_INT_RXBUFHAFU: Receive buffer half full interrupt
 *                        @arg UART_INT_ABC      : Auto baud rate completed interrupt
 *                        @arg UART_INT_ABE      : Auto baud rate error interrupt
 *
 * @retval    None
 *
 */
void UART_EnableInterrupt(UART_INT_T interrupt)
{
    UART->IER |= interrupt;
}

/*!
 * @brief     Disables the specifies UART inetrrupt.
 *
 * @param     interrupt : specifies the UART inetrrupt flag.
 *                        This parameter can be one of the following value:
 *                        @arg UART_INT_TX       : Transmit interrupt
 *                        @arg UART_INT_RX       : Receive interrupt
 *                        @arg UART_INT_TXOE     : Transmit overflow error interrupt
 *                        @arg UART_INT_RXOE     : Receive overflow error interrupt
 *                        @arg UART_INT_PE       : Parity error interrupt
 *                        @arg UART_INT_FE       : Frame error interrupt
 *                        @arg UART_INT_TXBUFFU  : Transmit buffer full interrupt
 *                        @arg UART_INT_RXBUFFU  : Receive buffer full interrupt
 *                        @arg UART_INT_TXBUFEM  : Transmit buffer empty interrupt
 *                        @arg UART_INT_RXBUFEM  : Receive buffer empty interrupt
 *                        @arg UART_INT_TXBUFHAFU: Transmit buffer half full interrupt
 *                        @arg UART_INT_RXBUFHAFU: Receive buffer half full interrupt
 *                        @arg UART_INT_ABC      : Auto baud rate completed interrupt
 *                        @arg UART_INT_ABE      : Auto baud rate error interrupt
 *
 * @retval    None
 *
 */
void UART_DisableInterrupt(UART_INT_T interrupt)
{
    UART->IER &= ~interrupt;
}

/*!
 * @brief     Reads the specified UART flag.
 *
 * @param     flag: specifies the UART flag.
 *                  This parameter can be one of the following values:
 *                  @arg UART_FLAG_TXC      : Transmit completed flag
 *                  @arg UART_FLAG_RXC      : Receive completed flag
 *                  @arg UART_FLAG_TXOE     : Transmit overflow error flag
 *                  @arg UART_FLAG_RXOE     : Receive overflow error flag
 *                  @arg UART_FLAG_PE       : Parity error flag
 *                  @arg UART_FLAG_FE       : Frame error flag
 *                  @arg UART_FLAG_TXBUFFU  : Transmit buffer full flag
 *                  @arg UART_FLAG_RXBUFFU  : Receive buffer full flag
 *                  @arg UART_FLAG_TXBUFEM  : Transmit buffer empty flag
 *                  @arg UART_FLAG_RXBUFEM  : Receive buffer empty flag
 *                  @arg UART_FLAG_TXBUFHAFU: Transmit buffer half full flag
 *                  @arg UART_FLAG_RXBUFHAFU: Receive buffer half full flag
 *                  @arg UART_FLAG_TXBSY    : Transmit busy
 *                  @arg UART_FLAG_RXBSY    : Receive busy
 *                  @arg UART_FLAG_ABC      : Auto baud rate completed flag
 *                  @arg UART_FLAG_ABE      : Auto baud rate error flag
 *
 * @retval    The new state of flag(SET or RESET).
 *
 */
uint8_t UART_ReadFlag(UART_FLAG_T flag)
{
    uint8_t status = RESET;

    if((UART->SR & flag) != (uint32_t)RESET)
    {
        status = SET;
    }
    else
    {
        status = RESET;
    }
    return status;
}

/*!
 * @brief     Clears the specified UART flag.
 *
 * @param     flag: specifies the UART flag.
 *                  This parameter can be one of the following values:
 *                  @arg UART_CLEAR_TXC : Transmit completed flag
 *                  @arg UART_CLEAR_RXC : Receive completed flag
 *                  @arg UART_CLEAR_TXOE: Transmit overflow error flag
 *                  @arg UART_CLEAR_RXOE: Receive overflow error flag
 *                  @arg UART_CLEAR_PE  : Parity error flag
 *                  @arg UART_CLEAR_FE  : Frame error flag
 *                  @arg UART_CLEAR_ABC : Auto baud rate completed flag
 *                  @arg UART_CLEAR_ABE : Auto baud rate error flag
 *
 * @retval    None
 *
 */
void UART_ClearFlag(UART_CLEAR_T flag)
{
    UART->SCR |= flag;
}

/**@} end of group UART_Functions*/
/**@} end of group UART_Driver*/
/**@} end of group Peripherals_Library*/
