/*
 * Copyright (c) 2016, Freescale Semiconductor, Inc.
 * Copyright 2016-2019 NXP
 * All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */
#include "fsl_i2c.h"

/*******************************************************************************
 * Definitions
 ******************************************************************************/

/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.ii2c"
#endif

/*! @brief i2c transfer state. */
enum _i2c_transfer_states
{
    kIdleState             = 0x0U, /*!< I2C bus idle. */
    kCheckAddressState     = 0x1U, /*!< 7-bit address check state. */
    kSendCommandState      = 0x2U, /*!< Send command byte phase. */
    kSendDataState         = 0x3U, /*!< Send data transfer phase. */
    kReceiveDataBeginState = 0x4U, /*!< Receive data transfer phase begin. */
    kReceiveDataState      = 0x5U, /*!< Receive data transfer phase. */
};

/*! @brief Common sets of flags used by the driver. */
enum _i2c_flag_constants
{
    kClearFlags = kI2C_ArbitrationLostFlag | kI2C_IntPendingFlag,
    kIrqFlags   = kI2C_GlobalInterruptEnable,
};

/*! @brief Typedef for interrupt handler. */
typedef void (*i2c_isr_t)(I2C_Type *base, void *i2cHandle);

/*******************************************************************************
 * Prototypes
 ******************************************************************************/

/*!
 * @brief Get instance number for I2C module.
 *
 * @param base I2C peripheral base address.
 */
uint32_t I2C_GetInstance(I2C_Type *base);

/*!
 * @brief Set up master transfer, send slave address and decide the initial
 * transfer state.
 *
 * @param base I2C peripheral base address.
 * @param handle pointer to i2c_master_handle_t structure which stores the transfer state.
 * @param xfer pointer to i2c_master_transfer_t structure.
 */
static status_t I2C_InitTransferStateMachine(I2C_Type *base, i2c_master_handle_t *handle, i2c_master_transfer_t *xfer);

/*!
 * @brief Check and clear status operation.
 *
 * @param base I2C peripheral base address.
 * @param status current i2c hardware status.
 * @retval kStatus_Success No error found.
 * @retval kStatus_I2C_ArbitrationLost Transfer error, arbitration lost.
 * @retval kStatus_I2C_Nak Received Nak error.
 */
static status_t I2C_CheckAndClearError(I2C_Type *base, uint32_t status);

/*!
 * @brief Master run transfer state machine to perform a byte of transfer.
 *
 * @param base I2C peripheral base address.
 * @param handle pointer to i2c_master_handle_t structure which stores the transfer state
 * @param isDone input param to get whether the thing is done, true is done
 * @retval kStatus_Success No error found.
 * @retval kStatus_I2C_ArbitrationLost Transfer error, arbitration lost.
 * @retval kStatus_I2C_Nak Received Nak error.
 * @retval kStatus_I2C_Timeout Transfer error, wait signal timeout.
 */
static status_t I2C_MasterTransferRunStateMachine(I2C_Type *base, i2c_master_handle_t *handle, bool *isDone);

/*!
 * @brief I2C common interrupt handler.
 *
 * @param base I2C peripheral base address.
 * @param handle pointer to i2c_master_handle_t structure which stores the transfer state
 */
static void I2C_TransferCommonIRQHandler(I2C_Type *base, void *handle);

/*!
 * @brief Wait for status ready.
 *
 * @param base I2C peripheral base address.
 * @param statusFlag statusFlag #_i2c_flags
 * @retval kStatus_I2C_Timeout Wait signal timeout.
 * @retval kStatus_Success Polling flag successfully.
 */
static status_t I2C_WaitForStatusReady(I2C_Type *base, uint8_t statusFlag);

/*******************************************************************************
 * Variables
 ******************************************************************************/

/*! @brief SCL clock divider used to calculate baudrate. */
static const uint16_t s_i2cDividerTable[] = {
    30,  32,  36,  42,  48,  52,  60,  72,  80,   88,   104,  128,  144,  160,  192,  240,
    288, 320, 384, 480, 576, 640, 768, 960, 1152, 1280, 1536, 1920, 2304, 2560, 3072, 3840,
    22,  24,  26,  28,  32,  36,  40,  44,  48,   56,   64,   72,   80,   96,   112,  128,
    160, 192, 224, 256, 320, 384, 448, 512, 640,  768,  896,  1024, 1280, 1536, 1792, 2048};

/*! @brief Pointers to i2c bases for each instance. */
static I2C_Type *const s_i2cBases[] = I2C_BASE_PTRS;

/*! @brief Pointers to i2c IRQ number for each instance. */
static const IRQn_Type s_i2cIrqs[] = I2C_IRQS;

#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/*! @brief Pointers to i2c clocks for each instance. */
static const clock_ip_name_t s_i2cClocks[] = I2C_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */

/*! @brief Pointers to i2c handles for each instance. */
static void *s_i2cHandle[ARRAY_SIZE(s_i2cBases)];

/*! @brief Pointer to master IRQ handler for each instance. */
static i2c_isr_t s_i2cMasterIsr;

/*! @brief Pointer to slave IRQ handler for each instance. */
static i2c_isr_t s_i2cSlaveIsr;

/*******************************************************************************
 * Codes
 ******************************************************************************/

uint32_t I2C_GetInstance(I2C_Type *base)
{
    uint32_t instance;

    /* Find the instance index from base address mappings. */
    for (instance = 0; instance < ARRAY_SIZE(s_i2cBases); instance++)
    {
        if (s_i2cBases[instance] == base)
        {
            break;
        }
    }

    assert(instance < ARRAY_SIZE(s_i2cBases));

    return instance;
}

static status_t I2C_WaitForStatusReady(I2C_Type *base, uint8_t statusFlag)
{
#if I2C_RETRY_TIMES
    uint32_t waitTimes = I2C_RETRY_TIMES;
    /* Wait for TCF bit and manually trigger tx interrupt. */
    while ((0U == (base->I2SR & statusFlag)) && (0U != --waitTimes))
    {
    }
    if (0U == waitTimes)
    {
        return kStatus_I2C_Timeout;
    }
#else
    /* Wait for TCF bit and manually trigger tx interrupt. */
    while (0U == (base->I2SR & statusFlag))
    {
    }
#endif
    return kStatus_Success;
}

static status_t I2C_InitTransferStateMachine(I2C_Type *base, i2c_master_handle_t *handle, i2c_master_transfer_t *xfer)
{
    status_t result           = kStatus_Success;
    i2c_direction_t direction = xfer->direction;

    /* Initialize the handle transfer information. */
    handle->transfer = *xfer;

    /* Save total transfer size. */
    handle->transferSize = xfer->dataSize;

    /* Initial transfer state. */
    if (handle->transfer.subaddressSize > 0U)
    {
        if (xfer->direction == kI2C_Read)
        {
            direction = kI2C_Write;
        }
    }

    handle->state = (uint8_t)kCheckAddressState;

    /* Clear all status before transfer. */
    I2C_MasterClearStatusFlags(base, (uint32_t)kClearFlags);

    /* Handle no start option. */
    if ((handle->transfer.flags & (uint32_t)kI2C_TransferNoStartFlag) != 0U)
    {
        /* No need to send start flag, directly go to send command or data */
        if (handle->transfer.subaddressSize > 0U)
        {
            handle->state = (uint8_t)kSendCommandState;
        }
        else
        {
            if (direction == kI2C_Write)
            {
                /* Next state, send data. */
                handle->state = (uint8_t)kSendDataState;
            }
            else
            {
                /* Only support write with no stop signal. */
                return kStatus_InvalidArgument;
            }
        }

        if (I2C_WaitForStatusReady(base, (uint8_t)kI2C_TransferCompleteFlag) != kStatus_Success)
        {
            return kStatus_I2C_Timeout;
        }
        I2C_MasterTransferHandleIRQ(base, handle);
    }
    /* If repeated start is requested, send repeated start. */
    else if ((handle->transfer.flags & (uint32_t)kI2C_TransferRepeatedStartFlag) != 0U)
    {
        result = I2C_MasterRepeatedStart(base, handle->transfer.slaveAddress, direction);
    }
    else /* For normal transfer, send start. */
    {
        result = I2C_MasterStart(base, handle->transfer.slaveAddress, direction);
    }

    return result;
}

static status_t I2C_CheckAndClearError(I2C_Type *base, uint32_t status)
{
    status_t result = kStatus_Success;

    /* Check arbitration lost. */
    if ((status & (uint32_t)kI2C_ArbitrationLostFlag) != 0U)
    {
        /* Clear arbitration lost flag. */
        base->I2SR &= (~(uint8_t)kI2C_ArbitrationLostFlag);

        /* Reset I2C controller*/
        base->I2CR &= ~(uint16_t)I2C_I2CR_IEN_MASK;
        base->I2CR |= I2C_I2CR_IEN_MASK;

        result = kStatus_I2C_ArbitrationLost;
    }
    /* Check NAK */
    else if ((status & (uint32_t)kI2C_ReceiveNakFlag) != 0U)
    {
        result = kStatus_I2C_Nak;
    }
    else
    {
        /* Avoid MISRA 2012 rule 15.7 violation */
    }

    return result;
}

static status_t I2C_MasterTransferRunStateMachine(I2C_Type *base, i2c_master_handle_t *handle, bool *isDone)
{
    status_t result        = kStatus_Success;
    uint32_t statusFlags   = base->I2SR;
    *isDone                = false;
    volatile uint8_t dummy = 0U;
    bool ignoreNak         = ((handle->state == (uint8_t)kSendDataState) && (handle->transfer.dataSize == 0U)) ||
                     ((handle->state == (uint8_t)kReceiveDataState) && (handle->transfer.dataSize == 1U));

    /* Add this to avoid build warning. */
    dummy++;

    /* Check & clear error flags. */
    result = I2C_CheckAndClearError(base, statusFlags);

    /* Ignore Nak when it's appeared for last byte. */
    if ((result == kStatus_I2C_Nak) && ignoreNak)
    {
        result = kStatus_Success;
    }

    /* Handle Check address state to check the slave address is Acked in slave
       probe application. */
    if (handle->state == (uint8_t)kCheckAddressState)
    {
        if ((statusFlags & (uint32_t)kI2C_ReceiveNakFlag) != 0U)
        {
            result = kStatus_I2C_Addr_Nak;
        }
        else
        {
            if (handle->transfer.subaddressSize > 0U)
            {
                handle->state = (uint8_t)kSendCommandState;
            }
            else
            {
                if (handle->transfer.direction == kI2C_Write)
                {
                    /* Next state, send data. */
                    handle->state = (uint8_t)kSendDataState;
                }
                else
                {
                    /* Next state, receive data begin. */
                    handle->state = (uint8_t)kReceiveDataBeginState;
                }
            }
        }
    }

    if (result != kStatus_Success)
    {
        return result;
    }

    /* Run state machine. */
    switch (handle->state)
    {
        /* Send I2C command. */
        case (uint8_t)kSendCommandState:
            if (handle->transfer.subaddressSize != 0U)
            {
                handle->transfer.subaddressSize--;
                base->I2DR = (uint16_t)((handle->transfer.subaddress) >> (8U * handle->transfer.subaddressSize));
            }
            else
            {
                if (handle->transfer.direction == kI2C_Write)
                {
                    /* Send first byte of data. */
                    if (handle->transfer.dataSize > 0U)
                    {
                        /* Next state, send data. */
                        handle->state = (uint8_t)kSendDataState;
                        base->I2DR    = *handle->transfer.data;
                        handle->transfer.data++;
                        handle->transfer.dataSize--;
                    }
                    else
                    {
                        *isDone = true;
                    }
                }
                else
                {
                    /* Send repeated start and slave address. */
                    result = I2C_MasterRepeatedStart(base, handle->transfer.slaveAddress, kI2C_Read);

                    /* Next state, receive data begin. */
                    handle->state = (uint8_t)kReceiveDataBeginState;
                }
            }
            break;

        /* Send I2C data. */
        case (uint8_t)kSendDataState:
            /* Send one byte of data. */
            if (handle->transfer.dataSize > 0U)
            {
                base->I2DR = *handle->transfer.data;
                handle->transfer.data++;
                handle->transfer.dataSize--;
            }
            else
            {
                *isDone = true;
            }
            break;

        /* Start I2C data receive. */
        case (uint8_t)kReceiveDataBeginState:
            base->I2CR &= ~((uint16_t)I2C_I2CR_MTX_MASK | (uint16_t)I2C_I2CR_TXAK_MASK);

            /* Send nak at the last receive byte. */
            if (handle->transfer.dataSize == 1U)
            {
                base->I2CR |= I2C_I2CR_TXAK_MASK;
            }

            /* Read dummy to release the bus. */
            dummy = (uint8_t)base->I2DR;

            /* Next state, receive data. */
            handle->state = (uint8_t)kReceiveDataState;
            break;

        /* Receive I2C data. */
        case (uint8_t)kReceiveDataState:
            /* Receive one byte of data. */
            if (0U != handle->transfer.dataSize--)
            {
                if (handle->transfer.dataSize == 0U)
                {
                    *isDone = true;

                    /* Send stop if kI2C_TransferNoStop is not asserted. */
                    if (0U == (handle->transfer.flags & (uint32_t)kI2C_TransferNoStopFlag))
                    {
                        result = I2C_MasterStop(base);
                    }
                    else
                    {
                        base->I2CR |= I2C_I2CR_MTX_MASK;
                    }
                }

                /* Send NAK at the last receive byte. */
                if (handle->transfer.dataSize == 1U)
                {
                    base->I2CR |= I2C_I2CR_TXAK_MASK;
                }

                /* Read the data byte into the transfer buffer. */
                *handle->transfer.data = (uint8_t)base->I2DR;
                handle->transfer.data++;
            }
            break;

        default:
            assert(false);
            break;
    }

    return result;
}

static void I2C_TransferCommonIRQHandler(I2C_Type *base, void *handle)
{
    /* Check if master interrupt. */
    if (((base->I2SR & (uint8_t)kI2C_ArbitrationLostFlag) != 0U) || ((base->I2CR & (uint8_t)I2C_I2CR_MSTA_MASK) != 0U))
    {
        s_i2cMasterIsr(base, handle);
    }
    else
    {
        s_i2cSlaveIsr(base, handle);
    }
    __DSB();
}

/*!
 * brief Initializes the I2C peripheral. Call this API to ungate the I2C clock
 * and configure the I2C with master configuration.
 *
 * note This API should be called at the beginning of the application.
 * Otherwise, any operation to the I2C module can cause a hard fault
 * because the clock is not enabled. The configuration structure can be custom filled
 * or it can be set with default values by using the I2C_MasterGetDefaultConfig().
 * After calling this API, the master is ready to transfer.
 * This is an example.
 * code
 * i2c_master_config_t config = {
 * .enableMaster = true,
 * .baudRate_Bps = 100000
 * };
 * I2C_MasterInit(I2C0, &config, 12000000U);
 * endcode
 *
 * param base I2C base pointer
 * param masterConfig A pointer to the master configuration structure
 * param srcClock_Hz I2C peripheral clock frequency in Hz
 */
