/*!
 * @file        bmp561_i2c.c
 *
 * @brief       This file provides all the I2C 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_i2c.h"

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

/** @addtogroup I2C_Driver I2C Driver
  @{
*/

/** @addtogroup I2C_Functions Functions
  @{
*/

/*!
 * @brief     Enables I2C.
 *
 * @param     None
 *
 * @retval    None
 *
 */
void I2C_Enable(void)
{
    I2C->CTRL_B.EN = BIT_SET;
}

/*!
 * @brief     Disables I2C.
 *
 * @param     None
 *
 * @retval    None
 *
 */
void I2C_Disable(void)
{
    I2C->CTRL_B.EN = BIT_RESET;
}

/*!
 * @brief     Clears I2C TXFIFO.
 *
 * @param     None
 *
 * @retval    None
 *
 */
void I2C_ClearTXFIFO(void)
{
    I2C->CTRL_B.FFC = BIT_SET;
}

/*!
 * @brief     Enables I2C slave ack broadcast.
 *
 * @param     None
 *
 * @retval    None
 *
 */
void I2C_EnableBroadcast(void)
{
    I2C->CTRL_B.GCEN = BIT_SET;
}

/*!
 * @brief     Disables I2C slave ack broadcast.
 *
 * @param     None
 *
 * @retval    None
 *
 */
void I2C_DisableBroadcast(void)
{
    I2C->CTRL_B.GCEN = BIT_RESET;
}

/*!
 * @brief     I2C send ACK.
 *
 * @param     None
 *
 * @retval    None
 *
 */
void I2C_SendACK(void)
{
    I2C->CTRL_B.ACK = BIT_SET;
}

/*!
 * @brief     I2C send NACK.
 *
 * @param     None
 *
 * @retval    None
 *
 */
void I2C_SendNACK(void)
{
    I2C->CTRL_B.ACK = BIT_RESET;
}

/*!
 * @brief     Enables I2C clock stretch.
 *
 * @param     None
 *
 * @retval    None
 *
 */
void I2C_EnableClockStretch(void)
{
    I2C->CTRL_B.NOSTR = BIT_SET;
}

/*!
 * @brief     Disables I2C clock stretch.
 *
 * @param     None
 *
 * @retval    None
 *
 */
void I2C_DisableClockStretch(void)
{
    I2C->CTRL_B.NOSTR = BIT_RESET;
}

/*!
 * @brief     Enables I2C STOP signal.
 *
 * @param     None
 *
 * @retval    None
 *
 */
void I2C_EnableStop(void)
{
    I2C->CTRL_B.STOP = BIT_SET;
}

/*!
 * @brief     Disables I2C STOP signal.
 *
 * @param     None
 *
 * @retval    None
 *
 */
void I2C_DisableStop(void)
{
    I2C->CTRL_B.STOP = BIT_RESET;
}

/*!
 * @brief     Enables I2C START signal.
 *
 * @param     None
 *
 * @retval    None
 *
 */
void I2C_EnableStart(void)
{
    I2C->CTRL_B.START = BIT_SET;
}

/*!
 * @brief     Disables I2C START signal.
 *
 * @param     None
 *
 * @retval    None
 *
 */
void I2C_DisableStart(void)
{
    I2C->CTRL_B.START = BIT_RESET;
}

/*!
 * @brief     Enables I2C auto end.
 *
 * @param     None
 *
 * @retval    None
 *
 * @note      Only vaild in master mode while sending data.
 *
 */
void I2C_EnableAutoEnd(void)
{
    I2C->CTRL_B.AUTOEND = BIT_SET;
}

/*!
 * @brief     Disables I2C auto end.
 *
 * @param     None
 *
 * @retval    None
 *
 * @note      Only vaild in master mode while sending data.
 *
 */
void I2C_DisableAutoEnd(void)
{
    I2C->CTRL_B.AUTOEND = BIT_RESET;
}

/*!
 * @brief     Enables I2C timeout.
 *
 * @param     None
 *
 * @retval    None
 *
 */
void I2C_EnableTimeOut(void)
{
    I2C->CTRL_B.TOEN = BIT_SET;
}

/*!
 * @brief     Disables I2C timeout.
 *
 * @param     None
 *
 * @retval    None
 *
 */
void I2C_DisableTimeOut(void)
{
    I2C->CTRL_B.TOEN = BIT_RESET;
}

/*!
 * @brief     Configures I2C master mode filter width.
 *
 * @param     filter: specifies the filter width.
 *                    This parameter can be one of the following value:
 *                    @arg I2C_FILTER_BYPASS: bypass
 *                    @arg I2C_FILTER_1PCLK : 1 pclk
 *                    @arg I2C_FILTER_2PCLK : 2 pclk
 *                    @arg I2C_FILTER_3PCLK : 3 pclk
 *
 * @retval    None
 *
 */
