@@ -14,11 +14,14 @@ TwoWire::TwoWire(XMC_I2C_t *conf) {
1414 slaveAddress = 0 ;
1515 txAddress = 0 ;
1616
17- rxBufferIndex = 0 ;
18- rxBufferLength = 0 ;
19- txBufferIndex = 0 ;
20- txBufferLength = 0 ;
21- pre_rxBufferCount = 0 ;
17+ rx_ringBuffer.clear ();
18+ tx_ringBuffer.clear ();
19+ pre_rx_ringBuffer.clear ();
20+ // rxBufferIndex = 0;
21+ // rxBufferLength = 0;
22+ // txBufferIndex = 0;
23+ // txBufferLength = 0;
24+ // pre_rxBufferCount = 0;
2225}
2326
2427// Public Methods //////////////////////////////////////////////////////////////
@@ -158,8 +161,7 @@ void TwoWire::end(void) {
158161
159162void TwoWire::setClock (uint32_t clock) { XMC_I2C_CH_SetBaudrate (XMC_I2C_config->channel , clock); }
160163
161- size_t TwoWire::requestFrom (
162- uint8_t address, size_t quantity, uint32_t iaddress, uint8_t isize, bool sendStop) {
164+ size_t TwoWire::requestFrom (uint8_t address, size_t quantity, uint32_t iaddress, uint8_t isize, bool sendStop) {
163165 uint32_t StatusFlag;
164166 beginTransmission (address);
165167 // clamp to buffer length
@@ -266,9 +268,7 @@ size_t TwoWire::requestFrom(
266268 }
267269 }
268270
269- // set rx buffer iterator vars
270- rxBufferIndex = 0 ;
271- rxBufferLength = quantity;
271+
272272 // indicate that we are done transmitting
273273 transmitting = 0 ;
274274
@@ -298,8 +298,7 @@ void TwoWire::beginTransmission(uint8_t address) {
298298 // set address of targeted slave
299299 txAddress = address;
300300 // reset tx buffer iterator vars
301- txBufferIndex = 0 ;
302- txBufferLength = 0 ;
301+ tx_ringBuffer.clear ();
303302 // Clear all Status Flags
304303 XMC_I2C_CH_ClearStatusFlag (XMC_I2C_config->channel , 0xFFFFFFFF );
305304}
@@ -321,8 +320,9 @@ uint8_t TwoWire::endTransmission(bool sendStop) {
321320
322321 XMC_I2C_CH_MasterStart (XMC_I2C_config->channel , (txAddress << 1 ), XMC_I2C_CH_CMD_WRITE);
323322
324- for (uint8_t count = 0 ; count < txBufferLength; count++) {
325- XMC_I2C_CH_MasterTransmit (XMC_I2C_config->channel , txBuffer[count]);
323+ while (tx_ringBuffer.available ()) {
324+ uint8_t data = tx_ringBuffer.read_char ();
325+ XMC_I2C_CH_MasterTransmit (XMC_I2C_config->channel , data);
326326
327327 timeout = WIRE_COMMUNICATION_TIMEOUT;
328328 // Wait for ACK, leave when NACK is detected
@@ -359,9 +359,7 @@ uint8_t TwoWire::endTransmission(bool sendStop) {
359359 inRepStart = true ;
360360 }
361361
362- // reset tx buffer iterator vars
363- txBufferIndex = 0 ;
364- txBufferLength = 0 ;
362+
365363 // indicate that we are done transmitting
366364 transmitting = 0 ;
367365 return 0 ;
@@ -378,15 +376,12 @@ size_t TwoWire::write(uint8_t data) {
378376 if (transmitting) {
379377 // in master transmitter mode
380378 // don't bother if buffer is full
381- if (txBufferLength >= BUFFER_LENGTH ) {
379+ if (tx_ringBuffer. isFull () ) {
382380 // TODO: setWriteError();
383381 return 0 ;
384382 }
385383 // put byte in tx buffer
386- txBuffer[txBufferIndex] = data;
387- ++txBufferIndex;
388- // update amount in buffer
389- txBufferLength = txBufferIndex;
384+ tx_ringBuffer.store_char (data);
390385 } else {
391386 // in slave send mode
392387 // reply to master
@@ -423,8 +418,10 @@ size_t TwoWire::write(const uint8_t *data, size_t quantity) {
423418 if (transmitting) {
424419 // in master transmitter mode
425420 for (size_t i = 0 ; i < quantity; ++i) {
426- write (data[i]);
421+ if (!write (data[i])) {
422+ return 1 ;
427423 }
424+ }
428425 } else {
429426 // in slave send mode
430427 // reply to master
@@ -459,34 +456,28 @@ size_t TwoWire::write(const uint8_t *data, size_t quantity) {
459456// must be called in:
460457// slave rx event callback
461458// or after requestFrom(address, numBytes)
462- int TwoWire::available (void ) { return rxBufferLength - rxBufferIndex ; }
459+ int TwoWire::available (void ) { return rx_ringBuffer. available () ; }
463460
464461// must be called in:
465462// slave rx event callback
466463// or after requestFrom(address, numBytes)
467464int TwoWire::read (void ) {
468- int value = -1 ;
469-
470- // get each successive byte on each call
471- if (rxBufferIndex < rxBufferLength) {
472- value = rxBuffer[rxBufferIndex];
473- ++rxBufferIndex;
474- }
475-
476- return value;
465+ if (rx_ringBuffer.available () == 0 ){
466+ // read from ring buffer
467+ return -1 ;
468+ }
469+ return rx_ringBuffer.read_char ();
477470}
478471
479472// must be called in:
480473// slave rx event callback
481474// or after requestFrom(address, numBytes)
482475int TwoWire::peek (void ) {
483- int value = -1 ;
484-
485- if (rxBufferIndex < rxBufferLength) {
486- value = rxBuffer[rxBufferIndex];
476+ if (rx_ringBuffer.available () == 0 ){
477+ // read from ring buffer
478+ return -1 ;
487479 }
488-
489- return value;
480+ return rx_ringBuffer.peek ();
490481}
491482
492483void TwoWire::flush (void ) {
@@ -502,13 +493,16 @@ void TwoWire::flush(void) {
502493 (void )XMC_I2C_CH_GetReceivedData (XMC_I2C_config->channel );
503494 }
504495 XMC_I2C_CH_ClearStatusFlag (XMC_I2C_config->channel , 0xFFFFFFFF );
496+ rx_ringBuffer.clear ();
497+ tx_ringBuffer.clear ();
498+ pre_rx_ringBuffer.clear ();
505499}
506500
507501// behind the scenes function that is called after each received byte
508502void TwoWire::ReceiveHandler (void ) {
509503 // no stop or read request
510- pre_rxBuffer[pre_rxBufferCount] = XMC_I2C_CH_GetReceivedData (XMC_I2C_config->channel );
511- pre_rxBufferCount++;
504+ pre_rx_ringBuffer. store_char ( XMC_I2C_CH_GetReceivedData (XMC_I2C_config->channel ) );
505+
512506}
513507
514508// behind the scenes function that is called after receiving stop or read request
@@ -537,48 +531,37 @@ void TwoWire::ProtocolHandler(void) {
537531 } else if (flag_status & (uint32_t )XMC_I2C_CH_STATUS_FLAG_SLAVE_READ_REQUESTED) {
538532 XMC_I2C_CH_ClearStatusFlag (XMC_I2C_config->channel ,
539533 XMC_I2C_CH_STATUS_FLAG_SLAVE_READ_REQUESTED);
540- uint8_t numBytes = pre_rxBufferCount;
541-
542- pre_rxBufferCount = 0 ;
543-
544- OnReceiveService (pre_rxBuffer, numBytes);
534+ OnReceiveService ();
545535
546536 OnRequestService ();
547537 } else if (flag_status & (uint32_t )XMC_I2C_CH_STATUS_FLAG_STOP_CONDITION_RECEIVED) {
548538 XMC_I2C_CH_ClearStatusFlag (XMC_I2C_config->channel ,
549539 XMC_I2C_CH_STATUS_FLAG_STOP_CONDITION_RECEIVED);
550- uint8_t numBytes = pre_rxBufferCount;
551-
552- pre_rxBufferCount = 0 ;
553-
554- OnReceiveService (pre_rxBuffer, numBytes);
540+
541+ OnReceiveService ();
555542 }
556543 }
557544}
558545
559546// behind the scenes callback function that is called when a data block is received
560- void TwoWire::OnReceiveService (uint8_t *inBytes, uint8_t numBytes ) {
547+ void TwoWire::OnReceiveService () {
561548 // don't bother if user hasn't registered a callback
562549 if (!user_onReceive) {
563550 return ;
564551 }
565- // don't bother if rx buffer is in use by a master requestFrom() op
566- // i know this drops data, but it allows for slight stupidity
567- // meaning, they may not have read all the master requestFrom() data yet
568- if (rxBufferIndex < rxBufferLength) {
569- return ;
570- }
571-
572- // copy twi rx buffer into local read buffer
573- // this enables new reads to happen in parallel
574- for (uint8_t i = 0 ; i < numBytes; ++i) {
575- rxBuffer[i] = inBytes[i];
552+ while (pre_rx_ringBuffer.available ()) {
553+ // read from pre-receive buffer
554+ if (rx_ringBuffer.availableForStore ()) {
555+ // buffer is full, stop reading
556+ rx_ringBuffer.store_char (pre_rx_ringBuffer.read_char ());
557+ } else {
558+ // buffer is full, stop reading
559+ hasError = true ;
560+ break ;
561+ }
576562 }
577- // set rx iterator vars
578- rxBufferIndex = 0 ;
579- rxBufferLength = numBytes;
580563 // alert user program
581- user_onReceive (numBytes );
564+ user_onReceive (rx_ringBuffer. available () );
582565
583566 /* Flush receive buffer*/
584567 (void )XMC_I2C_CH_GetReceivedData (XMC_I2C_config->channel );
@@ -593,8 +576,7 @@ void TwoWire::OnRequestService(void) {
593576 }
594577 // reset tx buffer iterator vars
595578 // !!! this will kill any pending pre-master sendTo() activity
596- txBufferIndex = 0 ;
597- txBufferLength = 0 ;
579+ tx_ringBuffer.clear ();
598580 // alert user program
599581 user_onRequest ();
600582}
0 commit comments