Skip to content

Commit adcc8b8

Browse files
authored
Merge pull request #256 from ianfixes/2020-12-28_wrapup
Finish 2020 milestone
2 parents e592ea7 + e133689 commit adcc8b8

17 files changed

+412
-133
lines changed

Diff for: .github/workflows/README.md

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
## Note to `arduino_ci` users
2+
3+
In this project, we define a workflow for each target platform. **If you're looking for an example you can copy from, take only `linux.yaml`.**
4+
5+
6+
### Long version
7+
8+
The reason that all platforms are tested in _this_ project is to ensure that, as a framework, `arduino_ci` will run properly on any developer's personal workstation (regardless of OS).
9+
10+
For testing an individual Arduino library in the context of GitHub, [Linux is the cheapest option](https://docs.github.com/en/free-pro-team@latest/github/setting-up-and-managing-billing-and-payments-on-github/about-billing-for-github-actions) and produces results identical to the other OSes.

Diff for: .rubocop.yml

+4
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ Layout/EmptyLinesAroundMethodBody:
4545
Layout/EmptyLinesAroundModuleBody:
4646
Enabled: false
4747

48+
# This can add clarity
49+
Style/CommentedKeyword:
50+
Enabled: false
51+
4852
# Configuration parameters: AllowForAlignment.
4953
Layout/ExtraSpacing:
5054
Enabled: false

Diff for: CHANGELOG.md

+11
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,18 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1515
- `assertNAN()` and `assertNotNAN()` for comparing floats to `NaN`
1616
- `assertion()`, `ReporterTAP.onAssert()`, and `testBehaviorExp` macro to handle simple expression evaluation (is true, is false, etc)
1717
- `Wire.resetMocks()` and documentation
18+
- `shiftIn()` and `shiftOut()`
19+
- `CIConfig.is_default` to detect when the default configuration is used
20+
- `ArduinoBackend.boards_installed?` to detect whether a board family (or package, like `arduino:avr`) is installed
21+
- `ArduinoBackend.library_available?` to detect whether the library manager knows of a library
22+
- Sanity checks for `library.properties` `includes=` and `depends=` entries
1823

1924
### Changed
2025
- Rubocop expected syntax downgraded from ruby 2.6 to 2.5
2126
- `assertEqual()` and `assertNotEqual()` use actual `==` and `!=` -- they no longer require a type to be totally ordered just to do equality tests
2227
- Evaluative assertions (is true/false/null/etc) now produce simpler error messages instead of masquerading as an operation (e.g. "== true")
28+
- `LibraryProperties.to_h` now properly uses formatters and symbolic keys, in order to support a `.to_s`
29+
- Architectures from `library.properties` are considered when iterating over unit test or examples compilation, as well as the configured platforms
2330

2431
### Deprecated
2532

@@ -28,6 +35,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
2835
### Fixed
2936
- Warnings about directory name mismatches are now based on proper comparison of strings
3037
- Now using the recommended "stable" URL for the `esp32` board family
38+
- `esp8266:huzzah` options updated as per upstream
39+
- Errors about `'_NOP' was not declared in this scope` (test added)
40+
- `pinMode()` and `analogReference()` are now functions (no longer macros), because that conflicted with actual function names in the wild
41+
- `analogReadResolution()` and `analogWriteResolution()` are also no longer macros
3142

3243
### Security
3344

Diff for: REFERENCE.md

+15-1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ This completely skips the compilation tests (of library examples) portion of the
2929
This completely skips the compilation tests (of library examples) portion of the CI script. It does not skip the compilation of unit tests.
3030

3131

32+
### `--skip-library-properties` option
33+
34+
This completely skips validation of entries in `library.properties`.
35+
36+
3237
### `--testfile-select` option
3338

3439
This allows a file (or glob) pattern to be executed in your tests directory, creating a whitelist of files to test. E.g. `--testfile-select=test_animal_*.cpp` would match `test_animal_cat.cpp` and `test_animal_dog.cpp` (testing only those) and not `test_plant_rose.cpp`.
@@ -59,6 +64,11 @@ If set, testing will fail if no unit test files are detected (or if the director
5964
If set, testing will fail if no example sketches are detected. This is to avoid communicating a passing status in cases where a commit may have accidentally moved or deleted the examples.
6065

6166

67+
### `SKIP_LIBRARY_PROPERTIES` environment variable
68+
69+
If set, testing will skip validating `library.properties` entries. This is to work around any possible bugs in `arduino_ci`'s interpretation of what is "correct".
70+
71+
6272
## Indirectly Overriding Build Behavior (medium term use), and Advanced Options
6373

6474
For build behavior that you'd like to persist across commits (e.g. defining the set of platforms to test against, disabling a test that you expect to re-enable at some future point), a special configuration file called `.arduino-ci.yml` can be used. There are 3 places you can put them:
@@ -84,6 +94,8 @@ packages:
8494
8595
To define a platform called `bogo` that uses a board called `potato:salad:bogo` (based on the `potato:salad` family), set it up in the `plaforms:` section. Note that this will override any default configuration of `bogo` if it had existed in `arduino_ci`'s `misc/default.yml` file. If this board defines particular features in the compiler, you can set those here.
8696

97+
> Note that the platform names are arbitrary -- just keys in this yaml file and in the [`default.yml`](https://github.com/Arduino-CI/arduino_ci/blob/master/misc/default.yml) file included in this gem. That said, they are also case sensitive; defining the `bogo` platform will not let you refer to it as `Bogo` nor `BOGO`.
98+
8799
```yaml
88100
platforms:
89101
# our custom definition of the "bogo" platform
@@ -117,7 +129,9 @@ platforms:
117129
### Control How Examples Are Compiled
118130
119131
Put a file `.arduino-ci.yml` in each example directory where you require a different configuration than default.
120-
The `compile:` section controls the platforms on which the compilation will be attempted, as well as any external libraries that must be installed and included.
132+
The `compile:` section controls the platforms on which the compilation will be attempted, as well as any external libraries that must be installed and included. This works by _overriding_ portions of the default configuration.
133+
134+
> Note that the platform names _must_ match (case-sensitive) the platform names in the underlying [`default.yml`](https://github.com/Arduino-CI/arduino_ci/blob/master/misc/default.yml), or else match platforms that you have defined yourself in your `.arduino-ci.yml` override.
121135

122136
```yaml
123137
compile:

Diff for: SampleProjects/TestSomething/test/godmode.cpp

+66
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,72 @@ unittest(spi) {
222222
assertEqual("LMNOe", String(inBuf));
223223
}
224224

225+
unittest(shift_in) {
226+
227+
uint8_t dataPin = 2;
228+
uint8_t clockPin = 3;
229+
uint8_t input;
230+
bool actualClock[16];
231+
uint8_t originalSize;
232+
233+
// verify data
234+
state->reset();
235+
state->digitalPin[dataPin].fromAscii("|", true); // 0111 1100
236+
originalSize = state->digitalPin[clockPin].historySize();
237+
238+
input = shiftIn(dataPin, clockPin, MSBFIRST);
239+
assertEqual(0x7C, (uint)input); // 0111 1100
240+
assertEqual('|', input); // 0111 1100
241+
assertEqual((uint)'|', (uint)input); // 0111 1100
242+
243+
// now verify clock
244+
assertEqual(16, state->digitalPin[clockPin].historySize() - originalSize);
245+
int numMoved = state->digitalPin[clockPin].toArray(actualClock, 16);
246+
assertEqual(16, numMoved);
247+
for (int i = 0; i < 16; ++i) assertEqual(i % 2, actualClock[i]);
248+
249+
state->reset();
250+
state->digitalPin[dataPin].fromAscii("|", true); // 0111 1100
251+
input = shiftIn(dataPin, clockPin, LSBFIRST); // <- note the LSB/MSB flip
252+
assertEqual(0x3E, (uint)input); // 0011 1110
253+
assertEqual('>', input); // 0011 1110
254+
assertEqual((uint)'>', (uint)input); // 0011 1110
255+
256+
// test setting MSB
257+
state->reset();
258+
state->digitalPin[dataPin].fromAscii("U", true); // 0101 0101
259+
input = shiftIn(dataPin, clockPin, LSBFIRST); // <- note the LSB/MSB flip
260+
assertEqual(0xAA, (uint)input); // 1010 1010
261+
}
262+
263+
unittest(shift_out) {
264+
265+
uint8_t dataPin = 2;
266+
uint8_t clockPin = 3;
267+
uint8_t output;
268+
bool actualClock[16];
269+
uint8_t originalSize;
270+
271+
state->reset();
272+
originalSize = state->digitalPin[clockPin].historySize();
273+
shiftOut(dataPin, clockPin, MSBFIRST, '|');
274+
assertEqual("|", state->digitalPin[dataPin].toAscii(1, true));
275+
assertEqual(16, state->digitalPin[clockPin].historySize() - originalSize);
276+
int numMoved = state->digitalPin[clockPin].toArray(actualClock, 16);
277+
for (int i = 0; i < 16; ++i) assertEqual(i % 2, actualClock[i]);
278+
279+
state->reset();
280+
shiftOut(dataPin, clockPin, LSBFIRST, '|');
281+
assertEqual(">", state->digitalPin[dataPin].toAscii(1, true));
282+
283+
}
284+
285+
unittest(no_ops) {
286+
pinMode(1, INPUT);
287+
analogReference(3);
288+
analogReadResolution(4);
289+
analogWriteResolution(5);
290+
}
225291

226292
#ifdef HAVE_HWSERIAL0
227293

Diff for: cpp/arduino/Arduino.h

-5
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,6 @@ typedef uint8_t byte;
3636
#define highByte(w) ((uint8_t) ((w) >> 8))
3737
#define lowByte(w) ((uint8_t) ((w) & 0xff))
3838

39-
// Arduino defines this
40-
#define _NOP() do { 0; } while (0)
41-
4239
// might as well use that NO-op macro for these, while unit testing
4340
// you need interrupts? interrupt yourself
4441
#define yield() _NOP()
@@ -70,5 +67,3 @@ inline unsigned int makeWord(unsigned int w) { return w; }
7067
inline unsigned int makeWord(unsigned char h, unsigned char l) { return (h << 8) | l; }
7168

7269
#define word(...) makeWord(__VA_ARGS__)
73-
74-

Diff for: cpp/arduino/ArduinoDefines.h

+3
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,6 @@
9292
#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega168__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
9393
#define LED_BUILTIN 13
9494
#endif
95+
96+
// Arduino defines this
97+
#define _NOP() do { 0; } while (0)

Diff for: cpp/arduino/Godmode.h

+63-6
Original file line numberDiff line numberDiff line change
@@ -160,21 +160,78 @@ class GodmodeState {
160160
};
161161

162162
// io pins
163-
#define pinMode(...) _NOP()
164-
#define analogReference(...) _NOP()
163+
inline void pinMode(uint8_t pin, uint8_t mode) { _NOP(); }
164+
inline void analogReference(uint8_t mode) { _NOP(); }
165165

166166
void digitalWrite(uint8_t, uint8_t);
167167
int digitalRead(uint8_t);
168168
int analogRead(uint8_t);
169169
void analogWrite(uint8_t, int);
170-
#define analogReadResolution(...) _NOP()
171-
#define analogWriteResolution(...) _NOP()
170+
inline void analogReadResolution(uint8_t bits) { _NOP(); }
171+
inline void analogWriteResolution(uint8_t bits) { _NOP(); }
172172
void attachInterrupt(uint8_t interrupt, void ISR(void), uint8_t mode);
173173
void detachInterrupt(uint8_t interrupt);
174174

175175
// TODO: issue #26 to track the commanded state here
176-
inline void tone(uint8_t _pin, unsigned int frequency, unsigned long duration = 0) {}
177-
inline void noTone(uint8_t _pin) {}
176+
inline void tone(uint8_t _pin, unsigned int frequency, unsigned long duration = 0) { throw "Not Yet Implemented"; }
177+
inline void noTone(uint8_t _pin) { throw "Not Yet Implemented"; }
178+
inline uint8_t pulseIn(uint8_t _pin, uint8_t _value, uint32_t _timeout) { throw "Not Yet Implemented"; }
179+
inline uint8_t pulseIn(uint8_t pin, uint8_t value) { return pulseIn(pin, value, (uint32_t) 1000000); }
180+
inline uint32_t pulseInLong(uint8_t _pin, uint8_t _value, uint32_t _timeout) { throw "Not Yet Implemented"; }
181+
inline uint32_t pulseInLong(uint8_t pin, uint8_t value) { return pulseInLong(pin, value, (uint32_t) 1000000); }
182+
183+
/**
184+
* Shifts in a byte of data one bit at a time.
185+
*
186+
* Starts from either the most (i.e. the leftmost) or least (rightmost)
187+
* significant bit. For each bit, the clock pin is pulled high, the next bit is
188+
* read from the data line, and then the clock pin is taken low.
189+
*
190+
* @param dataPin the pin on which to input each bit
191+
* @param clockPin the pin to toggle to signal a read from dataPin
192+
* @param bitOrder which order to shift in the bits; either MSBFIRST or LSBFIRST. B=Bit, not byte
193+
*
194+
* @return The value read
195+
*/
196+
inline uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, bool bitOrder) {
197+
bool mFirst = bitOrder == MSBFIRST;
198+
uint8_t ret = 0x00;
199+
for (uint8_t i = 0, mask = (bitOrder == MSBFIRST ? 0x80 : 0x01); i < 8; ++i) {
200+
digitalWrite(clockPin, HIGH);
201+
uint8_t setBit = mFirst ? 0x80 : 0x01;
202+
uint8_t val = (mFirst ? (setBit >> i) : (setBit << i));
203+
ret = ret | (digitalRead(dataPin) ? val : 0x00);
204+
digitalWrite(clockPin, LOW);
205+
}
206+
return ret;
207+
}
208+
209+
/**
210+
* Shifts out a byte of data one bit at a time.
211+
*
212+
* Starts from either the most (i.e. the leftmost) or least (rightmost)
213+
* significant bit. Each bit is written in turn to a data pin, after which a
214+
* clock pin is pulsed (taken high, then low) to indicate that the bit is
215+
* available.
216+
*
217+
* @param dataPin the pin on which to input each bit
218+
* @param clockPin the pin to toggle to signal a write from dataPin
219+
* @param bitOrder which order to shift in the bits; either MSBFIRST or LSBFIRST. B=Bit, not byte
220+
* @param value the data to shift out
221+
*
222+
* @return The value read
223+
*/
224+
inline void shiftOut(uint8_t dataPin, uint8_t clockPin, bool bitOrder, uint8_t value) {
225+
bool mFirst = bitOrder == MSBFIRST;
226+
uint8_t ret = 0x00;
227+
for (uint8_t i = 0, mask = (bitOrder == MSBFIRST ? 0x80 : 0x01); i < 8; ++i) {
228+
uint8_t setBit = mFirst ? 0x80 : 0x01;
229+
uint8_t val = (mFirst ? (setBit >> i) : (setBit << i));
230+
digitalWrite(dataPin, (value & val) ? HIGH : LOW);
231+
digitalWrite(clockPin, HIGH);
232+
digitalWrite(clockPin, LOW);
233+
}
234+
}
178235

179236
// These definitions allow the following to compile (see issue #193):
180237
// https://github.com/arduino-libraries/Ethernet/blob/master/src/utility/w5100.h:341

0 commit comments

Comments
 (0)