
/**
 ******************************************************************************
 *
 * @file        MG32x02z_DS1621_API.c
 * @brief       Control DS1621 (Thermometer IC) by I2C protocol. 
 *
 * @par         Project
 *              MG32x02z
 * @version     V1.02
 * @date        2022/09/27
 * @author      Megawin Software Center
 * @copyright   Copyright (c) 2017 MegaWin Technology Co., Ltd.
 *              All rights reserved.
 *
 ******************************************************************************* 
 * @par Disclaimer
 * The Demo software is provided "AS IS" without any warranty, either
 * expressed or implied, including, but not limited to, the implied warranties
 * of merchantability and fitness for a particular purpose. The author will
 * not be liable for any special, incidental, consequential or indirect
 * damages due to loss of data or any other reason.
 * These statements agree with the world wide and local dictated laws about
 * authorship and violence against these laws.
 *******************************************************************************
 *******************************************************************************
 */


/* Includes ------------------------------------------------------------------*/
#include "MG32x02z_DS1621_API.h"

/* Wizard menu ---------------------------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
static Sample_I2C_HandleTypeDef gSI2C1;    /*!< for I2C0                 */

/* Exported variables --------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
/* External vairables --------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/


/**
 *******************************************************************************
 * @brief       Initial LM35DZ 
 * @param[in]   None
 * @return      None
 *******************************************************************************
 */
void API_DS1621_Init(void)
{
    uint8_t String0[10];
    GPIO_InitTypeDef    GPIOX;

    /** 
     * Config I2C module for accessing DS1621 (PE2+PE3 for I2C1)
     */

    GPIOX.Pin           = (GPIO_Pin_2 | GPIO_Pin_3);
    GPIOX.Mode          = GPIO_MODE_OPENDRAIN_O;
    GPIOX.Pull          = GPIO_PULLUP;
    GPIOX.Speed         = GPIO_SPEED_HIGH;
    GPIOX.Inverse       = GPIO_INVERSE_DISABLE;
    GPIOX.OUTDrive      = GPIO_OUTDRIVE_LEVEL0;
    GPIOX.FilterDivider = GPIO_FILTERDIVIDER_BYPASS;
    GPIOX.Alternate     = 2;

    MID_GPIO_Init( IOME ,&GPIOX);
    //-----------------------------------------------------------------------------
    gSI2C1.Instance = I2C1;
    gSI2C1.Init.CK_I2C_PR_Frequency = 48000000;
    gSI2C1.Init.SCL_Clock = 100000;
    gSI2C1.Init.OwnAddress1 = ADDRESS_BYTE_WRITE;   /*!< Bit[7:1]Device Address */
                                                    /*   Bit0 Read / Write */
    gSI2C1.DMACHx = DMAChannel0;
    //
    Sample_I2C_ByteMode_Init(&gSI2C1);
    Sample_I2C_Enable_Listen(&gSI2C1);

    //-----------------------------------------------------------------------------
    // (Master TX) Bus Master initiates a START condition. (START)
    // (Master TX) Bus Master sends DS1621 address; R/W = 0. <address,0>
    // (Master RX) DS1621 generates acknowledge bit. (ACK)

    // (Master TX) Bus Master sends Access Config command protocol. (Access_Config)
    // (Master RX) DS1621 generates acknowledge bit. (ACK)
    // (Master TX) Bus Master sets up DS1621 for output polarity active high, continuous conversion. (0x02)
    // (Master RX) DS1621 generates acknowledge bit. (ACK)

    // (I2C) STA, Addr+W, ACK, Access_Config, 0x02, STP
    String0[0] = Access_Config;
    String0[1] = 0x02;
    Sample_I2C_ByteMode_MasterTransmit(&gSI2C1, (uint16_t)ADDRESS_BYTE_WRITE, (uint8_t *)String0, 2);

    // (Master TX) Bus Master generates a repeated START condition.
    // (Master TX) Bus Master sends DS1621 address; R/W = 0. <address,0>
    // (Master RX) DS1621 generates acknowledge bit. (ACK)

    // (Master TX) Bus Master sends Access TH command. (Access_TH)
    // (Master RX) DS1621 generates acknowledge bit. (ACK)

    // (Master TX) Bus Master sends first byte of data for TH limit of +125¢XC. (0x7D)
    // (Master RX) DS1621 generates acknowledge bit. (ACK)

    // (Master TX) Bus Master sends second byte of data for TH limit of +40¢XC (0x00)
    // (Master RX) DS1621 generates acknowledge bit. (ACK)

    // (I2C) STA, Addr+W, ACK, Access_TH, 0x28, 0x00, STP
    String0[0] = Access_TH;
    String0[1] = 0x7D;
    String0[2] = 0x00;
    Sample_I2C_ByteMode_MasterTransmit(&gSI2C1, (uint16_t)ADDRESS_BYTE_WRITE, (uint8_t *)String0, 3);

    // (Master TX) Bus Master generates a repeated START condition.
    // (Master TX) Bus Master sends DS1621 address; R/W = 0. <address,0>
    // (Master RX) DS1621 generates acknowledge bit. (ACK)

    // (Master TX) Bus Master sends Access TL command. (Access_TL)
    // (Master RX) DS1621 generates acknowledge bit. (ACK)

    // (Master TX) Bus Master sends first byte of data for TL limit of -55¢XC. (0xC9)
    // (Master RX) DS1621 generates acknowledge bit. (ACK)

    // (Master TX) Bus Master sends second byte of data for TL limit of -55¢XC (0x00)
    // (Master RX) DS1621 generates acknowledge bit. (ACK)

    // (I2C) STA, Addr+W, ACK, Access_TL, 0x0A, 0x00, STP
    String0[0] = Access_TL;
    String0[1] = 0xC9;
    String0[2] = 0x00;
    Sample_I2C_ByteMode_MasterTransmit(&gSI2C1, (uint16_t)ADDRESS_BYTE_WRITE, (uint8_t *)String0, 3);

    // (Master TX) Bus Master generates a repeated START condition.
    // (Master TX) Bus Master sends DS1621 address; R/W = 0. <address,0>
    // (Master RX) DS1621 generates acknowledge bit. (ACK)
    
    // (Master TX) Bus Master sends Start Convert T command protocol. (Start_Convert_T)
    // (Master RX) DS1621 generates acknowledge bit. (ACK)
    
    // (Master TX) Bus Master initiates STOP condition.

    // (I2C) STA, Addr+W, ACK, Start_Convert_T, STP 
    String0[0] = Start_Convert_T;
    Sample_I2C_ByteMode_MasterTransmit(&gSI2C1, (uint16_t)ADDRESS_BYTE_WRITE, (uint8_t *)String0, 1);
}



/**
 *******************************************************************************
 * @brief       Get thermometer data from LM35DZ 
 * @param[in]   None
 * @return      return LM35DZ data
 *******************************************************************************
 */
