Color Oled(SSD1331) connect to STMicroelectronics Nucleo-F466

Dependencies:   ssd1331

Committer:
kadonotakashi
Date:
Thu Oct 11 02:27:46 2018 +0000
Revision:
3:f3764f852aa8
Parent:
0:8fdf9a60065b
Nucreo 446 + SSD1331 test version;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kadonotakashi 0:8fdf9a60065b 1 /*
kadonotakashi 0:8fdf9a60065b 2 * Copyright (c) 2015, Freescale Semiconductor, Inc.
kadonotakashi 0:8fdf9a60065b 3 * All rights reserved.
kadonotakashi 0:8fdf9a60065b 4 *
kadonotakashi 0:8fdf9a60065b 5 * Redistribution and use in source and binary forms, with or without modification,
kadonotakashi 0:8fdf9a60065b 6 * are permitted provided that the following conditions are met:
kadonotakashi 0:8fdf9a60065b 7 *
kadonotakashi 0:8fdf9a60065b 8 * o Redistributions of source code must retain the above copyright notice, this list
kadonotakashi 0:8fdf9a60065b 9 * of conditions and the following disclaimer.
kadonotakashi 0:8fdf9a60065b 10 *
kadonotakashi 0:8fdf9a60065b 11 * o Redistributions in binary form must reproduce the above copyright notice, this
kadonotakashi 0:8fdf9a60065b 12 * list of conditions and the following disclaimer in the documentation and/or
kadonotakashi 0:8fdf9a60065b 13 * other materials provided with the distribution.
kadonotakashi 0:8fdf9a60065b 14 *
kadonotakashi 0:8fdf9a60065b 15 * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
kadonotakashi 0:8fdf9a60065b 16 * contributors may be used to endorse or promote products derived from this
kadonotakashi 0:8fdf9a60065b 17 * software without specific prior written permission.
kadonotakashi 0:8fdf9a60065b 18 *
kadonotakashi 0:8fdf9a60065b 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
kadonotakashi 0:8fdf9a60065b 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
kadonotakashi 0:8fdf9a60065b 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
kadonotakashi 0:8fdf9a60065b 22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
kadonotakashi 0:8fdf9a60065b 23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
kadonotakashi 0:8fdf9a60065b 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
kadonotakashi 0:8fdf9a60065b 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
kadonotakashi 0:8fdf9a60065b 26 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
kadonotakashi 0:8fdf9a60065b 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
kadonotakashi 0:8fdf9a60065b 28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
kadonotakashi 0:8fdf9a60065b 29 */
kadonotakashi 0:8fdf9a60065b 30
kadonotakashi 0:8fdf9a60065b 31 #include "fsl_sai_edma.h"
kadonotakashi 0:8fdf9a60065b 32
kadonotakashi 0:8fdf9a60065b 33 /*******************************************************************************
kadonotakashi 0:8fdf9a60065b 34 * Definitations
kadonotakashi 0:8fdf9a60065b 35 ******************************************************************************/
kadonotakashi 0:8fdf9a60065b 36 /* Used for 32byte aligned */
kadonotakashi 0:8fdf9a60065b 37 #define STCD_ADDR(address) (edma_tcd_t *)(((uint32_t)address + 32) & ~0x1FU)
kadonotakashi 0:8fdf9a60065b 38
kadonotakashi 0:8fdf9a60065b 39 /*<! Structure definition for uart_edma_private_handle_t. The structure is private. */
kadonotakashi 0:8fdf9a60065b 40 typedef struct _sai_edma_private_handle
kadonotakashi 0:8fdf9a60065b 41 {
kadonotakashi 0:8fdf9a60065b 42 I2S_Type *base;
kadonotakashi 0:8fdf9a60065b 43 sai_edma_handle_t *handle;
kadonotakashi 0:8fdf9a60065b 44 } sai_edma_private_handle_t;
kadonotakashi 0:8fdf9a60065b 45
kadonotakashi 0:8fdf9a60065b 46 enum _sai_edma_transfer_state
kadonotakashi 0:8fdf9a60065b 47 {
kadonotakashi 0:8fdf9a60065b 48 kSAI_Busy = 0x0U, /*!< SAI is busy */
kadonotakashi 0:8fdf9a60065b 49 kSAI_Idle, /*!< Transfer is done. */
kadonotakashi 0:8fdf9a60065b 50 };
kadonotakashi 0:8fdf9a60065b 51
kadonotakashi 0:8fdf9a60065b 52 /*<! Private handle only used for internally. */
kadonotakashi 0:8fdf9a60065b 53 static sai_edma_private_handle_t s_edmaPrivateHandle[FSL_FEATURE_SOC_I2S_COUNT][2];
kadonotakashi 0:8fdf9a60065b 54
kadonotakashi 0:8fdf9a60065b 55 /*******************************************************************************
kadonotakashi 0:8fdf9a60065b 56 * Prototypes
kadonotakashi 0:8fdf9a60065b 57 ******************************************************************************/
kadonotakashi 0:8fdf9a60065b 58 /*!
kadonotakashi 0:8fdf9a60065b 59 * @brief Get the instance number for SAI.
kadonotakashi 0:8fdf9a60065b 60 *
kadonotakashi 0:8fdf9a60065b 61 * @param base SAI base pointer.
kadonotakashi 0:8fdf9a60065b 62 */
kadonotakashi 0:8fdf9a60065b 63 extern uint32_t SAI_GetInstance(I2S_Type *base);
kadonotakashi 0:8fdf9a60065b 64
kadonotakashi 0:8fdf9a60065b 65 /*!
kadonotakashi 0:8fdf9a60065b 66 * @brief SAI EDMA callback for send.
kadonotakashi 0:8fdf9a60065b 67 *
kadonotakashi 0:8fdf9a60065b 68 * @param handle pointer to sai_edma_handle_t structure which stores the transfer state.
kadonotakashi 0:8fdf9a60065b 69 * @param userData Parameter for user callback.
kadonotakashi 0:8fdf9a60065b 70 * @param done If the DMA transfer finished.
kadonotakashi 0:8fdf9a60065b 71 * @param tcds The TCD index.
kadonotakashi 0:8fdf9a60065b 72 */
kadonotakashi 0:8fdf9a60065b 73 static void SAI_TxEDMACallback(edma_handle_t *handle, void *userData, bool done, uint32_t tcds);
kadonotakashi 0:8fdf9a60065b 74
kadonotakashi 0:8fdf9a60065b 75 /*!
kadonotakashi 0:8fdf9a60065b 76 * @brief SAI EDMA callback for receive.
kadonotakashi 0:8fdf9a60065b 77 *
kadonotakashi 0:8fdf9a60065b 78 * @param handle pointer to sai_edma_handle_t structure which stores the transfer state.
kadonotakashi 0:8fdf9a60065b 79 * @param userData Parameter for user callback.
kadonotakashi 0:8fdf9a60065b 80 * @param done If the DMA transfer finished.
kadonotakashi 0:8fdf9a60065b 81 * @param tcds The TCD index.
kadonotakashi 0:8fdf9a60065b 82 */
kadonotakashi 0:8fdf9a60065b 83 static void SAI_RxEDMACallback(edma_handle_t *handle, void *userData, bool done, uint32_t tcds);
kadonotakashi 0:8fdf9a60065b 84
kadonotakashi 0:8fdf9a60065b 85 /*******************************************************************************
kadonotakashi 0:8fdf9a60065b 86 * Code
kadonotakashi 0:8fdf9a60065b 87 ******************************************************************************/
kadonotakashi 0:8fdf9a60065b 88 static void SAI_TxEDMACallback(edma_handle_t *handle, void *userData, bool done, uint32_t tcds)
kadonotakashi 0:8fdf9a60065b 89 {
kadonotakashi 0:8fdf9a60065b 90 sai_edma_private_handle_t *privHandle = (sai_edma_private_handle_t *)userData;
kadonotakashi 0:8fdf9a60065b 91 sai_edma_handle_t *saiHandle = privHandle->handle;
kadonotakashi 0:8fdf9a60065b 92
kadonotakashi 0:8fdf9a60065b 93 /* If finished a blcok, call the callback function */
kadonotakashi 0:8fdf9a60065b 94 memset(&saiHandle->saiQueue[saiHandle->queueDriver], 0, sizeof(sai_transfer_t));
kadonotakashi 0:8fdf9a60065b 95 saiHandle->queueDriver = (saiHandle->queueDriver + 1) % SAI_XFER_QUEUE_SIZE;
kadonotakashi 0:8fdf9a60065b 96 if (saiHandle->callback)
kadonotakashi 0:8fdf9a60065b 97 {
kadonotakashi 0:8fdf9a60065b 98 (saiHandle->callback)(privHandle->base, saiHandle, kStatus_SAI_TxIdle, saiHandle->userData);
kadonotakashi 0:8fdf9a60065b 99 }
kadonotakashi 0:8fdf9a60065b 100
kadonotakashi 0:8fdf9a60065b 101 /* If all data finished, just stop the transfer */
kadonotakashi 0:8fdf9a60065b 102 if (saiHandle->saiQueue[saiHandle->queueDriver].data == NULL)
kadonotakashi 0:8fdf9a60065b 103 {
kadonotakashi 0:8fdf9a60065b 104 SAI_TransferAbortSendEDMA(privHandle->base, saiHandle);
kadonotakashi 0:8fdf9a60065b 105 }
kadonotakashi 0:8fdf9a60065b 106 }
kadonotakashi 0:8fdf9a60065b 107
kadonotakashi 0:8fdf9a60065b 108 static void SAI_RxEDMACallback(edma_handle_t *handle, void *userData, bool done, uint32_t tcds)
kadonotakashi 0:8fdf9a60065b 109 {
kadonotakashi 0:8fdf9a60065b 110 sai_edma_private_handle_t *privHandle = (sai_edma_private_handle_t *)userData;
kadonotakashi 0:8fdf9a60065b 111 sai_edma_handle_t *saiHandle = privHandle->handle;
kadonotakashi 0:8fdf9a60065b 112
kadonotakashi 0:8fdf9a60065b 113 /* If finished a blcok, call the callback function */
kadonotakashi 0:8fdf9a60065b 114 memset(&saiHandle->saiQueue[saiHandle->queueDriver], 0, sizeof(sai_transfer_t));
kadonotakashi 0:8fdf9a60065b 115 saiHandle->queueDriver = (saiHandle->queueDriver + 1) % SAI_XFER_QUEUE_SIZE;
kadonotakashi 0:8fdf9a60065b 116 if (saiHandle->callback)
kadonotakashi 0:8fdf9a60065b 117 {
kadonotakashi 0:8fdf9a60065b 118 (saiHandle->callback)(privHandle->base, saiHandle, kStatus_SAI_RxIdle, saiHandle->userData);
kadonotakashi 0:8fdf9a60065b 119 }
kadonotakashi 0:8fdf9a60065b 120
kadonotakashi 0:8fdf9a60065b 121 /* If all data finished, just stop the transfer */
kadonotakashi 0:8fdf9a60065b 122 if (saiHandle->saiQueue[saiHandle->queueDriver].data == NULL)
kadonotakashi 0:8fdf9a60065b 123 {
kadonotakashi 0:8fdf9a60065b 124 SAI_TransferAbortReceiveEDMA(privHandle->base, saiHandle);
kadonotakashi 0:8fdf9a60065b 125 }
kadonotakashi 0:8fdf9a60065b 126 }
kadonotakashi 0:8fdf9a60065b 127
kadonotakashi 0:8fdf9a60065b 128 void SAI_TransferTxCreateHandleEDMA(
kadonotakashi 0:8fdf9a60065b 129 I2S_Type *base, sai_edma_handle_t *handle, sai_edma_callback_t callback, void *userData, edma_handle_t *dmaHandle)
kadonotakashi 0:8fdf9a60065b 130 {
kadonotakashi 0:8fdf9a60065b 131 assert(handle && dmaHandle);
kadonotakashi 0:8fdf9a60065b 132
kadonotakashi 0:8fdf9a60065b 133 uint32_t instance = SAI_GetInstance(base);
kadonotakashi 0:8fdf9a60065b 134
kadonotakashi 0:8fdf9a60065b 135 /* Set sai base to handle */
kadonotakashi 0:8fdf9a60065b 136 handle->dmaHandle = dmaHandle;
kadonotakashi 0:8fdf9a60065b 137 handle->callback = callback;
kadonotakashi 0:8fdf9a60065b 138 handle->userData = userData;
kadonotakashi 0:8fdf9a60065b 139
kadonotakashi 0:8fdf9a60065b 140 /* Set SAI state to idle */
kadonotakashi 0:8fdf9a60065b 141 handle->state = kSAI_Idle;
kadonotakashi 0:8fdf9a60065b 142
kadonotakashi 0:8fdf9a60065b 143 s_edmaPrivateHandle[instance][0].base = base;
kadonotakashi 0:8fdf9a60065b 144 s_edmaPrivateHandle[instance][0].handle = handle;
kadonotakashi 0:8fdf9a60065b 145
kadonotakashi 0:8fdf9a60065b 146 /* Need to use scatter gather */
kadonotakashi 0:8fdf9a60065b 147 EDMA_InstallTCDMemory(dmaHandle, STCD_ADDR(handle->tcd), SAI_XFER_QUEUE_SIZE);
kadonotakashi 0:8fdf9a60065b 148
kadonotakashi 0:8fdf9a60065b 149 /* Install callback for Tx dma channel */
kadonotakashi 0:8fdf9a60065b 150 EDMA_SetCallback(dmaHandle, SAI_TxEDMACallback, &s_edmaPrivateHandle[instance][0]);
kadonotakashi 0:8fdf9a60065b 151 }
kadonotakashi 0:8fdf9a60065b 152
kadonotakashi 0:8fdf9a60065b 153 void SAI_TransferRxCreateHandleEDMA(
kadonotakashi 0:8fdf9a60065b 154 I2S_Type *base, sai_edma_handle_t *handle, sai_edma_callback_t callback, void *userData, edma_handle_t *dmaHandle)
kadonotakashi 0:8fdf9a60065b 155 {
kadonotakashi 0:8fdf9a60065b 156 assert(handle && dmaHandle);
kadonotakashi 0:8fdf9a60065b 157
kadonotakashi 0:8fdf9a60065b 158 uint32_t instance = SAI_GetInstance(base);
kadonotakashi 0:8fdf9a60065b 159
kadonotakashi 0:8fdf9a60065b 160 /* Set sai base to handle */
kadonotakashi 0:8fdf9a60065b 161 handle->dmaHandle = dmaHandle;
kadonotakashi 0:8fdf9a60065b 162 handle->callback = callback;
kadonotakashi 0:8fdf9a60065b 163 handle->userData = userData;
kadonotakashi 0:8fdf9a60065b 164
kadonotakashi 0:8fdf9a60065b 165 /* Set SAI state to idle */
kadonotakashi 0:8fdf9a60065b 166 handle->state = kSAI_Idle;
kadonotakashi 0:8fdf9a60065b 167
kadonotakashi 0:8fdf9a60065b 168 s_edmaPrivateHandle[instance][1].base = base;
kadonotakashi 0:8fdf9a60065b 169 s_edmaPrivateHandle[instance][1].handle = handle;
kadonotakashi 0:8fdf9a60065b 170
kadonotakashi 0:8fdf9a60065b 171 /* Need to use scatter gather */
kadonotakashi 0:8fdf9a60065b 172 EDMA_InstallTCDMemory(dmaHandle, STCD_ADDR(handle->tcd), SAI_XFER_QUEUE_SIZE);
kadonotakashi 0:8fdf9a60065b 173
kadonotakashi 0:8fdf9a60065b 174 /* Install callback for Tx dma channel */
kadonotakashi 0:8fdf9a60065b 175 EDMA_SetCallback(dmaHandle, SAI_RxEDMACallback, &s_edmaPrivateHandle[instance][1]);
kadonotakashi 0:8fdf9a60065b 176 }
kadonotakashi 0:8fdf9a60065b 177
kadonotakashi 0:8fdf9a60065b 178 void SAI_TransferTxSetFormatEDMA(I2S_Type *base,
kadonotakashi 0:8fdf9a60065b 179 sai_edma_handle_t *handle,
kadonotakashi 0:8fdf9a60065b 180 sai_transfer_format_t *format,
kadonotakashi 0:8fdf9a60065b 181 uint32_t mclkSourceClockHz,
kadonotakashi 0:8fdf9a60065b 182 uint32_t bclkSourceClockHz)
kadonotakashi 0:8fdf9a60065b 183 {
kadonotakashi 0:8fdf9a60065b 184 assert(handle && format);
kadonotakashi 0:8fdf9a60065b 185
kadonotakashi 0:8fdf9a60065b 186 /* Configure the audio format to SAI registers */
kadonotakashi 0:8fdf9a60065b 187 SAI_TxSetFormat(base, format, mclkSourceClockHz, bclkSourceClockHz);
kadonotakashi 0:8fdf9a60065b 188
kadonotakashi 0:8fdf9a60065b 189 /* Get the tranfer size from format, this should be used in EDMA configuration */
kadonotakashi 0:8fdf9a60065b 190 handle->bytesPerFrame = format->bitWidth / 8U;
kadonotakashi 0:8fdf9a60065b 191
kadonotakashi 0:8fdf9a60065b 192 /* Update the data channel SAI used */
kadonotakashi 0:8fdf9a60065b 193 handle->channel = format->channel;
kadonotakashi 0:8fdf9a60065b 194 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
kadonotakashi 0:8fdf9a60065b 195 handle->count = FSL_FEATURE_SAI_FIFO_COUNT - format->watermark;
kadonotakashi 0:8fdf9a60065b 196 #else
kadonotakashi 0:8fdf9a60065b 197 handle->count = 1U;
kadonotakashi 0:8fdf9a60065b 198 #endif /* FSL_FEATURE_SAI_FIFO_COUNT */
kadonotakashi 0:8fdf9a60065b 199 }
kadonotakashi 0:8fdf9a60065b 200
kadonotakashi 0:8fdf9a60065b 201 void SAI_TransferRxSetFormatEDMA(I2S_Type *base,
kadonotakashi 0:8fdf9a60065b 202 sai_edma_handle_t *handle,
kadonotakashi 0:8fdf9a60065b 203 sai_transfer_format_t *format,
kadonotakashi 0:8fdf9a60065b 204 uint32_t mclkSourceClockHz,
kadonotakashi 0:8fdf9a60065b 205 uint32_t bclkSourceClockHz)
kadonotakashi 0:8fdf9a60065b 206 {
kadonotakashi 0:8fdf9a60065b 207 assert(handle && format);
kadonotakashi 0:8fdf9a60065b 208
kadonotakashi 0:8fdf9a60065b 209 /* Configure the audio format to SAI registers */
kadonotakashi 0:8fdf9a60065b 210 SAI_RxSetFormat(base, format, mclkSourceClockHz, bclkSourceClockHz);
kadonotakashi 0:8fdf9a60065b 211
kadonotakashi 0:8fdf9a60065b 212 /* Get the tranfer size from format, this should be used in EDMA configuration */
kadonotakashi 0:8fdf9a60065b 213 handle->bytesPerFrame = format->bitWidth / 8U;
kadonotakashi 0:8fdf9a60065b 214
kadonotakashi 0:8fdf9a60065b 215 /* Update the data channel SAI used */
kadonotakashi 0:8fdf9a60065b 216 handle->channel = format->channel;
kadonotakashi 0:8fdf9a60065b 217
kadonotakashi 0:8fdf9a60065b 218 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
kadonotakashi 0:8fdf9a60065b 219 handle->count = format->watermark;
kadonotakashi 0:8fdf9a60065b 220 #else
kadonotakashi 0:8fdf9a60065b 221 handle->count = 1U;
kadonotakashi 0:8fdf9a60065b 222 #endif /* FSL_FEATURE_SAI_FIFO_COUNT */
kadonotakashi 0:8fdf9a60065b 223 }
kadonotakashi 0:8fdf9a60065b 224
kadonotakashi 0:8fdf9a60065b 225 status_t SAI_TransferSendEDMA(I2S_Type *base, sai_edma_handle_t *handle, sai_transfer_t *xfer)
kadonotakashi 0:8fdf9a60065b 226 {
kadonotakashi 0:8fdf9a60065b 227 assert(handle && xfer);
kadonotakashi 0:8fdf9a60065b 228
kadonotakashi 0:8fdf9a60065b 229 edma_transfer_config_t config = {0};
kadonotakashi 0:8fdf9a60065b 230 uint32_t destAddr = SAI_TxGetDataRegisterAddress(base, handle->channel);
kadonotakashi 0:8fdf9a60065b 231
kadonotakashi 0:8fdf9a60065b 232 /* Check if input parameter invalid */
kadonotakashi 0:8fdf9a60065b 233 if ((xfer->data == NULL) || (xfer->dataSize == 0U))
kadonotakashi 0:8fdf9a60065b 234 {
kadonotakashi 0:8fdf9a60065b 235 return kStatus_InvalidArgument;
kadonotakashi 0:8fdf9a60065b 236 }
kadonotakashi 0:8fdf9a60065b 237
kadonotakashi 0:8fdf9a60065b 238 if (handle->saiQueue[handle->queueUser].data)
kadonotakashi 0:8fdf9a60065b 239 {
kadonotakashi 0:8fdf9a60065b 240 return kStatus_SAI_QueueFull;
kadonotakashi 0:8fdf9a60065b 241 }
kadonotakashi 0:8fdf9a60065b 242
kadonotakashi 0:8fdf9a60065b 243 /* Change the state of handle */
kadonotakashi 0:8fdf9a60065b 244 handle->state = kSAI_Busy;
kadonotakashi 0:8fdf9a60065b 245
kadonotakashi 0:8fdf9a60065b 246 /* Update the queue state */
kadonotakashi 0:8fdf9a60065b 247 handle->transferSize[handle->queueUser] = xfer->dataSize;
kadonotakashi 0:8fdf9a60065b 248 handle->saiQueue[handle->queueUser].data = xfer->data;
kadonotakashi 0:8fdf9a60065b 249 handle->saiQueue[handle->queueUser].dataSize = xfer->dataSize;
kadonotakashi 0:8fdf9a60065b 250 handle->queueUser = (handle->queueUser + 1) % SAI_XFER_QUEUE_SIZE;
kadonotakashi 0:8fdf9a60065b 251
kadonotakashi 0:8fdf9a60065b 252 /* Prepare edma configure */
kadonotakashi 0:8fdf9a60065b 253 EDMA_PrepareTransfer(&config, xfer->data, handle->bytesPerFrame, (void *)destAddr, handle->bytesPerFrame,
kadonotakashi 0:8fdf9a60065b 254 handle->count * handle->bytesPerFrame, xfer->dataSize, kEDMA_MemoryToPeripheral);
kadonotakashi 0:8fdf9a60065b 255
kadonotakashi 0:8fdf9a60065b 256 /* Store the initially configured eDMA minor byte transfer count into the SAI handle */
kadonotakashi 0:8fdf9a60065b 257 handle->nbytes = handle->count * handle->bytesPerFrame;
kadonotakashi 0:8fdf9a60065b 258
kadonotakashi 0:8fdf9a60065b 259 EDMA_SubmitTransfer(handle->dmaHandle, &config);
kadonotakashi 0:8fdf9a60065b 260
kadonotakashi 0:8fdf9a60065b 261 /* Start DMA transfer */
kadonotakashi 0:8fdf9a60065b 262 EDMA_StartTransfer(handle->dmaHandle);
kadonotakashi 0:8fdf9a60065b 263
kadonotakashi 0:8fdf9a60065b 264 /* Enable DMA enable bit */
kadonotakashi 0:8fdf9a60065b 265 SAI_TxEnableDMA(base, kSAI_FIFORequestDMAEnable, true);
kadonotakashi 0:8fdf9a60065b 266
kadonotakashi 0:8fdf9a60065b 267 /* Enable SAI Tx clock */
kadonotakashi 0:8fdf9a60065b 268 SAI_TxEnable(base, true);
kadonotakashi 0:8fdf9a60065b 269
kadonotakashi 0:8fdf9a60065b 270 return kStatus_Success;
kadonotakashi 0:8fdf9a60065b 271 }
kadonotakashi 0:8fdf9a60065b 272
kadonotakashi 0:8fdf9a60065b 273 status_t SAI_TransferReceiveEDMA(I2S_Type *base, sai_edma_handle_t *handle, sai_transfer_t *xfer)
kadonotakashi 0:8fdf9a60065b 274 {
kadonotakashi 0:8fdf9a60065b 275 assert(handle && xfer);
kadonotakashi 0:8fdf9a60065b 276
kadonotakashi 0:8fdf9a60065b 277 edma_transfer_config_t config = {0};
kadonotakashi 0:8fdf9a60065b 278 uint32_t srcAddr = SAI_RxGetDataRegisterAddress(base, handle->channel);
kadonotakashi 0:8fdf9a60065b 279
kadonotakashi 0:8fdf9a60065b 280 /* Check if input parameter invalid */
kadonotakashi 0:8fdf9a60065b 281 if ((xfer->data == NULL) || (xfer->dataSize == 0U))
kadonotakashi 0:8fdf9a60065b 282 {
kadonotakashi 0:8fdf9a60065b 283 return kStatus_InvalidArgument;
kadonotakashi 0:8fdf9a60065b 284 }
kadonotakashi 0:8fdf9a60065b 285
kadonotakashi 0:8fdf9a60065b 286 if (handle->saiQueue[handle->queueUser].data)
kadonotakashi 0:8fdf9a60065b 287 {
kadonotakashi 0:8fdf9a60065b 288 return kStatus_SAI_QueueFull;
kadonotakashi 0:8fdf9a60065b 289 }
kadonotakashi 0:8fdf9a60065b 290
kadonotakashi 0:8fdf9a60065b 291 /* Change the state of handle */
kadonotakashi 0:8fdf9a60065b 292 handle->state = kSAI_Busy;
kadonotakashi 0:8fdf9a60065b 293
kadonotakashi 0:8fdf9a60065b 294 /* Update queue state */
kadonotakashi 0:8fdf9a60065b 295 handle->transferSize[handle->queueUser] = xfer->dataSize;
kadonotakashi 0:8fdf9a60065b 296 handle->saiQueue[handle->queueUser].data = xfer->data;
kadonotakashi 0:8fdf9a60065b 297 handle->saiQueue[handle->queueUser].dataSize = xfer->dataSize;
kadonotakashi 0:8fdf9a60065b 298 handle->queueUser = (handle->queueUser + 1) % SAI_XFER_QUEUE_SIZE;
kadonotakashi 0:8fdf9a60065b 299
kadonotakashi 0:8fdf9a60065b 300 /* Prepare edma configure */
kadonotakashi 0:8fdf9a60065b 301 EDMA_PrepareTransfer(&config, (void *)srcAddr, handle->bytesPerFrame, xfer->data, handle->bytesPerFrame,
kadonotakashi 0:8fdf9a60065b 302 handle->count * handle->bytesPerFrame, xfer->dataSize, kEDMA_PeripheralToMemory);
kadonotakashi 0:8fdf9a60065b 303
kadonotakashi 0:8fdf9a60065b 304 /* Store the initially configured eDMA minor byte transfer count into the SAI handle */
kadonotakashi 0:8fdf9a60065b 305 handle->nbytes = handle->count * handle->bytesPerFrame;
kadonotakashi 0:8fdf9a60065b 306
kadonotakashi 0:8fdf9a60065b 307 EDMA_SubmitTransfer(handle->dmaHandle, &config);
kadonotakashi 0:8fdf9a60065b 308
kadonotakashi 0:8fdf9a60065b 309 /* Start DMA transfer */
kadonotakashi 0:8fdf9a60065b 310 EDMA_StartTransfer(handle->dmaHandle);
kadonotakashi 0:8fdf9a60065b 311
kadonotakashi 0:8fdf9a60065b 312 /* Enable DMA enable bit */
kadonotakashi 0:8fdf9a60065b 313 SAI_RxEnableDMA(base, kSAI_FIFORequestDMAEnable, true);
kadonotakashi 0:8fdf9a60065b 314
kadonotakashi 0:8fdf9a60065b 315 /* Enable SAI Rx clock */
kadonotakashi 0:8fdf9a60065b 316 SAI_RxEnable(base, true);
kadonotakashi 0:8fdf9a60065b 317
kadonotakashi 0:8fdf9a60065b 318 return kStatus_Success;
kadonotakashi 0:8fdf9a60065b 319 }
kadonotakashi 0:8fdf9a60065b 320
kadonotakashi 0:8fdf9a60065b 321 void SAI_TransferAbortSendEDMA(I2S_Type *base, sai_edma_handle_t *handle)
kadonotakashi 0:8fdf9a60065b 322 {
kadonotakashi 0:8fdf9a60065b 323 assert(handle);
kadonotakashi 0:8fdf9a60065b 324
kadonotakashi 0:8fdf9a60065b 325 /* Disable dma */
kadonotakashi 0:8fdf9a60065b 326 EDMA_AbortTransfer(handle->dmaHandle);
kadonotakashi 0:8fdf9a60065b 327
kadonotakashi 0:8fdf9a60065b 328 /* Disable DMA enable bit */
kadonotakashi 0:8fdf9a60065b 329 SAI_TxEnableDMA(base, kSAI_FIFORequestDMAEnable, false);
kadonotakashi 0:8fdf9a60065b 330
kadonotakashi 0:8fdf9a60065b 331 /* Disable Tx */
kadonotakashi 0:8fdf9a60065b 332 SAI_TxEnable(base, false);
kadonotakashi 0:8fdf9a60065b 333
kadonotakashi 0:8fdf9a60065b 334 /* Set the handle state */
kadonotakashi 0:8fdf9a60065b 335 handle->state = kSAI_Idle;
kadonotakashi 0:8fdf9a60065b 336 }
kadonotakashi 0:8fdf9a60065b 337
kadonotakashi 0:8fdf9a60065b 338 void SAI_TransferAbortReceiveEDMA(I2S_Type *base, sai_edma_handle_t *handle)
kadonotakashi 0:8fdf9a60065b 339 {
kadonotakashi 0:8fdf9a60065b 340 assert(handle);
kadonotakashi 0:8fdf9a60065b 341
kadonotakashi 0:8fdf9a60065b 342 /* Disable dma */
kadonotakashi 0:8fdf9a60065b 343 EDMA_AbortTransfer(handle->dmaHandle);
kadonotakashi 0:8fdf9a60065b 344
kadonotakashi 0:8fdf9a60065b 345 /* Disable DMA enable bit */
kadonotakashi 0:8fdf9a60065b 346 SAI_RxEnableDMA(base, kSAI_FIFORequestDMAEnable, false);
kadonotakashi 0:8fdf9a60065b 347
kadonotakashi 0:8fdf9a60065b 348 /* Disable Rx */
kadonotakashi 0:8fdf9a60065b 349 SAI_RxEnable(base, false);
kadonotakashi 0:8fdf9a60065b 350
kadonotakashi 0:8fdf9a60065b 351 /* Set the handle state */
kadonotakashi 0:8fdf9a60065b 352 handle->state = kSAI_Idle;
kadonotakashi 0:8fdf9a60065b 353 }
kadonotakashi 0:8fdf9a60065b 354
kadonotakashi 0:8fdf9a60065b 355 status_t SAI_TransferGetSendCountEDMA(I2S_Type *base, sai_edma_handle_t *handle, size_t *count)
kadonotakashi 0:8fdf9a60065b 356 {
kadonotakashi 0:8fdf9a60065b 357 assert(handle);
kadonotakashi 0:8fdf9a60065b 358
kadonotakashi 0:8fdf9a60065b 359 status_t status = kStatus_Success;
kadonotakashi 0:8fdf9a60065b 360
kadonotakashi 0:8fdf9a60065b 361 if (handle->state != kSAI_Busy)
kadonotakashi 0:8fdf9a60065b 362 {
kadonotakashi 0:8fdf9a60065b 363 status = kStatus_NoTransferInProgress;
kadonotakashi 0:8fdf9a60065b 364 }
kadonotakashi 0:8fdf9a60065b 365 else
kadonotakashi 0:8fdf9a60065b 366 {
kadonotakashi 0:8fdf9a60065b 367 *count = (handle->transferSize[handle->queueDriver] -
kadonotakashi 0:8fdf9a60065b 368 (uint32_t)handle->nbytes *
kadonotakashi 0:8fdf9a60065b 369 EDMA_GetRemainingMajorLoopCount(handle->dmaHandle->base, handle->dmaHandle->channel));
kadonotakashi 0:8fdf9a60065b 370 }
kadonotakashi 0:8fdf9a60065b 371
kadonotakashi 0:8fdf9a60065b 372 return status;
kadonotakashi 0:8fdf9a60065b 373 }
kadonotakashi 0:8fdf9a60065b 374
kadonotakashi 0:8fdf9a60065b 375 status_t SAI_TransferGetReceiveCountEDMA(I2S_Type *base, sai_edma_handle_t *handle, size_t *count)
kadonotakashi 0:8fdf9a60065b 376 {
kadonotakashi 0:8fdf9a60065b 377 assert(handle);
kadonotakashi 0:8fdf9a60065b 378
kadonotakashi 0:8fdf9a60065b 379 status_t status = kStatus_Success;
kadonotakashi 0:8fdf9a60065b 380
kadonotakashi 0:8fdf9a60065b 381 if (handle->state != kSAI_Busy)
kadonotakashi 0:8fdf9a60065b 382 {
kadonotakashi 0:8fdf9a60065b 383 status = kStatus_NoTransferInProgress;
kadonotakashi 0:8fdf9a60065b 384 }
kadonotakashi 0:8fdf9a60065b 385 else
kadonotakashi 0:8fdf9a60065b 386 {
kadonotakashi 0:8fdf9a60065b 387 *count = (handle->transferSize[handle->queueDriver] -
kadonotakashi 0:8fdf9a60065b 388 (uint32_t)handle->nbytes *
kadonotakashi 0:8fdf9a60065b 389 EDMA_GetRemainingMajorLoopCount(handle->dmaHandle->base, handle->dmaHandle->channel));
kadonotakashi 0:8fdf9a60065b 390 }
kadonotakashi 0:8fdf9a60065b 391
kadonotakashi 0:8fdf9a60065b 392 return status;
kadonotakashi 0:8fdf9a60065b 393 }