SD Cards and FatFS
Okay, I am not happy to admit I have spent far too long trying to get a SD card to work on my own PCB and microcontroller. I have always worked with Wiring based libraries in the past. This is essentially the Arduino ecosystem of libraries, so I have never had to dig down into the implementation. If you find yourself in a similar situation, my ultimate solution was to relax, and read the docs.
An extremely common library for embedded file systems is the open source FatFs. However, the author only takes responsibility for the fat specific components. Thus, the programmer is responsible for writing the embedded block drivers for accessing the media, the low level disk I/O layer.
Through googling one can find much discussion between different cards whether they are SD, SDHC or SDXC and their SD version. Likewise, there are several sample projects for different microcontrollers implementing this layer, such as the common STM32 libraries.
- https://stm32f4-discovery.net/2014/07/library-21-read-sd-card-fatfs-stm32f4xx-devices/
- https://github.com/kiwih/cubemx-mmc-sd-card
- https://github.com/erley/stm32-sdcard
- http://www.rjhcoding.com/avrc-sd-interface-1.php
- http://hades.mech.northwestern.edu/index.php/PIC32MX:Interfacing_to_a_Secure_Digital(SD)_Flash_Card#Code
Through trying to port these libraries I found that many of these sample projects looked familiar. Surely several people did not write the same code? Turns out they didn't, and that's when I found the original code.
FatFS Example Drivers
Turns out, right at the bottom of the FatFs page there is a Resources section which includes drivers for 13+ devices and architectures. This code comes directly from the author of FatFs itself, so I trust taking these as a starting point much more than a standalone git repository from a random developer.
To port these examples to your own device, one only needs to be able to write the following:
- Send and Receive a byte over SPI
- Set CS high or low, simple GPIO
- Delay in ms
Additionally, it is helpful to be able to:
- Turn off the SPI lines, GPIO set as inputs
- Toggle the power switch to the SD card
- Access the real time clock (RTC)
As I am currently working with a SAML11 series micro, I started with the mmc_avr_spi.c
driver and adapted it. Once I started from here, I had the driver working within a few hours. I highly suggest starting from these example drivers and modifying.
However, my driver would only work when I had completely powered off the board and restarted the microcontroller. Any ideas? Read the next post for the solution.