Skip to content

Commit 226bc18

Browse files
committed
Completed wire implementation with address tracking via maps + tests
1 parent 13862bc commit 226bc18

File tree

2 files changed

+75
-18
lines changed

2 files changed

+75
-18
lines changed

SampleProjects/TestSomething/test/wire.cpp

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include <ArduinoUnitTests.h>
22
#include <Arduino.h>
33
#include <vector>
4+
#include <map>
45

56
#include <Wire.h>
67
using namespace std;
@@ -37,15 +38,41 @@ unittest(begin_write_end) {
3738
assertEqual(0x07, Wire.getTxBufferElement(0));
3839
assertEqual(0x0E, Wire.getTxBufferElement(1));
3940

40-
Wire.endTransmission(true);
41+
Wire.endTransmission();
4142
assertTrue(Wire.isTxBufferEmpty());
42-
assertEqual(0x07, Wire.getWriteDataElement(0));
43-
assertEqual(0x0E, Wire.getWriteDataElement(1));
43+
44+
vector<int> finalData = {0x07, 0x0E};
45+
assert(finalData == Wire.getDataWritten(14));
4446
}
4547

46-
// want to add read test, though it seems to depend on requestFrom
48+
unittest(readTwo_writeOne) {
49+
Wire.begin();
50+
51+
vector<int> data1 = {0x07, 0x0E}, data2 = {1, 4, 7};
52+
Wire.setDataToRead(19, data1);
53+
Wire.setDataToRead(34, data2);
4754

55+
assertEqual(2, Wire.requestFrom(19, 1));
56+
assertEqual(3, Wire.requestFrom(34, 1));
57+
assertEqual(data1.size() + data2.size(), Wire.getRxBufferSize());
4858

59+
Wire.beginTransmission(47);
60+
assertEqual(47, Wire.getAddress());
61+
assertTrue(Wire.isTxBufferEmpty());
62+
for (int i = 0; i < 5; i++) {
63+
Wire.write(Wire.read());
64+
}
65+
assertEqual(0x07, Wire.getTxBufferElement(0));
66+
assertEqual(0x0E, Wire.getTxBufferElement(1));
67+
assertEqual(1, Wire.getTxBufferElement(2));
68+
assertEqual(4, Wire.getTxBufferElement(3));
69+
assertEqual(7, Wire.getTxBufferElement(4));
70+
71+
Wire.endTransmission();
72+
assertTrue(Wire.isTxBufferEmpty());
4973

74+
vector<int> finalData = {0x07, 0x0E, 1, 4, 7};
75+
assert(finalData == Wire.getDataWritten(47));
76+
}
5077

5178
unittest_main()

cpp/arduino/Wire.h

Lines changed: 44 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,38 @@
22
#pragma once
33

44
#include <inttypes.h>
5+
6+
// https://github.com/Arduino-CI/arduino_ci/issues/165
7+
#ifdef max
8+
#undef max
9+
#ifdef __cplusplus
10+
template <class T, class L>
11+
auto max(const T &a, const L &b) -> decltype((b < a) ? b : a) {
12+
return (a < b) ? b : a;
13+
}
14+
#else
15+
#define max(a, b) \
16+
({ \
17+
__typeof__(a) _a = (a); \
18+
__typeof__(b) _b = (b); \
19+
_a > _b ? _a : _b; \
20+
})
21+
#endif
22+
#endif
23+
24+
// map is already defined in AvrMath.h. Need to use C++'s map.
25+
#ifdef map
26+
#undef map
27+
#endif
28+
29+
530
#include <vector>
31+
#include <map>
632
#include <cassert>
733
#include "Stream.h"
834

935
using std::vector;
36+
using std::map;
1037

