FatFs is a very nice FAT file system implementation suitable for SD cards and external memory.
The MSP-EXP430F5529 happens to have a micro SD card peripheral.
The bridge is in the bsp430mmc.c
file, which is a lightly modified version of the generic example that came with the FatFs sample package before sometime in 2013 when it was removed (post R0.09b).
This has been tested with R0.09 and R0.10 versions of FatFS. By default it will expect R0.10, which includes an API change. If you are using an older release (e.g. R0.09b) you need to tell the source code, because there's no usable information in the FatFS headers. Add EXT_CPPFLAGS=-DFATFS_IS_PRE_R0_10=1
to the make
command line.
bsp430mmc.c
Only the BSP430-specific elements of this file are extracted here. The first block is the initialization code:
#ifndef BSP430_MMC_FAST_HZ
#define BSP430_MMC_FAST_HZ 8000000UL
#endif
#include "ff_compat.h"
#include "diskio.h"
#ifndef CT_MMC
#define CT_MMC 0x01
#define CT_SD1 0x02
#define CT_SD2 0x04
#define CT_SDC (CT_SD1|CT_SD2)
#define CT_BLOCK 0x08
#endif
#define APP_SD_CS_PORT_HPL xBSP430hplLookupPORT(APP_SD_CS_PORT_PERIPH_HANDLE)
static int
configureSPIforSD (int fastp)
{
unsigned int init_spi_divisor;
if (fastp) {
} else {
}
if (0 == init_spi_divisor) {
init_spi_divisor = 1;
}
if (sdspi) {
}
miso_port->dir &= ~APP_SD_MISO_PORT_BIT;
UCSSEL__SMCLK, init_spi_divisor);
APP_SD_CS_PORT_HPL->sel &= ~APP_SD_CS_PORT_BIT;
APP_SD_CS_PORT_HPL->out |= APP_SD_CS_PORT_BIT;
APP_SD_CS_PORT_HPL->dir |= APP_SD_CS_PORT_BIT;
return (0 != sdspi) ? 0 : -1;
}
#define INIT_PORT() configureSPIforSD(0)
#define REINIT_PORT_FAST() configureSPIforSD(1)
#define DLY_US(n_) BSP430_CORE_DELAY_CYCLES(((n_) * BSP430_CLOCK_NOMINAL_MCLK_HZ)/1000000)
#define CS_H() do { APP_SD_CS_PORT_HPL->out |= APP_SD_CS_PORT_BIT; } while (0)
#define CS_L() do { APP_SD_CS_PORT_HPL->out &= ~APP_SD_CS_PORT_BIT; } while (0)
The second block is the SPI transmit/receive infrastructure:
static
void xmit_mmc (
const BYTE* buff,
UINT bc
)
{
}
static
void rcvr_mmc (
BYTE *buff,
UINT bc
)
{
}
There are a couple other enhancements to detect when the SPI interface configuration failed, but otherwise the driver is unmodified from ChaN's generic one.
main.c
#include <stdio.h>
#undef DIR
#include "diskio.h"
#include "ff.h"
#include "ff_compat.h"
char buffer[1024];
void main ()
{
unsigned int reset_flags;
unsigned long reset_causes;
int rv;
FATFS fso;
DIR dir_obj;
FILINFO finfo;
{
unsigned int sysrstiv;
reset_causes = 0;
reset_causes |= 1UL << (sysrstiv / 2);
}
}
cprintf(
"\nBUILD " __DATE__
" " __TIME__
"\n");
cprintf(
"FatFS Revision ID: %lu\n", (
unsigned long)_FATFS);
cprintf(
"System reset bitmask %lx; causes:\n", reset_causes);
{
int bit = 0;
while (bit < (8 * sizeof(reset_causes))) {
if (reset_causes & (1UL << bit)) {
}
++bit;
}
}
if (reset_flags & BSP430_SYS_FLAG_SYSRST_BOR) {
}
if (reset_flags & BSP430_SYS_FLAG_SYSRST_LPM5WU) {
}
if (reset_flags & BSP430_SYS_FLAG_SYSRST_POR) {
}
if (reset_flags & BSP430_SYS_FLAG_SYSRST_PUC) {
}
cprintf(
"Set core voltage gets %d\n", rv);
#if (FATFS_IS_PRE_R0_10 - 0)
rv = f_mount(0, &fso);
#else
rv = f_mount(&fso, "", 1);
#endif
if (FR_OK == rv) {
rv = f_opendir(&dir_obj, "/");
}
while (FR_OK == rv) {
rv = f_readdir(&dir_obj, &finfo);
if (FR_OK != rv) {
break;
}
if (0 == finfo.fname[0]) {
break;
}
cprintf(
"%s %lu %u %u %#x\n", finfo.fname, finfo.fsize, finfo.fdate, finfo.ftime, finfo.fattrib);
}
{
FIL fil_obj;
rv = f_open(&fil_obj, "0:BOOT.LOG", FA_OPEN_ALWAYS | FA_READ | FA_WRITE);
cprintf(
"Boot log open returned %d\n", rv);
if (FR_OK == rv) {
UINT nbytes = -1;
rv = f_read(&fil_obj, buffer, sizeof(buffer), &nbytes);
cprintf(
"Read boot log %u got %d with %u read\n",
(unsigned int)sizeof(buffer), rv, nbytes);
if (0 == rv) {
buffer[nbytes] = 0;
}
rv = f_lseek(&fil_obj, f_size(&fil_obj));
cprintf(
"Seek to end got %d\n", rv);
if (FR_OK == rv) {
int nb = snprintf(buffer, sizeof(buffer), "Booted build " __DATE__ " " __TIME__ "\n");
UINT nw;
rv = f_write(&fil_obj, buffer, nb, &nw);
cprintf(
"write %u got %d nw %u\n", nb, rv, nw);
}
f_close(&fil_obj);
}
}
#if (FATFS_IS_PRE_R0_10 - 0)
f_mount(0, NULL);
#else
f_mount(NULL, NULL, 1);
#endif
}
bsp430_config.h
#define BSP430_PLATFORM_BOOT_CONFIGURE_LFXT1 1
#define configBSP430_PLATFORM_SPIN_FOR_JUMPER 1
#define configBSP430_CONSOLE 1
#define configBSP430_UPTIME 1
#define configBSP430_SERIAL_ENABLE_SPI 1
#define configBSP430_HAL_USCI5_B1 1
#define APP_SD_SPI_PERIPH_HANDLE BSP430_PERIPH_USCI5_B1
#define configBSP430_HPL_PORT4 1
#define APP_SD_MISO_PORT_PERIPH_HANDLE BSP430_PERIPH_PORT4
#define APP_SD_MISO_PORT_BIT BIT2
#define configBSP430_HPL_PORT3 1
#define APP_SD_CS_PORT_PERIPH_HANDLE BSP430_PERIPH_PORT3
#define APP_SD_CS_PORT_BIT BIT7
#define BSP430_SERIAL_SPI_READ_TX_BYTE(i_) 0xFF
Makefile
PLATFORM ?= exp430f5529
TEST_PLATFORMS=exp430f5529
AUX_CPPFLAGS = -Ifatfs/src
MODULES=$(MODULES_PLATFORM)
MODULES += $(MODULES_UPTIME)
MODULES += $(MODULES_CONSOLE)
MODULES += $(MODULES_SERIAL)
MODULES += periph/sys
MODULES += periph/pmm
SRC=bsp430mmc.c main.c fatfs/src/ff.c
include $(BSP430_ROOT)/make/Makefile.common