aparrish
Posts: 3
Joined: Wed Dec 06, 2023 7:59 pm

is there an elegant way to share GPIO write access between both PIOs?

Wed Dec 06, 2023 8:59 pm

Hi there! So in this project I'm working on, I have programs running on both PIOs. The programs on the PIOs both need to be able to write to the same set of pins, though they will never be writing to those pins at the same time. The problem is that, as I understand it, write access for each GPIO can only be assigned to one of the two PIOs at a time (see section 2.19.2 "Function Select" in the RP2040 datasheet). My question: is there an elegant and fast way to switch the PIO that a GPIO is associated with on the fly, preferably with as little use of the CPU as possible?

I know that two state machines on the *same* PIO can output to the same set of pins, but my PIO programs are fairly sophisticated, and I don't think there's any realistic way for me to squeeze *both* of them into 32 instructions or less (which is why I'm using both PIOs). I could just bite the bullet and allocate a different set of pins for each PIO's output, but I'd really like to share pins between the two, since (as I mentioned) the PIO programs never use the pins at the same time, and the RP2040 has so few GPIOs to begin with. This is for a low-power, timing-critical application (margins of nanoseconds), so I'd prefer to avoid offloading work to the CPU.

(I realize I'm probably asking a question whose answer is "no, that's impossible!" but I figured it couldn't hurt to ask, in case I've missed something obvious!)

arg001
Posts: 606
Joined: Tue Jan 23, 2018 10:06 am

Re: is there an elegant way to share GPIO write access between both PIOs?

Wed Dec 06, 2023 9:59 pm

No, there isn't any way for a PIO program to affect the GPIO function select.

If it's really impossible for the CPU to do it, you could consider using DMA to write the GPIOx_CTRL registers, and you could even contrive for that DMA to be triggered by the PIO program.

But I have to wonder if this is really the best architecture - whether the PIO code could be partitioned differently (for example: PIO0 always controlling the pins, PIO1 doing whatever other logic these programs do, and data flowing from PIO1 to PIO0 by DMA).

User avatar
adam_green
Posts: 80
Joined: Tue Dec 14, 2021 12:43 am

Re: is there an elegant way to share GPIO write access between both PIOs?

Wed Dec 06, 2023 11:09 pm

arg001 wrote:
Wed Dec 06, 2023 9:59 pm
But I have to wonder if this is really the best architecture - whether the PIO code could be partitioned differently (for example: PIO0 always controlling the pins, PIO1 doing whatever other logic these programs do, and data flowing from PIO1 to PIO0 by DMA).
I have to agree with arg001's comment here. You might want to describe what you are trying to accomplish with your PIO code and your current solution. From what I have seen so far on this forum, there are people who really know their way around the RP2040 generally and the PIO peripheral specifically and they could probably give some great advice if they knew more about what you wanted to accomplish with the RP2040.

aparrish
Posts: 3
Joined: Wed Dec 06, 2023 7:59 pm

Re: is there an elegant way to share GPIO write access between both PIOs?

Thu Dec 07, 2023 4:51 am

Thank you for your response!!
arg001 wrote:
Wed Dec 06, 2023 9:59 pm
But I have to wonder if this is really the best architecture - whether te PIO code could be partitioned differently (for example: PIO0 always controlling the pins, PIO1 doing whatever other logic these programs do, and data flowing from PIO1 to PIO0 by DMA).
This is a valid question! I am open to suggestions for sure. Here's the project: I'm trying to use PIO to emulate a Game Boy cartridge MBC (memory bank controller). In my design, the RP2040 is connected to the data pins of the Game Boy cartridge edge, and to the cart's upper address pins. When the Game Boy "writes" to "address" that changes the memory bank index (which to the RP2040 looks like the cart edge's write pin going low, and certain data appearing on the address pins and data pins), I have the PIO "latch" the desired memory bank into a PIO state machine register. When the Game Boy "reads" from the banked memory area (write pin high), the PIO outputs the latched memory bank to the upper address pins of the memory chip.

The problem is that I need to do this for *both* the ROM chip in the cartridge *and* the SRAM chip in the cartridge. The Game Boy's memory map is set up such that the address range of ROM access is different (0x0000-0x7FFF) from the range for SRAM access (0xA000-0xBFFF), so technically I can use the same output GPIO for the upper address pins of both ROM and SRAM, since the two chips can never be active simultaneously. (And, in fact, this is how original MBC chips work!)

My idea was to have one PIO do the work of latching/writing ROM banks, and the other PIO do the work of latching/writing SRAM banks (and in fact my code works fine for these two use cases, as long as I'm only trying to do one or the other). There are other ways of breaking up the labor (e.g., as you suggest, one PIO handles reading bank switches, another PIO handles writing the bank numbers), but the difficulty is in sharing state (i.e., the latched bank numbers for both ROM and SRAM) between state machines and PIOs. DMA seems like a good solution here!

(Plausibly I could do both SRAM and ROM banking in the same PIO program, but there aren't enough state machine registers to keep track of both bank numbers. Right now I'm keeping the bank number in y, and I need OSR, ISR and x for various other purposes.)

fwiw, this is mainly a learning exercise for me—a way to become familiar with the internals of both the RP2040 and Game Boy cartridges. Though I definitely wouldn't mind having something that actually works when all is said and done!

aparrish
Posts: 3
Joined: Wed Dec 06, 2023 7:59 pm

Re: is there an elegant way to share GPIO write access between both PIOs?

Thu Dec 07, 2023 4:52 am

adam_green wrote:
Wed Dec 06, 2023 11:09 pm
From what I have seen so far on this forum, there are people who really know their way around the RP2040 generally and the PIO peripheral specifically and they could probably give some great advice if they knew more about what you wanted to accomplish with the RP2040.
(good point! just posted a bit more detail)

Return to “General”