/*
 * Copyright (c) 2015, Freescale Semiconductor, Inc.
 * Copyright 2016-2017 NXP
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * o Redistributions of source code must retain the above copyright notice, this list
 *   of conditions and the following disclaimer.
 *
 * o Redistributions in binary form must reproduce the above copyright notice, this
 *   list of conditions and the following disclaimer in the documentation and/or
 *   other materials provided with the distribution.
 *
 * o Neither the name of the copyright holder nor the names of its
 *   contributors may be used to endorse or promote products derived from this
 *   software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "fsl_lpi2c.h"
#include <stdlib.h>
#include <string.h>

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

/*! @brief Common sets of flags used by the driver. */
enum _lpi2c_flag_constants
{
    /*! All flags which are cleared by the driver upon starting a transfer. */
    kMasterClearFlags = kLPI2C_MasterEndOfPacketFlag | kLPI2C_MasterStopDetectFlag | kLPI2C_MasterNackDetectFlag |
                        kLPI2C_MasterArbitrationLostFlag | kLPI2C_MasterFifoErrFlag | kLPI2C_MasterPinLowTimeoutFlag |
                        kLPI2C_MasterDataMatchFlag,

    /*! IRQ sources enabled by the non-blocking transactional API. */
    kMasterIrqFlags = kLPI2C_MasterArbitrationLostFlag | kLPI2C_MasterTxReadyFlag | kLPI2C_MasterRxReadyFlag |
                      kLPI2C_MasterStopDetectFlag | kLPI2C_MasterNackDetectFlag | kLPI2C_MasterPinLowTimeoutFlag |
                      kLPI2C_MasterFifoErrFlag,

    /*! Errors to check for. */
    kMasterErrorFlags = kLPI2C_MasterNackDetectFlag | kLPI2C_MasterArbitrationLostFlag | kLPI2C_MasterFifoErrFlag |
                        kLPI2C_MasterPinLowTimeoutFlag,

    /*! All flags which are cleared by the driver upon starting a transfer. */
    kSlaveClearFlags = kLPI2C_SlaveRepeatedStartDetectFlag | kLPI2C_SlaveStopDetectFlag | kLPI2C_SlaveBitErrFlag |
                       kLPI2C_SlaveFifoErrFlag,

    /*! IRQ sources enabled by the non-blocking transactional API. */
    kSlaveIrqFlags = kLPI2C_SlaveTxReadyFlag | kLPI2C_SlaveRxReadyFlag | kLPI2C_SlaveStopDetectFlag |
                     kLPI2C_SlaveRepeatedStartDetectFlag | kLPI2C_SlaveFifoErrFlag | kLPI2C_SlaveBitErrFlag |
                     kLPI2C_SlaveTransmitAckFlag | kLPI2C_SlaveAddressValidFlag,

    /*! Errors to check for. */
    kSlaveErrorFlags = kLPI2C_SlaveFifoErrFlag | kLPI2C_SlaveBitErrFlag,
};

/* ! @brief LPI2C master fifo commands. */
enum _lpi2c_master_fifo_cmd
{
    kTxDataCmd = LPI2C_MTDR_CMD(0x0U), /*!< Transmit DATA[7:0] */
    kRxDataCmd = LPI2C_MTDR_CMD(0X1U), /*!< Receive (DATA[7:0] + 1) bytes */
    kStopCmd = LPI2C_MTDR_CMD(0x2U),   /*!< Generate STOP condition */
    kStartCmd = LPI2C_MTDR_CMD(0x4U),  /*!< Generate(repeated) START and transmit address in DATA[[7:0] */
};

/*!
 * @brief Default watermark values.
 *
 * The default watermarks are set to zero.
 */
enum _lpi2c_default_watermarks
{
    kDefaultTxWatermark = 0,
    kDefaultRxWatermark = 0,
};

/*! @brief States for the state machine used by transactional APIs. */
enum _lpi2c_transfer_states
{
    kIdleState = 0,
    kSendCommandState,
    kIssueReadCommandState,
    kTransferDataState,
    kStopState,
    kWaitForCompletionState,
};

/*! @brief Typedef for master interrupt handler. */
typedef void (*lpi2c_master_isr_t)(LPI2C_Type *base, lpi2c_master_handle_t *handle);

/*! @brief Typedef for slave interrupt handler. */
typedef void (*lpi2c_slave_isr_t)(LPI2C_Type *base, lpi2c_slave_handle_t *handle);

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

/* Not static so it can be used from fsl_lpi2c_edma.c. */
uint32_t LPI2C_GetInstance(LPI2C_Type *base);

static uint32_t LPI2C_GetCyclesForWidth(uint32_t sourceClock_Hz,
                                        uint32_t width_ns,
                                        uint32_t maxCycles,
                                        uint32_t prescaler);

/* Not static so it can be used from fsl_lpi2c_edma.c. */
status_t LPI2C_MasterCheckAndClearError(LPI2C_Type *base, uint32_t status);

static status_t LPI2C_MasterWaitForTxReady(LPI2C_Type *base);

/* Not static so it can be used from fsl_lpi2c_edma.c. */
status_t LPI2C_CheckForBusyBus(LPI2C_Type *base);

static status_t LPI2C_RunTransferStateMachine(LPI2C_Type *base, lpi2c_master_handle_t *handle, bool *isDone);

static void LPI2C_InitTransferStateMachine(lpi2c_master_handle_t *handle);

static status_t LPI2C_SlaveCheckAndClearError(LPI2C_Type *base, uint32_t flags);

static void LPI2C_CommonIRQHandler(LPI2C_Type *base, uint32_t instance);

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

/*! @brief Array to map LPI2C instance number to base pointer. */
static LPI2C_Type *const kLpi2cBases[] = LPI2C_BASE_PTRS;

/*! @brief Array to map LPI2C instance number to IRQ number. */
static IRQn_Type const kLpi2cIrqs[] = LPI2C_IRQS;

#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/*! @brief Array to map LPI2C instance number to clock gate enum. */
static clock_ip_name_t const kLpi2cClocks[] = LPI2C_CLOCKS;

#if defined(LPI2C_PERIPH_CLOCKS)
/*! @brief Array to map LPI2C instance number to pheripheral clock gate enum. */
static const clock_ip_name_t kLpi2cPeriphClocks[] = LPI2C_PERIPH_CLOCKS;
#endif

#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */

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

/*! @brief Pointers to master handles for each instance. */
static lpi2c_master_handle_t *s_lpi2cMasterHandle[FSL_FEATURE_SOC_LPI2C_COUNT];

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

/*! @brief Pointers to slave handles for each instance. */
static lpi2c_slave_handle_t *s_lpi2cSlaveHandle[FSL_FEATURE_SOC_LPI2C_COUNT];

/*******************************************************************************
 * Code
 ******************************************************************************/

/*!
 * @brief Returns an instance number given a base address.
 *
 * If an invalid base address is passed, debug builds will assert. Release builds will just return
 * instance number 0.
 *
 * @param base The LPI2C peripheral base address.
 * @return LPI2C instance number starting from 0.
 */
uint32_t LPI2C_GetInstance(LPI2C_Type *base)
{
    uint32_t instance;
    for (instance = 0; instance < ARRAY_SIZE(kLpi2cBases); ++instance)
    {
        if (kLpi2cBases[instance] == base)
        {
            return instance;
        }
    }

    assert(false);
    return 0;
}

/*!
 * @brief Computes a cycle count for a given time in nanoseconds.
 * @param sourceClock_Hz LPI2C functional clock frequency in Hertz.
 * @param width_ns Desired with in nanoseconds.
 * @param maxCycles Maximum cycle count, determined by the number of bits wide the cycle count field is.
 * @param prescaler LPI2C prescaler setting. Pass 1 if the prescaler should not be used, as for slave glitch widths.
 */
