1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-06-07 16:23:38 +03:00

Merge branch 'esp8266' of https://github.com/ficeto/Arduino into ficeto-esp8266

This commit is contained in:
Ivan Grokhotkov 2015-05-14 13:34:31 +03:00
commit dea91ca620
18 changed files with 718 additions and 329 deletions

View File

@ -214,6 +214,7 @@ void loop(void);
#include "HardwareSerial.h" #include "HardwareSerial.h"
#include "FileSystem.h" #include "FileSystem.h"
#include "Esp.h" #include "Esp.h"
#include "debug.h"
uint16_t makeWord(uint16_t w); uint16_t makeWord(uint16_t w);
uint16_t makeWord(byte h, byte l); uint16_t makeWord(byte h, byte l);
@ -231,6 +232,7 @@ long random(long, long);
void randomSeed(unsigned int); void randomSeed(unsigned int);
long map(long, long, long, long, long); long map(long, long, long, long, long);
#endif #endif
#include "pins_arduino.h" #include "pins_arduino.h"

View File

@ -1,178 +1,208 @@
/**** /*
* Sming Framework Project - Open Source framework for high efficiency native ESP8266 development. FileSystem.cpp - SPIFS implementation for esp8266
* Created 2015 by Skurydin Alexey
* http://github.com/anakod/Sming
* All files of the Sming Core are provided under the LGPL v3 license.
****/
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 "FileSystem.h"
#include "WString.h" #include "Arduino.h"
file_t fileOpen(const String name, FileOpenFlags flags) boolean FSClass::mount(){
{ if(_mounted) return true;
int repeats = 0; _mounted = spiffs_mount();
bool notExist; return _mounted;
bool canRecreate = (flags & eFO_CreateIfNotExist) == eFO_CreateIfNotExist;
int res;
do
{
notExist = false;
res = SPIFFS_open(&_filesystemStorageHandle, name.c_str(), (spiffs_flags)flags, 0);
int code = SPIFFS_errno(&_filesystemStorageHandle);
if (res < 0)
{
debugf("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);
//debugf("recreate? %d %d %d", notExist, canRecreate, (repeats < 3));
if (notExist && canRecreate)
fileDelete(name); // fix for deleted files
}
} while (notExist && canRecreate && repeats++ < 3);
return res;
} }
void fileClose(file_t file) void FSClass::unmount(){
{ if(!_mounted) return;
SPIFFS_close(&_filesystemStorageHandle, file); spiffs_unmount();
_mounted = false;
} }
size_t fileWrite(file_t file, const void* data, size_t size) boolean FSClass::format(){
{ return spiffs_format();
int res = SPIFFS_write(&_filesystemStorageHandle, file, (void *)data, size);
if (res < 0)
{
debugf("write errno %d\n", SPIFFS_errno(&_filesystemStorageHandle));
return res;
}
return res;
} }
size_t fileRead(file_t file, void* data, size_t size) boolean FSClass::exists(const char *filename){
{
int res = SPIFFS_read(&_filesystemStorageHandle, file, data, size);
if (res < 0)
{
debugf("read errno %d\n", SPIFFS_errno(&_filesystemStorageHandle));
return res;
}
return res;
}
int fileSeek(file_t file, int offset, SeekOriginFlags origin)
{
return SPIFFS_lseek(&_filesystemStorageHandle, file, offset, origin);
}
bool fileIsEOF(file_t file)
{
return SPIFFS_eof(&_filesystemStorageHandle, file);
}
int32_t fileTell(file_t file)
{
return SPIFFS_tell(&_filesystemStorageHandle, file);
}
int fileFlush(file_t file)
{
return SPIFFS_fflush(&_filesystemStorageHandle, file);
}
int fileStats(const String name, spiffs_stat *stat)
{
return SPIFFS_stat(&_filesystemStorageHandle, name.c_str(), stat);
}
int fileStats(file_t file, spiffs_stat *stat)
{
return SPIFFS_fstat(&_filesystemStorageHandle, file, stat);
}
void fileDelete(const String name)
{
SPIFFS_remove(&_filesystemStorageHandle, name.c_str());
}
void fileDelete(file_t file)
{
SPIFFS_fremove(&_filesystemStorageHandle, file);
}
bool fileExist(const String name)
{
spiffs_stat stat = {0}; spiffs_stat stat = {0};
if (fileStats(name.c_str(), &stat) < 0) return false; if (SPIFFS_stat(&_filesystemStorageHandle, filename, &stat) < 0) return false;
return stat.name[0] != '\0'; return stat.name[0] != '\0';
} }
boolean FSClass::create(const char *filepath){
return SPIFFS_creat(&_filesystemStorageHandle, filepath, 0) == 0;
}
int fileLastError(file_t fd) boolean FSClass::remove(const char *filepath){
{ return SPIFFS_remove(&_filesystemStorageHandle, filepath) == 0;
}
boolean FSClass::rename(const char *filename, const char *newname){
return SPIFFS_rename(&_filesystemStorageHandle, filename, newname) == 0;
}
FSFile FSClass::open(const char *filename, uint8_t mode){
int repeats = 0;
bool notExist;
bool canRecreate = (mode & SPIFFS_CREAT) == SPIFFS_CREAT;
int res;
do{
notExist = false;
res = SPIFFS_open(&_filesystemStorageHandle, filename, (spiffs_flags)mode, 0);
int code = SPIFFS_errno(&_filesystemStorageHandle);
if (res < 0){
debugf("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(res);
}
return FSFile();
}
FSClass FS;
FSFile::FSFile(){
_file = 0;
_stats = {0};
}
FSFile::FSFile(file_t f){
_file = f;
if(SPIFFS_fstat(&_filesystemStorageHandle, _file, &_stats) != 0){
debugf("mount errno %d\n", SPIFFS_errno(&_filesystemStorageHandle));
}
}
void FSFile::close(){
if (! _file) return;
SPIFFS_close(&_filesystemStorageHandle, _file);
_file = 0;
}
uint32_t FSFile::size(){
if(! _file) return 0;
uint32_t pos = SPIFFS_tell(&_filesystemStorageHandle, _file);
SPIFFS_lseek(&_filesystemStorageHandle, _file, 0, SPIFFS_SEEK_END);
uint32_t size = SPIFFS_tell(&_filesystemStorageHandle, _file);
SPIFFS_lseek(&_filesystemStorageHandle, _file, pos, SPIFFS_SEEK_SET);
return size;
}
uint32_t FSFile::seek(uint32_t pos){
if (! _file) return 0;
return SPIFFS_lseek(&_filesystemStorageHandle, _file, pos, SPIFFS_SEEK_SET);
}
uint32_t FSFile::position(){
if (! _file) return 0;
return SPIFFS_tell(&_filesystemStorageHandle, _file);
}
boolean FSFile::eof(){
if (! _file) return 0;
return SPIFFS_eof(&_filesystemStorageHandle, _file);
}
boolean FSFile::isDirectory(void){
return false;
}
int FSFile::read(void *buf, uint16_t nbyte){
if (! _file) return -1;
return SPIFFS_read(&_filesystemStorageHandle, _file, buf, nbyte);
}
int FSFile::read(){
if (! _file) return -1;
int val;
if(SPIFFS_read(&_filesystemStorageHandle, _file, &val, 1) != 1) return -1;
return val;
}
int FSFile::peek() {
if (! _file) return 0;
int c = read();
SPIFFS_lseek(&_filesystemStorageHandle, _file, -1, SPIFFS_SEEK_CUR);
return c;
}
int FSFile::available() {
if (! _file) return 0;
uint32_t pos = SPIFFS_tell(&_filesystemStorageHandle, _file);
SPIFFS_lseek(&_filesystemStorageHandle, _file, 0, SPIFFS_SEEK_END);
uint32_t size = SPIFFS_tell(&_filesystemStorageHandle, _file);
SPIFFS_lseek(&_filesystemStorageHandle, _file, pos, SPIFFS_SEEK_SET);
return size - pos;
}
size_t FSFile::write(const uint8_t *buf, size_t size){
if (! _file) return 0;
return SPIFFS_write(&_filesystemStorageHandle, _file, (uint8_t *)buf, size);
}
size_t FSFile::write(uint8_t val) {
if (! _file) return 0;
return write(&val, 1);
}
void FSFile::flush(){
if (! _file) return;
SPIFFS_fflush(&_filesystemStorageHandle, _file);
}
uint32_t FSFile::remove(){
if (! _file) return 0;
return SPIFFS_fremove(&_filesystemStorageHandle, _file);
_file = 0;
}
int FSFile::lastError(){
return SPIFFS_errno(&_filesystemStorageHandle); return SPIFFS_errno(&_filesystemStorageHandle);
} }
void fileClearLastError(file_t fd) void FSFile::clearError(){
{
_filesystemStorageHandle.errno = SPIFFS_OK; _filesystemStorageHandle.errno = SPIFFS_OK;
} }
void fileSetContent(const String fileName, const char *content) char * FSFile::name(){
{ return 0;
file_t file = fileOpen(fileName.c_str(), eFO_CreateNewAlways | eFO_WriteOnly);
fileWrite(file, content, os_strlen(content));
fileClose(file);
} }
uint32_t fileGetSize(const String fileName)
{
file_t file = fileOpen(fileName.c_str(), eFO_ReadOnly);
// Get size
fileSeek(file, 0, eSO_FileEnd);
int size = fileTell(file); /*
fileClose(file); spiffs_DIR *dirOpen(spiffs_DIR *d){
return size; return SPIFFS_opendir(&_filesystemStorageHandle, 0, d);
} }
String fileGetContent(const String fileName) int dirClose(spiffs_DIR *d){
{ return SPIFFS_closedir(d);
file_t file = fileOpen(fileName.c_str(), eFO_ReadOnly);
// Get size
fileSeek(file, 0, eSO_FileEnd);
int size = fileTell(file);
if (size <= 0)
{
fileClose(file);
return "";
}
fileSeek(file, 0, eSO_FileStart);
char* buffer = new char[size + 1];
buffer[size] = 0;
fileRead(file, buffer, size);
fileClose(file);
String res = buffer;
delete[] buffer;
return res;
} }
int fileGetContent(const String fileName, char* buffer, int bufSize) file_t dirOpenFile(spiffs_dirent* entry, uint8_t flags){
{ return SPIFFS_open_by_dirent(&_filesystemStorageHandle, entry, (spiffs_flags)flags, 0);
if (buffer == NULL || bufSize == 0) return 0;
*buffer = 0;
file_t file = fileOpen(fileName.c_str(), eFO_ReadOnly);
// Get size
fileSeek(file, 0, eSO_FileEnd);
int size = fileTell(file);
if (size <= 0 || bufSize <= size)
{
fileClose(file);
return 0;
}
buffer[size] = 0;
fileSeek(file, 0, eSO_FileStart);
fileRead(file, buffer, size);
fileClose(file);
return size;
} }
*/

View File

@ -1,59 +1,105 @@
/**** /*
* Sming Framework Project - Open Source framework for high efficiency native ESP8266 development. FileSystem.h - SPIFS implementation for esp8266
* Created 2015 by Skurydin Alexey
* http://github.com/anakod/Sming
* All files of the Sming Core are provided under the LGPL v3 license.
****/
#ifndef _SMING_CORE_FILESYSTEM_H_ Copyright (c) 2015 Hristo Gochkov. All rights reserved.
#define _SMING_CORE_FILESYSTEM_H_ 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 "spiffs/spiffs.h" #include "spiffs/spiffs.h"
#include "Arduino.h"
class String; class String;
enum FileOpenFlags #define FSFILE_READ SPIFFS_RDONLY
{ #define FSFILE_WRITE (SPIFFS_RDONLY | SPIFFS_WRONLY | SPIFFS_CREAT | SPIFFS_APPEND | SPIFFS_TRUNC)
eFO_ReadOnly = SPIFFS_RDONLY,
eFO_WriteOnly = SPIFFS_WRONLY, class FSFile : public Stream {
eFO_ReadWrite = eFO_ReadOnly | eFO_WriteOnly, private:
eFO_CreateIfNotExist = SPIFFS_CREAT, spiffs_stat _stats;
eFO_Append = SPIFFS_APPEND, file_t _file;
eFO_Truncate = SPIFFS_TRUNC,
eFO_CreateNewAlways = eFO_CreateIfNotExist | eFO_Truncate public:
FSFile(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 remove();
uint32_t position();
uint32_t size();
boolean eof();
void close();
int lastError();
void clearError();
operator bool(){ return _file > 0; }
char * name();
boolean isDirectory(void);
template<typename T> size_t write(T &src){
uint8_t obuf[64];
size_t doneLen = 0;
size_t sentLen;
int i;
while (src.available() > 64){
src.read(obuf, 64);
sentLen = write(obuf, 64);
doneLen = doneLen + sentLen;
if(sentLen != 64){
return doneLen;
}
}
size_t leftLen = src.available();
src.read(obuf, leftLen);
sentLen = write(obuf, leftLen);
doneLen = doneLen + sentLen;
return doneLen;
}
using Print::write;
}; };
static FileOpenFlags operator|(FileOpenFlags lhs, FileOpenFlags rhs) class FSClass {
{
return (FileOpenFlags) ((int)lhs| (int)rhs);
}
typedef enum private:
{ boolean _mounted;
eSO_FileStart = SPIFFS_SEEK_SET,
eSO_CurrentPos = SPIFFS_SEEK_CUR, public:
eSO_FileEnd = SPIFFS_SEEK_END boolean mount();
} SeekOriginFlags; void unmount();
boolean format();
boolean exists(const char *filename);
boolean create(const char *filepath);
boolean remove(const char *filepath);
boolean rename(const char *filename, const char *newname);
FSFile open(const char *filename, uint8_t mode = FSFILE_READ);
file_t fileOpen(const String name, FileOpenFlags flags); private:
void fileClose(file_t file); friend class FSFile;
size_t fileWrite(file_t file, const void* data, size_t size); };
size_t fileRead(file_t file, void* data, size_t size);
int fileSeek(file_t file, int offset, SeekOriginFlags origin);
bool fileIsEOF(file_t file);
int32_t fileTell(file_t file);
int fileFlush(file_t file);
int fileLastError(file_t fd);
void fileClearLastError(file_t fd);
void fileSetContent(const String fileName, const char *content);
uint32_t fileGetSize(const String fileName);
String fileGetContent(const String fileName);
int fileGetContent(const String fileName, char* buffer, int bufSize);
extern FSClass FS;
int fileStats(const String name, spiffs_stat *stat); #endif
int fileStats(file_t file, spiffs_stat *stat);
void fileDelete(const String name);
void fileDelete(file_t file);
bool fileExist(const String name);
#endif /* _SMING_CORE_FILESYSTEM_H_ */

View File

@ -18,6 +18,7 @@
Modified 23 November 2006 by David A. Mellis Modified 23 November 2006 by David A. Mellis
Modified December 2014 by Ivan Grokhotkov Modified December 2014 by Ivan Grokhotkov
Modified May 2015 by Michael C. Miller - esp8266 progmem support
*/ */
#include <stdlib.h> #include <stdlib.h>
@ -42,6 +43,18 @@ size_t ICACHE_FLASH_ATTR Print::write(const uint8_t *buffer, size_t size) {
return n; return n;
} }
size_t ICACHE_FLASH_ATTR Print::print(const __FlashStringHelper *ifsh) {
PGM_P p = reinterpret_cast<PGM_P>(ifsh);
size_t n = 0;
while (1) {
uint8_t c = pgm_read_byte(p++);
if (c == 0) break;
n += write(c);
}
return n;
}
size_t ICACHE_FLASH_ATTR Print::print(const String &s) { size_t ICACHE_FLASH_ATTR Print::print(const String &s) {
return write(s.c_str(), s.length()); return write(s.c_str(), s.length());
} }
@ -92,6 +105,12 @@ size_t ICACHE_FLASH_ATTR Print::print(double n, int digits) {
return printFloat(n, digits); return printFloat(n, digits);
} }
size_t ICACHE_FLASH_ATTR Print::println(const __FlashStringHelper *ifsh) {
size_t n = print(ifsh);
n += println();
return n;
}
size_t ICACHE_FLASH_ATTR Print::print(const Printable& x) { size_t ICACHE_FLASH_ATTR Print::print(const Printable& x) {
return x.printTo(*this); return x.printTo(*this);
} }

View File

@ -63,6 +63,7 @@ class Print {
return write((const uint8_t *) buffer, size); return write((const uint8_t *) buffer, size);
} }
size_t print(const __FlashStringHelper *);
size_t print(const String &); size_t print(const String &);
size_t print(const char[]); size_t print(const char[]);
size_t print(char); size_t print(char);
@ -74,6 +75,7 @@ class Print {
size_t print(double, int = 2); size_t print(double, int = 2);
size_t print(const Printable&); size_t print(const Printable&);
size_t println(const __FlashStringHelper *);
size_t println(const String &s); size_t println(const String &s);
size_t println(const char[]); size_t println(const char[]);
size_t println(char); size_t println(char);

View File

@ -4,6 +4,7 @@
Copyright (c) 2009-10 Hernando Barragan. All rights reserved. Copyright (c) 2009-10 Hernando Barragan. All rights reserved.
Copyright 2011, Paul Stoffregen, paul@pjrc.com Copyright 2011, Paul Stoffregen, paul@pjrc.com
Modified by Ivan Grokhotkov, 2014 - esp8266 support Modified by Ivan Grokhotkov, 2014 - esp8266 support
Modified by Michael C. Miller, 2015 - esp8266 progmem support
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
@ -44,6 +45,11 @@ ICACHE_FLASH_ATTR String::String(const String &value) {
*this = value; *this = value;
} }
ICACHE_FLASH_ATTR String::String(const __FlashStringHelper *pstr) {
init();
*this = pstr; // see operator =
}
#ifdef __GXX_EXPERIMENTAL_CXX0X__ #ifdef __GXX_EXPERIMENTAL_CXX0X__
ICACHE_FLASH_ATTR String::String(String &&rval) { ICACHE_FLASH_ATTR String::String(String &&rval) {
init(); init();
@ -167,6 +173,16 @@ String & ICACHE_FLASH_ATTR String::copy(const char *cstr, unsigned int length) {
return *this; return *this;
} }
String & ICACHE_FLASH_ATTR String::copy(const __FlashStringHelper *pstr, unsigned int length) {
if (!reserve(length)) {
invalidate();
return *this;
}
len = length;
strcpy_P(buffer, (PGM_P)pstr);
return *this;
}
#ifdef __GXX_EXPERIMENTAL_CXX0X__ #ifdef __GXX_EXPERIMENTAL_CXX0X__
void ICACHE_FLASH_ATTR String::move(String &rhs) { void ICACHE_FLASH_ATTR String::move(String &rhs) {
if(buffer) { if(buffer) {
@ -223,6 +239,14 @@ String & ICACHE_FLASH_ATTR String::operator =(const char *cstr) {
return *this; return *this;
} }
String & ICACHE_FLASH_ATTR String::operator = (const __FlashStringHelper *pstr)
{
if (pstr) copy(pstr, strlen_P((PGM_P)pstr));
else invalidate();
return *this;
}
// /*********************************************/ // /*********************************************/
// /* concat */ // /* concat */
// /*********************************************/ // /*********************************************/
@ -299,6 +323,17 @@ unsigned char ICACHE_FLASH_ATTR String::concat(double num) {
return concat(string, strlen(string)); return concat(string, strlen(string));
} }
unsigned char ICACHE_FLASH_ATTR String::concat(const __FlashStringHelper * str) {
if (!str) return 0;
int length = strlen_P((PGM_P)str);
if (length == 0) return 1;
unsigned int newlen = len + length;
if (!reserve(newlen)) return 0;
strcpy_P(buffer + len, (PGM_P)str);
len = newlen;
return 1;
}
/*********************************************/ /*********************************************/
/* Concatenate */ /* Concatenate */
/*********************************************/ /*********************************************/
@ -373,6 +408,13 @@ StringSumHelper & ICACHE_FLASH_ATTR operator +(const StringSumHelper &lhs, doubl
return a; return a;
} }
StringSumHelper & ICACHE_FLASH_ATTR operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(rhs)) a.invalidate();
return a;
}
// /*********************************************/ // /*********************************************/
// /* Comparison */ // /* Comparison */
// /*********************************************/ // /*********************************************/

View File

@ -26,15 +26,17 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#define PROGMEM #include <pgmspace.h>
// An inherited class for holding the result of a concatenation. These // An inherited class for holding the result of a concatenation. These
// result objects are assumed to be writable by subsequent concatenations. // result objects are assumed to be writable by subsequent concatenations.
class StringSumHelper; class StringSumHelper;
typedef char* __FlashStringHelper; // an abstract class used as a means to proide a unique pointer type
//#define F(str) []() -> const char * { static const char tmp[] ICACHE_RODATA_ATTR = str; return &tmp[0]; }() // but really has no body
#define F(str) str class __FlashStringHelper;
#define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))
// The string class // The string class
class String { class String {
@ -53,6 +55,7 @@ class String {
// be false). // be false).
String(const char *cstr = ""); String(const char *cstr = "");
String(const String &str); String(const String &str);
String(const __FlashStringHelper *str);
#ifdef __GXX_EXPERIMENTAL_CXX0X__ #ifdef __GXX_EXPERIMENTAL_CXX0X__
String(String &&rval); String(String &&rval);
String(StringSumHelper &&rval); String(StringSumHelper &&rval);
@ -81,6 +84,7 @@ class String {
// marked as invalid ("if (s)" will be false). // marked as invalid ("if (s)" will be false).
String & operator =(const String &rhs); String & operator =(const String &rhs);
String & operator =(const char *cstr); String & operator =(const char *cstr);
String & operator = (const __FlashStringHelper *str);
#ifdef __GXX_EXPERIMENTAL_CXX0X__ #ifdef __GXX_EXPERIMENTAL_CXX0X__
String & operator =(String &&rval); String & operator =(String &&rval);
String & operator =(StringSumHelper &&rval); String & operator =(StringSumHelper &&rval);
@ -101,6 +105,7 @@ class String {
unsigned char concat(unsigned long num); unsigned char concat(unsigned long num);
unsigned char concat(float num); unsigned char concat(float num);
unsigned char concat(double num); unsigned char concat(double num);
unsigned char concat(const __FlashStringHelper * str);
// if there's not enough memory for the concatenated value, the string // if there's not enough memory for the concatenated value, the string
// will be left unchanged (but this isn't signalled in any way) // will be left unchanged (but this isn't signalled in any way)
@ -144,6 +149,10 @@ class String {
concat(num); concat(num);
return (*this); return (*this);
} }
String & operator += (const __FlashStringHelper *str){
concat(str);
return (*this);
}
friend StringSumHelper & operator +(const StringSumHelper &lhs, const String &rhs); friend StringSumHelper & operator +(const StringSumHelper &lhs, const String &rhs);
friend StringSumHelper & operator +(const StringSumHelper &lhs, const char *cstr); friend StringSumHelper & operator +(const StringSumHelper &lhs, const char *cstr);
@ -155,6 +164,7 @@ class String {
friend StringSumHelper & operator +(const StringSumHelper &lhs, unsigned long num); friend StringSumHelper & operator +(const StringSumHelper &lhs, unsigned long num);
friend StringSumHelper & operator +(const StringSumHelper &lhs, float num); friend StringSumHelper & operator +(const StringSumHelper &lhs, float num);
friend StringSumHelper & operator +(const StringSumHelper &lhs, double num); friend StringSumHelper & operator +(const StringSumHelper &lhs, double num);
friend StringSumHelper & operator +(const StringSumHelper &lhs, const __FlashStringHelper *rhs);
// comparison (only works w/ Strings and "strings") // comparison (only works w/ Strings and "strings")
operator StringIfHelperType() const { operator StringIfHelperType() const {
@ -237,6 +247,7 @@ class String {
// copy and move // copy and move
String & copy(const char *cstr, unsigned int length); String & copy(const char *cstr, unsigned int length);
String & copy(const __FlashStringHelper *pstr, unsigned int length);
#ifdef __GXX_EXPERIMENTAL_CXX0X__ #ifdef __GXX_EXPERIMENTAL_CXX0X__
void move(String &rhs); void move(String &rhs);
#endif #endif

35
cores/esp8266/debug.cpp Normal file
View File

@ -0,0 +1,35 @@
/*
debug.cpp - debug helper functions
Copyright (c) 2015 Markus Sattler. 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 "Arduino.h"
#include "debug.h"
void ICACHE_RAM_ATTR hexdump(uint8_t *mem, uint32_t len, uint8_t cols) {
os_printf("\n[HEXDUMP] Address: 0x%08X len: 0x%X (%d)", mem, len, len);
for(uint32_t i = 0; i < len; i++) {
if(i % cols == 0) {
os_printf("\n[0x%08X] 0x%08X: ", mem, i);
}
os_printf("%02X ", *mem);
mem++;
}
os_printf("\n");
}

View File

@ -3,6 +3,9 @@
#include <stddef.h> #include <stddef.h>
// #define DEBUGV(...) ets_printf(__VA_ARGS__) // #define DEBUGV(...) ets_printf(__VA_ARGS__)
#define DEBUGV(...) #define DEBUGV(...)
void hexdump(uint8_t *mem, uint32_t len, uint8_t cols = 16);
#endif//ARD_DEBUG_H #endif//ARD_DEBUG_H

View File

@ -116,7 +116,7 @@ char* strncpy(char * dest, const char * src, size_t n) {
return ets_strncpy(dest, src, n); return ets_strncpy(dest, src, n);
} }
size_t strnlen(const char *s, size_t len) { size_t ICACHE_FLASH_ATTR strnlen(const char *s, size_t len) {
// there is no ets_strnlen // there is no ets_strnlen
const char *cp; const char *cp;
for (cp = s; len != 0 && *cp != '\0'; cp++, len--); for (cp = s; len != 0 && *cp != '\0'; cp++, len--);
@ -127,7 +127,7 @@ char* strstr(const char *haystack, const char *needle) {
return ets_strstr(haystack, needle); return ets_strstr(haystack, needle);
} }
char* strchr(const char * str, int character) { char* ICACHE_FLASH_ATTR strchr(const char * str, int character) {
while(1) { while(1) {
if(*str == 0x00) { if(*str == 0x00) {
return NULL; return NULL;
@ -139,7 +139,7 @@ char* strchr(const char * str, int character) {
} }
} }
char * strrchr(const char * str, int character) { char * ICACHE_FLASH_ATTR strrchr(const char * str, int character) {
char * ret = NULL; char * ret = NULL;
while(1) { while(1) {
if(*str == 0x00) { if(*str == 0x00) {
@ -223,7 +223,7 @@ char* ICACHE_FLASH_ATTR strtok(char * str, const char * delimiters) {
return ret; return ret;
} }
int strcasecmp(const char * str1, const char * str2) { int ICACHE_FLASH_ATTR strcasecmp(const char * str1, const char * str2) {
int d = 0; int d = 0;
while(1) { while(1) {
int c1 = tolower(*str1++); int c1 = tolower(*str1++);

161
cores/esp8266/pgmspace.cpp Normal file
View File

@ -0,0 +1,161 @@
/*
pgmspace.cpp - string functions that support PROGMEM
Copyright (c) 2015 Michael C. Miller. All right reserved.
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 <ctype.h>
#include "pgmspace.h"
size_t ICACHE_FLASH_ATTR strnlen_P(const char* s, size_t size) {
const char* cp;
for (cp = s; size != 0 && pgm_read_byte(cp) != '\0'; cp++, size--);
return (size_t)(cp - s);
}
void* ICACHE_FLASH_ATTR memcpy_P(void* dest, const void* src, size_t count) {
const uint8_t* read = reinterpret_cast<const uint8_t*>(src);
uint8_t* write = reinterpret_cast<uint8_t*>(dest);
while (count)
{
*write++ = pgm_read_byte(read++);
count--;
}
return dest;
}
char* ICACHE_FLASH_ATTR strncpy_P(char* dest, const char* src, size_t size) {
const char* read = src;
char* write = dest;
char ch = '.';
while (size > 0 && ch != '\0')
{
ch = pgm_read_byte(read++);
*write++ = ch;
size--;
}
return dest;
}
char* ICACHE_FLASH_ATTR strncat_P(char* dest, const char* src, size_t size) {
char* write = dest;
while (*write != '\0')
{
write++;
}
const char* read = src;
char ch = '.';
while (size > 0 && ch != '\0')
{
ch = pgm_read_byte(read++);
*write++ = ch;
size--;
}
if (ch != '\0')
{
*write = '\0';
}
return dest;
}
int ICACHE_FLASH_ATTR strncmp_P(const char* str1, const char* str2P, size_t size) {
int result = 0;
while (size > 0)
{
char ch1 = *str1++;
char ch2 = pgm_read_byte(str2P++);
result = ch1 - ch2;
if (result != 0 || ch2 == '\0')
{
break;
}
size--;
}
return result;
}
int ICACHE_FLASH_ATTR strncasecmp_P(const char* str1, const char* str2P, size_t size) {
int result = 0;
while (size > 0)
{
char ch1 = tolower(*str1++);
char ch2 = tolower(pgm_read_byte(str2P++));
result = ch1 - ch2;
if (result != 0 || ch2 == '\0')
{
break;
}
size--;
}
return result;
}
int ICACHE_FLASH_ATTR printf_P(const char* formatP, ...) {
int ret;
va_list arglist;
va_start(arglist, formatP);
size_t fmtLen = strlen_P(formatP);
char* format = new char[fmtLen + 1];
strcpy_P(format, formatP);
ret = os_printf(format, arglist);
delete [] format;
va_end(arglist);
return ret;
}
int ICACHE_FLASH_ATTR snprintf_P(char* str, size_t strSize, const char* formatP, ...) {
int ret;
va_list arglist;
va_start(arglist, formatP);
ret = vsnprintf_P(str, strSize, formatP, arglist);
va_end(arglist);
return ret;
}
int ICACHE_FLASH_ATTR vsnprintf_P(char* str, size_t strSize, const char* formatP, va_list ap) {
int ret;
size_t fmtLen = strlen_P(formatP);
char* format = new char[fmtLen + 1];
strcpy_P(format, formatP);
ret = ets_vsnprintf(str, strSize, format, ap);
delete [] format;
return ret;
}

View File

@ -12,13 +12,11 @@ extern "C" {
} }
#endif #endif
#define PROGMEM #define PROGMEM ICACHE_RODATA_ATTR
#define PGM_P const char * #define PGM_P const char *
#define PSTR(str) (str) #define PGM_VOID_P const void *
#define PSTR(s) (__extension__({static const char __c[] PROGMEM = (s); &__c[0];}))
#define vsnprintf_P(...) ets_vsnprintf( __VA_ARGS__ )
#define snprintf_P(...) snprintf( __VA_ARGS__ )
#define printf_P(...) os_printf(__VA_ARGS__)
#define _SFR_BYTE(n) (n) #define _SFR_BYTE(n) (n)
@ -32,23 +30,56 @@ typedef uint16_t prog_uint16_t;
typedef int32_t prog_int32_t; typedef int32_t prog_int32_t;
typedef uint32_t prog_uint32_t; typedef uint32_t prog_uint32_t;
#define memcpy_P(dest, src, num) memcpy((dest), (src), (num)) #define SIZE_IRRELEVANT 0x7fffffff
#define strcpy_P(dest, src) strcpy((dest), (src))
#define strcat_P(dest, src) strcat((dest), (src))
#define strcmp_P(a, b) strcmp((a), (b))
#define strstr_P(a, b) strstr((a), (b))
#define strlen_P(s) strlen((const char *)(s))
#define strcasecmp_P(a, b) strcasecmp((a), (b))
#define strncpy_P(dest, src, size) strncpy((dest), (src), (size))
#define strncat_P(dest, src, size) strncat((dest), (src), (size))
#define strncmp_P(a, b, size) strncmp((a), (b), (size))
#define strnlen_P(s, size) strnlen((const char *)(s), (size))
#define strncasecmp_P(a, b, size) strncasecmp((a), (b), (size))
#define pgm_read_byte(addr) (*(const unsigned char *)(addr)) extern void* memcpy_P(void* dest, const void* src, size_t count);
#define pgm_read_word(addr) (*(const unsigned short *)(addr))
#define pgm_read_dword(addr) (*(const unsigned long *)(addr)) extern char* strncpy_P(char* dest, const char* src, size_t size);
#define pgm_read_float(addr) (*(const float *)(addr)) #define strcpy_P(dest, src) strncpy_P((dest), (src), SIZE_IRRELEVANT)
extern char* strncat_P(char* dest, const char* src, size_t size);
#define strcat_P(dest, src) strncat_P((dest), (src), SIZE_IRRELEVANT)
extern int strncmp_P(const char* str1, const char* str2P, size_t size);
#define strcmp_P(str1, str2P) strncmp_P((str1), (str2P), SIZE_IRRELEVANT)
extern int strncasecmp_P(const char* str1, const char* str2P, size_t size);
#define strcasecmp_P(str1, str2P) strncasecmp_P((str1), (str2P), SIZE_IRRELEVANT)
extern size_t strnlen_P(const char *s, size_t size);
#define strlen_P(strP) strnlen_P((strP), SIZE_IRRELEVANT)
extern int printf_P(const char *formatP, ...);
extern int snprintf_P(char *str, size_t strSize, const char *formatP, ...);
extern int vsnprintf_P(char *str, size_t strSize, const char *formatP, va_list ap);
// flash memory must be read using 32 bit aligned addresses else a processor
// exception will be triggered
// order within the 32 bit values are
// --------------
// b3, b2, b1, b0
// w1, w0
#define pgm_read_byte(addr) \
(__extension__({ \
PGM_P __local = (PGM_P)(addr); /* isolate varible for macro expansion */ \
ptrdiff_t __offset = ((uint32_t)__local & 0x00000003); /* byte aligned mask */ \
const uint32_t* __addr32 = reinterpret_cast<const uint32_t*>(reinterpret_cast<const uint8_t*>(__local)-__offset); \
uint8_t __result = ((*__addr32) >> (__offset * 8)); \
__result; \
}))
#define pgm_read_word(addr) \
(__extension__({ \
PGM_P __local = (PGM_P)(addr); /* isolate varible for macro expansion */ \
ptrdiff_t __offset = ((uint32_t)__local & 0x00000002); /* word aligned mask */ \
const uint32_t* __addr32 = reinterpret_cast<const uint32_t*>(reinterpret_cast<const uint8_t*>(__local) - __offset); \
uint16_t __result = ((*__addr32) >> (__offset * 8)); \
__result; \
}))
#define pgm_read_dword(addr) (*reinterpret_cast<const uint32_t*>(addr))
#define pgm_read_float(addr) (*reinterpret_cast<const float*>(addr))
#define pgm_read_byte_near(addr) pgm_read_byte(addr) #define pgm_read_byte_near(addr) pgm_read_byte(addr)
#define pgm_read_word_near(addr) pgm_read_word(addr) #define pgm_read_word_near(addr) pgm_read_word(addr)

View File

@ -8,21 +8,17 @@ static u8_t spiffs_work_buf[LOG_PAGE_SIZE*2];
static u8_t spiffs_fds[32*4]; static u8_t spiffs_fds[32*4];
static u8_t spiffs_cache[(LOG_PAGE_SIZE+32)*4]; static u8_t spiffs_cache[(LOG_PAGE_SIZE+32)*4];
static s32_t api_spiffs_read(u32_t addr, u32_t size, u8_t *dst) static s32_t api_spiffs_read(u32_t addr, u32_t size, u8_t *dst){
{
flashmem_read(dst, addr, size); flashmem_read(dst, addr, size);
return SPIFFS_OK; return SPIFFS_OK;
} }
static s32_t api_spiffs_write(u32_t addr, u32_t size, u8_t *src) static s32_t api_spiffs_write(u32_t addr, u32_t size, u8_t *src){
{
//debugf("api_spiffs_write");
flashmem_write(src, addr, size); flashmem_write(src, addr, size);
return SPIFFS_OK; return SPIFFS_OK;
} }
static s32_t api_spiffs_erase(u32_t addr, u32_t size) static s32_t api_spiffs_erase(u32_t addr, u32_t size){
{
debugf("api_spiffs_erase"); debugf("api_spiffs_erase");
u32_t sect_first = flashmem_get_sector_of_address(addr); u32_t sect_first = flashmem_get_sector_of_address(addr);
u32_t sect_last = sect_first; u32_t sect_last = sect_first;
@ -45,48 +41,38 @@ extern uint32_t _SPIFFS_end;
spiffs_config spiffs_get_storage_config() spiffs_config spiffs_get_storage_config()
{ {
spiffs_config cfg = {0}; spiffs_config cfg = {0};
if ((u32_t)&_SPIFFS_start == 0) return cfg;
cfg.phys_addr = (u32_t)&_SPIFFS_start; cfg.phys_addr = (u32_t)&_SPIFFS_start;
if (cfg.phys_addr == 0)
return cfg;
cfg.phys_addr += 0x3000;
cfg.phys_addr &= 0xFFFFC000; // align to 4 sector.
cfg.phys_size = (u32_t)((u32_t)&_SPIFFS_end - (u32_t)&_SPIFFS_start); cfg.phys_size = (u32_t)((u32_t)&_SPIFFS_end - (u32_t)&_SPIFFS_start);
/*cfg.phys_addr = INTERNAL_FLASH_SIZE - SPIFFS_WORK_SIZE + INTERNAL_FLASH_START_ADDRESS;
cfg.phys_addr += 0x3000;
cfg.phys_addr &= 0xFFFFC000; // align to 4 sector.
cfg.phys_size = SPIFFS_WORK_SIZE;*/
cfg.phys_erase_block = INTERNAL_FLASH_SECTOR_SIZE; // according to datasheet cfg.phys_erase_block = INTERNAL_FLASH_SECTOR_SIZE; // according to datasheet
cfg.log_block_size = INTERNAL_FLASH_SECTOR_SIZE * 2; // Important to make large cfg.log_block_size = INTERNAL_FLASH_SECTOR_SIZE * 2; // Important to make large
cfg.log_page_size = LOG_PAGE_SIZE; // as we said cfg.log_page_size = LOG_PAGE_SIZE; // as we said
return cfg; return cfg;
} }
bool spiffs_format_internal() bool spiffs_format_internal(){
{
spiffs_config cfg = spiffs_get_storage_config(); spiffs_config cfg = spiffs_get_storage_config();
if (cfg.phys_addr == 0) if (cfg.phys_addr == 0){
{ SYSTEM_ERROR("Can't format file system, wrong address");
SYSTEM_ERROR("Can't format file system, wrong address"); return false;
return false;
} }
u32_t sect_first, sect_last; u32_t sect_first, sect_last;
sect_first = cfg.phys_addr; sect_first = flashmem_get_first_free_block_address();
sect_first = flashmem_get_sector_of_address((u32_t)&_SPIFFS_start);
sect_last = flashmem_get_sector_of_address((u32_t)&_SPIFFS_end); sect_last = flashmem_get_sector_of_address((u32_t)&_SPIFFS_end);
debugf("sect_first: %x, sect_last: %x\n", sect_first, sect_last); debugf("sect_first: %x, sect_last: %x\n", sect_first, sect_last);
while( sect_first <= sect_last ) while( sect_first <= sect_last ){
if(!flashmem_erase_sector( sect_first ++ )) if(!flashmem_erase_sector( sect_first ++ ))
return false; return false;
}
return true;
} }
void spiffs_mount() bool spiffs_mount(){
{
spiffs_config cfg = spiffs_get_storage_config(); spiffs_config cfg = spiffs_get_storage_config();
if (cfg.phys_addr == 0) if (cfg.phys_addr == 0){
{ SYSTEM_ERROR("Can't start file system, wrong address");
SYSTEM_ERROR("Can't start file system, wrong address"); return false;
return;
} }
debugf("fs.start:%x, size:%d Kb\n", cfg.phys_addr, cfg.phys_size / 1024); debugf("fs.start:%x, size:%d Kb\n", cfg.phys_addr, cfg.phys_size / 1024);
@ -94,17 +80,18 @@ void spiffs_mount()
cfg.hal_read_f = api_spiffs_read; cfg.hal_read_f = api_spiffs_read;
cfg.hal_write_f = api_spiffs_write; cfg.hal_write_f = api_spiffs_write;
cfg.hal_erase_f = api_spiffs_erase; cfg.hal_erase_f = api_spiffs_erase;
uint32_t dat; uint32_t dat;
bool writeFirst = false; bool writeFirst = false;
flashmem_read(&dat, cfg.phys_addr, 4); flashmem_read(&dat, cfg.phys_addr, 4);
//debugf("%X", dat);
if (dat == UINT32_MAX) if (dat == UINT32_MAX){
{ debugf("First init file system");
debugf("First init file system"); if(!spiffs_format_internal()){
spiffs_format_internal(); SYSTEM_ERROR("Can't format file system");
writeFirst = true; return false;
}
writeFirst = true;
} }
int res = SPIFFS_mount(&_filesystemStorageHandle, int res = SPIFFS_mount(&_filesystemStorageHandle,
@ -116,66 +103,44 @@ void spiffs_mount()
sizeof(spiffs_cache), sizeof(spiffs_cache),
NULL); NULL);
debugf("mount res: %d\n", res); debugf("mount res: %d\n", res);
if (writeFirst) if(res != 0) return false;
{
file_t fd = SPIFFS_open(&_filesystemStorageHandle, "initialize_fs_header.dat", SPIFFS_CREAT | SPIFFS_TRUNC | SPIFFS_RDWR, 0); if (writeFirst){
SPIFFS_write(&_filesystemStorageHandle, fd, (u8_t *)"1", 1); file_t fd = SPIFFS_open(&_filesystemStorageHandle, "initialize_fs_header.dat", SPIFFS_CREAT | SPIFFS_TRUNC | SPIFFS_RDWR, 0);
SPIFFS_fremove(&_filesystemStorageHandle, fd); SPIFFS_write(&_filesystemStorageHandle, fd, (u8_t *)"1", 1);
SPIFFS_close(&_filesystemStorageHandle, fd); SPIFFS_fremove(&_filesystemStorageHandle, fd);
SPIFFS_close(&_filesystemStorageHandle, fd);
} }
return true;
//dat=0;
//flashmem_read(&dat, cfg.phys_addr, 4);
//debugf("%X", dat);
} }
void spiffs_unmount() void spiffs_unmount(){
{
SPIFFS_unmount(&_filesystemStorageHandle); SPIFFS_unmount(&_filesystemStorageHandle);
} }
// FS formatting function bool spiffs_format(){
bool spiffs_format()
{
spiffs_unmount(); spiffs_unmount();
spiffs_format_internal(); if(!spiffs_format_internal()) return false;
spiffs_mount(); spiffs_mount();
return true; return true;
} }
//int spiffs_check( void ) void test_spiffs(){
//{
// ets_wdt_disable();
// int res = (int)SPIFFS_check(&_filesystemStorageHandle);
// ets_wdt_enable();
// return res;
//}
void test_spiffs()
{
char buf[12] = {0}; char buf[12] = {0};
// Surely, I've mounted spiffs before entering here
spiffs_file fd; spiffs_file fd;
spiffs_stat st = {0}; spiffs_stat st = {0};
SPIFFS_stat(&_filesystemStorageHandle, "my_file.txt", &st); SPIFFS_stat(&_filesystemStorageHandle, "my_file.txt", &st);
if (st.size <= 0) if (st.size <= 0){
{ fd = SPIFFS_open(&_filesystemStorageHandle, "my_file.txt", SPIFFS_CREAT | SPIFFS_TRUNC | SPIFFS_RDWR, 0);
fd = SPIFFS_open(&_filesystemStorageHandle, "my_file.txt", SPIFFS_CREAT | SPIFFS_TRUNC | SPIFFS_RDWR, 0); if (SPIFFS_write(&_filesystemStorageHandle, fd, (u8_t *)"Hello world", 11) < 0)
if (SPIFFS_write(&_filesystemStorageHandle, fd, (u8_t *)"Hello world", 11) < 0) debugf("errno %d\n", SPIFFS_errno(&_filesystemStorageHandle));
debugf("errno %d\n", SPIFFS_errno(&_filesystemStorageHandle)); SPIFFS_close(&_filesystemStorageHandle, fd);
SPIFFS_close(&_filesystemStorageHandle, fd); debugf("file created");
debugf("file created"); } else debugf("file %s exist :)", st.name);
}
else
debugf("file %s exist :)", st.name);
fd = SPIFFS_open(&_filesystemStorageHandle, "my_file.txt", SPIFFS_RDWR, 0); fd = SPIFFS_open(&_filesystemStorageHandle, "my_file.txt", SPIFFS_RDWR, 0);
if (SPIFFS_read(&_filesystemStorageHandle, fd, (u8_t *)buf, 11) < 0) debugf("errno %d\n", SPIFFS_errno(&_filesystemStorageHandle)); if (SPIFFS_read(&_filesystemStorageHandle, fd, (u8_t *)buf, 11) < 0) debugf("errno %d\n", SPIFFS_errno(&_filesystemStorageHandle));
SPIFFS_close(&_filesystemStorageHandle, fd); SPIFFS_close(&_filesystemStorageHandle, fd);
debugf("--> %s <--\n", buf); debugf("--> %s <--\n", buf);
} }

View File

@ -83,12 +83,10 @@ typedef enum {
} spiffs_check_report; } spiffs_check_report;
/* file system check callback function */ /* file system check callback function */
typedef void (*spiffs_check_callback)(spiffs_check_type type, spiffs_check_report report, typedef void (*spiffs_check_callback)(spiffs_check_type type, spiffs_check_report report, u32_t arg1, u32_t arg2);
u32_t arg1, u32_t arg2);
#ifndef SPIFFS_DBG #ifndef SPIFFS_DBG
#define SPIFFS_DBG(...) \ #define SPIFFS_DBG(...) printf(__VA_ARGS__)
print(__VA_ARGS__)
#endif #endif
#ifndef SPIFFS_GC_DBG #ifndef SPIFFS_GC_DBG
#define SPIFFS_GC_DBG(...) printf(__VA_ARGS__) #define SPIFFS_GC_DBG(...) printf(__VA_ARGS__)
@ -456,7 +454,7 @@ u32_t SPIFFS_buffer_bytes_for_cache(spiffs *fs, u32_t num_pages);
#endif #endif
void spiffs_mount(); bool spiffs_mount();
void spiffs_unmount(); void spiffs_unmount();
bool spiffs_format(); bool spiffs_format();
spiffs_config spiffs_get_storage_config(); spiffs_config spiffs_get_storage_config();

View File

@ -20,7 +20,7 @@ static spiffs_cache_page *spiffs_cache_page_get(spiffs *fs, spiffs_page_ix pix)
if ((cache->cpage_use_map & (1<<i)) && if ((cache->cpage_use_map & (1<<i)) &&
(cp->flags & SPIFFS_CACHE_FLAG_TYPE_WR) == 0 && (cp->flags & SPIFFS_CACHE_FLAG_TYPE_WR) == 0 &&
cp->pix == pix ) { cp->pix == pix ) {
SPIFFS_CACHE_DBG("CACHE_GET: have cache page %u for %04x\n", i, pix); SPIFFS_CACHE_DBG("CACHE_GET: have cache page %d for %04x\n", i, pix);
cp->last_access = cache->last_access; cp->last_access = cache->last_access;
return cp; return cp;
} }
@ -46,9 +46,9 @@ static s32_t spiffs_cache_page_free(spiffs *fs, int ix, u8_t write_back) {
cache->cpage_use_map &= ~(1 << ix); cache->cpage_use_map &= ~(1 << ix);
if (cp->flags & SPIFFS_CACHE_FLAG_TYPE_WR) { if (cp->flags & SPIFFS_CACHE_FLAG_TYPE_WR) {
SPIFFS_CACHE_DBG("CACHE_FREE: free cache page %u objid %04x\n", ix, cp->obj_id); SPIFFS_CACHE_DBG("CACHE_FREE: free cache page %d objid %04x\n", ix, cp->obj_id);
} else { } else {
SPIFFS_CACHE_DBG("CACHE_FREE: free cache page %u pix %04x\n", ix, cp->pix); SPIFFS_CACHE_DBG("CACHE_FREE: free cache page %d pix %04x\n", ix, cp->pix);
} }
} }
@ -98,7 +98,7 @@ static spiffs_cache_page *spiffs_cache_page_allocate(spiffs *fs) {
spiffs_cache_page *cp = spiffs_get_cache_page_hdr(fs, cache, i); spiffs_cache_page *cp = spiffs_get_cache_page_hdr(fs, cache, i);
cache->cpage_use_map |= (1<<i); cache->cpage_use_map |= (1<<i);
cp->last_access = cache->last_access; cp->last_access = cache->last_access;
SPIFFS_CACHE_DBG("CACHE_ALLO: allocated cache page %u\n", i); SPIFFS_CACHE_DBG("CACHE_ALLO: allocated cache page %d\n", i);
return cp; return cp;
} }
} }

View File

@ -55,7 +55,6 @@ void returnOK(){
message += "Access-Control-Allow-Origin: *\r\n"; message += "Access-Control-Allow-Origin: *\r\n";
message += "\r\n"; message += "\r\n";
client.print(message); client.print(message);
message = 0;
client.stop(); client.stop();
} }
@ -69,7 +68,6 @@ void returnFail(String msg){
message += msg; message += msg;
message += "\r\n"; message += "\r\n";
client.print(message); client.print(message);
message = 0;
client.stop(); client.stop();
} }
@ -108,8 +106,8 @@ bool loadFromSdCard(String path){
head += "\r\nAccess-Control-Allow-Origin: *"; head += "\r\nAccess-Control-Allow-Origin: *";
head += "\r\n\r\n"; head += "\r\n\r\n";
client.print(head); client.print(head);
dataType = 0; dataType = String();
path = 0; path = String();
if(client.write(dataFile) != dataFile.size()){ if(client.write(dataFile) != dataFile.size()){
DBG_OUTPUT_PORT.println("Sent less data than expected!"); DBG_OUTPUT_PORT.println("Sent less data than expected!");
@ -159,11 +157,11 @@ void deleteRecursive(String path){
entry.close(); entry.close();
SD.remove((char *)entryPath.c_str()); SD.remove((char *)entryPath.c_str());
} }
entryPath = 0; entryPath = String();
yield(); yield();
} }
SD.rmdir((char *)path.c_str()); SD.rmdir((char *)path.c_str());
path = 0; path = String();
file.close(); file.close();
} }
@ -173,7 +171,7 @@ void handleDelete(){
if(path == "/" || !SD.exists((char *)path.c_str())) return returnFail("BAD PATH"); if(path == "/" || !SD.exists((char *)path.c_str())) return returnFail("BAD PATH");
deleteRecursive(path); deleteRecursive(path);
returnOK(); returnOK();
path = 0; path = String();
} }
void handleCreate(){ void handleCreate(){
@ -190,7 +188,7 @@ void handleCreate(){
SD.mkdir((char *)path.c_str()); SD.mkdir((char *)path.c_str());
} }
returnOK(); returnOK();
path = 0; path = String();
} }
void printDirectory() { void printDirectory() {
@ -198,7 +196,7 @@ void printDirectory() {
String path = server.arg("dir"); String path = server.arg("dir");
if(path != "/" && !SD.exists((char *)path.c_str())) return returnFail("BAD PATH"); if(path != "/" && !SD.exists((char *)path.c_str())) return returnFail("BAD PATH");
File dir = SD.open((char *)path.c_str()); File dir = SD.open((char *)path.c_str());
path = 0; path = String();
if(!dir.isDirectory()){ if(!dir.isDirectory()){
dir.close(); dir.close();
return returnFail("NOT DIR"); return returnFail("NOT DIR");
@ -229,7 +227,7 @@ void printDirectory() {
output += "]"; output += "]";
client.write(output.c_str(), output.length()); client.write(output.c_str(), output.length());
client.stop(); client.stop();
output = 0; output = String();
} }
void handleNotFound(){ void handleNotFound(){

View File

@ -48,6 +48,28 @@ public:
boolean isDirectory(void); boolean isDirectory(void);
File openNextFile(uint8_t mode = O_RDONLY); File openNextFile(uint8_t mode = O_RDONLY);
void rewindDirectory(void); void rewindDirectory(void);
template<typename T> size_t write(T &src){
uint8_t obuf[512];
size_t doneLen = 0;
size_t sentLen;
int i;
while (src.available() > 512){
src.read(obuf, 512);
sentLen = write(obuf, 512);
doneLen = doneLen + sentLen;
if(sentLen != 512){
return doneLen;
}
}
size_t leftLen = src.available();
src.read(obuf, leftLen);
sentLen = write(obuf, leftLen);
doneLen = doneLen + sentLen;
return doneLen;
}
using Print::write; using Print::write;
}; };

View File

@ -308,6 +308,13 @@ void SPIClass::write32(uint32_t data, bool msb) {
while(SPI1CMD & SPIBUSY) {} while(SPI1CMD & SPIBUSY) {}
} }
/**
* Note:
* data need to be aligned to 32Bit
* or you get an Fatal exception (9)
* @param data uint8_t *
* @param size uint32_t
*/
void SPIClass::writeBytes(uint8_t * data, uint32_t size) { void SPIClass::writeBytes(uint8_t * data, uint32_t size) {
while(size) { while(size) {
if(size > 64) { if(size > 64) {
@ -340,6 +347,15 @@ void SPIClass::writeBytes_(uint8_t * data, uint8_t size) {
while(SPI1CMD & SPIBUSY) {} while(SPI1CMD & SPIBUSY) {}
} }
/**
* Note:
* data need to be aligned to 32Bit
* or you get an Fatal exception (9)
* @param data uint8_t *
* @param size uint8_t max for size is 64Byte
* @param repeat uint32_t
*/
void SPIClass::writePattern(uint8_t * data, uint8_t size, uint32_t repeat) { void SPIClass::writePattern(uint8_t * data, uint8_t size, uint32_t repeat) {
if(size > 64) return; //max Hardware FIFO if(size > 64) return; //max Hardware FIFO
@ -376,6 +392,14 @@ void SPIClass::writePattern_(uint8_t * data, uint8_t size, uint8_t repeat) {
writeBytes(&buffer[0], bytes); writeBytes(&buffer[0], bytes);
} }
/**
* Note:
* in and out need to be aligned to 32Bit
* or you get an Fatal exception (9)
* @param out uint8_t *
* @param in uint8_t *
* @param size uint32_t
*/
void SPIClass::transferBytes(uint8_t * out, uint8_t * in, uint32_t size) { void SPIClass::transferBytes(uint8_t * out, uint8_t * in, uint32_t size) {
while(size) { while(size) {
if(size > 64) { if(size > 64) {