Cool project. Thanks for doing a write-up that includes so much detail.
I do a lot of PCB review for students and makers, so if you're interested I wrote up some notes. Consider this an incomplete review because I only had so much free time, but hopefully this information can be helpful for your next rev or next project.
Design:
- Add ESD protection to all pins exposed by connectors and around the buttons. A simple TVS will work. However, the capacitance of the TVS needs to be small enough to minimize burden on your higher speed lines like USB and VGA. I'd use a cheap TVS for the low speed pins and then maybe look at some dedicated USB-HS protection parts and then just re-use those on the VGA lines. The USB3300 part you're using looks to have some minimal built-in ESD protection but as you observed it's probably not enough for real world use.
- Consider a buffer between your resistor DAC and the output. This could be an op-amp or a dedicated buffer chip. This will let the resistor DAC operate without significant load, isolated from the cable. You can then put a 75 ohm resistor in series with the buffer output to get optimal impedance matching with the 75-ohm VGA cable and load. You can get away with resistors connected straight to the VGA cable for demo purposes, but having it properly buffered and impedance matched will clean up the edges even further.
- Look into the design of an R-2R DAC as an alternative to the weighted-summing configuration you've used. You would want 0.1% resistors at 8-bit depth but you'd only have to buy and manage 2 resistor values (R and 2R) which is helpful when doing hand assembly.
- Better yet: This project is a good place to use a real DAC chip. Resistor DACs are cool to play with and useful for ultra-cheap demo boards where manufacturing cost is a high priority (Like the RP2040 VGA demo) but for a hand-assembled project like this a good DAC chip is great choice. It would shrink your PCB, reduce assembly time, and allow you to choose a physically smaller MCU package because you don't need 24 IO pins for the resistors.
Schematic:
- When using hierarchical schematics it's a good practice to avoid putting ICs and components in the root sheet. I suggest adding additional sheets for the MCU and other parts, then connect the blocks in the root. Treat the root page like a block diagram.
- KiCAD's bus functionality could help reduce a lot of the pins going into your blocks, like USB_D[0:7] and VGA_R[0:7]
- Breaking up that big STM symbol into a couple parts would be a good way to learn how to use KiCAD's symbol editor and would allow everything to fit on standard A4 sheets
- Don't hesitate to add notes to the schematic that might be helpful during debugging, assembly, or for your future self when you return to the project.
- I like to do a cleanup pass on schematics to make sure all labels are readable and there's enough space to comfortably see everything. It's a good practice to get into and pays off when you're tired from a long debugging session and trying to read a schematic. I suggest using the empty space on some of your pages to space components out more so no text is overlapping or hard to read.
PCB:
- You used 0.15mm (5.9 mil) traces almost everywhere. It's best to avoid using small traces unless you have to. You want to stay away from the minimum trace/space of your PCB manufacturer by default and reserve those for only the places where you need it. It will improve yields and make rework easier. Many of your traces could be 0.25mm or 0.5mm without any problem.
- Likewise, avoid letting traces run too close to pads unless you really need to. It's okay when you need to squeeze a trace into a narrow spot, but by default you should try to give as much room between pads and traces and between adjacent traces as you can. The tighter the spacing, the easier it becomes to accidentally short something out during assembly.
- Similar story with vias: Try not to use the absolute smallest vias everywhere when you have space.
- A lot of your vias are grouped together in a way that creates large slots in your ground plane. This doesn't matter too much at the low speeds you're working with, but it's good practice to avoid creating large cutouts in ground planes. The return current has to flow somewhere and those big slots will force it to take a longer path, which increases emissions and distorts high speed signals.
Do you have advice how I could get someone to do a (possibly paid) review of PCBs for small hobby projects?
Being new to this space, it's hard to learn quickly when the feedback cycle involves having PCBs manufactured, shipped, soldering them and then finding out what could have been better. (Or it works and you never find out what you did wasn't the right way to do it)
> someone to do a (possibly paid) review of PCBs for small hobby projects?
This is one of those awkward things where if you post to r/diyelectronics you might get someone doing it for free, but as soon as you try to pay for it both parties realize the going rate for experienced EEs is somewhere around $100/hour.
Some notes because I weirdly just went through almost the exact same project for work:
* I also started with an RP2040 because the PIO is such a good Swiss Army knife for working with custom digital protocols. An RP2040 with a faster USB PHY would be killer!
* The STM32U5 series has variants with built-in High Speed USB PHYs, along with 2.5 megabytes of SRAM, along with easily solderable footprints (down to LQFP64) if you want to solder at home instead of having a PCB fab do it.
* JLCPCB and/or PCBWay can assemble boards for quite cheap these days
* ESD protection would be good to add to the board, as others have noted and as you mention in the post
* Ideally all routed traces which have fast rise/fall times (most digital signals) should have a solid reference plane under them along the entire trace, to avoid cross-talk and EMI, along with vias for your reference plane if your signal changes layers.
* If you control the rendering, and color banding is still an issue, look into Interleaved Gradient Noise
* I hadn't heard of GUD before. I just made a simple USB Bulk Out endpoint in the firmware and in my application code, took less than a day. Sometimes a custom solution is quicker and easier but it depends on where it's running and who you're distributing it to. Obviously my custom solution isn't interoperable with other things, but for now it doesn't need to be.
I plan to write up a blog post on the project I worked on, I'll be sure to post it to HN when I do.
Pro tip: ST actually has a free tool called CubeMX that you can use to avoid the USB mistake. I've used a few H7 parts in the past and it's never been something we missed. I'm actually surprised people were surprised. USB high speed has very different voltage levels than full and low speed, and they're not ones digital chips often use, so it's very common to need an external PHY. Just like Ethernet.
My advice is to never shoot the board before you have all your IO planned out in the tool. That's saved us a bunch of times.
Also, give the U5 series a look? Hyperram, internal HS phy, and parallel display port.
Also also I'm pretty sure pis can put out parallel display on the 40 pin header. Maybe not 24 bit, though.
The example image for blanking from pyroelectro.com seems off to me. The blanking was on all sides of the images, not just two sides. The beam was off before reaching the end of the line, during the retrace, and still partially at the beginning of the line. The same for the retrace back to the top. The vertical blanking at the top of the image was important as things like CC and VITC were encoded there (as well as some other non-standard uses). Essentially, the active picture was window boxed in the blanking. This example image does not represent that well at all
The example isn't wrong, it's just looking at the timing a little differently from how you're used to. It's treating the blanking time as all occurring at the end of a line, instead of splitting it into front porch / back porch. This is a common pattern in video generators, since it means you can use a single counter for display and blanking, and define the blanking condition in terms of the counter exceeding the active count, e.g.
The issue was not with PIO. It was with the fact that both rp2040 and rp2350 only support usb1.1, which doesn't have enough bandwidth to do uncompressed ~320x240x16bpp@60Hz.
> I actually made decent progress here, although I kernel panicked many, many times. I never bothered to set up a proper development environment (oops), so pretty much any bug would require me to reboot my computer. This was super annoying and tedious, although I did learn a lot. I found cursed things in the official documentation, like interrobangs!
Wouldn't it be trivial to do this development in a VM with USB pass-through?
Arcade machines were so weird (and amazing). Example: A TON of effort was put into copy protection, for example. There are still a few games that haven't completely been broken into, despite being 30-40 years old.
The systems from the 80s-90s were also very odd/exotic. Some systems (like certain variants of Street Fighter II) had interesting bugs that needed to be worked around.
The article doesn't mention what games they are actually running on the arcade machine. They mentioned the 18-bit DAC being a limitation, but most 2D arcade games only output 15-bit color.
I don't know, as impressive as this is, I think using a MiSTeR would be much easier.
I also produce hardware projects and share them open source but unfortunately at a certain level of complexity people don't reproduce them. It's kind of sad but also I'm glad to be able to give back as I've had people help me learn to code in the past, sit down with me through video and yeah. Or people sharing knowledge in question answer forums.
There is the inspiration aspect too I've had some of my repos get forked/modded so that's something but yeah ultimately gotta do it for yourself. Getting published in tech websites is cool though, like I had a project get picked up by a Japanese website that was neat.
> The RP2040 can only do USB FS (full-speed), which is capable of 11 Mbps. At the 320x240x16 bpp we were originally targeting, every frame is 153.6 kB. At our maximum USB FS speed, that's less than 10 FPS! Embarrasingly, I had originally done the math with a bandwidth of 11 MBps, not 11 Mbps, so I was off by a factor of 8.
I wrote a book about Windows NT Server system administration, and sustained this error through chapters discussing hard disk and network bandwidth.
God bless my technical editor, who caught this before publication.
> I like the Raspberry Pi RP2040 a lot. It's relatively cheap (around $1 USD) and has tons of on-board RAM - 264 KB in fact! It also has what is called Programmable IO, or PIO.
I wonder how benchmarks would compare between the RP2040 and, say, a Z80.
It would destroy the Z80. It's a 32bit, dual core CPU running at 133MHz. Even single cored it'll thrash a Z80. Heck, I bet you could create a drop-in replacement board for the Z80 using an RP2040.
My sweet spot of choice between power and price is the ESP32 S3 (2x core @ 240mhz) at ~$6 per board, but yeah, the power to dollar ratio is crazy these days, across the board. And they are absolutely tiny and sip power if you write the code well.
The key here is the "PIO" which you won't find on a Teensy. It lets you do extreme "bit banging" tricks including generating video. People have even implemented Ethernet on it. I've used it for some custom serial protocols ("Weigand") used by alarm panels.
The Pico PIO has an instruction set and can be programmed.
You write PIO assembly that runs autonomously on a state machine, with explicit timing (e.g., out, in, set, mov, jmp, wait) and cycle‑accurate interfaces. The CPU communicates via small FIFOs, and interrupts are optional; the PIO can be “fire‑and‑forget” for many protocols.
Yes, I understand that, but I wonder about the multiple (obviously there is more to it than clock speed). I chose the Z80 because of its long-standing reputation.
The RP2040 is a Cortex-M0, which is about the smallest core you find on modern systems but still a pipelined 32 bit RISC machine running in the dozens of MHz.
Note though, that the article is really about the PIO device on these SOCs', which isn't part of the main CPU at all. It's sort of a very limited programmable hardware engine for the specific task of doing PCB level interconnect using GPIO and lightly buffered streaming. In some sense it's like a thematic midpoint between an FPGA and a CPU.
It's... honestly it's just really weird. And IMHO has really, really, REALLY limited application. It's for people who would otherwise be tempted to bitbang an I2C or UART, but not for ones who can put hardware on the board themselves, or who have a FPGA handy, or even for people who want to do non-trivial stuff like QSPI displays[1] or whatnot.
Basically PIO smells like a wart to me. I genuinely don't know who wants it. Regular hackers aren't sophisticated enough to use it productively and the snobby nerds have better options.
[1] The linked article appears to be doing a quarter-VGA display in 3-bit/8-color, and is sort of right at the limit of the power of the engine.
> The linked article appears to be doing a quarter-VGA display in 3-bit/8-color, and is sort of right at the limit of the power of the engine.
The resolution and color depth restrictions were the product of the low data rate of USB FS (~12 Mbps), not inherent limitations of PIO.
> It's... honestly it's just really weird. And IMHO has really, really, REALLY limited application.
I'd agree with "weird". But it's useful weird; it turns out that there are a lot of situations where PIO can avoid the need for an application-specific peripheral, and can provide that function in a more flexible fashion than a fixed-function peripheral could. Dmitry's SDIO device emulator is a great example - almost every other SDIO peripheral on the market is host-only.
> it turns out that there are a lot of situations where PIO can avoid the need for an application-specific peripheral
And I can only repeat: I think that's an aspirational delusion. I'm not aware of anyone shipping a PIO solution to anyone in volume. It's "useful weird" to Hackerspace nerds like us, and that leads to some epistemological skew.
Hardware needs to be boring and reliably supported (by people you can sue!) or else no one will bet a 10k unit PCB run on it. This is anything but.
>Basically PIO smells like a wart to me. I genuinely don't know who wants it. Regular hackers aren't sophisticated enough to use it productively and the snobby nerds have better options.
I mean, I applaud your work. But let's also be honest (in the "tough love" sense): those are all toys with significant limitations that preclude anyone shipping any of them on an actual device to an actual consumer. I mean, your SOC (maybe a $2 one) surely already includes a SPI master and USB host!
Actual interconnects that solve real market problems have big boring spec books and competing implementations and silicon vendors. The application for PIO is basically limited to "I have to connect to this crazy old junk and no one makes the part I'd otherwise need".
Having dealt with the errata sheets for microcontrollers with all those fancy IO devices that solve real marketing problems etc, I'd kill to fix those problems with a software upgrade.
if you find a SoC for $1 that has 2 Ethernet ports, and a usb host on it, while also having two cores and supporting 32MB of RAM you'll surprise me. rp2350 does all of the above for $1
Have you tested out the 2x PSRAM configuration; if so, have you written anything up about it? :) I've thought about a configuration like that myself but haven't committed to any hardware yet.
How are you handling startup? The approach I had in mind was putting boot flash on the second channel with a separate CS pin from PSRAM and configuring that in OTP; any idea if that would work?
Yes, sort of. Basically a tiny loader in OTP that enables nCS1 on some pin, copies code from there to ram on nCS0, reconfigures nCS1 to point to second ram. This does break usb flashing. Use swd.
Is there no way to do that without code in OTP? The bootrom is supposed to scan for an IMAGE_DEF on both memory banks, and can use nCS1 as specified in FLASH_DEVINFO. Unless there's something I'm missing, that should be sufficient.
This looks really cool. I'm restoring an 80's SEGA candy cab with a CRT and have been trying to figure out the best way to most accurately utilize the 15khz display in it. I tried bit-banging from a Raspberry Pi's GPIO, but landed on using an AMD GPU with the capability outputting a usable signal. This also looks like something I want to toy around with.
Cool project. Thanks for doing a write-up that includes so much detail.
I do a lot of PCB review for students and makers, so if you're interested I wrote up some notes. Consider this an incomplete review because I only had so much free time, but hopefully this information can be helpful for your next rev or next project.
Design:
- Add ESD protection to all pins exposed by connectors and around the buttons. A simple TVS will work. However, the capacitance of the TVS needs to be small enough to minimize burden on your higher speed lines like USB and VGA. I'd use a cheap TVS for the low speed pins and then maybe look at some dedicated USB-HS protection parts and then just re-use those on the VGA lines. The USB3300 part you're using looks to have some minimal built-in ESD protection but as you observed it's probably not enough for real world use.
- Consider a buffer between your resistor DAC and the output. This could be an op-amp or a dedicated buffer chip. This will let the resistor DAC operate without significant load, isolated from the cable. You can then put a 75 ohm resistor in series with the buffer output to get optimal impedance matching with the 75-ohm VGA cable and load. You can get away with resistors connected straight to the VGA cable for demo purposes, but having it properly buffered and impedance matched will clean up the edges even further.
- Look into the design of an R-2R DAC as an alternative to the weighted-summing configuration you've used. You would want 0.1% resistors at 8-bit depth but you'd only have to buy and manage 2 resistor values (R and 2R) which is helpful when doing hand assembly.
- Better yet: This project is a good place to use a real DAC chip. Resistor DACs are cool to play with and useful for ultra-cheap demo boards where manufacturing cost is a high priority (Like the RP2040 VGA demo) but for a hand-assembled project like this a good DAC chip is great choice. It would shrink your PCB, reduce assembly time, and allow you to choose a physically smaller MCU package because you don't need 24 IO pins for the resistors.
Schematic:
- When using hierarchical schematics it's a good practice to avoid putting ICs and components in the root sheet. I suggest adding additional sheets for the MCU and other parts, then connect the blocks in the root. Treat the root page like a block diagram.
- KiCAD's bus functionality could help reduce a lot of the pins going into your blocks, like USB_D[0:7] and VGA_R[0:7]
- Breaking up that big STM symbol into a couple parts would be a good way to learn how to use KiCAD's symbol editor and would allow everything to fit on standard A4 sheets
- Don't hesitate to add notes to the schematic that might be helpful during debugging, assembly, or for your future self when you return to the project.
- I like to do a cleanup pass on schematics to make sure all labels are readable and there's enough space to comfortably see everything. It's a good practice to get into and pays off when you're tired from a long debugging session and trying to read a schematic. I suggest using the empty space on some of your pages to space components out more so no text is overlapping or hard to read.
PCB:
- You used 0.15mm (5.9 mil) traces almost everywhere. It's best to avoid using small traces unless you have to. You want to stay away from the minimum trace/space of your PCB manufacturer by default and reserve those for only the places where you need it. It will improve yields and make rework easier. Many of your traces could be 0.25mm or 0.5mm without any problem.
- Likewise, avoid letting traces run too close to pads unless you really need to. It's okay when you need to squeeze a trace into a narrow spot, but by default you should try to give as much room between pads and traces and between adjacent traces as you can. The tighter the spacing, the easier it becomes to accidentally short something out during assembly.
- Similar story with vias: Try not to use the absolute smallest vias everywhere when you have space.
- A lot of your vias are grouped together in a way that creates large slots in your ground plane. This doesn't matter too much at the low speeds you're working with, but it's good practice to avoid creating large cutouts in ground planes. The return current has to flow somewhere and those big slots will force it to take a longer path, which increases emissions and distorts high speed signals.
Thanks for posting this - love this kind of positive, constructive criticism. Picked up a few tips for myself from it to!
Do you have advice how I could get someone to do a (possibly paid) review of PCBs for small hobby projects?
Being new to this space, it's hard to learn quickly when the feedback cycle involves having PCBs manufactured, shipped, soldering them and then finding out what could have been better. (Or it works and you never find out what you did wasn't the right way to do it)
> someone to do a (possibly paid) review of PCBs for small hobby projects?
This is one of those awkward things where if you post to r/diyelectronics you might get someone doing it for free, but as soon as you try to pay for it both parties realize the going rate for experienced EEs is somewhere around $100/hour.
You can post to the PrintedCircuitBoard subreddit to (potentially) get a review:
https://old.reddit.com/r/PrintedCircuitBoard/comments/zj6ac8...
This is great advice! Thanks!
Did you consider connecting the usb3300 to the PIO?
Sorry just to clarify - it isn't my project. I just thought it was a great post with some really helpful tips!
Some notes because I weirdly just went through almost the exact same project for work:
* I also started with an RP2040 because the PIO is such a good Swiss Army knife for working with custom digital protocols. An RP2040 with a faster USB PHY would be killer!
* The STM32U5 series has variants with built-in High Speed USB PHYs, along with 2.5 megabytes of SRAM, along with easily solderable footprints (down to LQFP64) if you want to solder at home instead of having a PCB fab do it.
* JLCPCB and/or PCBWay can assemble boards for quite cheap these days
* ESD protection would be good to add to the board, as others have noted and as you mention in the post
* Ideally all routed traces which have fast rise/fall times (most digital signals) should have a solid reference plane under them along the entire trace, to avoid cross-talk and EMI, along with vias for your reference plane if your signal changes layers.
* If you control the rendering, and color banding is still an issue, look into Interleaved Gradient Noise
* I hadn't heard of GUD before. I just made a simple USB Bulk Out endpoint in the firmware and in my application code, took less than a day. Sometimes a custom solution is quicker and easier but it depends on where it's running and who you're distributing it to. Obviously my custom solution isn't interoperable with other things, but for now it doesn't need to be.
I plan to write up a blog post on the project I worked on, I'll be sure to post it to HN when I do.
https://blog.demofox.org/2022/01/01/interleaved-gradient-noi...
Pro tip: ST actually has a free tool called CubeMX that you can use to avoid the USB mistake. I've used a few H7 parts in the past and it's never been something we missed. I'm actually surprised people were surprised. USB high speed has very different voltage levels than full and low speed, and they're not ones digital chips often use, so it's very common to need an external PHY. Just like Ethernet.
My advice is to never shoot the board before you have all your IO planned out in the tool. That's saved us a bunch of times.
Also, give the U5 series a look? Hyperram, internal HS phy, and parallel display port.
Also also I'm pretty sure pis can put out parallel display on the 40 pin header. Maybe not 24 bit, though.
The example image for blanking from pyroelectro.com seems off to me. The blanking was on all sides of the images, not just two sides. The beam was off before reaching the end of the line, during the retrace, and still partially at the beginning of the line. The same for the retrace back to the top. The vertical blanking at the top of the image was important as things like CC and VITC were encoded there (as well as some other non-standard uses). Essentially, the active picture was window boxed in the blanking. This example image does not represent that well at all
The example isn't wrong, it's just looking at the timing a little differently from how you're used to. It's treating the blanking time as all occurring at the end of a line, instead of splitting it into front porch / back porch. This is a common pattern in video generators, since it means you can use a single counter for display and blanking, and define the blanking condition in terms of the counter exceeding the active count, e.g.
The new RP 2350 has an enhanced PIO that relaxes some of the constraints the author ran into here.
Also the new HSTX (high-speed serial transmit) unit is really well suited for rapid line coding.
Here's a different project that generates a high resolution high depth VGA signal from the RP 2350: https://www.breatharian.eu/hw/disphstx/index_en.html
And here's NTSC composite using just the original PIO: https://github.com/obstruse/pico-composite8
The issue was not with PIO. It was with the fact that both rp2040 and rp2350 only support usb1.1, which doesn't have enough bandwidth to do uncompressed ~320x240x16bpp@60Hz.
> I actually made decent progress here, although I kernel panicked many, many times. I never bothered to set up a proper development environment (oops), so pretty much any bug would require me to reboot my computer. This was super annoying and tedious, although I did learn a lot. I found cursed things in the official documentation, like interrobangs!
Wouldn't it be trivial to do this development in a VM with USB pass-through?
Arcade machines were so weird (and amazing). Example: A TON of effort was put into copy protection, for example. There are still a few games that haven't completely been broken into, despite being 30-40 years old.
The systems from the 80s-90s were also very odd/exotic. Some systems (like certain variants of Street Fighter II) had interesting bugs that needed to be worked around.
The article doesn't mention what games they are actually running on the arcade machine. They mentioned the 18-bit DAC being a limitation, but most 2D arcade games only output 15-bit color.
I don't know, as impressive as this is, I think using a MiSTeR would be much easier.
All the games are custom ones built by people at the Recurse Center!
Philosophical tangent
I also produce hardware projects and share them open source but unfortunately at a certain level of complexity people don't reproduce them. It's kind of sad but also I'm glad to be able to give back as I've had people help me learn to code in the past, sit down with me through video and yeah. Or people sharing knowledge in question answer forums.
There is the inspiration aspect too I've had some of my repos get forked/modded so that's something but yeah ultimately gotta do it for yourself. Getting published in tech websites is cool though, like I had a project get picked up by a Japanese website that was neat.
> The RP2040 can only do USB FS (full-speed), which is capable of 11 Mbps. At the 320x240x16 bpp we were originally targeting, every frame is 153.6 kB. At our maximum USB FS speed, that's less than 10 FPS! Embarrasingly, I had originally done the math with a bandwidth of 11 MBps, not 11 Mbps, so I was off by a factor of 8.
I wrote a book about Windows NT Server system administration, and sustained this error through chapters discussing hard disk and network bandwidth.
God bless my technical editor, who caught this before publication.
CRT tech is neat, the flat ones are cooler
https://www.youtube.com/watch?v=pjzK-Lppa1c
Cool project! I've been doing software for so long but originally got an EE degree. I miss messing around with hardware.
> I like the Raspberry Pi RP2040 a lot. It's relatively cheap (around $1 USD) and has tons of on-board RAM - 264 KB in fact! It also has what is called Programmable IO, or PIO.
I wonder how benchmarks would compare between the RP2040 and, say, a Z80.
It would destroy the Z80. It's a 32bit, dual core CPU running at 133MHz. Even single cored it'll thrash a Z80. Heck, I bet you could create a drop-in replacement board for the Z80 using an RP2040.
Note it was possible to use a Z80 to function as a display controller, people used to do it back in the day...
https://archive.org/details/Cheap_Video_Cookbook_Don_Lancast...
The Galaksija computer used it's Z80 to help generate the video signal. I'm not sure how its implementation compares to your link.
https://en.wikipedia.org/wiki/Galaksija_(computer)
https://media.ccc.de/v/29c3-5178-en-the_ultimate_galaksija_t...
Crazy what you can buy nowadays like the Teensy 4.0 with 600MHz base clock
Granted that's $20 not $1
My sweet spot of choice between power and price is the ESP32 S3 (2x core @ 240mhz) at ~$6 per board, but yeah, the power to dollar ratio is crazy these days, across the board. And they are absolutely tiny and sip power if you write the code well.
The key here is the "PIO" which you won't find on a Teensy. It lets you do extreme "bit banging" tricks including generating video. People have even implemented Ethernet on it. I've used it for some custom serial protocols ("Weigand") used by alarm panels.
Really I guess I don't know what that is then as I buy the Teensy since it has so much IO, multiple UART, multiple I2C busses, sd card reading, etc...
edit: interesting
(Teensy | Pico)
Special Features: CAN Bus (3x), SDIO, S/PDIF | PIO (Programmable I/O) (8 SMs)
The Pico PIO has an instruction set and can be programmed.
You write PIO assembly that runs autonomously on a state machine, with explicit timing (e.g., out, in, set, mov, jmp, wait) and cycle‑accurate interfaces. The CPU communicates via small FIFOs, and interrupts are optional; the PIO can be “fire‑and‑forget” for many protocols.
That's cool, I'm not at that level right now, side note I bought an FPGA like 5 years ago and still haven't used it.
Yes, I understand that, but I wonder about the multiple (obviously there is more to it than clock speed). I chose the Z80 because of its long-standing reputation.
The RP2040 is a Cortex-M0, which is about the smallest core you find on modern systems but still a pipelined 32 bit RISC machine running in the dozens of MHz.
Note though, that the article is really about the PIO device on these SOCs', which isn't part of the main CPU at all. It's sort of a very limited programmable hardware engine for the specific task of doing PCB level interconnect using GPIO and lightly buffered streaming. In some sense it's like a thematic midpoint between an FPGA and a CPU.
It's... honestly it's just really weird. And IMHO has really, really, REALLY limited application. It's for people who would otherwise be tempted to bitbang an I2C or UART, but not for ones who can put hardware on the board themselves, or who have a FPGA handy, or even for people who want to do non-trivial stuff like QSPI displays[1] or whatnot.
Basically PIO smells like a wart to me. I genuinely don't know who wants it. Regular hackers aren't sophisticated enough to use it productively and the snobby nerds have better options.
[1] The linked article appears to be doing a quarter-VGA display in 3-bit/8-color, and is sort of right at the limit of the power of the engine.
> The linked article appears to be doing a quarter-VGA display in 3-bit/8-color, and is sort of right at the limit of the power of the engine.
The resolution and color depth restrictions were the product of the low data rate of USB FS (~12 Mbps), not inherent limitations of PIO.
> It's... honestly it's just really weird. And IMHO has really, really, REALLY limited application.
I'd agree with "weird". But it's useful weird; it turns out that there are a lot of situations where PIO can avoid the need for an application-specific peripheral, and can provide that function in a more flexible fashion than a fixed-function peripheral could. Dmitry's SDIO device emulator is a great example - almost every other SDIO peripheral on the market is host-only.
> it turns out that there are a lot of situations where PIO can avoid the need for an application-specific peripheral
And I can only repeat: I think that's an aspirational delusion. I'm not aware of anyone shipping a PIO solution to anyone in volume. It's "useful weird" to Hackerspace nerds like us, and that leads to some epistemological skew.
Hardware needs to be boring and reliably supported (by people you can sue!) or else no one will bet a 10k unit PCB run on it. This is anything but.
driving complex displays with no spu use: https://dmitry.gr/?r=06.%20Thoughts&proj=09.ComplexPioMachin... (my work)
pretending to be memory stick and sd card at dozens of mhz as a slave to a sync bus (my work)
ethernet: https://github.com/kingyoPiyo/Pico-10BASE-T (not my work)
68k bus slave (my work)
usb host https://github.com/sekigon-gonnoc/Pico-PIO-USB (not my work)
all on a $1 chip
> what are you blathering on about, sir?
Please don't.
I mean, I applaud your work. But let's also be honest (in the "tough love" sense): those are all toys with significant limitations that preclude anyone shipping any of them on an actual device to an actual consumer. I mean, your SOC (maybe a $2 one) surely already includes a SPI master and USB host!
Actual interconnects that solve real market problems have big boring spec books and competing implementations and silicon vendors. The application for PIO is basically limited to "I have to connect to this crazy old junk and no one makes the part I'd otherwise need".
Having dealt with the errata sheets for microcontrollers with all those fancy IO devices that solve real marketing problems etc, I'd kill to fix those problems with a software upgrade.
if you find a SoC for $1 that has 2 Ethernet ports, and a usb host on it, while also having two cores and supporting 32MB of RAM you'll surprise me. rp2350 does all of the above for $1
Have you tested out the 2x PSRAM configuration; if so, have you written anything up about it? :) I've thought about a configuration like that myself but haven't committed to any hardware yet.
yes i have tested it and no i have not written about it (yet). it does work and with the new ISSI 16MB chips, it gives 32MB of continuous memory!
Awesome - I might just have to try it.
How are you handling startup? The approach I had in mind was putting boot flash on the second channel with a separate CS pin from PSRAM and configuring that in OTP; any idea if that would work?
Yes, sort of. Basically a tiny loader in OTP that enables nCS1 on some pin, copies code from there to ram on nCS0, reconfigures nCS1 to point to second ram. This does break usb flashing. Use swd.
Is there no way to do that without code in OTP? The bootrom is supposed to scan for an IMAGE_DEF on both memory banks, and can use nCS1 as specified in FLASH_DEVINFO. Unless there's something I'm missing, that should be sufficient.
There's something deeply poetic about using modern engineering knowledge to breathe new life into the warm, fuzzy glow of an analog CRT.
Wonder if doing everything with cheap FPGA would be practical.
This looks really cool. I'm restoring an 80's SEGA candy cab with a CRT and have been trying to figure out the best way to most accurately utilize the 15khz display in it. I tried bit-banging from a Raspberry Pi's GPIO, but landed on using an AMD GPU with the capability outputting a usable signal. This also looks like something I want to toy around with.
> I have a full CI/CD pipeline set up for my PCBs
Oh more on this, please!