uint16_t API_DS1621_GetTemperature(void)
{
    uint8_t String0[2];

    //-----------------------------------------------------------------------------
    /* Blocking mode: Polling */
    //-----------------------------------------------------------------------------
    // STA, Addr+W, ACK, Read_Temperature, STP 
    String0[0] = Read_Temperature;
    Sample_I2C_ByteMode_MasterTransmit(&gSI2C1, (uint16_t)ADDRESS_BYTE_WRITE, (uint8_t *)String0, 1);
    // STA, Addr+R, ACK, <read data - 2 bytes>, STP 
    Sample_I2C_ByteMode_MasterReceive(&gSI2C1, (uint16_t)ADDRESS_BYTE_READ, (uint8_t *)String0, 2);

    // return ADC result
    return (uint16_t ) ((String0[0] << 8) | String0[1]);
}



/**
 *******************************************************************************
 * @brief       Initialize the I2C peripheral for byte-mode
 * @details     1. GPIO Initial
 *      \n      1.1 CSC for GPIO Config
 *      \n      1.2 GPIO Config
 *      \n      2. I2C Initial
 *      \n      2.1 CSC for I2C Config
 *      \n      2.2 I2C Output Clock Config 
 *      \n      2.3 I2C Opration Mode Config
 *      \n      2.4 I2C Interrupt Config
 *      \n      2.5 I2C Timeout Config
 *      \n      2.6 I2C Enable
 *
 * @param[in]   SI2C : Sample_I2C pointer to a Sample_I2C_HandleTypeDef 
 *              structure that contains the configuration information for the
 *              specified I2C.
 * @return      DRV_Return
 * @exception   None
 * @note        
 * @par         Example
 * @code        
                Sample_I2C_ByteMode_Init(&I2C0_Init);
                Sample_I2C_ByteMode_Init(&I2C1_Init);
 * @endcode     
 * @par         Modify
 *              DRV_Return Sample_I2C_ByteMode_Init(Sample_I2C_InitTypeDef *SI2C)
 *******************************************************************************
 */
SMP_Return Sample_I2C_ByteMode_Init(Sample_I2C_HandleTypeDef *SI2C)
{
//    PIN_InitTypeDef PINX_InitStruct;
    uint16_t lI2C_Pre = 1;
    uint16_t lI2C_DIV = 0;
    uint16_t lI2C_DIV_CAL = 1;
    uint16_t lI2C_HT_LT = 0;

    //===== Check I2C Busy =====//
    if(__I2C_GetFlagStatus(SI2C->Instance, I2C_FLAG_BUSYF))
        return SMP_Busy;

    __I2C_Disable(SI2C->Instance);

    //===== I2C Output Clock Config =====//
    // CK_I2C_PR
    // SCL Output Clock
    // HT + LT, <= 32 >=9, CK_I2C_PR / SCL Clock / Prescaler / DIV

  #if defined(MG32F02A132) || defined(MG32F02A072) || defined(MA862)
    do{
        lI2C_HT_LT = SI2C->Init.CK_I2C_PR_Frequency / SI2C->Init.SCL_Clock / lI2C_Pre / lI2C_DIV_CAL;
        if((lI2C_HT_LT >= 32) || (lI2C_HT_LT <=9)) 
        {
            lI2C_Pre ++;
            if(lI2C_Pre > 8)
            {
                lI2C_Pre = 1;
                lI2C_DIV_CAL += lI2C_DIV_CAL;
            }
        }
    }while((lI2C_HT_LT >= 32) || (lI2C_HT_LT <=9));
  #else
    do{
        lI2C_HT_LT = (uint16_t)(((SI2C->Init.CK_I2C_PR_Frequency / SI2C->Init.SCL_Clock) / lI2C_Pre) / lI2C_DIV_CAL);
        if((lI2C_HT_LT >= 64) || (lI2C_HT_LT <=9)) 
        {
            lI2C_Pre ++;
            if(lI2C_Pre > 8)
            {
                lI2C_Pre = 1;
                lI2C_DIV_CAL += lI2C_DIV_CAL;
            }
        }
    }while((lI2C_HT_LT >= 64) || (lI2C_HT_LT <=9));
  #endif

    if(lI2C_DIV_CAL == 1)
        lI2C_DIV = 0;
    else
    {
        lI2C_DIV_CAL = (lI2C_DIV_CAL >> 1);
        do{
            lI2C_DIV ++;
            lI2C_DIV_CAL = (lI2C_DIV_CAL >> 1);
        }while(lI2C_DIV_CAL != 0);
    }

    __I2C_SetClockSource(SI2C->Instance, I2C_CLK_SRC_PROC);
    __I2C_SetClockPrescaler(SI2C->Instance, lI2C_Pre - 1);
    __I2C_SetClockDivider(SI2C->Instance, (lI2C_DIV << 4));
    __I2C_SetSCLLowTime(SI2C->Instance, (lI2C_HT_LT >> 1) - 1);
    __I2C_SetSCLHighTime(SI2C->Instance, (lI2C_HT_LT - (lI2C_HT_LT >> 1)));

    //===== I2C Opration Mode Config =====//
    if(SI2C->Init.SCL_Clock > 450000)
    {
        if(SI2C->Init.CK_I2C_PR_Frequency >= 36000000UL)
            __I2C_SetPreDriveTime(SI2C->Instance, I2C_PDRV_3T);
        else if(SI2C->Init.CK_I2C_PR_Frequency >= 24000000UL)
            __I2C_SetPreDriveTime(SI2C->Instance, I2C_PDRV_2T);
        else
            __I2C_SetPreDriveTime(SI2C->Instance, I2C_PDRV_1T);
    }
    else
        __I2C_SetPreDriveTime(SI2C->Instance, I2C_PDRV_0T);

    __I2C_GeneralCallAddress_Disable(SI2C->Instance);
    __I2C_SlaveAddressDetect_Disable(SI2C->Instance, (I2C_SADR_0 | I2C_SADR_1 | I2C_SADR_2));

    __I2C_SetSlaveAddress1(SI2C->Instance, SI2C->Init.OwnAddress1);
    __I2C_SetSlaveAddress2(SI2C->Instance, SI2C->Init.OwnAddress2);

  #if defined(MG32_1ST)
  #else
    __I2C_SetSlaveAddress1Mask(SI2C->Instance, 0xFE);
  #endif

    //===== I2C Interrupt Config =====//
    if(SI2C->Instance == I2C0)
    {
        NVIC_EnableIRQ(I2C0_IRQn);
        NVIC_SetPriority(I2C0_IRQn, 3);                                         // Suggest SYSTICK Priority = 0
                                                                                //           Other Priority > 0
    }

  #if defined(MG32_1ST)
    if(SI2C->Instance == I2C1)
    {
        NVIC_EnableIRQ(I2Cx_IRQn);
        NVIC_SetPriority(I2Cx_IRQn, 3);                                         // Suggest SYSTICK Priority = 0
    }
  #endif

    __I2C_ITEA_Disable(SI2C->Instance);
    __I2C_IT_Disable(SI2C->Instance, (I2C_IT_TMOUT | I2C_IT_EVENT | I2C_IT_ERR | I2C_IT_BUF ));

    //===== I2C Timeout Config =====//
    __I2C_TMO_Disable(SI2C->Instance);
    __I2C_SetTimeOutClockSource(SI2C->Instance, I2C_TMO_CKS_DIV64);
    __I2C_SetTimeOutDetectionMode(SI2C->Instance, I2C_TMO_MDS_GENERAL);
    __I2C_SetTimeOutCount(SI2C->Instance, I2C_TMO_MDS_GENERAL);

    //===== I2C Enable =====//
    __I2C_Enable(SI2C->Instance);
    SI2C->State.B = Sample_I2C_State_Ready;
    return SMP_Success;
}


