Pin state on reset?

I’ve built a board with a small motor driver attached to the Photon pins D0-D3. Whenever the board is in reset, one of the motors starts running, because D3 appears to drive high when in reset. Even with a 100k pulldown, the pin measures 2.3 volts during reset, and D5 likewise appears to go high at reset.

Is there any documentation on what pin states we can expect during reset? I would have expected them all to be HI-Z.

I believe you are running into the JTAG port, which is doc’ed here (see the footnote in particular):

If you can’t change pins, you can do what the footnote says.


Ah, thanks for pointing that out. However, I can't parse the footnote:

(if JTAG debugging is not required, i.e. USE_SWD_JTAG=y is not specified on the command line.)

I assume that should say something like "if JTAG debugging is not required, specify USE_SWD_JTAG=n on the command line"? It's not very useful if you're using, in any case.

Semi-automatic mode could get you to setup() quicker where you could set your pin states, then call Particle.connect() manually afterwards.

True. This is a shield for kids to learn programming with, though, so in the interest of simplicity I think I’ll simply have to pick another pin, even if it means giving up on PWM on that pin.

@bko, This seems like one of those subtle things that could easily trip up users. Could you elaborate on your answer? The documentation is very unclear to me. Is USE_SWD_JTAG=y the default, and one would need to change it to “n” to keep D3 (also D5 and D7) from being briefly HIGH? If so, how would one do that?

Default state after reset for a short period of time before these pins are restored to GPIO (if JTAG debugging is not required, i.e. USE_SWD_JTAG=y is not specified on the command line.)

This means: unless you recompile the system firwmare with debug support (which is not the default), all IO will be configured as input on boot, but since the microcontroller sets a pull-up/pull-down on D3, D5, D6, D7 during reset, there will be a blip of output between the end of reset and when the system firmware gets to change the pin settings (a few milliseconds). Also note that those pins are pulled DURING reset for some debugger features to work.

It's not possible to turn this off as far as I understand.


Thanks to @jvanier for filling in a great answer here!

Using JTAG makes it so that you cannot really brick your device if you have a JTAG programmer like the Particle programmer shield or the ST-Micro JTAG device, so that is part of the overall strategy of the devices. JTAG also makes advanced debugging possible and is really the only way to debug low-level complex stuff.

Yes, the driven state at power-up does trip some folks up. Typically the problem is short-lived since by the time your device runs the code in setup(), the pins are back to the usual state. There are two good ways around this: (1) know which pins are used for JTAG and avoid them for certain jobs and (2) design your external logic to require the opposite level or two pins a known state to activate. For instance, driving relays with these pins was a problem in the past so design your opto-isolator in the relay driver to require one pin to be held low while another set of pins is driven high to control the relays.

1 Like

It's definitely longer than that - closer to half a second. Long enough for the robot to jump off the table if I'm not paying attention. :smile:

This is true for default SYSTEM_MODE(AUTOMATIC) since setup() only gets executed after cloud connect, hence the hint of CuriousTech to use SYSTEM_MODE(SEMI_AUTOMATIC).
You can also use the STARTUP() macro to have some code executed as early as possible.


This poorly written post on a STM forum agrees with the 0.5s you are seeing.

A proper solution would be to disable the JTAG pins super duper early in the startup, even before configuring the clock PLL. This would have to be done in WICED in the crt0_GCC.c. Developers shouldn’t have to worry about this.