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