In recent project I used Espruino itself to run test regression. Espruino pins drive devices under test with analog and digital signals: voltages, low and high pulses, low and high states, etc.
After reset, all free ports / pins are input - very high impedance and the pin output latch registers are set to low. This makes the read of a connected test candidate pin on input mode with a very weak pull-up to deliver high value. Espruino has though this specialty that makes lazy programming easy: On reset, pin mode is not just set straight to "input" mode, but to "auto" mode. In mode, the pin will adjust to the automatically applied operation: on pin.read() the pin switches to input mode behavior, and on pin.write() the pin switches to output mode behavior. The pin input/output control register are set automatically. No need for the application to configure the pin when plain input and plain output are sufficient.
For a test setup, assume the Espruino pin A0 is the test pin (test driver) for the tested pin x2 of Espruino itself or of a device connected to and controlled by Espruino. A0 is initially in input mode - no pull-up or pull-down - and the tested x2 pin is in input (very weak) pull-up mode. A read by the x1 pin will deliver a High / true.
When the tested pin x1 is NOT under watch / is NOT on interrupt, changing the testing pin A0 from input to output H in order to keep continuously High / true on texted pin x1 is not a challenge, since the switching falls between two test reads. The code for switching looks like this:
A0.mode("output"); // switching test pin to output mode
A0.set(); // set A0 High to keep x1 input on High
When the tested pin x1 is under watch / is on interrupt, the watch / event fire because there is a very brief period between switching to output mode and asserting High where the still set to Low pin latch / output register pulls the test pin A0 AND the tested pin x1 low.
The hope that using Espruino's unique "auto" pin mode feature could help got quickly dashed: applying a pin.set() H 'immediately' after a reset shows the same issue: the reset latch / output register is briefly exposed when the pin switches automatically from input to output - in fact is connecting the pin with the output register just before setting it to high... :(
// reset, A0.mode("auto") or A0.mode() followed by A0.read();
A0.set(); // switch from "input" "auto" to output and H
Therefore, the following sequence has to be use to keep the A0 test pin AND x1 tested pin 'seamlessly' high:
A0.mode("input"); // or "input_pullup" - lets A0 and x1 pin stay on High
A0.set(); // latches / sets output reg to H, but w/ no effect on pin A0 (yet)
A0.mode("output"); // exposes output reg's H (w/ 'going with the flow')
In other words, to put a pin on input, then re/set the pin's latch /output register as desired and finally put the pin in output mode prevents exposing an undesired previous value and possible generation of a watch / interrupt spike.
Thanks - actually that's something that might be easy enough to fix: https://github.com/espruino/Espruino/blob/master/src/jspin.c#L218
However how big is the spike you're noticing when using Espruno's .set on its own? It should be really very small - significantly less than a microsecond?
The spike is long enough for a hardware device watching, such as a MCP23017 Portexpander pin, to trigger interrupt operation. Did not (self) test on a watched Espruino-Wifi pin.
It should be fixed in latest builds now
Don't worry about formatting, just type in the text and we'll take care of making sense of it. We will auto-convert links, and if you put asterisks around words we will make them bold.
For a full reference visit the Markdown syntax.
© Espruino, powered by microcosm.
Report a problem