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
00060
00061
00062
00063
00064 #include "chip.h"
00065 #include <assert.h>
00066 static uint8_t xDmad_Initialized = 0;
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079 static uint32_t XDMAD_AllocateXdmacChannel( sXdmad *pXdmad,
00080 uint8_t bSrcID,
00081 uint8_t bDstID)
00082 {
00083 uint32_t i;
00084
00085 if ((( bSrcID != XDMAD_TRANSFER_MEMORY )
00086 && ( bDstID != XDMAD_TRANSFER_MEMORY ))) {
00087 return XDMAD_ALLOC_FAILED;
00088 }
00089
00090 if ( bDstID == XDMAD_TRANSFER_MEMORY) {
00091 if( (!XDMAIF_IsValidatedPeripherOnDma(bSrcID)) ) {
00092 TRACE_ERROR("%s:: Allocation failed", __FUNCTION__);
00093 return XDMAD_ALLOC_FAILED;
00094 }
00095 }
00096
00097 if ( bSrcID == XDMAD_TRANSFER_MEMORY ) {
00098 if( (!XDMAIF_IsValidatedPeripherOnDma(bDstID)) ) {
00099 TRACE_ERROR("%s:: Allocation failed", __FUNCTION__);
00100 return XDMAD_ALLOC_FAILED;
00101 }
00102 }
00103
00104 for (i = 0; i < pXdmad->numChannels; i ++) {
00105 if ( pXdmad->XdmaChannels[i].state == XDMAD_STATE_FREE ) {
00106
00107 pXdmad->XdmaChannels[i].state = XDMAD_STATE_ALLOCATED;
00108
00109 pXdmad->XdmaChannels[i].bSrcPeriphID = bSrcID;
00110 pXdmad->XdmaChannels[i].bDstPeriphID = bDstID;
00111 pXdmad->XdmaChannels[i].bSrcTxIfID =
00112 XDMAIF_Get_ChannelNumber(bSrcID, 0);
00113 pXdmad->XdmaChannels[i].bSrcRxIfID =
00114 XDMAIF_Get_ChannelNumber(bSrcID, 1);
00115 pXdmad->XdmaChannels[i].bDstTxIfID =
00116 XDMAIF_Get_ChannelNumber(bDstID, 0);
00117 pXdmad->XdmaChannels[i].bDstRxIfID =
00118 XDMAIF_Get_ChannelNumber(bDstID, 1);
00119 return ((i) & 0xFF);
00120 }
00121 }
00122 TRACE_ERROR("%s:: Allocation failed, all channels are occupied", __FUNCTION__);
00123 return XDMAD_ALLOC_FAILED;
00124 }
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137 void XDMAD_Initialize( sXdmad *pXdmad, uint8_t bPollingMode )
00138 {
00139 uint32_t j;
00140 uint32_t volatile timer=0x7FF;
00141
00142 assert( pXdmad) ;
00143 LockMutex(pXdmad->xdmaMutex, timer);
00144 if (xDmad_Initialized) {
00145 ReleaseMutex(pXdmad->xdmaMutex);
00146 return;
00147 }
00148 pXdmad->pXdmacs = XDMAC;
00149 pXdmad->pollingMode = bPollingMode;
00150 pXdmad->numControllers = XDMAC_CONTROLLER_NUM;
00151 pXdmad->numChannels = (XDMAC_GTYPE_NB_CH( XDMAC_GetType(XDMAC) ) + 1);
00152
00153 for (j = 0; j < pXdmad->numChannels; j ++) {
00154 pXdmad->XdmaChannels[j].fCallback = 0;
00155 pXdmad->XdmaChannels[j].pArg = 0;
00156 pXdmad->XdmaChannels[j].bIrqOwner = 0;
00157 pXdmad->XdmaChannels[j].bSrcPeriphID = 0;
00158 pXdmad->XdmaChannels[j].bDstPeriphID = 0;
00159 pXdmad->XdmaChannels[j].bSrcTxIfID = 0;
00160 pXdmad->XdmaChannels[j].bSrcRxIfID = 0;
00161 pXdmad->XdmaChannels[j].bDstTxIfID = 0;
00162 pXdmad->XdmaChannels[j].bDstRxIfID = 0;
00163 pXdmad->XdmaChannels[j].state = XDMAD_STATE_FREE;
00164 }
00165 xDmad_Initialized = 1;
00166 ReleaseMutex(pXdmad->xdmaMutex);
00167 }
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178 uint32_t XDMAD_AllocateChannel( sXdmad *pXdmad,
00179 uint8_t bSrcID,
00180 uint8_t bDstID)
00181 {
00182 uint32_t dwChannel = XDMAD_ALLOC_FAILED;
00183 uint32_t volatile timer=0x7FF;
00184
00185 LockMutex(pXdmad->xdmaMutex, timer);
00186 dwChannel = XDMAD_AllocateXdmacChannel( pXdmad, bSrcID, bDstID );
00187 ReleaseMutex(pXdmad->xdmaMutex);
00188
00189 return dwChannel;
00190 }
00191
00192
00193
00194
00195
00196
00197 eXdmadRC XDMAD_FreeChannel( sXdmad *pXdmad,
00198 uint32_t dwChannel )
00199 {
00200 uint8_t iChannel = (dwChannel) & 0xFF;
00201 assert( pXdmad != NULL ) ;
00202 if (iChannel >= pXdmad->numChannels) return XDMAD_ERROR;
00203 switch ( pXdmad->XdmaChannels[iChannel].state ) {
00204 case XDMAD_STATE_ALLOCATED:
00205 case XDMAD_STATE_START:
00206 case XDMAD_STATE_IN_XFR:
00207 return XDMAD_BUSY;
00208 case XDMAD_STATE_DONE:
00209 case XDMAD_STATE_HALTED:
00210 pXdmad->XdmaChannels[iChannel].state = XDMAD_STATE_FREE;
00211 break;
00212 }
00213 return XDMAD_OK;
00214 }
00215
00216
00217
00218
00219
00220
00221
00222
00223 eXdmadRC XDMAD_SetCallback( sXdmad *pXdmad,
00224 uint32_t dwChannel,
00225 XdmadTransferCallback fCallback,
00226 void* pArg )
00227 {
00228
00229 uint8_t iChannel = (dwChannel) & 0xFF;
00230 assert( pXdmad != NULL ) ;
00231 if (iChannel >= pXdmad->numChannels) return XDMAD_ERROR;
00232 if ( pXdmad->XdmaChannels[iChannel].state == XDMAD_STATE_FREE )
00233 return XDMAD_ERROR;
00234 else if ( pXdmad->XdmaChannels[iChannel].state == XDMAD_STATE_START )
00235 return XDMAD_BUSY;
00236
00237 pXdmad->XdmaChannels[iChannel].fCallback = fCallback;
00238 pXdmad->XdmaChannels[iChannel].pArg = pArg;
00239
00240 return XDMAD_OK;
00241 }
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251 eXdmadRC XDMAD_PrepareChannel( sXdmad *pXdmad, uint32_t dwChannel)
00252 {
00253
00254 uint8_t iChannel = (dwChannel) & 0xFF;
00255 Xdmac *pXdmac = pXdmad->pXdmacs;
00256
00257 assert( pXdmad != NULL ) ;
00258 if (iChannel >= pXdmad->numChannels) return XDMAD_ERROR;
00259
00260 if ( pXdmad->XdmaChannels[iChannel].state == XDMAD_STATE_FREE )
00261 return XDMAD_ERROR;
00262 else if ( ( pXdmad->XdmaChannels[iChannel].state == XDMAD_STATE_START )
00263 || ( pXdmad->XdmaChannels[iChannel].state == XDMAD_STATE_IN_XFR ) )
00264 return XDMAD_BUSY;
00265
00266
00267
00268 if (!PMC_IsPeriphEnabled( ID_XDMAC )) {
00269 PMC_EnablePeripheral( ID_XDMAC );
00270 }
00271
00272 XDMAC_GetChannelIsr( pXdmac,iChannel );
00273
00274 XDMAC_DisableGIt (pXdmac, iChannel);
00275 XDMAC_DisableChannelIt (pXdmac, iChannel, 0xFF);
00276
00277 XDMAC_DisableChannel( pXdmac, iChannel );
00278 XDMAC_SetSourceAddr(pXdmac, iChannel, 0);
00279 XDMAC_SetDestinationAddr(pXdmac, iChannel, 0);
00280 XDMAC_SetBlockControl(pXdmac, iChannel, 0);
00281 XDMAC_SetChannelConfig( pXdmac, iChannel, 0x20);
00282 XDMAC_SetDescriptorAddr(pXdmac, iChannel, 0, 0);
00283 XDMAC_SetDescriptorControl(pXdmac, iChannel, 0);
00284 return XDMAD_OK;
00285 }
00286
00287
00288
00289
00290
00291 void XDMAD_Handler( sXdmad *pDmad)
00292 {
00293 Xdmac *pXdmac;
00294 sXdmadChannel *pCh;
00295 uint32_t xdmaChannelIntStatus, xdmaGlobaIntStatus,xdmaGlobalChStatus;
00296 uint8_t bExec = 0;
00297 uint8_t _iChannel;
00298 assert( pDmad != NULL ) ;
00299
00300 pXdmac = pDmad->pXdmacs;
00301 xdmaGlobaIntStatus = XDMAC_GetGIsr(pXdmac);
00302 if ((xdmaGlobaIntStatus & 0xFFFFFF) != 0) {
00303 xdmaGlobalChStatus = XDMAC_GetGlobalChStatus(pXdmac);
00304 for (_iChannel = 0; _iChannel < pDmad->numChannels; _iChannel ++) {
00305 if (!(xdmaGlobaIntStatus & (1<<_iChannel))) continue;
00306 pCh = &pDmad->XdmaChannels[_iChannel];
00307 if ( pCh->state == XDMAD_STATE_FREE) return ;
00308 if ((xdmaGlobalChStatus & ( XDMAC_GS_ST0 << _iChannel)) == 0) {
00309 bExec = 0;
00310 xdmaChannelIntStatus = XDMAC_GetMaskChannelIsr( pXdmac, _iChannel);
00311 if (xdmaChannelIntStatus & XDMAC_CIS_BIS) {
00312 if((XDMAC_GetChannelItMask(pXdmac, _iChannel) & XDMAC_CIM_LIM)
00313 == 0 ) {
00314 pCh->state = XDMAD_STATE_DONE ;
00315 bExec = 1;
00316 }
00317 TRACE_DEBUG("XDMAC_CIS_BIS\n\r");
00318 }
00319 if (xdmaChannelIntStatus & XDMAC_CIS_FIS) {
00320 TRACE_DEBUG("XDMAC_CIS_FIS\n\r");
00321 }
00322 if (xdmaChannelIntStatus & XDMAC_CIS_RBEIS) {
00323 TRACE_DEBUG("XDMAC_CIS_RBEIS\n\r");
00324 }
00325 if (xdmaChannelIntStatus & XDMAC_CIS_WBEIS) {
00326 TRACE_DEBUG("XDMAC_CIS_WBEIS\n\r");
00327 }
00328 if (xdmaChannelIntStatus & XDMAC_CIS_ROIS) {
00329 TRACE_DEBUG("XDMAC_CIS_ROIS\n\r");
00330 }
00331 if (xdmaChannelIntStatus & XDMAC_CIS_LIS) {
00332 TRACE_DEBUG("XDMAC_CIS_LIS\n\r");
00333 pCh->state = XDMAD_STATE_DONE ;
00334 bExec = 1;
00335 }
00336 if (xdmaChannelIntStatus & XDMAC_CIS_DIS )
00337 {
00338 pCh->state = XDMAD_STATE_DONE ;
00339 bExec = 1;
00340 }
00341 SCB_CleanInvalidateDCache();
00342 } else {
00343 SCB_CleanInvalidateDCache();
00344
00345 if( XDMAC_GetChannelIsr( pXdmac, _iChannel) & XDMAC_CIS_BIS) {
00346
00347 pCh->fCallback(_iChannel, pCh->pArg);
00348 }
00349 }
00350
00351 if (bExec && pCh->fCallback) {
00352 pCh->fCallback(_iChannel, pCh->pArg);
00353 }
00354 }
00355 }
00356 }
00357
00358
00359
00360
00361
00362
00363
00364 eXdmadRC XDMAD_IsTransferDone( sXdmad *pXdmad, uint32_t dwChannel )
00365 {
00366 uint8_t iChannel = (dwChannel) & 0xFF;
00367 uint8_t state;
00368 assert( pXdmad != NULL ) ;
00369 if (iChannel >= pXdmad->numChannels)
00370 return XDMAD_ERROR;
00371
00372 SCB_CleanInvalidateDCache();
00373 state = pXdmad->XdmaChannels[iChannel].state;
00374 if ( state == XDMAD_STATE_ALLOCATED ) return XDMAD_OK;
00375 if ( state == XDMAD_STATE_FREE ) return XDMAD_ERROR;
00376 else if ( state != XDMAD_STATE_DONE ) {
00377 if(pXdmad->pollingMode) XDMAD_Handler( pXdmad);
00378 return XDMAD_BUSY;
00379 }
00380 return XDMAD_OK;
00381 }
00382
00383
00384
00385
00386
00387
00388
00389 eXdmadRC XDMAD_ConfigureTransfer( sXdmad *pXdmad,
00390 uint32_t dwChannel,
00391 sXdmadCfg *pXdmaParam,
00392 uint32_t dwXdmaDescCfg,
00393 uint32_t dwXdmaDescAddr,
00394 uint32_t dwXdmaIntEn)
00395 {
00396 uint8_t iChannel = (dwChannel) & 0xFF;
00397
00398 assert( pXdmad != NULL ) ;
00399 if (iChannel >= pXdmad->numChannels)
00400 return XDMAD_ERROR;
00401
00402 Xdmac *pXdmac = pXdmad->pXdmacs;
00403 XDMAC_GetChannelIsr( pXdmac, iChannel);
00404
00405 if ( pXdmad->XdmaChannels[iChannel].state == XDMAD_STATE_FREE )
00406 return XDMAD_ERROR;
00407 if ( pXdmad->XdmaChannels[iChannel].state == XDMAD_STATE_START )
00408 return XDMAD_BUSY;
00409
00410 if ((dwXdmaDescCfg & XDMAC_CNDC_NDE) == XDMAC_CNDC_NDE_DSCR_FETCH_EN) {
00411 if ((dwXdmaDescCfg & XDMAC_CNDC_NDVIEW_Msk) == XDMAC_CNDC_NDVIEW_NDV0) {
00412 XDMAC_SetChannelConfig( pXdmac, iChannel, pXdmaParam->mbr_cfg );
00413 XDMAC_SetSourceAddr(pXdmac, iChannel, pXdmaParam->mbr_sa);
00414 XDMAC_SetDestinationAddr(pXdmac, iChannel, pXdmaParam->mbr_da);
00415 }
00416 if ((dwXdmaDescCfg & XDMAC_CNDC_NDVIEW_Msk) == XDMAC_CNDC_NDVIEW_NDV1) {
00417 XDMAC_SetChannelConfig( pXdmac, iChannel, pXdmaParam->mbr_cfg );
00418 }
00419 XDMAC_SetDescriptorAddr(pXdmac, iChannel, dwXdmaDescAddr, 0);
00420 XDMAC_SetDescriptorControl(pXdmac, iChannel, dwXdmaDescCfg);
00421 XDMAC_DisableChannelIt (pXdmac, iChannel, 0xFF);
00422 XDMAC_EnableChannelIt (pXdmac,iChannel, dwXdmaIntEn );
00423 } else {
00424
00425 XDMAC_SetSourceAddr(pXdmac, iChannel, pXdmaParam->mbr_sa);
00426 XDMAC_SetDestinationAddr(pXdmac, iChannel, pXdmaParam->mbr_da);
00427 XDMAC_SetMicroblockControl(pXdmac, iChannel, pXdmaParam->mbr_ubc);
00428 XDMAC_SetBlockControl(pXdmac, iChannel, pXdmaParam->mbr_bc);
00429 XDMAC_SetDataStride_MemPattern(pXdmac, iChannel, pXdmaParam->mbr_ds);
00430 XDMAC_SetSourceMicroBlockStride(pXdmac, iChannel, pXdmaParam->mbr_sus);
00431 XDMAC_SetDestinationMicroBlockStride(pXdmac, iChannel, pXdmaParam->mbr_dus);
00432 XDMAC_SetChannelConfig( pXdmac, iChannel, pXdmaParam->mbr_cfg );
00433 XDMAC_SetDescriptorAddr(pXdmac, iChannel, 0, 0);
00434 XDMAC_SetDescriptorControl(pXdmac, iChannel, 0);
00435 XDMAC_EnableChannelIt (pXdmac,iChannel,dwXdmaIntEn);
00436 }
00437 return XDMAD_OK;
00438 }
00439
00440
00441
00442
00443
00444
00445 eXdmadRC XDMAD_StartTransfer( sXdmad *pXdmad, uint32_t dwChannel )
00446 {
00447 uint8_t iChannel = (dwChannel) & 0xFF;
00448
00449 assert( pXdmad != NULL ) ;
00450 if (iChannel >= pXdmad->numChannels) return XDMAD_ERROR;
00451
00452 Xdmac *pXdmac = pXdmad->pXdmacs;
00453 if ( pXdmad->XdmaChannels[iChannel].state == XDMAD_STATE_FREE ) {
00454 TRACE_ERROR("%s:: XDMAD_STATE_FREE \n\r", __FUNCTION__);
00455 return XDMAD_ERROR;
00456 } else if ( pXdmad->XdmaChannels[iChannel].state == XDMAD_STATE_START ) {
00457 TRACE_ERROR("%s:: XDMAD_STATE_START \n\r", __FUNCTION__)
00458 return XDMAD_BUSY;
00459 }
00460
00461 pXdmad->XdmaChannels[iChannel].state = XDMAD_STATE_START;
00462 XDMAC_EnableChannel(pXdmac, iChannel);
00463 if ( pXdmad->pollingMode == 0 ) {
00464 XDMAC_EnableGIt( pXdmac, iChannel);
00465 }
00466 return XDMAD_OK;
00467 }
00468
00469
00470
00471
00472
00473
00474
00475 eXdmadRC XDMAD_StopTransfer( sXdmad *pXdmad, uint32_t dwChannel )
00476 {
00477 uint8_t _iChannel = (dwChannel) & 0xFF;
00478 assert( pXdmad != NULL ) ;
00479 if (_iChannel >= pXdmad->numChannels) return XDMAD_ERROR;
00480 Xdmac *pXdmac = pXdmad->pXdmacs;
00481
00482 pXdmad->XdmaChannels[_iChannel].state = XDMAD_STATE_HALTED;
00483
00484 XDMAC_DisableChannel(pXdmac, _iChannel);
00485
00486 XDMAC_DisableChannelIt(pXdmac, _iChannel, 0xFF);
00487
00488 XDMAC_GetChannelIsr( pXdmac, _iChannel);
00489 XDMAC_GetGlobalChStatus(pXdmac);
00490 return XDMAD_OK;
00491 }
00492
00493
00494