Skip to content

Commit bb61617

Browse files
committed
Added crude high level Wire implementation + Wire unit tests.
1 parent 6eee41a commit bb61617

File tree

1 file changed

+45
-7
lines changed

1 file changed

+45
-7
lines changed

cpp/arduino/Wire.h

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,12 @@
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
711
class TwoWire : public ObservableDataStream
812
{
913
public:
@@ -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+
133167
private:
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

138176
extern TwoWire Wire;

0 commit comments

Comments
 (0)