RP2350: Internal pull down issue

If you are seeing some strange behavior using internal pull-down on the RP2350 boards using Micro-python or other be aware that that is a chip issue see

https://forums.raspberrypi.com/viewtopic.php?t=375631

I though I was going mad. I dropped a Pico2 into a board I had made for the Pico. This is has 8 switches with pull-downs.

BTW this is Errata 9 in the RP2350 data sheet!

The problem appears to be far worse than defined by Errata 9. It’s not just pulldowns.

In particular it makes the ADC channels almost unuseable in some scenarios.
This is what I have confirmed so far (and this has been reported by others as well)

  1. Power cycle a board. Using any GPIO pin, observe that the pin is a high impedance and that applying VDD and releasing will not cause the pin to latch high (you may need to use a 1M resistor to ground afterward to be sure of clearing any floating gate charge)

  2. Configure the pin in Micropython as an input but with a pullup. Observe that the pin now operates normally and if pulled to ground, reports 0 as the value, returning to 1 when signal is removed.

  3. Configure the pin as an input but with NO pullup. Observe that if the pin is pulled to VDD it will latch at approximately 2.1V and remain at that voltage unless pulled down to zero.

This particularly affects scenarios like resistive touchscreens where you do not want either a pullup or a pulldown, and the spurious behaviour causes tracking errors due to the extra current sourced by the nominally high impedance input when it latches, which appears across the touchscreen resistance at that point.

It will also affect ADC applications where the source input impedance is significant as the pin will jump from 0 to 2.1V as the input signal changes, likely causing discontinuities in the tracked analogue signal.

It looks like the problem occurs when the pin is actually enabled, which will not be the case at power up. However I’m not clear the mitigation in E9 is going to help because if the pin behaves erroneously even for a short transient period of time as an analogue input, for instance, it’s going to cause significant errors on the ADC channels. In any case, you can’t currently apply the mitigation in Micropython or Circuitpython; changes to the underlying C code are required.

@ajay_m

Ouch, that’s even worse! Was hoping to use the improved ADC without the RP2040 ADC bug!!
I am sure there will be lots of developers all over this and hopefully we will get full clarity, but it doesn’t look good! I see on the Raspberry PI froum (above) the “Bus Pirate Devs” are pausing production.

We’re concerned enough that we pulled the next batch back from assembly. It’s been a long day of chasing this down and I need some time to think before poking it more. I will do some plain pin tests tomorrow to confirm what is reported here.

Ok, I was partially wrong on this one. Yes, a pin enabled for input with no pullup or pulldown does latch, that’s definitely correct. However when you subsequently perform an ADC read, the pin transitions back to a high impedance state and then stays there. And you can perform ADC reads without ever configuring the pin. I had not realised that, because I had always passed a pin object to the ADC constructor, not realising it will alternatively just take a pin number.

Now I’m not sure if in that scenario there’s any kind of slew issue that would cause a transient ADC reading to be incorrect. Because of course the pin is reconfigured by the looks of it on the ADC read and was potentially latched at 2.1V before the ADC read cycle is initiated. Depending on the impedance and capacitance that is present at that time, it might take a finite time to discharge that away
At present I still have the anomaly that my touchscreen tracking code is showing high ADC readings in the middle of the X axis, and these correlate to the pin latching high while configured as a digital input. (which it needs to be in the initial touch detection phase of the read).
I was in the process of recording the voltages and resulting ADC values for each overlay button when I found the latching behaviour, but this may not be the root cause.
My code, as I said, works perfectly on the RP2040. I understand that the RP2350 ADC is better so I wouldn’t expect the kind of non-linearity I’m seeing here - I’ll have to do further research.

The non linearity is caused by setting ISO when resetting the pin to a high impedance state. It is necessary only to set input enabled to 0. When this is done adc behaviour is correct. I have no explanation for this behaviour but there you are.