/**
 ******************************************************************************
 *
 * @file        Sample_I2C_ByteMode.c
 *
 * @brief       This is the Sample I2C Byte Mode Transfer C code format file.
 *
 * @par         Project
 *              MG32
 * @version     V2.26
 * @date        2023/05/29
 * @author      Megawin Software Center
 * @copyright   Copyright (c) 2023 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 "Sample_I2C_ByteMode.h"
#include "Sample__Common.h"

/* Wizard menu ---------------------------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
#if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) /* ARM Compiler V6 */
  #pragma clang diagnostic push
  #pragma clang diagnostic ignored "-Wmissing-variable-declarations"
#endif
    Sample_I2C_HandleTypeDef gSI2C0;    /*!< for I2C0                       */
    Sample_I2C_HandleTypeDef gSI2C1;    /*!< for I2C1                       */

    const uint8_t String0[] = {" Welcome use MEGAWIN ARM Coretex-M0 Series MG32 Product"}; /*!< I2C Tx pattern  */
    uint8_t gRXBuffer[80];          /*!< I2C Rx Buffer                      */
    uint8_t gTXBuffer[80] = {" Welcome use MEGAWIN ARM Coretex-M0 Series MG32 Product"};   /*!< I2C Tx Buffer   */
    uint8_t EEPROM_Address = 0x00;  /*!< I2C                                */
#if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) /* ARM Compiler V6 */
  #pragma clang diagnostic pop
#endif

/* Private function prototypes -----------------------------------------------*/
void Sample_I2C0_ByteMode(void);
void I2C0_IRQHandler(void);
#if defined(MG32_1ST) || defined(MG32_3RD) || defined(MG32_4TH)  || defined(MG32_5TH)
    void Sample_I2C1_ByteMode(void);
    void I2Cx_IRQHandler(void);
#endif
void DMA_IRQHandler(void);
SMP_Return Sample_I2C_DeInit(Sample_I2C_HandleTypeDef *SI2C);
SMP_Return Sample_I2C_ByteMode_Init(Sample_I2C_HandleTypeDef *SI2C);
void Sample_I2C_Delay(uint32_t Delay);

/* Exported variables --------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
/* External vairables --------------------------------------------------------*/
extern SMP_Return Sample_DMA_Init(void);
extern SMP_Return Sample_DMA_M2P_IT(DMAChannel_Struct* DMACHx, uint32_t SourceAddress, DMA_DestinationRequestDef DestinationPeripheral, uint32_t Length);
extern SMP_Return Sample_DMA_P2M_IT(DMAChannel_Struct* DMACHx, DMA_SourcenRequestDef SourcePeripheral, uint32_t DestinationAddress, uint32_t Length);
extern SMP_Return Sample_DMAChannel_IT_Handle(DMAChannel_Struct* DMACHx);

/**
 *******************************************************************************
 * @brief       Initialize the I2C0 peripheral for byte-mode
 * @details     1. I2C Initialze
 *      \n      2. Check Target device Ready
 *      \n      3. Write Data to Target device.
 *      \n      4. Read Data from Target device.
 * @exception   None
 * @note        
 * @par         Example
 * @code        
                Sample_I2C_ByteMode_Init(&I2C0_Init);
 * @endcode     
 * @par         Modify
 *              DRV_Return Sample_I2C_ByteMode_Init(Sample_I2C_InitTypeDef *sI2C)
 *******************************************************************************
 */
