00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 #include "chip.h"
00055 #include "string.h"
00056 #include "stdlib.h"
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 static void USARTD_Rx_Cb(uint32_t channel, UsartDma *pArg)
00069 {
00070
00071 UsartChannel *pUsartdCh = pArg->pRxChannel;
00072
00073 if (channel != pUsartdCh->ChNum)
00074 return;
00075
00076
00077 XDMAD_FreeChannel(pArg->pXdmad, pUsartdCh->ChNum);
00078 pUsartdCh->dmaProgress = 1;
00079 SCB_InvalidateDCache_by_Addr((uint32_t *)pUsartdCh->pBuff, pUsartdCh->BuffSize);
00080
00081 }
00082
00083
00084
00085
00086
00087
00088
00089 static void USARTD_Tx_Cb(uint32_t channel, UsartDma *pArg)
00090 {
00091 UsartChannel *pUsartdCh = pArg->pTxChannel;
00092
00093 if (channel != pUsartdCh->ChNum)
00094 return;
00095
00096
00097 XDMAD_FreeChannel(pArg->pXdmad, pUsartdCh->ChNum);
00098
00099 pUsartdCh->dmaProgress = 1;
00100 }
00101
00102
00103
00104
00105
00106
00107
00108
00109 static uint8_t _configureRxDma(UsartDma *pUsart, UsartChannel *pUsartRx)
00110 {
00111 sXdmadCfg xdmadRxCfg;
00112 uint32_t xdmaCndc, xdmaInt;
00113 uint32_t i, LLI_Size;
00114 Usart *pUsartHwRx = pUsart->pUsartHw;
00115 sXdmad *pXdmadRx = pUsart->pXdmad;
00116 uint8_t *pBuff = 0;
00117
00118
00119
00120 if (pUsartRx->dmaProgrammingMode < XDMAD_LLI) {
00121 xdmadRxCfg.mbr_ubc = pUsartRx->BuffSize;
00122 xdmadRxCfg.mbr_da = (uint32_t)pUsartRx->pBuff;
00123
00124 xdmadRxCfg.mbr_sa = (uint32_t)&pUsartHwRx->US_RHR;
00125 xdmadRxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN |
00126 XDMAC_CC_MBSIZE_SIXTEEN |
00127 XDMAC_CC_DSYNC_PER2MEM |
00128 XDMAC_CC_CSIZE_CHK_1 |
00129 XDMAC_CC_DWIDTH_BYTE |
00130 XDMAC_CC_SIF_AHB_IF1 |
00131 XDMAC_CC_DIF_AHB_IF1 |
00132 XDMAC_CC_SAM_FIXED_AM |
00133 XDMAC_CC_DAM_INCREMENTED_AM |
00134 XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber
00135 (pUsart->usartId, XDMAD_TRANSFER_RX));
00136
00137 xdmadRxCfg.mbr_bc = 0;
00138
00139 if (pUsartRx->dmaProgrammingMode == XDMAD_MULTI)
00140 xdmadRxCfg.mbr_bc = pUsartRx->dmaBlockSize;
00141
00142 xdmadRxCfg.mbr_sus = 0;
00143 xdmadRxCfg.mbr_dus = 0;
00144 xdmaCndc = 0;
00145 xdmaInt = (XDMAC_CIE_BIE |
00146 XDMAC_CIE_DIE |
00147 XDMAC_CIE_FIE |
00148 XDMAC_CIE_RBIE |
00149 XDMAC_CIE_WBIE |
00150 XDMAC_CIE_ROIE);
00151 } else if (pUsartRx->dmaProgrammingMode == XDMAD_LLI) {
00152
00153
00154 LLI_Size = pUsartRx->dmaBlockSize;
00155 pBuff = pUsartRx->pBuff;
00156
00157 if (pUsartRx->pLLIview != NULL) {
00158 free(pUsartRx->pLLIview);
00159 pUsartRx->pLLIview = NULL;
00160 }
00161
00162 pUsartRx->pLLIview = malloc(sizeof(LinkedListDescriporView1) * LLI_Size);
00163
00164 if (pUsartRx->pLLIview == NULL) {
00165 TRACE_ERROR(" Can not allocate memory to Rx LLI");
00166 return USARTD_ERROR;
00167 }
00168
00169 xdmadRxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN |
00170 XDMAC_CC_MBSIZE_SIXTEEN |
00171 XDMAC_CC_DSYNC_PER2MEM |
00172 XDMAC_CC_MEMSET_NORMAL_MODE |
00173 XDMAC_CC_CSIZE_CHK_1 |
00174 XDMAC_CC_DWIDTH_BYTE |
00175 XDMAC_CC_SIF_AHB_IF1 |
00176 XDMAC_CC_DIF_AHB_IF1 |
00177 XDMAC_CC_SAM_FIXED_AM |
00178 XDMAC_CC_DAM_INCREMENTED_AM |
00179 XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber
00180 (pUsart->usartId, XDMAD_TRANSFER_RX));
00181 xdmadRxCfg.mbr_bc = 0;
00182
00183 for (i = 0; i < LLI_Size; i++) {
00184 pUsartRx->pLLIview[i].mbr_ubc = XDMA_UBC_NVIEW_NDV1 |
00185 XDMA_UBC_NSEN_UNCHANGED |
00186 XDMA_UBC_NDEN_UPDATED |
00187 ((i == LLI_Size - 1) ? (
00188 (pUsartRx->dmaRingBuffer) ?
00189 XDMA_UBC_NDE_FETCH_EN : 0) :
00190 XDMA_UBC_NDE_FETCH_EN) |
00191 pUsartRx->BuffSize;
00192 pUsartRx->pLLIview[i].mbr_sa = (uint32_t)&pUsartHwRx->US_RHR;
00193 pUsartRx->pLLIview[i].mbr_da = (uint32_t)pBuff;
00194 pUsartRx->pLLIview[i].mbr_nda = (i == (LLI_Size - 1)) ?
00195 ((pUsartRx->dmaRingBuffer) ? (uint32_t)pUsartRx->pLLIview : 0)
00196 : (uint32_t)&pUsartRx->pLLIview[ i + 1 ];
00197 pBuff += pUsartRx->BuffSize;
00198 }
00199
00200 SCB_CleanDCache_by_Addr((uint32_t *)(pUsartRx->pLLIview),
00201 sizeof(LinkedListDescriporView1)*LLI_Size);
00202 xdmaCndc = XDMAC_CNDC_NDVIEW_NDV1 |
00203 XDMAC_CNDC_NDE_DSCR_FETCH_EN |
00204 XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED |
00205 XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED;
00206 xdmaInt = ((pUsartRx->dmaRingBuffer) ? XDMAC_CIE_BIE : XDMAC_CIE_LIE);
00207 } else
00208 return 1;
00209
00210 if (XDMAD_ConfigureTransfer(
00211 pXdmadRx, pUsartRx->ChNum, &xdmadRxCfg, xdmaCndc,
00212 (uint32_t)pUsartRx->pLLIview, xdmaInt))
00213 return USARTD_ERROR;
00214
00215 return 0;
00216 }
00217
00218
00219
00220
00221
00222
00223
00224
00225 static uint8_t _configureTxDma(UsartDma *pUsart, UsartChannel *pUsartTx)
00226 {
00227 sXdmadCfg xdmadTxCfg;
00228 uint32_t xdmaCndc, xdmaInt, LLI_Size, i;
00229 uint8_t *pBuff = 0;
00230 Usart *pUsartHwTx = pUsart->pUsartHw;
00231 sXdmad *pXdmadTx = pUsart->pXdmad;
00232
00233
00234
00235 if (pUsartTx->dmaProgrammingMode < XDMAD_LLI) {
00236
00237 xdmadTxCfg.mbr_ubc = pUsartTx->BuffSize;
00238
00239 xdmadTxCfg.mbr_sa = (uint32_t)pUsartTx->pBuff;
00240 xdmadTxCfg.mbr_da = (uint32_t)&pUsartHwTx->US_THR;
00241
00242 xdmadTxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN |
00243 XDMAC_CC_MBSIZE_SIXTEEN |
00244 XDMAC_CC_DSYNC_MEM2PER |
00245 XDMAC_CC_CSIZE_CHK_1 |
00246 XDMAC_CC_DWIDTH_BYTE |
00247 XDMAC_CC_SIF_AHB_IF1 |
00248 XDMAC_CC_DIF_AHB_IF1 |
00249 XDMAC_CC_SAM_INCREMENTED_AM |
00250 XDMAC_CC_DAM_FIXED_AM |
00251 XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber
00252 (pUsart->usartId, XDMAD_TRANSFER_TX));
00253
00254 xdmadTxCfg.mbr_bc = 0;
00255
00256 if (pUsartTx->dmaProgrammingMode == XDMAD_MULTI)
00257 xdmadTxCfg.mbr_bc = pUsartTx->dmaBlockSize;
00258
00259 xdmadTxCfg.mbr_sus = 0;
00260 xdmadTxCfg.mbr_dus = 0;
00261 xdmadTxCfg.mbr_ds = 0;
00262 xdmaCndc = 0;
00263
00264
00265 xdmaInt = (XDMAC_CIE_BIE |
00266 XDMAC_CIE_RBIE |
00267 XDMAC_CIE_WBIE |
00268 XDMAC_CIE_ROIE);
00269 } else if (pUsartTx->dmaProgrammingMode == XDMAD_LLI) {
00270 LLI_Size = pUsartTx->dmaBlockSize;
00271 pBuff = pUsartTx->pBuff;
00272
00273
00274
00275 if (pUsartTx->pLLIview != NULL) {
00276 free(pUsartTx->pLLIview);
00277 pUsartTx->pLLIview = NULL;
00278 }
00279
00280 pUsartTx->pLLIview = malloc(sizeof(LinkedListDescriporView1) * LLI_Size);
00281
00282 if (pUsartTx->pLLIview == NULL) {
00283 TRACE_ERROR(" Can not allocate memory to Tx LLI");
00284 return USARTD_ERROR;
00285 }
00286
00287 xdmadTxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN |
00288 XDMAC_CC_MBSIZE_SIXTEEN |
00289 XDMAC_CC_DSYNC_MEM2PER |
00290 XDMAC_CC_MEMSET_NORMAL_MODE |
00291 XDMAC_CC_CSIZE_CHK_1 |
00292 XDMAC_CC_DWIDTH_BYTE |
00293 XDMAC_CC_SIF_AHB_IF1 |
00294 XDMAC_CC_DIF_AHB_IF1 |
00295 XDMAC_CC_SAM_INCREMENTED_AM |
00296 XDMAC_CC_DAM_FIXED_AM |
00297 XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber
00298 (pUsart->usartId, XDMAD_TRANSFER_TX));
00299 xdmadTxCfg.mbr_bc = 0;
00300
00301 for (i = 0; i < LLI_Size; i++) {
00302 pUsartTx->pLLIview[i].mbr_ubc = XDMA_UBC_NVIEW_NDV1 |
00303 XDMA_UBC_NSEN_UPDATED |
00304 XDMA_UBC_NDEN_UNCHANGED |
00305 ((i == LLI_Size - 1) ? ((pUsartTx->dmaRingBuffer)
00306 ? XDMA_UBC_NDE_FETCH_EN : 0) :
00307 XDMA_UBC_NDE_FETCH_EN) | pUsartTx->BuffSize;
00308 pUsartTx->pLLIview[i].mbr_sa = (uint32_t)pBuff;
00309 pUsartTx->pLLIview[i].mbr_da = (uint32_t)&pUsartHwTx->US_THR;
00310 pUsartTx->pLLIview[i].mbr_nda = (i == (LLI_Size - 1)) ?
00311 ((pUsartTx->dmaRingBuffer) ? (uint32_t)pUsartTx->pLLIview : 0)
00312 : (uint32_t)&pUsartTx->pLLIview[ i + 1 ];
00313 pBuff += pUsartTx->BuffSize;
00314 }
00315
00316 SCB_CleanDCache_by_Addr((uint32_t *)(pUsartTx->pLLIview),
00317 sizeof(LinkedListDescriporView1)*LLI_Size);
00318 xdmaCndc = XDMAC_CNDC_NDVIEW_NDV1 |
00319 XDMAC_CNDC_NDE_DSCR_FETCH_EN |
00320 XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED |
00321 XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED;
00322 xdmaInt = ((pUsartTx->dmaRingBuffer) ? XDMAC_CIE_BIE : XDMAC_CIE_LIE);
00323 } else {
00324 TRACE_ERROR("DmaProgState is incorrect \n\r");
00325 return 1;
00326 }
00327
00328 if (XDMAD_ConfigureTransfer(pXdmadTx, pUsartTx->ChNum,
00329 &xdmadTxCfg, xdmaCndc, (uint32_t)pUsartTx->pLLIview, xdmaInt))
00330 return USARTD_ERROR;
00331
00332 return 0;
00333 }
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350 uint32_t USARTD_Configure(UsartDma *pUsartd ,
00351 uint8_t usartId,
00352 uint32_t UsartMode,
00353 uint32_t BaudRate,
00354 uint32_t UsartClk)
00355 {
00356
00357 PMC_EnablePeripheral(usartId);
00358
00359
00360 pUsartd->usartId = usartId;
00361
00362 if (usartId == ID_USART0)
00363 pUsartd->pUsartHw = USART0;
00364
00365 if (usartId == ID_USART1)
00366 pUsartd->pUsartHw = USART1;
00367
00368 if (usartId == ID_USART2)
00369 pUsartd->pUsartHw = USART2;
00370
00371
00372 pUsartd->pXdmad->pXdmacs = XDMAC;
00373
00374
00375 USART_Configure (pUsartd->pUsartHw, UsartMode, BaudRate, UsartClk);
00376
00377
00378 XDMAD_Initialize(pUsartd->pXdmad, 0);
00379
00380
00381 if (!(NVIC_GetActive(XDMAC_IRQn)))
00382 NVIC_ClearPendingIRQ(XDMAC_IRQn);
00383
00384 return 0;
00385 }
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396 uint32_t USARTD_EnableRxChannels(UsartDma *pUsartd, UsartChannel *pRxCh)
00397 {
00398 uint32_t Channel;
00399
00400 assert(pRxCh);
00401
00402 pUsartd->pRxChannel = pRxCh;
00403
00404
00405 USART_SetReceiverEnabled (pUsartd->pUsartHw , ENABLE);
00406
00407
00408
00409 Channel = XDMAD_AllocateChannel(pUsartd->pXdmad, pUsartd->usartId,
00410 XDMAD_TRANSFER_MEMORY);
00411
00412 if (Channel == XDMAD_ALLOC_FAILED)
00413 return USARTD_ERROR;
00414
00415 pRxCh->ChNum = Channel;
00416
00417
00418 if (pUsartd->pRxChannel->callback) {
00419 XDMAD_SetCallback(pUsartd->pXdmad, pRxCh->ChNum,
00420 (XdmadTransferCallback)pRxCh->callback, pRxCh->pArgument);
00421 } else {
00422 XDMAD_SetCallback(pUsartd->pXdmad, pRxCh->ChNum,
00423 (XdmadTransferCallback)USARTD_Rx_Cb, pUsartd);
00424 }
00425
00426
00427 if (XDMAD_PrepareChannel(pUsartd->pXdmad, pRxCh->ChNum))
00428 return USARTD_ERROR;
00429
00430 if (_configureRxDma(pUsartd , pUsartd->pRxChannel))
00431 return USARTD_ERROR_LOCK;
00432
00433
00434 if (!(NVIC_GetActive(XDMAC_IRQn))) {
00435
00436 NVIC_EnableIRQ(XDMAC_IRQn);
00437 }
00438
00439 return 0;
00440 }
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451 uint32_t USARTD_EnableTxChannels(UsartDma *pUsartd, UsartChannel *pTxCh)
00452 {
00453
00454 uint32_t Channel;
00455
00456 assert(pTxCh);
00457
00458
00459 pUsartd->pTxChannel = pTxCh;
00460
00461
00462 USART_SetTransmitterEnabled (pUsartd->pUsartHw , ENABLE);
00463
00464
00465 Channel = XDMAD_AllocateChannel(pUsartd->pXdmad, XDMAD_TRANSFER_MEMORY,
00466 pUsartd->usartId);
00467
00468 if (Channel == XDMAD_ALLOC_FAILED)
00469 return USARTD_ERROR;
00470
00471 pTxCh->ChNum = Channel;
00472
00473
00474 if (pUsartd->pTxChannel->callback) {
00475 XDMAD_SetCallback(pUsartd->pXdmad, pTxCh->ChNum,
00476 (XdmadTransferCallback)pTxCh->callback, pTxCh->pArgument);
00477 } else
00478 XDMAD_SetCallback(pUsartd->pXdmad, pTxCh->ChNum,
00479 (XdmadTransferCallback)USARTD_Tx_Cb, pUsartd);
00480
00481 if (XDMAD_PrepareChannel(pUsartd->pXdmad, pTxCh->ChNum))
00482 return USARTD_ERROR;
00483
00484 if (_configureTxDma(pUsartd , pUsartd->pTxChannel))
00485 return USARTD_ERROR_LOCK;
00486
00487
00488 if (!(NVIC_GetActive(XDMAC_IRQn))) {
00489
00490 NVIC_EnableIRQ(XDMAC_IRQn);
00491 }
00492
00493 return 0;
00494 }
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505 uint32_t USARTD_DisableRxChannels(UsartDma *pUsartd, UsartChannel *pRxCh)
00506 {
00507 assert(pRxCh);
00508
00509
00510 USART_SetReceiverEnabled (pUsartd->pUsartHw , DISABLE);
00511
00512 XDMAD_StopTransfer(pUsartd->pXdmad, pRxCh->ChNum);
00513
00514 XDMAD_SetCallback(pUsartd->pXdmad, pRxCh->ChNum, NULL, NULL);
00515
00516
00517 if (XDMAD_FreeChannel(pUsartd->pXdmad, pRxCh->ChNum) != XDMAD_OK)
00518 return USARTD_ERROR;
00519
00520 if (pRxCh->dmaProgrammingMode == XDMAD_LLI) {
00521 free(pRxCh->pLLIview);
00522 pRxCh->pLLIview = NULL;
00523 }
00524
00525 pRxCh->dmaProgress = 1;
00526 return 0;
00527 }
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539 uint32_t USARTD_DisableTxChannels(UsartDma *pUsartd, UsartChannel *pTxCh)
00540 {
00541 assert(pTxCh);
00542
00543
00544 USART_SetTransmitterEnabled (pUsartd->pUsartHw , DISABLE);
00545
00546 XDMAD_StopTransfer(pUsartd->pXdmad, pTxCh->ChNum);
00547
00548 XDMAD_SetCallback(pUsartd->pXdmad, pTxCh->ChNum, NULL, NULL);
00549
00550
00551 if (XDMAD_FreeChannel(pUsartd->pXdmad, pTxCh->ChNum) != XDMAD_OK)
00552 return USARTD_ERROR;
00553
00554 if (pTxCh->dmaProgrammingMode == XDMAD_LLI) {
00555 free(pTxCh->pLLIview);
00556 pTxCh->pLLIview = NULL;
00557 }
00558
00559 pTxCh->dmaProgress = 1;
00560 return 0;
00561 }
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572 uint32_t USARTD_SendData(UsartDma *pUsartd)
00573 {
00574
00575 pUsartd->pTxChannel->dmaProgress = 0;
00576 SCB_CleanDCache_by_Addr((uint32_t *)pUsartd->pTxChannel->pBuff,
00577 pUsartd->pTxChannel->BuffSize);
00578
00579 if (XDMAD_StartTransfer(pUsartd->pXdmad, pUsartd->pTxChannel->ChNum))
00580 return USARTD_ERROR_LOCK;
00581
00582 return 0;
00583 }
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594 uint32_t USARTD_RcvData(UsartDma *pUsartd)
00595 {
00596
00597 pUsartd->pRxChannel->dmaProgress = 0;
00598
00599 if (XDMAD_StartTransfer(pUsartd->pXdmad, pUsartd->pRxChannel->ChNum))
00600 return USARTD_ERROR_LOCK;
00601
00602 return 0;
00603 }
00604