mirror of
https://github.com/esp8266/Arduino.git
synced 2025-06-13 13:01:55 +03:00
Merge remote-tracking branch 'remotes/esp8266/esp8266' into esp8266
This commit is contained in:
@ -209,7 +209,6 @@ void loop(void);
|
||||
#include "WString.h"
|
||||
|
||||
#include "HardwareSerial.h"
|
||||
#include "FileSystem.h"
|
||||
#include "Esp.h"
|
||||
#include "debug.h"
|
||||
|
||||
|
@ -27,7 +27,9 @@ extern "C" {
|
||||
//extern "C" void ets_wdt_init(uint32_t val);
|
||||
extern "C" void ets_wdt_enable(void);
|
||||
extern "C" void ets_wdt_disable(void);
|
||||
extern "C" void wdt_feed(void);
|
||||
extern "C" void wdt_feed(void) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* User-defined Literals
|
||||
|
@ -1,388 +0,0 @@
|
||||
/*
|
||||
FileSystem.cpp - SPIFS implementation for esp8266
|
||||
|
||||
Copyright (c) 2015 Hristo Gochkov. All rights reserved.
|
||||
This file is part of the esp8266 core for Arduino environment.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#include "FileSystem.h"
|
||||
#include "Arduino.h"
|
||||
#include "spiffs/spiffs_esp8266.h"
|
||||
|
||||
// These addresses and sizes are defined in the linker script.
|
||||
// For each flash memory size there is a linker script variant
|
||||
// which sets spiffs location and size.
|
||||
extern "C" uint32_t _SPIFFS_start;
|
||||
extern "C" uint32_t _SPIFFS_end;
|
||||
extern "C" uint32_t _SPIFFS_page;
|
||||
extern "C" uint32_t _SPIFFS_block;
|
||||
|
||||
static s32_t api_spiffs_read(u32_t addr, u32_t size, u8_t *dst);
|
||||
static s32_t api_spiffs_write(u32_t addr, u32_t size, u8_t *src);
|
||||
static s32_t api_spiffs_erase(u32_t addr, u32_t size);
|
||||
|
||||
FSClass FS((uint32_t) &_SPIFFS_start, (uint32_t) &_SPIFFS_end, (uint32_t) &_SPIFFS_page, (uint32_t) &_SPIFFS_block, 4);
|
||||
|
||||
FSClass::FSClass(uint32_t beginAddress, uint32_t endAddress, uint32_t pageSize, uint32_t blockSize, uint32_t maxOpenFiles)
|
||||
: _beginAddress(beginAddress)
|
||||
, _endAddress(endAddress)
|
||||
, _pageSize(pageSize)
|
||||
, _blockSize(blockSize)
|
||||
, _maxOpenFiles(maxOpenFiles)
|
||||
, _fs({0})
|
||||
{
|
||||
}
|
||||
|
||||
int FSClass::_mountInternal(){
|
||||
if (_beginAddress == 0 || _beginAddress >= _endAddress){
|
||||
SPIFFS_API_DBG_E("Can't start file system, wrong address\r\n");
|
||||
return SPIFFS_ERR_NOT_CONFIGURED;
|
||||
}
|
||||
if(_pageSize == 0) _pageSize = 256;
|
||||
if(_blockSize == 0) _blockSize = 4096;
|
||||
|
||||
spiffs_config cfg = {0};
|
||||
cfg.phys_addr = _beginAddress;
|
||||
cfg.phys_size = _endAddress - _beginAddress;
|
||||
cfg.phys_erase_block = INTERNAL_FLASH_SECTOR_SIZE;
|
||||
cfg.log_block_size = _blockSize;
|
||||
cfg.log_page_size = _pageSize;
|
||||
cfg.hal_read_f = api_spiffs_read;
|
||||
cfg.hal_write_f = api_spiffs_write;
|
||||
cfg.hal_erase_f = api_spiffs_erase;
|
||||
|
||||
SPIFFS_API_DBG_V("FSClass::_mountInternal: start:%x, size:%d Kb\n", cfg.phys_addr, cfg.phys_size / 1024);
|
||||
|
||||
_work.reset(new uint8_t[2*_pageSize]);
|
||||
_fdsSize = 32 * _maxOpenFiles;
|
||||
_fds.reset(new uint8_t[_fdsSize]);
|
||||
_cacheSize = (32 + _pageSize) * _maxOpenFiles;
|
||||
_cache.reset(new uint8_t[_cacheSize]);
|
||||
|
||||
s32_t res = SPIFFS_mount(&_fs,
|
||||
&cfg,
|
||||
_work.get(),
|
||||
_fds.get(),
|
||||
_fdsSize,
|
||||
_cache.get(),
|
||||
_cacheSize,
|
||||
NULL);
|
||||
SPIFFS_API_DBG_V("FSClass::_mountInternal: %d\n", res);
|
||||
return res;
|
||||
}
|
||||
|
||||
bool FSClass::mount() {
|
||||
if(SPIFFS_mounted(&_fs))
|
||||
return true;
|
||||
|
||||
int res = _mountInternal();
|
||||
if(res != SPIFFS_OK){
|
||||
int formated = SPIFFS_format(&_fs);
|
||||
if(formated != SPIFFS_OK)
|
||||
return false;
|
||||
res = _mountInternal();
|
||||
}
|
||||
return (res == SPIFFS_OK);
|
||||
}
|
||||
|
||||
// TODO: need to invalidate open file objects
|
||||
void FSClass::unmount() {
|
||||
if(SPIFFS_mounted(&_fs))
|
||||
SPIFFS_unmount(&_fs);
|
||||
}
|
||||
|
||||
bool FSClass::format() {
|
||||
if(!SPIFFS_mounted(&_fs)){
|
||||
_mountInternal();
|
||||
}
|
||||
SPIFFS_unmount(&_fs);
|
||||
int formated = SPIFFS_format(&_fs);
|
||||
if(formated != SPIFFS_OK)
|
||||
return false;
|
||||
return (_mountInternal() == SPIFFS_OK);
|
||||
}
|
||||
|
||||
bool FSClass::check() {
|
||||
return SPIFFS_check(&_fs) == SPIFFS_OK;
|
||||
}
|
||||
|
||||
bool FSClass::exists(char *filename) {
|
||||
spiffs_stat stat = {0};
|
||||
if (SPIFFS_stat(&_fs, filename, &stat) < 0)
|
||||
return false;
|
||||
return stat.name[0] != '\0';
|
||||
}
|
||||
|
||||
bool FSClass::create(char *filepath){
|
||||
return SPIFFS_creat(&_fs, filepath, 0) == SPIFFS_OK;
|
||||
}
|
||||
|
||||
bool FSClass::remove(char *filepath){
|
||||
return SPIFFS_remove(&_fs, filepath) == SPIFFS_OK;
|
||||
}
|
||||
|
||||
bool FSClass::rename(char *filename, char *newname) {
|
||||
return SPIFFS_rename(&_fs, filename, newname) == SPIFFS_OK;
|
||||
}
|
||||
|
||||
size_t FSClass::totalBytes(){
|
||||
u32_t totalBytes;
|
||||
u32_t usedBytes;
|
||||
if(SPIFFS_info(&_fs, &totalBytes, &usedBytes) == SPIFFS_OK)
|
||||
return totalBytes;
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t FSClass::usedBytes(){
|
||||
u32_t totalBytes;
|
||||
u32_t usedBytes;
|
||||
if(SPIFFS_info(&_fs, &totalBytes, &usedBytes) == SPIFFS_OK)
|
||||
return usedBytes;
|
||||
return 0;
|
||||
}
|
||||
|
||||
FSFile FSClass::open(char *filename, uint8_t mode) {
|
||||
if(strcmp(filename, "") == 0 ||
|
||||
strcmp(filename, "/") == 0)
|
||||
return FSFile(&_fs, "/");
|
||||
|
||||
int repeats = 0;
|
||||
bool notExist;
|
||||
bool canRecreate = (mode & SPIFFS_CREAT) == SPIFFS_CREAT;
|
||||
int res;
|
||||
|
||||
do{
|
||||
notExist = false;
|
||||
res = SPIFFS_open(&_fs, filename, (spiffs_flags)mode, 0);
|
||||
int code = SPIFFS_errno(&_fs);
|
||||
if (res < 0){
|
||||
SPIFFS_API_DBG_E("open errno %d\n", code);
|
||||
notExist = (code == SPIFFS_ERR_NOT_FOUND || code == SPIFFS_ERR_DELETED || code == SPIFFS_ERR_FILE_DELETED || code == SPIFFS_ERR_IS_FREE);
|
||||
if (notExist && canRecreate)
|
||||
remove(filename); // fix for deleted files
|
||||
}
|
||||
} while (notExist && canRecreate && repeats++ < 3);
|
||||
|
||||
if(res){
|
||||
return FSFile(&_fs, res);
|
||||
}
|
||||
return FSFile();
|
||||
}
|
||||
|
||||
FSFile FSClass::open(spiffs_dirent* entry, uint8_t mode){
|
||||
int res = SPIFFS_open_by_dirent(&_fs, entry, (spiffs_flags)mode, 0);
|
||||
if (res){
|
||||
return FSFile(&_fs, res);
|
||||
}
|
||||
return FSFile();
|
||||
}
|
||||
|
||||
FSFile::FSFile()
|
||||
: _file(0)
|
||||
, _stats({0})
|
||||
, _fs(0)
|
||||
{
|
||||
}
|
||||
|
||||
FSFile::FSFile(spiffs* fs, String path)
|
||||
: _fs(fs)
|
||||
{
|
||||
if(path == "/"){
|
||||
_file = 0x1;
|
||||
os_sprintf((char*)_stats.name, "%s", (char*)path.c_str());
|
||||
_stats.size = 0;
|
||||
_stats.type = SPIFFS_TYPE_DIR;
|
||||
SPIFFS_opendir(_fs, (char*)_stats.name, &_dir);
|
||||
} else {
|
||||
_file = SPIFFS_open(_fs, (char *)path.c_str(), (spiffs_flags)FSFILE_READ, 0);
|
||||
if(SPIFFS_fstat(_fs, _file, &_stats) != 0){
|
||||
SPIFFS_API_DBG_E("fstat errno %d\n", SPIFFS_errno(_fs));
|
||||
}
|
||||
//debugf("FSFile name: %s, size: %d, type: %d\n", _stats.name, _stats.size, _stats.type);
|
||||
if(_stats.type == SPIFFS_TYPE_DIR){
|
||||
SPIFFS_opendir(_fs, (char*)_stats.name, &_dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FSFile::FSFile(spiffs* fs, file_t f)
|
||||
: _file(f)
|
||||
, _fs(fs)
|
||||
{
|
||||
if(SPIFFS_fstat(_fs, _file, &_stats) != 0){
|
||||
SPIFFS_API_DBG_E("fstat errno %d\n", SPIFFS_errno(_fs));
|
||||
}
|
||||
//debugf("FSFile name: %s, size: %d, type: %d\n", _stats.name, _stats.size, _stats.type);
|
||||
if(_stats.type == SPIFFS_TYPE_DIR){
|
||||
SPIFFS_opendir(_fs, (char*)_stats.name, &_dir);
|
||||
}
|
||||
}
|
||||
|
||||
void FSFile::close() {
|
||||
if (!_file)
|
||||
return;
|
||||
if(_stats.type == SPIFFS_TYPE_DIR){
|
||||
SPIFFS_closedir(&_dir);
|
||||
}
|
||||
if(os_strlen((char*)_stats.name) > 1)
|
||||
SPIFFS_close(_fs, _file);
|
||||
_file = 0;
|
||||
}
|
||||
|
||||
char * FSFile::name(){
|
||||
return (char*)_stats.name;
|
||||
}
|
||||
|
||||
bool FSFile::isDirectory(void) {
|
||||
return _stats.type == SPIFFS_TYPE_DIR;
|
||||
}
|
||||
|
||||
void FSFile::rewindDirectory() {
|
||||
if (!_file || !isDirectory())
|
||||
return;
|
||||
SPIFFS_closedir(&_dir);
|
||||
SPIFFS_opendir(_fs, (char*)_stats.name, &_dir);
|
||||
}
|
||||
|
||||
FSFile FSFile::openNextFile(){
|
||||
if (!_file || !isDirectory())
|
||||
return FSFile();
|
||||
struct spiffs_dirent e;
|
||||
struct spiffs_dirent *pe = &e;
|
||||
if ((pe = SPIFFS_readdir(&_dir, pe))){
|
||||
// TODO: store actual FS pointer
|
||||
return FS.open((char *)pe->name);
|
||||
}
|
||||
return FSFile();
|
||||
}
|
||||
|
||||
uint32_t FSFile::size() {
|
||||
if(!_file)
|
||||
return 0;
|
||||
if(_stats.size)
|
||||
return _stats.size;
|
||||
uint32_t pos = SPIFFS_tell(_fs, _file);
|
||||
SPIFFS_lseek(_fs, _file, 0, SPIFFS_SEEK_END);
|
||||
_stats.size = SPIFFS_tell(_fs, _file);
|
||||
SPIFFS_lseek(_fs, _file, pos, SPIFFS_SEEK_SET);
|
||||
return _stats.size;
|
||||
}
|
||||
|
||||
int FSFile::available() {
|
||||
if (!_file)
|
||||
return 0;
|
||||
uint32_t pos = SPIFFS_tell(_fs, _file);
|
||||
return size() - pos;
|
||||
}
|
||||
|
||||
uint32_t FSFile::seek(uint32_t pos) {
|
||||
if (!_file)
|
||||
return 0;
|
||||
return SPIFFS_lseek(_fs, _file, pos, SPIFFS_SEEK_SET);
|
||||
}
|
||||
|
||||
uint32_t FSFile::position() {
|
||||
if (!_file)
|
||||
return 0;
|
||||
return SPIFFS_tell(_fs, _file);
|
||||
}
|
||||
|
||||
bool FSFile::eof() {
|
||||
if (!_file)
|
||||
return 0;
|
||||
return SPIFFS_eof(_fs, _file);
|
||||
}
|
||||
|
||||
int FSFile::read(void *buf, uint16_t nbyte) {
|
||||
if (!_file || isDirectory())
|
||||
return -1;
|
||||
return SPIFFS_read(_fs, _file, buf, nbyte);
|
||||
}
|
||||
|
||||
int FSFile::read() {
|
||||
if (! _file || isDirectory())
|
||||
return -1;
|
||||
int val;
|
||||
if(SPIFFS_read(_fs, _file, &val, 1) != 1) return -1;
|
||||
return val;
|
||||
}
|
||||
|
||||
int FSFile::peek() {
|
||||
if (!_file || isDirectory())
|
||||
return 0;
|
||||
int c = read();
|
||||
SPIFFS_lseek(_fs, _file, -1, SPIFFS_SEEK_CUR);
|
||||
return c;
|
||||
}
|
||||
|
||||
size_t FSFile::write(const uint8_t *buf, size_t size){
|
||||
if (!_file || isDirectory())
|
||||
return 0;
|
||||
int res = SPIFFS_write(_fs, _file, (uint8_t *)buf, size);
|
||||
return (res > 0)?(size_t)res:0;
|
||||
}
|
||||
|
||||
size_t FSFile::write(uint8_t val) {
|
||||
if (!_file || isDirectory())
|
||||
return 0;
|
||||
return write(&val, 1);
|
||||
}
|
||||
|
||||
void FSFile::flush(){
|
||||
if (!_file || isDirectory())
|
||||
return;
|
||||
SPIFFS_fflush(_fs, _file);
|
||||
}
|
||||
|
||||
bool FSFile::remove(){
|
||||
if (!_file)
|
||||
return 0;
|
||||
close();
|
||||
return SPIFFS_remove(_fs, (char *)_stats.name) == 0;
|
||||
}
|
||||
|
||||
int FSFile::lastError(){
|
||||
return SPIFFS_errno(_fs);
|
||||
}
|
||||
|
||||
void FSFile::clearError(){
|
||||
_fs->err_code = SPIFFS_OK;
|
||||
}
|
||||
|
||||
|
||||
static s32_t api_spiffs_read(u32_t addr, u32_t size, u8_t *dst){
|
||||
SPIFFS_API_DBG_V("api_spiffs_read: 0x%08x len: %u\n", addr, size);
|
||||
flashmem_read(dst, addr, size);
|
||||
return SPIFFS_OK;
|
||||
}
|
||||
|
||||
static s32_t api_spiffs_write(u32_t addr, u32_t size, u8_t *src){
|
||||
SPIFFS_API_DBG_V("api_spiffs_write: 0x%08x len: %u\n", addr, size);
|
||||
flashmem_write(src, addr, size);
|
||||
return SPIFFS_OK;
|
||||
}
|
||||
|
||||
static s32_t api_spiffs_erase(u32_t addr, u32_t size){
|
||||
SPIFFS_API_DBG_V("api_spiffs_erase: 0x%08x len: %u\n", addr, size);
|
||||
u32_t sect_first = flashmem_get_sector_of_address(addr);
|
||||
u32_t sect_last = flashmem_get_sector_of_address(addr+size);
|
||||
while( sect_first <= sect_last )
|
||||
if( !flashmem_erase_sector( sect_first ++ ) )
|
||||
return SPIFFS_ERR_INTERNAL;
|
||||
return SPIFFS_OK;
|
||||
}
|
||||
|
||||
|
@ -1,132 +0,0 @@
|
||||
/*
|
||||
FileSystem.h - SPIFS implementation for esp8266
|
||||
|
||||
Copyright (c) 2015 Hristo Gochkov. All rights reserved.
|
||||
This file is part of the esp8266 core for Arduino environment.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#ifndef _SPIFFS_CORE_FILESYSTEM_H_
|
||||
#define _SPIFFS_CORE_FILESYSTEM_H_
|
||||
|
||||
#include <memory>
|
||||
#include "spiffs/spiffs.h"
|
||||
#include "Arduino.h"
|
||||
|
||||
#define FSFILE_READ SPIFFS_RDONLY
|
||||
#define FSFILE_WRITE (SPIFFS_RDONLY | SPIFFS_WRONLY | SPIFFS_CREAT | SPIFFS_APPEND )
|
||||
#define FSFILE_OVERWRITE (SPIFFS_RDONLY | SPIFFS_WRONLY | SPIFFS_CREAT | SPIFFS_APPEND | SPIFFS_TRUNC )
|
||||
|
||||
class FSFile : public Stream {
|
||||
private:
|
||||
spiffs_stat _stats;
|
||||
file_t _file;
|
||||
spiffs_DIR _dir;
|
||||
spiffs * _fs;
|
||||
|
||||
public:
|
||||
FSFile(spiffs* fs, String path);
|
||||
FSFile(spiffs* fs, file_t f);
|
||||
FSFile(void);
|
||||
virtual size_t write(uint8_t);
|
||||
virtual size_t write(const uint8_t *buf, size_t size);
|
||||
virtual int read();
|
||||
virtual int peek();
|
||||
virtual int available();
|
||||
virtual void flush();
|
||||
int read(void *buf, uint16_t nbyte);
|
||||
uint32_t seek(uint32_t pos);
|
||||
uint32_t position();
|
||||
uint32_t size();
|
||||
bool eof();
|
||||
void close();
|
||||
bool remove();
|
||||
int lastError();
|
||||
void clearError();
|
||||
operator bool() { return _file > 0; }
|
||||
char * name();
|
||||
bool isDirectory(void);
|
||||
void rewindDirectory(void);
|
||||
FSFile openNextFile(void);
|
||||
|
||||
template<typename T> size_t write(T &src){
|
||||
const size_t bufferSize = 64;
|
||||
uint8_t obuf[bufferSize];
|
||||
size_t bytesWritten = 0;
|
||||
while (true){
|
||||
size_t available = src.available();
|
||||
if(!available)
|
||||
return bytesWritten;
|
||||
size_t willWrite = (available < bufferSize) ? available : bufferSize;
|
||||
src.read(obuf, willWrite);
|
||||
size_t cb = write(obuf, willWrite);
|
||||
if (cb != willWrite) {
|
||||
return bytesWritten;
|
||||
}
|
||||
bytesWritten += cb;
|
||||
}
|
||||
return bytesWritten;
|
||||
}
|
||||
|
||||
using Print::write;
|
||||
};
|
||||
|
||||
class FSClass {
|
||||
public:
|
||||
FSClass(uint32_t beginAddress, uint32_t endAddress, uint32_t pageSize, uint32_t blockSize, uint32_t maxOpenFiles);
|
||||
|
||||
bool mount();
|
||||
void unmount();
|
||||
bool format();
|
||||
bool check();
|
||||
bool exists(char *filename);
|
||||
bool create(char *filepath);
|
||||
bool remove(char *filepath);
|
||||
bool rename(char *filename, char *newname);
|
||||
size_t totalBytes();
|
||||
size_t usedBytes();
|
||||
size_t size(){ return _fs.cfg.phys_size; }
|
||||
size_t blockSize(){ return _fs.cfg.log_block_size; }
|
||||
size_t totalBlocks(){ return _fs.block_count; }
|
||||
size_t freeBlocks(){ return _fs.free_blocks; }
|
||||
size_t pageSize(){ return _fs.cfg.log_page_size; }
|
||||
size_t allocatedPages(){ return _fs.stats_p_allocated; }
|
||||
size_t deletedPages(){ return _fs.stats_p_deleted; }
|
||||
|
||||
FSFile open(char *filename, uint8_t mode = FSFILE_READ);
|
||||
FSFile open(spiffs_dirent* entry, uint8_t mode = FSFILE_READ);
|
||||
|
||||
protected:
|
||||
int _mountInternal();
|
||||
std::unique_ptr<uint8_t[]> _work;
|
||||
std::unique_ptr<uint8_t[]> _fds;
|
||||
size_t _fdsSize;
|
||||
std::unique_ptr<uint8_t[]> _cache;
|
||||
size_t _cacheSize;
|
||||
uint32_t _beginAddress;
|
||||
uint32_t _endAddress;
|
||||
uint32_t _pageSize;
|
||||
uint32_t _blockSize;
|
||||
uint32_t _maxOpenFiles;
|
||||
spiffs _fs;
|
||||
|
||||
|
||||
private:
|
||||
friend class FSFile;
|
||||
};
|
||||
|
||||
extern FSClass FS;
|
||||
|
||||
#endif
|
@ -116,6 +116,12 @@ void init_done() {
|
||||
esp_schedule();
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
void user_rf_pre_init() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
void user_init(void) {
|
||||
uart_div_modify(0, UART_CLK_FREQ / (115200));
|
||||
|
@ -25,6 +25,8 @@
|
||||
#include "eagle_soc.h"
|
||||
#include "ets_sys.h"
|
||||
|
||||
uint8_t esp8266_gpioToFn[16] = {0x34, 0x18, 0x38, 0x14, 0x3C, 0x40, 0x1C, 0x20, 0x24, 0x28, 0x2C, 0x30, 0x04, 0x08, 0x0C, 0x10};
|
||||
|
||||
extern void __pinMode(uint8_t pin, uint8_t mode) {
|
||||
if(pin < 16){
|
||||
if(mode == SPECIAL){
|
||||
|
@ -68,7 +68,7 @@
|
||||
#define GPCD 2 //DRIVER 0:normal,1:open drain
|
||||
#define GPCS 0 //SOURCE 0:GPIO_DATA,1:SigmaDelta
|
||||
|
||||
static uint8_t esp8266_gpioToFn[16] = {0x34, 0x18, 0x38, 0x14, 0x3C, 0x40, 0x1C, 0x20, 0x24, 0x28, 0x2C, 0x30, 0x04, 0x08, 0x0C, 0x10};
|
||||
extern uint8_t esp8266_gpioToFn[16];
|
||||
#define GPF(p) ESP8266_REG(0x800 + esp8266_gpioToFn[(p & 0xF)])
|
||||
|
||||
#define GPMUX ESP8266_REG(0x800)
|
||||
|
@ -511,7 +511,6 @@ u32_t SPIFFS_buffer_bytes_for_cache(spiffs *fs, u32_t num_pages);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "spiffs_esp8266.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -1,164 +0,0 @@
|
||||
/****
|
||||
* Sming Framework Project - Open Source framework for high efficiency native ESP8266 development.
|
||||
* Created 2015 by Skurydin Alexey
|
||||
* http://github.com/anakod/Sming
|
||||
* All files of the Sming Core are provided under the LGPL v3 license.
|
||||
****/
|
||||
|
||||
#include "spiffs_esp8266.h"
|
||||
#include "spi_flash.h"
|
||||
#include "esp8266_peri.h"
|
||||
#include "Arduino.h"
|
||||
|
||||
/*
|
||||
FLASH ACCESS FUNCTIONS
|
||||
*/
|
||||
|
||||
//lowest level sector erase method
|
||||
bool flashmem_erase_sector( uint32_t sector_id ){
|
||||
WDT_RESET();
|
||||
noInterrupts();
|
||||
uint32_t chip_size = flashchip->chip_size;
|
||||
flashchip->chip_size = 0x01000000;
|
||||
bool erased = spi_flash_erase_sector( sector_id ) == SPI_FLASH_RESULT_OK;
|
||||
flashchip->chip_size = chip_size;
|
||||
interrupts();
|
||||
return erased;
|
||||
}
|
||||
|
||||
//lowest level data write method
|
||||
uint32_t flashmem_write_internal( const void *from, uint32_t toaddr, uint32_t size ){
|
||||
toaddr -= INTERNAL_FLASH_START_ADDRESS;
|
||||
SpiFlashOpResult r;
|
||||
const uint32_t blkmask = INTERNAL_FLASH_WRITE_UNIT_SIZE - 1;
|
||||
uint32_t *apbuf = NULL;
|
||||
if(((uint32_t)from) & blkmask){
|
||||
apbuf = (uint32_t *)os_malloc(size);
|
||||
if(!apbuf)
|
||||
return 0;
|
||||
os_memcpy(apbuf, from, size);
|
||||
}
|
||||
WDT_RESET();
|
||||
noInterrupts();
|
||||
uint32_t chip_size = flashchip->chip_size;
|
||||
flashchip->chip_size = 0x01000000;
|
||||
r = spi_flash_write(toaddr, apbuf?(uint32 *)apbuf:(uint32 *)from, size);
|
||||
flashchip->chip_size = chip_size;
|
||||
interrupts();
|
||||
if(apbuf)
|
||||
os_free(apbuf);
|
||||
if(SPI_FLASH_RESULT_OK == r)
|
||||
return size;
|
||||
else{
|
||||
SPIFFS_API_DBG_E( "ERROR in flash_write: r=%d at %08X\n", ( int )r, ( unsigned )toaddr+INTERNAL_FLASH_START_ADDRESS );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
//lowest level data read method
|
||||
uint32_t flashmem_read_internal( void *to, uint32_t fromaddr, uint32_t size ){
|
||||
fromaddr -= INTERNAL_FLASH_START_ADDRESS;
|
||||
SpiFlashOpResult r;
|
||||
WDT_RESET();
|
||||
noInterrupts();
|
||||
uint32_t chip_size = flashchip->chip_size;
|
||||
flashchip->chip_size = 0x01000000;
|
||||
r = spi_flash_read(fromaddr, (uint32 *)to, size);
|
||||
flashchip->chip_size = chip_size;
|
||||
interrupts();
|
||||
if(SPI_FLASH_RESULT_OK == r)
|
||||
return size;
|
||||
else{
|
||||
SPIFFS_API_DBG_E( "ERROR in flash_read: r=%d at %08X\n", ( int )r, ( unsigned )fromaddr+INTERNAL_FLASH_START_ADDRESS );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
//mid level data write method
|
||||
uint32_t flashmem_write( const void *from, uint32_t toaddr, uint32_t size ){
|
||||
uint32_t temp, rest, ssize = size;
|
||||
unsigned i;
|
||||
char tmpdata[ INTERNAL_FLASH_WRITE_UNIT_SIZE ];
|
||||
const uint8_t *pfrom = ( const uint8_t* )from;
|
||||
const uint32_t blksize = INTERNAL_FLASH_WRITE_UNIT_SIZE;
|
||||
const uint32_t blkmask = INTERNAL_FLASH_WRITE_UNIT_SIZE - 1;
|
||||
|
||||
// Align the start
|
||||
if(toaddr & blkmask){
|
||||
rest = toaddr & blkmask;
|
||||
temp = toaddr & ~blkmask; // this is the actual aligned address
|
||||
// c_memcpy( tmpdata, ( const void* )temp, blksize );
|
||||
flashmem_read_internal( tmpdata, temp, blksize );
|
||||
for( i = rest; size && ( i < blksize ); i ++, size --, pfrom ++ )
|
||||
tmpdata[ i ] = *pfrom;
|
||||
flashmem_write_internal( tmpdata, temp, blksize );
|
||||
if( size == 0 )
|
||||
return ssize;
|
||||
toaddr = temp + blksize;
|
||||
}
|
||||
// The start address is now a multiple of blksize
|
||||
// Compute how many bytes we can write as multiples of blksize
|
||||
rest = size & blkmask;
|
||||
temp = size & ~blkmask;
|
||||
// Program the blocks now
|
||||
if(temp){
|
||||
flashmem_write_internal( pfrom, toaddr, temp );
|
||||
toaddr += temp;
|
||||
pfrom += temp;
|
||||
}
|
||||
// And the final part of a block if needed
|
||||
if(rest){
|
||||
// c_memcpy( tmpdata, ( const void* )toaddr, blksize );
|
||||
flashmem_read_internal( tmpdata, toaddr, blksize );
|
||||
for( i = 0; size && ( i < rest ); i ++, size --, pfrom ++ )
|
||||
tmpdata[ i ] = *pfrom;
|
||||
flashmem_write_internal( tmpdata, toaddr, blksize );
|
||||
}
|
||||
return ssize;
|
||||
}
|
||||
|
||||
//mid level data write method
|
||||
uint32_t flashmem_read( void *to, uint32_t fromaddr, uint32_t size ){
|
||||
uint32_t temp, rest, ssize = size;
|
||||
unsigned i;
|
||||
char tmpdata[ INTERNAL_FLASH_READ_UNIT_SIZE ];
|
||||
uint8_t *pto = ( uint8_t* )to;
|
||||
const uint32_t blksize = INTERNAL_FLASH_READ_UNIT_SIZE;
|
||||
const uint32_t blkmask = INTERNAL_FLASH_READ_UNIT_SIZE - 1;
|
||||
|
||||
// Align the start
|
||||
if(fromaddr & blkmask){
|
||||
rest = fromaddr & blkmask;
|
||||
temp = fromaddr & ~blkmask; // this is the actual aligned address
|
||||
flashmem_read_internal( tmpdata, temp, blksize );
|
||||
for( i = rest; size && ( i < blksize ); i ++, size --, pto ++ )
|
||||
*pto = tmpdata[ i ];
|
||||
|
||||
if( size == 0 )
|
||||
return ssize;
|
||||
fromaddr = temp + blksize;
|
||||
}
|
||||
// The start address is now a multiple of blksize
|
||||
// Compute how many bytes we can read as multiples of blksize
|
||||
rest = size & blkmask;
|
||||
temp = size & ~blkmask;
|
||||
// Program the blocks now
|
||||
if(temp){
|
||||
flashmem_read_internal( pto, fromaddr, temp );
|
||||
fromaddr += temp;
|
||||
pto += temp;
|
||||
}
|
||||
// And the final part of a block if needed
|
||||
if(rest){
|
||||
flashmem_read_internal( tmpdata, fromaddr, blksize );
|
||||
for( i = 0; size && ( i < rest ); i ++, size --, pto ++ )
|
||||
*pto = tmpdata[ i ];
|
||||
}
|
||||
return ssize;
|
||||
}
|
||||
|
||||
//shorthand when start and end addresses of the sector are not needed
|
||||
uint32_t flashmem_get_sector_of_address( uint32_t addr ){
|
||||
return (addr - INTERNAL_FLASH_START_ADDRESS) / INTERNAL_FLASH_SECTOR_SIZE;
|
||||
}
|
||||
|
@ -1,42 +0,0 @@
|
||||
/****
|
||||
* Sming Framework Project - Open Source framework for high efficiency native ESP8266 development.
|
||||
* Created 2015 by Skurydin Alexey
|
||||
* http://github.com/anakod/Sming
|
||||
* All files of the Sming Core are provided under the LGPL v3 license.
|
||||
****/
|
||||
|
||||
#ifndef SYSTEM_FLASHMEM_H_
|
||||
#define SYSTEM_FLASHMEM_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "spiffs.h"
|
||||
|
||||
/*******************
|
||||
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.
|
||||
********************/
|
||||
|
||||
#define SPIFFS_API_DBG_V(fmt, ...) //os_printf(fmt, ##__VA_ARGS__)
|
||||
#define SPIFFS_API_DBG_E(fmt, ...) //os_printf("ERROR: " fmt , ##__VA_ARGS__)
|
||||
|
||||
#define INTERNAL_FLASH_SECTOR_SIZE 4096
|
||||
#define INTERNAL_FLASH_START_ADDRESS 0x40200000
|
||||
|
||||
#define INTERNAL_FLASH_WRITE_UNIT_SIZE 4
|
||||
#define INTERNAL_FLASH_READ_UNIT_SIZE 4
|
||||
|
||||
extern uint32_t flashmem_write( const void *from, uint32_t toaddr, uint32_t size );
|
||||
extern uint32_t flashmem_read( void *to, uint32_t fromaddr, uint32_t size );
|
||||
extern bool flashmem_erase_sector( uint32_t sector_id );
|
||||
uint32_t flashmem_get_sector_of_address( uint32_t addr );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SYSTEM_FLASHMEM_H_ */
|
Reference in New Issue
Block a user