Skip to content

Commit 3ec3cd3

Browse files
authored
Merge pull request #70 from bxparks/develop
merge 1.3.1 into master
2 parents 927054b + 2432c0e commit 3ec3cd3

File tree

6 files changed

+147
-32
lines changed

6 files changed

+147
-32
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
# Changelog
22

33
* Unreleased
4+
* 1.3.1 (2022-08-13)
5+
* Add `tone()` and `noTone()` stubs. By @kwisii in
6+
[PR#69](https://github.com/bxparks/EpoxyDuino/pull/69).
7+
* Add `uint8_t digitalWriteValue(pin)` which returns the value of the
8+
most recent `digitalWrite(pin, val)`. By @kwisii in
9+
[PR#68](https://github.com/bxparks/EpoxyDuino/pull/68).
410
* 1.3.0 (2022-03-28)
511
* Add support for `EXTRA_CPPFLAGS`, similar to `EXTRA_CXXFLAGS`.
612
* Add `digitalReadValue(pin, val)` to control the return value of

README.md

Lines changed: 96 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ The disadvantages are:
7171
environments (e.g. 16-bit `int` versus 32-bit `int`, or 32-bit `long` versus
7272
64-bit `long`).
7373

74-
**Version**: 1.3.0 (2022-03.28)
74+
**Version**: 1.3.1 (2022-08-13)
7575

7676
**Changelog**: See [CHANGELOG.md](CHANGELOG.md)
7777

@@ -99,6 +99,9 @@ The disadvantages are:
9999
* [Debugging](#Debugging)
100100
* [Valgrind](#Valgrind)
101101
* [Controlling digitalRead()](#DigitalReadValue)
102+
* [Mock digitalRead() digitalWrite()](#MockDigitalReadDigitalWrite)
103+
* [digitalReadValue()](#DigitalReadValue)
104+
* [digitalWriteValue()](#DigitalWriteValue)
102105
* [Supported Arduino Features](#SupportedArduinoFeatures)
103106
* [Arduino Functions](#ArduinoFunctions)
104107
* [Serial Port Emulation](#SerialPortEmulation)
@@ -691,7 +694,7 @@ example:
691694

692695
I am not an expert on any of these sanitizers, and I have not enabled them by
693696
default in the `EpoxyDuino.mk` file. But you have the capability to add them to
694-
your `Makefile` through the `CXXFLAGS` variable.
697+
your `Makefile` through the `EXTRA_CXXFLAGS` variable.
695698

696699
Below are some things that I have found useful in my own limited experience.
697700

@@ -706,8 +709,8 @@ start:
706709
* This is not strictly necessary but this will allow Valgrind to print line
707710
numbers to the source code in the stack trace.
708711
* Two ways:
709-
* Pass the pass through the command line: `$ make CXXFLAGS=-g`
710-
* Edit the `Makefile` and add a `CXXFLAGS += -g` directive
712+
* Pass the pass through the command line: `$ make EXTRA_CXXFLAGS=-g`
713+
* Edit the `Makefile` and add a `EXTRA_CXXFLAGS = -g` directive
711714
near the top of the file.
712715
2. Run the program under the `valgrind` program.
713716
* Valgrind has tons of options and flags. Here are the flags that I use
@@ -719,15 +722,26 @@ start:
719722
When the program crashes because of a `nullptr` dereference, Valgrind will show
720723
exactly where that happened in the source code.
721724

722-
<a name="DigitalReadValue"></a>
723-
### Controlling digitalRead()
725+
<a name="MockDigitalReadDigitalWrite"></a>
726+
### Mock digitalRead() digitalWrite()
727+
728+
EpoxyDuino is not meant to simulate the actual hardware. By default, the
729+
`digitalRead()` and `digitalWrite()` functions are just stubs which don't do
730+
anything. However for testing purposes, it is sometimes useful to be able to
731+
control the values returned by `digitalRead()`, or to read back the value
732+
written by `digitalWrite()`. Two functions have been added to EpoxyDuino to
733+
allow this mocking.
724734

725-
By default, the `digitalRead(pin)` function simply returns a 0, because
726-
EpoxyDuino does not actually have any hardware pins. For testing purposes, it
727-
can be useful to control the value that will be returned by a `digitalRead()`.
735+
* `void digitalReadValue(uint8_t pin, uint8_t val)`
736+
* Sets the value returned by the subsequent `digitalRead(pin)` to `val`.
737+
* `uint8_t digitalWriteValue(uint8_t pin)`
738+
* Returns the value of the most recent `digitalWrite(pin, val)`.
739+
740+
<a name="DigitalReadValue"></a>
741+
#### digitalReadValue()
728742

729-
The `digitalReadValue(pin, val)` function sets the value that will be returned
730-
by the corresponding `digitalRead(pin)`. Here is an example of how this can be
743+
The `digitalReadValue(pin, val)` function sets the value that will be
744+
returned by the next `digitalRead(pin)`. Here is an example of how this can be
731745
used:
732746

733747
```C++
@@ -758,6 +772,42 @@ The `pin` parameter should satisfy `0 <= pin < 32`. If `pin >= 32`, then
758772
`digitalReadValue()` is a no-op and the corresponding `digitalRead(pin)` will
759773
always return 0.
760774

775+
<a name="DigitalWriteValue"></a>
776+
#### digitalWriteValue()
777+
778+
The `digitalWriteValue(pin)` function returns the value that was written by
779+
the most recent `digitalWrite(pin, val)`. Here is an example of how this can be
780+
used:
781+
782+
```C++
783+
#include <Arduino.h>
784+
785+
...
786+
const uint8_t PIN = 9;
787+
788+
void something() {
789+
digitalWrite(PIN, 0);
790+
791+
#if defined(EPOXY_DUINO)
792+
uint8_t val = digitalWriteValue(PIN);
793+
// val should be 0
794+
#endif
795+
796+
digitalWrite(PIN, 1);
797+
798+
#if defined(EPOXY_DUINO)
799+
uint8_t val = digitalWriteValue(PIN);
800+
// val should be 1
801+
#endif
802+
}
803+
```
804+
805+
The `#if defined(EPOXY_DUINO)` is recommended because `digitalWriteValue()` is
806+
not a standard Arduino function. It is defined only in EpoxyDuino.
807+
808+
The `pin` parameter should satisfy `0 <= pin < 32`. If `pin >= 32`, then
809+
`digitalWriteValue()` always return 0.
810+
761811
<a name="SupportedArduinoFeatures"></a>
762812
## Supported Arduino Features
763813

@@ -1076,30 +1126,30 @@ intended. This limitation may be sufficient for Continuous Integration purposes.
10761126
<a name="SystemRequirements"></a>
10771127
## System Requirements
10781128

1079-
This library has Tier 1 support on:
1129+
**Tier 1: Fully Supported**
1130+
1131+
The following environments are tested on each release of EpoxyDuino.
10801132

10811133
* Ubuntu 20.04.4 LTS
10821134
* g++ (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0
10831135
* clang++ version 10.0.0-4ubuntu1
10841136
* GNU Make 4.2.1
10851137

1086-
The following environments are Tier 2 because I do not test them often enough:
1138+
**Tier 2: Best Effort**
10871139

1088-
* Ubuntu 18.04 LTS
1089-
* g++ (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
1090-
* clang++ 8.0.0-3~ubuntu18.04.2
1091-
* clang++ 6.0.0-1ubuntu2
1092-
* GNU Make 4.1
1140+
The following environments are supported on a best-effort basis because I don't
1141+
test them as often.
1142+
1143+
* MacOS 11.6.7 (Big Sur)
1144+
* clang++
1145+
* Apple clang version 13.0.0 (clang-1300.0.29.30)
1146+
* Target: x86_64-apple-darwin20.6.0
1147+
* GNU Make 3.81
1148+
* (Big Sur is the latest MacOS that I am able to test.)
10931149
* Raspbian GNU/Linux 10 (buster)
10941150
* On Raspberry Pi Model 3B
10951151
* g++ (Raspbian 8.3.0-6+rpi1) 8.3.0
10961152
* GNU Make 4.2.1
1097-
* MacOS 10.14.5 (Mojave)
1098-
* clang++ Apple LLVM version 10.0.1
1099-
* GNU Make 3.81
1100-
* MacOS 10.14.6 (Mojave)
1101-
* Apple clang version 11.0.0 (clang-1100.0.33.17)
1102-
* GNU Make 3.81
11031153
* FreeBSD 12.2
11041154
* c++: FreeBSD clang version 10.0.1
11051155
* gmake: GNU Make 4.3
@@ -1108,6 +1158,24 @@ The following environments are Tier 2 because I do not test them often enough:
11081158
* Create a shell alias, or
11091159
* Create a symlink in `~/bin`.
11101160

1161+
**Tier 3: Should Work**
1162+
1163+
The following environments are older OS environments which worked with previous
1164+
versions of EpoxyDuino. But I am not able to validate them against the latest
1165+
EpoxyDuino release because I no longer use these older environments.
1166+
1167+
* Ubuntu 18.04 LTS
1168+
* g++ (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
1169+
* clang++ 8.0.0-3~ubuntu18.04.2
1170+
* clang++ 6.0.0-1ubuntu2
1171+
* GNU Make 4.1
1172+
* MacOS 10.14.6 (Mojave)
1173+
* Apple clang version 11.0.0 (clang-1100.0.33.17)
1174+
* GNU Make 3.81
1175+
* MacOS 10.14.5 (Mojave)
1176+
* clang++ Apple LLVM version 10.0.1
1177+
* GNU Make 3.81
1178+
11111179
<a name="License"></a>
11121180
## License
11131181

@@ -1202,3 +1270,7 @@ people ask similar questions later.
12021270
* Add `digitalReadValue(pin, val)` to control the return value of
12031271
`digitalRead(pin)` by @CaioPellicani. See
12041272
[PR#61](https://github.com/bxparks/EpoxyDuino/pull/61).
1273+
* Add `tone()` and `noTone()` stubs, by @kwisii in
1274+
[PR#69](https://github.com/bxparks/EpoxyDuino/pull/69).
1275+
* Add `uint8_t digitalWriteValue(pin)` by @kwisii in
1276+
[PR#68](https://github.com/bxparks/EpoxyDuino/pull/68).

cores/epoxy/Arduino.cpp

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,29 +21,44 @@
2121
// Arduino methods emulated in Unix
2222
// -----------------------------------------------------------------------
2323

24-
static uint32_t digitalPinValues = 0;
24+
static uint32_t digitalReadPinValues = 0;
25+
static uint32_t digitalWritePinValues = 0;
2526

2627
void yield() {
2728
usleep(1000); // prevents program from consuming 100% CPU
2829
}
2930

3031
void pinMode(uint8_t /*pin*/, uint8_t /*mode*/) {}
3132

32-
void digitalWrite(uint8_t /*pin*/, uint8_t /*val*/) {}
33+
void digitalWrite(uint8_t pin, uint8_t val) {
34+
if (pin >= 32) return;
35+
36+
if (val == 0) {
37+
digitalWritePinValues &= ~(((uint32_t)0x1) << pin);
38+
} else {
39+
digitalWritePinValues |= ((uint32_t)0x1) << pin;
40+
}
41+
}
42+
43+
uint8_t digitalWriteValue(uint8_t pin) {
44+
if (pin >= 32) return 0;
45+
46+
return (digitalWritePinValues & (((uint32_t)0x1) << pin)) != 0;
47+
}
3348

3449
int digitalRead(uint8_t pin) {
3550
if (pin >= 32) return 0;
3651

37-
return (digitalPinValues & (((uint32_t)0x1) << pin)) != 0;
52+
return (digitalReadPinValues & (((uint32_t)0x1) << pin)) != 0;
3853
}
3954

4055
void digitalReadValue(uint8_t pin, uint8_t val) {
4156
if (pin >= 32) return;
4257

4358
if (val == 0) {
44-
digitalPinValues &= ~(((uint32_t)0x1) << pin);
59+
digitalReadPinValues &= ~(((uint32_t)0x1) << pin);
4560
} else {
46-
digitalPinValues |= ((uint32_t)0x1) << pin;
61+
digitalReadPinValues |= ((uint32_t)0x1) << pin;
4762
}
4863
}
4964

@@ -65,6 +80,10 @@ unsigned long micros() {
6580
return us;
6681
}
6782

83+
void tone(uint8_t /*_pin*/, unsigned int /*frequency*/, unsigned long /*duration*/) {}
84+
85+
void noTone(uint8_t /*_pin*/) {}
86+
6887
void delay(unsigned long ms) {
6988
usleep(ms * 1000);
7089
}

cores/epoxy/Arduino.h

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
#define EPOXY_DUINO_EPOXY_ARDUINO_H
1515

1616
// xx.yy.zz => xxyyzz (without leading 0)
17-
#define EPOXY_DUINO_VERSION 10300
18-
#define EPOXY_DUINO_VERSION_STRING "1.3.0"
17+
#define EPOXY_DUINO_VERSION 10301
18+
#define EPOXY_DUINO_VERSION_STRING "1.3.1"
1919

2020
#include <algorithm> // min(), max()
2121
#include <cmath> // abs()
@@ -235,6 +235,18 @@ void analogWrite(uint8_t pin, int val);
235235
*/
236236
void digitalReadValue(uint8_t pin, uint8_t val);
237237

238+
/**
239+
* Check the value that was set by `digitalWrite(pin, val)` by setting the interesting
240+
* pin argument, where the return value is either 0 or 1. This may be useful for testing
241+
* purposes. This works only if `pin < 32` because the underlying implementation
242+
* uses a `uint32_t` for storage. If the `pin` is greater than or equal to 32,
243+
* this function will return 0.
244+
*
245+
* This function is available only on EpoxyDuino. It is not a standard Arduino
246+
* function, so it is not available when compiling on actual hardware.
247+
*/
248+
uint8_t digitalWriteValue(uint8_t pin);
249+
238250
unsigned long millis();
239251
unsigned long micros();
240252
void delay(unsigned long ms);
@@ -278,6 +290,9 @@ void enableTerminalEcho();
278290

279291
}
280292

293+
void tone(uint8_t _pin, unsigned int frequency, unsigned long duration = 0);
294+
void noTone(uint8_t _pin);
295+
281296
// WMath prototypes
282297
long random(long);
283298
long random(long, long);

examples/StdioSerialEcho/StdioSerialEcho.ino

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,5 +110,8 @@ void setup(void) {
110110
}
111111

112112
void loop(void) {
113+
// Choose one of the following loop methods to test Serial.available()
114+
// and Serial.read(). Both of them should work:
113115
loopExplicitly();
116+
//loopImplicitly();
114117
}

library.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "EpoxyDuino",
3-
"version": "1.3.0",
3+
"version": "1.3.1",
44
"description": "Compile and run Arduino programs natively on Linux, MacOS and FreeBSD.",
55
"keywords": [
66
"unit-test",

0 commit comments

Comments
 (0)