pioasm & sdk support of wait gpio on rp2350b #2141
Labels
No labels
bazel
bluetooth
board settings
boot_stage2
bug
build
c++
can't reproduce
clang
clib-interface
cmsis
code cleanliness
code size
compiler version issues
cyw43_driver
debug
discussion
documentation
duplicate
dynamic_clock
elf2uf2
enhancement
errata
filesystem
flash layout
floating point
FreeRTOS
hardware_adc
hardware_claim
hardware_clocks
hardware_dma
hardware_exception
hardware_flash
hardware_gpio
hardware_i2c
hardware_irq
hardware_pio
hardware_pwm
hardware_rcp
hardware_rtc
hardware_spi
hardware_sync
hardware_uart
hardware_vreg
hardware_watchdog
hardware_xosc
help wanted
host
IAR
installation
invalid
linker scripts
lto
lwip
mbedtls
missing API
needs reporter detail
networking
newlib
newlib-multicore
non-c
non-cmake
non-gcc
openocd
orphan PR
OS integration
pico_async_context
pico_base
pico_binary_info
pico_flash
picolibc
pico_lwip
pico_malloc
pico_multicore
pico_printf
pico_runtime
pico_stdio
pico_stdio_usb
pico_sync
pico_time
pico_util
pioasm
port
question
review
review2
rtos interop
runtime init
static library
svd
test
tinyusb
vscode
wifi integration
wontfix
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
gh-raspberrypi/pico-sdk#2141
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Hi! Over in CircuitPython I'm working on proper support for the high IO bank on the RP2350B.
As part of that, I think I've found a problem in pioasm and maybe
add_program_at_offset.I have the following (useless) pio program:
pioasm from 2.1.0 (& tip of develop, 2.1.0-6-g969f589) compiles it to the following:
Notice how the instruction encoding 0x2022 is used for both the
wait gpioandwait pin, and the instruction written aswait 0 gpio 34has decoded to the impossible (?)wait 0 pin, 34.I'm not sure what needs to happen here. I am pretty sure that at runtime you need a PIO peripheral with its gpio_offset set to 16, and that the instruction encodings loaded into
instr_memshould actually be0x2002(gpio 16+2 = 18) and0x2012(gpio 16+18=34). but I don't know whether this should be the encoding in theprogram_instructions[]array, or ifadd_program_at_offsetin the sdk should take care of altering thewait gpioinstruction encodings similar to how it altersjmpencodings depending on the load address.This bears directly on how we implement this in CircuitPython, since we want to use
pio_add_programand friends to load the instructions into the PIO peripheral, but also use our own python implementation of pioasm.Looking at section 11.4.3. of https://datasheets.raspberrypi.com/rp2350/rp2350-datasheet.pdf shows that
Indexis only encoded with 5 bits (and thus has a maximum value of 32), which I guess means that the mapping of gpio34 -> gpio18 has to be done before encoding things into theprogram_instructions[]array? 🤔 And presumably at the moment trying to set anIndexfield of 34 is overflowing into theSourcefield? Which would explain whywait 0 gpio 34is encoding to the same thing aswait 0 pin, 2( because34 = (1 << 5) | (2 & 0x1f)) ?Looking at https://github.com/raspberrypi/pico-sdk/blob/develop/tools/pioasm/pio_assembler.cpp#L394 it seems that it does keep track of which GPIOs are being used, so I guess the part of
pioasmthat does the final output needs to be modified to takeprogram.used_gpio_rangesinto account when calculation the WAIT gpioIndex?And I believe that this would need to be done at the "output stage" rather than "parse stage" because if you have
wait 0 gpio 20followed bywait 0 gpio 1then the GPIO20 would get encoded toIndex20 (because the later GPIO1 forces the use of the "lower" GPIO range); but if you hadwait 0 gpio 20followed bywait 0 gpio 34then the GPIO20 would get encoded toIndex4 (because the later GPIO34 forces the use of the "higher" GPIO range).(This is all just my educated guess - I could be entirely wrong! 😂 )
without presuming how the implementation should look, I thought of two possibilities: First, that the encoding in
program_instructionsjust takes the lower 5 bits (so wait 0 gpio 34 would encode to 0x2002), and then ``add_program_at_offsetperformsinstr ^ 0x10onwait gpio` instructions when loading them, if the high gpio range is marked as used.The second one is what I understand from your reply: when pioasm gets to the output stage, and the high gpio range is marked as used, it outputs
0x2002forwait 0 gpio 18and0x2012forwait 0 gpio 34. In that case, no change is needed toadd_program_at_offset. Not requiring a change to the runtime sdk code does seem like it could be preferable.I see there's a file
.../pioasm/test/amethyst.piothat hasbut I don't see if this is part of an automated test suite that can be run, or whether there's an expected output. However, it looks like someone did at least check that pioasm accepts these high pin numbers in
wait gpio.On further reflection, there has to be a component of this at load time: A program which uses
wait gpio 18could be loaded in a pio with gpio_offset=0 (so the required encoding is 0x2012) or in one with gpio_offset=16 (so the required encoding is 0x2002).pio_claim_free_sm_and_add_program_for_gpio_range should handle this? It can load a program into the appropriate pio with the base set correctly. However I can't immediately see it handling the invalid (?) request for a gpio count >= 32 for rp2350b
Yes, from a brief look, i think the majority of comments above are correct
This is an oversight; The 16-bit program does store
(pin & 31)which matches what happens with thepio_sm_configregister values. We also need to add a 32-bit value to the pio_program which holds bit 5 ofarg2I'll have to have a bit of a think about where the runtime component belongs such that we can make sure we do it after the PIO base is set.
merged into develop
Thanks!
@jepler Just a short question in regards to this issue: Have you been able to test this on hardware? I came to the conclusion a few months back that WAIT GPIO is just broken for pins > 32 and it is a hardware issue. I tried to get attention for this in the forums, but I don't think there are that many RP2350B out there at the moment: https://forums.raspberrypi.com/viewtopic.php?p=2258703&hilit=wait+gpio+rp2350b
In my tests I actually did the calculations of pin shift manually, setting the GPIO_BASE register manually. The same code got different results depending on if the hardware came out of a POR or reset via debugger depending on what software I flashed beforehand. Really strange behavior. I settled on skipping using WAIT GPIO and use WAIT PIN instead as that works flawlessly although there are even more pins shifts envolved.
@shilga If you're still seeing problems with this even after upgrading to pico-sdk 2.1.1 then I suggest you create a new issue here explaining your problems in detail, including example code. Thanks!