File indexing completed on 2025-05-11 08:22:59
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "fsl_flexspi_edma.h"
0010
0011
0012
0013
0014
0015
0016 #ifndef FSL_COMPONENT_ID
0017 #define FSL_COMPONENT_ID "platform.drivers.flexspi_edma"
0018 #endif
0019
0020
0021 typedef struct _flexspi_edma_private_handle
0022 {
0023 FLEXSPI_Type *base;
0024 flexspi_edma_handle_t *handle;
0025 } flexspi_edma_private_handle_t;
0026
0027
0028 enum
0029 {
0030 kFLEXSPI_Idle,
0031 kFLEXSPI_Busy
0032 };
0033
0034
0035
0036
0037
0038
0039 static FLEXSPI_Type *const s_flexspiBases[] = FLEXSPI_BASE_PTRS;
0040
0041
0042 static flexspi_edma_private_handle_t s_edmaPrivateHandle[ARRAY_SIZE(s_flexspiBases)];
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057 static void FLEXSPI_TransferEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds);
0058
0059
0060
0061
0062 static uint8_t FLEXSPI_CalculatePower(uint8_t value)
0063 {
0064 uint8_t power = 0;
0065 while (value >> 1 != 0U)
0066 {
0067 power++;
0068 value = value >> 1;
0069 }
0070
0071 return power;
0072 }
0073 static void FLEXSPI_TransferEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds)
0074 {
0075 flexspi_edma_private_handle_t *flexspiPrivateHandle = (flexspi_edma_private_handle_t *)param;
0076
0077
0078 handle = handle;
0079 tcds = tcds;
0080
0081 if (transferDone)
0082 {
0083
0084 while (!FLEXSPI_GetBusIdleStatus(flexspiPrivateHandle->base))
0085 {
0086 }
0087
0088 FLEXSPI_TransferAbortEDMA(flexspiPrivateHandle->base, flexspiPrivateHandle->handle);
0089
0090 if (flexspiPrivateHandle->handle->completionCallback != NULL)
0091 {
0092 flexspiPrivateHandle->handle->completionCallback(flexspiPrivateHandle->base, flexspiPrivateHandle->handle,
0093 kStatus_Success, flexspiPrivateHandle->handle->userData);
0094 }
0095 }
0096 }
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108 void FLEXSPI_TransferCreateHandleEDMA(FLEXSPI_Type *base,
0109 flexspi_edma_handle_t *handle,
0110 flexspi_edma_callback_t callback,
0111 void *userData,
0112 edma_handle_t *txDmaHandle,
0113 edma_handle_t *rxDmaHandle)
0114 {
0115 assert(handle);
0116
0117 uint32_t instance = FLEXSPI_GetInstance(base);
0118
0119 s_edmaPrivateHandle[instance].base = base;
0120 s_edmaPrivateHandle[instance].handle = handle;
0121
0122 (void)memset(handle, 0, sizeof(*handle));
0123
0124 handle->state = kFLEXSPI_Idle;
0125 handle->txDmaHandle = txDmaHandle;
0126 handle->rxDmaHandle = rxDmaHandle;
0127 handle->nsize = kFLEXPSI_EDMAnSize1Bytes;
0128
0129 handle->completionCallback = callback;
0130 handle->userData = userData;
0131 }
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142 void FLEXSPI_TransferUpdateSizeEDMA(FLEXSPI_Type *base,
0143 flexspi_edma_handle_t *handle,
0144 flexspi_edma_transfer_nsize_t nsize)
0145 {
0146 handle->nsize = nsize;
0147 }
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161 status_t FLEXSPI_TransferEDMA(FLEXSPI_Type *base, flexspi_edma_handle_t *handle, flexspi_transfer_t *xfer)
0162 {
0163 uint32_t configValue = 0;
0164 status_t result = kStatus_Success;
0165 edma_transfer_config_t xferConfig;
0166 uint32_t instance = FLEXSPI_GetInstance(base);
0167 uint8_t power = 0;
0168
0169 assert(handle);
0170 assert(xfer);
0171
0172
0173 if (handle->state != (uint32_t)kFLEXSPI_Idle)
0174 {
0175 result = kStatus_FLEXSPI_Busy;
0176 }
0177 else
0178 {
0179 handle->transferSize = xfer->dataSize;
0180 handle->state = kFLEXSPI_Busy;
0181
0182
0183 base->FLSHCR2[xfer->port] |= FLEXSPI_FLSHCR2_CLRINSTRPTR_MASK;
0184
0185
0186 base->INTR |= FLEXSPI_INTR_AHBCMDERR_MASK | FLEXSPI_INTR_IPCMDERR_MASK | FLEXSPI_INTR_AHBCMDGE_MASK |
0187 FLEXSPI_INTR_IPCMDGE_MASK;
0188
0189
0190 base->IPCR0 = xfer->deviceAddress;
0191
0192
0193 base->IPTXFCR |= FLEXSPI_IPTXFCR_CLRIPTXF_MASK;
0194 base->IPRXFCR |= FLEXSPI_IPRXFCR_CLRIPRXF_MASK;
0195
0196
0197 if ((xfer->cmdType == kFLEXSPI_Read) || (xfer->cmdType == kFLEXSPI_Write))
0198 {
0199 configValue = FLEXSPI_IPCR1_IDATSZ(xfer->dataSize);
0200 }
0201
0202
0203 configValue |= FLEXSPI_IPCR1_ISEQID(xfer->seqIndex) | FLEXSPI_IPCR1_ISEQNUM((uint32_t)xfer->SeqNumber - 1U);
0204 base->IPCR1 = configValue;
0205 }
0206
0207 if ((xfer->cmdType == kFLEXSPI_Write) || (xfer->cmdType == kFLEXSPI_Config))
0208 {
0209 handle->count = (uint8_t)((base->IPTXFCR & FLEXSPI_IPTXFCR_TXWMRK_MASK) >> FLEXSPI_IPTXFCR_TXWMRK_SHIFT) + 1U;
0210
0211 if (xfer->dataSize < 8U * (uint32_t)handle->count)
0212 {
0213 handle->nbytes = (uint8_t)xfer->dataSize;
0214 }
0215 else
0216 {
0217
0218 if (((handle->count) & (handle->count - 1U)) != 0U)
0219 {
0220 return kStatus_InvalidArgument;
0221 }
0222
0223 handle->nbytes = (8U * handle->count);
0224 }
0225
0226 power = FLEXSPI_CalculatePower(8U * handle->count);
0227
0228
0229 EDMA_PrepareTransfer(&xferConfig, xfer->data, (uint32_t)handle->nsize,
0230 (void *)(uint32_t *)FLEXSPI_GetTxFifoAddress(base), (uint32_t)handle->nsize,
0231 (uint32_t)handle->nbytes, xfer->dataSize, kEDMA_MemoryToMemory);
0232
0233
0234 (void)EDMA_SubmitTransfer(handle->txDmaHandle, &xferConfig);
0235 EDMA_SetModulo(handle->txDmaHandle->base, handle->txDmaHandle->channel, kEDMA_ModuloDisable,
0236 (edma_modulo_t)power);
0237 EDMA_SetCallback(handle->txDmaHandle, FLEXSPI_TransferEDMACallback,
0238 &s_edmaPrivateHandle[FLEXSPI_GetInstance(base)]);
0239 EDMA_StartTransfer(handle->txDmaHandle);
0240
0241
0242 FLEXSPI_EnableTxDMA(base, true);
0243
0244
0245 base->IPCMD |= FLEXSPI_IPCMD_TRG_MASK;
0246 }
0247 else if (xfer->cmdType == kFLEXSPI_Read)
0248 {
0249 handle->count = (uint8_t)((base->IPRXFCR & FLEXSPI_IPRXFCR_RXWMRK_MASK) >> FLEXSPI_IPRXFCR_RXWMRK_SHIFT) + 1U;
0250
0251 if (xfer->dataSize < 8U * (uint32_t)handle->count)
0252 {
0253 handle->nbytes = (uint8_t)xfer->dataSize;
0254 }
0255 else
0256 {
0257
0258 if (((handle->count) & (handle->count - 1U)) != 0U)
0259 {
0260 return kStatus_InvalidArgument;
0261 }
0262
0263 handle->nbytes = (8U * handle->count);
0264 }
0265
0266 power = FLEXSPI_CalculatePower(8U * handle->count);
0267
0268
0269 EDMA_PrepareTransfer(&xferConfig, (void *)(uint32_t *)FLEXSPI_GetRxFifoAddress(base), (uint32_t)handle->nsize,
0270 xfer->data, (uint32_t)handle->nsize, (uint32_t)handle->nbytes, xfer->dataSize,
0271 kEDMA_MemoryToMemory);
0272
0273
0274 (void)EDMA_SubmitTransfer(handle->rxDmaHandle, &xferConfig);
0275 EDMA_SetModulo(handle->txDmaHandle->base, handle->txDmaHandle->channel, (edma_modulo_t)power,
0276 kEDMA_ModuloDisable);
0277 EDMA_SetCallback(handle->rxDmaHandle, FLEXSPI_TransferEDMACallback, &s_edmaPrivateHandle[instance]);
0278 EDMA_StartTransfer(handle->rxDmaHandle);
0279
0280
0281 FLEXSPI_EnableRxDMA(base, true);
0282
0283
0284 base->IPCMD |= FLEXSPI_IPCMD_TRG_MASK;
0285 }
0286 else
0287 {
0288
0289 base->IPCMD |= FLEXSPI_IPCMD_TRG_MASK;
0290
0291 while (!FLEXSPI_GetBusIdleStatus(base))
0292 {
0293 }
0294 result = FLEXSPI_CheckAndClearError(base, base->INTR);
0295
0296 handle->state = kFLEXSPI_Idle;
0297
0298 if (handle->completionCallback != NULL)
0299 {
0300 handle->completionCallback(base, handle, result, handle->userData);
0301 }
0302 }
0303
0304 return result;
0305 }
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315 void FLEXSPI_TransferAbortEDMA(FLEXSPI_Type *base, flexspi_edma_handle_t *handle)
0316 {
0317 assert(handle);
0318
0319 if ((base->IPTXFCR & FLEXSPI_IPTXFCR_TXDMAEN_MASK) != 0x00U)
0320 {
0321 FLEXSPI_EnableTxDMA(base, false);
0322 EDMA_AbortTransfer(handle->txDmaHandle);
0323 }
0324
0325 if ((base->IPRXFCR & FLEXSPI_IPRXFCR_RXDMAEN_MASK) != 0x00U)
0326 {
0327 FLEXSPI_EnableRxDMA(base, false);
0328 EDMA_AbortTransfer(handle->rxDmaHandle);
0329 }
0330
0331 handle->state = kFLEXSPI_Idle;
0332 }
0333
0334 status_t FLEXSPI_TransferGetTransferCountEDMA(FLEXSPI_Type *base, flexspi_edma_handle_t *handle, size_t *count)
0335 {
0336 assert(handle);
0337 assert(count);
0338
0339 status_t result = kStatus_Success;
0340
0341 if (handle->state != (uint32_t)kFLEXSPI_Busy)
0342 {
0343 result = kStatus_NoTransferInProgress;
0344 }
0345 else
0346 {
0347 if ((base->IPRXFCR & FLEXSPI_IPRXFCR_RXDMAEN_MASK) != 0x00U)
0348 {
0349 *count = (handle->transferSize -
0350 (uint32_t)handle->nbytes *
0351 EDMA_GetRemainingMajorLoopCount(handle->rxDmaHandle->base, handle->rxDmaHandle->channel));
0352 }
0353 else if ((base->IPTXFCR & FLEXSPI_IPTXFCR_TXDMAEN_MASK) != 0x00U)
0354 {
0355 *count = (handle->transferSize -
0356 (uint32_t)handle->nbytes *
0357 EDMA_GetRemainingMajorLoopCount(handle->txDmaHandle->base, handle->txDmaHandle->channel));
0358 }
0359 else
0360 {
0361 ;
0362 }
0363 }
0364
0365 return result;
0366 }