static uint32_t LPI2C_GetCyclesForWidth(uint32_t sourceClock_Hz,
                                        uint32_t width_ns,
                                        uint32_t maxCycles,
                                        uint32_t prescaler)
{
    uint32_t busCycle_ns = 1000000 / (sourceClock_Hz / prescaler / 1000);
    uint32_t cycles = 0;

    /* Search for the cycle count just below the desired glitch width. */
    while ((((cycles + 1) * busCycle_ns) < width_ns) && (cycles + 1 < maxCycles))
    {
        ++cycles;
    }

    /* If we end up with zero cycles, then set the filter to a single cycle unless the */
    /* bus clock is greater than 10x the desired glitch width. */
    if ((cycles == 0) && (busCycle_ns <= (width_ns * 10)))
    {
        cycles = 1;
    }

    return cycles;
}

/*!
 * @brief Convert provided flags to status code, and clear any errors if present.
 * @param base The LPI2C peripheral base address.
 * @param status Current status flags value that will be checked.
 * @retval #kStatus_Success
 * @retval #kStatus_LPI2C_PinLowTimeout
 * @retval #kStatus_LPI2C_ArbitrationLost
 * @retval #kStatus_LPI2C_Nak
 * @retval #kStatus_LPI2C_FifoError
 */
status_t LPI2C_MasterCheckAndClearError(LPI2C_Type *base, uint32_t status)
{
    status_t result = kStatus_Success;

    /* Check for error. These errors cause a stop to automatically be sent. We must */
    /* clear the errors before a new transfer can start. */
    status &= kMasterErrorFlags;
    if (status)
    {
        /* Select the correct error code. Ordered by severity, with bus issues first. */
        if (status & kLPI2C_MasterPinLowTimeoutFlag)
        {
            result = kStatus_LPI2C_PinLowTimeout;
        }
        else if (status & kLPI2C_MasterArbitrationLostFlag)
        {
            result = kStatus_LPI2C_ArbitrationLost;
        }
        else if (status & kLPI2C_MasterNackDetectFlag)
        {
            result = kStatus_LPI2C_Nak;
        }
        else if (status & kLPI2C_MasterFifoErrFlag)
        {
            result = kStatus_LPI2C_FifoError;
        }
        else
        {
            assert(false);
        }

        /* Clear the flags. */
        LPI2C_MasterClearStatusFlags(base, status);

        /* Reset fifos. These flags clear automatically. */
        base->MCR |= LPI2C_MCR_RRF_MASK | LPI2C_MCR_RTF_MASK;
    }

    return result;
}

/*!
 * @brief Wait until there is room in the tx fifo.
 * @param base The LPI2C peripheral base address.
 * @retval #kStatus_Success
 * @retval #kStatus_LPI2C_PinLowTimeout
 * @retval #kStatus_LPI2C_ArbitrationLost
 * @retval #kStatus_LPI2C_Nak
 * @retval #kStatus_LPI2C_FifoError
 */
static status_t LPI2C_MasterWaitForTxReady(LPI2C_Type *base)
{
    uint32_t status;
    size_t txCount;
    size_t txFifoSize = FSL_FEATURE_LPI2C_FIFO_SIZEn(base);

#if LPI2C_WAIT_TIMEOUT
    uint32_t waitTimes = LPI2C_WAIT_TIMEOUT;
#endif
    do
    {
        status_t result;

        /* Get the number of words in the tx fifo and compute empty slots. */
        LPI2C_MasterGetFifoCounts(base, NULL, &txCount);
        txCount = txFifoSize - txCount;

        /* Check for error flags. */
        status = LPI2C_MasterGetStatusFlags(base);
        result = LPI2C_MasterCheckAndClearError(base, status);
        if (result)
        {
            return result;
        }
#if LPI2C_WAIT_TIMEOUT
    } while ((!txCount) && (--waitTimes));

    if (waitTimes == 0)
    {
        return kStatus_LPI2C_Timeout;
    }
#else
    } while (!txCount);
#endif

    return kStatus_Success;
}

/*!
 * @brief Make sure the bus isn't already busy.
 *
 * A busy bus is allowed if we are the one driving it.
 *
 * @param base The LPI2C peripheral base address.
 * @retval #kStatus_Success
 * @retval #kStatus_LPI2C_Busy
 */
status_t LPI2C_CheckForBusyBus(LPI2C_Type *base)
{
    uint32_t status = LPI2C_MasterGetStatusFlags(base);
    if ((status & kLPI2C_MasterBusBusyFlag) && (!(status & kLPI2C_MasterBusyFlag)))
    {
        return kStatus_LPI2C_Busy;
    }

    return kStatus_Success;
}

void LPI2C_MasterGetDefaultConfig(lpi2c_master_config_t *masterConfig)
{
    masterConfig->enableMaster = true;
    masterConfig->debugEnable = false;
    masterConfig->enableDoze = true;
    masterConfig->ignoreAck = false;
    masterConfig->pinConfig = kLPI2C_2PinOpenDrain;
    masterConfig->baudRate_Hz = 100000U;
    masterConfig->busIdleTimeout_ns = 0;
    masterConfig->pinLowTimeout_ns = 0;
    masterConfig->sdaGlitchFilterWidth_ns = 0;
    masterConfig->sclGlitchFilterWidth_ns = 0;
    masterConfig->hostRequest.enable = false;
    masterConfig->hostRequest.source = kLPI2C_HostRequestExternalPin;
    masterConfig->hostRequest.polarity = kLPI2C_HostRequestPinActiveHigh;
}

void LPI2C_MasterInit(LPI2C_Type *base, const lpi2c_master_config_t *masterConfig, uint32_t sourceClock_Hz)
{
    uint32_t prescaler;
    uint32_t cycles;
    uint32_t cfgr2;
    uint32_t value;

#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)

    uint32_t instance = LPI2C_GetInstance(base);

    /* Ungate the clock. */
    CLOCK_EnableClock(kLpi2cClocks[instance]);
#if defined(LPI2C_PERIPH_CLOCKS)
    /* Ungate the functional clock in initialize function. */
    CLOCK_EnableClock(kLpi2cPeriphClocks[instance]);
#endif

#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */

    /* Reset peripheral before configuring it. */
    LPI2C_MasterReset(base);

    /* Doze bit: 0 is enable, 1 is disable */
    base->MCR = LPI2C_MCR_DBGEN(masterConfig->debugEnable) | LPI2C_MCR_DOZEN(!(masterConfig->enableDoze));

    /* host request */
    value = base->MCFGR0;
    value &= (~(LPI2C_MCFGR0_HREN_MASK | LPI2C_MCFGR0_HRPOL_MASK | LPI2C_MCFGR0_HRSEL_MASK));
    value |= LPI2C_MCFGR0_HREN(masterConfig->hostRequest.enable) |
             LPI2C_MCFGR0_HRPOL(masterConfig->hostRequest.polarity) |
             LPI2C_MCFGR0_HRSEL(masterConfig->hostRequest.source);
    base->MCFGR0 = value;

    /* pin config and ignore ack */
    value = base->MCFGR1;
    value &= ~(LPI2C_MCFGR1_PINCFG_MASK | LPI2C_MCFGR1_IGNACK_MASK);
    value |= LPI2C_MCFGR1_PINCFG(masterConfig->pinConfig);
    value |= LPI2C_MCFGR1_IGNACK(masterConfig->ignoreAck);
    base->MCFGR1 = value;

    LPI2C_MasterSetWatermarks(base, kDefaultTxWatermark, kDefaultRxWatermark);

    LPI2C_MasterSetBaudRate(base, sourceClock_Hz, masterConfig->baudRate_Hz);

    /* Configure glitch filters and bus idle and pin low timeouts. */
    prescaler = (base->MCFGR1 & LPI2C_MCFGR1_PRESCALE_MASK) >> LPI2C_MCFGR1_PRESCALE_SHIFT;
    cfgr2 = base->MCFGR2;
    if (masterConfig->busIdleTimeout_ns)
    {
        cycles = LPI2C_GetCyclesForWidth(sourceClock_Hz, masterConfig->busIdleTimeout_ns,
                                         (LPI2C_MCFGR2_BUSIDLE_MASK >> LPI2C_MCFGR2_BUSIDLE_SHIFT), prescaler);
        cfgr2 &= ~LPI2C_MCFGR2_BUSIDLE_MASK;
        cfgr2 |= LPI2C_MCFGR2_BUSIDLE(cycles);
    }
    if (masterConfig->sdaGlitchFilterWidth_ns)
    {
        cycles = LPI2C_GetCyclesForWidth(sourceClock_Hz, masterConfig->sdaGlitchFilterWidth_ns,
                                         (LPI2C_MCFGR2_FILTSDA_MASK >> LPI2C_MCFGR2_FILTSDA_SHIFT), 1);
        cfgr2 &= ~LPI2C_MCFGR2_FILTSDA_MASK;
        cfgr2 |= LPI2C_MCFGR2_FILTSDA(cycles);
    }
    if (masterConfig->sclGlitchFilterWidth_ns)
    {
        cycles = LPI2C_GetCyclesForWidth(sourceClock_Hz, masterConfig->sclGlitchFilterWidth_ns,
                                         (LPI2C_MCFGR2_FILTSCL_MASK >> LPI2C_MCFGR2_FILTSCL_SHIFT), 1);
        cfgr2 &= ~LPI2C_MCFGR2_FILTSCL_MASK;
        cfgr2 |= LPI2C_MCFGR2_FILTSCL(cycles);
    }
    base->MCFGR2 = cfgr2;
    if (masterConfig->pinLowTimeout_ns)
    {
        cycles = LPI2C_GetCyclesForWidth(sourceClock_Hz, masterConfig->pinLowTimeout_ns / 256,
                                         (LPI2C_MCFGR2_BUSIDLE_MASK >> LPI2C_MCFGR2_BUSIDLE_SHIFT), prescaler);
        base->MCFGR3 = (base->MCFGR3 & ~LPI2C_MCFGR3_PINLOW_MASK) | LPI2C_MCFGR3_PINLOW(cycles);
    }

    LPI2C_MasterEnable(base, masterConfig->enableMaster);
}

