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_sai_dma.h"
<> 144:ef7eb2e8f9f7 32
<> 144:ef7eb2e8f9f7 33 /*******************************************************************************
<> 144:ef7eb2e8f9f7 34 * Definitions
<> 144:ef7eb2e8f9f7 35 ******************************************************************************/
<> 144:ef7eb2e8f9f7 36 /*<! Structure definition for sai_dma_private_handle_t. The structure is private. */
<> 144:ef7eb2e8f9f7 37 typedef struct _sai_dma_private_handle
<> 144:ef7eb2e8f9f7 38 {
<> 144:ef7eb2e8f9f7 39 I2S_Type *base;
<> 144:ef7eb2e8f9f7 40 sai_dma_handle_t *handle;
<> 144:ef7eb2e8f9f7 41 } sai_dma_private_handle_t;
<> 144:ef7eb2e8f9f7 42
<> 144:ef7eb2e8f9f7 43 enum _sai_dma_states
<> 144:ef7eb2e8f9f7 44 {
<> 144:ef7eb2e8f9f7 45 kSAI_Idle = 0x0U,
<> 144:ef7eb2e8f9f7 46 kSAI_Busy = 0x1U,
<> 144:ef7eb2e8f9f7 47 };
<> 144:ef7eb2e8f9f7 48
<> 144:ef7eb2e8f9f7 49 /*<! Private handle only used for internally. */
<> 144:ef7eb2e8f9f7 50 static sai_dma_private_handle_t s_dmaPrivateHandle[FSL_FEATURE_SOC_I2S_COUNT][2];
<> 144:ef7eb2e8f9f7 51
<> 144:ef7eb2e8f9f7 52 /*******************************************************************************
<> 144:ef7eb2e8f9f7 53 * Prototypes
<> 144:ef7eb2e8f9f7 54 ******************************************************************************/
<> 144:ef7eb2e8f9f7 55 /*!
<> 144:ef7eb2e8f9f7 56 * @brief Get the instance number for SAI.
<> 144:ef7eb2e8f9f7 57 *
<> 144:ef7eb2e8f9f7 58 * @param base SAI base pointer.
<> 144:ef7eb2e8f9f7 59 */
<> 144:ef7eb2e8f9f7 60 extern uint32_t SAI_GetInstance(I2S_Type *base);
<> 144:ef7eb2e8f9f7 61
<> 144:ef7eb2e8f9f7 62 /*!
<> 144:ef7eb2e8f9f7 63 * @brief SAI EDMA callback for send.
<> 144:ef7eb2e8f9f7 64 *
<> 144:ef7eb2e8f9f7 65 * @param handle pointer to sai_dma_handle_t structure which stores the transfer state.
<> 144:ef7eb2e8f9f7 66 * @param userData Parameter for user callback.
<> 144:ef7eb2e8f9f7 67 */
<> 144:ef7eb2e8f9f7 68 static void SAI_TxDMACallback(dma_handle_t *handle, void *userData);
<> 144:ef7eb2e8f9f7 69
<> 144:ef7eb2e8f9f7 70 /*!
<> 144:ef7eb2e8f9f7 71 * @brief SAI EDMA callback for receive.
<> 144:ef7eb2e8f9f7 72 *
<> 144:ef7eb2e8f9f7 73 * @param handle pointer to sai_dma_handle_t structure which stores the transfer state.
<> 144:ef7eb2e8f9f7 74 * @param userData Parameter for user callback.
<> 144:ef7eb2e8f9f7 75 */
<> 144:ef7eb2e8f9f7 76 static void SAI_RxDMACallback(dma_handle_t *handle, void *userData);
<> 144:ef7eb2e8f9f7 77
<> 144:ef7eb2e8f9f7 78 /*******************************************************************************
<> 144:ef7eb2e8f9f7 79 * Code
<> 144:ef7eb2e8f9f7 80 ******************************************************************************/
<> 144:ef7eb2e8f9f7 81 static void SAI_TxDMACallback(dma_handle_t *handle, void *userData)
<> 144:ef7eb2e8f9f7 82 {
<> 144:ef7eb2e8f9f7 83 sai_dma_private_handle_t *privHandle = (sai_dma_private_handle_t *)userData;
<> 144:ef7eb2e8f9f7 84 sai_dma_handle_t *saiHandle = privHandle->handle;
<> 144:ef7eb2e8f9f7 85
<> 144:ef7eb2e8f9f7 86 /* Update queue counter */
<> 144:ef7eb2e8f9f7 87 memset(&saiHandle->saiQueue[saiHandle->queueDriver], 0, sizeof(sai_transfer_t));
<> 144:ef7eb2e8f9f7 88 saiHandle->queueDriver = (saiHandle->queueDriver + 1) % SAI_XFER_QUEUE_SIZE;
<> 144:ef7eb2e8f9f7 89
<> 144:ef7eb2e8f9f7 90 /* Call callback function */
<> 144:ef7eb2e8f9f7 91 if (saiHandle->callback)
<> 144:ef7eb2e8f9f7 92 {
<> 144:ef7eb2e8f9f7 93 (saiHandle->callback)(privHandle->base, saiHandle, kStatus_SAI_TxIdle, saiHandle->userData);
<> 144:ef7eb2e8f9f7 94 }
<> 144:ef7eb2e8f9f7 95
<> 144:ef7eb2e8f9f7 96 /* If all data finished, just stop the transfer */
<> 144:ef7eb2e8f9f7 97 if (saiHandle->saiQueue[saiHandle->queueDriver].data == NULL)
<> 144:ef7eb2e8f9f7 98 {
<> 144:ef7eb2e8f9f7 99 SAI_TransferAbortSendDMA(privHandle->base, saiHandle);
<> 144:ef7eb2e8f9f7 100 }
<> 144:ef7eb2e8f9f7 101 }
<> 144:ef7eb2e8f9f7 102
<> 144:ef7eb2e8f9f7 103 static void SAI_RxDMACallback(dma_handle_t *handle, void *userData)
<> 144:ef7eb2e8f9f7 104 {
<> 144:ef7eb2e8f9f7 105 sai_dma_private_handle_t *privHandle = (sai_dma_private_handle_t *)userData;
<> 144:ef7eb2e8f9f7 106 sai_dma_handle_t *saiHandle = privHandle->handle;
<> 144:ef7eb2e8f9f7 107
<> 144:ef7eb2e8f9f7 108 /* Update queue counter */
<> 144:ef7eb2e8f9f7 109 memset(&saiHandle->saiQueue[saiHandle->queueDriver], 0, sizeof(sai_transfer_t));
<> 144:ef7eb2e8f9f7 110 saiHandle->queueDriver = (saiHandle->queueDriver + 1) % SAI_XFER_QUEUE_SIZE;
<> 144:ef7eb2e8f9f7 111
<> 144:ef7eb2e8f9f7 112 /* Call callback function */
<> 144:ef7eb2e8f9f7 113 if (saiHandle->callback)
<> 144:ef7eb2e8f9f7 114 {
<> 144:ef7eb2e8f9f7 115 (saiHandle->callback)(privHandle->base, saiHandle, kStatus_SAI_RxIdle, saiHandle->userData);
<> 144:ef7eb2e8f9f7 116 }
<> 144:ef7eb2e8f9f7 117
<> 144:ef7eb2e8f9f7 118 /* If all data finished, just stop the transfer */
<> 144:ef7eb2e8f9f7 119 if (saiHandle->saiQueue[saiHandle->queueDriver].data == NULL)
<> 144:ef7eb2e8f9f7 120 {
<> 144:ef7eb2e8f9f7 121 SAI_TransferAbortReceiveDMA(privHandle->base, saiHandle);
<> 144:ef7eb2e8f9f7 122 }
<> 144:ef7eb2e8f9f7 123 }
<> 144:ef7eb2e8f9f7 124
<> 144:ef7eb2e8f9f7 125 void SAI_TransferTxCreateHandleDMA(
<> 144:ef7eb2e8f9f7 126 I2S_Type *base, sai_dma_handle_t *handle, sai_dma_callback_t callback, void *userData, dma_handle_t *dmaHandle)
<> 144:ef7eb2e8f9f7 127 {
<> 144:ef7eb2e8f9f7 128 assert(handle && dmaHandle);
<> 144:ef7eb2e8f9f7 129
<> 144:ef7eb2e8f9f7 130 uint32_t instance = SAI_GetInstance(base);
<> 144:ef7eb2e8f9f7 131
<> 144:ef7eb2e8f9f7 132 /* Set sai base to handle */
<> 144:ef7eb2e8f9f7 133 handle->dmaHandle = dmaHandle;
<> 144:ef7eb2e8f9f7 134 handle->callback = callback;
<> 144:ef7eb2e8f9f7 135 handle->userData = userData;
<> 144:ef7eb2e8f9f7 136
<> 144:ef7eb2e8f9f7 137 /* Set SAI state to idle */
<> 144:ef7eb2e8f9f7 138 handle->state = kSAI_Idle;
<> 144:ef7eb2e8f9f7 139
<> 144:ef7eb2e8f9f7 140 s_dmaPrivateHandle[instance][0].base = base;
<> 144:ef7eb2e8f9f7 141 s_dmaPrivateHandle[instance][0].handle = handle;
<> 144:ef7eb2e8f9f7 142
<> 144:ef7eb2e8f9f7 143 /* Use FIFO error continue nstead of using interrupt to handle error */
<> 144:ef7eb2e8f9f7 144 #if defined(FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR) && (FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR)
<> 144:ef7eb2e8f9f7 145 base->TCR4 |= I2S_TCR4_FCONT_MASK;
<> 144:ef7eb2e8f9f7 146 #endif
<> 144:ef7eb2e8f9f7 147
<> 144:ef7eb2e8f9f7 148 /* Install callback for Tx dma channel */
<> 144:ef7eb2e8f9f7 149 DMA_SetCallback(dmaHandle, SAI_TxDMACallback, &s_dmaPrivateHandle[instance][0]);
<> 144:ef7eb2e8f9f7 150 }
<> 144:ef7eb2e8f9f7 151
<> 144:ef7eb2e8f9f7 152 void SAI_TransferRxCreateHandleDMA(
<> 144:ef7eb2e8f9f7 153 I2S_Type *base, sai_dma_handle_t *handle, sai_dma_callback_t callback, void *userData, dma_handle_t *dmaHandle)
<> 144:ef7eb2e8f9f7 154 {
<> 144:ef7eb2e8f9f7 155 assert(handle && dmaHandle);
<> 144:ef7eb2e8f9f7 156
<> 144:ef7eb2e8f9f7 157 uint32_t instance = SAI_GetInstance(base);
<> 144:ef7eb2e8f9f7 158
<> 144:ef7eb2e8f9f7 159 /* Set sai base to handle */
<> 144:ef7eb2e8f9f7 160 handle->dmaHandle = dmaHandle;
<> 144:ef7eb2e8f9f7 161 handle->callback = callback;
<> 144:ef7eb2e8f9f7 162 handle->userData = userData;
<> 144:ef7eb2e8f9f7 163
<> 144:ef7eb2e8f9f7 164 /* Set SAI state to idle */
<> 144:ef7eb2e8f9f7 165 handle->state = kSAI_Idle;
<> 144:ef7eb2e8f9f7 166
<> 144:ef7eb2e8f9f7 167 s_dmaPrivateHandle[instance][1].base = base;
<> 144:ef7eb2e8f9f7 168 s_dmaPrivateHandle[instance][1].handle = handle;
<> 144:ef7eb2e8f9f7 169
<> 144:ef7eb2e8f9f7 170 /* Use FIFO error continue nstead of using interrupt to handle error */
<> 144:ef7eb2e8f9f7 171 #if defined(FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR) && (FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR)
<> 144:ef7eb2e8f9f7 172 base->RCR4 |= I2S_RCR4_FCONT_MASK;
<> 144:ef7eb2e8f9f7 173 #endif
<> 144:ef7eb2e8f9f7 174
<> 144:ef7eb2e8f9f7 175 /* Install callback for Tx dma channel */
<> 144:ef7eb2e8f9f7 176 DMA_SetCallback(dmaHandle, SAI_RxDMACallback, &s_dmaPrivateHandle[instance][1]);
<> 144:ef7eb2e8f9f7 177 }
<> 144:ef7eb2e8f9f7 178
<> 144:ef7eb2e8f9f7 179 void SAI_TransferTxSetFormatDMA(I2S_Type *base,
<> 144:ef7eb2e8f9f7 180 sai_dma_handle_t *handle,
<> 144:ef7eb2e8f9f7 181 sai_transfer_format_t *format,
<> 144:ef7eb2e8f9f7 182 uint32_t mclkSourceClockHz,
<> 144:ef7eb2e8f9f7 183 uint32_t bclkSourceClockHz)
<> 144:ef7eb2e8f9f7 184 {
<> 144:ef7eb2e8f9f7 185 assert(handle && format);
<> 144:ef7eb2e8f9f7 186
<> 144:ef7eb2e8f9f7 187 dma_transfer_config_t config = {0};
<> 144:ef7eb2e8f9f7 188
<> 144:ef7eb2e8f9f7 189 /* Configure the audio format to SAI registers */
<> 144:ef7eb2e8f9f7 190 SAI_TxSetFormat(base, format, mclkSourceClockHz, bclkSourceClockHz);
<> 144:ef7eb2e8f9f7 191
<> 144:ef7eb2e8f9f7 192 /* Update the information in handle */
<> 144:ef7eb2e8f9f7 193 handle->channel = format->channel;
<> 144:ef7eb2e8f9f7 194
<> 144:ef7eb2e8f9f7 195 /* Configure the data format into DMA register */
<> 144:ef7eb2e8f9f7 196 config.destAddr = SAI_TxGetDataRegisterAddress(base, format->channel);
<> 144:ef7eb2e8f9f7 197 config.enableDestIncrement = false;
<> 144:ef7eb2e8f9f7 198 config.enableSrcIncrement = true;
<> 144:ef7eb2e8f9f7 199 switch (format->bitWidth)
<> 144:ef7eb2e8f9f7 200 {
<> 144:ef7eb2e8f9f7 201 case 8:
<> 144:ef7eb2e8f9f7 202 config.srcSize = kDMA_Transfersize8bits;
<> 144:ef7eb2e8f9f7 203 config.destSize = kDMA_Transfersize8bits;
<> 144:ef7eb2e8f9f7 204 handle->bytesPerFrame = 1U;
<> 144:ef7eb2e8f9f7 205 break;
<> 144:ef7eb2e8f9f7 206 case 16:
<> 144:ef7eb2e8f9f7 207 config.srcSize = kDMA_Transfersize16bits;
<> 144:ef7eb2e8f9f7 208 config.destSize = kDMA_Transfersize16bits;
<> 144:ef7eb2e8f9f7 209 handle->bytesPerFrame = 2U;
<> 144:ef7eb2e8f9f7 210 break;
<> 144:ef7eb2e8f9f7 211 default:
<> 144:ef7eb2e8f9f7 212 config.srcSize = kDMA_Transfersize32bits;
<> 144:ef7eb2e8f9f7 213 config.destSize = kDMA_Transfersize32bits;
<> 144:ef7eb2e8f9f7 214 handle->bytesPerFrame = 4U;
<> 144:ef7eb2e8f9f7 215 break;
<> 144:ef7eb2e8f9f7 216 }
<> 144:ef7eb2e8f9f7 217
<> 144:ef7eb2e8f9f7 218 /* Configure DMA channel */
<> 144:ef7eb2e8f9f7 219 DMA_SubmitTransfer(handle->dmaHandle, &config, true);
<> 144:ef7eb2e8f9f7 220 }
<> 144:ef7eb2e8f9f7 221
<> 144:ef7eb2e8f9f7 222 void SAI_TransferRxSetFormatDMA(I2S_Type *base,
<> 144:ef7eb2e8f9f7 223 sai_dma_handle_t *handle,
<> 144:ef7eb2e8f9f7 224 sai_transfer_format_t *format,
<> 144:ef7eb2e8f9f7 225 uint32_t mclkSourceClockHz,
<> 144:ef7eb2e8f9f7 226 uint32_t bclkSourceClockHz)
<> 144:ef7eb2e8f9f7 227 {
<> 144:ef7eb2e8f9f7 228 assert(handle && format);
<> 144:ef7eb2e8f9f7 229
<> 144:ef7eb2e8f9f7 230 dma_transfer_config_t config = {0};
<> 144:ef7eb2e8f9f7 231
<> 144:ef7eb2e8f9f7 232 /* Configure the audio format to SAI registers */
<> 144:ef7eb2e8f9f7 233 SAI_RxSetFormat(base, format, mclkSourceClockHz, bclkSourceClockHz);
<> 144:ef7eb2e8f9f7 234 handle->channel = format->channel;
<> 144:ef7eb2e8f9f7 235
<> 144:ef7eb2e8f9f7 236 /* Configure the data format into DMA register */
<> 144:ef7eb2e8f9f7 237 config.srcAddr = SAI_RxGetDataRegisterAddress(base, format->channel);
<> 144:ef7eb2e8f9f7 238 config.enableDestIncrement = true;
<> 144:ef7eb2e8f9f7 239 config.enableSrcIncrement = false;
<> 144:ef7eb2e8f9f7 240 switch (format->bitWidth)
<> 144:ef7eb2e8f9f7 241 {
<> 144:ef7eb2e8f9f7 242 case 8:
<> 144:ef7eb2e8f9f7 243 config.srcSize = kDMA_Transfersize8bits;
<> 144:ef7eb2e8f9f7 244 config.destSize = kDMA_Transfersize8bits;
<> 144:ef7eb2e8f9f7 245 handle->bytesPerFrame = 1U;
<> 144:ef7eb2e8f9f7 246 break;
<> 144:ef7eb2e8f9f7 247 case 16:
<> 144:ef7eb2e8f9f7 248 config.srcSize = kDMA_Transfersize16bits;
<> 144:ef7eb2e8f9f7 249 config.destSize = kDMA_Transfersize16bits;
<> 144:ef7eb2e8f9f7 250 handle->bytesPerFrame = 2U;
<> 144:ef7eb2e8f9f7 251 break;
<> 144:ef7eb2e8f9f7 252 default:
<> 144:ef7eb2e8f9f7 253 config.srcSize = kDMA_Transfersize32bits;
<> 144:ef7eb2e8f9f7 254 config.destSize = kDMA_Transfersize32bits;
<> 144:ef7eb2e8f9f7 255 handle->bytesPerFrame = 4U;
<> 144:ef7eb2e8f9f7 256 break;
<> 144:ef7eb2e8f9f7 257 }
<> 144:ef7eb2e8f9f7 258
<> 144:ef7eb2e8f9f7 259 /* Configure DMA channel */
<> 144:ef7eb2e8f9f7 260 DMA_SubmitTransfer(handle->dmaHandle, &config, true);
<> 144:ef7eb2e8f9f7 261 }
<> 144:ef7eb2e8f9f7 262
<> 144:ef7eb2e8f9f7 263 status_t SAI_TransferSendDMA(I2S_Type *base, sai_dma_handle_t *handle, sai_transfer_t *xfer)
<> 144:ef7eb2e8f9f7 264 {
<> 144:ef7eb2e8f9f7 265 assert(handle && xfer);
<> 144:ef7eb2e8f9f7 266
<> 144:ef7eb2e8f9f7 267 /* Check if input parameter invalid */
<> 144:ef7eb2e8f9f7 268 if ((xfer->data == NULL) || (xfer->dataSize == 0U))
<> 144:ef7eb2e8f9f7 269 {
<> 144:ef7eb2e8f9f7 270 return kStatus_InvalidArgument;
<> 144:ef7eb2e8f9f7 271 }
<> 144:ef7eb2e8f9f7 272
<> 144:ef7eb2e8f9f7 273 if (handle->saiQueue[handle->queueUser].data)
<> 144:ef7eb2e8f9f7 274 {
<> 144:ef7eb2e8f9f7 275 return kStatus_SAI_QueueFull;
<> 144:ef7eb2e8f9f7 276 }
<> 144:ef7eb2e8f9f7 277
<> 144:ef7eb2e8f9f7 278 handle->transferSize[handle->queueUser] = xfer->dataSize;
<> 144:ef7eb2e8f9f7 279 handle->saiQueue[handle->queueUser].data = xfer->data;
<> 144:ef7eb2e8f9f7 280 handle->saiQueue[handle->queueUser].dataSize = xfer->dataSize;
<> 144:ef7eb2e8f9f7 281 handle->queueUser = (handle->queueUser + 1) % SAI_XFER_QUEUE_SIZE;
<> 144:ef7eb2e8f9f7 282
<> 144:ef7eb2e8f9f7 283 /* Set the source address */
<> 144:ef7eb2e8f9f7 284 DMA_SetSourceAddress(handle->dmaHandle->base, handle->dmaHandle->channel, (uint32_t)(xfer->data));
<> 144:ef7eb2e8f9f7 285
<> 144:ef7eb2e8f9f7 286 /* Set the transfer size */
<> 144:ef7eb2e8f9f7 287 DMA_SetTransferSize(handle->dmaHandle->base, handle->dmaHandle->channel, xfer->dataSize);
<> 144:ef7eb2e8f9f7 288
<> 144:ef7eb2e8f9f7 289 /* Change the state of handle */
<> 144:ef7eb2e8f9f7 290 handle->state = kSAI_Busy;
<> 144:ef7eb2e8f9f7 291
<> 144:ef7eb2e8f9f7 292 /* Start DMA transfer */
<> 144:ef7eb2e8f9f7 293 DMA_StartTransfer(handle->dmaHandle);
<> 144:ef7eb2e8f9f7 294
<> 144:ef7eb2e8f9f7 295 /* Enable DMA request and start SAI */
<> 144:ef7eb2e8f9f7 296 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
<> 144:ef7eb2e8f9f7 297 SAI_TxEnableDMA(base, kSAI_FIFORequestDMAEnable, true);
<> 144:ef7eb2e8f9f7 298 #else
<> 144:ef7eb2e8f9f7 299 SAI_TxEnableDMA(base, kSAI_FIFOWarningDMAEnable, true);
<> 144:ef7eb2e8f9f7 300 #endif
<> 144:ef7eb2e8f9f7 301 SAI_TxEnable(base, true);
<> 144:ef7eb2e8f9f7 302
<> 144:ef7eb2e8f9f7 303 return kStatus_Success;
<> 144:ef7eb2e8f9f7 304 }
<> 144:ef7eb2e8f9f7 305
<> 144:ef7eb2e8f9f7 306 status_t SAI_TransferReceiveDMA(I2S_Type *base, sai_dma_handle_t *handle, sai_transfer_t *xfer)
<> 144:ef7eb2e8f9f7 307 {
<> 144:ef7eb2e8f9f7 308 assert(handle && xfer);
<> 144:ef7eb2e8f9f7 309
<> 144:ef7eb2e8f9f7 310 /* Check if input parameter invalid */
<> 144:ef7eb2e8f9f7 311 if ((xfer->data == NULL) || (xfer->dataSize == 0U))
<> 144:ef7eb2e8f9f7 312 {
<> 144:ef7eb2e8f9f7 313 return kStatus_InvalidArgument;
<> 144:ef7eb2e8f9f7 314 }
<> 144:ef7eb2e8f9f7 315
<> 144:ef7eb2e8f9f7 316 if (handle->saiQueue[handle->queueUser].data)
<> 144:ef7eb2e8f9f7 317 {
<> 144:ef7eb2e8f9f7 318 return kStatus_SAI_QueueFull;
<> 144:ef7eb2e8f9f7 319 }
<> 144:ef7eb2e8f9f7 320
<> 144:ef7eb2e8f9f7 321 /* Add into queue */
<> 144:ef7eb2e8f9f7 322 handle->transferSize[handle->queueUser] = xfer->dataSize;
<> 144:ef7eb2e8f9f7 323 handle->saiQueue[handle->queueUser].data = xfer->data;
<> 144:ef7eb2e8f9f7 324 handle->saiQueue[handle->queueUser].dataSize = xfer->dataSize;
<> 144:ef7eb2e8f9f7 325 handle->queueUser = (handle->queueUser + 1) % SAI_XFER_QUEUE_SIZE;
<> 144:ef7eb2e8f9f7 326
<> 144:ef7eb2e8f9f7 327 /* Set the source address */
<> 144:ef7eb2e8f9f7 328 DMA_SetDestinationAddress(handle->dmaHandle->base, handle->dmaHandle->channel, (uint32_t)(xfer->data));
<> 144:ef7eb2e8f9f7 329
<> 144:ef7eb2e8f9f7 330 /* Set the transfer size */
<> 144:ef7eb2e8f9f7 331 DMA_SetTransferSize(handle->dmaHandle->base, handle->dmaHandle->channel, xfer->dataSize);
<> 144:ef7eb2e8f9f7 332
<> 144:ef7eb2e8f9f7 333 /* Change the state of handle */
<> 144:ef7eb2e8f9f7 334 handle->state = kSAI_Busy;
<> 144:ef7eb2e8f9f7 335
<> 144:ef7eb2e8f9f7 336 /* Start DMA transfer */
<> 144:ef7eb2e8f9f7 337 DMA_StartTransfer(handle->dmaHandle);
<> 144:ef7eb2e8f9f7 338
<> 144:ef7eb2e8f9f7 339 /* Enable DMA request and start SAI */
<> 144:ef7eb2e8f9f7 340 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
<> 144:ef7eb2e8f9f7 341 SAI_RxEnableDMA(base, kSAI_FIFORequestDMAEnable, true);
<> 144:ef7eb2e8f9f7 342 #else
<> 144:ef7eb2e8f9f7 343 SAI_RxEnableDMA(base, kSAI_FIFOWarningDMAEnable, true);
<> 144:ef7eb2e8f9f7 344 #endif
<> 144:ef7eb2e8f9f7 345 SAI_RxEnable(base, true);
<> 144:ef7eb2e8f9f7 346
<> 144:ef7eb2e8f9f7 347 return kStatus_Success;
<> 144:ef7eb2e8f9f7 348 }
<> 144:ef7eb2e8f9f7 349
<> 144:ef7eb2e8f9f7 350 void SAI_TransferAbortSendDMA(I2S_Type *base, sai_dma_handle_t *handle)
<> 144:ef7eb2e8f9f7 351 {
<> 144:ef7eb2e8f9f7 352 assert(handle);
<> 144:ef7eb2e8f9f7 353
<> 144:ef7eb2e8f9f7 354 /* Disable dma */
<> 144:ef7eb2e8f9f7 355 DMA_AbortTransfer(handle->dmaHandle);
<> 144:ef7eb2e8f9f7 356
<> 144:ef7eb2e8f9f7 357 /* Disable DMA enable bit */
<> 144:ef7eb2e8f9f7 358 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
<> 144:ef7eb2e8f9f7 359 SAI_TxEnableDMA(base, kSAI_FIFORequestDMAEnable, false);
<> 144:ef7eb2e8f9f7 360 #else
<> 144:ef7eb2e8f9f7 361 SAI_TxEnableDMA(base, kSAI_FIFOWarningDMAEnable, false);
<> 144:ef7eb2e8f9f7 362 #endif
<> 144:ef7eb2e8f9f7 363
<> 144:ef7eb2e8f9f7 364 /* Set the handle state */
<> 144:ef7eb2e8f9f7 365 handle->state = kSAI_Idle;
<> 144:ef7eb2e8f9f7 366
<> 144:ef7eb2e8f9f7 367 /* Clear the queue */
<> 144:ef7eb2e8f9f7 368 memset(handle->saiQueue, 0, sizeof(sai_transfer_t) * SAI_XFER_QUEUE_SIZE);
<> 144:ef7eb2e8f9f7 369 handle->queueDriver = 0;
<> 144:ef7eb2e8f9f7 370 handle->queueUser = 0;
<> 144:ef7eb2e8f9f7 371 }
<> 144:ef7eb2e8f9f7 372
<> 144:ef7eb2e8f9f7 373 void SAI_TransferAbortReceiveDMA(I2S_Type *base, sai_dma_handle_t *handle)
<> 144:ef7eb2e8f9f7 374 {
<> 144:ef7eb2e8f9f7 375 assert(handle);
<> 144:ef7eb2e8f9f7 376
<> 144:ef7eb2e8f9f7 377 /* Disable dma */
<> 144:ef7eb2e8f9f7 378 DMA_AbortTransfer(handle->dmaHandle);
<> 144:ef7eb2e8f9f7 379
<> 144:ef7eb2e8f9f7 380 /* Disable DMA enable bit */
<> 144:ef7eb2e8f9f7 381 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
<> 144:ef7eb2e8f9f7 382 SAI_RxEnableDMA(base, kSAI_FIFORequestDMAEnable, false);
<> 144:ef7eb2e8f9f7 383 #else
<> 144:ef7eb2e8f9f7 384 SAI_RxEnableDMA(base, kSAI_FIFOWarningDMAEnable, false);
<> 144:ef7eb2e8f9f7 385 #endif
<> 144:ef7eb2e8f9f7 386 /* Set the handle state */
<> 144:ef7eb2e8f9f7 387 handle->state = kSAI_Idle;
<> 144:ef7eb2e8f9f7 388
<> 144:ef7eb2e8f9f7 389 /* Clear the queue */
<> 144:ef7eb2e8f9f7 390 memset(handle->saiQueue, 0, sizeof(sai_transfer_t) * SAI_XFER_QUEUE_SIZE);
<> 144:ef7eb2e8f9f7 391 handle->queueDriver = 0;
<> 144:ef7eb2e8f9f7 392 handle->queueUser = 0;
<> 144:ef7eb2e8f9f7 393 }
<> 144:ef7eb2e8f9f7 394
<> 144:ef7eb2e8f9f7 395 status_t SAI_TransferGetSendCountDMA(I2S_Type *base, sai_dma_handle_t *handle, size_t *count)
<> 144:ef7eb2e8f9f7 396 {
<> 144:ef7eb2e8f9f7 397 assert(handle);
<> 144:ef7eb2e8f9f7 398
<> 144:ef7eb2e8f9f7 399 status_t status = kStatus_Success;
<> 144:ef7eb2e8f9f7 400
<> 144:ef7eb2e8f9f7 401 if (handle->state != kSAI_Busy)
<> 144:ef7eb2e8f9f7 402 {
<> 144:ef7eb2e8f9f7 403 status = kStatus_NoTransferInProgress;
<> 144:ef7eb2e8f9f7 404 }
<> 144:ef7eb2e8f9f7 405 else
<> 144:ef7eb2e8f9f7 406 {
<> 144:ef7eb2e8f9f7 407 *count = handle->transferSize[handle->queueDriver] -
<> 144:ef7eb2e8f9f7 408 DMA_GetRemainingBytes(handle->dmaHandle->base, handle->dmaHandle->channel);
<> 144:ef7eb2e8f9f7 409 }
<> 144:ef7eb2e8f9f7 410
<> 144:ef7eb2e8f9f7 411 return status;
<> 144:ef7eb2e8f9f7 412 }
<> 144:ef7eb2e8f9f7 413
<> 144:ef7eb2e8f9f7 414 status_t SAI_TransferGetReceiveCountDMA(I2S_Type *base, sai_dma_handle_t *handle, size_t *count)
<> 144:ef7eb2e8f9f7 415 {
<> 144:ef7eb2e8f9f7 416 assert(handle);
<> 144:ef7eb2e8f9f7 417
<> 144:ef7eb2e8f9f7 418 status_t status = kStatus_Success;
<> 144:ef7eb2e8f9f7 419
<> 144:ef7eb2e8f9f7 420 if (handle->state != kSAI_Busy)
<> 144:ef7eb2e8f9f7 421 {
<> 144:ef7eb2e8f9f7 422 status = kStatus_NoTransferInProgress;
<> 144:ef7eb2e8f9f7 423 }
<> 144:ef7eb2e8f9f7 424 else
<> 144:ef7eb2e8f9f7 425 {
<> 144:ef7eb2e8f9f7 426 *count = handle->transferSize[handle->queueDriver] -
<> 144:ef7eb2e8f9f7 427 DMA_GetRemainingBytes(handle->dmaHandle->base, handle->dmaHandle->channel);
<> 144:ef7eb2e8f9f7 428 }
<> 144:ef7eb2e8f9f7 429
<> 144:ef7eb2e8f9f7 430 return status;
<> 144:ef7eb2e8f9f7 431 }