/**
 *******************************************************************************
 * @brief       I2C Byte Mode Master Receive
 * @details     Receives in master mode an amount of data in blocking mode.
 *              
 * @param[in]   SI2C : Sample_I2C pointer to a Sample_I2C_HandleTypeDef 
 *              structure that contains the configuration information for the
 *              specified I2C.
 * @param[in]   DevAddress : Target device address: The device 7 bits address
 *              value in datasheet must be shift at right before call interface.
 * @param[in]   pBuffer : Pointer to data buffer.
 * @param[in]   Size : Amount of data to be sent.
 * @return      DRV status
 * @exception   None
 * @note        
 * @par         Example
 * @code        
                Sample_I2C_ByteMode_MasterReceive(&gSI2C1, 0xA0, (uint8_t *)&DataBuffer, 256);
 * @endcode     
 * @par         Modify
 *              DRV_Return Sample_I2C_ByteMode_MasterReceive(Sample_I2C_HandleTypeDef *SI2C, uint16_t DevAddress, uint8_t *pBuffer, uint16_t Size)
 *******************************************************************************
 */
SMP_Return Sample_I2C_ByteMode_MasterReceive(Sample_I2C_HandleTypeDef *SI2C, uint16_t DevAddress, uint8_t *pBuffer, uint16_t Size)
{
    //-----Check---------------------------
    if((SI2C->State.B & Sample_I2C_State_Ready) == 0)
        return SMP_Failure;

    //----- State Check -------------------
    if(__I2C_GetFlagStatus(SI2C->Instance, I2C_FLAG_BUSYF) != CLR)
        if(__I2C_GetEventFlag(SI2C->Instance) != 0)
            if(__I2C_GetEventCode(SI2C->Instance) != 0x10)
                return SMP_Busy;

    //---- Disable All Interrupt --------
    __I2C_IT_Disable(SI2C->Instance, I2C_IT_ERR | I2C_IT_BUF | I2C_IT_EVENT); // Disable Interrupt

    //---- Clear I2C Flag ---------------
    __I2C_ClearFlag(SI2C->Instance, (I2C_FLAG_NACKF | I2C_FLAG_ALOSF | I2C_FLAG_BERRF | I2C_FLAG_ROVRF | I2C_FLAG_TOVRF | I2C_FLAG_STOPF | I2C_FLAG_RSTRF));

    //-----Set_Config-----------------------
    SI2C->State.B = (SI2C->State.B & (~(Sample_I2C_State_Busy_Tx | Sample_I2C_State_Error))) | Sample_I2C_State_Busy_Rx;
    SI2C->Error.H = 0;
    SI2C->SlaveAddress = (uint8_t)(DevAddress | 0x0001);
    SI2C->pBuffer = pBuffer;
    SI2C->XferSize = Size;
    SI2C->XferCount = 0;
    SI2C->Control.H = (SI2C->Control.H & (~Sample_I2C_XferNext_Mask)) | Sample_I2C_XferNext_STOP;

    //-----Start----------------------------
    if(__I2C_GetEventCode(SI2C->Instance) == 0xF8)
        Set_STA_STO_AA_100(SI2C->Instance);

    do{
        Sample_I2C_ByteMode_Handle(SI2C);
    }while(SI2C->State.MBit.Busy != 0);

    if((SI2C->State.B & Sample_I2C_State_Error) == Sample_I2C_State_Timeout)
        return SMP_Timeout;

    if((SI2C->State.B & Sample_I2C_State_Error) == Sample_I2C_State_Error)
        return SMP_Failure;

    return SMP_Success;
}


 /**
 *******************************************************************************
 * @brief       I2C ByteMode Handle
 * @details     
 * @param[in]   SI2C : Sample_I2C pointer to a Sample_I2C_HandleTypeDef 
 *                     structure that contains the configuration 
 *                     information for the specified I2C.
 * @return      No
 * @exception   None
 * @note        
 * @par         Example
 * @code        
                Sample_I2C_ByteMode_Handle(Sample_I2C_HandleTypeDef &gSI2C1);
 * @endcode     
 * @par         Modify
 *              void Sample_I2C_ByteMode_Handle(Sample_I2C_HandleTypeDef *SI2C);
 *******************************************************************************
 */
void Sample_I2C_ByteMode_Handle(Sample_I2C_HandleTypeDef *SI2C)
{
    uint8_t lState;

    if(__I2C_GetEventFlag(SI2C->Instance) == 0)
        return;

    lState = __I2C_GetEventCode(SI2C->Instance);
    switch(lState){
        case 0x00:  // Bus Error
            SI2C->Error.H |= Sample_I2C_Error_BusError;
            SI2C->State.B |= Sample_I2C_State_Error;
            __I2C_ClearFlag(SI2C->Instance, I2C_FLAG_BERRF | I2C_FLAG_ERRF);
            __I2C_ClearEventFlag(SI2C->Instance);
            while(__I2C_GetEventCode(SI2C->Instance) != 0xF8);

            __I2C_IT_Disable(SI2C->Instance, (I2C_IT_EVENT | I2C_IT_BUF |I2C_IT_ERR));
            SI2C->Control.H &= ~(Sample_I2C_DMA_MTx | Sample_I2C_DMA_MRx | Sample_I2C_DMA_SRx | Sample_I2C_DMA_STx);
            if((SI2C->Control.H & Sample_I2C_Listen) != 0)
            {
                __I2C_SlaveAddressDetect_Enable(SI2C->Instance, I2C_SADR_1);

                if(SI2C->Init.DualAddressMode != 0)
                __I2C_SlaveAddressDetect_Enable(SI2C->Instance, I2C_SADR_2);

                if(SI2C->Init.GeneralCallMode != 0)
                __I2C_SlaveAddressDetect_Enable(SI2C->Instance, I2C_SADR_0);

                Set_ASSERT_ACKNOWLEDGE_SET(SI2C->Instance);
                SI2C->State.B |= Sample_I2C_State_Listen;
            }
            else
            {
                __I2C_SlaveAddressDetect_Disable(SI2C->Instance, (I2C_SADR_0 | I2C_SADR_1 | I2C_SADR_2));
                Set_STA_STO_AA_000(SI2C->Instance);
                SI2C->State.B &= ~Sample_I2C_State_Listen;
            }
            SI2C->State.B &= ~Sample_I2C_State_Busy;
            break;
//-------------------------------------
        case 0x08:  // A START condition has been transmitted
        case 0x10:  // Repeated start condition
            Set_STA_STO_AA_000(SI2C->Instance);
            __I2C_SendSBUF(SI2C->Instance, ((uint8_t)SI2C->SlaveAddress));
            break;

        case 0x18:  // MT SLA+W sent and ACK received
            SI2C->State.B &= ~Sample_I2C_State_Listen;
            if((SI2C->Control.H & Sample_I2C_DMA_MTx) != 0)
            {
                //if((SI2C->Control.H & Sample_I2C_XferNext_Mask) == Sample_I2C_XferNext_RepeatStart)
                //    PreSet_STA_STO_AA_100(SI2C->Instance);
                //else
                //    PreSet_STA_STO_AA_010(SI2C->Instance);

                PreSet_STA_STO_AA_000(SI2C->Instance);
                __I2C_TXDMA_Enable(SI2C->Instance);
                return;
            }
            goto SMP_I2C_ByteMode_Handle_0x28;
        case 0x28:  // MT DATA sent and ACK received

SMP_I2C_ByteMode_Handle_0x28:
            if(SI2C->XferCount == SI2C->XferSize)
            {
                if((SI2C->Control.H & Sample_I2C_XferNext_Mask) == Sample_I2C_XferNext_RepeatStart)
                {
                    Set_STA_STO_AA_100(SI2C->Instance);
                    __I2C_ClearEventFlag(SI2C->Instance);
                    while(__I2C_GetEventCode(SI2C->Instance) != 0x10);
                }
                else
                {
                    Set_STA_STO_AA_010(SI2C->Instance);
                    __I2C_ClearEventFlag(SI2C->Instance);
                    while(__I2C_GetEventCode(SI2C->Instance) != 0xF8);
                }
                __I2C_IT_Disable(SI2C->Instance, (I2C_IT_EVENT | I2C_IT_BUF |I2C_IT_ERR));
                SI2C->Control.H &= ~(Sample_I2C_DMA_MTx | Sample_I2C_DMA_MRx | Sample_I2C_DMA_SRx | Sample_I2C_DMA_STx);
                if((SI2C->Control.H & Sample_I2C_Listen) != 0)
                {
                    __I2C_SlaveAddressDetect_Enable(SI2C->Instance, I2C_SADR_1);
    
                    if(SI2C->Init.DualAddressMode != 0)
                    __I2C_SlaveAddressDetect_Enable(SI2C->Instance, I2C_SADR_2);
    
                    if(SI2C->Init.GeneralCallMode != 0)
                    __I2C_SlaveAddressDetect_Enable(SI2C->Instance, I2C_SADR_0);
    
                    Set_ASSERT_ACKNOWLEDGE_SET(SI2C->Instance);
                    SI2C->State.B |= Sample_I2C_State_Listen;
                }
                else
                {
                    __I2C_SlaveAddressDetect_Disable(SI2C->Instance, (I2C_SADR_0 | I2C_SADR_1 | I2C_SADR_2));
                    Set_STA_STO_AA_000(SI2C->Instance);
                    SI2C->State.B &= ~Sample_I2C_State_Listen;
                }
                SI2C->State.B &= ~Sample_I2C_State_Busy;
                return;
            }

            __I2C_SendSBUF(SI2C->Instance, SI2C->pBuffer[SI2C->XferCount]);
            SI2C->XferCount ++;
            break;

        case 0x30:  // MT DATA sent NACK received
            if((SI2C->Control.H & Sample_I2C_DMA_MTx) != 0)
            {
                SI2C->Control.H &= ~Sample_I2C_DMA_MTx;
                SI2C->XferCount = (SI2C->XferSize - SI2C->DMACHx->CNT.H[0]);
            }
            if(SI2C->XferCount < SI2C->XferSize)
            {
                SI2C->XferCount--;
                SI2C->Error.H |= Sample_I2C_Error_NACK;
                SI2C->State.B |= Sample_I2C_State_Error;
            }
            __I2C_ClearFlag(SI2C->Instance, I2C_FLAG_NACKF | I2C_FLAG_ERRF);
            Set_STA_STO_AA_010(SI2C->Instance);
            __I2C_ClearEventFlag(SI2C->Instance);
            while(__I2C_GetEventCode(SI2C->Instance) != 0xF8);

            __I2C_IT_Disable(SI2C->Instance, (I2C_IT_EVENT | I2C_IT_BUF |I2C_IT_ERR));
            SI2C->Control.H &= ~(Sample_I2C_DMA_MTx | Sample_I2C_DMA_MRx | Sample_I2C_DMA_SRx | Sample_I2C_DMA_STx);
            if((SI2C->Control.H & Sample_I2C_Listen) != 0)
            {
                __I2C_SlaveAddressDetect_Enable(SI2C->Instance, I2C_SADR_1);

                if(SI2C->Init.DualAddressMode != 0)
                __I2C_SlaveAddressDetect_Enable(SI2C->Instance, I2C_SADR_2);

                if(SI2C->Init.GeneralCallMode != 0)
                __I2C_SlaveAddressDetect_Enable(SI2C->Instance, I2C_SADR_0);

                Set_ASSERT_ACKNOWLEDGE_SET(SI2C->Instance);
                SI2C->State.B |= Sample_I2C_State_Listen;
            }
            else
            {
                __I2C_SlaveAddressDetect_Disable(SI2C->Instance, (I2C_SADR_0 | I2C_SADR_1 | I2C_SADR_2));
                Set_STA_STO_AA_000(SI2C->Instance);
                SI2C->State.B &= ~Sample_I2C_State_Listen;
            }
            SI2C->State.B &= ~Sample_I2C_State_Busy;
            return;

        case 0x20:  // MT SLA+W sent NACK received 
        case 0x48:  // MR SLA+R sent NACK received
            SI2C->Error.H |= Sample_I2C_Error_NACK;
            SI2C->State.B |= Sample_I2C_State_Error;
            __I2C_ClearFlag(SI2C->Instance, I2C_FLAG_NACKF | I2C_FLAG_ERRF);
            Set_STA_STO_AA_010(SI2C->Instance);
            __I2C_ClearEventFlag(SI2C->Instance);
            while(__I2C_GetEventCode(SI2C->Instance) != 0xF8);

            __I2C_IT_Disable(SI2C->Instance, (I2C_IT_EVENT | I2C_IT_BUF |I2C_IT_ERR));
            SI2C->Control.H &= ~(Sample_I2C_DMA_MTx | Sample_I2C_DMA_MRx | Sample_I2C_DMA_SRx | Sample_I2C_DMA_STx);
            if((SI2C->Control.H & Sample_I2C_Listen) != 0)
            {
                __I2C_SlaveAddressDetect_Enable(SI2C->Instance, I2C_SADR_1);

                if(SI2C->Init.DualAddressMode != 0)
                __I2C_SlaveAddressDetect_Enable(SI2C->Instance, I2C_SADR_2);

                if(SI2C->Init.GeneralCallMode != 0)
                __I2C_SlaveAddressDetect_Enable(SI2C->Instance, I2C_SADR_0);

                Set_ASSERT_ACKNOWLEDGE_SET(SI2C->Instance);
                SI2C->State.B |= Sample_I2C_State_Listen;
            }
            else
            {
                __I2C_SlaveAddressDetect_Disable(SI2C->Instance, (I2C_SADR_0 | I2C_SADR_1 | I2C_SADR_2));
                Set_STA_STO_AA_000(SI2C->Instance);
                SI2C->State.B &= ~Sample_I2C_State_Listen;
            }
            SI2C->State.B &= ~Sample_I2C_State_Busy;
            return;

//-------------------------------------
        case 0x38:  // Arbitration lost
            __I2C_ClearFlag(SI2C->Instance, I2C_FLAG_ALOSF | I2C_FLAG_ERRF);
            SI2C->Error.H |= Sample_I2C_Error_ArbitrationLost;
            SI2C->State.B |= Sample_I2C_State_Error;

            __I2C_IT_Disable(SI2C->Instance, (I2C_IT_EVENT | I2C_IT_BUF |I2C_IT_ERR));
            SI2C->Control.H &= (~(Sample_I2C_DMA_MTx | Sample_I2C_DMA_MRx | Sample_I2C_DMA_SRx | Sample_I2C_DMA_STx));
            if((SI2C->Control.H & Sample_I2C_Listen) != 0)
            {
                __I2C_SlaveAddressDetect_Enable(SI2C->Instance, I2C_SADR_1);

                if(SI2C->Init.DualAddressMode != 0)
                __I2C_SlaveAddressDetect_Enable(SI2C->Instance, I2C_SADR_2);

                if(SI2C->Init.GeneralCallMode != 0)
                __I2C_SlaveAddressDetect_Enable(SI2C->Instance, I2C_SADR_0);

                Set_ASSERT_ACKNOWLEDGE_SET(SI2C->Instance);
                SI2C->State.B |= Sample_I2C_State_Listen;
            }
            else
            {
                __I2C_SlaveAddressDetect_Disable(SI2C->Instance, (I2C_SADR_0 | I2C_SADR_1 | I2C_SADR_2));
                Set_STA_STO_AA_000(SI2C->Instance);
                SI2C->State.B &= ~Sample_I2C_State_Listen;
            }
            SI2C->State.B &= ~Sample_I2C_State_Busy;
            break;

//-------------------------------------
        case 0x40:  // SLA+R sent and ACK received
            SI2C->State.B &= ~Sample_I2C_State_Listen;
            Set_STA_STO_AA_001(SI2C->Instance);
            if(SI2C->XferCount >= (SI2C->XferSize - 1))
            {
                Set_STA_STO_AA_000(SI2C->Instance);
                break;
            }

            if((SI2C->Control.H & Sample_I2C_DMA_MRx) != 0)
            {
                //if((SI2C->Control.H & Sample_I2C_XferNext_Mask) == Sample_I2C_XferNext_RepeatStart)
                //    PreSet_STA_STO_AA_100(SI2C->Instance);
                //else
                //    PreSet_STA_STO_AA_010(SI2C->Instance);

                PreSet_STA_STO_AA_000(SI2C->Instance);
                __I2C_RXDMA_Enable(SI2C->Instance);
                return;
            }
            break;

        case 0x50:  // Data Received and ACK sent
            SI2C->pBuffer[SI2C->XferCount] = __I2C_ReceiveSBUF(SI2C->Instance);
            SI2C->XferCount++;
            if(SI2C->XferCount >= (SI2C->XferSize - 1))
                Set_STA_STO_AA_000(SI2C->Instance);
            break;

        case 0x58:  // Data Received and NACK sent
            SI2C->pBuffer[SI2C->XferCount] = __I2C_ReceiveSBUF(SI2C->Instance);
            SI2C->XferCount++;
            if((SI2C->Control.H & Sample_I2C_XferNext_Mask) == Sample_I2C_XferNext_RepeatStart)
            {
                __I2C_IT_Disable(SI2C->Instance, I2C_IT_EVENT);
                Set_STA_STO_AA_100(SI2C->Instance);
                __I2C_ClearEventFlag(SI2C->Instance);
                while(__I2C_GetEventCode(SI2C->Instance) != 0x10);
            }
            else
            {
                Set_STA_STO_AA_010(SI2C->Instance);
                __I2C_ClearEventFlag(SI2C->Instance);
                while(__I2C_GetEventCode(SI2C->Instance) != 0xF8);
            }

            __I2C_IT_Disable(SI2C->Instance, (I2C_IT_EVENT | I2C_IT_BUF |I2C_IT_ERR));
            SI2C->Control.H &= ~(Sample_I2C_DMA_MTx | Sample_I2C_DMA_MRx | Sample_I2C_DMA_SRx | Sample_I2C_DMA_STx);
            if((SI2C->Control.H & Sample_I2C_Listen) != 0)
            {
                __I2C_SlaveAddressDetect_Enable(SI2C->Instance, I2C_SADR_1);

                if(SI2C->Init.DualAddressMode != 0)
                __I2C_SlaveAddressDetect_Enable(SI2C->Instance, I2C_SADR_2);

                if(SI2C->Init.GeneralCallMode != 0)
                __I2C_SlaveAddressDetect_Enable(SI2C->Instance, I2C_SADR_0);

                Set_ASSERT_ACKNOWLEDGE_SET(SI2C->Instance);
                SI2C->State.B |= Sample_I2C_State_Listen;
            }
            else
            {
                __I2C_SlaveAddressDetect_Disable(SI2C->Instance, (I2C_SADR_0 | I2C_SADR_1 | I2C_SADR_2));
                Set_STA_STO_AA_000(SI2C->Instance);
                SI2C->State.B &= ~Sample_I2C_State_Listen;
            }
            SI2C->State.B &= ~Sample_I2C_State_Busy;
            return;

//-------------------------------------
        case 0x68:  // Arbitration lost in SLA+R/W as master,
                    // Own SLA+W has been Received ACK has bee returned
        case 0x78:  // Arbitration lost in SLA+R/W as master,
                    // General Call address has been received ACK has been returned
            if(__I2C_GetFlagStatus(SI2C->Instance, I2C_FLAG_ALOSF) != 0)
            {
                __I2C_ClearFlag(SI2C->Instance, I2C_FLAG_ALOSF | I2C_FLAG_ERRF);
                SI2C->Error.H |= Sample_I2C_Error_ArbitrationLost;
                SI2C->State.B |= Sample_I2C_State_Error;

                __I2C_IT_Disable(SI2C->Instance, (I2C_IT_EVENT | I2C_IT_BUF |I2C_IT_ERR));
                SI2C->Control.H &= ~(Sample_I2C_DMA_MTx | Sample_I2C_DMA_MRx | Sample_I2C_DMA_SRx | Sample_I2C_DMA_STx);
                Set_STA_STO_AA_001(SI2C->Instance);
                SI2C->State.B |= Sample_I2C_State_Listen;
                SI2C->State.B &= ~Sample_I2C_State_Busy;
                return;
            }
            goto SMP_I2C_ByteMode_Handle_0x60_0x70;
            
        case 0x60:  // Own SLA+W has bee Received ACK has been returned
        case 0x70:  // General Call address has been received ACK has been returned
SMP_I2C_ByteMode_Handle_0x60_0x70:
            SI2C->State.B &= ~Sample_I2C_State_Listen;
            if((SI2C->Control.H & Sample_I2C_DMA_SRx) != 0)
            {
                PreSet_STA_STO_AA_001(SI2C->Instance);
                __I2C_RXDMA_Enable(SI2C->Instance);
                return;
            }
            break;

        case 0x80:  // Data byte has been received ACK has been return
        case 0x90:  // Previously address with General Call address
                    // Data byte has been received ACK has been return
            SI2C->pBuffer[SI2C->XferCount] = __I2C_ReceiveSBUF(SI2C->Instance);
            SI2C->XferCount++;
            if(SI2C->XferCount >= (SI2C->XferSize))
                Set_STA_STO_AA_000(SI2C->Instance);
            break;

        case 0xA0:  // A STOP or repeated START has been received while will addressed as SLV/REC
            if((SI2C->Control.H & (Sample_I2C_DMA_SRx | Sample_I2C_DMA_STx)) != 0)
            {
                if((SI2C->DMACHx->CNT.H[0] == 0) && ((SI2C->DMACHx->A.W & DMA_CH0A_CH0_REQ_enable_w) != 0))
                    SI2C->XferCount = SI2C->DMACHx->CNT.H[0];
                else
                    SI2C->XferCount = (SI2C->XferSize - SI2C->DMACHx->CNT.H[0]);
            }

            if (SI2C->XferCount == 0)
            {
                SI2C->State.B |= Sample_I2C_State_Listen;
                break;
            }

            if(SI2C->XferCount < (SI2C->XferSize - 1))
            {
                SI2C->Error.H |= Sample_I2C_Error_Size;
                //SI2C->State.B |= Sample_I2C_State_Error;
            }

            __I2C_IT_Disable(SI2C->Instance, (I2C_IT_EVENT | I2C_IT_BUF |I2C_IT_ERR));
            SI2C->Control.H &= ~(Sample_I2C_DMA_MTx | Sample_I2C_DMA_MRx | Sample_I2C_DMA_SRx | Sample_I2C_DMA_STx);
            if((SI2C->Control.H & Sample_I2C_Listen) != 0)
            {
                __I2C_SlaveAddressDetect_Enable(SI2C->Instance, I2C_SADR_1);

                if(SI2C->Init.DualAddressMode != 0)
                __I2C_SlaveAddressDetect_Enable(SI2C->Instance, I2C_SADR_2);

                if(SI2C->Init.GeneralCallMode != 0)
                __I2C_SlaveAddressDetect_Enable(SI2C->Instance, I2C_SADR_0);

                Set_ASSERT_ACKNOWLEDGE_SET(SI2C->Instance);
                SI2C->State.B |= Sample_I2C_State_Listen;
            }
            else
            {
                __I2C_SlaveAddressDetect_Disable(SI2C->Instance, (I2C_SADR_0 | I2C_SADR_1 | I2C_SADR_2));
                Set_STA_STO_AA_000(SI2C->Instance);
                SI2C->State.B &= ~Sample_I2C_State_Listen;
            }
            SI2C->State.B &= ~Sample_I2C_State_Busy;
            break;

        case 0x88:  // Data byte has been received Not ACK has been return
        case 0x98:  // Previously address with General Call address
                    // Data byte has been received Not ACK has been return
            SI2C->XferCount++;
            SI2C->Error.H |= Sample_I2C_Error_Over;
            SI2C->State.B |= Sample_I2C_State_Error;
            __I2C_SlaveAddressDetect_Disable(SI2C->Instance, (I2C_SADR_0 | I2C_SADR_1 | I2C_SADR_2));
            __I2C_IT_Disable(SI2C->Instance, (I2C_IT_EVENT | I2C_IT_BUF |I2C_IT_ERR));

            __I2C_IT_Disable(SI2C->Instance, (I2C_IT_EVENT | I2C_IT_BUF |I2C_IT_ERR));
            SI2C->Control.H &= ~(Sample_I2C_DMA_MTx | Sample_I2C_DMA_MRx | Sample_I2C_DMA_SRx | Sample_I2C_DMA_STx);
            if((SI2C->Control.H & Sample_I2C_Listen) != 0)
            {
                __I2C_SlaveAddressDetect_Enable(SI2C->Instance, I2C_SADR_1);

                if(SI2C->Init.DualAddressMode != 0)
                __I2C_SlaveAddressDetect_Enable(SI2C->Instance, I2C_SADR_2);

                if(SI2C->Init.GeneralCallMode != 0)
                __I2C_SlaveAddressDetect_Enable(SI2C->Instance, I2C_SADR_0);

                Set_ASSERT_ACKNOWLEDGE_SET(SI2C->Instance);
                SI2C->State.B |= Sample_I2C_State_Listen;
            }
            else
            {
                __I2C_SlaveAddressDetect_Disable(SI2C->Instance, (I2C_SADR_0 | I2C_SADR_1 | I2C_SADR_2));
                Set_STA_STO_AA_000(SI2C->Instance);
                SI2C->State.B &= ~Sample_I2C_State_Listen;
            }
            SI2C->State.B &= ~Sample_I2C_State_Busy;
            break;

//-------------------------------------
        case 0xB0:  // Arbitration lost in SLA+R/W as master,
                    // Own SLA+R has been Received ACK has bee returned
            if(__I2C_GetFlagStatus(SI2C->Instance, I2C_FLAG_ALOSF) != 0)
            {
                __I2C_ClearFlag(SI2C->Instance, I2C_FLAG_ALOSF | I2C_FLAG_ERRF);
                SI2C->Error.H |= Sample_I2C_Error_ArbitrationLost;
                SI2C->State.B |= Sample_I2C_State_Error;

                __I2C_IT_Disable(SI2C->Instance, (I2C_IT_EVENT | I2C_IT_BUF |I2C_IT_ERR));
                SI2C->Control.H &= ~(Sample_I2C_DMA_MTx | Sample_I2C_DMA_MRx | Sample_I2C_DMA_SRx | Sample_I2C_DMA_STx);
                Set_STA_STO_AA_001(SI2C->Instance);
                SI2C->State.B |= Sample_I2C_State_Listen;
                SI2C->State.B &= ~Sample_I2C_State_Busy;
                return;
            }           
            goto SMP_I2C_ByteMode_Handle_0xA8;
        case 0xA8:  // Own SLA+R has bee Received ACK has been returned
SMP_I2C_ByteMode_Handle_0xA8:
            SI2C->State.B &= ~Sample_I2C_State_Listen;
            if((SI2C->Control.H & Sample_I2C_DMA_STx) != 0)
            {
                PreSet_STA_STO_AA_000(SI2C->Instance);
                __I2C_TXDMA_Enable(SI2C->Instance);
                return;
            }
            goto SMP_I2C_ByteMode_Handle_0xB8;
        case 0xB8:  // Data byte in SIDAT has been transmitted ACK has been received
SMP_I2C_ByteMode_Handle_0xB8:
            if(SI2C->XferCount < SI2C->XferSize)
            {
                __I2C_SendSBUF(SI2C->Instance, (SI2C->pBuffer[SI2C->XferCount]));
                SI2C->XferCount ++;
            }
            else
            {
                SI2C->Error.H |= Sample_I2C_Error_Over;
                SI2C->State.B |= Sample_I2C_State_Error;
                Set_STA_STO_AA_000(SI2C->Instance);
                __I2C_SendSBUF(SI2C->Instance, 0xFF);
            }
            break;

        case 0xC0:  // Data byte or Last data byte in SIDAT has been transmitted Not ACK has been received
            __I2C_ClearFlag(SI2C->Instance, (I2C_FLAG_NACKF | I2C_FLAG_ERRF));

            if((SI2C->Control.H & Sample_I2C_DMA_STx) != 0)
                SI2C->XferCount = (SI2C->XferSize - SI2C->DMACHx->CNT.H[0]);

            if(SI2C->XferCount < (SI2C->XferSize))
            {
                SI2C->Error.H |= Sample_I2C_Error_NACK;
                SI2C->State.B |= Sample_I2C_State_Error;
            }

            __I2C_IT_Disable(SI2C->Instance, (I2C_IT_EVENT | I2C_IT_BUF |I2C_IT_ERR));
            SI2C->Control.H &= ~(Sample_I2C_DMA_MTx | Sample_I2C_DMA_MRx | Sample_I2C_DMA_SRx | Sample_I2C_DMA_STx);
            if((SI2C->Control.H & Sample_I2C_Listen) != 0)
            {
                __I2C_SlaveAddressDetect_Enable(SI2C->Instance, I2C_SADR_1);

                if(SI2C->Init.DualAddressMode != 0)
                __I2C_SlaveAddressDetect_Enable(SI2C->Instance, I2C_SADR_2);

                if(SI2C->Init.GeneralCallMode != 0)
                __I2C_SlaveAddressDetect_Enable(SI2C->Instance, I2C_SADR_0);

                Set_ASSERT_ACKNOWLEDGE_SET(SI2C->Instance);
                SI2C->State.B |= Sample_I2C_State_Listen;
            }
            else
            {
                __I2C_SlaveAddressDetect_Disable(SI2C->Instance, (I2C_SADR_0 | I2C_SADR_1 | I2C_SADR_2));
                Set_STA_STO_AA_000(SI2C->Instance);
                SI2C->State.B &= ~Sample_I2C_State_Listen;
            }
            SI2C->State.B &= ~Sample_I2C_State_Busy;
            break;

        case 0xC8:  // Last Data byte in SIDAT has been transmitted ACK has been received
            if(SI2C->XferCount >= (SI2C->XferSize - 1))
            {
                SI2C->Error.H |= Sample_I2C_Error_Over;
                SI2C->State.B |= Sample_I2C_State_Error;
            }

            do{
                if(__I2C_GetEventFlag(SI2C->Instance) != 0)
                {
                    SI2C->XferCount ++;
                    __I2C_ClearEventFlag(SI2C->Instance);
                }
            }while(__I2C_GetEventCode(SI2C->Instance) == 0xC8);

            __I2C_IT_Disable(SI2C->Instance, (I2C_IT_EVENT | I2C_IT_BUF |I2C_IT_ERR));
            SI2C->Control.H &= ~(Sample_I2C_DMA_MTx | Sample_I2C_DMA_MRx | Sample_I2C_DMA_SRx | Sample_I2C_DMA_STx);
            if((SI2C->Control.H & Sample_I2C_Listen) != 0)
            {
                __I2C_SlaveAddressDetect_Enable(SI2C->Instance, I2C_SADR_1);

                if(SI2C->Init.DualAddressMode != 0)
                __I2C_SlaveAddressDetect_Enable(SI2C->Instance, I2C_SADR_2);

                if(SI2C->Init.GeneralCallMode != 0)
                __I2C_SlaveAddressDetect_Enable(SI2C->Instance, I2C_SADR_0);

                Set_ASSERT_ACKNOWLEDGE_SET(SI2C->Instance);
                SI2C->State.B |= Sample_I2C_State_Listen;
            }
            else
            {
                __I2C_SlaveAddressDetect_Disable(SI2C->Instance, (I2C_SADR_0 | I2C_SADR_1 | I2C_SADR_2));
                Set_STA_STO_AA_000(SI2C->Instance);
                SI2C->State.B &= ~Sample_I2C_State_Listen;
            }
            SI2C->State.B &= ~Sample_I2C_State_Busy;
            break;

//-------------------------------------
//        case 0xD0: 
//        case 0xD8:
//        case 0xE0:
//        case 0xE8:
//        case 0xF0:
//-------------------------------------      
        case 0xF8:  // Bus Idle

        default:
            break;
    }
    __I2C_ClearEventFlag(SI2C->Instance);
}


