I wanted to take some time to talk about one of the really cool features of the Retro Watch: the FPGA and how it works in conjunction with the DA14706 main application processor. What better way to do that than with a demo!
Lets start with a basic system block diagram:
The main application CPU feels like it was created just for the Retro Watch. It has a LOT of ram for an embedded MCU (over 1MB) and that ram is very well partitioned to avoid bus conflicts when doing data moves behing the scenes (very important for rendering graphics without making the rest of the CPU pause).
And it has an absolutely absurd amount of QSPI ports. The first is actually an 8 bit SPI port (though currently we are only using half its potential with a 4 bit spi flash chip). It then has two memory mapped QSPI busses which can directly drive FLASH or PSRAM chips. In our case, an 8MB PSRAM chip provides extra ram for projects that need it; its not very fast ram but it does have a 4KB cache to speed things up a bit. The other QSPI port is connected to the FPGA. This port is both for configuring the FPGA on start up and for communicating with it while running. This gives us a moderately fast memory-mapped interface which is pretty specacular. Notice the PSRAM QSPI bus is also connected to the FPGA. This allows the FPGA to utilize the PSRAM directly, or eaves drop for some hacky memory tricks.
Finally, there is a QSPI specifically for the LCD. While our design actually uses the much faster MCU bus (a parallel 8 bit bus for talking to LCDs) it does give us the flexibilty to support a wider range of LCDs in the future (if we decide the front display should be EINK for instance).
The GPU is pretty basic. It has two hardware layers that can do on the fly color format conversion and color keying. It also has a simple blitting engine which can blit 2D buffers about without loading down the CPU (again, supporting various color format conversions on the fly). The blitting engine does some simple scaling and antialiasing but thats about as exciting as it gets. Even as limited as it seems, this frees up a LOT of resources compared to software rendering and makes our 160Mhz CPU into a pretty narly 2D graphics renderer in its own right.
BUt probably the coolest thing about this GPU (for us) is that you can put the blit textures and the hardware framebuffers anywhere in memory...including the memory-mapped QSPI buses! Why is that cool? I can memory map the FPGA directly into a framebuffer and poof: we have an infintantely configurable, cycle accurate, graphics core we can match up to pretty much any 2D game console that requires almost no interaction from the CPU for the actual rendering (okay, so there are some memory concerns for anything too far past snes era stuff but someone clever might be able to do N64 or PSX).
Not going to lie, I love everything about this project but its the FPGA that really gets me excited to develop on it.
Lets go through a simple example of how we might use the FPGA to render graphics. We are going to take it easy on ourselves and not try to sync up the LCD rendering with FPGA rendering and just make a simple Tile Map renderer that renders one line of pixeles at a time. It will then raise an interrupt to let us know when its done so we can copy it to a fraembuffer, and then moves on to the next line.
Part 2 is comming soon!