void LPI2C_MasterDeinit(LPI2C_Type *base)
{
    /* Restore to reset state. */
    LPI2C_MasterReset(base);

#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)

    uint32_t instance = LPI2C_GetInstance(base);

    /* Gate clock. */
    CLOCK_DisableClock(kLpi2cClocks[instance]);
#if defined(LPI2C_PERIPH_CLOCKS)
    /* Gate the functional clock. */
    CLOCK_DisableClock(kLpi2cPeriphClocks[instance]);
#endif

#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
}

void LPI2C_MasterConfigureDataMatch(LPI2C_Type *base, const lpi2c_data_match_config_t *config)
{
    /* Disable master mode. */
    bool wasEnabled = (base->MCR & LPI2C_MCR_MEN_MASK) >> LPI2C_MCR_MEN_SHIFT;
    LPI2C_MasterEnable(base, false);

    base->MCFGR1 = (base->MCFGR1 & ~LPI2C_MCFGR1_MATCFG_MASK) | LPI2C_MCFGR1_MATCFG(config->matchMode);
    base->MCFGR0 = (base->MCFGR0 & ~LPI2C_MCFGR0_RDMO_MASK) | LPI2C_MCFGR0_RDMO(config->rxDataMatchOnly);
    base->MDMR = LPI2C_MDMR_MATCH0(config->match0) | LPI2C_MDMR_MATCH1(config->match1);

    /* Restore master mode. */
    if (wasEnabled)
    {
        LPI2C_MasterEnable(base, true);
    }
}

