PIO wait/jmp requires explicit GPIO function setup – documentation misleading?
Hi everyone,
I'm working with a custom RP2350 board and encountered an unexpected issue while using PIO to read GPIO input states via wait and jmp. According to the SDK documentation in pio.h, it says:
This implies that no explicit pin function setup is needed if you're only reading the pin (e.g., using wait 1 pin X or jmp pin X). However, in practice, I found that the PIO state machine does not respond to pin changes unless I explicitly configure the pin using either:
or
Without one of these, the state machine stalls at wait or jmp, even though gpio_get(pin) works fine and reflects the correct pin state.
This behavior was not noticeable on the RP2040, but on the RP2350 (on a custom board), it's reproducible and consistent.
Example PIO program:
Initialization using C SDK:
My questions to the community:
Best regards,
Jan-Gerd Meinen
I'm working with a custom RP2350 board and encountered an unexpected issue while using PIO to read GPIO input states via wait and jmp. According to the SDK documentation in pio.h, it says:
Code: Select all
/*! rief Setup the function select for a GPIO to use output from the given PIO instance
* ...
* Note that this is not necessary for a state machine to be able to read the *input* value from a GPIO, but only for it to set the output value or output enable.
*/
Code: Select all
gpio_set_function(pin, GPIO_FUNC_SIO);
Code: Select all
pio_gpio_init(pio, pin);
This behavior was not noticeable on the RP2040, but on the RP2350 (on a custom board), it's reproducible and consistent.
Example PIO program:
Code: Select all
.program in_out
.side_set 1
wait 1 pin 0 side 0 ; Wait for rising edge
wait 0 pin 0 side 1 ; Wait for falling edge, set side=1 during transition
Code: Select all
% c-sdk{
static inline void in_out_program_init(PIO pio, uint sm, uint offset, uint pin, uint sideset_pin)
{
pio_sm_config c = in_out_program_get_default_config(offset);
sm_config_set_in_pins(&c, pin); // For wait and in instructions
sm_config_set_jmp_pin(&c, pin); // For jmp instructions
pio_gpio_init(pio, pin);
pio_gpio_init(pio, sideset_pin);
pio_sm_set_consecutive_pindirs(pio, sm, sideset_pin, 1, true);
sm_config_set_sideset_pins(&c, sideset_pin);
pio_sm_init(pio, sm, offset, &c); // Load configuration
pio_sm_set_enabled(pio, sm, true); // Start the state machine
}
%}
- Is this a known difference between RP2040 and RP2350?
- Is there a technical reason why wait/jmp requires explicit pin function setup, even for input-only use?
- Should the SDK documentation be updated to reflect this?
Best regards,
Jan-Gerd Meinen
Re: PIO wait/jmp requires explicit GPIO function setup – documentation misleading?
Yep, there is a hardware difference with the PADs, on RP2350 they have a feature named isolation, and are isolated by default.derGerd wrote: Is this a known difference between RP2040 and RP2350?
Is there a technical reason why wait/jmp requires explicit pin function setup, even for input-only use?
Should the SDK documentation be updated to reflect this?
From RP2350 datasheet:
9.7. Pad isolation latches
...
NOTE
Non-SDK applications ported from RP2040 must clear the ISO bit before using a GPIO, as this feature was not
present on RP2040. The SDK automatically clears the ISO bit when gpio_set_function() is called.
- PicoTinker
- Posts: 110
- Joined: Sun Mar 07, 2021 3:52 am
Re: PIO wait/jmp requires explicit GPIO function setup – documentation misleading?
Ah, that explains my observation. The comment on pio.h:
completely misled me.
Code: Select all
/*! \brief Setup the function select for a GPIO to use output from the given PIO instance
* \ingroup hardware_pio
*
* PIO appears as an alternate function in the GPIO muxing, just like an SPI
* or UART. This function configures that multiplexing to connect a given PIO
* instance to a GPIO. Note that this is not necessary for a state machine to
* be able to read the *input* value from a GPIO, but only for it to set the
* output value or output enable.
*
* \param pio The PIO instance; e.g. \ref pio0 or \ref pio1
* \param pin the GPIO pin whose function select to set
*/
static inline void pio_gpio_init(PIO pio, uint pin) {
check_pio_param(pio);
valid_params_if(HARDWARE_PIO, pin < NUM_BANK0_GPIOS);
gpio_set_function(pin, PIO_FUNCSEL_NUM(pio, pin));
}- PicoTinker
- Posts: 110
- Joined: Sun Mar 07, 2021 3:52 am
Jump to
- Community
- General discussion
- Announcements
- Other languages
- Deutsch
- Español
- Français
- Italiano
- Nederlands
- 日本語
- Polski
- Português
- Русский
- Türkçe
- User groups and events
- Raspberry Pi Official Magazine
- Using the Raspberry Pi
- Beginners
- Troubleshooting
- Advanced users
- Assistive technology and accessibility
- Education
- Picademy
- Teaching and learning resources
- Staffroom, classroom and projects
- Astro Pi
- Mathematica
- High Altitude Balloon
- Weather station
- Programming
- C/C++
- Java
- Python
- Scratch
- Other programming languages
- Windows 10 for IoT
- Wolfram Language
- Bare metal, Assembly language
- Graphics programming
- OpenGLES
- OpenVG
- OpenMAX
- General programming discussion
- Projects
- Networking and servers
- Automation, sensing and robotics
- Graphics, sound and multimedia
- Other projects
- Media centres
- Gaming
- AIY Projects
- Hardware and peripherals
- Camera board
- Compute Module
- Official Display
- HATs and other add-ons
- Device Tree
- Interfacing (DSI, CSI, I2C, etc.)
- Keyboard computers (400, 500, 500+)
- Raspberry Pi Pico
- General
- SDK
- MicroPython
- Other RP2040 boards
- Zephyr
- Rust
- AI Accelerator
- AI Camera - IMX500
- Hailo
- Software
- Raspberry Pi OS
- Raspberry Pi Connect
- Raspberry Pi Desktop for PC and Mac
- Beta testing
- Other
- Android
- Debian
- FreeBSD
- Gentoo
- Linux Kernel
- NetBSD
- openSUSE
- Plan 9
- Puppy
- Arch
- Pidora / Fedora
- RISCOS
- Ubuntu
- Ye Olde Pi Shoppe
- For sale
- Wanted
- Off topic
- Off topic discussion