This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Ensure GPIO initializes to default low

Using: NRF52840, SDK 14.2, S140

My GPIO initialization code is as follows. This is the first thing that happens in main.c.

nrf_gpio_cfg_output(NRF_GPIO_PIN_MAP(1, 0));
nrf_gpio_pin_clear(NRF_GPIO_PIN_MAP(1, 0));

nrf_gpio_cfg_output(NRF_GPIO_PIN_MAP(1, 14));
nrf_gpio_pin_set(NRF_GPIO_PIN_MAP(1, 14));

Here are logic analyzer traces of 2 GPIOs (I can also scope them soon). Top one (P1.0) should be initialized low, bottom one (P1.14) should be initialized high.

PROBLEM 1: You can see in this picture that something spurious happens to both GPIOs upon powerup, where they both look like they're being initialized to the wrong value for ~4ms before being set to the proper values. This may be clearer in this zoom in view of the little blip at time B above: 

This blip lasts about 4 ms. Below is an example measured from a different trial. Across multiple trials, it appears that P1.0 always goes high before it goes low. This is concerning, because there can be suboptimal system behavior if P1.0 is not initialized properly. Why might this be happening?

PROBLEM 2: there is also a consistent blip high AFTER the device is powered off (or generally upon poweroff, hard to tell exact sequence) -- see time point A in the first image. What might this be?

Thank you!

  • Hi,

    how close is your initialization code to the start of main()?  As soon as your GPIO initialization is executed, the pins are set to the right state immediately, without any delay. As for powering off, you cannot contol pin state at this time with software. If your pins have some load that should be in known state while CPU is powering-on/powering-off/browned-out, you need hardware pull-up or pull-down resistors on that pins.

  • In general the initialisation order shown above is incorrect, choose the pin high or low level before driving it as an output when the pin was previously not configured.

    nrf_gpio_pin_clear(NRF_GPIO_PIN_MAP(1, 0)); // Drives low as soon as configured as output
    nrf_gpio_cfg_output(NRF_GPIO_PIN_MAP(1, 0));
    
    nrf_gpio_pin_set(NRF_GPIO_PIN_MAP(1, 14)); // Drives high as soon as configured as output
    nrf_gpio_cfg_output(NRF_GPIO_PIN_MAP(1, 14));

    On power off - assuming Vdd collapses from 3 volts-ish towards 0 volts - any external item connected to the pin will back-drive the pin through the internal schottky protection diode if the external item either has a power source or has any significant capacitance (which acts like a power source). If the signal is as clean as shown in the trace (often not the case depending on the logic analyzer instrument, scope is preferred) then something else is afoot ..

  • @dmitry, as mentioned above, the initialization code is basically the first thing that happens in main():

    (the initialization are inside gpio_init).

    , thanks for the note. I changed the order of my initializations, and it took care of part of the problem (things that should be initialized high getting first initialized low). 

    But the 4ms high blip still shows up for the pins that should be initialized low. I tested with an oscilloscope, and it shows P1.0 is low consistently. I will note that when the scope is not connected to anything, it reads low, and when the logic analyzer is not connected to anything, it reads high. So it seems like the pins are floating for 4ms upon startup. This is a long time. Why might this be happening? 

    As another example: P0.6 and P1.0 both are supposed to go low. There is 50 us between when P0.6 goes low and P1.0 goes low. There are 25 pins initialized in between them, so this seems about right. It also supports the hypothesis that the pins are all floating until they are initialized. 

  • Sorry I missed that mention. 4ms is within the device specification, see 5.3.8.3 Device startup times - up to 10 ms is allowed in case of 10us VDD rise time. But it shouldn't matter anyway (unless your device is powered from an energy harvester, in this case you probably have to look for alternative solution). The pin is floating until it's initialized - if this is unacceptable, there should be a pull-up/pull-down on that pin.

  • How long does the softdevice take to initialize, and is it possible to initialize GPIO before the softdevice?

Related