arduino_ci 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +21 -19
- data/REFERENCE.md +625 -0
- data/cpp/arduino/Arduino.h +1 -2
- data/cpp/arduino/AvrMath.h +117 -17
- data/cpp/arduino/Client.h +26 -0
- data/cpp/arduino/EEPROM.h +64 -0
- data/cpp/arduino/Godmode.cpp +7 -0
- data/cpp/arduino/Godmode.h +58 -9
- data/cpp/arduino/HardwareSerial.h +4 -4
- data/cpp/arduino/IPAddress.h +59 -0
- data/cpp/arduino/Print.h +9 -12
- data/cpp/arduino/Printable.h +8 -0
- data/cpp/arduino/SPI.h +11 -3
- data/cpp/arduino/Server.h +5 -0
- data/cpp/arduino/Udp.h +27 -0
- data/cpp/arduino/Wire.h +173 -77
- data/cpp/arduino/avr/io.h +10 -1
- data/cpp/arduino/avr/pgmspace.h +76 -46
- data/cpp/unittest/OstreamHelpers.h +4 -0
- data/exe/arduino_ci.rb +401 -0
- data/exe/arduino_ci_remote.rb +2 -393
- data/lib/arduino_ci.rb +1 -0
- data/lib/arduino_ci/arduino_downloader.rb +5 -4
- data/lib/arduino_ci/arduino_installation.rb +5 -5
- data/lib/arduino_ci/cpp_library.rb +124 -24
- data/lib/arduino_ci/installed_cpp_library.rb +0 -0
- data/lib/arduino_ci/library_properties.rb +86 -0
- data/lib/arduino_ci/version.rb +1 -1
- data/misc/default.yml +50 -3
- metadata +15 -7
- data/cpp/arduino/Arduino.h.orig +0 -143
- data/exe/libasan.rb +0 -29
data/cpp/arduino/Print.h
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
#include <stdio.h>
|
4
4
|
#include <avr/pgmspace.h>
|
5
|
+
|
6
|
+
#include "Printable.h"
|
5
7
|
#include "WString.h"
|
6
8
|
|
7
9
|
#define DEC 10
|
@@ -12,22 +14,17 @@
|
|
12
14
|
#endif
|
13
15
|
#define BIN 2
|
14
16
|
|
15
|
-
class Print;
|
16
|
-
|
17
|
-
class Printable
|
18
|
-
{
|
19
|
-
public:
|
20
|
-
virtual size_t printTo(Print& p) const = 0;
|
21
|
-
};
|
22
|
-
|
23
17
|
class Print
|
24
18
|
{
|
19
|
+
private:
|
20
|
+
int write_error;
|
21
|
+
protected:
|
22
|
+
void setWriteError(int err = 1) { write_error = err; }
|
25
23
|
public:
|
26
|
-
Print() {}
|
24
|
+
Print() : write_error(0) {}
|
27
25
|
|
28
|
-
|
29
|
-
|
30
|
-
void clearWriteError() { }
|
26
|
+
int getWriteError() { return write_error; }
|
27
|
+
void clearWriteError() { setWriteError(0); }
|
31
28
|
virtual int availableForWrite() { return 0; }
|
32
29
|
|
33
30
|
virtual size_t write(uint8_t) = 0;
|
data/cpp/arduino/SPI.h
CHANGED
@@ -40,7 +40,11 @@
|
|
40
40
|
|
41
41
|
class SPISettings {
|
42
42
|
public:
|
43
|
-
|
43
|
+
uint8_t bitOrder;
|
44
|
+
|
45
|
+
SPISettings(uint32_t clock, uint8_t bitOrder = MSBFIRST, uint8_t dataMode = SPI_MODE0) {
|
46
|
+
this->bitOrder = bitOrder;
|
47
|
+
};
|
44
48
|
SPISettings(){};
|
45
49
|
};
|
46
50
|
|
@@ -68,6 +72,7 @@ public:
|
|
68
72
|
// and configure the correct settings.
|
69
73
|
void beginTransaction(SPISettings settings)
|
70
74
|
{
|
75
|
+
this->bitOrder = settings.bitOrder;
|
71
76
|
#ifdef SPI_TRANSACTION_MISMATCH_LED
|
72
77
|
if (inTransactionFlag) {
|
73
78
|
pinMode(SPI_TRANSACTION_MISMATCH_LED, OUTPUT);
|
@@ -94,10 +99,12 @@ public:
|
|
94
99
|
uint16_t transfer16(uint16_t data) {
|
95
100
|
union { uint16_t val; struct { uint8_t lsb; uint8_t msb; }; } in, out;
|
96
101
|
in.val = data;
|
97
|
-
if (
|
102
|
+
if (bitOrder == MSBFIRST) {
|
98
103
|
out.msb = transfer(in.msb);
|
99
104
|
out.lsb = transfer(in.lsb);
|
100
|
-
}
|
105
|
+
}
|
106
|
+
else
|
107
|
+
{
|
101
108
|
out.lsb = transfer(in.lsb);
|
102
109
|
out.msb = transfer(in.msb);
|
103
110
|
}
|
@@ -143,6 +150,7 @@ private:
|
|
143
150
|
#endif
|
144
151
|
|
145
152
|
bool isStarted = false;
|
153
|
+
uint8_t bitOrder;
|
146
154
|
String* dataIn;
|
147
155
|
String* dataOut;
|
148
156
|
};
|
data/cpp/arduino/Udp.h
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
#pragma once
|
2
|
+
|
3
|
+
#include <IPAddress.h>
|
4
|
+
#include <Stream.h>
|
5
|
+
|
6
|
+
class UDP : public Stream {
|
7
|
+
protected:
|
8
|
+
uint8_t *rawIPAddress(IPAddress &addr) { return addr.raw_address(); };
|
9
|
+
|
10
|
+
public:
|
11
|
+
UDP() {
|
12
|
+
// The Stream mock defines a String buffer but never puts anyting in it!
|
13
|
+
if (!mGodmodeDataIn) {
|
14
|
+
mGodmodeDataIn = new String;
|
15
|
+
}
|
16
|
+
}
|
17
|
+
~UDP() {
|
18
|
+
if (mGodmodeDataIn) {
|
19
|
+
delete mGodmodeDataIn;
|
20
|
+
mGodmodeDataIn = nullptr;
|
21
|
+
}
|
22
|
+
}
|
23
|
+
virtual size_t write(uint8_t value) {
|
24
|
+
mGodmodeDataIn->concat(value);
|
25
|
+
return 1;
|
26
|
+
}
|
27
|
+
};
|
data/cpp/arduino/Wire.h
CHANGED
@@ -1,138 +1,234 @@
|
|
1
|
+
/*
|
2
|
+
* The Wire Library (https://www.arduino.cc/en/Reference/Wire)
|
3
|
+
* allows you to communicate with I2C/TWI devices. The general
|
4
|
+
* TWI protocol supports one "master" device and many "slave"
|
5
|
+
* devices that share the same two wires (SDA and SCL for data
|
6
|
+
* and clock respectively).
|
7
|
+
*
|
8
|
+
* You initialize the library by calling begin() as a master or
|
9
|
+
* begin(myAddress) as a slave (with an int from 8-127). In the
|
10
|
+
* initial mock implementation we support only the master role.
|
11
|
+
*
|
12
|
+
* To send bytes from a master to a slave, start with
|
13
|
+
* beginTransmission(slaveAddress), then use write(byte) to
|
14
|
+
* enqueue data, and finish with endTransmission().
|
15
|
+
*
|
16
|
+
* When a master wants to read, it starts with a call to
|
17
|
+
* requestFrom(slaveAddress, quantity) which blocks until the
|
18
|
+
* request finishes. The return value is either 0 (if the slave
|
19
|
+
* does not respond) or the number of bytes requested (which
|
20
|
+
* might be more than the number sent since reading is simply
|
21
|
+
* looking at a pin value at each clock tick).
|
22
|
+
*
|
23
|
+
* A master can write to or read from two or more slaves in
|
24
|
+
* quick succession (say, during one loop() function), so our
|
25
|
+
* mock needs to support preloading data to be read from multiple
|
26
|
+
* slaves and archive data sent to multiple slaves.
|
27
|
+
*
|
28
|
+
* In the mock, this is handled by having an array of wireData_t
|
29
|
+
* structures, each of which contains a deque for input and a
|
30
|
+
* deque for output. You can preload data to be read and you can
|
31
|
+
* look at a log of data that has been written.
|
32
|
+
*/
|
1
33
|
|
2
34
|
#pragma once
|
3
35
|
|
4
36
|
#include <inttypes.h>
|
5
37
|
#include "Stream.h"
|
38
|
+
#include <cassert>
|
39
|
+
#include <deque>
|
40
|
+
using std::deque;
|
41
|
+
|
42
|
+
const size_t SLAVE_COUNT = 128;
|
43
|
+
const size_t BUFFER_LENGTH = 32;
|
44
|
+
|
45
|
+
struct wireData_t {
|
46
|
+
uint8_t misoSize; // bytes remaining for this read
|
47
|
+
uint8_t mosiSize; // bytes included in this write
|
48
|
+
deque<uint8_t> misoBuffer; // master in, slave out
|
49
|
+
deque<uint8_t> mosiBuffer; // master out, slave in
|
50
|
+
};
|
51
|
+
|
52
|
+
// Some inspiration taken from
|
53
|
+
// https://github.com/arduino/ArduinoCore-megaavr/blob/d2a81093ba66d22dbda14c30d146c231c5910734/libraries/Wire/src/Wire.cpp
|
54
|
+
class TwoWire : public ObservableDataStream {
|
55
|
+
private:
|
56
|
+
bool _didBegin = false;
|
57
|
+
wireData_t *in = nullptr; // pointer to current slave for writing
|
58
|
+
wireData_t *out = nullptr; // pointer to current slave for reading
|
59
|
+
wireData_t slaves[SLAVE_COUNT];
|
6
60
|
|
7
|
-
class TwoWire : public ObservableDataStream
|
8
|
-
{
|
9
61
|
public:
|
62
|
+
// constructor initializes internal data
|
10
63
|
TwoWire() {
|
64
|
+
for (int i = 0; i < SLAVE_COUNT; ++i) {
|
65
|
+
slaves[i].misoSize = 0;
|
66
|
+
slaves[i].mosiSize = 0;
|
67
|
+
}
|
11
68
|
}
|
12
69
|
|
13
70
|
// https://www.arduino.cc/en/Reference/WireBegin
|
14
|
-
// Initiate the Wire library and join the I2C bus as a master or slave. This
|
15
|
-
|
16
|
-
|
17
|
-
}
|
18
|
-
void begin(int address) {
|
19
|
-
i2cAddress = address;
|
20
|
-
isMaster = false;
|
21
|
-
}
|
71
|
+
// Initiate the Wire library and join the I2C bus as a master or slave. This
|
72
|
+
// should normally be called only once.
|
73
|
+
void begin() { begin(0); }
|
22
74
|
void begin(uint8_t address) {
|
23
|
-
|
24
|
-
|
25
|
-
void end() {
|
26
|
-
// TODO: implement
|
75
|
+
assert(address == 0);
|
76
|
+
_didBegin = true;
|
27
77
|
}
|
78
|
+
void begin(int address) { begin((uint8_t)address); }
|
79
|
+
// NOTE: end() is not part of the published API so we ignore it
|
80
|
+
void end() {}
|
28
81
|
|
29
82
|
// https://www.arduino.cc/en/Reference/WireSetClock
|
30
|
-
// This function modifies the clock frequency for I2C communication. I2C slave
|
31
|
-
// clock frequency, however 100KHz is usually
|
32
|
-
|
33
|
-
|
34
|
-
}
|
83
|
+
// This function modifies the clock frequency for I2C communication. I2C slave
|
84
|
+
// devices have no minimum working clock frequency, however 100KHz is usually
|
85
|
+
// the baseline.
|
86
|
+
// Since the mock does not actually write pins we ignore this.
|
87
|
+
void setClock(uint32_t clock) {}
|
35
88
|
|
36
89
|
// https://www.arduino.cc/en/Reference/WireBeginTransmission
|
37
|
-
// Begin a transmission to the I2C slave device with the given address.
|
38
|
-
// transmission with the write() function and
|
39
|
-
|
40
|
-
|
41
|
-
}
|
90
|
+
// Begin a transmission to the I2C slave device with the given address.
|
91
|
+
// Subsequently, queue bytes for transmission with the write() function and
|
92
|
+
// transmit them by calling endTransmission().
|
93
|
+
// For the mock we update our output to the proper destination.
|
42
94
|
void beginTransmission(uint8_t address) {
|
43
|
-
|
95
|
+
assert(_didBegin);
|
96
|
+
assert(address > 0 && address < SLAVE_COUNT);
|
97
|
+
assert(out == nullptr);
|
98
|
+
out = &slaves[address];
|
99
|
+
out->mosiSize = 0;
|
44
100
|
}
|
101
|
+
void beginTransmission(int address) { beginTransmission((uint8_t)address); }
|
45
102
|
|
46
103
|
// https://www.arduino.cc/en/Reference/WireEndTransmission
|
47
|
-
// Ends a transmission to a slave device that was begun by beginTransmission()
|
48
|
-
// queued by write().
|
49
|
-
|
50
|
-
|
104
|
+
// Ends a transmission to a slave device that was begun by beginTransmission()
|
105
|
+
// and transmits the bytes that were queued by write().
|
106
|
+
// In the mock we just leave the bytes there in the buffer
|
107
|
+
// to be read by the testing API and we ignore the sendStop.
|
108
|
+
uint8_t endTransmission(bool sendStop) {
|
109
|
+
assert(_didBegin);
|
110
|
+
assert(out);
|
111
|
+
out = nullptr;
|
51
112
|
return 0; // success
|
52
113
|
}
|
53
|
-
uint8_t endTransmission(void) {
|
54
|
-
return endTransmission((uint8_t)true);
|
55
|
-
}
|
114
|
+
uint8_t endTransmission(void) { return endTransmission(true); }
|
56
115
|
|
57
116
|
// https://www.arduino.cc/en/Reference/WireRequestFrom
|
58
|
-
// Used by the master to request bytes from a slave device. The bytes may then
|
59
|
-
// available() and read() functions.
|
60
|
-
uint8_t requestFrom(
|
61
|
-
|
62
|
-
|
117
|
+
// Used by the master to request bytes from a slave device. The bytes may then
|
118
|
+
// be retrieved with the available() and read() functions.
|
119
|
+
uint8_t requestFrom(uint8_t address, uint8_t quantity, uint32_t _iaddress, uint8_t _isize, uint8_t stop) {
|
120
|
+
assert(_didBegin);
|
121
|
+
assert(address > 0 && address < SLAVE_COUNT);
|
122
|
+
assert(quantity <= BUFFER_LENGTH);
|
123
|
+
in = &slaves[address];
|
124
|
+
// do we have enough data in the input buffer
|
125
|
+
if (quantity <= (in->misoBuffer).size()) { // enough data
|
126
|
+
in->misoSize = quantity;
|
127
|
+
return quantity;
|
128
|
+
} else { // not enough data
|
129
|
+
in->misoSize = 0;
|
130
|
+
in = nullptr;
|
131
|
+
return 0;
|
132
|
+
}
|
63
133
|
}
|
64
|
-
|
65
|
-
|
66
|
-
return requestFrom(address, quantity, stop);
|
134
|
+
|
135
|
+
uint8_t requestFrom(uint8_t address, uint8_t quantity, uint8_t stop) {
|
136
|
+
return requestFrom((uint8_t)address, (uint8_t)quantity, (uint32_t)0, (uint8_t)0, (uint8_t)stop);
|
67
137
|
}
|
138
|
+
|
68
139
|
uint8_t requestFrom(uint8_t address, uint8_t quantity) {
|
69
|
-
return requestFrom((
|
140
|
+
return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)true);
|
70
141
|
}
|
71
|
-
|
72
|
-
|
142
|
+
|
143
|
+
uint8_t requestFrom(int address, int quantity) {
|
144
|
+
return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)true);
|
73
145
|
}
|
74
|
-
uint8_t requestFrom(
|
75
|
-
|
76
|
-
return 0;
|
146
|
+
uint8_t requestFrom(int address, int quantity, int stop) {
|
147
|
+
return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)stop);
|
77
148
|
}
|
78
149
|
|
79
150
|
// https://www.arduino.cc/en/Reference/WireWrite
|
80
|
-
// Writes data from a slave device in response to a request from a master, or
|
81
|
-
// master to slave device (in-between
|
151
|
+
// Writes data from a slave device in response to a request from a master, or
|
152
|
+
// queues bytes for transmission from a master to slave device (in-between
|
153
|
+
// calls to beginTransmission() and endTransmission()).
|
82
154
|
size_t write(uint8_t value) {
|
83
|
-
|
84
|
-
|
155
|
+
assert(out);
|
156
|
+
assert(++(out->mosiSize) <= BUFFER_LENGTH);
|
157
|
+
(out->mosiBuffer).push_back(value);
|
158
|
+
return 1; // number of bytes written
|
159
|
+
}
|
160
|
+
size_t write(const char *str) {
|
161
|
+
return str == NULL ? 0 : write((const uint8_t *)str, String(str).length());
|
85
162
|
}
|
86
|
-
size_t write(const char *str) { return str == NULL ? 0 : write((const uint8_t *)str, String(str).length()); }
|
87
163
|
size_t write(const uint8_t *buffer, size_t size) {
|
88
164
|
size_t n;
|
89
|
-
for (n = 0; size && write(*buffer++) && ++n; --size)
|
165
|
+
for (n = 0; size && write(*buffer++) && ++n; --size)
|
166
|
+
;
|
90
167
|
return n;
|
91
168
|
}
|
92
|
-
size_t write(const char *buffer, size_t size) {
|
169
|
+
size_t write(const char *buffer, size_t size) {
|
170
|
+
return write((const uint8_t *)buffer, size);
|
171
|
+
}
|
93
172
|
size_t write(unsigned long n) { return write((uint8_t)n); }
|
94
173
|
size_t write(long n) { return write((uint8_t)n); }
|
95
174
|
size_t write(unsigned int n) { return write((uint8_t)n); }
|
96
175
|
size_t write(int n) { return write((uint8_t)n); }
|
97
176
|
|
98
177
|
// https://www.arduino.cc/en/Reference/WireAvailable
|
99
|
-
// Returns the number of bytes available for retrieval with read(). This
|
100
|
-
// call to requestFrom() or on a
|
178
|
+
// Returns the number of bytes available for retrieval with read(). This
|
179
|
+
// should be called on a master device after a call to requestFrom() or on a
|
180
|
+
// slave inside the onReceive() handler.
|
101
181
|
int available(void) {
|
102
|
-
|
103
|
-
return
|
182
|
+
assert(in);
|
183
|
+
return in->misoSize;
|
104
184
|
}
|
105
185
|
|
106
186
|
// https://www.arduino.cc/en/Reference/WireRead
|
107
|
-
// Reads a byte that was transmitted from a slave device to a master after a
|
108
|
-
// from a master to a slave. read()
|
109
|
-
|
110
|
-
|
111
|
-
|
187
|
+
// Reads a byte that was transmitted from a slave device to a master after a
|
188
|
+
// call to requestFrom() or was transmitted from a master to a slave. read()
|
189
|
+
// inherits from the Stream utility class.
|
190
|
+
// In the mock we simply return the next byte from the input buffer.
|
191
|
+
uint8_t read(void) {
|
192
|
+
uint8_t value = peek();
|
193
|
+
--in->misoSize;
|
194
|
+
in->misoBuffer.pop_front();
|
195
|
+
return value; // The next byte received
|
112
196
|
}
|
113
|
-
|
114
|
-
|
115
|
-
|
197
|
+
|
198
|
+
// part of the Stream API
|
199
|
+
uint8_t peek(void) {
|
200
|
+
assert(in);
|
201
|
+
assert(0 < in->misoSize);
|
202
|
+
return in->misoBuffer.front(); // The next byte received
|
116
203
|
}
|
204
|
+
|
205
|
+
// part of the Stream API
|
117
206
|
void flush(void) {
|
118
|
-
//
|
207
|
+
// NOTE: commented out in the megaavr repository
|
208
|
+
// data already at the (mock) destination
|
119
209
|
}
|
120
210
|
|
121
211
|
// https://www.arduino.cc/en/Reference/WireOnReceive
|
122
|
-
// Registers a function to be called when a slave device receives a
|
123
|
-
|
124
|
-
|
125
|
-
}
|
212
|
+
// Registers a function to be called when a slave device receives a
|
213
|
+
// transmission from a master.
|
214
|
+
// We don't (yet) support the slave role in the mock
|
215
|
+
void onReceive(void (*callback)(int)) { assert(false); }
|
126
216
|
|
127
217
|
// https://www.arduino.cc/en/Reference/WireOnRequest
|
128
|
-
// Register a function to be called when a master requests data from this
|
129
|
-
|
130
|
-
|
131
|
-
}
|
218
|
+
// Register a function to be called when a master requests data from this
|
219
|
+
// slave device.
|
220
|
+
// We don't (yet) support the slave role in the mock
|
221
|
+
void onRequest(void (*callback)(void)) { assert(false); }
|
132
222
|
|
133
|
-
|
134
|
-
|
135
|
-
|
223
|
+
// testing methods
|
224
|
+
bool didBegin() { return _didBegin; }
|
225
|
+
|
226
|
+
deque<uint8_t> *getMiso(uint8_t address) {
|
227
|
+
return &slaves[address].misoBuffer;
|
228
|
+
}
|
229
|
+
deque<uint8_t> *getMosi(uint8_t address) {
|
230
|
+
return &slaves[address].mosiBuffer;
|
231
|
+
}
|
136
232
|
};
|
137
233
|
|
138
234
|
extern TwoWire Wire;
|
data/cpp/arduino/avr/io.h
CHANGED
@@ -96,7 +96,16 @@
|
|
96
96
|
#ifndef _AVR_IO_H_
|
97
97
|
#define _AVR_IO_H_
|
98
98
|
|
99
|
-
#
|
99
|
+
#include <stdint.h>
|
100
|
+
|
101
|
+
// hardware mocks
|
102
|
+
// this set of macros is all we need from the sfr file
|
103
|
+
extern volatile uint8_t __ARDUINO_CI_SFR_MOCK[1024];
|
104
|
+
#define _SFR_IO8(io_addr) (*(volatile uint8_t *)(__ARDUINO_CI_SFR_MOCK + io_addr))
|
105
|
+
#define _SFR_IO16(io_addr) (*(volatile uint16_t *)(__ARDUINO_CI_SFR_MOCK + io_addr))
|
106
|
+
#define _SFR_MEM8(io_addr) (*(volatile uint8_t *)(__ARDUINO_CI_SFR_MOCK + io_addr))
|
107
|
+
#define _SFR_MEM16(io_addr) (*(volatile uint16_t *)(__ARDUINO_CI_SFR_MOCK + io_addr))
|
108
|
+
#define _SFR_MEM32(io_addr) (*(volatile uint32_t *)(__ARDUINO_CI_SFR_MOCK + io_addr))
|
100
109
|
|
101
110
|
#if defined (__AVR_AT94K__)
|
102
111
|
# include "ioat94k.h"
|