Here’s my Beaglebone project:
I love old Atari 8 bit computers.
ABX uses the PRU-ICSS to emulate RAM for the 6502 and graphics chip in the Atari. I never did figure out how to drive a bi-directional bus directly from the PRU like was asking about back in June:
Alexander Hiam’s blog helped me understand why the control module can’t be written by the PRU, namely that you have be the kernel to do so:
So, instead I just use the OE lines on the level shifters (that I need anyway to talk the Atari) to multiplex between r30 and r31.
There are a very limited number of PRU signals pinned out on the A5, so I multiplex the address and data 8 bits at a time. The Atari runs at 1.79Mhz, so I only have about 55 PRU cycles to figure out what address to read or write and to respond in the case of a read. This is plenty if I just talk to the local memory of the PRU. There’s too much latency to DDR, however, so I resort to shutting down the RAM emulation and bursting memory from DDR to the local memory when the Atari wants more data. Then the memory emulation resumes. This means the Atari has to have a resident program in it’s own memory to run while it waits for this transaction. Luckily the PRU-ICSS’s local memory (8KB for each PRU + 12KB shared = 28KB total) is plenty for the little Atari for short periods (like every 1/30th of a second) and the PRU can burst data from DDR plenty fast.
I found that if I shut down one of the PRUs, then I can access its r30 and r31 registers from the other PRU via the local memory map. This allows me to access all of the available pinned out signals from a single thread of execution which simplifies things a lot. Note, however, that there are a few stall cycles when reading the other PRU’s registers this way, so it’s not the single cycle resolution you get when accessing r30 and r31 directly, but it’s no worse than accessing the local memory.