Skip to content

Commit

Permalink
FatFs integration (SDIO backend) (#242)
Browse files Browse the repository at this point in the history
  • Loading branch information
UncleRus authored and sheinz committed Oct 24, 2016
1 parent 2994a56 commit f1d44f5
Show file tree
Hide file tree
Showing 23 changed files with 38,479 additions and 0 deletions.
8 changes: 8 additions & 0 deletions examples/fatfs/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
PROGRAM = fatfs
EXTRA_COMPONENTS = extras/sdio extras/fatfs
#ESPBAUD = 460800

# FatFS parameters, see extras/fatfs/defaults.mk
FATFS_CODE_PAGE = 866

include ../../common.mk
132 changes: 132 additions & 0 deletions examples/fatfs/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
/*
* Example of using FatFs
*
* Part of esp-open-rtos
* Copyright (C) 2016 Ruslan V. Uss <[email protected]>
* BSD Licensed as described in the file LICENSE
*/
#include <esp/uart.h>
#include <espressif/esp_common.h>
#include <stdio.h>
#include <fatfs/ff.h>

#define CS_GPIO_PIN 2
#define TEST_FILENAME "/test_loooong_filename.txt"
#define TEST_CONTENTS "Hello! It's FatFs on esp8266 with ESP Open RTOS!"
#define READBUF_SIZE 256
#define DELAY_MS 3000

static const char contents[] = TEST_CONTENTS;

static const char *results[] = {
[FR_OK] = "Succeeded",
[FR_DISK_ERR] = "A hard error occurred in the low level disk I/O layer",
[FR_INT_ERR] = "Assertion failed",
[FR_NOT_READY] = "The physical drive cannot work",
[FR_NO_FILE] = "Could not find the file",
[FR_NO_PATH] = "Could not find the path",
[FR_INVALID_NAME] = "The path name format is invalid",
[FR_DENIED] = "Access denied due to prohibited access or directory full",
[FR_EXIST] = "Access denied due to prohibited access",
[FR_INVALID_OBJECT] = "The file/directory object is invalid",
[FR_WRITE_PROTECTED] = "The physical drive is write protected",
[FR_INVALID_DRIVE] = "The logical drive number is invalid",
[FR_NOT_ENABLED] = "The volume has no work area",
[FR_NO_FILESYSTEM] = "There is no valid FAT volume",
[FR_MKFS_ABORTED] = "The f_mkfs() aborted due to any problem",
[FR_TIMEOUT] = "Could not get a grant to access the volume within defined period",
[FR_LOCKED] = "The operation is rejected according to the file sharing policy",
[FR_NOT_ENOUGH_CORE] = "LFN working buffer could not be allocated",
[FR_TOO_MANY_OPEN_FILES] = "Number of open files > _FS_LOCK",
[FR_INVALID_PARAMETER] = "Given parameter is invalid"
};

static char readbuf[READBUF_SIZE];

static bool failed(FRESULT res)
{
bool fail = res != FR_OK;
if (fail)
printf("\n Error: ");
printf("\n %s\n", results[res]);
return fail;
}

void check_fatfs()
{
const char *vol = f_gpio_to_volume(CS_GPIO_PIN);

printf("\nCreating test file\n----------------------------\n");

FATFS fs;
// Mount filesystem
printf("f_mount(&fs, \"%s\")", vol);
if (failed(f_mount(&fs, vol, 1)))
return;

// Set default drive
printf("f_chdrive(\"%s\")", vol);
if (failed(f_chdrive(vol)))
return;

FIL f;
// Create test file
printf("f_open(&f, \"%s\", FA_WRITE | FA_CREATE_ALWAYS)", TEST_FILENAME);
if (failed(f_open(&f, TEST_FILENAME, FA_WRITE | FA_CREATE_ALWAYS)))
return;

size_t written;
// Write test string
printf("f_write(&f, \"%s\")", contents);
if (failed(f_write(&f, contents, sizeof(contents) - 1, &written)))
return;
printf(" Bytes written: %d\n", written);

// Close file
printf("f_close(&f)");
if (failed(f_close(&f)))
return;

printf("\nReading test file\n----------------------------\n");

// Open test file
printf("f_open(&f, \"%s\", FA_READ)", TEST_FILENAME);
if (failed(f_open(&f, TEST_FILENAME, FA_READ)))
return;

printf(" File size: %u\n", (uint32_t)f_size(&f));

size_t readed;
// Read file
printf("f_read(&f, ...)");
if (failed(f_read(&f, readbuf, sizeof(readbuf) - 1, &readed)))
return;
readbuf[readed] = 0;

printf(" Readed %u bytes, test file contents: %s\n", readed, readbuf);

// Close file
printf("f_close(&f)");
if (failed(f_close(&f)))
return;

// Unmount
printf("f_mount(NULL, \"%s\")", vol);
if (failed(f_mount(NULL, vol, 0)))
return;
}

void user_init(void)
{
uart_set_baud(0, 115200);
printf("SDK version:%s\n\n", sdk_system_get_sdk_version());

while (true)
{
printf("***********************************\nTesting FAT filesystem\n***********************************\n");
check_fatfs();
printf("\n\n");
for (size_t i = 0; i < DELAY_MS; i ++)
sdk_os_delay_us(1000);
}
}
8 changes: 8 additions & 0 deletions examples/fatfs_rtc/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
PROGRAM = fatfs
EXTRA_COMPONENTS = extras/sdio extras/fatfs extras/i2c extras/ds1307
ESPBAUD = 460800

# We provide uint32_t get_fattime() based on the RTC
FATFS_FS_NORTC = 0

include ../../common.mk
15 changes: 15 additions & 0 deletions examples/fatfs_rtc/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
This example shows how to use real-time clock (e.g. ds1307)
with FatFs for real timestamps on the filesystem objects.

1. Set `FATFS_FS_NORTC` to 0 (it's 1 by default) in application makefile.
2. Define function `uint32_t get_fattime()` which will return current time in
timestamp format:

Bits | Date part
-------|----------
0..4 | Second / 2 (0..29)
5..10 | Minute (0..59)
11..15 | Hour (0..23)
16..20 | Day (1..31)
21..24 | Month (1..12)
25..31 | Year origin from 1980 (0..127)
133 changes: 133 additions & 0 deletions examples/fatfs_rtc/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
/*
* Example of using FatFs with RTC clock
*
* Part of esp-open-rtos
* Copyright (C) 2016 Ruslan V. Uss <[email protected]>
* BSD Licensed as described in the file LICENSE
*/
#include <esp/uart.h>
#include <espressif/esp_common.h>
#include <stdio.h>
#include <fatfs/ff.h>
#include <FreeRTOS.h>
#include <task.h>
#include <i2c/i2c.h>
#include <ds1307/ds1307.h>

// SD card
#define CS_GPIO_PIN 2

// ds1307
#define SCL_PIN 5
#define SDA_PIN 4

#define TEST_FILENAME "/test_rtc_file.txt"
#define TEST_CONTENTS "Hello! It's a test file and it can be deleted!"
#define DELAY_MS 3000

// This function called by FatFs
uint32_t get_fattime()
{
struct tm time;
ds1307_get_time(&time);

return ((uint32_t)(time.tm_year - 1980) << 25)
| ((uint32_t)time.tm_mon << 21)
| ((uint32_t)time.tm_mday << 16)
| ((uint32_t)time.tm_hour << 11)
| ((uint32_t)time.tm_min << 5)
| ((uint32_t)time.tm_sec >> 1);
}

static const char contents[] = TEST_CONTENTS;
static FATFS fs;

static void dump_fileinfo()
{
FILINFO info;
printf("File: %s\n", TEST_FILENAME);
if (f_stat(TEST_FILENAME, &info) != FR_OK)
{
printf("Cannot get file status\n");
return;
}
printf("File size: %u bytes\n", (uint32_t)info.fsize);
printf(
"Modified: %04d-%02d-%02d %02d:%02d:%02d\n",
(info.fdate >> 9) + 1980, // year
(info.fdate >> 5) & 0x0f, // month
info.fdate & 0x1f, // day
info.ftime >> 11, // hours
(info.ftime >> 5) & 0x3F, // minutes
(info.ftime & 0x1f) << 1 // seconds
);

}

void rewrite_file_task(void *p)
{
const char *volume = f_gpio_to_volume(CS_GPIO_PIN);

while (true)
{
do
{
if (f_mount(&fs, volume, 1) != FR_OK)
{
printf("Cannot mount volume %s\n", volume);
break;
}

if (f_chdrive(volume) != FR_OK)
{
printf("Cannot set default drive %s\n", volume);
break;
}

printf("\nTest file\n----------------------------\n");

dump_fileinfo();

printf("\nRe-creating test file\n----------------------------\n");

FIL f; //< It's big and it's on the stack! We need larger stack size

if (f_open(&f, TEST_FILENAME, FA_WRITE | FA_CREATE_ALWAYS) != FR_OK)
{
printf("Cannot create file %s\n", TEST_FILENAME);
break;
}

size_t bw;
if (f_write(&f, contents, sizeof(contents) - 1, &bw))
{
printf("Cannot write to file\n");
break;
}
printf("Bytes written: %d\n", bw);

if (f_close(&f) != FR_OK)
{
printf("Cannot close file\n");
break;
}

dump_fileinfo();

f_mount(NULL, volume, 0);
}
while (false);

vTaskDelay(DELAY_MS / portTICK_RATE_MS);
}
}

void user_init(void)
{
uart_set_baud(0, 115200);
printf("SDK version:%s\n\n", sdk_system_get_sdk_version());

i2c_init (SCL_PIN, SDA_PIN);

xTaskCreate(rewrite_file_task, (signed char *)"task1", 512, NULL, 2, NULL);
}
55 changes: 55 additions & 0 deletions extras/fatfs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# FatFs - Generic FAT File System Module

Current version: R0.12b

## How to use

Connect your SD card to ESP module

SD pin | ESP8266
--------|------------
1. DAT2 | -
2. /CS | Any accessible GPIO (15, 5, 4, 0, 2, 16)
3. DI | HMOSI (GPIO13)
4. VDD | +3V3
5. CLK | HCLK (GPIO14)
6. VSS | GND
7. DO | HMISO (GPIO12)
8. RSV | -

Add `extras/sdio` and `extras/fatfs` to `EXTRA_COMPONENTS` parameter of your
makefile, e.g.

```Makefile
EXTRA_COMPONENTS = extras/sdio extras/fatfs
```

Use `const char *f_gpio_to_volume(uint8_t gpio)` to get the FatFs volume ID
based on GPIO which is used for CS pin.

## FatFs configuration

Almost all of the FatFs parameters are configurable in the Makefile of your
project. See default values and their meaning in `defaults.mk`.

## Original documentation

http://elm-chan.org/fsw/ff/00index_e.html

## License

Copyright (C) 20xx, ChaN, all right reserved.

FatFs module is an open source software. Redistribution and use of FatFs in
source and binary forms, with or without modification, are permitted provided
that the following condition is met:

1. Redistributions of source code must retain the above copyright notice,
this condition and the following disclaimer.

This software is provided by the copyright holder and contributors "AS IS"
and any warranties related to this software are DISCLAIMED.
The copyright owner or contributors be NOT LIABLE for any damages caused
by use of this software.


Loading

0 comments on commit f1d44f5

Please sign in to comment.