/**
*     Copyright (c) 2022, Nations Technologies Inc.
* 
*     All rights reserved.
*
*     This software is the exclusive property of Nations Technologies Inc. (Hereinafter 
* referred to as NATIONS). This software, and the product of NATIONS described herein 
* (Hereinafter referred to as the Product) are owned by NATIONS under the laws and treaties
* of the People's Republic of China and other applicable jurisdictions worldwide.
*
*     NATIONS does not grant any license under its patents, copyrights, trademarks, or other 
* intellectual property rights. Names and brands of third party may be mentioned or referred 
* thereto (if any) for identification purposes only.
*
*     NATIONS reserves the right to make changes, corrections, enhancements, modifications, and 
* improvements to this software at any time without notice. Please contact NATIONS and obtain 
* the latest version of this software before placing orders.

*     Although NATIONS has attempted to provide accurate and reliable information, NATIONS assumes 
* no responsibility for the accuracy and reliability of this software.
* 
*     It is the responsibility of the user of this software to properly design, program, and test 
* the functionality and safety of any application made of this information and any resulting product. 
* In no event shall NATIONS be liable for any direct, indirect, incidental, special,exemplary, or 
* consequential damages arising in any way out of the use of this software or the Product.
*
*     NATIONS Products are neither intended nor warranted for usage in systems or equipment, any
* malfunction or failure of which may cause loss of human life, bodily injury or severe property 
* damage. Such applications are deemed, "Insecure Usage".
*
*     All Insecure Usage shall be made at user's risk. User shall indemnify NATIONS and hold NATIONS 
* harmless from and against all claims, costs, damages, and other liabilities, arising from or related 
* to any customer's Insecure Usage.

*     Any express or implied warranty with regard to this software or the Product, including,but not 
* limited to, the warranties of merchantability, fitness for a particular purpose and non-infringement
* are disclaimed to the fullest extent permitted by law.

*     Unless otherwise explicitly permitted by NATIONS, anyone may not duplicate, modify, transcribe
* or otherwise distribute this software for any purposes, in whole or in part.
*
*     NATIONS products and technologies shall not be used for or incorporated into any products or systems
* whose manufacture, use, or sale is prohibited under any applicable domestic or foreign laws or regulations. 
* User shall comply with any applicable export control laws and regulations promulgated and administered by 
* the governments of any countries asserting jurisdiction over the parties or transactions.
**/

/**
*\*\file n32g003_i2c.c
*\*\author Nations
*\*\version v1.0.0
*\*\copyright Copyright (c) 2022, Nations Technologies Inc. All rights reserved.
**/
#include "n32g003_rcc.h"
#include "n32g003_i2c.h"


/**
*\*\name    I2C_Reset.
*\*\fun     Reset the I2Cx registers.
*\*\param   I2Cx :
*\*\          - I2C
*\*\return  none
**/
void I2C_Reset(I2C_Module* I2Cx)
{
       /* I2C Reset */
        RCC_Peripheral_Reset(RCC_RST_I2CRST);
}

/**
*\*\name    I2C_Initializes.
*\*\fun     Initializes the I2Cx peripheral according to the specified
*\*\        parameters in the I2C_InitParam
*\*\param   I2Cx :
*\*\          - I2C
*\*\param   I2C_InitParam :
*\*\          - ClkSpeed(common speed:100000(100KHz) - 400000(400KHz) - 1000000(1MHz)):
*\*\            - between 1 to 1000000
*\*\          - DutyCycle(If the ClkSpeed does not exceed 100KHz,duty is fixed at 1:1,
*\*\                      otherwise it can be configured as 2:1 or 16:9):
*\*\            - I2C_SMDUTYCYCLE_1
*\*\            - I2C_FMDUTYCYCLE_16_9
*\*\            - I2C_FMDUTYCYCLE_2
*\*\          - OwnAddr1:
*\*\            - between 0 to 0x3FF
*\*\          - AckEnable:
*\*\            - I2C_ACKEN
*\*\            - I2C_ACKDIS
*\*\          - AddrMode:
*\*\            - I2C_ADDR_MODE_7BIT
*\*\            - I2C_ADDR_MODE_10BIT
*\*\return  none
**/
void I2C_Initializes(I2C_Module* I2Cx, I2C_InitType* I2C_InitParam)
{
    I2C_Clock_Speed_Config(I2Cx, I2C_InitParam->ClkSpeed, I2C_InitParam->DutyCycle);  
    I2C_Acknowledgement_Config(I2Cx, I2C_InitParam->AckEnable);
    I2C_Addressing_Mode_Config(I2Cx, I2C_InitParam->AddrMode);
    I2C_Own_Addr1_Config(I2Cx, I2C_InitParam->OwnAddr1);
}

/**
*\*\name    I2C_Clock_Speed_Config.
*\*\fun     Initializes the clock speed.
*\*\param   I2Cx :
*\*\          - I2C
*\*\param   clk_speed
*\*\          - between 1 to 1000000
*\*\param   duty_cycle:
*\*\          - I2C_SMDUTYCYCLE_1
*\*\          - I2C_FMDUTYCYCLE_16_9
*\*\          - I2C_FMDUTYCYCLE_2
*\*\return  none
**/
void I2C_Clock_Speed_Config(I2C_Module* I2Cx, uint32_t clk_speed, uint16_t duty_cycle)
{
    uint16_t temp_value = 0, freq_value = 0, speed_value = 0x04;
    uint32_t pclk_value  = 8000000, trise_value = 0;
    RCC_ClocksType rcc_clocks;

	  /* Get pclk frequency value */
    RCC_Clocks_Frequencies_Value_Get( &rcc_clocks );
    /* Get the I2Cx CTRL2 value */
    temp_value = I2Cx->CTRL2;
    /* Clear frequency FREQ[5:0] bits */
    temp_value &= I2C_CLKFREQ_RESET;
		/* Get APB1 frequency value */
    pclk_value = rcc_clocks.PclkFreq;
    /* Set frequency bits depending on pclk_value value */
    freq_value = ( uint16_t )( pclk_value / 1000000 );
	if (freq_value > APB_FREQ_MAX_VALUE) 
    {
        freq_value = APB_FREQ_MAX_VALUE;
    }
    temp_value |= freq_value;
    /* Write to I2Cx CTRL2 */
    I2Cx->CTRL2 = temp_value;
   
    /** I2Cx CLKCTRL config **/
    /* Disable the selected I2C peripheral to configure TMRISE */
    I2Cx->CTRL1 &= I2C_EN_RESET;  
    /* Get the I2Cx TMRISE value */
    trise_value = I2Cx->TMRISE;
    /* Clear TMRISE[5:0] bits */
    trise_value &= (~I2C_TMRISE_MASK);
		/* Reset temp_value */
    /* Clear CLKCTRL:FSMODE, DUTY and CLKCTRL[11:0] bits */
    temp_value = 0;

		 /*If the ClkSpeed does not exceed 100KHz, mode(FSMODE[bit15]) is standard, duty is fixed at 1:1,ignore
		 DUTY[bit14] */
    /* Configure speed in standard mode */

    if ( clk_speed <= CLK_SPEED_100K )
    {
        /* Standard mode speed calculate */
        speed_value = ( uint16_t )( pclk_value / (clk_speed * 2));
        /* Test if CLKCTRL value is under 0x4*/

        if ( speed_value < SM_CLKCTRL_LOW_LIMIT )
        {
            /* Set minimum allowed value */
            speed_value = SM_CLKCTRL_LOW_LIMIT;
        }

        /* Set speed value for standard mode */
        temp_value |= speed_value;

        /* Set Maximum Rise Time for standard mode */
        trise_value |= ((freq_value + 1) & I2C_TMRISE_MASK);         
    }
		/*If ClkSpeed exceeds 100KHz, mode(FSMODE[bit15]) is fast, duty(DUTY[bit14]) can be
		configured as 2:1 or 16:9 */
    /* Configure speed in fast mode */
    else if ( clk_speed <= CLK_SPEED_1M )
    {
        if ( duty_cycle != I2C_FMDUTYCYCLE_16_9 )
        {
            /* Fast mode speed calculate: Tlow/Thigh = 2 */
            speed_value = ( uint16_t )( pclk_value / ( clk_speed * 3 ) );
        }
        else /*I2C_InitStruct->DutyCycle == DutyCycle_16_9*/
        {
            /* Fast mode speed calculate: Tlow/Thigh = 16/9 */
            speed_value = ( uint16_t )( pclk_value / ( clk_speed * 25 ) );
            /* Set DUTY bit */
            speed_value |= I2C_FMDUTYCYCLE_16_9;
        }

        /* Test if CLKCTRL value is under 0x1*/
        if (( speed_value & I2C_CLKCTRL_SET ) < FM_CLKCTRL_LOW_LIMIT )
        {
            /* Set minimum allowed value */
            speed_value |= ( uint16_t )FM_CLKCTRL_LOW_LIMIT;
        }

        /* Set speed value and set F/S bit for fast mode */
        temp_value |= ( uint16_t )( speed_value | I2C_FSMODE_SET );

        /* Set Maximum Rise Time for fast mode */
        /* if APB frequency is 48MHz,period = 1/48*1000ns,so trise_value = period/TRISE+1=48*TRISE/1000+1,See the manual for details*/
        if(clk_speed <= CLK_SPEED_400K)   /* 100KHz~400KHz */ 
        {
            trise_value |= (((uint16_t)(((freq_value * (uint16_t)FM_TRISE_400K) / (uint16_t)1000) + (uint16_t)1)) & I2C_TMRISE_MASK);
        }
        else  /* 400KHz~1MHz */ 
        {
            trise_value |= (((uint16_t)(((freq_value * (uint16_t)FM_TRISE_1M) / (uint16_t)1000) + (uint16_t)1)) & I2C_TMRISE_MASK);
        }
    }
		/* Write to I2Cx TMRISE */
    I2Cx->TMRISE = trise_value;

    /* Write to I2Cx CLKCTRL */
    I2Cx->CLKCTRL = temp_value;

    /* Enable the selected I2C peripheral */
    I2Cx->CTRL1 |= I2C_EN_SET;

}

/**
*\*\name    I2C_Acknowledgement_Config.
*\*\fun     Initializes the acknowledgement.
*\*\param   I2Cx :
*\*\          - I2C
*\*\param   ack
*\*\          - I2C_ACKEN
*\*\          - I2C_ACKDIS
*\*\return  none
**/
void I2C_Acknowledgement_Config(I2C_Module* I2Cx, uint16_t ack)
{
    uint16_t temp_value = 0;

    /* Get the I2Cx CTRL1 value */
    temp_value = I2Cx->CTRL1;
    /* Clear ACKEN bits */
    temp_value &= I2C_ACKEN_CLR_MASK;
    /* Set ACKEN bits according to ack value */
    temp_value |= (uint16_t)((uint32_t)ack);
    /* Set I2Cx CTRL1 */
    I2Cx->CTRL1 = temp_value;
}

/**
*\*\name    I2C_Addressing_Mode_Config.
*\*\fun     Initializes addressing mode.
*\*\param   I2Cx :
*\*\          - I2C
*\*\param   mode
*\*\          - I2C_ADDR_MODE_7BIT
*\*\          - I2C_ADDR_MODE_10BIT
*\*\return  none
**/
void I2C_Addressing_Mode_Config(I2C_Module* I2Cx, uint16_t mode)
{
    uint16_t temp_value = 0;

    /* Get the I2Cx OADDR1 value */
    temp_value = I2Cx->OADDR1;
    /* Clear ADDRMODE bits */
    temp_value &= I2C_ADDRMODE_CLR_MASK;
    /* Set ACKEN bits according to mode value */
    temp_value |= mode;
    /* Set I2Cx OADDR1 */
    I2Cx->OADDR1 = temp_value;
}

/**
*\*\name    I2C_Own_Addr1_Config.
*\*\fun     Initializes the own address.
*\*\param   I2Cx :
*\*\          - I2C
*\*\param   addr1    between 0 to 0x3FF
*\*\return  none
**/
void I2C_Own_Addr1_Config(I2C_Module* I2Cx, uint16_t addr1)
{
    uint16_t temp_value = 0;

    /* Get the I2Cx OADDR1 value */
    temp_value = I2Cx->OADDR1;
    /* Clear ADDRMODE bits */
    temp_value &= I2C_OADDR_CLR_MASK;
    /* Set ACKEN bits according to mode value */
    temp_value |= addr1;
    /* Set I2Cx OADDR1 */
    I2Cx->OADDR1 = temp_value;

}

/**
*\*\name    I2C_Initializes_Structure.
*\*\fun     Fills each I2C_InitStruct member with its default value.
*\*\param   I2C_InitStruct :
*\*\          - ClkSpeed
*\*\          - BusMode -none
*\*\          - DutyCycle
*\*\          - OwnAddr1
*\*\          - AckEnable
*\*\          - AddrMode
*\*\return  none
**/
void I2C_Initializes_Structure(I2C_InitType* I2C_InitStruct)
{
    /*---------------- Reset I2C init structure parameters values ----------------*/
    /* initialize the ClkSpeed member */
    I2C_InitStruct->ClkSpeed = 5000;
    /* Initialize the DutyCycle member */
    I2C_InitStruct->DutyCycle = I2C_FMDUTYCYCLE_2;
    /* Initialize the OwnAddr1 member */
    I2C_InitStruct->OwnAddr1 = 0;
    /* Initialize the AckEnable member */
    I2C_InitStruct->AckEnable = I2C_ACKDIS;
    /* Initialize the AddrMode member */
    I2C_InitStruct->AddrMode = I2C_ADDR_MODE_7BIT;
}

/**
*\*\name    I2C_ON.
*\*\fun     I2Cx turn ON.
*\*\param   I2Cx :
*\*\          - I2C
*\*\return  none
**/
void I2C_ON(I2C_Module* I2Cx)
{
    /* Enable the selected I2C peripheral */
    I2Cx->CTRL1 |= I2C_EN_SET;
}

/**
*\*\name    I2C_OFF.
*\*\fun     I2Cx turn OFF.
*\*\param   I2Cx :
*\*\          - I2C
*\*\return  none
**/
void I2C_OFF(I2C_Module* I2Cx)
{
    /* Disable the selected I2C peripheral */
    I2Cx->CTRL1 &= I2C_EN_RESET;
}

/**
*\*\name    I2C_Generate_Start_Enable.
*\*\fun     Enable Generate a START condition.
*\*\param   I2Cx :
*\*\          - I2C
*\*\return  none
**/
void I2C_Generate_Start_Enable(I2C_Module* I2Cx)
{
    /* Generate a START condition */
    I2Cx->CTRL1 |= I2C_START_SET;
}

/**
*\*\name    I2C_Generate_Start_Disable.
*\*\fun     Disable the START condition generation.
*\*\param   I2Cx :
*\*\          - I2C
*\*\return  none
**/
void I2C_Generate_Start_Disable(I2C_Module* I2Cx)
{
    /* Disable the START condition generation */
    I2Cx->CTRL1 &= I2C_START_RESET;
}

/**
*\*\name    I2C_Generate_Stop_Enable.
*\*\fun     Enable Generate a STOP condition.
*\*\param   I2Cx :
*\*\          - I2C
*\*\return  none
**/
void I2C_Generate_Stop_Enable(I2C_Module* I2Cx)
{
    /* Generate a STOP condition */
    I2Cx->CTRL1 |= I2C_STOP_SET;
}

/**
*\*\name    I2C_Generate_Stop_Disable.
*\*\fun     Disable the STOP condition generation.
*\*\param   I2Cx :
*\*\          - I2C
*\*\return  none
**/
void I2C_Generate_Stop_Disable(I2C_Module* I2Cx)
{
    /* Disable the STOP condition generation */
    I2Cx->CTRL1 &= I2C_STOP_RESET;
}

/**
*\*\name    I2C_Acknowledg_Enable.
*\*\fun     Enable the acknowledgement.
*\*\param   I2Cx :
*\*\          - I2C
*\*\return  none
**/
void I2C_Acknowledg_Enable(I2C_Module* I2Cx)
{
   /* Enable the acknowledgement */
   I2Cx->CTRL1 |= I2C_ACK_SET;
}

/**
*\*\name    I2C_Acknowledg_Disable.
*\*\fun     Disable the acknowledgement.
*\*\param   I2Cx :
*\*\          - I2C
*\*\return  none
**/
void I2C_Acknowledg_Disable(I2C_Module* I2Cx)
{
   /* Disable the acknowledgement */
   I2Cx->CTRL1 &= I2C_ACK_RESET;
}

/**
*\*\name    I2C_Own_Addr2_Set.
*\*\fun     Set the specified I2C own address2.
*\*\param   I2Cx :
*\*\          - I2C
*\*\param   address
*\*\          - 7bit I2C own address2
*\*\return  none
**/
void I2C_Own_Addr2_Set(I2C_Module* I2Cx, uint8_t address)
{
    uint16_t temp_value = 0;

    /* Get the old register value */
    temp_value = I2Cx->OADDR2;

    /* Reset I2Cx Own address2 bit [7:1] */
    temp_value &= I2C_ADDR2_RESET;

    /* Set I2Cx Own address2 */
    temp_value |= (uint16_t)((uint16_t)address & I2C_ADDR2_SET);

    /* Store the new register value */
    I2Cx->OADDR2 = temp_value;
}

/**
*\*\name    I2C_Dual_Addr_Enable.
*\*\fun     Enables the specified I2C dual addressing mode.
*\*\param   I2Cx :
*\*\          - I2C
*\*\return  none
**/
void I2C_Dual_Addr_Enable(I2C_Module* I2Cx)
{
    /* Enable dual addressing mode */
    I2Cx->OADDR2 |= I2C_DUALEN_SET;
}

/**
*\*\name    I2C_Dual_Addr_Disable.
*\*\fun     Disable the specified I2C dual addressing mode.
*\*\param   I2Cx :
*\*\          - I2C
*\*\return  none
**/
void I2C_Dual_Addr_Disable(I2C_Module* I2Cx)
{
    /* Disable dual addressing mode */
    I2Cx->OADDR2 &= I2C_DUALEN_RESET;
}

/**
*\*\name    I2C_General_Call_Enable.
*\*\fun     Enables the specified I2C general call feature.
*\*\param   I2Cx :
*\*\          - I2C
*\*\return  none
**/
void I2C_General_Call_Enable(I2C_Module* I2Cx)
{
    /* Enable generall call */
    I2Cx->CTRL1 |= I2C_GCEN_SET;
}

/**
*\*\name    I2C_General_Call_Disable.
*\*\fun     Disable the specified I2C general call feature.
*\*\param   I2Cx :
*\*\          - I2C
*\*\return  none
**/
void I2C_General_Call_Disable(I2C_Module* I2Cx)
{
    /* Disable generall call */
    I2Cx->CTRL1 &= I2C_GCEN_RESET;
}

/**
*\*\name    I2C_Interrupts_Enable.
*\*\fun     Enables the specified I2C interrupts.
*\*\param   I2Cx :
*\*\          - I2C
*\*\param   I2C_IT :
*\*\          - I2C_INT_BUF Buffer interrupt mask
*\*\          - I2C_INT_EVENT Event interrupt mask
*\*\          - I2C_INT_ERR Error interrupt mask
*\*\return  none
**/
void I2C_Interrupts_Enable(I2C_Module* I2Cx, uint16_t I2C_IT)
{
    /* Enable the selected I2C interrupts */
    I2Cx->CTRL2 |= I2C_IT;
}

/**
*\*\name    I2C_Interrupts_Disable.
*\*\fun     Disables the specified I2C interrupts.
*\*\param   I2Cx :
*\*\          - I2C
*\*\param   I2C_IT :
*\*\          - I2C_INT_BUF Buffer interrupt mask
*\*\          - I2C_INT_EVENT Event interrupt mask
*\*\          - I2C_INT_ERR Error interrupt mask
*\*\return  none
**/
void I2C_Interrupts_Disable(I2C_Module* I2Cx, uint16_t I2C_IT)
{
    /* Disable the selected I2C interrupts */
    I2Cx->CTRL2 &= (uint16_t)~I2C_IT;
}

/**
*\*\name    I2C_Data_Send.
*\*\fun     Sends a data byte through the I2Cx peripheral.
*\*\param   I2Cx :
*\*\          - I2C
*\*\param   data
*\*\return  none
**/
void I2C_Data_Send(I2C_Module* I2Cx, uint8_t data)
{
    /* Write in the DAT register the data to be sent */
    I2Cx->DAT = data;
}

/**
*\*\name    I2C_Data_Recv.
*\*\fun     Returns the most recent received data by the I2Cx peripheral.
*\*\param   I2Cx :
*\*\          - I2C
*\*\return  The value of the received data
**/
uint8_t I2C_Data_Recv(I2C_Module* I2Cx)
{
    /* Return the data in the DAT register */
    return (uint8_t)I2Cx->DAT;
}

/**
*\*\name    I2C_7bit_Addr_Send.
*\*\fun     Transmits the address byte to select the slave device.
*\*\param   I2Cx :
*\*\          - I2C
*\*\param   address
*\*\param   mode :
*\*\          - I2C_DIRECTION_SEND Transmitter mode
*\*\          - I2C_DIRECTION_RECV Receiver mode
*\*\return  none
**/
void I2C_7bit_Addr_Send(I2C_Module* I2Cx, uint8_t address, uint8_t mode)
{
    /* Test on the direction to set/reset the read/write bit */
    if (mode == I2C_DIRECTION_RECV)
    {
        /* Set the address bit0 for read */
        address |= I2C_ADDR0_SET;
    }
    else
    {
        /* Reset the address bit0 for write */
        address &= I2C_ADDR0_RESET;
    }
    /* Send the address */
    I2Cx->DAT = address;
}

/**
*\*\name    I2C_Register_Value_Get.
*\*\fun     Reads the specified I2C register and returns its value.
*\*\param   I2Cx :
*\*\          - I2C
*\*\param   I2C_Register :
*\*\          - I2C_REG_CTRL1 CTRL1 register
*\*\          - I2C_REG_CTRL2 CTRL2 register
*\*\          - I2C_REG_OADDR1 OADDR1 register
*\*\          - I2C_REG_OADDR2 OADDR2 register
*\*\          - I2C_REG_DAT DAT register
*\*\          - I2C_REG_STS1 STS1 register
*\*\          - I2C_REG_STS2 STS2 register
*\*\          - I2C_REG_CLKCTRL CLKCTRL register
*\*\          - I2C_REG_TMRISE TMRISE register
*\*\          - I2C_REG_GFLTRCTRL GFLTRCTRL register
*\*\          - I2C_REG_BYTENUM BYTENUM register
*\*\return  none
**/
uint16_t I2C_Register_Value_Get(I2C_Module* I2Cx, uint8_t I2C_Register)
{
    __IO uint32_t temp_value = 0;
    temp_value = (uint32_t)I2Cx;
    temp_value += I2C_Register;

    /* Return the selected register value */
    return (*(__IO uint16_t*)temp_value);
}

/**
*\*\name    I2C_Software_Reset_Enable.
*\*\fun     Enables the specified I2C software reset.
*\*\param   I2Cx :
*\*\          - I2C
*\*\return  none
**/
void I2C_Software_Reset_Enable(I2C_Module* I2Cx)
{
    /* Peripheral under reset */
    I2Cx->CTRL1 |= I2C_SWRESET_SET;
}

/**
*\*\name    I2C_Software_Reset_Disable.
*\*\fun     Disables the specified I2C software reset.
*\*\param   I2Cx :
*\*\          - I2C
*\*\return  none
**/
void I2C_Software_Reset_Disable(I2C_Module* I2Cx)
{
    /* Peripheral not under reset */
    I2Cx->CTRL1 &= I2C_SWRESET_RESET;
}

/**
*\*\name    I2C_NACK_Position_Set.
*\*\fun     Selects the specified I2C NACK position in master receiver mode.
*\*\        This function is useful in I2C Master Receiver mode when the number
*\*\        of data to be received is equal to 2. In this case, this function
*\*\        should be called (with parameter I2C_NACK_POS_NEXT) before data
*\*\        reception starts,as described in the 2-byte reception procedure
*\*\        recommended in Reference Manual in Section: Master receiver.
*\*\param   I2Cx :
*\*\          - I2C
*\*\param   position :
*\*\          - I2C_NACK_POS_NEXT Indicates that the next byte will be the last received byte.
*\*\          - I2C_NACK_POS_CURRENT Indicates that current byte is the last received byte.
*\*\note    This function configures the same bit (POS) as I2C_PEC_Position_Set()
*\*\        but is intended to be used in I2C mode while I2C_PEC_Position_Set()
*\*\        is intended to used in SMBUS mode.
*\*\return  none
**/
void I2C_NACK_Position_Set(I2C_Module* I2Cx, uint16_t position)
{
    if (position == I2C_NACK_POS_NEXT)
    {
        /* Next byte in shift register is the last received byte */
        I2Cx->CTRL1 |= I2C_NACK_POS_NEXT;
    }
    else
    {
        /* Current byte in shift register is the last received byte */
        I2Cx->CTRL1 &= I2C_NACK_POS_CURRENT;
    }
}

/**
*\*\name    I2C_PEC_Send_Enable.
*\*\fun     Enables the specified I2C PEC transfer.
*\*\param   I2Cx :
*\*\          - I2C
*\*\return  none
**/
void I2C_PEC_Send_Enable(I2C_Module* I2Cx)
{
    /* Enable the selected I2C PEC transmission */
    I2Cx->CTRL1 |= I2C_PEC_SET;
}

/**
*\*\name    I2C_PEC_Send_Disable.
*\*\fun     Disables the specified I2C PEC transfer.
*\*\param   I2Cx :
*\*\          - I2C
*\*\return  none
**/
void I2C_PEC_Send_Disable(I2C_Module* I2Cx)
{
    /* Disable the selected I2C PEC transmission */
    I2Cx->CTRL1 &= I2C_PEC_RESET;
}

/**
*\*\name    I2C_NACK_Position_Set.
*\*\fun     Selects the specified I2C PEC position.
*\*\param   I2Cx :
*\*\          - I2C
*\*\param   position :
*\*\          - I2C_PEC_POS_NEXT Indicates that the next byte is PEC
*\*\          - I2C_PEC_POS_CURRENT Indicates that current byte is PEC
*\*\note    This function configures the same bit (POS) as I2C_NACK_Position_Set()
*\*\        but is intended to be used in SMBUS mode while I2C_NACK_Position_Set()
*\*\        is intended to used in I2C mode.
*\*\return  none
**/
void I2C_PEC_Position_Set(I2C_Module* I2Cx, uint16_t position)
{
    if (position == I2C_PEC_POS_NEXT)
    {
        /* Next byte in shift register is PEC */
        I2Cx->CTRL1 |= I2C_PEC_POS_NEXT;
    }
    else
    {
        /* Current byte in shift register is PEC */
        I2Cx->CTRL1 &= I2C_PEC_POS_CURRENT;
    }
}

/**
*\*\name    I2C_PEC_Compute_Enable.
*\*\fun     Enables PEC value compute.
*\*\param   I2Cx :
*\*\          - I2C
*\*\return  none
**/
void I2C_PEC_Compute_Enable(I2C_Module* I2Cx)
{
    /* Enable the selected I2C PEC calculation */
    I2Cx->CTRL1 |= I2C_PECEN_SET;
}

/**
*\*\name    I2C_PEC_Compute_Disable.
*\*\fun     Disables PEC value compute.
*\*\param   I2Cx :
*\*\          - I2C
*\*\return  none
**/
void I2C_PEC_Compute_Disable(I2C_Module* I2Cx)
{
    /* Disable the selected I2C PEC calculation */
    I2Cx->CTRL1 &= I2C_PECEN_RESET;
}

/**
*\*\name    I2C_PEC_Get.
*\*\fun     Get the PEC value for the specified I2C.
*\*\param   I2Cx :
*\*\          - I2C
*\*\return  The PEC value
**/
uint8_t I2C_PEC_Get(I2C_Module* I2Cx)
{
    /* Return the selected I2C PEC value */
    return ((I2Cx->STS2) >> 8);
}

/**
*\*\name    I2C_Extend_Clock_Enable.
*\*\fun     Enables the specified I2C clock extending.
*\*\param   I2Cx :
*\*\          - I2C
*\*\return  none
**/
void I2C_Extend_Clock_Enable(I2C_Module* I2Cx)
{
    /* Enable the selected I2C Clock extending */
    I2Cx->CTRL1 &= I2C_NOEXTEND_RESET;
}

/**
*\*\name    I2C_Extend_Clock_Disable.
*\*\fun     Disables the specified I2C clock extending.
*\*\param   I2Cx :
*\*\          - I2C
*\*\return  none
**/
void I2C_Extend_Clock_Disable(I2C_Module* I2Cx)
{
    /* Disable the selected I2C Clock extending */
    I2Cx->CTRL1 |= I2C_NOEXTEND_SET;
}

/**
*\*\name    I2C_Fast_Mode_Duty_Cycle_Set.
*\*\fun     Set the specified I2C fast mode duty cycle.
*\*\param   I2Cx :
*\*\          - I2C
*\*\param   duty_cycle :
*\*\          - I2C_FMDUTYCYCLE_2 I2C fast mode Tlow/Thigh = 2
*\*\          - I2C_FMDUTYCYCLE_16_9 I2C fast mode Tlow/Thigh = 16/9
*\*\return  none
**/
void I2C_Fast_Mode_Duty_Cycle_Set(I2C_Module* I2Cx, uint16_t duty_cycle)
{
    if (duty_cycle == I2C_FMDUTYCYCLE_16_9)
    {
        /* I2C fast mode Tlow/Thigh=16/9 */
        I2Cx->CLKCTRL |= I2C_FMDUTYCYCLE_16_9;
    }
    else
    {
        /* I2C fast mode Tlow/Thigh=2 */
        I2Cx->CLKCTRL &= I2C_FMDUTYCYCLE_2;
    }
}

/**
*\*\name    I2C_Digital_Filter_Width_Set.
*\*\fun     SDA digital filter width selection.
*\*\param   I2Cx :
*\*\          - I2C
*\*\param   width :
*\*\          - 0x00 ~ 0x0F     The numbers of pclk cycles(width is 0x00: Disable the digital filter).
*\*\return  none
**/
void I2C_SDA_Digital_Filter_Width_Set(I2C_Module* I2Cx, uint8_t width)
{
    uint16_t temp_value = 0;

    temp_value = I2Cx->GFLTRCTRL;
    /* Clear SDADFW[3:0] bits */
    temp_value &= I2C_SDADFW_MASK;
    /* Set SDADFW[3:0] bits according to width value */
    temp_value |= (uint16_t)width ;
    /* Store the new value */
    I2Cx->GFLTRCTRL = temp_value;

}

/**
*\*\name    I2C_SCL_Digital_Filter_Width_Set.
*\*\fun     SCL digital filter width selection.
*\*\param   I2Cx :
*\*\          - I2C
*\*\param   width :
*\*\          - 0x00            Disable the digital filter.
*\*\          - 0x01 ~ 0x0F     The numbers of pclk cycles.
*\*\return  none
**/
void I2C_SCL_Digital_Filter_Width_Set(I2C_Module* I2Cx, uint8_t width)
{
    uint16_t temp_value = 0;

    temp_value = I2Cx->GFLTRCTRL;
    /* Clear SCLDFW[3:0] bits */
    temp_value &= I2C_SCLDFW_MASK;
    /* Set SCLDFW[3:0] bits according to width value */
    temp_value |= ((uint16_t)width << 4);
    /* Store the new value */
    I2Cx->GFLTRCTRL = temp_value;

}

/**
*\*\name    I2C_SDA_Analog_Filter_Width_Set.
*\*\fun     SDA analog filter width selection.
*\*\param   I2Cx :
*\*\          - I2C
*\*\param   width :
*\*\        - I2C_ANALOG_FILTER_WIDTH_5NS
*\*\        - I2C_ANALOG_FILTER_WIDTH_15NS
*\*\        - I2C_ANALOG_FILTER_WIDTH_25NS
*\*\        - I2C_ANALOG_FILTER_WIDTH_35NS
*\*\return  none
**/
void I2C_SDA_Analog_Filter_Width_Set(I2C_Module* I2Cx, uint16_t width)
{
    uint16_t temp_value = 0;

    temp_value = I2Cx->GFLTRCTRL;
    /* Clear SDAAFW[1:0] bits */
    temp_value &= I2C_SDAAFW_MASK;
    /* Set SDAAFW[1:0] bits according to width value */
    temp_value |= width;
    /* Store the new value */
    I2Cx->GFLTRCTRL = temp_value;

}

/**
*\*\name    I2C_SDA_Analog_Filter_Enable.
*\*\fun     Enables the SDA analog filter.
*\*\param   I2Cx :
*\*\          - I2C
*\*\return  none
**/
void I2C_SDA_Analog_Filter_Enable(I2C_Module* I2Cx)
{
    /* Enable the SDA analog filter */
    I2Cx->GFLTRCTRL &= I2C_SCLAFENN_RESET;
}

/**
*\*\name    I2C_SDA_Analog_Filter_Disable.
*\*\fun     Disables the SDA analog filter.
*\*\param   I2Cx :
*\*\          - I2C
*\*\return  none
**/
void I2C_SDA_Analog_Filter_Disable(I2C_Module* I2Cx)
{
    /* Disable the SDA analog filter */
    I2Cx->GFLTRCTRL |= I2C_SCLAFENN_SET;
}

/**
*\*\name    I2C_SCL_Analog_Filter_Width_Set.
*\*\fun     SCL analog filter width selection.
*\*\param   I2Cx :
*\*\          - I2C
*\*\param   width :
*\*\        - I2C_ANALOG_FILTER_WIDTH_5NS
*\*\        - I2C_ANALOG_FILTER_WIDTH_15NS
*\*\        - I2C_ANALOG_FILTER_WIDTH_25NS
*\*\        - I2C_ANALOG_FILTER_WIDTH_35NS
*\*\return  none
**/
void I2C_SCL_Analog_Filter_Width_Set(I2C_Module* I2Cx, uint16_t width)
{
    uint16_t temp_value = 0;

    temp_value = I2Cx->GFLTRCTRL;
    /* Clear SCLAFW[1:0] bits */
    temp_value &= I2C_SCLAFW_MASK;
    /* Set SCLAFW[1:0] bits according to width value */
    temp_value |= (width << 3);
    /* Store the new value */
    I2Cx->GFLTRCTRL = temp_value;

}

/**
*\*\name    I2C_SCL_Analog_Filter_Enable.
*\*\fun     Enables the SCL analog filter.
*\*\param   I2Cx :
*\*\          - I2C
*\*\return  none
**/
void I2C_SCL_Analog_Filter_Enable(I2C_Module* I2Cx)
{
    /* Enable the SCL analog filter */
    I2Cx->GFLTRCTRL &= I2C_SCLAFENN_RESET;
}

/**
*\*\name    I2C_SCL_Analog_Filter_Disable.
*\*\fun     Disables the SCL analog filter.
*\*\param   I2Cx :
*\*\          - I2C
*\*\return  none
**/

void I2C_SCL_Analog_Filter_Disable(I2C_Module* I2Cx)
{
    /* Disable the SCL analog filter */
    I2Cx->GFLTRCTRL |= I2C_SCLAFENN_SET;
}

/**
*\*\brief I2C State Monitoring Functions
*\*\      This I2C driver provides three different ways for I2C state monitoring
*\*\      depending on the application requirements and constraints:
*\*\
*\*\
*\*\ 1) Basic state monitoring:
*\*\    Using I2C_Event_Check() function:
*\*\    It compares the status registers (STS1 and STS2) content to a given event
*\*\    (can be the combination of one or more flags).
*\*\    It returns SUCCESS if the current status includes the given flags
*\*\    and returns ERROR if one or more flags are missing in the current status.
*\*\    - When to use:
*\*\      - This function is suitable for most applications as well as for startup
*\*\      activity since the events are fully described in the product reference manual.
*\*\      - It is also suitable for users who need to define their own events.
*\*\    - Limitations:
*\*\      - If an error occurs (ie. error flags are set besides to the monitored flags),
*\*\        the I2C_Event_Check() function may return SUCCESS despite the communication
*\*\        hold or corrupted real state.
*\*\        In this case, it is advised to use error interrupts to monitor the error
*\*\        events and handle them in the interrupt IRQ handler.
*\*\
*\*\note
*\*\        For error management, it is advised to use the following functions:
*\*\          - I2C_ConfigInt() to configure and enable the error interrupts (I2C_INT_ERR).
*\*\          - I2Cx_ER_IRQHandler() which is called when the error interrupt occurs.
*\*\            Where x is the peripheral instance (I2C, I2C2 ...)
*\*\          - I2C_Flag_Status_Get() or I2C_GetIntStatus() to be called into I2Cx_ER_IRQHandler()
*\*\            in order to determine which error occured.
*\*\          - I2C_Flag_Status_Clear() or I2C_ClrIntPendingBit() and/or I2C_EnableSoftwareReset()
*\*\            and/or I2C_Generate_Stop_Enable() in order to clear the error flag and source,
*\*\            and return to correct communication status.
*\*\
*\*\
*\*\  2) Advanced state monitoring:
*\*\     Using the function I2C_Last_Event_Get() which returns the image of both status
*\*\     registers in a single word (uint32_t) (Status Register 2 value is shifted left
*\*\     by 16 bits and concatenated to Status Register 1).
*\*\     - When to use:
*\*\       - This function is suitable for the same applications above but it allows to
*\*\         overcome the mentioned limitation of I2C_Flag_Status_Get() function.
*\*\         The returned value could be compared to events already defined in the
*\*\         library (n32g003_i2c.h) or to custom values defined by user.
*\*\       - This function is suitable when multiple flags are monitored at the same time.
*\*\       - At the opposite of I2C_Event_Check() function, this function allows user to
*\*\         choose when an event is accepted (when all events flags are set and no
*\*\         other flags are set or just when the needed flags are set like
*\*\         I2C_Event_Check() function).
*\*\     - Limitations:
*\*\       - User may need to define his own events.
*\*\       - Same remark concerning the error management is applicable for this
*\*\         function if user decides to check only regular communication flags (and
*\*\         ignores error flags).
*\*\
*\*\
*\*\  3) Flag-based state monitoring:
*\*\     Using the function I2C_Flag_Status_Get() which simply returns the status of
*\*\     one single flag (ie. I2C_FLAG_RXDATNE ...).
*\*\     - When to use:
*\*\        - This function could be used for specific applications or in debug phase.
*\*\        - It is suitable when only one flag checking is needed (most I2C events
*\*\          are monitored through multiple flags).
*\*\     - Limitations:
*\*\        - When calling this function, the Status register is accessed. Some flags are
*\*\          cleared when the status register is accessed. So checking the status
*\*\          of one Flag, may clear other ones.
*\*\        - Function may need to be called twice or more in order to monitor one
*\*\          single event.
*\*\
*\*\  For detailed description of Events, please refer to section I2C_Events in
*\*\  n32g003_i2c.h file.
*\*\
**/


/**
*\*\name    I2C_Event_Check.
*\*\fun     Checks whether the last I2Cx Event is equal to the one passed as parameter.
*\*\param   I2Cx :
*\*\          - I2C
*\*\param   I2C_event :
*\*\          - I2C_EVT_SLAVE_SEND_ADDR_MATCHED                 EV1
*\*\          - I2C_EVT_SLAVE_RECV_ADDR_MATCHED                 EV1
*\*\          - I2C_EVT_SLAVE_SEND_ADDR2_MATCHED                EV1
*\*\          - I2C_EVT_SLAVE_RECV_ADDR2_MATCHED                EV1
*\*\          - I2C_EVT_SLAVE_GCALLADDR_MATCHED                 EV1
*\*\          - I2C_EVT_SLAVE_DATA_RECVD                        EV2
*\*\          - (I2C_EVT_SLAVE_DATA_RECVD | I2C_FLAG_DUALFLAG)  EV2
*\*\          - (I2C_EVT_SLAVE_DATA_RECVD | I2C_FLAG_GCALLADDR) EV2
*\*\          - I2C_EVT_SLAVE_DATA_SENDED                       EV3
*\*\          - (I2C_EVT_SLAVE_DATA_SENDED | I2C_FLAG_DUALFLAG) EV3
*\*\          - (I2C_EVT_SLAVE_DATA_SENDED | I2C_FLAG_GCALLADDR)EV3
*\*\          - I2C_EVT_SLAVE_ACK_MISS                          EV3_2
*\*\          - I2C_EVT_SLAVE_STOP_RECVD                        EV4
*\*\          - I2C_EVT_MASTER_MODE_FLAG                        EV5
*\*\          - I2C_EVT_MASTER_TXMODE_FLAG                      EV6
*\*\          - I2C_EVT_MASTER_RXMODE_FLAG                      EV6
*\*\          - I2C_EVT_MASTER_DATA_RECVD_FLAG                  EV7
*\*\          - I2C_EVT_MASTER_DATA_SENDING                     EV8
*\*\          - I2C_EVT_MASTER_DATA_SENDED                      EV8_2
*\*\          - I2C_EVT_MASTER_MODE_ADDRESS10_FLAG              EV9
*\*\note    For detailed description of Events, please refer to section
*\*\        I2C_Events in n32g003_i2c.h file.
*\*\return  SUCCESS or ERROR
**/

ErrorStatus I2C_Event_Check( I2C_Module* I2Cx, uint32_t I2C_event )
{
     uint32_t le_value = 0;
    uint32_t flag1 = 0, flag2 = 0;

    /* Read the I2Cx status register */
    flag1 = I2Cx->STS1;
    flag2 = I2Cx->STS2;
    flag2 = flag2 << RCC_FLAG_STS2_OFFSET;

    /* Get the last event value from I2C status register */
    le_value = (flag1 | flag2) & I2C_FLAG_Mask;

    /* Check whether the last event contains the I2C_event */
    if ((le_value & I2C_event) == I2C_event)
    {
        /* Return SUCCESS: last event is equal to I2C_event */
        return SUCCESS;
    }
    else
    {
        /* Return ERROR: last event is different from I2C_event */
        return ERROR;
    }
}

/**
*\*\name    I2C_Last_Event_Get.
*\*\fun     Returns the last I2Cx Event.
*\*\param   I2Cx :
*\*\          - I2C
*\*\note    For detailed description of Events, please refer to section
*\*\        I2C_Events in n32g003_i2c.h file.
*\*\return  The last event
**/

uint32_t I2C_Last_Event_Get( I2C_Module* I2Cx )
{
    uint32_t flag1 = 0, flag2 = 0;

    /* Read the I2Cx status register */
    flag1 = I2Cx->STS1;
    flag2 = I2Cx->STS2;
    flag2 = flag2 << RCC_FLAG_STS2_OFFSET;

    /* Return the last event value from I2C status register */
    return (flag1 | flag2) & I2C_FLAG_Mask;
}

/**
*\*\name    I2C_Flag_Status_Get.
*\*\fun     Checks whether the specified I2C flag is set or not.
*\*\param   I2Cx :
*\*\          - I2C
*\*\param   I2C_flag :
*\*\          - I2C_FLAG_DUALFLAG     Dual flag (Slave mode)
*\*\          - I2C_FLAG_GCALLADDR    General call header flag (Slave mode)
*\*\          - I2C_FLAG_TRF          Transmitter/Receiver flag
*\*\          - I2C_FLAG_BUSY         Bus busy flag
*\*\          - I2C_FLAG_MSMODE       Master/Slave flag
*\*\          - I2C_FLAG_PECERR       PEC error in reception flag
*\*\          - I2C_FLAG_OVERRUN      Overrun/Underrun flag (Slave mode)
*\*\          - I2C_FLAG_ACKFAIL      Acknowledge failure flag
*\*\          - I2C_FLAG_ARLOST       Arbitration lost flag (Master mode)
*\*\          - I2C_FLAG_BUSERR       Bus error flag
*\*\          - I2C_FLAG_TXDATE       Data register empty flag (Transmitter)
*\*\          - I2C_FLAG_RXDATNE      Data register not empty (Receiver) flag
*\*\          - I2C_FLAG_STOPF        Stop detection flag (Slave mode)
*\*\          - I2C_FLAG_ADDR10F      10-bit header sent flag (Master mode)
*\*\          - I2C_FLAG_BYTEF        Byte transfer finished flag
*\*\          - I2C_FLAG_ADDRF        Address sent flag (Master mode) 
*\*\                                  Address matched flag (Slave mode)
*\*\          - I2C_FLAG_STARTBF      Start bit flag (Master mode)
*\*\return  SET or RESET
**/

FlagStatus I2C_Flag_Status_Get( I2C_Module* I2Cx, uint32_t I2C_flag )
{
    __IO uint32_t temp_value0 = 0, temp_value1 = 0;

    /* Get the I2Cx peripheral base address */
    temp_value0 = (uint32_t)I2Cx;

    /* Read flag register index */
    temp_value1 = I2C_flag >> RCC_FLAG_GET_OFFSET;

    /* Get bit[23:0] of the flag */
    I2C_flag &= I2C_FLAG_Mask;

    if (temp_value1 == 0)
    {
        /* Flag in I2Cx STS2 Register */
        I2C_flag = (uint32_t)(I2C_flag >> RCC_FLAG_STS2_OFFSET);
        /* Get the I2Cx STS2 register address */
        temp_value0 += 0x18;
    }
    else
    {
        /* Get the I2Cx STS1 register address */
        temp_value0 += 0x14;
    }

    if (((*(__IO uint32_t*)temp_value0) & I2C_flag) == (uint32_t)RESET)
    {
        /* I2C_flag is reset */
        return RESET;
    }
    else
    {
        /* I2C_flag is set */
        return SET;
    }
}

/**
*\*\name    I2C_Flag_Status_Clear.
*\*\fun     Clears the I2Cx's flags.
*\*\param   I2Cx :
*\*\          - I2C
*\*\param   I2C_flag :
*\*\          - I2C_FLAG_PECERR      PEC error in reception flag
*\*\          - I2C_FLAG_OVERRUN     Overrun/Underrun flag (Slave mode)
*\*\          - I2C_FLAG_ACKFAIL     Acknowledge failure flag
*\*\          - I2C_FLAG_ARLOST      Arbitration lost flag (Master mode)
*\*\          - I2C_FLAG_BUSERR      Bus error flag
*\*\note    - STOPF (STOP detection) is cleared by software sequence: a read operation
*\*\          to I2C_STS1 register (I2C_Flag_Get()) followed by a write operation
*\*\          to I2C_CTRL1 register (I2C_ON() to re-enable the I2C peripheral).
*\*\        - ADD10 (10-bit header sent) is cleared by software sequence: a read
*\*\          operation to I2C_STS1 (I2C_Flag_Get()) followed by writing the
*\*\          second byte of the address in DAT register.
*\*\        - BTF (Byte Transfer Finished) is cleared by software sequence: a read
*\*\          operation to I2C_STS1 register (I2C_Flag_Get()) followed by a
*\*\          read/write to I2C_DAT register (I2C_Data_Send()).
*\*\        - ADDR (Address sent) is cleared by software sequence: a read operation to
*\*\          I2C_STS1 register (I2C_Flag_Get()) followed by a read operation to
*\*\          I2C_STS2 register ((void)(I2Cx->STS2)).
*\*\        - SB (Start Bit) is cleared software sequence: a read operation to I2C_STS1
*\*\          register (I2C_Flag_Get()) followed by a write operation to I2C_DAT
*\*\          register (I2C_Data_Send()).
*\*\return  none
**/


void I2C_Flag_Status_Clear( I2C_Module* I2Cx, uint32_t I2C_flag )
{
     uint32_t temp_value = 0;

    /* Get the I2C flag position */
    temp_value = I2C_flag & I2C_FLAG_Mask;
    /* Clear the selected I2C flag */
    I2Cx->STS1 = (uint16_t)~temp_value;
}

