Gordon Craig / mbed-dev

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_dma.h"
<> 154:37f96f9d4de2 32
<> 154:37f96f9d4de2 33 /*******************************************************************************
<> 154:37f96f9d4de2 34 * Definitions
<> 154:37f96f9d4de2 35 ******************************************************************************/
<> 154:37f96f9d4de2 36
<> 154:37f96f9d4de2 37 /*<! @brief Structure definition for i2c_master_dma_handle_t. The structure is private. */
<> 154:37f96f9d4de2 38 typedef struct _i2c_master_dma_private_handle
<> 154:37f96f9d4de2 39 {
<> 154:37f96f9d4de2 40 I2C_Type *base;
<> 154:37f96f9d4de2 41 i2c_master_dma_handle_t *handle;
<> 154:37f96f9d4de2 42 } i2c_master_dma_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 DMA callback for I2C master DMA driver.
<> 154:37f96f9d4de2 70 *
<> 154:37f96f9d4de2 71 * @param handle DMA handler for I2C master DMA driver
<> 154:37f96f9d4de2 72 * @param userData user param passed to the callback function
<> 154:37f96f9d4de2 73 */
<> 154:37f96f9d4de2 74 static void I2C_MasterTransferCallbackDMA(dma_handle_t *handle, void *userData);
<> 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 DMA 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_dma_handle_t structure which stores the transfer state.
<> 154:37f96f9d4de2 92 */
<> 154:37f96f9d4de2 93 static void I2C_MasterTransferDMAConfig(I2C_Type *base, i2c_master_dma_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_dma_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_InitTransferStateMachineDMA(I2C_Type *base,
<> 154:37f96f9d4de2 104 i2c_master_dma_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_dma_private_handle_t s_dmaPrivateHandle[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_MasterTransferCallbackDMA(dma_handle_t *handle, void *userData)
<> 154:37f96f9d4de2 127 {
<> 154:37f96f9d4de2 128 i2c_master_dma_private_handle_t *i2cPrivateHandle = (i2c_master_dma_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
<> 154:37f96f9d4de2 166 i2cPrivateHandle->handle->state = kIdleState;
<> 154:37f96f9d4de2 167
<> 154:37f96f9d4de2 168 if (i2cPrivateHandle->handle->completionCallback)
<> 154:37f96f9d4de2 169 {
<> 154:37f96f9d4de2 170 i2cPrivateHandle->handle->completionCallback(i2cPrivateHandle->base, i2cPrivateHandle->handle, result,
<> 154:37f96f9d4de2 171 i2cPrivateHandle->handle->userData);
<> 154:37f96f9d4de2 172 }
<> 154:37f96f9d4de2 173 }
<> 154:37f96f9d4de2 174
<> 154:37f96f9d4de2 175 static status_t I2C_CheckAndClearError(I2C_Type *base, uint32_t status)
<> 154:37f96f9d4de2 176 {
<> 154:37f96f9d4de2 177 status_t result = kStatus_Success;
<> 154:37f96f9d4de2 178
<> 154:37f96f9d4de2 179 /* Check arbitration lost. */
<> 154:37f96f9d4de2 180 if (status & kI2C_ArbitrationLostFlag)
<> 154:37f96f9d4de2 181 {
<> 154:37f96f9d4de2 182 /* Clear arbitration lost flag. */
<> 154:37f96f9d4de2 183 base->S = kI2C_ArbitrationLostFlag;
<> 154:37f96f9d4de2 184 result = kStatus_I2C_ArbitrationLost;
<> 154:37f96f9d4de2 185 }
<> 154:37f96f9d4de2 186 /* Check NAK */
<> 154:37f96f9d4de2 187 else if (status & kI2C_ReceiveNakFlag)
<> 154:37f96f9d4de2 188 {
<> 154:37f96f9d4de2 189 result = kStatus_I2C_Nak;
<> 154:37f96f9d4de2 190 }
<> 154:37f96f9d4de2 191 else
<> 154:37f96f9d4de2 192 {
<> 154:37f96f9d4de2 193 }
<> 154:37f96f9d4de2 194
<> 154:37f96f9d4de2 195 return result;
<> 154:37f96f9d4de2 196 }
<> 154:37f96f9d4de2 197
<> 154:37f96f9d4de2 198 static status_t I2C_InitTransferStateMachineDMA(I2C_Type *base,
<> 154:37f96f9d4de2 199 i2c_master_dma_handle_t *handle,
<> 154:37f96f9d4de2 200 i2c_master_transfer_t *xfer)
<> 154:37f96f9d4de2 201 {
<> 154:37f96f9d4de2 202 assert(handle);
<> 154:37f96f9d4de2 203 assert(xfer);
<> 154:37f96f9d4de2 204
<> 154:37f96f9d4de2 205 /* Set up transfer first. */
<> 154:37f96f9d4de2 206 i2c_direction_t direction = xfer->direction;
<> 154:37f96f9d4de2 207 status_t result = kStatus_Success;
<> 154:37f96f9d4de2 208 uint16_t timeout = UINT16_MAX;
<> 154:37f96f9d4de2 209
<> 154:37f96f9d4de2 210 if (handle->state != kIdleState)
<> 154:37f96f9d4de2 211 {
<> 154:37f96f9d4de2 212 return kStatus_I2C_Busy;
<> 154:37f96f9d4de2 213 }
<> 154:37f96f9d4de2 214 else
<> 154:37f96f9d4de2 215 {
<> 154:37f96f9d4de2 216 /* Init the handle member. */
<> 154:37f96f9d4de2 217 handle->transfer = *xfer;
<> 154:37f96f9d4de2 218
<> 154:37f96f9d4de2 219 /* Save total transfer size. */
<> 154:37f96f9d4de2 220 handle->transferSize = xfer->dataSize;
<> 154:37f96f9d4de2 221
<> 154:37f96f9d4de2 222 handle->state = kTransferDataState;
<> 154:37f96f9d4de2 223
<> 154:37f96f9d4de2 224 /* Wait until ready to complete. */
<> 154:37f96f9d4de2 225 while ((!(base->S & kI2C_TransferCompleteFlag)) && (--timeout))
<> 154:37f96f9d4de2 226 {
<> 154:37f96f9d4de2 227 }
<> 154:37f96f9d4de2 228
<> 154:37f96f9d4de2 229 /* Failed to start the transfer. */
<> 154:37f96f9d4de2 230 if (timeout == 0)
<> 154:37f96f9d4de2 231 {
<> 154:37f96f9d4de2 232 return kStatus_I2C_Timeout;
<> 154:37f96f9d4de2 233 }
<> 154:37f96f9d4de2 234
<> 154:37f96f9d4de2 235 /* Clear all status before transfer. */
<> 154:37f96f9d4de2 236 I2C_MasterClearStatusFlags(base, kClearFlags);
<> 154:37f96f9d4de2 237
<> 154:37f96f9d4de2 238 /* Change to send write address when it's a read operation with command. */
<> 154:37f96f9d4de2 239 if ((xfer->subaddressSize > 0) && (xfer->direction == kI2C_Read))
<> 154:37f96f9d4de2 240 {
<> 154:37f96f9d4de2 241 direction = kI2C_Write;
<> 154:37f96f9d4de2 242 }
<> 154:37f96f9d4de2 243
<> 154:37f96f9d4de2 244 /* If repeated start is requested, send repeated start. */
<> 154:37f96f9d4de2 245 if (handle->transfer.flags & kI2C_TransferRepeatedStartFlag)
<> 154:37f96f9d4de2 246 {
<> 154:37f96f9d4de2 247 result = I2C_MasterRepeatedStart(base, handle->transfer.slaveAddress, direction);
<> 154:37f96f9d4de2 248 }
<> 154:37f96f9d4de2 249 else /* For normal transfer, send start. */
<> 154:37f96f9d4de2 250 {
<> 154:37f96f9d4de2 251 result = I2C_MasterStart(base, handle->transfer.slaveAddress, direction);
<> 154:37f96f9d4de2 252 }
<> 154:37f96f9d4de2 253
<> 154:37f96f9d4de2 254 /* Send subaddress. */
<> 154:37f96f9d4de2 255 if (handle->transfer.subaddressSize)
<> 154:37f96f9d4de2 256 {
<> 154:37f96f9d4de2 257 do
<> 154:37f96f9d4de2 258 {
<> 154:37f96f9d4de2 259 /* Wait until data transfer complete. */
<> 154:37f96f9d4de2 260 while (!(base->S & kI2C_IntPendingFlag))
<> 154:37f96f9d4de2 261 {
<> 154:37f96f9d4de2 262 }
<> 154:37f96f9d4de2 263
<> 154:37f96f9d4de2 264 /* Clear interrupt pending flag. */
<> 154:37f96f9d4de2 265 base->S = kI2C_IntPendingFlag;
<> 154:37f96f9d4de2 266
<> 154:37f96f9d4de2 267 handle->transfer.subaddressSize--;
<> 154:37f96f9d4de2 268 base->D = ((handle->transfer.subaddress) >> (8 * handle->transfer.subaddressSize));
<> 154:37f96f9d4de2 269
<> 154:37f96f9d4de2 270 /* Check if there's transfer error. */
<> 154:37f96f9d4de2 271 result = I2C_CheckAndClearError(base, base->S);
<> 154:37f96f9d4de2 272
<> 154:37f96f9d4de2 273 if (result)
<> 154:37f96f9d4de2 274 {
<> 154:37f96f9d4de2 275 return result;
<> 154:37f96f9d4de2 276 }
<> 154:37f96f9d4de2 277
<> 154:37f96f9d4de2 278 } while ((handle->transfer.subaddressSize > 0) && (result == kStatus_Success));
<> 154:37f96f9d4de2 279
<> 154:37f96f9d4de2 280 if (handle->transfer.direction == kI2C_Read)
<> 154:37f96f9d4de2 281 {
<> 154:37f96f9d4de2 282 /* Wait until data transfer complete. */
<> 154:37f96f9d4de2 283 while (!(base->S & kI2C_IntPendingFlag))
<> 154:37f96f9d4de2 284 {
<> 154:37f96f9d4de2 285 }
<> 154:37f96f9d4de2 286
<> 154:37f96f9d4de2 287 /* Clear pending flag. */
<> 154:37f96f9d4de2 288 base->S = kI2C_IntPendingFlag;
<> 154:37f96f9d4de2 289
<> 154:37f96f9d4de2 290 /* Send repeated start and slave address. */
<> 154:37f96f9d4de2 291 result = I2C_MasterRepeatedStart(base, handle->transfer.slaveAddress, kI2C_Read);
<> 154:37f96f9d4de2 292 }
<> 154:37f96f9d4de2 293 }
<> 154:37f96f9d4de2 294
<> 154:37f96f9d4de2 295 if (result)
<> 154:37f96f9d4de2 296 {
<> 154:37f96f9d4de2 297 return result;
<> 154:37f96f9d4de2 298 }
<> 154:37f96f9d4de2 299
<> 154:37f96f9d4de2 300 /* Wait until data transfer complete. */
<> 154:37f96f9d4de2 301 while (!(base->S & kI2C_IntPendingFlag))
<> 154:37f96f9d4de2 302 {
<> 154:37f96f9d4de2 303 }
<> 154:37f96f9d4de2 304
<> 154:37f96f9d4de2 305 /* Clear pending flag. */
<> 154:37f96f9d4de2 306 base->S = kI2C_IntPendingFlag;
<> 154:37f96f9d4de2 307
<> 154:37f96f9d4de2 308 /* Check if there's transfer error. */
<> 154:37f96f9d4de2 309 result = I2C_CheckAndClearError(base, base->S);
<> 154:37f96f9d4de2 310 }
<> 154:37f96f9d4de2 311
<> 154:37f96f9d4de2 312 return result;
<> 154:37f96f9d4de2 313 }
<> 154:37f96f9d4de2 314
<> 154:37f96f9d4de2 315 static void I2C_MasterTransferDMAConfig(I2C_Type *base, i2c_master_dma_handle_t *handle)
<> 154:37f96f9d4de2 316 {
<> 154:37f96f9d4de2 317 dma_transfer_config_t transfer_config;
<> 154:37f96f9d4de2 318 dma_transfer_options_t transfer_options = kDMA_EnableInterrupt;
<> 154:37f96f9d4de2 319
<> 154:37f96f9d4de2 320 if (handle->transfer.direction == kI2C_Read)
<> 154:37f96f9d4de2 321 {
<> 154:37f96f9d4de2 322 transfer_config.srcAddr = (uint32_t)I2C_GetDataRegAddr(base);
<> 154:37f96f9d4de2 323 transfer_config.destAddr = (uint32_t)(handle->transfer.data);
<> 154:37f96f9d4de2 324
<> 154:37f96f9d4de2 325 /* Send stop if kI2C_TransferNoStop flag is not asserted. */
<> 154:37f96f9d4de2 326 if (!(handle->transfer.flags & kI2C_TransferNoStopFlag))
<> 154:37f96f9d4de2 327 {
<> 154:37f96f9d4de2 328 transfer_config.transferSize = (handle->transfer.dataSize - 1);
<> 154:37f96f9d4de2 329 }
<> 154:37f96f9d4de2 330 else
<> 154:37f96f9d4de2 331 {
<> 154:37f96f9d4de2 332 transfer_config.transferSize = handle->transfer.dataSize;
<> 154:37f96f9d4de2 333 }
<> 154:37f96f9d4de2 334
<> 154:37f96f9d4de2 335 transfer_config.srcSize = kDMA_Transfersize8bits;
<> 154:37f96f9d4de2 336 transfer_config.enableSrcIncrement = false;
<> 154:37f96f9d4de2 337 transfer_config.destSize = kDMA_Transfersize8bits;
<> 154:37f96f9d4de2 338 transfer_config.enableDestIncrement = true;
<> 154:37f96f9d4de2 339 }
<> 154:37f96f9d4de2 340 else
<> 154:37f96f9d4de2 341 {
<> 154:37f96f9d4de2 342 transfer_config.srcAddr = (uint32_t)(handle->transfer.data + 1);
<> 154:37f96f9d4de2 343 transfer_config.destAddr = (uint32_t)I2C_GetDataRegAddr(base);
<> 154:37f96f9d4de2 344 transfer_config.transferSize = (handle->transfer.dataSize - 1);
<> 154:37f96f9d4de2 345 transfer_config.srcSize = kDMA_Transfersize8bits;
<> 154:37f96f9d4de2 346 transfer_config.enableSrcIncrement = true;
<> 154:37f96f9d4de2 347 transfer_config.destSize = kDMA_Transfersize8bits;
<> 154:37f96f9d4de2 348 transfer_config.enableDestIncrement = false;
<> 154:37f96f9d4de2 349 }
<> 154:37f96f9d4de2 350
<> 154:37f96f9d4de2 351 DMA_SubmitTransfer(handle->dmaHandle, &transfer_config, transfer_options);
<> 154:37f96f9d4de2 352 DMA_StartTransfer(handle->dmaHandle);
<> 154:37f96f9d4de2 353 }
<> 154:37f96f9d4de2 354
<> 154:37f96f9d4de2 355 void I2C_MasterTransferCreateHandleDMA(I2C_Type *base,
<> 154:37f96f9d4de2 356 i2c_master_dma_handle_t *handle,
<> 154:37f96f9d4de2 357 i2c_master_dma_transfer_callback_t callback,
<> 154:37f96f9d4de2 358 void *userData,
<> 154:37f96f9d4de2 359 dma_handle_t *dmaHandle)
<> 154:37f96f9d4de2 360 {
<> 154:37f96f9d4de2 361 assert(handle);
<> 154:37f96f9d4de2 362 assert(dmaHandle);
<> 154:37f96f9d4de2 363
<> 154:37f96f9d4de2 364 uint32_t instance = I2C_GetInstance(base);
<> 154:37f96f9d4de2 365
<> 154:37f96f9d4de2 366 /* Zero handle. */
<> 154:37f96f9d4de2 367 memset(handle, 0, sizeof(*handle));
<> 154:37f96f9d4de2 368
<> 154:37f96f9d4de2 369 /* Set the user callback and userData. */
<> 154:37f96f9d4de2 370 handle->completionCallback = callback;
<> 154:37f96f9d4de2 371 handle->userData = userData;
<> 154:37f96f9d4de2 372
<> 154:37f96f9d4de2 373 /* Set the handle for DMA. */
<> 154:37f96f9d4de2 374 handle->dmaHandle = dmaHandle;
<> 154:37f96f9d4de2 375
<> 154:37f96f9d4de2 376 s_dmaPrivateHandle[instance].base = base;
<> 154:37f96f9d4de2 377 s_dmaPrivateHandle[instance].handle = handle;
<> 154:37f96f9d4de2 378
<> 154:37f96f9d4de2 379 DMA_SetCallback(dmaHandle, (dma_callback)I2C_MasterTransferCallbackDMA, &s_dmaPrivateHandle[instance]);
<> 154:37f96f9d4de2 380 }
<> 154:37f96f9d4de2 381
<> 154:37f96f9d4de2 382 status_t I2C_MasterTransferDMA(I2C_Type *base, i2c_master_dma_handle_t *handle, i2c_master_transfer_t *xfer)
<> 154:37f96f9d4de2 383 {
<> 154:37f96f9d4de2 384 assert(handle);
<> 154:37f96f9d4de2 385 assert(xfer);
<> 154:37f96f9d4de2 386
<> 154:37f96f9d4de2 387 status_t result;
<> 154:37f96f9d4de2 388 uint8_t tmpReg;
<> 154:37f96f9d4de2 389 volatile uint8_t dummy = 0;
<> 154:37f96f9d4de2 390
<> 154:37f96f9d4de2 391 /* Add this to avoid build warning. */
<> 154:37f96f9d4de2 392 dummy++;
<> 154:37f96f9d4de2 393
<> 154:37f96f9d4de2 394 /* Disable dma transfer. */
<> 154:37f96f9d4de2 395 I2C_EnableDMA(base, false);
<> 154:37f96f9d4de2 396
<> 154:37f96f9d4de2 397 /* Send address and command buffer(if there is), until senddata phase or receive data phase. */
<> 154:37f96f9d4de2 398 result = I2C_InitTransferStateMachineDMA(base, handle, xfer);
<> 154:37f96f9d4de2 399
<> 154:37f96f9d4de2 400 if (result != kStatus_Success)
<> 154:37f96f9d4de2 401 {
<> 154:37f96f9d4de2 402 /* Send stop if received Nak. */
<> 154:37f96f9d4de2 403 if (result == kStatus_I2C_Nak)
<> 154:37f96f9d4de2 404 {
<> 154:37f96f9d4de2 405 if (I2C_MasterStop(base) != kStatus_Success)
<> 154:37f96f9d4de2 406 {
<> 154:37f96f9d4de2 407 result = kStatus_I2C_Timeout;
<> 154:37f96f9d4de2 408 }
<> 154:37f96f9d4de2 409 }
<> 154:37f96f9d4de2 410
<> 154:37f96f9d4de2 411 /* Reset the state to idle state. */
<> 154:37f96f9d4de2 412 handle->state = kIdleState;
<> 154:37f96f9d4de2 413
<> 154:37f96f9d4de2 414 return result;
<> 154:37f96f9d4de2 415 }
<> 154:37f96f9d4de2 416
<> 154:37f96f9d4de2 417 /* Configure dma transfer. */
<> 154:37f96f9d4de2 418 /* For i2c send, need to send 1 byte first to trigger the dma, for i2c read,
<> 154:37f96f9d4de2 419 need to send stop before reading the last byte, so the dma transfer size should
<> 154:37f96f9d4de2 420 be (xSize - 1). */
<> 154:37f96f9d4de2 421 if (handle->transfer.dataSize > 1)
<> 154:37f96f9d4de2 422 {
<> 154:37f96f9d4de2 423 I2C_MasterTransferDMAConfig(base, handle);
<> 154:37f96f9d4de2 424 if (handle->transfer.direction == kI2C_Read)
<> 154:37f96f9d4de2 425 {
<> 154:37f96f9d4de2 426 /* Change direction for receive. */
<> 154:37f96f9d4de2 427 base->C1 &= ~I2C_C1_TX_MASK;
<> 154:37f96f9d4de2 428
<> 154:37f96f9d4de2 429 /* Read dummy to release the bus. */
<> 154:37f96f9d4de2 430 dummy = base->D;
<> 154:37f96f9d4de2 431
<> 154:37f96f9d4de2 432 /* Enabe dma transfer. */
<> 154:37f96f9d4de2 433 I2C_EnableDMA(base, true);
<> 154:37f96f9d4de2 434 }
<> 154:37f96f9d4de2 435 else
<> 154:37f96f9d4de2 436 {
<> 154:37f96f9d4de2 437 /* Enabe dma transfer. */
<> 154:37f96f9d4de2 438 I2C_EnableDMA(base, true);
<> 154:37f96f9d4de2 439
<> 154:37f96f9d4de2 440 /* Send the first data. */
<> 154:37f96f9d4de2 441 base->D = *handle->transfer.data;
<> 154:37f96f9d4de2 442 }
<> 154:37f96f9d4de2 443 }
<> 154:37f96f9d4de2 444 else /* If transfer size is 1, use polling method. */
<> 154:37f96f9d4de2 445 {
<> 154:37f96f9d4de2 446 if (handle->transfer.direction == kI2C_Read)
<> 154:37f96f9d4de2 447 {
<> 154:37f96f9d4de2 448 tmpReg = base->C1;
<> 154:37f96f9d4de2 449
<> 154:37f96f9d4de2 450 /* Change direction to Rx. */
<> 154:37f96f9d4de2 451 tmpReg &= ~I2C_C1_TX_MASK;
<> 154:37f96f9d4de2 452
<> 154:37f96f9d4de2 453 /* Configure send NAK */
<> 154:37f96f9d4de2 454 tmpReg |= I2C_C1_TXAK_MASK;
<> 154:37f96f9d4de2 455
<> 154:37f96f9d4de2 456 base->C1 = tmpReg;
<> 154:37f96f9d4de2 457
<> 154:37f96f9d4de2 458 /* Read dummy to release the bus. */
<> 154:37f96f9d4de2 459 dummy = base->D;
<> 154:37f96f9d4de2 460 }
<> 154:37f96f9d4de2 461 else
<> 154:37f96f9d4de2 462 {
<> 154:37f96f9d4de2 463 base->D = *handle->transfer.data;
<> 154:37f96f9d4de2 464 }
<> 154:37f96f9d4de2 465
<> 154:37f96f9d4de2 466 /* Wait until data transfer complete. */
<> 154:37f96f9d4de2 467 while (!(base->S & kI2C_IntPendingFlag))
<> 154:37f96f9d4de2 468 {
<> 154:37f96f9d4de2 469 }
<> 154:37f96f9d4de2 470
<> 154:37f96f9d4de2 471 /* Clear pending flag. */
<> 154:37f96f9d4de2 472 base->S = kI2C_IntPendingFlag;
<> 154:37f96f9d4de2 473
<> 154:37f96f9d4de2 474 /* Send stop if kI2C_TransferNoStop flag is not asserted. */
<> 154:37f96f9d4de2 475 if (!(handle->transfer.flags & kI2C_TransferNoStopFlag))
<> 154:37f96f9d4de2 476 {
<> 154:37f96f9d4de2 477 result = I2C_MasterStop(base);
<> 154:37f96f9d4de2 478 }
<> 154:37f96f9d4de2 479
<> 154:37f96f9d4de2 480 /* Read the last byte of data. */
<> 154:37f96f9d4de2 481 if (handle->transfer.direction == kI2C_Read)
<> 154:37f96f9d4de2 482 {
<> 154:37f96f9d4de2 483 *handle->transfer.data = base->D;
<> 154:37f96f9d4de2 484 }
<> 154:37f96f9d4de2 485
<> 154:37f96f9d4de2 486 /* Reset the state to idle. */
<> 154:37f96f9d4de2 487 handle->state = kIdleState;
<> 154:37f96f9d4de2 488 }
<> 154:37f96f9d4de2 489
<> 154:37f96f9d4de2 490 return result;
<> 154:37f96f9d4de2 491 }
<> 154:37f96f9d4de2 492
<> 154:37f96f9d4de2 493 status_t I2C_MasterTransferGetCountDMA(I2C_Type *base, i2c_master_dma_handle_t *handle, size_t *count)
<> 154:37f96f9d4de2 494 {
<> 154:37f96f9d4de2 495 assert(handle);
<> 154:37f96f9d4de2 496
<> 154:37f96f9d4de2 497 if (!count)
<> 154:37f96f9d4de2 498 {
<> 154:37f96f9d4de2 499 return kStatus_InvalidArgument;
<> 154:37f96f9d4de2 500 }
<> 154:37f96f9d4de2 501
<> 154:37f96f9d4de2 502 if (kIdleState != handle->state)
<> 154:37f96f9d4de2 503 {
<> 154:37f96f9d4de2 504 *count = (handle->transferSize - DMA_GetRemainingBytes(handle->dmaHandle->base, handle->dmaHandle->channel));
<> 154:37f96f9d4de2 505 }
<> 154:37f96f9d4de2 506 else
<> 154:37f96f9d4de2 507 {
<> 154:37f96f9d4de2 508 *count = handle->transferSize;
<> 154:37f96f9d4de2 509 }
<> 154:37f96f9d4de2 510
<> 154:37f96f9d4de2 511 return kStatus_Success;
<> 154:37f96f9d4de2 512 }
<> 154:37f96f9d4de2 513
<> 154:37f96f9d4de2 514 void I2C_MasterTransferAbortDMA(I2C_Type *base, i2c_master_dma_handle_t *handle)
<> 154:37f96f9d4de2 515 {
<> 154:37f96f9d4de2 516 DMA_AbortTransfer(handle->dmaHandle);
<> 154:37f96f9d4de2 517
<> 154:37f96f9d4de2 518 /* Disable dma transfer. */
<> 154:37f96f9d4de2 519 I2C_EnableDMA(base, false);
<> 154:37f96f9d4de2 520
<> 154:37f96f9d4de2 521 /* Reset the state to idle. */
<> 154:37f96f9d4de2 522 handle->state = kIdleState;
<> 154:37f96f9d4de2 523 }