/**
 *******************************************************************************
 * @brief       I2C Enable Listen
 * @details     
 * @param[in]   SI2C : Sample_I2C pointer to a Sample_I2C_HandleTypeDef 
 *              structure that contains the configuration information for the
 *              specified I2C.
 * @return      SMP Return
 *         \n     SMP_Success : Address Listen Mode.
 *         \n     SMP_Failure : Data access process is ongoing.
 * @exception   None
 * @note        
 * @par         Example
 * @code        
                while(Sample_I2C_Get_Listen_State(&gSI2C1) != SMP_Success);
                if(Sample_I2C_Get_Listen_State(&gSI2C1) == SMP_Success)
                if(Sample_I2C_Get_Listen_State(&gSI2C1) != SMP_Success)
 * @endcode     
 * @par         Modify
 *              SMP_Return Sample_I2C_Get_Listen_State(Sample_I2C_HandleTypeDef *SI2C)
 *******************************************************************************
 */
SMP_Return Sample_I2C_Enable_Listen(Sample_I2C_HandleTypeDef *SI2C)
{
    if((SI2C->State.B & Sample_I2C_State_Ready) == 0)
        return SMP_Failure;

    if((SI2C->State.B & Sample_I2C_State_Busy) != 0)
        if((SI2C->State.B & Sample_I2C_State_Listen) == 0)
            return SMP_Failure;

    //---- Disable All Interrupt --------
    __I2C_IT_Disable(SI2C->Instance, I2C_IT_ERR | I2C_IT_BUF | I2C_IT_EVENT); // Disable Interrupt

    //---- Clear I2C Flag ---------------
    __I2C_ClearFlag(SI2C->Instance, (I2C_FLAG_NACKF | I2C_FLAG_ALOSF | I2C_FLAG_BERRF | I2C_FLAG_ROVRF | I2C_FLAG_TOVRF | I2C_FLAG_STOPF | I2C_FLAG_RSTRF));

    //---- Enable Listen ------
    __I2C_SlaveAddressDetect_Enable(SI2C->Instance, I2C_SADR_1);

    if(SI2C->Init.DualAddressMode != 0)
        __I2C_SlaveAddressDetect_Enable(SI2C->Instance, I2C_SADR_2);

    if(SI2C->Init.GeneralCallMode != 0)
        __I2C_SlaveAddressDetect_Enable(SI2C->Instance, I2C_SADR_0);

    Set_ASSERT_ACKNOWLEDGE_SET(SI2C->Instance);

    //-----Set_Config-----------------------
    SI2C->Control.H |= Sample_I2C_Listen;

    SI2C->State.B |= Sample_I2C_State_Listen;

    return SMP_Success;
}


