added prescaler for 16 bit pwm in LPC1347 target

Fork of mbed-dev by mbed official

Committer:
JojoS
Date:
Sat Sep 10 15:32:04 2016 +0000
Revision:
147:ba84b7dc41a7
Parent:
144:ef7eb2e8f9f7
added prescaler for 16 bit timers (solution as in LPC11xx), default prescaler 31 for max 28 ms period time

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 */