added prescaler for 16 bit pwm in LPC1347 target

Fork of mbed-dev by mbed official

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

Who changed what in which revision?

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