void Sample_I2C0_ByteMode(void)
{
    Sample_DMA_Init();

//-----------------------------------------------------------------------------
    gSI2C0.Instance = I2C0;
    gSI2C0.Init.CK_I2C_PR_Frequency = 48000000;
    gSI2C0.Init.SCL_Clock = 1000000;
    gSI2C0.Init.OwnAddress1 = 0xA0;  /*!< Bit[7:1]Device Address */
                                     /*   Bit0 Read / Write */
//    gSI2C0.DMACHx = DMAChannel0;

//    DRV_Return Sample_I2C_ByteMode_Init(Sample_I2C_InitTypeDef *sI2C);
    Sample_I2C_ByteMode_Init(&gSI2C0);

    Sample_I2C_Enable_Listen(&gSI2C0);

//    Sample_I2C_Disable_Listen(&gSI2C0);

//-----------------------------------------------------------------------------
#if defined(MG32_2ND)
#else
    gSI2C1.Instance = I2C1;
    gSI2C1.Init.CK_I2C_PR_Frequency = 48000000;
    gSI2C1.Init.SCL_Clock = 700000;
    gSI2C1.Init.OwnAddress1 = 0x40;

    gSI2C1.DMACHx = DMAChannel0;

//  DRV_Return Sample_I2C_ByteMode_Init(Sample_I2C_InitTypeDef *sI2C);
    Sample_I2C_ByteMode_Init(&gSI2C1);

    Sample_I2C_Enable_Listen(&gSI2C1);

//    Sample_I2C_Disable_Listen(&gSI2C1);
#endif

/*=============================================================================*/
/******* Blocking mode: Polling */
//    SMP_Return Sample_I2C_IsDeviceReady(Sample_I2C_HandleTypeDef *SI2C, uint16_t DevAddress, uint32_t Trials)
    if(Sample_I2C_IsDeviceReady(&gSI2C0, (uint16_t)0xA0, 10) != SMP_Success)
        printf("Target device is not ready\n\r");

//    SMP_Return Sample_I2C_ByteMode_MasterTransmit(Sample_I2C_HandleTypeDef *SI2C, uint16_t DevAddress, uint8_t *pData, uint16_t Lenth)
    if(Sample_I2C_ByteMode_MasterTransmit(&gSI2C0, (uint16_t)0xA0, (uint8_t *)gTXBuffer, (sizeof(String0)-1)) != SMP_Success)
        printf("Mater transmited data fail\n\r");

//-----------------------------------------------------------------------------
//    SMP_Return Sample_I2C_IsDeviceReady(Sample_I2C_HandleTypeDef *SI2C, uint16_t DevAddress, uint32_t Trials)
    if(Sample_I2C_IsDeviceReady(&gSI2C0, (uint16_t)0xA0, 10) != SMP_Success)
        printf("Target device is not ready\n\r");

//    SMP_Return Sample_I2C_ByteMode_MasterTransmit_RepeatStart(Sample_I2C_HandleTypeDef *SI2C, uint16_t DevAddress, uint8_t *pData, uint16_t Lenth)
    if(Sample_I2C_ByteMode_MasterTransmit_RepeatStart(&gSI2C0, (uint16_t)0xA0, (uint8_t *)&EEPROM_Address, 1) != SMP_Success)
        printf("Mater transmited Interrupt fail\n\r");
    while(Sample_I2C_Get_Transfer_State(&gSI2C0) == SMP_Busy);

//    SMP_Return Sample_I2C_ByteMode_MasterReceive(Sample_I2C_HandleTypeDef *SI2C, uint16_t DevAddress, uint8_t *pData, uint16_t Lenth)
    if(Sample_I2C_ByteMode_MasterReceive(&gSI2C0, (uint16_t)0xA0, (uint8_t *)gRXBuffer, (sizeof(String0)-1)) != SMP_Success)
        printf("Mater received data fail\n\r");

//-----------------------------------------------------------------------------
//    SMP_Return Sample_I2C_ByteMode_SlaveReceive_IT(Sample_I2C_HandleTypeDef *SI2C, uint8_t *pData, uint16_t Lenth)
    if(Sample_I2C_ByteMode_SlaveReceive(&gSI2C0, (uint8_t *)gRXBuffer, (sizeof(String0)-1)) != SMP_Success)
        printf("Slave received data fail\n\r");

//-----------------------------------------------------------------------------
//    SMP_Return Sample_I2C_ByteMode_SlaveTransmit(Sample_I2C_HandleTypeDef *SI2C, uint8_t *pData, uint16_t Lenth)
    if(Sample_I2C_ByteMode_SlaveTransmit(&gSI2C0, (uint8_t *)gTXBuffer, (sizeof(String0)-1)) != SMP_Success)
        printf("Slave transmited data fail\n\r");

/*=============================================================================*/
/******* Non-Blocking mode: Interrupt */
//    SMP_Return Sample_I2C_IsDeviceReady(Sample_I2C_HandleTypeDef *SI2C, uint16_t DevAddress, uint32_t Trials)
    if(Sample_I2C_IsDeviceReady(&gSI2C0, (uint16_t)0xA0, 10) != SMP_Success)
        printf("Target device is not ready\n\r");

    gTXBuffer[0] = 0;

//    SMP_Return Sample_I2C_ByteMode_MasterTransmit_IT(Sample_I2C_HandleTypeDef *SI2C, uint16_t DevAddress, uint8_t *pData, uint16_t Lenth)
    if(Sample_I2C_ByteMode_MasterTransmit_IT(&gSI2C0, (uint16_t)0xA0, (uint8_t *)gTXBuffer, 17) != SMP_Success)
        printf("Mater transmited Interrupt fail\n\r");
    while(Sample_I2C_Get_Transfer_State(&gSI2C0) == SMP_Busy);

//-----------------------------------------------------------------------------
//    SMP_Return Sample_I2C_IsDeviceReady(Sample_I2C_HandleTypeDef *SI2C, uint16_t DevAddress, uint32_t Trials)
    if(Sample_I2C_IsDeviceReady(&gSI2C0, (uint16_t)0xA0, 10) != SMP_Success)
        printf("Target device is not ready\n\r");

//    SMP_Return Sample_I2C_ByteMode_MasterTransmit_IT_RepeatStart(Sample_I2C_HandleTypeDef *SI2C, uint16_t DevAddress, uint8_t *pData, uint16_t Lenth)
    if(Sample_I2C_ByteMode_MasterTransmit_IT_RepeatStart(&gSI2C0, (uint16_t)0xA0, (uint8_t *)&EEPROM_Address, 1) != SMP_Success)
        printf("Mater transmited Interrupt fail\n\r");
    while(Sample_I2C_Get_Transfer_State(&gSI2C0) == SMP_Busy);

//    SMP_Return Sample_I2C_ByteMode_MasterReceive_IT(Sample_I2C_HandleTypeDef *SI2C, uint16_t DevAddress, uint8_t *pData, uint16_t Lenth)
    if(Sample_I2C_ByteMode_MasterReceive_IT(&gSI2C0, (uint16_t)0xA0, (uint8_t *)gRXBuffer, 16) != SMP_Success)
        printf("Mater received data fail\n\r");
    while(Sample_I2C_Get_Transfer_State(&gSI2C0) == SMP_Busy);

//-----------------------------------------------------------------------------
//    SMP_Return Sample_I2C_ByteMode_SlaveReceive_IT(Sample_I2C_HandleTypeDef *SI2C, uint8_t *pData, uint16_t Lenth)
    if(Sample_I2C_ByteMode_SlaveReceive_IT(&gSI2C0, (uint8_t *)gRXBuffer, (sizeof(String0)-1)) != SMP_Success)
        printf("Slave received data fail\n\r");
    while(Sample_I2C_Get_Listen_State(&gSI2C0) == SMP_Busy);
    while(Sample_I2C_Get_Transfer_State(&gSI2C0) == SMP_Busy);

//-----------------------------------------------------------------------------
//    SMP_Return Sample_I2C_ByteMode_SlaveTransmit_IT(Sample_I2C_HandleTypeDef *SI2C, uint8_t *pData, uint16_t Lenth)
    if(Sample_I2C_ByteMode_SlaveTransmit_IT(&gSI2C0, (uint8_t *)gTXBuffer, (sizeof(String0)-1)) != SMP_Success)
        printf("Slave transmited data fail\n\r");
    while(Sample_I2C_Get_Listen_State(&gSI2C0) == SMP_Busy);
    while(Sample_I2C_Get_Transfer_State(&gSI2C0) == SMP_Busy);

/*=============================================================================*/
/******* Non-Blocking mode: DMA */
//    SMP_Return Sample_I2C_IsDeviceReady(Sample_I2C_HandleTypeDef *SI2C, uint16_t DevAddress, uint32_t Trials)
    if(Sample_I2C_IsDeviceReady(&gSI2C0, (uint16_t)0xA0, 10) != SMP_Success)
        printf("Target device is not ready\n\r");

//    SMP_Return Sample_I2C_ByteMode_MasterTransmit_DMA(Sample_I2C_HandleTypeDef *SI2C, uint16_t DevAddress, uint8_t *pData, uint16_t Lenth)
    if(Sample_I2C_ByteMode_MasterTransmit_DMA(&gSI2C0, (uint16_t)0xA0, (uint8_t *)gTXBuffer, (sizeof(String0)-1)) != SMP_Success)
        printf("Mater transmited data fail\n\r");
    while(Sample_I2C_Get_Transfer_State(&gSI2C0) == SMP_Busy);

//-----------------------------------------------------------------------------
//    SMP_Return Sample_I2C_IsDeviceReady(Sample_I2C_HandleTypeDef *SI2C, uint16_t DevAddress, uint32_t Trials)
    if(Sample_I2C_IsDeviceReady(&gSI2C0, (uint16_t)0xA0, 10) != SMP_Success)
        printf("Target device is not ready\n\r");

//    SMP_Return Sample_I2C_ByteMode_MasterTransmit_DMA_RepeatStart(Sample_I2C_HandleTypeDef *SI2C, uint16_t DevAddress, uint8_t *pData, uint16_t Lenth)
    if(Sample_I2C_ByteMode_MasterTransmit_DMA_RepeatStart(&gSI2C0, (uint16_t)0xA0, (uint8_t *)&EEPROM_Address, 1) != SMP_Success)
        printf("Mater transmited Interrupt fail\n\r");
    while(Sample_I2C_Get_Transfer_State(&gSI2C0) == SMP_Busy);

//    SMP_Return Sample_I2C_ByteMode_MasterReceive_DMA(Sample_I2C_HandleTypeDef *SI2C, uint16_t DevAddress, uint8_t *pData, uint16_t Lenth)
    if(Sample_I2C_ByteMode_MasterReceive_DMA(&gSI2C0, (uint16_t)0xA0, (uint8_t *)gRXBuffer, (sizeof(String0)-1)) != SMP_Success)
        printf("Mater received data fail\n\r");
    while(Sample_I2C_Get_Transfer_State(&gSI2C0) == SMP_Busy);

//-----------------------------------------------------------------------------
//    SMP_Return Sample_I2C_ByteMode_SlaveReceive_DMA(Sample_I2C_HandleTypeDef *SI2C, uint8_t *pData, uint16_t Lenth)
    if(Sample_I2C_ByteMode_SlaveReceive_DMA(&gSI2C0, (uint8_t *)gRXBuffer, (sizeof(String0)-1)) != SMP_Success)
        printf("Slave received data fail\n\r");
    while(Sample_I2C_Get_Listen_State(&gSI2C0) == SMP_Busy);
    while(Sample_I2C_Get_Transfer_State(&gSI2C0) == SMP_Busy);

//-----------------------------------------------------------------------------
//    SMP_Return Sample_I2C_ByteMode_SlaveTransmit_DMA(Sample_I2C_HandleTypeDef *SI2C, uint8_t *pData, uint16_t Lenth)
    if(Sample_I2C_ByteMode_SlaveTransmit_DMA(&gSI2C0, (uint8_t *)gTXBuffer, (sizeof(String0)-1)) != SMP_Success)
        printf("Slave transmited data fail\n\r");
    while(Sample_I2C_Get_Listen_State(&gSI2C0) == SMP_Busy);
    while(Sample_I2C_Get_Transfer_State(&gSI2C0) == SMP_Busy);

/*=============================================================================*/
/******* Non-Blocking mode: Slave Interrup Rx to DMA Tx*/
//    SMP_Return Sample_I2C_ByteMode_SlaveReceive_IT(Sample_I2C_HandleTypeDef *SI2C, uint8_t *pData, uint16_t Lenth)
    if(Sample_I2C_ByteMode_SlaveReceive_IT(&gSI2C0, (uint8_t *)gRXBuffer, (sizeof(String0)-1)) != SMP_Success)
        printf("Slave received data fail\n\r");
    while(Sample_I2C_Get_Listen_State(&gSI2C0) == SMP_Busy);
    while(Sample_I2C_Get_Transfer_State(&gSI2C0) == SMP_Busy);

    Delay(1);

//    SMP_Return Sample_I2C_ByteMode_SlaveTransmit_DMA(Sample_I2C_HandleTypeDef *SI2C, uint8_t *pData, uint16_t Lenth)
    if(Sample_I2C_ByteMode_SlaveTransmit_DMA(&gSI2C0, (uint8_t *)gTXBuffer, (sizeof(String0)-1)) != SMP_Success)
        printf("Slave transmited data fail\n\r");
    while(Sample_I2C_Get_Listen_State(&gSI2C0) == SMP_Busy);
    while(Sample_I2C_Get_Transfer_State(&gSI2C0) == SMP_Busy);
}



