@@ -67,8 +67,7 @@ void TwoWire::begin(uint8_t address, bool generalCall)
6767 rxBufferAllocated = 0 ;
6868 resetRxBuffer ();
6969
70- txBufferIndex = 0 ;
71- txBufferLength = 0 ;
70+ txDataSize = 0 ;
7271 txAddress = 0 ;
7372 txBuffer = nullptr ;
7473 txBufferAllocated = 0 ;
@@ -125,48 +124,43 @@ uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint32_t iaddres
125124
126125 if (_i2c.isMaster == 1 ) {
127126 allocateRxBuffer (quantity);
128- // error if no memory block available to allocate the buffer
129- if (rxBuffer == nullptr ) {
130- setWriteError ();
131- } else {
132127
133- if (isize > 0 ) {
134- // send internal address; this mode allows sending a repeated start to access
135- // some devices' internal registers. This function is executed by the hardware
136- // TWI module on other processors (for example Due's TWI_IADR and TWI_MMR registers)
128+ if (isize > 0 ) {
129+ // send internal address; this mode allows sending a repeated start to access
130+ // some devices' internal registers. This function is executed by the hardware
131+ // TWI module on other processors (for example Due's TWI_IADR and TWI_MMR registers)
137132
138- beginTransmission (address);
133+ beginTransmission (address);
139134
140- // the maximum size of internal address is 3 bytes
141- if (isize > 3 ) {
142- isize = 3 ;
143- }
135+ // the maximum size of internal address is 3 bytes
136+ if (isize > 3 ) {
137+ isize = 3 ;
138+ }
144139
145- // write internal register address - most significant byte first
146- while (isize-- > 0 ) {
147- write ((uint8_t )(iaddress >> (isize * 8 )));
148- }
149- endTransmission (false );
140+ // write internal register address - most significant byte first
141+ while (isize-- > 0 ) {
142+ write ((uint8_t )(iaddress >> (isize * 8 )));
150143 }
144+ endTransmission (false );
145+ }
151146
152- // perform blocking read into buffer
147+ // perform blocking read into buffer
153148#if defined(I2C_OTHER_FRAME)
154- if (sendStop == 0 ) {
155- _i2c.handle .XferOptions = I2C_OTHER_FRAME ;
156- } else {
157- _i2c.handle .XferOptions = I2C_OTHER_AND_LAST_FRAME;
158- }
149+ if (sendStop == 0 ) {
150+ _i2c.handle .XferOptions = I2C_OTHER_FRAME ;
151+ } else {
152+ _i2c.handle .XferOptions = I2C_OTHER_AND_LAST_FRAME;
153+ }
159154#endif
160155
161- if (I2C_OK == i2c_master_read (&_i2c, address << 1 , rxBuffer, quantity)) {
162- read = quantity;
163- }
156+ if (I2C_OK == i2c_master_read (&_i2c, address << 1 , rxBuffer, quantity)) {
157+ read = quantity;
158+ }
164159
165- // set rx buffer iterator vars
166- rxBufferIndex = 0 ;
167- rxBufferLength = read;
160+ // set rx buffer iterator vars
161+ rxBufferIndex = 0 ;
162+ rxBufferLength = read;
168163
169- }
170164 }
171165 return read;
172166}
@@ -202,9 +196,8 @@ void TwoWire::beginTransmission(uint8_t address)
202196 transmitting = 1 ;
203197 // set address of targeted slave
204198 txAddress = address << 1 ;
205- // reset tx buffer iterator vars
206- txBufferIndex = 0 ;
207- txBufferLength = 0 ;
199+ // reset tx data size
200+ txDataSize = 0 ;
208201}
209202
210203void TwoWire::beginTransmission (int address)
@@ -242,7 +235,7 @@ uint8_t TwoWire::endTransmission(uint8_t sendStop)
242235
243236 if (_i2c.isMaster == 1 ) {
244237 // transmit buffer (blocking)
245- switch (i2c_master_write (&_i2c, txAddress, txBuffer, txBufferLength )) {
238+ switch (i2c_master_write (&_i2c, txAddress, txBuffer, txDataSize )) {
246239 case I2C_OK :
247240 ret = 0 ; // Success
248241 break ;
@@ -266,9 +259,8 @@ uint8_t TwoWire::endTransmission(uint8_t sendStop)
266259 // reset Tx buffer
267260 resetTxBuffer ();
268261
269- // reset tx buffer iterator vars
270- txBufferIndex = 0 ;
271- txBufferLength = 0 ;
262+ // reset tx buffer data size
263+ txDataSize = 0 ;
272264
273265 // indicate that we are done transmitting
274266 transmitting = 0 ;
@@ -292,17 +284,13 @@ size_t TwoWire::write(uint8_t data)
292284 size_t ret = 1 ;
293285 if (transmitting) {
294286 // in master transmitter mode
295- allocateTxBuffer (txBufferLength + 1 );
296- // error if no memory block available to allocate the buffer
297- if (txBuffer == nullptr ) {
298- setWriteError ();
287+ if (allocateTxBuffer (txDataSize + 1 ) == 0 ) {
299288 ret = 0 ;
300289 } else {
301290 // put byte in tx buffer
302- txBuffer[txBufferIndex] = data;
303- ++txBufferIndex;
291+ txBuffer[txDataSize] = data;
304292 // update amount in buffer
305- txBufferLength = txBufferIndex ;
293+ txDataSize++ ;
306294 }
307295 } else {
308296 // in slave send mode
@@ -327,17 +315,14 @@ size_t TwoWire::write(const uint8_t *data, size_t quantity)
327315
328316 if (transmitting) {
329317 // in master transmitter mode
330- allocateTxBuffer (txBufferLength + quantity);
331- // error if no memory block available to allocate the buffer
332- if (txBuffer == nullptr ) {
333- setWriteError ();
318+ if (allocateTxBuffer (txDataSize + quantity) == 0 ) {
334319 ret = 0 ;
335320 } else {
336321 // put bytes in tx buffer
337- memcpy (&(txBuffer[txBufferIndex ]), data, quantity);
338- txBufferIndex = txBufferIndex + quantity;
322+ memcpy (&(txBuffer[txDataSize ]), data, quantity);
323+
339324 // update amount in buffer
340- txBufferLength = txBufferIndex ;
325+ txDataSize += quantity ;
341326 }
342327 } else {
343328 // in slave send mode
@@ -397,8 +382,7 @@ void TwoWire::flush(void)
397382 rxBufferIndex = 0 ;
398383 rxBufferLength = 0 ;
399384 resetRxBuffer ();
400- txBufferIndex = 0 ;
401- txBufferLength = 0 ;
385+ txDataSize = 0 ;
402386 resetTxBuffer ();
403387}
404388
@@ -416,12 +400,7 @@ void TwoWire::onReceiveService(i2c_t *obj)
416400 // i know this drops data, but it allows for slight stupidity
417401 // meaning, they may not have read all the master requestFrom() data yet
418402 if (TW->rxBufferIndex >= TW->rxBufferLength ) {
419-
420403 TW->allocateRxBuffer (numBytes);
421- // error if no memory block available to allocate the buffer
422- if (TW->rxBuffer == nullptr ) {
423- Error_Handler ();
424- }
425404
426405 // copy twi rx buffer into local read buffer
427406 // this enables new reads to happen in parallel
@@ -442,10 +421,9 @@ void TwoWire::onRequestService(i2c_t *obj)
442421
443422 // don't bother if user hasn't registered a callback
444423 if (TW->user_onRequest ) {
445- // reset tx buffer iterator vars
424+ // reset tx data size
446425 // !!! this will kill any pending pre-master sendTo() activity
447- TW->txBufferIndex = 0 ;
448- TW->txBufferLength = 0 ;
426+ TW->txDataSize = 0 ;
449427 // alert user program
450428 TW->user_onRequest ();
451429 }
@@ -485,9 +463,12 @@ void TwoWire::allocateRxBuffer(size_t length)
485463 }
486464}
487465
488- inline void TwoWire::allocateTxBuffer (size_t length)
466+ inline size_t TwoWire::allocateTxBuffer (size_t length)
489467{
490- if (txBufferAllocated < length) {
468+ size_t ret = length;
469+ if (length > WIRE_MAX_TX_BUFF_LENGTH) {
470+ ret = 0 ;
471+ } else if (txBufferAllocated < length) {
491472 // By default we allocate BUFFER_LENGTH bytes. It is the min size of the buffer.
492473 if (length < BUFFER_LENGTH) {
493474 length = BUFFER_LENGTH;
@@ -500,6 +481,7 @@ inline void TwoWire::allocateTxBuffer(size_t length)
500481 _Error_Handler (" No enough memory! (%i)\n " , length);
501482 }
502483 }
484+ return ret;
503485}
504486
505487/* *
0 commit comments