Can I get some clarification of the pull resistances contained in the datasheet for this device?
For example, Pin 30 / D10, the datasheet indicates Internal pull resistance of 2.2k, but is this a pullup or pulldown? Pulldown correct? Are all the listed pull resistances in the datasheet the same direction?
I am having an issue where doing firmware updates via USB or Cloud will cause this pin to go low and its not clear if its an active low or just an internal pulldown that's doing it.
The pull listed in the datasheet is only when INPUT_PULLUP or INPUT_PULLDOWN is used, and is in that direction with that resistance. Boot pins and SWD pins can be pulled when in the bootloader (including DFU mode) but D10 shouldn't be one of those pins.
That PIN definitely goes low with a cloud or CLI initiated DFU mode. If I manually initiate DFU mode with the setup button it does not go low.
This is a P2 on a custom board, but nothing fancy. It's probably something obvious but I'm not seeing it.
Actually, its not the DFU mode specifically. If I do a soft reset with System.reset(); several pins (including D10) are pulled low. If I use the reset button this does not happen.
What is at play here?
I took a brief look at what happens on software reset (including DFU) and I didn't see anything that should cause pins to go into output mode and be driven low. The code is here.
Try setting up some outputs in the setup() and you should see what I am describing.
Here is a simple example setting up 7 pins as outputs. Note the unexplained behavior on POR vs. Soft Reset with just this code.
const int pin_loop_s = S3;
const int pin_dump_s = A1;
const int pin_y_in_s = S2;
const int pin_y_out_s = S1;
const int pin_ewt_s = S4;
const int pin_lwt_s = D2;
const int pin_fault_s = D3;
void setup() {
pinMode(pin_loop_s, OUTPUT);
digitalWrite(pin_loop_s, true);
pinMode(pin_dump_s, OUTPUT);
digitalWrite(pin_dump_s, true);
pinMode(pin_y_in_s, OUTPUT);
digitalWrite(pin_y_in_s, true);
pinMode(pin_y_out_s, OUTPUT);
digitalWrite(pin_y_out_s, true);
pinMode(pin_ewt_s, OUTPUT);
digitalWrite(pin_ewt_s, true);
pinMode(pin_lwt_s, OUTPUT);
digitalWrite(pin_lwt_s, true);
pinMode(pin_fault_s, OUTPUT);
digitalWrite(pin_fault_s, false);
}
I can mitigate the issue to some extent by setting the pins to INPUTS before a cloud update or Soft Reset command. But I can't mitigate if I update with CLI since I can't trap that event in code before it happens.
pinMode(pin_loop_s, INPUT);
pinMode(pin_dump_s, INPUT);
pinMode(pin_y_in_s, INPUT);
pinMode(pin_y_out_s, INPUT);
pinMode(pin_ewt_s, INPUT);
pinMode(pin_lwt_s, INPUT);
pinMode(pin_fault_s, INPUT);
Could you try setting the pins to INPUT in a system reset handler?
Indeed that's what I did above. It mitigates my issue for the most part, but I was not understanding what was at play that causes this. I'm not developing a life-safety device but not liking edge cases where pins can change unexpectedly.
1 Like
I don't have an answer for you but some things I discovered while running into similar problems:
- Near as I can tell, pin configuration does not change (mostly) during soft reset. I assume so the device can enter/leave low power sleep without changing pin configuration. Since they're not put into High-Z, code at boot can impact the pins.
- There's a ROMed bootloader that always runs at startup and provides a serial shell on pins 63 and 64. I don't think it impacts pin 30 but worth being aware of.