22#pragma once
33
44#include < inttypes.h>
5+ #include < vector>
6+ #include < cassert>
57#include " Stream.h"
68
9+
10+ // Some inspiration taken from https://github.com/arduino/ArduinoCore-megaavr/blob/d2a81093ba66d22dbda14c30d146c231c5910734/libraries/Wire/src/Wire.cpp
711class TwoWire : public ObservableDataStream
812{
913public:
@@ -14,30 +18,36 @@ class TwoWire : public ObservableDataStream
1418 // Initiate the Wire library and join the I2C bus as a master or slave. This should normally be called only once.
1519 void begin () {
1620 isMaster = true ;
21+ txAddress = 0 ;
1722 }
1823 void begin (int address) {
19- i2cAddress = address;
24+ txAddress = address;
2025 isMaster = false ;
2126 }
2227 void begin (uint8_t address) {
2328 begin ((int )address);
2429 }
2530 void end () {
2631 // TODO: implement
32+ // NOTE: unnecessary for current high level implementation
2733 }
2834
2935 // https://www.arduino.cc/en/Reference/WireSetClock
3036 // This function modifies the clock frequency for I2C communication. I2C slave devices have no minimum working
3137 // clock frequency, however 100KHz is usually the baseline.
32- void setClock (uint32_t ) {
38+ void setClock (uint32_t clock ) {
3339 // TODO: implement?
40+ // NOTE: unnecessary for current high level implementation
3441 }
3542
3643 // https://www.arduino.cc/en/Reference/WireBeginTransmission
3744 // Begin a transmission to the I2C slave device with the given address. Subsequently, queue bytes for
3845 // transmission with the write() function and transmit them by calling endTransmission().
3946 void beginTransmission (int address) {
4047 // TODO: implement
48+ assert (isMaster);
49+ txAddress = address;
50+ txBuffer.clear ();
4151 }
4252 void beginTransmission (uint8_t address) {
4353 beginTransmission ((int )address);
@@ -47,7 +57,10 @@ class TwoWire : public ObservableDataStream
4757 // Ends a transmission to a slave device that was begun by beginTransmission() and transmits the bytes that were
4858 // queued by write().
4959 uint8_t endTransmission (uint8_t sendStop) {
50- // TODO: implement
60+ assert (isMaster);
61+ txAddress = 0 ;
62+ writeData = txBuffer;
63+ txBuffer.clear ();
5164 return 0 ; // success
5265 }
5366 uint8_t endTransmission (void ) {
@@ -59,6 +72,8 @@ class TwoWire : public ObservableDataStream
5972 // available() and read() functions.
6073 uint8_t requestFrom (int address, int quantity, int stop) {
6174 // TODO: implement
75+ // NOTE: deemed unnecessary for current high level implementation
76+ assert (isMaster);
6277 return 0 ; // number of bytes returned from the slave device
6378 }
6479 uint8_t requestFrom (int address, int quantity) {
@@ -81,7 +96,8 @@ class TwoWire : public ObservableDataStream
8196 // master to slave device (in-between calls to beginTransmission() and endTransmission()).
8297 size_t write (uint8_t value) {
8398 // TODO: implement
84- return 0 ; // number of bytes written
99+ txBuffer.push_back (value);
100+ return 1 ; // number of bytes written
85101 }
86102 size_t write (const char *str) { return str == NULL ? 0 : write ((const uint8_t *)str, String (str).length ()); }
87103 size_t write (const uint8_t *buffer, size_t size) {
@@ -100,39 +116,61 @@ class TwoWire : public ObservableDataStream
100116 // call to requestFrom() or on a slave inside the onReceive() handler.
101117 int available (void ) {
102118 // TODO: implement
103- return 0 ; // number of bytes available for reading
119+ // NOTE: probably unnecessary for current high level implementation
120+
121+ return rxBuffer.size (); // number of bytes available for reading
104122 }
105123
106124 // https://www.arduino.cc/en/Reference/WireRead
107125 // Reads a byte that was transmitted from a slave device to a master after a call to requestFrom() or was transmitted
108126 // from a master to a slave. read() inherits from the Stream utility class.
109127 int read (void ) {
110128 // TODO: implement
111- return ' \0 ' ; // The next byte received
129+ int value = -1 ;
130+ value = rxBuffer.at (0 );
131+ rxBuffer.erase (rxBuffer.begin ());
132+ return value; // The next byte received
112133 }
113134 int peek (void ) {
114135 // TODO: implement
136+ int value = -1 ;
137+ value = rxBuffer.at (0 );
115138 return 0 ;
116139 }
117140 void flush (void ) {
118141 // TODO: implement
142+ // NOTE: commented out in the megaavr repository
143+ txBuffer.clear ();
144+ rxBuffer.clear ();
119145 }
120146
121147 // https://www.arduino.cc/en/Reference/WireOnReceive
122148 // Registers a function to be called when a slave device receives a transmission from a master.
123149 void onReceive ( void (*callback)(int ) ) {
124150 // TODO: implement
151+ user_onReceive = callback;
125152 }
126153
127154 // https://www.arduino.cc/en/Reference/WireOnRequest
128155 // Register a function to be called when a master requests data from this slave device.
129156 void onRequest ( void (*callback)(void ) ) {
130157 // TODO: implement
158+ user_onRequest = callback;
131159 }
132160
161+ // testing methods
162+ bool getIsMaster () { return isMaster; }
163+ int getAddress () { return txAddress; }
164+ vector<uint8_t > getTxBuffer () { return txBuffer; }
165+ vector<uint8_t > getWriteData () { return writeData; }
166+
133167private:
134- int i2cAddress;
135168 bool isMaster = false ;
169+ uint8_t txAddress;
170+ static void (*user_onReceive)(int );
171+ static void (*user_onRequest)(void );
172+ // Consider queue data structure for a more "buffer-like" implementation with HEAD/TAIL
173+ vector<uint8_t > txBuffer, rxBuffer, writeData;
136174};
137175
138176extern TwoWire Wire;
0 commit comments