Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
Nodemcu Firmware
Commits
fa7cf878
Commit
fa7cf878
authored
Mar 18, 2015
by
zeroday
Browse files
Merge pull request #287 from nodemcu/dev
Dev merge to master
parents
6c8cace9
1652df50
Changes
187
Hide whitespace changes
Inline
Side-by-side
app/modules/Makefile
View file @
fa7cf878
...
@@ -39,7 +39,9 @@ endif
...
@@ -39,7 +39,9 @@ endif
INCLUDES
:=
$(INCLUDES)
-I
$(PDIR)
include
INCLUDES
:=
$(INCLUDES)
-I
$(PDIR)
include
INCLUDES
+=
-I
./
INCLUDES
+=
-I
./
INCLUDES
+=
-I
../libc
INCLUDES
+=
-I
../libc
INCLUDES
+=
-I
../coap
INCLUDES
+=
-I
../mqtt
INCLUDES
+=
-I
../mqtt
INCLUDES
+=
-I
../u8glib
INCLUDES
+=
-I
../lua
INCLUDES
+=
-I
../lua
INCLUDES
+=
-I
../platform
INCLUDES
+=
-I
../platform
INCLUDES
+=
-I
../wofs
INCLUDES
+=
-I
../wofs
...
...
app/modules/auxmods.h
View file @
fa7cf878
...
@@ -61,9 +61,15 @@ LUALIB_API int ( luaopen_i2c )( lua_State *L );
...
@@ -61,9 +61,15 @@ LUALIB_API int ( luaopen_i2c )( lua_State *L );
#define AUXLIB_WIFI "wifi"
#define AUXLIB_WIFI "wifi"
LUALIB_API
int
(
luaopen_wifi
)(
lua_State
*
L
);
LUALIB_API
int
(
luaopen_wifi
)(
lua_State
*
L
);
#define AUXLIB_COAP "coap"
LUALIB_API
int
(
luaopen_coap
)(
lua_State
*
L
);
#define AUXLIB_MQTT "mqtt"
#define AUXLIB_MQTT "mqtt"
LUALIB_API
int
(
luaopen_mqtt
)(
lua_State
*
L
);
LUALIB_API
int
(
luaopen_mqtt
)(
lua_State
*
L
);
#define AUXLIB_U8G "u8g"
LUALIB_API
int
(
luaopen_u8g
)(
lua_State
*
L
);
#define AUXLIB_NODE "node"
#define AUXLIB_NODE "node"
LUALIB_API
int
(
luaopen_node
)(
lua_State
*
L
);
LUALIB_API
int
(
luaopen_node
)(
lua_State
*
L
);
...
@@ -92,5 +98,9 @@ LUALIB_API int ( luaopen_ow )( lua_State *L );
...
@@ -92,5 +98,9 @@ LUALIB_API int ( luaopen_ow )( lua_State *L );
lua_pushnumber( L, val );\
lua_pushnumber( L, val );\
lua_setfield( L, -2, name )
lua_setfield( L, -2, name )
#define MOD_REG_LUDATA( L, name, val )\
lua_pushlightuserdata( L, val );\
lua_setfield( L, -2, name )
#endif
#endif
app/modules/coap.c
0 → 100644
View file @
fa7cf878
// Module for coapwork
//#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
#include "platform.h"
#include "auxmods.h"
#include "lrotable.h"
#include "c_string.h"
#include "c_stdlib.h"
#include "c_types.h"
#include "mem.h"
#include "espconn.h"
#include "driver/uart.h"
#include "coap.h"
#include "uri.h"
#include "node.h"
#include "coap_timer.h"
#include "coap_io.h"
#include "coap_server.h"
coap_queue_t
*
gQueue
=
NULL
;
typedef
struct
lcoap_userdata
{
lua_State
*
L
;
struct
espconn
*
pesp_conn
;
int
self_ref
;
}
lcoap_userdata
;
static
void
coap_received
(
void
*
arg
,
char
*
pdata
,
unsigned
short
len
)
{
NODE_DBG
(
"coap_received is called.
\n
"
);
struct
espconn
*
pesp_conn
=
arg
;
lcoap_userdata
*
cud
=
(
lcoap_userdata
*
)
pesp_conn
->
reverse
;
// static uint8_t buf[MAX_MESSAGE_SIZE+1] = {0}; // +1 for string '\0'
uint8_t
buf
[
MAX_MESSAGE_SIZE
+
1
]
=
{
0
};
// +1 for string '\0'
c_memset
(
buf
,
0
,
sizeof
(
buf
));
// wipe prev data
if
(
len
>
MAX_MESSAGE_SIZE
)
{
NODE_DBG
(
"Request Entity Too Large.
\n
"
);
// NOTE: should response 4.13 to client...
return
;
}
// c_memcpy(buf, pdata, len);
size_t
rsplen
=
coap_server_respond
(
pdata
,
len
,
buf
,
MAX_MESSAGE_SIZE
+
1
);
espconn_sent
(
pesp_conn
,
(
unsigned
char
*
)
buf
,
rsplen
);
// c_memset(buf, 0, sizeof(buf));
}
static
void
coap_sent
(
void
*
arg
)
{
NODE_DBG
(
"coap_sent is called.
\n
"
);
}
// Lua: s = coap.create(function(conn))
static
int
coap_create
(
lua_State
*
L
,
const
char
*
mt
)
{
struct
espconn
*
pesp_conn
=
NULL
;
lcoap_userdata
*
cud
;
unsigned
type
;
int
stack
=
1
;
// create a object
cud
=
(
lcoap_userdata
*
)
lua_newuserdata
(
L
,
sizeof
(
lcoap_userdata
));
// pre-initialize it, in case of errors
cud
->
self_ref
=
LUA_NOREF
;
cud
->
pesp_conn
=
NULL
;
// set its metatable
luaL_getmetatable
(
L
,
mt
);
lua_setmetatable
(
L
,
-
2
);
// create the espconn struct
pesp_conn
=
(
struct
espconn
*
)
c_zalloc
(
sizeof
(
struct
espconn
));
if
(
!
pesp_conn
)
return
luaL_error
(
L
,
"not enough memory"
);
cud
->
pesp_conn
=
pesp_conn
;
pesp_conn
->
type
=
ESPCONN_UDP
;
pesp_conn
->
proto
.
tcp
=
NULL
;
pesp_conn
->
proto
.
udp
=
NULL
;
pesp_conn
->
proto
.
udp
=
(
esp_udp
*
)
c_zalloc
(
sizeof
(
esp_udp
));
if
(
!
pesp_conn
->
proto
.
udp
){
c_free
(
pesp_conn
);
cud
->
pesp_conn
=
pesp_conn
=
NULL
;
return
luaL_error
(
L
,
"not enough memory"
);
}
pesp_conn
->
state
=
ESPCONN_NONE
;
NODE_DBG
(
"UDP server/client is set.
\n
"
);
cud
->
L
=
L
;
pesp_conn
->
reverse
=
cud
;
NODE_DBG
(
"coap_create is called.
\n
"
);
return
1
;
}
// Lua: server:delete()
static
int
coap_delete
(
lua_State
*
L
,
const
char
*
mt
)
{
struct
espconn
*
pesp_conn
=
NULL
;
lcoap_userdata
*
cud
;
cud
=
(
lcoap_userdata
*
)
luaL_checkudata
(
L
,
1
,
mt
);
luaL_argcheck
(
L
,
cud
,
1
,
"Server/Client expected"
);
if
(
cud
==
NULL
){
NODE_DBG
(
"userdata is nil.
\n
"
);
return
0
;
}
// free (unref) callback ref
if
(
LUA_NOREF
!=
cud
->
self_ref
){
luaL_unref
(
L
,
LUA_REGISTRYINDEX
,
cud
->
self_ref
);
cud
->
self_ref
=
LUA_NOREF
;
}
cud
->
L
=
NULL
;
if
(
cud
->
pesp_conn
)
{
if
(
cud
->
pesp_conn
->
proto
.
udp
->
remote_port
||
cud
->
pesp_conn
->
proto
.
udp
->
local_port
)
espconn_delete
(
cud
->
pesp_conn
);
c_free
(
cud
->
pesp_conn
->
proto
.
udp
);
cud
->
pesp_conn
->
proto
.
udp
=
NULL
;
c_free
(
cud
->
pesp_conn
);
cud
->
pesp_conn
=
NULL
;
}
NODE_DBG
(
"coap_delete is called.
\n
"
);
return
0
;
}
// Lua: server:listen( port, ip )
static
int
coap_start
(
lua_State
*
L
,
const
char
*
mt
)
{
struct
espconn
*
pesp_conn
=
NULL
;
lcoap_userdata
*
cud
;
unsigned
port
;
size_t
il
;
ip_addr_t
ipaddr
;
cud
=
(
lcoap_userdata
*
)
luaL_checkudata
(
L
,
1
,
mt
);
luaL_argcheck
(
L
,
cud
,
1
,
"Server/Client expected"
);
if
(
cud
==
NULL
){
NODE_DBG
(
"userdata is nil.
\n
"
);
return
0
;
}
pesp_conn
=
cud
->
pesp_conn
;
port
=
luaL_checkinteger
(
L
,
2
);
pesp_conn
->
proto
.
udp
->
local_port
=
port
;
NODE_DBG
(
"UDP port is set: %d.
\n
"
,
port
);
if
(
lua_isstring
(
L
,
3
)
)
// deal with the ip string
{
const
char
*
ip
=
luaL_checklstring
(
L
,
3
,
&
il
);
if
(
ip
==
NULL
)
{
ip
=
"0.0.0.0"
;
}
ipaddr
.
addr
=
ipaddr_addr
(
ip
);
c_memcpy
(
pesp_conn
->
proto
.
udp
->
local_ip
,
&
ipaddr
.
addr
,
4
);
NODE_DBG
(
"UDP ip is set: "
);
NODE_DBG
(
IPSTR
,
IP2STR
(
&
ipaddr
.
addr
));
NODE_DBG
(
"
\n
"
);
}
if
(
LUA_NOREF
==
cud
->
self_ref
){
lua_pushvalue
(
L
,
1
);
// copy to the top of stack
cud
->
self_ref
=
luaL_ref
(
L
,
LUA_REGISTRYINDEX
);
}
espconn_regist_recvcb
(
pesp_conn
,
coap_received
);
espconn_regist_sentcb
(
pesp_conn
,
coap_sent
);
espconn_create
(
pesp_conn
);
NODE_DBG
(
"Coap Server started on port: %d
\n
"
,
port
);
NODE_DBG
(
"coap_start is called.
\n
"
);
return
0
;
}
// Lua: server:close()
static
int
coap_close
(
lua_State
*
L
,
const
char
*
mt
)
{
struct
espconn
*
pesp_conn
=
NULL
;
lcoap_userdata
*
cud
;
cud
=
(
lcoap_userdata
*
)
luaL_checkudata
(
L
,
1
,
mt
);
luaL_argcheck
(
L
,
cud
,
1
,
"Server/Client expected"
);
if
(
cud
==
NULL
){
NODE_DBG
(
"userdata is nil.
\n
"
);
return
0
;
}
if
(
cud
->
pesp_conn
)
{
if
(
cud
->
pesp_conn
->
proto
.
udp
->
remote_port
||
cud
->
pesp_conn
->
proto
.
udp
->
local_port
)
espconn_delete
(
cud
->
pesp_conn
);
}
if
(
LUA_NOREF
!=
cud
->
self_ref
){
luaL_unref
(
L
,
LUA_REGISTRYINDEX
,
cud
->
self_ref
);
cud
->
self_ref
=
LUA_NOREF
;
}
NODE_DBG
(
"coap_close is called.
\n
"
);
return
0
;
}
// Lua: server/client:on( "method", function(s) )
static
int
coap_on
(
lua_State
*
L
,
const
char
*
mt
)
{
NODE_DBG
(
"coap_on is called.
\n
"
);
return
0
;
}
static
void
coap_response_handler
(
void
*
arg
,
char
*
pdata
,
unsigned
short
len
)
{
NODE_DBG
(
"coap_response_handler is called.
\n
"
);
struct
espconn
*
pesp_conn
=
arg
;
coap_packet_t
pkt
;
pkt
.
content
.
p
=
NULL
;
pkt
.
content
.
len
=
0
;
// static uint8_t buf[MAX_MESSAGE_SIZE+1] = {0}; // +1 for string '\0'
uint8_t
buf
[
MAX_MESSAGE_SIZE
+
1
]
=
{
0
};
// +1 for string '\0'
c_memset
(
buf
,
0
,
sizeof
(
buf
));
// wipe prev data
int
rc
;
if
(
len
>
MAX_MESSAGE_SIZE
)
{
NODE_DBG
(
"Request Entity Too Large.
\n
"
);
// NOTE: should response 4.13 to client...
return
;
}
c_memcpy
(
buf
,
pdata
,
len
);
if
(
0
!=
(
rc
=
coap_parse
(
&
pkt
,
buf
,
len
))){
NODE_DBG
(
"Bad packet rc=%d
\n
"
,
rc
);
}
else
{
#ifdef COAP_DEBUG
coap_dumpPacket
(
&
pkt
);
#endif
/* check if this is a response to our original request */
if
(
!
check_token
(
&
pkt
))
{
/* drop if this was just some message, or send RST in case of notification */
if
(
pkt
.
hdr
.
t
==
COAP_TYPE_CON
||
pkt
.
hdr
.
t
==
COAP_TYPE_NONCON
){
// coap_send_rst(pkt); // send RST response
// or, just ignore it.
}
goto
end
;
}
if
(
pkt
.
hdr
.
t
==
COAP_TYPE_RESET
)
{
NODE_DBG
(
"got RST
\n
"
);
goto
end
;
}
uint32_t
ip
=
0
,
port
=
0
;
coap_tid_t
id
=
COAP_INVALID_TID
;
c_memcpy
(
&
ip
,
pesp_conn
->
proto
.
udp
->
remote_ip
,
sizeof
(
ip
));
port
=
pesp_conn
->
proto
.
udp
->
remote_port
;
coap_transaction_id
(
ip
,
port
,
&
pkt
,
&
id
);
/* transaction done, remove the node from queue */
// stop timer
coap_timer_stop
();
// remove the node
coap_remove_node
(
&
gQueue
,
id
);
// calculate time elapsed
coap_timer_update
(
&
gQueue
);
coap_timer_start
(
&
gQueue
);
if
(
COAP_RESPONSE_CLASS
(
pkt
.
hdr
.
code
)
==
2
)
{
/* There is no block option set, just read the data and we are done. */
NODE_DBG
(
"%d.%02d
\t
"
,
(
pkt
.
hdr
.
code
>>
5
),
pkt
.
hdr
.
code
&
0x1F
);
NODE_DBG
((
char
*
)
pkt
.
payload
.
p
);
}
else
if
(
COAP_RESPONSE_CLASS
(
pkt
.
hdr
.
code
)
>=
4
)
{
NODE_DBG
(
"%d.%02d
\t
"
,
(
pkt
.
hdr
.
code
>>
5
),
pkt
.
hdr
.
code
&
0x1F
);
NODE_DBG
((
char
*
)
pkt
.
payload
.
p
);
}
}
end:
if
(
!
gQueue
){
// if there is no node pending in the queue, disconnect from host.
if
(
pesp_conn
->
proto
.
udp
->
remote_port
||
pesp_conn
->
proto
.
udp
->
local_port
)
espconn_delete
(
pesp_conn
);
}
// c_memset(buf, 0, sizeof(buf));
}
// Lua: client:request( [CON], uri, [payload] )
static
int
coap_request
(
lua_State
*
L
,
coap_method_t
m
)
{
struct
espconn
*
pesp_conn
=
NULL
;
lcoap_userdata
*
cud
;
int
stack
=
1
;
cud
=
(
lcoap_userdata
*
)
luaL_checkudata
(
L
,
stack
,
"coap_client"
);
luaL_argcheck
(
L
,
cud
,
stack
,
"Server/Client expected"
);
if
(
cud
==
NULL
){
NODE_DBG
(
"userdata is nil.
\n
"
);
return
0
;
}
stack
++
;
pesp_conn
=
cud
->
pesp_conn
;
ip_addr_t
ipaddr
;
uint8_t
host
[
32
];
unsigned
t
;
if
(
lua_isnumber
(
L
,
stack
)
)
{
t
=
lua_tointeger
(
L
,
stack
);
stack
++
;
if
(
t
!=
COAP_TYPE_CON
&&
t
!=
COAP_TYPE_NONCON
)
return
luaL_error
(
L
,
"wrong arg type"
);
}
else
{
t
=
COAP_TYPE_CON
;
// default to CON
}
size_t
l
;
const
char
*
url
=
luaL_checklstring
(
L
,
stack
,
&
l
);
stack
++
;
if
(
url
==
NULL
)
return
luaL_error
(
L
,
"wrong arg type"
);
coap_uri_t
*
uri
=
coap_new_uri
(
url
,
l
);
// should call free(uri) somewhere
if
(
uri
==
NULL
)
return
luaL_error
(
L
,
"uri wrong format."
);
pesp_conn
->
proto
.
udp
->
remote_port
=
uri
->
port
;
NODE_DBG
(
"UDP port is set: %d.
\n
"
,
uri
->
port
);
pesp_conn
->
proto
.
udp
->
local_port
=
espconn_port
();
if
(
uri
->
host
.
length
){
c_memcpy
(
host
,
uri
->
host
.
s
,
uri
->
host
.
length
);
host
[
uri
->
host
.
length
]
=
'\0'
;
ipaddr
.
addr
=
ipaddr_addr
(
host
);
NODE_DBG
(
"Host len(%d):"
,
uri
->
host
.
length
);
NODE_DBG
(
host
);
NODE_DBG
(
"
\n
"
);
c_memcpy
(
pesp_conn
->
proto
.
udp
->
remote_ip
,
&
ipaddr
.
addr
,
4
);
NODE_DBG
(
"UDP ip is set: "
);
NODE_DBG
(
IPSTR
,
IP2STR
(
&
ipaddr
.
addr
));
NODE_DBG
(
"
\n
"
);
}
coap_pdu_t
*
pdu
=
coap_new_pdu
();
// should call coap_delete_pdu() somewhere
if
(
!
pdu
){
if
(
uri
)
c_free
(
uri
);
return
;
}
const
char
*
payload
=
NULL
;
l
=
0
;
if
(
lua_isstring
(
L
,
stack
)
){
payload
=
luaL_checklstring
(
L
,
stack
,
&
l
);
if
(
payload
==
NULL
)
l
=
0
;
}
coap_make_request
(
&
(
pdu
->
scratch
),
pdu
->
pkt
,
t
,
m
,
uri
,
payload
,
l
);
#ifdef COAP_DEBUG
coap_dumpPacket
(
pdu
->
pkt
);
#endif
int
rc
;
if
(
0
!=
(
rc
=
coap_build
(
pdu
->
msg
.
p
,
&
(
pdu
->
msg
.
len
),
pdu
->
pkt
))){
NODE_DBG
(
"coap_build failed rc=%d
\n
"
,
rc
);
}
else
{
#ifdef COAP_DEBUG
NODE_DBG
(
"Sending: "
);
coap_dump
(
pdu
->
msg
.
p
,
pdu
->
msg
.
len
,
true
);
NODE_DBG
(
"
\n
"
);
#endif
espconn_regist_recvcb
(
pesp_conn
,
coap_response_handler
);
sint8_t
con
=
espconn_create
(
pesp_conn
);
if
(
ESPCONN_OK
!=
con
){
NODE_DBG
(
"Connect to host. code:%d
\n
"
,
con
);
// coap_delete_pdu(pdu);
}
// else
{
coap_tid_t
tid
=
COAP_INVALID_TID
;
if
(
pdu
->
pkt
->
hdr
.
t
==
COAP_TYPE_CON
){
tid
=
coap_send_confirmed
(
pesp_conn
,
pdu
);
}
else
{
tid
=
coap_send
(
pesp_conn
,
pdu
);
}
if
(
pdu
->
pkt
->
hdr
.
t
!=
COAP_TYPE_CON
||
tid
==
COAP_INVALID_TID
){
coap_delete_pdu
(
pdu
);
}
}
}
if
(
uri
)
c_free
((
void
*
)
uri
);
NODE_DBG
(
"coap_request is called.
\n
"
);
return
0
;
}
extern
coap_luser_entry
*
variable_entry
;
extern
coap_luser_entry
*
function_entry
;
// Lua: coap:var/func( string )
static
int
coap_regist
(
lua_State
*
L
,
const
char
*
mt
,
int
isvar
)
{
size_t
l
;
const
char
*
name
=
luaL_checklstring
(
L
,
2
,
&
l
);
if
(
name
==
NULL
)
return
luaL_error
(
L
,
"name must be set."
);
coap_luser_entry
*
h
=
NULL
;
// if(lua_isstring(L, 3))
if
(
isvar
)
h
=
variable_entry
;
else
h
=
function_entry
;
while
(
NULL
!=
h
->
next
){
// goto the end of the list
if
(
h
->
name
!=
NULL
&&
c_strcmp
(
h
->
name
,
name
)
==
0
)
// key exist, override it
break
;
h
=
h
->
next
;
}
if
(
h
->
name
==
NULL
||
c_strcmp
(
h
->
name
,
name
)
!=
0
){
// not exists. make a new one.
h
->
next
=
(
coap_luser_entry
*
)
c_zalloc
(
sizeof
(
coap_luser_entry
));
h
=
h
->
next
;
if
(
h
==
NULL
)
return
luaL_error
(
L
,
"not enough memory"
);
h
->
next
=
NULL
;
h
->
name
=
NULL
;
h
->
L
=
NULL
;
}
h
->
L
=
L
;
h
->
name
=
name
;
NODE_DBG
(
"coap_regist is called.
\n
"
);
return
0
;
}
// Lua: s = coap.createServer(function(conn))
static
int
coap_createServer
(
lua_State
*
L
)
{
const
char
*
mt
=
"coap_server"
;
return
coap_create
(
L
,
mt
);
}
// Lua: server:delete()
static
int
coap_server_delete
(
lua_State
*
L
)
{
const
char
*
mt
=
"coap_server"
;
return
coap_delete
(
L
,
mt
);
}
// Lua: server:listen( port, ip, function(err) )
static
int
coap_server_listen
(
lua_State
*
L
)
{
const
char
*
mt
=
"coap_server"
;
return
coap_start
(
L
,
mt
);
}
// Lua: server:close()
static
int
coap_server_close
(
lua_State
*
L
)
{
const
char
*
mt
=
"coap_server"
;
return
coap_close
(
L
,
mt
);
}
// Lua: server:on( "method", function(server) )
static
int
coap_server_on
(
lua_State
*
L
)
{
const
char
*
mt
=
"coap_server"
;
return
coap_on
(
L
,
mt
);
}
// Lua: server:var( "name" )
static
int
coap_server_var
(
lua_State
*
L
)
{
const
char
*
mt
=
"coap_server"
;
return
coap_regist
(
L
,
mt
,
1
);
}
// Lua: server:func( "name" )
static
int
coap_server_func
(
lua_State
*
L
)
{
const
char
*
mt
=
"coap_server"
;
return
coap_regist
(
L
,
mt
,
0
);
}
// Lua: s = coap.createClient(function(conn))
static
int
coap_createClient
(
lua_State
*
L
)
{
const
char
*
mt
=
"coap_client"
;
return
coap_create
(
L
,
mt
);
}
// Lua: client:gcdelete()
static
int
coap_client_gcdelete
(
lua_State
*
L
)
{
const
char
*
mt
=
"coap_client"
;
return
coap_delete
(
L
,
mt
);
}
// client:get( string, function(sent) )
static
int
coap_client_get
(
lua_State
*
L
)
{
return
coap_request
(
L
,
COAP_METHOD_GET
);
}
// client:post( string, function(sent) )
static
int
coap_client_post
(
lua_State
*
L
)
{
return
coap_request
(
L
,
COAP_METHOD_POST
);
}
// client:put( string, function(sent) )
static
int
coap_client_put
(
lua_State
*
L
)
{
return
coap_request
(
L
,
COAP_METHOD_PUT
);
}
// client:delete( string, function(sent) )
static
int
coap_client_delete
(
lua_State
*
L
)
{
return
coap_request
(
L
,
COAP_METHOD_DELETE
);
}
// Module function map
#define MIN_OPT_LEVEL 2
#include "lrodefs.h"
static
const
LUA_REG_TYPE
coap_server_map
[]
=
{
{
LSTRKEY
(
"listen"
),
LFUNCVAL
(
coap_server_listen
)
},
{
LSTRKEY
(
"close"
),
LFUNCVAL
(
coap_server_close
)
},
{
LSTRKEY
(
"var"
),
LFUNCVAL
(
coap_server_var
)
},
{
LSTRKEY
(
"func"
),
LFUNCVAL
(
coap_server_func
)
},
{
LSTRKEY
(
"__gc"
),
LFUNCVAL
(
coap_server_delete
)
},
#if LUA_OPTIMIZE_MEMORY > 0
{
LSTRKEY
(
"__index"
),
LROVAL
(
coap_server_map
)
},
#endif
{
LNILKEY
,
LNILVAL
}
};
static
const
LUA_REG_TYPE
coap_client_map
[]
=
{
{
LSTRKEY
(
"get"
),
LFUNCVAL
(
coap_client_get
)
},
{
LSTRKEY
(
"post"
),
LFUNCVAL
(
coap_client_post
)
},
{
LSTRKEY
(
"put"
),
LFUNCVAL
(
coap_client_put
)
},
{
LSTRKEY
(
"delete"
),
LFUNCVAL
(
coap_client_delete
)
},
{
LSTRKEY
(
"__gc"
),
LFUNCVAL
(
coap_client_gcdelete
)
},
#if LUA_OPTIMIZE_MEMORY > 0
{
LSTRKEY
(
"__index"
),
LROVAL
(
coap_client_map
)
},
#endif
{
LNILKEY
,
LNILVAL
}
};
const
LUA_REG_TYPE
coap_map
[]
=
{
{
LSTRKEY
(
"Server"
),
LFUNCVAL
(
coap_createServer
)
},
{
LSTRKEY
(
"Client"
),
LFUNCVAL
(
coap_createClient
)
},
#if LUA_OPTIMIZE_MEMORY > 0
{
LSTRKEY
(
"CON"
),
LNUMVAL
(
COAP_TYPE_CON
)
},
{
LSTRKEY
(
"NON"
),
LNUMVAL
(
COAP_TYPE_NONCON
)
},
{
LSTRKEY
(
"__metatable"
),
LROVAL
(
coap_map
)
},
#endif
{
LNILKEY
,
LNILVAL
}
};
LUALIB_API
int
luaopen_coap
(
lua_State
*
L
)
{
endpoint_setup
();
#if LUA_OPTIMIZE_MEMORY > 0
luaL_rometatable
(
L
,
"coap_server"
,
(
void
*
)
coap_server_map
);
// create metatable for coap_server
luaL_rometatable
(
L
,
"coap_client"
,
(
void
*
)
coap_client_map
);
// create metatable for coap_client
return
0
;
#else // #if LUA_OPTIMIZE_MEMORY > 0
int
n
;
luaL_register
(
L
,
AUXLIB_COAP
,
coap_map
);
// Set it as its own metatable
lua_pushvalue
(
L
,
-
1
);
lua_setmetatable
(
L
,
-
2
);
// Module constants
MOD_REG_NUMBER
(
L
,
"CON"
,
COAP_TYPE_CON
);
MOD_REG_NUMBER
(
L
,
"NON"
,
COAP_TYPE_NONCON
);
n
=
lua_gettop
(
L
);
// create metatable
luaL_newmetatable
(
L
,
"coap_server"
);
// metatable.__index = metatable
lua_pushliteral
(
L
,
"__index"
);
lua_pushvalue
(
L
,
-
2
);
lua_rawset
(
L
,
-
3
);
// Setup the methods inside metatable
luaL_register
(
L
,
NULL
,
coap_server_map
);
lua_settop
(
L
,
n
);
// create metatable
luaL_newmetatable
(
L
,
"coap_client"
);
// metatable.__index = metatable
lua_pushliteral
(
L
,
"__index"
);
lua_pushvalue
(
L
,
-
2
);
lua_rawset
(
L
,
-
3
);
// Setup the methods inside metatable
luaL_register
(
L
,
NULL
,
coap_client_map
);
return
1
;
#endif // #if LUA_OPTIMIZE_MEMORY > 0
}
app/modules/file.c
View file @
fa7cf878
...
@@ -111,7 +111,7 @@ static int file_seek (lua_State *L)
...
@@ -111,7 +111,7 @@ static int file_seek (lua_State *L)
long
offset
=
luaL_optlong
(
L
,
2
,
0
);
long
offset
=
luaL_optlong
(
L
,
2
,
0
);
op
=
fs_seek
(
file_fd
,
offset
,
mode
[
op
]);
op
=
fs_seek
(
file_fd
,
offset
,
mode
[
op
]);
if
(
op
)
if
(
op
)
lua_push
boolean
(
L
,
1
);
/* error */
lua_push
nil
(
L
);
/* error */
else
else
lua_pushinteger
(
L
,
fs_tell
(
file_fd
));
lua_pushinteger
(
L
,
fs_tell
(
file_fd
));
return
1
;
return
1
;
...
@@ -175,6 +175,22 @@ static int file_rename( lua_State* L )
...
@@ -175,6 +175,22 @@ static int file_rename( lua_State* L )
return
1
;
return
1
;
}
}
// Lua: fsinfo()
static
int
file_fsinfo
(
lua_State
*
L
)
{
uint32_t
total
,
used
;
SPIFFS_info
(
&
fs
,
&
total
,
&
used
);
NODE_DBG
(
"total: %d, used:%d
\n
"
,
total
,
used
);
if
(
total
>
0x7FFFFFFF
||
used
>
0x7FFFFFFF
||
used
>
total
)
{
return
luaL_error
(
L
,
"file system error"
);;
}
lua_pushinteger
(
L
,
total
-
used
);
lua_pushinteger
(
L
,
used
);
lua_pushinteger
(
L
,
total
);
return
3
;
}
#endif
#endif
// g_read()
// g_read()
...
@@ -308,6 +324,7 @@ const LUA_REG_TYPE file_map[] =
...
@@ -308,6 +324,7 @@ const LUA_REG_TYPE file_map[] =
{
LSTRKEY
(
"flush"
),
LFUNCVAL
(
file_flush
)
},
{
LSTRKEY
(
"flush"
),
LFUNCVAL
(
file_flush
)
},
// { LSTRKEY( "check" ), LFUNCVAL( file_check ) },
// { LSTRKEY( "check" ), LFUNCVAL( file_check ) },
{
LSTRKEY
(
"rename"
),
LFUNCVAL
(
file_rename
)
},
{
LSTRKEY
(
"rename"
),
LFUNCVAL
(
file_rename
)
},
{
LSTRKEY
(
"fsinfo"
),
LFUNCVAL
(
file_fsinfo
)
},
#endif
#endif
#if LUA_OPTIMIZE_MEMORY > 0
#if LUA_OPTIMIZE_MEMORY > 0
...
...
app/
lua
/linit.c
→
app/
modules
/linit.c
View file @
fa7cf878
...
@@ -15,6 +15,8 @@
...
@@ -15,6 +15,8 @@
#include "lrotable.h"
#include "lrotable.h"
#include "luaconf.h"
#include "luaconf.h"
#include "user_modules.h"
#if defined(LUA_USE_MODULES)
#if defined(LUA_USE_MODULES)
#include "modules.h"
#include "modules.h"
#endif
#endif
...
@@ -28,12 +30,26 @@ LUA_MODULES_ROM
...
@@ -28,12 +30,26 @@ LUA_MODULES_ROM
static
const
luaL_Reg
lualibs
[]
=
{
static
const
luaL_Reg
lualibs
[]
=
{
{
""
,
luaopen_base
},
{
""
,
luaopen_base
},
{
LUA_LOADLIBNAME
,
luaopen_package
},
{
LUA_LOADLIBNAME
,
luaopen_package
},
// {LUA_IOLIBNAME, luaopen_io},
#if defined(LUA_USE_BUILTIN_IO)
{
LUA_STRLIBNAME
,
luaopen_string
},
{
LUA_IOLIBNAME
,
luaopen_io
},
#endif
#if defined(LUA_USE_BUILTIN_STRING)
{
LUA_STRLIBNAME
,
luaopen_string
},
#endif
#if LUA_OPTIMIZE_MEMORY == 0
#if LUA_OPTIMIZE_MEMORY == 0
// {LUA_MATHLIBNAME, luaopen_math},
#if defined(LUA_USE_BUILTIN_MATH)
{
LUA_MATHLIBNAME
,
luaopen_math
},
#endif
#if defined(LUA_USE_BUILTIN_TABLE)
{
LUA_TABLIBNAME
,
luaopen_table
},
{
LUA_TABLIBNAME
,
luaopen_table
},
// {LUA_DBLIBNAME, luaopen_debug},
#endif
#if defined(LUA_USE_BUILTIN_DEBUG)
{
LUA_DBLIBNAME
,
luaopen_debug
},
#endif
#endif
#endif
#if defined(LUA_MODULES_ROM)
#if defined(LUA_MODULES_ROM)
#undef _ROM
#undef _ROM
...
@@ -43,12 +59,30 @@ static const luaL_Reg lualibs[] = {
...
@@ -43,12 +59,30 @@ static const luaL_Reg lualibs[] = {
{
NULL
,
NULL
}
{
NULL
,
NULL
}
};
};
#if defined(LUA_USE_BUILTIN_STRING)
extern
const
luaR_entry
strlib
[];
extern
const
luaR_entry
strlib
[];
#endif
#if defined(LUA_USE_BUILTIN_OS)
extern
const
luaR_entry
syslib
[];
extern
const
luaR_entry
syslib
[];
#endif
#if defined(LUA_USE_BUILTIN_TABLE)
extern
const
luaR_entry
tab_funcs
[];
extern
const
luaR_entry
tab_funcs
[];
// extern const luaR_entry dblib[];
#endif
#if defined(LUA_USE_BUILTIN_DEBUG)
extern
const
luaR_entry
dblib
[];
#endif
#if defined(LUA_USE_BUILTIN_COROUTINE)
extern
const
luaR_entry
co_funcs
[];
extern
const
luaR_entry
co_funcs
[];
// extern const luaR_entry math_map[];
#endif
#if defined(LUA_USE_BUILTIN_MATH)
extern
const
luaR_entry
math_map
[];
#endif
#if defined(LUA_MODULES_ROM) && LUA_OPTIMIZE_MEMORY == 2
#if defined(LUA_MODULES_ROM) && LUA_OPTIMIZE_MEMORY == 2
#undef _ROM
#undef _ROM
#define _ROM( name, openf, table ) extern const luaR_entry table[];
#define _ROM( name, openf, table ) extern const luaR_entry table[];
...
@@ -57,11 +91,30 @@ LUA_MODULES_ROM
...
@@ -57,11 +91,30 @@ LUA_MODULES_ROM
const
luaR_table
lua_rotable
[]
=
const
luaR_table
lua_rotable
[]
=
{
{
#if LUA_OPTIMIZE_MEMORY > 0
#if LUA_OPTIMIZE_MEMORY > 0
#if defined(LUA_USE_BUILTIN_STRING)
{
LUA_STRLIBNAME
,
strlib
},
{
LUA_STRLIBNAME
,
strlib
},
#endif
#if defined(LUA_USE_BUILTIN_TABLE)
{
LUA_TABLIBNAME
,
tab_funcs
},
{
LUA_TABLIBNAME
,
tab_funcs
},
// {LUA_DBLIBNAME, dblib},
#endif
#if defined(LUA_USE_BUILTIN_DEBUG)
{
LUA_DBLIBNAME
,
dblib
},
#endif
#if defined(LUA_USE_BUILTIN_COROUTINE)
{
LUA_COLIBNAME
,
co_funcs
},
{
LUA_COLIBNAME
,
co_funcs
},
// {LUA_MATHLIBNAME, math_map},
#endif
#if defined(LUA_USE_BUILTIN_MATH)
{
LUA_MATHLIBNAME
,
math_map
},
#endif
#if defined(LUA_USE_BUILTIN_OS)
{
LUA_OSLIBNAME
,
syslib
},
#endif
#if defined(LUA_MODULES_ROM) && LUA_OPTIMIZE_MEMORY == 2
#if defined(LUA_MODULES_ROM) && LUA_OPTIMIZE_MEMORY == 2
#undef _ROM
#undef _ROM
#define _ROM( name, openf, table ) { name, table },
#define _ROM( name, openf, table ) { name, table },
...
...
app/modules/modules.h
View file @
fa7cf878
...
@@ -37,6 +37,14 @@
...
@@ -37,6 +37,14 @@
#define ROM_MODULES_NET
#define ROM_MODULES_NET
#endif
#endif
#if defined(LUA_USE_MODULES_COAP)
#define MODULES_COAP "coap"
#define ROM_MODULES_COAP \
_ROM(MODULES_COAP, luaopen_coap, coap_map)
#else
#define ROM_MODULES_COAP
#endif
#if defined(LUA_USE_MODULES_MQTT)
#if defined(LUA_USE_MODULES_MQTT)
#define MODULES_MQTT "mqtt"
#define MODULES_MQTT "mqtt"
#define ROM_MODULES_MQTT \
#define ROM_MODULES_MQTT \
...
@@ -45,6 +53,14 @@
...
@@ -45,6 +53,14 @@
#define ROM_MODULES_MQTT
#define ROM_MODULES_MQTT
#endif
#endif
#if defined(LUA_USE_MODULES_U8G)
#define MODULES_U8G "u8g"
#define ROM_MODULES_U8G \
_ROM(MODULES_U8G, luaopen_u8g, lu8g_map)
#else
#define ROM_MODULES_U8G
#endif
#if defined(LUA_USE_MODULES_I2C)
#if defined(LUA_USE_MODULES_I2C)
#define MODULES_I2C "i2c"
#define MODULES_I2C "i2c"
#define ROM_MODULES_I2C \
#define ROM_MODULES_I2C \
...
@@ -120,17 +136,19 @@
...
@@ -120,17 +136,19 @@
#if defined(LUA_USE_MODULES_WS2812)
#if defined(LUA_USE_MODULES_WS2812)
#define MODULES_WS2812 "ws2812"
#define MODULES_WS2812 "ws2812"
#define ROM_MODULES_WS2812 \
#define ROM_MODULES_WS2812 \
_ROM(MODULES_WS2812, luaopen_ws2812, ws2812_map)
_ROM(MODULES_WS2812, luaopen_ws2812, ws2812_map)
#else
#else
#define ROM_MODULES_WS2812
#define ROM_MODULES_WS2812
#endif
#endif
#define LUA_MODULES_ROM
\
#define LUA_MODULES_ROM \
ROM_MODULES_GPIO \
ROM_MODULES_GPIO \
ROM_MODULES_PWM \
ROM_MODULES_PWM \
ROM_MODULES_WIFI \
ROM_MODULES_WIFI \
ROM_MODULES_MQTT \
ROM_MODULES_COAP \
ROM_MODULES_MQTT \
ROM_MODULES_U8G \
ROM_MODULES_I2C \
ROM_MODULES_I2C \
ROM_MODULES_SPI \
ROM_MODULES_SPI \
ROM_MODULES_TMR \
ROM_MODULES_TMR \
...
@@ -140,8 +158,8 @@
...
@@ -140,8 +158,8 @@
ROM_MODULES_ADC \
ROM_MODULES_ADC \
ROM_MODULES_UART \
ROM_MODULES_UART \
ROM_MODULES_OW \
ROM_MODULES_OW \
ROM_MODULES_BIT
\
ROM_MODULES_BIT
\
ROM_MODULES_WS2812
ROM_MODULES_WS2812
#endif
#endif
app/modules/mqtt.c
View file @
fa7cf878
...
@@ -1102,7 +1102,7 @@ const LUA_REG_TYPE mqtt_map[] =
...
@@ -1102,7 +1102,7 @@ const LUA_REG_TYPE mqtt_map[] =
{
LNILKEY
,
LNILVAL
}
{
LNILKEY
,
LNILVAL
}
};
};
LUALIB_API
int
ICACHE_FLASH_ATTR
luaopen_mqtt
(
lua_State
*
L
)
LUALIB_API
int
luaopen_mqtt
(
lua_State
*
L
)
{
{
#if LUA_OPTIMIZE_MEMORY > 0
#if LUA_OPTIMIZE_MEMORY > 0
luaL_rometatable
(
L
,
"mqtt.socket"
,
(
void
*
)
mqtt_socket_map
);
// create metatable for mqtt.socket
luaL_rometatable
(
L
,
"mqtt.socket"
,
(
void
*
)
mqtt_socket_map
);
// create metatable for mqtt.socket
...
...
app/modules/net.c
View file @
fa7cf878
...
@@ -200,10 +200,15 @@ static void net_dns_found(const char *name, ip_addr_t *ipaddr, void *arg)
...
@@ -200,10 +200,15 @@ static void net_dns_found(const char *name, ip_addr_t *ipaddr, void *arg)
return
;
return
;
}
}
if
(
nud
->
self_ref
==
LUA_NOREF
){
NODE_DBG
(
"self_ref null.
\n
"
);
return
;
}
if
(
ipaddr
==
NULL
)
if
(
ipaddr
==
NULL
)
{
{
NODE_ERR
(
"DNS Fail!
\n
"
);
NODE_ERR
(
"DNS Fail!
\n
"
);
return
;
goto
end
;
}
}
// ipaddr->addr is a uint32_t ip
// ipaddr->addr is a uint32_t ip
...
@@ -214,16 +219,12 @@ static void net_dns_found(const char *name, ip_addr_t *ipaddr, void *arg)
...
@@ -214,16 +219,12 @@ static void net_dns_found(const char *name, ip_addr_t *ipaddr, void *arg)
c_sprintf
(
ip_str
,
IPSTR
,
IP2STR
(
&
(
ipaddr
->
addr
)));
c_sprintf
(
ip_str
,
IPSTR
,
IP2STR
(
&
(
ipaddr
->
addr
)));
}
}
if
(
nud
->
self_ref
==
LUA_NOREF
){
NODE_DBG
(
"self_ref null.
\n
"
);
return
;
}
lua_rawgeti
(
gL
,
LUA_REGISTRYINDEX
,
nud
->
cb_dns_found_ref
);
// the callback function
lua_rawgeti
(
gL
,
LUA_REGISTRYINDEX
,
nud
->
cb_dns_found_ref
);
// the callback function
lua_rawgeti
(
gL
,
LUA_REGISTRYINDEX
,
nud
->
self_ref
);
// pass the userdata(conn) to callback func in lua
lua_rawgeti
(
gL
,
LUA_REGISTRYINDEX
,
nud
->
self_ref
);
// pass the userdata(conn) to callback func in lua
lua_pushstring
(
gL
,
ip_str
);
// the ip para
lua_pushstring
(
gL
,
ip_str
);
// the ip para
lua_call
(
gL
,
2
,
0
);
lua_call
(
gL
,
2
,
0
);
end:
if
((
pesp_conn
->
type
==
ESPCONN_TCP
&&
pesp_conn
->
proto
.
tcp
->
remote_port
==
0
)
if
((
pesp_conn
->
type
==
ESPCONN_TCP
&&
pesp_conn
->
proto
.
tcp
->
remote_port
==
0
)
||
(
pesp_conn
->
type
==
ESPCONN_UDP
&&
pesp_conn
->
proto
.
udp
->
remote_port
==
0
)
){
||
(
pesp_conn
->
type
==
ESPCONN_UDP
&&
pesp_conn
->
proto
.
udp
->
remote_port
==
0
)
){
lua_gc
(
gL
,
LUA_GCSTOP
,
0
);
lua_gc
(
gL
,
LUA_GCSTOP
,
0
);
...
@@ -597,12 +598,22 @@ static void socket_dns_found(const char *name, ip_addr_t *ipaddr, void *arg)
...
@@ -597,12 +598,22 @@ static void socket_dns_found(const char *name, ip_addr_t *ipaddr, void *arg)
NODE_DBG
(
"pesp_conn null.
\n
"
);
NODE_DBG
(
"pesp_conn null.
\n
"
);
return
;
return
;
}
}
lnet_userdata
*
nud
=
(
lnet_userdata
*
)
pesp_conn
->
reverse
;
if
(
nud
==
NULL
)
return
;
if
(
gL
==
NULL
)
return
;
if
(
ipaddr
==
NULL
)
if
(
ipaddr
==
NULL
)
{
{
dns_reconn_count
++
;
dns_reconn_count
++
;
if
(
dns_reconn_count
>=
5
){
if
(
dns_reconn_count
>=
5
){
NODE_ERR
(
"DNS Fail!
\n
"
);
NODE_ERR
(
"DNS Fail!
\n
"
);
lua_gc
(
gL
,
LUA_GCSTOP
,
0
);
if
(
nud
->
self_ref
!=
LUA_NOREF
){
luaL_unref
(
gL
,
LUA_REGISTRYINDEX
,
nud
->
self_ref
);
nud
->
self_ref
=
LUA_NOREF
;
// unref this, and the net.socket userdata will delete it self
}
lua_gc
(
gL
,
LUA_GCRESTART
,
0
);
return
;
return
;
}
}
NODE_ERR
(
"DNS retry %d!
\n
"
,
dns_reconn_count
);
NODE_ERR
(
"DNS retry %d!
\n
"
,
dns_reconn_count
);
...
@@ -1241,6 +1252,31 @@ static int net_socket_unhold( lua_State* L )
...
@@ -1241,6 +1252,31 @@ static int net_socket_unhold( lua_State* L )
return
0
;
return
0
;
}
}
// Lua: ip,port = sk:getpeer()
static
int
net_socket_getpeer
(
lua_State
*
L
)
{
lnet_userdata
*
nud
;
const
char
*
mt
=
"net.socket"
;
nud
=
(
lnet_userdata
*
)
luaL_checkudata
(
L
,
1
,
mt
);
luaL_argcheck
(
L
,
nud
,
1
,
"Server/Socket expected"
);
if
(
nud
!=
NULL
&&
nud
->
pesp_conn
!=
NULL
){
char
temp
[
20
]
=
{
0
};
c_sprintf
(
temp
,
IPSTR
,
IP2STR
(
&
(
nud
->
pesp_conn
->
proto
.
tcp
->
remote_ip
)
)
);
if
(
nud
->
pesp_conn
->
proto
.
tcp
->
remote_port
!=
0
)
{
lua_pushstring
(
L
,
temp
);
lua_pushinteger
(
L
,
nud
->
pesp_conn
->
proto
.
tcp
->
remote_port
);
}
else
{
lua_pushnil
(
L
);
lua_pushnil
(
L
);
}
}
else
{
lua_pushnil
(
L
);
lua_pushnil
(
L
);
}
return
2
;
}
// Lua: socket:dns( string, function(ip) )
// Lua: socket:dns( string, function(ip) )
static
int
net_socket_dns
(
lua_State
*
L
)
static
int
net_socket_dns
(
lua_State
*
L
)
{
{
...
@@ -1302,6 +1338,7 @@ static const LUA_REG_TYPE net_socket_map[] =
...
@@ -1302,6 +1338,7 @@ static const LUA_REG_TYPE net_socket_map[] =
{
LSTRKEY
(
"hold"
),
LFUNCVAL
(
net_socket_hold
)
},
{
LSTRKEY
(
"hold"
),
LFUNCVAL
(
net_socket_hold
)
},
{
LSTRKEY
(
"unhold"
),
LFUNCVAL
(
net_socket_unhold
)
},
{
LSTRKEY
(
"unhold"
),
LFUNCVAL
(
net_socket_unhold
)
},
{
LSTRKEY
(
"dns"
),
LFUNCVAL
(
net_socket_dns
)
},
{
LSTRKEY
(
"dns"
),
LFUNCVAL
(
net_socket_dns
)
},
{
LSTRKEY
(
"getpeer"
),
LFUNCVAL
(
net_socket_getpeer
)
},
// { LSTRKEY( "delete" ), LFUNCVAL ( net_socket_delete ) },
// { LSTRKEY( "delete" ), LFUNCVAL ( net_socket_delete ) },
{
LSTRKEY
(
"__gc"
),
LFUNCVAL
(
net_socket_delete
)
},
{
LSTRKEY
(
"__gc"
),
LFUNCVAL
(
net_socket_delete
)
},
#if LUA_OPTIMIZE_MEMORY > 0
#if LUA_OPTIMIZE_MEMORY > 0
...
...
app/modules/node.c
View file @
fa7cf878
...
@@ -23,12 +23,16 @@
...
@@ -23,12 +23,16 @@
#include "user_interface.h"
#include "user_interface.h"
#include "flash_api.h"
#include "flash_api.h"
#include "flash_fs.h"
#include "flash_fs.h"
#include "user_version.h"
#define CPU80MHZ 80
#define CPU160MHZ 160
// Lua: restart()
// Lua: restart()
static
int
node_restart
(
lua_State
*
L
)
static
int
node_restart
(
lua_State
*
L
)
{
{
system_restart
();
system_restart
();
return
0
;
return
0
;
}
}
// Lua: dsleep( us, option )
// Lua: dsleep( us, option )
...
@@ -55,7 +59,7 @@ static int node_deepsleep( lua_State* L )
...
@@ -55,7 +59,7 @@ static int node_deepsleep( lua_State* L )
else
else
system_deep_sleep
(
us
);
system_deep_sleep
(
us
);
}
}
return
0
;
return
0
;
}
}
// Lua: dsleep_set_options
// Lua: dsleep_set_options
...
@@ -79,10 +83,14 @@ static int node_info( lua_State* L )
...
@@ -79,10 +83,14 @@ static int node_info( lua_State* L )
lua_pushinteger
(
L
,
NODE_VERSION_REVISION
);
lua_pushinteger
(
L
,
NODE_VERSION_REVISION
);
lua_pushinteger
(
L
,
system_get_chip_id
());
// chip id
lua_pushinteger
(
L
,
system_get_chip_id
());
// chip id
lua_pushinteger
(
L
,
spi_flash_get_id
());
// flash id
lua_pushinteger
(
L
,
spi_flash_get_id
());
// flash id
lua_pushinteger
(
L
,
flash_get_size_byte
()
/
1024
);
// flash size in KB
#if defined(FLASH_SAFE_API)
lua_pushinteger
(
L
,
flash_get_mode
());
lua_pushinteger
(
L
,
flash_safe_get_size_byte
()
/
1024
);
// flash size in KB
lua_pushinteger
(
L
,
flash_get_speed
());
#else
return
8
;
lua_pushinteger
(
L
,
flash_rom_get_size_byte
()
/
1024
);
// flash size in KB
#endif // defined(FLASH_SAFE_API)
lua_pushinteger
(
L
,
flash_rom_get_mode
());
lua_pushinteger
(
L
,
flash_rom_get_speed
());
return
8
;
}
}
// Lua: chipid()
// Lua: chipid()
...
@@ -90,7 +98,7 @@ static int node_chipid( lua_State* L )
...
@@ -90,7 +98,7 @@ static int node_chipid( lua_State* L )
{
{
uint32_t
id
=
system_get_chip_id
();
uint32_t
id
=
system_get_chip_id
();
lua_pushinteger
(
L
,
id
);
lua_pushinteger
(
L
,
id
);
return
1
;
return
1
;
}
}
// Lua: readvdd33()
// Lua: readvdd33()
static
int
node_readvdd33
(
lua_State
*
L
)
static
int
node_readvdd33
(
lua_State
*
L
)
...
@@ -105,24 +113,23 @@ static int node_flashid( lua_State* L )
...
@@ -105,24 +113,23 @@ static int node_flashid( lua_State* L )
{
{
uint32_t
id
=
spi_flash_get_id
();
uint32_t
id
=
spi_flash_get_id
();
lua_pushinteger
(
L
,
id
);
lua_pushinteger
(
L
,
id
);
return
1
;
return
1
;
}
}
// Lua: flashsize()
// Lua: flashsize()
static
int
node_flashsize
(
lua_State
*
L
)
static
int
node_flashsize
(
lua_State
*
L
)
{
{
//uint32_t sz = 0;
if
(
lua_type
(
L
,
1
)
==
LUA_TNUMBER
)
//if(lua_type(L, 1) == LUA_TNUMBER)
{
//{
flash_rom_set_size_byte
(
luaL_checkinteger
(
L
,
1
));
// sz = luaL_checkinteger(L, 1);
}
// if(sz > 0)
#if defined(FLASH_SAFE_API)
// {
uint32_t
sz
=
flash_safe_get_size_byte
();
// flash_set_size_byte(sz);
#else
// }
uint32_t
sz
=
flash_rom_get_size_byte
();
//}
#endif // defined(FLASH_SAFE_API)
uint32_t
sz
=
flash_get_size_byte
();
lua_pushinteger
(
L
,
sz
);
lua_pushinteger
(
L
,
sz
);
return
1
;
return
1
;
}
}
// Lua: heap()
// Lua: heap()
...
@@ -130,7 +137,7 @@ static int node_heap( lua_State* L )
...
@@ -130,7 +137,7 @@ static int node_heap( lua_State* L )
{
{
uint32_t
sz
=
system_get_free_heap_size
();
uint32_t
sz
=
system_get_free_heap_size
();
lua_pushinteger
(
L
,
sz
);
lua_pushinteger
(
L
,
sz
);
return
1
;
return
1
;
}
}
static
lua_State
*
gL
=
NULL
;
static
lua_State
*
gL
=
NULL
;
...
@@ -145,7 +152,7 @@ static int node_led( lua_State* L )
...
@@ -145,7 +152,7 @@ static int node_led( lua_State* L )
if
(
lua_isnumber
(
L
,
1
)
)
if
(
lua_isnumber
(
L
,
1
)
)
{
{
low
=
lua_tointeger
(
L
,
1
);
low
=
lua_tointeger
(
L
,
1
);
if
(
low
<
0
){
if
(
low
<
0
)
{
return
luaL_error
(
L
,
"wrong arg type"
);
return
luaL_error
(
L
,
"wrong arg type"
);
}
}
}
else
{
}
else
{
...
@@ -154,7 +161,7 @@ static int node_led( lua_State* L )
...
@@ -154,7 +161,7 @@ static int node_led( lua_State* L )
if
(
lua_isnumber
(
L
,
2
)
)
if
(
lua_isnumber
(
L
,
2
)
)
{
{
high
=
lua_tointeger
(
L
,
2
);
high
=
lua_tointeger
(
L
,
2
);
if
(
high
<
0
){
if
(
high
<
0
)
{
return
luaL_error
(
L
,
"wrong arg type"
);
return
luaL_error
(
L
,
"wrong arg type"
);
}
}
}
else
{
}
else
{
...
@@ -162,14 +169,14 @@ static int node_led( lua_State* L )
...
@@ -162,14 +169,14 @@ static int node_led( lua_State* L )
}
}
led_high_count
=
(
uint32_t
)
high
/
READLINE_INTERVAL
;
led_high_count
=
(
uint32_t
)
high
/
READLINE_INTERVAL
;
led_low_count
=
(
uint32_t
)
low
/
READLINE_INTERVAL
;
led_low_count
=
(
uint32_t
)
low
/
READLINE_INTERVAL
;
return
0
;
return
0
;
}
}
static
int
long_key_ref
=
LUA_NOREF
;
static
int
long_key_ref
=
LUA_NOREF
;
static
int
short_key_ref
=
LUA_NOREF
;
static
int
short_key_ref
=
LUA_NOREF
;
void
default_long_press
(
void
*
arg
){
void
default_long_press
(
void
*
arg
)
{
if
(
led_high_count
==
12
&&
led_low_count
==
12
){
if
(
led_high_count
==
12
&&
led_low_count
==
12
)
{
led_low_count
=
led_high_count
=
6
;
led_low_count
=
led_high_count
=
6
;
}
else
{
}
else
{
led_low_count
=
led_high_count
=
12
;
led_low_count
=
led_high_count
=
12
;
...
@@ -179,32 +186,32 @@ void default_long_press(void *arg){
...
@@ -179,32 +186,32 @@ void default_long_press(void *arg){
// NODE_DBG("default_long_press is called. hc: %d, lc: %d\n", led_high_count, led_low_count);
// NODE_DBG("default_long_press is called. hc: %d, lc: %d\n", led_high_count, led_low_count);
}
}
void
default_short_press
(
void
*
arg
){
void
default_short_press
(
void
*
arg
)
{
system_restart
();
system_restart
();
}
}
void
key_long_press
(
void
*
arg
){
void
key_long_press
(
void
*
arg
)
{
NODE_DBG
(
"key_long_press is called.
\n
"
);
NODE_DBG
(
"key_long_press is called.
\n
"
);
if
(
long_key_ref
==
LUA_NOREF
){
if
(
long_key_ref
==
LUA_NOREF
)
{
default_long_press
(
arg
);
default_long_press
(
arg
);
return
;
return
;
}
}
if
(
!
gL
)
if
(
!
gL
)
return
;
return
;
lua_rawgeti
(
gL
,
LUA_REGISTRYINDEX
,
long_key_ref
);
lua_rawgeti
(
gL
,
LUA_REGISTRYINDEX
,
long_key_ref
);
lua_call
(
gL
,
0
,
0
);
lua_call
(
gL
,
0
,
0
);
}
}
void
key_short_press
(
void
*
arg
){
void
key_short_press
(
void
*
arg
)
{
NODE_DBG
(
"key_short_press is called.
\n
"
);
NODE_DBG
(
"key_short_press is called.
\n
"
);
if
(
short_key_ref
==
LUA_NOREF
){
if
(
short_key_ref
==
LUA_NOREF
)
{
default_short_press
(
arg
);
default_short_press
(
arg
);
return
;
return
;
}
}
if
(
!
gL
)
if
(
!
gL
)
return
;
return
;
lua_rawgeti
(
gL
,
LUA_REGISTRYINDEX
,
short_key_ref
);
lua_rawgeti
(
gL
,
LUA_REGISTRYINDEX
,
short_key_ref
);
lua_call
(
gL
,
0
,
0
);
lua_call
(
gL
,
0
,
0
);
}
}
// Lua: key(type, function)
// Lua: key(type, function)
...
@@ -212,32 +219,32 @@ static int node_key( lua_State* L )
...
@@ -212,32 +219,32 @@ static int node_key( lua_State* L )
{
{
int
*
ref
=
NULL
;
int
*
ref
=
NULL
;
size_t
sl
;
size_t
sl
;
const
char
*
str
=
luaL_checklstring
(
L
,
1
,
&
sl
);
const
char
*
str
=
luaL_checklstring
(
L
,
1
,
&
sl
);
if
(
str
==
NULL
)
if
(
str
==
NULL
)
return
luaL_error
(
L
,
"wrong arg type"
);
return
luaL_error
(
L
,
"wrong arg type"
);
if
(
sl
==
5
&&
c_strcmp
(
str
,
"short"
)
==
0
){
if
(
sl
==
5
&&
c_strcmp
(
str
,
"short"
)
==
0
)
{
ref
=
&
short_key_ref
;
ref
=
&
short_key_ref
;
}
else
if
(
sl
==
4
&&
c_strcmp
(
str
,
"long"
)
==
0
){
}
else
if
(
sl
==
4
&&
c_strcmp
(
str
,
"long"
)
==
0
)
{
ref
=
&
long_key_ref
;
ref
=
&
long_key_ref
;
}
else
{
}
else
{
ref
=
&
short_key_ref
;
ref
=
&
short_key_ref
;
}
}
gL
=
L
;
gL
=
L
;
// luaL_checkanyfunction(L, 2);
// luaL_checkanyfunction(L, 2);
if
(
lua_type
(
L
,
2
)
==
LUA_TFUNCTION
||
lua_type
(
L
,
2
)
==
LUA_TLIGHTFUNCTION
){
if
(
lua_type
(
L
,
2
)
==
LUA_TFUNCTION
||
lua_type
(
L
,
2
)
==
LUA_TLIGHTFUNCTION
)
{
lua_pushvalue
(
L
,
2
);
// copy argument (func) to the top of stack
lua_pushvalue
(
L
,
2
);
// copy argument (func) to the top of stack
if
(
*
ref
!=
LUA_NOREF
)
if
(
*
ref
!=
LUA_NOREF
)
luaL_unref
(
L
,
LUA_REGISTRYINDEX
,
*
ref
);
luaL_unref
(
L
,
LUA_REGISTRYINDEX
,
*
ref
);
*
ref
=
luaL_ref
(
L
,
LUA_REGISTRYINDEX
);
*
ref
=
luaL_ref
(
L
,
LUA_REGISTRYINDEX
);
}
else
{
// unref the key press function
}
else
{
// unref the key press function
if
(
*
ref
!=
LUA_NOREF
)
if
(
*
ref
!=
LUA_NOREF
)
luaL_unref
(
L
,
LUA_REGISTRYINDEX
,
*
ref
);
luaL_unref
(
L
,
LUA_REGISTRYINDEX
,
*
ref
);
*
ref
=
LUA_NOREF
;
*
ref
=
LUA_NOREF
;
}
}
return
0
;
return
0
;
}
}
#endif
#endif
...
@@ -247,15 +254,15 @@ extern void dojob(lua_Load *load);
...
@@ -247,15 +254,15 @@ extern void dojob(lua_Load *load);
// Lua: input("string")
// Lua: input("string")
static
int
node_input
(
lua_State
*
L
)
static
int
node_input
(
lua_State
*
L
)
{
{
size_t
l
=
0
;
size_t
l
=
0
;
const
char
*
s
=
luaL_checklstring
(
L
,
1
,
&
l
);
const
char
*
s
=
luaL_checklstring
(
L
,
1
,
&
l
);
if
(
s
!=
NULL
&&
l
>
0
&&
l
<
LUA_MAXINPUT
-
1
)
if
(
s
!=
NULL
&&
l
>
0
&&
l
<
LUA_MAXINPUT
-
1
)
{
{
lua_Load
*
load
=
&
gLoad
;
lua_Load
*
load
=
&
gLoad
;
if
(
load
->
line_position
==
0
){
if
(
load
->
line_position
==
0
)
{
c_memcpy
(
load
->
line
,
s
,
l
);
c_memcpy
(
load
->
line
,
s
,
l
);
load
->
line
[
l
+
1
]
=
'\0'
;
load
->
line
[
l
+
1
]
=
'\0'
;
load
->
line_position
=
c_strlen
(
load
->
line
)
+
1
;
load
->
line_position
=
c_strlen
(
load
->
line
)
+
1
;
load
->
done
=
1
;
load
->
done
=
1
;
NODE_DBG
(
"Get command:
\n
"
);
NODE_DBG
(
"Get command:
\n
"
);
NODE_DBG
(
load
->
line
);
// buggy here
NODE_DBG
(
load
->
line
);
// buggy here
...
@@ -270,18 +277,18 @@ static int node_input( lua_State* L )
...
@@ -270,18 +277,18 @@ static int node_input( lua_State* L )
static
int
output_redir_ref
=
LUA_NOREF
;
static
int
output_redir_ref
=
LUA_NOREF
;
static
int
serial_debug
=
1
;
static
int
serial_debug
=
1
;
void
output_redirect
(
const
char
*
str
){
void
output_redirect
(
const
char
*
str
)
{
// if(c_strlen(str)>=TX_BUFF_SIZE){
// if(c_strlen(str)>=TX_BUFF_SIZE){
// NODE_ERR("output too long.\n");
// NODE_ERR("output too long.\n");
// return;
// return;
// }
// }
if
(
output_redir_ref
==
LUA_NOREF
||
!
gL
){
if
(
output_redir_ref
==
LUA_NOREF
||
!
gL
)
{
uart0_sendStr
(
str
);
uart0_sendStr
(
str
);
return
;
return
;
}
}
if
(
serial_debug
!=
0
){
if
(
serial_debug
!=
0
)
{
uart0_sendStr
(
str
);
uart0_sendStr
(
str
);
}
}
...
@@ -295,15 +302,15 @@ static int node_output( lua_State* L )
...
@@ -295,15 +302,15 @@ static int node_output( lua_State* L )
{
{
gL
=
L
;
gL
=
L
;
// luaL_checkanyfunction(L, 1);
// luaL_checkanyfunction(L, 1);
if
(
lua_type
(
L
,
1
)
==
LUA_TFUNCTION
||
lua_type
(
L
,
1
)
==
LUA_TLIGHTFUNCTION
){
if
(
lua_type
(
L
,
1
)
==
LUA_TFUNCTION
||
lua_type
(
L
,
1
)
==
LUA_TLIGHTFUNCTION
)
{
lua_pushvalue
(
L
,
1
);
// copy argument (func) to the top of stack
lua_pushvalue
(
L
,
1
);
// copy argument (func) to the top of stack
if
(
output_redir_ref
!=
LUA_NOREF
)
if
(
output_redir_ref
!=
LUA_NOREF
)
luaL_unref
(
L
,
LUA_REGISTRYINDEX
,
output_redir_ref
);
luaL_unref
(
L
,
LUA_REGISTRYINDEX
,
output_redir_ref
);
output_redir_ref
=
luaL_ref
(
L
,
LUA_REGISTRYINDEX
);
output_redir_ref
=
luaL_ref
(
L
,
LUA_REGISTRYINDEX
);
}
else
{
// unref the key press function
}
else
{
// unref the key press function
if
(
output_redir_ref
!=
LUA_NOREF
)
if
(
output_redir_ref
!=
LUA_NOREF
)
luaL_unref
(
L
,
LUA_REGISTRYINDEX
,
output_redir_ref
);
luaL_unref
(
L
,
LUA_REGISTRYINDEX
,
output_redir_ref
);
output_redir_ref
=
LUA_NOREF
;
output_redir_ref
=
LUA_NOREF
;
serial_debug
=
1
;
serial_debug
=
1
;
return
0
;
return
0
;
}
}
...
@@ -311,26 +318,26 @@ static int node_output( lua_State* L )
...
@@ -311,26 +318,26 @@ static int node_output( lua_State* L )
if
(
lua_isnumber
(
L
,
2
)
)
if
(
lua_isnumber
(
L
,
2
)
)
{
{
serial_debug
=
lua_tointeger
(
L
,
2
);
serial_debug
=
lua_tointeger
(
L
,
2
);
if
(
serial_debug
!=
0
)
if
(
serial_debug
!=
0
)
serial_debug
=
1
;
serial_debug
=
1
;
}
else
{
}
else
{
serial_debug
=
1
;
// default to 1
serial_debug
=
1
;
// default to 1
}
}
return
0
;
return
0
;
}
}
static
int
writer
(
lua_State
*
L
,
const
void
*
p
,
size_t
size
,
void
*
u
)
static
int
writer
(
lua_State
*
L
,
const
void
*
p
,
size_t
size
,
void
*
u
)
{
{
UNUSED
(
L
);
UNUSED
(
L
);
int
file_fd
=
*
(
(
int
*
)
u
);
int
file_fd
=
*
(
(
int
*
)
u
);
if
((
FS_OPEN_OK
-
1
)
==
file_fd
)
if
((
FS_OPEN_OK
-
1
)
==
file_fd
)
return
1
;
return
1
;
NODE_DBG
(
"get fd:%d,size:%d
\n
"
,
file_fd
,
size
);
NODE_DBG
(
"get fd:%d,size:%d
\n
"
,
file_fd
,
size
);
if
(
size
!=
0
&&
(
size
!=
fs_write
(
file_fd
,
(
const
char
*
)
p
,
size
))
)
if
(
size
!=
0
&&
(
size
!=
fs_write
(
file_fd
,
(
const
char
*
)
p
,
size
))
)
return
1
;
return
1
;
NODE_DBG
(
"write fd:%d,size:%d
\n
"
,
file_fd
,
size
);
NODE_DBG
(
"write fd:%d,size:%d
\n
"
,
file_fd
,
size
);
return
0
;
return
0
;
}
}
...
@@ -342,55 +349,73 @@ static int node_compile( lua_State* L )
...
@@ -342,55 +349,73 @@ static int node_compile( lua_State* L )
int
file_fd
=
FS_OPEN_OK
-
1
;
int
file_fd
=
FS_OPEN_OK
-
1
;
size_t
len
;
size_t
len
;
const
char
*
fname
=
luaL_checklstring
(
L
,
1
,
&
len
);
const
char
*
fname
=
luaL_checklstring
(
L
,
1
,
&
len
);
if
(
len
>
FS_NAME_MAX_LENGTH
)
if
(
len
>
FS_NAME_MAX_LENGTH
)
return
luaL_error
(
L
,
"filename too long"
);
return
luaL_error
(
L
,
"filename too long"
);
char
output
[
FS_NAME_MAX_LENGTH
];
char
output
[
FS_NAME_MAX_LENGTH
];
c_strcpy
(
output
,
fname
);
c_strcpy
(
output
,
fname
);
// check here that filename end with ".lua".
// check here that filename end with ".lua".
if
(
len
<
4
||
(
c_strcmp
(
output
+
len
-
4
,
".lua"
)
!=
0
)
)
if
(
len
<
4
||
(
c_strcmp
(
output
+
len
-
4
,
".lua"
)
!=
0
)
)
return
luaL_error
(
L
,
"not a .lua file"
);
return
luaL_error
(
L
,
"not a .lua file"
);
output
[
c_strlen
(
output
)
-
2
]
=
'c'
;
output
[
c_strlen
(
output
)
-
2
]
=
'c'
;
output
[
c_strlen
(
output
)
-
1
]
=
'\0'
;
output
[
c_strlen
(
output
)
-
1
]
=
'\0'
;
NODE_DBG
(
output
);
NODE_DBG
(
output
);
NODE_DBG
(
"
\n
"
);
NODE_DBG
(
"
\n
"
);
if
(
luaL_loadfsfile
(
L
,
fname
)
!=
0
){
if
(
luaL_loadfsfile
(
L
,
fname
)
!=
0
)
{
return
luaL_error
(
L
,
lua_tostring
(
L
,
-
1
));
return
luaL_error
(
L
,
lua_tostring
(
L
,
-
1
));
}
}
f
=
toproto
(
L
,
-
1
);
f
=
toproto
(
L
,
-
1
);
int
stripping
=
1
;
/* strip debug information? */
int
stripping
=
1
;
/* strip debug information? */
file_fd
=
fs_open
(
output
,
fs_mode2flag
(
"w+"
));
file_fd
=
fs_open
(
output
,
fs_mode2flag
(
"w+"
));
if
(
file_fd
<
FS_OPEN_OK
)
if
(
file_fd
<
FS_OPEN_OK
)
{
{
return
luaL_error
(
L
,
"cannot open/write to file"
);
return
luaL_error
(
L
,
"cannot open/write to file"
);
}
}
lua_lock
(
L
);
lua_lock
(
L
);
int
result
=
luaU_dump
(
L
,
f
,
writer
,
&
file_fd
,
stripping
);
int
result
=
luaU_dump
(
L
,
f
,
writer
,
&
file_fd
,
stripping
);
lua_unlock
(
L
);
lua_unlock
(
L
);
fs_flush
(
file_fd
);
fs_flush
(
file_fd
);
fs_close
(
file_fd
);
fs_close
(
file_fd
);
file_fd
=
FS_OPEN_OK
-
1
;
file_fd
=
FS_OPEN_OK
-
1
;
if
(
result
==
LUA_ERR_CC_INTOVERFLOW
){
if
(
result
==
LUA_ERR_CC_INTOVERFLOW
)
{
return
luaL_error
(
L
,
"value too big or small for target integer type"
);
return
luaL_error
(
L
,
"value too big or small for target integer type"
);
}
}
if
(
result
==
LUA_ERR_CC_NOTINTEGER
){
if
(
result
==
LUA_ERR_CC_NOTINTEGER
)
{
return
luaL_error
(
L
,
"target lua_Number is integral but fractional value found"
);
return
luaL_error
(
L
,
"target lua_Number is integral but fractional value found"
);
}
}
return
0
;
return
0
;
}
}
// Lua: setcpufreq(mhz)
// mhz is either CPU80MHZ od CPU160MHZ
static
int
node_setcpufreq
(
lua_State
*
L
)
{
// http://www.esp8266.com/viewtopic.php?f=21&t=1369
uint32_t
new_freq
=
luaL_checkinteger
(
L
,
1
);
if
(
new_freq
==
CPU160MHZ
){
REG_SET_BIT
(
0x3ff00014
,
BIT
(
0
));
os_update_cpu_frequency
(
CPU160MHZ
);
}
else
{
REG_CLR_BIT
(
0x3ff00014
,
BIT
(
0
));
os_update_cpu_frequency
(
CPU80MHZ
);
}
new_freq
=
ets_get_cpu_frequency
();
lua_pushinteger
(
L
,
new_freq
);
return
1
;
}
// Module function map
// Module function map
#define MIN_OPT_LEVEL 2
#define MIN_OPT_LEVEL 2
#include "lrodefs.h"
#include "lrodefs.h"
const
LUA_REG_TYPE
node_map
[]
=
const
LUA_REG_TYPE
node_map
[]
=
{
{
{
LSTRKEY
(
"restart"
),
LFUNCVAL
(
node_restart
)
},
{
LSTRKEY
(
"restart"
),
LFUNCVAL
(
node_restart
)
},
{
LSTRKEY
(
"dsleep"
),
LFUNCVAL
(
node_deepsleep
)
},
{
LSTRKEY
(
"dsleep"
),
LFUNCVAL
(
node_deepsleep
)
},
...
@@ -407,7 +432,10 @@ const LUA_REG_TYPE node_map[] =
...
@@ -407,7 +432,10 @@ const LUA_REG_TYPE node_map[] =
{
LSTRKEY
(
"output"
),
LFUNCVAL
(
node_output
)
},
{
LSTRKEY
(
"output"
),
LFUNCVAL
(
node_output
)
},
{
LSTRKEY
(
"readvdd33"
),
LFUNCVAL
(
node_readvdd33
)
},
{
LSTRKEY
(
"readvdd33"
),
LFUNCVAL
(
node_readvdd33
)
},
{
LSTRKEY
(
"compile"
),
LFUNCVAL
(
node_compile
)
},
{
LSTRKEY
(
"compile"
),
LFUNCVAL
(
node_compile
)
},
// Combined to dsleep(us, option)
{
LSTRKEY
(
"CPU80MHZ"
),
LNUMVAL
(
CPU80MHZ
)
},
{
LSTRKEY
(
"CPU160MHZ"
),
LNUMVAL
(
CPU160MHZ
)
},
{
LSTRKEY
(
"setcpufreq"
),
LFUNCVAL
(
node_setcpufreq
)
},
// Combined to dsleep(us, option)
// { LSTRKEY( "dsleepsetoption" ), LFUNCVAL( node_deepsleep_setoption) },
// { LSTRKEY( "dsleepsetoption" ), LFUNCVAL( node_deepsleep_setoption) },
#if LUA_OPTIMIZE_MEMORY > 0
#if LUA_OPTIMIZE_MEMORY > 0
...
@@ -424,5 +452,5 @@ LUALIB_API int luaopen_node( lua_State *L )
...
@@ -424,5 +452,5 @@ LUALIB_API int luaopen_node( lua_State *L )
// Add constants
// Add constants
return
1
;
return
1
;
#endif // #if LUA_OPTIMIZE_MEMORY > 0
#endif // #if LUA_OPTIMIZE_MEMORY > 0
}
}
app/modules/tmr.c
View file @
fa7cf878
...
@@ -148,24 +148,30 @@ static int tmr_wdclr( lua_State* L )
...
@@ -148,24 +148,30 @@ static int tmr_wdclr( lua_State* L )
}
}
static
os_timer_t
rtc_timer_updator
;
static
os_timer_t
rtc_timer_updator
;
static
uint
64
_t
cur_count
=
0
;
static
uint
32
_t
cur_count
=
0
;
static
uint
64
_t
rtc_
u
s
=
0
;
static
uint
32
_t
rtc_
10m
s
=
0
;
void
rtc_timer_update_cb
(
void
*
arg
){
void
rtc_timer_update_cb
(
void
*
arg
){
uint64_t
t
=
(
uint64_t
)
system_get_rtc_time
();
uint32_t
t
=
(
uint32_t
)
system_get_rtc_time
();
uint64_t
delta
=
(
t
>=
cur_count
)
?
(
t
-
cur_count
)
:
(
0x100000000
+
t
-
cur_count
);
uint32_t
delta
=
0
;
if
(
t
>=
cur_count
){
delta
=
t
-
cur_count
;
}
else
{
delta
=
0xFFFFFFF
-
cur_count
+
t
+
1
;
}
// uint64_t delta = (t>=cur_count)?(t - cur_count):(0x100000000 + t - cur_count);
// NODE_ERR("%x\n",t);
// NODE_ERR("%x\n",t);
cur_count
=
t
;
cur_count
=
t
;
u
nsigned
c
=
system_rtc_clock_cali_proc
();
u
int32_t
c
=
system_rtc_clock_cali_proc
();
uint
64
_t
itg
=
c
>>
12
;
uint
32
_t
itg
=
c
>>
12
;
// ~=5
uint
64
_t
dec
=
c
&
0xFFF
;
uint
32
_t
dec
=
c
&
0xFFF
;
// ~=2ff
rtc_
u
s
+=
(
delta
*
itg
+
((
delta
*
dec
)
>>
12
));
rtc_
10m
s
+=
(
delta
*
itg
+
((
delta
*
dec
)
>>
12
))
/
10000
;
// TODO: store rtc_
u
s to rtc memory.
// TODO: store rtc_
10m
s to rtc memory.
}
}
// Lua: time() , return rtc time in second
// Lua: time() , return rtc time in second
static
int
tmr_time
(
lua_State
*
L
)
static
int
tmr_time
(
lua_State
*
L
)
{
{
uint
64
_t
local
=
rtc_
u
s
;
uint
32
_t
local
=
rtc_
10m
s
;
lua_pushinteger
(
L
,
((
uint32_t
)(
local
/
100
0000
))
&
0x7FFFFFFF
);
lua_pushinteger
(
L
,
((
uint32_t
)(
local
/
100
))
&
0x7FFFFFFF
);
return
1
;
return
1
;
}
}
...
...
app/modules/u8g.c
0 → 100644
View file @
fa7cf878
// Module for U8glib
#include "lualib.h"
#include "lauxlib.h"
#include "platform.h"
#include "auxmods.h"
#include "lrotable.h"
//#include "c_string.h"
#include "c_stdlib.h"
#include "u8g.h"
#include "u8g_config.h"
struct
_lu8g_userdata_t
{
u8g_t
u8g
;
u8g_pb_t
pb
;
u8g_dev_t
dev
;
};
typedef
struct
_lu8g_userdata_t
lu8g_userdata_t
;
// shorthand macro for the u8g structure inside the userdata
#define LU8G (&(lud->u8g))
// function to read 4-byte aligned from program memory AKA irom0
u8g_pgm_uint8_t
ICACHE_FLASH_ATTR
u8g_pgm_read
(
const
u8g_pgm_uint8_t
*
adr
)
{
uint32_t
iadr
=
(
uint32_t
)
adr
;
// set up pointer to 4-byte aligned memory location
uint32_t
*
ptr
=
(
uint32_t
*
)(
iadr
&
~
0x3
);
// read 4-byte aligned
uint32_t
pgm_data
=
*
ptr
;
// return the correct byte within the retrieved 32bit word
return
pgm_data
>>
((
iadr
%
4
)
*
8
);
}
// helper function: retrieve and check userdata argument
static
lu8g_userdata_t
*
get_lud
(
lua_State
*
L
)
{
lu8g_userdata_t
*
lud
=
(
lu8g_userdata_t
*
)
luaL_checkudata
(
L
,
1
,
"u8g.display"
);
luaL_argcheck
(
L
,
lud
,
1
,
"u8g.display expected"
);
return
lud
;
}
// helper function: retrieve given number of integer arguments
static
void
lu8g_get_int_args
(
lua_State
*
L
,
uint8_t
stack
,
uint8_t
num
,
u8g_uint_t
*
args
)
{
while
(
num
--
>
0
)
{
*
args
++
=
luaL_checkinteger
(
L
,
stack
++
);
}
}
// Lua: u8g.begin( self )
static
int
lu8g_begin
(
lua_State
*
L
)
{
lu8g_userdata_t
*
lud
;
if
((
lud
=
get_lud
(
L
))
==
NULL
)
return
0
;
u8g_Begin
(
LU8G
);
return
0
;
}
// Lua: u8g.setFont( self, font )
static
int
lu8g_setFont
(
lua_State
*
L
)
{
lu8g_userdata_t
*
lud
;
if
((
lud
=
get_lud
(
L
))
==
NULL
)
return
0
;
u8g_fntpgm_uint8_t
*
font
=
(
u8g_fntpgm_uint8_t
*
)
lua_touserdata
(
L
,
2
);
if
(
font
!=
NULL
)
u8g_SetFont
(
LU8G
,
font
);
return
0
;
}
// Lua: u8g.setFontRefHeightAll( self )
static
int
lu8g_setFontRefHeightAll
(
lua_State
*
L
)
{
lu8g_userdata_t
*
lud
;
if
((
lud
=
get_lud
(
L
))
==
NULL
)
return
0
;
u8g_SetFontRefHeightAll
(
LU8G
);
return
0
;
}
// Lua: u8g.setFontRefHeightExtendedText( self )
static
int
lu8g_setFontRefHeightExtendedText
(
lua_State
*
L
)
{
lu8g_userdata_t
*
lud
;
if
((
lud
=
get_lud
(
L
))
==
NULL
)
return
0
;
u8g_SetFontRefHeightExtendedText
(
LU8G
);
return
0
;
}
// Lua: u8g.setFontRefHeightText( self )
static
int
lu8g_setFontRefHeightText
(
lua_State
*
L
)
{
lu8g_userdata_t
*
lud
;
if
((
lud
=
get_lud
(
L
))
==
NULL
)
return
0
;
u8g_SetFontRefHeightText
(
LU8G
);
return
0
;
}
// Lua: u8g.setDefaultBackgroundColor( self )
static
int
lu8g_setDefaultBackgroundColor
(
lua_State
*
L
)
{
lu8g_userdata_t
*
lud
;
if
((
lud
=
get_lud
(
L
))
==
NULL
)
return
0
;
u8g_SetDefaultBackgroundColor
(
LU8G
);
return
0
;
}
// Lua: u8g.setDefaultForegroundColor( self )
static
int
lu8g_setDefaultForegroundColor
(
lua_State
*
L
)
{
lu8g_userdata_t
*
lud
;
if
((
lud
=
get_lud
(
L
))
==
NULL
)
return
0
;
u8g_SetDefaultForegroundColor
(
LU8G
);
return
0
;
}
// Lua: u8g.setFontPosBaseline( self )
static
int
lu8g_setFontPosBaseline
(
lua_State
*
L
)
{
lu8g_userdata_t
*
lud
;
if
((
lud
=
get_lud
(
L
))
==
NULL
)
return
0
;
u8g_SetFontPosBaseline
(
LU8G
);
return
0
;
}
// Lua: u8g.setFontPosBottom( self )
static
int
lu8g_setFontPosBottom
(
lua_State
*
L
)
{
lu8g_userdata_t
*
lud
;
if
((
lud
=
get_lud
(
L
))
==
NULL
)
return
0
;
u8g_SetFontPosBottom
(
LU8G
);
return
0
;
}
// Lua: u8g.setFontPosCenter( self )
static
int
lu8g_setFontPosCenter
(
lua_State
*
L
)
{
lu8g_userdata_t
*
lud
;
if
((
lud
=
get_lud
(
L
))
==
NULL
)
return
0
;
u8g_SetFontPosCenter
(
LU8G
);
return
0
;
}
// Lua: u8g.setFontPosTop( self )
static
int
lu8g_setFontPosTop
(
lua_State
*
L
)
{
lu8g_userdata_t
*
lud
;
if
((
lud
=
get_lud
(
L
))
==
NULL
)
return
0
;
u8g_SetFontPosTop
(
LU8G
);
return
0
;
}
// Lua: int = u8g.getFontAscent( self )
static
int
lu8g_getFontAscent
(
lua_State
*
L
)
{
lu8g_userdata_t
*
lud
;
if
((
lud
=
get_lud
(
L
))
==
NULL
)
return
0
;
lua_pushinteger
(
L
,
u8g_GetFontAscent
(
LU8G
)
);
return
1
;
}
// Lua: int = u8g.getFontDescent( self )
static
int
lu8g_getFontDescent
(
lua_State
*
L
)
{
lu8g_userdata_t
*
lud
;
if
((
lud
=
get_lud
(
L
))
==
NULL
)
return
0
;
lua_pushinteger
(
L
,
u8g_GetFontDescent
(
LU8G
)
);
return
1
;
}
// Lua: int = u8g.getFontLineSpacing( self )
static
int
lu8g_getFontLineSpacing
(
lua_State
*
L
)
{
lu8g_userdata_t
*
lud
;
if
((
lud
=
get_lud
(
L
))
==
NULL
)
return
0
;
lua_pushinteger
(
L
,
u8g_GetFontLineSpacing
(
LU8G
)
);
return
1
;
}
// Lua: int = u8g.getMode( self )
static
int
lu8g_getMode
(
lua_State
*
L
)
{
lu8g_userdata_t
*
lud
;
if
((
lud
=
get_lud
(
L
))
==
NULL
)
return
0
;
lua_pushinteger
(
L
,
u8g_GetMode
(
LU8G
)
);
return
1
;
}
// Lua: u8g.setColorIndex( self, color )
static
int
lu8g_setColorIndex
(
lua_State
*
L
)
{
lu8g_userdata_t
*
lud
;
if
((
lud
=
get_lud
(
L
))
==
NULL
)
return
0
;
u8g_SetColorIndex
(
LU8G
,
luaL_checkinteger
(
L
,
2
)
);
return
0
;
}
// Lua: int = u8g.getColorIndex( self )
static
int
lu8g_getColorIndex
(
lua_State
*
L
)
{
lu8g_userdata_t
*
lud
;
if
((
lud
=
get_lud
(
L
))
==
NULL
)
return
0
;
lua_pushinteger
(
L
,
u8g_GetColorIndex
(
LU8G
)
);
return
1
;
}
static
int
lu8g_generic_drawStr
(
lua_State
*
L
,
uint8_t
rot
)
{
lu8g_userdata_t
*
lud
;
if
((
lud
=
get_lud
(
L
))
==
NULL
)
return
0
;
u8g_uint_t
args
[
2
];
lu8g_get_int_args
(
L
,
2
,
2
,
args
);
const
char
*
s
=
luaL_checkstring
(
L
,
(
1
+
2
)
+
1
);
if
(
s
==
NULL
)
return
0
;
switch
(
rot
)
{
case
1
:
lua_pushinteger
(
L
,
u8g_DrawStr90
(
LU8G
,
args
[
0
],
args
[
1
],
s
)
);
break
;
case
2
:
lua_pushinteger
(
L
,
u8g_DrawStr180
(
LU8G
,
args
[
0
],
args
[
1
],
s
)
);
break
;
case
3
:
lua_pushinteger
(
L
,
u8g_DrawStr270
(
LU8G
,
args
[
0
],
args
[
1
],
s
)
);
break
;
default:
lua_pushinteger
(
L
,
u8g_DrawStr
(
LU8G
,
args
[
0
],
args
[
1
],
s
)
);
break
;
}
return
1
;
}
// Lua: pix_len = u8g.drawStr( self, x, y, string )
static
int
lu8g_drawStr
(
lua_State
*
L
)
{
lu8g_userdata_t
*
lud
;
return
lu8g_generic_drawStr
(
L
,
0
);
}
// Lua: pix_len = u8g.drawStr90( self, x, y, string )
static
int
lu8g_drawStr90
(
lua_State
*
L
)
{
lu8g_userdata_t
*
lud
;
return
lu8g_generic_drawStr
(
L
,
1
);
}
// Lua: pix_len = u8g.drawStr180( self, x, y, string )
static
int
lu8g_drawStr180
(
lua_State
*
L
)
{
lu8g_userdata_t
*
lud
;
return
lu8g_generic_drawStr
(
L
,
2
);
}
// Lua: pix_len = u8g.drawStr270( self, x, y, string )
static
int
lu8g_drawStr270
(
lua_State
*
L
)
{
lu8g_userdata_t
*
lud
;
return
lu8g_generic_drawStr
(
L
,
3
);
}
// Lua: u8g.drawLine( self, x1, y1, x2, y2 )
static
int
lu8g_drawLine
(
lua_State
*
L
)
{
lu8g_userdata_t
*
lud
;
if
((
lud
=
get_lud
(
L
))
==
NULL
)
return
0
;
u8g_uint_t
args
[
4
];
lu8g_get_int_args
(
L
,
2
,
4
,
args
);
u8g_DrawLine
(
LU8G
,
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
]
);
return
0
;
}
// Lua: u8g.drawTriangle( self, x0, y0, x1, y1, x2, y2 )
static
int
lu8g_drawTriangle
(
lua_State
*
L
)
{
lu8g_userdata_t
*
lud
;
if
((
lud
=
get_lud
(
L
))
==
NULL
)
return
0
;
u8g_uint_t
args
[
6
];
lu8g_get_int_args
(
L
,
2
,
6
,
args
);
u8g_DrawTriangle
(
LU8G
,
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
],
args
[
4
],
args
[
5
]
);
return
0
;
}
// Lua: u8g.drawBox( self, x, y, width, height )
static
int
lu8g_drawBox
(
lua_State
*
L
)
{
lu8g_userdata_t
*
lud
;
if
((
lud
=
get_lud
(
L
))
==
NULL
)
return
0
;
u8g_uint_t
args
[
4
];
lu8g_get_int_args
(
L
,
2
,
4
,
args
);
u8g_DrawBox
(
LU8G
,
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
]
);
return
0
;
}
// Lua: u8g.drawRBox( self, x, y, width, height, radius )
static
int
lu8g_drawRBox
(
lua_State
*
L
)
{
lu8g_userdata_t
*
lud
;
if
((
lud
=
get_lud
(
L
))
==
NULL
)
return
0
;
u8g_uint_t
args
[
5
];
lu8g_get_int_args
(
L
,
2
,
5
,
args
);
u8g_DrawRBox
(
LU8G
,
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
],
args
[
4
]
);
return
0
;
}
// Lua: u8g.drawFrame( self, x, y, width, height )
static
int
lu8g_drawFrame
(
lua_State
*
L
)
{
lu8g_userdata_t
*
lud
;
if
((
lud
=
get_lud
(
L
))
==
NULL
)
return
0
;
u8g_uint_t
args
[
4
];
lu8g_get_int_args
(
L
,
2
,
4
,
args
);
u8g_DrawFrame
(
LU8G
,
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
]
);
return
0
;
}
// Lua: u8g.drawRFrame( self, x, y, width, height, radius )
static
int
lu8g_drawRFrame
(
lua_State
*
L
)
{
lu8g_userdata_t
*
lud
;
if
((
lud
=
get_lud
(
L
))
==
NULL
)
return
0
;
u8g_uint_t
args
[
5
];
lu8g_get_int_args
(
L
,
2
,
5
,
args
);
u8g_DrawRFrame
(
LU8G
,
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
],
args
[
4
]
);
return
0
;
}
// Lua: u8g.drawDisc( self, x0, y0, rad, opt = U8G_DRAW_ALL )
static
int
lu8g_drawDisc
(
lua_State
*
L
)
{
lu8g_userdata_t
*
lud
;
if
((
lud
=
get_lud
(
L
))
==
NULL
)
return
0
;
u8g_uint_t
args
[
3
];
lu8g_get_int_args
(
L
,
2
,
3
,
args
);
u8g_uint_t
opt
=
luaL_optinteger
(
L
,
(
1
+
3
)
+
1
,
U8G_DRAW_ALL
);
u8g_DrawDisc
(
LU8G
,
args
[
0
],
args
[
1
],
args
[
2
],
opt
);
return
0
;
}
// Lua: u8g.drawCircle( self, x0, y0, rad, opt = U8G_DRAW_ALL )
static
int
lu8g_drawCircle
(
lua_State
*
L
)
{
lu8g_userdata_t
*
lud
;
if
((
lud
=
get_lud
(
L
))
==
NULL
)
return
0
;
u8g_uint_t
args
[
3
];
lu8g_get_int_args
(
L
,
2
,
3
,
args
);
u8g_uint_t
opt
=
luaL_optinteger
(
L
,
(
1
+
3
)
+
1
,
U8G_DRAW_ALL
);
u8g_DrawCircle
(
LU8G
,
args
[
0
],
args
[
1
],
args
[
2
],
opt
);
return
0
;
}
// Lua: u8g.drawEllipse( self, x0, y0, rx, ry, opt = U8G_DRAW_ALL )
static
int
lu8g_drawEllipse
(
lua_State
*
L
)
{
lu8g_userdata_t
*
lud
;
if
((
lud
=
get_lud
(
L
))
==
NULL
)
return
0
;
u8g_uint_t
args
[
4
];
lu8g_get_int_args
(
L
,
2
,
4
,
args
);
u8g_uint_t
opt
=
luaL_optinteger
(
L
,
(
1
+
4
)
+
1
,
U8G_DRAW_ALL
);
u8g_DrawEllipse
(
LU8G
,
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
],
opt
);
return
0
;
}
// Lua: u8g.drawFilledEllipse( self, x0, y0, rx, ry, opt = U8G_DRAW_ALL )
static
int
lu8g_drawFilledEllipse
(
lua_State
*
L
)
{
lu8g_userdata_t
*
lud
;
if
((
lud
=
get_lud
(
L
))
==
NULL
)
return
0
;
u8g_uint_t
args
[
4
];
lu8g_get_int_args
(
L
,
2
,
4
,
args
);
u8g_uint_t
opt
=
luaL_optinteger
(
L
,
(
1
+
4
)
+
1
,
U8G_DRAW_ALL
);
u8g_DrawFilledEllipse
(
LU8G
,
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
],
opt
);
return
0
;
}
// Lua: u8g.drawPixel( self, x, y )
static
int
lu8g_drawPixel
(
lua_State
*
L
)
{
lu8g_userdata_t
*
lud
;
if
((
lud
=
get_lud
(
L
))
==
NULL
)
return
0
;
u8g_uint_t
args
[
2
];
lu8g_get_int_args
(
L
,
2
,
2
,
args
);
u8g_DrawPixel
(
LU8G
,
args
[
0
],
args
[
1
]
);
return
0
;
}
// Lua: u8g.drawHLine( self, x, y, width )
static
int
lu8g_drawHLine
(
lua_State
*
L
)
{
lu8g_userdata_t
*
lud
;
if
((
lud
=
get_lud
(
L
))
==
NULL
)
return
0
;
u8g_uint_t
args
[
3
];
lu8g_get_int_args
(
L
,
2
,
3
,
args
);
u8g_DrawHLine
(
LU8G
,
args
[
0
],
args
[
1
],
args
[
2
]
);
return
0
;
}
// Lua: u8g.drawVLine( self, x, y, width )
static
int
lu8g_drawVLine
(
lua_State
*
L
)
{
lu8g_userdata_t
*
lud
;
if
((
lud
=
get_lud
(
L
))
==
NULL
)
return
0
;
u8g_uint_t
args
[
3
];
lu8g_get_int_args
(
L
,
2
,
3
,
args
);
u8g_DrawVLine
(
LU8G
,
args
[
0
],
args
[
1
],
args
[
2
]
);
return
0
;
}
// Lua: u8g.drawXBM( self, x, y, width, height, data )
static
int
lu8g_drawXBM
(
lua_State
*
L
)
{
lu8g_userdata_t
*
lud
;
if
((
lud
=
get_lud
(
L
))
==
NULL
)
return
0
;
u8g_uint_t
args
[
4
];
lu8g_get_int_args
(
L
,
2
,
4
,
args
);
const
char
*
xbm_data
=
luaL_checkstring
(
L
,
(
1
+
4
)
+
1
);
if
(
xbm_data
==
NULL
)
return
0
;
u8g_DrawXBM
(
LU8G
,
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
],
(
const
uint8_t
*
)
xbm_data
);
return
0
;
}
// Lua: u8g.drawBitmap( self, x, y, count, height, data )
static
int
lu8g_drawBitmap
(
lua_State
*
L
)
{
lu8g_userdata_t
*
lud
;
if
((
lud
=
get_lud
(
L
))
==
NULL
)
return
0
;
u8g_uint_t
args
[
4
];
lu8g_get_int_args
(
L
,
2
,
4
,
args
);
const
char
*
bm_data
=
luaL_checkstring
(
L
,
(
1
+
4
)
+
1
);
if
(
bm_data
==
NULL
)
return
0
;
u8g_DrawBitmap
(
LU8G
,
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
],
(
const
uint8_t
*
)
bm_data
);
return
0
;
}
// Lua: u8g.setScale2x2( self )
static
int
lu8g_setScale2x2
(
lua_State
*
L
)
{
lu8g_userdata_t
*
lud
;
if
((
lud
=
get_lud
(
L
))
==
NULL
)
return
0
;
u8g_SetScale2x2
(
LU8G
);
return
0
;
}
// Lua: u8g.undoScale( self )
static
int
lu8g_undoScale
(
lua_State
*
L
)
{
lu8g_userdata_t
*
lud
;
if
((
lud
=
get_lud
(
L
))
==
NULL
)
return
0
;
u8g_UndoScale
(
LU8G
);
return
0
;
}
// Lua: u8g.firstPage( self )
static
int
lu8g_firstPage
(
lua_State
*
L
)
{
lu8g_userdata_t
*
lud
;
if
((
lud
=
get_lud
(
L
))
==
NULL
)
return
0
;
u8g_FirstPage
(
LU8G
);
return
0
;
}
// Lua: bool = u8g.nextPage( self )
static
int
lu8g_nextPage
(
lua_State
*
L
)
{
lu8g_userdata_t
*
lud
;
if
((
lud
=
get_lud
(
L
))
==
NULL
)
return
0
;
lua_pushboolean
(
L
,
u8g_NextPage
(
LU8G
)
);
return
1
;
}
// Lua: u8g.sleepOn( self )
static
int
lu8g_sleepOn
(
lua_State
*
L
)
{
lu8g_userdata_t
*
lud
;
if
((
lud
=
get_lud
(
L
))
==
NULL
)
return
0
;
u8g_SleepOn
(
LU8G
);
return
0
;
}
// Lua: u8g.sleepOff( self )
static
int
lu8g_sleepOff
(
lua_State
*
L
)
{
lu8g_userdata_t
*
lud
;
if
((
lud
=
get_lud
(
L
))
==
NULL
)
return
0
;
u8g_SleepOff
(
LU8G
);
return
0
;
}
// Lua: u8g.setRot90( self )
static
int
lu8g_setRot90
(
lua_State
*
L
)
{
lu8g_userdata_t
*
lud
;
if
((
lud
=
get_lud
(
L
))
==
NULL
)
return
0
;
u8g_SetRot90
(
LU8G
);
return
0
;
}
// Lua: u8g.setRot180( self )
static
int
lu8g_setRot180
(
lua_State
*
L
)
{
lu8g_userdata_t
*
lud
;
if
((
lud
=
get_lud
(
L
))
==
NULL
)
return
0
;
u8g_SetRot180
(
LU8G
);
return
0
;
}
// Lua: u8g.setRot270( self )
static
int
lu8g_setRot270
(
lua_State
*
L
)
{
lu8g_userdata_t
*
lud
;
if
((
lud
=
get_lud
(
L
))
==
NULL
)
return
0
;
u8g_SetRot270
(
LU8G
);
return
0
;
}
// Lua: u8g.undoRotation( self )
static
int
lu8g_undoRotation
(
lua_State
*
L
)
{
lu8g_userdata_t
*
lud
;
if
((
lud
=
get_lud
(
L
))
==
NULL
)
return
0
;
u8g_UndoRotation
(
LU8G
);
return
0
;
}
// Lua: width = u8g.getWidth( self )
static
int
lu8g_getWidth
(
lua_State
*
L
)
{
lu8g_userdata_t
*
lud
;
if
((
lud
=
get_lud
(
L
))
==
NULL
)
return
0
;
lua_pushinteger
(
L
,
u8g_GetWidth
(
LU8G
)
);
return
1
;
}
// Lua: height = u8g.getHeight( self )
static
int
lu8g_getHeight
(
lua_State
*
L
)
{
lu8g_userdata_t
*
lud
;
if
((
lud
=
get_lud
(
L
))
==
NULL
)
return
0
;
lua_pushinteger
(
L
,
u8g_GetHeight
(
LU8G
)
);
return
1
;
}
// ------------------------------------------------------------
// comm functions
//
#define I2C_CMD_MODE 0x000
#define I2C_DATA_MODE 0x040
#define ESP_I2C_ID 0
static
uint8_t
do_i2c_start
(
uint8_t
id
,
uint8_t
sla
)
{
platform_i2c_send_start
(
id
);
// ignore return value -> tolerate missing ACK
platform_i2c_send_address
(
id
,
sla
,
PLATFORM_I2C_DIRECTION_TRANSMITTER
);
return
1
;
}
static
uint8_t
u8g_com_esp8266_ssd_start_sequence
(
u8g_t
*
u8g
)
{
/* are we requested to set the a0 state? */
if
(
u8g
->
pin_list
[
U8G_PI_SET_A0
]
==
0
)
return
1
;
/* setup bus, might be a repeated start */
if
(
do_i2c_start
(
ESP_I2C_ID
,
u8g
->
i2c_addr
)
==
0
)
return
0
;
if
(
u8g
->
pin_list
[
U8G_PI_A0_STATE
]
==
0
)
{
// ignore return value -> tolerate missing ACK
if
(
platform_i2c_send_byte
(
ESP_I2C_ID
,
I2C_CMD_MODE
)
==
0
)
;
//return 0;
}
else
{
platform_i2c_send_byte
(
ESP_I2C_ID
,
I2C_DATA_MODE
);
}
u8g
->
pin_list
[
U8G_PI_SET_A0
]
=
0
;
return
1
;
}
static
void
lu8g_digital_write
(
u8g_t
*
u8g
,
uint8_t
pin_index
,
uint8_t
value
)
{
uint8_t
pin
;
pin
=
u8g
->
pin_list
[
pin_index
];
if
(
pin
!=
U8G_PIN_NONE
)
platform_gpio_write
(
pin
,
value
);
}
uint8_t
u8g_com_esp8266_hw_spi_fn
(
u8g_t
*
u8g
,
uint8_t
msg
,
uint8_t
arg_val
,
void
*
arg_ptr
)
{
switch
(
msg
)
{
case
U8G_COM_MSG_STOP
:
break
;
case
U8G_COM_MSG_INIT
:
// we assume that the SPI interface was already initialized
// just care for the /CS and D/C pins
lu8g_digital_write
(
u8g
,
U8G_PI_CS
,
PLATFORM_GPIO_HIGH
);
platform_gpio_mode
(
u8g
->
pin_list
[
U8G_PI_CS
],
PLATFORM_GPIO_OUTPUT
,
PLATFORM_GPIO_FLOAT
);
platform_gpio_mode
(
u8g
->
pin_list
[
U8G_PI_A0
],
PLATFORM_GPIO_OUTPUT
,
PLATFORM_GPIO_FLOAT
);
break
;
case
U8G_COM_MSG_ADDRESS
:
/* define cmd (arg_val = 0) or data mode (arg_val = 1) */
lu8g_digital_write
(
u8g
,
U8G_PI_A0
,
arg_val
==
0
?
PLATFORM_GPIO_LOW
:
PLATFORM_GPIO_HIGH
);
break
;
case
U8G_COM_MSG_CHIP_SELECT
:
if
(
arg_val
==
0
)
{
/* disable */
lu8g_digital_write
(
u8g
,
U8G_PI_CS
,
PLATFORM_GPIO_HIGH
);
}
else
{
/* enable */
//u8g_com_arduino_digital_write(u8g, U8G_PI_SCK, LOW);
lu8g_digital_write
(
u8g
,
U8G_PI_CS
,
PLATFORM_GPIO_LOW
);
}
break
;
case
U8G_COM_MSG_RESET
:
if
(
u8g
->
pin_list
[
U8G_PI_RESET
]
!=
U8G_PIN_NONE
)
lu8g_digital_write
(
u8g
,
U8G_PI_RESET
,
arg_val
==
0
?
PLATFORM_GPIO_LOW
:
PLATFORM_GPIO_HIGH
);
break
;
case
U8G_COM_MSG_WRITE_BYTE
:
platform_spi_send_recv
(
1
,
arg_val
);
break
;
case
U8G_COM_MSG_WRITE_SEQ
:
{
register
uint8_t
*
ptr
=
arg_ptr
;
while
(
arg_val
>
0
)
{
platform_spi_send_recv
(
1
,
*
ptr
++
);
arg_val
--
;
}
}
break
;
case
U8G_COM_MSG_WRITE_SEQ_P
:
{
register
uint8_t
*
ptr
=
arg_ptr
;
while
(
arg_val
>
0
)
{
platform_spi_send_recv
(
1
,
u8g_pgm_read
(
ptr
)
);
ptr
++
;
arg_val
--
;
}
}
break
;
}
return
1
;
}
uint8_t
u8g_com_esp8266_ssd_i2c_fn
(
u8g_t
*
u8g
,
uint8_t
msg
,
uint8_t
arg_val
,
void
*
arg_ptr
)
{
switch
(
msg
)
{
case
U8G_COM_MSG_INIT
:
// we assume that the i2c bus was already initialized
//u8g_i2c_init(u8g->pin_list[U8G_PI_I2C_OPTION]);
break
;
case
U8G_COM_MSG_STOP
:
break
;
case
U8G_COM_MSG_RESET
:
/* Currently disabled, but it could be enable. Previous restrictions have been removed */
/* u8g_com_arduino_digital_write(u8g, U8G_PI_RESET, arg_val); */
break
;
case
U8G_COM_MSG_CHIP_SELECT
:
u8g
->
pin_list
[
U8G_PI_A0_STATE
]
=
0
;
u8g
->
pin_list
[
U8G_PI_SET_A0
]
=
1
;
/* force a0 to set again, also forces start condition */
if
(
arg_val
==
0
)
{
/* disable chip, send stop condition */
platform_i2c_send_stop
(
ESP_I2C_ID
);
}
else
{
/* enable, do nothing: any byte writing will trigger the i2c start */
}
break
;
case
U8G_COM_MSG_WRITE_BYTE
:
//u8g->pin_list[U8G_PI_SET_A0] = 1;
if
(
u8g_com_esp8266_ssd_start_sequence
(
u8g
)
==
0
)
return
platform_i2c_stop
(
ESP_I2C_ID
),
0
;
// ignore return value -> tolerate missing ACK
if
(
platform_i2c_send_byte
(
ESP_I2C_ID
,
arg_val
)
==
0
)
;
//return platform_i2c_send_stop( ESP_I2C_ID ), 0;
// platform_i2c_send_stop( ESP_I2C_ID );
break
;
case
U8G_COM_MSG_WRITE_SEQ
:
//u8g->pin_list[U8G_PI_SET_A0] = 1;
if
(
u8g_com_esp8266_ssd_start_sequence
(
u8g
)
==
0
)
return
platform_i2c_send_stop
(
ESP_I2C_ID
),
0
;
{
register
uint8_t
*
ptr
=
arg_ptr
;
while
(
arg_val
>
0
)
{
// ignore return value -> tolerate missing ACK
if
(
platform_i2c_send_byte
(
ESP_I2C_ID
,
*
ptr
++
)
==
0
)
;
//return platform_i2c_send_stop( ESP_I2C_ID ), 0;
arg_val
--
;
}
}
// platform_i2c_send_stop( ESP_I2C_ID );
break
;
case
U8G_COM_MSG_WRITE_SEQ_P
:
//u8g->pin_list[U8G_PI_SET_A0] = 1;
if
(
u8g_com_esp8266_ssd_start_sequence
(
u8g
)
==
0
)
return
platform_i2c_send_stop
(
ESP_I2C_ID
),
0
;
{
register
uint8_t
*
ptr
=
arg_ptr
;
while
(
arg_val
>
0
)
{
// ignore return value -> tolerate missing ACK
if
(
platform_i2c_send_byte
(
ESP_I2C_ID
,
u8g_pgm_read
(
ptr
)
)
==
0
)
;
//return 0;
ptr
++
;
arg_val
--
;
}
}
// platform_i2c_send_stop( ESP_I2C_ID );
break
;
case
U8G_COM_MSG_ADDRESS
:
/* define cmd (arg_val = 0) or data mode (arg_val = 1) */
u8g
->
pin_list
[
U8G_PI_A0_STATE
]
=
arg_val
;
u8g
->
pin_list
[
U8G_PI_SET_A0
]
=
1
;
/* force a0 to set again */
break
;
}
return
1
;
}
// device destructor
static
int
lu8g_close_display
(
lua_State
*
L
)
{
lu8g_userdata_t
*
lud
;
if
((
lud
=
get_lud
(
L
))
==
NULL
)
return
0
;
// free up allocated page buffer
if
(
lud
->
pb
.
buf
!=
NULL
)
{
c_free
(
lud
->
pb
.
buf
);
lud
->
pb
.
buf
=
NULL
;
}
return
0
;
}
// device constructors
uint8_t
u8g_dev_ssd1306_128x64_fn
(
u8g_t
*
u8g
,
u8g_dev_t
*
dev
,
uint8_t
msg
,
void
*
arg
);
// Lua: object = u8g.ssd1306_128x64_i2c( i2c_addr )
static
int
lu8g_ssd1306_128x64_i2c
(
lua_State
*
L
)
{
unsigned
addr
=
luaL_checkinteger
(
L
,
1
);
if
(
addr
==
0
)
return
luaL_error
(
L
,
"i2c address required"
);
lu8g_userdata_t
*
lud
=
(
lu8g_userdata_t
*
)
lua_newuserdata
(
L
,
sizeof
(
lu8g_userdata_t
)
);
lud
->
u8g
.
i2c_addr
=
(
uint8_t
)
addr
;
// Don't use the pre-defined device structure for u8g_dev_ssd1306_128x64_i2c here
// Reason: linking the pre-defined structures allocates RAM for the device/comm structure
// *before* the display is constructed (especially the page buffers)
// this consumes heap even when the device is not used at all
#if 1
// build device entry
lud
->
dev
=
(
u8g_dev_t
){
u8g_dev_ssd1306_128x64_fn
,
&
(
lud
->
pb
),
U8G_COM_SSD_I2C
};
// populate and allocate page buffer
// constants taken from u8g_dev_ssd1306_128x64.c:
// PAGE_HEIGHT
// | Height
// | | WIDTH
// | | |
lud
->
pb
=
(
u8g_pb_t
){
{
8
,
64
,
0
,
0
,
0
},
128
,
NULL
};
//
if
((
lud
->
pb
.
buf
=
(
void
*
)
c_zalloc
(
lud
->
pb
.
width
))
==
NULL
)
return
luaL_error
(
L
,
"out of memory"
);
// and finally init device using specific interface init function
u8g_InitI2C
(
LU8G
,
&
(
lud
->
dev
),
U8G_I2C_OPT_NONE
);
#else
u8g_InitI2C
(
LU8G
,
&
u8g_dev_ssd1306_128x64_i2c
,
U8G_I2C_OPT_NONE
);
#endif
// set its metatable
luaL_getmetatable
(
L
,
"u8g.display"
);
lua_setmetatable
(
L
,
-
2
);
return
1
;
}
// Lua: object = u8g.ssd1306_128x64_spi( cs, dc, [res] )
static
int
lu8g_ssd1306_128x64_spi
(
lua_State
*
L
)
{
unsigned
cs
=
luaL_checkinteger
(
L
,
1
);
if
(
cs
==
0
)
return
luaL_error
(
L
,
"CS pin required"
);
unsigned
dc
=
luaL_checkinteger
(
L
,
2
);
if
(
dc
==
0
)
return
luaL_error
(
L
,
"D/C pin required"
);
unsigned
res
=
luaL_optinteger
(
L
,
3
,
U8G_PIN_NONE
);
lu8g_userdata_t
*
lud
=
(
lu8g_userdata_t
*
)
lua_newuserdata
(
L
,
sizeof
(
lu8g_userdata_t
)
);
// Don't use the pre-defined device structure for u8g_dev_ssd1306_128x64_spi here
// Reason: linking the pre-defined structures allocates RAM for the device/comm structure
// *before* the display is constructed (especially the page buffers)
// this consumes heap even when the device is not used at all
#if 1
// build device entry
lud
->
dev
=
(
u8g_dev_t
){
u8g_dev_ssd1306_128x64_fn
,
&
(
lud
->
pb
),
U8G_COM_HW_SPI
};
// populate and allocate page buffer
// constants taken from u8g_dev_ssd1306_128x64.c:
// PAGE_HEIGHT
// | Height
// | | WIDTH
// | | |
lud
->
pb
=
(
u8g_pb_t
){
{
8
,
64
,
0
,
0
,
0
},
128
,
NULL
};
//
if
((
lud
->
pb
.
buf
=
(
void
*
)
c_zalloc
(
lud
->
pb
.
width
))
==
NULL
)
return
luaL_error
(
L
,
"out of memory"
);
// and finally init device using specific interface init function
u8g_InitHWSPI
(
LU8G
,
&
(
lud
->
dev
),
cs
,
dc
,
res
);
#else
u8g_InitHWSPI
(
LU8G
,
&
u8g_dev_ssd1306_128x64_spi
,
cs
,
dc
,
res
);
#endif
// set its metatable
luaL_getmetatable
(
L
,
"u8g.display"
);
lua_setmetatable
(
L
,
-
2
);
return
1
;
}
uint8_t
u8g_dev_pcd8544_fn
(
u8g_t
*
u8g
,
u8g_dev_t
*
dev
,
uint8_t
msg
,
void
*
arg
);
// Lua: object = u8g.pcd8544_84x48( sce, dc, res )
static
int
lu8g_pcd8544_84x48
(
lua_State
*
L
)
{
unsigned
sce
=
luaL_checkinteger
(
L
,
1
);
if
(
sce
==
0
)
return
luaL_error
(
L
,
"SCE pin required"
);
unsigned
dc
=
luaL_checkinteger
(
L
,
2
);
if
(
dc
==
0
)
return
luaL_error
(
L
,
"D/C pin required"
);
unsigned
res
=
luaL_checkinteger
(
L
,
3
);
if
(
res
==
0
)
return
luaL_error
(
L
,
"RES pin required"
);
lu8g_userdata_t
*
lud
=
(
lu8g_userdata_t
*
)
lua_newuserdata
(
L
,
sizeof
(
lu8g_userdata_t
)
);
// Don't use the pre-defined device structure for u8g_dev_pcd8544_84x48_hw_spi here
// Reason: linking the pre-defined structures allocates RAM for the device/comm structure
// *before* the display is constructed (especially the page buffers)
// this consumes heap even when the device is not used at all
#if 1
// build device entry
lud
->
dev
=
(
u8g_dev_t
){
u8g_dev_pcd8544_fn
,
&
(
lud
->
pb
),
U8G_COM_HW_SPI
};
// populate and allocate page buffer
// constants taken from u8g_dev_pcd8544_84x48.c:
// PAGE_HEIGHT
// | Height
// | | WIDTH
// | | |
lud
->
pb
=
(
u8g_pb_t
){
{
8
,
48
,
0
,
0
,
0
},
84
,
NULL
};
//
if
((
lud
->
pb
.
buf
=
(
void
*
)
c_zalloc
(
lud
->
pb
.
width
))
==
NULL
)
return
luaL_error
(
L
,
"out of memory"
);
// and finally init device using specific interface init function
u8g_InitHWSPI
(
LU8G
,
&
(
lud
->
dev
),
sce
,
dc
,
res
);
#else
u8g_InitHWSPI
(
LU8G
,
&
u8g_dev_pcd8544_84x48_hw_spi
,
sce
,
dc
,
res
);
#endif
// set its metatable
luaL_getmetatable
(
L
,
"u8g.display"
);
lua_setmetatable
(
L
,
-
2
);
return
1
;
}
// Module function map
#define MIN_OPT_LEVEL 2
#include "lrodefs.h"
static
const
LUA_REG_TYPE
lu8g_display_map
[]
=
{
{
LSTRKEY
(
"begin"
),
LFUNCVAL
(
lu8g_begin
)
},
{
LSTRKEY
(
"setFont"
),
LFUNCVAL
(
lu8g_setFont
)
},
{
LSTRKEY
(
"setFontRefHeightAll"
),
LFUNCVAL
(
lu8g_setFontRefHeightAll
)
},
{
LSTRKEY
(
"setFontRefHeightExtendedText"
),
LFUNCVAL
(
lu8g_setFontRefHeightExtendedText
)
},
{
LSTRKEY
(
"setFontRefHeightText"
),
LFUNCVAL
(
lu8g_setFontRefHeightText
)
},
{
LSTRKEY
(
"setDefaultBackgroundColor"
),
LFUNCVAL
(
lu8g_setDefaultBackgroundColor
)
},
{
LSTRKEY
(
"setDefaultForegroundColor"
),
LFUNCVAL
(
lu8g_setDefaultForegroundColor
)
},
{
LSTRKEY
(
"setFontPosBaseline"
),
LFUNCVAL
(
lu8g_setFontPosBaseline
)
},
{
LSTRKEY
(
"setFontPosBottom"
),
LFUNCVAL
(
lu8g_setFontPosBottom
)
},
{
LSTRKEY
(
"setFontPosCenter"
),
LFUNCVAL
(
lu8g_setFontPosCenter
)
},
{
LSTRKEY
(
"setFontPosTop"
),
LFUNCVAL
(
lu8g_setFontPosTop
)
},
{
LSTRKEY
(
"getFontAscent"
),
LFUNCVAL
(
lu8g_getFontAscent
)
},
{
LSTRKEY
(
"getFontDescent"
),
LFUNCVAL
(
lu8g_getFontDescent
)
},
{
LSTRKEY
(
"getFontLineSpacing"
),
LFUNCVAL
(
lu8g_getFontLineSpacing
)
},
{
LSTRKEY
(
"getMode"
),
LFUNCVAL
(
lu8g_getMode
)
},
{
LSTRKEY
(
"setColorIndex"
),
LFUNCVAL
(
lu8g_setColorIndex
)
},
{
LSTRKEY
(
"getColorIndex"
),
LFUNCVAL
(
lu8g_getColorIndex
)
},
{
LSTRKEY
(
"drawStr"
),
LFUNCVAL
(
lu8g_drawStr
)
},
{
LSTRKEY
(
"drawStr90"
),
LFUNCVAL
(
lu8g_drawStr90
)
},
{
LSTRKEY
(
"drawStr180"
),
LFUNCVAL
(
lu8g_drawStr180
)
},
{
LSTRKEY
(
"drawStr270"
),
LFUNCVAL
(
lu8g_drawStr270
)
},
{
LSTRKEY
(
"drawBox"
),
LFUNCVAL
(
lu8g_drawBox
)
},
{
LSTRKEY
(
"drawLine"
),
LFUNCVAL
(
lu8g_drawLine
)
},
{
LSTRKEY
(
"drawTriangle"
),
LFUNCVAL
(
lu8g_drawTriangle
)
},
{
LSTRKEY
(
"drawRBox"
),
LFUNCVAL
(
lu8g_drawRBox
)
},
{
LSTRKEY
(
"drawFrame"
),
LFUNCVAL
(
lu8g_drawFrame
)
},
{
LSTRKEY
(
"drawRFrame"
),
LFUNCVAL
(
lu8g_drawRFrame
)
},
{
LSTRKEY
(
"drawDisc"
),
LFUNCVAL
(
lu8g_drawDisc
)
},
{
LSTRKEY
(
"drawCircle"
),
LFUNCVAL
(
lu8g_drawCircle
)
},
{
LSTRKEY
(
"drawEllipse"
),
LFUNCVAL
(
lu8g_drawEllipse
)
},
{
LSTRKEY
(
"drawFilledEllipse"
),
LFUNCVAL
(
lu8g_drawFilledEllipse
)
},
{
LSTRKEY
(
"drawPixel"
),
LFUNCVAL
(
lu8g_drawPixel
)
},
{
LSTRKEY
(
"drawHLine"
),
LFUNCVAL
(
lu8g_drawHLine
)
},
{
LSTRKEY
(
"drawVLine"
),
LFUNCVAL
(
lu8g_drawVLine
)
},
{
LSTRKEY
(
"drawBitmap"
),
LFUNCVAL
(
lu8g_drawBitmap
)
},
{
LSTRKEY
(
"drawXBM"
),
LFUNCVAL
(
lu8g_drawXBM
)
},
{
LSTRKEY
(
"setScale2x2"
),
LFUNCVAL
(
lu8g_setScale2x2
)
},
{
LSTRKEY
(
"undoScale"
),
LFUNCVAL
(
lu8g_undoScale
)
},
{
LSTRKEY
(
"firstPage"
),
LFUNCVAL
(
lu8g_firstPage
)
},
{
LSTRKEY
(
"nextPage"
),
LFUNCVAL
(
lu8g_nextPage
)
},
{
LSTRKEY
(
"sleepOn"
),
LFUNCVAL
(
lu8g_sleepOn
)
},
{
LSTRKEY
(
"sleepOff"
),
LFUNCVAL
(
lu8g_sleepOff
)
},
{
LSTRKEY
(
"setRot90"
),
LFUNCVAL
(
lu8g_setRot90
)
},
{
LSTRKEY
(
"setRot180"
),
LFUNCVAL
(
lu8g_setRot180
)
},
{
LSTRKEY
(
"setRot270"
),
LFUNCVAL
(
lu8g_setRot270
)
},
{
LSTRKEY
(
"undoRotation"
),
LFUNCVAL
(
lu8g_undoRotation
)
},
{
LSTRKEY
(
"getWidth"
),
LFUNCVAL
(
lu8g_getWidth
)
},
{
LSTRKEY
(
"getHeight"
),
LFUNCVAL
(
lu8g_getHeight
)
},
{
LSTRKEY
(
"__gc"
),
LFUNCVAL
(
lu8g_close_display
)
},
#if LUA_OPTIMIZE_MEMORY > 0
{
LSTRKEY
(
"__index"
),
LROVAL
(
lu8g_display_map
)
},
#endif
{
LNILKEY
,
LNILVAL
}
};
const
LUA_REG_TYPE
lu8g_map
[]
=
{
#ifdef U8G_SSD1306_128x64_I2C
{
LSTRKEY
(
"ssd1306_128x64_i2c"
),
LFUNCVAL
(
lu8g_ssd1306_128x64_i2c
)
},
#endif
#ifdef U8G_SSD1306_128x64_I2C
{
LSTRKEY
(
"ssd1306_128x64_spi"
),
LFUNCVAL
(
lu8g_ssd1306_128x64_spi
)
},
#endif
#ifdef U8G_PCD8544_84x48
{
LSTRKEY
(
"pcd8544_84x48"
),
LFUNCVAL
(
lu8g_pcd8544_84x48
)
},
#endif
#if LUA_OPTIMIZE_MEMORY > 0
// Register fonts
#undef U8G_FONT_TABLE_ENTRY
#define U8G_FONT_TABLE_ENTRY(font) { LSTRKEY( #font ), LUDATA( (void *)(u8g_ ## font) ) },
U8G_FONT_TABLE
// Options for circle/ ellipse drwing
{
LSTRKEY
(
"DRAW_UPPER_RIGHT"
),
LNUMVAL
(
U8G_DRAW_UPPER_RIGHT
)
},
{
LSTRKEY
(
"DRAW_UPPER_LEFT"
),
LNUMVAL
(
U8G_DRAW_UPPER_LEFT
)
},
{
LSTRKEY
(
"DRAW_LOWER_RIGHT"
),
LNUMVAL
(
U8G_DRAW_LOWER_RIGHT
)
},
{
LSTRKEY
(
"DRAW_LOWER_LEFT"
),
LNUMVAL
(
U8G_DRAW_LOWER_LEFT
)
},
{
LSTRKEY
(
"DRAW_ALL"
),
LNUMVAL
(
U8G_DRAW_ALL
)
},
// Display modes
{
LSTRKEY
(
"MODE_BW"
),
LNUMVAL
(
U8G_MODE_BW
)
},
{
LSTRKEY
(
"MODE_GRAY2BIT"
),
LNUMVAL
(
U8G_MODE_GRAY2BIT
)
},
{
LSTRKEY
(
"__metatable"
),
LROVAL
(
lu8g_map
)
},
#endif
{
LNILKEY
,
LNILVAL
}
};
LUALIB_API
int
luaopen_u8g
(
lua_State
*
L
)
{
#if LUA_OPTIMIZE_MEMORY > 0
luaL_rometatable
(
L
,
"u8g.display"
,
(
void
*
)
lu8g_display_map
);
// create metatable
return
0
;
#else // #if LUA_OPTIMIZE_MEMORY > 0
int
n
;
luaL_register
(
L
,
AUXLIB_U8G
,
lu8g_map
);
// Set it as its own metatable
lua_pushvalue
(
L
,
-
1
);
lua_setmetatable
(
L
,
-
2
);
// Module constants
// Register fonts
#undef U8G_FONT_TABLE_ENTRY
#define U8G_FONT_TABLE_ENTRY(font) MOD_REG_LUDATA( L, #font, (void *)(u8g_ ## font) );
U8G_FONT_TABLE
// Options for circle/ ellipse drawing
MOD_REG_NUMBER
(
L
,
"DRAW_UPPER_RIGHT"
,
U8G_DRAW_UPPER_RIGHT
);
MOD_REG_NUMBER
(
L
,
"DRAW_UPPER_LEFT"
,
U8G_DRAW_UPPER_RIGHT
);
MOD_REG_NUMBER
(
L
,
"DRAW_LOWER_RIGHT"
,
U8G_DRAW_UPPER_RIGHT
);
MOD_REG_NUMBER
(
L
,
"DRAW_LOWER_LEFT"
,
U8G_DRAW_UPPER_RIGHT
);
// Display modes
MOD_REG_NUMBER
(
L
,
"MODE_BW"
,
U8G_MODE_BW
);
MOD_REG_NUMBER
(
L
,
"MODE_GRAY2BIT"
,
U8G_MODE_BW
);
// create metatable
luaL_newmetatable
(
L
,
"u8g.display"
);
// metatable.__index = metatable
lua_pushliteral
(
L
,
"__index"
);
lua_pushvalue
(
L
,
-
2
);
lua_rawset
(
L
,
-
3
);
// Setup the methods inside metatable
luaL_register
(
L
,
NULL
,
u8g_display_map
);
return
1
;
#endif // #if LUA_OPTIMIZE_MEMORY > 0
}
app/modules/ws2812.c
View file @
fa7cf878
...
@@ -8,47 +8,56 @@
...
@@ -8,47 +8,56 @@
* from user Markus Gritsch.
* from user Markus Gritsch.
* I just put this code into its own module and pushed into a forked repo,
* 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.
* 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.
// -- This WS2812 code must be compiled with -O2 to get the timing right.
Read this:
// -- http://wp.josh.com/2014/05/13/ws2812-neopixels-are-not-so-finicky-once-you-get-to-know-them/
// -- 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.
//
--
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
)
{
static
void
ICACHE_FLASH_ATTR
send_ws_0
(
uint8_t
gpio
)
{
uint8_t
i
;
uint8_t
i
;
i
=
4
;
i
=
4
;
while
(
i
--
)
GPIO_REG_WRITE
(
GPIO_OUT_W1TS_ADDRESS
,
1
<<
gpio
);
while
(
i
--
)
i
=
9
;
while
(
i
--
)
GPIO_REG_WRITE
(
GPIO_OUT_W1TC_ADDRESS
,
1
<<
gpio
);
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
)
{
static
void
ICACHE_FLASH_ATTR
send_ws_1
(
uint8_t
gpio
)
{
uint8_t
i
;
uint8_t
i
;
i
=
8
;
i
=
8
;
while
(
i
--
)
GPIO_REG_WRITE
(
GPIO_OUT_W1TS_ADDRESS
,
1
<<
gpio
);
while
(
i
--
)
i
=
6
;
while
(
i
--
)
GPIO_REG_WRITE
(
GPIO_OUT_W1TC_ADDRESS
,
1
<<
gpio
);
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")
// Lua: ws2812.write(pin, "string")
// Byte triples in the string are interpreted as
G R
B values.
// Byte triples in the string are interpreted as
R G
B values
and sent to the hardware as G R B
.
// ws2812.write(4, string.char(
0,
255, 0)) uses GPIO2 and sets the first LED red.
// ws2812.write(4, string.char(255
, 0
, 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(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.
// ws2812.write(4, string.char(0, 255, 0, 255, 255, 255)) first LED green, second LED white.
static
int
ICACHE_FLASH_ATTR
ws2812_write
(
lua_State
*
L
)
{
static
int
ICACHE_FLASH_ATTR
ws2812_writergb
(
lua_State
*
L
)
{
const
uint8_t
pin
=
luaL_checkinteger
(
L
,
1
);
const
uint8_t
pin
=
luaL_checkinteger
(
L
,
1
);
size_t
length
;
size_t
length
;
const
char
*
buffer
=
luaL_checklstring
(
L
,
2
,
&
length
);
char
*
buffer
=
(
char
*
)
luaL_checklstring
(
L
,
2
,
&
length
);
// Cast away the constness.
// Initialize the output pin:
platform_gpio_mode
(
pin
,
PLATFORM_GPIO_OUTPUT
,
PLATFORM_GPIO_FLOAT
);
platform_gpio_mode
(
pin
,
PLATFORM_GPIO_OUTPUT
,
PLATFORM_GPIO_FLOAT
);
platform_gpio_write
(
pin
,
0
);
platform_gpio_write
(
pin
,
0
);
os_delay_us
(
10
);
// Ignore incomplete Byte triples at the end of buffer:
length
-=
length
%
3
;
// Rearrange R G B values to G R B order needed by WS2812 LEDs:
size_t
i
;
for
(
i
=
0
;
i
<
length
;
i
+=
3
)
{
const
char
r
=
buffer
[
i
];
const
char
g
=
buffer
[
i
+
1
];
buffer
[
i
]
=
g
;
buffer
[
i
+
1
]
=
r
;
}
// Do not remove these:
os_delay_us
(
1
);
os_delay_us
(
1
);
// Send the buffer:
os_intr_lock
();
os_intr_lock
();
const
char
*
const
end
=
buffer
+
length
;
const
char
*
const
end
=
buffer
+
length
;
while
(
buffer
!=
end
)
{
while
(
buffer
!=
end
)
{
...
@@ -68,7 +77,7 @@ static int ICACHE_FLASH_ATTR ws2812_write(lua_State* L) {
...
@@ -68,7 +77,7 @@ static int ICACHE_FLASH_ATTR ws2812_write(lua_State* L) {
#include "lrodefs.h"
#include "lrodefs.h"
const
LUA_REG_TYPE
ws2812_map
[]
=
const
LUA_REG_TYPE
ws2812_map
[]
=
{
{
{
LSTRKEY
(
"write"
),
LFUNCVAL
(
ws2812_write
)},
{
LSTRKEY
(
"write
rgb
"
),
LFUNCVAL
(
ws2812_write
rgb
)},
{
LNILKEY
,
LNILVAL
}
{
LNILKEY
,
LNILVAL
}
};
};
...
@@ -77,6 +86,3 @@ LUALIB_API int luaopen_ws2812(lua_State *L) {
...
@@ -77,6 +86,3 @@ LUALIB_API int luaopen_ws2812(lua_State *L) {
LREGISTER
(
L
,
"ws2812"
,
ws2812_map
);
LREGISTER
(
L
,
"ws2812"
,
ws2812_map
);
return
1
;
return
1
;
}
}
// ----------------------------------------------------------------------------
app/platform/cpu_esp8266.h
View file @
fa7cf878
...
@@ -30,7 +30,11 @@
...
@@ -30,7 +30,11 @@
#elif defined(FLASH_16M)
#elif defined(FLASH_16M)
#define FLASH_SEC_NUM 0x1000
#define FLASH_SEC_NUM 0x1000
#elif defined(FLASH_AUTOSIZE)
#elif defined(FLASH_AUTOSIZE)
#define FLASH_SEC_NUM (flash_get_sec_num())
#if defined(FLASH_SAFE_API)
#define FLASH_SEC_NUM (flash_safe_get_sec_num())
#else
#define FLASH_SEC_NUM (flash_rom_get_sec_num())
#endif // defined(FLASH_SAFE_API)
#else
#else
#define FLASH_SEC_NUM 0x80
#define FLASH_SEC_NUM 0x80
#endif
#endif
...
@@ -54,8 +58,14 @@
...
@@ -54,8 +58,14 @@
// SpiFlashOpResult spi_flash_erase_sector(uint16 sec);
// SpiFlashOpResult spi_flash_erase_sector(uint16 sec);
// SpiFlashOpResult spi_flash_write(uint32 des_addr, uint32 *src_addr, uint32 size);
// SpiFlashOpResult spi_flash_write(uint32 des_addr, uint32 *src_addr, uint32 size);
// SpiFlashOpResult spi_flash_read(uint32 src_addr, uint32 *des_addr, uint32 size);
// SpiFlashOpResult spi_flash_read(uint32 src_addr, uint32 *des_addr, uint32 size);
#if defined(FLASH_SAFE_API)
#define flash_write flash_safe_write
#define flash_erase flash_safe_erase_sector
#define flash_read flash_safe_read
#else
#define flash_write spi_flash_write
#define flash_write spi_flash_write
#define flash_erase spi_flash_erase_sector
#define flash_erase spi_flash_erase_sector
#define flash_read spi_flash_read
#define flash_read spi_flash_read
#endif // defined(FLASH_SAFE_API)
#endif // #ifndef __CPU_ESP8266_H__
#endif // #ifndef __CPU_ESP8266_H__
app/platform/flash_api.c
View file @
fa7cf878
...
@@ -20,74 +20,154 @@ static volatile const uint8_t flash_init_data[128] ICACHE_STORE_ATTR ICACHE_RODA
...
@@ -20,74 +20,154 @@ static volatile const uint8_t flash_init_data[128] ICACHE_STORE_ATTR ICACHE_RODA
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
};
};
SPIFlashInfo
flash_get_info
(
void
)
uint32_t
flash_detect_size_byte
(
void
)
{
#define FLASH_BUFFER_SIZE_DETECT 32
uint32_t
dummy_size
=
FLASH_SIZE_256KBYTE
;
uint8_t
data_orig
[
FLASH_BUFFER_SIZE_DETECT
]
ICACHE_STORE_ATTR
=
{
0
};
uint8_t
data_new
[
FLASH_BUFFER_SIZE_DETECT
]
ICACHE_STORE_ATTR
=
{
0
};
if
(
SPI_FLASH_RESULT_OK
==
flash_safe_read
(
0
,
(
uint32
*
)
data_orig
,
FLASH_BUFFER_SIZE_DETECT
))
{
dummy_size
=
FLASH_SIZE_256KBYTE
;
while
((
dummy_size
<
FLASH_SIZE_16MBYTE
)
&&
(
SPI_FLASH_RESULT_OK
==
flash_safe_read
(
dummy_size
,
(
uint32
*
)
data_new
,
FLASH_BUFFER_SIZE_DETECT
))
&&
(
0
!=
os_memcmp
(
data_orig
,
data_new
,
FLASH_BUFFER_SIZE_DETECT
))
)
{
dummy_size
*=
2
;
}
};
return
dummy_size
;
#undef FLASH_BUFFER_SIZE_DETECT
}
uint32_t
flash_safe_get_size_byte
(
void
)
{
static
uint32_t
flash_size
=
0
;
if
(
flash_size
==
0
)
{
flash_size
=
flash_detect_size_byte
();
}
return
flash_size
;
}
uint16_t
flash_safe_get_sec_num
(
void
)
{
return
(
flash_safe_get_size_byte
()
/
(
SPI_FLASH_SEC_SIZE
));
}
SpiFlashOpResult
flash_safe_read
(
uint32
src_addr
,
uint32
*
des_addr
,
uint32
size
)
{
SpiFlashOpResult
result
=
SPI_FLASH_RESULT_ERR
;
FLASH_SAFEMODE_ENTER
();
result
=
spi_flash_read
(
src_addr
,
(
uint32
*
)
des_addr
,
size
);
FLASH_SAFEMODE_LEAVE
();
return
result
;
}
SpiFlashOpResult
flash_safe_write
(
uint32
des_addr
,
uint32
*
src_addr
,
uint32
size
)
{
SpiFlashOpResult
result
=
SPI_FLASH_RESULT_ERR
;
FLASH_SAFEMODE_ENTER
();
result
=
spi_flash_write
(
des_addr
,
src_addr
,
size
);
FLASH_SAFEMODE_LEAVE
();
return
result
;
}
SpiFlashOpResult
flash_safe_erase_sector
(
uint16
sec
)
{
SpiFlashOpResult
result
=
SPI_FLASH_RESULT_ERR
;
FLASH_SAFEMODE_ENTER
();
result
=
spi_flash_erase_sector
(
sec
);
FLASH_SAFEMODE_LEAVE
();
return
result
;
}
SPIFlashInfo
flash_rom_getinfo
(
void
)
{
{
volatile
SPIFlashInfo
spi_flash_info
ICACHE_STORE_ATTR
;
volatile
SPIFlashInfo
spi_flash_info
ICACHE_STORE_ATTR
;
spi_flash_info
=
*
((
SPIFlashInfo
*
)(
FLASH_MAP_START_ADDRESS
));
// Don't use it before cache read disabled
// FLASH_DISABLE_CACHE();
// spi_flash_info = *((SPIFlashInfo *)(FLASH_ADDRESS_START_MAP));
// FLASH_ENABLE_CACHE();
// Needn't safe mode.
spi_flash_read
(
0
,
(
uint32
*
)(
&
spi_flash_info
),
sizeof
(
spi_flash_info
));
return
spi_flash_info
;
return
spi_flash_info
;
}
}
uint8_t
flash_get_size
(
void
)
uint8_t
flash_
rom_
get_size
_type
(
void
)
{
{
return
flash_get
_
info
().
size
;
return
flash_
rom_
getinfo
().
size
;
}
}
uint32_t
flash_get_size_byte
(
void
)
uint32_t
flash_
rom_
get_size_byte
(
void
)
{
{
uint32_t
flash_size
=
0
;
static
uint32_t
flash_size
=
0
;
switch
(
flash_
get_info
().
size
)
if
(
flash_
size
==
0
)
{
{
case
SIZE_2MBIT
:
switch
(
flash_rom_getinfo
().
size
)
// 2Mbit, 256kByte
{
flash_size
=
256
*
1024
;
case
SIZE_2MBIT
:
break
;
// 2Mbit, 256kByte
case
SIZE_4MBIT
:
flash_size
=
256
*
1024
;
// 4Mbit, 512kByte
break
;
flash_size
=
512
*
1024
;
case
SIZE_4MBIT
:
break
;
// 4Mbit, 512kByte
case
SIZE_8MBIT
:
flash_size
=
512
*
1024
;
// 8Mbit, 1MByte
break
;
flash_size
=
1
*
1024
*
1024
;
case
SIZE_8MBIT
:
break
;
// 8Mbit, 1MByte
case
SIZE_16MBIT
:
flash_size
=
1
*
1024
*
1024
;
// 16Mbit, 2MByte
break
;
flash_size
=
2
*
1024
*
1024
;
case
SIZE_16MBIT
:
break
;
// 16Mbit, 2MByte
case
SIZE_32MBIT
:
flash_size
=
2
*
1024
*
1024
;
// 32Mbit, 4MByte
break
;
flash_size
=
4
*
1024
*
1024
;
case
SIZE_32MBIT
:
case
SIZE_64MBIT
:
// 32Mbit, 4MByte
// 64Mbit, 8MByte
flash_size
=
4
*
1024
*
1024
;
flash_size
=
8
*
1024
*
1024
;
break
;
case
SIZE_128MBIT
:
case
SIZE_64MBIT
:
// 128Mbit, 16MByte
// 64Mbit, 8MByte
flash_size
=
16
*
1024
*
1024
;
flash_size
=
8
*
1024
*
1024
;
break
;
break
;
default:
case
SIZE_128MBIT
:
// Unknown flash size, fall back mode.
// 128Mbit, 16MByte
flash_size
=
512
*
1024
;
flash_size
=
16
*
1024
*
1024
;
break
;
break
;
default:
// Unknown flash size, fall back mode.
flash_size
=
512
*
1024
;
break
;
}
}
}
return
flash_size
;
return
flash_size
;
}
}
bool
flash_set_size
(
uint8_t
size
)
bool
flash_
rom_
set_size
_type
(
uint8_t
size
)
{
{
// Dangerous, here are dinosaur infested!!!!!
// Dangerous, here are dinosaur infested!!!!!
// Reboot required!!!
// Reboot required!!!
// If you don't know what you're doing, your nodemcu may turn into stone ...
// If you don't know what you're doing, your nodemcu may turn into stone ...
NODE_DBG
(
"
\n
BEGIN SET FLASH HEADER
\n
"
);
uint8_t
data
[
SPI_FLASH_SEC_SIZE
]
ICACHE_STORE_ATTR
;
uint8_t
data
[
SPI_FLASH_SEC_SIZE
]
ICACHE_STORE_ATTR
;
spi_flash_read
(
0
,
(
uint32
*
)
data
,
sizeof
(
data
));
if
(
SPI_FLASH_RESULT_OK
==
spi_flash_read
(
0
,
(
uint32
*
)
data
,
SPI_FLASH_SEC_SIZE
))
SPIFlashInfo
*
p_spi_flash_info
=
(
SPIFlashInfo
*
)(
data
);
{
p_spi_flash_info
->
size
=
size
;
((
SPIFlashInfo
*
)(
&
data
[
0
]))
->
size
=
size
;
spi_flash_erase_sector
(
0
);
if
(
SPI_FLASH_RESULT_OK
==
spi_flash_erase_sector
(
0
*
SPI_FLASH_SEC_SIZE
))
spi_flash_write
(
0
,
(
uint32
*
)
data
,
sizeof
(
data
));
{
//p_spi_flash_info = flash_get_info();
NODE_DBG
(
"
\n
ERASE SUCCESS
\n
"
);
//p_spi_flash_info->size = size;
}
if
(
SPI_FLASH_RESULT_OK
==
spi_flash_write
(
0
,
(
uint32
*
)
data
,
SPI_FLASH_SEC_SIZE
))
{
NODE_DBG
(
"
\n
WRITE SUCCESS, %u
\n
"
,
size
);
}
}
NODE_DBG
(
"
\n
END SET FLASH HEADER
\n
"
);
return
true
;
return
true
;
}
}
bool
flash_set_size_byte
(
uint32_t
size
)
bool
flash_
rom_
set_size_byte
(
uint32_t
size
)
{
{
// Dangerous, here are dinosaur infested!!!!!
// Dangerous, here are dinosaur infested!!!!!
// Reboot required!!!
// Reboot required!!!
...
@@ -99,27 +179,37 @@ bool flash_set_size_byte(uint32_t size)
...
@@ -99,27 +179,37 @@ bool flash_set_size_byte(uint32_t size)
case
256
*
1024
:
case
256
*
1024
:
// 2Mbit, 256kByte
// 2Mbit, 256kByte
flash_size
=
SIZE_2MBIT
;
flash_size
=
SIZE_2MBIT
;
flash_set_size
(
flash_size
);
flash_
rom_
set_size
_type
(
flash_size
);
break
;
break
;
case
512
*
1024
:
case
512
*
1024
:
// 4Mbit, 512kByte
// 4Mbit, 512kByte
flash_size
=
SIZE_4MBIT
;
flash_size
=
SIZE_4MBIT
;
flash_set_size
(
flash_size
);
flash_
rom_
set_size
_type
(
flash_size
);
break
;
break
;
case
1
*
1024
*
1024
:
case
1
*
1024
*
1024
:
// 8Mbit, 1MByte
// 8Mbit, 1MByte
flash_size
=
SIZE_8MBIT
;
flash_size
=
SIZE_8MBIT
;
flash_set_size
(
flash_size
);
flash_
rom_
set_size
_type
(
flash_size
);
break
;
break
;
case
2
*
1024
*
1024
:
case
2
*
1024
*
1024
:
// 16Mbit, 2MByte
// 16Mbit, 2MByte
flash_size
=
SIZE_16MBIT
;
flash_size
=
SIZE_16MBIT
;
flash_set_size
(
flash_size
);
flash_
rom_
set_size
_type
(
flash_size
);
break
;
break
;
case
4
*
1024
*
1024
:
case
4
*
1024
*
1024
:
// 32Mbit, 4MByte
// 32Mbit, 4MByte
flash_size
=
SIZE_32MBIT
;
flash_size
=
SIZE_32MBIT
;
flash_set_size
(
flash_size
);
flash_rom_set_size_type
(
flash_size
);
break
;
case
8
*
1024
*
1024
:
// 64Mbit, 8MByte
flash_size
=
SIZE_64MBIT
;
flash_rom_set_size_type
(
flash_size
);
break
;
case
16
*
1024
*
1024
:
// 128Mbit, 16MByte
flash_size
=
SIZE_128MBIT
;
flash_rom_set_size_type
(
flash_size
);
break
;
break
;
default:
default:
// Unknown flash size.
// Unknown flash size.
...
@@ -129,14 +219,22 @@ bool flash_set_size_byte(uint32_t size)
...
@@ -129,14 +219,22 @@ bool flash_set_size_byte(uint32_t size)
return
result
;
return
result
;
}
}
uint16_t
flash_get_sec_num
(
void
)
uint16_t
flash_
rom_
get_sec_num
(
void
)
{
{
return
flash_get_size_byte
()
/
SPI_FLASH_SEC_SIZE
;
//static uint16_t sec_num = 0;
// return flash_rom_get_size_byte() / (SPI_FLASH_SEC_SIZE);
// c_printf("\nflash_rom_get_size_byte()=%d\n", ( flash_rom_get_size_byte() / (SPI_FLASH_SEC_SIZE) ));
// if( sec_num == 0 )
//{
// sec_num = 4 * 1024 * 1024 / (SPI_FLASH_SEC_SIZE);
//}
//return sec_num;
return
(
flash_rom_get_size_byte
()
/
(
SPI_FLASH_SEC_SIZE
)
);
}
}
uint8_t
flash_get_mode
(
void
)
uint8_t
flash_
rom_
get_mode
(
void
)
{
{
SPIFlashInfo
spi_flash_info
=
flash_get
_
info
();
SPIFlashInfo
spi_flash_info
=
flash_
rom_
getinfo
();
switch
(
spi_flash_info
.
mode
)
switch
(
spi_flash_info
.
mode
)
{
{
// Reserved for future use
// Reserved for future use
...
@@ -152,10 +250,10 @@ uint8_t flash_get_mode(void)
...
@@ -152,10 +250,10 @@ uint8_t flash_get_mode(void)
return
spi_flash_info
.
mode
;
return
spi_flash_info
.
mode
;
}
}
uint32_t
flash_get_speed
(
void
)
uint32_t
flash_
rom_
get_speed
(
void
)
{
{
uint32_t
speed
=
0
;
uint32_t
speed
=
0
;
SPIFlashInfo
spi_flash_info
=
flash_get
_
info
();
SPIFlashInfo
spi_flash_info
=
flash_
rom_
getinfo
();
switch
(
spi_flash_info
.
speed
)
switch
(
spi_flash_info
.
speed
)
{
{
case
SPEED_40MHZ
:
case
SPEED_40MHZ
:
...
@@ -178,11 +276,55 @@ uint32_t flash_get_speed(void)
...
@@ -178,11 +276,55 @@ uint32_t flash_get_speed(void)
return
speed
;
return
speed
;
}
}
bool
flash_rom_set_speed
(
uint32_t
speed
)
{
// Dangerous, here are dinosaur infested!!!!!
// Reboot required!!!
// If you don't know what you're doing, your nodemcu may turn into stone ...
NODE_DBG
(
"
\n
BEGIN SET FLASH HEADER
\n
"
);
uint8_t
data
[
SPI_FLASH_SEC_SIZE
]
ICACHE_STORE_ATTR
;
uint8_t
speed_type
=
SPEED_40MHZ
;
if
(
speed
<
26700000
)
{
speed_type
=
SPEED_20MHZ
;
}
else
if
(
speed
<
40000000
)
{
speed_type
=
SPEED_26MHZ
;
}
else
if
(
speed
<
80000000
)
{
speed_type
=
SPEED_40MHZ
;
}
else
if
(
speed
>=
80000000
)
{
speed_type
=
SPEED_80MHZ
;
}
if
(
SPI_FLASH_RESULT_OK
==
spi_flash_read
(
0
,
(
uint32
*
)
data
,
SPI_FLASH_SEC_SIZE
))
{
((
SPIFlashInfo
*
)(
&
data
[
0
]))
->
speed
=
speed_type
;
if
(
SPI_FLASH_RESULT_OK
==
spi_flash_erase_sector
(
0
*
SPI_FLASH_SEC_SIZE
))
{
NODE_DBG
(
"
\n
ERASE SUCCESS
\n
"
);
}
if
(
SPI_FLASH_RESULT_OK
==
spi_flash_write
(
0
,
(
uint32
*
)
data
,
SPI_FLASH_SEC_SIZE
))
{
NODE_DBG
(
"
\n
WRITE SUCCESS, %u
\n
"
,
speed_type
);
}
}
NODE_DBG
(
"
\n
END SET FLASH HEADER
\n
"
);
return
true
;
}
bool
flash_init_data_written
(
void
)
bool
flash_init_data_written
(
void
)
{
{
// FLASH SEC - 4
// FLASH SEC - 4
uint32_t
data
[
2
]
ICACHE_STORE_ATTR
;
uint32_t
data
[
2
]
ICACHE_STORE_ATTR
;
if
(
SPI_FLASH_RESULT_OK
==
spi_flash_read
((
flash_get_sec_num
()
-
4
)
*
SPI_FLASH_SEC_SIZE
,
(
uint32
*
)
data
,
sizeof
(
data
)))
#if defined(FLASH_SAFE_API)
if
(
SPI_FLASH_RESULT_OK
==
flash_safe_read
((
flash_rom_get_sec_num
()
-
4
)
*
SPI_FLASH_SEC_SIZE
,
(
uint32
*
)
data
,
sizeof
(
data
)))
#else
if
(
SPI_FLASH_RESULT_OK
==
spi_flash_read
((
flash_rom_get_sec_num
()
-
4
)
*
SPI_FLASH_SEC_SIZE
,
(
uint32
*
)
data
,
sizeof
(
data
)))
#endif // defined(FLASH_SAFE_API)
{
{
if
(
data
[
0
]
==
0xFFFFFFFF
&&
data
[
1
]
==
0xFFFFFFFF
)
if
(
data
[
0
]
==
0xFFFFFFFF
&&
data
[
1
]
==
0xFFFFFFFF
)
{
{
...
@@ -199,13 +341,23 @@ bool flash_init_data_default(void)
...
@@ -199,13 +341,23 @@ bool flash_init_data_default(void)
// Reboot required!!!
// Reboot required!!!
// It will init system data to default!
// It will init system data to default!
bool
result
=
false
;
bool
result
=
false
;
if
(
SPI_FLASH_RESULT_OK
==
spi_flash_erase_sector
((
flash_get_sec_num
()
-
4
)))
#if defined(FLASH_SAFE_API)
if
(
SPI_FLASH_RESULT_OK
==
flash_safe_erase_sector
((
flash_safe_get_sec_num
()
-
4
)))
{
if
(
SPI_FLASH_RESULT_OK
==
flash_safe_write
((
flash_safe_get_sec_num
()
-
4
)
*
SPI_FLASH_SEC_SIZE
,
(
uint32
*
)
flash_init_data
,
128
))
{
result
=
true
;
}
}
#else
if
(
SPI_FLASH_RESULT_OK
==
spi_flash_erase_sector
((
flash_rom_get_sec_num
()
-
4
)))
{
{
if
(
SPI_FLASH_RESULT_OK
==
spi_flash_write
((
flash_get_sec_num
()
-
4
)
*
SPI_FLASH_SEC_SIZE
,
(
uint32
*
)
flash_init_data
,
128
))
if
(
SPI_FLASH_RESULT_OK
==
spi_flash_write
((
flash_
rom_
get_sec_num
()
-
4
)
*
SPI_FLASH_SEC_SIZE
,
(
uint32
*
)
flash_init_data
,
128
))
{
{
result
=
true
;
result
=
true
;
}
}
}
}
#endif // defined(FLASH_SAFE_API)
return
result
;
return
result
;
}
}
...
@@ -216,8 +368,13 @@ bool flash_init_data_blank(void)
...
@@ -216,8 +368,13 @@ bool flash_init_data_blank(void)
// Reboot required!!!
// Reboot required!!!
// It will init system config to blank!
// It will init system config to blank!
bool
result
=
false
;
bool
result
=
false
;
if
((
SPI_FLASH_RESULT_OK
==
spi_flash_erase_sector
((
flash_get_sec_num
()
-
2
)))
&&
#if defined(FLASH_SAFE_API)
(
SPI_FLASH_RESULT_OK
==
spi_flash_erase_sector
((
flash_get_sec_num
()
-
1
))))
if
((
SPI_FLASH_RESULT_OK
==
flash_safe_erase_sector
((
flash_rom_get_sec_num
()
-
2
)))
&&
(
SPI_FLASH_RESULT_OK
==
flash_safe_erase_sector
((
flash_rom_get_sec_num
()
-
1
))))
#else
if
((
SPI_FLASH_RESULT_OK
==
spi_flash_erase_sector
((
flash_rom_get_sec_num
()
-
2
)))
&&
(
SPI_FLASH_RESULT_OK
==
spi_flash_erase_sector
((
flash_rom_get_sec_num
()
-
1
))))
#endif // defined(FLASH_SAFE_API)
{
{
result
=
true
;
result
=
true
;
}
}
...
@@ -232,13 +389,39 @@ bool flash_self_destruct(void)
...
@@ -232,13 +389,39 @@ bool flash_self_destruct(void)
return
true
;
return
true
;
}
}
uint8_t
byte_of_aligned_array
(
const
uint8_t
*
aligned_array
,
uint32_t
index
)
uint8_t
byte_of_aligned_array
(
const
uint8_t
*
aligned_array
,
uint32_t
index
)
{
{
if
(
(((
uint32_t
)
aligned_array
)
%
4
)
!=
0
){
if
(
(((
uint32_t
)
aligned_array
)
%
4
)
!=
0
)
{
NODE_DBG
(
"aligned_array is not 4-byte aligned.
\n
"
);
NODE_DBG
(
"aligned_array is not 4-byte aligned.
\n
"
);
return
0
;
return
0
;
}
}
uint32_t
v
=
((
uint32_t
*
)
aligned_array
)[
index
/
4
];
uint32_t
v
=
((
uint32_t
*
)
aligned_array
)[
index
/
4
];
uint8_t
*
p
=
(
uint8_t
*
)
(
&
v
);
uint8_t
*
p
=
(
uint8_t
*
)
(
&
v
);
return
p
[
(
index
%
4
)
];
return
p
[
(
index
%
4
)
];
}
}
// uint8_t flash_rom_get_checksum(void)
// {
// // SPIFlashInfo spi_flash_info ICACHE_STORE_ATTR = flash_rom_getinfo();
// // uint32_t address = sizeof(spi_flash_info) + spi_flash_info.segment_size;
// // uint32_t address_aligned_4bytes = (address + 3) & 0xFFFFFFFC;
// // uint8_t buffer[64] = {0};
// // spi_flash_read(address, (uint32 *) buffer, 64);
// // uint8_t i = 0;
// // c_printf("\nBEGIN DUMP\n");
// // for (i = 0; i < 64; i++)
// // {
// // c_printf("%02x," , buffer[i]);
// // }
// // i = (address + 0x10) & 0x10 - 1;
// // c_printf("\nSIZE:%d CHECK SUM:%02x\n", spi_flash_info.segment_size, buffer[i]);
// // c_printf("\nEND DUMP\n");
// // return buffer[0];
// return 0;
// }
// uint8_t flash_rom_calc_checksum(void)
// {
// return 0;
// }
\ No newline at end of file
app/platform/flash_api.h
View file @
fa7cf878
...
@@ -3,34 +3,62 @@
...
@@ -3,34 +3,62 @@
#include "ets_sys.h"
#include "ets_sys.h"
#include "user_config.h"
#include "user_config.h"
#include "cpu_esp8266.h"
#include "cpu_esp8266.h"
#define FLASH_MAP_START_ADDRESS (INTERNAL_FLASH_START_ADDRESS)
#define FLASH_ADDRESS_START_MAP (INTERNAL_FLASH_START_ADDRESS)
#define FLASH_SIZE_2MBIT (2 * 1024 * 1024)
#define FLASH_SIZE_4MBIT (4 * 1024 * 1024)
#define FLASH_SIZE_8MBIT (8 * 1024 * 1024)
#define FLASH_SIZE_16MBIT (16 * 1024 * 1024)
#define FLASH_SIZE_32MBIT (32 * 1024 * 1024)
#define FLASH_SIZE_64MBIT (64 * 1024 * 1024)
#define FLASH_SIZE_128MBIT (128 * 1024 * 1024)
#define FLASH_SIZE_256KBYTE (FLASH_SIZE_2MBIT / 8)
#define FLASH_SIZE_512KBYTE (FLASH_SIZE_4MBIT / 8)
#define FLASH_SIZE_1MBYTE (FLASH_SIZE_8MBIT / 8)
#define FLASH_SIZE_2MBYTE (FLASH_SIZE_16MBIT / 8)
#define FLASH_SIZE_4MBYTE (FLASH_SIZE_32MBIT / 8)
#define FLASH_SIZE_8MBYTE (FLASH_SIZE_64MBIT / 8)
#define FLASH_SIZE_16MBYTE (FLASH_SIZE_128MBIT/ 8)
#define FLASH_SAFEMODE_ENTER() \
do { \
extern SpiFlashChip * flashchip; \
flashchip->chip_size = FLASH_SIZE_16MBYTE
#define FLASH_SAFEMODE_LEAVE() \
flashchip->chip_size = flash_rom_get_size_byte(); \
} while(0)
/******************************************************************************
/******************************************************************************
* ROM Function definition
* ROM Function definition
* Note: It is unsafe to use ROM function, but it may efficient.
* Note: It is unsafe to use ROM function, but it may efficient.
* SPIEraseSector
* SPIEraseSector
*
unknown
SPIEraseSector(uint16 sec);
*
SpiFlashOpResult
SPIEraseSector(uint16 sec);
* The 1st parameter is flash sector number.
* The 1st parameter is flash sector number.
* Note: Must disable cache read before using it.
* SPIRead
(Unsafe)
* SPIRead
*
unknown
SPIRead(uint32_t src_addr, uint32_t *des_addr, uint32_t size);
*
SpiFlashOpResult
SPIRead(uint32_t src_addr, uint32_t *des_addr, uint32_t size);
* The 1st parameter is source addresses.
* The 1st parameter is source addresses.
* The 2nd parameter is destination addresses.
* The 2nd parameter is destination addresses.
* The 3rd parameter is size.
* The 3rd parameter is size.
* Note:
Sometimes it have no effect, may be need a delay or other option(lock or unlock, etc.) with known reason
.
* Note:
Must disable cache read before using it
.
* SPIWrite
(Unsafe)
* SPIWrite
*
unknown
SPIWrite(uint32_t des_addr, uint32_t *src_addr, uint32_t size);
*
SpiFlashOpResult
SPIWrite(uint32_t des_addr, uint32_t *src_addr, uint32_t size);
* The 1st parameter is destination addresses.
* The 1st parameter is destination addresses.
* The 2nd parameter is source addresses.
* The 2nd parameter is source addresses.
* The 3rd parameter is size.
* The 3rd parameter is size.
* Note:
Sometimes it have no effect, may be need a delay or other option(lock or unlock, etc.) with known reason
.
* Note:
Must disable cache read before using it
.
*******************************************************************************/
*******************************************************************************/
typedef
struct
typedef
struct
{
{
uint8_t
unknown0
;
uint8_t
header_magic
;
uint8_t
unknown1
;
uint8_t
segment_count
;
enum
enum
{
{
MODE_QIO
=
0
,
MODE_QIO
=
0
,
...
@@ -55,20 +83,31 @@ typedef struct
...
@@ -55,20 +83,31 @@ typedef struct
SIZE_64MBIT
=
5
,
SIZE_64MBIT
=
5
,
SIZE_128MBIT
=
6
,
SIZE_128MBIT
=
6
,
}
size
:
4
;
}
size
:
4
;
uint32_t
entry_point
;
uint32_t
memory_offset
;
uint32_t
segment_size
;
}
ICACHE_STORE_TYPEDEF_ATTR
SPIFlashInfo
;
}
ICACHE_STORE_TYPEDEF_ATTR
SPIFlashInfo
;
SPIFlashInfo
flash_get_info
(
void
);
uint32_t
flash_detect_size_byte
(
void
);
uint8_t
flash_get_size
(
void
);
uint32_t
flash_safe_get_size_byte
(
void
);
uint32_t
flash_get_size_byte
(
void
);
uint16_t
flash_safe_get_sec_num
(
void
);
bool
flash_set_size
(
uint8_t
);
SpiFlashOpResult
flash_safe_read
(
uint32
src_addr
,
uint32
*
des_addr
,
uint32
size
);
bool
flash_set_size_byte
(
uint32_t
);
SpiFlashOpResult
flash_safe_write
(
uint32
des_addr
,
uint32
*
src_addr
,
uint32
size
);
uint16_t
flash_get_sec_num
(
void
);
SpiFlashOpResult
flash_safe_erase_sector
(
uint16
sec
);
uint8_t
flash_get_mode
(
void
);
SPIFlashInfo
flash_rom_getinfo
(
void
);
uint32_t
flash_get_speed
(
void
);
uint8_t
flash_rom_get_size_type
(
void
);
uint32_t
flash_rom_get_size_byte
(
void
);
bool
flash_rom_set_size_type
(
uint8_t
);
bool
flash_rom_set_size_byte
(
uint32_t
);
uint16_t
flash_rom_get_sec_num
(
void
);
uint8_t
flash_rom_get_mode
(
void
);
uint32_t
flash_rom_get_speed
(
void
);
bool
flash_init_data_written
(
void
);
bool
flash_init_data_written
(
void
);
bool
flash_init_data_default
(
void
);
bool
flash_init_data_default
(
void
);
bool
flash_init_data_blank
(
void
);
bool
flash_init_data_blank
(
void
);
bool
flash_self_destruct
(
void
);
bool
flash_self_destruct
(
void
);
uint8_t
byte_of_aligned_array
(
const
uint8_t
*
aligned_array
,
uint32_t
index
);
uint8_t
byte_of_aligned_array
(
const
uint8_t
*
aligned_array
,
uint32_t
index
);
// uint8_t flash_rom_get_checksum(void);
// uint8_t flash_rom_calc_checksum(void);
#endif // __FLASH_API_H__
#endif // __FLASH_API_H__
app/platform/flash_fs.h
View file @
fa7cf878
...
@@ -69,6 +69,7 @@
...
@@ -69,6 +69,7 @@
#define fs_format myspiffs_format
#define fs_format myspiffs_format
#define fs_check myspiffs_check
#define fs_check myspiffs_check
#define fs_rename myspiffs_rename
#define fs_rename myspiffs_rename
#define fs_size myspiffs_size
#define FS_NAME_MAX_LENGTH SPIFFS_OBJ_NAME_LEN
#define FS_NAME_MAX_LENGTH SPIFFS_OBJ_NAME_LEN
...
...
app/spiffs/spiffs.c
View file @
fa7cf878
...
@@ -160,11 +160,14 @@ int myspiffs_error( int fd ){
...
@@ -160,11 +160,14 @@ int myspiffs_error( int fd ){
return
SPIFFS_errno
(
&
fs
);
return
SPIFFS_errno
(
&
fs
);
}
}
void
myspiffs_clearerr
(
int
fd
){
void
myspiffs_clearerr
(
int
fd
){
fs
.
errno
=
SPIFFS_OK
;
SPIFFS_clearerr
(
&
fs
)
;
}
}
int
myspiffs_rename
(
const
char
*
old
,
const
char
*
newname
){
int
myspiffs_rename
(
const
char
*
old
,
const
char
*
newname
){
return
SPIFFS_rename
(
&
fs
,
(
char
*
)
old
,
(
char
*
)
newname
);
return
SPIFFS_rename
(
&
fs
,
(
char
*
)
old
,
(
char
*
)
newname
);
}
}
size_t
myspiffs_size
(
int
fd
){
return
SPIFFS_size
(
&
fs
,
(
spiffs_file
)
fd
);
}
#if 0
#if 0
void test_spiffs() {
void test_spiffs() {
char buf[12];
char buf[12];
...
...
app/spiffs/spiffs.h
View file @
fa7cf878
...
@@ -9,6 +9,10 @@
...
@@ -9,6 +9,10 @@
#ifndef SPIFFS_H_
#ifndef SPIFFS_H_
#define SPIFFS_H_
#define SPIFFS_H_
#if defined(__cplusplus)
extern
"C"
{
#endif
#include "c_stdio.h"
#include "c_stdio.h"
#include "spiffs_config.h"
#include "spiffs_config.h"
...
@@ -181,7 +185,7 @@ typedef struct {
...
@@ -181,7 +185,7 @@ typedef struct {
u32_t
fd_count
;
u32_t
fd_count
;
// last error
// last error
s32_t
err
no
;
s32_t
err
_code
;
// current number of free blocks
// current number of free blocks
u32_t
free_blocks
;
u32_t
free_blocks
;
...
@@ -375,9 +379,9 @@ void SPIFFS_close(spiffs *fs, spiffs_file fh);
...
@@ -375,9 +379,9 @@ void SPIFFS_close(spiffs *fs, spiffs_file fh);
* Renames a file
* Renames a file
* @param fs the file system struct
* @param fs the file system struct
* @param old path of file to rename
* @param old path of file to rename
* @param new
new path of file
* @param new
Path
new path of file
*/
*/
s32_t
SPIFFS_rename
(
spiffs
*
fs
,
char
*
old
,
char
*
new
);
s32_t
SPIFFS_rename
(
spiffs
*
fs
,
char
*
old
,
char
*
new
Path
);
/**
/**
* Returns last error of last file operation.
* Returns last error of last file operation.
...
@@ -385,6 +389,12 @@ s32_t SPIFFS_rename(spiffs *fs, char *old, char *new);
...
@@ -385,6 +389,12 @@ s32_t SPIFFS_rename(spiffs *fs, char *old, char *new);
*/
*/
s32_t
SPIFFS_errno
(
spiffs
*
fs
);
s32_t
SPIFFS_errno
(
spiffs
*
fs
);
/**
* Clears last error.
* @param fs the file system struct
*/
void
SPIFFS_clearerr
(
spiffs
*
fs
);
/**
/**
* Opens a directory stream corresponding to the given name.
* Opens a directory stream corresponding to the given name.
* The stream is positioned at the first entry in the directory.
* The stream is positioned at the first entry in the directory.
...
@@ -416,6 +426,21 @@ struct spiffs_dirent *SPIFFS_readdir(spiffs_DIR *d, struct spiffs_dirent *e);
...
@@ -416,6 +426,21 @@ struct spiffs_dirent *SPIFFS_readdir(spiffs_DIR *d, struct spiffs_dirent *e);
*/
*/
s32_t
SPIFFS_check
(
spiffs
*
fs
);
s32_t
SPIFFS_check
(
spiffs
*
fs
);
/**
* Returns number of total bytes available and number of used bytes.
* This is an estimation, and depends on if there a many files with little
* data or few files with much data.
* NB: If used number of bytes exceeds total bytes, a SPIFFS_check should
* run. This indicates a power loss in midst of things. In worst case
* (repeated powerlosses in mending or gc) you might have to delete some files.
*
* @param fs the file system struct
* @param total total number of bytes in filesystem
* @param used used number of bytes in filesystem
*/
s32_t
SPIFFS_info
(
spiffs
*
fs
,
u32_t
*
total
,
u32_t
*
used
);
/**
/**
* Check if EOF reached.
* Check if EOF reached.
* @param fs the file system struct
* @param fs the file system struct
...
@@ -423,6 +448,7 @@ s32_t SPIFFS_check(spiffs *fs);
...
@@ -423,6 +448,7 @@ s32_t SPIFFS_check(spiffs *fs);
*/
*/
s32_t
SPIFFS_eof
(
spiffs
*
fs
,
spiffs_file
fh
);
s32_t
SPIFFS_eof
(
spiffs
*
fs
,
spiffs_file
fh
);
s32_t
SPIFFS_tell
(
spiffs
*
fs
,
spiffs_file
fh
);
s32_t
SPIFFS_tell
(
spiffs
*
fs
,
spiffs_file
fh
);
s32_t
SPIFFS_size
(
spiffs
*
fs
,
spiffs_file
fh
);
#if SPIFFS_TEST_VISUALISATION
#if SPIFFS_TEST_VISUALISATION
/**
/**
...
@@ -465,5 +491,10 @@ int myspiffs_error( int fd );
...
@@ -465,5 +491,10 @@ int myspiffs_error( int fd );
void
myspiffs_clearerr
(
int
fd
);
void
myspiffs_clearerr
(
int
fd
);
int
myspiffs_check
(
void
);
int
myspiffs_check
(
void
);
int
myspiffs_rename
(
const
char
*
old
,
const
char
*
newname
);
int
myspiffs_rename
(
const
char
*
old
,
const
char
*
newname
);
size_t
myspiffs_size
(
int
fd
);
#if defined(__cplusplus)
}
#endif
#endif
/* SPIFFS_H_ */
#endif
/* SPIFFS_H_ */
app/spiffs/spiffs_config.h
View file @
fa7cf878
...
@@ -30,19 +30,19 @@ typedef uint8_t u8_t;
...
@@ -30,19 +30,19 @@ typedef uint8_t u8_t;
// Set generic spiffs debug output call.
// Set generic spiffs debug output call.
#ifndef SPIFFS_DGB
#ifndef SPIFFS_DGB
#define SPIFFS_DBG(...)
#define SPIFFS_DBG(...)
//printf(__VA_ARGS__)
#endif
#endif
// Set spiffs debug output call for garbage collecting.
// Set spiffs debug output call for garbage collecting.
#ifndef SPIFFS_GC_DGB
#ifndef SPIFFS_GC_DGB
#define SPIFFS_GC_DBG(...)
#define SPIFFS_GC_DBG(...)
//printf(__VA_ARGS__)
#endif
#endif
// Set spiffs debug output call for caching.
// Set spiffs debug output call for caching.
#ifndef SPIFFS_CACHE_DGB
#ifndef SPIFFS_CACHE_DGB
#define SPIFFS_CACHE_DBG(...)
#define SPIFFS_CACHE_DBG(...)
//printf(__VA_ARGS__)
#endif
#endif
// Set spiffs debug output call for system consistency checks.
// Set spiffs debug output call for system consistency checks.
#ifndef SPIFFS_CHECK_DGB
#ifndef SPIFFS_CHECK_DGB
#define SPIFFS_CHECK_DBG(...)
#define SPIFFS_CHECK_DBG(...)
//printf(__VA_ARGS__)
#endif
#endif
// Enable/disable API functions to determine exact number of bytes
// Enable/disable API functions to determine exact number of bytes
...
@@ -77,7 +77,7 @@ typedef uint8_t u8_t;
...
@@ -77,7 +77,7 @@ typedef uint8_t u8_t;
// Define maximum number of gc runs to perform to reach desired free pages.
// Define maximum number of gc runs to perform to reach desired free pages.
#ifndef SPIFFS_GC_MAX_RUNS
#ifndef SPIFFS_GC_MAX_RUNS
#define SPIFFS_GC_MAX_RUNS
3
#define SPIFFS_GC_MAX_RUNS
5
#endif
#endif
// Enable/disable statistics on gc. Debug/test purpose only.
// Enable/disable statistics on gc. Debug/test purpose only.
...
...
app/spiffs/spiffs_gc.c
View file @
fa7cf878
...
@@ -119,16 +119,21 @@ s32_t spiffs_gc_check(
...
@@ -119,16 +119,21 @@ s32_t spiffs_gc_check(
spiffs
*
fs
,
spiffs
*
fs
,
u32_t
len
)
{
u32_t
len
)
{
s32_t
res
;
s32_t
res
;
u
32_t
free_pages
=
s
32_t
free_pages
=
(
SPIFFS_PAGES_PER_BLOCK
(
fs
)
-
SPIFFS_OBJ_LOOKUP_PAGES
(
fs
))
*
fs
->
block_count
(
SPIFFS_PAGES_PER_BLOCK
(
fs
)
-
SPIFFS_OBJ_LOOKUP_PAGES
(
fs
))
*
(
fs
->
block_count
-
2
)
-
fs
->
stats_p_allocated
-
fs
->
stats_p_deleted
;
-
fs
->
stats_p_allocated
-
fs
->
stats_p_deleted
;
int
tries
=
0
;
int
tries
=
0
;
if
(
fs
->
free_blocks
>
3
&&
if
(
fs
->
free_blocks
>
3
&&
len
<
free_pages
*
SPIFFS_DATA_PAGE_SIZE
(
fs
))
{
(
s32_t
)
len
<
free_pages
*
(
s32_t
)
SPIFFS_DATA_PAGE_SIZE
(
fs
))
{
return
SPIFFS_OK
;
return
SPIFFS_OK
;
}
}
u32_t
needed_pages
=
(
len
+
SPIFFS_DATA_PAGE_SIZE
(
fs
)
-
1
)
/
SPIFFS_DATA_PAGE_SIZE
(
fs
);
if
(
fs
->
free_blocks
<=
2
&&
(
s32_t
)
needed_pages
>
free_pages
)
{
return
SPIFFS_ERR_FULL
;
}
//printf("gcing started %i dirty, blocks %i free, want %i bytes\n", fs->stats_p_allocated + fs->stats_p_deleted, fs->free_blocks, len);
//printf("gcing started %i dirty, blocks %i free, want %i bytes\n", fs->stats_p_allocated + fs->stats_p_deleted, fs->free_blocks, len);
do
{
do
{
...
@@ -168,16 +173,22 @@ s32_t spiffs_gc_check(
...
@@ -168,16 +173,22 @@ s32_t spiffs_gc_check(
SPIFFS_CHECK_RES
(
res
);
SPIFFS_CHECK_RES
(
res
);
free_pages
=
free_pages
=
(
SPIFFS_PAGES_PER_BLOCK
(
fs
)
-
SPIFFS_OBJ_LOOKUP_PAGES
(
fs
))
*
fs
->
block_count
(
SPIFFS_PAGES_PER_BLOCK
(
fs
)
-
SPIFFS_OBJ_LOOKUP_PAGES
(
fs
))
*
(
fs
->
block_count
-
2
)
-
fs
->
stats_p_allocated
-
fs
->
stats_p_deleted
;
-
fs
->
stats_p_allocated
-
fs
->
stats_p_deleted
;
}
while
(
++
tries
<
SPIFFS_GC_MAX_RUNS
&&
(
fs
->
free_blocks
<=
2
||
}
while
(
++
tries
<
SPIFFS_GC_MAX_RUNS
&&
(
fs
->
free_blocks
<=
2
||
len
>
free_pages
*
SPIFFS_DATA_PAGE_SIZE
(
fs
)));
(
s32_t
)
len
>
free_pages
*
(
s32_t
)
SPIFFS_DATA_PAGE_SIZE
(
fs
)));
SPIFFS_GC_DBG
(
"gc_check: finished
\n
"
);
free_pages
=
(
SPIFFS_PAGES_PER_BLOCK
(
fs
)
-
SPIFFS_OBJ_LOOKUP_PAGES
(
fs
))
*
(
fs
->
block_count
-
2
)
-
fs
->
stats_p_allocated
-
fs
->
stats_p_deleted
;
if
((
s32_t
)
len
>
free_pages
*
(
s32_t
)
SPIFFS_DATA_PAGE_SIZE
(
fs
))
{
res
=
SPIFFS_ERR_FULL
;
}
//printf("gcing
finished %i dirty, blocks %i free, %i pages free, %i tries, res %i\n",
SPIFFS_GC_DBG
(
"gc_check:
finished
,
%i dirty, blocks %i free, %i pages free, %i tries, res %i
\n
"
,
//
fs->stats_p_allocated + fs->stats_p_deleted,
fs
->
stats_p_allocated
+
fs
->
stats_p_deleted
,
//
fs->free_blocks, free_pages, tries, res);
fs
->
free_blocks
,
free_pages
,
tries
,
res
);
return
res
;
return
res
;
}
}
...
...
Prev
1
2
3
4
5
6
7
…
10
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment