Skip to content

Commit 7bbadfb

Browse files
committed
Use TwiBuffers class for all buffers needed by Wire and twi. Allows
optionally tweaking Wire buffer and twi buffer sizes at compile time. enum TWI_STATE : uint8_t becomes uint8_t. twi_state type changed form uint8_t to TWI_STATE. Added examples for customized buffers. Do println() after all received characters have been printed in master_reader.ino.
1 parent 073cd4c commit 7bbadfb

File tree

11 files changed

+581
-67
lines changed

11 files changed

+581
-67
lines changed

libraries/Wire/examples/master_reader/master_reader.ino

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ void loop() {
2424
char c = Wire.read(); // receive a byte as character
2525
Serial.print(c); // print the character
2626
}
27+
Serial.println();
2728

2829
delay(500);
2930
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// Wire Master Reader Custom Buffer
2+
3+
// Demonstrates use of the Wire library
4+
// Reads data from an I2C/TWI slave device
5+
// Refer to the "Wire Slave Sender Custom Buffer" example for use with this
6+
7+
// Created 31 Dec 2024
8+
9+
// This example code is in the public domain.
10+
11+
12+
#include <Wire.h>
13+
#include <TwoWireBuffers.h>
14+
15+
// request 6 bytes from slave device #8
16+
size_t constexpr REQUESTED_BYTE_COUNT = 6;
17+
18+
/**** Begin Customize buffers ****/
19+
// Note: If you spell namespace 'WireBuffers' wrongly, all buffer
20+
// sizes of the 'Wire' object stay at default (32 bytes).
21+
namespace WireBuffers {
22+
size_t constexpr RECEIVE_BUFFER_SIZE = REQUESTED_BYTE_COUNT;
23+
size_t constexpr TRANSMIT_BUFFER_SIZE = 0; // There is no transmit in this sketch.
24+
// We operate as a master only, so we use the macro that will set slave buffers to zero.
25+
SET_BUFFERS_FOR_MASTER_ONLY(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE);
26+
}
27+
/**** End Customize buffers ******/
28+
29+
// This is just for curiosity.
30+
// Set to false if you don't want to see actual buffer sizes on serial monitor.
31+
#define VERBOSE true
32+
33+
void setup() {
34+
Wire.begin(); // join I2C bus (address optional for master)
35+
Serial.begin(9600); // start serial for output
36+
#if VERBOSE
37+
printWireBuffers();
38+
#endif
39+
}
40+
41+
void loop() {
42+
Wire.requestFrom(8, REQUESTED_BYTE_COUNT);
43+
44+
while (Wire.available()) { // slave may send less than requested
45+
char c = Wire.read(); // receive a byte as character
46+
Serial.print(c); // print the character
47+
}
48+
Serial.println();
49+
50+
delay(500);
51+
}
52+
53+
#if VERBOSE
54+
void printWireBuffers() {
55+
delay(100);
56+
Serial.println();
57+
Serial.print("Wire transmit buffer size is ");
58+
Serial.println(Wire.txBufferCapacity());
59+
Serial.print("Wire receive buffer size is ");
60+
Serial.println(Wire.rxBufferCapacity());
61+
62+
TwoWireBuffers::Interface& buffers = WireBuffers::instance();
63+
Serial.print("twi_masterBuffer size is ");
64+
Serial.println(buffers.twi_masterBufferCapacity());
65+
66+
Serial.print("twi_rxBuffer size is ");
67+
Serial.println(buffers.twi_rxBufferCapacity());
68+
69+
Serial.print("twi_txBuffer size is ");
70+
Serial.println(buffers.twi_txBufferCapacity());
71+
delay(500);
72+
}
73+
#endif

libraries/Wire/examples/master_writer/master_writer.ino

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ void setup() {
1616
Wire.begin(); // join I2C bus (address optional for master)
1717
}
1818

19-
byte x = 0;
19+
static byte x = 0;
2020