/**
 *******************************************************************************
 * @brief       I2C Is Device Ready
 * @details     Checks if target device is ready for communication.
 * @param[in]   SI2C : Sample_I2C pointer to a Sample_I2C_HandleTypeDef 
 *              structure that contains the configuration information for the
 *              specified I2C.
 * @param[in]   DevAddress : Target device address: The device 7 bits address
 *              value in datasheet must be shift at right before call interface.
 * @param[in]   Trials : Number of trials
 * @return      DRV status
 * @exception   None
 * @note        
 * @par         Example
 * @code        
                if(Sample_I2C_IsDeviceReady(&gSI2C1, 0xA0, (uint8_t *)&DataBuffer, 256) != DRV_Success)
 * @endcode     
 * @par         Modify
 *              DRV_Return Sample_I2C_IsDeviceReady(Sample_I2C_HandleTypeDef *SI2C, uint16_t DevAddress, uint32_t Trials)
 *******************************************************************************
 */
SMP_Return Sample_I2C_IsDeviceReady(Sample_I2C_HandleTypeDef *SI2C, uint16_t DevAddress, uint32_t Trials)
{
    volatile uint8_t lEventTemp;

//-----Check---------------------------
    if((SI2C->State.B & Sample_I2C_State_Ready) == 0)
        return SMP_Failure;

//----- State Check -------------------
    if(__I2C_GetFlagStatus(SI2C->Instance, I2C_FLAG_BUSYF) != CLR)
        if(__I2C_GetEventFlag(SI2C->Instance) != 0)
        {
            lEventTemp = __I2C_GetEventCode(SI2C->Instance);
            if((lEventTemp != 0x08) && (lEventTemp != 0x10))
                return SMP_Busy;
        }

//---- Disable All Interrupt --------
    __I2C_IT_Disable(SI2C->Instance, I2C_IT_ERR | I2C_IT_BUF | I2C_IT_EVENT); // Disable Interrupt

//---- Clear I2C Flag ---------------
    __I2C_ClearFlag(SI2C->Instance, (I2C_FLAG_NACKF | I2C_FLAG_ALOSF | I2C_FLAG_BERRF | I2C_FLAG_ROVRF | I2C_FLAG_TOVRF | I2C_FLAG_STOPF | I2C_FLAG_RSTRF));

//-----Set_Config-----------------------
    do{
        SI2C->State.B = (SI2C->State.B & (~(Sample_I2C_State_Busy_Rx | Sample_I2C_State_Error))) | Sample_I2C_State_Busy_Tx;
        SI2C->Error.H = 0;
        SI2C->SlaveAddress = (uint8_t)(DevAddress & 0xFFFE);
        SI2C->pBuffer = 0x00000000;
        SI2C->XferSize = 0;
        SI2C->XferCount = 0;
        SI2C->Control.H = (SI2C->Control.H & (~Sample_I2C_XferNext_Mask)) | Sample_I2C_XferNext_STOP;

//-----Start----------------------------
        if(__I2C_GetEventCode(SI2C->Instance) == 0xF8)
            Set_STA_STO_AA_100(SI2C->Instance);

        do{
            Sample_I2C_ByteMode_Handle(SI2C);
        }while(SI2C->State.MBit.Busy != 0);

        if((SI2C->State.B & Sample_I2C_State_Error) == 0)
            return SMP_Success;

        Sample_I2C_Delay(1);

    }while(-- Trials > 0);
    return SMP_Failure;
}


