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