void LPI2C_MasterSetBaudRate(LPI2C_Type *base, uint32_t sourceClock_Hz, uint32_t baudRate_Hz)
{
    uint32_t prescale = 0;
    uint32_t bestPre = 0;
    uint32_t bestClkHi = 0;
    uint32_t absError = 0;
    uint32_t bestError = 0xffffffffu;
    uint32_t value;
    uint32_t clkHiCycle;
    uint32_t computedRate;
    int i;
    bool wasEnabled;

    /* Disable master mode. */
    wasEnabled = (base->MCR & LPI2C_MCR_MEN_MASK) >> LPI2C_MCR_MEN_SHIFT;
    LPI2C_MasterEnable(base, false);

    /* Baud rate = (sourceClock_Hz/2^prescale)/(CLKLO+1+CLKHI+1 + ROUNDDOWN((2+FILTSCL)/2^prescale) */
    /* Assume CLKLO = 2*CLKHI, SETHOLD = CLKHI, DATAVD = CLKHI/2. */
    for (prescale = 1; (prescale <= 128) && (bestError != 0); prescale = 2 * prescale)
    {
        for (clkHiCycle = 1; clkHiCycle < 32; clkHiCycle++)
        {
            if (clkHiCycle == 1)
            {
                computedRate = (sourceClock_Hz / prescale) / (1 + 3 + 2 + 2 / prescale);
            }
            else
            {
                computedRate = (sourceClock_Hz / prescale) / (3 * clkHiCycle + 2 + 2 / prescale);
            }

            absError = baudRate_Hz > computedRate ? baudRate_Hz - computedRate : computedRate - baudRate_Hz;

            if (absError < bestError)
            {
                bestPre = prescale;
                bestClkHi = clkHiCycle;
                bestError = absError;

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

    /* Standard, fast, fast mode plus and ultra-fast transfers. */
    value = LPI2C_MCCR0_CLKHI(bestClkHi);

    if (bestClkHi < 2)
    {
        value |= LPI2C_MCCR0_CLKLO(3) | LPI2C_MCCR0_SETHOLD(2) | LPI2C_MCCR0_DATAVD(1);
    }
    else
    {
        value |= LPI2C_MCCR0_CLKLO(2 * bestClkHi) | LPI2C_MCCR0_SETHOLD(bestClkHi) | LPI2C_MCCR0_DATAVD(bestClkHi / 2);
    }

    base->MCCR0 = value;

    for (i = 0; i < 8; i++)
    {
        if (bestPre == (1U << i))
        {
            bestPre = i;
            break;
        }
    }
    base->MCFGR1 = (base->MCFGR1 & ~LPI2C_MCFGR1_PRESCALE_MASK) | LPI2C_MCFGR1_PRESCALE(bestPre);

    /* Restore master mode. */
    if (wasEnabled)
    {
        LPI2C_MasterEnable(base, true);
    }
}

status_t LPI2C_MasterStart(LPI2C_Type *base, uint8_t address, lpi2c_direction_t dir)
{
    /* Return an error if the bus is already in use not by us. */
    status_t result = LPI2C_CheckForBusyBus(base);
    if (result)
    {
        return result;
    }

    /* Clear all flags. */
    LPI2C_MasterClearStatusFlags(base, kMasterClearFlags);

    /* Turn off auto-stop option. */
    base->MCFGR1 &= ~LPI2C_MCFGR1_AUTOSTOP_MASK;

    /* Wait until there is room in the fifo. */
    result = LPI2C_MasterWaitForTxReady(base);
    if (result)
    {
        return result;
    }

    /* Issue start command. */
    base->MTDR = kStartCmd | (((uint32_t)address << 1U) | (uint32_t)dir);

    return kStatus_Success;
}

status_t LPI2C_MasterStop(LPI2C_Type *base)
{
    /* Wait until there is room in the fifo. */
    status_t result = LPI2C_MasterWaitForTxReady(base);
    if (result)
    {
        return result;
    }

    /* Send the STOP signal */
    base->MTDR = kStopCmd;

/* Wait for the stop detected flag to set, indicating the transfer has completed on the bus. */
/* Also check for errors while waiting. */
#if LPI2C_WAIT_TIMEOUT
    uint32_t waitTimes = LPI2C_WAIT_TIMEOUT;
#endif

#if LPI2C_WAIT_TIMEOUT
    while ((result == kStatus_Success) && (--waitTimes))
#else
    while (result == kStatus_Success)
#endif
    {
        uint32_t status = LPI2C_MasterGetStatusFlags(base);

        /* Check for error flags. */
        result = LPI2C_MasterCheckAndClearError(base, status);

        /* Check if the stop was sent successfully. */
        if (status & kLPI2C_MasterStopDetectFlag)
        {
            LPI2C_MasterClearStatusFlags(base, kLPI2C_MasterStopDetectFlag);
            break;
        }
    }

#if LPI2C_WAIT_TIMEOUT
    if (waitTimes == 0)
    {
        return kStatus_LPI2C_Timeout;
    }
#endif

    return result;
}

status_t LPI2C_MasterReceive(LPI2C_Type *base, void *rxBuff, size_t rxSize)
{
    status_t result;
    uint8_t *buf;

    assert(rxBuff);

    /* Handle empty read. */
    if (!rxSize)
    {
        return kStatus_Success;
    }

    /* Wait until there is room in the command fifo. */
    result = LPI2C_MasterWaitForTxReady(base);
    if (result)
    {
        return result;
    }

    /* Issue command to receive data. */
    base->MTDR = kRxDataCmd | LPI2C_MTDR_DATA(rxSize - 1);

#if LPI2C_WAIT_TIMEOUT
    uint32_t waitTimes = LPI2C_WAIT_TIMEOUT;
#endif

    /* Receive data */
    buf = (uint8_t *)rxBuff;
    while (rxSize--)
    {
        /* Read LPI2C receive fifo register. The register includes a flag to indicate whether */
        /* the FIFO is empty, so we can both get the data and check if we need to keep reading */
        /* using a single register read. */
        uint32_t value;
        do
        {
            /* Check for errors. */
            result = LPI2C_MasterCheckAndClearError(base, LPI2C_MasterGetStatusFlags(base));
            if (result)
            {
                return result;
            }

            value = base->MRDR;
#if LPI2C_WAIT_TIMEOUT
        } while ((value & LPI2C_MRDR_RXEMPTY_MASK) && (--waitTimes));
        if (waitTimes == 0)
        {
            return kStatus_LPI2C_Timeout;
        }
#else
        } while (value & LPI2C_MRDR_RXEMPTY_MASK);
#endif

        *buf++ = value & LPI2C_MRDR_DATA_MASK;
    }

    return kStatus_Success;
}

status_t LPI2C_MasterSend(LPI2C_Type *base, const void *txBuff, size_t txSize)
{
    uint8_t *buf = (uint8_t *)((void *)txBuff);

    assert(txBuff);

    /* Send data buffer */
    while (txSize--)
    {
        /* Wait until there is room in the fifo. This also checks for errors. */
        status_t result = LPI2C_MasterWaitForTxReady(base);
        if (result)
        {
            return result;
        }

        /* Write byte into LPI2C master data register. */
        base->MTDR = *buf++;
    }

    return kStatus_Success;
}

status_t LPI2C_MasterTransferBlocking(LPI2C_Type *base, lpi2c_master_transfer_t *transfer)
{
    status_t result = kStatus_Success;
    uint16_t commandBuffer[7];
    uint32_t cmdCount = 0;

    assert(transfer);
    assert(transfer->subaddressSize <= sizeof(transfer->subaddress));

    /* Return an error if the bus is already in use not by us. */
    result = LPI2C_CheckForBusyBus(base);
    if (result)
    {
        return result;
    }

    /* Clear all flags. */
    LPI2C_MasterClearStatusFlags(base, kMasterClearFlags);

    /* Turn off auto-stop option. */
    base->MCFGR1 &= ~LPI2C_MCFGR1_AUTOSTOP_MASK;

    lpi2c_direction_t direction = transfer->subaddressSize ? kLPI2C_Write : transfer->direction;
    if (!(transfer->flags & kLPI2C_TransferNoStartFlag))
    {
        commandBuffer[cmdCount++] =
            (uint16_t)kStartCmd | (uint16_t)((uint16_t)((uint16_t)transfer->slaveAddress << 1U) | (uint16_t)direction);
    }

    /* Subaddress, MSB first. */
    if (transfer->subaddressSize)
    {
        uint32_t subaddressRemaining = transfer->subaddressSize;
        while (subaddressRemaining--)
        {
            uint8_t subaddressByte = (transfer->subaddress >> (8 * subaddressRemaining)) & 0xff;
            commandBuffer[cmdCount++] = subaddressByte;
        }
    }

    /* Reads need special handling. */
    if ((transfer->dataSize) && (transfer->direction == kLPI2C_Read))
    {
        /* Need to send repeated start if switching directions to read. */
        if (direction == kLPI2C_Write)
        {
            commandBuffer[cmdCount++] =
                (uint16_t)kStartCmd |
                (uint16_t)((uint16_t)((uint16_t)transfer->slaveAddress << 1U) | (uint16_t)kLPI2C_Read);
        }
    }

    /* Send command buffer */
    uint32_t index = 0;
    while (cmdCount--)
    {
        /* Wait until there is room in the fifo. This also checks for errors. */
        result = LPI2C_MasterWaitForTxReady(base);
        if (result)
        {
            return result;
        }

        /* Write byte into LPI2C master data register. */
        base->MTDR = commandBuffer[index];
        index++;
    }

    /* Transmit data. */
    if ((transfer->direction == kLPI2C_Write) && (transfer->dataSize > 0))
    {
        /* Send Data. */
        result = LPI2C_MasterSend(base, transfer->data, transfer->dataSize);
    }

    /* Receive Data. */
    if ((transfer->direction == kLPI2C_Read) && (transfer->dataSize > 0))
    {
        result = LPI2C_MasterReceive(base, transfer->data, transfer->dataSize);
    }

    if (result)
    {
        return result;
    }

    if ((transfer->flags & kLPI2C_TransferNoStopFlag) == 0)
    {
        result = LPI2C_MasterStop(base);
    }

    return result;
}

void LPI2C_MasterTransferCreateHandle(LPI2C_Type *base,
                                      lpi2c_master_handle_t *handle,
                                      lpi2c_master_transfer_callback_t callback,
                                      void *userData)
{
    uint32_t instance;

    assert(handle);

    /* Clear out the handle. */
    memset(handle, 0, sizeof(*handle));

    /* Look up instance number */
    instance = LPI2C_GetInstance(base);

    /* Save base and instance. */
    handle->completionCallback = callback;
    handle->userData = userData;

    /* Save this handle for IRQ use. */
    s_lpi2cMasterHandle[instance] = handle;

    /* Set irq handler. */
    s_lpi2cMasterIsr = LPI2C_MasterTransferHandleIRQ;

    /* Clear internal IRQ enables and enable NVIC IRQ. */
    LPI2C_MasterDisableInterrupts(base, kMasterIrqFlags);
    EnableIRQ(kLpi2cIrqs[instance]);
}

/*!
 * @brief Execute states until FIFOs are exhausted.
 * @param handle Master nonblocking driver handle.
 * @param[out] isDone Set to true if the transfer has completed.
 * @retval #kStatus_Success
 * @retval #kStatus_LPI2C_PinLowTimeout
 * @retval #kStatus_LPI2C_ArbitrationLost
 * @retval #kStatus_LPI2C_Nak
 * @retval #kStatus_LPI2C_FifoError
 */
static status_t LPI2C_RunTransferStateMachine(LPI2C_Type *base, lpi2c_master_handle_t *handle, bool *isDone)
{
    uint32_t status;
    status_t result = kStatus_Success;
    lpi2c_master_transfer_t *xfer;
    size_t txCount;
    size_t rxCount;
    size_t txFifoSize = FSL_FEATURE_LPI2C_FIFO_SIZEn(base);
    bool state_complete = false;

    /* Set default isDone return value. */
    *isDone = false;

    /* Check for errors. */
    status = LPI2C_MasterGetStatusFlags(base);
    result = LPI2C_MasterCheckAndClearError(base, status);
    if (result)
    {
        return result;
    }

    /* Get pointer to private data. */
    xfer = &handle->transfer;

    /* Get fifo counts and compute room in tx fifo. */
    LPI2C_MasterGetFifoCounts(base, &rxCount, &txCount);
    txCount = txFifoSize - txCount;

    while (!state_complete)
    {
        /* Execute the state. */
        switch (handle->state)
        {
            case kSendCommandState:
            {
                /* Make sure there is room in the tx fifo for the next command. */
                if (!txCount--)
                {
                    state_complete = true;
                    break;
                }

                /* Issue command. buf is a uint8_t* pointing at the uint16 command array. */
                base->MTDR = *(uint16_t *)handle->buf;
                handle->buf += sizeof(uint16_t);

                /* Count down until all commands are sent. */
                if (--handle->remainingBytes == 0)
                {
                    /* Choose next state and set up buffer pointer and count. */
                    if (xfer->dataSize)
                    {
                        /* Either a send or receive transfer is next. */
                        handle->state = kTransferDataState;
                        handle->buf = (uint8_t *)xfer->data;
                        handle->remainingBytes = xfer->dataSize;
                        if (xfer->direction == kLPI2C_Read)
                        {
                            /* Disable TX interrupt */
                            LPI2C_MasterDisableInterrupts(base, kLPI2C_MasterTxReadyFlag);
                        }
                    }
                    else
                    {
                        /* No transfer, so move to stop state. */
                        handle->state = kStopState;
                    }
                }
                break;
            }

            case kIssueReadCommandState:
                /* Make sure there is room in the tx fifo for the read command. */
                if (!txCount--)
                {
                    state_complete = true;
                    break;
                }

                base->MTDR = kRxDataCmd | LPI2C_MTDR_DATA(xfer->dataSize - 1);

                /* Move to transfer state. */
                handle->state = kTransferDataState;
                if (xfer->direction == kLPI2C_Read)
                {
                    /* Disable TX interrupt */
                    LPI2C_MasterDisableInterrupts(base, kLPI2C_MasterTxReadyFlag);
                }
                break;

            case kTransferDataState:
                if (xfer->direction == kLPI2C_Write)
                {
                    /* Make sure there is room in the tx fifo. */
                    if (!txCount--)
                    {
                        state_complete = true;
                        break;
                    }

                    /* Put byte to send in fifo. */
                    base->MTDR = *(handle->buf)++;
                }
                else
                {
                    /* XXX handle receive sizes > 256, use kIssueReadCommandState */
                    /* Make sure there is data in the rx fifo. */
                    if (!rxCount--)
                    {
                        state_complete = true;
                        break;
                    }

                    /* Read byte from fifo. */
                    *(handle->buf)++ = base->MRDR & LPI2C_MRDR_DATA_MASK;
                }

                /* Move to stop when the transfer is done. */
                if (--handle->remainingBytes == 0)
                {
                    handle->state = kStopState;
                }
                break;

            case kStopState:
                /* Only issue a stop transition if the caller requested it. */
                if ((xfer->flags & kLPI2C_TransferNoStopFlag) == 0)
                {
                    /* Make sure there is room in the tx fifo for the stop command. */
                    if (!txCount--)
                    {
                        state_complete = true;
                        break;
                    }

                    base->MTDR = kStopCmd;
                }
                else
                {
                    /* Caller doesn't want to send a stop, so we're done now. */
                    *isDone = true;
                    state_complete = true;
                    break;
                }
                handle->state = kWaitForCompletionState;
                break;

            case kWaitForCompletionState:
                /* We stay in this state until the stop state is detected. */
                if (status & kLPI2C_MasterStopDetectFlag)
                {
                    *isDone = true;
                }
                state_complete = true;
                break;
            default:
                assert(false);
                break;
        }
    }
    return result;
}

/*!
 * @brief Prepares the transfer state machine and fills in the command buffer.
 * @param handle Master nonblocking driver handle.
 */
static void LPI2C_InitTransferStateMachine(lpi2c_master_handle_t *handle)
{
    lpi2c_master_transfer_t *xfer = &handle->transfer;

    /* Handle no start option. */
    if (xfer->flags & kLPI2C_TransferNoStartFlag)
    {
        if (xfer->direction == kLPI2C_Read)
        {
            /* Need to issue read command first. */
            handle->state = kIssueReadCommandState;
        }
        else
        {
            /* Start immediately in the data transfer state. */
            handle->state = kTransferDataState;
        }

        handle->buf = (uint8_t *)xfer->data;
        handle->remainingBytes = xfer->dataSize;
    }
    else
    {
        uint16_t *cmd = (uint16_t *)&handle->commandBuffer;
        uint32_t cmdCount = 0;

        /* Initial direction depends on whether a subaddress was provided, and of course the actual */
        /* data transfer direction. */
        lpi2c_direction_t direction = xfer->subaddressSize ? kLPI2C_Write : xfer->direction;

        /* Start command. */
        cmd[cmdCount++] =
            (uint16_t)kStartCmd | (uint16_t)((uint16_t)((uint16_t)xfer->slaveAddress << 1U) | (uint16_t)direction);

        /* Subaddress, MSB first. */
        if (xfer->subaddressSize)
        {
            uint32_t subaddressRemaining = xfer->subaddressSize;
            while (subaddressRemaining--)
            {
                uint8_t subaddressByte = (xfer->subaddress >> (8 * subaddressRemaining)) & 0xff;
                cmd[cmdCount++] = subaddressByte;
            }
        }

        /* Reads need special handling. */
        if ((xfer->dataSize) && (xfer->direction == kLPI2C_Read))
        {
            /* Need to send repeated start if switching directions to read. */
            if (direction == kLPI2C_Write)
            {
                cmd[cmdCount++] = (uint16_t)kStartCmd |
                                  (uint16_t)((uint16_t)((uint16_t)xfer->slaveAddress << 1U) | (uint16_t)kLPI2C_Read);
            }

            /* Read command. */
            cmd[cmdCount++] = kRxDataCmd | LPI2C_MTDR_DATA(xfer->dataSize - 1);
        }

        /* Set up state machine for transferring the commands. */
        handle->state = kSendCommandState;
        handle->remainingBytes = cmdCount;
        handle->buf = (uint8_t *)&handle->commandBuffer;
    }
}

status_t LPI2C_MasterTransferNonBlocking(LPI2C_Type *base,
                                         lpi2c_master_handle_t *handle,
                                         lpi2c_master_transfer_t *transfer)
{
    status_t result;

    assert(handle);
    assert(transfer);
    assert(transfer->subaddressSize <= sizeof(transfer->subaddress));

    /* Return busy if another transaction is in progress. */
    if (handle->state != kIdleState)
    {
        return kStatus_LPI2C_Busy;
    }

    /* Return an error if the bus is already in use not by us. */
    result = LPI2C_CheckForBusyBus(base);
    if (result)
    {
        return result;
    }

    /* Disable LPI2C IRQ sources while we configure stuff. */
    LPI2C_MasterDisableInterrupts(base, kMasterIrqFlags);

    /* Save transfer into handle. */
    handle->transfer = *transfer;

    /* Generate commands to send. */
    LPI2C_InitTransferStateMachine(handle);

    /* Clear all flags. */
    LPI2C_MasterClearStatusFlags(base, kMasterClearFlags);

    /* Turn off auto-stop option. */
    base->MCFGR1 &= ~LPI2C_MCFGR1_AUTOSTOP_MASK;

    /* Enable LPI2C internal IRQ sources. NVIC IRQ was enabled in CreateHandle() */
    LPI2C_MasterEnableInterrupts(base, kMasterIrqFlags);

    return result;
}

status_t LPI2C_MasterTransferGetCount(LPI2C_Type *base, lpi2c_master_handle_t *handle, size_t *count)
{
    assert(handle);

    if (!count)
    {
        return kStatus_InvalidArgument;
    }

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

    uint8_t state;
    uint16_t remainingBytes;
    uint32_t dataSize;

    /* Cache some fields with IRQs disabled. This ensures all field values */
    /* are synchronized with each other during an ongoing transfer. */
    uint32_t irqs = LPI2C_MasterGetEnabledInterrupts(base);
    LPI2C_MasterDisableInterrupts(base, irqs);
    state = handle->state;
    remainingBytes = handle->remainingBytes;
    dataSize = handle->transfer.dataSize;
    LPI2C_MasterEnableInterrupts(base, irqs);

    /* Get transfer count based on current transfer state. */
    switch (state)
    {
        case kIdleState:
        case kSendCommandState:
        case kIssueReadCommandState: /* XXX return correct value for this state when >256 reads are supported */
            *count = 0;
            break;

        case kTransferDataState:
            *count = dataSize - remainingBytes;
            break;

        case kStopState:
        case kWaitForCompletionState:
        default:
            *count = dataSize;
            break;
    }

    return kStatus_Success;
}

void LPI2C_MasterTransferAbort(LPI2C_Type *base, lpi2c_master_handle_t *handle)
{
    if (handle->state != kIdleState)
    {
        /* Disable internal IRQ enables. */
        LPI2C_MasterDisableInterrupts(base, kMasterIrqFlags);

        /* Reset fifos. */
        base->MCR |= LPI2C_MCR_RRF_MASK | LPI2C_MCR_RTF_MASK;

        /* Send a stop command to finalize the transfer. */
        base->MTDR = kStopCmd;

        /* Reset handle. */
        handle->state = kIdleState;
    }
}

void LPI2C_MasterTransferHandleIRQ(LPI2C_Type *base, lpi2c_master_handle_t *handle)
{
    bool isDone;
    status_t result;

    /* Don't do anything if we don't have a valid handle. */
    if (!handle)
    {
        return;
    }

    if (handle->state == kIdleState)
    {
        return;
    }

    result = LPI2C_RunTransferStateMachine(base, handle, &isDone);

    if (isDone || (result != kStatus_Success))
    {
        /* XXX need to handle data that may be in rx fifo below watermark level? */

        /* XXX handle error, terminate xfer */

        /* Disable internal IRQ enables. */
        LPI2C_MasterDisableInterrupts(base, kMasterIrqFlags);

        /* Set handle to idle state. */
        handle->state = kIdleState;

        /* Invoke callback. */
        if (handle->completionCallback)
        {
            handle->completionCallback(base, handle, result, handle->userData);
        }
    }
}

void LPI2C_SlaveGetDefaultConfig(lpi2c_slave_config_t *slaveConfig)
{
    slaveConfig->enableSlave = true;
    slaveConfig->address0 = 0U;
    slaveConfig->address1 = 0U;
    slaveConfig->addressMatchMode = kLPI2C_MatchAddress0;
    slaveConfig->filterDozeEnable = true;
    slaveConfig->filterEnable = true;
    slaveConfig->enableGeneralCall = false;
    slaveConfig->sclStall.enableAck = false;
    slaveConfig->sclStall.enableTx = true;
    slaveConfig->sclStall.enableRx = true;
    slaveConfig->sclStall.enableAddress = false;
    slaveConfig->ignoreAck = false;
    slaveConfig->enableReceivedAddressRead = false;
    slaveConfig->sdaGlitchFilterWidth_ns = 0; /* TODO determine default width values */
    slaveConfig->sclGlitchFilterWidth_ns = 0;
    slaveConfig->dataValidDelay_ns = 0;
    slaveConfig->clockHoldTime_ns = 0;
}

void LPI2C_SlaveInit(LPI2C_Type *base, const lpi2c_slave_config_t *slaveConfig, uint32_t sourceClock_Hz)
{
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)

    uint32_t instance = LPI2C_GetInstance(base);

    /* Ungate the clock. */
    CLOCK_EnableClock(kLpi2cClocks[instance]);
#if defined(LPI2C_PERIPH_CLOCKS)
    /* Ungate the functional clock in initialize function. */
    CLOCK_EnableClock(kLpi2cPeriphClocks[instance]);
#endif

#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */

    /* Restore to reset conditions. */
    LPI2C_SlaveReset(base);

    /* Configure peripheral. */
    base->SAMR = LPI2C_SAMR_ADDR0(slaveConfig->address0) | LPI2C_SAMR_ADDR1(slaveConfig->address1);

    base->SCFGR1 =
        LPI2C_SCFGR1_ADDRCFG(slaveConfig->addressMatchMode) | LPI2C_SCFGR1_IGNACK(slaveConfig->ignoreAck) |
        LPI2C_SCFGR1_RXCFG(slaveConfig->enableReceivedAddressRead) | LPI2C_SCFGR1_GCEN(slaveConfig->enableGeneralCall) |
        LPI2C_SCFGR1_ACKSTALL(slaveConfig->sclStall.enableAck) | LPI2C_SCFGR1_TXDSTALL(slaveConfig->sclStall.enableTx) |
        LPI2C_SCFGR1_RXSTALL(slaveConfig->sclStall.enableRx) |
        LPI2C_SCFGR1_ADRSTALL(slaveConfig->sclStall.enableAddress);

    base->SCFGR2 =
        LPI2C_SCFGR2_FILTSDA(LPI2C_GetCyclesForWidth(sourceClock_Hz, slaveConfig->sdaGlitchFilterWidth_ns,
                                                     (LPI2C_SCFGR2_FILTSDA_MASK >> LPI2C_SCFGR2_FILTSDA_SHIFT), 1)) |
        LPI2C_SCFGR2_FILTSCL(LPI2C_GetCyclesForWidth(sourceClock_Hz, slaveConfig->sclGlitchFilterWidth_ns,
                                                     (LPI2C_SCFGR2_FILTSCL_MASK >> LPI2C_SCFGR2_FILTSCL_SHIFT), 1)) |
        LPI2C_SCFGR2_DATAVD(LPI2C_GetCyclesForWidth(sourceClock_Hz, slaveConfig->dataValidDelay_ns,
                                                    (LPI2C_SCFGR2_DATAVD_MASK >> LPI2C_SCFGR2_DATAVD_SHIFT), 1)) |
        LPI2C_SCFGR2_CLKHOLD(LPI2C_GetCyclesForWidth(sourceClock_Hz, slaveConfig->clockHoldTime_ns,
                                                     (LPI2C_SCFGR2_CLKHOLD_MASK >> LPI2C_SCFGR2_CLKHOLD_SHIFT), 1));

    /* Save SCR to last so we don't enable slave until it is configured */
    base->SCR = LPI2C_SCR_FILTDZ(slaveConfig->filterDozeEnable) | LPI2C_SCR_FILTEN(slaveConfig->filterEnable) |
                LPI2C_SCR_SEN(slaveConfig->enableSlave);
}

void LPI2C_SlaveDeinit(LPI2C_Type *base)
{
    LPI2C_SlaveReset(base);

#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)

    uint32_t instance = LPI2C_GetInstance(base);

    /* Gate the clock. */
    CLOCK_DisableClock(kLpi2cClocks[instance]);

#if defined(LPI2C_PERIPH_CLOCKS)
    /* Gate the functional clock. */
    CLOCK_DisableClock(kLpi2cPeriphClocks[instance]);
#endif

#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
}

/*!
 * @brief Convert provided flags to status code, and clear any errors if present.
 * @param base The LPI2C peripheral base address.
 * @param status Current status flags value that will be checked.
 * @retval #kStatus_Success
 * @retval #kStatus_LPI2C_BitError
 * @retval #kStatus_LPI2C_FifoError
 */
static status_t LPI2C_SlaveCheckAndClearError(LPI2C_Type *base, uint32_t flags)
{
    status_t result = kStatus_Success;

    flags &= kSlaveErrorFlags;
    if (flags)
    {
        if (flags & kLPI2C_SlaveBitErrFlag)
        {
            result = kStatus_LPI2C_BitError;
        }
        else if (flags & kLPI2C_SlaveFifoErrFlag)
        {
            result = kStatus_LPI2C_FifoError;
        }
        else
        {
            assert(false);
        }

        /* Clear the errors. */
        LPI2C_SlaveClearStatusFlags(base, flags);
    }

    return result;
}

status_t LPI2C_SlaveSend(LPI2C_Type *base, const void *txBuff, size_t txSize, size_t *actualTxSize)
{
    uint8_t *buf = (uint8_t *)((void *)txBuff);
    size_t remaining = txSize;

    assert(txBuff);

#if LPI2C_WAIT_TIMEOUT
    uint32_t waitTimes = LPI2C_WAIT_TIMEOUT;
#endif

    while (remaining)
    {
        uint32_t flags;
        status_t result;

        /* Wait until we can transmit. */
        do
        {
            /* Check for errors */
            flags = LPI2C_SlaveGetStatusFlags(base);
            result = LPI2C_SlaveCheckAndClearError(base, flags);
            if (result)
            {
                if (actualTxSize)
                {
                    *actualTxSize = txSize - remaining;
                }
                return result;
            }
#if LPI2C_WAIT_TIMEOUT
        } while (
            (!(flags & (kLPI2C_SlaveTxReadyFlag | kLPI2C_SlaveStopDetectFlag | kLPI2C_SlaveRepeatedStartDetectFlag))) &&
            (--waitTimes));
        if (waitTimes == 0)
        {
            return kStatus_LPI2C_Timeout;
        }
#else
        } while (
            !(flags & (kLPI2C_SlaveTxReadyFlag | kLPI2C_SlaveStopDetectFlag | kLPI2C_SlaveRepeatedStartDetectFlag)));
#endif

        /* Send a byte. */
        if (flags & kLPI2C_SlaveTxReadyFlag)
        {
            base->STDR = *buf++;
            --remaining;
        }

        /* Exit loop if we see a stop or restart */
        if (flags & (kLPI2C_SlaveStopDetectFlag | kLPI2C_SlaveRepeatedStartDetectFlag))
        {
            LPI2C_SlaveClearStatusFlags(base, kLPI2C_SlaveStopDetectFlag | kLPI2C_SlaveRepeatedStartDetectFlag);
            break;
        }
    }

    if (actualTxSize)
    {
        *actualTxSize = txSize - remaining;
    }

    return kStatus_Success;
}

