File indexing completed on 2025-05-11 08:22:59
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "fsl_flexio_spi_edma.h"
0010
0011
0012
0013
0014
0015
0016 #ifndef FSL_COMPONENT_ID
0017 #define FSL_COMPONENT_ID "platform.drivers.flexio_spi_edma"
0018 #endif
0019
0020
0021 typedef struct _flexio_spi_master_edma_private_handle
0022 {
0023 FLEXIO_SPI_Type *base;
0024 flexio_spi_master_edma_handle_t *handle;
0025 } flexio_spi_master_edma_private_handle_t;
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 static void FLEXIO_SPI_TxEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds);
0038
0039
0040
0041
0042
0043
0044
0045 static void FLEXIO_SPI_RxEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds);
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056 static status_t FLEXIO_SPI_EDMAConfig(FLEXIO_SPI_Type *base,
0057 flexio_spi_master_edma_handle_t *handle,
0058 flexio_spi_transfer_t *xfer);
0059
0060
0061
0062
0063
0064
0065 static const uint32_t s_dummyData = FLEXIO_SPI_DUMMYDATA;
0066
0067
0068 #define FLEXIO_SPI_HANDLE_COUNT 2
0069
0070
0071 static flexio_spi_master_edma_private_handle_t s_edmaPrivateHandle[FLEXIO_SPI_HANDLE_COUNT];
0072
0073
0074
0075
0076
0077 static void FLEXIO_SPI_TxEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds)
0078 {
0079 tcds = tcds;
0080 flexio_spi_master_edma_private_handle_t *spiPrivateHandle = (flexio_spi_master_edma_private_handle_t *)param;
0081
0082
0083 if (transferDone)
0084 {
0085 FLEXIO_SPI_EnableDMA(spiPrivateHandle->base, (uint32_t)kFLEXIO_SPI_TxDmaEnable, false);
0086
0087
0088 spiPrivateHandle->handle->txInProgress = false;
0089
0090
0091 if ((spiPrivateHandle->handle->txInProgress == false) && (spiPrivateHandle->handle->rxInProgress == false))
0092 {
0093 if (spiPrivateHandle->handle->callback != NULL)
0094 {
0095 (spiPrivateHandle->handle->callback)(spiPrivateHandle->base, spiPrivateHandle->handle, kStatus_Success,
0096 spiPrivateHandle->handle->userData);
0097 }
0098 }
0099 }
0100 }
0101
0102 static void FLEXIO_SPI_RxEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds)
0103 {
0104 tcds = tcds;
0105 flexio_spi_master_edma_private_handle_t *spiPrivateHandle = (flexio_spi_master_edma_private_handle_t *)param;
0106
0107 if (transferDone)
0108 {
0109
0110 FLEXIO_SPI_EnableDMA(spiPrivateHandle->base, (uint32_t)kFLEXIO_SPI_RxDmaEnable, false);
0111
0112
0113 spiPrivateHandle->handle->rxInProgress = false;
0114
0115
0116 if ((spiPrivateHandle->handle->txInProgress == false) && (spiPrivateHandle->handle->rxInProgress == false))
0117 {
0118 if (spiPrivateHandle->handle->callback != NULL)
0119 {
0120 (spiPrivateHandle->handle->callback)(spiPrivateHandle->base, spiPrivateHandle->handle, kStatus_Success,
0121 spiPrivateHandle->handle->userData);
0122 }
0123 }
0124 }
0125 }
0126
0127 static status_t FLEXIO_SPI_EDMAConfig(FLEXIO_SPI_Type *base,
0128 flexio_spi_master_edma_handle_t *handle,
0129 flexio_spi_transfer_t *xfer)
0130 {
0131 edma_transfer_config_t xferConfig = {0};
0132 flexio_spi_shift_direction_t direction = kFLEXIO_SPI_MsbFirst;
0133 uint8_t bytesPerFrame;
0134 uint8_t dataFormat = FLEXIO_SPI_XFER_DATA_FORMAT(xfer->flags);
0135
0136
0137 switch (dataFormat)
0138 {
0139 case (uint8_t)kFLEXIO_SPI_8bitMsb:
0140 bytesPerFrame = 1U;
0141 direction = kFLEXIO_SPI_MsbFirst;
0142 break;
0143 case (uint8_t)kFLEXIO_SPI_8bitLsb:
0144 bytesPerFrame = 1U;
0145 direction = kFLEXIO_SPI_LsbFirst;
0146 break;
0147 case (uint8_t)kFLEXIO_SPI_16bitMsb:
0148 bytesPerFrame = 2U;
0149 direction = kFLEXIO_SPI_MsbFirst;
0150 break;
0151 case (uint8_t)kFLEXIO_SPI_16bitLsb:
0152 bytesPerFrame = 2U;
0153 direction = kFLEXIO_SPI_LsbFirst;
0154 break;
0155 case (uint8_t)kFLEXIO_SPI_32bitMsb:
0156 bytesPerFrame = 4U;
0157 direction = kFLEXIO_SPI_MsbFirst;
0158 break;
0159 case (uint8_t)kFLEXIO_SPI_32bitLsb:
0160 bytesPerFrame = 4U;
0161 direction = kFLEXIO_SPI_LsbFirst;
0162 break;
0163 default:
0164 bytesPerFrame = 1U;
0165 direction = kFLEXIO_SPI_MsbFirst;
0166 assert(true);
0167 break;
0168 }
0169
0170
0171 if ((xfer->dataSize % bytesPerFrame) != 0U)
0172 {
0173 return kStatus_InvalidArgument;
0174 }
0175
0176
0177 handle->transferSize = xfer->dataSize;
0178
0179
0180 xferConfig.destAddr = FLEXIO_SPI_GetTxDataRegisterAddress(base, direction);
0181 xferConfig.destOffset = 0;
0182 if (bytesPerFrame == 1U)
0183 {
0184 xferConfig.srcTransferSize = kEDMA_TransferSize1Bytes;
0185 xferConfig.destTransferSize = kEDMA_TransferSize1Bytes;
0186 xferConfig.minorLoopBytes = 1U;
0187 }
0188 else if (bytesPerFrame == 2U)
0189 {
0190 if (direction == kFLEXIO_SPI_MsbFirst)
0191 {
0192 xferConfig.destAddr -= 1U;
0193 }
0194 xferConfig.srcTransferSize = kEDMA_TransferSize2Bytes;
0195 xferConfig.destTransferSize = kEDMA_TransferSize2Bytes;
0196 xferConfig.minorLoopBytes = 2U;
0197 }
0198 else
0199 {
0200 if (direction == kFLEXIO_SPI_MsbFirst)
0201 {
0202 xferConfig.destAddr -= 3U;
0203 }
0204 xferConfig.srcTransferSize = kEDMA_TransferSize4Bytes;
0205 xferConfig.destTransferSize = kEDMA_TransferSize4Bytes;
0206 xferConfig.minorLoopBytes = 4U;
0207 }
0208
0209
0210 if (xfer->txData != NULL)
0211 {
0212 xferConfig.srcOffset = (int16_t)bytesPerFrame;
0213 xferConfig.srcAddr = (uint32_t)(xfer->txData);
0214 }
0215 else
0216 {
0217
0218 xferConfig.srcOffset = 0;
0219 xferConfig.srcAddr = (uint32_t)(&s_dummyData);
0220 }
0221
0222 xferConfig.majorLoopCounts = (xfer->dataSize / xferConfig.minorLoopBytes);
0223
0224
0225 handle->nbytes = (uint8_t)xferConfig.minorLoopBytes;
0226
0227 if (handle->txHandle != NULL)
0228 {
0229 (void)EDMA_SubmitTransfer(handle->txHandle, &xferConfig);
0230 }
0231
0232
0233 if (xfer->rxData != NULL)
0234 {
0235 xferConfig.srcAddr = FLEXIO_SPI_GetRxDataRegisterAddress(base, direction);
0236 if (bytesPerFrame == 2U)
0237 {
0238 if (direction == kFLEXIO_SPI_LsbFirst)
0239 {
0240 xferConfig.srcAddr -= 1U;
0241 }
0242 }
0243 else if (bytesPerFrame == 4U)
0244 {
0245 if (direction == kFLEXIO_SPI_LsbFirst)
0246 {
0247 xferConfig.srcAddr -= 3U;
0248 }
0249 }
0250 else
0251 {
0252 }
0253 xferConfig.srcOffset = 0;
0254 xferConfig.destAddr = (uint32_t)(xfer->rxData);
0255 xferConfig.destOffset = (int16_t)bytesPerFrame;
0256 (void)EDMA_SubmitTransfer(handle->rxHandle, &xferConfig);
0257 handle->rxInProgress = true;
0258 FLEXIO_SPI_EnableDMA(base, (uint32_t)kFLEXIO_SPI_RxDmaEnable, true);
0259 EDMA_StartTransfer(handle->rxHandle);
0260 }
0261
0262
0263 if (handle->txHandle != NULL)
0264 {
0265 handle->txInProgress = true;
0266 FLEXIO_SPI_EnableDMA(base, (uint32_t)kFLEXIO_SPI_TxDmaEnable, true);
0267 EDMA_StartTransfer(handle->txHandle);
0268 }
0269
0270 return kStatus_Success;
0271 }
0272
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290 status_t FLEXIO_SPI_MasterTransferCreateHandleEDMA(FLEXIO_SPI_Type *base,
0291 flexio_spi_master_edma_handle_t *handle,
0292 flexio_spi_master_edma_transfer_callback_t callback,
0293 void *userData,
0294 edma_handle_t *txHandle,
0295 edma_handle_t *rxHandle)
0296 {
0297 assert(handle != NULL);
0298
0299 uint8_t index = 0;
0300
0301
0302 for (index = 0U; index < (uint8_t)FLEXIO_SPI_HANDLE_COUNT; index++)
0303 {
0304 if (s_edmaPrivateHandle[index].base == NULL)
0305 {
0306 s_edmaPrivateHandle[index].base = base;
0307 s_edmaPrivateHandle[index].handle = handle;
0308 break;
0309 }
0310 }
0311
0312 if (index == (uint16_t)FLEXIO_SPI_HANDLE_COUNT)
0313 {
0314 return kStatus_OutOfRange;
0315 }
0316
0317
0318 handle->txHandle = txHandle;
0319 handle->rxHandle = rxHandle;
0320
0321
0322 handle->callback = callback;
0323 handle->userData = userData;
0324
0325
0326 handle->txInProgress = false;
0327 handle->rxInProgress = false;
0328
0329
0330 if (handle->txHandle != NULL)
0331 {
0332 EDMA_SetCallback(handle->txHandle, FLEXIO_SPI_TxEDMACallback, &s_edmaPrivateHandle[index]);
0333 }
0334 if (handle->rxHandle != NULL)
0335 {
0336 EDMA_SetCallback(handle->rxHandle, FLEXIO_SPI_RxEDMACallback, &s_edmaPrivateHandle[index]);
0337 }
0338
0339 return kStatus_Success;
0340 }
0341
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356 status_t FLEXIO_SPI_MasterTransferEDMA(FLEXIO_SPI_Type *base,
0357 flexio_spi_master_edma_handle_t *handle,
0358 flexio_spi_transfer_t *xfer)
0359 {
0360 assert(handle != NULL);
0361 assert(xfer != NULL);
0362
0363 uint32_t dataMode = 0;
0364 uint16_t timerCmp = (uint16_t)base->flexioBase->TIMCMP[base->timerIndex[0]];
0365 uint8_t dataFormat = FLEXIO_SPI_XFER_DATA_FORMAT(xfer->flags);
0366
0367 timerCmp &= 0x00FFU;
0368
0369
0370 if ((handle->txInProgress) || (handle->rxInProgress))
0371 {
0372 return kStatus_FLEXIO_SPI_Busy;
0373 }
0374
0375
0376 if (((xfer->txData == NULL) && (xfer->rxData == NULL)) || (xfer->dataSize == 0U))
0377 {
0378 return kStatus_InvalidArgument;
0379 }
0380
0381
0382
0383
0384
0385
0386
0387 if ((xfer->flags & (uint8_t)kFLEXIO_SPI_csContinuous) != 0U)
0388 {
0389 base->flexioBase->TIMCFG[base->timerIndex[0]] =
0390 (base->flexioBase->TIMCFG[base->timerIndex[0]] & ~FLEXIO_TIMCFG_TSTOP_MASK) |
0391 FLEXIO_TIMCFG_TSTOP(kFLEXIO_TimerStopBitDisabled);
0392 }
0393 else
0394 {
0395 base->flexioBase->TIMCFG[base->timerIndex[0]] =
0396 (base->flexioBase->TIMCFG[base->timerIndex[0]] & ~FLEXIO_TIMCFG_TSTOP_MASK) |
0397 FLEXIO_TIMCFG_TSTOP(kFLEXIO_TimerStopBitEnableOnTimerDisable);
0398 }
0399
0400
0401 if ((dataFormat == (uint8_t)kFLEXIO_SPI_8bitMsb) || (dataFormat == (uint8_t)kFLEXIO_SPI_8bitLsb))
0402 {
0403 dataMode = (8UL * 2UL - 1UL) << 8U;
0404 }
0405 else if ((dataFormat == (uint8_t)kFLEXIO_SPI_16bitMsb) || (dataFormat == (uint8_t)kFLEXIO_SPI_16bitLsb))
0406 {
0407 dataMode = (16UL * 2UL - 1UL) << 8U;
0408 }
0409 else if ((dataFormat == (uint8_t)kFLEXIO_SPI_32bitMsb) || (dataFormat == (uint8_t)kFLEXIO_SPI_32bitLsb))
0410 {
0411 dataMode = (32UL * 2UL - 1UL) << 8U;
0412 }
0413 else
0414 {
0415 dataMode = (8UL * 2UL - 1UL) << 8U;
0416 }
0417
0418 dataMode |= timerCmp;
0419
0420 base->flexioBase->TIMCMP[base->timerIndex[0]] = dataMode;
0421
0422 return FLEXIO_SPI_EDMAConfig(base, handle, xfer);
0423 }
0424
0425
0426
0427
0428
0429
0430
0431
0432 status_t FLEXIO_SPI_MasterTransferGetCountEDMA(FLEXIO_SPI_Type *base,
0433 flexio_spi_master_edma_handle_t *handle,
0434 size_t *count)
0435 {
0436 assert(handle != NULL);
0437
0438 if (NULL == count)
0439 {
0440 return kStatus_InvalidArgument;
0441 }
0442
0443 if (handle->rxInProgress)
0444 {
0445 *count =
0446 (handle->transferSize - (uint32_t)handle->nbytes * EDMA_GetRemainingMajorLoopCount(
0447 handle->rxHandle->base, handle->rxHandle->channel));
0448 }
0449 else
0450 {
0451 *count =
0452 (handle->transferSize - (uint32_t)handle->nbytes * EDMA_GetRemainingMajorLoopCount(
0453 handle->txHandle->base, handle->txHandle->channel));
0454 }
0455
0456 return kStatus_Success;
0457 }
0458
0459
0460
0461
0462
0463
0464
0465 void FLEXIO_SPI_MasterTransferAbortEDMA(FLEXIO_SPI_Type *base, flexio_spi_master_edma_handle_t *handle)
0466 {
0467 assert(handle != NULL);
0468
0469
0470 EDMA_AbortTransfer(handle->txHandle);
0471 EDMA_AbortTransfer(handle->rxHandle);
0472
0473
0474 FLEXIO_SPI_EnableDMA(base, (uint32_t)kFLEXIO_SPI_DmaAllEnable, false);
0475
0476
0477 handle->txInProgress = false;
0478 handle->rxInProgress = false;
0479 }
0480
0481
0482
0483
0484
0485
0486
0487
0488
0489
0490
0491
0492
0493
0494
0495 status_t FLEXIO_SPI_SlaveTransferEDMA(FLEXIO_SPI_Type *base,
0496 flexio_spi_slave_edma_handle_t *handle,
0497 flexio_spi_transfer_t *xfer)
0498 {
0499 assert(handle != NULL);
0500 assert(xfer != NULL);
0501
0502 uint32_t dataMode = 0U;
0503 uint8_t dataFormat = FLEXIO_SPI_XFER_DATA_FORMAT(xfer->flags);
0504
0505
0506 if ((handle->txInProgress) || (handle->rxInProgress))
0507 {
0508 return kStatus_FLEXIO_SPI_Busy;
0509 }
0510
0511
0512
0513
0514
0515
0516 FLEXIO_SPI_FlushShifters(base);
0517 if ((xfer->flags & (uint8_t)kFLEXIO_SPI_csContinuous) != 0U)
0518 {
0519 base->flexioBase->TIMCFG[base->timerIndex[0]] |= FLEXIO_TIMCFG_TIMDIS(kFLEXIO_TimerDisableOnTriggerFallingEdge);
0520 }
0521 else
0522 {
0523 if ((base->flexioBase->SHIFTCTL[base->shifterIndex[0]] & FLEXIO_SHIFTCTL_TIMPOL_MASK) ==
0524 FLEXIO_SHIFTCTL_TIMPOL(kFLEXIO_ShifterTimerPolarityOnNegitive))
0525 {
0526 base->flexioBase->TIMCFG[base->timerIndex[0]] =
0527 (base->flexioBase->TIMCFG[base->timerIndex[0]] & ~FLEXIO_TIMCFG_TIMDIS_MASK) |
0528 FLEXIO_TIMCFG_TIMDIS(kFLEXIO_TimerDisableOnTimerCompare);
0529 }
0530 else
0531 {
0532 base->flexioBase->TIMCFG[base->timerIndex[0]] =
0533 (base->flexioBase->TIMCFG[base->timerIndex[0]] & ~FLEXIO_TIMCFG_TIMDIS_MASK) |
0534 FLEXIO_TIMCFG_TIMDIS(kFLEXIO_TimerDisableOnTriggerFallingEdge);
0535 }
0536 }
0537
0538
0539 if (((xfer->txData == NULL) && (xfer->rxData == NULL)) || (xfer->dataSize == 0U))
0540 {
0541 return kStatus_InvalidArgument;
0542 }
0543
0544
0545 if ((dataFormat == (uint8_t)kFLEXIO_SPI_8bitMsb) || (dataFormat == (uint8_t)kFLEXIO_SPI_8bitLsb))
0546 {
0547 dataMode = 8U * 2U - 1U;
0548 }
0549 else if ((dataFormat == (uint8_t)kFLEXIO_SPI_16bitMsb) || (dataFormat == (uint8_t)kFLEXIO_SPI_16bitLsb))
0550 {
0551 dataMode = 16U * 2U - 1U;
0552 }
0553 else if ((dataFormat == (uint8_t)kFLEXIO_SPI_32bitMsb) || (dataFormat == (uint8_t)kFLEXIO_SPI_32bitLsb))
0554 {
0555 dataMode = 32UL * 2UL - 1UL;
0556 }
0557 else
0558 {
0559 dataMode = 8U * 2U - 1U;
0560 }
0561
0562 base->flexioBase->TIMCMP[base->timerIndex[0]] = dataMode;
0563
0564 return FLEXIO_SPI_EDMAConfig(base, handle, xfer);
0565 }