added prescaler for 16 bit pwm in LPC1347 target

Fork of mbed-dev by mbed official

Committer:
<>
Date:
Fri Sep 02 15:07:44 2016 +0100
Revision:
144:ef7eb2e8f9f7
This updates the lib to the mbed lib v125

Who changed what in which revision?

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