added prescaler for 16 bit pwm in LPC1347 target

Fork of mbed-dev by mbed official

Revision:
144:ef7eb2e8f9f7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL43Z/drivers/fsl_flexio_i2c_master.c	Fri Sep 02 15:07:44 2016 +0100
@@ -0,0 +1,732 @@
+/*
+ * Copyright (c) 2015, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * 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 Freescale Semiconductor, Inc. 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_flexio_i2c_master.h"
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*! @brief  FLEXIO I2C transfer state */
+enum _flexio_i2c_master_transfer_states
+{
+    kFLEXIO_I2C_Idle = 0x0U,             /*!< I2C bus idle */
+    kFLEXIO_I2C_CheckAddress = 0x1U,     /*!< 7-bit address check state */
+    kFLEXIO_I2C_SendCommand = 0x2U,      /*!< Send command byte phase */
+    kFLEXIO_I2C_SendData = 0x3U,         /*!< Send data transfer phase*/
+    kFLEXIO_I2C_ReceiveDataBegin = 0x4U, /*!< Receive data begin transfer phase*/
+    kFLEXIO_I2C_ReceiveData = 0x5U,      /*!< Receive data transfer phase*/
+};
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+
+/*!
+ * @brief Set up master transfer, send slave address and decide the initial
+ * transfer state.
+ *
+ * @param base pointer to FLEXIO_I2C_Type structure
+ * @param handle pointer to flexio_i2c_master_handle_t structure which stores the transfer state
+ * @param transfer pointer to flexio_i2c_master_transfer_t structure
+ */
+static status_t FLEXIO_I2C_MasterTransferInitStateMachine(FLEXIO_I2C_Type *base,
+                                                          flexio_i2c_master_handle_t *handle,
+                                                          flexio_i2c_master_transfer_t *xfer);
+
+/*!
+ * @brief Master run transfer state machine to perform a byte of transfer.
+ *
+ * @param base pointer to FLEXIO_I2C_Type structure
+ * @param handle pointer to flexio_i2c_master_handle_t structure which stores the transfer state
+ * @param statusFlags flexio i2c hardware status
+ * @retval kStatus_Success Successfully run state machine
+ * @retval kStatus_FLEXIO_I2C_Nak Receive Nak during transfer
+ */
+static status_t FLEXIO_I2C_MasterTransferRunStateMachine(FLEXIO_I2C_Type *base,
+                                                         flexio_i2c_master_handle_t *handle,
+                                                         uint32_t statusFlags);
+
+/*!
+ * @brief Complete transfer, disable interrupt and call callback.
+ *
+ * @param base pointer to FLEXIO_I2C_Type structure
+ * @param handle pointer to flexio_i2c_master_handle_t structure which stores the transfer state
+ * @param status flexio transfer status
+ */
+static void FLEXIO_I2C_MasterTransferComplete(FLEXIO_I2C_Type *base,
+                                              flexio_i2c_master_handle_t *handle,
+                                              status_t status);
+
+/*******************************************************************************
+ * Codes
+ ******************************************************************************/
+
+static status_t FLEXIO_I2C_MasterTransferInitStateMachine(FLEXIO_I2C_Type *base,
+                                                          flexio_i2c_master_handle_t *handle,
+                                                          flexio_i2c_master_transfer_t *xfer)
+{
+    bool needRestart;
+    uint32_t byteCount;
+
+    /* Init the handle member. */
+    handle->transfer.slaveAddress = xfer->slaveAddress;
+    handle->transfer.direction = xfer->direction;
+    handle->transfer.subaddress = xfer->subaddress;
+    handle->transfer.subaddressSize = xfer->subaddressSize;
+    handle->transfer.data = xfer->data;
+    handle->transfer.dataSize = xfer->dataSize;
+    handle->transfer.flags = xfer->flags;
+    handle->transferSize = xfer->dataSize;
+
+    /* Initial state, i2c check address state. */
+    handle->state = kFLEXIO_I2C_CheckAddress;
+
+    /* Clear all status before transfer. */
+    FLEXIO_I2C_MasterClearStatusFlags(base, kFLEXIO_I2C_ReceiveNakFlag);
+
+    /* Calculate whether need to send re-start. */
+    needRestart = (handle->transfer.subaddressSize != 0) && (handle->transfer.direction == kFLEXIO_I2C_Read);
+
+    /* Calculate total byte count in a frame. */
+    byteCount = 1;
+
+    if (!needRestart)
+    {
+        byteCount += handle->transfer.dataSize;
+    }
+
+    if (handle->transfer.subaddressSize != 0)
+    {
+        byteCount += handle->transfer.subaddressSize;
+        /* Next state, send command byte. */
+        handle->state = kFLEXIO_I2C_SendCommand;
+    }
+
+    /* Configure data count. */
+    if (FLEXIO_I2C_MasterSetTransferCount(base, byteCount) != kStatus_Success)
+    {
+        return kStatus_InvalidArgument;
+    }
+
+    while (!((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[0]))))
+    {
+    }
+
+    /* Send address byte first. */
+    if (needRestart)
+    {
+        FLEXIO_I2C_MasterStart(base, handle->transfer.slaveAddress, kFLEXIO_I2C_Write);
+    }
+    else
+    {
+        FLEXIO_I2C_MasterStart(base, handle->transfer.slaveAddress, handle->transfer.direction);
+    }
+
+    return kStatus_Success;
+}
+
+static status_t FLEXIO_I2C_MasterTransferRunStateMachine(FLEXIO_I2C_Type *base,
+                                                         flexio_i2c_master_handle_t *handle,
+                                                         uint32_t statusFlags)
+{
+    if (statusFlags & kFLEXIO_I2C_ReceiveNakFlag)
+    {
+        /* Clear receive nak flag. */
+        FLEXIO_ClearShifterErrorFlags(base->flexioBase, 1U << base->shifterIndex[1]);
+
+        if ((!((handle->state == kFLEXIO_I2C_SendData) && (handle->transfer.dataSize == 0U))) &&
+            (!(((handle->state == kFLEXIO_I2C_ReceiveData) || (handle->state == kFLEXIO_I2C_ReceiveDataBegin)) &&
+               (handle->transfer.dataSize == 1U))))
+        {
+            FLEXIO_I2C_MasterReadByte(base);
+
+            FLEXIO_I2C_MasterAbortStop(base);
+
+            handle->state = kFLEXIO_I2C_Idle;
+
+            return kStatus_FLEXIO_I2C_Nak;
+        }
+    }
+
+    if (handle->state == kFLEXIO_I2C_CheckAddress)
+    {
+        if (handle->transfer.direction == kFLEXIO_I2C_Write)
+        {
+            /* Next state, send data. */
+            handle->state = kFLEXIO_I2C_SendData;
+        }
+        else
+        {
+            /* Next state, receive data begin. */
+            handle->state = kFLEXIO_I2C_ReceiveDataBegin;
+        }
+    }
+
+    if ((statusFlags & kFLEXIO_I2C_RxFullFlag) && (handle->state != kFLEXIO_I2C_ReceiveData))
+    {
+        FLEXIO_I2C_MasterReadByte(base);
+    }
+
+    switch (handle->state)
+    {
+        case kFLEXIO_I2C_SendCommand:
+            if (statusFlags & kFLEXIO_I2C_TxEmptyFlag)
+            {
+                if (handle->transfer.subaddressSize > 0)
+                {
+                    handle->transfer.subaddressSize--;
+                    FLEXIO_I2C_MasterWriteByte(
+                        base, ((handle->transfer.subaddress) >> (8 * handle->transfer.subaddressSize)));
+
+                    if (handle->transfer.subaddressSize == 0)
+                    {
+                        /* Load re-start in advance. */
+                        if (handle->transfer.direction == kFLEXIO_I2C_Read)
+                        {
+                            while (!((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[0]))))
+                            {
+                            }
+                            FLEXIO_I2C_MasterRepeatedStart(base);
+                        }
+                    }
+                }
+                else
+                {
+                    if (handle->transfer.direction == kFLEXIO_I2C_Write)
+                    {
+                        /* Next state, send data. */
+                        handle->state = kFLEXIO_I2C_SendData;
+
+                        /* Send first byte of data. */
+                        if (handle->transfer.dataSize > 0)
+                        {
+                            FLEXIO_I2C_MasterWriteByte(base, *handle->transfer.data);
+
+                            handle->transfer.data++;
+                            handle->transfer.dataSize--;
+                        }
+                    }
+                    else
+                    {
+                        FLEXIO_I2C_MasterSetTransferCount(base, (handle->transfer.dataSize + 1));
+                        FLEXIO_I2C_MasterStart(base, handle->transfer.slaveAddress, kFLEXIO_I2C_Read);
+
+                        /* Next state, receive data begin. */
+                        handle->state = kFLEXIO_I2C_ReceiveDataBegin;
+                    }
+                }
+            }
+            break;
+
+        /* Send command byte. */
+        case kFLEXIO_I2C_SendData:
+            if (statusFlags & kFLEXIO_I2C_TxEmptyFlag)
+            {
+                /* Send one byte of data. */
+                if (handle->transfer.dataSize > 0)
+                {
+                    FLEXIO_I2C_MasterWriteByte(base, *handle->transfer.data);
+
+                    handle->transfer.data++;
+                    handle->transfer.dataSize--;
+                }
+                else
+                {
+                    FLEXIO_I2C_MasterStop(base);
+                    handle->state = kFLEXIO_I2C_Idle;
+                }
+            }
+            break;
+
+        case kFLEXIO_I2C_ReceiveDataBegin:
+            if (statusFlags & kFLEXIO_I2C_TxEmptyFlag)
+            {
+                /* Read one byte of data. */
+                FLEXIO_I2C_MasterWriteByte(base, 0xFFFFFFFFU);
+
+                /* Send nak at the last receive byte. */
+                if (handle->transfer.dataSize == 1)
+                {
+                    FLEXIO_I2C_MasterEnableAck(base, false);
+                    while (!((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[0]))))
+                    {
+                    }
+                    FLEXIO_I2C_MasterStop(base);
+                }
+                else
+                {
+                    FLEXIO_I2C_MasterEnableAck(base, true);
+                }
+            }
+            else
+            {
+                handle->state = kFLEXIO_I2C_ReceiveData;
+            }
+            break;
+
+        case kFLEXIO_I2C_ReceiveData:
+            if (statusFlags & kFLEXIO_I2C_RxFullFlag)
+            {
+                *handle->transfer.data = FLEXIO_I2C_MasterReadByte(base);
+                handle->transfer.data++;
+                /* Receive one byte of data. */
+                if (handle->transfer.dataSize--)
+                {
+                    if (handle->transfer.dataSize != 0)
+                    {
+                        FLEXIO_I2C_MasterWriteByte(base, 0xFFFFFFFFU);
+                    }
+                    else
+                    {
+                        FLEXIO_I2C_MasterDisableInterrupts(base, kFLEXIO_I2C_RxFullInterruptEnable);
+                        handle->state = kFLEXIO_I2C_Idle;
+                    }
+
+                    /* Send nak at the last receive byte. */
+                    if (handle->transfer.dataSize == 1)
+                    {
+                        FLEXIO_I2C_MasterEnableAck(base, false);
+                        while (!((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[0]))))
+                        {
+                        }
+                        FLEXIO_I2C_MasterStop(base);
+                    }
+                }
+            }
+            break;
+
+        default:
+            break;
+    }
+
+    return kStatus_Success;
+}
+
+static void FLEXIO_I2C_MasterTransferComplete(FLEXIO_I2C_Type *base,
+                                              flexio_i2c_master_handle_t *handle,
+                                              status_t status)
+{
+    FLEXIO_I2C_MasterDisableInterrupts(base, kFLEXIO_I2C_TxEmptyInterruptEnable | kFLEXIO_I2C_RxFullInterruptEnable);
+
+    if (handle->completionCallback)
+    {
+        handle->completionCallback(base, handle, status, handle->userData);
+    }
+}
+
+void FLEXIO_I2C_MasterInit(FLEXIO_I2C_Type *base, flexio_i2c_master_config_t *masterConfig, uint32_t srcClock_Hz)
+{
+    assert(base && masterConfig);
+
+    flexio_shifter_config_t shifterConfig;
+    flexio_timer_config_t timerConfig;
+    uint32_t controlVal = 0;
+
+    memset(&shifterConfig, 0, sizeof(shifterConfig));
+    memset(&timerConfig, 0, sizeof(timerConfig));
+
+    /* Ungate flexio clock. */
+    CLOCK_EnableClock(kCLOCK_Flexio0);
+
+    FLEXIO_Reset(base->flexioBase);
+
+    /* Do hardware configuration. */
+    /* 1. Configure the shifter 0 for tx. */
+    shifterConfig.timerSelect = base->timerIndex[1];
+    shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive;
+    shifterConfig.pinConfig = kFLEXIO_PinConfigOpenDrainOrBidirection;
+    shifterConfig.pinSelect = base->SDAPinIndex;
+    shifterConfig.pinPolarity = kFLEXIO_PinActiveLow;
+    shifterConfig.shifterMode = kFLEXIO_ShifterModeTransmit;
+    shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin;
+    shifterConfig.shifterStop = kFLEXIO_ShifterStopBitHigh;
+    shifterConfig.shifterStart = kFLEXIO_ShifterStartBitLow;
+
+    FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[0], &shifterConfig);
+
+    /* 2. Configure the shifter 1 for rx. */
+    shifterConfig.timerSelect = base->timerIndex[1];
+    shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnNegitive;
+    shifterConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled;
+    shifterConfig.pinSelect = base->SDAPinIndex;
+    shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh;
+    shifterConfig.shifterMode = kFLEXIO_ShifterModeReceive;
+    shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin;
+    shifterConfig.shifterStop = kFLEXIO_ShifterStopBitLow;
+    shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable;
+
+    FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[1], &shifterConfig);
+
+    /*3. Configure the timer 0 for generating bit clock. */
+    timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(base->shifterIndex[0]);
+    timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow;
+    timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal;
+    timerConfig.pinConfig = kFLEXIO_PinConfigOpenDrainOrBidirection;
+    timerConfig.pinSelect = base->SCLPinIndex;
+    timerConfig.pinPolarity = kFLEXIO_PinActiveHigh;
+    timerConfig.timerMode = kFLEXIO_TimerModeDual8BitBaudBit;
+    timerConfig.timerOutput = kFLEXIO_TimerOutputZeroNotAffectedByReset;
+    timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput;
+    timerConfig.timerReset = kFLEXIO_TimerResetOnTimerPinEqualToTimerOutput;
+    timerConfig.timerDisable = kFLEXIO_TimerDisableOnTimerCompare;
+    timerConfig.timerEnable = kFLEXIO_TimerEnableOnTriggerHigh;
+    timerConfig.timerStop = kFLEXIO_TimerStopBitEnableOnTimerDisable;
+    timerConfig.timerStart = kFLEXIO_TimerStartBitEnabled;
+
+    /* Set TIMCMP[7:0] = (baud rate divider / 2) - 1. */
+    timerConfig.timerCompare = (srcClock_Hz / masterConfig->baudRate_Bps) / 2 - 1;
+
+    FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[0], &timerConfig);
+
+    /* 4. Configure the timer 1 for controlling shifters. */
+    timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(base->shifterIndex[0]);
+    timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow;
+    timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal;
+    timerConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled;
+    timerConfig.pinSelect = base->SCLPinIndex;
+    timerConfig.pinPolarity = kFLEXIO_PinActiveLow;
+    timerConfig.timerMode = kFLEXIO_TimerModeSingle16Bit;
+    timerConfig.timerOutput = kFLEXIO_TimerOutputOneNotAffectedByReset;
+    timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnPinInputShiftPinInput;
+    timerConfig.timerReset = kFLEXIO_TimerResetNever;
+    timerConfig.timerDisable = kFLEXIO_TimerDisableOnPreTimerDisable;
+    timerConfig.timerEnable = kFLEXIO_TimerEnableOnPrevTimerEnable;
+    timerConfig.timerStop = kFLEXIO_TimerStopBitEnableOnTimerCompare;
+    timerConfig.timerStart = kFLEXIO_TimerStartBitEnabled;
+
+    /* Set TIMCMP[15:0] = (number of bits x 2) - 1. */
+    timerConfig.timerCompare = 8 * 2 - 1;
+
+    FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[1], &timerConfig);
+
+    /* Configure FLEXIO I2C Master. */
+    controlVal = base->flexioBase->CTRL;
+    controlVal &=
+        ~(FLEXIO_CTRL_DOZEN_MASK | FLEXIO_CTRL_DBGE_MASK | FLEXIO_CTRL_FASTACC_MASK | FLEXIO_CTRL_FLEXEN_MASK);
+    controlVal |=
+        (FLEXIO_CTRL_DOZEN(masterConfig->enableInDoze) | FLEXIO_CTRL_DBGE(masterConfig->enableInDebug) |
+         FLEXIO_CTRL_FASTACC(masterConfig->enableFastAccess) | FLEXIO_CTRL_FLEXEN(masterConfig->enableMaster));
+
+    base->flexioBase->CTRL = controlVal;
+}
+
+void FLEXIO_I2C_MasterDeinit(FLEXIO_I2C_Type *base)
+{
+    FLEXIO_Deinit(base->flexioBase);
+}
+
+void FLEXIO_I2C_MasterGetDefaultConfig(flexio_i2c_master_config_t *masterConfig)
+{
+    assert(masterConfig);
+
+    masterConfig->enableMaster = true;
+    masterConfig->enableInDoze = false;
+    masterConfig->enableInDebug = true;
+    masterConfig->enableFastAccess = false;
+
+    /* Default baud rate at 100kbps. */
+    masterConfig->baudRate_Bps = 100000U;
+}
+
+uint32_t FLEXIO_I2C_MasterGetStatusFlags(FLEXIO_I2C_Type *base)
+{
+    uint32_t status = 0;
+
+    status =
+        ((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[0])) >> base->shifterIndex[0]);
+    status |=
+        (((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[1])) >> (base->shifterIndex[1]))
+         << 1U);
+    status |=
+        (((FLEXIO_GetShifterErrorFlags(base->flexioBase) & (1U << base->shifterIndex[1])) >> (base->shifterIndex[1]))
+         << 2U);
+
+    return status;
+}
+
+void FLEXIO_I2C_MasterClearStatusFlags(FLEXIO_I2C_Type *base, uint32_t mask)
+{
+    if (mask & kFLEXIO_I2C_TxEmptyFlag)
+    {
+        FLEXIO_ClearShifterStatusFlags(base->flexioBase, 1U << base->shifterIndex[0]);
+    }
+
+    if (mask & kFLEXIO_I2C_RxFullFlag)
+    {
+        FLEXIO_ClearShifterStatusFlags(base->flexioBase, 1U << base->shifterIndex[1]);
+    }
+
+    if (mask & kFLEXIO_I2C_ReceiveNakFlag)
+    {
+        FLEXIO_ClearShifterErrorFlags(base->flexioBase, 1U << base->shifterIndex[1]);
+    }
+}
+
+void FLEXIO_I2C_MasterEnableInterrupts(FLEXIO_I2C_Type *base, uint32_t mask)
+{
+    if (mask & kFLEXIO_I2C_TxEmptyInterruptEnable)
+    {
+        FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1U << base->shifterIndex[0]);
+    }
+    if (mask & kFLEXIO_I2C_RxFullInterruptEnable)
+    {
+        FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1U << base->shifterIndex[1]);
+    }
+}
+
+void FLEXIO_I2C_MasterDisableInterrupts(FLEXIO_I2C_Type *base, uint32_t mask)
+{
+    if (mask & kFLEXIO_I2C_TxEmptyInterruptEnable)
+    {
+        FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1U << base->shifterIndex[0]);
+    }
+    if (mask & kFLEXIO_I2C_RxFullInterruptEnable)
+    {
+        FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1U << base->shifterIndex[1]);
+    }
+}
+
+void FLEXIO_I2C_MasterSetBaudRate(FLEXIO_I2C_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz)
+{
+    uint16_t timerDiv = 0;
+    uint16_t timerCmp = 0;
+    FLEXIO_Type *flexioBase = base->flexioBase;
+
+    /* Set TIMCMP[7:0] = (baud rate divider / 2) - 1.*/
+    timerDiv = srcClock_Hz / baudRate_Bps;
+    timerDiv = timerDiv / 2 - 1U;
+
+    timerCmp = flexioBase->TIMCMP[base->timerIndex[0]];
+    timerCmp &= 0xFF00;
+    timerCmp |= timerDiv;
+
+    flexioBase->TIMCMP[base->timerIndex[0]] = timerCmp;
+}
+
+status_t FLEXIO_I2C_MasterSetTransferCount(FLEXIO_I2C_Type *base, uint8_t count)
+{
+    if (count > 14U)
+    {
+        return kStatus_InvalidArgument;
+    }
+
+    uint16_t timerCmp = 0;
+    uint32_t timerConfig = 0;
+    FLEXIO_Type *flexioBase = base->flexioBase;
+
+    timerCmp = flexioBase->TIMCMP[base->timerIndex[0]];
+    timerCmp &= 0x00FFU;
+    timerCmp |= (count * 18 + 1U) << 8U;
+    flexioBase->TIMCMP[base->timerIndex[0]] = timerCmp;
+    timerConfig = flexioBase->TIMCFG[base->timerIndex[0]];
+    timerConfig &= ~FLEXIO_TIMCFG_TIMDIS_MASK;
+    timerConfig |= FLEXIO_TIMCFG_TIMDIS(kFLEXIO_TimerDisableOnTimerCompare);
+    flexioBase->TIMCFG[base->timerIndex[0]] = timerConfig;
+
+    return kStatus_Success;
+}
+
+void FLEXIO_I2C_MasterStart(FLEXIO_I2C_Type *base, uint8_t address, flexio_i2c_direction_t direction)
+{
+    uint32_t data;
+
+    data = ((uint32_t)address) << 1U | ((direction == kFLEXIO_I2C_Read) ? 1U : 0U);
+
+    FLEXIO_I2C_MasterWriteByte(base, data);
+}
+
+void FLEXIO_I2C_MasterRepeatedStart(FLEXIO_I2C_Type *base)
+{
+    /* Prepare for RESTART condition, no stop.*/
+    FLEXIO_I2C_MasterWriteByte(base, 0xFFFFFFFFU);
+}
+
+void FLEXIO_I2C_MasterStop(FLEXIO_I2C_Type *base)
+{
+    /* Prepare normal stop. */
+    FLEXIO_I2C_MasterSetTransferCount(base, 0x0U);
+    FLEXIO_I2C_MasterWriteByte(base, 0x0U);
+}
+
+void FLEXIO_I2C_MasterAbortStop(FLEXIO_I2C_Type *base)
+{
+    uint32_t tmpConfig;
+
+    /* Prepare abort stop. */
+    tmpConfig = base->flexioBase->TIMCFG[base->timerIndex[0]];
+    tmpConfig &= ~FLEXIO_TIMCFG_TIMDIS_MASK;
+    tmpConfig |= FLEXIO_TIMCFG_TIMDIS(kFLEXIO_TimerDisableOnPinBothEdge);
+    base->flexioBase->TIMCFG[base->timerIndex[0]] = tmpConfig;
+}
+
+void FLEXIO_I2C_MasterEnableAck(FLEXIO_I2C_Type *base, bool enable)
+{
+    uint32_t tmpConfig = 0;
+
+    tmpConfig = base->flexioBase->SHIFTCFG[base->shifterIndex[0]];
+    tmpConfig &= ~FLEXIO_SHIFTCFG_SSTOP_MASK;
+    if (enable)
+    {
+        tmpConfig |= FLEXIO_SHIFTCFG_SSTOP(kFLEXIO_ShifterStopBitLow);
+    }
+    else
+    {
+        tmpConfig |= FLEXIO_SHIFTCFG_SSTOP(kFLEXIO_ShifterStopBitHigh);
+    }
+    base->flexioBase->SHIFTCFG[base->shifterIndex[0]] = tmpConfig;
+}
+
+status_t FLEXIO_I2C_MasterWriteBlocking(FLEXIO_I2C_Type *base, const uint8_t *txBuff, uint8_t txSize)
+{
+    assert(txBuff);
+    assert(txSize);
+
+    uint32_t status;
+
+    while (txSize--)
+    {
+        FLEXIO_I2C_MasterWriteByte(base, *txBuff++);
+
+        /* Wait until data transfer complete. */
+        while (!((status = FLEXIO_I2C_MasterGetStatusFlags(base)) & kFLEXIO_I2C_RxFullFlag))
+        {
+        }
+
+        if (status & kFLEXIO_I2C_ReceiveNakFlag)
+        {
+            FLEXIO_ClearShifterErrorFlags(base->flexioBase, 1U << base->shifterIndex[1]);
+            return kStatus_FLEXIO_I2C_Nak;
+        }
+    }
+    return kStatus_Success;
+}
+
+void FLEXIO_I2C_MasterReadBlocking(FLEXIO_I2C_Type *base, uint8_t *rxBuff, uint8_t rxSize)
+{
+    assert(rxBuff);
+    assert(rxSize);
+
+    while (rxSize--)
+    {
+        /* Wait until data transfer complete. */
+        while (!(FLEXIO_I2C_MasterGetStatusFlags(base) & kFLEXIO_I2C_RxFullFlag))
+        {
+        }
+
+        *rxBuff++ = FLEXIO_I2C_MasterReadByte(base);
+    }
+}
+
+status_t FLEXIO_I2C_MasterTransferCreateHandle(FLEXIO_I2C_Type *base,
+                                               flexio_i2c_master_handle_t *handle,
+                                               flexio_i2c_master_transfer_callback_t callback,
+                                               void *userData)
+{
+    assert(handle);
+
+    IRQn_Type flexio_irqs[] = FLEXIO_IRQS;
+
+    /* Zero the handle. */
+    memset(handle, 0, sizeof(*handle));
+
+    /* Register callback and userData. */
+    handle->completionCallback = callback;
+    handle->userData = userData;
+
+    /* Enable interrupt in NVIC. */
+    EnableIRQ(flexio_irqs[0]);
+
+    /* Save the context in global variables to support the double weak mechanism. */
+    return FLEXIO_RegisterHandleIRQ(base, handle, FLEXIO_I2C_MasterTransferHandleIRQ);
+}
+
+status_t FLEXIO_I2C_MasterTransferNonBlocking(FLEXIO_I2C_Type *base,
+                                              flexio_i2c_master_handle_t *handle,
+                                              flexio_i2c_master_transfer_t *xfer)
+{
+    assert(handle);
+    assert(xfer);
+
+    if (handle->state != kFLEXIO_I2C_Idle)
+    {
+        return kStatus_FLEXIO_I2C_Busy;
+    }
+    else
+    {
+        /* Set up transfer machine. */
+        FLEXIO_I2C_MasterTransferInitStateMachine(base, handle, xfer);
+
+        /* Enable both tx empty and rxfull interrupt. */
+        FLEXIO_I2C_MasterEnableInterrupts(base, kFLEXIO_I2C_TxEmptyInterruptEnable | kFLEXIO_I2C_RxFullInterruptEnable);
+
+        return kStatus_Success;
+    }
+}
+
+void FLEXIO_I2C_MasterTransferAbort(FLEXIO_I2C_Type *base, flexio_i2c_master_handle_t *handle)
+{
+    assert(handle);
+
+    /* Disable interrupts. */
+    FLEXIO_I2C_MasterDisableInterrupts(base, kFLEXIO_I2C_TxEmptyInterruptEnable | kFLEXIO_I2C_RxFullInterruptEnable);
+
+    /* Reset to idle state. */
+    handle->state = kFLEXIO_I2C_Idle;
+}
+
+status_t FLEXIO_I2C_MasterTransferGetCount(FLEXIO_I2C_Type *base, flexio_i2c_master_handle_t *handle, size_t *count)
+{
+    if (!count)
+    {
+        return kStatus_InvalidArgument;
+    }
+
+    *count = handle->transferSize - handle->transfer.dataSize;
+
+    return kStatus_Success;
+}
+
+void FLEXIO_I2C_MasterTransferHandleIRQ(void *i2cType, void *i2cHandle)
+{
+    FLEXIO_I2C_Type *base = (FLEXIO_I2C_Type *)i2cType;
+    flexio_i2c_master_handle_t *handle = (flexio_i2c_master_handle_t *)i2cHandle;
+    uint32_t statusFlags;
+    status_t result;
+
+    statusFlags = FLEXIO_I2C_MasterGetStatusFlags(base);
+
+    result = FLEXIO_I2C_MasterTransferRunStateMachine(base, handle, statusFlags);
+
+    if (handle->state == kFLEXIO_I2C_Idle)
+    {
+        FLEXIO_I2C_MasterTransferComplete(base, handle, result);
+    }
+}