status_t LPI2C_SlaveReceive(LPI2C_Type *base, void *rxBuff, size_t rxSize, size_t *actualRxSize)
{
    uint8_t *buf = (uint8_t *)rxBuff;
    size_t remaining = rxSize;

    assert(rxBuff);

#if LPI2C_WAIT_TIMEOUT
    uint32_t waitTimes = LPI2C_WAIT_TIMEOUT;
#endif

    while (remaining)
    {
        uint32_t flags;
        status_t result;

        /* Wait until we can receive. */
        do
        {
            /* Check for errors */
            flags = LPI2C_SlaveGetStatusFlags(base);
            result = LPI2C_SlaveCheckAndClearError(base, flags);
            if (result)
            {
                if (actualRxSize)
                {
                    *actualRxSize = rxSize - remaining;
                }
                return result;
            }
#if LPI2C_WAIT_TIMEOUT
        } while (
            (!(flags & (kLPI2C_SlaveRxReadyFlag | kLPI2C_SlaveStopDetectFlag | kLPI2C_SlaveRepeatedStartDetectFlag))) &&
            (--waitTimes));
        if (waitTimes == 0)
        {
            return kStatus_LPI2C_Timeout;
        }
#else
        } while (
            !(flags & (kLPI2C_SlaveRxReadyFlag | kLPI2C_SlaveStopDetectFlag | kLPI2C_SlaveRepeatedStartDetectFlag)));
#endif

        /* Receive a byte. */
        if (flags & kLPI2C_SlaveRxReadyFlag)
        {
            *buf++ = base->SRDR & LPI2C_SRDR_DATA_MASK;
            --remaining;
        }

        /* Exit loop if we see a stop or restart */
        if (flags & (kLPI2C_SlaveStopDetectFlag | kLPI2C_SlaveRepeatedStartDetectFlag))
        {
            LPI2C_SlaveClearStatusFlags(base, kLPI2C_SlaveStopDetectFlag | kLPI2C_SlaveRepeatedStartDetectFlag);
            break;
        }
    }

    if (actualRxSize)
    {
        *actualRxSize = rxSize - remaining;
    }

    return kStatus_Success;
}

void LPI2C_SlaveTransferCreateHandle(LPI2C_Type *base,
                                     lpi2c_slave_handle_t *handle,
                                     lpi2c_slave_transfer_callback_t callback,
                                     void *userData)
{
    uint32_t instance;

    assert(handle);

    /* Clear out the handle. */
    memset(handle, 0, sizeof(*handle));

    /* Look up instance number */
    instance = LPI2C_GetInstance(base);

    /* Save base and instance. */
    handle->callback = callback;
    handle->userData = userData;

    /* Save this handle for IRQ use. */
    s_lpi2cSlaveHandle[instance] = handle;

    /* Set irq handler. */
    s_lpi2cSlaveIsr = LPI2C_SlaveTransferHandleIRQ;

    /* Clear internal IRQ enables and enable NVIC IRQ. */
    LPI2C_SlaveDisableInterrupts(base, kSlaveIrqFlags);
    EnableIRQ(kLpi2cIrqs[instance]);

    /* Nack by default. */
    base->STAR = LPI2C_STAR_TXNACK_MASK;
}

status_t LPI2C_SlaveTransferNonBlocking(LPI2C_Type *base, lpi2c_slave_handle_t *handle, uint32_t eventMask)
{
    uint32_t status;

    assert(handle);

    /* Return busy if another transaction is in progress. */
    if (handle->isBusy)
    {
        return kStatus_LPI2C_Busy;
    }

    /* Return an error if the bus is already in use not by us. */
    status = LPI2C_SlaveGetStatusFlags(base);
    if ((status & kLPI2C_SlaveBusBusyFlag) && (!(status & kLPI2C_SlaveBusyFlag)))
    {
        return kStatus_LPI2C_Busy;
    }

    /* Disable LPI2C IRQ sources while we configure stuff. */
    LPI2C_SlaveDisableInterrupts(base, kSlaveIrqFlags);

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

    /* Record that we're busy. */
    handle->isBusy = true;

    /* Set up event mask. tx and rx are always enabled. */
    handle->eventMask = eventMask | kLPI2C_SlaveTransmitEvent | kLPI2C_SlaveReceiveEvent;

    /* Ack by default. */
    base->STAR = 0;

    /* Clear all flags. */
    LPI2C_SlaveClearStatusFlags(base, kSlaveClearFlags);

    /* Enable LPI2C internal IRQ sources. NVIC IRQ was enabled in CreateHandle() */
    LPI2C_SlaveEnableInterrupts(base, kSlaveIrqFlags);

    return kStatus_Success;
}

