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

Reconfigure GPIO pins during runtime

Hi all,

I have the following issue: For an electrochemical measurement I need to use 4 GPIO pins bundled in pairs, each pair with an output (GPIO HI) and ground (GPIO LO). Sadly I cannot just configure the 4 as LO and then activate the one I need, since in the solution everything would be virtually short circuited, rendering one output with three grounds.

What I thought of is having the four pins "disconnected" or "hi-Z" and just activating the pair on demand. After some reading I found out the GPIOs in the nRF5340 do not support high impedance. Someone suggested to reconfigure them as inputs to achieve high impedance, which could possibly work, but I have not found out how to reconfigure them during runtime. Next a snippet of my strategy:

void funcion(){ 
    int ret;
    ret = gpio_pin_configure(dev0, PIN0, GPIO_OUTPUT_INACTIVE | FLAGS0);
    while(ret);
    ret = gpio_pin_configure(dev1, PIN1, GPIO_OUTPUT_INACTIVE | FLAGS1);
    while(ret);
    
    gpio_pin_toggle(dev0, PIN0);
    
    k_usleep((PULSE_DURATION));
    
    gpio_pin_toggle(dev0, PIN0);
    
    k_usleep((PULSE_DURATION));
    
    ret = gpio_pin_configure(dev0, PIN0, GPIO_DISCONNECTED);
    while(ret);
    ret = gpio_pin_configure(dev1, PIN1, GPIO_DISCONNECTED);
    while(ret);
    //ret = gpio_pin_configure(dev0, PIN0, GPIO_INPUT | FLAGS0);
    //while(ret);
    //ret = gpio_pin_configure(dev1, PIN1, GPIO_INPUT | FLAGS1);
    //while(ret);
}

This seems to crash the app whenever I do the second re-configuring, both with disconnecting and input. 

How could I do the switching properly? Or is there a better solution to my problem?

Thanks,
Fran89

Off-topic and not necessary to refer to in the answer: I am having a frustratingly hard time migrating from the nRF52 to the nRF53. The documentation and examples are rather scarce, and most refers to the Zephyr project docs which are also cryptic, like any other Linux doc. I just leave this comment here to encourage you to expand (and update) examples and guides to make the landing into the nRF53 a bit more intuitive, and for others in my situation to know you're not the only ones.

Parents
  • One of the advantages of using a multiple-register set/reset/port scheme is that up to 32-bits of an i/o port can simultaneously be written in any combination with a single instruction. gpio_pin_toggle() and other similar port functions hide this advantage by using a single pin number as a parameter, like older simpler cpus; however you can instead use something like nrf_gpio_port_out_write() which takes any combination of the 32 pins including changing 2 pins from low to high and vice versa with a single instruction by using a 32-bit mask. Underneath this instruction is P0.OUTCLR = mask.

    Search for the definition in nrf_gpio.c and write  new function gpio_port_toggle() which takes a mask as a parameter, or simply use the low-level instruction directly.

    Off topic - I concur

Reply
  • One of the advantages of using a multiple-register set/reset/port scheme is that up to 32-bits of an i/o port can simultaneously be written in any combination with a single instruction. gpio_pin_toggle() and other similar port functions hide this advantage by using a single pin number as a parameter, like older simpler cpus; however you can instead use something like nrf_gpio_port_out_write() which takes any combination of the 32 pins including changing 2 pins from low to high and vice versa with a single instruction by using a 32-bit mask. Underneath this instruction is P0.OUTCLR = mask.

    Search for the definition in nrf_gpio.c and write  new function gpio_port_toggle() which takes a mask as a parameter, or simply use the low-level instruction directly.

    Off topic - I concur

Children
Related