/**
 *******************************************************************************
 * @brief       for I2C Dlelay
 * @details     ms Delay.
 *              
 * @param[in]   Delay : Delay Time. unit ms.
 * @return      No
 * @exception   None
 * @note        
 * @par         Example
 * @code        
                Sample_I2C_Delay(20);
                Sample_I2C_Delay(5);
 * @endcode     
 * @par         Modify
 *              void Sample_I2C_Delay(uint32_t Delay)
 *******************************************************************************
 */
void Sample_I2C_Delay(uint32_t Delay)
{
    //=========================================================
    //Prevent unused argument compilcation warning
    ((void)(Delay));
    
    // to do ...
}

/**
 *******************************************************************************
 * @brief       I2C Byte Mode Master Transmit
 * @details     Transmits in master mode an amount of data in blocking mode.
 * @param[in]   SI2C : Sample_I2C pointer to a Sample_I2C_HandleTypeDef 
 *              structure that contains the configuration information for the
 *              specified I2C.
 * @param[in]   DevAddress : Target device address: The device 7 bits address
 *              value in datasheet must be shift at right before call interface.
 * @param[in]   pBuffer : Pointer to data buffer.
 * @param[in]   Size : Amount of data to be sent.
 * @return      DRV status
 * @exception   None
 * @note        
 * @par         Example
 * @code        
                Sample_I2C_ByteMode_MasterTransmit(&gSI2C1, 0xA0, (uint8_t *)&DataBuffer, 256);
 * @endcode     
 * @par         Modify
 *              DRV_Return Sample_I2C_ByteMode_MasterTransmit(Sample_I2C_HandleTypeDef *SI2C, uint16_t DevAddress, uint8_t *pBuffer, uint16_t Size)
 *******************************************************************************
 */