/**
 *******************************************************************************
 * @brief       Interrupt Handler the I2C0 peripheral
 * @details     
 * @exception   None
 * @note        
 * @par         Example
 * @code        
                void I2C0_IRQHandler(void)
 * @endcode     
 * @par         Modify
 *              void I2C0_IRQHandler(void)
 *******************************************************************************
 */
void I2C0_IRQHandler(void)
{
    // void Sample_I2C_ByteMode_Handle(Sample_I2C_HandleTypeDef *Sample_I2C);
    Sample_I2C_ByteMode_Handle(&gSI2C0);
}



#if defined(MG32_1ST) || defined(MG32_3RD) || defined(MG32_4TH) || defined(MG32_5TH)
/**
 *******************************************************************************
 * @brief       Initialize the I2C1 peripheral for byte-mode
 * @details     1. I2C Initialze
 *      \n      2. Check Target device Ready
 *      \n      3. Write Data to Target device.
 *      \n      4. Read Data from Target device.
 *
 * @return      No
 * @exception   None
 * @note        
 * @par         Example
 * @code        
                Sample_I2C_ByteMode_Init(&I2C1_Init);
 * @endcode     
 * @par         Modify
 *              DRV_Return Sample_I2C_ByteMode_Init(Sample_I2C_InitTypeDef *sI2C)
 *******************************************************************************
 */
void Sample_I2C1_ByteMode(void)
{
    gSI2C1.Instance = I2C1;
    gSI2C1.Init.CK_I2C_PR_Frequency = 48000000;
    gSI2C1.Init.SCL_Clock = 700000;
    gSI2C1.Init.OwnAddress1 = 0x40;

    gSI2C1.DMACHx = DMAChannel0;

//  DRV_Return Sample_I2C_ByteMode_Init(Sample_I2C_InitTypeDef *sI2C);
    Sample_I2C_ByteMode_Init(&gSI2C1);

    Sample_I2C_Enable_Listen(&gSI2C1);

//    Sample_I2C_Disable_Listen(&gSI2C1);

/*=============================================================================*/
/******* Blocking mode: Polling */
//    SMP_Return Sample_I2C_IsDeviceReady(Sample_I2C_HandleTypeDef *SI2C, uint16_t DevAddress, uint32_t Trials)
    if(Sample_I2C_IsDeviceReady(&gSI2C1, (uint16_t)0xA0, 10) != SMP_Success)
        printf("Target device is not ready\n\r");

//    SMP_Return Sample_I2C_ByteMode_MasterTransmit(Sample_I2C_HandleTypeDef *SI2C, uint16_t DevAddress, uint8_t *pData, uint16_t Lenth)
    if(Sample_I2C_ByteMode_MasterTransmit(&gSI2C1, (uint16_t)0xA0, (uint8_t *)gTXBuffer, (sizeof(String0)-1)) != SMP_Success)
        printf("Mater transmited data fail\n\r");

//    SMP_Return Sample_I2C_ByteMode_MasterReceive(Sample_I2C_HandleTypeDef *SI2C, uint16_t DevAddress, uint8_t *pData, uint16_t Lenth)
    if(Sample_I2C_ByteMode_MasterReceive(&gSI2C1, (uint16_t)0xA0, (uint8_t *)gRXBuffer, (sizeof(String0)-1)) != SMP_Success)
        printf("Mater received data fail\n\r");

//    SMP_Return Sample_I2C_ByteMode_SlaveReceive_IT(Sample_I2C_HandleTypeDef *SI2C, uint8_t *pData, uint16_t Lenth)
    if(Sample_I2C_ByteMode_SlaveReceive(&gSI2C1, (uint8_t *)gRXBuffer, (sizeof(String0)-1)) != SMP_Success)
        printf("Slave received data fail\n\r");

//    SMP_Return Sample_I2C_ByteMode_SlaveTransmit(Sample_I2C_HandleTypeDef *SI2C, uint8_t *pData, uint16_t Lenth)
    if(Sample_I2C_ByteMode_SlaveTransmit(&gSI2C1, (uint8_t *)gTXBuffer, (sizeof(String0)-1)) != SMP_Success)
        printf("Slave transmited data fail\n\r");

/*=============================================================================*/
/******* Non-Blocking mode: Interrupt */

//    SMP_Return Sample_I2C_IsDeviceReady(Sample_I2C_HandleTypeDef *SI2C, uint16_t DevAddress, uint32_t Trials)
    if(Sample_I2C_IsDeviceReady(&gSI2C1, (uint16_t)0xA0, 10) != SMP_Success)
        printf("Target device is not ready\n\r");

//    SMP_Return Sample_I2C_ByteMode_MasterTransmit_IT(Sample_I2C_HandleTypeDef *SI2C, uint16_t DevAddress, uint8_t *pData, uint16_t Lenth)
    if(Sample_I2C_ByteMode_MasterTransmit_IT(&gSI2C1, (uint16_t)0xA0, (uint8_t *)gTXBuffer, (sizeof(String0)-1)) != SMP_Success)
        printf("Mater transmited Interrupt fail\n\r");

    if(Sample_I2C_Get_Listen_State(&gSI2C1) != SMP_Success)
        __NOP();
    while(Sample_I2C_Get_Transfer_State(&gSI2C1) == SMP_Busy);

//    SMP_Return Sample_I2C_ByteMode_MasterReceive_IT(Sample_I2C_HandleTypeDef *SI2C, uint16_t DevAddress, uint8_t *pData, uint16_t Lenth)
    if(Sample_I2C_ByteMode_MasterReceive_IT(&gSI2C1, (uint16_t)0xA0, (uint8_t *)gRXBuffer, (sizeof(String0)-1)) != SMP_Success)
        printf("Mater received data fail\n\r");
    while(Sample_I2C_Get_Transfer_State(&gSI2C1) == SMP_Busy);

//    SMP_Return Sample_I2C_ByteMode_SlaveReceive_IT(Sample_I2C_HandleTypeDef *SI2C, uint8_t *pData, uint16_t Lenth)
    if(Sample_I2C_ByteMode_SlaveReceive_IT(&gSI2C1, (uint8_t *)gRXBuffer, (sizeof(String0)-1)) != SMP_Success)
        printf("Slave received data fail\n\r");
    while(Sample_I2C_Get_Listen_State(&gSI2C1) == SMP_Busy);
    while(Sample_I2C_Get_Transfer_State(&gSI2C1) == SMP_Busy);

//    SMP_Return Sample_I2C_ByteMode_SlaveTransmit_IT(Sample_I2C_HandleTypeDef *SI2C, uint8_t *pData, uint16_t Lenth)
    if(Sample_I2C_ByteMode_SlaveTransmit_IT(&gSI2C1, (uint8_t *)gTXBuffer, (sizeof(String0)-1)) != SMP_Success)
        printf("Slave transmited data fail\n\r");
    while(Sample_I2C_Get_Listen_State(&gSI2C1) == SMP_Busy);
    while(Sample_I2C_Get_Transfer_State(&gSI2C1) == SMP_Busy);

/*=============================================================================*/
/******* Non-Blocking mode: DMA */
//    SMP_Return Sample_I2C_IsDeviceReady(Sample_I2C_HandleTypeDef *SI2C, uint16_t DevAddress, uint32_t Trials)
    if(Sample_I2C_IsDeviceReady(&gSI2C1, (uint16_t)0xA0, 10) != SMP_Success)
        printf("Target device is not ready\n\r");

//    SMP_Return Sample_I2C_ByteMode_MasterTransmit_DMA(Sample_I2C_HandleTypeDef *SI2C, uint16_t DevAddress, uint8_t *pData, uint16_t Lenth)
    if(Sample_I2C_ByteMode_MasterTransmit_DMA(&gSI2C1, (uint16_t)0xA0, (uint8_t *)gTXBuffer, (sizeof(String0)-1)) != SMP_Success)
        printf("Mater transmited data fail\n\r");
    while(Sample_I2C_Get_Transfer_State(&gSI2C1) == SMP_Busy);

//    SMP_Return Sample_I2C_ByteMode_MasterReceive_DMA(Sample_I2C_HandleTypeDef *SI2C, uint16_t DevAddress, uint8_t *pData, uint16_t Lenth)
    if(Sample_I2C_ByteMode_MasterReceive_DMA(&gSI2C1, (uint16_t)0xA0, (uint8_t *)gRXBuffer, (sizeof(String0)-1)) != SMP_Success)
        printf("Mater received data fail\n\r");
    while(Sample_I2C_Get_Transfer_State(&gSI2C1) == SMP_Busy);

//    SMP_Return Sample_I2C_ByteMode_SlaveReceive_DMA(Sample_I2C_HandleTypeDef *SI2C, uint8_t *pData, uint16_t Lenth)
    if(Sample_I2C_ByteMode_SlaveReceive_DMA(&gSI2C1, (uint8_t *)gRXBuffer, (sizeof(String0)-1)) != SMP_Success)
        printf("Slave received data fail\n\r");
    while(Sample_I2C_Get_Listen_State(&gSI2C1) == SMP_Busy);
    while(Sample_I2C_Get_Transfer_State(&gSI2C1) == SMP_Busy);

//    SMP_Return Sample_I2C_ByteMode_SlaveTransmit_DMA(Sample_I2C_HandleTypeDef *SI2C, uint8_t *pData, uint16_t Lenth)
    if(Sample_I2C_ByteMode_SlaveTransmit_DMA(&gSI2C1, (uint8_t *)gTXBuffer, (sizeof(String0)-1)) != SMP_Success)
        printf("Slave transmited data fail\n\r");
    while(Sample_I2C_Get_Listen_State(&gSI2C1) == SMP_Busy);
    while(Sample_I2C_Get_Transfer_State(&gSI2C1) == SMP_Busy);

/*=============================================================================*/
/******* Non-Blocking mode: Slave Interrup Rx to DMA Tx*/
//    SMP_Return Sample_I2C_ByteMode_SlaveReceive_IT(Sample_I2C_HandleTypeDef *SI2C, uint8_t *pData, uint16_t Lenth)
    if(Sample_I2C_ByteMode_SlaveReceive_IT(&gSI2C1, (uint8_t *)gRXBuffer, (sizeof(String0)-1)) != SMP_Success)
        printf("Slave received data fail\n\r");
    while(Sample_I2C_Get_Listen_State(&gSI2C1) == SMP_Busy);
    while(Sample_I2C_Get_Transfer_State(&gSI2C1) == SMP_Busy);

//    SMP_Return Sample_I2C_ByteMode_SlaveTransmit_DMA(Sample_I2C_HandleTypeDef *SI2C, uint8_t *pData, uint16_t Lenth)
    if(Sample_I2C_ByteMode_SlaveTransmit_DMA(&gSI2C1, (uint8_t *)gTXBuffer, (sizeof(String0)-1)) != SMP_Success)
        printf("Slave transmited data fail\n\r");
    while(Sample_I2C_Get_Listen_State(&gSI2C1) == SMP_Busy);
    while(Sample_I2C_Get_Transfer_State(&gSI2C1) == SMP_Busy);
}