/**
*\*\name    I2C_Interrupt_Status_Get.
*\*\fun     Checks whether the specified I2C interrupt has occurred or not.
*\*\param   I2Cx :
*\*\          - I2C
*\*\param   Interrupt :
*\*\          - I2C_INT_PECERR      PEC error in reception flag
*\*\          - I2C_INT_OVERRUN     Overrun/Underrun flag (Slave mode)
*\*\          - I2C_INT_ACKFAIL     Acknowledge failure flag
*\*\          - I2C_INT_ARLOST      Arbitration lost flag (Master mode)
*\*\          - I2C_INT_BUSERR      Bus error flag
*\*\          - I2C_INT_TXDATE      Data register empty flag (Transmitter)
*\*\          - I2C_INT_RXDATNE     Data register not empty (Receiver) flag
*\*\          - I2C_INT_STOPF       Stop detection flag (Slave mode)
*\*\          - I2C_INT_ADDR10F     10-bit header sent flag (Master mode)
*\*\          - I2C_INT_BYTEF       Byte transfer finished flag
*\*\          - I2C_INT_ADDRF       Address sent flag (Master mode) 
*\*\                                Address matched flag (Slave mode)
*\*\          - I2C_INT_STARTBF     Start bit flag (Master mode)
*\*\return  SET or RESET
**/

ITStatus I2C_Interrupt_Status_Get( I2C_Module* I2Cx, uint32_t Interrupt )
{
     uint32_t temp_value = 0;

    /* Check if the interrupt source is enabled or not */
    temp_value = (uint32_t)(((Interrupt & I2C_INTEN_MASK) >> 16) & (I2Cx->CTRL2));

    /* Get bit[23:0] of the flag */
    Interrupt &= I2C_FLAG_Mask;

    /* Check the status of the specified I2C flag */
    if (((I2Cx->STS1 & Interrupt) != (uint32_t)RESET) && temp_value)
    {
        /* Interrupt is set */
        return SET;
    }
    else
    {
        /* Interrupt is reset */
        return RESET;
    }
}


/**
*\*\name    I2C_Interrupt_Statu_Clear.
*\*\fun     Clears the I2Cx's interrupt statu bits.
*\*\param   I2Cx :
*\*\          - I2C
*\*\param   Interrupt :
*\*\          - I2C_INT_PECERR      PEC error in reception flag
*\*\          - I2C_INT_OVERRUN     Overrun/Underrun flag (Slave mode)
*\*\          - I2C_INT_ACKFAIL     Acknowledge failure flag
*\*\          - I2C_INT_ARLOST      Arbitration lost flag (Master mode)
*\*\          - I2C_INT_BUSERR      Bus error flag
*\*\note    - STOPF (STOP detection) is cleared by software sequence: a read operation
*\*\          to I2C_STS1 register (I2C_Flag_Get()) followed by a write operation
*\*\          to I2C_CTRL1 register (I2C_ON() to re-enable the I2C peripheral).
*\*\        - ADD10 (10-bit header sent) is cleared by software sequence: a read
*\*\          operation to I2C_STS1 (I2C_Flag_Get()) followed by writing the
*\*\          second byte of the address in DAT register.
*\*\        - BTF (Byte Transfer Finished) is cleared by software sequence: a read
*\*\          operation to I2C_STS1 register (I2C_Flag_Get()) followed by a
*\*\          read/write to I2C_DAT register (I2C_Data_Send()).
*\*\        - ADDR (Address sent) is cleared by software sequence: a read operation to
*\*\          I2C_STS1 register (I2C_Flag_Get()) followed by a read operation to
*\*\          I2C_STS2 register ((void)(I2Cx->STS2)).
*\*\        - SB (Start Bit) is cleared software sequence: a read operation to I2C_STS1
*\*\          register (I2C_Flag_Get()) followed by a write operation to I2C_DAT
*\*\          register (I2C_Data_Send()).
*\*\return  none
**/
void I2C_Interrupt_Statu_Clear(I2C_Module* I2Cx, uint32_t Interrupt)
{
    uint32_t temp_value = 0;

    /* Get the I2C flag position */
    temp_value = Interrupt & I2C_FLAG_Mask;
    /* Clear the selected I2C flag */
    I2Cx->STS1 = (uint16_t)~temp_value;
}

/**
*\*\name    I2C_ByteNum_Enable.
*\*\fun     Enables the specified I2C peripheral ByteNum function.
*\*\param   I2Cx :
*\*\          - I2C
*\*\return  none
**/

void I2C_ByteNum_enable(I2C_Module* I2Cx)
{
				/* Enable the selected I2C peripheral ByteNum function*/
        I2Cx->BYTENUM |= I2C_BYTENUMEN_SET;
}

/**
*\*\name    I2C_ByteNum_Disable.
*\*\fun     disables the specified I2C peripheral ByteNum function.
*\*\param   I2Cx :
*\*\          - I2C
*\*\return  none
**/

void I2C_ByteNum_Disable(I2C_Module* I2Cx)
{
				/* Disable the selected I2C peripheral ByteNum function*/
        I2Cx->BYTENUM &= I2C_BYTENUMEN_RESET;
}


/**
*\*\name    I2C_Master_Received_DataBytesNum_Set.
*\*\fun     Set the number of data bytes that will be received by master receiver of I2C peripheral.
*\*\param   I2Cx :
*\*\          - I2C
*\*\param   Number_Of_bytes(the number of data bytes) :
*\*\          - 0x0~0x3FFF
*\*\return  none
**/


void I2C_Master_Received_DataBytesNum_Set(I2C_Module* I2Cx, uint16_t Number_Of_bytes)
{
		uint16_t temp_value = 0;
	
		temp_value = I2Cx->BYTENUM;
	  /* Clear BYTENUM[13:0] bits */
    temp_value &= I2C_BYTENUM_MASK;
		/* Set BYTENUM[13:0] bits according to Number_Of_bytes value */
    temp_value |= Number_Of_bytes;
		/* Store the new value */
		I2Cx->BYTENUM = temp_value;
}

/**
*\*\name    I2C_ByteNum_Last_StartStop_Set.
*\*\fun     Configure the last status after master have finished sending the required data bytes.
*\*\param   I2Cx :
*\*\          - I2C
*\*\param   LastStatus :
*\*\          - I2C_BYTENUM_LAST_STOP
*\*\ 		 - I2C_BYTENUM_LAST_START
*\*\return  none
**/

void I2C_ByteNum_Last_StartStop_Set(I2C_Module* I2Cx, uint16_t LastStatus)
{
		 if (LastStatus == I2C_BYTENUM_LAST_START)
    {
        /* Next byte in shift register is PEC */
        I2Cx->BYTENUM |= I2C_BYTENUM_LAST_START;
    }
    else
    {
        /* Current byte in shift register is PEC */
        I2Cx->BYTENUM &= I2C_BYTENUM_LAST_STOP;
    }
}




