1 /* ----------------------------------------------------------------------------
\r
2 * SAM Software Package License
\r
3 * ----------------------------------------------------------------------------
\r
4 * Copyright (c) 2011, Atmel Corporation
\r
6 * All rights reserved.
\r
8 * Redistribution and use in source and binary forms, with or without
\r
9 * modification, are permitted provided that the following conditions are met:
\r
11 * - Redistributions of source code must retain the above copyright notice,
\r
12 * this list of conditions and the disclaimer below.
\r
14 * Atmel's name may not be used to endorse or promote products derived from
\r
15 * this software without specific prior written permission.
\r
17 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
\r
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
\r
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
\r
20 * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
\r
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
\r
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
\r
23 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
\r
24 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
\r
25 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
\r
26 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\r
27 * ----------------------------------------------------------------------------
\r
31 /*----------------------------------------------------------------------------
\r
33 *----------------------------------------------------------------------------*/
\r
38 /*----------------------------------------------------------------------------
\r
40 *----------------------------------------------------------------------------*/
\r
41 #define TWITIMEOUTMAX 50000
\r
42 static sXdmad twi_dma;
\r
43 static sXdmadCfg twi_dmaCfg;
\r
44 static uint32_t dmaWriteChannel,dmaReadChannel;
\r
45 static LinkedListDescriporView1 dmaWriteLinkList[1];
\r
46 static LinkedListDescriporView1 dmaReadLinkList[1];
\r
47 /*----------------------------------------------------------------------------
\r
49 *----------------------------------------------------------------------------*/
\r
51 /** TWI driver callback function.*/
\r
52 typedef void (*TwiCallback)(Async *);
\r
54 /** \brief TWI asynchronous transfer descriptor.*/
\r
55 typedef struct _AsyncTwi {
\r
57 /** Asynchronous transfer status. */
\r
58 volatile uint8_t status;
\r
59 // Callback function to invoke when transfer completes or fails.*/
\r
60 TwiCallback callback;
\r
61 /** Pointer to the data buffer.*/
\r
63 /** Total number of bytes to transfer.*/
\r
65 /** Number of already transferred bytes.*/
\r
66 uint32_t transferred;
\r
71 * \brief Initializes a TWI DMA Read channel.
\r
73 static void TWID_DmaInitializeRead(uint8_t TWI_ID)
\r
76 /* Allocate a XDMA channel, Read accesses into TWI_THR */
\r
77 dmaReadChannel = XDMAD_AllocateChannel( &twi_dma, TWI_ID, XDMAD_TRANSFER_MEMORY);
\r
78 if ( dmaReadChannel == XDMAD_ALLOC_FAILED )
\r
80 printf("-E- Can't allocate XDMA channel\n\r");
\r
82 XDMAD_PrepareChannel(&twi_dma, dmaReadChannel );
\r
86 * \brief Initializes a TWI DMA write channel.
\r
88 static void TWID_DmaInitializeWrite(uint8_t TWI_ID)
\r
91 /* Allocate a XDMA channel, Write accesses into TWI_THR */
\r
92 dmaWriteChannel = XDMAD_AllocateChannel( &twi_dma, XDMAD_TRANSFER_MEMORY, TWI_ID);
\r
93 if ( dmaWriteChannel == XDMAD_ALLOC_FAILED )
\r
95 printf("-E- Can't allocate XDMA channel\n\r");
\r
97 XDMAD_PrepareChannel(&twi_dma, dmaWriteChannel );
\r
103 * \brief Configure xDMA write linker list for TWI transfer.
\r
105 static void TWID_XdmaConfigureWrite(uint8_t *buf, uint32_t len, uint8_t TWI_ID)
\r
108 uint32_t xdmaCndc, Thr;
\r
110 Thr = (uint32_t)&(TWI0->TWIHS_THR);
\r
111 if(TWI_ID==ID_TWI1)
\r
113 Thr = (uint32_t)&(TWI1->TWIHS_THR);
\r
115 if(TWI_ID==ID_TWI2)
\r
117 Thr = (uint32_t)&(TWI2->TWIHS_THR);
\r
119 for ( i = 0; i < 1; i++){
\r
120 dmaWriteLinkList[i].mbr_ubc = XDMA_UBC_NVIEW_NDV1
\r
121 |(( i == len - 1) ? 0: XDMA_UBC_NDE_FETCH_EN)
\r
123 dmaWriteLinkList[i].mbr_sa = (uint32_t)&buf[i];
\r
124 dmaWriteLinkList[i].mbr_da = Thr;
\r
125 if ( i == len - 1) dmaWriteLinkList[i].mbr_nda = 0;
\r
126 else dmaWriteLinkList[i].mbr_nda = (uint32_t)&dmaWriteLinkList[ i + 1 ];
\r
128 twi_dmaCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN
\r
129 | XDMAC_CC_MBSIZE_SINGLE
\r
130 | XDMAC_CC_DSYNC_MEM2PER
\r
131 | XDMAC_CC_CSIZE_CHK_1
\r
132 | XDMAC_CC_DWIDTH_BYTE
\r
133 | XDMAC_CC_SIF_AHB_IF0
\r
134 | XDMAC_CC_DIF_AHB_IF1
\r
135 | XDMAC_CC_SAM_INCREMENTED_AM
\r
136 | XDMAC_CC_DAM_FIXED_AM
\r
137 | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber(TWI_ID, XDMAD_TRANSFER_TX ));
\r
138 xdmaCndc = XDMAC_CNDC_NDVIEW_NDV1
\r
139 | XDMAC_CNDC_NDE_DSCR_FETCH_EN
\r
140 | XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED
\r
141 | XDMAC_CNDC_NDDUP_DST_PARAMS_UNCHANGED ;
\r
143 XDMAD_ConfigureTransfer( &twi_dma, dmaWriteChannel, &twi_dmaCfg, xdmaCndc, (uint32_t)&dmaWriteLinkList[0]);
\r
149 * \brief Configure xDMA read linker list for TWI transfer.
\r
151 static void TWID_XdmaConfigureRead(uint8_t *buf, uint32_t len, uint8_t TWI_ID)
\r
154 uint32_t xdmaCndc, Rhr;
\r
156 Rhr = (uint32_t)&(TWI0->TWIHS_RHR);
\r
157 if(TWI_ID==ID_TWI1)
\r
159 Rhr = (uint32_t)&(TWI1->TWIHS_RHR);
\r
161 if(TWI_ID==ID_TWI2)
\r
163 Rhr = (uint32_t)&(TWI2->TWIHS_RHR);
\r
165 for ( i = 0; i < 1; i++){
\r
166 dmaReadLinkList[i].mbr_ubc = XDMA_UBC_NVIEW_NDV1
\r
167 | (( i == len - 1) ? 0: XDMA_UBC_NDE_FETCH_EN)
\r
169 dmaReadLinkList[i].mbr_sa = Rhr;
\r
170 dmaReadLinkList[i].mbr_da = (uint32_t)&buf[i];
\r
172 dmaReadLinkList[i].mbr_nda = 0;
\r
174 dmaReadLinkList[i].mbr_nda = (uint32_t)&dmaReadLinkList[ i + 1 ];
\r
176 twi_dmaCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN
\r
177 | XDMAC_CC_MBSIZE_SINGLE
\r
178 | XDMAC_CC_DSYNC_PER2MEM
\r
179 | XDMAC_CC_CSIZE_CHK_1
\r
180 | XDMAC_CC_DWIDTH_BYTE
\r
181 | XDMAC_CC_SIF_AHB_IF1
\r
182 | XDMAC_CC_DIF_AHB_IF0
\r
183 | XDMAC_CC_SAM_FIXED_AM
\r
184 | XDMAC_CC_DAM_INCREMENTED_AM
\r
185 | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber(TWI_ID, XDMAD_TRANSFER_RX ));
\r
186 xdmaCndc = XDMAC_CNDC_NDVIEW_NDV1
\r
187 | XDMAC_CNDC_NDE_DSCR_FETCH_EN
\r
188 | XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED
\r
189 | XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED ;
\r
191 XDMAD_ConfigureTransfer( &twi_dma, dmaReadChannel, &twi_dmaCfg, xdmaCndc, (uint32_t)&dmaReadLinkList[0]);
\r
195 /*----------------------------------------------------------------------------
\r
197 *----------------------------------------------------------------------------*/
\r
200 * \brief Returns 1 if the given transfer has ended; otherwise returns 0.
\r
201 * \param pAsync Pointer to an Async instance.
\r
203 uint32_t ASYNC_IsFinished( Async* pAsync )
\r
205 return (pAsync->status != ASYNC_STATUS_PENDING) ;
\r
211 * \brief Initializes a TWI driver instance, using the given TWI peripheral.
\r
212 * \note The peripheral must have been initialized properly before calling this function.
\r
213 * \param pTwid Pointer to the Twid instance to initialize.
\r
214 * \param pTwi Pointer to the TWI peripheral to use.
\r
216 void TWID_Initialize(Twid *pTwid, Twihs *pTwi)
\r
218 TRACE_DEBUG( "TWID_Initialize()\n\r" ) ;
\r
219 assert( pTwid != NULL ) ;
\r
220 assert( pTwi != NULL ) ;
\r
222 /* Initialize driver. */
\r
223 pTwid->pTwi = pTwi;
\r
224 pTwid->pTransfer = 0;
\r
229 * \brief Interrupt handler for a TWI peripheral. Manages asynchronous transfer
\r
230 * occuring on the bus. This function MUST be called by the interrupt service
\r
231 * routine of the TWI peripheral if asynchronous read/write are needed.
\r
232 * \param pTwid Pointer to a Twid instance.
\r
234 void TWID_Handler( Twid *pTwid )
\r
237 AsyncTwi *pTransfer ;
\r
240 assert( pTwid != NULL ) ;
\r
242 pTransfer = (AsyncTwi*)pTwid->pTransfer ;
\r
243 assert( pTransfer != NULL ) ;
\r
244 pTwi = pTwid->pTwi ;
\r
245 assert( pTwi != NULL ) ;
\r
247 /* Retrieve interrupt status */
\r
248 status = TWI_GetMaskedStatus(pTwi);
\r
250 /* Byte received */
\r
251 if (TWI_STATUS_RXRDY(status)) {
\r
253 pTransfer->pData[pTransfer->transferred] = TWI_ReadByte(pTwi);
\r
254 pTransfer->transferred++;
\r
256 /* check for transfer finish */
\r
257 if (pTransfer->transferred == pTransfer->num) {
\r
259 TWI_DisableIt(pTwi, TWIHS_IDR_RXRDY);
\r
260 TWI_EnableIt(pTwi, TWIHS_IER_TXCOMP);
\r
263 else if (pTransfer->transferred == (pTransfer->num - 1)) {
\r
269 else if (TWI_STATUS_TXRDY(status)) {
\r
271 /* Transfer finished ? */
\r
272 if (pTransfer->transferred == pTransfer->num) {
\r
274 TWI_DisableIt(pTwi, TWIHS_IDR_TXRDY);
\r
275 TWI_EnableIt(pTwi, TWIHS_IER_TXCOMP);
\r
276 TWI_SendSTOPCondition(pTwi);
\r
278 /* Bytes remaining */
\r
281 TWI_WriteByte(pTwi, pTransfer->pData[pTransfer->transferred]);
\r
282 pTransfer->transferred++;
\r
285 /* Transfer complete*/
\r
286 else if (TWI_STATUS_TXCOMP(status)) {
\r
288 TWI_DisableIt(pTwi, TWIHS_IDR_TXCOMP);
\r
289 pTransfer->status = 0;
\r
290 if (pTransfer->callback) {
\r
292 pTransfer->callback((Async *) pTransfer);
\r
294 pTwid->pTransfer = 0;
\r
299 * \brief Asynchronously reads data from a slave on the TWI bus. An optional
\r
300 * callback function is triggered when the transfer is complete.
\r
301 * \param pTwid Pointer to a Twid instance.
\r
302 * \param address TWI slave address.
\r
303 * \param iaddress Optional slave internal address.
\r
304 * \param isize Internal address size in bytes.
\r
305 * \param pData Data buffer for storing received bytes.
\r
306 * \param num Number of bytes to read.
\r
307 * \param pAsync Asynchronous transfer descriptor.
\r
308 * \return 0 if the transfer has been started; otherwise returns a TWI error code.
\r
320 AsyncTwi *pTransfer;
\r
323 assert( pTwid != NULL ) ;
\r
324 pTwi = pTwid->pTwi;
\r
325 pTransfer = (AsyncTwi *) pTwid->pTransfer;
\r
327 assert( (address & 0x80) == 0 ) ;
\r
328 assert( (iaddress & 0xFF000000) == 0 ) ;
\r
329 assert( isize < 4 ) ;
\r
331 /* Check that no transfer is already pending*/
\r
334 TRACE_ERROR("TWID_Read: A transfer is already pending\n\r");
\r
335 return TWID_ERROR_BUSY;
\r
338 /* Set STOP signal if only one byte is sent*/
\r
344 /* Asynchronous transfer*/
\r
347 /* Update the transfer descriptor */
\r
348 pTwid->pTransfer = pAsync;
\r
349 pTransfer = (AsyncTwi *) pAsync;
\r
350 pTransfer->status = ASYNC_STATUS_PENDING;
\r
351 pTransfer->pData = pData;
\r
352 pTransfer->num = num;
\r
353 pTransfer->transferred = 0;
\r
355 /* Enable read interrupt and start the transfer */
\r
356 TWI_EnableIt(pTwi, TWIHS_IER_RXRDY);
\r
357 TWI_StartRead(pTwi, address, iaddress, isize);
\r
359 /* Synchronous transfer*/
\r
363 TWI_StartRead(pTwi, address, iaddress, isize);
\r
365 /* Read all bytes, setting STOP before the last byte*/
\r
374 /* Wait for byte then read and store it*/
\r
376 while( !TWI_ByteReceived(pTwi) && (++timeout<TWITIMEOUTMAX) );
\r
377 if (timeout == TWITIMEOUTMAX) {
\r
378 TRACE_ERROR("TWID Timeout BR\n\r");
\r
380 *pData++ = TWI_ReadByte(pTwi);
\r
384 /* Wait for transfer to be complete */
\r
386 while( !TWI_TransferComplete(pTwi) && (++timeout<TWITIMEOUTMAX) );
\r
387 if (timeout == TWITIMEOUTMAX) {
\r
388 TRACE_ERROR("TWID Timeout TC\n\r");
\r
396 * \brief Asynchronously sends data to a slave on the TWI bus. An optional callback
\r
397 * function is invoked whenever the transfer is complete.
\r
398 * \param pTwid Pointer to a Twid instance.
\r
399 * \param address TWI slave address.
\r
400 * \param iaddress Optional slave internal address.
\r
401 * \param isize Number of internal address bytes.
\r
402 * \param pData Data buffer for storing received bytes.
\r
403 * \param num Data buffer to send.
\r
404 * \param pAsync Asynchronous transfer descriptor.
\r
405 * \return 0 if the transfer has been started; otherwise returns a TWI error code.
\r
407 uint8_t TWID_Write(
\r
416 Twihs *pTwi = pTwid->pTwi;
\r
417 AsyncTwi *pTransfer = (AsyncTwi *) pTwid->pTransfer;
\r
420 assert( pTwi != NULL ) ;
\r
421 assert( (address & 0x80) == 0 ) ;
\r
422 assert( (iaddress & 0xFF000000) == 0 ) ;
\r
423 assert( isize < 4 ) ;
\r
425 /* Check that no transfer is already pending */
\r
428 TRACE_ERROR("TWI_Write: A transfer is already pending\n\r");
\r
429 return TWID_ERROR_BUSY;
\r
432 /* Asynchronous transfer */
\r
435 /* Update the transfer descriptor */
\r
436 pTwid->pTransfer = pAsync;
\r
437 pTransfer = (AsyncTwi *) pAsync;
\r
438 pTransfer->status = ASYNC_STATUS_PENDING;
\r
439 pTransfer->pData = pData;
\r
440 pTransfer->num = num;
\r
441 pTransfer->transferred = 1;
\r
443 /* Enable write interrupt and start the transfer */
\r
444 TWI_StartWrite(pTwi, address, iaddress, isize, *pData);
\r
445 TWI_EnableIt(pTwi, TWIHS_IER_TXRDY);
\r
447 /* Synchronous transfer*/
\r
451 TWI_StartWrite(pTwi, address, iaddress, isize, *pData++);
\r
454 /* Send all bytes */
\r
457 /* Wait before sending the next byte */
\r
459 while( !TWI_ByteSent(pTwi) && (++timeout<TWITIMEOUTMAX) );
\r
460 if (timeout == TWITIMEOUTMAX) {
\r
461 TRACE_ERROR("TWID Timeout BS\n\r");
\r
464 TWI_WriteByte(pTwi, *pData++);
\r
468 /* Wait for actual end of transfer */
\r
471 /* Send a STOP condition */
\r
472 TWI_SendSTOPCondition(pTwi);
\r
474 while( !TWI_TransferComplete(pTwi) && (++timeout<TWITIMEOUTMAX) );
\r
475 if (timeout == TWITIMEOUTMAX) {
\r
476 TRACE_ERROR("TWID Timeout TC2\n\r");
\r
485 * \brief Initializes a TWI driver instance, using the given TWI peripheral.
\r
486 * \note The peripheral must have been initialized properly before calling this function.
\r
487 * \param pTwid Pointer to the Twid instance to initialize.
\r
488 * \param pTwi Pointer to the TWI peripheral to use.
\r
490 void TWID_DmaInitialize(Twid *pTwid, Twihs *pTwi)
\r
492 TRACE_DEBUG( "TWID_Initialize()\n\r" ) ;
\r
493 assert( pTwid != NULL ) ;
\r
494 assert( pTwi != NULL ) ;
\r
496 /* Initialize driver. */
\r
497 pTwid->pTwi = pTwi;
\r
498 pTwid->pTransfer = 0;
\r
500 /* Initialize XDMA driver instance with polling mode */
\r
501 XDMAD_Initialize( &twi_dma, 1 );
\r
505 * \brief Asynchronously reads data from a slave on the TWI bus. An optional
\r
506 * callback function is triggered when the transfer is complete.
\r
507 * \param pTwid Pointer to a Twid instance.
\r
508 * \param address TWI slave address.
\r
509 * \param iaddress Optional slave internal address.
\r
510 * \param isize Internal address size in bytes.
\r
511 * \param pData Data buffer for storing received bytes.
\r
512 * \param num Number of bytes to read.
\r
513 * \param pAsync Asynchronous transfer descriptor.
\r
514 * \param TWI_ID TWI ID for TWI0, TWI1, TWI2.
\r
515 * \return 0 if the transfer has been started; otherwise returns a TWI error code.
\r
517 uint8_t TWID_DmaRead(
\r
528 AsyncTwi *pTransfer;
\r
529 uint32_t timeout = 0;
\r
532 assert( pTwid != NULL ) ;
\r
533 pTwi = pTwid->pTwi;
\r
534 pTransfer = (AsyncTwi *) pTwid->pTransfer;
\r
536 assert( (address & 0x80) == 0 ) ;
\r
537 assert( (iaddress & 0xFF000000) == 0 ) ;
\r
538 assert( isize < 4 ) ;
\r
540 /* Check that no transfer is already pending*/
\r
543 TRACE_ERROR("TWID_Read: A transfer is already pending\n\r");
\r
544 return TWID_ERROR_BUSY;
\r
547 /* Asynchronous transfer*/
\r
550 /* Update the transfer descriptor */
\r
551 pTwid->pTransfer = pAsync;
\r
552 pTransfer = (AsyncTwi *) pAsync;
\r
553 pTransfer->status = ASYNC_STATUS_PENDING;
\r
554 pTransfer->pData = pData;
\r
555 pTransfer->num = num;
\r
556 pTransfer->transferred = 0;
\r
558 /* Enable read interrupt and start the transfer */
\r
559 TWI_EnableIt(pTwi, TWI_IER_RXRDY);
\r
560 TWI_StartRead(pTwi, address, iaddress, isize);
\r
562 /* Synchronous transfer*/
\r
565 TWID_DmaInitializeRead(TWI_ID);
\r
566 TWID_XdmaConfigureRead(pData, num, TWI_ID);
\r
568 XDMAD_StartTransfer( &twi_dma, dmaReadChannel );
\r
570 TWI_StartRead(pTwi, address, iaddress, isize);
\r
572 while((XDMAD_IsTransferDone(&twi_dma, dmaReadChannel)) && (++timeout<TWITIMEOUTMAX));
\r
574 XDMAD_StopTransfer( &twi_dma, dmaReadChannel );
\r
576 status = TWI_GetStatus(pTwi);
\r
578 while( !(status & TWI_SR_RXRDY) && (++timeout<TWITIMEOUTMAX));
\r
582 TWI_ReadByte(pTwi);
\r
584 status = TWI_GetStatus(pTwi);
\r
586 while( !(status & TWI_SR_RXRDY) && (++timeout<TWITIMEOUTMAX));
\r
588 TWI_ReadByte(pTwi);
\r
590 status = TWI_GetStatus(pTwi);
\r
592 while( !(status & TWI_SR_TXCOMP) && (++timeout<TWITIMEOUTMAX));
\r
593 if (timeout == TWITIMEOUTMAX) {
\r
594 TRACE_ERROR("TWID Timeout Read\n\r");
\r
596 XDMAD_FreeChannel(&twi_dma, dmaReadChannel);
\r
605 * \brief Asynchronously sends data to a slave on the TWI bus. An optional callback
\r
606 * function is invoked whenever the transfer is complete.
\r
607 * \param pTwid Pointer to a Twid instance.
\r
608 * \param address TWI slave address.
\r
609 * \param iaddress Optional slave internal address.
\r
610 * \param isize Number of internal address bytes.
\r
611 * \param pData Data buffer for storing received bytes.
\r
612 * \param num Data buffer to send.
\r
613 * \param pAsync Asynchronous transfer descriptor.
\r
614 * \param TWI_ID TWI ID for TWI0, TWI1, TWI2.
\r
615 * \return 0 if the transfer has been started; otherwise returns a TWI error code.
\r
617 uint8_t TWID_DmaWrite(
\r
627 Twihs *pTwi = pTwid->pTwi;
\r
628 AsyncTwi *pTransfer = (AsyncTwi *) pTwid->pTransfer;
\r
629 uint32_t timeout = 0;
\r
631 //uint8_t singleTransfer = 0;
\r
632 assert( pTwi != NULL ) ;
\r
633 assert( (address & 0x80) == 0 ) ;
\r
634 assert( (iaddress & 0xFF000000) == 0 ) ;
\r
635 assert( isize < 4 ) ;
\r
637 // if(num == 1) singleTransfer = 1;
\r
638 /* Check that no transfer is already pending */
\r
641 TRACE_ERROR("TWI_Write: A transfer is already pending\n\r");
\r
642 return TWID_ERROR_BUSY;
\r
645 /* Asynchronous transfer */
\r
648 /* Update the transfer descriptor */
\r
649 pTwid->pTransfer = pAsync;
\r
650 pTransfer = (AsyncTwi *) pAsync;
\r
651 pTransfer->status = ASYNC_STATUS_PENDING;
\r
652 pTransfer->pData = pData;
\r
653 pTransfer->num = num;
\r
654 pTransfer->transferred = 1;
\r
656 /* Enable write interrupt and start the transfer */
\r
657 TWI_StartWrite(pTwi, address, iaddress, isize, *pData);
\r
658 TWI_EnableIt(pTwi, TWI_IER_TXRDY);
\r
660 /* Synchronous transfer*/
\r
663 TWID_DmaInitializeWrite(TWI_ID);
\r
664 TWID_XdmaConfigureWrite(pData, num, TWI_ID);
\r
665 /* Set slave address and number of internal address bytes. */
\r
666 pTwi->TWIHS_MMR = 0;
\r
667 pTwi->TWIHS_MMR = (isize << 8) | (address << 16);
\r
669 /* Set internal address bytes. */
\r
670 pTwi->TWIHS_IADR = 0;
\r
671 pTwi->TWIHS_IADR = iaddress;
\r
672 XDMAD_StartTransfer( &twi_dma, dmaWriteChannel );
\r
674 while(XDMAD_IsTransferDone(&twi_dma, dmaWriteChannel));
\r
676 XDMAD_StopTransfer( &twi_dma, dmaWriteChannel );
\r
678 status = TWI_GetStatus(pTwi);
\r
680 while( !(status & TWI_SR_TXRDY) && (timeout++ < TWITIMEOUTMAX) )
\r
682 status = TWI_GetStatus(pTwi);
\r
684 if (timeout == TWITIMEOUTMAX) {
\r
685 TRACE_ERROR("TWID Timeout TXRDY\n\r");
\r
688 /* Send a STOP condition */
\r
691 status = TWI_GetStatus(pTwi);
\r
693 while( !(status & TWI_SR_TXCOMP) && (++timeout<TWITIMEOUTMAX))
\r
695 status = TWI_GetStatus(pTwi);
\r
697 if (timeout == TWITIMEOUTMAX) {
\r
698 TRACE_ERROR("TWID Timeout Write\n\r");
\r
701 XDMAD_FreeChannel(&twi_dma, dmaWriteChannel);
\r