/**
 *******************************************************************************
 * @brief       Interrupt Handler the I2C1 peripheral
 * @details     
 * @return      No
 * @exception   None
 * @note        
 * @par         Example
 * @code        
                void I2C0_IRQHandler(void)
 * @endcode     
 * @par         Modify
 *              void I2Cx_IRQHandler(void)
 *******************************************************************************
 */
void I2Cx_IRQHandler(void)
{
    // void Sample_I2C_ByteMode_Handle(Sample_I2C_HandleTypeDef *Sample_I2C);
    Sample_I2C_ByteMode_Handle(&gSI2C1);
}
#endif



/**
 *******************************************************************************
 * @brief       Interrupt Handler the DMA peripheral
 * @details     
 * @exception   None
 * @note        
 * @par         Example
 * @code        
                void DMA_IRQHandler(void);
 * @endcode     
 * @par         Modify
 *              void DMA_IRQHandler(void)
 *******************************************************************************
 */
void DMA_IRQHandler(void)
{
    Sample_I2C_DMA_Handle(&gSI2C0);
    Sample_I2C_DMA_Handle(&gSI2C1);
}



/**
 *******************************************************************************
 * @brief       DeInitialize I2C peripheral
 * @details     Enable CSC to SPI clock
 *
 * @param[in]   SI2C : Sample_I2C pointer to a Sample_I2C_HandleTypeDef 
 *              structure that contains the configuration information for the
 *              specified I2C.
 * @return      DRV_Return
 * @note        
 * @par         Example
 * @code
                Sample_I2C_DeInit(&I2C0_Init);
                Sample_I2C_DeInit(&I2C1_Init);
 * @endcode
 *******************************************************************************
 */
SMP_Return Sample_I2C_DeInit(Sample_I2C_HandleTypeDef *SI2C)
{
//-----Check---------------------------
    if((SI2C->State.B & Sample_I2C_State_Ready) == 0)
        return SMP_Failure;

//----- State Check -------------------
    if(__I2C_GetFlagStatus(SI2C->Instance, I2C_FLAG_BUSYF))
        return SMP_Busy;

    __I2C_Disable(SI2C->Instance);

    SI2C->Instance->CR0.W = 0;

    SI2C->State.B = Sample_I2C_State_Reset;
    SI2C->Error.H = Sample_I2C_Error_None;

    SI2C->Instance->STA.W = (~(I2C_FLAG_EVENTF | I2C_FLAG_TXF));
    SI2C->Instance->INT.W = 0;
    SI2C->Instance->CLK.W = 0;
    SI2C->Instance->CR1.W = 0;
    SI2C->Instance->CR2.W = 0;
    SI2C->Instance->SADR.W = 0;
    SI2C->Instance->TMOUT.W = 0;
    SI2C->Instance->CR0.W = 0;

    return SMP_Success;
}



