Start-Up/Flashing "troubles" with D-pins (summarized)

In order to pull together these threads, I'd like to summarize what has been established during these discussions

Facts are:

Current Core behaviour:

  • When the Core starts up, all the D pins are actively pulled low by the Core, till instructed otherwise in setup(), which - in SYSTEM_MODE(AUTOMATIC) - only runs after the cloud connection is established (class constructors might run - in undefined order - before that).
  • While flashing the Core, this doesn't seem to be the case, but the JTAG pins do get internal pull resistors attached (see quote) which is especially noticable on D7 (blue on-board LED).

The expected and surely preferable way to treat all pins would be, to have them high impedance input and without any pull resistors from start till user code - and only user code - alters the pin mode.

As for JTAG pins, that might not be possible, but if it can't be helped, it needs clear documenting, in order to prevent users from attaching external circuitry, that couldn't cope with this default behaviour.


On the :spark: Spark Core, the A pins and pins RX & TX don't seem to suffer such issues.
For the :spark: Spark Photon and :spark: Spark Electron tests might be in order.


... to be continued

4 Likes

Please explicitly explain further on which means (OTA, DFU) if possible for clarity :wink:

I don’t think this is necessary, since OTA and DFU do behave just the same in this regard.

press and holding down the reset button causes d7 to dimm on the core …

I’d guess this is connected to JTAG, since it’s desirable to have JTAG available immediately when releasing the RST button.

1 Like

I just tested this behavior on the Photon. None of the D/A pins get pulled LOW during startup/flashing.

Whether all pins D3, D5, D6 and D7 should be connected to PULL DOWN resistors?
I noticed that the pin (D4 - JTAG_TDO - PB3 - Floating) and (D6- JTAG_TCK - PA14 - ~ 40k pull-down) has not troubled effect and without resistors.
When I connect pull up to D6 as recommended here https://github.com/spark/firmware/issues/414 , then shows up above mentioned problem.
Whether all pins should be connected to pull down including pin D6?

I’m not sure what your intended use of D6 is, but the table shown in this post is not intended to show default recommended external setup, but how to counteract the effects of the internal pull resistors if they get in your way.
If they don’t, there is no need for extra pull resistors.

@Carsten4207, could you elaborate how you did the measurement? To recreate your test setup and verify.

Hello,
I solved the problem :grinning:
It’s about the electron. D0 - D7 are connected of the eght solid state relay through mosfet transistor.
To all pins I connect pull down resistor with a value 4,7K, and now no longer exist undefined conditions when turn the power of the electron.

2 Likes

I solved this very simply by using the fast io functions to set the desired initial value before configuring as an output and thus driving the output line.

   pinSetFast(pin); // initialize to HIGH
   pinSetMode(pin, OUTPUT);  // enable output

or

   pinResetFast(pin); // initialize to LOW
   pinSetMode(pin, OUTPUT);  // enable output

In reality, the library should have a setPinMode that takes a third argument which is the initial value. In my case I have some outputs that are active low and some that are active hi so I wrote a generic wrapper so I can change an output from active high to active low later and not worry about spreading HIGH and LOW around my code:

const int STOP = D0;
const int START = A0;
const int RESET = A1;

// define which outputs are active low
const int ACTIVE_LOW_MASK = (1 << STOP)  | (1<<START));

const bool Off = false;
const bool On = true;
void setPinMode(int pin, PinMode mode, bool on) {
    bool invert = (1<<pin) & ACTIVE_LOW_MASK;
    if (invert) on = ! on;
    if (on) pinSetFast(pin);
    else pinResetFast(pin);
    pinMode(pin, mode);
}

void pinOn(int pin) {
    digitalWrite(pin, ACTIVE_LOW_MASK & (1<<pin) ? LOW : HIGH);
}

void pinOff(int pin) {
    digitalWrite(pin,  ACTIVE_LOW_MASK & (1<<pin) ? HIGH : LOW);
}

void pinToggle(int pin) {
    if (digitalRead(pin)) digitalWrite(pin, LOW);
    else digitalWrite(pin, HIGH);
}

void setup() {
  setPinMode(START, OUTPUT, On);
  setPinMode(STOP, OUTPUT, Off);
  setPinMode(RESET, OUTPUT, Off);
}

1 Like

Excellent solution :smile:
Do you have tested for all D0 - D7 pin ?
The problem occurs exclusively on those pins.

That's not quite addressing the exact problem discussed here tho'
The point of this thread is that some JTAG pins act like outputs for a very brief moment before any of your code can run
So there is no software solution for that very "problem" (at least in user code).

1 Like

Good point. I think though there are multiple issues as listed in the first post. My fix deals with the issues of enabling outputs with an initial value other than low so when the pin is configured by pinSetMode to be an OUTPUT, the state is under control of the user and a quick pulse to an unexpected state does not occur.

While I agree that setting the desired output state once the GPIO gets set as OUTPUT would be beneficial for some use cases, I do not really see any reference to this as an issue in my intial post.
Could you point me to that quote?

2 Likes

The first post referenced above mentions this code sequence:

pinMode(D0, OUTPUT);
digitalWrite(D0, HIGH);

This results in a driven low value in the interval between the pinMode and digitalWrite call which I think may be what some users are measuring. Use of pinSetFast eliminates this particular interval. On my board I also see a driven low spike of 50us shortly after power-on but that’s not enough to light up an LED or fire a relay to close but is certainly undesirable.

You are correct in pointing out that use of pinSetFast does not in any way address the behavior of the core in driving the outputs low briefly before user code starts or during programming.

2 Likes