raspiezo / mbed-dev

Dependents:   Nucleo_L432KC_Quadrature_Decoder_with_ADC_and_DAC

Fork of mbed-dev by mbed official

Committer:
<>
Date:
Wed Jan 04 16:58:05 2017 +0000
Revision:
154:37f96f9d4de2
This updates the lib to the mbed lib v133

Who changed what in which revision?

UserRevisionLine numberNew contents of line
<> 154:37f96f9d4de2 1 /*
<> 154:37f96f9d4de2 2 * Copyright (c) 2015, Freescale Semiconductor, Inc.
<> 154:37f96f9d4de2 3 * All rights reserved.
<> 154:37f96f9d4de2 4 *
<> 154:37f96f9d4de2 5 * Redistribution and use in source and binary forms, with or without modification,
<> 154:37f96f9d4de2 6 * are permitted provided that the following conditions are met:
<> 154:37f96f9d4de2 7 *
<> 154:37f96f9d4de2 8 * o Redistributions of source code must retain the above copyright notice, this list
<> 154:37f96f9d4de2 9 * of conditions and the following disclaimer.
<> 154:37f96f9d4de2 10 *
<> 154:37f96f9d4de2 11 * o Redistributions in binary form must reproduce the above copyright notice, this
<> 154:37f96f9d4de2 12 * list of conditions and the following disclaimer in the documentation and/or
<> 154:37f96f9d4de2 13 * other materials provided with the distribution.
<> 154:37f96f9d4de2 14 *
<> 154:37f96f9d4de2 15 * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
<> 154:37f96f9d4de2 16 * contributors may be used to endorse or promote products derived from this
<> 154:37f96f9d4de2 17 * software without specific prior written permission.
<> 154:37f96f9d4de2 18 *
<> 154:37f96f9d4de2 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
<> 154:37f96f9d4de2 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
<> 154:37f96f9d4de2 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
<> 154:37f96f9d4de2 22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
<> 154:37f96f9d4de2 23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
<> 154:37f96f9d4de2 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
<> 154:37f96f9d4de2 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
<> 154:37f96f9d4de2 26 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
<> 154:37f96f9d4de2 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
<> 154:37f96f9d4de2 28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<> 154:37f96f9d4de2 29 */
<> 154:37f96f9d4de2 30
<> 154:37f96f9d4de2 31 #include "fsl_i2c_edma.h"
<> 154:37f96f9d4de2 32
<> 154:37f96f9d4de2 33 /*******************************************************************************
<> 154:37f96f9d4de2 34 * Definitions
<> 154:37f96f9d4de2 35 ******************************************************************************/
<> 154:37f96f9d4de2 36
<> 154:37f96f9d4de2 37 /*<! @breif Structure definition for i2c_master_edma_private_handle_t. The structure is private. */
<> 154:37f96f9d4de2 38 typedef struct _i2c_master_edma_private_handle
<> 154:37f96f9d4de2 39 {
<> 154:37f96f9d4de2 40 I2C_Type *base;
<> 154:37f96f9d4de2 41 i2c_master_edma_handle_t *handle;
<> 154:37f96f9d4de2 42 } i2c_master_edma_private_handle_t;
<> 154:37f96f9d4de2 43
<> 154:37f96f9d4de2 44 /*! @brief i2c master DMA transfer state. */
<> 154:37f96f9d4de2 45 enum _i2c_master_dma_transfer_states
<> 154:37f96f9d4de2 46 {
<> 154:37f96f9d4de2 47 kIdleState = 0x0U, /*!< I2C bus idle. */
<> 154:37f96f9d4de2 48 kTransferDataState = 0x1U, /*!< 7-bit address check state. */
<> 154:37f96f9d4de2 49 };
<> 154:37f96f9d4de2 50
<> 154:37f96f9d4de2 51 /*! @brief Common sets of flags used by the driver. */
<> 154:37f96f9d4de2 52 enum _i2c_flag_constants
<> 154:37f96f9d4de2 53 {
<> 154:37f96f9d4de2 54 /*! All flags which are cleared by the driver upon starting a transfer. */
<> 154:37f96f9d4de2 55 #if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT
<> 154:37f96f9d4de2 56 kClearFlags = kI2C_ArbitrationLostFlag | kI2C_IntPendingFlag | kI2C_StartDetectFlag | kI2C_StopDetectFlag,
<> 154:37f96f9d4de2 57 #elif defined(FSL_FEATURE_I2C_HAS_STOP_DETECT) && FSL_FEATURE_I2C_HAS_STOP_DETECT
<> 154:37f96f9d4de2 58 kClearFlags = kI2C_ArbitrationLostFlag | kI2C_IntPendingFlag | kI2C_StopDetectFlag,
<> 154:37f96f9d4de2 59 #else
<> 154:37f96f9d4de2 60 kClearFlags = kI2C_ArbitrationLostFlag | kI2C_IntPendingFlag,
<> 154:37f96f9d4de2 61 #endif
<> 154:37f96f9d4de2 62 };
<> 154:37f96f9d4de2 63
<> 154:37f96f9d4de2 64 /*******************************************************************************
<> 154:37f96f9d4de2 65 * Prototypes
<> 154:37f96f9d4de2 66 ******************************************************************************/
<> 154:37f96f9d4de2 67
<> 154:37f96f9d4de2 68 /*!
<> 154:37f96f9d4de2 69 * @brief EDMA callback for I2C master EDMA driver.
<> 154:37f96f9d4de2 70 *
<> 154:37f96f9d4de2 71 * @param handle EDMA handler for I2C master EDMA driver
<> 154:37f96f9d4de2 72 * @param userData user param passed to the callback function
<> 154:37f96f9d4de2 73 */
<> 154:37f96f9d4de2 74 static void I2C_MasterTransferCallbackEDMA(edma_handle_t *handle, void *userData, bool transferDone, uint32_t tcds);
<> 154:37f96f9d4de2 75
<> 154:37f96f9d4de2 76 /*!
<> 154:37f96f9d4de2 77 * @brief Check and clear status operation.
<> 154:37f96f9d4de2 78 *
<> 154:37f96f9d4de2 79 * @param base I2C peripheral base address.
<> 154:37f96f9d4de2 80 * @param status current i2c hardware status.
<> 154:37f96f9d4de2 81 * @retval kStatus_Success No error found.
<> 154:37f96f9d4de2 82 * @retval kStatus_I2C_ArbitrationLost Transfer error, arbitration lost.
<> 154:37f96f9d4de2 83 * @retval kStatus_I2C_Nak Received Nak error.
<> 154:37f96f9d4de2 84 */
<> 154:37f96f9d4de2 85 static status_t I2C_CheckAndClearError(I2C_Type *base, uint32_t status);
<> 154:37f96f9d4de2 86
<> 154:37f96f9d4de2 87 /*!
<> 154:37f96f9d4de2 88 * @brief EDMA config for I2C master driver.
<> 154:37f96f9d4de2 89 *
<> 154:37f96f9d4de2 90 * @param base I2C peripheral base address.
<> 154:37f96f9d4de2 91 * @param handle pointer to i2c_master_edma_handle_t structure which stores the transfer state
<> 154:37f96f9d4de2 92 */
<> 154:37f96f9d4de2 93 static void I2C_MasterTransferEDMAConfig(I2C_Type *base, i2c_master_edma_handle_t *handle);
<> 154:37f96f9d4de2 94
<> 154:37f96f9d4de2 95 /*!
<> 154:37f96f9d4de2 96 * @brief Set up master transfer, send slave address and sub address(if any), wait until the
<> 154:37f96f9d4de2 97 * wait until address sent status return.
<> 154:37f96f9d4de2 98 *
<> 154:37f96f9d4de2 99 * @param base I2C peripheral base address.
<> 154:37f96f9d4de2 100 * @param handle pointer to i2c_master_edma_handle_t structure which stores the transfer state
<> 154:37f96f9d4de2 101 * @param xfer pointer to i2c_master_transfer_t structure
<> 154:37f96f9d4de2 102 */
<> 154:37f96f9d4de2 103 static status_t I2C_InitTransferStateMachineEDMA(I2C_Type *base,
<> 154:37f96f9d4de2 104 i2c_master_edma_handle_t *handle,
<> 154:37f96f9d4de2 105 i2c_master_transfer_t *xfer);
<> 154:37f96f9d4de2 106
<> 154:37f96f9d4de2 107 /*!
<> 154:37f96f9d4de2 108 * @brief Get the I2C instance from peripheral base address.
<> 154:37f96f9d4de2 109 *
<> 154:37f96f9d4de2 110 * @param base I2C peripheral base address.
<> 154:37f96f9d4de2 111 * @return I2C instance.
<> 154:37f96f9d4de2 112 */
<> 154:37f96f9d4de2 113 extern uint32_t I2C_GetInstance(I2C_Type *base);
<> 154:37f96f9d4de2 114
<> 154:37f96f9d4de2 115 /*******************************************************************************
<> 154:37f96f9d4de2 116 * Variables
<> 154:37f96f9d4de2 117 ******************************************************************************/
<> 154:37f96f9d4de2 118
<> 154:37f96f9d4de2 119 /*<! Private handle only used for internally. */
<> 154:37f96f9d4de2 120 static i2c_master_edma_private_handle_t s_edmaPrivateHandle[FSL_FEATURE_SOC_I2C_COUNT];
<> 154:37f96f9d4de2 121
<> 154:37f96f9d4de2 122 /*******************************************************************************
<> 154:37f96f9d4de2 123 * Codes
<> 154:37f96f9d4de2 124 ******************************************************************************/
<> 154:37f96f9d4de2 125
<> 154:37f96f9d4de2 126 static void I2C_MasterTransferCallbackEDMA(edma_handle_t *handle, void *userData, bool transferDone, uint32_t tcds)
<> 154:37f96f9d4de2 127 {
<> 154:37f96f9d4de2 128 i2c_master_edma_private_handle_t *i2cPrivateHandle = (i2c_master_edma_private_handle_t *)userData;
<> 154:37f96f9d4de2 129 status_t result = kStatus_Success;
<> 154:37f96f9d4de2 130
<> 154:37f96f9d4de2 131 /* Disable DMA. */
<> 154:37f96f9d4de2 132 I2C_EnableDMA(i2cPrivateHandle->base, false);
<> 154:37f96f9d4de2 133
<> 154:37f96f9d4de2 134 /* Send stop if kI2C_TransferNoStop flag is not asserted. */
<> 154:37f96f9d4de2 135 if (!(i2cPrivateHandle->handle->transfer.flags & kI2C_TransferNoStopFlag))
<> 154:37f96f9d4de2 136 {
<> 154:37f96f9d4de2 137 if (i2cPrivateHandle->handle->transfer.direction == kI2C_Read)
<> 154:37f96f9d4de2 138 {
<> 154:37f96f9d4de2 139 /* Change to send NAK at the last byte. */
<> 154:37f96f9d4de2 140 i2cPrivateHandle->base->C1 |= I2C_C1_TXAK_MASK;
<> 154:37f96f9d4de2 141
<> 154:37f96f9d4de2 142 /* Wait the last data to be received. */
<> 154:37f96f9d4de2 143 while (!(i2cPrivateHandle->base->S & kI2C_TransferCompleteFlag))
<> 154:37f96f9d4de2 144 {
<> 154:37f96f9d4de2 145 }
<> 154:37f96f9d4de2 146
<> 154:37f96f9d4de2 147 /* Send stop signal. */
<> 154:37f96f9d4de2 148 result = I2C_MasterStop(i2cPrivateHandle->base);
<> 154:37f96f9d4de2 149
<> 154:37f96f9d4de2 150 /* Read the last data byte. */
<> 154:37f96f9d4de2 151 *(i2cPrivateHandle->handle->transfer.data + i2cPrivateHandle->handle->transfer.dataSize - 1) =
<> 154:37f96f9d4de2 152 i2cPrivateHandle->base->D;
<> 154:37f96f9d4de2 153 }
<> 154:37f96f9d4de2 154 else
<> 154:37f96f9d4de2 155 {
<> 154:37f96f9d4de2 156 /* Wait the last data to be sent. */
<> 154:37f96f9d4de2 157 while (!(i2cPrivateHandle->base->S & kI2C_TransferCompleteFlag))
<> 154:37f96f9d4de2 158 {
<> 154:37f96f9d4de2 159 }
<> 154:37f96f9d4de2 160
<> 154:37f96f9d4de2 161 /* Send stop signal. */
<> 154:37f96f9d4de2 162 result = I2C_MasterStop(i2cPrivateHandle->base);
<> 154:37f96f9d4de2 163 }
<> 154:37f96f9d4de2 164 }
<> 154:37f96f9d4de2 165 else
<> 154:37f96f9d4de2 166 {
<> 154:37f96f9d4de2 167 if (i2cPrivateHandle->handle->transfer.direction == kI2C_Read)
<> 154:37f96f9d4de2 168 {
<> 154:37f96f9d4de2 169 /* Change to send NAK at the last byte. */
<> 154:37f96f9d4de2 170 i2cPrivateHandle->base->C1 |= I2C_C1_TXAK_MASK;
<> 154:37f96f9d4de2 171
<> 154:37f96f9d4de2 172 /* Wait the last data to be received. */
<> 154:37f96f9d4de2 173 while (!(i2cPrivateHandle->base->S & kI2C_TransferCompleteFlag))
<> 154:37f96f9d4de2 174 {
<> 154:37f96f9d4de2 175 }
<> 154:37f96f9d4de2 176
<> 154:37f96f9d4de2 177 /* Change direction to send. */
<> 154:37f96f9d4de2 178 i2cPrivateHandle->base->C1 |= I2C_C1_TX_MASK;
<> 154:37f96f9d4de2 179
<> 154:37f96f9d4de2 180 /* Read the last data byte. */
<> 154:37f96f9d4de2 181 *(i2cPrivateHandle->handle->transfer.data + i2cPrivateHandle->handle->transfer.dataSize - 1) =
<> 154:37f96f9d4de2 182 i2cPrivateHandle->base->D;
<> 154:37f96f9d4de2 183 }
<> 154:37f96f9d4de2 184 }
<> 154:37f96f9d4de2 185
<> 154:37f96f9d4de2 186 i2cPrivateHandle->handle->state = kIdleState;
<> 154:37f96f9d4de2 187
<> 154:37f96f9d4de2 188 if (i2cPrivateHandle->handle->completionCallback)
<> 154:37f96f9d4de2 189 {
<> 154:37f96f9d4de2 190 i2cPrivateHandle->handle->completionCallback(i2cPrivateHandle->base, i2cPrivateHandle->handle, result,
<> 154:37f96f9d4de2 191 i2cPrivateHandle->handle->userData);
<> 154:37f96f9d4de2 192 }
<> 154:37f96f9d4de2 193 }
<> 154:37f96f9d4de2 194
<> 154:37f96f9d4de2 195 static status_t I2C_CheckAndClearError(I2C_Type *base, uint32_t status)
<> 154:37f96f9d4de2 196 {
<> 154:37f96f9d4de2 197 status_t result = kStatus_Success;
<> 154:37f96f9d4de2 198
<> 154:37f96f9d4de2 199 /* Check arbitration lost. */
<> 154:37f96f9d4de2 200 if (status & kI2C_ArbitrationLostFlag)
<> 154:37f96f9d4de2 201 {
<> 154:37f96f9d4de2 202 /* Clear arbitration lost flag. */
<> 154:37f96f9d4de2 203 base->S = kI2C_ArbitrationLostFlag;
<> 154:37f96f9d4de2 204 result = kStatus_I2C_ArbitrationLost;
<> 154:37f96f9d4de2 205 }
<> 154:37f96f9d4de2 206 /* Check NAK */
<> 154:37f96f9d4de2 207 else if (status & kI2C_ReceiveNakFlag)
<> 154:37f96f9d4de2 208 {
<> 154:37f96f9d4de2 209 result = kStatus_I2C_Nak;
<> 154:37f96f9d4de2 210 }
<> 154:37f96f9d4de2 211 else
<> 154:37f96f9d4de2 212 {
<> 154:37f96f9d4de2 213 }
<> 154:37f96f9d4de2 214
<> 154:37f96f9d4de2 215 return result;
<> 154:37f96f9d4de2 216 }
<> 154:37f96f9d4de2 217
<> 154:37f96f9d4de2 218 static status_t I2C_InitTransferStateMachineEDMA(I2C_Type *base,
<> 154:37f96f9d4de2 219 i2c_master_edma_handle_t *handle,
<> 154:37f96f9d4de2 220 i2c_master_transfer_t *xfer)
<> 154:37f96f9d4de2 221 {
<> 154:37f96f9d4de2 222 assert(handle);
<> 154:37f96f9d4de2 223 assert(xfer);
<> 154:37f96f9d4de2 224
<> 154:37f96f9d4de2 225 status_t result = kStatus_Success;
<> 154:37f96f9d4de2 226
<> 154:37f96f9d4de2 227 if (handle->state != kIdleState)
<> 154:37f96f9d4de2 228 {
<> 154:37f96f9d4de2 229 return kStatus_I2C_Busy;
<> 154:37f96f9d4de2 230 }
<> 154:37f96f9d4de2 231 else
<> 154:37f96f9d4de2 232 {
<> 154:37f96f9d4de2 233 i2c_direction_t direction = xfer->direction;
<> 154:37f96f9d4de2 234
<> 154:37f96f9d4de2 235 /* Init the handle member. */
<> 154:37f96f9d4de2 236 handle->transfer = *xfer;
<> 154:37f96f9d4de2 237
<> 154:37f96f9d4de2 238 /* Save total transfer size. */
<> 154:37f96f9d4de2 239 handle->transferSize = xfer->dataSize;
<> 154:37f96f9d4de2 240
<> 154:37f96f9d4de2 241 handle->state = kTransferDataState;
<> 154:37f96f9d4de2 242
<> 154:37f96f9d4de2 243 /* Clear all status before transfer. */
<> 154:37f96f9d4de2 244 I2C_MasterClearStatusFlags(base, kClearFlags);
<> 154:37f96f9d4de2 245
<> 154:37f96f9d4de2 246 /* Change to send write address when it's a read operation with command. */
<> 154:37f96f9d4de2 247 if ((xfer->subaddressSize > 0) && (xfer->direction == kI2C_Read))
<> 154:37f96f9d4de2 248 {
<> 154:37f96f9d4de2 249 direction = kI2C_Write;
<> 154:37f96f9d4de2 250 }
<> 154:37f96f9d4de2 251
<> 154:37f96f9d4de2 252 /* If repeated start is requested, send repeated start. */
<> 154:37f96f9d4de2 253 if (handle->transfer.flags & kI2C_TransferRepeatedStartFlag)
<> 154:37f96f9d4de2 254 {
<> 154:37f96f9d4de2 255 result = I2C_MasterRepeatedStart(base, handle->transfer.slaveAddress, direction);
<> 154:37f96f9d4de2 256 }
<> 154:37f96f9d4de2 257 else /* For normal transfer, send start. */
<> 154:37f96f9d4de2 258 {
<> 154:37f96f9d4de2 259 result = I2C_MasterStart(base, handle->transfer.slaveAddress, direction);
<> 154:37f96f9d4de2 260 }
<> 154:37f96f9d4de2 261
<> 154:37f96f9d4de2 262 if (result)
<> 154:37f96f9d4de2 263 {
<> 154:37f96f9d4de2 264 return result;
<> 154:37f96f9d4de2 265 }
<> 154:37f96f9d4de2 266
<> 154:37f96f9d4de2 267 while (!(base->S & kI2C_IntPendingFlag))
<> 154:37f96f9d4de2 268 {
<> 154:37f96f9d4de2 269 }
<> 154:37f96f9d4de2 270
<> 154:37f96f9d4de2 271 /* Check if there's transfer error. */
<> 154:37f96f9d4de2 272 result = I2C_CheckAndClearError(base, base->S);
<> 154:37f96f9d4de2 273
<> 154:37f96f9d4de2 274 /* Return if error. */
<> 154:37f96f9d4de2 275 if (result)
<> 154:37f96f9d4de2 276 {
<> 154:37f96f9d4de2 277 if (result == kStatus_I2C_Nak)
<> 154:37f96f9d4de2 278 {
<> 154:37f96f9d4de2 279 result = kStatus_I2C_Addr_Nak;
<> 154:37f96f9d4de2 280
<> 154:37f96f9d4de2 281 if (I2C_MasterStop(base) != kStatus_Success)
<> 154:37f96f9d4de2 282 {
<> 154:37f96f9d4de2 283 result = kStatus_I2C_Timeout;
<> 154:37f96f9d4de2 284 }
<> 154:37f96f9d4de2 285
<> 154:37f96f9d4de2 286 if (handle->completionCallback)
<> 154:37f96f9d4de2 287 {
<> 154:37f96f9d4de2 288 (handle->completionCallback)(base, handle, result, handle->userData);
<> 154:37f96f9d4de2 289 }
<> 154:37f96f9d4de2 290 }
<> 154:37f96f9d4de2 291
<> 154:37f96f9d4de2 292 return result;
<> 154:37f96f9d4de2 293 }
<> 154:37f96f9d4de2 294
<> 154:37f96f9d4de2 295 /* Send subaddress. */
<> 154:37f96f9d4de2 296 if (handle->transfer.subaddressSize)
<> 154:37f96f9d4de2 297 {
<> 154:37f96f9d4de2 298 do
<> 154:37f96f9d4de2 299 {
<> 154:37f96f9d4de2 300 /* Clear interrupt pending flag. */
<> 154:37f96f9d4de2 301 base->S = kI2C_IntPendingFlag;
<> 154:37f96f9d4de2 302
<> 154:37f96f9d4de2 303 handle->transfer.subaddressSize--;
<> 154:37f96f9d4de2 304 base->D = ((handle->transfer.subaddress) >> (8 * handle->transfer.subaddressSize));
<> 154:37f96f9d4de2 305
<> 154:37f96f9d4de2 306 /* Wait until data transfer complete. */
<> 154:37f96f9d4de2 307 while (!(base->S & kI2C_IntPendingFlag))
<> 154:37f96f9d4de2 308 {
<> 154:37f96f9d4de2 309 }
<> 154:37f96f9d4de2 310
<> 154:37f96f9d4de2 311 /* Check if there's transfer error. */
<> 154:37f96f9d4de2 312 result = I2C_CheckAndClearError(base, base->S);
<> 154:37f96f9d4de2 313
<> 154:37f96f9d4de2 314 if (result)
<> 154:37f96f9d4de2 315 {
<> 154:37f96f9d4de2 316 return result;
<> 154:37f96f9d4de2 317 }
<> 154:37f96f9d4de2 318
<> 154:37f96f9d4de2 319 } while ((handle->transfer.subaddressSize > 0) && (result == kStatus_Success));
<> 154:37f96f9d4de2 320
<> 154:37f96f9d4de2 321 if (handle->transfer.direction == kI2C_Read)
<> 154:37f96f9d4de2 322 {
<> 154:37f96f9d4de2 323 /* Clear pending flag. */
<> 154:37f96f9d4de2 324 base->S = kI2C_IntPendingFlag;
<> 154:37f96f9d4de2 325
<> 154:37f96f9d4de2 326 /* Send repeated start and slave address. */
<> 154:37f96f9d4de2 327 result = I2C_MasterRepeatedStart(base, handle->transfer.slaveAddress, kI2C_Read);
<> 154:37f96f9d4de2 328
<> 154:37f96f9d4de2 329 if (result)
<> 154:37f96f9d4de2 330 {
<> 154:37f96f9d4de2 331 return result;
<> 154:37f96f9d4de2 332 }
<> 154:37f96f9d4de2 333
<> 154:37f96f9d4de2 334 /* Wait until data transfer complete. */
<> 154:37f96f9d4de2 335 while (!(base->S & kI2C_IntPendingFlag))
<> 154:37f96f9d4de2 336 {
<> 154:37f96f9d4de2 337 }
<> 154:37f96f9d4de2 338
<> 154:37f96f9d4de2 339 /* Check if there's transfer error. */
<> 154:37f96f9d4de2 340 result = I2C_CheckAndClearError(base, base->S);
<> 154:37f96f9d4de2 341
<> 154:37f96f9d4de2 342 if (result)
<> 154:37f96f9d4de2 343 {
<> 154:37f96f9d4de2 344 return result;
<> 154:37f96f9d4de2 345 }
<> 154:37f96f9d4de2 346 }
<> 154:37f96f9d4de2 347 }
<> 154:37f96f9d4de2 348
<> 154:37f96f9d4de2 349 /* Clear pending flag. */
<> 154:37f96f9d4de2 350 base->S = kI2C_IntPendingFlag;
<> 154:37f96f9d4de2 351 }
<> 154:37f96f9d4de2 352
<> 154:37f96f9d4de2 353 return result;
<> 154:37f96f9d4de2 354 }
<> 154:37f96f9d4de2 355
<> 154:37f96f9d4de2 356 static void I2C_MasterTransferEDMAConfig(I2C_Type *base, i2c_master_edma_handle_t *handle)
<> 154:37f96f9d4de2 357 {
<> 154:37f96f9d4de2 358 edma_transfer_config_t transfer_config;
<> 154:37f96f9d4de2 359
<> 154:37f96f9d4de2 360 if (handle->transfer.direction == kI2C_Read)
<> 154:37f96f9d4de2 361 {
<> 154:37f96f9d4de2 362 transfer_config.srcAddr = (uint32_t)I2C_GetDataRegAddr(base);
<> 154:37f96f9d4de2 363 transfer_config.destAddr = (uint32_t)(handle->transfer.data);
<> 154:37f96f9d4de2 364 transfer_config.majorLoopCounts = (handle->transfer.dataSize - 1);
<> 154:37f96f9d4de2 365 transfer_config.srcTransferSize = kEDMA_TransferSize1Bytes;
<> 154:37f96f9d4de2 366 transfer_config.srcOffset = 0;
<> 154:37f96f9d4de2 367 transfer_config.destTransferSize = kEDMA_TransferSize1Bytes;
<> 154:37f96f9d4de2 368 transfer_config.destOffset = 1;
<> 154:37f96f9d4de2 369 transfer_config.minorLoopBytes = 1;
<> 154:37f96f9d4de2 370 }
<> 154:37f96f9d4de2 371 else
<> 154:37f96f9d4de2 372 {
<> 154:37f96f9d4de2 373 transfer_config.srcAddr = (uint32_t)(handle->transfer.data + 1);
<> 154:37f96f9d4de2 374 transfer_config.destAddr = (uint32_t)I2C_GetDataRegAddr(base);
<> 154:37f96f9d4de2 375 transfer_config.majorLoopCounts = (handle->transfer.dataSize - 1);
<> 154:37f96f9d4de2 376 transfer_config.srcTransferSize = kEDMA_TransferSize1Bytes;
<> 154:37f96f9d4de2 377 transfer_config.srcOffset = 1;
<> 154:37f96f9d4de2 378 transfer_config.destTransferSize = kEDMA_TransferSize1Bytes;
<> 154:37f96f9d4de2 379 transfer_config.destOffset = 0;
<> 154:37f96f9d4de2 380 transfer_config.minorLoopBytes = 1;
<> 154:37f96f9d4de2 381 }
<> 154:37f96f9d4de2 382
<> 154:37f96f9d4de2 383 /* Store the initially configured eDMA minor byte transfer count into the I2C handle */
<> 154:37f96f9d4de2 384 handle->nbytes = transfer_config.minorLoopBytes;
<> 154:37f96f9d4de2 385
<> 154:37f96f9d4de2 386 EDMA_SubmitTransfer(handle->dmaHandle, &transfer_config);
<> 154:37f96f9d4de2 387 EDMA_StartTransfer(handle->dmaHandle);
<> 154:37f96f9d4de2 388 }
<> 154:37f96f9d4de2 389
<> 154:37f96f9d4de2 390 void I2C_MasterCreateEDMAHandle(I2C_Type *base,
<> 154:37f96f9d4de2 391 i2c_master_edma_handle_t *handle,
<> 154:37f96f9d4de2 392 i2c_master_edma_transfer_callback_t callback,
<> 154:37f96f9d4de2 393 void *userData,
<> 154:37f96f9d4de2 394 edma_handle_t *edmaHandle)
<> 154:37f96f9d4de2 395 {
<> 154:37f96f9d4de2 396 assert(handle);
<> 154:37f96f9d4de2 397 assert(edmaHandle);
<> 154:37f96f9d4de2 398
<> 154:37f96f9d4de2 399 uint32_t instance = I2C_GetInstance(base);
<> 154:37f96f9d4de2 400
<> 154:37f96f9d4de2 401 /* Zero handle. */
<> 154:37f96f9d4de2 402 memset(handle, 0, sizeof(*handle));
<> 154:37f96f9d4de2 403
<> 154:37f96f9d4de2 404 /* Set the user callback and userData. */
<> 154:37f96f9d4de2 405 handle->completionCallback = callback;
<> 154:37f96f9d4de2 406 handle->userData = userData;
<> 154:37f96f9d4de2 407
<> 154:37f96f9d4de2 408 /* Set the base for the handle. */
<> 154:37f96f9d4de2 409 base = base;
<> 154:37f96f9d4de2 410
<> 154:37f96f9d4de2 411 /* Set the handle for EDMA. */
<> 154:37f96f9d4de2 412 handle->dmaHandle = edmaHandle;
<> 154:37f96f9d4de2 413
<> 154:37f96f9d4de2 414 s_edmaPrivateHandle[instance].base = base;
<> 154:37f96f9d4de2 415 s_edmaPrivateHandle[instance].handle = handle;
<> 154:37f96f9d4de2 416
<> 154:37f96f9d4de2 417 EDMA_SetCallback(edmaHandle, (edma_callback)I2C_MasterTransferCallbackEDMA, &s_edmaPrivateHandle[instance]);
<> 154:37f96f9d4de2 418 }
<> 154:37f96f9d4de2 419
<> 154:37f96f9d4de2 420 status_t I2C_MasterTransferEDMA(I2C_Type *base, i2c_master_edma_handle_t *handle, i2c_master_transfer_t *xfer)
<> 154:37f96f9d4de2 421 {
<> 154:37f96f9d4de2 422 assert(handle);
<> 154:37f96f9d4de2 423 assert(xfer);
<> 154:37f96f9d4de2 424
<> 154:37f96f9d4de2 425 status_t result;
<> 154:37f96f9d4de2 426 uint8_t tmpReg;
<> 154:37f96f9d4de2 427 volatile uint8_t dummy = 0;
<> 154:37f96f9d4de2 428
<> 154:37f96f9d4de2 429 /* Add this to avoid build warning. */
<> 154:37f96f9d4de2 430 dummy++;
<> 154:37f96f9d4de2 431
<> 154:37f96f9d4de2 432 /* Disable dma xfer. */
<> 154:37f96f9d4de2 433 I2C_EnableDMA(base, false);
<> 154:37f96f9d4de2 434
<> 154:37f96f9d4de2 435 /* Send address and command buffer(if there is), until senddata phase or receive data phase. */
<> 154:37f96f9d4de2 436 result = I2C_InitTransferStateMachineEDMA(base, handle, xfer);
<> 154:37f96f9d4de2 437
<> 154:37f96f9d4de2 438 if (result)
<> 154:37f96f9d4de2 439 {
<> 154:37f96f9d4de2 440 /* Send stop if received Nak. */
<> 154:37f96f9d4de2 441 if (result == kStatus_I2C_Nak)
<> 154:37f96f9d4de2 442 {
<> 154:37f96f9d4de2 443 if (I2C_MasterStop(base) != kStatus_Success)
<> 154:37f96f9d4de2 444 {
<> 154:37f96f9d4de2 445 result = kStatus_I2C_Timeout;
<> 154:37f96f9d4de2 446 }
<> 154:37f96f9d4de2 447 }
<> 154:37f96f9d4de2 448
<> 154:37f96f9d4de2 449 /* Reset the state to idle state. */
<> 154:37f96f9d4de2 450 handle->state = kIdleState;
<> 154:37f96f9d4de2 451
<> 154:37f96f9d4de2 452 return result;
<> 154:37f96f9d4de2 453 }
<> 154:37f96f9d4de2 454
<> 154:37f96f9d4de2 455 /* Configure dma transfer. */
<> 154:37f96f9d4de2 456 /* For i2c send, need to send 1 byte first to trigger the dma, for i2c read,
<> 154:37f96f9d4de2 457 need to send stop before reading the last byte, so the dma transfer size should
<> 154:37f96f9d4de2 458 be (xSize - 1). */
<> 154:37f96f9d4de2 459 if (handle->transfer.dataSize > 1)
<> 154:37f96f9d4de2 460 {
<> 154:37f96f9d4de2 461 I2C_MasterTransferEDMAConfig(base, handle);
<> 154:37f96f9d4de2 462 if (handle->transfer.direction == kI2C_Read)
<> 154:37f96f9d4de2 463 {
<> 154:37f96f9d4de2 464 /* Change direction for receive. */
<> 154:37f96f9d4de2 465 base->C1 &= ~(I2C_C1_TX_MASK | I2C_C1_TXAK_MASK);
<> 154:37f96f9d4de2 466
<> 154:37f96f9d4de2 467 /* Read dummy to release the bus. */
<> 154:37f96f9d4de2 468 dummy = base->D;
<> 154:37f96f9d4de2 469
<> 154:37f96f9d4de2 470 /* Enabe dma transfer. */
<> 154:37f96f9d4de2 471 I2C_EnableDMA(base, true);
<> 154:37f96f9d4de2 472 }
<> 154:37f96f9d4de2 473 else
<> 154:37f96f9d4de2 474 {
<> 154:37f96f9d4de2 475 /* Enabe dma transfer. */
<> 154:37f96f9d4de2 476 I2C_EnableDMA(base, true);
<> 154:37f96f9d4de2 477
<> 154:37f96f9d4de2 478 /* Send the first data. */
<> 154:37f96f9d4de2 479 base->D = *handle->transfer.data;
<> 154:37f96f9d4de2 480 }
<> 154:37f96f9d4de2 481 }
<> 154:37f96f9d4de2 482 else /* If transfer size is 1, use polling method. */
<> 154:37f96f9d4de2 483 {
<> 154:37f96f9d4de2 484 if (handle->transfer.direction == kI2C_Read)
<> 154:37f96f9d4de2 485 {
<> 154:37f96f9d4de2 486 tmpReg = base->C1;
<> 154:37f96f9d4de2 487
<> 154:37f96f9d4de2 488 /* Change direction to Rx. */
<> 154:37f96f9d4de2 489 tmpReg &= ~I2C_C1_TX_MASK;
<> 154:37f96f9d4de2 490
<> 154:37f96f9d4de2 491 /* Configure send NAK */
<> 154:37f96f9d4de2 492 tmpReg |= I2C_C1_TXAK_MASK;
<> 154:37f96f9d4de2 493
<> 154:37f96f9d4de2 494 base->C1 = tmpReg;
<> 154:37f96f9d4de2 495
<> 154:37f96f9d4de2 496 /* Read dummy to release the bus. */
<> 154:37f96f9d4de2 497 dummy = base->D;
<> 154:37f96f9d4de2 498 }
<> 154:37f96f9d4de2 499 else
<> 154:37f96f9d4de2 500 {
<> 154:37f96f9d4de2 501 base->D = *handle->transfer.data;
<> 154:37f96f9d4de2 502 }
<> 154:37f96f9d4de2 503
<> 154:37f96f9d4de2 504 /* Wait until data transfer complete. */
<> 154:37f96f9d4de2 505 while (!(base->S & kI2C_IntPendingFlag))
<> 154:37f96f9d4de2 506 {
<> 154:37f96f9d4de2 507 }
<> 154:37f96f9d4de2 508
<> 154:37f96f9d4de2 509 /* Clear pending flag. */
<> 154:37f96f9d4de2 510 base->S = kI2C_IntPendingFlag;
<> 154:37f96f9d4de2 511
<> 154:37f96f9d4de2 512 /* Send stop if kI2C_TransferNoStop flag is not asserted. */
<> 154:37f96f9d4de2 513 if (!(handle->transfer.flags & kI2C_TransferNoStopFlag))
<> 154:37f96f9d4de2 514 {
<> 154:37f96f9d4de2 515 result = I2C_MasterStop(base);
<> 154:37f96f9d4de2 516 }
<> 154:37f96f9d4de2 517 else
<> 154:37f96f9d4de2 518 {
<> 154:37f96f9d4de2 519 /* Change direction to send. */
<> 154:37f96f9d4de2 520 base->C1 |= I2C_C1_TX_MASK;
<> 154:37f96f9d4de2 521 }
<> 154:37f96f9d4de2 522
<> 154:37f96f9d4de2 523 /* Read the last byte of data. */
<> 154:37f96f9d4de2 524 if (handle->transfer.direction == kI2C_Read)
<> 154:37f96f9d4de2 525 {
<> 154:37f96f9d4de2 526 *handle->transfer.data = base->D;
<> 154:37f96f9d4de2 527 }
<> 154:37f96f9d4de2 528
<> 154:37f96f9d4de2 529 /* Reset the state to idle. */
<> 154:37f96f9d4de2 530 handle->state = kIdleState;
<> 154:37f96f9d4de2 531 }
<> 154:37f96f9d4de2 532
<> 154:37f96f9d4de2 533 return result;
<> 154:37f96f9d4de2 534 }
<> 154:37f96f9d4de2 535
<> 154:37f96f9d4de2 536 status_t I2C_MasterTransferGetCountEDMA(I2C_Type *base, i2c_master_edma_handle_t *handle, size_t *count)
<> 154:37f96f9d4de2 537 {
<> 154:37f96f9d4de2 538 assert(handle->dmaHandle);
<> 154:37f96f9d4de2 539
<> 154:37f96f9d4de2 540 if (!count)
<> 154:37f96f9d4de2 541 {
<> 154:37f96f9d4de2 542 return kStatus_InvalidArgument;
<> 154:37f96f9d4de2 543 }
<> 154:37f96f9d4de2 544
<> 154:37f96f9d4de2 545 if (kIdleState != handle->state)
<> 154:37f96f9d4de2 546 {
<> 154:37f96f9d4de2 547 *count = (handle->transferSize -
<> 154:37f96f9d4de2 548 (uint32_t)handle->nbytes *
<> 154:37f96f9d4de2 549 EDMA_GetRemainingMajorLoopCount(handle->dmaHandle->base, handle->dmaHandle->channel));
<> 154:37f96f9d4de2 550 }
<> 154:37f96f9d4de2 551 else
<> 154:37f96f9d4de2 552 {
<> 154:37f96f9d4de2 553 *count = handle->transferSize;
<> 154:37f96f9d4de2 554 }
<> 154:37f96f9d4de2 555
<> 154:37f96f9d4de2 556 return kStatus_Success;
<> 154:37f96f9d4de2 557 }
<> 154:37f96f9d4de2 558
<> 154:37f96f9d4de2 559 void I2C_MasterTransferAbortEDMA(I2C_Type *base, i2c_master_edma_handle_t *handle)
<> 154:37f96f9d4de2 560 {
<> 154:37f96f9d4de2 561 EDMA_AbortTransfer(handle->dmaHandle);
<> 154:37f96f9d4de2 562
<> 154:37f96f9d4de2 563 /* Disable dma transfer. */
<> 154:37f96f9d4de2 564 I2C_EnableDMA(base, false);
<> 154:37f96f9d4de2 565
<> 154:37f96f9d4de2 566 /* Reset the state to idle. */
<> 154:37f96f9d4de2 567 handle->state = kIdleState;
<> 154:37f96f9d4de2 568 }