1138
// Some inspiration taken from https://github.com/arduino/ArduinoCore-megaavr/blob/d2a81093ba66d22dbda14c30d146c231c5910734/libraries/Wire/src/Wire.cpp
1239
class TwoWire : public ObservableDataStream
@@ -45,7 +72,6 @@ class TwoWire : public ObservableDataStream
4572
// Begin a transmission to the I2C slave device with the given address. Subsequently, queue bytes for
4673
// transmission with the write() function and transmit them by calling endTransmission().
4774
void beginTransmission(int address) {
48-
// TODO: implement
4975
assert(isMaster);
5076
txAddress = address;
5177
txBuffer.clear();
@@ -59,9 +85,12 @@ class TwoWire : public ObservableDataStream
5985
// queued by write().
6086
uint8_t endTransmission(uint8_t sendStop) {
6187
assert(isMaster);
62-
txAddress = 0;
63-
writeData = txBuffer;
88+
int bufferSize = txBuffer.size();
89+
dataWritten[txAddress] = txBuffer;
6490
txBuffer.clear();
91+
// ensure separate objects
92+
assert(bufferSize == dataWritten[txAddress].size());
93+
txAddress = 0;
6594
return 0; // success
6695
}
6796
uint8_t endTransmission(void) {
@@ -72,10 +101,13 @@ class TwoWire : public ObservableDataStream
72101
// Used by the master to request bytes from a slave device. The bytes may then be retrieved with the
73102
// available() and read() functions.
74103
uint8_t requestFrom(int address, int quantity, int stop) {
75-
// TODO: implement
76-
// NOTE: deemed unnecessary for current high level implementation
104+
// TODO: implement quantity and stop?
77105
assert(isMaster);
78-
return 0; // number of bytes returned from the slave device
106+
107+
int oldRxBufferLength = rxBuffer.size();
108+
// append vector to vector
109+
rxBuffer.insert(rxBuffer.end(), dataToRead[address].begin(), dataToRead[address].end());
110+
return rxBuffer.size()-oldRxBufferLength; // number of bytes returned from the slave device
79111
}
80112
uint8_t requestFrom(int address, int quantity) {
81113
int stop = true;
@@ -96,7 +128,6 @@ class TwoWire : public ObservableDataStream
96128
// Writes data from a slave device in response to a request from a master, or queues bytes for transmission from a
97129
// master to slave device (in-between calls to beginTransmission() and endTransmission()).
98130
size_t write(uint8_t value) {
99-
// TODO: implement
100131
txBuffer.push_back(value);
101132
return 1; // number of bytes written
102133
}
@@ -116,9 +147,6 @@ class TwoWire : public ObservableDataStream
116147
// Returns the number of bytes available for retrieval with read(). This should be called on a master device after a
117148
// call to requestFrom() or on a slave inside the onReceive() handler.
118149
int available(void) {
119-
// TODO: implement
120-
// NOTE: probably unnecessary for current high level implementation
121-
122150
return rxBuffer.size(); // number of bytes available for reading
123151
}
124152

@@ -163,16 +191,18 @@ class TwoWire : public ObservableDataStream
163191
bool getIsMaster() { return isMaster; }
164192
int getAddress() { return txAddress; }
165193
bool isTxBufferEmpty() { return txBuffer.empty(); }
166-
uint8_t getTxBufferElement(int index) { return txBuffer.at(index); }
167-
uint8_t getWriteDataElement(int index) { return writeData.at(index); }
194+
int getTxBufferElement(int index) { return txBuffer.at(index); }
195+
vector<int> getDataWritten(int address) { return dataWritten.at(address); }
196+
int getRxBufferSize() { return rxBuffer.size(); }
197+
void setDataToRead(int address, vector<int> data) { dataToRead[address] = data; }
168198

169199
private:
170200
bool isMaster = false;
171201
uint8_t txAddress;
172202
static void (*user_onReceive)(int);
173203
static void (*user_onRequest)(void);
174-
// Consider queue data structure for a more "buffer-like" implementation with HEAD/TAIL
175-
vector<uint8_t> txBuffer, rxBuffer, writeData;
204+
vector<int> txBuffer, rxBuffer;
205+
map<uint8_t, vector<int>> dataToRead, dataWritten;
176206
};
177207

178208
extern TwoWire Wire;

0 commit comments

Comments
 (0)