/**
 *******************************************************************************
 * @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;
    uint32_t lTemp32;
    uint16_t lI2C_Pre = 1;
    uint16_t lI2C_DIV = 0;
    uint16_t lI2C_DIV_CAL = 1;
    uint16_t lI2C_HT_LT = 0;
//    uint16_t lI2C_LT;
//    uint16_t lI2C_HT;

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

    __I2C_Disable(SI2C->Instance);

    //===== GPIO Initial =====//
      //===== CSC for GPIO Config =====//
    UnProtectModuleReg(CSCprotect);                                             // Unprotect CSC module
    CSC_PeriphOnModeClock_Config(CSC_ON_PortB, ENABLE);                         // Enable PortB clock
    CSC_PeriphOnModeClock_Config(CSC_ON_PortC, ENABLE);                         // Enable PortC clock
//    CSC_PeriphOnModeClock_Config(CSC_ON_PortD, ENABLE);                       // Enable PortD clock
//    CSC_PeriphOnModeClock_Config(CSC_ON_PortE, ENABLE);                       // Enable PortE clock
    ProtectModuleReg(CSCprotect);                                               // protect CSC module

      //===== GPIO Config =====//
    PINX_InitStruct.PINX_Mode               = PINX_Mode_OpenDrain_O;            // Pin select pusu pull mode
    PINX_InitStruct.PINX_PUResistant        = PINX_PUResistant_Disable;         // Enable pull up resistor
    PINX_InitStruct.PINX_Speed              = PINX_Speed_High;
    PINX_InitStruct.PINX_OUTDrive           = PINX_OUTDrive_Level0;             // Pin output driver full strength.
    PINX_InitStruct.PINX_FilterDivider      = PINX_FilterDivider_Bypass;        // Pin input deglitch filter clock divider bypass
    PINX_InitStruct.PINX_Inverse            = PINX_Inverse_Disable;             // Pin input data not inverse
    PINX_InitStruct.PINX_Alternate_Function = 2;                                // Pin AFS = 2

    if(SI2C->Instance == I2C0)
    {
        GPIO_PinMode_Config(PINB(10),&PINX_InitStruct);                         // I2C0 SCL setup at PB10
        GPIO_PinMode_Config(PINB(11),&PINX_InitStruct);                         // I2C0 SDA setup at PB11

//        GPIO_PinMode_Config(PINC(4),&PINX_InitStruct);                          // I2C0 SCL setup at PC4
//        GPIO_PinMode_Config(PINC(5),&PINX_InitStruct);                          // I2C0 SDA setup at PC5

//        GPIO_PinMode_Config(PINC(8),&PINX_InitStruct);                          // I2C0 SCL setup at PC8
//        GPIO_PinMode_Config(PINC(9),&PINX_InitStruct);                          // I2C0 SDA setup at PC9

//        GPIO_PinMode_Config(PIND(5),&PINX_InitStruct);                          // I2C0 SCL setup at PD5
//        GPIO_PinMode_Config(PIND(6),&PINX_InitStruct);                          // I2C0 SDA setup at PD6

//        GPIO_PinMode_Config(PINE(0),&PINX_InitStruct);                          // I2C0 SCL setup at PE0
//        GPIO_PinMode_Config(PINE(1),&PINX_InitStruct);                          // I2C0 SDA setup at PE1
    }

    if(SI2C->Instance == I2C1)
    {
        GPIO_PinMode_Config(PINC(10),&PINX_InitStruct);                           // I2C1 SCL setup at PC10
        GPIO_PinMode_Config(PINC(11),&PINX_InitStruct);                           // I2C1 SDA setup at PC11

//        GPIO_PinMode_Config(PIND(8),&PINX_InitStruct);                          // I2C1 SCL setup at PD8
//        GPIO_PinMode_Config(PIND(9),&PINX_InitStruct);                          // I2C1 SDA setup at PD9

//        GPIO_PinMode_Config(PINE(2),&PINX_InitStruct);                          // I2C1 SCL setup at PE2
//        GPIO_PinMode_Config(PINE(3),&PINX_InitStruct);                          // I2C1 SDA setup at PE3
    }

    //===== I2C Initial =====//
      //=== CSC for I2C Config ===//
    UnProtectModuleReg(CSCprotect);                                             // Unprotect CSC module
    if(SI2C->Instance == I2C0)
        CSC_PeriphOnModeClock_Config(CSC_ON_I2C0, ENABLE);                      // Enable SPI0 module clock
    if(SI2C->Instance == I2C1)
        CSC_PeriphOnModeClock_Config(CSC_ON_I2C1, ENABLE);                      // Enable SPI0 module clock
    ProtectModuleReg(CSCprotect);                                               // protect CSC module

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

  #if defined(MG32_1ST)
    do{
        // lI2C_HT_LT = (uint16_t)(SI2C->Init.CK_I2C_PR_Frequency / SI2C->Init.SCL_Clock / lI2C_Pre / lI2C_DIV_CAL);
        lTemp32 = SI2C->Init.SCL_Clock;
        lTemp32 = SI2C->Init.CK_I2C_PR_Frequency / lTemp32;
        lTemp32 = lTemp32 / lI2C_Pre;
        lTemp32 = lTemp32 / 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);
        lTemp32 = SI2C->Init.SCL_Clock;
        lTemp32 = SI2C->Init.CK_I2C_PR_Frequency / lTemp32;
        lTemp32 = lTemp32 / lI2C_Pre;
        lTemp32 = lTemp32 / lI2C_DIV_CAL;

        //lI2C_HT_LT = SI2C->Init.CK_I2C_PR_Frequency / SI2C->Init.SCL_Clock;
        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) || defined(MG32_3RD) || defined(MG32_4TH) || defined(MG32_5TH)
    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, 0xFF);

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


/**
 *******************************************************************************
 * @brief       for I2C Dlelay
 * @details     ms Delay.
 *              
 * @param[in]   Delay : Delay Time. unit ms.
 * @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)
{
    uint32_t lCount = 0;
    do{
        __NOP();
    }while(++lCount < Delay);
    // to do ...
}



/**
 *******************************************************************************
 * @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(&gSI2C0, 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       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(&gSI2C0, 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;
}



/**
 *******************************************************************************
 * @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_RepeatStart(&gSI2C0, 0xA0, (uint8_t *)&DataBuffer, 256);
 * @endcode     
 * @par         Modify
 *              DRV_Return Sample_I2C_ByteMode_MasterTransmit_RepeatStart(Sample_I2C_HandleTypeDef *SI2C, uint16_t DevAddress, uint8_t *pBuffer, uint16_t Size)
 *******************************************************************************
 */
SMP_Return Sample_I2C_ByteMode_MasterTransmit_RepeatStart(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;
}



/**
 *******************************************************************************
 * @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(&gSI2C0, 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 Byte Mode Slave 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]   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_SlaveReceive(&gSI2C0, 0xA0, (uint8_t *)&DataBuffer, 256);
 * @endcode     
 * @par         Modify
 *              DRV_Return Sample_I2C_ByteMode_SlaveReceive(Sample_I2C_HandleTypeDef *SI2C, uint16_t DevAddress, uint8_t *pBuffer, uint16_t Size)
 *******************************************************************************
 */
SMP_Return Sample_I2C_ByteMode_SlaveReceive(Sample_I2C_HandleTypeDef *SI2C, 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 == 0x10) || (lEventTemp == 0x08))
            {
                do{
                    Set_STA_STO_AA_010(SI2C->Instance);
                    __I2C_ClearEventFlag(SI2C->Instance);
                    __I2C_WaitSTOClear(SI2C->Instance);
                }while(__I2C_GetEventCode(SI2C->Instance) != 0xF8);
            }

            lEventTemp = __I2C_GetEventCode(SI2C->Instance);
            if((lEventTemp != 0xF8) && (lEventTemp != 0xA0) && \
               (lEventTemp != 0x60) && (lEventTemp != 0x68) && \
               (lEventTemp != 0x70) && (lEventTemp != 0x78))
                return SMP_Busy;
        }
        else
        {
            lEventTemp = __I2C_GetEventCode(SI2C->Instance);
            if((lEventTemp != 0xA0) && (lEventTemp != 0xF8))
                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));

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

