Merge pull request #203 from nodemcu/dev

Fixed floating point bug.
add file.rename
This commit is contained in:
zeroday 2015-02-12 11:03:00 +08:00
commit 18886ea638
39 changed files with 1918 additions and 740 deletions

View File

@ -125,6 +125,7 @@ pre_build/latest/nodemcu_512k_latest.bin is removed. use pre_build/latest/nodemc
#define LUA_USE_MODULES_UART
#define LUA_USE_MODULES_OW
#define LUA_USE_MODULES_BIT
#define LUA_USE_MODULES_WS2812
#endif /* LUA_USE_MODULES */
...
// LUA_NUMBER_INTEGRAL
@ -330,3 +331,13 @@ cu:send("hello")
ds18b20 = nil
package.loaded["ds18b20"]=nil
```
####Control a WS2812 based light strip
```lua
-- set the color of one LED on GPIO 2 to red
ws2812.write(4, string.char(0, 255, 0))
-- set the color of 10 LEDs on GPIO 0 to blue
ws2812.write(3, string.char(0, 0, 255):rep(10))
-- first LED green, second LED white
ws2812.write(4, string.char(255, 0, 0, 255, 255, 255))
```

View File

@ -33,18 +33,23 @@ typedef enum {
} UartExistParity;
typedef enum {
BIT_RATE_1200 = 1200,
BIT_RATE_2400 = 2400,
BIT_RATE_4800 = 4800,
BIT_RATE_9600 = 9600,
BIT_RATE_300 = 300,
BIT_RATE_600 = 600,
BIT_RATE_1200 = 1200,
BIT_RATE_2400 = 2400,
BIT_RATE_4800 = 4800,
BIT_RATE_9600 = 9600,
BIT_RATE_19200 = 19200,
BIT_RATE_38400 = 38400,
BIT_RATE_57600 = 57600,
BIT_RATE_74880 = 74880,
BIT_RATE_115200 = 115200,
BIT_RATE_230400 = 230400,
BIT_RATE_460800 = 460800,
BIT_RATE_921600 = 921600
BIT_RATE_115200 = 115200,
BIT_RATE_230400 = 230400,
BIT_RATE_256000 = 256000,
BIT_RATE_460800 = 460800,
BIT_RATE_921600 = 921600,
BIT_RATE_1843200 = 1843200,
BIT_RATE_3686400 = 3686400,
} UartBautRate;
typedef enum {

View File

@ -394,5 +394,21 @@ extern sint8 espconn_igmp_join(ip_addr_t *host_ip, ip_addr_t *multicast_ip);
*******************************************************************************/
extern sint8 espconn_igmp_leave(ip_addr_t *host_ip, ip_addr_t *multicast_ip);
/******************************************************************************
* FunctionName : espconn_recv_hold
* Description : hold tcp receive
* Parameters : espconn -- espconn to hold
* Returns : none
*******************************************************************************/
extern sint8 espconn_recv_hold(struct espconn *pespconn);
/******************************************************************************
* FunctionName : espconn_recv_unhold
* Description : unhold tcp receive
* Parameters : espconn -- espconn to unhold
* Returns : none
*******************************************************************************/
extern sint8 espconn_recv_unhold(struct espconn *pespconn);
#endif

View File

@ -277,6 +277,8 @@ struct tcp_pcb {
/* KEEPALIVE counter */
u8_t keep_cnt_sent;
u8_t hold;
};
struct tcp_pcb_listen {

View File

@ -13,6 +13,8 @@
// #define FLASH_1M
// #define FLASH_2M
// #define FLASH_4M
// #define FLASH_8M
// #define FLASH_16M
#define FLASH_AUTOSIZE
// #define DEVELOP_VERSION
#define FULL_VERSION_FOR_USER
@ -40,7 +42,6 @@
#define ICACHE_STORE_TYPEDEF_ATTR __attribute__((aligned(4),packed))
#define ICACHE_STORE_ATTR __attribute__((aligned(4)))
#define ICACHE_RAM_ATTR __attribute__((section(".iram0.text")))
// #define ICACHE_RODATA_ATTR __attribute__((section(".rodata2.text")))
#define CLIENT_SSL_ENABLE
#define GPIO_INTERRUPT_ENABLE
@ -64,12 +65,10 @@
#define LUA_USE_MODULES_OW
#define LUA_USE_MODULES_BIT
#define LUA_USE_MODULES_MQTT
#define LUA_USE_MODULES_WS2812
#endif /* LUA_USE_MODULES */
// #define LUA_NUMBER_INTEGRAL
#ifndef LUA_NUMBER_INTEGRAL
#define PRINTF_LONG_SUPPORT
#endif
#define LUA_OPTRAM
#ifdef LUA_OPTRAM

View File

@ -1,60 +1,62 @@
#include "c_math.h"
#include "c_types.h"
#include "user_config.h"
double floor(double x)
{
return (double) (x < 0.f ? (((int) x) - 1) : ((int) x));
}
double pow(double x, double y)
{
#define MAXEXP 2031 /* (MAX_EXP * 16) - 1 */
#define MINEXP -2047 /* (MIN_EXP * 16) - 1 */
#define HUGE MAXFLOAT
double a1[] =
{
1.0,
0.95760328069857365,
0.91700404320467123,
0.87812608018664974,
0.84089641525371454,
0.80524516597462716,
0.77110541270397041,
0.73841307296974966,
0.70710678118654752,
0.67712777346844637,
0.64841977732550483,
0.62092890603674203,
0.59460355750136054,
0.56939431737834583,
0.54525386633262883,
0.52213689121370692,
0.50000000000000000
};
double a2[] =
{
0.24114209503420288E-17,
0.92291566937243079E-18,
-0.15241915231122319E-17,
-0.35421849765286817E-17,
-0.31286215245415074E-17,
-0.44654376565694490E-17,
0.29306999570789681E-17,
0.11260851040933474E-17
};
double p1 = 0.833333333333332114e-1;
double p2 = 0.125000000005037992e-1;
double p3 = 0.223214212859242590e-2;
double p4 = 0.434457756721631196e-3;
double q1 = 0.693147180559945296e0;
double q2 = 0.240226506959095371e0;
double q3 = 0.555041086640855953e-1;
double q4 = 0.961812905951724170e-2;
double q5 = 0.133335413135857847e-2;
double q6 = 0.154002904409897646e-3;
double q7 = 0.149288526805956082e-4;
double k = 0.442695040888963407;
double a1[] ICACHE_STORE_ATTR ICACHE_RODATA_ATTR =
{
1.0,
0.95760328069857365,
0.91700404320467123,
0.87812608018664974,
0.84089641525371454,
0.80524516597462716,
0.77110541270397041,
0.73841307296974966,
0.70710678118654752,
0.67712777346844637,
0.64841977732550483,
0.62092890603674203,
0.59460355750136054,
0.56939431737834583,
0.54525386633262883,
0.52213689121370692,
0.50000000000000000
};
double a2[] ICACHE_STORE_ATTR ICACHE_RODATA_ATTR =
{
0.24114209503420288E-17,
0.92291566937243079E-18,
-0.15241915231122319E-17,
-0.35421849765286817E-17,
-0.31286215245415074E-17,
-0.44654376565694490E-17,
0.29306999570789681E-17,
0.11260851040933474E-17
};
double p1 ICACHE_STORE_ATTR ICACHE_RODATA_ATTR = 0.833333333333332114e-1;
double p2 ICACHE_STORE_ATTR ICACHE_RODATA_ATTR = 0.125000000005037992e-1;
double p3 ICACHE_STORE_ATTR ICACHE_RODATA_ATTR = 0.223214212859242590e-2;
double p4 ICACHE_STORE_ATTR ICACHE_RODATA_ATTR = 0.434457756721631196e-3;
double q1 ICACHE_STORE_ATTR ICACHE_RODATA_ATTR = 0.693147180559945296e0;
double q2 ICACHE_STORE_ATTR ICACHE_RODATA_ATTR = 0.240226506959095371e0;
double q3 ICACHE_STORE_ATTR ICACHE_RODATA_ATTR = 0.555041086640855953e-1;
double q4 ICACHE_STORE_ATTR ICACHE_RODATA_ATTR = 0.961812905951724170e-2;
double q5 ICACHE_STORE_ATTR ICACHE_RODATA_ATTR = 0.133335413135857847e-2;
double q6 ICACHE_STORE_ATTR ICACHE_RODATA_ATTR = 0.154002904409897646e-3;
double q7 ICACHE_STORE_ATTR ICACHE_RODATA_ATTR = 0.149288526805956082e-4;
double k ICACHE_STORE_ATTR ICACHE_RODATA_ATTR = 0.442695040888963407;
double pow(double x, double y)
{
double frexp(), g, ldexp(), r, u1, u2, v, w, w1, w2, y1, y2, z;
int iw1, m, p;

File diff suppressed because it is too large Load Diff

View File

@ -3,68 +3,65 @@
#include "c_types.h"
#include "c_string.h"
#include "user_interface.h"
#include "user_config.h"
// const char *lua_init_value = "print(\"Hello world\")";
const char *lua_init_value = "@init.lua";
// int c_abs(int x){
// return x>0?x:0-x;
// return x>0?x:0-x;
// }
// void c_exit(int e){
// }
const char *c_getenv(const char *__string){
if (c_strcmp(__string, "LUA_INIT") == 0){
return lua_init_value;
}
return NULL;
const char *c_getenv(const char *__string)
{
if (c_strcmp(__string, "LUA_INIT") == 0)
{
return lua_init_value;
}
return NULL;
}
// make sure there is enough memory before real malloc, otherwise malloc will panic and reset
// void *c_malloc(size_t __size){
// if(__size>system_get_free_heap_size()){
// NODE_ERR("malloc: not enough memory\n");
// return NULL;
// }
// return (void *)os_malloc(__size);
// if(__size>system_get_free_heap_size()){
// NODE_ERR("malloc: not enough memory\n");
// return NULL;
// }
// return (void *)os_malloc(__size);
// }
// void *c_zalloc(size_t __size){
// if(__size>system_get_free_heap_size()){
// NODE_ERR("zalloc: not enough memory\n");
// return NULL;
// }
// return (void *)os_zalloc(__size);
// if(__size>system_get_free_heap_size()){
// NODE_ERR("zalloc: not enough memory\n");
// return NULL;
// }
// return (void *)os_zalloc(__size);
// }
// void c_free(void *p){
// // NODE_ERR("free1: %d\n", system_get_free_heap_size());
// os_free(p);
// // NODE_ERR("-free1: %d\n", system_get_free_heap_size());
// // NODE_ERR("free1: %d\n", system_get_free_heap_size());
// os_free(p);
// // NODE_ERR("-free1: %d\n", system_get_free_heap_size());
// }
// int c_rand(void){
// int c_rand(void){
// }
// void c_srand(unsigned int __seed){
// }
// int c_atoi(const char *__nptr){
// int c_atoi(const char *__nptr){
// }
#include <_ansi.h>
//#include <reent.h>
#include <string.h>
//#include "mprec.h"
double c_strtod(const char *string, char **endPtr)
double powersOf10[] ICACHE_STORE_ATTR ICACHE_RODATA_ATTR = /* Table giving binary powers of 10. Entry */
{
int maxExponent = 511; /* Largest possible base 10 exponent. Any
* exponent larger than this will already
* produce underflow or overflow, so there's
* no need to worry about additional digits.
*/
double powersOf10[] = { /* Table giving binary powers of 10. Entry */
10., /* is 10^2^i. Used to convert decimal */
100., /* exponents into floating-point numbers. */
10., /* is 10^2^i. Used to convert decimal */
100., /* exponents into floating-point numbers. */
1.0e4,
1.0e8,
1.0e16,
@ -72,43 +69,57 @@ double c_strtod(const char *string, char **endPtr)
1.0e64,
1.0e128,
1.0e256
};
};
double c_strtod(const char *string, char **endPtr)
{
int maxExponent = 511; /* Largest possible base 10 exponent. Any
* exponent larger than this will already
* produce underflow or overflow, so there's
* no need to worry about additional digits.
*/
int sign, expSign = FALSE;
double fraction, dblExp, *d;
register const char *p;
register int c;
int exp = 0; /* Exponent read from "EX" field. */
int fracExp = 0; /* Exponent that derives from the fractional
* part. Under normal circumstatnces, it is
* the negative of the number of digits in F.
* However, if I is very long, the last digits
* of I get dropped (otherwise a long I with a
* large negative exponent could cause an
* unnecessary overflow on I alone). In this
* case, fracExp is incremented one for each
* dropped digit. */
int mantSize; /* Number of digits in mantissa. */
int decPt; /* Number of mantissa digits BEFORE decimal
* point. */
const char *pExp; /* Temporarily holds location of exponent
* in string. */
int exp = 0; /* Exponent read from "EX" field. */
int fracExp = 0; /* Exponent that derives from the fractional
* part. Under normal circumstatnces, it is
* the negative of the number of digits in F.
* However, if I is very long, the last digits
* of I get dropped (otherwise a long I with a
* large negative exponent could cause an
* unnecessary overflow on I alone). In this
* case, fracExp is incremented one for each
* dropped digit. */
int mantSize; /* Number of digits in mantissa. */
int decPt; /* Number of mantissa digits BEFORE decimal
* point. */
const char *pExp; /* Temporarily holds location of exponent
* in string. */
/*
* Strip off leading blanks and check for a sign.
*/
p = string;
while (isspace((unsigned char)(*p))) {
p += 1;
while (isspace((unsigned char)(*p)))
{
p += 1;
}
if (*p == '-') {
sign = TRUE;
p += 1;
} else {
if (*p == '+') {
p += 1;
}
sign = FALSE;
if (*p == '-')
{
sign = TRUE;
p += 1;
}
else
{
if (*p == '+')
{
p += 1;
}
sign = FALSE;
}
/*
@ -119,14 +130,16 @@ double c_strtod(const char *string, char **endPtr)
decPt = -1;
for (mantSize = 0; ; mantSize += 1)
{
c = *p;
if (!isdigit(c)) {
if ((c != '.') || (decPt >= 0)) {
break;
}
decPt = mantSize;
}
p += 1;
c = *p;
if (!isdigit(c))
{
if ((c != '.') || (decPt >= 0))
{
break;
}
decPt = mantSize;
}
p += 1;
}
/*
@ -135,49 +148,60 @@ double c_strtod(const char *string, char **endPtr)
* If the mantissa has more than 18 digits, ignore the extras, since
* they can't affect the value anyway.
*/
pExp = p;
p -= mantSize;
if (decPt < 0) {
decPt = mantSize;
} else {
mantSize -= 1; /* One of the digits was the point. */
if (decPt < 0)
{
decPt = mantSize;
}
if (mantSize > 18) {
fracExp = decPt - 18;
mantSize = 18;
} else {
fracExp = decPt - mantSize;
else
{
mantSize -= 1; /* One of the digits was the point. */
}
if (mantSize == 0) {
fraction = 0.0;
p = string;
goto done;
} else {
int frac1, frac2;
frac1 = 0;
for ( ; mantSize > 9; mantSize -= 1)
{
c = *p;
p += 1;
if (c == '.') {
c = *p;
p += 1;
}
frac1 = 10*frac1 + (c - '0');
}
frac2 = 0;
for (; mantSize > 0; mantSize -= 1)
{
c = *p;
p += 1;
if (c == '.') {
c = *p;
p += 1;
}
frac2 = 10*frac2 + (c - '0');
}
fraction = (1.0e9 * frac1) + frac2;
if (mantSize > 18)
{
fracExp = decPt - 18;
mantSize = 18;
}
else
{
fracExp = decPt - mantSize;
}
if (mantSize == 0)
{
fraction = 0.0;
p = string;
goto done;
}
else
{
int frac1, frac2;
frac1 = 0;
for ( ; mantSize > 9; mantSize -= 1)
{
c = *p;
p += 1;
if (c == '.')
{
c = *p;
p += 1;
}
frac1 = 10 * frac1 + (c - '0');
}
frac2 = 0;
for (; mantSize > 0; mantSize -= 1)
{
c = *p;
p += 1;
if (c == '.')
{
c = *p;
p += 1;
}
frac2 = 10 * frac2 + (c - '0');
}
fraction = (1.0e9 * frac1) + frac2;
}
/*
@ -185,30 +209,40 @@ double c_strtod(const char *string, char **endPtr)
*/
p = pExp;
if ((*p == 'E') || (*p == 'e')) {
p += 1;
if (*p == '-') {
expSign = TRUE;
p += 1;
} else {
if (*p == '+') {
p += 1;
}
expSign = FALSE;
}
if (!isdigit((unsigned char)(*p))) {
p = pExp;
goto done;
}
while (isdigit((unsigned char)(*p))) {
exp = exp * 10 + (*p - '0');
p += 1;
}
if ((*p == 'E') || (*p == 'e'))
{
p += 1;
if (*p == '-')
{
expSign = TRUE;
p += 1;
}
else
{
if (*p == '+')
{
p += 1;
}
expSign = FALSE;
}
if (!isdigit((unsigned char)(*p)))
{
p = pExp;
goto done;
}
while (isdigit((unsigned char)(*p)))
{
exp = exp * 10 + (*p - '0');
p += 1;
}
}
if (expSign) {
exp = fracExp - exp;
} else {
exp = fracExp + exp;
if (expSign)
{
exp = fracExp - exp;
}
else
{
exp = fracExp + exp;
}
/*
@ -217,41 +251,52 @@ double c_strtod(const char *string, char **endPtr)
* many powers of 2 of 10. Then combine the exponent with the
* fraction.
*/
if (exp < 0) {
expSign = TRUE;
exp = -exp;
} else {
expSign = FALSE;
if (exp < 0)
{
expSign = TRUE;
exp = -exp;
}
if (exp > maxExponent) {
exp = maxExponent;
// errno = ERANGE;
else
{
expSign = FALSE;
}
if (exp > maxExponent)
{
exp = maxExponent;
// errno = ERANGE;
}
dblExp = 1.0;
for (d = powersOf10; exp != 0; exp >>= 1, d += 1) {
if (exp & 01) {
dblExp *= *d;
}
for (d = powersOf10; exp != 0; exp >>= 1, d += 1)
{
if (exp & 01)
{
dblExp *= *d;
}
}
if (expSign) {
fraction /= dblExp;
} else {
fraction *= dblExp;
if (expSign)
{
fraction /= dblExp;
}
else
{
fraction *= dblExp;
}
done:
if (endPtr != NULL) {
*endPtr = (char *) p;
if (endPtr != NULL)
{
*endPtr = (char *) p;
}
if (sign) {
return -fraction;
if (sign)
{
return -fraction;
}
return fraction;
}
// long c_strtol(const char *__n, char **__end_PTR, int __base){
// long c_strtol(const char *__n, char **__end_PTR, int __base){
// }
// unsigned long c_strtoul(const char *__n, char **__end_PTR, int __base){
// }

View File

@ -601,8 +601,7 @@ extern int readline4lua(const char *prompt, char *buffer, int length);
#endif // #if !defined LUA_INTEGRAL_LONGLONG
#else
#define LUA_NUMBER_SCAN "%lf"
//#define LUA_NUMBER_FMT "%.14g"
#define LUA_NUMBER_FMT "%g"
#define LUA_NUMBER_FMT "%.14g"
#endif // #if defined LUA_NUMBER_INTEGRAL
#define lua_number2str(s,n) c_sprintf((s), LUA_NUMBER_FMT, (n))
#define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */

View File

@ -718,3 +718,32 @@ espconn_gethostbyname(struct espconn *pespconn, const char *hostname, ip_addr_t
return dns_gethostbyname(hostname, addr, found, pespconn);
}
sint8 espconn_recv_hold(struct espconn *pespconn) {
espconn_msg *pnode = NULL;
if (pespconn == NULL) {
return ESPCONN_ARG;
}
pespconn->state = ESPCONN_WRITE;
if (!espconn_find_connection(pespconn, &pnode)) {
return ESPCONN_ARG;
}
espconn_tcp_hold(pnode);
return ESPCONN_OK;
}
sint8 espconn_recv_unhold(struct espconn *pespconn) {
espconn_msg *pnode = NULL;
if (pespconn == NULL) {
return ESPCONN_ARG;
}
pespconn->state = ESPCONN_WRITE;
if (!espconn_find_connection(pespconn, &pnode)) {
return ESPCONN_ARG;
}
espconn_tcp_unhold(pnode);
return ESPCONN_OK;
}

View File

@ -948,3 +948,19 @@ sint8 ICACHE_FLASH_ATTR espconn_tcp_delete(struct espconn *pdeletecon)
return ESPCONN_ARG;
}
}
void espconn_tcp_hold(void *arg) {
espconn_msg *ptcp_sent = arg;
struct tcp_pcb *pcb = NULL;
pcb = ptcp_sent->pcommon.pcb;
pcb->hold = 1;
}
void espconn_tcp_unhold(void *arg) {
espconn_msg *ptcp_sent = arg;
struct tcp_pcb *pcb = NULL;
pcb = ptcp_sent->pcommon.pcb;
pcb->hold = 0;
}

View File

@ -1259,6 +1259,7 @@ tcp_alloc(u8_t prio)
#endif /* LWIP_TCP_KEEPALIVE */
pcb->keep_cnt_sent = 0; //<2F><><EFBFBD>ķ<EFBFBD><C4B7>ʹ<EFBFBD><CDB4><EFBFBD>
pcb->hold = 0;
}
return pcb;
}

View File

@ -1137,7 +1137,7 @@ tcp_receive(struct tcp_pcb *pcb)
/* If the incoming segment contains data, we must process it
further. */
if (tcplen > 0) {
if ((tcplen > 0) && (!pcb->hold)) {
/* This code basically does three things:
+) If the incoming segment contains data that is the next

View File

@ -125,7 +125,7 @@ static int file_remove( lua_State* L )
if( len > FS_NAME_MAX_LENGTH )
return luaL_error(L, "filename too long");
file_close(L);
SPIFFS_remove(&fs, fname);
SPIFFS_remove(&fs, (char *)fname);
return 0;
}
@ -150,6 +150,31 @@ static int file_check( lua_State* L )
}
#endif
// Lua: rename("oldname", "newname")
static int file_rename( lua_State* L )
{
size_t len;
if((FS_OPEN_OK - 1)!=file_fd){
fs_close(file_fd);
file_fd = FS_OPEN_OK - 1;
}
const char *oldname = luaL_checklstring( L, 1, &len );
if( len > FS_NAME_MAX_LENGTH )
return luaL_error(L, "filename too long");
const char *newname = luaL_checklstring( L, 2, &len );
if( len > FS_NAME_MAX_LENGTH )
return luaL_error(L, "filename too long");
if(SPIFFS_OK==myspiffs_rename( oldname, newname )){
lua_pushboolean(L, 1);
} else {
lua_pushboolean(L, 0);
}
return 1;
}
#endif
// g_read()
@ -282,6 +307,7 @@ const LUA_REG_TYPE file_map[] =
{ LSTRKEY( "seek" ), LFUNCVAL( file_seek ) },
{ LSTRKEY( "flush" ), LFUNCVAL( file_flush ) },
// { LSTRKEY( "check" ), LFUNCVAL( file_check ) },
{ LSTRKEY( "rename" ), LFUNCVAL( file_rename ) },
#endif
#if LUA_OPTIMIZE_MEMORY > 0

View File

@ -117,6 +117,15 @@
#define ROM_MODULES_BIT
#endif
#if defined(LUA_USE_MODULES_WS2812)
#define MODULES_WS2812 "ws2812"
#define ROM_MODULES_WS2812 \
_ROM(MODULES_WS2812, luaopen_ws2812, ws2812_map)
#else
#define ROM_MODULES_WS2812
#endif
#define LUA_MODULES_ROM \
ROM_MODULES_GPIO \
ROM_MODULES_PWM \
@ -131,7 +140,8 @@
ROM_MODULES_ADC \
ROM_MODULES_UART \
ROM_MODULES_OW \
ROM_MODULES_BIT
ROM_MODULES_BIT \
ROM_MODULES_WS2812
#endif

View File

@ -1193,6 +1193,54 @@ static int net_socket_send( lua_State* L )
return net_send(L, mt);
}
static int net_socket_hold( lua_State* L )
{
const char *mt = "net.socket";
struct espconn *pesp_conn = NULL;
lnet_userdata *nud;
size_t l;
nud = (lnet_userdata *)luaL_checkudata(L, 1, mt);
luaL_argcheck(L, nud, 1, "Server/Socket expected");
if(nud==NULL){
NODE_DBG("userdata is nil.\n");
return 0;
}
if(nud->pesp_conn == NULL){
NODE_DBG("nud->pesp_conn is NULL.\n");
return 0;
}
pesp_conn = nud->pesp_conn;
espconn_recv_hold(pesp_conn);
return 0;
}
static int net_socket_unhold( lua_State* L )
{
const char *mt = "net.socket";
struct espconn *pesp_conn = NULL;
lnet_userdata *nud;
size_t l;
nud = (lnet_userdata *)luaL_checkudata(L, 1, mt);
luaL_argcheck(L, nud, 1, "Server/Socket expected");
if(nud==NULL){
NODE_DBG("userdata is nil.\n");
return 0;
}
if(nud->pesp_conn == NULL){
NODE_DBG("nud->pesp_conn is NULL.\n");
return 0;
}
pesp_conn = nud->pesp_conn;
espconn_recv_unhold(pesp_conn);
return 0;
}
// Lua: socket:dns( string, function(ip) )
static int net_socket_dns( lua_State* L )
{
@ -1251,6 +1299,8 @@ static const LUA_REG_TYPE net_socket_map[] =
{ LSTRKEY( "close" ), LFUNCVAL ( net_socket_close ) },
{ LSTRKEY( "on" ), LFUNCVAL ( net_socket_on ) },
{ LSTRKEY( "send" ), LFUNCVAL ( net_socket_send ) },
{ LSTRKEY( "hold" ), LFUNCVAL ( net_socket_hold ) },
{ LSTRKEY( "unhold" ), LFUNCVAL ( net_socket_unhold ) },
{ LSTRKEY( "dns" ), LFUNCVAL ( net_socket_dns ) },
// { LSTRKEY( "delete" ), LFUNCVAL ( net_socket_delete ) },
{ LSTRKEY( "__gc" ), LFUNCVAL ( net_socket_delete ) },

82
app/modules/ws2812.c Normal file
View File

@ -0,0 +1,82 @@
#include "lualib.h"
#include "lauxlib.h"
#include "platform.h"
#include "auxmods.h"
#include "lrotable.h"
/**
* All this code is mostly from http://www.esp8266.com/viewtopic.php?f=21&t=1143&sid=a620a377672cfe9f666d672398415fcb
* from user Markus Gritsch.
* I just put this code into its own module and pushed into a forked repo,
* to easily create a pull request. Thanks to Markus Gritsch for the code.
*
*/
// ----------------------------------------------------------------------------
// -- This WS2812 code must be compiled with -O2 to get the timing right.
// -- http://wp.josh.com/2014/05/13/ws2812-neopixels-are-not-so-finicky-once-you-get-to-know-them/
// The ICACHE_FLASH_ATTR is there to trick the compiler and get the very first pulse width correct.
static void ICACHE_FLASH_ATTR send_ws_0(uint8_t gpio) {
uint8_t i;
i = 4;
while (i--)
GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, 1 << gpio);
i = 9;
while (i--)
GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, 1 << gpio);
}
static void ICACHE_FLASH_ATTR send_ws_1(uint8_t gpio) {
uint8_t i;
i = 8;
while (i--)
GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, 1 << gpio);
i = 6;
while (i--)
GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, 1 << gpio);
}
// Lua: ws2812.write(pin, "string")
// Byte triples in the string are interpreted as G R B values.
// ws2812.write(4, string.char(0, 255, 0)) uses GPIO2 and sets the first LED red.
// ws2812.write(3, string.char(0, 0, 255):rep(10)) uses GPIO0 and sets ten LEDs blue.
// ws2812.write(4, string.char(255, 0, 0, 255, 255, 255)) first LED green, second LED white.
static int ICACHE_FLASH_ATTR ws2812_write(lua_State* L) {
const uint8_t pin = luaL_checkinteger(L, 1);
size_t length;
const char *buffer = luaL_checklstring(L, 2, &length);
platform_gpio_mode(pin, PLATFORM_GPIO_OUTPUT, PLATFORM_GPIO_FLOAT);
platform_gpio_write(pin, 0);
os_delay_us(10);
os_intr_lock();
const char * const end = buffer + length;
while (buffer != end) {
uint8_t mask = 0x80;
while (mask) {
(*buffer & mask) ? send_ws_1(pin_num[pin]) : send_ws_0(pin_num[pin]);
mask >>= 1;
}
++buffer;
}
os_intr_unlock();
return 0;
}
#define MIN_OPT_LEVEL 2
#include "lrodefs.h"
const LUA_REG_TYPE ws2812_map[] =
{
{ LSTRKEY( "write" ), LFUNCVAL( ws2812_write )},
{ LNILKEY, LNILVAL}
};
LUALIB_API int luaopen_ws2812(lua_State *L) {
// TODO: Make sure that the GPIO system is initialized
LREGISTER(L, "ws2812", ws2812_map);
return 1;
}
// ----------------------------------------------------------------------------

View File

@ -25,6 +25,10 @@
#define FLASH_SEC_NUM 0x200
#elif defined(FLASH_4M)
#define FLASH_SEC_NUM 0x400
#elif defined(FLASH_8M)
#define FLASH_SEC_NUM 0x800
#elif defined(FLASH_16M)
#define FLASH_SEC_NUM 0x1000
#elif defined(FLASH_AUTOSIZE)
#define FLASH_SEC_NUM (flash_get_sec_num())
#else

View File

@ -56,6 +56,12 @@ uint32_t flash_get_size_byte(void)
case SIZE_32MBIT:
// 32Mbit, 4MByte
flash_size = 4 * 1024 * 1024;
case SIZE_64MBIT:
// 64Mbit, 8MByte
flash_size = 8 * 1024 * 1024;
case SIZE_128MBIT:
// 128Mbit, 16MByte
flash_size = 16 * 1024 * 1024;
break;
default:
// Unknown flash size, fall back mode.

View File

@ -52,6 +52,8 @@ typedef struct
SIZE_8MBIT = 2,
SIZE_16MBIT = 3,
SIZE_32MBIT = 4,
SIZE_64MBIT = 5,
SIZE_128MBIT = 6,
} size : 4;
} ICACHE_STORE_TYPEDEF_ATTR SPIFlashInfo;

View File

@ -68,6 +68,7 @@
#define fs_format myspiffs_format
#define fs_check myspiffs_check
#define fs_rename myspiffs_rename
#define FS_NAME_MAX_LENGTH SPIFFS_OBJ_NAME_LEN

View File

@ -185,6 +185,8 @@ uint32_t platform_uart_setup( unsigned id, uint32_t baud, int databits, int pari
{
switch( baud )
{
case BIT_RATE_300:
case BIT_RATE_600:
case BIT_RATE_1200:
case BIT_RATE_2400:
case BIT_RATE_4800:
@ -195,8 +197,11 @@ uint32_t platform_uart_setup( unsigned id, uint32_t baud, int databits, int pari
case BIT_RATE_74880:
case BIT_RATE_115200:
case BIT_RATE_230400:
case BIT_RATE_256000:
case BIT_RATE_460800:
case BIT_RATE_921600:
case BIT_RATE_1843200:
case BIT_RATE_3686400:
UartDev.baut_rate = baud;
break;
default:

20
app/spiffs/LICENSE Normal file
View File

@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2013-2015 Peter Andersson (pelleplutt1976<at>gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -40,7 +40,7 @@ Also, toss up some of the needed buffers:
static u8_t spiffs_work_buf[LOG_PAGE_SIZE*2];
static u8_t spiffs_fds[32*4];
static u8_t spiffs_cache[(LOG_PAGE_SIZE+32)*4];
static u8_t spiffs_cache_buf[(LOG_PAGE_SIZE+32)*4];
Now, write the my_spiffs_mount function:
@ -50,7 +50,7 @@ Now, write the my_spiffs_mount function:
cfg.phys_addr = 0; // start spiffs at start of spi flash
cfg.phys_erase_block = 65536; // according to datasheet
cfg.log_block_size = 65536; // let us not complicate things
cfg.log_block_size = LOG_PAGE_SIZE; // as we said
cfg.log_page_size = LOG_PAGE_SIZE; // as we said
cfg.hal_read_f = my_spi_read;
cfg.hal_write_f = my_spi_write;
@ -61,8 +61,8 @@ Now, write the my_spiffs_mount function:
spiffs_work_buf,
spiffs_fds,
sizeof(spiffs_fds),
spiffs_cache,
sizeof(spiffs_cache),
spiffs_cache_buf,
sizeof(spiffs_cache_buf),
0);
printf("mount res: %i\n", res);
}
@ -127,6 +127,29 @@ Compile, run, cross fingers hard, and you'll get the output:
Got errors? Check spiffs.h for error definitions to get a clue what went voodoo.
* THINGS TO CHECK
When you alter the spiffs_config values, make sure you also check the typedefs
in spiffs_config.h:
- spiffs_block_ix
- spiffs_page_ix
- spiffs_obj_id
- spiffs_span_ix
The sizes of these typedefs must not underflow, else spiffs might end up in
eternal loops. Each typedef is commented what check for.
Also, if you alter the code or just want to verify your configuration, you can
run
> make test
in the spiffs folder. This will run all testcases using the configuration in
default/spiffs_config.h and test/params_test.h. The tests are written for linux
but should run under cygwin also.
* INTEGRATING SPIFFS
In order to integrate spiffs to your embedded target, you will basically need:

View File

@ -1,36 +0,0 @@
/*
* params_test.h
*
* Created on: May 26, 2013
* Author: petera
*/
#ifndef PARAMS_TEST_H_
#define PARAMS_TEST_H_
// // total emulated spi flash size
// #define PHYS_FLASH_SIZE (16*1024*1024)
// // spiffs file system size
// #define SPIFFS_FLASH_SIZE (2*1024*1024)
// // spiffs file system offset in emulated spi flash
// #define SPIFFS_PHYS_ADDR (4*1024*1024)
// #define SECTOR_SIZE 65536
// #define LOG_BLOCK (SECTOR_SIZE*2)
// #define LOG_PAGE (SECTOR_SIZE/256)
// #define FD_BUF_SIZE 64*6
// #define CACHE_BUF_SIZE (LOG_PAGE + 32)*8
// #define ASSERT(c, m) real_assert((c),(m), __FILE__, __LINE__);
typedef signed int s32_t;
typedef unsigned int u32_t;
typedef signed short s16_t;
typedef unsigned short u16_t;
typedef signed char s8_t;
typedef unsigned char u8_t;
void real_assert(int c, const char *n, const char *file, int l);
#endif /* PARAMS_TEST_H_ */

View File

@ -98,7 +98,7 @@ int myspiffs_check( void )
}
int myspiffs_open(const char *name, int flags){
return (int)SPIFFS_open(&fs, name, (spiffs_flags)flags, 0);
return (int)SPIFFS_open(&fs, (char *)name, (spiffs_flags)flags, 0);
}
int myspiffs_close( int fd ){
@ -162,6 +162,9 @@ int myspiffs_error( int fd ){
void myspiffs_clearerr( int fd ){
fs.errno = SPIFFS_OK;
}
int myspiffs_rename( const char *old, const char *newname ){
return SPIFFS_rename(&fs, (char *)old, (char *)newname);
}
#if 0
void test_spiffs() {
char buf[12];

View File

@ -36,6 +36,7 @@
#define SPIFFS_ERR_INDEX_INVALID -10020
#define SPIFFS_ERR_NOT_WRITABLE -10021
#define SPIFFS_ERR_NOT_READABLE -10022
#define SPIFFS_ERR_CONFLICTING_NAME -10023
#define SPIFFS_ERR_INTERNAL -10050
@ -225,6 +226,7 @@ struct spiffs_dirent {
u8_t name[SPIFFS_OBJ_NAME_LEN];
spiffs_obj_type type;
u32_t size;
spiffs_page_ix pix;
};
typedef struct {
@ -265,7 +267,7 @@ void SPIFFS_unmount(spiffs *fs);
* @param path the path of the new file
* @param mode ignored, for posix compliance
*/
s32_t SPIFFS_creat(spiffs *fs, const char *path, spiffs_mode mode);
s32_t SPIFFS_creat(spiffs *fs, char *path, spiffs_mode mode);
/**
* Opens/creates a file.
@ -276,7 +278,23 @@ s32_t SPIFFS_creat(spiffs *fs, const char *path, spiffs_mode mode);
* SPIFFS_WR_ONLY, SPIFFS_RDWR, SPIFFS_DIRECT
* @param mode ignored, for posix compliance
*/
spiffs_file SPIFFS_open(spiffs *fs, const char *path, spiffs_flags flags, spiffs_mode mode);
spiffs_file SPIFFS_open(spiffs *fs, char *path, spiffs_flags flags, spiffs_mode mode);
/**
* Opens a file by given dir entry.
* Optimization purposes, when traversing a file system with SPIFFS_readdir
* a normal SPIFFS_open would need to traverse the filesystem again to find
* the file, whilst SPIFFS_open_by_dirent already knows where the file resides.
* @param fs the file system struct
* @param path the dir entry to the file
* @param flags the flags for the open command, can be combinations of
* SPIFFS_APPEND, SPIFFS_TRUNC, SPIFFS_CREAT, SPIFFS_RD_ONLY,
* SPIFFS_WR_ONLY, SPIFFS_RDWR, SPIFFS_DIRECT.
* SPIFFS_CREAT will have no effect in this case.
* @param mode ignored, for posix compliance
*/
spiffs_file SPIFFS_open_by_dirent(spiffs *fs, struct spiffs_dirent *e, spiffs_flags flags, spiffs_mode mode);
/**
* Reads from given filehandle.
@ -314,7 +332,7 @@ s32_t SPIFFS_lseek(spiffs *fs, spiffs_file fh, s32_t offs, int whence);
* @param fs the file system struct
* @param path the path of the file to remove
*/
s32_t SPIFFS_remove(spiffs *fs, const char *path);
s32_t SPIFFS_remove(spiffs *fs, char *path);
/**
* Removes a file by filehandle
@ -329,7 +347,7 @@ s32_t SPIFFS_fremove(spiffs *fs, spiffs_file fh);
* @param path the path of the file to stat
* @param s the stat struct to populate
*/
s32_t SPIFFS_stat(spiffs *fs, const char *path, spiffs_stat *s);
s32_t SPIFFS_stat(spiffs *fs, char *path, spiffs_stat *s);
/**
* Gets file status by filehandle
@ -353,6 +371,14 @@ s32_t SPIFFS_fflush(spiffs *fs, spiffs_file fh);
*/
void SPIFFS_close(spiffs *fs, spiffs_file fh);
/**
* Renames a file
* @param fs the file system struct
* @param old path of file to rename
* @param new new path of file
*/
s32_t SPIFFS_rename(spiffs *fs, char *old, char *new);
/**
* Returns last error of last file operation.
* @param fs the file system struct
@ -368,7 +394,7 @@ s32_t SPIFFS_errno(spiffs *fs);
* @param name the name of the directory
* @param d pointer the directory stream to be populated
*/
spiffs_DIR *SPIFFS_opendir(spiffs *fs, const char *name, spiffs_DIR *d);
spiffs_DIR *SPIFFS_opendir(spiffs *fs, char *name, spiffs_DIR *d);
/**
* Closes a directory stream
@ -438,5 +464,6 @@ int myspiffs_flush( int fd );
int myspiffs_error( int fd );
void myspiffs_clearerr( int fd );
int myspiffs_check( void );
int myspiffs_rename( const char *old, const char *newname );
#endif /* SPIFFS_H_ */

View File

@ -124,6 +124,7 @@ s32_t spiffs_phys_rd(
u32_t addr,
u32_t len,
u8_t *dst) {
(void)fh;
s32_t res = SPIFFS_OK;
spiffs_cache *cache = spiffs_get_cache(fs);
spiffs_cache_page *cp = spiffs_cache_page_get(fs, SPIFFS_PADDR_TO_PAGE(fs, addr));
@ -172,6 +173,7 @@ s32_t spiffs_phys_wr(
u32_t addr,
u32_t len,
u8_t *src) {
(void)fh;
spiffs_page_ix pix = SPIFFS_PADDR_TO_PAGE(fs, addr);
spiffs_cache *cache = spiffs_get_cache(fs);
spiffs_cache_page *cp = spiffs_cache_page_get(fs, pix);
@ -249,7 +251,7 @@ spiffs_cache_page *spiffs_cache_page_allocate_by_fd(spiffs *fs, spiffs_fd *fd) {
// unrefers all fds that this cache page refers to and releases the cache page
void spiffs_cache_fd_release(spiffs *fs, spiffs_cache_page *cp) {
if (cp == 0) return;
int i;
u32_t i;
spiffs_fd *fds = (spiffs_fd *)fs->fd_space;
for (i = 0; i < fs->fd_count; i++) {
spiffs_fd *cur_fd = &fds[i];
@ -282,7 +284,7 @@ void spiffs_cache_init(spiffs *fs) {
spiffs_cache cache;
c_memset(&cache, 0, sizeof(spiffs_cache));
cache.cpage_count = cache_entries;
cache.cpages = (u8_t *)(fs->cache) + sizeof(spiffs_cache);
cache.cpages = (u8_t *)((u8_t *)fs->cache + sizeof(spiffs_cache));
cache.cpage_use_map = 0xffffffff;
cache.cpage_use_mask = cache_mask;

View File

@ -156,6 +156,8 @@ static s32_t spiffs_delete_obj_lazy(spiffs *fs, spiffs_obj_id obj_id) {
// validates the given look up entry
static s32_t spiffs_lookup_check_validate(spiffs *fs, spiffs_obj_id lu_obj_id, spiffs_page_header *p_hdr,
spiffs_page_ix cur_pix, spiffs_block_ix cur_block, int cur_entry, int *reload_lu) {
(void)cur_block;
(void)cur_entry;
u8_t delete_page = 0;
s32_t res = SPIFFS_OK;
spiffs_page_ix objix_pix;
@ -327,7 +329,7 @@ static s32_t spiffs_lookup_check_validate(spiffs *fs, spiffs_obj_id lu_obj_id, s
} else if (((lu_obj_id & SPIFFS_OBJ_ID_IX_FLAG) && (p_hdr->flags & SPIFFS_PH_FLAG_INDEX)) ||
((lu_obj_id & SPIFFS_OBJ_ID_IX_FLAG) == 0 && (p_hdr->flags & SPIFFS_PH_FLAG_INDEX) == 0)) {
SPIFFS_CHECK_DBG("LU: %04x lu/page index marking differ\n", cur_pix);
spiffs_page_ix data_pix, objix_pix;
spiffs_page_ix data_pix, objix_pix_d;
// see if other data page exists for given obj id and span index
res = spiffs_obj_lu_find_id_and_span(fs, lu_obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, p_hdr->span_ix, cur_pix, &data_pix);
if (res == SPIFFS_ERR_NOT_FOUND) {
@ -336,20 +338,20 @@ static s32_t spiffs_lookup_check_validate(spiffs *fs, spiffs_obj_id lu_obj_id, s
}
SPIFFS_CHECK_RES(res);
// see if other object index exists for given obj id and span index
res = spiffs_obj_lu_find_id_and_span(fs, lu_obj_id | SPIFFS_OBJ_ID_IX_FLAG, p_hdr->span_ix, cur_pix, &objix_pix);
res = spiffs_obj_lu_find_id_and_span(fs, lu_obj_id | SPIFFS_OBJ_ID_IX_FLAG, p_hdr->span_ix, cur_pix, &objix_pix_d);
if (res == SPIFFS_ERR_NOT_FOUND) {
res = SPIFFS_OK;
objix_pix = 0;
objix_pix_d = 0;
}
SPIFFS_CHECK_RES(res);
delete_page = 1;
// if other data page exists and object index exists, just delete page
if (data_pix && objix_pix) {
if (data_pix && objix_pix_d) {
SPIFFS_CHECK_DBG("LU: FIXUP: other index and data page exists, simply remove\n");
} else
// if only data page exists, make this page index
if (data_pix && objix_pix == 0) {
if (data_pix && objix_pix_d == 0) {
SPIFFS_CHECK_DBG("LU: FIXUP: other data page exists, make this index\n");
if (fs->check_cb_f) fs->check_cb_f(SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_INDEX, lu_obj_id, p_hdr->span_ix);
spiffs_page_header new_ph;
@ -365,7 +367,7 @@ static s32_t spiffs_lookup_check_validate(spiffs *fs, spiffs_obj_id lu_obj_id, s
SPIFFS_CHECK_RES(res);
} else
// if only index exists, make data page
if (data_pix == 0 && objix_pix) {
if (data_pix == 0 && objix_pix_d) {
SPIFFS_CHECK_DBG("LU: FIXUP: other index page exists, make this data\n");
if (fs->check_cb_f) fs->check_cb_f(SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_LOOKUP, lu_obj_id, p_hdr->span_ix);
spiffs_page_header new_ph;
@ -426,6 +428,8 @@ static s32_t spiffs_lookup_check_validate(spiffs *fs, spiffs_obj_id lu_obj_id, s
static s32_t spiffs_lookup_check_v(spiffs *fs, spiffs_obj_id obj_id, spiffs_block_ix cur_block, int cur_entry,
u32_t user_data, void *user_p) {
(void)user_data;
(void)user_p;
s32_t res = SPIFFS_OK;
spiffs_page_header p_hdr;
spiffs_page_ix cur_pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, cur_block, cur_entry);
@ -453,6 +457,7 @@ static s32_t spiffs_lookup_check_v(spiffs *fs, spiffs_obj_id obj_id, spiffs_bloc
// Scans all object look up. For each entry, corresponding page header is checked for validity.
// If an object index header page is found, this is also checked
s32_t spiffs_lookup_consistency_check(spiffs *fs, u8_t check_all_objects) {
(void)check_all_objects;
s32_t res = SPIFFS_OK;
if (fs->check_cb_f) fs->check_cb_f(SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_PROGRESS, 0, 0);
@ -689,8 +694,8 @@ static s32_t spiffs_page_consistency_check_i(spiffs *fs) {
spiffs_page_ix objix_pix;
spiffs_page_ix rpix;
int byte_ix;
int bit_ix;
u32_t byte_ix;
u8_t bit_ix;
for (byte_ix = 0; !restart && byte_ix < SPIFFS_CFG_LOG_PAGE_SZ(fs); byte_ix++) {
for (bit_ix = 0; !restart && bit_ix < 8/bits; bit_ix ++) {
u8_t bitmask = (fs->work[byte_ix] >> (bit_ix * bits)) & 0x7;
@ -838,7 +843,7 @@ s32_t spiffs_page_consistency_check(spiffs *fs) {
// searches for given object id in temporary object id index,
// returns the index or -1
static int spiffs_object_index_search(spiffs *fs, spiffs_obj_id obj_id) {
int i;
u32_t i;
spiffs_obj_id *obj_table = (spiffs_obj_id *)fs->work;
obj_id &= ~SPIFFS_OBJ_ID_IX_FLAG;
for (i = 0; i < SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id); i++) {
@ -849,8 +854,9 @@ static int spiffs_object_index_search(spiffs *fs, spiffs_obj_id obj_id) {
return -1;
}
s32_t spiffs_object_index_consistency_check_v(spiffs *fs, spiffs_obj_id obj_id, spiffs_block_ix cur_block,
static s32_t spiffs_object_index_consistency_check_v(spiffs *fs, spiffs_obj_id obj_id, spiffs_block_ix cur_block,
int cur_entry, u32_t user_data, void *user_p) {
(void)user_data;
s32_t res_c = SPIFFS_VIS_COUNTINUE;
s32_t res = SPIFFS_OK;
u32_t *log_ix = (u32_t *)user_p;

View File

@ -35,7 +35,7 @@ static s32_t spiffs_gc_erase_block(
#if SPIFFS_CACHE
{
int i;
u32_t i;
for (i = 0; i < SPIFFS_PAGES_PER_BLOCK(fs); i++) {
spiffs_cache_drop_page(fs, SPIFFS_PAGE_FOR_BLOCK(fs, bix) + i);
}
@ -61,7 +61,7 @@ s32_t spiffs_gc_quick(
fs->stats_gc_runs++;
#endif
u32_t entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id));
int entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id));
// find fully deleted blocks
// check each block
@ -70,29 +70,33 @@ s32_t spiffs_gc_quick(
int obj_lookup_page = 0;
// check each object lookup page
while (res == SPIFFS_OK && obj_lookup_page < SPIFFS_OBJ_LOOKUP_PAGES(fs)) {
while (res == SPIFFS_OK && obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs)) {
int entry_offset = obj_lookup_page * entries_per_page;
res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ,
0, cur_block_addr + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work);
// check each entry
while (res == SPIFFS_OK &&
cur_entry - entry_offset < entries_per_page && cur_entry < SPIFFS_PAGES_PER_BLOCK(fs)-SPIFFS_OBJ_LOOKUP_PAGES(fs)) {
cur_entry - entry_offset < entries_per_page &&
cur_entry < (int)(SPIFFS_PAGES_PER_BLOCK(fs)-SPIFFS_OBJ_LOOKUP_PAGES(fs))) {
spiffs_obj_id obj_id = obj_lu_buf[cur_entry-entry_offset];
if (obj_id == SPIFFS_OBJ_ID_DELETED) {
deleted_pages_in_block++;
} else if (obj_id == SPIFFS_OBJ_ID_FREE) {
// kill scan, go for next block
obj_lookup_page = SPIFFS_OBJ_LOOKUP_PAGES(fs);
res = 1; // kill object lu loop
break;
} else {
// kill scan, go for next block
obj_lookup_page = SPIFFS_OBJ_LOOKUP_PAGES(fs);
res = 1; // kill object lu loop
break;
}
cur_entry++;
} // per entry
obj_lookup_page++;
} // per object lookup page
if (res == 1) res = SPIFFS_OK;
if (res == SPIFFS_OK && deleted_pages_in_block == SPIFFS_PAGES_PER_BLOCK(fs)-SPIFFS_OBJ_LOOKUP_PAGES(fs)) {
// found a fully deleted block
@ -184,20 +188,20 @@ s32_t spiffs_gc_erase_page_stats(
spiffs_block_ix bix) {
s32_t res = SPIFFS_OK;
int obj_lookup_page = 0;
u32_t entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id));
int entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id));
spiffs_obj_id *obj_lu_buf = (spiffs_obj_id *)fs->lu_work;
int cur_entry = 0;
u32_t dele = 0;
u32_t allo = 0;
// check each object lookup page
while (res == SPIFFS_OK && obj_lookup_page < SPIFFS_OBJ_LOOKUP_PAGES(fs)) {
while (res == SPIFFS_OK && obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs)) {
int entry_offset = obj_lookup_page * entries_per_page;
res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ,
0, bix * SPIFFS_CFG_LOG_BLOCK_SZ(fs) + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work);
// check each entry
while (res == SPIFFS_OK &&
cur_entry - entry_offset < entries_per_page && cur_entry < SPIFFS_PAGES_PER_BLOCK(fs)-SPIFFS_OBJ_LOOKUP_PAGES(fs)) {
cur_entry - entry_offset < entries_per_page && cur_entry < (int)(SPIFFS_PAGES_PER_BLOCK(fs)-SPIFFS_OBJ_LOOKUP_PAGES(fs))) {
spiffs_obj_id obj_id = obj_lu_buf[cur_entry-entry_offset];
if (obj_id == SPIFFS_OBJ_ID_FREE) {
} else if (obj_id == SPIFFS_OBJ_ID_DELETED) {
@ -239,7 +243,7 @@ s32_t spiffs_gc_find_candidate(
*block_candidates = cand_blocks;
u32_t entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id));
int entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id));
// check each block
while (res == SPIFFS_OK && blocks--) {
@ -248,16 +252,18 @@ s32_t spiffs_gc_find_candidate(
int obj_lookup_page = 0;
// check each object lookup page
while (res == SPIFFS_OK && obj_lookup_page < SPIFFS_OBJ_LOOKUP_PAGES(fs)) {
while (res == SPIFFS_OK && obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs)) {
int entry_offset = obj_lookup_page * entries_per_page;
res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ,
0, cur_block_addr + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work);
// check each entry
while (res == SPIFFS_OK &&
cur_entry - entry_offset < entries_per_page && cur_entry < SPIFFS_PAGES_PER_BLOCK(fs)-SPIFFS_OBJ_LOOKUP_PAGES(fs)) {
cur_entry - entry_offset < entries_per_page &&
cur_entry < (int)(SPIFFS_PAGES_PER_BLOCK(fs)-SPIFFS_OBJ_LOOKUP_PAGES(fs))) {
spiffs_obj_id obj_id = obj_lu_buf[cur_entry-entry_offset];
if (obj_id == SPIFFS_OBJ_ID_FREE) {
// when a free entry is encountered, scan logic ensures that all following entries are free also
res = 1; // kill object lu loop
break;
} else if (obj_id == SPIFFS_OBJ_ID_DELETED) {
deleted_pages_in_block++;
@ -268,6 +274,7 @@ s32_t spiffs_gc_find_candidate(
} // per entry
obj_lookup_page++;
} // per object lookup page
if (res == 1) res = SPIFFS_OK;
// calculate score and insert into candidate table
// stoneage sort, but probably not so many blocks
@ -352,7 +359,7 @@ typedef struct {
//
s32_t spiffs_gc_clean(spiffs *fs, spiffs_block_ix bix) {
s32_t res = SPIFFS_OK;
u32_t entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id));
int entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id));
int cur_entry = 0;
spiffs_obj_id *obj_lu_buf = (spiffs_obj_id *)fs->lu_work;
spiffs_gc gc;
@ -380,14 +387,14 @@ s32_t spiffs_gc_clean(spiffs *fs, spiffs_block_ix bix) {
int obj_lookup_page = cur_entry / entries_per_page;
u8_t scan = 1;
// check each object lookup page
while (scan && res == SPIFFS_OK && obj_lookup_page < SPIFFS_OBJ_LOOKUP_PAGES(fs)) {
while (scan && res == SPIFFS_OK && obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs)) {
int entry_offset = obj_lookup_page * entries_per_page;
res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ,
0, bix * SPIFFS_CFG_LOG_BLOCK_SZ(fs) + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page),
SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work);
// check each entry
while (scan && res == SPIFFS_OK &&
cur_entry - entry_offset < entries_per_page && cur_entry < SPIFFS_PAGES_PER_BLOCK(fs)-SPIFFS_OBJ_LOOKUP_PAGES(fs)) {
cur_entry - entry_offset < entries_per_page && cur_entry < (int)(SPIFFS_PAGES_PER_BLOCK(fs)-SPIFFS_OBJ_LOOKUP_PAGES(fs))) {
spiffs_obj_id obj_id = obj_lu_buf[cur_entry-entry_offset];
cur_pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, cur_entry);
@ -526,7 +533,6 @@ s32_t spiffs_gc_clean(spiffs *fs, spiffs_block_ix bix) {
SPIFFS_CHECK_RES(res);
} else {
// store object index page
spiffs_page_ix new_objix_pix;
res = spiffs_page_move(fs, 0, fs->work, gc.cur_obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, gc.cur_objix_pix, &new_objix_pix);
SPIFFS_GC_DBG("gc_clean: MOVE_DATA store modified objix page, %04x:%04x\n", new_objix_pix, objix->p_hdr.span_ix);
SPIFFS_CHECK_RES(res);

View File

@ -51,7 +51,9 @@ s32_t SPIFFS_mount(spiffs *fs, spiffs_config *config, u8_t *work,
addr_lsb = (u8_t)(((u32_t)cache) & (ptr_size-1));
// #pragma GCC diagnostic pop
if (addr_lsb) {
cache = (u8_t *)cache + (ptr_size-addr_lsb);
u8_t *cache_8 = (u8_t *)cache;
cache_8 += (ptr_size-addr_lsb);
cache = cache_8;
cache_size -= (ptr_size-addr_lsb);
}
if (cache_size & (ptr_size-1)) {
@ -85,7 +87,7 @@ s32_t SPIFFS_mount(spiffs *fs, spiffs_config *config, u8_t *work,
void SPIFFS_unmount(spiffs *fs) {
if (!SPIFFS_CHECK_MOUNT(fs)) return;
SPIFFS_LOCK(fs);
int i;
u32_t i;
spiffs_fd *fds = (spiffs_fd *)fs->fd_space;
for (i = 0; i < fs->fd_count; i++) {
spiffs_fd *cur_fd = &fds[i];
@ -104,21 +106,23 @@ s32_t SPIFFS_errno(spiffs *fs) {
return fs->errno;
}
s32_t SPIFFS_creat(spiffs *fs, const char *path, spiffs_mode mode) {
s32_t SPIFFS_creat(spiffs *fs, char *path, spiffs_mode mode) {
(void)mode;
SPIFFS_API_CHECK_MOUNT(fs);
SPIFFS_LOCK(fs);
spiffs_obj_id obj_id;
s32_t res;
res = spiffs_obj_lu_find_free_obj_id(fs, &obj_id);
res = spiffs_obj_lu_find_free_obj_id(fs, &obj_id, (u8_t *)path);
SPIFFS_API_CHECK_RES_UNLOCK(fs, res);
res = spiffs_object_create(fs, obj_id, (u8_t*)path, SPIFFS_TYPE_FILE, 0);
res = spiffs_object_create(fs, obj_id, (u8_t *)path, SPIFFS_TYPE_FILE, 0);
SPIFFS_API_CHECK_RES_UNLOCK(fs, res);
SPIFFS_UNLOCK(fs);
return 0;
}
spiffs_file SPIFFS_open(spiffs *fs, const char *path, spiffs_flags flags, spiffs_mode mode) {
spiffs_file SPIFFS_open(spiffs *fs, char *path, spiffs_flags flags, spiffs_mode mode) {
(void)mode;
SPIFFS_API_CHECK_MOUNT(fs);
SPIFFS_LOCK(fs);
@ -138,7 +142,8 @@ spiffs_file SPIFFS_open(spiffs *fs, const char *path, spiffs_flags flags, spiffs
if ((flags & SPIFFS_CREAT) && res == SPIFFS_ERR_NOT_FOUND) {
spiffs_obj_id obj_id;
res = spiffs_obj_lu_find_free_obj_id(fs, &obj_id);
// no need to enter conflicting name here, already looked for it above
res = spiffs_obj_lu_find_free_obj_id(fs, &obj_id, 0);
if (res < SPIFFS_OK) {
spiffs_fd_return(fs, fd->file_nbr);
}
@ -155,7 +160,36 @@ spiffs_file SPIFFS_open(spiffs *fs, const char *path, spiffs_flags flags, spiffs
}
SPIFFS_API_CHECK_RES_UNLOCK(fs, res);
}
res = spiffs_object_open_by_page(fs, pix, fd, flags, flags);
res = spiffs_object_open_by_page(fs, pix, fd, flags, mode);
if (res < SPIFFS_OK) {
spiffs_fd_return(fs, fd->file_nbr);
}
SPIFFS_API_CHECK_RES_UNLOCK(fs, res);
if (flags & SPIFFS_TRUNC) {
res = spiffs_object_truncate(fd, 0, 0);
if (res < SPIFFS_OK) {
spiffs_fd_return(fs, fd->file_nbr);
}
SPIFFS_API_CHECK_RES_UNLOCK(fs, res);
}
fd->fdoffset = 0;
SPIFFS_UNLOCK(fs);
return fd->file_nbr;
}
spiffs_file SPIFFS_open_by_dirent(spiffs *fs, struct spiffs_dirent *e, spiffs_flags flags, spiffs_mode mode) {
SPIFFS_API_CHECK_MOUNT(fs);
SPIFFS_LOCK(fs);
spiffs_fd *fd;
s32_t res = spiffs_fd_find_new(fs, &fd);
SPIFFS_API_CHECK_RES_UNLOCK(fs, res);
res = spiffs_object_open_by_page(fs, e->pix, fd, flags, mode);
if (res < SPIFFS_OK) {
spiffs_fd_return(fs, fd->file_nbr);
}
@ -201,12 +235,13 @@ s32_t SPIFFS_read(spiffs *fs, spiffs_file fh, void *buf, u32_t len) {
SPIFFS_API_CHECK_RES_UNLOCK(fs, SPIFFS_ERR_END_OF_OBJECT);
}
res = spiffs_object_read(fd, fd->fdoffset, avail, (u8_t*)buf);
if (res == SPIFFS_OK) {
if (res == SPIFFS_ERR_END_OF_OBJECT) {
fd->fdoffset += avail;
SPIFFS_UNLOCK(fs);
return avail;
} else {
SPIFFS_API_CHECK_RES_UNLOCK(fs, res);
len = avail;
}
} else {
// reading within file size
@ -221,14 +256,17 @@ s32_t SPIFFS_read(spiffs *fs, spiffs_file fh, void *buf, u32_t len) {
}
static s32_t spiffs_hydro_write(spiffs *fs, spiffs_fd *fd, void *buf, u32_t offset, s32_t len) {
(void)fs;
s32_t res = SPIFFS_OK;
s32_t remaining = len;
if (fd->size != SPIFFS_UNDEFINED_LEN && offset < fd->size) {
s32_t m_len = MIN(fd->size - offset, len);
s32_t m_len = MIN((s32_t)(fd->size - offset), len);
res = spiffs_object_modify(fd, offset, (u8_t *)buf, m_len);
SPIFFS_CHECK_RES(res);
remaining -= m_len;
buf = (u8_t *)buf + m_len;
u8_t *buf_8 = (u8_t *)buf;
buf_8 += m_len;
buf = buf_8;
offset += m_len;
}
if (remaining > 0) {
@ -280,7 +318,7 @@ s32_t SPIFFS_write(spiffs *fs, spiffs_file fh, void *buf, u32_t len) {
#if SPIFFS_CACHE_WR
if ((fd->flags & SPIFFS_DIRECT) == 0) {
if (len < SPIFFS_CFG_LOG_PAGE_SZ(fs)) {
if (len < (s32_t)SPIFFS_CFG_LOG_PAGE_SZ(fs)) {
// small write, try to cache it
u8_t alloc_cpage = 1;
if (fd->cache_page) {
@ -379,7 +417,7 @@ s32_t SPIFFS_lseek(spiffs *fs, spiffs_file fh, s32_t offs, int whence) {
break;
}
if (offs > fd->size) {
if (offs > (s32_t)fd->size) {
res = SPIFFS_ERR_END_OF_OBJECT;
}
SPIFFS_API_CHECK_RES_UNLOCK(fs, res);
@ -401,7 +439,7 @@ s32_t SPIFFS_lseek(spiffs *fs, spiffs_file fh, s32_t offs, int whence) {
return 0;
}
s32_t SPIFFS_remove(spiffs *fs, const char *path) {
s32_t SPIFFS_remove(spiffs *fs, char *path) {
SPIFFS_API_CHECK_MOUNT(fs);
SPIFFS_LOCK(fs);
@ -412,7 +450,7 @@ s32_t SPIFFS_remove(spiffs *fs, const char *path) {
res = spiffs_fd_find_new(fs, &fd);
SPIFFS_API_CHECK_RES_UNLOCK(fs, res);
res = spiffs_object_find_object_index_header_by_name(fs, (u8_t*)path, &pix);
res = spiffs_object_find_object_index_header_by_name(fs, (u8_t *)path, &pix);
if (res != SPIFFS_OK) {
spiffs_fd_return(fs, fd->file_nbr);
}
@ -482,7 +520,7 @@ static s32_t spiffs_stat_pix(spiffs *fs, spiffs_page_ix pix, spiffs_file fh, spi
return res;
}
s32_t SPIFFS_stat(spiffs *fs, const char *path, spiffs_stat *s) {
s32_t SPIFFS_stat(spiffs *fs, char *path, spiffs_stat *s) {
SPIFFS_API_CHECK_MOUNT(fs);
SPIFFS_LOCK(fs);
@ -580,7 +618,48 @@ void SPIFFS_close(spiffs *fs, spiffs_file fh) {
SPIFFS_UNLOCK(fs);
}
spiffs_DIR *SPIFFS_opendir(spiffs *fs, const char *name, spiffs_DIR *d) {
s32_t SPIFFS_rename(spiffs *fs, char *old, char *new) {
SPIFFS_API_CHECK_MOUNT(fs);
SPIFFS_LOCK(fs);
spiffs_page_ix pix_old, pix_dummy;
spiffs_fd *fd;
s32_t res = spiffs_object_find_object_index_header_by_name(fs, (u8_t*)old, &pix_old);
SPIFFS_API_CHECK_RES_UNLOCK(fs, res);
res = spiffs_object_find_object_index_header_by_name(fs, (u8_t*)new, &pix_dummy);
if (res == SPIFFS_ERR_NOT_FOUND) {
res = SPIFFS_OK;
} else if (res == SPIFFS_OK) {
res = SPIFFS_ERR_CONFLICTING_NAME;
}
SPIFFS_API_CHECK_RES_UNLOCK(fs, res);
res = spiffs_fd_find_new(fs, &fd);
SPIFFS_API_CHECK_RES_UNLOCK(fs, res);
res = spiffs_object_open_by_page(fs, pix_old, fd, 0, 0);
if (res != SPIFFS_OK) {
spiffs_fd_return(fs, fd->file_nbr);
}
SPIFFS_API_CHECK_RES_UNLOCK(fs, res);
res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, fd->objix_hdr_pix, 0, (u8_t*)new,
0, &pix_dummy);
if (res != SPIFFS_OK) {
spiffs_fd_return(fs, fd->file_nbr);
}
SPIFFS_API_CHECK_RES_UNLOCK(fs, res);
SPIFFS_UNLOCK(fs);
return res;
}
spiffs_DIR *SPIFFS_opendir(spiffs *fs, char *name, spiffs_DIR *d) {
(void)name;
if (!SPIFFS_CHECK_MOUNT(fs)) {
fs->errno = SPIFFS_ERR_NOT_MOUNTED;
return 0;
@ -598,6 +677,7 @@ static s32_t spiffs_read_dir_v(
int ix_entry,
u32_t user_data,
void *user_p) {
(void)user_data;
s32_t res;
spiffs_page_object_ix_header objix_hdr;
if (obj_id == SPIFFS_OBJ_ID_FREE || obj_id == SPIFFS_OBJ_ID_DELETED ||
@ -618,6 +698,7 @@ static s32_t spiffs_read_dir_v(
strcpy((char *)e->name, (char *)objix_hdr.name);
e->type = objix_hdr.type;
e->size = objix_hdr.size == SPIFFS_UNDEFINED_LEN ? 0 : objix_hdr.size;
e->pix = pix;
return SPIFFS_OK;
}
@ -670,11 +751,11 @@ s32_t SPIFFS_check(spiffs *fs) {
res = spiffs_lookup_consistency_check(fs, 0);
res = spiffs_object_index_consistency_check(fs);
// NODE_ERR("before spiffs_object_index_consistency_check\n");
res = spiffs_page_consistency_check(fs);
// NODE_ERR("spiffs_page_consistency_check\n");
res = spiffs_obj_lu_scan(fs);
// NODE_ERR("spiffs_obj_lu_scan\n");
SPIFFS_UNLOCK(fs);
return res;
}
@ -723,7 +804,7 @@ s32_t SPIFFS_vis(spiffs *fs) {
SPIFFS_API_CHECK_MOUNT(fs);
SPIFFS_LOCK(fs);
u32_t entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id));
int entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id));
spiffs_obj_id *obj_lu_buf = (spiffs_obj_id *)fs->lu_work;
spiffs_block_ix bix = 0;
@ -732,13 +813,13 @@ s32_t SPIFFS_vis(spiffs *fs) {
int obj_lookup_page = 0;
int cur_entry = 0;
while (res == SPIFFS_OK && obj_lookup_page < SPIFFS_OBJ_LOOKUP_PAGES(fs)) {
while (res == SPIFFS_OK && obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs)) {
int entry_offset = obj_lookup_page * entries_per_page;
res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ,
0, bix * SPIFFS_CFG_LOG_BLOCK_SZ(fs) + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work);
// check each entry
while (res == SPIFFS_OK &&
cur_entry - entry_offset < entries_per_page && cur_entry < SPIFFS_PAGES_PER_BLOCK(fs)-SPIFFS_OBJ_LOOKUP_PAGES(fs)) {
cur_entry - entry_offset < entries_per_page && cur_entry < (int)(SPIFFS_PAGES_PER_BLOCK(fs)-SPIFFS_OBJ_LOOKUP_PAGES(fs))) {
spiffs_obj_id obj_id = obj_lu_buf[cur_entry-entry_offset];
if (cur_entry == 0) {
spiffs_printf("%4i ", bix);

View File

@ -134,10 +134,10 @@ s32_t spiffs_obj_lu_find_entry_visitor(
spiffs_obj_id *obj_lu_buf = (spiffs_obj_id *)fs->lu_work;
int cur_entry = starting_lu_entry;
u32_t entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id));
int entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id));
// wrap initial
if (cur_entry >= SPIFFS_OBJ_LOOKUP_MAX_ENTRIES(fs) - 1) {
if (cur_entry >= (int)SPIFFS_OBJ_LOOKUP_MAX_ENTRIES(fs) - 1) {
cur_entry = 0;
cur_block++;
cur_block_addr = cur_block * SPIFFS_CFG_LOG_BLOCK_SZ(fs);
@ -152,14 +152,14 @@ s32_t spiffs_obj_lu_find_entry_visitor(
while (res == SPIFFS_OK && entry_count > 0) {
int obj_lookup_page = cur_entry / entries_per_page;
// check each object lookup page
while (res == SPIFFS_OK && obj_lookup_page < SPIFFS_OBJ_LOOKUP_PAGES(fs)) {
while (res == SPIFFS_OK && obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs)) {
int entry_offset = obj_lookup_page * entries_per_page;
res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ,
0, cur_block_addr + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work);
// check each entry
while (res == SPIFFS_OK &&
cur_entry - entry_offset < entries_per_page && // for non-last obj lookup pages
cur_entry < SPIFFS_OBJ_LOOKUP_MAX_ENTRIES(fs)) // for last obj lookup page
cur_entry < (int)SPIFFS_OBJ_LOOKUP_MAX_ENTRIES(fs)) // for last obj lookup page
{
if ((flags & SPIFFS_VIS_CHECK_ID) == 0 || obj_lu_buf[cur_entry-entry_offset] == obj_id) {
if (block_ix) *block_ix = cur_block;
@ -221,6 +221,9 @@ static s32_t spiffs_obj_lu_scan_v(
int ix_entry,
u32_t user_data,
void *user_p) {
(void)bix;
(void)user_data;
(void)user_p;
if (obj_id == SPIFFS_OBJ_ID_FREE) {
if (ix_entry == 0) {
fs->free_blocks++;
@ -714,9 +717,10 @@ void spiffs_cb_object_event(
spiffs_span_ix spix,
spiffs_page_ix new_pix,
u32_t new_size) {
(void)fd;
// update index caches in all file descriptors
obj_id &= ~SPIFFS_OBJ_ID_IX_FLAG;
int i;
u32_t i;
spiffs_fd *fds = (spiffs_fd *)fs->fd_space;
for (i = 0; i < fs->fd_count; i++) {
spiffs_fd *cur_fd = &fds[i];
@ -769,6 +773,7 @@ s32_t spiffs_object_open_by_page(
spiffs_fd *fd,
spiffs_flags flags,
spiffs_mode mode) {
(void)mode;
s32_t res = SPIFFS_OK;
spiffs_page_object_ix_header oix_hdr;
spiffs_obj_id obj_id;
@ -1238,6 +1243,7 @@ static s32_t spiffs_object_find_object_index_header_by_name_v(
int ix_entry,
u32_t user_data,
void *user_p) {
(void)user_data;
s32_t res;
spiffs_page_object_ix_header objix_hdr;
spiffs_page_ix pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, ix_entry);
@ -1307,7 +1313,7 @@ s32_t spiffs_object_truncate(
spiffs_page_ix objix_pix = fd->objix_hdr_pix;
spiffs_span_ix data_spix = (fd->size > 0 ? fd->size-1 : 0) / SPIFFS_DATA_PAGE_SIZE(fs);
u32_t cur_size = fd->size == SPIFFS_UNDEFINED_LEN ? 0 : fd->size ;
u32_t cur_size = fd->size == (u32_t)SPIFFS_UNDEFINED_LEN ? 0 : fd->size ;
spiffs_span_ix cur_objix_spix = 0;
spiffs_span_ix prev_objix_spix = (spiffs_span_ix)-1;
spiffs_page_object_ix_header *objix_hdr = (spiffs_page_object_ix_header *)fs->work;
@ -1584,16 +1590,36 @@ typedef struct {
spiffs_obj_id min_obj_id;
spiffs_obj_id max_obj_id;
u32_t compaction;
const u8_t *conflicting_name;
} spiffs_free_obj_id_state;
static s32_t spiffs_obj_lu_find_free_obj_id_bitmap_v(spiffs *fs, spiffs_obj_id id, spiffs_block_ix bix, int ix_entry,
u32_t user_data, void *user_p) {
if (id != SPIFFS_OBJ_ID_FREE && id != SPIFFS_OBJ_ID_DELETED) {
spiffs_obj_id min_obj_id = user_data;
u8_t *conflicting_name = (u8_t *)user_p;
// if conflicting name parameter is given, also check if this name is found in object index hdrs
if (conflicting_name && (id & SPIFFS_OBJ_ID_IX_FLAG)) {
spiffs_page_ix pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, ix_entry);
int res;
spiffs_page_object_ix_header objix_hdr;
res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ,
0, SPIFFS_PAGE_TO_PADDR(fs, pix), sizeof(spiffs_page_object_ix_header), (u8_t *)&objix_hdr);
SPIFFS_CHECK_RES(res);
if (objix_hdr.p_hdr.span_ix == 0 &&
(objix_hdr.p_hdr.flags & (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_IXDELE)) ==
(SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_IXDELE)) {
if (strcmp((char *)user_p, (char *)objix_hdr.name) == 0) {
return SPIFFS_ERR_CONFLICTING_NAME;
}
}
}
id &= ~SPIFFS_OBJ_ID_IX_FLAG;
int bit_ix = (id-min_obj_id) & 7;
u32_t bit_ix = (id-min_obj_id) & 7;
int byte_ix = (id-min_obj_id) >> 3;
if (byte_ix >= 0 && byte_ix < SPIFFS_CFG_LOG_PAGE_SZ(fs)) {
if (byte_ix >= 0 && (u32_t)byte_ix < SPIFFS_CFG_LOG_PAGE_SZ(fs)) {
fs->work[byte_ix] |= (1<<bit_ix);
}
}
@ -1602,17 +1628,22 @@ static s32_t spiffs_obj_lu_find_free_obj_id_bitmap_v(spiffs *fs, spiffs_obj_id i
static s32_t spiffs_obj_lu_find_free_obj_id_compact_v(spiffs *fs, spiffs_obj_id id, spiffs_block_ix bix, int ix_entry,
u32_t user_data, void *user_p) {
(void)user_data;
if (id != SPIFFS_OBJ_ID_FREE && id != SPIFFS_OBJ_ID_DELETED && (id & SPIFFS_OBJ_ID_IX_FLAG)) {
s32_t res;
spiffs_free_obj_id_state *state = (spiffs_free_obj_id_state *)user_p;
spiffs_page_header ph;
spiffs_page_object_ix_header objix_hdr;
res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ,
0, SPIFFS_OBJ_LOOKUP_ENTRY_TO_PADDR(fs, bix, ix_entry), sizeof(spiffs_page_header), (u8_t*)&ph);
if (res == SPIFFS_OK && ph.span_ix == 0 &&
((ph.flags & (SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_DELET)) ==
0, SPIFFS_OBJ_LOOKUP_ENTRY_TO_PADDR(fs, bix, ix_entry), sizeof(spiffs_page_object_ix_header), (u8_t*)&objix_hdr);
if (res == SPIFFS_OK && objix_hdr.p_hdr.span_ix == 0 &&
((objix_hdr.p_hdr.flags & (SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_DELET)) ==
(SPIFFS_PH_FLAG_DELET))) {
// ok object look up entry
if (state->conflicting_name && strcmp((const char *)state->conflicting_name, (char *)objix_hdr.name) == 0) {
return SPIFFS_ERR_CONFLICTING_NAME;
}
id &= ~SPIFFS_OBJ_ID_IX_FLAG;
if (id >= state->min_obj_id && id <= state->max_obj_id) {
u8_t *map = (u8_t *)fs->work;
@ -1629,7 +1660,7 @@ static s32_t spiffs_obj_lu_find_free_obj_id_compact_v(spiffs *fs, spiffs_obj_id
// object ids cannot fit into a work buffer, these are grouped. When a group containing free
// object ids is found, the object lu is again scanned for object ids within group and bitmasked.
// Finally, the bitmasked is searched for a free id
s32_t spiffs_obj_lu_find_free_obj_id(spiffs *fs, spiffs_obj_id *obj_id) {
s32_t spiffs_obj_lu_find_free_obj_id(spiffs *fs, spiffs_obj_id *obj_id, u8_t *conflicting_name) {
s32_t res = SPIFFS_OK;
u32_t max_objects = (SPIFFS_CFG_PHYS_SZ(fs) / (u32_t)SPIFFS_CFG_LOG_PAGE_SZ(fs)) / 2;
spiffs_free_obj_id_state state;
@ -1640,14 +1671,16 @@ s32_t spiffs_obj_lu_find_free_obj_id(spiffs *fs, spiffs_obj_id *obj_id) {
state.max_obj_id = ((spiffs_obj_id)-1) & ~SPIFFS_OBJ_ID_IX_FLAG;
}
state.compaction = 0;
state.conflicting_name = conflicting_name;
while (res == SPIFFS_OK && free_obj_id == SPIFFS_OBJ_ID_FREE) {
if (state.max_obj_id - state.min_obj_id <= SPIFFS_CFG_LOG_PAGE_SZ(fs)*8) {
if (state.max_obj_id - state.min_obj_id <= (spiffs_obj_id)SPIFFS_CFG_LOG_PAGE_SZ(fs)*8) {
// possible to represent in bitmap
int i, j;
u32_t i, j;
SPIFFS_DBG("free_obj_id: BITM min:%04x max:%04x\n", state.min_obj_id, state.max_obj_id);
c_memset(fs->work, 0, SPIFFS_CFG_LOG_PAGE_SZ(fs));
res = spiffs_obj_lu_find_entry_visitor(fs, 0, 0, 0, 0, spiffs_obj_lu_find_free_obj_id_bitmap_v, state.min_obj_id, 0, 0, 0);
res = spiffs_obj_lu_find_entry_visitor(fs, 0, 0, 0, 0, spiffs_obj_lu_find_free_obj_id_bitmap_v, state.min_obj_id,
conflicting_name, 0, 0);
if (res == SPIFFS_VIS_END) res = SPIFFS_OK;
SPIFFS_CHECK_RES(res);
// traverse bitmask until found free obj_id
@ -1668,7 +1701,7 @@ s32_t spiffs_obj_lu_find_free_obj_id(spiffs *fs, spiffs_obj_id *obj_id) {
// not possible to represent all ids in range in a bitmap, compact and count
if (state.compaction != 0) {
// select element in compacted table, decrease range and recompact
int i, min_i = 0;
u32_t i, min_i = 0;
u8_t *map = (u8_t *)fs->work;
u8_t min_count = 0xff;
@ -1700,7 +1733,7 @@ s32_t spiffs_obj_lu_find_free_obj_id(spiffs *fs, spiffs_obj_id *obj_id) {
state.max_obj_id = state.min_obj_id + state.compaction;
// decrease compaction
}
if ((state.max_obj_id - state.min_obj_id <= SPIFFS_CFG_LOG_PAGE_SZ(fs)*8)) {
if ((state.max_obj_id - state.min_obj_id <= (spiffs_obj_id)SPIFFS_CFG_LOG_PAGE_SZ(fs)*8)) {
// no need for compacting, use bitmap
continue;
}
@ -1714,6 +1747,7 @@ s32_t spiffs_obj_lu_find_free_obj_id(spiffs *fs, spiffs_obj_id *obj_id) {
res = spiffs_obj_lu_find_entry_visitor(fs, 0, 0, 0, 0, spiffs_obj_lu_find_free_obj_id_compact_v, 0, &state, 0, 0);
if (res == SPIFFS_VIS_END) res = SPIFFS_OK;
SPIFFS_CHECK_RES(res);
state.conflicting_name = 0; // searched for conflicting name once, no need to do it again
}
}
@ -1721,7 +1755,7 @@ s32_t spiffs_obj_lu_find_free_obj_id(spiffs *fs, spiffs_obj_id *obj_id) {
}
s32_t spiffs_fd_find_new(spiffs *fs, spiffs_fd **fd) {
int i;
u32_t i;
spiffs_fd *fds = (spiffs_fd *)fs->fd_space;
for (i = 0; i < fs->fd_count; i++) {
spiffs_fd *cur_fd = &fds[i];
@ -1735,7 +1769,7 @@ s32_t spiffs_fd_find_new(spiffs *fs, spiffs_fd **fd) {
}
s32_t spiffs_fd_return(spiffs *fs, spiffs_file f) {
if (f <= 0 || f > fs->fd_count) {
if (f <= 0 || f > (s16_t)fs->fd_count) {
return SPIFFS_ERR_BAD_DESCRIPTOR;
}
spiffs_fd *fds = (spiffs_fd *)fs->fd_space;
@ -1748,7 +1782,7 @@ s32_t spiffs_fd_return(spiffs *fs, spiffs_file f) {
}
s32_t spiffs_fd_get(spiffs *fs, spiffs_file f, spiffs_fd **fd) {
if (f <= 0 || f > fs->fd_count) {
if (f <= 0 || f > (s16_t)fs->fd_count) {
return SPIFFS_ERR_BAD_DESCRIPTOR;
}
spiffs_fd *fds = (spiffs_fd *)fs->fd_space;

View File

@ -126,7 +126,7 @@
#define SPIFFS_OBJ_ID_IX_FLAG (1<<(8*sizeof(spiffs_obj_id)-1))
#define SPIFFS_UNDEFINED_LEN (-1)
#define SPIFFS_UNDEFINED_LEN (u32_t)(-1)
#define SPIFFS_OBJ_ID_DELETED ((spiffs_obj_id)0)
#define SPIFFS_OBJ_ID_FREE ((spiffs_obj_id)-1)
@ -487,7 +487,8 @@ s32_t spiffs_obj_lu_scan(
s32_t spiffs_obj_lu_find_free_obj_id(
spiffs *fs,
spiffs_obj_id *obj_id);
spiffs_obj_id *obj_id,
u8_t *conflicting_name);
s32_t spiffs_obj_lu_find_free(
spiffs *fs,

View File

@ -5,7 +5,7 @@ MEMORY
dport0_0_seg : org = 0x3FF00000, len = 0x10
dram0_0_seg : org = 0x3FFE8000, len = 0x14000
iram1_0_seg : org = 0x40100000, len = 0x8000
irom0_0_seg : org = 0x40210000, len = 0x51000
irom0_0_seg : org = 0x40210000, len = 0x54000
}
PHDRS

View File

@ -5,7 +5,7 @@
-- Vladimir Dronnikov <dronnikov@gmail.com>
--
-- Example:
-- require("irsend").nec(4, 0x00ff00ff)
-- dofile("irsend.lua").nec(4, 0x00ff00ff)
------------------------------------------------------------------------------
local M
do

View File

@ -6,7 +6,7 @@
-- Heavily based on work of Christee <Christee@nodemcu.com>
--
-- Example:
-- require("bmp085").read(sda, scl)
-- dofile("bmp085.lua").read(sda, scl)
------------------------------------------------------------------------------
local M
do
@ -59,20 +59,13 @@ do
MD = r16(0xBE)
end
-- get raw P
local p
-- NB: optimize for oss = 0
if not oss then oss = 0 end
if oss == 0 then
oss = 0
w8(0xF4, 0x34)
tmr.delay(5000)
p = r8(0xF6) * 256 + r8(0xF7)
else
w8(0xF4, 0x34 + 64 * oss)
tmr.delay(30000)
p = r8(0xF6) * 65536 + r8(0xF7) * 256 + r8(0xF8)
p = p / 2^(8 - oss)
end
if oss <= 0 then oss = 0 end
if oss > 3 then oss = 3 end
w8(0xF4, 0x34 + 64 * oss)
tmr.delay((4 + 3 ^ oss) * 1000)
local p = r8(0xF6) * 65536 + r8(0xF7) * 256 + r8(0xF8)
p = p / 2 ^ (8 - oss)
-- get T
w8(0xF4, 0x2E)
tmr.delay(5000)
@ -86,14 +79,14 @@ do
local X1 = B2 * (B6 * B6 / 4096) / 2048
local X2 = AC2 * B6 / 2048
local X3 = X1 + X2
local B3 = ((AC1 * 4 + X3) * 2^oss + 2) / 4
local B3 = ((AC1 * 4 + X3) * 2 ^ oss + 2) / 4
X1 = AC3 * B6 / 8192
X2 = (B1 * (B6 * B6 / 4096)) / 65536
X3 = (X1 + X2 + 2) / 4
local B4 = AC4 * (X3 + 32768) / 32768
local B7 = (p - B3) * (50000 / 2^oss)
local B7 = (p - B3) * (50000 / 2 ^ oss)
p = B7 / B4 * 2
X1 = (p / 256)^2
X1 = (p / 256) ^ 2
X1 = (X1 * 3038) / 65536
X2 = (-7357 * p) / 65536
p = p + (X1 + X2 + 3791) / 16

View File

@ -5,8 +5,8 @@
-- Vladimir Dronnikov <dronnikov@gmail.com>
--
-- Example:
-- print("DHT11", require("dht22").read(4))
-- print("DHT22", require("dht22").read(4, true))
-- print("DHT11", dofile("dht22.lua").read(4))
-- print("DHT22", dofile("dht22.lua").read(4, true))
-- NB: the very first read sometimes fails
------------------------------------------------------------------------------
local M

View File

@ -5,7 +5,7 @@
-- Vladimir Dronnikov <dronnikov@gmail.com>
--
-- Example:
-- require("ds18b20").read(4, function(r) for k, v in pairs(r) do print(k, v) end end)
-- dofile("ds18b20.lua").read(4, function(r) for k, v in pairs(r) do print(k, v) end end)
------------------------------------------------------------------------------
local M
do

View File

@ -0,0 +1,83 @@
------------------------------------------------------------------------------
-- Redis client module
--
-- LICENCE: http://opensource.org/licenses/MIT
-- Vladimir Dronnikov <dronnikov@gmail.com>
--
-- Example:
-- local redis = dofile("redis.lua").connect(host, port)
-- redis:publish("chan1", foo")
-- redis:subscribe("chan1", function(channel, msg) print(channel, msg) end)
------------------------------------------------------------------------------
local M
do
-- const
local REDIS_PORT = 6379
-- cache
local pairs, tonumber = pairs, tonumber
--
local publish = function(self, chn, s)
self._fd:send(("*3\r\n$7\r\npublish\r\n$%d\r\n%s\r\n$%d\r\n%s\r\n"):format(
#chn, chn, #s, s
))
-- TODO: confirmation? then queue of answers needed
end
local subscribe = function(self, chn, handler)
-- TODO: subscription to all channels, with single handler
self._fd:send(("*2\r\n$9\r\nsubscribe\r\n$%d\r\n%s\r\n"):format(
#chn, chn
))
self._handlers[chn] = handler
-- TODO: confirmation? then queue of answers needed
end
local unsubscribe = function(self, chn)
self._handlers[chn] = false
end
-- NB: pity we can not just augment what net.createConnection returns
local close = function(self)
self._fd:close()
end
local connect = function(host, port)
local _fd = net.createConnection(net.TCP, 0)
local self = {
_fd = _fd,
_handlers = { },
-- TODO: consider metatables?
close = close,
publish = publish,
subscribe = subscribe,
unsubscribe = unsubscribe,
}
_fd:on("connection", function()
--print("+FD")
end)
_fd:on("disconnection", function()
-- FIXME: this suddenly occurs. timeout?
--print("-FD")
end)
_fd:on("receive", function(fd, s)
--print("IN", s)
-- TODO: subscription to all channels
-- lookup message pattern to determine channel and payload
-- NB: pairs() iteration gives no fixed order!
for chn, handler in pairs(self._handlers) do
local p = ("*3\r\n$7\r\nmessage\r\n$%d\r\n%s\r\n$"):format(#chn, chn)
if s:find(p, 1, true) then
-- extract and check message length
-- NB: only the first TCP packet considered!
local _, start, len = s:find("(%d-)\r\n", #p)
if start and tonumber(len) == #s - start - 2 and handler then
handler(chn, s:sub(start + 1, -2)) -- ends with \r\n
end
end
end
end)
_fd:connect(port or REDIS_PORT, host)
return self
end
-- expose
M = {
connect = connect,
}
end
return M