Mass Storage

This week's challenge was to get the internal SD card slot working. There are 2 SD card slots on the board I designed, the internal one which is designed to be left in all the time as the main "hard drive" and an external one that can be used as removable storage. The internal one is on the SDMMC2 peripheral which is perhaps not ideal since this has a less direct route to core memory but it was possible to set it up with 4 wire SDIO so it should be capable of faster data transfers. I opted to use an SD card socket rather than doing an eMMC soldered down, partly because eMMC tends to be BGA which is hard to solder in one off prototypes and partly because it's really handy to be able to remove the storage and plug it in a PC for analysis.

Part number mix up

The first hold up this week was a part number mix up. SD cards are weird little computers all of their own. They can get into states where they simply will not talk any more, in that state the only option is to power cycle the card and start from scratch with initialisation. In long-running remote systems this presents an issue, if the device has sufficient power supply protection to keep it running through all kinds of disruptions and the host MCU has a watchdog it is still possible for the system to get "stuck" because the SD card is in a locked state. To prevent this issue I always add a load switch to the SD card power, the kind of chip you find on USB ports to isolate a device that's drawing too much current.

On this board I'd used the MIC2025-2YM from Microchip. It's a little high-side load switch that lets a logic pin turn a power rail on and off and also provides overcurrent protection. The problem was I'd actually designed the circuit for the MIC2025-1YM. The two chips are almost identical except that the enable pin is inverted. On the -2 variant I'd used the enable pin is active low but on the -1 as I'd designed for the pin is active high. Of course I could invert the logic in the code and get it working but the pull-down resistor that is meant to leave the SD card off by default is actually turning it on by default.

The fix is simple, in the short term I've inverted the logic and added a short reset pulse in the boot up sequence. In the long term I should get some of the -1 variant chips on order!

CubeMX configuration

I've used the CubeMX libraries to drive the SDMMC peripheral and the built in FatFS library to read the card. In the long term I intend to use my own Gristle driver but this was the quickest way to prove the hardware. As usual with CubeMX there are a number of tricks to get it working. I configured the SDMMC peripheral and enabled FatFS from the Middlewares list. The SD card detected okay and identified the card type but when I started trying to read the card it would always time out. After searching around I found lots of mentions of configuring DMA for the peripheral but it turns out on the H7 the SDIO peripheral has DMA built in and it's all setup by HAL. In the end I found it was just that the interupt was not enabled by default. Once I'd checked that box it sprung into life.

A screenshot of a PuTTY terminal with 4 short filenames listed.
Contents of an old SD card root directory listed.

The code for this demo is in this commit on GitHub.