@@ -29,11 +29,13 @@ extern "C" {
29
29
30
30
// Initialize Class Variables //////////////////////////////////////////////////
31
31
uint8_t *TwoWire::rxBuffer = nullptr ;
32
+ uint8_t TwoWire::rxBufferAllocated = 0 ;
32
33
uint8_t TwoWire::rxBufferIndex = 0 ;
33
34
uint8_t TwoWire::rxBufferLength = 0 ;
34
35
35
36
uint8_t TwoWire::txAddress = 0 ;
36
37
uint8_t *TwoWire::txBuffer = nullptr ;
38
+ uint8_t TwoWire::txBufferAllocated = 0 ;
37
39
uint8_t TwoWire::txBufferIndex = 0 ;
38
40
uint8_t TwoWire::txBufferLength = 0 ;
39
41
@@ -66,11 +68,11 @@ void TwoWire::begin(uint8_t address)
66
68
{
67
69
rxBufferIndex = 0 ;
68
70
rxBufferLength = 0 ;
69
- rxBuffer = resetBuffer (rxBuffer );
71
+ resetRxBuffer ( );
70
72
71
73
txBufferIndex = 0 ;
72
74
txBufferLength = 0 ;
73
- txBuffer = resetBuffer (txBuffer );
75
+ resetTxBuffer ( );
74
76
75
77
transmitting = 0 ;
76
78
@@ -101,8 +103,10 @@ void TwoWire::end(void)
101
103
{
102
104
free (txBuffer);
103
105
txBuffer = nullptr ;
106
+ txBufferAllocated = 0 ;
104
107
free (rxBuffer);
105
108
rxBuffer = nullptr ;
109
+ rxBufferAllocated = 0 ;
106
110
i2c_deinit (&_i2c);
107
111
}
108
112
@@ -115,7 +119,7 @@ uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint32_t iaddres
115
119
{
116
120
UNUSED (sendStop);
117
121
if (master == true ) {
118
- rxBuffer = allocateBuffer (rxBuffer, quantity);
122
+ allocateRxBuffer ( quantity);
119
123
// error if no memory block available to allocate the buffer
120
124
if (rxBuffer == nullptr ){
121
125
setWriteError ();
@@ -224,10 +228,8 @@ uint8_t TwoWire::endTransmission(uint8_t sendStop)
224
228
break ;
225
229
}
226
230
227
- // Reduce buffer size to free memory in case of large memory use
228
- if (txBufferLength > BUFFER_LENGTH) {
229
- txBuffer = resetBuffer (txBuffer);
230
- }
231
+ // reset Tx buffer
232
+ resetTxBuffer ();
231
233
232
234
// reset tx buffer iterator vars
233
235
txBufferIndex = 0 ;
@@ -255,7 +257,7 @@ size_t TwoWire::write(uint8_t data)
255
257
{
256
258
if (transmitting){
257
259
// in master transmitter mode
258
- txBuffer = allocateBuffer (txBuffer, txBufferLength + 1 );
260
+ allocateTxBuffer ( txBufferLength + 1 );
259
261
// error if no memory block available to allocate the buffer
260
262
if (txBuffer == nullptr ){
261
263
setWriteError ();
@@ -285,14 +287,20 @@ size_t TwoWire::write(uint8_t data)
285
287
*/
286
288
size_t TwoWire::write (const uint8_t *data, size_t quantity)
287
289
{
288
- size_t nb = 0 ;
289
-
290
290
if (transmitting){
291
291
// in master transmitter mode
292
- for (size_t i = 0 ; i < quantity; ++i){
293
- nb += write (data[i]);
292
+ allocateTxBuffer (txBufferLength + quantity);
293
+ // error if no memory block available to allocate the buffer
294
+ if (txBuffer == nullptr ){
295
+ setWriteError ();
296
+ return 0 ;
294
297
}
295
- return nb;
298
+ // put bytes in tx buffer
299
+ memcpy (&(txBuffer[txBufferIndex]), data, quantity);
300
+ txBufferIndex= txBufferIndex + quantity;
301
+ // update amount in buffer
302
+ txBufferLength = txBufferIndex;
303
+ return quantity;
296
304
}else {
297
305
// in slave send mode
298
306
// reply to master
@@ -323,11 +331,12 @@ int TwoWire::read(void)
323
331
value = rxBuffer[rxBufferIndex];
324
332
++rxBufferIndex;
325
333
326
- /* Reduce buffer size to free memory in case of large memory use when no more
327
- data available */
328
- if ((rxBufferIndex == rxBufferLength) && (rxBufferLength > BUFFER_LENGTH)) {
329
- rxBuffer = resetBuffer (rxBuffer);
330
- }
334
+ /* Commented as not I think it is not useful
335
+ * but kept to show that it is possible to
336
+ * reset rx buffer when no more data available */
337
+ /* if(rxBufferIndex == rxBufferLength) {
338
+ resetRxBuffer();
339
+ }*/
331
340
}
332
341
333
342
return value;
@@ -351,10 +360,10 @@ void TwoWire::flush(void)
351
360
{
352
361
rxBufferIndex = 0 ;
353
362
rxBufferLength = 0 ;
354
- rxBuffer = resetBuffer (rxBuffer );
363
+ resetRxBuffer ( );
355
364
txBufferIndex = 0 ;
356
365
txBufferLength = 0 ;
357
- txBuffer = resetBuffer (txBuffer );
366
+ resetTxBuffer ( );
358
367
}
359
368
360
369
// behind the scenes function that is called when data is received
@@ -373,9 +382,7 @@ void TwoWire::onReceiveService(uint8_t* inBytes, int numBytes)
373
382
}
374
383
// copy twi rx buffer into local read buffer
375
384
// this enables new reads to happen in parallel
376
- for (uint8_t i = 0 ; i < numBytes; ++i){
377
- rxBuffer[i] = inBytes[i];
378
- }
385
+ memcpy (rxBuffer, inBytes, numBytes);
379
386
// set rx iterator vars
380
387
rxBufferIndex = 0 ;
381
388
rxBufferLength = numBytes;
@@ -412,34 +419,41 @@ void TwoWire::onRequest( void (*function)(void) )
412
419
}
413
420
414
421
/* *
415
- * @brief Change the size of the buffer.
416
- * @param buffer: pointer to the allocated buffer
422
+ * @brief Allocate the Rx/Tx buffer to the requested length if needed
423
+ * @note Minimum allocated size is BUFFER_LENGTH)
417
424
* @param length: number of bytes to allocate
418
- * @retval pointer to the new buffer location
419
425
*/
420
- uint8_t * TwoWire::allocateBuffer ( uint8_t *buffer, size_t length)
426
+ inline void TwoWire::allocateRxBuffer ( size_t length)
421
427
{
428
+ if (rxBufferAllocated < length) {
422
429
// By default we allocate BUFFER_LENGTH bytes. It is the min size of the buffer.
423
- if (length < BUFFER_LENGTH) {
424
- length = BUFFER_LENGTH;
430
+ if (length < BUFFER_LENGTH) { length = BUFFER_LENGTH; }
431
+ rxBuffer = (uint8_t *)realloc (rxBuffer, length * sizeof (uint8_t ));
432
+ rxBufferAllocated = (rxBuffer != nullptr ) ? length: 0 ;
425
433
}
434
+ }
426
435
427
- buffer = (uint8_t *)realloc (buffer, length * sizeof (uint8_t ));
428
- return buffer;
436
+ inline void TwoWire::allocateTxBuffer (size_t length)
437
+ {
438
+ if (txBufferAllocated < length) {
439
+ // By default we allocate BUFFER_LENGTH bytes. It is the min size of the buffer.
440
+ if (length < BUFFER_LENGTH) { length = BUFFER_LENGTH; }
441
+ txBuffer = (uint8_t *)realloc (txBuffer, length * sizeof (uint8_t ));
442
+ txBufferAllocated = (txBuffer != nullptr ) ? length: 0 ;
443
+ }
429
444
}
430
445
431
446
/* *
432
- * @brief Reset the buffer. Reduce its size to BUFFER_LENGTH.
433
- * @param buffer: pointer to the allocated buffer
434
- * @retval pointer to the new buffer location
447
+ * @brief Reset Rx/Tx buffer content to 0
435
448
*/
436
- uint8_t * TwoWire::resetBuffer ( uint8_t *buffer )
449
+ inline void TwoWire::resetRxBuffer ( void )
437
450
{
438
- buffer = (uint8_t *)realloc (buffer, BUFFER_LENGTH * sizeof (uint8_t ));
439
- if (buffer != nullptr ) {
440
- memset (buffer, 0 , BUFFER_LENGTH);
441
- }
442
- return buffer;
451
+ if (rxBuffer != nullptr ) memset (rxBuffer, 0 , rxBufferAllocated);
452
+ }
453
+
454
+ inline void TwoWire::resetTxBuffer (void )
455
+ {
456
+ if (txBuffer != nullptr ) memset (txBuffer, 0 , txBufferAllocated);
443
457
}
444
458
445
459
// Preinstantiate Objects //////////////////////////////////////////////////////
0 commit comments