Skip to content

Commit c4b9f24

Browse files
committed
Enhance I2C buffer usage
Assume that user will probably use more than one time I2C size. write: avoid copy byte/byte in the buffer Signed-off-by: Frederic.Pillon <[email protected]>
1 parent dce90e5 commit c4b9f24

File tree

2 files changed

+75
-28
lines changed

2 files changed

+75
-28
lines changed

libraries/Wire/src/Wire.cpp

+67-25
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,13 @@ extern "C" {
2929

3030
// Initialize Class Variables //////////////////////////////////////////////////
3131
uint8_t *TwoWire::rxBuffer = nullptr;
32+
uint8_t TwoWire::rxBufferAllocated = 0;
3233
uint8_t TwoWire::rxBufferIndex = 0;
3334
uint8_t TwoWire::rxBufferLength = 0;
3435

3536
uint8_t TwoWire::txAddress = 0;
3637
uint8_t *TwoWire::txBuffer = nullptr;
38+
uint8_t TwoWire::txBufferAllocated = 0;
3739
uint8_t TwoWire::txBufferIndex = 0;
3840
uint8_t TwoWire::txBufferLength = 0;
3941

@@ -66,11 +68,11 @@ void TwoWire::begin(uint8_t address)
6668
{
6769
rxBufferIndex = 0;
6870
rxBufferLength = 0;
69-
rxBuffer = resetBuffer(rxBuffer);
71+
resetRxBuffer();
7072

7173
txBufferIndex = 0;
7274
txBufferLength = 0;
73-
txBuffer = resetBuffer(txBuffer);
75+
resetTxBuffer();
7476

7577
transmitting = 0;
7678

@@ -101,8 +103,10 @@ void TwoWire::end(void)
101103
{
102104
free(txBuffer);
103105
txBuffer = nullptr;
106+
txBufferAllocated = 0;
104107
free(rxBuffer);
105108
rxBuffer = nullptr;
109+
rxBufferAllocated = 0;
106110
i2c_deinit(&_i2c);
107111
}
108112

@@ -115,7 +119,7 @@ uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint32_t iaddres
115119
{
116120
UNUSED(sendStop);
117121
if (master == true) {
118-
rxBuffer = allocateBuffer(rxBuffer, quantity);
122+
allocateRxBuffer(quantity);
119123
// error if no memory block available to allocate the buffer
120124
if(rxBuffer == nullptr){
121125
setWriteError();
@@ -225,9 +229,7 @@ uint8_t TwoWire::endTransmission(uint8_t sendStop)
225229
}
226230

227231
//Reduce buffer size to free memory in case of large memory use
228-
if(txBufferLength > BUFFER_LENGTH) {
229-
txBuffer = resetBuffer(txBuffer);
230-
}
232+
resetTxBuffer();
231233

232234
// reset tx buffer iterator vars
233235
txBufferIndex = 0;
@@ -255,7 +257,7 @@ size_t TwoWire::write(uint8_t data)
255257
{
256258
if(transmitting){
257259
// in master transmitter mode
258-
txBuffer = allocateBuffer(txBuffer, txBufferLength + 1);
260+
allocateTxBuffer(txBufferLength + 1);
259261
// error if no memory block available to allocate the buffer
260262
if(txBuffer == nullptr){
261263
setWriteError();
@@ -285,14 +287,22 @@ size_t TwoWire::write(uint8_t data)
285287
*/
286288
size_t TwoWire::write(const uint8_t *data, size_t quantity)
287289
{
288-
size_t nb = 0;
290+
//size_t nb = 0;
289291

290292
if(transmitting){
291293
// in master transmitter mode
292-
for(size_t i = 0; i < quantity; ++i){
293-
nb += write(data[i]);
294+
allocateTxBuffer(txBufferLength + quantity);
295+
// error if no memory block available to allocate the buffer
296+
if(txBuffer == nullptr){
297+
setWriteError();
298+
return 0;
294299
}
295-
return nb;
300+
// put bytes in tx buffer
301+
memcpy(&(txBuffer[txBufferIndex]), data, quantity);
302+
txBufferIndex= txBufferIndex + quantity;
303+
// update amount in buffer
304+
txBufferLength = txBufferIndex;
305+
return quantity;
296306
}else{
297307
// in slave send mode
298308
// reply to master
@@ -326,7 +336,7 @@ int TwoWire::read(void)
326336
/* Reduce buffer size to free memory in case of large memory use when no more
327337
data available */
328338
if((rxBufferIndex == rxBufferLength) && (rxBufferLength > BUFFER_LENGTH)) {
329-
rxBuffer = resetBuffer(rxBuffer);
339+
resetRxBuffer();
330340
}
331341
}
332342

@@ -351,10 +361,10 @@ void TwoWire::flush(void)
351361
{
352362
rxBufferIndex = 0;
353363
rxBufferLength = 0;
354-
rxBuffer = resetBuffer(rxBuffer);
364+
resetRxBuffer();
355365
txBufferIndex = 0;
356366
txBufferLength = 0;
357-
txBuffer = resetBuffer(txBuffer);
367+
resetTxBuffer();
358368
}
359369

360370
// behind the scenes function that is called when data is received
@@ -417,29 +427,61 @@ void TwoWire::onRequest( void (*function)(void) )
417427
* @param length: number of bytes to allocate
418428
* @retval pointer to the new buffer location
419429
*/
420-
uint8_t *TwoWire::allocateBuffer(uint8_t *buffer, size_t length)
430+
void TwoWire::allocateRxBuffer(size_t length)
421431
{
422-
// By default we allocate BUFFER_LENGTH bytes. It is the min size of the buffer.
423-
if(length < BUFFER_LENGTH) {
424-
length = BUFFER_LENGTH;
432+
if(rxBufferAllocated < length) {
433+
// By default we allocate BUFFER_LENGTH bytes. It is the min size of the buffer.
434+
if(length < BUFFER_LENGTH) {
435+
length = BUFFER_LENGTH;
436+
}
437+
rxBuffer = (uint8_t *)realloc(rxBuffer, length * sizeof(uint8_t));
438+
rxBufferAllocated = length;
425439
}
440+
}
426441

427-
buffer = (uint8_t *)realloc(buffer, length * sizeof(uint8_t));
428-
return buffer;
442+
void TwoWire::allocateTxBuffer(size_t length)
443+
{
444+
if(txBufferAllocated < length) {
445+
// By default we allocate BUFFER_LENGTH bytes. It is the min size of the buffer.
446+
if(length < BUFFER_LENGTH) {
447+
length = BUFFER_LENGTH;
448+
}
449+
txBuffer = (uint8_t *)realloc(txBuffer, length * sizeof(uint8_t));
450+
txBufferAllocated = length;
451+
}
429452
}
430453

431454
/**
432455
* @brief Reset the buffer. Reduce is size if greater than BUFFER_LENGTH.
433456
* @param buffer: pointer to the allocated buffer
434457
* @retval pointer to the new buffer location
435458
*/
436-
uint8_t *TwoWire::resetBuffer(uint8_t *buffer)
459+
void TwoWire::resetRxBuffer(void)
437460
{
438-
buffer = (uint8_t *)realloc(buffer, BUFFER_LENGTH * sizeof(uint8_t));
439-
if(buffer != nullptr) {
440-
memset(buffer, 0, BUFFER_LENGTH);
461+
if(rxBufferAllocated != BUFFER_LENGTH) {
462+
rxBuffer = (uint8_t *)realloc(rxBuffer, BUFFER_LENGTH * sizeof(uint8_t));
463+
if(rxBuffer != nullptr) {
464+
memset(rxBuffer, 0, BUFFER_LENGTH);
465+
rxBufferAllocated = BUFFER_LENGTH;
466+
}
467+
else {
468+
rxBufferAllocated = 0;
469+
}
470+
}
471+
}
472+
473+
void TwoWire::resetTxBuffer(void)
474+
{
475+
if(txBufferAllocated != BUFFER_LENGTH) {
476+
txBuffer = (uint8_t *)realloc(txBuffer, BUFFER_LENGTH * sizeof(uint8_t));
477+
if(txBuffer != nullptr) {
478+
memset(txBuffer, 0, BUFFER_LENGTH);
479+
txBufferAllocated = BUFFER_LENGTH;
480+
}
481+
else {
482+
txBufferAllocated = 0;
483+
}
441484
}
442-
return buffer;
443485
}
444486

445487
// Preinstantiate Objects //////////////////////////////////////////////////////

libraries/Wire/src/Wire.h

+8-3
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,13 @@ class TwoWire : public Stream
3737
{
3838
private:
3939
static uint8_t *rxBuffer;
40+
static uint8_t rxBufferAllocated;
4041
static uint8_t rxBufferIndex;
4142
static uint8_t rxBufferLength;
4243

4344
static uint8_t txAddress;
4445
static uint8_t *txBuffer;
46+
static uint8_t txBufferAllocated;
4547
static uint8_t txBufferIndex;
4648
static uint8_t txBufferLength;
4749

@@ -56,8 +58,11 @@ class TwoWire : public Stream
5658
static void onRequestService(void);
5759
static void onReceiveService(uint8_t*, int);
5860

59-
uint8_t *allocateBuffer(uint8_t *buffer, size_t length);
60-
uint8_t *resetBuffer(uint8_t *buffer);
61+
void allocateRxBuffer(size_t length);
62+
void allocateTxBuffer(size_t length);
63+
void resetRxBuffer(void);
64+
void resetTxBuffer(void);
65+
6166

6267
public:
6368
TwoWire();
@@ -73,7 +78,7 @@ class TwoWire : public Stream
7378
uint8_t endTransmission(uint8_t);
7479
uint8_t requestFrom(uint8_t, uint8_t);
7580
uint8_t requestFrom(uint8_t, uint8_t, uint8_t);
76-
uint8_t requestFrom(uint8_t, uint8_t, uint32_t, uint8_t, uint8_t);
81+
uint8_t requestFrom(uint8_t, uint8_t, uint32_t, uint8_t, uint8_t);
7782
uint8_t requestFrom(int, int);
7883
uint8_t requestFrom(int, int, int);
7984
virtual size_t write(uint8_t);

0 commit comments

Comments
 (0)