@@ -92,10 +92,11 @@ static inline bool TWI_STATUS_NACK(uint32_t status) {
9292 return (status & TWI_SR_NACK) == TWI_SR_NACK;
9393}
9494
95- TwoWire::TwoWire (Twi *_twi, void (*_beginCb)(void )) :
95+ TwoWire::TwoWire (Twi *_twi, void (*_beginCb)(void ), void(*_endCb)( void ) ) :
9696 twi(_twi), rxBufferIndex(0 ), rxBufferLength(0 ), txAddress(0 ),
9797 txBufferLength(0 ), srvBufferIndex(0 ), srvBufferLength(0 ), status(
98- UNINITIALIZED), onBeginCallback(_beginCb), twiClock(TWI_CLOCK) {
98+ UNINITIALIZED), onBeginCallback(_beginCb),
99+ onEndCallback(_endCb), twiClock(TWI_CLOCK) {
99100}
100101
101102void TwoWire::begin (void ) {
@@ -126,25 +127,37 @@ void TwoWire::begin(int address) {
126127 begin ((uint8_t ) address);
127128}
128129
130+ void TwoWire::end (void ) {
131+ TWI_Disable (twi);
132+
133+ // Enable PDC channel
134+ twi->TWI_PTCR &= ~(UART_PTCR_RXTDIS | UART_PTCR_TXTDIS);
135+
136+ if (onEndCallback)
137+ onEndCallback ();
138+ }
139+
129140void TwoWire::setClock (uint32_t frequency) {
130141 twiClock = frequency;
131142 TWI_SetClock (twi, twiClock, VARIANT_MCK);
132143}
133144
134- uint8_t TwoWire::requestFrom (uint8_t address, uint8_t quantity, uint8_t sendStop) {
145+ uint8_t TwoWire::requestFrom (uint8_t address, uint8_t quantity, uint32_t iaddress, uint8_t isize, uint8_t sendStop) {
135146 if (quantity > BUFFER_LENGTH)
136147 quantity = BUFFER_LENGTH;
137148
138149 // perform blocking read into buffer
139150 int readed = 0 ;
140- TWI_StartRead (twi, address, 0 , 0 );
151+ TWI_StartRead (twi, address, iaddress, isize );
141152 do {
142153 // Stop condition must be set during the reception of last byte
143154 if (readed + 1 == quantity)
144155 TWI_SendSTOPCondition ( twi);
145156
146- TWI_WaitByteReceived (twi, RECV_TIMEOUT);
147- rxBuffer[readed++] = TWI_ReadByte (twi);
157+ if (TWI_WaitByteReceived (twi, RECV_TIMEOUT))
158+ rxBuffer[readed++] = TWI_ReadByte (twi);
159+ else
160+ break ;
148161 } while (readed < quantity);
149162 TWI_WaitTransferComplete (twi, RECV_TIMEOUT);
150163
@@ -155,6 +168,10 @@ uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop
155168 return readed;
156169}
157170
171+ uint8_t TwoWire::requestFrom (uint8_t address, uint8_t quantity, uint8_t sendStop) {
172+ return requestFrom ((uint8_t ) address, (uint8_t ) quantity, (uint32_t ) 0 , (uint8_t ) 0 , (uint8_t ) sendStop);
173+ }
174+
158175uint8_t TwoWire::requestFrom (uint8_t address, uint8_t quantity) {
159176 return requestFrom ((uint8_t ) address, (uint8_t ) quantity, (uint8_t ) true );
160177}
@@ -315,27 +332,25 @@ void TwoWire::onService(void) {
315332 }
316333 }
317334
318- if (status != SLAVE_IDLE) {
319- if (TWI_STATUS_TXCOMP (sr) && TWI_STATUS_EOSACC (sr)) {
320- if (status == SLAVE_RECV && onReceiveCallback) {
321- // Copy data into rxBuffer
322- // (allows to receive another packet while the
323- // user program reads actual data)
324- for (uint8_t i = 0 ; i < srvBufferLength; ++i)
325- rxBuffer[i] = srvBuffer[i];
326- rxBufferIndex = 0 ;
327- rxBufferLength = srvBufferLength;
328-
329- // Alert calling program
330- onReceiveCallback ( rxBufferLength);
331- }
332-
333- // Transfer completed
334- TWI_EnableIt (twi, TWI_SR_SVACC);
335- TWI_DisableIt (twi, TWI_IDR_RXRDY | TWI_IDR_GACC | TWI_IDR_NACK
336- | TWI_IDR_EOSACC | TWI_IDR_SCL_WS | TWI_IER_TXCOMP);
337- status = SLAVE_IDLE;
335+ if (status != SLAVE_IDLE && TWI_STATUS_EOSACC (sr)) {
336+ if (status == SLAVE_RECV && onReceiveCallback) {
337+ // Copy data into rxBuffer
338+ // (allows to receive another packet while the
339+ // user program reads actual data)
340+ for (uint8_t i = 0 ; i < srvBufferLength; ++i)
341+ rxBuffer[i] = srvBuffer[i];
342+ rxBufferIndex = 0 ;
343+ rxBufferLength = srvBufferLength;
344+
345+ // Alert calling program
346+ onReceiveCallback ( rxBufferLength);
338347 }
348+
349+ // Transfer completed
350+ TWI_EnableIt (twi, TWI_SR_SVACC);
351+ TWI_DisableIt (twi, TWI_IDR_RXRDY | TWI_IDR_GACC | TWI_IDR_NACK
352+ | TWI_IDR_EOSACC | TWI_IDR_SCL_WS | TWI_IER_TXCOMP);
353+ status = SLAVE_IDLE;
339354 }
340355
341356 if (status == SLAVE_RECV) {
@@ -375,7 +390,18 @@ static void Wire_Init(void) {
375390 NVIC_EnableIRQ (WIRE_ISR_ID);
376391}
377392
378- TwoWire Wire = TwoWire(WIRE_INTERFACE, Wire_Init);
393+ static void Wire_Deinit (void ) {
394+ NVIC_DisableIRQ (WIRE_ISR_ID);
395+ NVIC_ClearPendingIRQ (WIRE_ISR_ID);
396+
397+ pmc_disable_periph_clk (WIRE_INTERFACE_ID);
398+
399+ // no need to undo PIO_Configure,
400+ // as Peripheral A was enable by default before,
401+ // and pullups were not enabled
402+ }
403+
404+ TwoWire Wire = TwoWire(WIRE_INTERFACE, Wire_Init, Wire_Deinit);
379405
380406void WIRE_ISR_HANDLER (void ) {
381407 Wire.onService ();
@@ -402,7 +428,18 @@ static void Wire1_Init(void) {
402428 NVIC_EnableIRQ (WIRE1_ISR_ID);
403429}
404430
405- TwoWire Wire1 = TwoWire(WIRE1_INTERFACE, Wire1_Init);
431+ static void Wire1_Deinit (void ) {
432+ NVIC_DisableIRQ (WIRE1_ISR_ID);
433+ NVIC_ClearPendingIRQ (WIRE1_ISR_ID);
434+
435+ pmc_disable_periph_clk (WIRE1_INTERFACE_ID);
436+
437+ // no need to undo PIO_Configure,
438+ // as Peripheral A was enable by default before,
439+ // and pullups were not enabled
440+ }
441+
442+ TwoWire Wire1 = TwoWire(WIRE1_INTERFACE, Wire1_Init, Wire1_Deinit);
406443
407444void WIRE1_ISR_HANDLER (void ) {
408445 Wire1.onService ();
0 commit comments