//-----Start----------------------------
    __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_STA_STO_AA_001(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 Byte Mode Slave 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]   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_SlaveTransmit(&gSI2C0, 0xA0, (uint8_t *)&DataBuffer, 256);
 * @endcode     
 * @par         Modify
 *              DRV_Return Sample_I2C_ByteMode_SlaveTransmit(Sample_I2C_HandleTypeDef *SI2C, uint16_t DevAddress, uint8_t *pBuffer, uint16_t Size)
 *******************************************************************************
 */
SMP_Return Sample_I2C_ByteMode_SlaveTransmit(Sample_I2C_HandleTypeDef *SI2C, 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 == 0x10) || (lEventTemp == 0x08))
            {
                do{
                    Set_STA_STO_AA_010(SI2C->Instance);
                    __I2C_ClearEventFlag(SI2C->Instance);
                    __I2C_WaitSTOClear(SI2C->Instance);
                }while(__I2C_GetEventCode(SI2C->Instance) != 0xF8);
            }

            lEventTemp = __I2C_GetEventCode(SI2C->Instance);
            if((lEventTemp != 0xF8) && (lEventTemp != 0xA0) && \
               (lEventTemp != 0xA8) && (lEventTemp != 0xB0))
                return SMP_Busy;
        }
        else
        {
            lEventTemp = __I2C_GetEventCode(SI2C->Instance);
            if((lEventTemp != 0xA0) && (lEventTemp != 0xF8))
                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));

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

//-----Start----------------------------
    __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_STA_STO_AA_001(SI2C->Instance);

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

    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 Byte Mode Master Transmit with Interrupt
 * @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(&gSI2C0, 0xA0, (uint8_t *)&DataBuffer, 256);
 * @endcode     
 * @par         Modify
 *              DRV_Return Sample_I2C_ByteMode_MasterTransmit_IT(Sample_I2C_HandleTypeDef *SI2C, uint16_t DevAddress, uint8_t *pBuffer, uint16_t Size)
 *******************************************************************************
 */
SMP_Return Sample_I2C_ByteMode_MasterTransmit_IT(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));

//---- Prepare transfer parameters ----
    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);

//---- Configuration Interrupt --------
    __I2C_IT_Disable(SI2C->Instance, I2C_IT_TMOUT | I2C_IT_ERR | I2C_IT_BUF); // Disable TMOUT / ERR / BUF Interrupt
    __I2C_IT_Enable(SI2C->Instance, I2C_IT_EVENT | I2C_IT_IEA); // Enable EVENT and IEA Interrupt

    return SMP_Success;
}



/**
 *******************************************************************************
 * @brief       I2C Byte Mode Master Transmit with Interrupt
 * @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_RepeatStart(&gSI2C0, 0xA0, (uint8_t *)&DataBuffer, 256);
 * @endcode     
 * @par         Modify
 *              DRV_Return Sample_I2C_ByteMode_MasterTransmit_IT_RepeatStart(Sample_I2C_HandleTypeDef *SI2C, uint16_t DevAddress, uint8_t *pBuffer, uint16_t Size)
 *******************************************************************************
 */
SMP_Return Sample_I2C_ByteMode_MasterTransmit_IT_RepeatStart(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));

//---- Prepare transfer parameters ----
    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_RepeatStart;

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

//---- Configuration Interrupt --------
    __I2C_IT_Disable(SI2C->Instance, I2C_IT_TMOUT | I2C_IT_ERR | I2C_IT_BUF); // Disable TMOUT / ERR / BUF Interrupt
    __I2C_IT_Enable(SI2C->Instance, I2C_IT_EVENT | I2C_IT_IEA); // Enable EVENT and IEA Interrupt

    return SMP_Success;
}



/**
 *******************************************************************************
 * @brief       I2C Byte Mode Master Receive with Interrupt
 * @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(&gSI2C0, 0xA0, (uint8_t *)&DataBuffer, 256);
 * @endcode     
 * @par         Modify
 *              DRV_Return Sample_I2C_ByteMode_MasterReceive_IT(Sample_I2C_HandleTypeDef *SI2C, uint16_t DevAddress, uint8_t *pBuffer, uint16_t Size)
 *******************************************************************************
 */
SMP_Return Sample_I2C_ByteMode_MasterReceive_IT(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_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);

//----- Configuration Interrupt --------
    __I2C_IT_Disable(SI2C->Instance, I2C_IT_ERR | I2C_IT_BUF); // Disable TMOUT / ERR / BUF Interrupt
    __I2C_IT_Enable(SI2C->Instance, I2C_IT_EVENT | I2C_IT_IEA); // Enable EVENT and IEA Interrupt

    return SMP_Success;
}



/**
 *******************************************************************************
 * @brief       I2C Byte Mode Slave Receive with Interrupt
 * @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]   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_SlaveReceive(&gSI2C0, 0xA0, (uint8_t *)&DataBuffer, 256);
 * @endcode     
 * @par         Modify
 *              DRV_Return Sample_I2C_ByteMode_SlaveReceive_IT(Sample_I2C_HandleTypeDef *SI2C, uint16_t DevAddress, uint8_t *pBuffer, uint16_t Size)
 *******************************************************************************
 */
SMP_Return Sample_I2C_ByteMode_SlaveReceive_IT(Sample_I2C_HandleTypeDef *SI2C, 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 == 0x10) || (lEventTemp == 0x08))
            {
                do{
                    Set_STA_STO_AA_010(SI2C->Instance);
                    __I2C_ClearEventFlag(SI2C->Instance);
                    __I2C_WaitSTOClear(SI2C->Instance);
                }while(__I2C_GetEventCode(SI2C->Instance) != 0xF8);
            }

            lEventTemp = __I2C_GetEventCode(SI2C->Instance);
            if((lEventTemp != 0xF8) && (lEventTemp != 0xA0) && \
               (lEventTemp != 0x60) && (lEventTemp != 0x68) && \
               (lEventTemp != 0x70) && (lEventTemp != 0x78))
                return SMP_Busy;
        }
        else
        {
            lEventTemp = __I2C_GetEventCode(SI2C->Instance);
            if((lEventTemp != 0xA0) && (lEventTemp != 0xF8))
                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));

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

//---- Start ---------------------------
    __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_STA_STO_AA_001(SI2C->Instance);

//---- Configuration Interrupt --------
    __I2C_IT_Disable(SI2C->Instance, I2C_IT_ERR | I2C_IT_BUF); // Disable TMOUT / ERR / BUF Interrupt
    __I2C_IT_Enable(SI2C->Instance, I2C_IT_EVENT | I2C_IT_IEA); // Enable EVENT and IEA Interrupt

    return SMP_Success;
}



/**
 *******************************************************************************
 * @brief       I2C Byte Mode Slave Transmit with Interrupt
 * @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]   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_SlaveTransmit(&gSI2C0, 0xA0, (uint8_t *)&DataBuffer, 256);
 * @endcode     
 * @par         Modify
 *              DRV_Return Sample_I2C_ByteMode_SlaveTransmit_IT(Sample_I2C_HandleTypeDef *SI2C, uint16_t DevAddress, uint8_t *pBuffer, uint16_t Size)
 *******************************************************************************
 */
SMP_Return Sample_I2C_ByteMode_SlaveTransmit_IT(Sample_I2C_HandleTypeDef *SI2C, 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 == 0x10) || (lEventTemp == 0x08))
            {
                do{
                    Set_STA_STO_AA_010(SI2C->Instance);
                    __I2C_ClearEventFlag(SI2C->Instance);
                    __I2C_WaitSTOClear(SI2C->Instance);
                }while(__I2C_GetEventCode(SI2C->Instance) != 0xF8);
            }

            lEventTemp = __I2C_GetEventCode(SI2C->Instance);
            if((lEventTemp != 0xF8) && (lEventTemp != 0xA0) && \
               (lEventTemp != 0xA8) && (lEventTemp != 0xB0))
                return SMP_Busy;
        }
        else
        {
            lEventTemp = __I2C_GetEventCode(SI2C->Instance);
            if((lEventTemp != 0xA0) && (lEventTemp != 0xF8))
                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));

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

//----- Start -------------------------
    __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_STA_STO_AA_001(SI2C->Instance);

//----- Configuration Interrupt -------
    __I2C_IT_Disable(SI2C->Instance, I2C_IT_ERR | I2C_IT_BUF); // Disable TMOUT / ERR / BUF Interrupt
    __I2C_IT_Enable(SI2C->Instance, I2C_IT_EVENT | I2C_IT_IEA); // Enable EVENT and IEA Interrupt

    return SMP_Success;
}



/**
 *******************************************************************************
 * @brief       I2C Byte Mode Master Transmit with DMA
 * @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(&gSI2C0, 0xA0, (uint8_t *)&DataBuffer, 256);
 * @endcode     
 * @par         Modify
 *              DRV_Return Sample_I2C_ByteMode_MasterTransmit_DMA(Sample_I2C_HandleTypeDef *SI2C, uint16_t DevAddress, uint8_t *pBuffer, uint16_t Size)
 *******************************************************************************
 */
SMP_Return Sample_I2C_ByteMode_MasterTransmit_DMA(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 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));

//---- Prepare transfer parameters -----
    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 | Sample_I2C_DMA_MTx);

//---- DMA Channel Config --------------
    Sample_DMA_M2P_IT(SI2C->DMACHx, (uint32_t)pBuffer, DMA_I2C0_TX, Size);
    DMA_SetPriority(SI2C->DMACHx, DMA_LowestPriority);
    DMA_StartRequest(SI2C->DMACHx);

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

//---- Configuration Interrupt ---------
    __I2C_IT_Disable(SI2C->Instance, I2C_IT_ERR | I2C_IT_BUF); // Disable TMOUT / ERR / BUF Interrupt
    __I2C_IT_Enable(SI2C->Instance, I2C_IT_EVENT | I2C_IT_IEA); // Enable EVENT and IEA Interrupt

    return SMP_Success;
}



/**
 *******************************************************************************
 * @brief       I2C Byte Mode Master Transmit with DMA
 * @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_DMA_RepeatStart(&gSI2C0, 0xA0, (uint8_t *)&DataBuffer, 256);
 * @endcode     
 * @par         Modify
 *              DRV_Return Sample_I2C_ByteMode_MasterTransmit_DMA_RepeatStart(Sample_I2C_HandleTypeDef *SI2C, uint16_t DevAddress, uint8_t *pBuffer, uint16_t Size)
 *******************************************************************************
 */
SMP_Return Sample_I2C_ByteMode_MasterTransmit_DMA_RepeatStart(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 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));

//---- Prepare transfer parameters -----
    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 | Sample_I2C_DMA_MTx);

//---- DMA Channel Config --------------
    Sample_DMA_M2P_IT(SI2C->DMACHx, (uint32_t)pBuffer, DMA_I2C0_TX, Size);
    DMA_SetPriority(SI2C->DMACHx, DMA_LowestPriority);
    DMA_StartRequest(SI2C->DMACHx);

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

//---- Configuration Interrupt ---------
    __I2C_IT_Disable(SI2C->Instance, I2C_IT_ERR | I2C_IT_BUF); // Disable TMOUT / ERR / BUF Interrupt
    __I2C_IT_Enable(SI2C->Instance, I2C_IT_EVENT | I2C_IT_IEA); // Enable EVENT and IEA Interrupt

    return SMP_Success;
}



/**
 *******************************************************************************
 * @brief       I2C Byte Mode Master Receive with DMA
 * @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(&gSI2C0, 0xA0, (uint8_t *)&DataBuffer, 256);
 * @endcode     
 * @par         Modify
 *              DRV_Return Sample_I2C_ByteMode_MasterReceive_DMA(Sample_I2C_HandleTypeDef *SI2C, uint16_t DevAddress, uint8_t *pBuffer, uint16_t Size)
 *******************************************************************************
 */
SMP_Return Sample_I2C_ByteMode_MasterReceive_DMA(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_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 | Sample_I2C_DMA_MRx);

//---- DMA Channel Config --------------
    Sample_DMA_P2M_IT(SI2C->DMACHx, DMA_I2C0_RX, (uint32_t)pBuffer, Size);
    DMA_SetPriority(SI2C->DMACHx, DMA_LowestPriority);
    DMA_StartRequest(SI2C->DMACHx);

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

//---- Configuration Interrupt --------
    __I2C_IT_Disable(SI2C->Instance, I2C_IT_ERR | I2C_IT_BUF); // Disable TMOUT / ERR / BUF Interrupt
    __I2C_IT_Enable(SI2C->Instance, I2C_IT_EVENT | I2C_IT_IEA); // Enable EVENT and IEA Interrupt

    return SMP_Success;
}



/**
 *******************************************************************************
 * @brief       I2C Byte Mode Slave Receive with DMA
 * @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]   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_SlaveReceive(&gSI2C0, 0xA0, (uint8_t *)&DataBuffer, 256);
 * @endcode     
 * @par         Modify
 *              DRV_Return Sample_I2C_ByteMode_SlaveReceive_DMA(Sample_I2C_HandleTypeDef *SI2C, uint16_t DevAddress, uint8_t *pBuffer, uint16_t Size)
 *******************************************************************************
 */
SMP_Return Sample_I2C_ByteMode_SlaveReceive_DMA(Sample_I2C_HandleTypeDef *SI2C, 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 == 0x10) || (lEventTemp == 0x08))
            {
                do{
                    Set_STA_STO_AA_010(SI2C->Instance);
                    __I2C_ClearEventFlag(SI2C->Instance);
                    __I2C_WaitSTOClear(SI2C->Instance);
                }while(__I2C_GetEventCode(SI2C->Instance) != 0xF8);
            }

            lEventTemp = __I2C_GetEventCode(SI2C->Instance);
            if((lEventTemp != 0xF8) && (lEventTemp != 0xA0) && \
               (lEventTemp != 0x60) && (lEventTemp != 0x68) && \
               (lEventTemp != 0x70) && (lEventTemp != 0x78))
                return SMP_Busy;
        }
        else
        {
            lEventTemp = __I2C_GetEventCode(SI2C->Instance);
            if((lEventTemp != 0xA0) && (lEventTemp != 0xF8))
                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));

//---- Set_Config ----------------------
    SI2C->State.B = (SI2C->State.B & (~(Sample_I2C_State_Busy_Tx | Sample_I2C_State_Error))) | Sample_I2C_State_Listen_Rx;
    SI2C->Error.H = 0;
    SI2C->pBuffer = pBuffer;
    SI2C->XferSize = Size;
    SI2C->XferCount = 0;
    SI2C->Control.H = (SI2C->Control.H & (~Sample_I2C_XferNext_Mask)) | (Sample_I2C_XferNext_STOP | Sample_I2C_DMA_SRx);

//---- DMA Channel Config --------------
    Sample_DMA_P2M_IT(SI2C->DMACHx, DMA_I2C0_RX, (uint32_t)pBuffer, Size);
    DMA_SetPriority(SI2C->DMACHx, DMA_LowestPriority);
    DMA_StartRequest(SI2C->DMACHx);

//---- Start ---------------------------
    __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_STA_STO_AA_001(SI2C->Instance);

//---- Configuration Interrupt --------
    __I2C_IT_Disable(SI2C->Instance, I2C_IT_ERR | I2C_IT_BUF); // Disable TMOUT / ERR / BUF Interrupt
    __I2C_IT_Enable(SI2C->Instance, I2C_IT_EVENT | I2C_IT_IEA); // Enable EVENT and IEA Interrupt

    return SMP_Success;
}



