status_t SAI_TransferReceiveLoopEDMASetuped(I2S_Type *base, sai_edma_handle_t *handle, sai_transfer_t *xfer, uint32_t loopTransferCount) { assert((handle != NULL) && (xfer != NULL)); edma_transfer_config_t config = {0}; uint32_t srcAddr = SAI_RxGetDataRegisterAddress(base, handle->channel); sai_transfer_t *transfer = xfer; edma_tcd_t *currentTCD = STCD_ADDR(handle->tcd); uint32_t tcdIndex = 0U; uint32_t srcOffset = 0U; // for destOffset i take the size of the initial xfer block assuming that they are all the same length, if this is not the case - take this into account uint32_t destOffset = xfer[0].dataSize / 3U;// (3U) because a frame of three uint16_t, each of which must be in its own place edma_minor_offset_config_t minorOffset = { .enableSrcMinorOffset = false, .enableDestMinorOffset = true, .minorOffset = 0xFFFFFU - 3U * destOffset + 1U + (uint32_t)handle->bytesPerFrame}; // (3U) because a frame of three uint16_t, each of which must be in its own place /* Change the state of handle */ handle->state = (uint32_t)0; for (uint32_t i = 0U; i < loopTransferCount; i++) { transfer = &xfer[i]; if ((tcdIndex >= (uint32_t)SAI_XFER_QUEUE_SIZE) || (xfer->data == NULL) || (xfer->dataSize == 0U)) { return kStatus_InvalidArgument; } /* Update the queue state */ handle->transferSize[tcdIndex] = transfer->dataSize; handle->saiQueue[tcdIndex].data = transfer->data; handle->saiQueue[tcdIndex].dataSize = transfer->dataSize; /* Prepare edma configure */ EDMA_PrepareTransferConfig(&config, (uint32_t *)srcAddr, (uint32_t)handle->bytesPerFrame, (int16_t)srcOffset, transfer->data, (uint32_t)handle->bytesPerFrame, (int16_t)destOffset, (uint32_t)3U * handle->bytesPerFrame, transfer->dataSize);// (3U) because a frame of three uint16_t, each of which must be in its own place if (i == (loopTransferCount - 1U)) { EDMA_TcdSetTransferConfig(¤tTCD[tcdIndex], &config, ¤tTCD[0]); EDMA_TcdSetMinorOffsetConfig(¤tTCD[tcdIndex], &minorOffset); EDMA_TcdEnableInterrupts(¤tTCD[tcdIndex], (uint32_t)kEDMA_MajorInterruptEnable); TCD1_addr = ¤tTCD[tcdIndex]; handle->state = (uint32_t)kSAI_BusyLoopTransfer;; break; } else { EDMA_TcdSetTransferConfig(¤tTCD[tcdIndex], &config, ¤tTCD[tcdIndex + 1U]); EDMA_TcdSetMinorOffsetConfig(¤tTCD[tcdIndex], &minorOffset); EDMA_TcdEnableInterrupts(¤tTCD[tcdIndex], (uint32_t)kEDMA_MajorInterruptEnable); TCD0_addr = ¤tTCD[tcdIndex]; } tcdIndex = tcdIndex + 1U; } EDMA_InstallTCD(handle->dmaHandle->base, handle->dmaHandle->channel, ¤tTCD[0]); /* Start DMA transfer */ EDMA_StartTransfer(handle->dmaHandle); /* Enable DMA enable bit */ SAI_RxEnableDMA(base, kSAI_FIFORequestDMAEnable, true); /* Enable the channel FIFO */ base->RCR3 |= I2S_RCR3_RCE(1UL << handle->channel); /* Enable SAI Rx clock */ SAI_RxEnable(base, true); return kStatus_Success; } //I use the function like this int main(){ //eDma initialization ... //SAI initialization ... sai_transfer_t xfer2[2]; // we receive data in ABC_ABC_ABC format in a stream (A, B, C uint16_t values, one frame contains ABC ) //the data will be stored like this: [0..240) A, [240..480) B, [480..720) C. xfer2[0].data = (uint8_t *)&destAddr[0][0]; xfer2[0].dataSize = 720 * 2; // 'ping' buffer: 720 uint16_t in buffer, xfer2[1].data = (uint8_t *)&destAddr[1][0]; xfer2[1].dataSize = 720 * 2; // 'pong' buffer: 720 uint16_t in buffer, // call the function I edited to start receiving SAI_TransferReceiveLoopEDMASetuped(SAI0, &rxHandle, &xfer2, 2); while(1){ } return 0; }