File indexing completed on 2025-05-11 08:23:01
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include "fsl_spdif_edma.h"
0011
0012
0013 #ifndef FSL_COMPONENT_ID
0014 #define FSL_COMPONENT_ID "platform.drivers.spdif_edma"
0015 #endif
0016
0017
0018
0019
0020
0021 #define STCD_ADDR(address) (edma_tcd_t *)(((uint32_t)(address) + 32U) & ~0x1FU)
0022
0023
0024 typedef struct _spdif_edma_private_handle
0025 {
0026 SPDIF_Type *base;
0027 spdif_edma_handle_t *handle;
0028 } spdif_edma_private_handle_t;
0029
0030
0031
0032
0033 typedef union pvoid_to_u32
0034 {
0035 void *pvoid;
0036 uint32_t u32;
0037 } pvoid_to_u32_t;
0038
0039
0040 enum
0041 {
0042 kSPDIF_Busy = 0x0U,
0043 kSPDIF_Idle,
0044 };
0045
0046
0047 static spdif_edma_private_handle_t s_edmaPrivateHandle[FSL_FEATURE_SOC_SPDIF_COUNT][2];
0048 static uint8_t s_spdif_tx_watermark[4] = {16, 12, 8, 4};
0049 static uint8_t s_spdif_rx_watermark[4] = {1, 4, 8, 16};
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059 static status_t SPDIF_SubmitTransfer(edma_handle_t *handle,
0060 const edma_transfer_config_t *config,
0061 uint32_t rightChannel);
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071 static void SPDIF_TxEDMACallback(edma_handle_t *handle, void *userData, bool done, uint32_t tcds);
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081 static void SPDIF_RxEDMACallback(edma_handle_t *handle, void *userData, bool done, uint32_t tcds);
0082
0083
0084
0085
0086 static void SPDIF_TxEDMACallback(edma_handle_t *handle, void *userData, bool done, uint32_t tcds)
0087 {
0088 spdif_edma_private_handle_t *privHandle = (spdif_edma_private_handle_t *)userData;
0089 spdif_edma_handle_t *spdifHandle = privHandle->handle;
0090
0091
0092 (void)memset(&spdifHandle->spdifQueue[spdifHandle->queueDriver], 0, sizeof(spdif_edma_transfer_t));
0093 spdifHandle->queueDriver = (spdifHandle->queueDriver + 0x01U) % SPDIF_XFER_QUEUE_SIZE;
0094 if (spdifHandle->callback != NULL)
0095 {
0096 (spdifHandle->callback)(privHandle->base, spdifHandle, kStatus_SPDIF_TxIdle, spdifHandle->userData);
0097 }
0098
0099
0100 if (spdifHandle->spdifQueue[spdifHandle->queueDriver].rightData == NULL)
0101 {
0102 SPDIF_TransferAbortSendEDMA(privHandle->base, spdifHandle);
0103 }
0104 }
0105
0106 static void SPDIF_RxEDMACallback(edma_handle_t *handle, void *userData, bool done, uint32_t tcds)
0107 {
0108 spdif_edma_private_handle_t *privHandle = (spdif_edma_private_handle_t *)userData;
0109 spdif_edma_handle_t *spdifHandle = privHandle->handle;
0110
0111
0112 (void)memset(&spdifHandle->spdifQueue[spdifHandle->queueDriver], 0, sizeof(spdif_edma_transfer_t));
0113 spdifHandle->queueDriver = (spdifHandle->queueDriver + 0x01U) % SPDIF_XFER_QUEUE_SIZE;
0114 if (spdifHandle->callback != NULL)
0115 {
0116 (spdifHandle->callback)(privHandle->base, spdifHandle, kStatus_SPDIF_RxIdle, spdifHandle->userData);
0117 }
0118
0119
0120 if (spdifHandle->spdifQueue[spdifHandle->queueDriver].rightData == NULL)
0121 {
0122 SPDIF_TransferAbortReceiveEDMA(privHandle->base, spdifHandle);
0123 }
0124 }
0125
0126 static status_t SPDIF_SubmitTransfer(edma_handle_t *handle, const edma_transfer_config_t *config, uint32_t rightChannel)
0127 {
0128 edma_tcd_t *tcdRegs = (edma_tcd_t *)(uint32_t)&handle->base->TCD[handle->channel];
0129 uint32_t primask;
0130 uint16_t csr;
0131 int8_t currentTcd;
0132 int8_t previousTcd;
0133 int8_t nextTcd;
0134 int8_t tcdUsed = handle->tcdUsed;
0135 int8_t tcdSize = handle->tcdSize;
0136
0137
0138 primask = DisableGlobalIRQ();
0139 if (tcdUsed >= tcdSize)
0140 {
0141 EnableGlobalIRQ(primask);
0142
0143 return kStatus_EDMA_QueueFull;
0144 }
0145 currentTcd = handle->tail;
0146 handle->tcdUsed++;
0147
0148 nextTcd = currentTcd + 0x01;
0149 if (nextTcd == handle->tcdSize)
0150 {
0151 nextTcd = 0x00;
0152 }
0153
0154 handle->tail = nextTcd;
0155 EnableGlobalIRQ(primask);
0156
0157 previousTcd = (currentTcd != 0x00) ? (currentTcd - 0x01) : (handle->tcdSize - 0x01);
0158
0159 EDMA_TcdReset(&handle->tcdPool[currentTcd]);
0160 EDMA_TcdSetTransferConfig(&handle->tcdPool[currentTcd], config, NULL);
0161
0162 EDMA_TcdSetChannelLink(&handle->tcdPool[currentTcd], kEDMA_MinorLink, rightChannel);
0163 EDMA_TcdSetChannelLink(&handle->tcdPool[currentTcd], kEDMA_MajorLink, rightChannel);
0164
0165 handle->tcdPool[currentTcd].CSR |= DMA_CSR_INTMAJOR_MASK;
0166
0167 handle->tcdPool[currentTcd].DLAST_SGA = (uint32_t)&handle->tcdPool[nextTcd];
0168
0169 if (currentTcd != previousTcd)
0170 {
0171
0172 csr = (handle->tcdPool[previousTcd].CSR | (uint16_t)DMA_CSR_ESG_MASK) & ~(uint16_t)DMA_CSR_DREQ_MASK;
0173 handle->tcdPool[previousTcd].CSR = csr;
0174
0175
0176
0177
0178
0179
0180 if (tcdRegs->DLAST_SGA == (uint32_t)&handle->tcdPool[currentTcd])
0181 {
0182
0183 csr = (tcdRegs->CSR | (uint16_t)DMA_CSR_ESG_MASK) & ~(uint16_t)DMA_CSR_DREQ_MASK;
0184
0185 tcdRegs->CSR = csr;
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196 if ((tcdRegs->CSR & DMA_CSR_ESG_MASK) != 0x00U)
0197 {
0198 return kStatus_Success;
0199 }
0200
0201
0202
0203
0204
0205 if (tcdRegs->DLAST_SGA == (uint32_t)&handle->tcdPool[nextTcd])
0206 {
0207 return kStatus_Success;
0208 }
0209
0210
0211
0212
0213 }
0214 else if (tcdRegs->DLAST_SGA != 0x00U)
0215 {
0216
0217 return kStatus_Success;
0218 }
0219 else
0220 {
0221
0222
0223
0224
0225 }
0226 }
0227
0228 EDMA_InstallTCD(handle->base, handle->channel, &handle->tcdPool[currentTcd]);
0229
0230 if ((handle->flags & 0x80U) != 0x00U)
0231 {
0232 handle->base->SERQ = DMA_SERQ_SERQ(handle->channel);
0233 }
0234 else
0235 {
0236 ;
0237 }
0238
0239 return kStatus_Success;
0240 }
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256 void SPDIF_TransferTxCreateHandleEDMA(SPDIF_Type *base,
0257 spdif_edma_handle_t *handle,
0258 spdif_edma_callback_t callback,
0259 void *userData,
0260 edma_handle_t *dmaLeftHandle,
0261 edma_handle_t *dmaRightHandle)
0262 {
0263 assert(handle != NULL);
0264 assert(dmaLeftHandle != NULL);
0265 assert(dmaRightHandle != NULL);
0266
0267 uint32_t instance = SPDIF_GetInstance(base);
0268
0269
0270 (void)memset(handle, 0, sizeof(*handle));
0271
0272
0273 handle->dmaLeftHandle = dmaLeftHandle;
0274 handle->dmaRightHandle = dmaRightHandle;
0275 handle->callback = callback;
0276 handle->userData = userData;
0277 handle->count =
0278 s_spdif_tx_watermark[(base->SCR & SPDIF_SCR_TXFIFOEMPTY_SEL_MASK) >> SPDIF_SCR_TXFIFOEMPTY_SEL_SHIFT];
0279
0280
0281 handle->state = kSPDIF_Idle;
0282
0283 s_edmaPrivateHandle[instance][0].base = base;
0284 s_edmaPrivateHandle[instance][0].handle = handle;
0285
0286
0287 EDMA_InstallTCDMemory(dmaLeftHandle, STCD_ADDR(handle->leftTcd), SPDIF_XFER_QUEUE_SIZE);
0288 EDMA_InstallTCDMemory(dmaRightHandle, STCD_ADDR(handle->rightTcd), SPDIF_XFER_QUEUE_SIZE);
0289
0290
0291 EDMA_SetCallback(dmaRightHandle, SPDIF_TxEDMACallback, &s_edmaPrivateHandle[instance][0]);
0292 }
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308 void SPDIF_TransferRxCreateHandleEDMA(SPDIF_Type *base,
0309 spdif_edma_handle_t *handle,
0310 spdif_edma_callback_t callback,
0311 void *userData,
0312 edma_handle_t *dmaLeftHandle,
0313 edma_handle_t *dmaRightHandle)
0314 {
0315 assert(handle != NULL);
0316 assert(dmaLeftHandle != NULL);
0317 assert(dmaRightHandle != NULL);
0318
0319 uint32_t instance = SPDIF_GetInstance(base);
0320
0321
0322 (void)memset(handle, 0, sizeof(*handle));
0323
0324
0325 handle->dmaLeftHandle = dmaLeftHandle;
0326 handle->dmaRightHandle = dmaRightHandle;
0327 handle->callback = callback;
0328 handle->userData = userData;
0329 handle->count = s_spdif_rx_watermark[(base->SCR & SPDIF_SCR_RXFIFOFULL_SEL_MASK) >> SPDIF_SCR_RXFIFOFULL_SEL_SHIFT];
0330
0331
0332 handle->state = kSPDIF_Idle;
0333
0334 s_edmaPrivateHandle[instance][1].base = base;
0335 s_edmaPrivateHandle[instance][1].handle = handle;
0336
0337
0338 EDMA_InstallTCDMemory(dmaLeftHandle, STCD_ADDR(handle->leftTcd), SPDIF_XFER_QUEUE_SIZE);
0339 EDMA_InstallTCDMemory(dmaRightHandle, STCD_ADDR(handle->rightTcd), SPDIF_XFER_QUEUE_SIZE);
0340
0341
0342 EDMA_SetCallback(dmaRightHandle, SPDIF_RxEDMACallback, &s_edmaPrivateHandle[instance][1]);
0343 }
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358 status_t SPDIF_TransferSendEDMA(SPDIF_Type *base, spdif_edma_handle_t *handle, spdif_edma_transfer_t *xfer)
0359 {
0360 assert(handle != NULL);
0361 assert(xfer != NULL);
0362
0363 pvoid_to_u32_t destAddr;
0364 edma_transfer_config_t config = {0};
0365 destAddr.u32 = SPDIF_TxGetLeftDataRegisterAddress(base);
0366
0367
0368 if ((xfer->leftData == NULL) || (xfer->dataSize == 0U) || (xfer->rightData == NULL))
0369 {
0370 return kStatus_InvalidArgument;
0371 }
0372
0373 if ((handle->spdifQueue[handle->queueUser].leftData != NULL) ||
0374 (handle->spdifQueue[handle->queueUser].rightData != NULL))
0375 {
0376 return kStatus_SPDIF_QueueFull;
0377 }
0378
0379
0380 handle->state = kSPDIF_Busy;
0381
0382
0383 handle->transferSize[handle->queueUser] = xfer->dataSize;
0384 handle->spdifQueue[handle->queueUser].leftData = xfer->leftData;
0385 handle->spdifQueue[handle->queueUser].dataSize = xfer->dataSize;
0386 handle->spdifQueue[handle->queueUser].rightData = xfer->rightData;
0387 handle->queueUser = (handle->queueUser + 0x01U) % SPDIF_XFER_QUEUE_SIZE;
0388
0389
0390 handle->nbytes = handle->count * 8U;
0391
0392
0393 EDMA_PrepareTransfer(&config, xfer->leftData, 4U, destAddr.pvoid, 4U, (uint32_t)handle->count * 4U, xfer->dataSize,
0394 kEDMA_MemoryToPeripheral);
0395 (void)SPDIF_SubmitTransfer(handle->dmaLeftHandle, &config, handle->dmaRightHandle->channel);
0396
0397
0398 destAddr.u32 = SPDIF_TxGetRightDataRegisterAddress(base);
0399 EDMA_PrepareTransfer(&config, xfer->rightData, 4U, destAddr.pvoid, 4U, (uint32_t)handle->count * 4U, xfer->dataSize,
0400 kEDMA_MemoryToPeripheral);
0401 (void)EDMA_SubmitTransfer(handle->dmaRightHandle, &config);
0402
0403
0404 EDMA_StartTransfer(handle->dmaLeftHandle);
0405 EDMA_StartTransfer(handle->dmaRightHandle);
0406
0407
0408 SPDIF_EnableDMA(base, kSPDIF_TxDMAEnable, true);
0409
0410
0411 SPDIF_TxEnable(base, true);
0412
0413 return kStatus_Success;
0414 }
0415
0416
0417
0418
0419
0420
0421
0422
0423
0424
0425
0426
0427
0428
0429 status_t SPDIF_TransferReceiveEDMA(SPDIF_Type *base, spdif_edma_handle_t *handle, spdif_edma_transfer_t *xfer)
0430 {
0431 assert(handle != NULL);
0432 assert(xfer != NULL);
0433
0434 pvoid_to_u32_t srcAddr;
0435 edma_transfer_config_t config = {0};
0436 srcAddr.u32 = SPDIF_RxGetLeftDataRegisterAddress(base);
0437
0438
0439 if ((xfer->leftData == NULL) || (xfer->dataSize == 0U) || (xfer->rightData == NULL))
0440 {
0441 return kStatus_InvalidArgument;
0442 }
0443
0444 if ((handle->spdifQueue[handle->queueUser].leftData != NULL) ||
0445 (handle->spdifQueue[handle->queueUser].rightData != NULL))
0446 {
0447 return kStatus_SPDIF_QueueFull;
0448 }
0449
0450
0451 handle->state = kSPDIF_Busy;
0452
0453
0454 handle->transferSize[handle->queueUser] = xfer->dataSize;
0455 handle->spdifQueue[handle->queueUser].leftData = xfer->leftData;
0456 handle->spdifQueue[handle->queueUser].dataSize = xfer->dataSize;
0457 handle->spdifQueue[handle->queueUser].rightData = xfer->rightData;
0458 handle->queueUser = (handle->queueUser + 0x01U) % SPDIF_XFER_QUEUE_SIZE;
0459
0460
0461 handle->nbytes = handle->count * 8U;
0462
0463
0464 EDMA_PrepareTransfer(&config, srcAddr.pvoid, 4U, xfer->leftData, 4U, (uint32_t)handle->count * 4U, xfer->dataSize,
0465 kEDMA_PeripheralToMemory);
0466
0467 (void)SPDIF_SubmitTransfer(handle->dmaLeftHandle, &config, handle->dmaRightHandle->channel);
0468
0469
0470 srcAddr.u32 = SPDIF_RxGetRightDataRegisterAddress(base);
0471 EDMA_PrepareTransfer(&config, srcAddr.pvoid, 4U, xfer->rightData, 4U, (uint32_t)handle->count * 4U, xfer->dataSize,
0472 kEDMA_PeripheralToMemory);
0473 (void)EDMA_SubmitTransfer(handle->dmaRightHandle, &config);
0474
0475
0476 EDMA_StartTransfer(handle->dmaLeftHandle);
0477 EDMA_StartTransfer(handle->dmaRightHandle);
0478
0479
0480 SPDIF_EnableDMA(base, kSPDIF_RxDMAEnable, true);
0481
0482
0483 SPDIF_RxEnable(base, true);
0484
0485 return kStatus_Success;
0486 }
0487
0488
0489
0490
0491
0492
0493
0494 void SPDIF_TransferAbortSendEDMA(SPDIF_Type *base, spdif_edma_handle_t *handle)
0495 {
0496 assert(handle != NULL);
0497
0498
0499 EDMA_AbortTransfer(handle->dmaLeftHandle);
0500 EDMA_AbortTransfer(handle->dmaRightHandle);
0501
0502
0503 SPDIF_EnableDMA(base, kSPDIF_TxDMAEnable, false);
0504
0505
0506 (void)memset(handle->spdifQueue, 0, sizeof(handle->spdifQueue));
0507 (void)memset(handle->transferSize, 0, sizeof(handle->transferSize));
0508 handle->queueUser = 0U;
0509 handle->queueDriver = 0U;
0510
0511
0512 handle->state = kSPDIF_Idle;
0513 }
0514
0515
0516
0517
0518
0519
0520
0521 void SPDIF_TransferAbortReceiveEDMA(SPDIF_Type *base, spdif_edma_handle_t *handle)
0522 {
0523 assert(handle != NULL);
0524
0525
0526 EDMA_AbortTransfer(handle->dmaLeftHandle);
0527 EDMA_AbortTransfer(handle->dmaRightHandle);
0528
0529
0530 SPDIF_EnableDMA(base, kSPDIF_RxDMAEnable, false);
0531
0532
0533 (void)memset(handle->spdifQueue, 0, sizeof(handle->spdifQueue));
0534 (void)memset(handle->transferSize, 0, sizeof(handle->transferSize));
0535 handle->queueUser = 0U;
0536 handle->queueDriver = 0U;
0537
0538
0539 handle->state = kSPDIF_Idle;
0540 }
0541
0542
0543
0544
0545
0546
0547
0548
0549
0550
0551 status_t SPDIF_TransferGetSendCountEDMA(SPDIF_Type *base, spdif_edma_handle_t *handle, size_t *count)
0552 {
0553 assert(handle != NULL);
0554
0555 status_t status = kStatus_Success;
0556
0557 if (handle->state != (uint32_t)kSPDIF_Busy)
0558 {
0559 status = kStatus_NoTransferInProgress;
0560 }
0561 else
0562 {
0563 *count = (handle->transferSize[handle->queueDriver] -
0564 (uint32_t)handle->nbytes *
0565 EDMA_GetRemainingMajorLoopCount(handle->dmaRightHandle->base, handle->dmaRightHandle->channel));
0566 }
0567
0568 return status;
0569 }
0570
0571
0572
0573
0574
0575
0576
0577
0578
0579
0580 status_t SPDIF_TransferGetReceiveCountEDMA(SPDIF_Type *base, spdif_edma_handle_t *handle, size_t *count)
0581 {
0582 assert(handle != NULL);
0583
0584 status_t status = kStatus_Success;
0585
0586 if (handle->state != (uint32_t)kSPDIF_Busy)
0587 {
0588 status = kStatus_NoTransferInProgress;
0589 }
0590 else
0591 {
0592 *count = (handle->transferSize[handle->queueDriver] -
0593 (uint32_t)handle->nbytes *
0594 EDMA_GetRemainingMajorLoopCount(handle->dmaRightHandle->base, handle->dmaRightHandle->channel));
0595 }
0596
0597 return status;
0598 }