From dac910e5cc5224bdd28c25a548c0ea95c56c6ed6 Mon Sep 17 00:00:00 2001 From: dac1e Date: Tue, 31 Dec 2024 14:54:46 +0100 Subject: [PATCH 01/17] Make functions that just do a parameter cast inline. Use C++ static_cast operator instead of C cast operator. Use constexpr for TWI_CLOCK, RECV_TIMEOUT and XMIT_TIMEOUT. --- libraries/Wire/src/Wire.cpp | 20 ------------------ libraries/Wire/src/Wire.h | 42 ++++++++++++++++++++++++------------- 2 files changed, 27 insertions(+), 35 deletions(-) diff --git a/libraries/Wire/src/Wire.cpp b/libraries/Wire/src/Wire.cpp index 2cb7dfe2..893e83fb 100644 --- a/libraries/Wire/src/Wire.cpp +++ b/libraries/Wire/src/Wire.cpp @@ -172,22 +172,6 @@ uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint32_t iaddres return readed; } -uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop) { - return requestFrom((uint8_t) address, (uint8_t) quantity, (uint32_t) 0, (uint8_t) 0, (uint8_t) sendStop); -} - -uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity) { - return requestFrom((uint8_t) address, (uint8_t) quantity, (uint8_t) true); -} - -uint8_t TwoWire::requestFrom(int address, int quantity) { - return requestFrom((uint8_t) address, (uint8_t) quantity, (uint8_t) true); -} - -uint8_t TwoWire::requestFrom(int address, int quantity, int sendStop) { - return requestFrom((uint8_t) address, (uint8_t) quantity, (uint8_t) sendStop); -} - void TwoWire::beginTransmission(uint8_t address) { status = MASTER_SEND; @@ -196,10 +180,6 @@ void TwoWire::beginTransmission(uint8_t address) { txBufferLength = 0; } -void TwoWire::beginTransmission(int address) { - beginTransmission((uint8_t) address); -} - // // Originally, 'endTransmission' was an f(void) function. // It has been modified to take one parameter indicating diff --git a/libraries/Wire/src/Wire.h b/libraries/Wire/src/Wire.h index 3913c983..ab4d4c55 100644 --- a/libraries/Wire/src/Wire.h +++ b/libraries/Wire/src/Wire.h @@ -41,14 +41,26 @@ class TwoWire : public Stream { void end(); void setClock(uint32_t); void beginTransmission(uint8_t); - void beginTransmission(int); + inline void beginTransmission(int address) {beginTransmission(static_cast(address));} uint8_t endTransmission(void); - uint8_t endTransmission(uint8_t); - uint8_t requestFrom(uint8_t, uint8_t); - uint8_t requestFrom(uint8_t, uint8_t, uint8_t); - uint8_t requestFrom(uint8_t, uint8_t, uint32_t, uint8_t, uint8_t); - uint8_t requestFrom(int, int); - uint8_t requestFrom(int, int, int); + uint8_t endTransmission(uint8_t); + uint8_t requestFrom(uint8_t, uint8_t, uint32_t, uint8_t, uint8_t); + inline uint8_t requestFrom(uint8_t address, uint8_t quantity) { + return requestFrom(static_cast(address), static_cast(quantity), + static_cast(true)); + } + inline uint8_t requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop) { + return requestFrom(static_cast(address), static_cast(quantity), + static_cast(0), static_cast(0), static_cast(sendStop)); + } + inline uint8_t requestFrom(int address, int quantity) { + return requestFrom(static_cast(address), static_cast(quantity), + static_cast(true)); + } + inline uint8_t requestFrom(int address, int quantity, int sendStop) { + return requestFrom(static_cast(address), static_cast(quantity), + static_cast(sendStop)); + } virtual size_t write(uint8_t); virtual size_t write(const uint8_t *, size_t); virtual int available(void); @@ -58,11 +70,11 @@ class TwoWire : public Stream { void onReceive(void(*)(int)); void onRequest(void(*)(void)); - inline size_t write(unsigned long n) { return write((uint8_t)n); } - inline size_t write(long n) { return write((uint8_t)n); } - inline size_t write(unsigned int n) { return write((uint8_t)n); } - inline size_t write(int n) { return write((uint8_t)n); } - using Print::write; + inline size_t write(unsigned long n) { return write(static_cast(n)); } + inline size_t write(long n) { return write(static_cast(n)); } + inline size_t write(unsigned int n) { return write(static_cast(n)); } + inline size_t write(int n) { return write(static_cast(n)); } + using Print::write; void onService(void); @@ -108,12 +120,12 @@ class TwoWire : public Stream { TwoWireStatus status; // TWI clock frequency - static const uint32_t TWI_CLOCK = 100000; + static constexpr uint32_t TWI_CLOCK = 100000; uint32_t twiClock; // Timeouts ( - static const uint32_t RECV_TIMEOUT = 100000; - static const uint32_t XMIT_TIMEOUT = 100000; + static constexpr uint32_t RECV_TIMEOUT = 100000; + static constexpr uint32_t XMIT_TIMEOUT = 100000; }; #if WIRE_INTERFACES_COUNT > 0 From dd707d2f6c99282c36738dc0c9fd4c53e5058c4a Mon Sep 17 00:00:00 2001 From: dac1e Date: Tue, 31 Dec 2024 15:03:14 +0100 Subject: [PATCH 02/17] Added TwoWireBuffers.cpp and TwoWireBuffers.h. --- libraries/Wire/src/TwoWireBuffers.cpp | 29 +++++++ libraries/Wire/src/TwoWireBuffers.h | 119 ++++++++++++++++++++++++++ 2 files changed, 148 insertions(+) create mode 100644 libraries/Wire/src/TwoWireBuffers.cpp create mode 100644 libraries/Wire/src/TwoWireBuffers.h diff --git a/libraries/Wire/src/TwoWireBuffers.cpp b/libraries/Wire/src/TwoWireBuffers.cpp new file mode 100644 index 00000000..3c5edcb3 --- /dev/null +++ b/libraries/Wire/src/TwoWireBuffers.cpp @@ -0,0 +1,29 @@ +/* + twi.c - TWI/I2C library for Wiring & Arduino + Copyright (c) 2006 Nicholas Zambetti. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "TwoWireBuffers.h" + + +constexpr size_t RX_BUFFER_DEFAULT_LENGTH = 32; +constexpr size_t TX_BUFFER_DEFAULT_LENGTH = 32; + +// Default buffers for the one and only Wire object +namespace WireBuffers { + __attribute__((weak)) SET_BUFFERS_FOR_BOTH(RX_BUFFER_DEFAULT_LENGTH, TX_BUFFER_DEFAULT_LENGTH); +} // namespace Twi diff --git a/libraries/Wire/src/TwoWireBuffers.h b/libraries/Wire/src/TwoWireBuffers.h new file mode 100644 index 00000000..efe11e59 --- /dev/null +++ b/libraries/Wire/src/TwoWireBuffers.h @@ -0,0 +1,119 @@ +/* + twi.h - TWI/I2C library for Wiring & Arduino + Copyright (c) 2006 Nicholas Zambetti. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Modified 2020 by Greyson Christoforo (grey@christoforo.net) to implement timeouts +*/ + +#pragma once + +#ifndef TwiBuffers_h +#define TwiBuffers_h + +#include +#include + +namespace TwoWireBuffers { + +/* Template class that implements an compile time fixed size array. */ +template +class StaticBuffer { + uint8_t mByteArray[CAPACITY]; +public: + inline uint8_t capacity() const {return CAPACITY;} + inline uint8_t* storage() {return mByteArray;} +}; + +/* Specialization of StaticBuffer template class with zero size. */ +template<> +class StaticBuffer<0> { +public: + inline uint8_t capacity() const {return 0;} + inline uint8_t* storage() {return nullptr;} +}; + + +/* Interface that provides buffers for twi driver and TwoWire objects */ +class Interface { +public: + virtual uint8_t* rxWireBuffer() = 0; + virtual size_t rxWireBufferCapacity() = 0; + + virtual uint8_t* txWireBuffer() = 0; + virtual size_t txWireBufferCapacity() = 0; + + virtual uint8_t* srvWireBuffer() = 0; + virtual size_t srvWireBufferCapacity() = 0; +}; + +/* Template class implementing Interface with template parameter + * determined buffer sizes. + */ +template< + size_t RX_CAPACITY, // Receive buffer size. May be zero, if only transmitting data is needed + size_t TX_CAPACITY, // Transmit buffer size. May be zero, if only receiving data is needed + bool ENABLE_MASTER, // If master is disabled, it will save twi master buffer space + bool ENABLE_SLAVE // If slave is disabled, it will save twi slave buffer space + > +class Impl : public Interface { + static_assert(ENABLE_MASTER == true || ENABLE_SLAVE == true, + "You should not disable master and slave together."); + + static constexpr size_t SRV_CAPACITY = + RX_CAPACITY > TX_CAPACITY ? RX_CAPACITY : TX_CAPACITY; + + // Set the capacity for a TwoWire object. + TwoWireBuffers::StaticBuffer mRxWireBuffer; + TwoWireBuffers::StaticBuffer mTxWireBuffer; + TwoWireBuffers::StaticBuffer mSrvWireBuffer; + +public: + virtual uint8_t* rxWireBuffer() override {return mRxWireBuffer.storage();} + virtual size_t rxWireBufferCapacity() override {return mRxWireBuffer.capacity();} + + virtual uint8_t* txWireBuffer() override {return mTxWireBuffer.storage();} + virtual size_t txWireBufferCapacity() override {return mTxWireBuffer.capacity();} + + virtual uint8_t* srvWireBuffer() override {return mSrvWireBuffer.storage();} + virtual size_t srvWireBufferCapacity() override {return mSrvWireBuffer.capacity();} +}; + +} // namespace TwoWireBuffers + +namespace WireBuffers { // The buffers for the one and only Wire object + extern TwoWireBuffers::Interface& instance(); +} + +#define SET_BUFFERS_FOR_MASTER_ONLY(RX_BUFFER_CAPACITY, TX_BUFFER_CAPACITY) \ + TwoWireBuffers::Interface& instance() { \ + static TwoWireBuffers::Impl instance; \ + return instance; \ + } + +#define SET_BUFFERS_FOR_SLAVE_ONLY(RX_BUFFER_CAPACITY, TX_BUFFER_CAPACITY) \ + TwoWireBuffers::Interface& instance() { \ + static TwoWireBuffers::Impl instance; \ + return instance; \ + } + +#define SET_BUFFERS_FOR_BOTH(RX_BUFFER_CAPACITY, TX_BUFFER_CAPACITY) \ + TwoWireBuffers::Interface& instance() { \ + static TwoWireBuffers::Impl instance; \ + return instance; \ + } + +#endif /* TwiBuffers_h */ From 289a181a73ec26de56b5bfcfcac47d635a6bf1bc Mon Sep 17 00:00:00 2001 From: dac1e Date: Tue, 31 Dec 2024 15:52:54 +0100 Subject: [PATCH 03/17] Use TwoWireBuffers in Wire class. --- libraries/Wire/src/TwoWireBuffers.cpp | 13 +++++- libraries/Wire/src/TwoWireBuffers.h | 34 +++++--------- libraries/Wire/src/Wire.cpp | 67 +++++++++++++++++---------- libraries/Wire/src/Wire.h | 25 +++++++--- 4 files changed, 84 insertions(+), 55 deletions(-) diff --git a/libraries/Wire/src/TwoWireBuffers.cpp b/libraries/Wire/src/TwoWireBuffers.cpp index 3c5edcb3..b070504e 100644 --- a/libraries/Wire/src/TwoWireBuffers.cpp +++ b/libraries/Wire/src/TwoWireBuffers.cpp @@ -18,12 +18,21 @@ */ #include "TwoWireBuffers.h" - +#include "variant.h" constexpr size_t RX_BUFFER_DEFAULT_LENGTH = 32; constexpr size_t TX_BUFFER_DEFAULT_LENGTH = 32; -// Default buffers for the one and only Wire object +#if WIRE_INTERFACES_COUNT > 0 +// Default buffers for the Wire object namespace WireBuffers { __attribute__((weak)) SET_BUFFERS_FOR_BOTH(RX_BUFFER_DEFAULT_LENGTH, TX_BUFFER_DEFAULT_LENGTH); } // namespace Twi +#endif + +#if WIRE_INTERFACES_COUNT > 1 +// Default buffers for the Wire1 object +namespace Wire1Buffers { + __attribute__((weak)) SET_BUFFERS_FOR_BOTH(RX_BUFFER_DEFAULT_LENGTH, TX_BUFFER_DEFAULT_LENGTH); +} // namespace Twi +#endif diff --git a/libraries/Wire/src/TwoWireBuffers.h b/libraries/Wire/src/TwoWireBuffers.h index efe11e59..4ab6bf10 100644 --- a/libraries/Wire/src/TwoWireBuffers.h +++ b/libraries/Wire/src/TwoWireBuffers.h @@ -65,14 +65,10 @@ class Interface { */ template< size_t RX_CAPACITY, // Receive buffer size. May be zero, if only transmitting data is needed - size_t TX_CAPACITY, // Transmit buffer size. May be zero, if only receiving data is needed - bool ENABLE_MASTER, // If master is disabled, it will save twi master buffer space - bool ENABLE_SLAVE // If slave is disabled, it will save twi slave buffer space + size_t TX_CAPACITY // Transmit buffer size. May be zero, if only receiving data is needed > class Impl : public Interface { - static_assert(ENABLE_MASTER == true || ENABLE_SLAVE == true, - "You should not disable master and slave together."); - + // Service buffer is neede for transmit and receive. static constexpr size_t SRV_CAPACITY = RX_CAPACITY > TX_CAPACITY ? RX_CAPACITY : TX_CAPACITY; @@ -94,26 +90,18 @@ class Impl : public Interface { } // namespace TwoWireBuffers -namespace WireBuffers { // The buffers for the one and only Wire object - extern TwoWireBuffers::Interface& instance(); -} - -#define SET_BUFFERS_FOR_MASTER_ONLY(RX_BUFFER_CAPACITY, TX_BUFFER_CAPACITY) \ - TwoWireBuffers::Interface& instance() { \ - static TwoWireBuffers::Impl instance; \ - return instance; \ - } - -#define SET_BUFFERS_FOR_SLAVE_ONLY(RX_BUFFER_CAPACITY, TX_BUFFER_CAPACITY) \ - TwoWireBuffers::Interface& instance() { \ - static TwoWireBuffers::Impl instance; \ - return instance; \ - } - #define SET_BUFFERS_FOR_BOTH(RX_BUFFER_CAPACITY, TX_BUFFER_CAPACITY) \ TwoWireBuffers::Interface& instance() { \ - static TwoWireBuffers::Impl instance; \ + static TwoWireBuffers::Impl instance; \ return instance; \ } +// This macro is just for compatibility reasons with AVR core +#define SET_BUFFERS_FOR_MASTER_ONLY(RX_BUFFER_CAPACITY, TX_BUFFER_CAPACITY) \ + SET_BUFFERS_FOR_BOTH(RX_BUFFER_CAPACITY, TX_BUFFER_CAPACITY) + +// This macro is just for compatibility reasons with AVR core +#define SET_BUFFERS_FOR_SLAVE_ONLY(RX_BUFFER_CAPACITY, TX_BUFFER_CAPACITY) \ + SET_BUFFERS_FOR_BOTH(RX_BUFFER_CAPACITY, TX_BUFFER_CAPACITY) + #endif /* TwiBuffers_h */ diff --git a/libraries/Wire/src/Wire.cpp b/libraries/Wire/src/Wire.cpp index 893e83fb..9c84f585 100644 --- a/libraries/Wire/src/Wire.cpp +++ b/libraries/Wire/src/Wire.cpp @@ -27,6 +27,7 @@ extern "C" { } #include "Wire.h" +#include "TwoWireBuffers.h" static inline bool TWI_FailedAcknowledge(Twi *pTwi) { return pTwi->TWI_SR & TWI_SR_NACK; @@ -96,13 +97,20 @@ static inline bool TWI_STATUS_NACK(uint32_t status) { return (status & TWI_SR_NACK) == TWI_SR_NACK; } -TwoWire::TwoWire(Twi *_twi, void(*_beginCb)(void), void(*_endCb)(void)) : - twi(_twi), rxBufferIndex(0), rxBufferLength(0), txAddress(0), +TwoWire::TwoWire(TwoWireBuffers::Interface& _twbi, Twi *_twi, void(*_beginCb)(void), void(*_endCb)(void)) : + buffers(_twbi), twi(_twi), rxBufferIndex(0), rxBufferLength(0), txAddress(0), txBufferLength(0), srvBufferIndex(0), srvBufferLength(0), status( UNINITIALIZED), onBeginCallback(_beginCb), onEndCallback(_endCb), twiClock(TWI_CLOCK) { } +uint8_t* TwoWire::srvBuffer()const {return buffers.srvWireBuffer();} +size_t TwoWire::srvBufferCapacity()const {return buffers.srvWireBufferCapacity();} +uint8_t* TwoWire::rxBuffer()const {return buffers.rxWireBuffer();} +size_t TwoWire::rxBufferCapacity()const {return buffers.rxWireBufferCapacity();} +uint8_t* TwoWire::txBuffer()const {return buffers.txWireBuffer();} +size_t TwoWire::txBufferCapacity()const {return buffers.txWireBufferCapacity();} + void TwoWire::begin(void) { if (onBeginCallback) onBeginCallback(); @@ -147,19 +155,21 @@ void TwoWire::setClock(uint32_t frequency) { } uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint32_t iaddress, uint8_t isize, uint8_t sendStop) { - if (quantity > BUFFER_LENGTH) - quantity = BUFFER_LENGTH; + if (quantity > rxBufferCapacity()) + quantity = rxBufferCapacity(); // perform blocking read into buffer int readed = 0; TWI_StartRead(twi, address, iaddress, isize); + + uint8_t* const rxBuf = rxBuffer(); do { // Stop condition must be set during the reception of last byte if (readed + 1 == quantity) TWI_SendSTOPCondition( twi); if (TWI_WaitByteReceived(twi, RECV_TIMEOUT)) - rxBuffer[readed++] = TWI_ReadByte(twi); + rxBuf[readed++] = TWI_ReadByte(twi); else break; } while (readed < quantity); @@ -196,14 +206,15 @@ void TwoWire::beginTransmission(uint8_t address) { uint8_t TwoWire::endTransmission(uint8_t sendStop) { uint8_t error = 0; // transmit buffer (blocking) - TWI_StartWrite(twi, txAddress, 0, 0, txBuffer[0]); + uint8_t* const txBuf = txBuffer(); + TWI_StartWrite(twi, txAddress, 0, 0, txBuf[0]); if (!TWI_WaitByteSent(twi, XMIT_TIMEOUT)) error = 2; // error, got NACK on address transmit if (error == 0) { uint16_t sent = 1; while (sent < txBufferLength) { - TWI_WriteByte(twi, txBuffer[sent++]); + TWI_WriteByte(twi, txBuf[sent++]); if (!TWI_WaitByteSent(twi, XMIT_TIMEOUT)) error = 3; // error, got NACK during data transmmit } @@ -230,30 +241,32 @@ uint8_t TwoWire::endTransmission(void) size_t TwoWire::write(uint8_t data) { if (status == MASTER_SEND) { - if (txBufferLength >= BUFFER_LENGTH) + if (txBufferLength >= txBufferCapacity()) return 0; - txBuffer[txBufferLength++] = data; + txBuffer()[txBufferLength++] = data; return 1; } else { - if (srvBufferLength >= BUFFER_LENGTH) + if (srvBufferLength >= srvBufferCapacity()) return 0; - srvBuffer[srvBufferLength++] = data; + srvBuffer()[srvBufferLength++] = data; return 1; } } size_t TwoWire::write(const uint8_t *data, size_t quantity) { if (status == MASTER_SEND) { + uint8_t* const txBuf = txBuffer(); for (size_t i = 0; i < quantity; ++i) { - if (txBufferLength >= BUFFER_LENGTH) + if (txBufferLength >= txBufferCapacity()) return i; - txBuffer[txBufferLength++] = data[i]; + txBuf[txBufferLength++] = data[i]; } } else { + uint8_t* const srvBuf = srvBuffer(); for (size_t i = 0; i < quantity; ++i) { - if (srvBufferLength >= BUFFER_LENGTH) + if (srvBufferLength >= srvBufferCapacity()) return i; - srvBuffer[srvBufferLength++] = data[i]; + srvBuf[srvBufferLength++] = data[i]; } } return quantity; @@ -265,13 +278,13 @@ int TwoWire::available(void) { int TwoWire::read(void) { if (rxBufferIndex < rxBufferLength) - return rxBuffer[rxBufferIndex++]; + return rxBuffer()[rxBufferIndex++]; return -1; } int TwoWire::peek(void) { if (rxBufferIndex < rxBufferLength) - return rxBuffer[rxBufferIndex]; + return rxBuffer()[rxBufferIndex]; return -1; } @@ -321,8 +334,13 @@ void TwoWire::onService(void) { // Copy data into rxBuffer // (allows to receive another packet while the // user program reads actual data) - for (uint8_t i = 0; i < srvBufferLength; ++i) - rxBuffer[i] = srvBuffer[i]; + + uint8_t* const srvBuff = srvBuffer(); + uint8_t* const rxBuff = rxBuffer(); + for (size_t i = 0; i < srvBufferLength; ++i) { + rxBuff[i] = srvBuff[i]; + } + rxBufferIndex = 0; rxBufferLength = srvBufferLength; @@ -339,8 +357,8 @@ void TwoWire::onService(void) { if (status == SLAVE_RECV) { if (TWI_STATUS_RXRDY(sr)) { - if (srvBufferLength < BUFFER_LENGTH) - srvBuffer[srvBufferLength++] = TWI_ReadByte(twi); + if (srvBufferLength < srvBufferCapacity()) + srvBuffer()[srvBufferLength++] = TWI_ReadByte(twi); } } @@ -348,7 +366,7 @@ void TwoWire::onService(void) { if (TWI_STATUS_TXRDY(sr) && !TWI_STATUS_NACK(sr)) { uint8_t c = 'x'; if (srvBufferIndex < srvBufferLength) - c = srvBuffer[srvBufferIndex++]; + c = srvBuffer()[srvBufferIndex++]; TWI_WriteByte(twi, c); } } @@ -385,7 +403,7 @@ static void Wire_Deinit(void) { // and pullups were not enabled } -TwoWire Wire = TwoWire(WIRE_INTERFACE, Wire_Init, Wire_Deinit); +TwoWire Wire = TwoWire(WireBuffers::instance(), WIRE_INTERFACE, Wire_Init, Wire_Deinit); void WIRE_ISR_HANDLER(void) { Wire.onService(); @@ -423,11 +441,12 @@ static void Wire1_Deinit(void) { // and pullups were not enabled } -TwoWire Wire1 = TwoWire(WIRE1_INTERFACE, Wire1_Init, Wire1_Deinit); +TwoWire Wire1 = TwoWire(Wire1Buffers::instance(), WIRE1_INTERFACE, Wire1_Init, Wire1_Deinit); void WIRE1_ISR_HANDLER(void) { Wire1.onService(); } + #endif #pragma GCC diagnostic pop diff --git a/libraries/Wire/src/Wire.h b/libraries/Wire/src/Wire.h index ab4d4c55..128fd947 100644 --- a/libraries/Wire/src/Wire.h +++ b/libraries/Wire/src/Wire.h @@ -27,14 +27,17 @@ #include "Stream.h" #include "variant.h" -#define BUFFER_LENGTH 32 - // WIRE_HAS_END means Wire has end() #define WIRE_HAS_END 1 + +namespace TwoWireBuffers { + class Interface; +} + class TwoWire : public Stream { public: - TwoWire(Twi *twi, void(*begin_cb)(void), void(*end_cb)(void)); + TwoWire(TwoWireBuffers::Interface& twbi, Twi *twi, void(*begin_cb)(void), void(*end_cb)(void)); void begin(); void begin(uint8_t); void begin(int); @@ -79,18 +82,24 @@ class TwoWire : public Stream { void onService(void); private: + // The buffers to be used for this Wire object. + TwoWireBuffers::Interface& buffers; + // RX Buffer - uint8_t rxBuffer[BUFFER_LENGTH]; + inline uint8_t* rxBuffer()const; + inline size_t rxBufferCapacity()const; uint8_t rxBufferIndex; uint8_t rxBufferLength; // TX Buffer uint8_t txAddress; - uint8_t txBuffer[BUFFER_LENGTH]; + inline uint8_t* txBuffer()const; + inline size_t txBufferCapacity()const; uint8_t txBufferLength; // Service buffer - uint8_t srvBuffer[BUFFER_LENGTH]; + inline uint8_t* srvBuffer()const; + inline size_t srvBufferCapacity()const; uint8_t srvBufferIndex; uint8_t srvBufferLength; @@ -129,9 +138,13 @@ class TwoWire : public Stream { }; #if WIRE_INTERFACES_COUNT > 0 +// The buffers for the Wire object +namespace WireBuffers {extern TwoWireBuffers::Interface& instance();} extern TwoWire Wire; #endif #if WIRE_INTERFACES_COUNT > 1 +// The buffers for the Wire1 object +namespace Wire1Buffers {extern TwoWireBuffers::Interface& instance();} extern TwoWire Wire1; #endif From db268b4cea25f53decffe7bd19fcd539c7bfd5e6 Mon Sep 17 00:00:00 2001 From: dac1e Date: Tue, 31 Dec 2024 16:06:57 +0100 Subject: [PATCH 04/17] Made buffer capacity read functions of Wire class public. Added example sketches for custom buffers. println() after having printed all received characters in master_reader.ino. --- .../examples/master_reader/master_reader.ino | 14 ++-- .../master_reader_custombuffer.ino | 65 ++++++++++++++++++ .../master_writer_custombuffer.ino | 65 ++++++++++++++++++ .../slave_receiver_custombuffer.ino | 66 +++++++++++++++++++ .../slave_sender_custombuffer.ino | 64 ++++++++++++++++++ libraries/Wire/src/Wire.h | 7 +- 6 files changed, 270 insertions(+), 11 deletions(-) create mode 100644 libraries/Wire/examples/master_reader_custombuffer/master_reader_custombuffer.ino create mode 100644 libraries/Wire/examples/master_writer_custombuffer/master_writer_custombuffer.ino create mode 100644 libraries/Wire/examples/slave_receiver_custombuffer/slave_receiver_custombuffer.ino create mode 100644 libraries/Wire/examples/slave_sender_custombuffer/slave_sender_custombuffer.ino diff --git a/libraries/Wire/examples/master_reader/master_reader.ino b/libraries/Wire/examples/master_reader/master_reader.ino index 4124d7d6..214ffe99 100644 --- a/libraries/Wire/examples/master_reader/master_reader.ino +++ b/libraries/Wire/examples/master_reader/master_reader.ino @@ -12,21 +12,19 @@ #include -void setup() -{ - Wire.begin(); // join i2c bus (address optional for master) +void setup() { + Wire.begin(); // join I2C bus (address optional for master) Serial.begin(9600); // start serial for output } -void loop() -{ - Wire.requestFrom(2, 6); // request 6 bytes from slave device #2 +void loop() { + Wire.requestFrom(8, 6); // request 6 bytes from slave device #8 - while(Wire.available()) // slave may send less than requested - { + while (Wire.available()) { // slave may send less than requested char c = Wire.read(); // receive a byte as character Serial.print(c); // print the character } + Serial.println(); delay(500); } diff --git a/libraries/Wire/examples/master_reader_custombuffer/master_reader_custombuffer.ino b/libraries/Wire/examples/master_reader_custombuffer/master_reader_custombuffer.ino new file mode 100644 index 00000000..ab6abf93 --- /dev/null +++ b/libraries/Wire/examples/master_reader_custombuffer/master_reader_custombuffer.ino @@ -0,0 +1,65 @@ +// Wire Master Reader Custom Buffer + +// Demonstrates use of the Wire library +// Reads data from an I2C/TWI slave device +// Refer to the "Wire Slave Sender Custom Buffer" example for use with this + +// Created 31 Dec 2024 + +// This example code is in the public domain. + + +#include +#include + +// request 6 bytes from slave device #8 +size_t constexpr REQUESTED_BYTE_COUNT = 6; + +/**** Begin Customize buffers ****/ +// Note: If you spell namespace 'WireBuffers' wrongly, all buffer +// sizes of the 'Wire' object stay at default (32 bytes). +namespace WireBuffers { + size_t constexpr RECEIVE_BUFFER_SIZE = REQUESTED_BYTE_COUNT; + size_t constexpr TRANSMIT_BUFFER_SIZE = 0; // There is no transmit in this sketch. + // We operate as a master only, so we use the macro that will set slave buffers to zero. + SET_BUFFERS_FOR_MASTER_ONLY(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE); +} +/**** End Customize buffers ******/ + +// This is just for curiosity. +// Set to false if you don't want to see actual buffer sizes on serial monitor. +#define VERBOSE true + +void setup() { + Wire.begin(); // join I2C bus (address optional for master) + Serial.begin(9600); // start serial for output +#if VERBOSE + printWireBuffers(); +#endif +} + +void loop() { + Wire.requestFrom(8, REQUESTED_BYTE_COUNT); + + while (Wire.available()) { // slave may send less than requested + char c = Wire.read(); // receive a byte as character + Serial.print(c); // print the character + } + Serial.println(); + + delay(500); +} + +#if VERBOSE +void printWireBuffers() { + delay(100); + Serial.println(); + Serial.print("Wire transmit buffer size is "); + Serial.println(Wire.txBufferCapacity()); + Serial.print("Wire receive buffer size is "); + Serial.println(Wire.rxBufferCapacity()); + Serial.print("Wire service buffer size is "); + Serial.println(Wire.srvBufferCapacity()); + delay(500); +} +#endif diff --git a/libraries/Wire/examples/master_writer_custombuffer/master_writer_custombuffer.ino b/libraries/Wire/examples/master_writer_custombuffer/master_writer_custombuffer.ino new file mode 100644 index 00000000..40e28991 --- /dev/null +++ b/libraries/Wire/examples/master_writer_custombuffer/master_writer_custombuffer.ino @@ -0,0 +1,65 @@ +// Wire Master Writer Custom Buffer + +// Demonstrates use of the Wire library +// Writes data to an I2C/TWI slave device +// Refer to the "Wire Slave Receiver Custom Buffer" example for use with this + +// Created 31 Dec 2024 + +// This example code is in the public domain. + + +#include +#include + +// The following text will not fit into the default buffer of 32 bytes. +static const char text[] = "You really won't believe it, but x is "; + +/**** Begin Customize buffers ****/ +// Note: If you spell namespace 'WireBuffers' wrongly, all buffer sizes +// of the 'Wire' object stay at default (32 bytes). +namespace WireBuffers { + size_t constexpr RECEIVE_BUFFER_SIZE = 0; // There is no receive in this sketch. + size_t constexpr TRANSMIT_BUFFER_SIZE = 42; // Enhance the buffer to 42 characters. + // We operate as a master only, so we use the macro that will set slave buffers to zero. + SET_BUFFERS_FOR_MASTER_ONLY(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE); +} +/**** End Customize buffers ******/ + +// This is just for curiosity. +// Set to false if you don't want to see actual buffer sizes on serial monitor. +#define VERBOSE true + +void setup() { + Wire.begin(); // join I2C bus (address optional for master) +#if VERBOSE + Serial.begin(9600); // start serial for output + printWireBuffers(); +#endif +} + +static byte x = 0; + +void loop() { + Wire.beginTransmission(8); // transmit to device #8 + Wire.write(text); // sends five bytes + Wire.write(x); // sends one byte + Wire.endTransmission(); // stop transmitting + + x++; + delay(500); +} + +#if VERBOSE +void printWireBuffers() { + delay(100); + Serial.println(); + Serial.print("Wire transmit buffer size is "); + Serial.println(Wire.txBufferCapacity()); + Serial.print("Wire receive buffer size is "); + Serial.println(Wire.rxBufferCapacity()); + Serial.print("Wire service buffer size is "); + Serial.println(Wire.srvBufferCapacity()); + delay(500); +} +#endif diff --git a/libraries/Wire/examples/slave_receiver_custombuffer/slave_receiver_custombuffer.ino b/libraries/Wire/examples/slave_receiver_custombuffer/slave_receiver_custombuffer.ino new file mode 100644 index 00000000..e80b9b1f --- /dev/null +++ b/libraries/Wire/examples/slave_receiver_custombuffer/slave_receiver_custombuffer.ino @@ -0,0 +1,66 @@ +// Wire Slave Receiver Custom Buffer + +// Demonstrates use of the Wire library +// Receives data as an I2C/TWI slave device +// Refer to the "Wire Master Writer Custom Buffer" example for use with this + +// Created 31 Dec 2024 + +// This example code is in the public domain. + + +#include +#include + +/**** Begin Customize buffers ****/ +// Note: If you spell namespace 'WireBuffers' wrongly, all buffer sizes +// of the 'Wire' object stay at default (32 bytes). +namespace WireBuffers { + size_t constexpr RECEIVE_BUFFER_SIZE = 42; // Be able receive up to 42 characters in one message. + size_t constexpr TRANSMIT_BUFFER_SIZE = 0; // There is no transmit in this sketch. + // We operate as a slave only, so we use the macro that will set master buffers to zero. + SET_BUFFERS_FOR_SLAVE_ONLY(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE); +} +/**** End Customize buffers ******/ + +// This is just for curiosity. +// Set to false if you don't want to see actual buffer sizes on serial monitor. +#define VERBOSE true + +void setup() { + Wire.begin(8); // join I2C bus with address #8 + Wire.onReceive(receiveEvent); // register event + Serial.begin(9600); // start serial for output +#if VERBOSE + printWireBuffers(); +#endif +} + +void loop() { + delay(100); +} + +// function that executes whenever data is received from master +// this function is registered as an event, see setup() +void receiveEvent(int howMany) { + while (1 < Wire.available()) { // loop through all but the last + char c = Wire.read(); // receive byte as a character + Serial.print(c); // print the character + } + int x = Wire.read(); // receive byte as an integer + Serial.println(x); // print the integer +} + +#if VERBOSE +void printWireBuffers() { + delay(100); + Serial.println(); + Serial.print("Wire transmit buffer size is "); + Serial.println(Wire.txBufferCapacity()); + Serial.print("Wire receive buffer size is "); + Serial.println(Wire.rxBufferCapacity()); + Serial.print("Wire service buffer size is "); + Serial.println(Wire.srvBufferCapacity()); + delay(500); +} +#endif diff --git a/libraries/Wire/examples/slave_sender_custombuffer/slave_sender_custombuffer.ino b/libraries/Wire/examples/slave_sender_custombuffer/slave_sender_custombuffer.ino new file mode 100644 index 00000000..a824e946 --- /dev/null +++ b/libraries/Wire/examples/slave_sender_custombuffer/slave_sender_custombuffer.ino @@ -0,0 +1,64 @@ +// Wire Slave Sender Custom Buffer + +// Demonstrates use of the Wire library +// Sends data as an I2C/TWI slave device +// Refer to the "Wire Master Reader Custom Buffer" example for use with this + +// Created 31 Dec 2024 + +// This example code is in the public domain. + + +#include +#include + +static const char text[] = "hello "; // respond with message of 6 bytes + +/**** Begin Customize buffers ****/ +// Note: If you spell namespace 'WireBuffers' wrongly, all buffer sizes +// of the 'Wire' object stay at default (32 bytes). +namespace WireBuffers { + size_t constexpr RECEIVE_BUFFER_SIZE = 0; // There is no receive in this sketch. + size_t constexpr TRANSMIT_BUFFER_SIZE = sizeof(text)-1; // Don't need a byte for the \0 + // We operate as a slave only, so we use the macro that will set master buffers to zero. + SET_BUFFERS_FOR_SLAVE_ONLY(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE); +} +/**** End Customize buffers ******/ + +// This is just for curiosity. +// Set to false if you don't want to see actual buffer sizes on serial monitor. +#define VERBOSE true + +void setup() { + Wire.begin(8); // join I2C bus with address #8 + Wire.onRequest(requestEvent); // register event +#if VERBOSE + Serial.begin(9600); // start serial for output + printWireBuffers(); +#endif +} + +void loop() { + delay(100); +} + +// function that executes whenever data is requested by master +// this function is registered as an event, see setup() +void requestEvent() { + Wire.write(text); + // as expected by master +} + +#if VERBOSE +void printWireBuffers() { + delay(100); + Serial.println(); + Serial.print("Wire transmit buffer size is "); + Serial.println(Wire.txBufferCapacity()); + Serial.print("Wire receive buffer size is "); + Serial.println(Wire.rxBufferCapacity()); + Serial.print("Wire service buffer size is "); + Serial.println(Wire.srvBufferCapacity()); + delay(500); +} +#endif diff --git a/libraries/Wire/src/Wire.h b/libraries/Wire/src/Wire.h index 128fd947..cbf36aac 100644 --- a/libraries/Wire/src/Wire.h +++ b/libraries/Wire/src/Wire.h @@ -81,25 +81,26 @@ class TwoWire : public Stream { void onService(void); + inline size_t rxBufferCapacity()const; + inline size_t txBufferCapacity()const; + inline size_t srvBufferCapacity()const; + private: // The buffers to be used for this Wire object. TwoWireBuffers::Interface& buffers; // RX Buffer inline uint8_t* rxBuffer()const; - inline size_t rxBufferCapacity()const; uint8_t rxBufferIndex; uint8_t rxBufferLength; // TX Buffer uint8_t txAddress; inline uint8_t* txBuffer()const; - inline size_t txBufferCapacity()const; uint8_t txBufferLength; // Service buffer inline uint8_t* srvBuffer()const; - inline size_t srvBufferCapacity()const; uint8_t srvBufferIndex; uint8_t srvBufferLength; From 1e4100abc6bf79af4f717f37f0d16fddd4e873e4 Mon Sep 17 00:00:00 2001 From: dac1e Date: Tue, 31 Dec 2024 16:40:11 +0100 Subject: [PATCH 05/17] Use C++ cast operator. --- libraries/Wire/src/Wire.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/Wire/src/Wire.cpp b/libraries/Wire/src/Wire.cpp index 9c84f585..d82ccdba 100644 --- a/libraries/Wire/src/Wire.cpp +++ b/libraries/Wire/src/Wire.cpp @@ -325,7 +325,7 @@ void TwoWire::onService(void) { onRequestCallback(); else // create a default 1-byte response - write((uint8_t) 0); + write(static_cast(0)); } } From 9df2850f412f857e4ea3a3795c5bfc6fc141a027 Mon Sep 17 00:00:00 2001 From: dac1e Date: Wed, 1 Jan 2025 17:44:46 +0100 Subject: [PATCH 06/17] Simplified examples to choose Wire of Wire1. --- .../master_reader_custombuffer.ino | 89 ++++++++++++------ .../master_writer_custombuffer.ino | 89 ++++++++++++------ .../slave_receiver_custombuffer.ino | 91 +++++++++++++------ .../slave_sender_custombuffer.ino | 89 ++++++++++++------ libraries/Wire/src/TwoWireBuffers.cpp | 14 +-- libraries/Wire/src/TwoWireBuffers.h | 45 +++++---- libraries/Wire/src/Wire.cpp | 4 +- libraries/Wire/src/Wire.h | 2 - 8 files changed, 290 insertions(+), 133 deletions(-) diff --git a/libraries/Wire/examples/master_reader_custombuffer/master_reader_custombuffer.ino b/libraries/Wire/examples/master_reader_custombuffer/master_reader_custombuffer.ino index ab6abf93..197f5977 100644 --- a/libraries/Wire/examples/master_reader_custombuffer/master_reader_custombuffer.ino +++ b/libraries/Wire/examples/master_reader_custombuffer/master_reader_custombuffer.ino @@ -11,31 +11,27 @@ #include #include +#include "Arduino.h" + +#define USE_WIRE1 false // Set to true for using Wire1 // request 6 bytes from slave device #8 -size_t constexpr REQUESTED_BYTE_COUNT = 6; - -/**** Begin Customize buffers ****/ -// Note: If you spell namespace 'WireBuffers' wrongly, all buffer -// sizes of the 'Wire' object stay at default (32 bytes). -namespace WireBuffers { - size_t constexpr RECEIVE_BUFFER_SIZE = REQUESTED_BYTE_COUNT; - size_t constexpr TRANSMIT_BUFFER_SIZE = 0; // There is no transmit in this sketch. - // We operate as a master only, so we use the macro that will set slave buffers to zero. - SET_BUFFERS_FOR_MASTER_ONLY(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE); -} -/**** End Customize buffers ******/ +constexpr size_t REQUESTED_BYTE_COUNT = 6; + +constexpr size_t RECEIVE_BUFFER_SIZE = REQUESTED_BYTE_COUNT; +constexpr size_t TRANSMIT_BUFFER_SIZE = 0; // There is no transmit in this sketch. + +#if not USE_WIRE1 -// This is just for curiosity. -// Set to false if you don't want to see actual buffer sizes on serial monitor. -#define VERBOSE true +SET_WIRE_BUFFERS(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE, + true /* master buffers needed */, false /* no slave buffers needed */ ); void setup() { Wire.begin(); // join I2C bus (address optional for master) Serial.begin(9600); // start serial for output -#if VERBOSE - printWireBuffers(); -#endif + + // This is just for curiosity and can be removed + printWireBuffersCapacity(Serial); } void loop() { @@ -50,16 +46,55 @@ void loop() { delay(500); } -#if VERBOSE -void printWireBuffers() { - delay(100); +void printWireBuffersCapacity(Stream& stream) { + const auto& buffers = GET_WIRE_BUFFERS(); + + stream.print("Wire transmit buffer size is "); + stream.println(buffers.txWireBufferCapacity()); + + stream.print("Wire receive buffer size is "); + stream.println(buffers.rxWireBufferCapacity()); + + stream.print("Wire service buffer size is "); + stream.println(buffers.srvWireBufferCapacity()); +} + +#else + +SET_WIRE1_BUFFERS(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE, + true /* master buffers needed */, false /* no slave buffers needed */ ); + +void setup() { + Wire1.begin(); // join I2C bus (address optional for master) + Serial.begin(9600); // start serial for output + + // This is just for curiosity and can be removed + printWire1BuffersCapacity(Serial); +} + +void loop() { + Wire1.requestFrom(8, REQUESTED_BYTE_COUNT); + + while (Wire1.available()) { // slave may send less than requested + char c = Wire1.read(); // receive a byte as character + Serial.print(c); // print the character + } Serial.println(); - Serial.print("Wire transmit buffer size is "); - Serial.println(Wire.txBufferCapacity()); - Serial.print("Wire receive buffer size is "); - Serial.println(Wire.rxBufferCapacity()); - Serial.print("Wire service buffer size is "); - Serial.println(Wire.srvBufferCapacity()); + delay(500); } + +void printWire1BuffersCapacity(Stream& stream) { + const auto& buffers = GET_WIRE1_BUFFERS(); + + stream.print("Wire1 transmit buffer size is "); + stream.println(buffers.txWireBufferCapacity()); + + stream.print("Wire1 receive buffer size is "); + stream.println(buffers.rxWireBufferCapacity()); + + stream.print("Wire1 service buffer size is "); + stream.println(buffers.srvWireBufferCapacity()); +} + #endif diff --git a/libraries/Wire/examples/master_writer_custombuffer/master_writer_custombuffer.ino b/libraries/Wire/examples/master_writer_custombuffer/master_writer_custombuffer.ino index 40e28991..bb85c89a 100644 --- a/libraries/Wire/examples/master_writer_custombuffer/master_writer_custombuffer.ino +++ b/libraries/Wire/examples/master_writer_custombuffer/master_writer_custombuffer.ino @@ -11,31 +11,27 @@ #include #include +#include "Arduino.h" + +#define USE_WIRE1 false // Set to true for using Wire1 // The following text will not fit into the default buffer of 32 bytes. static const char text[] = "You really won't believe it, but x is "; -/**** Begin Customize buffers ****/ -// Note: If you spell namespace 'WireBuffers' wrongly, all buffer sizes -// of the 'Wire' object stay at default (32 bytes). -namespace WireBuffers { - size_t constexpr RECEIVE_BUFFER_SIZE = 0; // There is no receive in this sketch. - size_t constexpr TRANSMIT_BUFFER_SIZE = 42; // Enhance the buffer to 42 characters. - // We operate as a master only, so we use the macro that will set slave buffers to zero. - SET_BUFFERS_FOR_MASTER_ONLY(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE); -} -/**** End Customize buffers ******/ +size_t constexpr RECEIVE_BUFFER_SIZE = 0; // There is no receive in this sketch. +size_t constexpr TRANSMIT_BUFFER_SIZE = 42; // Enhance the buffer to 42 characters. -// This is just for curiosity. -// Set to false if you don't want to see actual buffer sizes on serial monitor. -#define VERBOSE true +#if not USE_WIRE1 + +SET_WIRE_BUFFERS(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE, + true /* master buffers needed */, false /* no slave buffers needed */ ); void setup() { Wire.begin(); // join I2C bus (address optional for master) -#if VERBOSE - Serial.begin(9600); // start serial for output - printWireBuffers(); -#endif + + // This is just for curiosity and can be removed + Serial.begin(9600); // start serial for output + printWireBuffersCapacity(Serial); } static byte x = 0; @@ -50,16 +46,55 @@ void loop() { delay(500); } -#if VERBOSE -void printWireBuffers() { - delay(100); - Serial.println(); - Serial.print("Wire transmit buffer size is "); - Serial.println(Wire.txBufferCapacity()); - Serial.print("Wire receive buffer size is "); - Serial.println(Wire.rxBufferCapacity()); - Serial.print("Wire service buffer size is "); - Serial.println(Wire.srvBufferCapacity()); +void printWireBuffersCapacity(Stream& stream) { + const auto& buffers = GET_WIRE_BUFFERS(); + + stream.print("Wire transmit buffer size is "); + stream.println(buffers.txWireBufferCapacity()); + + stream.print("Wire receive buffer size is "); + stream.println(buffers.rxWireBufferCapacity()); + + stream.print("Wire service buffer size is "); + stream.println(buffers.srvWireBufferCapacity()); +} + +#else + +SET_WIRE1_BUFFERS(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE, + true /* master buffers needed */, false /* no slave buffers needed */ ); + +void setup() { + Wire1.begin(); // join I2C bus (address optional for master) + + // This is just for curiosity and can be removed + Serial.begin(9600); // start serial for output + printWire1BuffersCapacity(Serial); +} + +static byte x = 0; + +void loop() { + Wire1.beginTransmission(8); // transmit to device #8 + Wire1.write(text); // sends five bytes + Wire1.write(x); // sends one byte + Wire1.endTransmission(); // stop transmitting + + x++; delay(500); } + +void printWire1BuffersCapacity(Stream& stream) { + const auto& buffers = GET_WIRE1_BUFFERS(); + + stream.print("Wire1 transmit buffer size is "); + stream.println(buffers.txWireBufferCapacity()); + + stream.print("Wire1 receive buffer size is "); + stream.println(buffers.rxWireBufferCapacity()); + + stream.print("Wire1 service buffer size is "); + stream.println(buffers.srvWireBufferCapacity()); +} + #endif diff --git a/libraries/Wire/examples/slave_receiver_custombuffer/slave_receiver_custombuffer.ino b/libraries/Wire/examples/slave_receiver_custombuffer/slave_receiver_custombuffer.ino index e80b9b1f..0374581e 100644 --- a/libraries/Wire/examples/slave_receiver_custombuffer/slave_receiver_custombuffer.ino +++ b/libraries/Wire/examples/slave_receiver_custombuffer/slave_receiver_custombuffer.ino @@ -11,29 +11,25 @@ #include #include +#include "Arduino.h" -/**** Begin Customize buffers ****/ -// Note: If you spell namespace 'WireBuffers' wrongly, all buffer sizes -// of the 'Wire' object stay at default (32 bytes). -namespace WireBuffers { - size_t constexpr RECEIVE_BUFFER_SIZE = 42; // Be able receive up to 42 characters in one message. - size_t constexpr TRANSMIT_BUFFER_SIZE = 0; // There is no transmit in this sketch. - // We operate as a slave only, so we use the macro that will set master buffers to zero. - SET_BUFFERS_FOR_SLAVE_ONLY(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE); -} -/**** End Customize buffers ******/ +#define USE_WIRE1 true // Set to true for using Wire1 + +size_t constexpr RECEIVE_BUFFER_SIZE = 42; // Be able receive up to 42 characters in one message. +size_t constexpr TRANSMIT_BUFFER_SIZE = 0; // There is no transmit in this sketch. -// This is just for curiosity. -// Set to false if you don't want to see actual buffer sizes on serial monitor. -#define VERBOSE true +#if not USE_WIRE1 + +SET_WIRE_BUFFERS(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE, + true /* master buffers needed */, false /* no slave buffers needed */ ); void setup() { Wire.begin(8); // join I2C bus with address #8 Wire.onReceive(receiveEvent); // register event Serial.begin(9600); // start serial for output -#if VERBOSE - printWireBuffers(); -#endif + + // This is just for curiosity and can be removed + printWireBuffersCapacity(Serial); } void loop() { @@ -51,16 +47,59 @@ void receiveEvent(int howMany) { Serial.println(x); // print the integer } -#if VERBOSE -void printWireBuffers() { +void printWireBuffersCapacity(Stream& stream) { + const auto& buffers = GET_WIRE_BUFFERS(); + + stream.print("Wire transmit buffer size is "); + stream.println(buffers.txWireBufferCapacity()); + + stream.print("Wire receive buffer size is "); + stream.println(buffers.rxWireBufferCapacity()); + + stream.print("Wire service buffer size is "); + stream.println(buffers.srvWireBufferCapacity()); +} + +#else + +SET_WIRE1_BUFFERS(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE, + true /* master buffers needed */, false /* no slave buffers needed */ ); + +void setup() { + Wire1.begin(8); // join I2C bus with address #8 + Wire1.onReceive(receiveEvent); // register event + Serial.begin(9600); // start serial for output + + // This is just for curiosity and can be removed + printWire1BuffersCapacity(Serial); +} + +void loop() { delay(100); - Serial.println(); - Serial.print("Wire transmit buffer size is "); - Serial.println(Wire.txBufferCapacity()); - Serial.print("Wire receive buffer size is "); - Serial.println(Wire.rxBufferCapacity()); - Serial.print("Wire service buffer size is "); - Serial.println(Wire.srvBufferCapacity()); - delay(500); } + +// function that executes whenever data is received from master +// this function is registered as an event, see setup() +void receiveEvent(int howMany) { + while (1 < Wire1.available()) { // loop through all but the last + char c = Wire1.read(); // receive byte as a character + Serial.print(c); // print the character + } + int x = Wire1.read(); // receive byte as an integer + Serial.println(x); // print the integer +} + +void printWire1BuffersCapacity(Stream& stream) { + const auto& buffers = GET_WIRE1_BUFFERS(); + + stream.print("Wire1 transmit buffer size is "); + stream.println(buffers.txWireBufferCapacity()); + + stream.print("Wire1 receive buffer size is "); + stream.println(buffers.rxWireBufferCapacity()); + + stream.print("Wire1 service buffer size is "); + stream.println(buffers.srvWireBufferCapacity()); +} + #endif diff --git a/libraries/Wire/examples/slave_sender_custombuffer/slave_sender_custombuffer.ino b/libraries/Wire/examples/slave_sender_custombuffer/slave_sender_custombuffer.ino index a824e946..845ec651 100644 --- a/libraries/Wire/examples/slave_sender_custombuffer/slave_sender_custombuffer.ino +++ b/libraries/Wire/examples/slave_sender_custombuffer/slave_sender_custombuffer.ino @@ -11,31 +11,27 @@ #include #include +#include "Arduino.h" + +#define USE_WIRE1 false // Set to true for using Wire1 static const char text[] = "hello "; // respond with message of 6 bytes -/**** Begin Customize buffers ****/ -// Note: If you spell namespace 'WireBuffers' wrongly, all buffer sizes -// of the 'Wire' object stay at default (32 bytes). -namespace WireBuffers { - size_t constexpr RECEIVE_BUFFER_SIZE = 0; // There is no receive in this sketch. - size_t constexpr TRANSMIT_BUFFER_SIZE = sizeof(text)-1; // Don't need a byte for the \0 - // We operate as a slave only, so we use the macro that will set master buffers to zero. - SET_BUFFERS_FOR_SLAVE_ONLY(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE); -} -/**** End Customize buffers ******/ +size_t constexpr RECEIVE_BUFFER_SIZE = 0; // There is no receive in this sketch. +size_t constexpr TRANSMIT_BUFFER_SIZE = sizeof(text)-1; // Don't need a byte for the \0 -// This is just for curiosity. -// Set to false if you don't want to see actual buffer sizes on serial monitor. -#define VERBOSE true +#if not USE_WIRE1 + +SET_WIRE_BUFFERS(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE, + true /* master buffers needed */, false /* no slave buffers needed */ ); void setup() { Wire.begin(8); // join I2C bus with address #8 Wire.onRequest(requestEvent); // register event -#if VERBOSE - Serial.begin(9600); // start serial for output - printWireBuffers(); -#endif + + // This is just for curiosity and can be removed + Serial.begin(9600); + printWireBuffersCapacity(Serial); } void loop() { @@ -49,16 +45,55 @@ void requestEvent() { // as expected by master } -#if VERBOSE -void printWireBuffers() { +void printWireBuffersCapacity(Stream& stream) { + const auto& buffers = GET_WIRE_BUFFERS(); + + stream.print("Wire transmit buffer size is "); + stream.println(buffers.txWireBufferCapacity()); + + stream.print("Wire receive buffer size is "); + stream.println(buffers.rxWireBufferCapacity()); + + stream.print("Wire service buffer size is "); + stream.println(buffers.srvWireBufferCapacity()); +} + +#else + +SET_WIRE1_BUFFERS(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE, + true /* master buffers needed */, false /* no slave buffers needed */ ); + +void setup() { + Wire1.begin(8); // join I2C bus with address #8 + Wire1.onRequest(requestEvent); // register event + + // This is just for curiosity and can be removed + Serial.begin(9600); + printWire1BuffersCapacity(Serial); +} + +void loop() { delay(100); - Serial.println(); - Serial.print("Wire transmit buffer size is "); - Serial.println(Wire.txBufferCapacity()); - Serial.print("Wire receive buffer size is "); - Serial.println(Wire.rxBufferCapacity()); - Serial.print("Wire service buffer size is "); - Serial.println(Wire.srvBufferCapacity()); - delay(500); } + +// function that executes whenever data is requested by master +// this function is registered as an event, see setup() +void requestEvent() { + Wire1.write(text); + // as expected by master +} + +void printWire1BuffersCapacity(Stream& stream) { + const auto& buffers = GET_WIRE_BUFFERS(); + + stream.print("Wire1 transmit buffer size is "); + stream.println(buffers.txWireBufferCapacity()); + + stream.print("Wire1 receive buffer size is "); + stream.println(buffers.rxWireBufferCapacity()); + + stream.print("Wire1 service buffer size is "); + stream.println(buffers.srvWireBufferCapacity()); +} + #endif diff --git a/libraries/Wire/src/TwoWireBuffers.cpp b/libraries/Wire/src/TwoWireBuffers.cpp index b070504e..0244dff3 100644 --- a/libraries/Wire/src/TwoWireBuffers.cpp +++ b/libraries/Wire/src/TwoWireBuffers.cpp @@ -25,14 +25,16 @@ constexpr size_t TX_BUFFER_DEFAULT_LENGTH = 32; #if WIRE_INTERFACES_COUNT > 0 // Default buffers for the Wire object -namespace WireBuffers { - __attribute__((weak)) SET_BUFFERS_FOR_BOTH(RX_BUFFER_DEFAULT_LENGTH, TX_BUFFER_DEFAULT_LENGTH); -} // namespace Twi +template<> __attribute__((weak)) TwoWireBuffers::Interface& WireBuffers<0>::instance() { \ + static TwoWireBuffers::Impl buffers; \ + return buffers; \ +} #endif #if WIRE_INTERFACES_COUNT > 1 // Default buffers for the Wire1 object -namespace Wire1Buffers { - __attribute__((weak)) SET_BUFFERS_FOR_BOTH(RX_BUFFER_DEFAULT_LENGTH, TX_BUFFER_DEFAULT_LENGTH); -} // namespace Twi +template<> __attribute__((weak)) TwoWireBuffers::Interface& WireBuffers<1>::instance() { \ + static TwoWireBuffers::Impl buffers; \ + return buffers; \ +} #endif diff --git a/libraries/Wire/src/TwoWireBuffers.h b/libraries/Wire/src/TwoWireBuffers.h index 4ab6bf10..03725082 100644 --- a/libraries/Wire/src/TwoWireBuffers.h +++ b/libraries/Wire/src/TwoWireBuffers.h @@ -26,6 +26,7 @@ #include #include +#include namespace TwoWireBuffers { @@ -51,13 +52,13 @@ class StaticBuffer<0> { class Interface { public: virtual uint8_t* rxWireBuffer() = 0; - virtual size_t rxWireBufferCapacity() = 0; + virtual size_t rxWireBufferCapacity()const = 0; virtual uint8_t* txWireBuffer() = 0; - virtual size_t txWireBufferCapacity() = 0; + virtual size_t txWireBufferCapacity()const = 0; virtual uint8_t* srvWireBuffer() = 0; - virtual size_t srvWireBufferCapacity() = 0; + virtual size_t srvWireBufferCapacity()const = 0; }; /* Template class implementing Interface with template parameter @@ -79,29 +80,41 @@ class Impl : public Interface { public: virtual uint8_t* rxWireBuffer() override {return mRxWireBuffer.storage();} - virtual size_t rxWireBufferCapacity() override {return mRxWireBuffer.capacity();} + virtual size_t rxWireBufferCapacity()const override {return mRxWireBuffer.capacity();} virtual uint8_t* txWireBuffer() override {return mTxWireBuffer.storage();} - virtual size_t txWireBufferCapacity() override {return mTxWireBuffer.capacity();} + virtual size_t txWireBufferCapacity()const override {return mTxWireBuffer.capacity();} virtual uint8_t* srvWireBuffer() override {return mSrvWireBuffer.storage();} - virtual size_t srvWireBufferCapacity() override {return mSrvWireBuffer.capacity();} + virtual size_t srvWireBufferCapacity()const override {return mSrvWireBuffer.capacity();} }; } // namespace TwoWireBuffers -#define SET_BUFFERS_FOR_BOTH(RX_BUFFER_CAPACITY, TX_BUFFER_CAPACITY) \ - TwoWireBuffers::Interface& instance() { \ - static TwoWireBuffers::Impl instance; \ - return instance; \ +template struct WireBuffers { // The buffers for the Wire object + static TwoWireBuffers::Interface& instance(); +}; + +#define SET_WIRE_BUFFERS_(wireNum, rxBufferCapacity, txBufferCapacity, enableMaster, enableSlave) \ + template<> TwoWireBuffers::Interface& WireBuffers::instance() { \ + static TwoWireBuffers::Impl buffers; \ + return buffers; \ } -// This macro is just for compatibility reasons with AVR core -#define SET_BUFFERS_FOR_MASTER_ONLY(RX_BUFFER_CAPACITY, TX_BUFFER_CAPACITY) \ - SET_BUFFERS_FOR_BOTH(RX_BUFFER_CAPACITY, TX_BUFFER_CAPACITY) +#define GET_WIRE_BUFFERS_(wireNum) WireBuffers::instance() + +#if WIRE_INTERFACES_COUNT > 0 + #define SET_WIRE_BUFFERS(rxBufferCapacity, txBufferCapacity, enableMaster, enableSlave) \ + SET_WIRE_BUFFERS_(0, rxBufferCapacity, txBufferCapacity, enableMaster, enableSlave) + + #define GET_WIRE_BUFFERS() GET_WIRE_BUFFERS_(0) +#endif + +#if WIRE_INTERFACES_COUNT > 1 + #define SET_WIRE1_BUFFERS(rxBufferCapacity, txBufferCapacity, enableMaster, enableSlave) \ + SET_WIRE_BUFFERS_(1, rxBufferCapacity, txBufferCapacity, enableMaster, enableSlave) -// This macro is just for compatibility reasons with AVR core -#define SET_BUFFERS_FOR_SLAVE_ONLY(RX_BUFFER_CAPACITY, TX_BUFFER_CAPACITY) \ - SET_BUFFERS_FOR_BOTH(RX_BUFFER_CAPACITY, TX_BUFFER_CAPACITY) + #define GET_WIRE1_BUFFERS() GET_WIRE_BUFFERS_(1) +#endif #endif /* TwiBuffers_h */ diff --git a/libraries/Wire/src/Wire.cpp b/libraries/Wire/src/Wire.cpp index d82ccdba..85b83948 100644 --- a/libraries/Wire/src/Wire.cpp +++ b/libraries/Wire/src/Wire.cpp @@ -403,7 +403,7 @@ static void Wire_Deinit(void) { // and pullups were not enabled } -TwoWire Wire = TwoWire(WireBuffers::instance(), WIRE_INTERFACE, Wire_Init, Wire_Deinit); +TwoWire Wire = TwoWire(WireBuffers<0>::instance(), WIRE_INTERFACE, Wire_Init, Wire_Deinit); void WIRE_ISR_HANDLER(void) { Wire.onService(); @@ -441,7 +441,7 @@ static void Wire1_Deinit(void) { // and pullups were not enabled } -TwoWire Wire1 = TwoWire(Wire1Buffers::instance(), WIRE1_INTERFACE, Wire1_Init, Wire1_Deinit); +TwoWire Wire1 = TwoWire(WireBuffers<1>::instance(), WIRE1_INTERFACE, Wire1_Init, Wire1_Deinit); void WIRE1_ISR_HANDLER(void) { Wire1.onService(); diff --git a/libraries/Wire/src/Wire.h b/libraries/Wire/src/Wire.h index cbf36aac..5e5be3f8 100644 --- a/libraries/Wire/src/Wire.h +++ b/libraries/Wire/src/Wire.h @@ -140,12 +140,10 @@ class TwoWire : public Stream { #if WIRE_INTERFACES_COUNT > 0 // The buffers for the Wire object -namespace WireBuffers {extern TwoWireBuffers::Interface& instance();} extern TwoWire Wire; #endif #if WIRE_INTERFACES_COUNT > 1 // The buffers for the Wire1 object -namespace Wire1Buffers {extern TwoWireBuffers::Interface& instance();} extern TwoWire Wire1; #endif From 7b28d8924fe35ab6feb0bb900dbce86900bc0419 Mon Sep 17 00:00:00 2001 From: dac1e Date: Wed, 1 Jan 2025 17:44:46 +0100 Subject: [PATCH 07/17] Simplified examples to choose Wire of Wire1. --- .../master_reader_custombuffer.ino | 89 ++++++++++++------ .../examples/master_writer/master_writer.ino | 2 +- .../master_writer_custombuffer.ino | 89 ++++++++++++------ .../slave_receiver_custombuffer.ino | 91 +++++++++++++------ .../slave_sender_custombuffer.ino | 89 ++++++++++++------ libraries/Wire/src/TwoWireBuffers.cpp | 14 +-- libraries/Wire/src/TwoWireBuffers.h | 45 +++++---- libraries/Wire/src/Wire.cpp | 4 +- libraries/Wire/src/Wire.h | 2 - 9 files changed, 291 insertions(+), 134 deletions(-) diff --git a/libraries/Wire/examples/master_reader_custombuffer/master_reader_custombuffer.ino b/libraries/Wire/examples/master_reader_custombuffer/master_reader_custombuffer.ino index ab6abf93..197f5977 100644 --- a/libraries/Wire/examples/master_reader_custombuffer/master_reader_custombuffer.ino +++ b/libraries/Wire/examples/master_reader_custombuffer/master_reader_custombuffer.ino @@ -11,31 +11,27 @@ #include #include +#include "Arduino.h" + +#define USE_WIRE1 false // Set to true for using Wire1 // request 6 bytes from slave device #8 -size_t constexpr REQUESTED_BYTE_COUNT = 6; - -/**** Begin Customize buffers ****/ -// Note: If you spell namespace 'WireBuffers' wrongly, all buffer -// sizes of the 'Wire' object stay at default (32 bytes). -namespace WireBuffers { - size_t constexpr RECEIVE_BUFFER_SIZE = REQUESTED_BYTE_COUNT; - size_t constexpr TRANSMIT_BUFFER_SIZE = 0; // There is no transmit in this sketch. - // We operate as a master only, so we use the macro that will set slave buffers to zero. - SET_BUFFERS_FOR_MASTER_ONLY(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE); -} -/**** End Customize buffers ******/ +constexpr size_t REQUESTED_BYTE_COUNT = 6; + +constexpr size_t RECEIVE_BUFFER_SIZE = REQUESTED_BYTE_COUNT; +constexpr size_t TRANSMIT_BUFFER_SIZE = 0; // There is no transmit in this sketch. + +#if not USE_WIRE1 -// This is just for curiosity. -// Set to false if you don't want to see actual buffer sizes on serial monitor. -#define VERBOSE true +SET_WIRE_BUFFERS(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE, + true /* master buffers needed */, false /* no slave buffers needed */ ); void setup() { Wire.begin(); // join I2C bus (address optional for master) Serial.begin(9600); // start serial for output -#if VERBOSE - printWireBuffers(); -#endif + + // This is just for curiosity and can be removed + printWireBuffersCapacity(Serial); } void loop() { @@ -50,16 +46,55 @@ void loop() { delay(500); } -#if VERBOSE -void printWireBuffers() { - delay(100); +void printWireBuffersCapacity(Stream& stream) { + const auto& buffers = GET_WIRE_BUFFERS(); + + stream.print("Wire transmit buffer size is "); + stream.println(buffers.txWireBufferCapacity()); + + stream.print("Wire receive buffer size is "); + stream.println(buffers.rxWireBufferCapacity()); + + stream.print("Wire service buffer size is "); + stream.println(buffers.srvWireBufferCapacity()); +} + +#else + +SET_WIRE1_BUFFERS(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE, + true /* master buffers needed */, false /* no slave buffers needed */ ); + +void setup() { + Wire1.begin(); // join I2C bus (address optional for master) + Serial.begin(9600); // start serial for output + + // This is just for curiosity and can be removed + printWire1BuffersCapacity(Serial); +} + +void loop() { + Wire1.requestFrom(8, REQUESTED_BYTE_COUNT); + + while (Wire1.available()) { // slave may send less than requested + char c = Wire1.read(); // receive a byte as character + Serial.print(c); // print the character + } Serial.println(); - Serial.print("Wire transmit buffer size is "); - Serial.println(Wire.txBufferCapacity()); - Serial.print("Wire receive buffer size is "); - Serial.println(Wire.rxBufferCapacity()); - Serial.print("Wire service buffer size is "); - Serial.println(Wire.srvBufferCapacity()); + delay(500); } + +void printWire1BuffersCapacity(Stream& stream) { + const auto& buffers = GET_WIRE1_BUFFERS(); + + stream.print("Wire1 transmit buffer size is "); + stream.println(buffers.txWireBufferCapacity()); + + stream.print("Wire1 receive buffer size is "); + stream.println(buffers.rxWireBufferCapacity()); + + stream.print("Wire1 service buffer size is "); + stream.println(buffers.srvWireBufferCapacity()); +} + #endif diff --git a/libraries/Wire/examples/master_writer/master_writer.ino b/libraries/Wire/examples/master_writer/master_writer.ino index ccaa0361..4028a5af 100644 --- a/libraries/Wire/examples/master_writer/master_writer.ino +++ b/libraries/Wire/examples/master_writer/master_writer.ino @@ -17,7 +17,7 @@ void setup() Wire.begin(); // join i2c bus (address optional for master) } -byte x = 0; +static byte x = 0; void loop() { diff --git a/libraries/Wire/examples/master_writer_custombuffer/master_writer_custombuffer.ino b/libraries/Wire/examples/master_writer_custombuffer/master_writer_custombuffer.ino index 40e28991..bb85c89a 100644 --- a/libraries/Wire/examples/master_writer_custombuffer/master_writer_custombuffer.ino +++ b/libraries/Wire/examples/master_writer_custombuffer/master_writer_custombuffer.ino @@ -11,31 +11,27 @@ #include #include +#include "Arduino.h" + +#define USE_WIRE1 false // Set to true for using Wire1 // The following text will not fit into the default buffer of 32 bytes. static const char text[] = "You really won't believe it, but x is "; -/**** Begin Customize buffers ****/ -// Note: If you spell namespace 'WireBuffers' wrongly, all buffer sizes -// of the 'Wire' object stay at default (32 bytes). -namespace WireBuffers { - size_t constexpr RECEIVE_BUFFER_SIZE = 0; // There is no receive in this sketch. - size_t constexpr TRANSMIT_BUFFER_SIZE = 42; // Enhance the buffer to 42 characters. - // We operate as a master only, so we use the macro that will set slave buffers to zero. - SET_BUFFERS_FOR_MASTER_ONLY(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE); -} -/**** End Customize buffers ******/ +size_t constexpr RECEIVE_BUFFER_SIZE = 0; // There is no receive in this sketch. +size_t constexpr TRANSMIT_BUFFER_SIZE = 42; // Enhance the buffer to 42 characters. -// This is just for curiosity. -// Set to false if you don't want to see actual buffer sizes on serial monitor. -#define VERBOSE true +#if not USE_WIRE1 + +SET_WIRE_BUFFERS(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE, + true /* master buffers needed */, false /* no slave buffers needed */ ); void setup() { Wire.begin(); // join I2C bus (address optional for master) -#if VERBOSE - Serial.begin(9600); // start serial for output - printWireBuffers(); -#endif + + // This is just for curiosity and can be removed + Serial.begin(9600); // start serial for output + printWireBuffersCapacity(Serial); } static byte x = 0; @@ -50,16 +46,55 @@ void loop() { delay(500); } -#if VERBOSE -void printWireBuffers() { - delay(100); - Serial.println(); - Serial.print("Wire transmit buffer size is "); - Serial.println(Wire.txBufferCapacity()); - Serial.print("Wire receive buffer size is "); - Serial.println(Wire.rxBufferCapacity()); - Serial.print("Wire service buffer size is "); - Serial.println(Wire.srvBufferCapacity()); +void printWireBuffersCapacity(Stream& stream) { + const auto& buffers = GET_WIRE_BUFFERS(); + + stream.print("Wire transmit buffer size is "); + stream.println(buffers.txWireBufferCapacity()); + + stream.print("Wire receive buffer size is "); + stream.println(buffers.rxWireBufferCapacity()); + + stream.print("Wire service buffer size is "); + stream.println(buffers.srvWireBufferCapacity()); +} + +#else + +SET_WIRE1_BUFFERS(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE, + true /* master buffers needed */, false /* no slave buffers needed */ ); + +void setup() { + Wire1.begin(); // join I2C bus (address optional for master) + + // This is just for curiosity and can be removed + Serial.begin(9600); // start serial for output + printWire1BuffersCapacity(Serial); +} + +static byte x = 0; + +void loop() { + Wire1.beginTransmission(8); // transmit to device #8 + Wire1.write(text); // sends five bytes + Wire1.write(x); // sends one byte + Wire1.endTransmission(); // stop transmitting + + x++; delay(500); } + +void printWire1BuffersCapacity(Stream& stream) { + const auto& buffers = GET_WIRE1_BUFFERS(); + + stream.print("Wire1 transmit buffer size is "); + stream.println(buffers.txWireBufferCapacity()); + + stream.print("Wire1 receive buffer size is "); + stream.println(buffers.rxWireBufferCapacity()); + + stream.print("Wire1 service buffer size is "); + stream.println(buffers.srvWireBufferCapacity()); +} + #endif diff --git a/libraries/Wire/examples/slave_receiver_custombuffer/slave_receiver_custombuffer.ino b/libraries/Wire/examples/slave_receiver_custombuffer/slave_receiver_custombuffer.ino index e80b9b1f..0374581e 100644 --- a/libraries/Wire/examples/slave_receiver_custombuffer/slave_receiver_custombuffer.ino +++ b/libraries/Wire/examples/slave_receiver_custombuffer/slave_receiver_custombuffer.ino @@ -11,29 +11,25 @@ #include #include +#include "Arduino.h" -/**** Begin Customize buffers ****/ -// Note: If you spell namespace 'WireBuffers' wrongly, all buffer sizes -// of the 'Wire' object stay at default (32 bytes). -namespace WireBuffers { - size_t constexpr RECEIVE_BUFFER_SIZE = 42; // Be able receive up to 42 characters in one message. - size_t constexpr TRANSMIT_BUFFER_SIZE = 0; // There is no transmit in this sketch. - // We operate as a slave only, so we use the macro that will set master buffers to zero. - SET_BUFFERS_FOR_SLAVE_ONLY(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE); -} -/**** End Customize buffers ******/ +#define USE_WIRE1 true // Set to true for using Wire1 + +size_t constexpr RECEIVE_BUFFER_SIZE = 42; // Be able receive up to 42 characters in one message. +size_t constexpr TRANSMIT_BUFFER_SIZE = 0; // There is no transmit in this sketch. -// This is just for curiosity. -// Set to false if you don't want to see actual buffer sizes on serial monitor. -#define VERBOSE true +#if not USE_WIRE1 + +SET_WIRE_BUFFERS(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE, + true /* master buffers needed */, false /* no slave buffers needed */ ); void setup() { Wire.begin(8); // join I2C bus with address #8 Wire.onReceive(receiveEvent); // register event Serial.begin(9600); // start serial for output -#if VERBOSE - printWireBuffers(); -#endif + + // This is just for curiosity and can be removed + printWireBuffersCapacity(Serial); } void loop() { @@ -51,16 +47,59 @@ void receiveEvent(int howMany) { Serial.println(x); // print the integer } -#if VERBOSE -void printWireBuffers() { +void printWireBuffersCapacity(Stream& stream) { + const auto& buffers = GET_WIRE_BUFFERS(); + + stream.print("Wire transmit buffer size is "); + stream.println(buffers.txWireBufferCapacity()); + + stream.print("Wire receive buffer size is "); + stream.println(buffers.rxWireBufferCapacity()); + + stream.print("Wire service buffer size is "); + stream.println(buffers.srvWireBufferCapacity()); +} + +#else + +SET_WIRE1_BUFFERS(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE, + true /* master buffers needed */, false /* no slave buffers needed */ ); + +void setup() { + Wire1.begin(8); // join I2C bus with address #8 + Wire1.onReceive(receiveEvent); // register event + Serial.begin(9600); // start serial for output + + // This is just for curiosity and can be removed + printWire1BuffersCapacity(Serial); +} + +void loop() { delay(100); - Serial.println(); - Serial.print("Wire transmit buffer size is "); - Serial.println(Wire.txBufferCapacity()); - Serial.print("Wire receive buffer size is "); - Serial.println(Wire.rxBufferCapacity()); - Serial.print("Wire service buffer size is "); - Serial.println(Wire.srvBufferCapacity()); - delay(500); } + +// function that executes whenever data is received from master +// this function is registered as an event, see setup() +void receiveEvent(int howMany) { + while (1 < Wire1.available()) { // loop through all but the last + char c = Wire1.read(); // receive byte as a character + Serial.print(c); // print the character + } + int x = Wire1.read(); // receive byte as an integer + Serial.println(x); // print the integer +} + +void printWire1BuffersCapacity(Stream& stream) { + const auto& buffers = GET_WIRE1_BUFFERS(); + + stream.print("Wire1 transmit buffer size is "); + stream.println(buffers.txWireBufferCapacity()); + + stream.print("Wire1 receive buffer size is "); + stream.println(buffers.rxWireBufferCapacity()); + + stream.print("Wire1 service buffer size is "); + stream.println(buffers.srvWireBufferCapacity()); +} + #endif diff --git a/libraries/Wire/examples/slave_sender_custombuffer/slave_sender_custombuffer.ino b/libraries/Wire/examples/slave_sender_custombuffer/slave_sender_custombuffer.ino index a824e946..845ec651 100644 --- a/libraries/Wire/examples/slave_sender_custombuffer/slave_sender_custombuffer.ino +++ b/libraries/Wire/examples/slave_sender_custombuffer/slave_sender_custombuffer.ino @@ -11,31 +11,27 @@ #include #include +#include "Arduino.h" + +#define USE_WIRE1 false // Set to true for using Wire1 static const char text[] = "hello "; // respond with message of 6 bytes -/**** Begin Customize buffers ****/ -// Note: If you spell namespace 'WireBuffers' wrongly, all buffer sizes -// of the 'Wire' object stay at default (32 bytes). -namespace WireBuffers { - size_t constexpr RECEIVE_BUFFER_SIZE = 0; // There is no receive in this sketch. - size_t constexpr TRANSMIT_BUFFER_SIZE = sizeof(text)-1; // Don't need a byte for the \0 - // We operate as a slave only, so we use the macro that will set master buffers to zero. - SET_BUFFERS_FOR_SLAVE_ONLY(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE); -} -/**** End Customize buffers ******/ +size_t constexpr RECEIVE_BUFFER_SIZE = 0; // There is no receive in this sketch. +size_t constexpr TRANSMIT_BUFFER_SIZE = sizeof(text)-1; // Don't need a byte for the \0 -// This is just for curiosity. -// Set to false if you don't want to see actual buffer sizes on serial monitor. -#define VERBOSE true +#if not USE_WIRE1 + +SET_WIRE_BUFFERS(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE, + true /* master buffers needed */, false /* no slave buffers needed */ ); void setup() { Wire.begin(8); // join I2C bus with address #8 Wire.onRequest(requestEvent); // register event -#if VERBOSE - Serial.begin(9600); // start serial for output - printWireBuffers(); -#endif + + // This is just for curiosity and can be removed + Serial.begin(9600); + printWireBuffersCapacity(Serial); } void loop() { @@ -49,16 +45,55 @@ void requestEvent() { // as expected by master } -#if VERBOSE -void printWireBuffers() { +void printWireBuffersCapacity(Stream& stream) { + const auto& buffers = GET_WIRE_BUFFERS(); + + stream.print("Wire transmit buffer size is "); + stream.println(buffers.txWireBufferCapacity()); + + stream.print("Wire receive buffer size is "); + stream.println(buffers.rxWireBufferCapacity()); + + stream.print("Wire service buffer size is "); + stream.println(buffers.srvWireBufferCapacity()); +} + +#else + +SET_WIRE1_BUFFERS(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE, + true /* master buffers needed */, false /* no slave buffers needed */ ); + +void setup() { + Wire1.begin(8); // join I2C bus with address #8 + Wire1.onRequest(requestEvent); // register event + + // This is just for curiosity and can be removed + Serial.begin(9600); + printWire1BuffersCapacity(Serial); +} + +void loop() { delay(100); - Serial.println(); - Serial.print("Wire transmit buffer size is "); - Serial.println(Wire.txBufferCapacity()); - Serial.print("Wire receive buffer size is "); - Serial.println(Wire.rxBufferCapacity()); - Serial.print("Wire service buffer size is "); - Serial.println(Wire.srvBufferCapacity()); - delay(500); } + +// function that executes whenever data is requested by master +// this function is registered as an event, see setup() +void requestEvent() { + Wire1.write(text); + // as expected by master +} + +void printWire1BuffersCapacity(Stream& stream) { + const auto& buffers = GET_WIRE_BUFFERS(); + + stream.print("Wire1 transmit buffer size is "); + stream.println(buffers.txWireBufferCapacity()); + + stream.print("Wire1 receive buffer size is "); + stream.println(buffers.rxWireBufferCapacity()); + + stream.print("Wire1 service buffer size is "); + stream.println(buffers.srvWireBufferCapacity()); +} + #endif diff --git a/libraries/Wire/src/TwoWireBuffers.cpp b/libraries/Wire/src/TwoWireBuffers.cpp index b070504e..0244dff3 100644 --- a/libraries/Wire/src/TwoWireBuffers.cpp +++ b/libraries/Wire/src/TwoWireBuffers.cpp @@ -25,14 +25,16 @@ constexpr size_t TX_BUFFER_DEFAULT_LENGTH = 32; #if WIRE_INTERFACES_COUNT > 0 // Default buffers for the Wire object -namespace WireBuffers { - __attribute__((weak)) SET_BUFFERS_FOR_BOTH(RX_BUFFER_DEFAULT_LENGTH, TX_BUFFER_DEFAULT_LENGTH); -} // namespace Twi +template<> __attribute__((weak)) TwoWireBuffers::Interface& WireBuffers<0>::instance() { \ + static TwoWireBuffers::Impl buffers; \ + return buffers; \ +} #endif #if WIRE_INTERFACES_COUNT > 1 // Default buffers for the Wire1 object -namespace Wire1Buffers { - __attribute__((weak)) SET_BUFFERS_FOR_BOTH(RX_BUFFER_DEFAULT_LENGTH, TX_BUFFER_DEFAULT_LENGTH); -} // namespace Twi +template<> __attribute__((weak)) TwoWireBuffers::Interface& WireBuffers<1>::instance() { \ + static TwoWireBuffers::Impl buffers; \ + return buffers; \ +} #endif diff --git a/libraries/Wire/src/TwoWireBuffers.h b/libraries/Wire/src/TwoWireBuffers.h index 4ab6bf10..03725082 100644 --- a/libraries/Wire/src/TwoWireBuffers.h +++ b/libraries/Wire/src/TwoWireBuffers.h @@ -26,6 +26,7 @@ #include #include +#include namespace TwoWireBuffers { @@ -51,13 +52,13 @@ class StaticBuffer<0> { class Interface { public: virtual uint8_t* rxWireBuffer() = 0; - virtual size_t rxWireBufferCapacity() = 0; + virtual size_t rxWireBufferCapacity()const = 0; virtual uint8_t* txWireBuffer() = 0; - virtual size_t txWireBufferCapacity() = 0; + virtual size_t txWireBufferCapacity()const = 0; virtual uint8_t* srvWireBuffer() = 0; - virtual size_t srvWireBufferCapacity() = 0; + virtual size_t srvWireBufferCapacity()const = 0; }; /* Template class implementing Interface with template parameter @@ -79,29 +80,41 @@ class Impl : public Interface { public: virtual uint8_t* rxWireBuffer() override {return mRxWireBuffer.storage();} - virtual size_t rxWireBufferCapacity() override {return mRxWireBuffer.capacity();} + virtual size_t rxWireBufferCapacity()const override {return mRxWireBuffer.capacity();} virtual uint8_t* txWireBuffer() override {return mTxWireBuffer.storage();} - virtual size_t txWireBufferCapacity() override {return mTxWireBuffer.capacity();} + virtual size_t txWireBufferCapacity()const override {return mTxWireBuffer.capacity();} virtual uint8_t* srvWireBuffer() override {return mSrvWireBuffer.storage();} - virtual size_t srvWireBufferCapacity() override {return mSrvWireBuffer.capacity();} + virtual size_t srvWireBufferCapacity()const override {return mSrvWireBuffer.capacity();} }; } // namespace TwoWireBuffers -#define SET_BUFFERS_FOR_BOTH(RX_BUFFER_CAPACITY, TX_BUFFER_CAPACITY) \ - TwoWireBuffers::Interface& instance() { \ - static TwoWireBuffers::Impl instance; \ - return instance; \ +template struct WireBuffers { // The buffers for the Wire object + static TwoWireBuffers::Interface& instance(); +}; + +#define SET_WIRE_BUFFERS_(wireNum, rxBufferCapacity, txBufferCapacity, enableMaster, enableSlave) \ + template<> TwoWireBuffers::Interface& WireBuffers::instance() { \ + static TwoWireBuffers::Impl buffers; \ + return buffers; \ } -// This macro is just for compatibility reasons with AVR core -#define SET_BUFFERS_FOR_MASTER_ONLY(RX_BUFFER_CAPACITY, TX_BUFFER_CAPACITY) \ - SET_BUFFERS_FOR_BOTH(RX_BUFFER_CAPACITY, TX_BUFFER_CAPACITY) +#define GET_WIRE_BUFFERS_(wireNum) WireBuffers::instance() + +#if WIRE_INTERFACES_COUNT > 0 + #define SET_WIRE_BUFFERS(rxBufferCapacity, txBufferCapacity, enableMaster, enableSlave) \ + SET_WIRE_BUFFERS_(0, rxBufferCapacity, txBufferCapacity, enableMaster, enableSlave) + + #define GET_WIRE_BUFFERS() GET_WIRE_BUFFERS_(0) +#endif + +#if WIRE_INTERFACES_COUNT > 1 + #define SET_WIRE1_BUFFERS(rxBufferCapacity, txBufferCapacity, enableMaster, enableSlave) \ + SET_WIRE_BUFFERS_(1, rxBufferCapacity, txBufferCapacity, enableMaster, enableSlave) -// This macro is just for compatibility reasons with AVR core -#define SET_BUFFERS_FOR_SLAVE_ONLY(RX_BUFFER_CAPACITY, TX_BUFFER_CAPACITY) \ - SET_BUFFERS_FOR_BOTH(RX_BUFFER_CAPACITY, TX_BUFFER_CAPACITY) + #define GET_WIRE1_BUFFERS() GET_WIRE_BUFFERS_(1) +#endif #endif /* TwiBuffers_h */ diff --git a/libraries/Wire/src/Wire.cpp b/libraries/Wire/src/Wire.cpp index d82ccdba..85b83948 100644 --- a/libraries/Wire/src/Wire.cpp +++ b/libraries/Wire/src/Wire.cpp @@ -403,7 +403,7 @@ static void Wire_Deinit(void) { // and pullups were not enabled } -TwoWire Wire = TwoWire(WireBuffers::instance(), WIRE_INTERFACE, Wire_Init, Wire_Deinit); +TwoWire Wire = TwoWire(WireBuffers<0>::instance(), WIRE_INTERFACE, Wire_Init, Wire_Deinit); void WIRE_ISR_HANDLER(void) { Wire.onService(); @@ -441,7 +441,7 @@ static void Wire1_Deinit(void) { // and pullups were not enabled } -TwoWire Wire1 = TwoWire(Wire1Buffers::instance(), WIRE1_INTERFACE, Wire1_Init, Wire1_Deinit); +TwoWire Wire1 = TwoWire(WireBuffers<1>::instance(), WIRE1_INTERFACE, Wire1_Init, Wire1_Deinit); void WIRE1_ISR_HANDLER(void) { Wire1.onService(); diff --git a/libraries/Wire/src/Wire.h b/libraries/Wire/src/Wire.h index cbf36aac..5e5be3f8 100644 --- a/libraries/Wire/src/Wire.h +++ b/libraries/Wire/src/Wire.h @@ -140,12 +140,10 @@ class TwoWire : public Stream { #if WIRE_INTERFACES_COUNT > 0 // The buffers for the Wire object -namespace WireBuffers {extern TwoWireBuffers::Interface& instance();} extern TwoWire Wire; #endif #if WIRE_INTERFACES_COUNT > 1 // The buffers for the Wire1 object -namespace Wire1Buffers {extern TwoWireBuffers::Interface& instance();} extern TwoWire Wire1; #endif From 3a4d54d7383494089793c7b0abb356781eb657bb Mon Sep 17 00:00:00 2001 From: dac1e Date: Wed, 1 Jan 2025 18:39:29 +0100 Subject: [PATCH 08/17] Apply const qualifiers in examples. Repositioned constexpr. --- .../master_reader_custombuffer.ino | 4 ++-- .../master_writer_custombuffer.ino | 12 ++++++------ .../slave_receiver_custombuffer.ino | 14 +++++++------- .../slave_sender_custombuffer.ino | 4 ++-- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/libraries/Wire/examples/master_reader_custombuffer/master_reader_custombuffer.ino b/libraries/Wire/examples/master_reader_custombuffer/master_reader_custombuffer.ino index 197f5977..e91cd8f8 100644 --- a/libraries/Wire/examples/master_reader_custombuffer/master_reader_custombuffer.ino +++ b/libraries/Wire/examples/master_reader_custombuffer/master_reader_custombuffer.ino @@ -38,7 +38,7 @@ void loop() { Wire.requestFrom(8, REQUESTED_BYTE_COUNT); while (Wire.available()) { // slave may send less than requested - char c = Wire.read(); // receive a byte as character + const char c = Wire.read(); // receive a byte as character Serial.print(c); // print the character } Serial.println(); @@ -76,7 +76,7 @@ void loop() { Wire1.requestFrom(8, REQUESTED_BYTE_COUNT); while (Wire1.available()) { // slave may send less than requested - char c = Wire1.read(); // receive a byte as character + const char c = Wire1.read(); // receive a byte as character Serial.print(c); // print the character } Serial.println(); diff --git a/libraries/Wire/examples/master_writer_custombuffer/master_writer_custombuffer.ino b/libraries/Wire/examples/master_writer_custombuffer/master_writer_custombuffer.ino index bb85c89a..79e04ac5 100644 --- a/libraries/Wire/examples/master_writer_custombuffer/master_writer_custombuffer.ino +++ b/libraries/Wire/examples/master_writer_custombuffer/master_writer_custombuffer.ino @@ -18,8 +18,8 @@ // The following text will not fit into the default buffer of 32 bytes. static const char text[] = "You really won't believe it, but x is "; -size_t constexpr RECEIVE_BUFFER_SIZE = 0; // There is no receive in this sketch. -size_t constexpr TRANSMIT_BUFFER_SIZE = 42; // Enhance the buffer to 42 characters. +constexpr size_t RECEIVE_BUFFER_SIZE = 0; // There is no receive in this sketch. +constexpr size_t TRANSMIT_BUFFER_SIZE = 42; // Enhance the buffer to 42 characters. #if not USE_WIRE1 @@ -38,8 +38,8 @@ static byte x = 0; void loop() { Wire.beginTransmission(8); // transmit to device #8 - Wire.write(text); // sends five bytes - Wire.write(x); // sends one byte + Wire.write(text); // sends multiple bytes + Wire.write(x); // sends one byte Wire.endTransmission(); // stop transmitting x++; @@ -76,8 +76,8 @@ static byte x = 0; void loop() { Wire1.beginTransmission(8); // transmit to device #8 - Wire1.write(text); // sends five bytes - Wire1.write(x); // sends one byte + Wire1.write(text); // sends multiple bytes + Wire1.write(x); // sends one byte Wire1.endTransmission(); // stop transmitting x++; diff --git a/libraries/Wire/examples/slave_receiver_custombuffer/slave_receiver_custombuffer.ino b/libraries/Wire/examples/slave_receiver_custombuffer/slave_receiver_custombuffer.ino index 0374581e..395a44de 100644 --- a/libraries/Wire/examples/slave_receiver_custombuffer/slave_receiver_custombuffer.ino +++ b/libraries/Wire/examples/slave_receiver_custombuffer/slave_receiver_custombuffer.ino @@ -13,10 +13,10 @@ #include #include "Arduino.h" -#define USE_WIRE1 true // Set to true for using Wire1 +#define USE_WIRE1 false // Set to true for using Wire1 -size_t constexpr RECEIVE_BUFFER_SIZE = 42; // Be able receive up to 42 characters in one message. -size_t constexpr TRANSMIT_BUFFER_SIZE = 0; // There is no transmit in this sketch. +constexpr size_t RECEIVE_BUFFER_SIZE = 42; // Be able receive up to 42 characters in one message. +constexpr size_t TRANSMIT_BUFFER_SIZE = 0; // There is no transmit in this sketch. #if not USE_WIRE1 @@ -40,10 +40,10 @@ void loop() { // this function is registered as an event, see setup() void receiveEvent(int howMany) { while (1 < Wire.available()) { // loop through all but the last - char c = Wire.read(); // receive byte as a character + const char c = Wire.read(); // receive byte as a character Serial.print(c); // print the character } - int x = Wire.read(); // receive byte as an integer + const int x = Wire.read(); // receive byte as an integer Serial.println(x); // print the integer } @@ -82,10 +82,10 @@ void loop() { // this function is registered as an event, see setup() void receiveEvent(int howMany) { while (1 < Wire1.available()) { // loop through all but the last - char c = Wire1.read(); // receive byte as a character + const char c = Wire1.read(); // receive byte as a character Serial.print(c); // print the character } - int x = Wire1.read(); // receive byte as an integer + const int x = Wire1.read(); // receive byte as an integer Serial.println(x); // print the integer } diff --git a/libraries/Wire/examples/slave_sender_custombuffer/slave_sender_custombuffer.ino b/libraries/Wire/examples/slave_sender_custombuffer/slave_sender_custombuffer.ino index 845ec651..9987e32d 100644 --- a/libraries/Wire/examples/slave_sender_custombuffer/slave_sender_custombuffer.ino +++ b/libraries/Wire/examples/slave_sender_custombuffer/slave_sender_custombuffer.ino @@ -17,8 +17,8 @@ static const char text[] = "hello "; // respond with message of 6 bytes -size_t constexpr RECEIVE_BUFFER_SIZE = 0; // There is no receive in this sketch. -size_t constexpr TRANSMIT_BUFFER_SIZE = sizeof(text)-1; // Don't need a byte for the \0 +constexpr size_t RECEIVE_BUFFER_SIZE = 0; // There is no receive in this sketch. +constexpr size_t TRANSMIT_BUFFER_SIZE = sizeof(text)-1; // Don't need a byte for the \0 #if not USE_WIRE1 From 7885765aeaa759b34bdda6b2f5ced081165786bc Mon Sep 17 00:00:00 2001 From: dac1e Date: Wed, 1 Jan 2025 18:48:49 +0100 Subject: [PATCH 09/17] Fixed wrong master slave buffer configuration in examples. --- .../master_reader_custombuffer.ino | 4 ++-- .../master_writer_custombuffer.ino | 4 ++-- .../slave_receiver_custombuffer.ino | 8 ++++---- .../slave_sender_custombuffer.ino | 8 ++++---- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/libraries/Wire/examples/master_reader_custombuffer/master_reader_custombuffer.ino b/libraries/Wire/examples/master_reader_custombuffer/master_reader_custombuffer.ino index e91cd8f8..7ab669f1 100644 --- a/libraries/Wire/examples/master_reader_custombuffer/master_reader_custombuffer.ino +++ b/libraries/Wire/examples/master_reader_custombuffer/master_reader_custombuffer.ino @@ -30,7 +30,7 @@ void setup() { Wire.begin(); // join I2C bus (address optional for master) Serial.begin(9600); // start serial for output - // This is just for curiosity and can be removed + // This is just for curiosity and could be removed printWireBuffersCapacity(Serial); } @@ -68,7 +68,7 @@ void setup() { Wire1.begin(); // join I2C bus (address optional for master) Serial.begin(9600); // start serial for output - // This is just for curiosity and can be removed + // This is just for curiosity and could be removed printWire1BuffersCapacity(Serial); } diff --git a/libraries/Wire/examples/master_writer_custombuffer/master_writer_custombuffer.ino b/libraries/Wire/examples/master_writer_custombuffer/master_writer_custombuffer.ino index 79e04ac5..4d73929e 100644 --- a/libraries/Wire/examples/master_writer_custombuffer/master_writer_custombuffer.ino +++ b/libraries/Wire/examples/master_writer_custombuffer/master_writer_custombuffer.ino @@ -29,7 +29,7 @@ SET_WIRE_BUFFERS(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE, void setup() { Wire.begin(); // join I2C bus (address optional for master) - // This is just for curiosity and can be removed + // This is just for curiosity and could be removed Serial.begin(9600); // start serial for output printWireBuffersCapacity(Serial); } @@ -67,7 +67,7 @@ SET_WIRE1_BUFFERS(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE, void setup() { Wire1.begin(); // join I2C bus (address optional for master) - // This is just for curiosity and can be removed + // This is just for curiosity and could be removed Serial.begin(9600); // start serial for output printWire1BuffersCapacity(Serial); } diff --git a/libraries/Wire/examples/slave_receiver_custombuffer/slave_receiver_custombuffer.ino b/libraries/Wire/examples/slave_receiver_custombuffer/slave_receiver_custombuffer.ino index 395a44de..5f62fe70 100644 --- a/libraries/Wire/examples/slave_receiver_custombuffer/slave_receiver_custombuffer.ino +++ b/libraries/Wire/examples/slave_receiver_custombuffer/slave_receiver_custombuffer.ino @@ -21,14 +21,14 @@ constexpr size_t TRANSMIT_BUFFER_SIZE = 0; // There is no transmit in this sket #if not USE_WIRE1 SET_WIRE_BUFFERS(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE, - true /* master buffers needed */, false /* no slave buffers needed */ ); + false /* no master buffers needed */, true /* slave buffers needed */ ); void setup() { Wire.begin(8); // join I2C bus with address #8 Wire.onReceive(receiveEvent); // register event Serial.begin(9600); // start serial for output - // This is just for curiosity and can be removed + // This is just for curiosity and could be removed printWireBuffersCapacity(Serial); } @@ -63,14 +63,14 @@ void printWireBuffersCapacity(Stream& stream) { #else SET_WIRE1_BUFFERS(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE, - true /* master buffers needed */, false /* no slave buffers needed */ ); + false /* no master buffers needed */, true /* slave buffers needed */ ); void setup() { Wire1.begin(8); // join I2C bus with address #8 Wire1.onReceive(receiveEvent); // register event Serial.begin(9600); // start serial for output - // This is just for curiosity and can be removed + // This is just for curiosity and could be removed printWire1BuffersCapacity(Serial); } diff --git a/libraries/Wire/examples/slave_sender_custombuffer/slave_sender_custombuffer.ino b/libraries/Wire/examples/slave_sender_custombuffer/slave_sender_custombuffer.ino index 9987e32d..b72e6ca7 100644 --- a/libraries/Wire/examples/slave_sender_custombuffer/slave_sender_custombuffer.ino +++ b/libraries/Wire/examples/slave_sender_custombuffer/slave_sender_custombuffer.ino @@ -23,13 +23,13 @@ constexpr size_t TRANSMIT_BUFFER_SIZE = sizeof(text)-1; // Don't need a byte for #if not USE_WIRE1 SET_WIRE_BUFFERS(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE, - true /* master buffers needed */, false /* no slave buffers needed */ ); + false /* no master buffers needed */, true /* slave buffers needed */ ); void setup() { Wire.begin(8); // join I2C bus with address #8 Wire.onRequest(requestEvent); // register event - // This is just for curiosity and can be removed + // This is just for curiosity and could be removed Serial.begin(9600); printWireBuffersCapacity(Serial); } @@ -61,13 +61,13 @@ void printWireBuffersCapacity(Stream& stream) { #else SET_WIRE1_BUFFERS(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE, - true /* master buffers needed */, false /* no slave buffers needed */ ); + false /* no master buffers needed */, true /* slave buffers needed */ ); void setup() { Wire1.begin(8); // join I2C bus with address #8 Wire1.onRequest(requestEvent); // register event - // This is just for curiosity and can be removed + // This is just for curiosity and could be removed Serial.begin(9600); printWire1BuffersCapacity(Serial); } From 8b016ebae81cf6c3dac70574f107c78668825ba3 Mon Sep 17 00:00:00 2001 From: dac1e Date: Thu, 2 Jan 2025 09:31:03 +0100 Subject: [PATCH 10/17] Added example slave_senderWire1Wire_connected. --- .../master_reader_custombuffer.ino | 2 +- .../master_writer_custombuffer.ino | 2 +- .../slave_receiver_custombuffer.ino | 2 +- .../slave_sender_Wire1Wire_connected.ino | 94 +++++++++++++++++++ .../slave_sender_custombuffer.ino | 2 +- 5 files changed, 98 insertions(+), 4 deletions(-) create mode 100644 libraries/Wire/examples/slave_sender_Wire1Wire_connected/slave_sender_Wire1Wire_connected.ino diff --git a/libraries/Wire/examples/master_reader_custombuffer/master_reader_custombuffer.ino b/libraries/Wire/examples/master_reader_custombuffer/master_reader_custombuffer.ino index 7ab669f1..20cb207f 100644 --- a/libraries/Wire/examples/master_reader_custombuffer/master_reader_custombuffer.ino +++ b/libraries/Wire/examples/master_reader_custombuffer/master_reader_custombuffer.ino @@ -1,6 +1,6 @@ // Wire Master Reader Custom Buffer -// Demonstrates use of the Wire library +// Demonstrates use of the Wire library with customized buffers // Reads data from an I2C/TWI slave device // Refer to the "Wire Slave Sender Custom Buffer" example for use with this diff --git a/libraries/Wire/examples/master_writer_custombuffer/master_writer_custombuffer.ino b/libraries/Wire/examples/master_writer_custombuffer/master_writer_custombuffer.ino index 4d73929e..8affd251 100644 --- a/libraries/Wire/examples/master_writer_custombuffer/master_writer_custombuffer.ino +++ b/libraries/Wire/examples/master_writer_custombuffer/master_writer_custombuffer.ino @@ -1,6 +1,6 @@ // Wire Master Writer Custom Buffer -// Demonstrates use of the Wire library +// Demonstrates use of the Wire library with customized buffers // Writes data to an I2C/TWI slave device // Refer to the "Wire Slave Receiver Custom Buffer" example for use with this diff --git a/libraries/Wire/examples/slave_receiver_custombuffer/slave_receiver_custombuffer.ino b/libraries/Wire/examples/slave_receiver_custombuffer/slave_receiver_custombuffer.ino index 5f62fe70..b4638683 100644 --- a/libraries/Wire/examples/slave_receiver_custombuffer/slave_receiver_custombuffer.ino +++ b/libraries/Wire/examples/slave_receiver_custombuffer/slave_receiver_custombuffer.ino @@ -1,6 +1,6 @@ // Wire Slave Receiver Custom Buffer -// Demonstrates use of the Wire library +// Demonstrates use of the Wire library with customized buffers // Receives data as an I2C/TWI slave device // Refer to the "Wire Master Writer Custom Buffer" example for use with this diff --git a/libraries/Wire/examples/slave_sender_Wire1Wire_connected/slave_sender_Wire1Wire_connected.ino b/libraries/Wire/examples/slave_sender_Wire1Wire_connected/slave_sender_Wire1Wire_connected.ino new file mode 100644 index 00000000..2f8b7d6b --- /dev/null +++ b/libraries/Wire/examples/slave_sender_Wire1Wire_connected/slave_sender_Wire1Wire_connected.ino @@ -0,0 +1,94 @@ +// Wire1Wire connected (scl <-> scl1, sda <-> sda1) + +// Demonstrates use of the Wire library on a single Arduino board +// with 2 Wire interfaces (like Arduino Due). +// Uses the option of customizing the buffers. +// +// Wire reads data from an I2C/TWI slave device +// Wire1 sends data as an I2C/TWI slave device + +// Created 02 Jan 2025 + +// This example code is in the public domain. + + +#include +#include +#include "Arduino.h" + +#if WIRE_INTERFACES_COUNT > 1 + +static const char text[] = "hello "; // respond with message of 6 bytes + +// Wire is the master reader +constexpr size_t M_RECEIVE_BUFFER_SIZE = sizeof(text)-1; // Don't need a byte for the \0 +constexpr size_t M_TRANSMIT_BUFFER_SIZE = 0; // There is no transmit in this sketch. +SET_WIRE_BUFFERS(M_RECEIVE_BUFFER_SIZE, M_TRANSMIT_BUFFER_SIZE, + true /* master buffers needed */, false /* no slave buffers needed */ ); + +// Wire1 is the slave sender +constexpr size_t S_RECEIVE_BUFFER_SIZE = 0; // There is no receive in this sketch. +constexpr size_t S_TRANSMIT_BUFFER_SIZE = sizeof(text)-1; // Don't need a byte for the \0 +SET_WIRE1_BUFFERS(S_RECEIVE_BUFFER_SIZE, S_TRANSMIT_BUFFER_SIZE, + false /* no master buffers needed */, true /* slave buffers needed */ ); + +void setup() { + Serial.begin(9600); // start serial for output + + Wire.begin(); // master joins I2C bus (address optional for master) + Wire1.begin(8); // slave joins I2C bus with address #8 + Wire1.onRequest(requestEvent); // register slave event + + // This is just for curiosity and could be removed + printWireBuffersCapacity(Serial); + printWire1BuffersCapacity(Serial); +} + +void loop() { + Wire.requestFrom(8, M_RECEIVE_BUFFER_SIZE); + + while (Wire.available()) { + const char c = Wire.read(); // receive a byte as character + Serial.print(c); // print the character + } + Serial.println(); + + delay(500); +} + +// function that executes whenever data is requested by master +// this function is registered as an event, see setup() +void requestEvent() { + Wire1.write(text); + // as expected by master +} + +// print Wire buffer sizes +void printWireBuffersCapacity(Stream& stream) { + const auto& buffers = GET_WIRE_BUFFERS(); + + stream.print("Wire transmit buffer size is "); + stream.println(buffers.txWireBufferCapacity()); + + stream.print("Wire receive buffer size is "); + stream.println(buffers.rxWireBufferCapacity()); + + stream.print("Wire service buffer size is "); + stream.println(buffers.srvWireBufferCapacity()); +} + +// print Wire1 buffer sizes +void printWire1BuffersCapacity(Stream& stream) { + const auto& buffers = GET_WIRE_BUFFERS(); + + stream.print("Wire1 transmit buffer size is "); + stream.println(buffers.txWireBufferCapacity()); + + stream.print("Wire1 receive buffer size is "); + stream.println(buffers.rxWireBufferCapacity()); + + stream.print("Wire1 service buffer size is "); + stream.println(buffers.srvWireBufferCapacity()); +} + +#endif diff --git a/libraries/Wire/examples/slave_sender_custombuffer/slave_sender_custombuffer.ino b/libraries/Wire/examples/slave_sender_custombuffer/slave_sender_custombuffer.ino index b72e6ca7..637f6fc4 100644 --- a/libraries/Wire/examples/slave_sender_custombuffer/slave_sender_custombuffer.ino +++ b/libraries/Wire/examples/slave_sender_custombuffer/slave_sender_custombuffer.ino @@ -1,6 +1,6 @@ // Wire Slave Sender Custom Buffer -// Demonstrates use of the Wire library +// Demonstrates use of the Wire library with customized buffers // Sends data as an I2C/TWI slave device // Refer to the "Wire Master Reader Custom Buffer" example for use with this From 90d0841970c955591a263d60f657666716c841d3 Mon Sep 17 00:00:00 2001 From: dac1e Date: Thu, 2 Jan 2025 10:37:08 +0100 Subject: [PATCH 11/17] Added hint about receiveEvent interrupt context. Added exampoe slave_receiver_Wire1Wire_connected. --- .../master_reader_custombuffer.ino | 2 +- .../slave_receiver/slave_receiver.ino | 5 + .../slave_receiver_Wire1Wire_connected.ino | 102 ++++++++++++++++++ .../slave_receiver_custombuffer.ino | 30 ++++-- .../slave_sender_Wire1Wire_connected.ino | 3 +- 5 files changed, 130 insertions(+), 12 deletions(-) create mode 100644 libraries/Wire/examples/slave_receiver_Wire1Wire_connected/slave_receiver_Wire1Wire_connected.ino diff --git a/libraries/Wire/examples/master_reader_custombuffer/master_reader_custombuffer.ino b/libraries/Wire/examples/master_reader_custombuffer/master_reader_custombuffer.ino index 20cb207f..f818892c 100644 --- a/libraries/Wire/examples/master_reader_custombuffer/master_reader_custombuffer.ino +++ b/libraries/Wire/examples/master_reader_custombuffer/master_reader_custombuffer.ino @@ -66,7 +66,7 @@ SET_WIRE1_BUFFERS(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE, void setup() { Wire1.begin(); // join I2C bus (address optional for master) - Serial.begin(9600); // start serial for output + Serial.begin(9600); // start serial for output // This is just for curiosity and could be removed printWire1BuffersCapacity(Serial); diff --git a/libraries/Wire/examples/slave_receiver/slave_receiver.ino b/libraries/Wire/examples/slave_receiver/slave_receiver.ino index 60dd4bdd..1fb2037f 100644 --- a/libraries/Wire/examples/slave_receiver/slave_receiver.ino +++ b/libraries/Wire/examples/slave_receiver/slave_receiver.ino @@ -26,6 +26,11 @@ void loop() // function that executes whenever data is received from master // this function is registered as an event, see setup() +// +// Hint: This function is called within an interrupt context. +// That means, that there must be enough space in the Serial output +// buffer for the characters to be printed. Otherwise the +// Serial.print() call will lock up. void receiveEvent(int howMany) { while(1 < Wire.available()) // loop through all but the last diff --git a/libraries/Wire/examples/slave_receiver_Wire1Wire_connected/slave_receiver_Wire1Wire_connected.ino b/libraries/Wire/examples/slave_receiver_Wire1Wire_connected/slave_receiver_Wire1Wire_connected.ino new file mode 100644 index 00000000..e1f38d17 --- /dev/null +++ b/libraries/Wire/examples/slave_receiver_Wire1Wire_connected/slave_receiver_Wire1Wire_connected.ino @@ -0,0 +1,102 @@ +// Wire1 connnected to Wire. (scl <-> scl1, sda <-> sda1) + +// Demonstrates use of the Wire library on a single Arduino board +// with 2 Wire interfaces (like Arduino Due). +// Uses the option of customizing the buffers. +// +// Wire data to an I2C/TWI slave device +// Wire1 receives data as an I2C/TWI slave device + +// Created 02 Jan 2025 + +// This example code is in the public domain. + + +#include +#include +#include "Arduino.h" + +#if WIRE_INTERFACES_COUNT > 1 + +static const char text[] = "You really won't believe it, but x is "; + +// Wire is the master writer +constexpr size_t M_RECEIVE_BUFFER_SIZE = 0; // There is no receive in this sketch. +constexpr size_t M_TRANSMIT_BUFFER_SIZE = 42; // Enhance the buffer to 42 characters. +SET_WIRE_BUFFERS(M_RECEIVE_BUFFER_SIZE, M_TRANSMIT_BUFFER_SIZE, + true /* master buffers needed */, false /* no slave buffers needed */ ); + +// Wire1 is the slave receiver +constexpr size_t S_RECEIVE_BUFFER_SIZE = 42; // Be able receive up to 42 characters in one message. +constexpr size_t S_TRANSMIT_BUFFER_SIZE = 0; // There is no transmit in this sketch. +SET_WIRE1_BUFFERS(S_RECEIVE_BUFFER_SIZE, S_TRANSMIT_BUFFER_SIZE, + false /* no master buffers needed */, true /* slave buffers needed */ ); + +void setup() { + Serial.begin(9600); // start serial for output + Wire.begin(); // master joins I2C bus (address optional for master) + Wire1.begin(8); // slave joins I2C bus with address #8 + Wire1.onReceive(receiveEvent); // register event + + // This is just for curiosity and could be removed + printWireBuffersCapacity(Serial); + printWire1BuffersCapacity(Serial); +} + +static byte x = 0; + +void loop() { + Wire.beginTransmission(8); // transmit to device #8 + Wire.write(text); // sends multiple bytes + Wire.write(x); // sends one byte + Wire.endTransmission(); // stop transmitting + + x++; + delay(500); +} + +// function that executes whenever data is received from master +// this function is registered as an event, see setup() +// +// Hint: This function is called within an interrupt context. +// That means, that there must be enough space in the Serial output +// buffer for the characters to be printed. Otherwise the +// Serial.print() call will lock up. +void receiveEvent(int howMany) { + while (1 < Wire1.available()) { // loop through all but the last + const char c = Wire1.read(); // receive byte as a character + Serial.print(c); // print the character + } + const int x = Wire1.read(); // receive byte as an integer + Serial.println(x); // print the integer +} + +void printWireBuffersCapacity(Stream& stream) { + const auto& buffers = GET_WIRE_BUFFERS(); + + stream.print("Wire transmit buffer size is "); + stream.println(buffers.txWireBufferCapacity()); + + stream.print("Wire receive buffer size is "); + stream.println(buffers.rxWireBufferCapacity()); + + stream.print("Wire service buffer size is "); + stream.println(buffers.srvWireBufferCapacity()); + delay(250); // Give time to finalize the print out +} + +void printWire1BuffersCapacity(Stream& stream) { + const auto& buffers = GET_WIRE1_BUFFERS(); + + stream.print("Wire1 transmit buffer size is "); + stream.println(buffers.txWireBufferCapacity()); + + stream.print("Wire1 receive buffer size is "); + stream.println(buffers.rxWireBufferCapacity()); + + stream.print("Wire1 service buffer size is "); + stream.println(buffers.srvWireBufferCapacity()); + delay(250); // Give time to free up Serial output buffer. +} + +#endif diff --git a/libraries/Wire/examples/slave_receiver_custombuffer/slave_receiver_custombuffer.ino b/libraries/Wire/examples/slave_receiver_custombuffer/slave_receiver_custombuffer.ino index b4638683..f72ba938 100644 --- a/libraries/Wire/examples/slave_receiver_custombuffer/slave_receiver_custombuffer.ino +++ b/libraries/Wire/examples/slave_receiver_custombuffer/slave_receiver_custombuffer.ino @@ -38,13 +38,18 @@ void loop() { // function that executes whenever data is received from master // this function is registered as an event, see setup() +// +// Hint: This function is called within an interrupt context. +// That means, that there must be enough space in the Serial output +// buffer for the characters to be printed. Otherwise the +// Serial.print() call will lock up. void receiveEvent(int howMany) { while (1 < Wire.available()) { // loop through all but the last - const char c = Wire.read(); // receive byte as a character - Serial.print(c); // print the character + const char c = Wire.read(); // receive byte as a character + Serial.print(c); // print the character } - const int x = Wire.read(); // receive byte as an integer - Serial.println(x); // print the integer + const int x = Wire.read(); // receive byte as an integer + Serial.println(x); // print the integer } void printWireBuffersCapacity(Stream& stream) { @@ -58,6 +63,7 @@ void printWireBuffersCapacity(Stream& stream) { stream.print("Wire service buffer size is "); stream.println(buffers.srvWireBufferCapacity()); + delay(250); // Give time to free up Serial output buffer. } #else @@ -68,7 +74,7 @@ SET_WIRE1_BUFFERS(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE, void setup() { Wire1.begin(8); // join I2C bus with address #8 Wire1.onReceive(receiveEvent); // register event - Serial.begin(9600); // start serial for output + Serial.begin(9600); // start serial for output // This is just for curiosity and could be removed printWire1BuffersCapacity(Serial); @@ -80,13 +86,18 @@ void loop() { // function that executes whenever data is received from master // this function is registered as an event, see setup() +// +// Hint: This function is called within an interrupt context. +// That means, that there must be enough space in the Serial output +// buffer for the characters to be printed. Otherwise the +// Serial.print() call will lock up. void receiveEvent(int howMany) { while (1 < Wire1.available()) { // loop through all but the last - const char c = Wire1.read(); // receive byte as a character - Serial.print(c); // print the character + const char c = Wire1.read(); // receive byte as a character + Serial.print(c); // print the character } - const int x = Wire1.read(); // receive byte as an integer - Serial.println(x); // print the integer + const int x = Wire1.read(); // receive byte as an integer + Serial.println(x); // print the integer } void printWire1BuffersCapacity(Stream& stream) { @@ -100,6 +111,7 @@ void printWire1BuffersCapacity(Stream& stream) { stream.print("Wire1 service buffer size is "); stream.println(buffers.srvWireBufferCapacity()); + delay(250); // Give time to free up Serial output buffer. } #endif diff --git a/libraries/Wire/examples/slave_sender_Wire1Wire_connected/slave_sender_Wire1Wire_connected.ino b/libraries/Wire/examples/slave_sender_Wire1Wire_connected/slave_sender_Wire1Wire_connected.ino index 2f8b7d6b..0a2bdb25 100644 --- a/libraries/Wire/examples/slave_sender_Wire1Wire_connected/slave_sender_Wire1Wire_connected.ino +++ b/libraries/Wire/examples/slave_sender_Wire1Wire_connected/slave_sender_Wire1Wire_connected.ino @@ -1,4 +1,4 @@ -// Wire1Wire connected (scl <-> scl1, sda <-> sda1) +// Wire1 connnected to Wire. (scl <-> scl1, sda <-> sda1) // Demonstrates use of the Wire library on a single Arduino board // with 2 Wire interfaces (like Arduino Due). @@ -34,7 +34,6 @@ SET_WIRE1_BUFFERS(S_RECEIVE_BUFFER_SIZE, S_TRANSMIT_BUFFER_SIZE, void setup() { Serial.begin(9600); // start serial for output - Wire.begin(); // master joins I2C bus (address optional for master) Wire1.begin(8); // slave joins I2C bus with address #8 Wire1.onRequest(requestEvent); // register slave event From be866c8be39df521a20355fa5cc790a166301cae Mon Sep 17 00:00:00 2001 From: dac1e Date: Thu, 2 Jan 2025 10:49:39 +0100 Subject: [PATCH 12/17] Added static_assert to check sufficient I2C interfaces. --- .../slave_receiver_Wire1Wire_connected.ino | 4 +--- .../slave_sender_Wire1Wire_connected.ino | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/libraries/Wire/examples/slave_receiver_Wire1Wire_connected/slave_receiver_Wire1Wire_connected.ino b/libraries/Wire/examples/slave_receiver_Wire1Wire_connected/slave_receiver_Wire1Wire_connected.ino index e1f38d17..47a97a23 100644 --- a/libraries/Wire/examples/slave_receiver_Wire1Wire_connected/slave_receiver_Wire1Wire_connected.ino +++ b/libraries/Wire/examples/slave_receiver_Wire1Wire_connected/slave_receiver_Wire1Wire_connected.ino @@ -16,7 +16,7 @@ #include #include "Arduino.h" -#if WIRE_INTERFACES_COUNT > 1 +static_assert(WIRE_INTERFACES_COUNT > 1, "You need two I2C interfaces on the Arduino board to run this sketch"); static const char text[] = "You really won't believe it, but x is "; @@ -98,5 +98,3 @@ void printWire1BuffersCapacity(Stream& stream) { stream.println(buffers.srvWireBufferCapacity()); delay(250); // Give time to free up Serial output buffer. } - -#endif diff --git a/libraries/Wire/examples/slave_sender_Wire1Wire_connected/slave_sender_Wire1Wire_connected.ino b/libraries/Wire/examples/slave_sender_Wire1Wire_connected/slave_sender_Wire1Wire_connected.ino index 0a2bdb25..dd08a25d 100644 --- a/libraries/Wire/examples/slave_sender_Wire1Wire_connected/slave_sender_Wire1Wire_connected.ino +++ b/libraries/Wire/examples/slave_sender_Wire1Wire_connected/slave_sender_Wire1Wire_connected.ino @@ -16,7 +16,7 @@ #include #include "Arduino.h" -#if WIRE_INTERFACES_COUNT > 1 +static_assert(WIRE_INTERFACES_COUNT > 1, "You need two I2C interfaces on the Arduino board to run this sketch"); static const char text[] = "hello "; // respond with message of 6 bytes @@ -89,5 +89,3 @@ void printWire1BuffersCapacity(Stream& stream) { stream.print("Wire1 service buffer size is "); stream.println(buffers.srvWireBufferCapacity()); } - -#endif From aecd8b1924938b1a2477693e615f5aad387bda01 Mon Sep 17 00:00:00 2001 From: dac1e Date: Thu, 2 Jan 2025 10:55:07 +0100 Subject: [PATCH 13/17] Fixed wrong comment. --- libraries/Wire/src/TwoWireBuffers.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/libraries/Wire/src/TwoWireBuffers.h b/libraries/Wire/src/TwoWireBuffers.h index 03725082..b2ee6300 100644 --- a/libraries/Wire/src/TwoWireBuffers.h +++ b/libraries/Wire/src/TwoWireBuffers.h @@ -15,8 +15,6 @@ You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Modified 2020 by Greyson Christoforo (grey@christoforo.net) to implement timeouts */ #pragma once From 6a4d011b2d8acc292e976697519dd962bd9052dd Mon Sep 17 00:00:00 2001 From: dac1e Date: Thu, 2 Jan 2025 11:25:20 +0100 Subject: [PATCH 14/17] Fixed typo. --- libraries/Wire/src/TwoWireBuffers.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/Wire/src/TwoWireBuffers.h b/libraries/Wire/src/TwoWireBuffers.h index b2ee6300..9e02e078 100644 --- a/libraries/Wire/src/TwoWireBuffers.h +++ b/libraries/Wire/src/TwoWireBuffers.h @@ -67,7 +67,7 @@ template< size_t TX_CAPACITY // Transmit buffer size. May be zero, if only receiving data is needed > class Impl : public Interface { - // Service buffer is neede for transmit and receive. + // Service buffer is needed for transmit and receive. static constexpr size_t SRV_CAPACITY = RX_CAPACITY > TX_CAPACITY ? RX_CAPACITY : TX_CAPACITY; From 35111609bf08143a8b2dc30ed29b98a29c663d61 Mon Sep 17 00:00:00 2001 From: dac1e Date: Thu, 2 Jan 2025 13:08:06 +0100 Subject: [PATCH 15/17] Fixed bug in printWire1BuffersCapacity(). --- .../slave_sender_Wire1Wire_connected.ino | 2 +- .../slave_sender_custombuffer/slave_sender_custombuffer.ino | 2 +- libraries/Wire/src/TwoWireBuffers.h | 3 +++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/libraries/Wire/examples/slave_sender_Wire1Wire_connected/slave_sender_Wire1Wire_connected.ino b/libraries/Wire/examples/slave_sender_Wire1Wire_connected/slave_sender_Wire1Wire_connected.ino index dd08a25d..ab11abc3 100644 --- a/libraries/Wire/examples/slave_sender_Wire1Wire_connected/slave_sender_Wire1Wire_connected.ino +++ b/libraries/Wire/examples/slave_sender_Wire1Wire_connected/slave_sender_Wire1Wire_connected.ino @@ -78,7 +78,7 @@ void printWireBuffersCapacity(Stream& stream) { // print Wire1 buffer sizes void printWire1BuffersCapacity(Stream& stream) { - const auto& buffers = GET_WIRE_BUFFERS(); + const auto& buffers = GET_WIRE1_BUFFERS(); stream.print("Wire1 transmit buffer size is "); stream.println(buffers.txWireBufferCapacity()); diff --git a/libraries/Wire/examples/slave_sender_custombuffer/slave_sender_custombuffer.ino b/libraries/Wire/examples/slave_sender_custombuffer/slave_sender_custombuffer.ino index 637f6fc4..89807266 100644 --- a/libraries/Wire/examples/slave_sender_custombuffer/slave_sender_custombuffer.ino +++ b/libraries/Wire/examples/slave_sender_custombuffer/slave_sender_custombuffer.ino @@ -84,7 +84,7 @@ void requestEvent() { } void printWire1BuffersCapacity(Stream& stream) { - const auto& buffers = GET_WIRE_BUFFERS(); + const auto& buffers = GET_WIRE1_BUFFERS(); stream.print("Wire1 transmit buffer size is "); stream.println(buffers.txWireBufferCapacity()); diff --git a/libraries/Wire/src/TwoWireBuffers.h b/libraries/Wire/src/TwoWireBuffers.h index 9e02e078..c039dfa3 100644 --- a/libraries/Wire/src/TwoWireBuffers.h +++ b/libraries/Wire/src/TwoWireBuffers.h @@ -93,6 +93,9 @@ template struct WireBuffers { // The buffers for the Wire object static TwoWireBuffers::Interface& instance(); }; +// Note: enableMaster and enableSlave don't have any impact on sam architecture, but they +// are present to keep the macro compatible with the one on the avr architecture, where +// it makes a difference in regard to memory consumption. #define SET_WIRE_BUFFERS_(wireNum, rxBufferCapacity, txBufferCapacity, enableMaster, enableSlave) \ template<> TwoWireBuffers::Interface& WireBuffers::instance() { \ static TwoWireBuffers::Impl buffers; \ From 8b3ffef1dad236d5cce6877c264cce3bf54306aa Mon Sep 17 00:00:00 2001 From: dac1e Date: Thu, 2 Jan 2025 14:07:53 +0100 Subject: [PATCH 16/17] Changed SET_WIRE_BUFFERS and GET_WIRE_BUFFERS tpo SET_Wire_BUFFERS respectively GET_Wire_BUFFERS. Changed SET_WIRE1_BUFFERS and GET_WIRE1_BUFFERS tpo SET_Wire1_BUFFERS respectively GET_Wire1_BUFFERS. --- .../master_reader_custombuffer.ino | 8 ++++---- .../master_writer_custombuffer.ino | 8 ++++---- .../slave_receiver_Wire1Wire_connected.ino | 8 ++++---- .../slave_receiver_custombuffer.ino | 8 ++++---- .../slave_sender_Wire1Wire_connected.ino | 8 ++++---- .../slave_sender_custombuffer.ino | 8 ++++---- libraries/Wire/src/TwoWireBuffers.h | 8 ++++---- 7 files changed, 28 insertions(+), 28 deletions(-) diff --git a/libraries/Wire/examples/master_reader_custombuffer/master_reader_custombuffer.ino b/libraries/Wire/examples/master_reader_custombuffer/master_reader_custombuffer.ino index f818892c..57bd82b5 100644 --- a/libraries/Wire/examples/master_reader_custombuffer/master_reader_custombuffer.ino +++ b/libraries/Wire/examples/master_reader_custombuffer/master_reader_custombuffer.ino @@ -23,7 +23,7 @@ constexpr size_t TRANSMIT_BUFFER_SIZE = 0; // There is no transmit in this sketc #if not USE_WIRE1 -SET_WIRE_BUFFERS(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE, +SET_Wire_BUFFERS(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE, true /* master buffers needed */, false /* no slave buffers needed */ ); void setup() { @@ -47,7 +47,7 @@ void loop() { } void printWireBuffersCapacity(Stream& stream) { - const auto& buffers = GET_WIRE_BUFFERS(); + const auto& buffers = GET_Wire_BUFFERS(); stream.print("Wire transmit buffer size is "); stream.println(buffers.txWireBufferCapacity()); @@ -61,7 +61,7 @@ void printWireBuffersCapacity(Stream& stream) { #else -SET_WIRE1_BUFFERS(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE, +SET_Wire1_BUFFERS(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE, true /* master buffers needed */, false /* no slave buffers needed */ ); void setup() { @@ -85,7 +85,7 @@ void loop() { } void printWire1BuffersCapacity(Stream& stream) { - const auto& buffers = GET_WIRE1_BUFFERS(); + const auto& buffers = GET_Wire1_BUFFERS(); stream.print("Wire1 transmit buffer size is "); stream.println(buffers.txWireBufferCapacity()); diff --git a/libraries/Wire/examples/master_writer_custombuffer/master_writer_custombuffer.ino b/libraries/Wire/examples/master_writer_custombuffer/master_writer_custombuffer.ino index 8affd251..0b5d97fd 100644 --- a/libraries/Wire/examples/master_writer_custombuffer/master_writer_custombuffer.ino +++ b/libraries/Wire/examples/master_writer_custombuffer/master_writer_custombuffer.ino @@ -23,7 +23,7 @@ constexpr size_t TRANSMIT_BUFFER_SIZE = 42; // Enhance the buffer to 42 characte #if not USE_WIRE1 -SET_WIRE_BUFFERS(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE, +SET_Wire_BUFFERS(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE, true /* master buffers needed */, false /* no slave buffers needed */ ); void setup() { @@ -47,7 +47,7 @@ void loop() { } void printWireBuffersCapacity(Stream& stream) { - const auto& buffers = GET_WIRE_BUFFERS(); + const auto& buffers = GET_Wire_BUFFERS(); stream.print("Wire transmit buffer size is "); stream.println(buffers.txWireBufferCapacity()); @@ -61,7 +61,7 @@ void printWireBuffersCapacity(Stream& stream) { #else -SET_WIRE1_BUFFERS(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE, +SET_Wire1_BUFFERS(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE, true /* master buffers needed */, false /* no slave buffers needed */ ); void setup() { @@ -85,7 +85,7 @@ void loop() { } void printWire1BuffersCapacity(Stream& stream) { - const auto& buffers = GET_WIRE1_BUFFERS(); + const auto& buffers = GET_Wire1_BUFFERS(); stream.print("Wire1 transmit buffer size is "); stream.println(buffers.txWireBufferCapacity()); diff --git a/libraries/Wire/examples/slave_receiver_Wire1Wire_connected/slave_receiver_Wire1Wire_connected.ino b/libraries/Wire/examples/slave_receiver_Wire1Wire_connected/slave_receiver_Wire1Wire_connected.ino index 47a97a23..8bdbcb7d 100644 --- a/libraries/Wire/examples/slave_receiver_Wire1Wire_connected/slave_receiver_Wire1Wire_connected.ino +++ b/libraries/Wire/examples/slave_receiver_Wire1Wire_connected/slave_receiver_Wire1Wire_connected.ino @@ -23,13 +23,13 @@ static const char text[] = "You really won't believe it, but x is "; // Wire is the master writer constexpr size_t M_RECEIVE_BUFFER_SIZE = 0; // There is no receive in this sketch. constexpr size_t M_TRANSMIT_BUFFER_SIZE = 42; // Enhance the buffer to 42 characters. -SET_WIRE_BUFFERS(M_RECEIVE_BUFFER_SIZE, M_TRANSMIT_BUFFER_SIZE, +SET_Wire_BUFFERS(M_RECEIVE_BUFFER_SIZE, M_TRANSMIT_BUFFER_SIZE, true /* master buffers needed */, false /* no slave buffers needed */ ); // Wire1 is the slave receiver constexpr size_t S_RECEIVE_BUFFER_SIZE = 42; // Be able receive up to 42 characters in one message. constexpr size_t S_TRANSMIT_BUFFER_SIZE = 0; // There is no transmit in this sketch. -SET_WIRE1_BUFFERS(S_RECEIVE_BUFFER_SIZE, S_TRANSMIT_BUFFER_SIZE, +SET_Wire1_BUFFERS(S_RECEIVE_BUFFER_SIZE, S_TRANSMIT_BUFFER_SIZE, false /* no master buffers needed */, true /* slave buffers needed */ ); void setup() { @@ -72,7 +72,7 @@ void receiveEvent(int howMany) { } void printWireBuffersCapacity(Stream& stream) { - const auto& buffers = GET_WIRE_BUFFERS(); + const auto& buffers = GET_Wire_BUFFERS(); stream.print("Wire transmit buffer size is "); stream.println(buffers.txWireBufferCapacity()); @@ -86,7 +86,7 @@ void printWireBuffersCapacity(Stream& stream) { } void printWire1BuffersCapacity(Stream& stream) { - const auto& buffers = GET_WIRE1_BUFFERS(); + const auto& buffers = GET_Wire1_BUFFERS(); stream.print("Wire1 transmit buffer size is "); stream.println(buffers.txWireBufferCapacity()); diff --git a/libraries/Wire/examples/slave_receiver_custombuffer/slave_receiver_custombuffer.ino b/libraries/Wire/examples/slave_receiver_custombuffer/slave_receiver_custombuffer.ino index f72ba938..fef329cd 100644 --- a/libraries/Wire/examples/slave_receiver_custombuffer/slave_receiver_custombuffer.ino +++ b/libraries/Wire/examples/slave_receiver_custombuffer/slave_receiver_custombuffer.ino @@ -20,7 +20,7 @@ constexpr size_t TRANSMIT_BUFFER_SIZE = 0; // There is no transmit in this sket #if not USE_WIRE1 -SET_WIRE_BUFFERS(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE, +SET_Wire_BUFFERS(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE, false /* no master buffers needed */, true /* slave buffers needed */ ); void setup() { @@ -53,7 +53,7 @@ void receiveEvent(int howMany) { } void printWireBuffersCapacity(Stream& stream) { - const auto& buffers = GET_WIRE_BUFFERS(); + const auto& buffers = GET_Wire_BUFFERS(); stream.print("Wire transmit buffer size is "); stream.println(buffers.txWireBufferCapacity()); @@ -68,7 +68,7 @@ void printWireBuffersCapacity(Stream& stream) { #else -SET_WIRE1_BUFFERS(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE, +SET_Wire1_BUFFERS(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE, false /* no master buffers needed */, true /* slave buffers needed */ ); void setup() { @@ -101,7 +101,7 @@ void receiveEvent(int howMany) { } void printWire1BuffersCapacity(Stream& stream) { - const auto& buffers = GET_WIRE1_BUFFERS(); + const auto& buffers = GET_Wire1_BUFFERS(); stream.print("Wire1 transmit buffer size is "); stream.println(buffers.txWireBufferCapacity()); diff --git a/libraries/Wire/examples/slave_sender_Wire1Wire_connected/slave_sender_Wire1Wire_connected.ino b/libraries/Wire/examples/slave_sender_Wire1Wire_connected/slave_sender_Wire1Wire_connected.ino index ab11abc3..9260aa23 100644 --- a/libraries/Wire/examples/slave_sender_Wire1Wire_connected/slave_sender_Wire1Wire_connected.ino +++ b/libraries/Wire/examples/slave_sender_Wire1Wire_connected/slave_sender_Wire1Wire_connected.ino @@ -23,13 +23,13 @@ static const char text[] = "hello "; // respond with message of 6 bytes // Wire is the master reader constexpr size_t M_RECEIVE_BUFFER_SIZE = sizeof(text)-1; // Don't need a byte for the \0 constexpr size_t M_TRANSMIT_BUFFER_SIZE = 0; // There is no transmit in this sketch. -SET_WIRE_BUFFERS(M_RECEIVE_BUFFER_SIZE, M_TRANSMIT_BUFFER_SIZE, +SET_Wire_BUFFERS(M_RECEIVE_BUFFER_SIZE, M_TRANSMIT_BUFFER_SIZE, true /* master buffers needed */, false /* no slave buffers needed */ ); // Wire1 is the slave sender constexpr size_t S_RECEIVE_BUFFER_SIZE = 0; // There is no receive in this sketch. constexpr size_t S_TRANSMIT_BUFFER_SIZE = sizeof(text)-1; // Don't need a byte for the \0 -SET_WIRE1_BUFFERS(S_RECEIVE_BUFFER_SIZE, S_TRANSMIT_BUFFER_SIZE, +SET_Wire1_BUFFERS(S_RECEIVE_BUFFER_SIZE, S_TRANSMIT_BUFFER_SIZE, false /* no master buffers needed */, true /* slave buffers needed */ ); void setup() { @@ -64,7 +64,7 @@ void requestEvent() { // print Wire buffer sizes void printWireBuffersCapacity(Stream& stream) { - const auto& buffers = GET_WIRE_BUFFERS(); + const auto& buffers = GET_Wire_BUFFERS(); stream.print("Wire transmit buffer size is "); stream.println(buffers.txWireBufferCapacity()); @@ -78,7 +78,7 @@ void printWireBuffersCapacity(Stream& stream) { // print Wire1 buffer sizes void printWire1BuffersCapacity(Stream& stream) { - const auto& buffers = GET_WIRE1_BUFFERS(); + const auto& buffers = GET_Wire1_BUFFERS(); stream.print("Wire1 transmit buffer size is "); stream.println(buffers.txWireBufferCapacity()); diff --git a/libraries/Wire/examples/slave_sender_custombuffer/slave_sender_custombuffer.ino b/libraries/Wire/examples/slave_sender_custombuffer/slave_sender_custombuffer.ino index 89807266..f09d692a 100644 --- a/libraries/Wire/examples/slave_sender_custombuffer/slave_sender_custombuffer.ino +++ b/libraries/Wire/examples/slave_sender_custombuffer/slave_sender_custombuffer.ino @@ -22,7 +22,7 @@ constexpr size_t TRANSMIT_BUFFER_SIZE = sizeof(text)-1; // Don't need a byte for #if not USE_WIRE1 -SET_WIRE_BUFFERS(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE, +SET_Wire_BUFFERS(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE, false /* no master buffers needed */, true /* slave buffers needed */ ); void setup() { @@ -46,7 +46,7 @@ void requestEvent() { } void printWireBuffersCapacity(Stream& stream) { - const auto& buffers = GET_WIRE_BUFFERS(); + const auto& buffers = GET_Wire_BUFFERS(); stream.print("Wire transmit buffer size is "); stream.println(buffers.txWireBufferCapacity()); @@ -60,7 +60,7 @@ void printWireBuffersCapacity(Stream& stream) { #else -SET_WIRE1_BUFFERS(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE, +SET_Wire1_BUFFERS(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE, false /* no master buffers needed */, true /* slave buffers needed */ ); void setup() { @@ -84,7 +84,7 @@ void requestEvent() { } void printWire1BuffersCapacity(Stream& stream) { - const auto& buffers = GET_WIRE1_BUFFERS(); + const auto& buffers = GET_Wire1_BUFFERS(); stream.print("Wire1 transmit buffer size is "); stream.println(buffers.txWireBufferCapacity()); diff --git a/libraries/Wire/src/TwoWireBuffers.h b/libraries/Wire/src/TwoWireBuffers.h index c039dfa3..b56c0bbe 100644 --- a/libraries/Wire/src/TwoWireBuffers.h +++ b/libraries/Wire/src/TwoWireBuffers.h @@ -105,17 +105,17 @@ template struct WireBuffers { // The buffers for the Wire object #define GET_WIRE_BUFFERS_(wireNum) WireBuffers::instance() #if WIRE_INTERFACES_COUNT > 0 - #define SET_WIRE_BUFFERS(rxBufferCapacity, txBufferCapacity, enableMaster, enableSlave) \ + #define SET_Wire_BUFFERS(rxBufferCapacity, txBufferCapacity, enableMaster, enableSlave) \ SET_WIRE_BUFFERS_(0, rxBufferCapacity, txBufferCapacity, enableMaster, enableSlave) - #define GET_WIRE_BUFFERS() GET_WIRE_BUFFERS_(0) + #define GET_Wire_BUFFERS() GET_WIRE_BUFFERS_(0) #endif #if WIRE_INTERFACES_COUNT > 1 - #define SET_WIRE1_BUFFERS(rxBufferCapacity, txBufferCapacity, enableMaster, enableSlave) \ + #define SET_Wire1_BUFFERS(rxBufferCapacity, txBufferCapacity, enableMaster, enableSlave) \ SET_WIRE_BUFFERS_(1, rxBufferCapacity, txBufferCapacity, enableMaster, enableSlave) - #define GET_WIRE1_BUFFERS() GET_WIRE_BUFFERS_(1) + #define GET_Wire1_BUFFERS() GET_WIRE_BUFFERS_(1) #endif #endif /* TwiBuffers_h */ From 309501b19206a74266fa45ec4a87a38ad8916f0b Mon Sep 17 00:00:00 2001 From: dac1e Date: Thu, 2 Jan 2025 14:19:21 +0100 Subject: [PATCH 17/17] Fixed comment lines. --- libraries/Wire/src/TwoWireBuffers.cpp | 2 +- libraries/Wire/src/TwoWireBuffers.h | 2 +- libraries/Wire/src/Wire.cpp | 2 +- libraries/Wire/src/Wire.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/Wire/src/TwoWireBuffers.cpp b/libraries/Wire/src/TwoWireBuffers.cpp index 0244dff3..b8160f85 100644 --- a/libraries/Wire/src/TwoWireBuffers.cpp +++ b/libraries/Wire/src/TwoWireBuffers.cpp @@ -1,5 +1,5 @@ /* - twi.c - TWI/I2C library for Wiring & Arduino + TwoWireBuffers.cpp - TWI/I2C library for Wiring & Arduino Copyright (c) 2006 Nicholas Zambetti. All right reserved. This library is free software; you can redistribute it and/or diff --git a/libraries/Wire/src/TwoWireBuffers.h b/libraries/Wire/src/TwoWireBuffers.h index b56c0bbe..b5960863 100644 --- a/libraries/Wire/src/TwoWireBuffers.h +++ b/libraries/Wire/src/TwoWireBuffers.h @@ -1,5 +1,5 @@ /* - twi.h - TWI/I2C library for Wiring & Arduino + TwoWireBuffers.h - TWI/I2C library for Wiring & Arduino Copyright (c) 2006 Nicholas Zambetti. All right reserved. This library is free software; you can redistribute it and/or diff --git a/libraries/Wire/src/Wire.cpp b/libraries/Wire/src/Wire.cpp index 85b83948..8135fd88 100644 --- a/libraries/Wire/src/Wire.cpp +++ b/libraries/Wire/src/Wire.cpp @@ -1,5 +1,5 @@ /* - * TwoWire.h - TWI/I2C library for Arduino Due + * Wire.cpp - TWI/I2C library for Arduino Due * Copyright (c) 2011 Cristian Maglie * All rights reserved. * diff --git a/libraries/Wire/src/Wire.h b/libraries/Wire/src/Wire.h index 5e5be3f8..1a32bf83 100644 --- a/libraries/Wire/src/Wire.h +++ b/libraries/Wire/src/Wire.h @@ -1,5 +1,5 @@ /* - * TwoWire.h - TWI/I2C library for Arduino Due + * Wire.h - TWI/I2C library for Arduino Due * Copyright (c) 2011 Cristian Maglie * All rights reserved. *