@@ -67,8 +67,7 @@ void TwoWire::begin(uint8_t address, bool generalCall)
67
67
rxBufferAllocated = 0 ;
68
68
resetRxBuffer ();
69
69
70
- txBufferIndex = 0 ;
71
- txBufferLength = 0 ;
70
+ txDataSize = 0 ;
72
71
txAddress = 0 ;
73
72
txBuffer = nullptr ;
74
73
txBufferAllocated = 0 ;
@@ -125,48 +124,43 @@ uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint32_t iaddres
125
124
126
125
if (_i2c.isMaster == 1 ) {
127
126
allocateRxBuffer (quantity);
128
- // error if no memory block available to allocate the buffer
129
- if (rxBuffer == nullptr ) {
130
- setWriteError ();
131
- } else {
132
127
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)
137
132
138
- beginTransmission (address);
133
+ beginTransmission (address);
139
134
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
+ }
144
139
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 )));
150
143
}
144
+ endTransmission (false );
145
+ }
151
146
152
- // perform blocking read into buffer
147
+ // perform blocking read into buffer
153
148
#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
+ }
159
154
#endif
160
155
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
+ }
164
159
165
- // set rx buffer iterator vars
166
- rxBufferIndex = 0 ;
167
- rxBufferLength = read ;
160
+ // set rx buffer iterator vars
161
+ rxBufferIndex = 0 ;
162
+ rxBufferLength = read ;
168
163
169
- }
170
164
}
171
165
return read ;
172
166
}
@@ -202,9 +196,8 @@ void TwoWire::beginTransmission(uint8_t address)
202
196
transmitting = 1 ;
203
197
// set address of targeted slave
204
198
txAddress = address << 1 ;
205
- // reset tx buffer iterator vars
206
- txBufferIndex = 0 ;
207
- txBufferLength = 0 ;
199
+ // reset tx data size
200
+ txDataSize = 0 ;
208
201
}
209
202
210
203
void TwoWire::beginTransmission (int address)
@@ -242,7 +235,7 @@ uint8_t TwoWire::endTransmission(uint8_t sendStop)
242
235
243
236
if (_i2c.isMaster == 1 ) {
244
237
// transmit buffer (blocking)
245
- switch (i2c_master_write (&_i2c, txAddress, txBuffer, txBufferLength )) {
238
+ switch (i2c_master_write (&_i2c, txAddress, txBuffer, txDataSize )) {
246
239
case I2C_OK :
247
240
ret = 0 ; // Success
248
241
break ;
@@ -266,9 +259,8 @@ uint8_t TwoWire::endTransmission(uint8_t sendStop)
266
259
// reset Tx buffer
267
260
resetTxBuffer ();
268
261
269
- // reset tx buffer iterator vars
270
- txBufferIndex = 0 ;
271
- txBufferLength = 0 ;
262
+ // reset tx buffer data size
263
+ txDataSize = 0 ;
272
264
273
265
// indicate that we are done transmitting
274
266
transmitting = 0 ;
@@ -292,17 +284,13 @@ size_t TwoWire::write(uint8_t data)
292
284
size_t ret = 1 ;
293
285
if (transmitting) {
294
286
// 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 ) {
299
288
ret = 0 ;
300
289
} else {
301
290
// put byte in tx buffer
302
- txBuffer[txBufferIndex] = data;
303
- ++txBufferIndex;
291
+ txBuffer[txDataSize] = data;
304
292
// update amount in buffer
305
- txBufferLength = txBufferIndex ;
293
+ txDataSize++ ;
306
294
}
307
295
} else {
308
296
// in slave send mode
@@ -327,17 +315,14 @@ size_t TwoWire::write(const uint8_t *data, size_t quantity)
327
315
328
316
if (transmitting) {
329
317
// 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 ) {
334
319
ret = 0 ;
335
320
} else {
336
321
// put bytes in tx buffer
337
- memcpy (&(txBuffer[txBufferIndex ]), data, quantity);
338
- txBufferIndex = txBufferIndex + quantity;
322
+ memcpy (&(txBuffer[txDataSize ]), data, quantity);
323
+
339
324
// update amount in buffer
340
- txBufferLength = txBufferIndex ;
325
+ txDataSize += quantity ;
341
326
}
342
327
} else {
343
328
// in slave send mode
@@ -397,8 +382,7 @@ void TwoWire::flush(void)
397
382
rxBufferIndex = 0 ;
398
383
rxBufferLength = 0 ;
399
384
resetRxBuffer ();
400
- txBufferIndex = 0 ;
401
- txBufferLength = 0 ;
385
+ txDataSize = 0 ;
402
386
resetTxBuffer ();
403
387
}
404
388
@@ -416,12 +400,7 @@ void TwoWire::onReceiveService(i2c_t *obj)
416
400
// i know this drops data, but it allows for slight stupidity
417
401
// meaning, they may not have read all the master requestFrom() data yet
418
402
if (TW->rxBufferIndex >= TW->rxBufferLength ) {
419
-
420
403
TW->allocateRxBuffer (numBytes);
421
- // error if no memory block available to allocate the buffer
422
- if (TW->rxBuffer == nullptr ) {
423
- Error_Handler ();
424
- }
425
404
426
405
// copy twi rx buffer into local read buffer
427
406
// this enables new reads to happen in parallel
@@ -442,10 +421,9 @@ void TwoWire::onRequestService(i2c_t *obj)
442
421
443
422
// don't bother if user hasn't registered a callback
444
423
if (TW->user_onRequest ) {
445
- // reset tx buffer iterator vars
424
+ // reset tx data size
446
425
// !!! this will kill any pending pre-master sendTo() activity
447
- TW->txBufferIndex = 0 ;
448
- TW->txBufferLength = 0 ;
426
+ TW->txDataSize = 0 ;
449
427
// alert user program
450
428
TW->user_onRequest ();
451
429
}
@@ -485,9 +463,12 @@ void TwoWire::allocateRxBuffer(size_t length)
485
463
}
486
464
}
487
465
488
- inline void TwoWire::allocateTxBuffer (size_t length)
466
+ inline size_t TwoWire::allocateTxBuffer (size_t length)
489
467
{
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) {
491
472
// By default we allocate BUFFER_LENGTH bytes. It is the min size of the buffer.
492
473
if (length < BUFFER_LENGTH) {
493
474
length = BUFFER_LENGTH;
@@ -500,6 +481,7 @@ inline void TwoWire::allocateTxBuffer(size_t length)
500
481
_Error_Handler (" No enough memory! (%i)\n " , length);
501
482
}
502
483
}
484
+ return ret;
503
485
}
504
486
505
487
/* *
0 commit comments