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.
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