Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PIO gpiobase not set with pin >= 32 #2030

Closed
sfe-SparkFro opened this issue Nov 8, 2024 · 13 comments
Closed

PIO gpiobase not set with pin >= 32 #2030

sfe-SparkFro opened this issue Nov 8, 2024 · 13 comments
Assignees
Milestone

Comments

@sfe-SparkFro
Copy link
Contributor

I tried running the PIO WS2812 example with an RP2350B, and found that the LED does not work when using a GPIO pin >=32. After some digging, it appears the root problem is that the pio->gpiobase is not getting set to 16. If I manually set the value, it works fine with GPIO pins >= 32.

Where is the correct place for gpiobase to be set? I put the following check into pio_sm_set_consecutive_pindirs() which worked for me, but I'm guessing it may be better to go somewhere else.

if(pin > 31 && pio_get_gpio_base(pio) == 0)
    pio->gpiobase = 0x10;
@sfe-SparkFro
Copy link
Contributor Author

Also, not sure whether #1834 is related

@lurch
Copy link
Contributor

lurch commented Nov 11, 2024

I wonder if this ought to be classed as a bug in the PIO WS2812 example? Perhaps there needs to be a call to pio_set_gpio_base() in https://github.com/raspberrypi/pico-examples/blob/develop/pio/ws2812/ws2812.pio#L36 ? 🤷
Disclaimer: I've not written any PIO code myself 😂

@kilograham kilograham self-assigned this Nov 11, 2024
@kilograham kilograham added this to the 2.1.0 milestone Nov 11, 2024
@sfe-SparkFro
Copy link
Contributor Author

I did consider whether it should be an issue with the example, but decided against that because IMO the SDK should abstract away things like setting gpiobase. The user should only have to worry about which PIO and pin they're using, which is why I opened the issue here. Although I've not written much PIO code either, so I'm not sure if this is something the user should actually need to worry about, but my naïve feeling is that the user shouldn't have to do things differently for GPIO >=32.

@lurch
Copy link
Contributor

lurch commented Nov 13, 2024

From what little I understand, I'm not sure how much the SDK can do "automatically" because you're never going to have PIO code which simultaneously works with pins 10 and 40? (because one is in the 0-32 range and the other is in the 16-48 range)

@StijnKuipers
Copy link

also - it is unclear how other pio related functions behave after a base is set.

pio_set_gpio_base(pio, 16);
pio_gpio_init(pio, somepin); <-- does somepin now need to be offset by 16? or is gpio number absolute?
sm_config_set_out_pins(&sm, somepin, 1); <-- how about here?

same for all other pio and sm functions that expect a pin number

@shtirlic
Copy link

shtirlic commented Nov 14, 2024

Here some info about the sm functions, also there is some magic with pioasm detection what range of pins is used, affecting fail to set gpio base
https://forums.raspberrypi.com/viewtopic.php?t=378871

@shtirlic
Copy link

shtirlic commented Nov 14, 2024

From what little I understand, I'm not sure how much the SDK can do "automatically" because you're never going to have PIO code which simultaneously works with pins 10 and 40? (because one is in the 0-32 range and the other is in the 16-48 range)

Theoretically it can be done if you can merge 2 PIO blocks , for example PIO1+PIO2(base 16) and we get a virtual PIO3 with all 48 pins and base 0

@peterharperuk
Copy link
Contributor

@StijnKuipers I believe both the functions you mention there handle things properly, i.e. you can pass a gpio number >31 and they should do the right thing.

@Octopus1633
Copy link

@StijnKuipers @sfe-SparkFro
Hello, I would like to ask how you solved this problem.I am testing the hello_pio program. And I also use the RP2350B. I want to use pin 45 to output high and low levels alternately.

I tried adding

pio_set_gpio_base(pio,16);

and changing the pin to 45

#define HELLO_PIO_LED_PIN 45

and found that the pin did not respond.

Then I tried to change the pin to a relative value

#define HELLO_PIO_LED_PIN (45-16)

Still no response, why is this?

@sfe-SparkFro
Copy link
Contributor Author

@Octopus1633 See my first message in this thread. That solution worked for my specific situation with the WS2812 PIO example, but I'm not sure whether that will work for every situation. I don't know enough about the PIO API to know what the "right" solution would be.

This issue has been assigned to the v2.1.0 milestone, so I'm guessing it will be addressed soon, but they're probably finishing work on other things right now.

@peterharperuk
Copy link
Contributor

@sfe-SparkFro I'll push an improvement to the WS2812 example

Where is the correct place for gpiobase to be set?

You should call pio_set_gpio_base before calling any pio or state machine functions. Then the base is set for that pio from then on for the programs that are loaded into its state machines.

We've added the pio_claim_free_sm_and_add_program_for_gpio_range function to make this easier, it can be used to set the gpio base on a free pio or pick a compatible pio.

peterharperuk added a commit to peterharperuk/pico-examples that referenced this issue Nov 19, 2024
peterharperuk added a commit to peterharperuk/pico-examples that referenced this issue Nov 19, 2024
@peterharperuk
Copy link
Contributor

See raspberrypi/pico-examples#574

I think apart from this there's nothing to do here?

@peterharperuk
Copy link
Contributor

peterharperuk commented Nov 20, 2024

Closing this as I'm fairly happy there's nothing else to fix here. Please reopen if you disagree. The simple answer is to use pio_claim_free_sm_and_add_program_for_gpio_range and always pass the real gpio number into sdk functions - don't take 16 off them or anything as the sdk accounts for the gpio base for you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants