2014-12-22 12:35:05 +01:00
|
|
|
|
#include "c_stdio.h"
|
|
|
|
|
#include "platform.h"
|
|
|
|
|
#include "spiffs.h"
|
|
|
|
|
|
|
|
|
|
spiffs fs;
|
|
|
|
|
|
|
|
|
|
#define LOG_PAGE_SIZE 256
|
|
|
|
|
|
|
|
|
|
static u8_t spiffs_work_buf[LOG_PAGE_SIZE*2];
|
|
|
|
|
static u8_t spiffs_fds[32*4];
|
2015-07-31 08:29:29 +02:00
|
|
|
|
#if SPIFFS_CACHE
|
|
|
|
|
static u8_t spiffs_cache[(LOG_PAGE_SIZE+32)*2];
|
|
|
|
|
#endif
|
2014-12-22 12:35:05 +01:00
|
|
|
|
|
2015-01-05 03:09:51 +01:00
|
|
|
|
static s32_t my_spiffs_read(u32_t addr, u32_t size, u8_t *dst) {
|
2014-12-22 12:35:05 +01:00
|
|
|
|
platform_flash_read(dst, addr, size);
|
|
|
|
|
return SPIFFS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-05 03:09:51 +01:00
|
|
|
|
static s32_t my_spiffs_write(u32_t addr, u32_t size, u8_t *src) {
|
2014-12-22 12:35:05 +01:00
|
|
|
|
platform_flash_write(src, addr, size);
|
|
|
|
|
return SPIFFS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-05 03:09:51 +01:00
|
|
|
|
static s32_t my_spiffs_erase(u32_t addr, u32_t size) {
|
2014-12-22 12:35:05 +01:00
|
|
|
|
u32_t sect_first = platform_flash_get_sector_of_address(addr);
|
|
|
|
|
u32_t sect_last = sect_first;
|
|
|
|
|
while( sect_first <= sect_last )
|
|
|
|
|
if( platform_flash_erase_sector( sect_first ++ ) == PLATFORM_ERR )
|
|
|
|
|
return SPIFFS_ERR_INTERNAL;
|
|
|
|
|
return SPIFFS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void myspiffs_check_callback(spiffs_check_type type, spiffs_check_report report, u32_t arg1, u32_t arg2){
|
|
|
|
|
// if(SPIFFS_CHECK_PROGRESS == report) return;
|
|
|
|
|
// NODE_ERR("type: %d, report: %d, arg1: %d, arg2: %d\n", type, report, arg1, arg2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************
|
|
|
|
|
The W25Q32BV array is organized into 16,384 programmable pages of 256-bytes each. Up to 256 bytes can be programmed at a time.
|
|
|
|
|
Pages can be erased in groups of 16 (4KB sector erase), groups of 128 (32KB block erase), groups of 256 (64KB block erase) or
|
|
|
|
|
the entire chip (chip erase). The W25Q32BV has 1,024 erasable sectors and 64 erasable blocks respectively.
|
|
|
|
|
The small 4KB sectors allow for greater flexibility in applications that require data and parameter storage.
|
|
|
|
|
|
|
|
|
|
********************/
|
|
|
|
|
|
2015-04-02 18:51:02 +02:00
|
|
|
|
void myspiffs_mount() {
|
2014-12-22 12:35:05 +01:00
|
|
|
|
spiffs_config cfg;
|
2015-10-09 04:54:51 +02:00
|
|
|
|
#ifdef SPIFFS_FIXED_LOCATION
|
|
|
|
|
cfg.phys_addr = SPIFFS_FIXED_LOCATION;
|
|
|
|
|
#else
|
2014-12-22 12:35:05 +01:00
|
|
|
|
cfg.phys_addr = ( u32_t )platform_flash_get_first_free_block_address( NULL );
|
2015-10-09 04:54:51 +02:00
|
|
|
|
#endif
|
2015-01-27 14:02:54 +01:00
|
|
|
|
cfg.phys_addr += 0x3000;
|
2015-01-27 13:47:41 +01:00
|
|
|
|
cfg.phys_addr &= 0xFFFFC000; // align to 4 sector.
|
2014-12-22 12:35:05 +01:00
|
|
|
|
cfg.phys_size = INTERNAL_FLASH_SIZE - ( ( u32_t )cfg.phys_addr - INTERNAL_FLASH_START_ADDRESS );
|
|
|
|
|
cfg.phys_erase_block = INTERNAL_FLASH_SECTOR_SIZE; // according to datasheet
|
|
|
|
|
cfg.log_block_size = INTERNAL_FLASH_SECTOR_SIZE; // let us not complicate things
|
|
|
|
|
cfg.log_page_size = LOG_PAGE_SIZE; // as we said
|
|
|
|
|
NODE_DBG("fs.start:%x,max:%x\n",cfg.phys_addr,cfg.phys_size);
|
|
|
|
|
|
|
|
|
|
cfg.hal_read_f = my_spiffs_read;
|
|
|
|
|
cfg.hal_write_f = my_spiffs_write;
|
|
|
|
|
cfg.hal_erase_f = my_spiffs_erase;
|
|
|
|
|
|
|
|
|
|
int res = SPIFFS_mount(&fs,
|
|
|
|
|
&cfg,
|
|
|
|
|
spiffs_work_buf,
|
|
|
|
|
spiffs_fds,
|
|
|
|
|
sizeof(spiffs_fds),
|
2015-07-31 08:29:29 +02:00
|
|
|
|
#if SPIFFS_CACHE
|
2014-12-22 12:35:05 +01:00
|
|
|
|
spiffs_cache,
|
|
|
|
|
sizeof(spiffs_cache),
|
2015-07-31 08:29:29 +02:00
|
|
|
|
#else
|
|
|
|
|
0, 0,
|
|
|
|
|
#endif
|
2014-12-22 12:35:05 +01:00
|
|
|
|
// myspiffs_check_callback);
|
|
|
|
|
0);
|
|
|
|
|
NODE_DBG("mount res: %i\n", res);
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-02 18:51:02 +02:00
|
|
|
|
void myspiffs_unmount() {
|
|
|
|
|
SPIFFS_unmount(&fs);
|
|
|
|
|
}
|
|
|
|
|
|
2014-12-22 12:35:05 +01:00
|
|
|
|
// FS formatting function
|
|
|
|
|
// Returns 1 if OK, 0 for error
|
2015-01-05 03:09:51 +01:00
|
|
|
|
int myspiffs_format( void )
|
2014-12-22 12:35:05 +01:00
|
|
|
|
{
|
|
|
|
|
SPIFFS_unmount(&fs);
|
|
|
|
|
u32_t sect_first, sect_last;
|
2015-10-09 04:54:51 +02:00
|
|
|
|
#ifdef SPIFFS_FIXED_LOCATION
|
|
|
|
|
sect_first = SPIFFS_FIXED_LOCATION;
|
|
|
|
|
#else
|
2014-12-22 12:35:05 +01:00
|
|
|
|
sect_first = ( u32_t )platform_flash_get_first_free_block_address( NULL );
|
2015-10-09 04:54:51 +02:00
|
|
|
|
#endif
|
2015-01-27 14:02:54 +01:00
|
|
|
|
sect_first += 0x3000;
|
2015-01-27 13:47:41 +01:00
|
|
|
|
sect_first &= 0xFFFFC000; // align to 4 sector.
|
2014-12-22 12:35:05 +01:00
|
|
|
|
sect_first = platform_flash_get_sector_of_address(sect_first);
|
|
|
|
|
sect_last = INTERNAL_FLASH_SIZE + INTERNAL_FLASH_START_ADDRESS - 4;
|
|
|
|
|
sect_last = platform_flash_get_sector_of_address(sect_last);
|
|
|
|
|
NODE_DBG("sect_first: %x, sect_last: %x\n", sect_first, sect_last);
|
|
|
|
|
while( sect_first <= sect_last )
|
|
|
|
|
if( platform_flash_erase_sector( sect_first ++ ) == PLATFORM_ERR )
|
|
|
|
|
return 0;
|
2015-04-02 18:51:02 +02:00
|
|
|
|
myspiffs_mount();
|
2014-12-22 12:35:05 +01:00
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-05 03:09:51 +01:00
|
|
|
|
int myspiffs_check( void )
|
2014-12-22 12:35:05 +01:00
|
|
|
|
{
|
|
|
|
|
// ets_wdt_disable();
|
|
|
|
|
// int res = (int)SPIFFS_check(&fs);
|
|
|
|
|
// ets_wdt_enable();
|
|
|
|
|
// return res;
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-05 03:09:51 +01:00
|
|
|
|
int myspiffs_open(const char *name, int flags){
|
2015-02-11 14:20:54 +01:00
|
|
|
|
return (int)SPIFFS_open(&fs, (char *)name, (spiffs_flags)flags, 0);
|
2014-12-22 12:35:05 +01:00
|
|
|
|
}
|
|
|
|
|
|
2015-01-05 03:09:51 +01:00
|
|
|
|
int myspiffs_close( int fd ){
|
2014-12-22 12:35:05 +01:00
|
|
|
|
SPIFFS_close(&fs, (spiffs_file)fd);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2015-01-05 03:09:51 +01:00
|
|
|
|
size_t myspiffs_write( int fd, const void* ptr, size_t len ){
|
2014-12-22 12:35:05 +01:00
|
|
|
|
#if 0
|
|
|
|
|
if(fd==c_stdout || fd==c_stderr){
|
|
|
|
|
uart0_tx_buffer((u8_t*)ptr, len);
|
|
|
|
|
return len;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
2015-01-07 08:57:17 +01:00
|
|
|
|
int res = SPIFFS_write(&fs, (spiffs_file)fd, (void *)ptr, len);
|
|
|
|
|
if (res < 0) {
|
|
|
|
|
NODE_DBG("write errno %i\n", SPIFFS_errno(&fs));
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
return res;
|
2014-12-22 12:35:05 +01:00
|
|
|
|
}
|
2015-01-05 03:09:51 +01:00
|
|
|
|
size_t myspiffs_read( int fd, void* ptr, size_t len){
|
2015-01-07 08:57:17 +01:00
|
|
|
|
int res = SPIFFS_read(&fs, (spiffs_file)fd, ptr, len);
|
|
|
|
|
if (res < 0) {
|
|
|
|
|
NODE_DBG("read errno %i\n", SPIFFS_errno(&fs));
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
return res;
|
2014-12-22 12:35:05 +01:00
|
|
|
|
}
|
2015-01-05 03:09:51 +01:00
|
|
|
|
int myspiffs_lseek( int fd, int off, int whence ){
|
2014-12-22 12:35:05 +01:00
|
|
|
|
return SPIFFS_lseek(&fs, (spiffs_file)fd, off, whence);
|
|
|
|
|
}
|
2015-01-05 03:09:51 +01:00
|
|
|
|
int myspiffs_eof( int fd ){
|
2014-12-22 12:35:05 +01:00
|
|
|
|
return SPIFFS_eof(&fs, (spiffs_file)fd);
|
|
|
|
|
}
|
2015-01-05 03:09:51 +01:00
|
|
|
|
int myspiffs_tell( int fd ){
|
2014-12-22 12:35:05 +01:00
|
|
|
|
return SPIFFS_tell(&fs, (spiffs_file)fd);
|
|
|
|
|
}
|
2015-01-05 03:09:51 +01:00
|
|
|
|
int myspiffs_getc( int fd ){
|
2015-01-08 09:03:21 +01:00
|
|
|
|
unsigned char c = 0xFF;
|
2015-01-07 08:57:17 +01:00
|
|
|
|
int res;
|
2014-12-22 12:35:05 +01:00
|
|
|
|
if(!myspiffs_eof(fd)){
|
2015-01-07 08:57:17 +01:00
|
|
|
|
res = SPIFFS_read(&fs, (spiffs_file)fd, &c, 1);
|
|
|
|
|
if (res != 1) {
|
|
|
|
|
NODE_DBG("getc errno %i\n", SPIFFS_errno(&fs));
|
|
|
|
|
return (int)EOF;
|
2015-01-08 09:03:21 +01:00
|
|
|
|
} else {
|
|
|
|
|
return (int)c;
|
2015-01-07 08:57:17 +01:00
|
|
|
|
}
|
2014-12-22 12:35:05 +01:00
|
|
|
|
}
|
2015-01-08 09:03:21 +01:00
|
|
|
|
return (int)EOF;
|
2014-12-22 12:35:05 +01:00
|
|
|
|
}
|
2015-01-05 03:09:51 +01:00
|
|
|
|
int myspiffs_ungetc( int c, int fd ){
|
2014-12-22 12:35:05 +01:00
|
|
|
|
return SPIFFS_lseek(&fs, (spiffs_file)fd, -1, SEEK_CUR);
|
|
|
|
|
}
|
2015-01-05 03:09:51 +01:00
|
|
|
|
int myspiffs_flush( int fd ){
|
2014-12-22 12:35:05 +01:00
|
|
|
|
return SPIFFS_fflush(&fs, (spiffs_file)fd);
|
|
|
|
|
}
|
2015-01-05 03:09:51 +01:00
|
|
|
|
int myspiffs_error( int fd ){
|
2014-12-22 12:35:05 +01:00
|
|
|
|
return SPIFFS_errno(&fs);
|
|
|
|
|
}
|
2015-01-05 03:09:51 +01:00
|
|
|
|
void myspiffs_clearerr( int fd ){
|
2015-03-09 18:12:36 +01:00
|
|
|
|
SPIFFS_clearerr(&fs);
|
2014-12-22 12:35:05 +01:00
|
|
|
|
}
|
2015-02-11 14:20:54 +01:00
|
|
|
|
int myspiffs_rename( const char *old, const char *newname ){
|
|
|
|
|
return SPIFFS_rename(&fs, (char *)old, (char *)newname);
|
|
|
|
|
}
|
2015-02-13 12:23:30 +01:00
|
|
|
|
size_t myspiffs_size( int fd ){
|
|
|
|
|
return SPIFFS_size(&fs, (spiffs_file)fd);
|
|
|
|
|
}
|
2014-12-22 12:35:05 +01:00
|
|
|
|
#if 0
|
2015-01-05 03:09:51 +01:00
|
|
|
|
void test_spiffs() {
|
2014-12-22 12:35:05 +01:00
|
|
|
|
char buf[12];
|
|
|
|
|
|
|
|
|
|
// Surely, I've mounted spiffs before entering here
|
|
|
|
|
|
|
|
|
|
spiffs_file fd = SPIFFS_open(&fs, "my_file", SPIFFS_CREAT | SPIFFS_TRUNC | SPIFFS_RDWR, 0);
|
|
|
|
|
if (SPIFFS_write(&fs, fd, (u8_t *)"Hello world", 12) < 0) NODE_DBG("errno %i\n", SPIFFS_errno(&fs));
|
|
|
|
|
SPIFFS_close(&fs, fd);
|
|
|
|
|
|
|
|
|
|
fd = SPIFFS_open(&fs, "my_file", SPIFFS_RDWR, 0);
|
|
|
|
|
if (SPIFFS_read(&fs, fd, (u8_t *)buf, 12) < 0) NODE_DBG("errno %i\n", SPIFFS_errno(&fs));
|
|
|
|
|
SPIFFS_close(&fs, fd);
|
|
|
|
|
|
|
|
|
|
NODE_DBG("--> %s <--\n", buf);
|
|
|
|
|
}
|
|
|
|
|
#endif
|