File indexing completed on 2025-05-11 08:23:00
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "fsl_lpuart_edma.h"
0010
0011
0012
0013
0014
0015
0016 #ifndef FSL_COMPONENT_ID
0017 #define FSL_COMPONENT_ID "platform.drivers.lpuart_edma"
0018 #endif
0019
0020
0021 typedef struct _lpuart_edma_private_handle
0022 {
0023 LPUART_Type *base;
0024 lpuart_edma_handle_t *handle;
0025 } lpuart_edma_private_handle_t;
0026
0027
0028 enum
0029 {
0030 kLPUART_TxIdle,
0031 kLPUART_TxBusy,
0032 kLPUART_RxIdle,
0033 kLPUART_RxBusy
0034 };
0035
0036
0037
0038
0039
0040
0041 #if (defined(LPUART12))
0042 #define LPUART_HANDLE_ARRAY_SIZE 13
0043 #else
0044 #if (defined(LPUART11))
0045 #define LPUART_HANDLE_ARRAY_SIZE 12
0046 #else
0047 #if (defined(LPUART10))
0048 #define LPUART_HANDLE_ARRAY_SIZE 11
0049 #else
0050 #if (defined(LPUART9))
0051 #define LPUART_HANDLE_ARRAY_SIZE 10
0052 #else
0053 #if (defined(LPUART8))
0054 #define LPUART_HANDLE_ARRAY_SIZE 9
0055 #else
0056 #if (defined(LPUART7))
0057 #define LPUART_HANDLE_ARRAY_SIZE 8
0058 #else
0059 #if (defined(LPUART6))
0060 #define LPUART_HANDLE_ARRAY_SIZE 7
0061 #else
0062 #if (defined(LPUART5))
0063 #define LPUART_HANDLE_ARRAY_SIZE 6
0064 #else
0065 #if (defined(LPUART4))
0066 #define LPUART_HANDLE_ARRAY_SIZE 5
0067 #else
0068 #if (defined(LPUART3))
0069 #define LPUART_HANDLE_ARRAY_SIZE 4
0070 #else
0071 #if (defined(LPUART2))
0072 #define LPUART_HANDLE_ARRAY_SIZE 3
0073 #else
0074 #if (defined(LPUART1))
0075 #define LPUART_HANDLE_ARRAY_SIZE 2
0076 #else
0077 #if (defined(LPUART0))
0078 #define LPUART_HANDLE_ARRAY_SIZE 1
0079 #else
0080 #define LPUART_HANDLE_ARRAY_SIZE FSL_FEATURE_SOC_LPUART_COUNT
0081 #endif
0082 #endif
0083 #endif
0084 #endif
0085 #endif
0086 #endif
0087 #endif
0088 #endif
0089 #endif
0090 #endif
0091 #endif
0092 #endif
0093 #endif
0094
0095
0096 static lpuart_edma_private_handle_t s_lpuartEdmaPrivateHandle[LPUART_HANDLE_ARRAY_SIZE];
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111 static void LPUART_SendEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds);
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122 static void LPUART_ReceiveEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds);
0123
0124
0125
0126
0127
0128 static void LPUART_SendEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds)
0129 {
0130 assert(NULL != param);
0131
0132 lpuart_edma_private_handle_t *lpuartPrivateHandle = (lpuart_edma_private_handle_t *)param;
0133
0134
0135 handle = handle;
0136 tcds = tcds;
0137
0138 if (transferDone)
0139 {
0140
0141 LPUART_EnableTxDMA(lpuartPrivateHandle->base, false);
0142
0143
0144 EDMA_AbortTransfer(handle);
0145
0146
0147 LPUART_EnableInterrupts(lpuartPrivateHandle->base, (uint32_t)kLPUART_TransmissionCompleteInterruptEnable);
0148 }
0149 }
0150
0151 static void LPUART_ReceiveEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds)
0152 {
0153 assert(NULL != param);
0154
0155 lpuart_edma_private_handle_t *lpuartPrivateHandle = (lpuart_edma_private_handle_t *)param;
0156
0157
0158 handle = handle;
0159 tcds = tcds;
0160
0161 if (transferDone)
0162 {
0163
0164 LPUART_TransferAbortReceiveEDMA(lpuartPrivateHandle->base, lpuartPrivateHandle->handle);
0165
0166 if (NULL != lpuartPrivateHandle->handle->callback)
0167 {
0168 lpuartPrivateHandle->handle->callback(lpuartPrivateHandle->base, lpuartPrivateHandle->handle,
0169 kStatus_LPUART_RxIdle, lpuartPrivateHandle->handle->userData);
0170 }
0171 }
0172 }
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186 void LPUART_TransferCreateHandleEDMA(LPUART_Type *base,
0187 lpuart_edma_handle_t *handle,
0188 lpuart_edma_transfer_callback_t callback,
0189 void *userData,
0190 edma_handle_t *txEdmaHandle,
0191 edma_handle_t *rxEdmaHandle)
0192 {
0193 assert(NULL != handle);
0194
0195 uint32_t instance = LPUART_GetInstance(base);
0196
0197 s_lpuartEdmaPrivateHandle[instance].base = base;
0198 s_lpuartEdmaPrivateHandle[instance].handle = handle;
0199
0200 (void)memset(handle, 0, sizeof(*handle));
0201
0202 handle->rxState = (uint8_t)kLPUART_RxIdle;
0203 handle->txState = (uint8_t)kLPUART_TxIdle;
0204
0205 handle->rxEdmaHandle = rxEdmaHandle;
0206 handle->txEdmaHandle = txEdmaHandle;
0207
0208 handle->callback = callback;
0209 handle->userData = userData;
0210
0211 #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO
0212
0213
0214
0215
0216
0217
0218
0219
0220 if (NULL != rxEdmaHandle)
0221 {
0222 base->WATER &= (~LPUART_WATER_RXWATER_MASK);
0223 }
0224 #endif
0225
0226
0227 s_lpuartHandle[instance] = handle;
0228
0229 s_lpuartIsr[instance] = LPUART_TransferEdmaHandleIRQ;
0230
0231 LPUART_DisableInterrupts(base, (uint32_t)kLPUART_AllInterruptEnable);
0232
0233 #if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ
0234 (void)EnableIRQ(s_lpuartTxIRQ[instance]);
0235 #else
0236 (void)EnableIRQ(s_lpuartIRQ[instance]);
0237 #endif
0238
0239
0240 if (NULL != txEdmaHandle)
0241 {
0242 EDMA_SetCallback(handle->txEdmaHandle, LPUART_SendEDMACallback, &s_lpuartEdmaPrivateHandle[instance]);
0243 }
0244
0245
0246 if (NULL != rxEdmaHandle)
0247 {
0248 EDMA_SetCallback(handle->rxEdmaHandle, LPUART_ReceiveEDMACallback, &s_lpuartEdmaPrivateHandle[instance]);
0249 }
0250 }
0251
0252
0253
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265 status_t LPUART_SendEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, lpuart_transfer_t *xfer)
0266 {
0267 assert(NULL != handle);
0268 assert(NULL != handle->txEdmaHandle);
0269 assert(NULL != xfer);
0270 assert(NULL != xfer->data);
0271 assert(0U != xfer->dataSize);
0272
0273 edma_transfer_config_t xferConfig;
0274 status_t status;
0275
0276
0277 if ((uint8_t)kLPUART_TxBusy == handle->txState)
0278 {
0279 status = kStatus_LPUART_TxBusy;
0280 }
0281 else
0282 {
0283 handle->txState = (uint8_t)kLPUART_TxBusy;
0284 handle->txDataSizeAll = xfer->dataSize;
0285
0286
0287 EDMA_PrepareTransfer(&xferConfig, xfer->data, sizeof(uint8_t),
0288 (void *)(uint32_t *)LPUART_GetDataRegisterAddress(base), sizeof(uint8_t), sizeof(uint8_t),
0289 xfer->dataSize, kEDMA_MemoryToPeripheral);
0290
0291
0292 handle->nbytes = (uint8_t)sizeof(uint8_t);
0293
0294
0295 if (kStatus_Success !=
0296 EDMA_SubmitTransfer(handle->txEdmaHandle, (const edma_transfer_config_t *)(uint32_t)&xferConfig))
0297 {
0298 return kStatus_Fail;
0299 }
0300 EDMA_StartTransfer(handle->txEdmaHandle);
0301
0302
0303 LPUART_EnableTxDMA(base, true);
0304
0305 status = kStatus_Success;
0306 }
0307
0308 return status;
0309 }
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324 status_t LPUART_ReceiveEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, lpuart_transfer_t *xfer)
0325 {
0326 assert(NULL != handle);
0327 assert(NULL != handle->rxEdmaHandle);
0328 assert(NULL != xfer);
0329 assert(NULL != xfer->data);
0330 assert(0U != xfer->dataSize);
0331
0332 edma_transfer_config_t xferConfig;
0333 status_t status;
0334
0335
0336 if ((uint8_t)kLPUART_RxBusy == handle->rxState)
0337 {
0338 status = kStatus_LPUART_RxBusy;
0339 }
0340 else
0341 {
0342 handle->rxState = (uint8_t)kLPUART_RxBusy;
0343 handle->rxDataSizeAll = xfer->dataSize;
0344
0345
0346 EDMA_PrepareTransfer(&xferConfig, (void *)(uint32_t *)LPUART_GetDataRegisterAddress(base), sizeof(uint8_t),
0347 xfer->data, sizeof(uint8_t), sizeof(uint8_t), xfer->dataSize, kEDMA_PeripheralToMemory);
0348
0349
0350 handle->nbytes = (uint8_t)sizeof(uint8_t);
0351
0352
0353 if (kStatus_Success !=
0354 EDMA_SubmitTransfer(handle->rxEdmaHandle, (const edma_transfer_config_t *)(uint32_t)&xferConfig))
0355 {
0356 return kStatus_Fail;
0357 }
0358 EDMA_StartTransfer(handle->rxEdmaHandle);
0359
0360
0361 LPUART_EnableRxDMA(base, true);
0362
0363 status = kStatus_Success;
0364 }
0365
0366 return status;
0367 }
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377 void LPUART_TransferAbortSendEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle)
0378 {
0379 assert(NULL != handle);
0380 assert(NULL != handle->txEdmaHandle);
0381
0382
0383 LPUART_EnableTxDMA(base, false);
0384
0385
0386 EDMA_AbortTransfer(handle->txEdmaHandle);
0387
0388 handle->txState = (uint8_t)kLPUART_TxIdle;
0389 }
0390
0391
0392
0393
0394
0395
0396
0397
0398
0399 void LPUART_TransferAbortReceiveEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle)
0400 {
0401 assert(NULL != handle);
0402 assert(NULL != handle->rxEdmaHandle);
0403
0404
0405 LPUART_EnableRxDMA(base, false);
0406
0407
0408 EDMA_AbortTransfer(handle->rxEdmaHandle);
0409
0410 handle->rxState = (uint8_t)kLPUART_RxIdle;
0411 }
0412
0413
0414
0415
0416
0417
0418
0419
0420
0421
0422
0423
0424
0425 status_t LPUART_TransferGetReceiveCountEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, uint32_t *count)
0426 {
0427 assert(NULL != handle);
0428 assert(NULL != handle->rxEdmaHandle);
0429 assert(NULL != count);
0430
0431 if ((uint8_t)kLPUART_RxIdle == handle->rxState)
0432 {
0433 return kStatus_NoTransferInProgress;
0434 }
0435
0436 *count = handle->rxDataSizeAll -
0437 ((uint32_t)handle->nbytes *
0438 EDMA_GetRemainingMajorLoopCount(handle->rxEdmaHandle->base, handle->rxEdmaHandle->channel));
0439
0440 return kStatus_Success;
0441 }
0442
0443
0444
0445
0446
0447
0448
0449
0450
0451
0452
0453
0454
0455
0456 status_t LPUART_TransferGetSendCountEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, uint32_t *count)
0457 {
0458 assert(NULL != handle);
0459 assert(NULL != handle->txEdmaHandle);
0460 assert(NULL != count);
0461
0462 if ((uint8_t)kLPUART_TxIdle == handle->txState)
0463 {
0464 return kStatus_NoTransferInProgress;
0465 }
0466
0467 *count = handle->txDataSizeAll -
0468 ((uint32_t)handle->nbytes *
0469 EDMA_GetRemainingMajorLoopCount(handle->txEdmaHandle->base, handle->txEdmaHandle->channel));
0470
0471 return kStatus_Success;
0472 }
0473
0474
0475
0476
0477
0478
0479
0480
0481
0482
0483
0484
0485 void LPUART_TransferEdmaHandleIRQ(LPUART_Type *base, void *lpuartEdmaHandle)
0486 {
0487 assert(lpuartEdmaHandle != NULL);
0488
0489 if (((uint32_t)kLPUART_TransmissionCompleteFlag & LPUART_GetStatusFlags(base)) != 0U)
0490 {
0491 lpuart_edma_handle_t *handle = (lpuart_edma_handle_t *)lpuartEdmaHandle;
0492
0493
0494 LPUART_DisableInterrupts(base, (uint32_t)kLPUART_TransmissionCompleteInterruptEnable);
0495
0496 handle->txState = (uint8_t)kLPUART_TxIdle;
0497
0498 if (handle->callback != NULL)
0499 {
0500 handle->callback(base, handle, kStatus_LPUART_TxIdle, handle->userData);
0501 }
0502 }
0503 }