added prescaler for 16 bit pwm in LPC1347 target

Fork of mbed-dev by mbed official

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

Who changed what in which revision?

UserRevisionLine numberNew contents of line
<> 144:ef7eb2e8f9f7 1 /*
<> 144:ef7eb2e8f9f7 2 * Copyright (c) 2015, Freescale Semiconductor, Inc.
<> 144:ef7eb2e8f9f7 3 * All rights reserved.
<> 144:ef7eb2e8f9f7 4 *
<> 144:ef7eb2e8f9f7 5 * Redistribution and use in source and binary forms, with or without modification,
<> 144:ef7eb2e8f9f7 6 * are permitted provided that the following conditions are met:
<> 144:ef7eb2e8f9f7 7 *
<> 144:ef7eb2e8f9f7 8 * o Redistributions of source code must retain the above copyright notice, this list
<> 144:ef7eb2e8f9f7 9 * of conditions and the following disclaimer.
<> 144:ef7eb2e8f9f7 10 *
<> 144:ef7eb2e8f9f7 11 * o Redistributions in binary form must reproduce the above copyright notice, this
<> 144:ef7eb2e8f9f7 12 * list of conditions and the following disclaimer in the documentation and/or
<> 144:ef7eb2e8f9f7 13 * other materials provided with the distribution.
<> 144:ef7eb2e8f9f7 14 *
<> 144:ef7eb2e8f9f7 15 * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
<> 144:ef7eb2e8f9f7 16 * contributors may be used to endorse or promote products derived from this
<> 144:ef7eb2e8f9f7 17 * software without specific prior written permission.
<> 144:ef7eb2e8f9f7 18 *
<> 144:ef7eb2e8f9f7 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
<> 144:ef7eb2e8f9f7 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
<> 144:ef7eb2e8f9f7 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
<> 144:ef7eb2e8f9f7 22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
<> 144:ef7eb2e8f9f7 23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
<> 144:ef7eb2e8f9f7 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
<> 144:ef7eb2e8f9f7 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
<> 144:ef7eb2e8f9f7 26 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
<> 144:ef7eb2e8f9f7 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
<> 144:ef7eb2e8f9f7 28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<> 144:ef7eb2e8f9f7 29 */
<> 144:ef7eb2e8f9f7 30
<> 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 }