/*!
* @brief The i2c slave
* The function runs i2c slave with interrupt active mode. Slave receive data from
* master and echo back to master
*/
void main(void)
{
    // Number byte data will be transfer
    uint32_t count = 0;
    // Buffer store data to transfer
    uint8_t dataBuff[100] = {0};
    // state of slave
    i2c_slave_state_t slave;
    // user configuration
    i2c_slave_user_config_t userConfig =
    {
        .address        = 0x7FU,
        .slaveCallback  = NULL,
        .callbackParam  = NULL,
        .slaveListening = false,
#if FSL_FEATURE_I2C_HAS_START_STOP_DETECT
        .startStopDetect  = false,
#endif
#if FSL_FEATURE_I2C_HAS_STOP_DETECT
        .stopDetect       = false,
#endif
    };

    // Initialize hardware
    hardware_init();
    // Configure pin for i2c slave
    configure_i2c_pins(BOARD_I2C_COMM_INSTANCE);
    // Initialize uart to debug
    dbg_uart_init();
    // Initialize OSA
    OSA_Init();

    printf("Slave is running ...");

    // Initialize slave
    I2C_DRV_SlaveInit(BOARD_I2C_COMM_INSTANCE, &userConfig, &slave);

    // Loop transfer
    while(1)
    {
        // Slave receive 1 byte from master
        I2C_DRV_SlaveReceiveDataBlocking(BOARD_I2C_COMM_INSTANCE, (uint8_t*)&count, 1, OSA_WAIT_FOREVER);

        // Slave receive buffer from master
        I2C_DRV_SlaveReceiveDataBlocking(BOARD_I2C_COMM_INSTANCE, dataBuff, count, 1000);

        // Slave send buffer received from master
        I2C_DRV_SlaveSendDataBlocking(BOARD_I2C_COMM_INSTANCE, dataBuff, count, 1000);
    }
}
/*!
* @brief The i2c slave
* The function runs i2c slave with interrupt active mode. Slave receive data from
* master and echo back to master
*/
int main(void)
{
    // Number byte data will be transfer
    uint32_t count = 0;
    uint32_t i     = 0;
    // Buffer store data to transfer
    uint8_t dataBuff[DATA_LENGTH] = {0};
    // state of slave
    i2c_slave_state_t slave;
    // user configuration
    i2c_slave_user_config_t userConfig =
    {
        .address        = 0x7FU,
        .slaveCallback  = NULL,
        .callbackParam  = NULL,
        .slaveListening = false,
#if FSL_FEATURE_I2C_HAS_START_STOP_DETECT
        .startStopDetect  = false,
#endif
#if FSL_FEATURE_I2C_HAS_STOP_DETECT
        .stopDetect       = false,
#endif
    };

    // Initialize hardware
    hardware_init();

    // Initialize OSA
    OSA_Init();

    PRINTF("\r\n================== I2C SLAVE NON-BLOCKING =================\r\n\r\n");
    PRINTF("Slave is running ...");

    // Initialize slave
    I2C_DRV_SlaveInit(BOARD_I2C_INSTANCE, &userConfig, &slave);

    // Loop transfer
    while(1)
    {
        // Slave receive buffer from master
        I2C_DRV_SlaveReceiveData(BOARD_I2C_INSTANCE, (uint8_t*)&count, 1);

        /* Wait until transfer is successful */
        while (I2C_DRV_SlaveGetReceiveStatus(BOARD_I2C_INSTANCE, NULL) != kStatus_I2C_Success);

        // Clear receive buffer
        for(i = 0; i < count; i++)
        {
            dataBuff[i] = 0;
        }

        // Slave receive buffer from master
        I2C_DRV_SlaveReceiveData(BOARD_I2C_INSTANCE, dataBuff, count);

        /* Wait until transfer is successful */
        while (I2C_DRV_SlaveGetReceiveStatus(BOARD_I2C_INSTANCE, NULL) != kStatus_I2C_Success);

        // Print receive data
        PRINTF("\r\nSlave received:\r\n");
        for (i = 0; i < count; i++)
        {
            // Print 16 numbers in a line.
            if ((i & 0x0F) == 0)
            {
                PRINTF("\r\n    ");
            }
            PRINTF(" %02X", dataBuff[i]);
        }

        // Slave send buffer received from master
        I2C_DRV_SlaveSendData(BOARD_I2C_INSTANCE, dataBuff, count);

        /* Wait until transfer is successful */
        while (I2C_DRV_SlaveGetTransmitStatus(BOARD_I2C_INSTANCE, NULL) != kStatus_I2C_Success);

        OSA_TimeDelay(1);
    }
}
/*!
 * @brief main function
 */
int main(void)
{
    i2c_slave_state_t slave;

    i2cData_t i2cData =
    {
      .subAddress = Invalid_Subaddress_Index,
      .data = 0,
      .state = CMD_MODE
    };

    i2c_slave_user_config_t userConfig =
    {
        .address = 0x3A,
        .slaveListening = true,
        .slaveCallback  = i2c_slave_event_callback_passive,
        .callbackParam  = &i2cData,
#if FSL_FEATURE_I2C_HAS_START_STOP_DETECT
        .startStopDetect  = false,
#endif
#if FSL_FEATURE_I2C_HAS_STOP_DETECT
        .stopDetect       = false,
#endif
    };

    // Low Power Configuration
    smc_power_mode_config_t smcConfig;

    // Init struct
    memset(&smcConfig, 0, sizeof(smcConfig));

    hardware_init();
    OSA_Init();
    GPIO_DRV_Init(0, ledPins);

    // Initiate I2C instance module
    I2C_DRV_SlaveInit(BOARD_I2C_INSTANCE, &userConfig, &slave);

    PRINTF("\r\n====== I2C Slave ======\r\n\r\n");

    // turn LED_slave on to indicate I2C slave status is waiting for date receiving
    LED_turnon_slave();
    LED_turnoff_master();
    OSA_TimeDelay(50);

    PRINTF("\r\n I2C slave enters low power mode...\r\n");

    // set to allow entering specific modes
    SMC_HAL_SetProtection(SMC, kAllowPowerModeVlp);

    // set power mode to specific Run mode
#if FSL_FEATURE_SMC_HAS_LPWUI
    smcConfig.lpwuiOptionValue = kSmcLpwuiEnabled;
#endif
#if FSL_FEATURE_SMC_HAS_PORPO
    smcConfig.porOptionValue = kSmcPorEnabled;
#endif

#if FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE
    smcConfig.powerModeName = kPowerModeRun;
    // If current status is HSRUN mode, change to RUN mode first.
    if (kStatHsrun == SMC_HAL_GetStat(SMC_BASE_PTR))
    {
        SMC_HAL_SetMode(SMC_BASE_PTR, &smcConfig);
    }
#endif

    smcConfig.powerModeName = kPowerModeWait;
    // Entry to Low Power Mode
    SMC_HAL_SetMode(SMC_BASE_PTR, &smcConfig);

    // LED_slave is still on during low power mode until I2C master send data to slave.
    // Turn off LED_slave to indicate MCU wake up by I2C address matching interrupt
    LED_turnoff_slave();
    PRINTF("\r\n I2C slave wakes up from low power mode by I2C address matching.\r\n");

    while(1);
}