2121
void loop() {
2222
Wire.beginTransmission(8); // transmit to device #8
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// Wire Master Writer Custom Buffer
2+
3+
// Demonstrates use of the Wire library
4+
// Writes data to an I2C/TWI slave device
5+
// Refer to the "Wire Slave Receiver Custom Buffer" example for use with this
6+
7+
// Created 31 Dec 2024
8+
9+
// This example code is in the public domain.
10+
11+
12+
#include <Wire.h>
13+
#include <TwoWireBuffers.h>
14+
15+
// The following text will not fit into the default buffer of 32 bytes.
16+
static const char text[] = "You really won't believe it, but x is ";
17+
18+
/**** Begin Customize buffers ****/
19+
// Note: If you spell namespace 'WireBuffers' wrongly, all buffer sizes
20+
// of the 'Wire' object stay at default (32 bytes).
21+
namespace WireBuffers {
22+
size_t constexpr RECEIVE_BUFFER_SIZE = 0; // There is no receive in this sketch.
23+
size_t constexpr TRANSMIT_BUFFER_SIZE = 42; // Enhance the buffer to 42 characters.
24+
// We operate as a master only, so we use the macro that will set slave buffers to zero.
25+
SET_BUFFERS_FOR_MASTER_ONLY(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE);
26+
}
27+
/**** End Customize buffers ******/
28+
29+
// This is just for curiosity.
30+
// Set to false if you don't want to see actual buffer sizes on serial monitor.
31+
#define VERBOSE true
32+
33+
void setup() {
34+
Wire.begin(); // join I2C bus (address optional for master)
35+
#if VERBOSE
36+
Serial.begin(9600); // start serial for output
37+
printWireBuffers();
38+
#endif
39+
}
40+
41+
static byte x = 0;
42+
43+
void loop() {
44+
Wire.beginTransmission(8); // transmit to device #8
45+
Wire.write(text); // sends five bytes
46+
Wire.write(x); // sends one byte
47+
Wire.endTransmission(); // stop transmitting
48+
49+
x++;
50+
delay(500);
51+
}
52+
53+
#if VERBOSE
54+
void printWireBuffers() {
55+
delay(100);
56+
Serial.println();
57+
Serial.print("Wire transmit buffer size is ");
58+
Serial.println(Wire.txBufferCapacity());
59+
Serial.print("Wire receive buffer size is ");
60+
Serial.println(Wire.rxBufferCapacity());
61+
62+
TwoWireBuffers::Interface& buffers = WireBuffers::instance();
63+
Serial.print("twi_masterBuffer size is ");
64+
Serial.println(buffers.twi_masterBufferCapacity());
65+
66+
Serial.print("twi_rxBuffer size is ");
67+
Serial.println(buffers.twi_rxBufferCapacity());
68+
69+
Serial.print("twi_txBuffer size is ");
70+
Serial.println(buffers.twi_txBufferCapacity());
71+
delay(500);
72+
}
73+
#endif
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// Wire Slave Receiver Custom Buffer
2+
3+
// Demonstrates use of the Wire library
4+
// Receives data as an I2C/TWI slave device
5+
// Refer to the "Wire Master Writer Custom Buffer" example for use with this
6+
7+
// Created 31 Dec 2024
8+
9+
// This example code is in the public domain.
10+
11+
12+
#include <Wire.h>
13+
#include <TwoWireBuffers.h>
14+
15+
/**** Begin Customize buffers ****/
16+
// Note: If you spell namespace 'WireBuffers' wrongly, all buffer sizes
17+
// of the 'Wire' object stay at default (32 bytes).
18+
namespace WireBuffers {
19+
size_t constexpr RECEIVE_BUFFER_SIZE = 42; // Be able receive up to 42 characters in one message.
20+
size_t constexpr TRANSMIT_BUFFER_SIZE = 0; // There is no transmit in this sketch.
21+
// We operate as a slave only, so we use the macro that will set master buffers to zero.
22+
SET_BUFFERS_FOR_SLAVE_ONLY(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE);
23+
}
24+
/**** End Customize buffers ******/
25+
26+
// This is just for curiosity.
27+
// Set to false if you don't want to see actual buffer sizes on serial monitor.
28+
#define VERBOSE true
29+
30+
void setup() {
31+
Wire.begin(8); // join I2C bus with address #8
32+
Wire.onReceive(receiveEvent); // register event
33+
Serial.begin(9600); // start serial for output
34+
#if VERBOSE
35+
printWireBuffers();
36+
#endif
37+
}
38+
39+
void loop() {
40+
delay(100);
41+
}
42+
43+
// function that executes whenever data is received from master
44+
// this function is registered as an event, see setup()
45+
void receiveEvent(int howMany) {
46+
while (1 < Wire.available()) { // loop through all but the last
47+
char c = Wire.read(); // receive byte as a character
48+
Serial.print(c); // print the character
49+
}
50+
int x = Wire.read(); // receive byte as an integer
51+
Serial.println(x); // print the integer
52+
}
53+
54+
#if VERBOSE
55+
void printWireBuffers() {
56+
delay(100);
57+
Serial.println();
58+
Serial.print("Wire transmit buffer size is ");
59+
Serial.println(Wire.txBufferCapacity());
60+
Serial.print("Wire receive buffer size is ");
61+
Serial.println(Wire.rxBufferCapacity());
62+
63+
TwoWireBuffers::Interface& buffers = WireBuffers::instance();
64+
Serial.print("twi_masterBuffer size is ");
65+
Serial.println(buffers.twi_masterBufferCapacity());
66+
67+
Serial.print("twi_rxBuffer size is ");
68+
Serial.println(buffers.twi_rxBufferCapacity());
69+
70+
Serial.print("twi_txBuffer size is ");
71+
Serial.println(buffers.twi_txBufferCapacity());
72+
delay(500);
73+
}
74+
#endif
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// Wire Slave Sender Custom Buffer
2+
3+
// Demonstrates use of the Wire library
4+
// Sends data as an I2C/TWI slave device
5+
// Refer to the "Wire Master Reader Custom Buffer" example for use with this
6+
7+
// Created 31 Dec 2024
8+
9+
// This example code is in the public domain.
10+
11+
12+
#include <Wire.h>
13+
#include <TwoWireBuffers.h>
14+
15+
static const char text[] = "hello "; // respond with message of 6 bytes
16+
17+
/**** Begin Customize buffers ****/
18+
// Note: If you spell namespace 'WireBuffers' wrongly, all buffer sizes
19+
// of the 'Wire' object stay at default (32 bytes).
20+
namespace WireBuffers {
21+
size_t constexpr RECEIVE_BUFFER_SIZE = 0; // There is no receive in this sketch.
22+
size_t constexpr TRANSMIT_BUFFER_SIZE = sizeof(text); // Don't need a byte for the \0
23+
// We operate as a slave only, so we use the macro that will set master buffers to zero.
24+
SET_BUFFERS_FOR_SLAVE_ONLY(RECEIVE_BUFFER_SIZE, TRANSMIT_BUFFER_SIZE);
25+
}
26+
/**** End Customize buffers ******/
27+
28+
// This is just for curiosity.
29+
// Set to false if you don't want to see actual buffer sizes on serial monitor.
30+
#define VERBOSE true
31+
32+
void setup() {
33+
Wire.begin(8); // join I2C bus with address #8
34+
Wire.onRequest(requestEvent); // register event
35+
#if VERBOSE
36+
Serial.begin(9600); // start serial for output
37+
printWireBuffers();
38+
#endif
39+
}
40+
41+
void loop() {
42+
delay(100);
43+
}
44+
45+
// function that executes whenever data is requested by master
46+
// this function is registered as an event, see setup()
47+
void requestEvent() {
48+
Wire.write(text);
49+
// as expected by master
50+
}
51+
52+
#if VERBOSE
53+
void printWireBuffers() {
54+
delay(100);
55+
Serial.println();
56+
Serial.print("Wire transmit buffer size is ");
57+
Serial.println(Wire.txBufferCapacity());
58+
Serial.print("Wire receive buffer size is ");
59+
Serial.println(Wire.rxBufferCapacity());
60+
61+
TwoWireBuffers::Interface& buffers = WireBuffers::instance();
62+
Serial.print("twi_masterBuffer size is ");
63+
Serial.println(buffers.twi_masterBufferCapacity());
64+
65+
Serial.print("twi_rxBuffer size is ");
66+
Serial.println(buffers.twi_rxBufferCapacity());
67+
68+
Serial.print("twi_txBuffer size is ");
69+
Serial.println(buffers.twi_txBufferCapacity());
70+
delay(500);
71+
}
72+
#endif

libraries/Wire/src/TwoWireBuffers.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
twi.c - TWI/I2C library for Wiring & Arduino
3+
Copyright (c) 2006 Nicholas Zambetti. All right reserved.
4+
5+
This library is free software; you can redistribute it and/or
6+
modify it under the terms of the GNU Lesser General Public
7+
License as published by the Free Software Foundation; either
8+
version 2.1 of the License, or (at your option) any later version.
9+
10+
This library is distributed in the hope that it will be useful,
11+
but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
Lesser General Public License for more details.
14+
15+
You should have received a copy of the GNU Lesser General Public
16+
License along with this library; if not, write to the Free Software
17+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18+
*/
19+
20+
#include "TwoWireBuffers.h"
21+
22+
23+
constexpr size_t RX_BUFFER_DEFAULT_LENGTH = 32;
24+
constexpr size_t TX_BUFFER_DEFAULT_LENGTH = 32;
25+
26+
// Default buffers for the one and only Wire object
27+
namespace WireBuffers {
28+
__attribute__((weak)) SET_BUFFERS_FOR_BOTH(RX_BUFFER_DEFAULT_LENGTH, TX_BUFFER_DEFAULT_LENGTH);
29+
} // namespace Twi

0 commit comments

Comments
 (0)