From b07c7f10d8a1ef0f24d636a6ccb740ec4e42271a Mon Sep 17 00:00:00 2001 From: Donna Whisnant Date: Fri, 30 Dec 2022 16:57:38 -0600 Subject: [PATCH] Don't waste RAM in the low-level TWI Wire drivers. Since twi_readFrom() and twi_writeTo() are both blocking functions, there is no need to allocate a special twi_masterBuffer. Doing so wastes valuable RAM, uses extra time to copy the data to the secondary buffer, and limits the transfer size to TWI_BUFFER_SIZE. Instead, it only needs a pointer to the buffer for the IRQ to use for the transfer. And, if asynchronous non-blocking functions are ever added, which will require a different API and callbacks, etc., then the existing txBuffer and rxBuffer for slave mode can just be used there too, since master mode and slave mode can't both be active at the same time. --- avr/libraries/Wire/src/utility/twi.c | 18 +++--------------- avr/libraries/Wire1/src/utility/twi1.c | 18 +++--------------- 2 files changed, 6 insertions(+), 30 deletions(-) diff --git a/avr/libraries/Wire/src/utility/twi.c b/avr/libraries/Wire/src/utility/twi.c index 7bca1905..1e4b7916 100755 --- a/avr/libraries/Wire/src/utility/twi.c +++ b/avr/libraries/Wire/src/utility/twi.c @@ -59,7 +59,7 @@ static volatile bool twi_do_reset_on_timeout = false; // reset the TWI register static void (*twi_onSlaveTransmit)(void); static void (*twi_onSlaveReceive)(uint8_t*, int); -static uint8_t twi_masterBuffer[TWI_BUFFER_SIZE]; +static uint8_t *twi_masterBuffer; static volatile uint8_t twi_masterBufferIndex; static volatile uint8_t twi_masterBufferLength; @@ -159,8 +159,6 @@ void twi_setFrequency(uint32_t frequency) */ uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sendStop) { - uint8_t i; - // ensure data will fit into buffer if(TWI_BUFFER_SIZE < length){ return 0; @@ -186,6 +184,7 @@ uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sen twi_error = 0xFF; // initialize buffer iteration vars + twi_masterBuffer = data; twi_masterBufferIndex = 0; twi_masterBufferLength = length-1; // This is not intuitive, read on... // On receive, the previously configured ACK/NACK setting is transmitted in @@ -244,11 +243,6 @@ uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sen if (twi_masterBufferIndex < length) length = twi_masterBufferIndex; - // copy twi buffer to data - for(i = 0; i < length; ++i){ - data[i] = twi_masterBuffer[i]; - } - return length; } @@ -270,8 +264,6 @@ uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sen */ uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait, uint8_t sendStop) { - uint8_t i; - // ensure data will fit into buffer if(TWI_BUFFER_SIZE < length){ return 1; @@ -298,14 +290,10 @@ uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait twi_error = 0xFF; // initialize buffer iteration vars + twi_masterBuffer = data; twi_masterBufferIndex = 0; twi_masterBufferLength = length; - // copy data to twi buffer - for(i = 0; i < length; ++i){ - twi_masterBuffer[i] = data[i]; - } - // build sla+w, slave device address + w bit twi_slarw = TW_WRITE; twi_slarw |= address << 1; diff --git a/avr/libraries/Wire1/src/utility/twi1.c b/avr/libraries/Wire1/src/utility/twi1.c index 57a9cf6e..1d0f4045 100755 --- a/avr/libraries/Wire1/src/utility/twi1.c +++ b/avr/libraries/Wire1/src/utility/twi1.c @@ -46,7 +46,7 @@ static volatile uint8_t twi_inRepStart; // in the middle of a repeated start static void (*twi_onSlaveTransmit)(void); static void (*twi_onSlaveReceive)(uint8_t*, int); -static uint8_t twi_masterBuffer[TWI1_BUFFER_SIZE]; +static uint8_t *twi_masterBuffer; static volatile uint8_t twi_masterBufferIndex; static volatile uint8_t twi_masterBufferLength; @@ -146,8 +146,6 @@ void twi_setFrequency1(uint32_t frequency) */ uint8_t twi_readFrom1(uint8_t address, uint8_t* data, uint8_t length, uint8_t sendStop) { - uint8_t i; - // ensure data will fit into buffer if(TWI1_BUFFER_SIZE < length){ return 0; @@ -163,6 +161,7 @@ uint8_t twi_readFrom1(uint8_t address, uint8_t* data, uint8_t length, uint8_t se twi_error = 0xFF; // initialize buffer iteration vars + twi_masterBuffer = data; twi_masterBufferIndex = 0; twi_masterBufferLength = length-1; // This is not intuitive, read on... // On receive, the previously configured ACK/NACK setting is transmitted in @@ -200,11 +199,6 @@ uint8_t twi_readFrom1(uint8_t address, uint8_t* data, uint8_t length, uint8_t se if (twi_masterBufferIndex < length) length = twi_masterBufferIndex; - // copy twi buffer to data - for(i = 0; i < length; ++i){ - data[i] = twi_masterBuffer[i]; - } - return length; } @@ -225,8 +219,6 @@ uint8_t twi_readFrom1(uint8_t address, uint8_t* data, uint8_t length, uint8_t se */ uint8_t twi_writeTo1(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait, uint8_t sendStop) { - uint8_t i; - // ensure data will fit into buffer if(TWI1_BUFFER_SIZE < length){ return 1; @@ -242,14 +234,10 @@ uint8_t twi_writeTo1(uint8_t address, uint8_t* data, uint8_t length, uint8_t wai twi_error = 0xFF; // initialize buffer iteration vars + twi_masterBuffer = data; twi_masterBufferIndex = 0; twi_masterBufferLength = length; - // copy data to twi buffer - for(i = 0; i < length; ++i){ - twi_masterBuffer[i] = data[i]; - } - // build sla+w, slave device address + w bit twi_slarw = TW_WRITE; twi_slarw |= address << 1;