I wanted to share something I have been working on for the last few days. (The idea came to me during a road trip over the weekend).
The idea is to use a ‘cheap’ (< $2) STM32F103C8 microcontroller to provide a VGA-out adapter for DIY Arduboys similar to the excellent FPGA based one that @uXe came up with: VGA1306 (VGA-out for DIY Arduboys implemented on an FPGA!).
The primary advantage is the low cost (< $2 for a ‘blue pill’ board) and easier toolchain (GNU GCC compatible) compared to the FPGA solution.
What makes this possible is the fast clock speed and excellent peripherals in the STM32F103C8. It has two hardware SPI peripherals which can be clocked up to 1/2 the primary clock speed, and both of which can be used by the DMA controller. It is normally clocked at up to 72 MHz, but can easily be overclocked as high as 128 MHz (or maybe even higher) as long as the USB functionality isn’t needed.
For this proof-of-concept, I am using a slight overclock of 80 MHz that allows 128 pixels (per line) to be clocked in using hardware SPI over DMA with a /16 prescaler in roughly the same amount of time (25.6 uS) that 640 pixels are normally clocked in with a 640x480@60Hz resolution (25.422 uS). This provides a 5x scaled pixel to the monitor’s VGA input. In theory, the clock could be cut down to 40 MHz (and prescaler changed to /8) or 20 MHz (prescaled to /4) or 10 MHz (prescaled to /2) to avoid the overclock (I haven’t tested it this way yet).
The VGA horizontal and vertical sync signals are handled by hardware timers with output pins driven by interrupts, so most of the time the main MCU is sitting idle.
There is plenty of RAM available (20 KB) for double-buffering (both a full input and output video buffer). The output buffer has to use horizontal addressing to match what the SPI DMA controllers needs for the VGA output, and the input buffer will need to match the vertical addressing that the Arduboy sends over. There should be plenty of time available in the vertical back porch (> 1 mS) to (at least start to) convert the input buffer to the output buffer.
So far, I have the entire output side of things working fairly nicely.
I still need to code and wire up the input side of things. I think I can use the second hardware SPI (in slave mode, potentially with DMA) on the input side to pull in the Arduboy’s video buffer. I should be able to just process the ‘data’ bytes and ignore the ‘command’ bytes normally intended for the SSD1306 (similar to the FPGA solution), so in theory this shouldn’t require any software changes on the Arduboy, and it shouldn’t require very much cpu time on the STM32 or cause much interference with the VGA output.
I imagine there will be plenty of pins and cpu time left over to be able to include a NES/SNES controller converter as well. Actually, there will probably be more RAM and CPU left over than the Arduboy has to begin with. And, there is an Arduino toolchain available (stm32duino), so in theory this one MCU/board might be able to handle everything (with a port of the required libraries).
I’m not quite ready to share code yet, but will do so when things are a little further done and tested.
On a 17" non-widescreen 4x3 (1280x1024 native) monitor with ~10x10 pixels:
On a 22" widescreen 16x10 (1680x1050 native) monitor with ~13x15 pixels:
The STM32F103C8T6 ‘Blue Pill’ board with VGA connector: