2
2
#pragma once
3
3
4
4
#include < inttypes.h>
5
+ #include < vector>
6
+ #include < cassert>
5
7
#include " Stream.h"
6
8
9
+
10
+ // Some inspiration taken from https://github.com/arduino/ArduinoCore-megaavr/blob/d2a81093ba66d22dbda14c30d146c231c5910734/libraries/Wire/src/Wire.cpp
7
11
class TwoWire : public ObservableDataStream
8
12
{
9
13
public:
@@ -14,30 +18,36 @@ class TwoWire : public ObservableDataStream
14
18
// Initiate the Wire library and join the I2C bus as a master or slave. This should normally be called only once.
15
19
void begin () {
16
20
isMaster = true ;
21
+ txAddress = 0 ;
17
22
}
18
23
void begin (int address) {
19
- i2cAddress = address;
24
+ txAddress = address;
20
25
isMaster = false ;
21
26
}
22
27
void begin (uint8_t address) {
23
28
begin ((int )address);
24
29
}
25
30
void end () {
26
31
// TODO: implement
32
+ // NOTE: unnecessary for current high level implementation
27
33
}
28
34
29
35
// https://www.arduino.cc/en/Reference/WireSetClock
30
36
// This function modifies the clock frequency for I2C communication. I2C slave devices have no minimum working
31
37
// clock frequency, however 100KHz is usually the baseline.
32
- void setClock (uint32_t ) {
38
+ void setClock (uint32_t clock ) {
33
39
// TODO: implement?
40
+ // NOTE: unnecessary for current high level implementation
34
41
}
35
42
36
43
// https://www.arduino.cc/en/Reference/WireBeginTransmission
37
44
// Begin a transmission to the I2C slave device with the given address. Subsequently, queue bytes for
38
45
// transmission with the write() function and transmit them by calling endTransmission().
39
46
void beginTransmission (int address) {
40
47
// TODO: implement
48
+ assert (isMaster);
49
+ txAddress = address;
50
+ txBuffer.clear ();
41
51
}
42
52
void beginTransmission (uint8_t address) {
43
53
beginTransmission ((int )address);
@@ -47,7 +57,10 @@ class TwoWire : public ObservableDataStream
47
57
// Ends a transmission to a slave device that was begun by beginTransmission() and transmits the bytes that were
48
58
// queued by write().
49
59
uint8_t endTransmission (uint8_t sendStop) {
50
- // TODO: implement
60
+ assert (isMaster);
61
+ txAddress = 0 ;
62
+ writeData = txBuffer;
63
+ txBuffer.clear ();
51
64
return 0 ; // success
52
65
}
53
66
uint8_t endTransmission (void ) {
@@ -59,6 +72,8 @@ class TwoWire : public ObservableDataStream
59
72
// available() and read() functions.
60
73
uint8_t requestFrom (int address, int quantity, int stop) {
61
74
// TODO: implement
75
+ // NOTE: deemed unnecessary for current high level implementation
76
+ assert (isMaster);
62
77
return 0 ; // number of bytes returned from the slave device
63
78
}
64
79
uint8_t requestFrom (int address, int quantity) {
@@ -81,7 +96,8 @@ class TwoWire : public ObservableDataStream
81
96
// master to slave device (in-between calls to beginTransmission() and endTransmission()).
82
97
size_t write (uint8_t value) {
83
98
// TODO: implement
84
- return 0 ; // number of bytes written
99
+ txBuffer.push_back (value);
100
+ return 1 ; // number of bytes written
85
101
}
86
102
size_t write (const char *str) { return str == NULL ? 0 : write ((const uint8_t *)str, String (str).length ()); }
87
103
size_t write (const uint8_t *buffer, size_t size) {
@@ -100,39 +116,61 @@ class TwoWire : public ObservableDataStream
100
116
// call to requestFrom() or on a slave inside the onReceive() handler.
101
117
int available (void ) {
102
118
// 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
104
122
}
105
123
106
124
// https://www.arduino.cc/en/Reference/WireRead
107
125
// Reads a byte that was transmitted from a slave device to a master after a call to requestFrom() or was transmitted
108
126
// from a master to a slave. read() inherits from the Stream utility class.
109
127
int read (void ) {
110
128
// 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
112
133
}
113
134
int peek (void ) {
114
135
// TODO: implement
136
+ int value = -1 ;
137
+ value = rxBuffer.at (0 );
115
138
return 0 ;
116
139
}
117
140
void flush (void ) {
118
141
// TODO: implement
142
+ // NOTE: commented out in the megaavr repository
143
+ txBuffer.clear ();
144
+ rxBuffer.clear ();
119
145
}
120
146
121
147
// https://www.arduino.cc/en/Reference/WireOnReceive
122
148
// Registers a function to be called when a slave device receives a transmission from a master.
123
149
void onReceive ( void (*callback)(int ) ) {
124
150
// TODO: implement
151
+ user_onReceive = callback;
125
152
}
126
153
127
154
// https://www.arduino.cc/en/Reference/WireOnRequest
128
155
// Register a function to be called when a master requests data from this slave device.
129
156
void onRequest ( void (*callback)(void ) ) {
130
157
// TODO: implement
158
+ user_onRequest = callback;
131
159
}
132
160
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
+
133
167
private:
134
- int i2cAddress;
135
168
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;
136
174
};
137
175
138
176
extern TwoWire Wire;
0 commit comments