void I2C_ConfigFilter(I2C_FILTER_T filter)
{
    I2C->CTRL_B.FILT = filter;
}

/*!
 * @brief     Configures I2C slave address.
 *
 * @param     address: I2C slave address.
 *                     This parameter can be configured from 0 to 0x7F.
 *
 * @retval    None
 *
 * @note      Default address is 0x55.
 *
 */
void I2C_ConfigSlaveAddr(uint8_t address)
{
    I2C->SADDR = (uint32_t)address;
}

/*!
 * @brief     Configures I2C master address.
 *
 * @param     address: I2C master address.
 *                     This parameter can be configured from 0 to 0x7F.
 *
 * @retval    None
 *
 */
void I2C_ConfigMasterAddr(uint8_t address)
{
    I2C->MADDR_B.ADDR = (uint32_t)address;
}

/*!
 * @brief     Configures I2C master mode read or write bit.
 *
 * @param     bit: specifies the I2C master mode read("1") or write("0").
 *                 This parameter can be 0x01(read) or 0x00(write).
 *
 * @retval    None
 *
 */
void I2C_ConfigMasterRWBit(uint8_t bit)
{
    I2C->MADDR_B.RD_WR = (uint32_t)bit;
}

/*!
 * @brief     Configures I2C CLK high and low period (frequency).
 *
 * @param     highPeriod: specifies high level period.
 *                        This parameter can be configured from 0 to 0xFF.
 *
 * @param     lowPeriod: specifies low level period.
 *                       This parameter can be configured from 0 to 0xFF.
 *
 * @retval    None
 *
 * @note      CLK = pclk/((SCLH + 1) + CTRL.FILT + 2 + (SCLL + 1) + CTRL.FILT + 2)
 *
 */
void I2C_ConfigClockPeriod(uint8_t highPeriod, uint8_t lowPeriod)
{
    I2C->SCLC_B.SCLL = (uint32_t)lowPeriod;
    I2C->SCLC_B.SCLH = (uint32_t)highPeriod;
}

/*!
 * @brief     Configures I2C timeout time.
 *
 * @param     time: specifies timeout time.
 *                  This parameter can be configured from 0 to 0x0FFFFFF.
 *
 * @retval    None
 *
 */
void I2C_ConfigTimeOut(uint32_t time)
{
    I2C->TIMEOUT = time;
}

/*!
 * @brief     Enables I2C interrupt.
 *
 * @param     interrupt: specifies the I2C interrupt.
 *                       This parameter can be one of the following values:
 *                       @arg I2C_INT_STA   : Receive START signal interrupt
 *                       @arg I2C_INT_STOP  : Receive STOP signal interrupt
 *                       @arg I2C_INT_ADR   : I2C address match or already send I2C address interrupt
 *                       @arg I2C_INT_GCS   : Recieve broadcast interrupt
 *                       @arg I2C_INT_ARBL  : Lose arbitration interrupt
 *                       @arg I2C_INT_NACK  : Recieve NACK interrupt
 *                       @arg I2C_INT_TOF   : Time out interrupt
 *                       @arg I2C_INT_BUSERR: Bus error(unexpected start or stop signal occurs)
 *                       @arg I2C_INT_OVR   : Overwrite or overread interrupt
 *                       @arg I2C_INT_RXFE  : RX FIFO empty interrupt
 *                       @arg I2C_INT_RXFH  : RX FIFO half empty interrupt
 *                       @arg I2C_INT_RXFF  : RX FIFO full interrupt
 *                       @arg I2C_INT_TXFE  : TX FIFO empty interrupt
 *                       @arg I2C_INT_TXFH  : TX FIFO half empty interrupt
 *                       @arg I2C_INT_TXFF  : TX FIFO full interrupt
 *
 * @retval    None
 *
 */
void I2C_EnableInterrupt(I2C_INT_T interrupt)
{
    I2C->IEN |= interrupt;
}