SMP_Return Sample_I2C_ByteMode_MasterTransmit(Sample_I2C_HandleTypeDef *SI2C, uint16_t DevAddress, uint8_t *pBuffer, uint16_t Size)
{
    volatile uint8_t lEventTemp;

    //-----Check---------------------------
    if((SI2C->State.B & Sample_I2C_State_Ready) == 0)
        return SMP_Failure;

    //----- State Check -------------------
    if(__I2C_GetFlagStatus(SI2C->Instance, I2C_FLAG_BUSYF) != CLR)
        if(__I2C_GetEventFlag(SI2C->Instance) != 0)
        {
            lEventTemp = __I2C_GetEventCode(SI2C->Instance);
            if((lEventTemp != 0x08) && (lEventTemp != 0x10))
                return SMP_Busy;
        }

    //---- Disable All Interrupt --------
    __I2C_IT_Disable(SI2C->Instance, I2C_IT_ERR | I2C_IT_BUF | I2C_IT_EVENT); // Disable Interrupt

    //---- Clear I2C Flag ---------------
    __I2C_ClearFlag(SI2C->Instance, (I2C_FLAG_NACKF | I2C_FLAG_ALOSF | I2C_FLAG_BERRF | I2C_FLAG_ROVRF | I2C_FLAG_TOVRF | I2C_FLAG_STOPF | I2C_FLAG_RSTRF));

    //-----Set_Config-----------------------
    SI2C->State.B = (SI2C->State.B & (~(Sample_I2C_State_Busy_Rx | Sample_I2C_State_Error))) | Sample_I2C_State_Busy_Tx;
    SI2C->Error.H = 0;
    SI2C->SlaveAddress = (uint8_t)DevAddress & 0xFFFE;
    SI2C->pBuffer = pBuffer;
    SI2C->XferSize = Size;
    SI2C->XferCount = 0;
    SI2C->Control.H = (SI2C->Control.H & (~Sample_I2C_XferNext_Mask)) | Sample_I2C_XferNext_STOP;

    //-----Start----------------------------
    if(__I2C_GetEventCode(SI2C->Instance) == 0xF8)
        Set_STA_STO_AA_100(SI2C->Instance);

    do{
        Sample_I2C_ByteMode_Handle(SI2C);
    }while(SI2C->State.MBit.Busy != 0);

    if((SI2C->State.B & Sample_I2C_State_Error) == Sample_I2C_State_Timeout)
        return SMP_Timeout;

    if((SI2C->State.B & Sample_I2C_State_Error) == Sample_I2C_State_Error)
        return SMP_Failure;

    return SMP_Success;
}


