The CPC disk operations are working! The video below shows the CPC loading a disk image from the eMMC, saving new files and unloading the disk image back to the eMMC. The image on the right is the UART console, which is also used to issue the mount and unmount commands (via ‘m’ and ‘u’ commands).
0:00 – Booting with numbered console messages
0:10 – Trying to list the contents of drive A: when it’s unmounted
0:16 – Issued the mount command, to read disk image from eMMC slot 1 and place it in RAM
0:22 – The load operation has completed from eMMC and the catalogue retried. The sectors read are listed in the console.
0:28 – Reboot the CPC, without unmounting the disk. Issue the screen save command.
0:40 – 16KB of screen data is written out to the ‘disk’. In reality, this just changes the disk image in RAM.
0:52 – Enter a short program to load the screen image and save that to the disk image.
1:24 Check the program works
1:30 Unmount the CPC disk. This is where the disk image gets written back to the eMMC.
1:36 Try to catalogue the unmounted disk
1:43 Reload and remount the disk image from eMMC
1:49 Image loaded to RAM, retry the cat command, then run the “go” program.
It’s been an interesting journey on the road to large scale storage on the CPC2. I’ve flip-flopped between eMMC and raw flash memory. At my last PCB assembly failure, I decided that the increased capacity in storage was not offset by the poor failure rate (50%) of mounting the 0.5mm pitch eMMC devices. The CPC2 needed only very limited space for it’s small 180K disks, so I’d decided to go with the 1GB raw flash, and write my own flash translation layer.
Then I discovered that eMMC also comes in 1mm pitch devices in the form of the Greenliant eMMC (GLS85VM1008A-M-I-LFWE) from Mouser. This changed the game again making assembly a lot easier, and I flipped again to go with eMMC onboard storage.
I added headers onto my fake SD Card and connected this to the DE10-Nano board.
I then proceeded to write the eMMC driver for the CPC2 supervisor.
I found the most important part of the specification document (JESD84-A44, free registration required) is the “Card State Transition Table” in section 7.11. This will show the path to activating the card and switching over to the data transfer state. There’s a lot of information on the internet about SDCard initialisation, but I found that the state transitions for SDCards are different from eMMC. So while my fake SDCard module just seemed to work in a Linux PC, it was probably a fluke. The hardware is a similar 4 data lines, clock and data, but the command sequences are slightly different. SDCards come in various types, SD, SDHC & SDXC and all can run at different voltages and each type requires a different initialisation process. Section 7.4.1 describes the card reset process and preparation for data transfer. For IP reasons I can’t reproduce the diagram here, but compare the simplicity of eMMC section 7.4.1 to this for SDxC:
Fortunately eMMC is a much more locked down format and initialisation was fairly simple to initialise if the card state table is followed. Once the basic media access functions had been written, it was fairly simple to write a higher level library to load the sector information to the RAM and write it back again to the eMMC.
Given the rich command set of the SD/eMMC, it’s surprising that once the card is initialised, there are just a few functions that are used, such as reading or writing a block, or blocks. It’s possible to lock regions and perform other functions like “trim”, but I didn’t implement any of these. Just a simple block read/write was sufficient for this application.
I’ve posted the latest code in my GitHub repository. Note that the ‘Supervisor’ code has been retired. The ATMEL SAM4SD device will no longer be used in the new design and will only remain the in the GitHub tree for reference. Two code bases are needed, the FPGA code and the Support code that drives the support logic for the CPC2.
Right now, the disk and ROM storage is working in the eMMC, and still on my to-do list is uploading a CPC “.DSK” file or ROM file to the storage, that will store the image in the eMMC. I’ll also store the support OS on the eMMC to be loaded during boot so that this isn’t tied into the FPGA bitstream.