status_t LPI2C_SlaveTransferGetCount(LPI2C_Type *base, lpi2c_slave_handle_t *handle, size_t *count)
{
    assert(handle);

    if (!count)
    {
        return kStatus_InvalidArgument;
    }

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

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

    return kStatus_Success;
}

void LPI2C_SlaveTransferAbort(LPI2C_Type *base, lpi2c_slave_handle_t *handle)
{
    assert(handle);

    /* Return idle if no transaction is in progress. */
    if (handle->isBusy)
    {
        /* Disable LPI2C IRQ sources. */
        LPI2C_SlaveDisableInterrupts(base, kSlaveIrqFlags);

        /* Nack by default. */
        base->STAR = LPI2C_STAR_TXNACK_MASK;

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

        /* We're no longer busy. */
        handle->isBusy = false;
    }
}

void LPI2C_SlaveTransferHandleIRQ(LPI2C_Type *base, lpi2c_slave_handle_t *handle)
{
    uint32_t flags;
    lpi2c_slave_transfer_t *xfer;

    /* Check for a valid handle in case of a spurious interrupt. */
    if (!handle)
    {
        return;
    }

    xfer = &handle->transfer;

    /* Get status flags. */
    flags = LPI2C_SlaveGetStatusFlags(base);

    if (flags & (kLPI2C_SlaveBitErrFlag | kLPI2C_SlaveFifoErrFlag))
    {
        xfer->event = kLPI2C_SlaveCompletionEvent;
        xfer->completionStatus = LPI2C_SlaveCheckAndClearError(base, flags);

        if ((handle->eventMask & kLPI2C_SlaveCompletionEvent) && (handle->callback))
        {
            handle->callback(base, xfer, handle->userData);
        }
        return;
    }
    if (flags & (kLPI2C_SlaveRepeatedStartDetectFlag | kLPI2C_SlaveStopDetectFlag))
    {
        xfer->event = (flags & kLPI2C_SlaveRepeatedStartDetectFlag) ? kLPI2C_SlaveRepeatedStartEvent :
                                                                      kLPI2C_SlaveCompletionEvent;
        xfer->receivedAddress = 0;
        xfer->completionStatus = kStatus_Success;
        xfer->transferredCount = handle->transferredCount;

        if (xfer->event == kLPI2C_SlaveCompletionEvent)
        {
            handle->isBusy = false;
        }

        if (handle->wasTransmit)
        {
            /* Subtract one from the transmit count to offset the fact that LPI2C asserts the */
            /* tx flag before it sees the nack from the master-receiver, thus causing one more */
            /* count that the master actually receives. */
            --xfer->transferredCount;
            handle->wasTransmit = false;
        }

        /* Clear the flag. */
        LPI2C_SlaveClearStatusFlags(base, flags & (kLPI2C_SlaveRepeatedStartDetectFlag | kLPI2C_SlaveStopDetectFlag));

        /* Revert to sending an Ack by default, in case we sent a Nack for receive. */
        base->STAR = 0;

        if ((handle->eventMask & xfer->event) && (handle->callback))
        {
            handle->callback(base, xfer, handle->userData);
        }

        /* Clean up transfer info on completion, after the callback has been invoked. */
        memset(&handle->transfer, 0, sizeof(handle->transfer));
    }
    if (flags & kLPI2C_SlaveAddressValidFlag)
    {
        xfer->event = kLPI2C_SlaveAddressMatchEvent;
        xfer->receivedAddress = base->SASR & LPI2C_SASR_RADDR_MASK;

        if ((handle->eventMask & kLPI2C_SlaveAddressMatchEvent) && (handle->callback))
        {
            handle->callback(base, xfer, handle->userData);
        }
    }
    if (flags & kLPI2C_SlaveTransmitAckFlag)
    {
        xfer->event = kLPI2C_SlaveTransmitAckEvent;

        if ((handle->eventMask & kLPI2C_SlaveTransmitAckEvent) && (handle->callback))
        {
            handle->callback(base, xfer, handle->userData);
        }
    }

    /* Handle transmit and receive. */
    if (flags & kLPI2C_SlaveTxReadyFlag)
    {
        handle->wasTransmit = true;

        /* If we're out of data, invoke callback to get more. */
        if ((!xfer->data) || (!xfer->dataSize))
        {
            xfer->event = kLPI2C_SlaveTransmitEvent;
            if (handle->callback)
            {
                handle->callback(base, xfer, handle->userData);
            }

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

        /* Transmit a byte. */
        if ((xfer->data) && (xfer->dataSize))
        {
            base->STDR = *xfer->data++;
            --xfer->dataSize;
            ++handle->transferredCount;
        }
    }
    if (flags & kLPI2C_SlaveRxReadyFlag)
    {
        /* If we're out of room in the buffer, invoke callback to get another. */
        if ((!xfer->data) || (!xfer->dataSize))
        {
            xfer->event = kLPI2C_SlaveReceiveEvent;
            if (handle->callback)
            {
                handle->callback(base, xfer, handle->userData);
            }

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

        /* Receive a byte. */
        if ((xfer->data) && (xfer->dataSize))
        {
            *xfer->data++ = base->SRDR;
            --xfer->dataSize;
            ++handle->transferredCount;
        }
        else
        {
            /* We don't have any room to receive more data, so send a nack. */
            base->STAR = LPI2C_STAR_TXNACK_MASK;
        }
    }
}

/*!
 * @brief Shared IRQ handler that can call both master and slave ISRs.
 *
 * The master and slave ISRs are called through function pointers in order to decouple
 * this code from the ISR functions. Without this, the linker would always pull in both
 * ISRs and every function they call, even if only the functional API was used.
 *
 * @param base The LPI2C peripheral base address.
 * @param instance The LPI2C peripheral instance number.
 */
static void LPI2C_CommonIRQHandler(LPI2C_Type *base, uint32_t instance)
{
    /* Check for master IRQ. */
    if ((base->MCR & LPI2C_MCR_MEN_MASK) && s_lpi2cMasterIsr)
    {
        /* Master mode. */
        s_lpi2cMasterIsr(base, s_lpi2cMasterHandle[instance]);
    }

    /* Check for slave IRQ. */
    if ((base->SCR & LPI2C_SCR_SEN_MASK) && s_lpi2cSlaveIsr)
    {
        /* Slave mode. */
        s_lpi2cSlaveIsr(base, s_lpi2cSlaveHandle[instance]);
    }
/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  exception return operation might vector to incorrect interrupt */
#if defined __CORTEX_M && (__CORTEX_M == 4U)
    __DSB();
#endif
}

#if defined(LPI2C0)
/* Implementation of LPI2C0 handler named in startup code. */
void LPI2C0_DriverIRQHandler(void)
{
    LPI2C_CommonIRQHandler(LPI2C0, 0);
}
#endif

#if defined(LPI2C1)
/* Implementation of LPI2C1 handler named in startup code. */
void LPI2C1_DriverIRQHandler(void)
{
    LPI2C_CommonIRQHandler(LPI2C1, 1);
}
#endif

#if defined(LPI2C2)
/* Implementation of LPI2C2 handler named in startup code. */
void LPI2C2_DriverIRQHandler(void)
{
    LPI2C_CommonIRQHandler(LPI2C2, 2);
}
#endif

#if defined(LPI2C3)
/* Implementation of LPI2C3 handler named in startup code. */
void LPI2C3_DriverIRQHandler(void)
{
    LPI2C_CommonIRQHandler(LPI2C3, 3);
}
#endif

#if defined(CM4_0__LPI2C)
/* Implementation of CM4_0__LPI2C handler named in startup code. */
void M4_0_LPI2C_DriverIRQHandler(void)
{
    LPI2C_CommonIRQHandler(CM4_0__LPI2C, LPI2C_GetInstance(CM4_0__LPI2C));
}
#endif

#if defined(CM4_1__LPI2C)
/* Implementation of CM4_1__LPI2C handler named in startup code. */
void M4_1_LPI2C_DriverIRQHandler(void)
{
    LPI2C_CommonIRQHandler(CM4_1__LPI2C, LPI2C_GetInstance(CM4_1__LPI2C));
}
#endif

#if defined(DMA__LPI2C0)
/* Implementation of DMA__LPI2C0 handler named in startup code. */
void DMA_I2C0_INT_DriverIRQHandler(void)
{
    LPI2C_CommonIRQHandler(DMA__LPI2C0, LPI2C_GetInstance(DMA__LPI2C0));
}
#endif

#if defined(DMA__LPI2C1)
/* Implementation of DMA__LPI2C1 handler named in startup code. */
void DMA_I2C1_INT_DriverIRQHandler(void)
{
    LPI2C_CommonIRQHandler(DMA__LPI2C1, LPI2C_GetInstance(DMA__LPI2C1));
}
#endif

#if defined(DMA__LPI2C2)
/* Implementation of DMA__LPI2C2 handler named in startup code. */
void DMA_I2C2_INT_DriverIRQHandler(void)
{
    LPI2C_CommonIRQHandler(DMA__LPI2C2, LPI2C_GetInstance(DMA__LPI2C2));
}
#endif

#if defined(DMA__LPI2C3)
/* Implementation of DMA__LPI2C3 handler named in startup code. */
void DMA_I2C3_INT_DriverIRQHandler(void)
{
    LPI2C_CommonIRQHandler(DMA__LPI2C3, LPI2C_GetInstance(DMA__LPI2C3));
}
#endif

#if defined(DMA__LPI2C4)
/* Implementation of DMA__LPI2C3 handler named in startup code. */
void DMA_I2C4_INT_DriverIRQHandler(void)
{
    LPI2C_CommonIRQHandler(DMA__LPI2C4, LPI2C_GetInstance(DMA__LPI2C4));
}
#endif