/*!
 * @brief     Disables I2C interrupt.
 *
 * @param     interrupt: specifies the I2C interrupt.
 *                       This parameter can be one of the following values:
 *                       @arg I2C_INT_STA   : Receive START signal interrupt
 *                       @arg I2C_INT_STOP  : Receive STOP signal interrupt
 *                       @arg I2C_INT_ADR   : I2C address match or already send I2C address interrupt
 *                       @arg I2C_INT_GCS   : Recieve broadcast interrupt
 *                       @arg I2C_INT_ARBL  : Lose arbitration interrupt
 *                       @arg I2C_INT_NACK  : Recieve NACK interrupt
 *                       @arg I2C_INT_TOF   : Time out interrupt
 *                       @arg I2C_INT_BUSERR: Bus error(unexpected start or stop signal occurs)
 *                       @arg I2C_INT_OVR   : overwrite or overread interrupt
 *                       @arg I2C_INT_RXFE  : RX FIFO empty interrupt
 *                       @arg I2C_INT_RXFH  : RX FIFO half empty interrupt
 *                       @arg I2C_INT_RXFF  : RX FIFO full interrupt
 *                       @arg I2C_INT_TXFE  : TX FIFO empty interrupt
 *                       @arg I2C_INT_TXFH  : TX FIFO half empty interrupt
 *                       @arg I2C_INT_TXFF  : TX FIFO full interrupt
 *
 * @retval    None
 *
 */
void I2C_DisableInterrupt(I2C_INT_T interrupt)
{
    I2C->IEN &= ~interrupt;
}

/*!
 * @brief     Reads the specified I2C flag.
 *
 * @param     flag: specifies the I2C flag.
 *                  This parameter can be one of the following values:
 *                  @arg I2C_FLAG_STA   : Master mode already sent START signal or slave mode recieved START signal flag
 *                  @arg I2C_FLAG_STOP  : Slave mode recieved STOP signal flag
 *                  @arg I2C_FLAG_ADR   : Master mode already sent address or slave mode address match flag
 *                  @arg I2C_FLAG_GCS   : Recieve broadcast signal flag
 *                  @arg I2C_FLAG_ARBL  : Lose arbitration flag
 *                  @arg I2C_FLAG_NACK  : Recieve NACK flag
 *                  @arg I2C_FLAG_TOF   : Timeout flag
 *                  @arg I2C_FLAG_BUSERR: Bus error(unexpected start or stop signal occurs) flag
 *                  @arg I2C_FLAG_OVR   : Overwrite or overread flag
 *                  @arg I2C_FLAG_RXFE  : RX FIFO empty flag
 *                  @arg I2C_FLAG_RXFH  : RX FIFO half full flag
 *                  @arg I2C_FLAG_RXFF  : RX FIFO full flag
 *                  @arg I2C_FLAG_TXFE  : TX FIFO empty flag
 *                  @arg I2C_FLAG_TXFH  : TX FIFO half full flag
 *                  @arg I2C_FLAG_TXFF  : TX FIFO full flag
 *                  @arg I2C_FLAG_MS    : Mode flag, master mode "1" / slave mode "0"
 *                  @arg I2C_FLAG_RD_WR : Read/Write flag, read "1" / write "0"
 *                  @arg I2C_FLAG_BUSY  : Bus busy flag
 *
 * @retval    The new state of flag(SET or RESET).
 *
 */
uint8_t I2C_ReadFlag(I2C_FLAG_T flag)
{
    uint8_t status = RESET;

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

/*!
 * @brief     Clears the specified I2C flag.
 *
 * @param     flag: specifies the I2C flag.
 *                  This parameter can be one of the following values:
 *                  @arg I2C_FLAG_STA   : Master mode already sent START signal or slave mode recieved START signal flag
 *                  @arg I2C_FLAG_STOP  : Slave mode recieved STOP signal flag
 *                  @arg I2C_FLAG_ADR   : Master mode already sent address or slave mode address match flag
 *                  @arg I2C_FLAG_GCS   : Recieve broadcast signal flag
 *                  @arg I2C_FLAG_ARBL  : Lose arbitration flag
 *                  @arg I2C_FLAG_NACK  : Recieve NACK flag
 *                  @arg I2C_FLAG_TOF   : Timeout flag
 *                  @arg I2C_FLAG_BUSERR: Bus error(unexpected start or stop signal occurs) flag
 *                  @arg I2C_FLAG_OVR   : Overwrite or overread flag
 *
 * @retval    The new state of flag(SET or RESET).
 *
 */
void I2C_ClearFlag(I2C_FLAG_T flag)
{
    I2C->SCR |= flag;
}

/*!
 * @brief     I2C read out one data from RX FIFO.
 *
 * @param     None
 *
 * @retval    The data value.
 *
 */
uint8_t I2C_ReadData(void)
{
    return (uint8_t)(I2C->RXDATA);
}

/*!
 * @brief     I2C write one data to TX FIFO.
 *
 * @param     Data: the send data value.
 *
 * @retval    None
 *
 */
void I2C_SendData(uint8_t data)
{
    I2C->TXDATA = (uint32_t)data;
}

/**@} end of group I2C_Functions*/
/**@} end of group I2C_Driver*/
/**@} end of group Peripherals_Library*/