void I2C_MasterInit(I2C_Type *base, const i2c_master_config_t *masterConfig, uint32_t srcClock_Hz)
{
    assert((masterConfig != NULL) && (srcClock_Hz != 0U));

#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
    /* Enable I2C clock. */
    CLOCK_EnableClock(s_i2cClocks[I2C_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */

    /* Reset the module. */
    base->IADR = 0;
    base->IFDR = 0;
    base->I2CR = 0;
    base->I2SR = 0;

    /* Disable I2C prior to configuring it. */
    base->I2CR &= ~((uint16_t)I2C_I2CR_IEN_MASK);

    /* Clear all flags. */
    I2C_MasterClearStatusFlags(base, (uint32_t)kClearFlags);

    /* Configure baud rate. */
    I2C_MasterSetBaudRate(base, masterConfig->baudRate_Bps, srcClock_Hz);

    /* Enable the I2C peripheral based on the configuration. */
    base->I2CR = I2C_I2CR_IEN(masterConfig->enableMaster);
}

/*!
 * brief De-initializes the I2C master peripheral. Call this API to gate the I2C clock.
 * The I2C master module can't work unless the I2C_MasterInit is called.
 * param base I2C base pointer
 */
void I2C_MasterDeinit(I2C_Type *base)
{
    /* Disable I2C module. */
    I2C_Enable(base, false);

#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
    /* Disable I2C clock. */
    CLOCK_DisableClock(s_i2cClocks[I2C_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
}

/*!
 * brief  Sets the I2C master configuration structure to default values.
 *
 * The purpose of this API is to get the configuration structure initialized for use in the I2C_MasterInit().
 * Use the initialized structure unchanged in the I2C_MasterInit() or modify
 * the structure before calling the I2C_MasterInit().
 * This is an example.
 * code
 * i2c_master_config_t config;
 * I2C_MasterGetDefaultConfig(&config);
 * endcode
 * param masterConfig A pointer to the master configuration structure.
 */
void I2C_MasterGetDefaultConfig(i2c_master_config_t *masterConfig)
{
    assert(masterConfig);

    /* Initializes the configure structure to zero. */
    (void)memset(masterConfig, 0, sizeof(*masterConfig));

    /* Default baud rate at 100kbps. */
    masterConfig->baudRate_Bps = 100000U;

    /* Enable the I2C peripheral. */
    masterConfig->enableMaster = true;
}

/*!
 * brief Enables I2C interrupt requests.
 *
 * param base I2C base pointer
 * param mask interrupt source
 *     The parameter can be combination of the following source if defined:
 *     arg kI2C_GlobalInterruptEnable
 *     arg kI2C_StopDetectInterruptEnable/kI2C_StartDetectInterruptEnable
 *     arg kI2C_SdaTimeoutInterruptEnable
 */
void I2C_EnableInterrupts(I2C_Type *base, uint32_t mask)
{
    if ((mask & (uint32_t)kI2C_GlobalInterruptEnable) != 0U)
    {
        base->I2CR |= I2C_I2CR_IIEN_MASK;
    }
}

/*!
 * brief Disables I2C interrupt requests.
 *
 * param base I2C base pointer
 * param mask interrupt source
 *     The parameter can be combination of the following source if defined:
 *     arg kI2C_GlobalInterruptEnable
 *     arg kI2C_StopDetectInterruptEnable/kI2C_StartDetectInterruptEnable
 *     arg kI2C_SdaTimeoutInterruptEnable
 */
void I2C_DisableInterrupts(I2C_Type *base, uint32_t mask)
{
    if ((mask & (uint32_t)kI2C_GlobalInterruptEnable) != 0U)
    {
        base->I2CR &= ~(uint16_t)I2C_I2CR_IIEN_MASK;
    }
}

/*!
 * brief Sets the I2C master transfer baud rate.
 *
 * param base I2C base pointer
 * param baudRate_Bps the baud rate value in bps
 * param srcClock_Hz Source clock
 */
void I2C_MasterSetBaudRate(I2C_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz)
{
    uint32_t computedRate;
    uint32_t absError;
    uint32_t bestError = UINT32_MAX;
    uint32_t bestIcr   = 0u;
    uint8_t i;

    /* Scan table to find best match. */
    for (i = 0u; i < sizeof(s_i2cDividerTable) / sizeof(s_i2cDividerTable[0]); ++i)
    {
        computedRate = srcClock_Hz / s_i2cDividerTable[i];
        absError     = baudRate_Bps > computedRate ? (baudRate_Bps - computedRate) : (computedRate - baudRate_Bps);

        if (absError < bestError)
        {
            bestIcr   = i;
            bestError = absError;

            /* If the error is 0, then we can stop searching because we won't find a better match. */
            if (absError == 0U)
            {
                break;
            }
        }
    }

    /* Set frequency register based on best settings. */
    base->IFDR = I2C_IFDR_IC(bestIcr);
}

/*!
 * brief Sends a START on the I2C bus.
 *
 * This function is used to initiate a new master mode transfer by sending the START signal.
 * The slave address is sent following the I2C START signal.
 *
 * param base I2C peripheral base pointer
 * param address 7-bit slave device address.
 * param direction Master transfer directions(transmit/receive).
 * retval kStatus_Success Successfully send the start signal.
 * retval kStatus_I2C_Busy Current bus is busy.
 */
status_t I2C_MasterStart(I2C_Type *base, uint8_t address, i2c_direction_t direction)
{
    status_t result      = kStatus_Success;
    uint32_t statusFlags = I2C_MasterGetStatusFlags(base);

    /* Return an error if the bus is already in use. */
    if ((statusFlags & (uint32_t)kI2C_BusBusyFlag) != 0U)
    {
        result = kStatus_I2C_Busy;
    }
    else
    {
        /* Send the START signal. */
        base->I2CR |= I2C_I2CR_MSTA_MASK | I2C_I2CR_MTX_MASK;

        base->I2DR = (uint16_t)(((uint32_t)address) << 1U | ((direction == kI2C_Read) ? 1U : 0U));
    }

    return result;
}

/*!
 * brief Sends a REPEATED START on the I2C bus.
 *
 * param base I2C peripheral base pointer
 * param address 7-bit slave device address.
 * param direction Master transfer directions(transmit/receive).
 * retval kStatus_Success Successfully send the start signal.
 * retval kStatus_I2C_Busy Current bus is busy but not occupied by current I2C master.
 */
status_t I2C_MasterRepeatedStart(I2C_Type *base, uint8_t address, i2c_direction_t direction)
{
    status_t result      = kStatus_Success;
    uint32_t statusFlags = I2C_MasterGetStatusFlags(base);

    /* Return an error if the bus is already in use, but not by us. */
    if (((statusFlags & (uint32_t)kI2C_BusBusyFlag) != 0U) && ((base->I2CR & (uint16_t)I2C_I2CR_MSTA_MASK) == 0U))
    {
        result = kStatus_I2C_Busy;
    }
    else
    {
        /* We are already in a transfer, so send a repeated start. */
        base->I2CR |= I2C_I2CR_RSTA_MASK | I2C_I2CR_MTX_MASK;

        base->I2DR = (uint16_t)(((uint32_t)address) << 1U | ((direction == kI2C_Read) ? 1U : 0U));
    }

    return result;
}

/*!
 * brief Sends a STOP signal on the I2C bus.
 *
 * retval kStatus_Success Successfully send the stop signal.
 * retval kStatus_I2C_Timeout Send stop signal failed, timeout.
 */
status_t I2C_MasterStop(I2C_Type *base)
{
    /* Issue the STOP command on the bus. */
    base->I2CR &= ~((uint16_t)I2C_I2CR_MSTA_MASK | (uint16_t)I2C_I2CR_MTX_MASK | (uint16_t)I2C_I2CR_TXAK_MASK);

#if I2C_RETRY_TIMES
    uint32_t waitTimes = I2C_RETRY_TIMES;
    /* Wait for IBB bit is cleared. */
    while ((0U != (base->I2SR & (uint8_t)kI2C_BusBusyFlag)) && (0U != --waitTimes))
    {
    }
    if (0U == waitTimes)
    {
        return kStatus_I2C_Timeout;
    }
#else
    /* Wait for IBB bit is cleared. */
    while (0U != (base->I2SR & (uint8_t)kI2C_BusBusyFlag))
    {
    }
#endif
    return kStatus_Success;
}

/*!
 * brief Performs a polling send transaction on the I2C bus.
 *
 * param base  The I2C peripheral base pointer.
 * param txBuff The pointer to the data to be transferred.
 * param txSize The length in bytes of the data to be transferred.
 * param flags Transfer control flag to decide whether need to send a stop, use kI2C_TransferDefaultFlag
 *  to issue a stop and kI2C_TransferNoStop to not send a stop.
 * retval kStatus_Success Successfully complete the data transmission.
 * retval kStatus_I2C_ArbitrationLost Transfer error, arbitration lost.
 * retval kStataus_I2C_Nak Transfer error, receive NAK during transfer.
 */
status_t I2C_MasterWriteBlocking(I2C_Type *base, const uint8_t *txBuff, size_t txSize, uint32_t flags)
{
    status_t result     = kStatus_Success;
    uint8_t statusFlags = 0;

    if (I2C_WaitForStatusReady(base, (uint8_t)kI2C_TransferCompleteFlag) != kStatus_Success)
    {
        return kStatus_I2C_Timeout;
    }

    /* Clear the IICIF flag. */
    base->I2SR &= ~(uint16_t)kI2C_IntPendingFlag;

    /* Setup the I2C peripheral to transmit data. */
    base->I2CR |= I2C_I2CR_MTX_MASK;

    while (0U != txSize--)
    {
        /* Send a byte of data. */
        base->I2DR = *txBuff++;

        if (I2C_WaitForStatusReady(base, (uint8_t)kI2C_IntPendingFlag) != kStatus_Success)
        {
            return kStatus_I2C_Timeout;
        }

        statusFlags = (uint8_t)base->I2SR;

        /* Clear the IICIF flag. */
        base->I2SR &= ~(uint16_t)kI2C_IntPendingFlag;

        /* Check if arbitration lost or no acknowledgement (NAK), return failure status. */
        if ((statusFlags & (uint8_t)kI2C_ArbitrationLostFlag) != 0U)
        {
            base->I2SR = (uint16_t)kI2C_ArbitrationLostFlag;
            result     = kStatus_I2C_ArbitrationLost;
        }

        if (((statusFlags & (uint8_t)kI2C_ReceiveNakFlag) != 0U) && (txSize != 0U))
        {
            base->I2SR = (uint16_t)kI2C_ReceiveNakFlag;
            result     = kStatus_I2C_Nak;
        }

        if (result != kStatus_Success)
        {
            /* Breaking out of the send loop. */
            break;
        }
    }

    if (((result == kStatus_Success) && (0U == (flags & (uint32_t)kI2C_TransferNoStopFlag))) ||
        (result == kStatus_I2C_Nak))
    {
        /* Clear the IICIF flag. */
        base->I2SR &= ~(uint16_t)kI2C_IntPendingFlag;

        /* Send stop. */
        result = I2C_MasterStop(base);
    }

    return result;
}

/*!
 * brief Performs a polling receive transaction on the I2C bus.
 *
 * note The I2C_MasterReadBlocking function stops the bus before reading the final byte.
 * Without stopping the bus prior for the final read, the bus issues another read, resulting
 * in garbage data being read into the data register.
 *
 * param base I2C peripheral base pointer.
 * param rxBuff The pointer to the data to store the received data.
 * param rxSize The length in bytes of the data to be received.
 * param flags Transfer control flag to decide whether need to send a stop, use kI2C_TransferDefaultFlag
 *  to issue a stop and kI2C_TransferNoStop to not send a stop.
 * retval kStatus_Success Successfully complete the data transmission.
 * retval kStatus_I2C_Timeout Send stop signal failed, timeout.
 */
status_t I2C_MasterReadBlocking(I2C_Type *base, uint8_t *rxBuff, size_t rxSize, uint32_t flags)
{
    status_t result        = kStatus_Success;
    volatile uint8_t dummy = 0;

    /* Add this to avoid build warning. */
    dummy++;

    if (I2C_WaitForStatusReady(base, (uint8_t)kI2C_TransferCompleteFlag) != kStatus_Success)
    {
        return kStatus_I2C_Timeout;
    }

    /* Clear the IICIF flag. */
    base->I2SR &= ~(uint16_t)kI2C_IntPendingFlag;

    /* Setup the I2C peripheral to receive data. */
    base->I2CR &= ~((uint16_t)I2C_I2CR_MTX_MASK | (uint16_t)I2C_I2CR_TXAK_MASK);

    /* If rxSize equals 1, configure to send NAK. */
    if (rxSize == 1U)
    {
        /* Issue NACK on read. */
        base->I2CR |= I2C_I2CR_TXAK_MASK;
    }

    /* Do dummy read. */
    dummy = (uint8_t)base->I2DR;

    while (0U != (rxSize--))
    {
        if (I2C_WaitForStatusReady(base, (uint8_t)kI2C_IntPendingFlag) != kStatus_Success)
        {
            return kStatus_I2C_Timeout;
        }

        /* Clear the IICIF flag. */
        base->I2SR &= ~(uint16_t)kI2C_IntPendingFlag;

        /* Single byte use case. */
        if (rxSize == 0U)
        {
            if (0U == (flags & (uint32_t)kI2C_TransferNoStopFlag))
            {
                /* Issue STOP command before reading last byte. */
                result = I2C_MasterStop(base);
            }
            else
            {
                /* Change direction to Tx to avoid extra clocks. */
                base->I2CR |= I2C_I2CR_MTX_MASK;
            }
        }

        if (rxSize == 1U)
        {
            /* Issue NACK on read. */
            base->I2CR |= I2C_I2CR_TXAK_MASK;
        }

        /* Read from the data register. */
        *rxBuff++ = (uint8_t)base->I2DR;
    }

    return result;
}

/*!
 * brief Performs a master polling transfer on the I2C bus.
 *
 * note The API does not return until the transfer succeeds or fails due
 * to arbitration lost or receiving a NAK.
 *
 * param base I2C peripheral base address.
 * param xfer Pointer to the transfer structure.
 * retval kStatus_Success Successfully complete the data transmission.
 * retval kStatus_I2C_Busy Previous transmission still not finished.
 * retval kStatus_I2C_Timeout Transfer error, wait signal timeout.
 * retval kStatus_I2C_ArbitrationLost Transfer error, arbitration lost.
 * retval kStataus_I2C_Nak Transfer error, receive NAK during transfer.
 */
status_t I2C_MasterTransferBlocking(I2C_Type *base, i2c_master_transfer_t *xfer)
{
    assert(xfer);

    i2c_direction_t direction = xfer->direction;
    status_t result           = kStatus_Success;

    /* Clear all status before transfer. */
    I2C_MasterClearStatusFlags(base, (uint32_t)kClearFlags);

    if (I2C_WaitForStatusReady(base, (uint8_t)kI2C_TransferCompleteFlag) != kStatus_Success)
    {
        return kStatus_I2C_Timeout;
    }

    /* Change to send write address when it's a read operation with command. */
    if ((xfer->subaddressSize > 0U) && (xfer->direction == kI2C_Read))
    {
        direction = kI2C_Write;
    }

    /* Handle no start option, only support write with no start signal. */
    if ((xfer->flags & (uint32_t)kI2C_TransferNoStartFlag) != 0U)
    {
        if (direction == kI2C_Read)
        {
            return kStatus_InvalidArgument;
        }
    }
    /* If repeated start is requested, send repeated start. */
    else if ((xfer->flags & (uint32_t)kI2C_TransferRepeatedStartFlag) != 0U)
    {
        result = I2C_MasterRepeatedStart(base, xfer->slaveAddress, direction);
    }
    else /* For normal transfer, send start. */
    {
        result = I2C_MasterStart(base, xfer->slaveAddress, direction);
    }

    if (0U == (xfer->flags & (uint32_t)kI2C_TransferNoStartFlag))
    {
        /* Return if error. */
        if (result != kStatus_Success)
        {
            return result;
        }

        if (I2C_WaitForStatusReady(base, (uint8_t)kI2C_IntPendingFlag) != kStatus_Success)
        {
            return kStatus_I2C_Timeout;
        }

        /* Check if there's transfer error. */
        result = I2C_CheckAndClearError(base, base->I2SR);

        /* Return if error. */
        if (result != kStatus_Success)
        {
            if (result == kStatus_I2C_Nak)
            {
                result = kStatus_I2C_Addr_Nak;

                (void)I2C_MasterStop(base);
            }

            return result;
        }
    }

    /* Send subaddress. */
    if (xfer->subaddressSize != 0U)
    {
        do
        {
            /* Clear interrupt pending flag. */
            base->I2SR &= ~(uint16_t)kI2C_IntPendingFlag;

            xfer->subaddressSize--;
            base->I2DR = (uint16_t)((xfer->subaddress) >> (8U * xfer->subaddressSize));

            if (I2C_WaitForStatusReady(base, (uint8_t)kI2C_IntPendingFlag) != kStatus_Success)
            {
                return kStatus_I2C_Timeout;
            }

            /* Check if there's transfer error. */
            result = I2C_CheckAndClearError(base, base->I2SR);

            if (result != kStatus_Success)
            {
                if (result == kStatus_I2C_Nak)
                {
                    (void)I2C_MasterStop(base);
                }

                return result;
            }

        } while (xfer->subaddressSize > 0U);

        if (xfer->direction == kI2C_Read)
        {
            /* Clear pending flag. */
            base->I2SR &= ~(uint16_t)kI2C_IntPendingFlag;

            /* Send repeated start and slave address. */
            result = I2C_MasterRepeatedStart(base, xfer->slaveAddress, kI2C_Read);

            /* Return if error. */
            if (result != kStatus_Success)
            {
                return result;
            }

            if (I2C_WaitForStatusReady(base, (uint8_t)kI2C_IntPendingFlag) != kStatus_Success)
            {
                return kStatus_I2C_Timeout;
            }

            /* Check if there's transfer error. */
            result = I2C_CheckAndClearError(base, base->I2SR);

            if (result != kStatus_Success)
            {
                if (result == kStatus_I2C_Nak)
                {
                    result = kStatus_I2C_Addr_Nak;

                    (void)I2C_MasterStop(base);
                }

                return result;
            }
        }
    }

    /* Transmit data. */
    if (xfer->direction == kI2C_Write)
    {
        if (xfer->dataSize > 0U)
        {
            /* Send Data. */
            result = I2C_MasterWriteBlocking(base, xfer->data, xfer->dataSize, xfer->flags);
        }
        else if (0U == (xfer->flags & (uint32_t)kI2C_TransferNoStopFlag))
        {
            /* Send stop. */
            result = I2C_MasterStop(base);
        }
        else
        {
            /* Avoid MISRA 2012 rule 15.7 violation */
        }
    }
    /* Receive Data. */
    if ((xfer->direction == kI2C_Read) && (xfer->dataSize > 0U))
    {
        result = I2C_MasterReadBlocking(base, xfer->data, xfer->dataSize, xfer->flags);
    }

    return result;
}

/*!
 * brief Initializes the I2C handle which is used in transactional functions.
 *
 * param base I2C base pointer.
 * param handle pointer to i2c_master_handle_t structure to store the transfer state.
 * param callback pointer to user callback function.
 * param userData user parameter passed to the callback function.
 */
void I2C_MasterTransferCreateHandle(I2C_Type *base,
                                    i2c_master_handle_t *handle,
                                    i2c_master_transfer_callback_t callback,
                                    void *userData)
{
    assert(handle);

    uint32_t instance = I2C_GetInstance(base);

    /* Zero handle. */
    (void)memset(handle, 0, sizeof(*handle));

    /* Set callback and userData. */
    handle->completionCallback = callback;
    handle->userData           = userData;

    /* Save the context in global variables to support the double weak mechanism. */
    s_i2cHandle[instance] = handle;

    /* Save master interrupt handler. */
    s_i2cMasterIsr = I2C_MasterTransferHandleIRQ;

    /* Enable NVIC interrupt. */
    (void)EnableIRQ(s_i2cIrqs[instance]);
}

/*!
 * brief Performs a master interrupt non-blocking transfer on the I2C bus.
 *
 * note Calling the API returns immediately after transfer initiates. The user needs
 * to call I2C_MasterGetTransferCount to poll the transfer status to check whether
 * the transfer is finished. If the return status is not kStatus_I2C_Busy, the transfer
 * is finished.
 *
 * param base I2C base pointer.
 * param handle pointer to i2c_master_handle_t structure which stores the transfer state.
 * param xfer pointer to i2c_master_transfer_t structure.
 * retval kStatus_Success Successfully start the data transmission.
 * retval kStatus_I2C_Busy Previous transmission still not finished.
 * retval kStatus_I2C_Timeout Transfer error, wait signal timeout.
 */
status_t I2C_MasterTransferNonBlocking(I2C_Type *base, i2c_master_handle_t *handle, i2c_master_transfer_t *xfer)
{
    assert(handle);
    assert(xfer);

    status_t result = kStatus_Success;

    /* Check if the I2C bus is idle - if not return busy status. */
    if (handle->state != (uint8_t)kIdleState)
    {
        result = kStatus_I2C_Busy;
    }
    else
    {
        /* Start up the master transfer state machine. */
        result = I2C_InitTransferStateMachine(base, handle, xfer);

        if (result == kStatus_Success)
        {
            /* Enable the I2C interrupts. */
            I2C_EnableInterrupts(base, (uint32_t)kI2C_GlobalInterruptEnable);
        }
    }

    return result;
}

/*!
 * brief Aborts an interrupt non-blocking transfer early.
 *
 * note This API can be called at any time when an interrupt non-blocking transfer initiates
 * to abort the transfer early.
 *
 * param base I2C base pointer.
 * param handle pointer to i2c_master_handle_t structure which stores the transfer state
 * retval kStatus_I2C_Timeout Timeout during polling flag.
 * retval kStatus_Success Successfully abort the transfer.
 */
status_t I2C_MasterTransferAbort(I2C_Type *base, i2c_master_handle_t *handle)
{
    assert(handle);

    volatile uint8_t dummy = 0;

    /* Add this to avoid build warning. */
    dummy++;

    /* Disable interrupt. */
    I2C_DisableInterrupts(base, (uint32_t)kI2C_GlobalInterruptEnable);

    /* Reset the state to idle. */
    handle->state = (uint8_t)kIdleState;

    /* Send STOP signal. */
    if (handle->transfer.direction == kI2C_Read)
    {
        base->I2CR |= I2C_I2CR_TXAK_MASK;

        if (I2C_WaitForStatusReady(base, (uint8_t)kI2C_IntPendingFlag) != kStatus_Success)
        {
            return kStatus_I2C_Timeout;
        }
        base->I2SR &= ~(uint16_t)kI2C_IntPendingFlag;

        base->I2CR &= ~((uint16_t)I2C_I2CR_MSTA_MASK | (uint16_t)I2C_I2CR_MTX_MASK | (uint16_t)I2C_I2CR_TXAK_MASK);
        dummy = (uint8_t)base->I2DR;
    }
    else
    {
        if (I2C_WaitForStatusReady(base, (uint8_t)kI2C_IntPendingFlag) != kStatus_Success)
        {
            return kStatus_I2C_Timeout;
        }
        base->I2SR &= ~(uint16_t)kI2C_IntPendingFlag;
        base->I2CR &= ~((uint16_t)I2C_I2CR_MSTA_MASK | (uint16_t)I2C_I2CR_MTX_MASK | (uint16_t)I2C_I2CR_TXAK_MASK);
    }
    return kStatus_Success;
}

/*!
 * brief Gets the master transfer status during a interrupt non-blocking transfer.
 *
 * param base I2C base pointer.
 * param handle pointer to i2c_master_handle_t structure which stores the transfer state.
 * param count Number of bytes transferred so far by the non-blocking transaction.
 * retval kStatus_InvalidArgument count is Invalid.
 * retval kStatus_Success Successfully return the count.
 */
status_t I2C_MasterTransferGetCount(I2C_Type *base, i2c_master_handle_t *handle, size_t *count)
{
    assert(handle);

    if (NULL == count)
    {
        return kStatus_InvalidArgument;
    }

    *count = handle->transferSize - handle->transfer.dataSize;

    return kStatus_Success;
}

/*!
 * brief Master interrupt handler.
 *
 * param base I2C base pointer.
 * param i2cHandle pointer to i2c_master_handle_t structure.
 */
void I2C_MasterTransferHandleIRQ(I2C_Type *base, void *i2cHandle)
{
    assert(i2cHandle);

    i2c_master_handle_t *handle = (i2c_master_handle_t *)i2cHandle;
    status_t result             = kStatus_Success;
    bool isDone;

    /* Clear the interrupt flag. */
    base->I2SR &= ~(uint16_t)kI2C_IntPendingFlag;

    /* Check transfer complete flag. */
    result = I2C_MasterTransferRunStateMachine(base, handle, &isDone);

    if (isDone || (result != kStatus_Success))
    {
        /* Send stop command if transfer done or received Nak. */
        if ((0U == (handle->transfer.flags & (uint32_t)kI2C_TransferNoStopFlag)) || (result == kStatus_I2C_Nak) ||
            (result == kStatus_I2C_Addr_Nak))
        {
            /* Ensure stop command is a need. */
            if ((base->I2CR & I2C_I2CR_MSTA_MASK) != 0U)
            {
                if (I2C_MasterStop(base) != kStatus_Success)
                {
                    result = kStatus_I2C_Timeout;
                }
            }
        }

        /* Restore handle to idle state. */
        handle->state = (uint8_t)kIdleState;

        /* Disable interrupt. */
        I2C_DisableInterrupts(base, (uint32_t)kI2C_GlobalInterruptEnable);

        /* Call the callback function after the function has completed. */
        if (handle->completionCallback != NULL)
        {
            handle->completionCallback(base, handle, result, handle->userData);
        }
    }
}

/*!
 * brief Initializes the I2C peripheral. Call this API to ungate the I2C clock
 * and initialize the I2C with the slave configuration.
 *
 * note This API should be called at the beginning of the application.
 * Otherwise, any operation to the I2C module can cause a hard fault
 * because the clock is not enabled. The configuration structure can partly be set
 * with default values by I2C_SlaveGetDefaultConfig() or it can be custom filled by the user.
 * This is an example.
 * code
 * i2c_slave_config_t config = {
 * .enableSlave = true,
 * .slaveAddress = 0x1DU,
 * };
 * I2C_SlaveInit(I2C0, &config);
 * endcode
 *
 * param base I2C base pointer
 * param slaveConfig A pointer to the slave configuration structure
 * param srcClock_Hz I2C peripheral clock frequency in Hz
 */
void I2C_SlaveInit(I2C_Type *base, const i2c_slave_config_t *slaveConfig)
{
    assert(slaveConfig != NULL);

#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
    /* Enable I2C clock. */
    CLOCK_EnableClock(s_i2cClocks[I2C_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */

    /* Reset the module. */
    base->IADR = 0;
    base->IFDR = 0;
    base->I2CR = 0;
    base->I2SR = 0;

    base->IADR = (uint16_t)((uint32_t)(slaveConfig->slaveAddress)) << 1U;
    base->I2CR = I2C_I2CR_IEN(slaveConfig->enableSlave);
}

/*!
 * brief De-initializes the I2C slave peripheral. Calling this API gates the I2C clock.
 * The I2C slave module can't work unless the I2C_SlaveInit is called to enable the clock.
 * param base I2C base pointer
 */
void I2C_SlaveDeinit(I2C_Type *base)
{
    /* Disable I2C module. */
    I2C_Enable(base, false);

#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
    /* Disable I2C clock. */
    CLOCK_DisableClock(s_i2cClocks[I2C_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
}

/*!
 * brief  Sets the I2C slave configuration structure to default values.
 *
 * The purpose of this API is to get the configuration structure initialized for use in the I2C_SlaveInit().
 * Modify fields of the structure before calling the I2C_SlaveInit().
 * This is an example.
 * code
 * i2c_slave_config_t config;
 * I2C_SlaveGetDefaultConfig(&config);
 * endcode
 * param slaveConfig A pointer to the slave configuration structure.
 */
void I2C_SlaveGetDefaultConfig(i2c_slave_config_t *slaveConfig)
{
    assert(slaveConfig);

    /* Initializes the configure structure to zero. */
    (void)memset(slaveConfig, 0, sizeof(*slaveConfig));

    /* Enable the I2C peripheral. */
    slaveConfig->enableSlave = true;
}

/*!
 * brief Performs a polling send transaction on the I2C bus.
 *
 * param base  The I2C peripheral base pointer.
 * param txBuff The pointer to the data to be transferred.
 * param txSize The length in bytes of the data to be transferred.
 * retval kStatus_Success Successfully complete the data transmission.
 * retval kStatus_I2C_ArbitrationLost Transfer error, arbitration lost.
 * retval kStataus_I2C_Nak Transfer error, receive NAK during transfer.
 */
status_t I2C_SlaveWriteBlocking(I2C_Type *base, const uint8_t *txBuff, size_t txSize)
{
    status_t result        = kStatus_Success;
    volatile uint8_t dummy = 0;

    /* Add this to avoid build warning. */
    dummy++;

    if (I2C_WaitForStatusReady(base, (uint8_t)kI2C_AddressMatchFlag) != kStatus_Success)
    {
        return kStatus_I2C_Timeout;
    }

    /* Read dummy to release bus. */
    dummy = (uint8_t)base->I2DR;

    result = I2C_MasterWriteBlocking(base, txBuff, txSize, (uint32_t)kI2C_TransferDefaultFlag);

    /* Switch to receive mode. */
    base->I2CR &= ~((uint16_t)I2C_I2CR_MTX_MASK | (uint16_t)I2C_I2CR_TXAK_MASK);

    /* Read dummy to release bus. */
    dummy = (uint8_t)base->I2DR;

    return result;
}

/*!
 * brief Performs a polling receive transaction on the I2C bus.
 *
 * param base I2C peripheral base pointer.
 * param rxBuff The pointer to the data to store the received data.
 * param rxSize The length in bytes of the data to be received.
 */
status_t I2C_SlaveReadBlocking(I2C_Type *base, uint8_t *rxBuff, size_t rxSize)
{
    volatile uint8_t dummy = 0;

    /* Add this to avoid build warning. */
    dummy++;

    if (I2C_WaitForStatusReady(base, (uint8_t)kI2C_AddressMatchFlag) != kStatus_Success)
    {
        return kStatus_I2C_Timeout;
    }

    /* Read dummy to release bus. */
    dummy = (uint8_t)base->I2DR;

    /* Clear the IICIF flag. */
    base->I2SR &= ~(uint16_t)kI2C_IntPendingFlag;

    /* Setup the I2C peripheral to receive data. */
    base->I2CR &= ~((uint16_t)I2C_I2CR_MTX_MASK);

    while (0U != rxSize--)
    {
        if (I2C_WaitForStatusReady(base, (uint8_t)kI2C_IntPendingFlag) != kStatus_Success)
        {
            return kStatus_I2C_Timeout;
        }
        /* Clear the IICIF flag. */
        base->I2SR &= ~(uint16_t)kI2C_IntPendingFlag;

        /* Read from the data register. */
        *rxBuff++ = (uint8_t)base->I2DR;
    }
    return kStatus_Success;
}

/*!
 * brief Initializes the I2C handle which is used in transactional functions.
 *
 * param base I2C base pointer.
 * param handle pointer to i2c_slave_handle_t structure to store the transfer state.
 * param callback pointer to user callback function.
 * param userData user parameter passed to the callback function.
 */
void I2C_SlaveTransferCreateHandle(I2C_Type *base,
                                   i2c_slave_handle_t *handle,
                                   i2c_slave_transfer_callback_t callback,
                                   void *userData)
{
    assert(handle);

    uint32_t instance = I2C_GetInstance(base);

    /* Zero handle. */
    (void)memset(handle, 0, sizeof(*handle));

    /* Set callback and userData. */
    handle->callback = callback;
    handle->userData = userData;

    /* Save the context in global variables to support the double weak mechanism. */
    s_i2cHandle[instance] = handle;

    /* Save slave interrupt handler. */
    s_i2cSlaveIsr = I2C_SlaveTransferHandleIRQ;

    /* Enable NVIC interrupt. */
    (void)EnableIRQ(s_i2cIrqs[instance]);
}

/*!
 * brief Starts accepting slave transfers.
 *
 * Call this API after calling the I2C_SlaveInit() and I2C_SlaveTransferCreateHandle() to start processing
 * transactions driven by an I2C master. The slave monitors the I2C bus and passes events to the
 * callback that was passed into the call to I2C_SlaveTransferCreateHandle(). The callback is always invoked
 * from the interrupt context.
 *
 * The set of events received by the callback is customizable. To do so, set the a eventMask parameter to
 * the OR'd combination of #i2c_slave_transfer_event_t enumerators for the events you wish to receive.
 * The #kI2C_SlaveTransmitEvent and #kLPI2C_SlaveReceiveEvent events are always enabled and do not need
 * to be included in the mask. Alternatively, pass 0 to get a default set of only the transmit and
 * receive events that are always enabled. In addition, the #kI2C_SlaveAllEvents constant is provided as
 * a convenient way to enable all events.
 *
 * param base The I2C peripheral base address.
 * param handle Pointer to #i2c_slave_handle_t structure which stores the transfer state.
 * param eventMask Bit mask formed by OR'ing together #i2c_slave_transfer_event_t enumerators to specify
 *      which events to send to the callback. Other accepted values are 0 to get a default set of
 *      only the transmit and receive events, and #kI2C_SlaveAllEvents to enable all events.
 *
 * retval #kStatus_Success Slave transfers were successfully started.
 * retval #kStatus_I2C_Busy Slave transfers have already been started on this handle.
 */
status_t I2C_SlaveTransferNonBlocking(I2C_Type *base, i2c_slave_handle_t *handle, uint32_t eventMask)
{
    assert(handle != NULL);

    /* Check if the I2C bus is idle - if not return busy status. */
    if (handle->state != (uint8_t)kIdleState)
    {
        return kStatus_I2C_Busy;
    }
    else
    {
        /* Disable LPI2C IRQ sources while we configure stuff. */
        (void)I2C_DisableInterrupts(base, (uint32_t)kIrqFlags);

        /* Clear transfer in handle. */
        (void)memset(&handle->transfer, 0, sizeof(handle->transfer));

        /* Record that we're busy. */
        handle->state = (uint8_t)kCheckAddressState;

        /* Set up event mask. tx and rx are always enabled. */
        handle->eventMask = eventMask | (uint32_t)kI2C_SlaveTransmitEvent | (uint32_t)kI2C_SlaveReceiveEvent;

        /* Clear all flags. */
        I2C_SlaveClearStatusFlags(base, (uint32_t)kClearFlags);

        /* Enable I2C internal IRQ sources. NVIC IRQ was enabled in CreateHandle() */
        I2C_EnableInterrupts(base, (uint32_t)kIrqFlags);
    }

    return kStatus_Success;
}

/*!
 * brief Aborts the slave transfer.
 *
 * note This API can be called at any time to stop slave for handling the bus events.
 *
 * param base I2C base pointer.
 * param handle pointer to i2c_slave_handle_t structure which stores the transfer state.
 */
void I2C_SlaveTransferAbort(I2C_Type *base, i2c_slave_handle_t *handle)
{
    assert(handle);

    if (handle->state != (uint8_t)kIdleState)
    {
        /* Disable interrupts. */
        I2C_DisableInterrupts(base, (uint32_t)kIrqFlags);

        /* Reset transfer info. */
        (void)memset(&handle->transfer, 0, sizeof(handle->transfer));

        /* Reset the state to idle. */
        handle->state = (uint8_t)kIdleState;
    }
}

/*!
 * brief Gets the slave transfer remaining bytes during a interrupt non-blocking transfer.
 *
 * param base I2C base pointer.
 * param handle pointer to i2c_slave_handle_t structure.
 * param count Number of bytes transferred so far by the non-blocking transaction.
 * retval kStatus_InvalidArgument count is Invalid.
 * retval kStatus_Success Successfully return the count.
 */
status_t I2C_SlaveTransferGetCount(I2C_Type *base, i2c_slave_handle_t *handle, size_t *count)
{
    assert(handle);

    if (NULL == count)
    {
        return kStatus_InvalidArgument;
    }

    /* Catch when there is not an active transfer. */
    if (handle->state == (uint8_t)kIdleState)
    {
        *count = 0;
        return kStatus_NoTransferInProgress;
    }

    /* For an active transfer, just return the count from the handle. */
    *count = handle->transfer.transferredCount;

    return kStatus_Success;
}

/*!
 * brief Slave interrupt handler.
 *
 * param base I2C base pointer.
 * param i2cHandle pointer to i2c_slave_handle_t structure which stores the transfer state
 */
void I2C_SlaveTransferHandleIRQ(I2C_Type *base, void *i2cHandle)
{
    assert(i2cHandle);

    uint32_t status;
    bool doTransmit            = false;
    i2c_slave_handle_t *handle = (i2c_slave_handle_t *)i2cHandle;
    i2c_slave_transfer_t *xfer;
    volatile uint8_t dummy = 0;

    /* Add this to avoid build warning. */
    dummy++;

    status = I2C_SlaveGetStatusFlags(base);
    xfer   = &(handle->transfer);

    /* Clear the interrupt flag. */
    base->I2SR &= ~(uint16_t)kI2C_IntPendingFlag;

    /* Check NAK */
    if ((status & (uint32_t)kI2C_ReceiveNakFlag) != 0U)
    {
        /* Set receive mode. */
        base->I2CR &= ~((uint16_t)I2C_I2CR_MTX_MASK | (uint16_t)I2C_I2CR_TXAK_MASK);

        /* Read dummy. */
        dummy = (uint8_t)base->I2DR;

        if (handle->transfer.dataSize != 0U)
        {
            xfer->event            = kI2C_SlaveCompletionEvent;
            xfer->completionStatus = kStatus_I2C_Nak;
            handle->state          = (uint8_t)kIdleState;

            if (((handle->eventMask & (uint32_t)xfer->event) != 0U) && (handle->callback != NULL))
            {
                handle->callback(base, xfer, handle->userData);
            }
        }
        else
        {
            xfer->event            = kI2C_SlaveCompletionEvent;
            xfer->completionStatus = kStatus_Success;
            handle->state          = (uint8_t)kIdleState;

            if (((handle->eventMask & (uint32_t)xfer->event) != 0U) && (handle->callback != NULL))
            {
                handle->callback(base, xfer, handle->userData);
            }
        }
    }
    /* Check address match. */
    else if ((status & (uint32_t)kI2C_AddressMatchFlag) != 0U)
    {
        xfer->event = kI2C_SlaveAddressMatchEvent;

        /* Slave transmit, master reading from slave. */
        if ((status & (uint32_t)kI2C_TransferDirectionFlag) != 0U)
        {
            handle->state = (uint8_t)kSendDataState;
            /* Change direction to send data. */
            base->I2CR |= I2C_I2CR_MTX_MASK;

            doTransmit = true;
        }
        else
        {
            handle->state = (uint8_t)kReceiveDataState;
            /* Slave receive, master writing to slave. */
            base->I2CR &= ~((uint16_t)I2C_I2CR_MTX_MASK | (uint16_t)I2C_I2CR_TXAK_MASK);

            /* Read dummy to release the bus. */
            dummy = (uint8_t)base->I2DR;
        }

        if (((handle->eventMask & (uint32_t)xfer->event) != 0U) && (handle->callback != NULL))
        {
            handle->callback(base, xfer, handle->userData);
        }
    }
    /* Check transfer complete flag. */
    else if ((status & (uint32_t)kI2C_TransferCompleteFlag) != 0U)
    {
        /* Slave transmit, master reading from slave. */
        if (handle->state == (uint8_t)kSendDataState)
        {
            doTransmit = true;
        }
        else
        {
            /* If we're out of data, invoke callback to get more. */
            if ((NULL == xfer->data) || (0U == xfer->dataSize))
            {
                xfer->event = kI2C_SlaveReceiveEvent;

                if (handle->callback != NULL)
                {
                    handle->callback(base, xfer, handle->userData);
                }

                /* Clear the transferred count now that we have a new buffer. */
                xfer->transferredCount = 0;
            }

            /* Slave receive, master writing to slave. */
            uint8_t data = (uint8_t)base->I2DR;

            if (handle->transfer.dataSize != 0U)
            {
                /* Receive data. */
                *handle->transfer.data++ = data;
                handle->transfer.dataSize--;
                xfer->transferredCount++;

                if (0U == handle->transfer.dataSize)
                {
                    xfer->event            = kI2C_SlaveCompletionEvent;
                    xfer->completionStatus = kStatus_Success;
                    handle->state          = (uint8_t)kIdleState;

                    /* Proceed receive complete event. */
                    if (((handle->eventMask & (uint32_t)xfer->event) != 0U) && (handle->callback != NULL))
                    {
                        handle->callback(base, xfer, handle->userData);
                    }
                }
            }
        }
    }
    else
    {
        /* Read dummy to release bus. */
        dummy = (uint8_t)base->I2DR;
    }

    /* Send data if there is the need. */
    if (doTransmit)
    {
        /* If we're out of data, invoke callback to get more. */
        if ((NULL == xfer->data) || (0U == xfer->dataSize))
        {
            xfer->event = kI2C_SlaveTransmitEvent;

            if (handle->callback != NULL)
            {
                handle->callback(base, xfer, handle->userData);
            }

            /* Clear the transferred count now that we have a new buffer. */
            xfer->transferredCount = 0;
        }

        if (handle->transfer.dataSize != 0U)
        {
            /* Send data. */
            base->I2DR = *handle->transfer.data++;
            handle->transfer.dataSize--;
            xfer->transferredCount++;
        }
        else
        {
            /* Switch to receive mode. */
            base->I2CR &= ~((uint16_t)I2C_I2CR_MTX_MASK | (uint16_t)I2C_I2CR_TXAK_MASK);

            /* Read dummy to release bus. */
            dummy = (uint8_t)base->I2DR;

            xfer->event            = kI2C_SlaveCompletionEvent;
            xfer->completionStatus = kStatus_Success;
            handle->state          = (uint8_t)kIdleState;

            /* Proceed txdone event. */
            if (((handle->eventMask & (uint32_t)xfer->event) != 0U) && (handle->callback != NULL))
            {
                handle->callback(base, xfer, handle->userData);
            }
        }
    }
}

#if defined(I2C1)
void I2C1_DriverIRQHandler(void)
{
    I2C_TransferCommonIRQHandler(I2C1, s_i2cHandle[1]);
}
#endif

#if defined(I2C2)
void I2C2_DriverIRQHandler(void)
{
    I2C_TransferCommonIRQHandler(I2C2, s_i2cHandle[2]);
}
#endif

#if defined(I2C3)
void I2C3_DriverIRQHandler(void)
{
    I2C_TransferCommonIRQHandler(I2C3, s_i2cHandle[3]);
}
#endif

#if defined(I2C4)
void I2C4_DriverIRQHandler(void)
{
    I2C_TransferCommonIRQHandler(I2C4, s_i2cHandle[4]);
}
#endif

#if defined(I2C5)
void I2C5_DriverIRQHandler(void)
{
    I2C_TransferCommonIRQHandler(I2C5, s_i2cHandle[5]);
}
#endif

#if defined(I2C6)
void I2C6_DriverIRQHandler(void)
{
    I2C_TransferCommonIRQHandler(I2C6, s_i2cHandle[6]);
}
#endif
