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