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 #include "chip.h"
00035
00036 #include <assert.h>
00037
00038
00039
00040
00041 #define TWITIMEOUTMAX 400
00042 static uint32_t dmaWriteChannel,dmaReadChannel;
00043
00044
00045
00046
00047
00048
00049 typedef void (*TwiCallback)(Async *);
00050
00051
00052 typedef struct _AsyncTwi {
00053
00054
00055 volatile uint8_t status;
00056
00057 TwiCallback callback;
00058
00059 uint8_t *pData;
00060
00061 uint32_t num;
00062
00063 uint32_t transferred;
00064
00065 } AsyncTwi;
00066
00067
00068
00069
00070 static void TWID_DmaInitializeRead(TwihsDma *pTwiXdma)
00071 {
00072
00073 dmaReadChannel = XDMAD_AllocateChannel( pTwiXdma->pTwiDma, pTwiXdma->Twi_id,
00074 XDMAD_TRANSFER_MEMORY);
00075 if ( dmaReadChannel == XDMAD_ALLOC_FAILED ) {
00076 printf("-E- Can't allocate XDMA channel\n\r");
00077 }
00078 XDMAD_PrepareChannel(pTwiXdma->pTwiDma, dmaReadChannel );
00079 }
00080
00081
00082
00083
00084 static void TWID_DmaInitializeWrite(TwihsDma *pTwiXdma)
00085 {
00086
00087 dmaWriteChannel = XDMAD_AllocateChannel( pTwiXdma->pTwiDma, XDMAD_TRANSFER_MEMORY,
00088 pTwiXdma->Twi_id);
00089 if ( dmaWriteChannel == XDMAD_ALLOC_FAILED ) {
00090 printf("-E- Can't allocate XDMA channel\n\r");
00091 }
00092 XDMAD_PrepareChannel(pTwiXdma->pTwiDma, dmaWriteChannel );
00093 }
00094
00095
00096
00097
00098 static uint8_t TWID_XdmaConfigureWrite(TwihsDma *pTwiXdma, uint8_t *buf, uint32_t len)
00099 {
00100 uint32_t xdmaCndc, Thr, xdmaInt;
00101 sXdmadCfg xdmadTxCfg;
00102
00103 Thr = (uint32_t)&(TWIHS0->TWIHS_THR);
00104 if(pTwiXdma->Twi_id==ID_TWIHS1) {
00105 Thr = (uint32_t)&(TWIHS1->TWIHS_THR);
00106 }
00107 if(pTwiXdma->Twi_id==ID_TWIHS2) {
00108 Thr = (uint32_t)&(TWIHS2->TWIHS_THR);
00109 }
00110 xdmadTxCfg.mbr_ubc = XDMA_UBC_NVIEW_NDV0 |
00111 XDMA_UBC_NDE_FETCH_DIS|
00112 XDMA_UBC_NSEN_UPDATED | len;
00113
00114 xdmadTxCfg.mbr_sa = (uint32_t)buf;
00115 xdmadTxCfg.mbr_da = Thr;
00116 xdmadTxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN |
00117 XDMAC_CC_MBSIZE_SINGLE |
00118 XDMAC_CC_DSYNC_MEM2PER |
00119 XDMAC_CC_CSIZE_CHK_1 |
00120 XDMAC_CC_DWIDTH_BYTE|
00121 XDMAC_CC_SIF_AHB_IF0 |
00122 XDMAC_CC_DIF_AHB_IF1 |
00123 XDMAC_CC_SAM_INCREMENTED_AM |
00124 XDMAC_CC_DAM_FIXED_AM |
00125 XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber(
00126 pTwiXdma->Twi_id, XDMAD_TRANSFER_TX ));
00127
00128 xdmadTxCfg.mbr_bc = 0;
00129 xdmadTxCfg.mbr_sus = 0;
00130 xdmadTxCfg.mbr_dus =0;
00131 xdmaCndc = 0;
00132
00133 xdmaInt = (XDMAC_CIE_BIE |
00134 XDMAC_CIE_RBIE |
00135 XDMAC_CIE_WBIE );
00136 if (XDMAD_ConfigureTransfer( pTwiXdma->pTwiDma, dmaWriteChannel,
00137 &xdmadTxCfg, xdmaCndc, 0, xdmaInt) )
00138 return USARTD_ERROR;
00139
00140 return 0;
00141 }
00142
00143
00144
00145
00146
00147 static uint8_t TWID_XdmaConfigureRead(TwihsDma *pTwiXdma, uint8_t *buf, uint32_t len)
00148 {
00149 uint32_t xdmaCndc, Rhr, xdmaInt;
00150 sXdmadCfg xdmadRxCfg;
00151
00152 Rhr = (uint32_t)&(TWIHS0->TWIHS_RHR);
00153 if(pTwiXdma->Twi_id==ID_TWIHS1) {
00154 Rhr = (uint32_t)&(TWIHS1->TWIHS_RHR);
00155 }
00156 if(pTwiXdma->Twi_id==ID_TWIHS2) {
00157 Rhr = (uint32_t)&(TWIHS2->TWIHS_RHR);
00158 }
00159 xdmadRxCfg.mbr_ubc = XDMA_UBC_NVIEW_NDV0 |
00160 XDMA_UBC_NDE_FETCH_DIS|
00161 XDMA_UBC_NDEN_UPDATED |
00162 len;
00163
00164 xdmadRxCfg.mbr_da = (uint32_t)buf;
00165 xdmadRxCfg.mbr_sa = Rhr;
00166
00167 xdmadRxCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN |
00168 XDMAC_CC_MBSIZE_SINGLE |
00169 XDMAC_CC_DSYNC_PER2MEM |
00170 XDMAC_CC_CSIZE_CHK_1 |
00171 XDMAC_CC_DWIDTH_BYTE |
00172 XDMAC_CC_SIF_AHB_IF1 |
00173 XDMAC_CC_DIF_AHB_IF0 |
00174 XDMAC_CC_SAM_FIXED_AM |
00175 XDMAC_CC_DAM_INCREMENTED_AM |
00176 XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber(
00177 pTwiXdma->Twi_id , XDMAD_TRANSFER_RX ));
00178
00179 xdmadRxCfg.mbr_bc = 0;
00180 xdmadRxCfg.mbr_sus = 0;
00181 xdmadRxCfg.mbr_dus =0;
00182 xdmaCndc = 0;
00183 xdmaInt = (XDMAC_CIE_BIE |
00184 XDMAC_CIE_RBIE |
00185 XDMAC_CIE_WBIE );
00186
00187 if (XDMAD_ConfigureTransfer( pTwiXdma->pTwiDma, dmaReadChannel,
00188 &xdmadRxCfg, xdmaCndc, 0, xdmaInt))
00189 return 1;
00190 return 0;
00191 }
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201 uint32_t ASYNC_IsFinished( Async* pAsync )
00202 {
00203 return (pAsync->status != ASYNC_STATUS_PENDING) ;
00204 }
00205
00206
00207
00208
00209
00210
00211
00212
00213 void TWID_Initialize(Twid *pTwid, Twihs *pTwi)
00214 {
00215 TRACE_DEBUG( "TWID_Initialize()\n\r" ) ;
00216 assert( pTwid != NULL ) ;
00217 assert( pTwi != NULL ) ;
00218
00219
00220 pTwid->pTwi = pTwi;
00221 pTwid->pTransfer = 0;
00222 }
00223
00224
00225
00226
00227
00228
00229
00230 void TWID_Handler( Twid *pTwid )
00231 {
00232 uint8_t status;
00233 AsyncTwi *pTransfer ;
00234 Twihs *pTwi ;
00235
00236 assert( pTwid != NULL ) ;
00237
00238 pTransfer = (AsyncTwi*)pTwid->pTransfer ;
00239 assert( pTransfer != NULL ) ;
00240 pTwi = pTwid->pTwi ;
00241 assert( pTwi != NULL ) ;
00242
00243
00244 status = TWI_GetMaskedStatus(pTwi);
00245
00246
00247 if (TWI_STATUS_RXRDY(status)) {
00248
00249 pTransfer->pData[pTransfer->transferred] = TWI_ReadByte(pTwi);
00250 pTransfer->transferred++;
00251
00252
00253 if (pTransfer->transferred == pTransfer->num) {
00254
00255 TWI_DisableIt(pTwi, TWIHS_IDR_RXRDY);
00256 TWI_EnableIt(pTwi, TWIHS_IER_TXCOMP);
00257 }
00258
00259 else if (pTransfer->transferred == (pTransfer->num - 1)) {
00260
00261 TWI_Stop(pTwi);
00262 }
00263 }
00264
00265 else if (TWI_STATUS_TXRDY(status)) {
00266
00267
00268 if (pTransfer->transferred == pTransfer->num) {
00269
00270 TWI_DisableIt(pTwi, TWIHS_IDR_TXRDY);
00271 TWI_EnableIt(pTwi, TWIHS_IER_TXCOMP);
00272 TWI_SendSTOPCondition(pTwi);
00273 }
00274
00275 else {
00276
00277 TWI_WriteByte(pTwi, pTransfer->pData[pTransfer->transferred]);
00278 pTransfer->transferred++;
00279 }
00280 }
00281
00282 else if (TWI_STATUS_TXCOMP(status)) {
00283
00284 TWI_DisableIt(pTwi, TWIHS_IDR_TXCOMP);
00285 pTransfer->status = 0;
00286 if (pTransfer->callback) {
00287 pTransfer->callback((Async *) pTransfer);
00288 }
00289 pTwid->pTransfer = 0;
00290 }
00291 }
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305 uint8_t TWID_Read(
00306 Twid *pTwid,
00307 uint8_t address,
00308 uint32_t iaddress,
00309 uint8_t isize,
00310 uint8_t *pData,
00311 uint32_t num,
00312 Async *pAsync)
00313 {
00314 Twihs *pTwi;
00315 AsyncTwi *pTransfer;
00316 uint32_t startTime;
00317 assert( pTwid != NULL ) ;
00318 pTwi = pTwid->pTwi;
00319 pTransfer = (AsyncTwi *) pTwid->pTransfer;
00320
00321 assert( (address & 0x80) == 0 ) ;
00322 assert( (iaddress & 0xFF000000) == 0 ) ;
00323 assert( isize < 4 ) ;
00324
00325
00326 if (pTransfer) {
00327
00328 TRACE_ERROR("TWID_Read: A transfer is already pending\n\r");
00329 return TWID_ERROR_BUSY;
00330 }
00331
00332
00333 if (num == 1) {
00334
00335 TWI_Stop(pTwi);
00336 }
00337
00338
00339 if (pAsync) {
00340
00341
00342 pTwid->pTransfer = pAsync;
00343 pTransfer = (AsyncTwi *) pAsync;
00344 pTransfer->status = ASYNC_STATUS_PENDING;
00345 pTransfer->pData = pData;
00346 pTransfer->num = num;
00347 pTransfer->transferred = 0;
00348
00349
00350 TWI_EnableIt(pTwi, TWIHS_IER_RXRDY);
00351 TWI_StartRead(pTwi, address, iaddress, isize);
00352 }
00353
00354 else {
00355
00356
00357 TWI_StartRead(pTwi, address, iaddress, isize);
00358
00359
00360 while (num > 0) {
00361
00362
00363 if (num == 1) {
00364 TWI_Stop(pTwi);
00365 }
00366
00367 startTime = GetTicks();
00368 while( !TWI_ByteReceived(pTwi)) {
00369 if ( (GetDelayInTicks(startTime, GetTicks() ) ) > TWITIMEOUTMAX) {
00370 TRACE_ERROR("TWID Timeout BR\n\r");
00371 break;
00372 }
00373 }
00374
00375 *pData++ = TWI_ReadByte(pTwi);
00376 num--;
00377 }
00378
00379
00380 startTime = GetTicks();
00381 while( !TWI_TransferComplete(pTwi) ) {
00382 if ( (GetDelayInTicks(startTime, GetTicks() ) ) > TWITIMEOUTMAX) {
00383 TRACE_ERROR("TWID Timeout TC\n\r");
00384 break;
00385 }
00386 }
00387 }
00388 return 0;
00389 }
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403 uint8_t TWID_Write(
00404 Twid *pTwid,
00405 uint8_t address,
00406 uint32_t iaddress,
00407 uint8_t isize,
00408 uint8_t *pData,
00409 uint32_t num,
00410 Async *pAsync)
00411 {
00412 Twihs *pTwi = pTwid->pTwi;
00413 uint32_t startTime;
00414 AsyncTwi *pTransfer = (AsyncTwi *) pTwid->pTransfer;
00415
00416 assert( pTwi != NULL ) ;
00417 assert( (address & 0x80) == 0 ) ;
00418 assert( (iaddress & 0xFF000000) == 0 ) ;
00419 assert( isize < 4 ) ;
00420
00421
00422 if (pTransfer) {
00423 TRACE_ERROR("TWI_Write: A transfer is already pending\n\r");
00424 return TWID_ERROR_BUSY;
00425 }
00426
00427
00428 if (pAsync) {
00429
00430 pTwid->pTransfer = pAsync;
00431 pTransfer = (AsyncTwi *) pAsync;
00432 pTransfer->status = ASYNC_STATUS_PENDING;
00433 pTransfer->pData = pData;
00434 pTransfer->num = num;
00435 pTransfer->transferred = 1;
00436
00437
00438 TWI_StartWrite(pTwi, address, iaddress, isize, *pData);
00439 TWI_EnableIt(pTwi, TWIHS_IER_TXRDY);
00440
00441 } else {
00442
00443
00444 TWI_StartWrite(pTwi, address, iaddress, isize, *pData++);
00445 num--;
00446
00447 while (num > 0) {
00448
00449 startTime = GetTicks();
00450 while( !TWI_ByteSent(pTwi) ) {
00451 if ( (GetDelayInTicks(startTime, GetTicks() ) ) > TWITIMEOUTMAX) {
00452 TRACE_ERROR("TWID Timeout BS\n\r");
00453 break;
00454 }
00455 }
00456 TWI_WriteByte(pTwi, *pData++);
00457 num--;
00458 }
00459
00460 startTime = GetTicks();
00461
00462 TWI_SendSTOPCondition(pTwi);
00463 while( !TWI_TransferComplete(pTwi) ) {
00464 if ( (GetDelayInTicks(startTime, GetTicks() ) ) > TWITIMEOUTMAX) {
00465 TRACE_ERROR("TWID Timeout TC2\n\r");
00466 break;
00467 }
00468 }
00469 }
00470 return 0;
00471 }
00472
00473
00474
00475
00476
00477
00478
00479
00480 void TWID_DmaInitialize(TwihsDma *pTwidma, Twihs *pTwi, uint8_t bPolling)
00481 {
00482 TRACE_DEBUG( "TWID_Initialize()\n\r" ) ;
00483 assert( pTwidma != NULL ) ;
00484
00485 if ((unsigned int)pTwi == (unsigned int)TWIHS0 ) pTwidma->Twi_id = ID_TWIHS0;
00486 if ((unsigned int)pTwi == (unsigned int)TWIHS1 ) pTwidma->Twi_id = ID_TWIHS1;
00487 if ((unsigned int)pTwi == (unsigned int)TWIHS2 ) pTwidma->Twi_id = ID_TWIHS2;
00488
00489
00490 pTwidma->pTwid->pTwi = pTwi;
00491 pTwidma->pTwid->pTransfer = 0;
00492
00493 if(!bPolling) {
00494
00495
00496 NVIC_ClearPendingIRQ(XDMAC_IRQn);
00497 NVIC_SetPriority(XDMAC_IRQn, 1);
00498 NVIC_EnableIRQ( XDMAC_IRQn );
00499 }
00500
00501 XDMAD_Initialize( pTwidma->pTwiDma, bPolling );
00502 }
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517 uint8_t TWID_DmaRead(
00518 TwihsDma *pTwiXdma,
00519 uint8_t address,
00520 uint32_t iaddress,
00521 uint8_t isize,
00522 uint8_t *pData,
00523 uint32_t num,
00524 Async *pAsync)
00525 {
00526 Twihs *pTwi;
00527 AsyncTwi *pTransfer;
00528 uint32_t status, startTime;
00529
00530 assert( pTwiXdma->pTwid != NULL ) ;
00531 pTwi = pTwiXdma->pTwid->pTwi;
00532 pTransfer = (AsyncTwi *) pTwiXdma->pTwid->pTransfer;
00533
00534 assert( (address & 0x80) == 0 ) ;
00535 assert( (iaddress & 0xFF000000) == 0 ) ;
00536 assert( isize < 4 ) ;
00537
00538
00539 if (pTransfer) {
00540
00541 TRACE_ERROR("TWID_Read: A transfer is already pending\n\r");
00542 return TWID_ERROR_BUSY;
00543 }
00544
00545 if (pAsync) {
00546
00547 pTwiXdma->pTwid->pTransfer = pAsync;
00548 pTransfer = (AsyncTwi *) pAsync;
00549 pTransfer->status = ASYNC_STATUS_PENDING;
00550 pTransfer->pData = pData;
00551 pTransfer->num = num;
00552 pTransfer->transferred = 0;
00553
00554
00555 TWI_EnableIt(pTwi, TWIHS_IER_RXRDY);
00556 TWI_StartRead(pTwi, address, iaddress, isize);
00557 } else {
00558
00559 TWID_DmaInitializeRead(pTwiXdma);
00560 TWID_XdmaConfigureRead(pTwiXdma, pData, (num - 2));
00561
00562
00563 SCB_CleanInvalidateDCache();
00564
00565 XDMAD_StartTransfer( pTwiXdma->pTwiDma, dmaReadChannel );
00566 TWI_StartRead(pTwi, address, iaddress, isize);
00567
00568 startTime = GetTicks();
00569 while( XDMAD_IsTransferDone(pTwiXdma->pTwiDma, dmaReadChannel) ) {
00570 if ( (GetDelayInTicks(startTime, GetTicks() ) ) > TWITIMEOUTMAX) {
00571 TRACE_ERROR("TWID DMA not done\n\r");
00572 break;
00573 }
00574 }
00575
00576 status = TWI_GetStatus(pTwi);
00577 startTime = GetTicks();
00578
00579 while( !(status & TWIHS_SR_RXRDY)) {
00580 status = TWI_GetStatus(pTwi);
00581 if ( (GetDelayInTicks(startTime, GetTicks() ) ) > TWITIMEOUTMAX) {
00582 TRACE_ERROR("TWID DMA not done\n\r");
00583 break;
00584 }
00585 }
00586 TWI_Stop(pTwi);
00587
00588 pData[num - 2] = TWI_ReadByte(pTwi);
00589 status = TWI_GetStatus(pTwi);
00590 startTime = GetTicks();
00591
00592 while( !(status & TWIHS_SR_RXRDY)) {
00593 status = TWI_GetStatus(pTwi);
00594 if ( (GetDelayInTicks(startTime, GetTicks() ) ) > TWITIMEOUTMAX) {
00595 TRACE_ERROR("TWID Timeout Read\n\r");
00596 break;
00597 }
00598 }
00599 pData[num-1] = TWI_ReadByte(pTwi);
00600 status = TWI_GetStatus(pTwi);
00601 startTime = GetTicks();
00602 while( !(status & TWIHS_SR_TXCOMP)) {
00603 status = TWI_GetStatus(pTwi);
00604 if ( (GetDelayInTicks(startTime, GetTicks() ) ) > TWITIMEOUTMAX) {
00605 TRACE_ERROR("TWID Timeout Read\n\r");
00606 break;
00607 }
00608 }
00609
00610 XDMAD_StopTransfer( pTwiXdma->pTwiDma, dmaReadChannel );
00611 XDMAD_FreeChannel(pTwiXdma->pTwiDma, dmaWriteChannel);
00612 }
00613 return 0;
00614 }
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629 uint8_t TWID_DmaWrite(
00630 TwihsDma *pTwiXdma,
00631 uint8_t address,
00632 uint32_t iaddress,
00633 uint8_t isize,
00634 uint8_t *pData,
00635 uint32_t num,
00636 Async *pAsync)
00637 {
00638 Twihs *pTwi = pTwiXdma->pTwid->pTwi;
00639 AsyncTwi *pTransfer = (AsyncTwi *) pTwiXdma->pTwid->pTransfer;
00640 uint32_t status, startTime;
00641
00642 assert( pTwi != NULL ) ;
00643 assert( (address & 0x80) == 0 ) ;
00644 assert( (iaddress & 0xFF000000) == 0 ) ;
00645 assert( isize < 4 ) ;
00646
00647
00648
00649 if (pTransfer) {
00650
00651 TRACE_ERROR("TWI_Write: A transfer is already pending\n\r");
00652 return TWID_ERROR_BUSY;
00653 }
00654
00655
00656 if (pAsync) {
00657
00658
00659 pTwiXdma->pTwid->pTransfer = pAsync;
00660 pTransfer = (AsyncTwi *) pAsync;
00661 pTransfer->status = ASYNC_STATUS_PENDING;
00662 pTransfer->pData = pData;
00663 pTransfer->num = num;
00664 pTransfer->transferred = 1;
00665
00666
00667 TWI_StartWrite(pTwi, address, iaddress, isize, *pData);
00668 TWI_EnableIt(pTwi, TWIHS_IER_TXRDY);
00669 } else {
00670
00671 TWID_DmaInitializeWrite(pTwiXdma);
00672 TWID_XdmaConfigureWrite(pTwiXdma, pData, (num - 1) );
00673
00674 pTwi->TWIHS_MMR = 0;
00675 pTwi->TWIHS_MMR = (isize << 8) | (address << 16);
00676
00677
00678 pTwi->TWIHS_IADR = 0;
00679 pTwi->TWIHS_IADR = iaddress;
00680
00681
00682 SCB_CleanInvalidateDCache();
00683
00684 startTime = GetTicks();
00685
00686 XDMAD_StartTransfer( pTwiXdma->pTwiDma, dmaWriteChannel );
00687
00688 while( (XDMAD_IsTransferDone(pTwiXdma->pTwiDma, dmaWriteChannel)) ) {
00689 if ( (GetDelayInTicks(startTime, GetTicks() ) ) > TWITIMEOUTMAX) {
00690 TRACE_ERROR("TWID DMA not done, Channel State is %d\n\r",
00691 pTwiXdma->pTwiDma->XdmaChannels[dmaWriteChannel].state);
00692 break;
00693 }
00694 }
00695 status = TWI_GetStatus(pTwi);
00696 startTime = GetTicks();
00697
00698 while( !(status & TWIHS_SR_TXRDY)) {
00699 status = TWI_GetStatus(pTwi);
00700 if ( (GetDelayInTicks(startTime, GetTicks() ) ) > TWITIMEOUTMAX) {
00701 TRACE_ERROR("TWID Timeout TXRDY\n\r");
00702 break;
00703 }
00704 }
00705
00706 TWI_Stop(pTwi);
00707
00708 TWI_WriteByte(pTwi, pData[num-1]);
00709 status = TWI_GetStatus(pTwi);
00710 startTime = GetTicks();
00711
00712 while( !(status & TWIHS_SR_TXCOMP)) {
00713 status = TWI_GetStatus(pTwi);
00714 if ( (GetDelayInTicks(startTime, GetTicks() ) ) > TWITIMEOUTMAX) {
00715 TRACE_ERROR("TWID Timeout Write\n\r");
00716 break;
00717 }
00718 }
00719 XDMAD_StopTransfer(pTwiXdma->pTwiDma, dmaWriteChannel );
00720 XDMAD_FreeChannel(pTwiXdma->pTwiDma, dmaWriteChannel);
00721
00722 }
00723 return 0;
00724 }