anyThing Connected Team / mbed-dev

Dependents:   BREAK_SENSOR_LED

Fork of mbed-dev by mbed official

Committer:
Anythingconnected
Date:
Mon Dec 18 10:14:27 2017 +0000
Revision:
180:d79f997829d6
Parent:
154:37f96f9d4de2
Getting byte by byte read to work

Who changed what in which revision?

UserRevisionLine numberNew contents of line
<> 154:37f96f9d4de2 1 /*
<> 154:37f96f9d4de2 2 * Copyright (c) 2015, Freescale Semiconductor, Inc.
<> 154:37f96f9d4de2 3 * All rights reserved.
<> 154:37f96f9d4de2 4 *
<> 154:37f96f9d4de2 5 * Redistribution and use in source and binary forms, with or without modification,
<> 154:37f96f9d4de2 6 * are permitted provided that the following conditions are met:
<> 154:37f96f9d4de2 7 *
<> 154:37f96f9d4de2 8 * o Redistributions of source code must retain the above copyright notice, this list
<> 154:37f96f9d4de2 9 * of conditions and the following disclaimer.
<> 154:37f96f9d4de2 10 *
<> 154:37f96f9d4de2 11 * o Redistributions in binary form must reproduce the above copyright notice, this
<> 154:37f96f9d4de2 12 * list of conditions and the following disclaimer in the documentation and/or
<> 154:37f96f9d4de2 13 * other materials provided with the distribution.
<> 154:37f96f9d4de2 14 *
<> 154:37f96f9d4de2 15 * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
<> 154:37f96f9d4de2 16 * contributors may be used to endorse or promote products derived from this
<> 154:37f96f9d4de2 17 * software without specific prior written permission.
<> 154:37f96f9d4de2 18 *
<> 154:37f96f9d4de2 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
<> 154:37f96f9d4de2 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
<> 154:37f96f9d4de2 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
<> 154:37f96f9d4de2 22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
<> 154:37f96f9d4de2 23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
<> 154:37f96f9d4de2 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
<> 154:37f96f9d4de2 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
<> 154:37f96f9d4de2 26 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
<> 154:37f96f9d4de2 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
<> 154:37f96f9d4de2 28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<> 154:37f96f9d4de2 29 */
<> 154:37f96f9d4de2 30 #include "fsl_i2c.h"
<> 154:37f96f9d4de2 31
<> 154:37f96f9d4de2 32 /*******************************************************************************
<> 154:37f96f9d4de2 33 * Definitions
<> 154:37f96f9d4de2 34 ******************************************************************************/
<> 154:37f96f9d4de2 35
<> 154:37f96f9d4de2 36 /*! @brief i2c transfer state. */
<> 154:37f96f9d4de2 37 enum _i2c_transfer_states
<> 154:37f96f9d4de2 38 {
<> 154:37f96f9d4de2 39 kIdleState = 0x0U, /*!< I2C bus idle. */
<> 154:37f96f9d4de2 40 kCheckAddressState = 0x1U, /*!< 7-bit address check state. */
<> 154:37f96f9d4de2 41 kSendCommandState = 0x2U, /*!< Send command byte phase. */
<> 154:37f96f9d4de2 42 kSendDataState = 0x3U, /*!< Send data transfer phase. */
<> 154:37f96f9d4de2 43 kReceiveDataBeginState = 0x4U, /*!< Receive data transfer phase begin. */
<> 154:37f96f9d4de2 44 kReceiveDataState = 0x5U, /*!< Receive data transfer phase. */
<> 154:37f96f9d4de2 45 };
<> 154:37f96f9d4de2 46
<> 154:37f96f9d4de2 47 /*! @brief Common sets of flags used by the driver. */
<> 154:37f96f9d4de2 48 enum _i2c_flag_constants
<> 154:37f96f9d4de2 49 {
<> 154:37f96f9d4de2 50 /*! All flags which are cleared by the driver upon starting a transfer. */
<> 154:37f96f9d4de2 51 #if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT
<> 154:37f96f9d4de2 52 kClearFlags = kI2C_ArbitrationLostFlag | kI2C_IntPendingFlag | kI2C_StartDetectFlag | kI2C_StopDetectFlag,
<> 154:37f96f9d4de2 53 kIrqFlags = kI2C_GlobalInterruptEnable | kI2C_StartStopDetectInterruptEnable,
<> 154:37f96f9d4de2 54 #elif defined(FSL_FEATURE_I2C_HAS_STOP_DETECT) && FSL_FEATURE_I2C_HAS_STOP_DETECT
<> 154:37f96f9d4de2 55 kClearFlags = kI2C_ArbitrationLostFlag | kI2C_IntPendingFlag | kI2C_StopDetectFlag,
<> 154:37f96f9d4de2 56 kIrqFlags = kI2C_GlobalInterruptEnable | kI2C_StopDetectInterruptEnable,
<> 154:37f96f9d4de2 57 #else
<> 154:37f96f9d4de2 58 kClearFlags = kI2C_ArbitrationLostFlag | kI2C_IntPendingFlag,
<> 154:37f96f9d4de2 59 kIrqFlags = kI2C_GlobalInterruptEnable,
<> 154:37f96f9d4de2 60 #endif
<> 154:37f96f9d4de2 61
<> 154:37f96f9d4de2 62 };
<> 154:37f96f9d4de2 63
<> 154:37f96f9d4de2 64 /*! @brief Typedef for interrupt handler. */
<> 154:37f96f9d4de2 65 typedef void (*i2c_isr_t)(I2C_Type *base, void *i2cHandle);
<> 154:37f96f9d4de2 66
<> 154:37f96f9d4de2 67 /*******************************************************************************
<> 154:37f96f9d4de2 68 * Prototypes
<> 154:37f96f9d4de2 69 ******************************************************************************/
<> 154:37f96f9d4de2 70
<> 154:37f96f9d4de2 71 /*!
<> 154:37f96f9d4de2 72 * @brief Get instance number for I2C module.
<> 154:37f96f9d4de2 73 *
<> 154:37f96f9d4de2 74 * @param base I2C peripheral base address.
<> 154:37f96f9d4de2 75 */
<> 154:37f96f9d4de2 76 uint32_t I2C_GetInstance(I2C_Type *base);
<> 154:37f96f9d4de2 77
<> 154:37f96f9d4de2 78 /*!
<> 154:37f96f9d4de2 79 * @brief Set SCL/SDA hold time, this API receives SCL stop hold time, calculate the
<> 154:37f96f9d4de2 80 * closest SCL divider and MULT value for the SDA hold time, SCL start and SCL stop
<> 154:37f96f9d4de2 81 * hold time. To reduce the ROM size, SDA/SCL hold value mapping table is not provided,
<> 154:37f96f9d4de2 82 * assume SCL divider = SCL stop hold value *2 to get the closest SCL divider value and MULT
<> 154:37f96f9d4de2 83 * value, then the related SDA hold time, SCL start and SCL stop hold time is used.
<> 154:37f96f9d4de2 84 *
<> 154:37f96f9d4de2 85 * @param base I2C peripheral base address.
<> 154:37f96f9d4de2 86 * @param sourceClock_Hz I2C functional clock frequency in Hertz.
<> 154:37f96f9d4de2 87 * @param sclStopHoldTime_ns SCL stop hold time in ns.
<> 154:37f96f9d4de2 88 */
<> 154:37f96f9d4de2 89 static void I2C_SetHoldTime(I2C_Type *base, uint32_t sclStopHoldTime_ns, uint32_t sourceClock_Hz);
<> 154:37f96f9d4de2 90
<> 154:37f96f9d4de2 91 /*!
<> 154:37f96f9d4de2 92 * @brief Set up master transfer, send slave address and decide the initial
<> 154:37f96f9d4de2 93 * transfer state.
<> 154:37f96f9d4de2 94 *
<> 154:37f96f9d4de2 95 * @param base I2C peripheral base address.
<> 154:37f96f9d4de2 96 * @param handle pointer to i2c_master_handle_t structure which stores the transfer state.
<> 154:37f96f9d4de2 97 * @param xfer pointer to i2c_master_transfer_t structure.
<> 154:37f96f9d4de2 98 */
<> 154:37f96f9d4de2 99 static status_t I2C_InitTransferStateMachine(I2C_Type *base, i2c_master_handle_t *handle, i2c_master_transfer_t *xfer);
<> 154:37f96f9d4de2 100
<> 154:37f96f9d4de2 101 /*!
<> 154:37f96f9d4de2 102 * @brief Check and clear status operation.
<> 154:37f96f9d4de2 103 *
<> 154:37f96f9d4de2 104 * @param base I2C peripheral base address.
<> 154:37f96f9d4de2 105 * @param status current i2c hardware status.
<> 154:37f96f9d4de2 106 * @retval kStatus_Success No error found.
<> 154:37f96f9d4de2 107 * @retval kStatus_I2C_ArbitrationLost Transfer error, arbitration lost.
<> 154:37f96f9d4de2 108 * @retval kStatus_I2C_Nak Received Nak error.
<> 154:37f96f9d4de2 109 */
<> 154:37f96f9d4de2 110 static status_t I2C_CheckAndClearError(I2C_Type *base, uint32_t status);
<> 154:37f96f9d4de2 111
<> 154:37f96f9d4de2 112 /*!
<> 154:37f96f9d4de2 113 * @brief Master run transfer state machine to perform a byte of transfer.
<> 154:37f96f9d4de2 114 *
<> 154:37f96f9d4de2 115 * @param base I2C peripheral base address.
<> 154:37f96f9d4de2 116 * @param handle pointer to i2c_master_handle_t structure which stores the transfer state
<> 154:37f96f9d4de2 117 * @param isDone input param to get whether the thing is done, true is done
<> 154:37f96f9d4de2 118 * @retval kStatus_Success No error found.
<> 154:37f96f9d4de2 119 * @retval kStatus_I2C_ArbitrationLost Transfer error, arbitration lost.
<> 154:37f96f9d4de2 120 * @retval kStatus_I2C_Nak Received Nak error.
<> 154:37f96f9d4de2 121 * @retval kStatus_I2C_Timeout Transfer error, wait signal timeout.
<> 154:37f96f9d4de2 122 */
<> 154:37f96f9d4de2 123 static status_t I2C_MasterTransferRunStateMachine(I2C_Type *base, i2c_master_handle_t *handle, bool *isDone);
<> 154:37f96f9d4de2 124
<> 154:37f96f9d4de2 125 /*!
<> 154:37f96f9d4de2 126 * @brief I2C common interrupt handler.
<> 154:37f96f9d4de2 127 *
<> 154:37f96f9d4de2 128 * @param base I2C peripheral base address.
<> 154:37f96f9d4de2 129 * @param handle pointer to i2c_master_handle_t structure which stores the transfer state
<> 154:37f96f9d4de2 130 */
<> 154:37f96f9d4de2 131 static void I2C_TransferCommonIRQHandler(I2C_Type *base, void *handle);
<> 154:37f96f9d4de2 132
<> 154:37f96f9d4de2 133 /*******************************************************************************
<> 154:37f96f9d4de2 134 * Variables
<> 154:37f96f9d4de2 135 ******************************************************************************/
<> 154:37f96f9d4de2 136
<> 154:37f96f9d4de2 137 /*! @brief Pointers to i2c handles for each instance. */
<> 154:37f96f9d4de2 138 static void *s_i2cHandle[FSL_FEATURE_SOC_I2C_COUNT] = {NULL};
<> 154:37f96f9d4de2 139
<> 154:37f96f9d4de2 140 /*! @brief SCL clock divider used to calculate baudrate. */
<> 154:37f96f9d4de2 141 static const uint16_t s_i2cDividerTable[] = {
<> 154:37f96f9d4de2 142 20, 22, 24, 26, 28, 30, 34, 40, 28, 32, 36, 40, 44, 48, 56, 68,
<> 154:37f96f9d4de2 143 48, 56, 64, 72, 80, 88, 104, 128, 80, 96, 112, 128, 144, 160, 192, 240,
<> 154:37f96f9d4de2 144 160, 192, 224, 256, 288, 320, 384, 480, 320, 384, 448, 512, 576, 640, 768, 960,
<> 154:37f96f9d4de2 145 640, 768, 896, 1024, 1152, 1280, 1536, 1920, 1280, 1536, 1792, 2048, 2304, 2560, 3072, 3840};
<> 154:37f96f9d4de2 146
<> 154:37f96f9d4de2 147 /*! @brief Pointers to i2c bases for each instance. */
<> 154:37f96f9d4de2 148 static I2C_Type *const s_i2cBases[] = I2C_BASE_PTRS;
<> 154:37f96f9d4de2 149
<> 154:37f96f9d4de2 150 /*! @brief Pointers to i2c IRQ number for each instance. */
<> 154:37f96f9d4de2 151 static const IRQn_Type s_i2cIrqs[] = I2C_IRQS;
<> 154:37f96f9d4de2 152
<> 154:37f96f9d4de2 153 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
<> 154:37f96f9d4de2 154 /*! @brief Pointers to i2c clocks for each instance. */
<> 154:37f96f9d4de2 155 static const clock_ip_name_t s_i2cClocks[] = I2C_CLOCKS;
<> 154:37f96f9d4de2 156 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
<> 154:37f96f9d4de2 157
<> 154:37f96f9d4de2 158 /*! @brief Pointer to master IRQ handler for each instance. */
<> 154:37f96f9d4de2 159 static i2c_isr_t s_i2cMasterIsr;
<> 154:37f96f9d4de2 160
<> 154:37f96f9d4de2 161 /*! @brief Pointer to slave IRQ handler for each instance. */
<> 154:37f96f9d4de2 162 static i2c_isr_t s_i2cSlaveIsr;
<> 154:37f96f9d4de2 163
<> 154:37f96f9d4de2 164 /*******************************************************************************
<> 154:37f96f9d4de2 165 * Codes
<> 154:37f96f9d4de2 166 ******************************************************************************/
<> 154:37f96f9d4de2 167
<> 154:37f96f9d4de2 168 uint32_t I2C_GetInstance(I2C_Type *base)
<> 154:37f96f9d4de2 169 {
<> 154:37f96f9d4de2 170 uint32_t instance;
<> 154:37f96f9d4de2 171
<> 154:37f96f9d4de2 172 /* Find the instance index from base address mappings. */
<> 154:37f96f9d4de2 173 for (instance = 0; instance < FSL_FEATURE_SOC_I2C_COUNT; instance++)
<> 154:37f96f9d4de2 174 {
<> 154:37f96f9d4de2 175 if (s_i2cBases[instance] == base)
<> 154:37f96f9d4de2 176 {
<> 154:37f96f9d4de2 177 break;
<> 154:37f96f9d4de2 178 }
<> 154:37f96f9d4de2 179 }
<> 154:37f96f9d4de2 180
<> 154:37f96f9d4de2 181 assert(instance < FSL_FEATURE_SOC_I2C_COUNT);
<> 154:37f96f9d4de2 182
<> 154:37f96f9d4de2 183 return instance;
<> 154:37f96f9d4de2 184 }
<> 154:37f96f9d4de2 185
<> 154:37f96f9d4de2 186 static void I2C_SetHoldTime(I2C_Type *base, uint32_t sclStopHoldTime_ns, uint32_t sourceClock_Hz)
<> 154:37f96f9d4de2 187 {
<> 154:37f96f9d4de2 188 uint32_t multiplier;
<> 154:37f96f9d4de2 189 uint32_t computedSclHoldTime;
<> 154:37f96f9d4de2 190 uint32_t absError;
<> 154:37f96f9d4de2 191 uint32_t bestError = UINT32_MAX;
<> 154:37f96f9d4de2 192 uint32_t bestMult = 0u;
<> 154:37f96f9d4de2 193 uint32_t bestIcr = 0u;
<> 154:37f96f9d4de2 194 uint8_t mult;
<> 154:37f96f9d4de2 195 uint8_t i;
<> 154:37f96f9d4de2 196
<> 154:37f96f9d4de2 197 /* Search for the settings with the lowest error. Mult is the MULT field of the I2C_F register,
<> 154:37f96f9d4de2 198 * and ranges from 0-2. It selects the multiplier factor for the divider. */
<> 154:37f96f9d4de2 199 /* SDA hold time = bus period (s) * mul * SDA hold value. */
<> 154:37f96f9d4de2 200 /* SCL start hold time = bus period (s) * mul * SCL start hold value. */
<> 154:37f96f9d4de2 201 /* SCL stop hold time = bus period (s) * mul * SCL stop hold value. */
<> 154:37f96f9d4de2 202
<> 154:37f96f9d4de2 203 for (mult = 0u; (mult <= 2u) && (bestError != 0); ++mult)
<> 154:37f96f9d4de2 204 {
<> 154:37f96f9d4de2 205 multiplier = 1u << mult;
<> 154:37f96f9d4de2 206
<> 154:37f96f9d4de2 207 /* Scan table to find best match. */
<> 154:37f96f9d4de2 208 for (i = 0u; i < sizeof(s_i2cDividerTable) / sizeof(s_i2cDividerTable[0]); ++i)
<> 154:37f96f9d4de2 209 {
<> 154:37f96f9d4de2 210 /* Assume SCL hold(stop) value = s_i2cDividerTable[i]/2. */
<> 154:37f96f9d4de2 211 computedSclHoldTime = ((multiplier * s_i2cDividerTable[i]) * 500000000U) / sourceClock_Hz;
<> 154:37f96f9d4de2 212 absError = sclStopHoldTime_ns > computedSclHoldTime ? (sclStopHoldTime_ns - computedSclHoldTime) :
<> 154:37f96f9d4de2 213 (computedSclHoldTime - sclStopHoldTime_ns);
<> 154:37f96f9d4de2 214
<> 154:37f96f9d4de2 215 if (absError < bestError)
<> 154:37f96f9d4de2 216 {
<> 154:37f96f9d4de2 217 bestMult = mult;
<> 154:37f96f9d4de2 218 bestIcr = i;
<> 154:37f96f9d4de2 219 bestError = absError;
<> 154:37f96f9d4de2 220
<> 154:37f96f9d4de2 221 /* If the error is 0, then we can stop searching because we won't find a better match. */
<> 154:37f96f9d4de2 222 if (absError == 0)
<> 154:37f96f9d4de2 223 {
<> 154:37f96f9d4de2 224 break;
<> 154:37f96f9d4de2 225 }
<> 154:37f96f9d4de2 226 }
<> 154:37f96f9d4de2 227 }
<> 154:37f96f9d4de2 228 }
<> 154:37f96f9d4de2 229
<> 154:37f96f9d4de2 230 /* Set frequency register based on best settings. */
<> 154:37f96f9d4de2 231 base->F = I2C_F_MULT(bestMult) | I2C_F_ICR(bestIcr);
<> 154:37f96f9d4de2 232 }
<> 154:37f96f9d4de2 233
<> 154:37f96f9d4de2 234 static status_t I2C_InitTransferStateMachine(I2C_Type *base, i2c_master_handle_t *handle, i2c_master_transfer_t *xfer)
<> 154:37f96f9d4de2 235 {
<> 154:37f96f9d4de2 236 status_t result = kStatus_Success;
<> 154:37f96f9d4de2 237 i2c_direction_t direction = xfer->direction;
<> 154:37f96f9d4de2 238
<> 154:37f96f9d4de2 239 /* Initialize the handle transfer information. */
<> 154:37f96f9d4de2 240 handle->transfer = *xfer;
<> 154:37f96f9d4de2 241
<> 154:37f96f9d4de2 242 /* Save total transfer size. */
<> 154:37f96f9d4de2 243 handle->transferSize = xfer->dataSize;
<> 154:37f96f9d4de2 244
<> 154:37f96f9d4de2 245 /* Initial transfer state. */
<> 154:37f96f9d4de2 246 if (handle->transfer.subaddressSize > 0)
<> 154:37f96f9d4de2 247 {
<> 154:37f96f9d4de2 248 if (xfer->direction == kI2C_Read)
<> 154:37f96f9d4de2 249 {
<> 154:37f96f9d4de2 250 direction = kI2C_Write;
<> 154:37f96f9d4de2 251 }
<> 154:37f96f9d4de2 252 }
<> 154:37f96f9d4de2 253
<> 154:37f96f9d4de2 254 handle->state = kCheckAddressState;
<> 154:37f96f9d4de2 255
<> 154:37f96f9d4de2 256 /* Clear all status before transfer. */
<> 154:37f96f9d4de2 257 I2C_MasterClearStatusFlags(base, kClearFlags);
<> 154:37f96f9d4de2 258
<> 154:37f96f9d4de2 259 /* If repeated start is requested, send repeated start. */
<> 154:37f96f9d4de2 260 if (handle->transfer.flags & kI2C_TransferRepeatedStartFlag)
<> 154:37f96f9d4de2 261 {
<> 154:37f96f9d4de2 262 result = I2C_MasterRepeatedStart(base, handle->transfer.slaveAddress, direction);
<> 154:37f96f9d4de2 263 }
<> 154:37f96f9d4de2 264 else /* For normal transfer, send start. */
<> 154:37f96f9d4de2 265 {
<> 154:37f96f9d4de2 266 result = I2C_MasterStart(base, handle->transfer.slaveAddress, direction);
<> 154:37f96f9d4de2 267 }
<> 154:37f96f9d4de2 268
<> 154:37f96f9d4de2 269 return result;
<> 154:37f96f9d4de2 270 }
<> 154:37f96f9d4de2 271
<> 154:37f96f9d4de2 272 static status_t I2C_CheckAndClearError(I2C_Type *base, uint32_t status)
<> 154:37f96f9d4de2 273 {
<> 154:37f96f9d4de2 274 status_t result = kStatus_Success;
<> 154:37f96f9d4de2 275
<> 154:37f96f9d4de2 276 /* Check arbitration lost. */
<> 154:37f96f9d4de2 277 if (status & kI2C_ArbitrationLostFlag)
<> 154:37f96f9d4de2 278 {
<> 154:37f96f9d4de2 279 /* Clear arbitration lost flag. */
<> 154:37f96f9d4de2 280 base->S = kI2C_ArbitrationLostFlag;
<> 154:37f96f9d4de2 281 result = kStatus_I2C_ArbitrationLost;
<> 154:37f96f9d4de2 282 }
<> 154:37f96f9d4de2 283 /* Check NAK */
<> 154:37f96f9d4de2 284 else if (status & kI2C_ReceiveNakFlag)
<> 154:37f96f9d4de2 285 {
<> 154:37f96f9d4de2 286 result = kStatus_I2C_Nak;
<> 154:37f96f9d4de2 287 }
<> 154:37f96f9d4de2 288 else
<> 154:37f96f9d4de2 289 {
<> 154:37f96f9d4de2 290 }
<> 154:37f96f9d4de2 291
<> 154:37f96f9d4de2 292 return result;
<> 154:37f96f9d4de2 293 }
<> 154:37f96f9d4de2 294
<> 154:37f96f9d4de2 295 static status_t I2C_MasterTransferRunStateMachine(I2C_Type *base, i2c_master_handle_t *handle, bool *isDone)
<> 154:37f96f9d4de2 296 {
<> 154:37f96f9d4de2 297 status_t result = kStatus_Success;
<> 154:37f96f9d4de2 298 uint32_t statusFlags = base->S;
<> 154:37f96f9d4de2 299 *isDone = false;
<> 154:37f96f9d4de2 300 volatile uint8_t dummy = 0;
<> 154:37f96f9d4de2 301 bool ignoreNak = ((handle->state == kSendDataState) && (handle->transfer.dataSize == 0U)) ||
<> 154:37f96f9d4de2 302 ((handle->state == kReceiveDataState) && (handle->transfer.dataSize == 1U));
<> 154:37f96f9d4de2 303
<> 154:37f96f9d4de2 304 /* Add this to avoid build warning. */
<> 154:37f96f9d4de2 305 dummy++;
<> 154:37f96f9d4de2 306
<> 154:37f96f9d4de2 307 /* Check & clear error flags. */
<> 154:37f96f9d4de2 308 result = I2C_CheckAndClearError(base, statusFlags);
<> 154:37f96f9d4de2 309
<> 154:37f96f9d4de2 310 /* Ignore Nak when it's appeared for last byte. */
<> 154:37f96f9d4de2 311 if ((result == kStatus_I2C_Nak) && ignoreNak)
<> 154:37f96f9d4de2 312 {
<> 154:37f96f9d4de2 313 result = kStatus_Success;
<> 154:37f96f9d4de2 314 }
<> 154:37f96f9d4de2 315
<> 154:37f96f9d4de2 316 /* Handle Check address state to check the slave address is Acked in slave
<> 154:37f96f9d4de2 317 probe application. */
<> 154:37f96f9d4de2 318 if (handle->state == kCheckAddressState)
<> 154:37f96f9d4de2 319 {
<> 154:37f96f9d4de2 320 if (statusFlags & kI2C_ReceiveNakFlag)
<> 154:37f96f9d4de2 321 {
<> 154:37f96f9d4de2 322 result = kStatus_I2C_Addr_Nak;
<> 154:37f96f9d4de2 323 }
<> 154:37f96f9d4de2 324 else
<> 154:37f96f9d4de2 325 {
<> 154:37f96f9d4de2 326 if (handle->transfer.subaddressSize > 0)
<> 154:37f96f9d4de2 327 {
<> 154:37f96f9d4de2 328 handle->state = kSendCommandState;
<> 154:37f96f9d4de2 329 }
<> 154:37f96f9d4de2 330 else
<> 154:37f96f9d4de2 331 {
<> 154:37f96f9d4de2 332 if (handle->transfer.direction == kI2C_Write)
<> 154:37f96f9d4de2 333 {
<> 154:37f96f9d4de2 334 /* Next state, send data. */
<> 154:37f96f9d4de2 335 handle->state = kSendDataState;
<> 154:37f96f9d4de2 336 }
<> 154:37f96f9d4de2 337 else
<> 154:37f96f9d4de2 338 {
<> 154:37f96f9d4de2 339 /* Next state, receive data begin. */
<> 154:37f96f9d4de2 340 handle->state = kReceiveDataBeginState;
<> 154:37f96f9d4de2 341 }
<> 154:37f96f9d4de2 342 }
<> 154:37f96f9d4de2 343 }
<> 154:37f96f9d4de2 344 }
<> 154:37f96f9d4de2 345
<> 154:37f96f9d4de2 346 if (result)
<> 154:37f96f9d4de2 347 {
<> 154:37f96f9d4de2 348 return result;
<> 154:37f96f9d4de2 349 }
<> 154:37f96f9d4de2 350
<> 154:37f96f9d4de2 351 /* Run state machine. */
<> 154:37f96f9d4de2 352 switch (handle->state)
<> 154:37f96f9d4de2 353 {
<> 154:37f96f9d4de2 354 /* Send I2C command. */
<> 154:37f96f9d4de2 355 case kSendCommandState:
<> 154:37f96f9d4de2 356 if (handle->transfer.subaddressSize)
<> 154:37f96f9d4de2 357 {
<> 154:37f96f9d4de2 358 handle->transfer.subaddressSize--;
<> 154:37f96f9d4de2 359 base->D = ((handle->transfer.subaddress) >> (8 * handle->transfer.subaddressSize));
<> 154:37f96f9d4de2 360 }
<> 154:37f96f9d4de2 361 else
<> 154:37f96f9d4de2 362 {
<> 154:37f96f9d4de2 363 if (handle->transfer.direction == kI2C_Write)
<> 154:37f96f9d4de2 364 {
<> 154:37f96f9d4de2 365 /* Next state, send data. */
<> 154:37f96f9d4de2 366 handle->state = kSendDataState;
<> 154:37f96f9d4de2 367
<> 154:37f96f9d4de2 368 /* Send first byte of data. */
<> 154:37f96f9d4de2 369 if (handle->transfer.dataSize > 0)
<> 154:37f96f9d4de2 370 {
<> 154:37f96f9d4de2 371 base->D = *handle->transfer.data;
<> 154:37f96f9d4de2 372 handle->transfer.data++;
<> 154:37f96f9d4de2 373 handle->transfer.dataSize--;
<> 154:37f96f9d4de2 374 }
<> 154:37f96f9d4de2 375 }
<> 154:37f96f9d4de2 376 else
<> 154:37f96f9d4de2 377 {
<> 154:37f96f9d4de2 378 /* Send repeated start and slave address. */
<> 154:37f96f9d4de2 379 result = I2C_MasterRepeatedStart(base, handle->transfer.slaveAddress, kI2C_Read);
<> 154:37f96f9d4de2 380
<> 154:37f96f9d4de2 381 /* Next state, receive data begin. */
<> 154:37f96f9d4de2 382 handle->state = kReceiveDataBeginState;
<> 154:37f96f9d4de2 383 }
<> 154:37f96f9d4de2 384 }
<> 154:37f96f9d4de2 385 break;
<> 154:37f96f9d4de2 386
<> 154:37f96f9d4de2 387 /* Send I2C data. */
<> 154:37f96f9d4de2 388 case kSendDataState:
<> 154:37f96f9d4de2 389 /* Send one byte of data. */
<> 154:37f96f9d4de2 390 if (handle->transfer.dataSize > 0)
<> 154:37f96f9d4de2 391 {
<> 154:37f96f9d4de2 392 base->D = *handle->transfer.data;
<> 154:37f96f9d4de2 393 handle->transfer.data++;
<> 154:37f96f9d4de2 394 handle->transfer.dataSize--;
<> 154:37f96f9d4de2 395 }
<> 154:37f96f9d4de2 396 else
<> 154:37f96f9d4de2 397 {
<> 154:37f96f9d4de2 398 *isDone = true;
<> 154:37f96f9d4de2 399 }
<> 154:37f96f9d4de2 400 break;
<> 154:37f96f9d4de2 401
<> 154:37f96f9d4de2 402 /* Start I2C data receive. */
<> 154:37f96f9d4de2 403 case kReceiveDataBeginState:
<> 154:37f96f9d4de2 404 base->C1 &= ~(I2C_C1_TX_MASK | I2C_C1_TXAK_MASK);
<> 154:37f96f9d4de2 405
<> 154:37f96f9d4de2 406 /* Send nak at the last receive byte. */
<> 154:37f96f9d4de2 407 if (handle->transfer.dataSize == 1)
<> 154:37f96f9d4de2 408 {
<> 154:37f96f9d4de2 409 base->C1 |= I2C_C1_TXAK_MASK;
<> 154:37f96f9d4de2 410 }
<> 154:37f96f9d4de2 411
<> 154:37f96f9d4de2 412 /* Read dummy to release the bus. */
<> 154:37f96f9d4de2 413 dummy = base->D;
<> 154:37f96f9d4de2 414
<> 154:37f96f9d4de2 415 /* Next state, receive data. */
<> 154:37f96f9d4de2 416 handle->state = kReceiveDataState;
<> 154:37f96f9d4de2 417 break;
<> 154:37f96f9d4de2 418
<> 154:37f96f9d4de2 419 /* Receive I2C data. */
<> 154:37f96f9d4de2 420 case kReceiveDataState:
<> 154:37f96f9d4de2 421 /* Receive one byte of data. */
<> 154:37f96f9d4de2 422 if (handle->transfer.dataSize--)
<> 154:37f96f9d4de2 423 {
<> 154:37f96f9d4de2 424 if (handle->transfer.dataSize == 0)
<> 154:37f96f9d4de2 425 {
<> 154:37f96f9d4de2 426 *isDone = true;
<> 154:37f96f9d4de2 427
<> 154:37f96f9d4de2 428 /* Send stop if kI2C_TransferNoStop is not asserted. */
<> 154:37f96f9d4de2 429 if (!(handle->transfer.flags & kI2C_TransferNoStopFlag))
<> 154:37f96f9d4de2 430 {
<> 154:37f96f9d4de2 431 result = I2C_MasterStop(base);
<> 154:37f96f9d4de2 432 }
<> 154:37f96f9d4de2 433 else
<> 154:37f96f9d4de2 434 {
<> 154:37f96f9d4de2 435 base->C1 |= I2C_C1_TX_MASK;
<> 154:37f96f9d4de2 436 }
<> 154:37f96f9d4de2 437 }
<> 154:37f96f9d4de2 438
<> 154:37f96f9d4de2 439 /* Send NAK at the last receive byte. */
<> 154:37f96f9d4de2 440 if (handle->transfer.dataSize == 1)
<> 154:37f96f9d4de2 441 {
<> 154:37f96f9d4de2 442 base->C1 |= I2C_C1_TXAK_MASK;
<> 154:37f96f9d4de2 443 }
<> 154:37f96f9d4de2 444
<> 154:37f96f9d4de2 445 /* Read the data byte into the transfer buffer. */
<> 154:37f96f9d4de2 446 *handle->transfer.data = base->D;
<> 154:37f96f9d4de2 447 handle->transfer.data++;
<> 154:37f96f9d4de2 448 }
<> 154:37f96f9d4de2 449 break;
<> 154:37f96f9d4de2 450
<> 154:37f96f9d4de2 451 default:
<> 154:37f96f9d4de2 452 break;
<> 154:37f96f9d4de2 453 }
<> 154:37f96f9d4de2 454
<> 154:37f96f9d4de2 455 return result;
<> 154:37f96f9d4de2 456 }
<> 154:37f96f9d4de2 457
<> 154:37f96f9d4de2 458 static void I2C_TransferCommonIRQHandler(I2C_Type *base, void *handle)
<> 154:37f96f9d4de2 459 {
<> 154:37f96f9d4de2 460 /* Check if master interrupt. */
<> 154:37f96f9d4de2 461 if ((base->S & kI2C_ArbitrationLostFlag) || (base->C1 & I2C_C1_MST_MASK))
<> 154:37f96f9d4de2 462 {
<> 154:37f96f9d4de2 463 s_i2cMasterIsr(base, handle);
<> 154:37f96f9d4de2 464 }
<> 154:37f96f9d4de2 465 else
<> 154:37f96f9d4de2 466 {
<> 154:37f96f9d4de2 467 s_i2cSlaveIsr(base, handle);
<> 154:37f96f9d4de2 468 }
<> 154:37f96f9d4de2 469 __DSB();
<> 154:37f96f9d4de2 470 }
<> 154:37f96f9d4de2 471
<> 154:37f96f9d4de2 472 void I2C_MasterInit(I2C_Type *base, const i2c_master_config_t *masterConfig, uint32_t srcClock_Hz)
<> 154:37f96f9d4de2 473 {
<> 154:37f96f9d4de2 474 assert(masterConfig && srcClock_Hz);
<> 154:37f96f9d4de2 475
<> 154:37f96f9d4de2 476 /* Temporary register for filter read. */
<> 154:37f96f9d4de2 477 uint8_t fltReg;
<> 154:37f96f9d4de2 478 #if defined(FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION) && FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION
<> 154:37f96f9d4de2 479 uint8_t c2Reg;
<> 154:37f96f9d4de2 480 #endif
<> 154:37f96f9d4de2 481 #if defined(FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE) && FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE
<> 154:37f96f9d4de2 482 uint8_t s2Reg;
<> 154:37f96f9d4de2 483 #endif
<> 154:37f96f9d4de2 484 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
<> 154:37f96f9d4de2 485 /* Enable I2C clock. */
<> 154:37f96f9d4de2 486 CLOCK_EnableClock(s_i2cClocks[I2C_GetInstance(base)]);
<> 154:37f96f9d4de2 487 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
<> 154:37f96f9d4de2 488
<> 154:37f96f9d4de2 489 /* Disable I2C prior to configuring it. */
<> 154:37f96f9d4de2 490 base->C1 &= ~(I2C_C1_IICEN_MASK);
<> 154:37f96f9d4de2 491
<> 154:37f96f9d4de2 492 /* Clear all flags. */
<> 154:37f96f9d4de2 493 I2C_MasterClearStatusFlags(base, kClearFlags);
<> 154:37f96f9d4de2 494
<> 154:37f96f9d4de2 495 /* Configure baud rate. */
<> 154:37f96f9d4de2 496 I2C_MasterSetBaudRate(base, masterConfig->baudRate_Bps, srcClock_Hz);
<> 154:37f96f9d4de2 497
<> 154:37f96f9d4de2 498 #if defined(FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION) && FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION
<> 154:37f96f9d4de2 499 /* Configure high drive feature. */
<> 154:37f96f9d4de2 500 c2Reg = base->C2;
<> 154:37f96f9d4de2 501 c2Reg &= ~(I2C_C2_HDRS_MASK);
<> 154:37f96f9d4de2 502 c2Reg |= I2C_C2_HDRS(masterConfig->enableHighDrive);
<> 154:37f96f9d4de2 503 base->C2 = c2Reg;
<> 154:37f96f9d4de2 504 #endif
<> 154:37f96f9d4de2 505
<> 154:37f96f9d4de2 506 /* Read out the FLT register. */
<> 154:37f96f9d4de2 507 fltReg = base->FLT;
<> 154:37f96f9d4de2 508
<> 154:37f96f9d4de2 509 #if defined(FSL_FEATURE_I2C_HAS_STOP_HOLD_OFF) && FSL_FEATURE_I2C_HAS_STOP_HOLD_OFF
<> 154:37f96f9d4de2 510 /* Configure the stop / hold enable. */
<> 154:37f96f9d4de2 511 fltReg &= ~(I2C_FLT_SHEN_MASK);
<> 154:37f96f9d4de2 512 fltReg |= I2C_FLT_SHEN(masterConfig->enableStopHold);
<> 154:37f96f9d4de2 513 #endif
<> 154:37f96f9d4de2 514
<> 154:37f96f9d4de2 515 /* Configure the glitch filter value. */
<> 154:37f96f9d4de2 516 fltReg &= ~(I2C_FLT_FLT_MASK);
<> 154:37f96f9d4de2 517 fltReg |= I2C_FLT_FLT(masterConfig->glitchFilterWidth);
<> 154:37f96f9d4de2 518
<> 154:37f96f9d4de2 519 /* Write the register value back to the filter register. */
<> 154:37f96f9d4de2 520 base->FLT = fltReg;
<> 154:37f96f9d4de2 521
<> 154:37f96f9d4de2 522 /* Enable/Disable double buffering. */
<> 154:37f96f9d4de2 523 #if defined(FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE) && FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE
<> 154:37f96f9d4de2 524 s2Reg = base->S2 & (~I2C_S2_DFEN_MASK);
<> 154:37f96f9d4de2 525 base->S2 = s2Reg | I2C_S2_DFEN(masterConfig->enableDoubleBuffering);
<> 154:37f96f9d4de2 526 #endif
<> 154:37f96f9d4de2 527
<> 154:37f96f9d4de2 528 /* Enable the I2C peripheral based on the configuration. */
<> 154:37f96f9d4de2 529 base->C1 = I2C_C1_IICEN(masterConfig->enableMaster);
<> 154:37f96f9d4de2 530 }
<> 154:37f96f9d4de2 531
<> 154:37f96f9d4de2 532 void I2C_MasterDeinit(I2C_Type *base)
<> 154:37f96f9d4de2 533 {
<> 154:37f96f9d4de2 534 /* Disable I2C module. */
<> 154:37f96f9d4de2 535 I2C_Enable(base, false);
<> 154:37f96f9d4de2 536
<> 154:37f96f9d4de2 537 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
<> 154:37f96f9d4de2 538 /* Disable I2C clock. */
<> 154:37f96f9d4de2 539 CLOCK_DisableClock(s_i2cClocks[I2C_GetInstance(base)]);
<> 154:37f96f9d4de2 540 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
<> 154:37f96f9d4de2 541 }
<> 154:37f96f9d4de2 542
<> 154:37f96f9d4de2 543 void I2C_MasterGetDefaultConfig(i2c_master_config_t *masterConfig)
<> 154:37f96f9d4de2 544 {
<> 154:37f96f9d4de2 545 assert(masterConfig);
<> 154:37f96f9d4de2 546
<> 154:37f96f9d4de2 547 /* Default baud rate at 100kbps. */
<> 154:37f96f9d4de2 548 masterConfig->baudRate_Bps = 100000U;
<> 154:37f96f9d4de2 549
<> 154:37f96f9d4de2 550 /* Default pin high drive is disabled. */
<> 154:37f96f9d4de2 551 #if defined(FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION) && FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION
<> 154:37f96f9d4de2 552 masterConfig->enableHighDrive = false;
<> 154:37f96f9d4de2 553 #endif
<> 154:37f96f9d4de2 554
<> 154:37f96f9d4de2 555 /* Default stop hold enable is disabled. */
<> 154:37f96f9d4de2 556 #if defined(FSL_FEATURE_I2C_HAS_STOP_HOLD_OFF) && FSL_FEATURE_I2C_HAS_STOP_HOLD_OFF
<> 154:37f96f9d4de2 557 masterConfig->enableStopHold = false;
<> 154:37f96f9d4de2 558 #endif
<> 154:37f96f9d4de2 559
<> 154:37f96f9d4de2 560 /* Default glitch filter value is no filter. */
<> 154:37f96f9d4de2 561 masterConfig->glitchFilterWidth = 0U;
<> 154:37f96f9d4de2 562
<> 154:37f96f9d4de2 563 /* Default enable double buffering. */
<> 154:37f96f9d4de2 564 #if defined(FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE) && FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE
<> 154:37f96f9d4de2 565 masterConfig->enableDoubleBuffering = true;
<> 154:37f96f9d4de2 566 #endif
<> 154:37f96f9d4de2 567
<> 154:37f96f9d4de2 568 /* Enable the I2C peripheral. */
<> 154:37f96f9d4de2 569 masterConfig->enableMaster = true;
<> 154:37f96f9d4de2 570 }
<> 154:37f96f9d4de2 571
<> 154:37f96f9d4de2 572 void I2C_EnableInterrupts(I2C_Type *base, uint32_t mask)
<> 154:37f96f9d4de2 573 {
<> 154:37f96f9d4de2 574 #ifdef I2C_HAS_STOP_DETECT
<> 154:37f96f9d4de2 575 uint8_t fltReg;
<> 154:37f96f9d4de2 576 #endif
<> 154:37f96f9d4de2 577
<> 154:37f96f9d4de2 578 if (mask & kI2C_GlobalInterruptEnable)
<> 154:37f96f9d4de2 579 {
<> 154:37f96f9d4de2 580 base->C1 |= I2C_C1_IICIE_MASK;
<> 154:37f96f9d4de2 581 }
<> 154:37f96f9d4de2 582
<> 154:37f96f9d4de2 583 #if defined(FSL_FEATURE_I2C_HAS_STOP_DETECT) && FSL_FEATURE_I2C_HAS_STOP_DETECT
<> 154:37f96f9d4de2 584 if (mask & kI2C_StopDetectInterruptEnable)
<> 154:37f96f9d4de2 585 {
<> 154:37f96f9d4de2 586 fltReg = base->FLT;
<> 154:37f96f9d4de2 587
<> 154:37f96f9d4de2 588 /* Keep STOPF flag. */
<> 154:37f96f9d4de2 589 fltReg &= ~I2C_FLT_STOPF_MASK;
<> 154:37f96f9d4de2 590
<> 154:37f96f9d4de2 591 /* Stop detect enable. */
<> 154:37f96f9d4de2 592 fltReg |= I2C_FLT_STOPIE_MASK;
<> 154:37f96f9d4de2 593 base->FLT = fltReg;
<> 154:37f96f9d4de2 594 }
<> 154:37f96f9d4de2 595 #endif /* FSL_FEATURE_I2C_HAS_STOP_DETECT */
<> 154:37f96f9d4de2 596
<> 154:37f96f9d4de2 597 #if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT
<> 154:37f96f9d4de2 598 if (mask & kI2C_StartStopDetectInterruptEnable)
<> 154:37f96f9d4de2 599 {
<> 154:37f96f9d4de2 600 fltReg = base->FLT;
<> 154:37f96f9d4de2 601
<> 154:37f96f9d4de2 602 /* Keep STARTF and STOPF flags. */
<> 154:37f96f9d4de2 603 fltReg &= ~(I2C_FLT_STOPF_MASK | I2C_FLT_STARTF_MASK);
<> 154:37f96f9d4de2 604
<> 154:37f96f9d4de2 605 /* Start and stop detect enable. */
<> 154:37f96f9d4de2 606 fltReg |= I2C_FLT_SSIE_MASK;
<> 154:37f96f9d4de2 607 base->FLT = fltReg;
<> 154:37f96f9d4de2 608 }
<> 154:37f96f9d4de2 609 #endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT */
<> 154:37f96f9d4de2 610 }
<> 154:37f96f9d4de2 611
<> 154:37f96f9d4de2 612 void I2C_DisableInterrupts(I2C_Type *base, uint32_t mask)
<> 154:37f96f9d4de2 613 {
<> 154:37f96f9d4de2 614 if (mask & kI2C_GlobalInterruptEnable)
<> 154:37f96f9d4de2 615 {
<> 154:37f96f9d4de2 616 base->C1 &= ~I2C_C1_IICIE_MASK;
<> 154:37f96f9d4de2 617 }
<> 154:37f96f9d4de2 618
<> 154:37f96f9d4de2 619 #if defined(FSL_FEATURE_I2C_HAS_STOP_DETECT) && FSL_FEATURE_I2C_HAS_STOP_DETECT
<> 154:37f96f9d4de2 620 if (mask & kI2C_StopDetectInterruptEnable)
<> 154:37f96f9d4de2 621 {
<> 154:37f96f9d4de2 622 base->FLT &= ~(I2C_FLT_STOPIE_MASK | I2C_FLT_STOPF_MASK);
<> 154:37f96f9d4de2 623 }
<> 154:37f96f9d4de2 624 #endif /* FSL_FEATURE_I2C_HAS_STOP_DETECT */
<> 154:37f96f9d4de2 625
<> 154:37f96f9d4de2 626 #if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT
<> 154:37f96f9d4de2 627 if (mask & kI2C_StartStopDetectInterruptEnable)
<> 154:37f96f9d4de2 628 {
<> 154:37f96f9d4de2 629 base->FLT &= ~(I2C_FLT_SSIE_MASK | I2C_FLT_STOPF_MASK | I2C_FLT_STARTF_MASK);
<> 154:37f96f9d4de2 630 }
<> 154:37f96f9d4de2 631 #endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT */
<> 154:37f96f9d4de2 632 }
<> 154:37f96f9d4de2 633
<> 154:37f96f9d4de2 634 void I2C_MasterSetBaudRate(I2C_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz)
<> 154:37f96f9d4de2 635 {
<> 154:37f96f9d4de2 636 uint32_t multiplier;
<> 154:37f96f9d4de2 637 uint32_t computedRate;
<> 154:37f96f9d4de2 638 uint32_t absError;
<> 154:37f96f9d4de2 639 uint32_t bestError = UINT32_MAX;
<> 154:37f96f9d4de2 640 uint32_t bestMult = 0u;
<> 154:37f96f9d4de2 641 uint32_t bestIcr = 0u;
<> 154:37f96f9d4de2 642 uint8_t mult;
<> 154:37f96f9d4de2 643 uint8_t i;
<> 154:37f96f9d4de2 644
<> 154:37f96f9d4de2 645 /* Search for the settings with the lowest error. Mult is the MULT field of the I2C_F register,
<> 154:37f96f9d4de2 646 * and ranges from 0-2. It selects the multiplier factor for the divider. */
<> 154:37f96f9d4de2 647 for (mult = 0u; (mult <= 2u) && (bestError != 0); ++mult)
<> 154:37f96f9d4de2 648 {
<> 154:37f96f9d4de2 649 multiplier = 1u << mult;
<> 154:37f96f9d4de2 650
<> 154:37f96f9d4de2 651 /* Scan table to find best match. */
<> 154:37f96f9d4de2 652 for (i = 0u; i < sizeof(s_i2cDividerTable) / sizeof(uint16_t); ++i)
<> 154:37f96f9d4de2 653 {
<> 154:37f96f9d4de2 654 computedRate = srcClock_Hz / (multiplier * s_i2cDividerTable[i]);
<> 154:37f96f9d4de2 655 absError = baudRate_Bps > computedRate ? (baudRate_Bps - computedRate) : (computedRate - baudRate_Bps);
<> 154:37f96f9d4de2 656
<> 154:37f96f9d4de2 657 if (absError < bestError)
<> 154:37f96f9d4de2 658 {
<> 154:37f96f9d4de2 659 bestMult = mult;
<> 154:37f96f9d4de2 660 bestIcr = i;
<> 154:37f96f9d4de2 661 bestError = absError;
<> 154:37f96f9d4de2 662
<> 154:37f96f9d4de2 663 /* If the error is 0, then we can stop searching because we won't find a better match. */
<> 154:37f96f9d4de2 664 if (absError == 0)
<> 154:37f96f9d4de2 665 {
<> 154:37f96f9d4de2 666 break;
<> 154:37f96f9d4de2 667 }
<> 154:37f96f9d4de2 668 }
<> 154:37f96f9d4de2 669 }
<> 154:37f96f9d4de2 670 }
<> 154:37f96f9d4de2 671
<> 154:37f96f9d4de2 672 /* Set frequency register based on best settings. */
<> 154:37f96f9d4de2 673 base->F = I2C_F_MULT(bestMult) | I2C_F_ICR(bestIcr);
<> 154:37f96f9d4de2 674 }
<> 154:37f96f9d4de2 675
<> 154:37f96f9d4de2 676 status_t I2C_MasterStart(I2C_Type *base, uint8_t address, i2c_direction_t direction)
<> 154:37f96f9d4de2 677 {
<> 154:37f96f9d4de2 678 status_t result = kStatus_Success;
<> 154:37f96f9d4de2 679 uint32_t statusFlags = I2C_MasterGetStatusFlags(base);
<> 154:37f96f9d4de2 680
<> 154:37f96f9d4de2 681 /* Return an error if the bus is already in use. */
<> 154:37f96f9d4de2 682 if (statusFlags & kI2C_BusBusyFlag)
<> 154:37f96f9d4de2 683 {
<> 154:37f96f9d4de2 684 result = kStatus_I2C_Busy;
<> 154:37f96f9d4de2 685 }
<> 154:37f96f9d4de2 686 else
<> 154:37f96f9d4de2 687 {
<> 154:37f96f9d4de2 688 /* Send the START signal. */
<> 154:37f96f9d4de2 689 base->C1 |= I2C_C1_MST_MASK | I2C_C1_TX_MASK;
<> 154:37f96f9d4de2 690
<> 154:37f96f9d4de2 691 #if defined(FSL_FEATURE_I2C_HAS_DOUBLE_BUFFERING) && FSL_FEATURE_I2C_HAS_DOUBLE_BUFFERING
<> 154:37f96f9d4de2 692 while (!(base->S2 & I2C_S2_EMPTY_MASK))
<> 154:37f96f9d4de2 693 {
<> 154:37f96f9d4de2 694 }
<> 154:37f96f9d4de2 695 #endif /* FSL_FEATURE_I2C_HAS_DOUBLE_BUFFERING */
<> 154:37f96f9d4de2 696
<> 154:37f96f9d4de2 697 base->D = (((uint32_t)address) << 1U | ((direction == kI2C_Read) ? 1U : 0U));
<> 154:37f96f9d4de2 698 }
<> 154:37f96f9d4de2 699
<> 154:37f96f9d4de2 700 return result;
<> 154:37f96f9d4de2 701 }
<> 154:37f96f9d4de2 702
<> 154:37f96f9d4de2 703 status_t I2C_MasterRepeatedStart(I2C_Type *base, uint8_t address, i2c_direction_t direction)
<> 154:37f96f9d4de2 704 {
<> 154:37f96f9d4de2 705 status_t result = kStatus_Success;
<> 154:37f96f9d4de2 706 uint8_t savedMult;
<> 154:37f96f9d4de2 707 uint32_t statusFlags = I2C_MasterGetStatusFlags(base);
<> 154:37f96f9d4de2 708 uint8_t timeDelay = 6;
<> 154:37f96f9d4de2 709
<> 154:37f96f9d4de2 710 /* Return an error if the bus is already in use, but not by us. */
<> 154:37f96f9d4de2 711 if ((statusFlags & kI2C_BusBusyFlag) && ((base->C1 & I2C_C1_MST_MASK) == 0))
<> 154:37f96f9d4de2 712 {
<> 154:37f96f9d4de2 713 result = kStatus_I2C_Busy;
<> 154:37f96f9d4de2 714 }
<> 154:37f96f9d4de2 715 else
<> 154:37f96f9d4de2 716 {
<> 154:37f96f9d4de2 717 savedMult = base->F;
<> 154:37f96f9d4de2 718 base->F = savedMult & (~I2C_F_MULT_MASK);
<> 154:37f96f9d4de2 719
<> 154:37f96f9d4de2 720 /* We are already in a transfer, so send a repeated start. */
<> 154:37f96f9d4de2 721 base->C1 |= I2C_C1_RSTA_MASK | I2C_C1_TX_MASK;
<> 154:37f96f9d4de2 722
<> 154:37f96f9d4de2 723 /* Restore the multiplier factor. */
<> 154:37f96f9d4de2 724 base->F = savedMult;
<> 154:37f96f9d4de2 725
<> 154:37f96f9d4de2 726 /* Add some delay to wait the Re-Start signal. */
<> 154:37f96f9d4de2 727 while (timeDelay--)
<> 154:37f96f9d4de2 728 {
<> 154:37f96f9d4de2 729 __NOP();
<> 154:37f96f9d4de2 730 }
<> 154:37f96f9d4de2 731
<> 154:37f96f9d4de2 732 #if defined(FSL_FEATURE_I2C_HAS_DOUBLE_BUFFERING) && FSL_FEATURE_I2C_HAS_DOUBLE_BUFFERING
<> 154:37f96f9d4de2 733 while (!(base->S2 & I2C_S2_EMPTY_MASK))
<> 154:37f96f9d4de2 734 {
<> 154:37f96f9d4de2 735 }
<> 154:37f96f9d4de2 736 #endif /* FSL_FEATURE_I2C_HAS_DOUBLE_BUFFERING */
<> 154:37f96f9d4de2 737
<> 154:37f96f9d4de2 738 base->D = (((uint32_t)address) << 1U | ((direction == kI2C_Read) ? 1U : 0U));
<> 154:37f96f9d4de2 739 }
<> 154:37f96f9d4de2 740
<> 154:37f96f9d4de2 741 return result;
<> 154:37f96f9d4de2 742 }
<> 154:37f96f9d4de2 743
<> 154:37f96f9d4de2 744 status_t I2C_MasterStop(I2C_Type *base)
<> 154:37f96f9d4de2 745 {
<> 154:37f96f9d4de2 746 status_t result = kStatus_Success;
<> 154:37f96f9d4de2 747 uint16_t timeout = UINT16_MAX;
<> 154:37f96f9d4de2 748
<> 154:37f96f9d4de2 749 /* Issue the STOP command on the bus. */
<> 154:37f96f9d4de2 750 base->C1 &= ~(I2C_C1_MST_MASK | I2C_C1_TX_MASK | I2C_C1_TXAK_MASK);
<> 154:37f96f9d4de2 751
<> 154:37f96f9d4de2 752 /* Wait until data transfer complete. */
<> 154:37f96f9d4de2 753 while ((base->S & kI2C_BusBusyFlag) && (--timeout))
<> 154:37f96f9d4de2 754 {
<> 154:37f96f9d4de2 755 }
<> 154:37f96f9d4de2 756
<> 154:37f96f9d4de2 757 if (timeout == 0)
<> 154:37f96f9d4de2 758 {
<> 154:37f96f9d4de2 759 result = kStatus_I2C_Timeout;
<> 154:37f96f9d4de2 760 }
<> 154:37f96f9d4de2 761
<> 154:37f96f9d4de2 762 return result;
<> 154:37f96f9d4de2 763 }
<> 154:37f96f9d4de2 764
<> 154:37f96f9d4de2 765 uint32_t I2C_MasterGetStatusFlags(I2C_Type *base)
<> 154:37f96f9d4de2 766 {
<> 154:37f96f9d4de2 767 uint32_t statusFlags = base->S;
<> 154:37f96f9d4de2 768
<> 154:37f96f9d4de2 769 #ifdef I2C_HAS_STOP_DETECT
<> 154:37f96f9d4de2 770 /* Look up the STOPF bit from the filter register. */
<> 154:37f96f9d4de2 771 if (base->FLT & I2C_FLT_STOPF_MASK)
<> 154:37f96f9d4de2 772 {
<> 154:37f96f9d4de2 773 statusFlags |= kI2C_StopDetectFlag;
<> 154:37f96f9d4de2 774 }
<> 154:37f96f9d4de2 775 #endif
<> 154:37f96f9d4de2 776
<> 154:37f96f9d4de2 777 #if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT
<> 154:37f96f9d4de2 778 /* Look up the STARTF bit from the filter register. */
<> 154:37f96f9d4de2 779 if (base->FLT & I2C_FLT_STARTF_MASK)
<> 154:37f96f9d4de2 780 {
<> 154:37f96f9d4de2 781 statusFlags |= kI2C_StartDetectFlag;
<> 154:37f96f9d4de2 782 }
<> 154:37f96f9d4de2 783 #endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT */
<> 154:37f96f9d4de2 784
<> 154:37f96f9d4de2 785 return statusFlags;
<> 154:37f96f9d4de2 786 }
<> 154:37f96f9d4de2 787
<> 154:37f96f9d4de2 788 status_t I2C_MasterWriteBlocking(I2C_Type *base, const uint8_t *txBuff, size_t txSize, uint32_t flags)
<> 154:37f96f9d4de2 789 {
<> 154:37f96f9d4de2 790 status_t result = kStatus_Success;
<> 154:37f96f9d4de2 791 uint8_t statusFlags = 0;
<> 154:37f96f9d4de2 792
<> 154:37f96f9d4de2 793 /* Wait until the data register is ready for transmit. */
<> 154:37f96f9d4de2 794 while (!(base->S & kI2C_TransferCompleteFlag))
<> 154:37f96f9d4de2 795 {
<> 154:37f96f9d4de2 796 }
<> 154:37f96f9d4de2 797
<> 154:37f96f9d4de2 798 /* Clear the IICIF flag. */
<> 154:37f96f9d4de2 799 base->S = kI2C_IntPendingFlag;
<> 154:37f96f9d4de2 800
<> 154:37f96f9d4de2 801 /* Setup the I2C peripheral to transmit data. */
<> 154:37f96f9d4de2 802 base->C1 |= I2C_C1_TX_MASK;
<> 154:37f96f9d4de2 803
<> 154:37f96f9d4de2 804 while (txSize--)
<> 154:37f96f9d4de2 805 {
<> 154:37f96f9d4de2 806 /* Send a byte of data. */
<> 154:37f96f9d4de2 807 base->D = *txBuff++;
<> 154:37f96f9d4de2 808
<> 154:37f96f9d4de2 809 /* Wait until data transfer complete. */
<> 154:37f96f9d4de2 810 while (!(base->S & kI2C_IntPendingFlag))
<> 154:37f96f9d4de2 811 {
<> 154:37f96f9d4de2 812 }
<> 154:37f96f9d4de2 813
<> 154:37f96f9d4de2 814 statusFlags = base->S;
<> 154:37f96f9d4de2 815
<> 154:37f96f9d4de2 816 /* Clear the IICIF flag. */
<> 154:37f96f9d4de2 817 base->S = kI2C_IntPendingFlag;
<> 154:37f96f9d4de2 818
<> 154:37f96f9d4de2 819 /* Check if arbitration lost or no acknowledgement (NAK), return failure status. */
<> 154:37f96f9d4de2 820 if (statusFlags & kI2C_ArbitrationLostFlag)
<> 154:37f96f9d4de2 821 {
<> 154:37f96f9d4de2 822 base->S = kI2C_ArbitrationLostFlag;
<> 154:37f96f9d4de2 823 result = kStatus_I2C_ArbitrationLost;
<> 154:37f96f9d4de2 824 }
<> 154:37f96f9d4de2 825
<> 154:37f96f9d4de2 826 if ((statusFlags & kI2C_ReceiveNakFlag) && txSize)
<> 154:37f96f9d4de2 827 {
<> 154:37f96f9d4de2 828 base->S = kI2C_ReceiveNakFlag;
<> 154:37f96f9d4de2 829 result = kStatus_I2C_Nak;
<> 154:37f96f9d4de2 830 }
<> 154:37f96f9d4de2 831
<> 154:37f96f9d4de2 832 if (result != kStatus_Success)
<> 154:37f96f9d4de2 833 {
<> 154:37f96f9d4de2 834 /* Breaking out of the send loop. */
<> 154:37f96f9d4de2 835 break;
<> 154:37f96f9d4de2 836 }
<> 154:37f96f9d4de2 837 }
<> 154:37f96f9d4de2 838
<> 154:37f96f9d4de2 839 if (((result == kStatus_Success) && (!(flags & kI2C_TransferNoStopFlag))) || (result == kStatus_I2C_Nak))
<> 154:37f96f9d4de2 840 {
<> 154:37f96f9d4de2 841 /* Clear the IICIF flag. */
<> 154:37f96f9d4de2 842 base->S = kI2C_IntPendingFlag;
<> 154:37f96f9d4de2 843
<> 154:37f96f9d4de2 844 /* Send stop. */
<> 154:37f96f9d4de2 845 result = I2C_MasterStop(base);
<> 154:37f96f9d4de2 846 }
<> 154:37f96f9d4de2 847
<> 154:37f96f9d4de2 848 return result;
<> 154:37f96f9d4de2 849 }
<> 154:37f96f9d4de2 850
<> 154:37f96f9d4de2 851 status_t I2C_MasterReadBlocking(I2C_Type *base, uint8_t *rxBuff, size_t rxSize, uint32_t flags)
<> 154:37f96f9d4de2 852 {
<> 154:37f96f9d4de2 853 status_t result = kStatus_Success;
<> 154:37f96f9d4de2 854 volatile uint8_t dummy = 0;
<> 154:37f96f9d4de2 855
<> 154:37f96f9d4de2 856 /* Add this to avoid build warning. */
<> 154:37f96f9d4de2 857 dummy++;
<> 154:37f96f9d4de2 858
<> 154:37f96f9d4de2 859 /* Wait until the data register is ready for transmit. */
<> 154:37f96f9d4de2 860 while (!(base->S & kI2C_TransferCompleteFlag))
<> 154:37f96f9d4de2 861 {
<> 154:37f96f9d4de2 862 }
<> 154:37f96f9d4de2 863
<> 154:37f96f9d4de2 864 /* Clear the IICIF flag. */
<> 154:37f96f9d4de2 865 base->S = kI2C_IntPendingFlag;
<> 154:37f96f9d4de2 866
<> 154:37f96f9d4de2 867 /* Setup the I2C peripheral to receive data. */
<> 154:37f96f9d4de2 868 base->C1 &= ~(I2C_C1_TX_MASK | I2C_C1_TXAK_MASK);
<> 154:37f96f9d4de2 869
<> 154:37f96f9d4de2 870 /* If rxSize equals 1, configure to send NAK. */
<> 154:37f96f9d4de2 871 if (rxSize == 1)
<> 154:37f96f9d4de2 872 {
<> 154:37f96f9d4de2 873 /* Issue NACK on read. */
<> 154:37f96f9d4de2 874 base->C1 |= I2C_C1_TXAK_MASK;
<> 154:37f96f9d4de2 875 }
<> 154:37f96f9d4de2 876
<> 154:37f96f9d4de2 877 /* Do dummy read. */
<> 154:37f96f9d4de2 878 dummy = base->D;
<> 154:37f96f9d4de2 879
<> 154:37f96f9d4de2 880 while ((rxSize--))
<> 154:37f96f9d4de2 881 {
<> 154:37f96f9d4de2 882 /* Wait until data transfer complete. */
<> 154:37f96f9d4de2 883 while (!(base->S & kI2C_IntPendingFlag))
<> 154:37f96f9d4de2 884 {
<> 154:37f96f9d4de2 885 }
<> 154:37f96f9d4de2 886
<> 154:37f96f9d4de2 887 /* Clear the IICIF flag. */
<> 154:37f96f9d4de2 888 base->S = kI2C_IntPendingFlag;
<> 154:37f96f9d4de2 889
<> 154:37f96f9d4de2 890 /* Single byte use case. */
<> 154:37f96f9d4de2 891 if (rxSize == 0)
<> 154:37f96f9d4de2 892 {
<> 154:37f96f9d4de2 893 if (!(flags & kI2C_TransferNoStopFlag))
<> 154:37f96f9d4de2 894 {
<> 154:37f96f9d4de2 895 /* Issue STOP command before reading last byte. */
<> 154:37f96f9d4de2 896 result = I2C_MasterStop(base);
<> 154:37f96f9d4de2 897 }
<> 154:37f96f9d4de2 898 else
<> 154:37f96f9d4de2 899 {
<> 154:37f96f9d4de2 900 /* Change direction to Tx to avoid extra clocks. */
<> 154:37f96f9d4de2 901 base->C1 |= I2C_C1_TX_MASK;
<> 154:37f96f9d4de2 902 }
<> 154:37f96f9d4de2 903 }
<> 154:37f96f9d4de2 904
<> 154:37f96f9d4de2 905 if (rxSize == 1)
<> 154:37f96f9d4de2 906 {
<> 154:37f96f9d4de2 907 /* Issue NACK on read. */
<> 154:37f96f9d4de2 908 base->C1 |= I2C_C1_TXAK_MASK;
<> 154:37f96f9d4de2 909 }
<> 154:37f96f9d4de2 910
<> 154:37f96f9d4de2 911 /* Read from the data register. */
<> 154:37f96f9d4de2 912 *rxBuff++ = base->D;
<> 154:37f96f9d4de2 913 }
<> 154:37f96f9d4de2 914
<> 154:37f96f9d4de2 915 return result;
<> 154:37f96f9d4de2 916 }
<> 154:37f96f9d4de2 917
<> 154:37f96f9d4de2 918 status_t I2C_MasterTransferBlocking(I2C_Type *base, i2c_master_transfer_t *xfer)
<> 154:37f96f9d4de2 919 {
<> 154:37f96f9d4de2 920 assert(xfer);
<> 154:37f96f9d4de2 921
<> 154:37f96f9d4de2 922 i2c_direction_t direction = xfer->direction;
<> 154:37f96f9d4de2 923 status_t result = kStatus_Success;
<> 154:37f96f9d4de2 924
<> 154:37f96f9d4de2 925 /* Clear all status before transfer. */
<> 154:37f96f9d4de2 926 I2C_MasterClearStatusFlags(base, kClearFlags);
<> 154:37f96f9d4de2 927
<> 154:37f96f9d4de2 928 /* Wait until ready to complete. */
<> 154:37f96f9d4de2 929 while (!(base->S & kI2C_TransferCompleteFlag))
<> 154:37f96f9d4de2 930 {
<> 154:37f96f9d4de2 931 }
<> 154:37f96f9d4de2 932
<> 154:37f96f9d4de2 933 /* Change to send write address when it's a read operation with command. */
<> 154:37f96f9d4de2 934 if ((xfer->subaddressSize > 0) && (xfer->direction == kI2C_Read))
<> 154:37f96f9d4de2 935 {
<> 154:37f96f9d4de2 936 direction = kI2C_Write;
<> 154:37f96f9d4de2 937 }
<> 154:37f96f9d4de2 938
<> 154:37f96f9d4de2 939 /* If repeated start is requested, send repeated start. */
<> 154:37f96f9d4de2 940 if (xfer->flags & kI2C_TransferRepeatedStartFlag)
<> 154:37f96f9d4de2 941 {
<> 154:37f96f9d4de2 942 result = I2C_MasterRepeatedStart(base, xfer->slaveAddress, direction);
<> 154:37f96f9d4de2 943 }
<> 154:37f96f9d4de2 944 else /* For normal transfer, send start. */
<> 154:37f96f9d4de2 945 {
<> 154:37f96f9d4de2 946 result = I2C_MasterStart(base, xfer->slaveAddress, direction);
<> 154:37f96f9d4de2 947 }
<> 154:37f96f9d4de2 948
<> 154:37f96f9d4de2 949 /* Return if error. */
<> 154:37f96f9d4de2 950 if (result)
<> 154:37f96f9d4de2 951 {
<> 154:37f96f9d4de2 952 return result;
<> 154:37f96f9d4de2 953 }
<> 154:37f96f9d4de2 954
<> 154:37f96f9d4de2 955 while (!(base->S & kI2C_IntPendingFlag))
<> 154:37f96f9d4de2 956 {
<> 154:37f96f9d4de2 957 }
<> 154:37f96f9d4de2 958
<> 154:37f96f9d4de2 959 /* Check if there's transfer error. */
<> 154:37f96f9d4de2 960 result = I2C_CheckAndClearError(base, base->S);
<> 154:37f96f9d4de2 961
<> 154:37f96f9d4de2 962 /* Return if error. */
<> 154:37f96f9d4de2 963 if (result)
<> 154:37f96f9d4de2 964 {
<> 154:37f96f9d4de2 965 if (result == kStatus_I2C_Nak)
<> 154:37f96f9d4de2 966 {
<> 154:37f96f9d4de2 967 result = kStatus_I2C_Addr_Nak;
<> 154:37f96f9d4de2 968
<> 154:37f96f9d4de2 969 I2C_MasterStop(base);
<> 154:37f96f9d4de2 970 }
<> 154:37f96f9d4de2 971
<> 154:37f96f9d4de2 972 return result;
<> 154:37f96f9d4de2 973 }
<> 154:37f96f9d4de2 974
<> 154:37f96f9d4de2 975 /* Send subaddress. */
<> 154:37f96f9d4de2 976 if (xfer->subaddressSize)
<> 154:37f96f9d4de2 977 {
<> 154:37f96f9d4de2 978 do
<> 154:37f96f9d4de2 979 {
<> 154:37f96f9d4de2 980 /* Clear interrupt pending flag. */
<> 154:37f96f9d4de2 981 base->S = kI2C_IntPendingFlag;
<> 154:37f96f9d4de2 982
<> 154:37f96f9d4de2 983 xfer->subaddressSize--;
<> 154:37f96f9d4de2 984 base->D = ((xfer->subaddress) >> (8 * xfer->subaddressSize));
<> 154:37f96f9d4de2 985
<> 154:37f96f9d4de2 986 /* Wait until data transfer complete. */
<> 154:37f96f9d4de2 987 while (!(base->S & kI2C_IntPendingFlag))
<> 154:37f96f9d4de2 988 {
<> 154:37f96f9d4de2 989 }
<> 154:37f96f9d4de2 990
<> 154:37f96f9d4de2 991 /* Check if there's transfer error. */
<> 154:37f96f9d4de2 992 result = I2C_CheckAndClearError(base, base->S);
<> 154:37f96f9d4de2 993
<> 154:37f96f9d4de2 994 if (result)
<> 154:37f96f9d4de2 995 {
<> 154:37f96f9d4de2 996 if (result == kStatus_I2C_Nak)
<> 154:37f96f9d4de2 997 {
<> 154:37f96f9d4de2 998 I2C_MasterStop(base);
<> 154:37f96f9d4de2 999 }
<> 154:37f96f9d4de2 1000
<> 154:37f96f9d4de2 1001 return result;
<> 154:37f96f9d4de2 1002 }
<> 154:37f96f9d4de2 1003
<> 154:37f96f9d4de2 1004 } while ((xfer->subaddressSize > 0) && (result == kStatus_Success));
<> 154:37f96f9d4de2 1005
<> 154:37f96f9d4de2 1006 if (xfer->direction == kI2C_Read)
<> 154:37f96f9d4de2 1007 {
<> 154:37f96f9d4de2 1008 /* Clear pending flag. */
<> 154:37f96f9d4de2 1009 base->S = kI2C_IntPendingFlag;
<> 154:37f96f9d4de2 1010
<> 154:37f96f9d4de2 1011 /* Send repeated start and slave address. */
<> 154:37f96f9d4de2 1012 result = I2C_MasterRepeatedStart(base, xfer->slaveAddress, kI2C_Read);
<> 154:37f96f9d4de2 1013
<> 154:37f96f9d4de2 1014 /* Return if error. */
<> 154:37f96f9d4de2 1015 if (result)
<> 154:37f96f9d4de2 1016 {
<> 154:37f96f9d4de2 1017 return result;
<> 154:37f96f9d4de2 1018 }
<> 154:37f96f9d4de2 1019
<> 154:37f96f9d4de2 1020 /* Wait until data transfer complete. */
<> 154:37f96f9d4de2 1021 while (!(base->S & kI2C_IntPendingFlag))
<> 154:37f96f9d4de2 1022 {
<> 154:37f96f9d4de2 1023 }
<> 154:37f96f9d4de2 1024
<> 154:37f96f9d4de2 1025 /* Check if there's transfer error. */
<> 154:37f96f9d4de2 1026 result = I2C_CheckAndClearError(base, base->S);
<> 154:37f96f9d4de2 1027
<> 154:37f96f9d4de2 1028 if (result)
<> 154:37f96f9d4de2 1029 {
<> 154:37f96f9d4de2 1030 if (result == kStatus_I2C_Nak)
<> 154:37f96f9d4de2 1031 {
<> 154:37f96f9d4de2 1032 result = kStatus_I2C_Addr_Nak;
<> 154:37f96f9d4de2 1033
<> 154:37f96f9d4de2 1034 I2C_MasterStop(base);
<> 154:37f96f9d4de2 1035 }
<> 154:37f96f9d4de2 1036
<> 154:37f96f9d4de2 1037 return result;
<> 154:37f96f9d4de2 1038 }
<> 154:37f96f9d4de2 1039 }
<> 154:37f96f9d4de2 1040 }
<> 154:37f96f9d4de2 1041
<> 154:37f96f9d4de2 1042 /* Transmit data. */
<> 154:37f96f9d4de2 1043 if ((xfer->direction == kI2C_Write) && (xfer->dataSize > 0))
<> 154:37f96f9d4de2 1044 {
<> 154:37f96f9d4de2 1045 /* Send Data. */
<> 154:37f96f9d4de2 1046 result = I2C_MasterWriteBlocking(base, xfer->data, xfer->dataSize, xfer->flags);
<> 154:37f96f9d4de2 1047 }
<> 154:37f96f9d4de2 1048
<> 154:37f96f9d4de2 1049 /* Receive Data. */
<> 154:37f96f9d4de2 1050 if ((xfer->direction == kI2C_Read) && (xfer->dataSize > 0))
<> 154:37f96f9d4de2 1051 {
<> 154:37f96f9d4de2 1052 result = I2C_MasterReadBlocking(base, xfer->data, xfer->dataSize, xfer->flags);
<> 154:37f96f9d4de2 1053 }
<> 154:37f96f9d4de2 1054
<> 154:37f96f9d4de2 1055 return result;
<> 154:37f96f9d4de2 1056 }
<> 154:37f96f9d4de2 1057
<> 154:37f96f9d4de2 1058 void I2C_MasterTransferCreateHandle(I2C_Type *base,
<> 154:37f96f9d4de2 1059 i2c_master_handle_t *handle,
<> 154:37f96f9d4de2 1060 i2c_master_transfer_callback_t callback,
<> 154:37f96f9d4de2 1061 void *userData)
<> 154:37f96f9d4de2 1062 {
<> 154:37f96f9d4de2 1063 assert(handle);
<> 154:37f96f9d4de2 1064
<> 154:37f96f9d4de2 1065 uint32_t instance = I2C_GetInstance(base);
<> 154:37f96f9d4de2 1066
<> 154:37f96f9d4de2 1067 /* Zero handle. */
<> 154:37f96f9d4de2 1068 memset(handle, 0, sizeof(*handle));
<> 154:37f96f9d4de2 1069
<> 154:37f96f9d4de2 1070 /* Set callback and userData. */
<> 154:37f96f9d4de2 1071 handle->completionCallback = callback;
<> 154:37f96f9d4de2 1072 handle->userData = userData;
<> 154:37f96f9d4de2 1073
<> 154:37f96f9d4de2 1074 /* Save the context in global variables to support the double weak mechanism. */
<> 154:37f96f9d4de2 1075 s_i2cHandle[instance] = handle;
<> 154:37f96f9d4de2 1076
<> 154:37f96f9d4de2 1077 /* Save master interrupt handler. */
<> 154:37f96f9d4de2 1078 s_i2cMasterIsr = I2C_MasterTransferHandleIRQ;
<> 154:37f96f9d4de2 1079
<> 154:37f96f9d4de2 1080 /* Enable NVIC interrupt. */
<> 154:37f96f9d4de2 1081 EnableIRQ(s_i2cIrqs[instance]);
<> 154:37f96f9d4de2 1082 }
<> 154:37f96f9d4de2 1083
<> 154:37f96f9d4de2 1084 status_t I2C_MasterTransferNonBlocking(I2C_Type *base, i2c_master_handle_t *handle, i2c_master_transfer_t *xfer)
<> 154:37f96f9d4de2 1085 {
<> 154:37f96f9d4de2 1086 assert(handle);
<> 154:37f96f9d4de2 1087 assert(xfer);
<> 154:37f96f9d4de2 1088
<> 154:37f96f9d4de2 1089 status_t result = kStatus_Success;
<> 154:37f96f9d4de2 1090
<> 154:37f96f9d4de2 1091 /* Check if the I2C bus is idle - if not return busy status. */
<> 154:37f96f9d4de2 1092 if (handle->state != kIdleState)
<> 154:37f96f9d4de2 1093 {
<> 154:37f96f9d4de2 1094 result = kStatus_I2C_Busy;
<> 154:37f96f9d4de2 1095 }
<> 154:37f96f9d4de2 1096 else
<> 154:37f96f9d4de2 1097 {
<> 154:37f96f9d4de2 1098 /* Start up the master transfer state machine. */
<> 154:37f96f9d4de2 1099 result = I2C_InitTransferStateMachine(base, handle, xfer);
<> 154:37f96f9d4de2 1100
<> 154:37f96f9d4de2 1101 if (result == kStatus_Success)
<> 154:37f96f9d4de2 1102 {
<> 154:37f96f9d4de2 1103 /* Enable the I2C interrupts. */
<> 154:37f96f9d4de2 1104 I2C_EnableInterrupts(base, kI2C_GlobalInterruptEnable);
<> 154:37f96f9d4de2 1105 }
<> 154:37f96f9d4de2 1106 }
<> 154:37f96f9d4de2 1107
<> 154:37f96f9d4de2 1108 return result;
<> 154:37f96f9d4de2 1109 }
<> 154:37f96f9d4de2 1110
<> 154:37f96f9d4de2 1111 void I2C_MasterTransferAbort(I2C_Type *base, i2c_master_handle_t *handle)
<> 154:37f96f9d4de2 1112 {
<> 154:37f96f9d4de2 1113 assert(handle);
<> 154:37f96f9d4de2 1114
<> 154:37f96f9d4de2 1115 volatile uint8_t dummy = 0;
<> 154:37f96f9d4de2 1116
<> 154:37f96f9d4de2 1117 /* Add this to avoid build warning. */
<> 154:37f96f9d4de2 1118 dummy++;
<> 154:37f96f9d4de2 1119
<> 154:37f96f9d4de2 1120 /* Disable interrupt. */
<> 154:37f96f9d4de2 1121 I2C_DisableInterrupts(base, kI2C_GlobalInterruptEnable);
<> 154:37f96f9d4de2 1122
<> 154:37f96f9d4de2 1123 /* Reset the state to idle. */
<> 154:37f96f9d4de2 1124 handle->state = kIdleState;
<> 154:37f96f9d4de2 1125
<> 154:37f96f9d4de2 1126 /* Send STOP signal. */
<> 154:37f96f9d4de2 1127 if (handle->transfer.direction == kI2C_Read)
<> 154:37f96f9d4de2 1128 {
<> 154:37f96f9d4de2 1129 base->C1 |= I2C_C1_TXAK_MASK;
<> 154:37f96f9d4de2 1130 while (!(base->S & kI2C_IntPendingFlag))
<> 154:37f96f9d4de2 1131 {
<> 154:37f96f9d4de2 1132 }
<> 154:37f96f9d4de2 1133 base->S = kI2C_IntPendingFlag;
<> 154:37f96f9d4de2 1134
<> 154:37f96f9d4de2 1135 base->C1 &= ~(I2C_C1_MST_MASK | I2C_C1_TX_MASK | I2C_C1_TXAK_MASK);
<> 154:37f96f9d4de2 1136 dummy = base->D;
<> 154:37f96f9d4de2 1137 }
<> 154:37f96f9d4de2 1138 else
<> 154:37f96f9d4de2 1139 {
<> 154:37f96f9d4de2 1140 while (!(base->S & kI2C_IntPendingFlag))
<> 154:37f96f9d4de2 1141 {
<> 154:37f96f9d4de2 1142 }
<> 154:37f96f9d4de2 1143 base->S = kI2C_IntPendingFlag;
<> 154:37f96f9d4de2 1144 base->C1 &= ~(I2C_C1_MST_MASK | I2C_C1_TX_MASK | I2C_C1_TXAK_MASK);
<> 154:37f96f9d4de2 1145 }
<> 154:37f96f9d4de2 1146 }
<> 154:37f96f9d4de2 1147
<> 154:37f96f9d4de2 1148 status_t I2C_MasterTransferGetCount(I2C_Type *base, i2c_master_handle_t *handle, size_t *count)
<> 154:37f96f9d4de2 1149 {
<> 154:37f96f9d4de2 1150 assert(handle);
<> 154:37f96f9d4de2 1151
<> 154:37f96f9d4de2 1152 if (!count)
<> 154:37f96f9d4de2 1153 {
<> 154:37f96f9d4de2 1154 return kStatus_InvalidArgument;
<> 154:37f96f9d4de2 1155 }
<> 154:37f96f9d4de2 1156
<> 154:37f96f9d4de2 1157 *count = handle->transferSize - handle->transfer.dataSize;
<> 154:37f96f9d4de2 1158
<> 154:37f96f9d4de2 1159 return kStatus_Success;
<> 154:37f96f9d4de2 1160 }
<> 154:37f96f9d4de2 1161
<> 154:37f96f9d4de2 1162 void I2C_MasterTransferHandleIRQ(I2C_Type *base, void *i2cHandle)
<> 154:37f96f9d4de2 1163 {
<> 154:37f96f9d4de2 1164 assert(i2cHandle);
<> 154:37f96f9d4de2 1165
<> 154:37f96f9d4de2 1166 i2c_master_handle_t *handle = (i2c_master_handle_t *)i2cHandle;
<> 154:37f96f9d4de2 1167 status_t result = kStatus_Success;
<> 154:37f96f9d4de2 1168 bool isDone;
<> 154:37f96f9d4de2 1169
<> 154:37f96f9d4de2 1170 /* Clear the interrupt flag. */
<> 154:37f96f9d4de2 1171 base->S = kI2C_IntPendingFlag;
<> 154:37f96f9d4de2 1172
<> 154:37f96f9d4de2 1173 /* Check transfer complete flag. */
<> 154:37f96f9d4de2 1174 result = I2C_MasterTransferRunStateMachine(base, handle, &isDone);
<> 154:37f96f9d4de2 1175
<> 154:37f96f9d4de2 1176 if (isDone || result)
<> 154:37f96f9d4de2 1177 {
<> 154:37f96f9d4de2 1178 /* Send stop command if transfer done or received Nak. */
<> 154:37f96f9d4de2 1179 if ((!(handle->transfer.flags & kI2C_TransferNoStopFlag)) || (result == kStatus_I2C_Nak) ||
<> 154:37f96f9d4de2 1180 (result == kStatus_I2C_Addr_Nak))
<> 154:37f96f9d4de2 1181 {
<> 154:37f96f9d4de2 1182 /* Ensure stop command is a need. */
<> 154:37f96f9d4de2 1183 if ((base->C1 & I2C_C1_MST_MASK))
<> 154:37f96f9d4de2 1184 {
<> 154:37f96f9d4de2 1185 if (I2C_MasterStop(base) != kStatus_Success)
<> 154:37f96f9d4de2 1186 {
<> 154:37f96f9d4de2 1187 result = kStatus_I2C_Timeout;
<> 154:37f96f9d4de2 1188 }
<> 154:37f96f9d4de2 1189 }
<> 154:37f96f9d4de2 1190 }
<> 154:37f96f9d4de2 1191
<> 154:37f96f9d4de2 1192 /* Restore handle to idle state. */
<> 154:37f96f9d4de2 1193 handle->state = kIdleState;
<> 154:37f96f9d4de2 1194
<> 154:37f96f9d4de2 1195 /* Disable interrupt. */
<> 154:37f96f9d4de2 1196 I2C_DisableInterrupts(base, kI2C_GlobalInterruptEnable);
<> 154:37f96f9d4de2 1197
<> 154:37f96f9d4de2 1198 /* Call the callback function after the function has completed. */
<> 154:37f96f9d4de2 1199 if (handle->completionCallback)
<> 154:37f96f9d4de2 1200 {
<> 154:37f96f9d4de2 1201 handle->completionCallback(base, handle, result, handle->userData);
<> 154:37f96f9d4de2 1202 }
<> 154:37f96f9d4de2 1203 }
<> 154:37f96f9d4de2 1204 }
<> 154:37f96f9d4de2 1205
<> 154:37f96f9d4de2 1206 void I2C_SlaveInit(I2C_Type *base, const i2c_slave_config_t *slaveConfig, uint32_t srcClock_Hz)
<> 154:37f96f9d4de2 1207 {
<> 154:37f96f9d4de2 1208 assert(slaveConfig);
<> 154:37f96f9d4de2 1209
<> 154:37f96f9d4de2 1210 uint8_t tmpReg;
<> 154:37f96f9d4de2 1211
<> 154:37f96f9d4de2 1212 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
<> 154:37f96f9d4de2 1213 CLOCK_EnableClock(s_i2cClocks[I2C_GetInstance(base)]);
<> 154:37f96f9d4de2 1214 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
<> 154:37f96f9d4de2 1215
<> 154:37f96f9d4de2 1216 /* Configure addressing mode. */
<> 154:37f96f9d4de2 1217 switch (slaveConfig->addressingMode)
<> 154:37f96f9d4de2 1218 {
<> 154:37f96f9d4de2 1219 case kI2C_Address7bit:
<> 154:37f96f9d4de2 1220 base->A1 = ((uint32_t)(slaveConfig->slaveAddress)) << 1U;
<> 154:37f96f9d4de2 1221 break;
<> 154:37f96f9d4de2 1222
<> 154:37f96f9d4de2 1223 case kI2C_RangeMatch:
<> 154:37f96f9d4de2 1224 assert(slaveConfig->slaveAddress < slaveConfig->upperAddress);
<> 154:37f96f9d4de2 1225 base->A1 = ((uint32_t)(slaveConfig->slaveAddress)) << 1U;
<> 154:37f96f9d4de2 1226 base->RA = ((uint32_t)(slaveConfig->upperAddress)) << 1U;
<> 154:37f96f9d4de2 1227 base->C2 |= I2C_C2_RMEN_MASK;
<> 154:37f96f9d4de2 1228 break;
<> 154:37f96f9d4de2 1229
<> 154:37f96f9d4de2 1230 default:
<> 154:37f96f9d4de2 1231 break;
<> 154:37f96f9d4de2 1232 }
<> 154:37f96f9d4de2 1233
<> 154:37f96f9d4de2 1234 /* Configure low power wake up feature. */
<> 154:37f96f9d4de2 1235 tmpReg = base->C1;
<> 154:37f96f9d4de2 1236 tmpReg &= ~I2C_C1_WUEN_MASK;
<> 154:37f96f9d4de2 1237 base->C1 = tmpReg | I2C_C1_WUEN(slaveConfig->enableWakeUp) | I2C_C1_IICEN(slaveConfig->enableSlave);
<> 154:37f96f9d4de2 1238
<> 154:37f96f9d4de2 1239 /* Configure general call & baud rate control & high drive feature. */
<> 154:37f96f9d4de2 1240 tmpReg = base->C2;
<> 154:37f96f9d4de2 1241 tmpReg &= ~(I2C_C2_SBRC_MASK | I2C_C2_GCAEN_MASK);
<> 154:37f96f9d4de2 1242 tmpReg |= I2C_C2_SBRC(slaveConfig->enableBaudRateCtl) | I2C_C2_GCAEN(slaveConfig->enableGeneralCall);
<> 154:37f96f9d4de2 1243 #if defined(FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION) && FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION
<> 154:37f96f9d4de2 1244 tmpReg &= ~I2C_C2_HDRS_MASK;
<> 154:37f96f9d4de2 1245 tmpReg |= I2C_C2_HDRS(slaveConfig->enableHighDrive);
<> 154:37f96f9d4de2 1246 #endif
<> 154:37f96f9d4de2 1247 base->C2 = tmpReg;
<> 154:37f96f9d4de2 1248
<> 154:37f96f9d4de2 1249 /* Enable/Disable double buffering. */
<> 154:37f96f9d4de2 1250 #if defined(FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE) && FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE
<> 154:37f96f9d4de2 1251 tmpReg = base->S2 & (~I2C_S2_DFEN_MASK);
<> 154:37f96f9d4de2 1252 base->S2 = tmpReg | I2C_S2_DFEN(slaveConfig->enableDoubleBuffering);
<> 154:37f96f9d4de2 1253 #endif
<> 154:37f96f9d4de2 1254
<> 154:37f96f9d4de2 1255 /* Set hold time. */
<> 154:37f96f9d4de2 1256 I2C_SetHoldTime(base, slaveConfig->sclStopHoldTime_ns, srcClock_Hz);
<> 154:37f96f9d4de2 1257 }
<> 154:37f96f9d4de2 1258
<> 154:37f96f9d4de2 1259 void I2C_SlaveDeinit(I2C_Type *base)
<> 154:37f96f9d4de2 1260 {
<> 154:37f96f9d4de2 1261 /* Disable I2C module. */
<> 154:37f96f9d4de2 1262 I2C_Enable(base, false);
<> 154:37f96f9d4de2 1263
<> 154:37f96f9d4de2 1264 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
<> 154:37f96f9d4de2 1265 /* Disable I2C clock. */
<> 154:37f96f9d4de2 1266 CLOCK_DisableClock(s_i2cClocks[I2C_GetInstance(base)]);
<> 154:37f96f9d4de2 1267 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
<> 154:37f96f9d4de2 1268 }
<> 154:37f96f9d4de2 1269
<> 154:37f96f9d4de2 1270 void I2C_SlaveGetDefaultConfig(i2c_slave_config_t *slaveConfig)
<> 154:37f96f9d4de2 1271 {
<> 154:37f96f9d4de2 1272 assert(slaveConfig);
<> 154:37f96f9d4de2 1273
<> 154:37f96f9d4de2 1274 /* By default slave is addressed with 7-bit address. */
<> 154:37f96f9d4de2 1275 slaveConfig->addressingMode = kI2C_Address7bit;
<> 154:37f96f9d4de2 1276
<> 154:37f96f9d4de2 1277 /* General call mode is disabled by default. */
<> 154:37f96f9d4de2 1278 slaveConfig->enableGeneralCall = false;
<> 154:37f96f9d4de2 1279
<> 154:37f96f9d4de2 1280 /* Slave address match waking up MCU from low power mode is disabled. */
<> 154:37f96f9d4de2 1281 slaveConfig->enableWakeUp = false;
<> 154:37f96f9d4de2 1282
<> 154:37f96f9d4de2 1283 #if defined(FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION) && FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION
<> 154:37f96f9d4de2 1284 /* Default pin high drive is disabled. */
<> 154:37f96f9d4de2 1285 slaveConfig->enableHighDrive = false;
<> 154:37f96f9d4de2 1286 #endif
<> 154:37f96f9d4de2 1287
<> 154:37f96f9d4de2 1288 /* Independent slave mode baud rate at maximum frequency is disabled. */
<> 154:37f96f9d4de2 1289 slaveConfig->enableBaudRateCtl = false;
<> 154:37f96f9d4de2 1290
<> 154:37f96f9d4de2 1291 /* Default enable double buffering. */
<> 154:37f96f9d4de2 1292 #if defined(FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE) && FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE
<> 154:37f96f9d4de2 1293 slaveConfig->enableDoubleBuffering = true;
<> 154:37f96f9d4de2 1294 #endif
<> 154:37f96f9d4de2 1295
<> 154:37f96f9d4de2 1296 /* Set default SCL stop hold time to 4us which is minimum requirement in I2C spec. */
<> 154:37f96f9d4de2 1297 slaveConfig->sclStopHoldTime_ns = 4000;
<> 154:37f96f9d4de2 1298
<> 154:37f96f9d4de2 1299 /* Enable the I2C peripheral. */
<> 154:37f96f9d4de2 1300 slaveConfig->enableSlave = true;
<> 154:37f96f9d4de2 1301 }
<> 154:37f96f9d4de2 1302
<> 154:37f96f9d4de2 1303 status_t I2C_SlaveWriteBlocking(I2C_Type *base, const uint8_t *txBuff, size_t txSize)
<> 154:37f96f9d4de2 1304 {
<> 154:37f96f9d4de2 1305 status_t result = kStatus_Success;
<> 154:37f96f9d4de2 1306 volatile uint8_t dummy = 0;
<> 154:37f96f9d4de2 1307
<> 154:37f96f9d4de2 1308 /* Add this to avoid build warning. */
<> 154:37f96f9d4de2 1309 dummy++;
<> 154:37f96f9d4de2 1310
<> 154:37f96f9d4de2 1311 #if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT
<> 154:37f96f9d4de2 1312 /* Check start flag. */
<> 154:37f96f9d4de2 1313 while (!(base->FLT & I2C_FLT_STARTF_MASK))
<> 154:37f96f9d4de2 1314 {
<> 154:37f96f9d4de2 1315 }
<> 154:37f96f9d4de2 1316 /* Clear STARTF flag. */
<> 154:37f96f9d4de2 1317 base->FLT |= I2C_FLT_STARTF_MASK;
<> 154:37f96f9d4de2 1318 /* Clear the IICIF flag. */
<> 154:37f96f9d4de2 1319 base->S = kI2C_IntPendingFlag;
<> 154:37f96f9d4de2 1320 #endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT */
<> 154:37f96f9d4de2 1321
<> 154:37f96f9d4de2 1322 /* Wait for address match flag. */
<> 154:37f96f9d4de2 1323 while (!(base->S & kI2C_AddressMatchFlag))
<> 154:37f96f9d4de2 1324 {
<> 154:37f96f9d4de2 1325 }
<> 154:37f96f9d4de2 1326
<> 154:37f96f9d4de2 1327 /* Read dummy to release bus. */
<> 154:37f96f9d4de2 1328 dummy = base->D;
<> 154:37f96f9d4de2 1329
<> 154:37f96f9d4de2 1330 result = I2C_MasterWriteBlocking(base, txBuff, txSize, kI2C_TransferDefaultFlag);
<> 154:37f96f9d4de2 1331
<> 154:37f96f9d4de2 1332 /* Switch to receive mode. */
<> 154:37f96f9d4de2 1333 base->C1 &= ~(I2C_C1_TX_MASK | I2C_C1_TXAK_MASK);
<> 154:37f96f9d4de2 1334
<> 154:37f96f9d4de2 1335 /* Read dummy to release bus. */
<> 154:37f96f9d4de2 1336 dummy = base->D;
<> 154:37f96f9d4de2 1337
<> 154:37f96f9d4de2 1338 return result;
<> 154:37f96f9d4de2 1339 }
<> 154:37f96f9d4de2 1340
<> 154:37f96f9d4de2 1341 void I2C_SlaveReadBlocking(I2C_Type *base, uint8_t *rxBuff, size_t rxSize)
<> 154:37f96f9d4de2 1342 {
<> 154:37f96f9d4de2 1343 volatile uint8_t dummy = 0;
<> 154:37f96f9d4de2 1344
<> 154:37f96f9d4de2 1345 /* Add this to avoid build warning. */
<> 154:37f96f9d4de2 1346 dummy++;
<> 154:37f96f9d4de2 1347
<> 154:37f96f9d4de2 1348 /* Wait until address match. */
<> 154:37f96f9d4de2 1349 #if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT
<> 154:37f96f9d4de2 1350 /* Check start flag. */
<> 154:37f96f9d4de2 1351 while (!(base->FLT & I2C_FLT_STARTF_MASK))
<> 154:37f96f9d4de2 1352 {
<> 154:37f96f9d4de2 1353 }
<> 154:37f96f9d4de2 1354 /* Clear STARTF flag. */
<> 154:37f96f9d4de2 1355 base->FLT |= I2C_FLT_STARTF_MASK;
<> 154:37f96f9d4de2 1356 /* Clear the IICIF flag. */
<> 154:37f96f9d4de2 1357 base->S = kI2C_IntPendingFlag;
<> 154:37f96f9d4de2 1358 #endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT */
<> 154:37f96f9d4de2 1359
<> 154:37f96f9d4de2 1360 /* Wait for address match and int pending flag. */
<> 154:37f96f9d4de2 1361 while (!(base->S & kI2C_AddressMatchFlag))
<> 154:37f96f9d4de2 1362 {
<> 154:37f96f9d4de2 1363 }
<> 154:37f96f9d4de2 1364 while (!(base->S & kI2C_IntPendingFlag))
<> 154:37f96f9d4de2 1365 {
<> 154:37f96f9d4de2 1366 }
<> 154:37f96f9d4de2 1367
<> 154:37f96f9d4de2 1368 /* Read dummy to release bus. */
<> 154:37f96f9d4de2 1369 dummy = base->D;
<> 154:37f96f9d4de2 1370
<> 154:37f96f9d4de2 1371 /* Clear the IICIF flag. */
<> 154:37f96f9d4de2 1372 base->S = kI2C_IntPendingFlag;
<> 154:37f96f9d4de2 1373
<> 154:37f96f9d4de2 1374 /* Setup the I2C peripheral to receive data. */
<> 154:37f96f9d4de2 1375 base->C1 &= ~(I2C_C1_TX_MASK);
<> 154:37f96f9d4de2 1376
<> 154:37f96f9d4de2 1377 while (rxSize--)
<> 154:37f96f9d4de2 1378 {
<> 154:37f96f9d4de2 1379 /* Wait until data transfer complete. */
<> 154:37f96f9d4de2 1380 while (!(base->S & kI2C_IntPendingFlag))
<> 154:37f96f9d4de2 1381 {
<> 154:37f96f9d4de2 1382 }
<> 154:37f96f9d4de2 1383 /* Clear the IICIF flag. */
<> 154:37f96f9d4de2 1384 base->S = kI2C_IntPendingFlag;
<> 154:37f96f9d4de2 1385
<> 154:37f96f9d4de2 1386 /* Read from the data register. */
<> 154:37f96f9d4de2 1387 *rxBuff++ = base->D;
<> 154:37f96f9d4de2 1388 }
<> 154:37f96f9d4de2 1389 }
<> 154:37f96f9d4de2 1390
<> 154:37f96f9d4de2 1391 void I2C_SlaveTransferCreateHandle(I2C_Type *base,
<> 154:37f96f9d4de2 1392 i2c_slave_handle_t *handle,
<> 154:37f96f9d4de2 1393 i2c_slave_transfer_callback_t callback,
<> 154:37f96f9d4de2 1394 void *userData)
<> 154:37f96f9d4de2 1395 {
<> 154:37f96f9d4de2 1396 assert(handle);
<> 154:37f96f9d4de2 1397
<> 154:37f96f9d4de2 1398 uint32_t instance = I2C_GetInstance(base);
<> 154:37f96f9d4de2 1399
<> 154:37f96f9d4de2 1400 /* Zero handle. */
<> 154:37f96f9d4de2 1401 memset(handle, 0, sizeof(*handle));
<> 154:37f96f9d4de2 1402
<> 154:37f96f9d4de2 1403 /* Set callback and userData. */
<> 154:37f96f9d4de2 1404 handle->callback = callback;
<> 154:37f96f9d4de2 1405 handle->userData = userData;
<> 154:37f96f9d4de2 1406
<> 154:37f96f9d4de2 1407 /* Save the context in global variables to support the double weak mechanism. */
<> 154:37f96f9d4de2 1408 s_i2cHandle[instance] = handle;
<> 154:37f96f9d4de2 1409
<> 154:37f96f9d4de2 1410 /* Save slave interrupt handler. */
<> 154:37f96f9d4de2 1411 s_i2cSlaveIsr = I2C_SlaveTransferHandleIRQ;
<> 154:37f96f9d4de2 1412
<> 154:37f96f9d4de2 1413 /* Enable NVIC interrupt. */
<> 154:37f96f9d4de2 1414 EnableIRQ(s_i2cIrqs[instance]);
<> 154:37f96f9d4de2 1415 }
<> 154:37f96f9d4de2 1416
<> 154:37f96f9d4de2 1417 status_t I2C_SlaveTransferNonBlocking(I2C_Type *base, i2c_slave_handle_t *handle, uint32_t eventMask)
<> 154:37f96f9d4de2 1418 {
<> 154:37f96f9d4de2 1419 assert(handle);
<> 154:37f96f9d4de2 1420
<> 154:37f96f9d4de2 1421 /* Check if the I2C bus is idle - if not return busy status. */
<> 154:37f96f9d4de2 1422 if (handle->isBusy)
<> 154:37f96f9d4de2 1423 {
<> 154:37f96f9d4de2 1424 return kStatus_I2C_Busy;
<> 154:37f96f9d4de2 1425 }
<> 154:37f96f9d4de2 1426 else
<> 154:37f96f9d4de2 1427 {
<> 154:37f96f9d4de2 1428 /* Disable LPI2C IRQ sources while we configure stuff. */
<> 154:37f96f9d4de2 1429 I2C_DisableInterrupts(base, kIrqFlags);
<> 154:37f96f9d4de2 1430
<> 154:37f96f9d4de2 1431 /* Clear transfer in handle. */
<> 154:37f96f9d4de2 1432 memset(&handle->transfer, 0, sizeof(handle->transfer));
<> 154:37f96f9d4de2 1433
<> 154:37f96f9d4de2 1434 /* Record that we're busy. */
<> 154:37f96f9d4de2 1435 handle->isBusy = true;
<> 154:37f96f9d4de2 1436
<> 154:37f96f9d4de2 1437 /* Set up event mask. tx and rx are always enabled. */
<> 154:37f96f9d4de2 1438 handle->eventMask = eventMask | kI2C_SlaveTransmitEvent | kI2C_SlaveReceiveEvent | kI2C_SlaveGenaralcallEvent;
<> 154:37f96f9d4de2 1439
<> 154:37f96f9d4de2 1440 /* Clear all flags. */
<> 154:37f96f9d4de2 1441 I2C_SlaveClearStatusFlags(base, kClearFlags);
<> 154:37f96f9d4de2 1442
<> 154:37f96f9d4de2 1443 /* Enable I2C internal IRQ sources. NVIC IRQ was enabled in CreateHandle() */
<> 154:37f96f9d4de2 1444 I2C_EnableInterrupts(base, kIrqFlags);
<> 154:37f96f9d4de2 1445 }
<> 154:37f96f9d4de2 1446
<> 154:37f96f9d4de2 1447 return kStatus_Success;
<> 154:37f96f9d4de2 1448 }
<> 154:37f96f9d4de2 1449
<> 154:37f96f9d4de2 1450 void I2C_SlaveTransferAbort(I2C_Type *base, i2c_slave_handle_t *handle)
<> 154:37f96f9d4de2 1451 {
<> 154:37f96f9d4de2 1452 assert(handle);
<> 154:37f96f9d4de2 1453
<> 154:37f96f9d4de2 1454 if (handle->isBusy)
<> 154:37f96f9d4de2 1455 {
<> 154:37f96f9d4de2 1456 /* Disable interrupts. */
<> 154:37f96f9d4de2 1457 I2C_DisableInterrupts(base, kIrqFlags);
<> 154:37f96f9d4de2 1458
<> 154:37f96f9d4de2 1459 /* Reset transfer info. */
<> 154:37f96f9d4de2 1460 memset(&handle->transfer, 0, sizeof(handle->transfer));
<> 154:37f96f9d4de2 1461
<> 154:37f96f9d4de2 1462 /* Reset the state to idle. */
<> 154:37f96f9d4de2 1463 handle->isBusy = false;
<> 154:37f96f9d4de2 1464 }
<> 154:37f96f9d4de2 1465 }
<> 154:37f96f9d4de2 1466
<> 154:37f96f9d4de2 1467 status_t I2C_SlaveTransferGetCount(I2C_Type *base, i2c_slave_handle_t *handle, size_t *count)
<> 154:37f96f9d4de2 1468 {
<> 154:37f96f9d4de2 1469 assert(handle);
<> 154:37f96f9d4de2 1470
<> 154:37f96f9d4de2 1471 if (!count)
<> 154:37f96f9d4de2 1472 {
<> 154:37f96f9d4de2 1473 return kStatus_InvalidArgument;
<> 154:37f96f9d4de2 1474 }
<> 154:37f96f9d4de2 1475
<> 154:37f96f9d4de2 1476 /* Catch when there is not an active transfer. */
<> 154:37f96f9d4de2 1477 if (!handle->isBusy)
<> 154:37f96f9d4de2 1478 {
<> 154:37f96f9d4de2 1479 *count = 0;
<> 154:37f96f9d4de2 1480 return kStatus_NoTransferInProgress;
<> 154:37f96f9d4de2 1481 }
<> 154:37f96f9d4de2 1482
<> 154:37f96f9d4de2 1483 /* For an active transfer, just return the count from the handle. */
<> 154:37f96f9d4de2 1484 *count = handle->transfer.transferredCount;
<> 154:37f96f9d4de2 1485
<> 154:37f96f9d4de2 1486 return kStatus_Success;
<> 154:37f96f9d4de2 1487 }
<> 154:37f96f9d4de2 1488
<> 154:37f96f9d4de2 1489 void I2C_SlaveTransferHandleIRQ(I2C_Type *base, void *i2cHandle)
<> 154:37f96f9d4de2 1490 {
<> 154:37f96f9d4de2 1491 assert(i2cHandle);
<> 154:37f96f9d4de2 1492
<> 154:37f96f9d4de2 1493 uint16_t status;
<> 154:37f96f9d4de2 1494 bool doTransmit = false;
<> 154:37f96f9d4de2 1495 i2c_slave_handle_t *handle = (i2c_slave_handle_t *)i2cHandle;
<> 154:37f96f9d4de2 1496 i2c_slave_transfer_t *xfer;
<> 154:37f96f9d4de2 1497 volatile uint8_t dummy = 0;
<> 154:37f96f9d4de2 1498
<> 154:37f96f9d4de2 1499 /* Add this to avoid build warning. */
<> 154:37f96f9d4de2 1500 dummy++;
<> 154:37f96f9d4de2 1501
<> 154:37f96f9d4de2 1502 status = I2C_SlaveGetStatusFlags(base);
<> 154:37f96f9d4de2 1503 xfer = &(handle->transfer);
<> 154:37f96f9d4de2 1504
<> 154:37f96f9d4de2 1505 #ifdef I2C_HAS_STOP_DETECT
<> 154:37f96f9d4de2 1506 /* Check stop flag. */
<> 154:37f96f9d4de2 1507 if (status & kI2C_StopDetectFlag)
<> 154:37f96f9d4de2 1508 {
<> 154:37f96f9d4de2 1509 I2C_MasterClearStatusFlags(base, kI2C_StopDetectFlag);
<> 154:37f96f9d4de2 1510
<> 154:37f96f9d4de2 1511 /* Clear the interrupt flag. */
<> 154:37f96f9d4de2 1512 base->S = kI2C_IntPendingFlag;
<> 154:37f96f9d4de2 1513
<> 154:37f96f9d4de2 1514 /* Call slave callback if this is the STOP of the transfer. */
<> 154:37f96f9d4de2 1515 if (handle->isBusy)
<> 154:37f96f9d4de2 1516 {
<> 154:37f96f9d4de2 1517 xfer->event = kI2C_SlaveCompletionEvent;
<> 154:37f96f9d4de2 1518 xfer->completionStatus = kStatus_Success;
<> 154:37f96f9d4de2 1519 handle->isBusy = false;
<> 154:37f96f9d4de2 1520
<> 154:37f96f9d4de2 1521 if ((handle->eventMask & xfer->event) && (handle->callback))
<> 154:37f96f9d4de2 1522 {
<> 154:37f96f9d4de2 1523 handle->callback(base, xfer, handle->userData);
<> 154:37f96f9d4de2 1524 }
<> 154:37f96f9d4de2 1525 }
<> 154:37f96f9d4de2 1526
<> 154:37f96f9d4de2 1527 return;
<> 154:37f96f9d4de2 1528 }
<> 154:37f96f9d4de2 1529 #endif /* I2C_HAS_STOP_DETECT */
<> 154:37f96f9d4de2 1530
<> 154:37f96f9d4de2 1531 #if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT
<> 154:37f96f9d4de2 1532 /* Check start flag. */
<> 154:37f96f9d4de2 1533 if (status & kI2C_StartDetectFlag)
<> 154:37f96f9d4de2 1534 {
<> 154:37f96f9d4de2 1535 I2C_MasterClearStatusFlags(base, kI2C_StartDetectFlag);
<> 154:37f96f9d4de2 1536
<> 154:37f96f9d4de2 1537 /* Clear the interrupt flag. */
<> 154:37f96f9d4de2 1538 base->S = kI2C_IntPendingFlag;
<> 154:37f96f9d4de2 1539
<> 154:37f96f9d4de2 1540 xfer->event = kI2C_SlaveStartEvent;
<> 154:37f96f9d4de2 1541
<> 154:37f96f9d4de2 1542 if ((handle->eventMask & xfer->event) && (handle->callback))
<> 154:37f96f9d4de2 1543 {
<> 154:37f96f9d4de2 1544 handle->callback(base, xfer, handle->userData);
<> 154:37f96f9d4de2 1545 }
<> 154:37f96f9d4de2 1546
<> 154:37f96f9d4de2 1547 if (!(status & kI2C_AddressMatchFlag))
<> 154:37f96f9d4de2 1548 {
<> 154:37f96f9d4de2 1549 return;
<> 154:37f96f9d4de2 1550 }
<> 154:37f96f9d4de2 1551 }
<> 154:37f96f9d4de2 1552 #endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT */
<> 154:37f96f9d4de2 1553
<> 154:37f96f9d4de2 1554 /* Clear the interrupt flag. */
<> 154:37f96f9d4de2 1555 base->S = kI2C_IntPendingFlag;
<> 154:37f96f9d4de2 1556
<> 154:37f96f9d4de2 1557 /* Check NAK */
<> 154:37f96f9d4de2 1558 if (status & kI2C_ReceiveNakFlag)
<> 154:37f96f9d4de2 1559 {
<> 154:37f96f9d4de2 1560 /* Set receive mode. */
<> 154:37f96f9d4de2 1561 base->C1 &= ~(I2C_C1_TX_MASK | I2C_C1_TXAK_MASK);
<> 154:37f96f9d4de2 1562
<> 154:37f96f9d4de2 1563 /* Read dummy. */
<> 154:37f96f9d4de2 1564 dummy = base->D;
<> 154:37f96f9d4de2 1565
<> 154:37f96f9d4de2 1566 if (handle->transfer.dataSize != 0)
<> 154:37f96f9d4de2 1567 {
<> 154:37f96f9d4de2 1568 xfer->event = kI2C_SlaveCompletionEvent;
<> 154:37f96f9d4de2 1569 xfer->completionStatus = kStatus_I2C_Nak;
<> 154:37f96f9d4de2 1570 handle->isBusy = false;
<> 154:37f96f9d4de2 1571
<> 154:37f96f9d4de2 1572 if ((handle->eventMask & xfer->event) && (handle->callback))
<> 154:37f96f9d4de2 1573 {
<> 154:37f96f9d4de2 1574 handle->callback(base, xfer, handle->userData);
<> 154:37f96f9d4de2 1575 }
<> 154:37f96f9d4de2 1576 }
<> 154:37f96f9d4de2 1577 else
<> 154:37f96f9d4de2 1578 {
<> 154:37f96f9d4de2 1579 #ifndef I2C_HAS_STOP_DETECT
<> 154:37f96f9d4de2 1580 xfer->event = kI2C_SlaveCompletionEvent;
<> 154:37f96f9d4de2 1581 xfer->completionStatus = kStatus_Success;
<> 154:37f96f9d4de2 1582 handle->isBusy = false;
<> 154:37f96f9d4de2 1583
<> 154:37f96f9d4de2 1584 if ((handle->eventMask & xfer->event) && (handle->callback))
<> 154:37f96f9d4de2 1585 {
<> 154:37f96f9d4de2 1586 handle->callback(base, xfer, handle->userData);
<> 154:37f96f9d4de2 1587 }
<> 154:37f96f9d4de2 1588 #endif /* !FSL_FEATURE_I2C_HAS_START_STOP_DETECT or !FSL_FEATURE_I2C_HAS_STOP_DETECT */
<> 154:37f96f9d4de2 1589 }
<> 154:37f96f9d4de2 1590 }
<> 154:37f96f9d4de2 1591 /* Check address match. */
<> 154:37f96f9d4de2 1592 else if (status & kI2C_AddressMatchFlag)
<> 154:37f96f9d4de2 1593 {
<> 154:37f96f9d4de2 1594 handle->isBusy = true;
<> 154:37f96f9d4de2 1595 xfer->event = kI2C_SlaveAddressMatchEvent;
<> 154:37f96f9d4de2 1596
<> 154:37f96f9d4de2 1597 /* Slave transmit, master reading from slave. */
<> 154:37f96f9d4de2 1598 if (status & kI2C_TransferDirectionFlag)
<> 154:37f96f9d4de2 1599 {
<> 154:37f96f9d4de2 1600 /* Change direction to send data. */
<> 154:37f96f9d4de2 1601 base->C1 |= I2C_C1_TX_MASK;
<> 154:37f96f9d4de2 1602
<> 154:37f96f9d4de2 1603 doTransmit = true;
<> 154:37f96f9d4de2 1604 }
<> 154:37f96f9d4de2 1605 else
<> 154:37f96f9d4de2 1606 {
<> 154:37f96f9d4de2 1607 /* Slave receive, master writing to slave. */
<> 154:37f96f9d4de2 1608 base->C1 &= ~(I2C_C1_TX_MASK | I2C_C1_TXAK_MASK);
<> 154:37f96f9d4de2 1609
<> 154:37f96f9d4de2 1610 /* Read dummy to release the bus. */
<> 154:37f96f9d4de2 1611 dummy = base->D;
<> 154:37f96f9d4de2 1612
<> 154:37f96f9d4de2 1613 if (dummy == 0)
<> 154:37f96f9d4de2 1614 {
<> 154:37f96f9d4de2 1615 xfer->event = kI2C_SlaveGenaralcallEvent;
<> 154:37f96f9d4de2 1616 }
<> 154:37f96f9d4de2 1617 }
<> 154:37f96f9d4de2 1618
<> 154:37f96f9d4de2 1619 if ((handle->eventMask & xfer->event) && (handle->callback))
<> 154:37f96f9d4de2 1620 {
<> 154:37f96f9d4de2 1621 handle->callback(base, xfer, handle->userData);
<> 154:37f96f9d4de2 1622 }
<> 154:37f96f9d4de2 1623 }
<> 154:37f96f9d4de2 1624 /* Check transfer complete flag. */
<> 154:37f96f9d4de2 1625 else if (status & kI2C_TransferCompleteFlag)
<> 154:37f96f9d4de2 1626 {
<> 154:37f96f9d4de2 1627 /* Slave transmit, master reading from slave. */
<> 154:37f96f9d4de2 1628 if (status & kI2C_TransferDirectionFlag)
<> 154:37f96f9d4de2 1629 {
<> 154:37f96f9d4de2 1630 doTransmit = true;
<> 154:37f96f9d4de2 1631 }
<> 154:37f96f9d4de2 1632 else
<> 154:37f96f9d4de2 1633 {
<> 154:37f96f9d4de2 1634 /* If we're out of data, invoke callback to get more. */
<> 154:37f96f9d4de2 1635 if ((!xfer->data) || (!xfer->dataSize))
<> 154:37f96f9d4de2 1636 {
<> 154:37f96f9d4de2 1637 xfer->event = kI2C_SlaveReceiveEvent;
<> 154:37f96f9d4de2 1638
<> 154:37f96f9d4de2 1639 if (handle->callback)
<> 154:37f96f9d4de2 1640 {
<> 154:37f96f9d4de2 1641 handle->callback(base, xfer, handle->userData);
<> 154:37f96f9d4de2 1642 }
<> 154:37f96f9d4de2 1643
<> 154:37f96f9d4de2 1644 /* Clear the transferred count now that we have a new buffer. */
<> 154:37f96f9d4de2 1645 xfer->transferredCount = 0;
<> 154:37f96f9d4de2 1646 }
<> 154:37f96f9d4de2 1647
<> 154:37f96f9d4de2 1648 /* Slave receive, master writing to slave. */
<> 154:37f96f9d4de2 1649 uint8_t data = base->D;
<> 154:37f96f9d4de2 1650
<> 154:37f96f9d4de2 1651 if (handle->transfer.dataSize)
<> 154:37f96f9d4de2 1652 {
<> 154:37f96f9d4de2 1653 /* Receive data. */
<> 154:37f96f9d4de2 1654 *handle->transfer.data++ = data;
<> 154:37f96f9d4de2 1655 handle->transfer.dataSize--;
<> 154:37f96f9d4de2 1656 xfer->transferredCount++;
<> 154:37f96f9d4de2 1657 if (!handle->transfer.dataSize)
<> 154:37f96f9d4de2 1658 {
<> 154:37f96f9d4de2 1659 #ifndef I2C_HAS_STOP_DETECT
<> 154:37f96f9d4de2 1660 xfer->event = kI2C_SlaveCompletionEvent;
<> 154:37f96f9d4de2 1661 xfer->completionStatus = kStatus_Success;
<> 154:37f96f9d4de2 1662 handle->isBusy = false;
<> 154:37f96f9d4de2 1663
<> 154:37f96f9d4de2 1664 /* Proceed receive complete event. */
<> 154:37f96f9d4de2 1665 if ((handle->eventMask & xfer->event) && (handle->callback))
<> 154:37f96f9d4de2 1666 {
<> 154:37f96f9d4de2 1667 handle->callback(base, xfer, handle->userData);
<> 154:37f96f9d4de2 1668 }
<> 154:37f96f9d4de2 1669 #endif /* !FSL_FEATURE_I2C_HAS_START_STOP_DETECT or !FSL_FEATURE_I2C_HAS_STOP_DETECT */
<> 154:37f96f9d4de2 1670 }
<> 154:37f96f9d4de2 1671 }
<> 154:37f96f9d4de2 1672 }
<> 154:37f96f9d4de2 1673 }
<> 154:37f96f9d4de2 1674 else
<> 154:37f96f9d4de2 1675 {
<> 154:37f96f9d4de2 1676 /* Read dummy to release bus. */
<> 154:37f96f9d4de2 1677 dummy = base->D;
<> 154:37f96f9d4de2 1678 }
<> 154:37f96f9d4de2 1679
<> 154:37f96f9d4de2 1680 /* Send data if there is the need. */
<> 154:37f96f9d4de2 1681 if (doTransmit)
<> 154:37f96f9d4de2 1682 {
<> 154:37f96f9d4de2 1683 /* If we're out of data, invoke callback to get more. */
<> 154:37f96f9d4de2 1684 if ((!xfer->data) || (!xfer->dataSize))
<> 154:37f96f9d4de2 1685 {
<> 154:37f96f9d4de2 1686 xfer->event = kI2C_SlaveTransmitEvent;
<> 154:37f96f9d4de2 1687
<> 154:37f96f9d4de2 1688 if (handle->callback)
<> 154:37f96f9d4de2 1689 {
<> 154:37f96f9d4de2 1690 handle->callback(base, xfer, handle->userData);
<> 154:37f96f9d4de2 1691 }
<> 154:37f96f9d4de2 1692
<> 154:37f96f9d4de2 1693 /* Clear the transferred count now that we have a new buffer. */
<> 154:37f96f9d4de2 1694 xfer->transferredCount = 0;
<> 154:37f96f9d4de2 1695 }
<> 154:37f96f9d4de2 1696
<> 154:37f96f9d4de2 1697 if (handle->transfer.dataSize)
<> 154:37f96f9d4de2 1698 {
<> 154:37f96f9d4de2 1699 /* Send data. */
<> 154:37f96f9d4de2 1700 base->D = *handle->transfer.data++;
<> 154:37f96f9d4de2 1701 handle->transfer.dataSize--;
<> 154:37f96f9d4de2 1702 xfer->transferredCount++;
<> 154:37f96f9d4de2 1703 }
<> 154:37f96f9d4de2 1704 else
<> 154:37f96f9d4de2 1705 {
<> 154:37f96f9d4de2 1706 /* Switch to receive mode. */
<> 154:37f96f9d4de2 1707 base->C1 &= ~(I2C_C1_TX_MASK | I2C_C1_TXAK_MASK);
<> 154:37f96f9d4de2 1708
<> 154:37f96f9d4de2 1709 /* Read dummy to release bus. */
<> 154:37f96f9d4de2 1710 dummy = base->D;
<> 154:37f96f9d4de2 1711
<> 154:37f96f9d4de2 1712 #ifndef I2C_HAS_STOP_DETECT
<> 154:37f96f9d4de2 1713 xfer->event = kI2C_SlaveCompletionEvent;
<> 154:37f96f9d4de2 1714 xfer->completionStatus = kStatus_Success;
<> 154:37f96f9d4de2 1715 handle->isBusy = false;
<> 154:37f96f9d4de2 1716
<> 154:37f96f9d4de2 1717 /* Proceed txdone event. */
<> 154:37f96f9d4de2 1718 if ((handle->eventMask & xfer->event) && (handle->callback))
<> 154:37f96f9d4de2 1719 {
<> 154:37f96f9d4de2 1720 handle->callback(base, xfer, handle->userData);
<> 154:37f96f9d4de2 1721 }
<> 154:37f96f9d4de2 1722 #endif /* !FSL_FEATURE_I2C_HAS_START_STOP_DETECT or !FSL_FEATURE_I2C_HAS_STOP_DETECT */
<> 154:37f96f9d4de2 1723 }
<> 154:37f96f9d4de2 1724 }
<> 154:37f96f9d4de2 1725 }
<> 154:37f96f9d4de2 1726
<> 154:37f96f9d4de2 1727 void I2C0_DriverIRQHandler(void)
<> 154:37f96f9d4de2 1728 {
<> 154:37f96f9d4de2 1729 I2C_TransferCommonIRQHandler(I2C0, s_i2cHandle[0]);
<> 154:37f96f9d4de2 1730 }
<> 154:37f96f9d4de2 1731
<> 154:37f96f9d4de2 1732 #if (FSL_FEATURE_SOC_I2C_COUNT > 1)
<> 154:37f96f9d4de2 1733 void I2C1_DriverIRQHandler(void)
<> 154:37f96f9d4de2 1734 {
<> 154:37f96f9d4de2 1735 I2C_TransferCommonIRQHandler(I2C1, s_i2cHandle[1]);
<> 154:37f96f9d4de2 1736 }
<> 154:37f96f9d4de2 1737 #endif /* I2C COUNT > 1 */
<> 154:37f96f9d4de2 1738
<> 154:37f96f9d4de2 1739 #if (FSL_FEATURE_SOC_I2C_COUNT > 2)
<> 154:37f96f9d4de2 1740 void I2C2_DriverIRQHandler(void)
<> 154:37f96f9d4de2 1741 {
<> 154:37f96f9d4de2 1742 I2C_TransferCommonIRQHandler(I2C2, s_i2cHandle[2]);
<> 154:37f96f9d4de2 1743 }
<> 154:37f96f9d4de2 1744 #endif /* I2C COUNT > 2 */
<> 154:37f96f9d4de2 1745 #if (FSL_FEATURE_SOC_I2C_COUNT > 3)
<> 154:37f96f9d4de2 1746 void I2C3_DriverIRQHandler(void)
<> 154:37f96f9d4de2 1747 {
<> 154:37f96f9d4de2 1748 I2C_TransferCommonIRQHandler(I2C3, s_i2cHandle[3]);
<> 154:37f96f9d4de2 1749 }
<> 154:37f96f9d4de2 1750 #endif /* I2C COUNT > 3 */