/**
 *******************************************************************************
 * @brief       I2C Byte Mode Slave Transmit with DMA
 * @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]   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_SlaveTransmit(&gSI2C0, 0xA0, (uint8_t *)&DataBuffer, 256);
 * @endcode     
 * @par         Modify
 *              DRV_Return Sample_I2C_ByteMode_SlaveTransmit_DMA(Sample_I2C_HandleTypeDef *SI2C, uint16_t DevAddress, uint8_t *pBuffer, uint16_t Size)
 *******************************************************************************
 */
SMP_Return Sample_I2C_ByteMode_SlaveTransmit_DMA(Sample_I2C_HandleTypeDef *SI2C, 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 == 0x10) || (lEventTemp == 0x08))
            {
                do{
                    Set_STA_STO_AA_010(SI2C->Instance);
                    __I2C_ClearEventFlag(SI2C->Instance);
                    __I2C_WaitSTOClear(SI2C->Instance);
                }while(__I2C_GetEventCode(SI2C->Instance) != 0xF8);
            }

            lEventTemp = __I2C_GetEventCode(SI2C->Instance);
            if((lEventTemp != 0xF8) && (lEventTemp != 0xA0) && \
               (lEventTemp != 0xA8) && (lEventTemp != 0xB0))
                return SMP_Busy;
        }
        else
        {
            lEventTemp = __I2C_GetEventCode(SI2C->Instance);
            if((lEventTemp != 0xA0) && (lEventTemp != 0xF8))
                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));

//-----Set_Config-----------------------
    SI2C->State.B = (SI2C->State.B & (~(Sample_I2C_State_Busy_Rx | Sample_I2C_State_Error))) | Sample_I2C_State_Listen_Tx;
    SI2C->Error.H = 0;
    SI2C->pBuffer = pBuffer;
    SI2C->XferSize = Size;
    SI2C->XferCount = 0;
    SI2C->Control.H = (SI2C->Control.H & (~Sample_I2C_XferNext_Mask)) | (Sample_I2C_XferNext_STOP | Sample_I2C_DMA_STx);

//---- DMA Channel Config --------------
    Sample_DMA_M2P_IT(SI2C->DMACHx, (uint32_t)pBuffer, DMA_I2C0_TX, Size);
    DMA_SetPriority(SI2C->DMACHx, DMA_LowestPriority);
    DMA_StartRequest(SI2C->DMACHx);

//-----Start----------------------------
    __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_STA_STO_AA_001(SI2C->Instance);

//---- Configuration Interrupt --------
    __I2C_IT_Disable(SI2C->Instance, I2C_IT_ERR | I2C_IT_BUF); // Disable TMOUT / ERR / BUF Interrupt
    __I2C_IT_Enable(SI2C->Instance, I2C_IT_EVENT | I2C_IT_IEA); // Enable EVENT and IEA Interrupt

    return SMP_Success;
}



/**
 *******************************************************************************
 * @brief       Interrupt Handler the I2C1 peripheral
 * @details     
 * @return      No
 * @exception   None
 * @note        
 * @par         Example
 * @code        
                void I2C0_IRQHandler(void)
 * @endcode     
 * @par         Modify
 *              void I2C0_IRQHandler(void)
 *******************************************************************************
 */
SMP_Return Sample_I2C_DMA_Handle(Sample_I2C_HandleTypeDef *SI2C)
{
    if((SI2C->DMACHx->A.B[3] & DMA_CH0A_CH0_ERR2F_mask_b3) != 0)
    {
        SI2C->DMACHx->A.B[3] = DMA_CH0A_CH0_ERR2F_mask_b3;
        SI2C->XferCount = (uint16_t)SI2C->DMACHx->CNT.W;
    }

    //if((SI2C->DMACHx->A.B[3] & DMA_CH0A_CH0_TH2F_mask_b3) != 0)
    //    SI2C->DMACHx->A.B[3] = DMA_CH0A_CH0_TH2F_mask_b3;

    if((SI2C->DMACHx->A.B[3] & DMA_CH0A_CH0_TC2F_mask_b3) != 0)
    {
        SI2C->DMACHx->A.B[3] = DMA_CH0A_CH0_TC2F_mask_b3;
        if((SI2C->Control.H & Sample_I2C_DMA_SRx) != 0)
            SI2C->XferCount = SI2C->XferSize - 1;
        else
            SI2C->XferCount = SI2C->XferSize;

        SI2C->Control.H &= ~((uint16_t)(Sample_I2C_DMA_MTx | Sample_I2C_DMA_MRx | Sample_I2C_DMA_SRx | Sample_I2C_DMA_STx));
    }
    SI2C->Control.H &= ~(Sample_I2C_DMA_MTx | Sample_I2C_DMA_MRx | Sample_I2C_DMA_STx | Sample_I2C_DMA_SRx);
    return SMP_Success;
}



/**
 *******************************************************************************
 * @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(&gSI2C0) == 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 Disable 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(&gSI2C0) == 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_Disable_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 Listen ------
    __I2C_SlaveAddressDetect_Disable(SI2C->Instance, (I2C_SADR_0 | I2C_SADR_1 | I2C_SADR_2));
    Set_ASSERT_ACKNOWLEDGE_CLR(SI2C->Instance);

//---- 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->Control.H &= ~Sample_I2C_Listen;

    SI2C->State.B &= ~Sample_I2C_State_Listen;

    return SMP_Success;
}



/**
 *******************************************************************************
 * @brief       Get I2C Tranfer State
 * @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
 *         \n     SMP_Failure
 *         \n     SMP_Busy
 * @exception   None
 * @note        
 * @par         Example
 * @code        
                while(Sample_I2C_Get_Transfer_State(&gSI2C1) == SMP_Busy);
                if(Sample_I2C_Get_Transfer_State(&gSI2C0) != SMP_Success);
                if(Sample_I2C_Get_Transfer_State(&gSI2C1) == SMP_Failure);
 * @endcode     
 * @par         Modify
 *              SMP_Return Sample_I2C_Get_Transfer_State(Sample_I2C_HandleTypeDef *SI2C)
 *******************************************************************************
 */
SMP_Return Sample_I2C_Get_Transfer_State(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)
        return SMP_Busy;

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

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

    return SMP_Success;
}



/**
 *******************************************************************************
 * @brief       Get I2C Listen State
 * @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_Busy    : Data access process is ongoing.
 *         \n     SMP_Failure : Initial Not Ready.
 * @exception   None
 * @note        
 * @par         Example
 * @code        
                while(Sample_I2C_Get_Listen_State(&gSI2C1) != SMP_Success);
                if(Sample_I2C_Get_Listen_State(&gSI2C0) == 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_Get_Listen_State(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_Busy;
        else
            return SMP_Success;
    }

    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.
 * @exception   None
 * @note        
 * @par         Example
 * @code        
                Sample_I2C_ByteMode_Handle(Sample_I2C_HandleTypeDef &gSI2C0);
 * @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;
            }
        #if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) /* ARM Compiler V6 */
            __attribute__((fallthrough));
        #endif
        case 0x28:  // MT DATA sent and ACK received
            if(SI2C->XferCount == SI2C->XferSize)
            {
                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;
            }

            __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
            SI2C->Error.H |= Sample_I2C_Error_ArbitrationLost;
            SI2C->State.B |= Sample_I2C_State_Error;
            __I2C_ClearFlag(SI2C->Instance, I2C_FLAG_ALOSF | I2C_FLAG_ERRF);

            __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;
            }

          #if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) /* ARM Compiler V6 */
            __attribute__((fallthrough));
          #endif
        case 0x60:  // Own SLA+W has bee Received ACK has been returned
        case 0x70:  // General Call address has been received ACK has been returned
            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;
            }
          #if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) /* ARM Compiler V6 */
            __attribute__((fallthrough));
          #endif
        case 0xA8:  // Own SLA+R has bee Received ACK has been returned
            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;
            }
          #if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) /* ARM Compiler V6 */
            __attribute__((fallthrough));
          #endif
        case 0xB8:  // Data byte in SIDAT has been transmitted ACK has been received
            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);
}


