diff --git a/README.md b/README.md index 4e0270c9..ab78ed81 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # **NodeMCU** # version 0.9.5 +[![Join the chat at https://gitter.im/nodemcu/nodemcu-firmware](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/nodemcu/nodemcu-firmware?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Build Status](https://travis-ci.org/nodemcu/nodemcu-firmware.svg)](https://travis-ci.org/nodemcu/nodemcu-firmware) [![Download](https://img.shields.io/badge/download-~400k-orange.svg)](https://github.com/nodemcu/nodemcu-firmware/releases/latest) ###A lua based firmware for wifi-soc esp8266 @@ -33,6 +34,10 @@ Tencent QQ group: 309957875
- cross compiler (done) # Change log +2015-03-15
+bugs fixed: #239, #273.
+reduce coap module memory usage, add coap module to default built. + 2015-03-11
fix bugs of spiffs.
build both float and integer version [latest releases](https://github.com/nodemcu/nodemcu-firmware/releases/latest).
@@ -437,3 +442,25 @@ Bitmaps and XBMs are supplied as strings to `drawBitmap()` and `drawXBM()`. This -- first LED green, second LED white ws2812.writergb(4, string.char(0, 255, 0, 255, 255, 255)) ``` + +####coap client and server +```lua +-- use copper addon for firefox +cs=coap.Server() +cs:listen(5683) + +myvar=1 +cs:var("myvar") -- get coap://192.168.18.103:5683/v1/v/myvar will return the value of myvar: 1 + +-- function should tack one string, return one string. +function myfun(payload) + print("myfun called") + respond = "hello" + return respond +end +cs:func("myfun") -- post coap://192.168.18.103:5683/v1/f/myfun will call myfun + +cc = coap.Client() +cc:get(coap.CON, "coap://192.168.18.100:5683/.well-known/core") +cc:post(coap.NON, "coap://192.168.18.100:5683/", "Hello") +``` \ No newline at end of file diff --git a/app/coap/coap.c b/app/coap/coap.c index 6dded680..af431d76 100644 --- a/app/coap/coap.c +++ b/app/coap/coap.c @@ -76,7 +76,7 @@ int coap_parseToken(coap_buffer_t *tokbuf, const coap_header_t *hdr, const uint8 else if (hdr->tkl <= 8) { - if (4 + hdr->tkl > buflen) + if (4U + hdr->tkl > buflen) return COAP_ERR_TOKEN_TOO_SHORT; // tok bigger than packet tokbuf->p = buf+4; // past header tokbuf->len = hdr->tkl; @@ -93,7 +93,7 @@ int coap_buildToken(const coap_buffer_t *tokbuf, const coap_header_t *hdr, uint8 { // inject token uint8_t *p; - if (buflen < 4 + hdr->tkl) + if (buflen < (4U + hdr->tkl)) return COAP_ERR_BUFFER_TOO_SMALL; p = buf + 4; if ((hdr->tkl > 0) && (hdr->tkl != tokbuf->len)) @@ -102,7 +102,7 @@ int coap_buildToken(const coap_buffer_t *tokbuf, const coap_header_t *hdr, uint8 if (hdr->tkl > 0) c_memcpy(p, tokbuf->p, hdr->tkl); - // http://tools.ietf.org/html/draft-ietf-core-coap-18#section-3.1 + // http://tools.ietf.org/html/rfc7252#section-3.1 // inject options return hdr->tkl; } @@ -111,8 +111,8 @@ int coap_buildToken(const coap_buffer_t *tokbuf, const coap_header_t *hdr, uint8 int coap_parseOption(coap_option_t *option, uint16_t *running_delta, const uint8_t **buf, size_t buflen) { const uint8_t *p = *buf; - uint16_t len, delta; uint8_t headlen = 1; + uint16_t len, delta; if (buflen < headlen) // too small return COAP_ERR_OPTION_TOO_SHORT_FOR_HEADER; @@ -179,14 +179,14 @@ int coap_parseOption(coap_option_t *option, uint16_t *running_delta, const uint8 return 0; } -// http://tools.ietf.org/html/draft-ietf-core-coap-18#section-3.1 +// http://tools.ietf.org/html/rfc7252#section-3.1 int coap_parseOptionsAndPayload(coap_option_t *options, uint8_t *numOptions, coap_buffer_t *payload, const coap_header_t *hdr, const uint8_t *buf, size_t buflen) { size_t optionIndex = 0; + uint16_t delta = 0; const uint8_t *p = buf + 4 + hdr->tkl; const uint8_t *end = buf + buflen; int rc; - uint16_t delta = 0; if (p > end) return COAP_ERR_OPTION_OVERRUNS_PACKET; // out of bounds @@ -215,7 +215,7 @@ int coap_parseOptionsAndPayload(coap_option_t *options, uint8_t *numOptions, coa return 0; } -int coap_buildOptionHeader(unsigned short optDelta, size_t length, uint8_t *buf, size_t buflen) +int coap_buildOptionHeader(uint32_t optDelta, size_t length, uint8_t *buf, size_t buflen) { int n = 0; uint8_t *p = buf; @@ -298,7 +298,7 @@ int coap_parse(coap_packet_t *pkt, const uint8_t *buf, size_t buflen) } // options are always stored consecutively, so can return a block with same option num -const coap_option_t * coap_findOptions(const coap_packet_t *pkt, uint8_t num, uint8_t *count) +const coap_option_t *coap_findOptions(const coap_packet_t *pkt, uint8_t num, uint8_t *count) { // FIXME, options is always sorted, can find faster than this size_t i; @@ -352,7 +352,7 @@ int coap_build(uint8_t *buf, size_t *buflen, const coap_packet_t *pkt) uint16_t optDelta = 0; int rc = 0; - if (p-buf > *buflen) + if (((size_t)(p-buf)) > *buflen) return COAP_ERR_BUFFER_TOO_SMALL; optDelta = pkt->opts[i].num - running_delta; @@ -381,17 +381,17 @@ int coap_build(uint8_t *buf, size_t *buflen, const coap_packet_t *pkt) return 0; } -void coap_option_nibble(uint16_t value, uint8_t *nibble) +void coap_option_nibble(uint32_t value, uint8_t *nibble) { if (value<13) { *nibble = (0xFF & value); } else - if (((uint32_t)value)<=0xFF+13) + if (value<=0xFF+13) { *nibble = 13; - } else if (((uint32_t)value) -269 <=0xFFFF) + } else if (value<=0xFFFF+269) { *nibble = 14; } @@ -405,7 +405,7 @@ int coap_make_response(coap_rw_buffer_t *scratch, coap_packet_t *pkt, const uint pkt->hdr.code = rspcode; pkt->hdr.id[0] = msgid_hi; pkt->hdr.id[1] = msgid_lo; - pkt->numopts = 0; + pkt->numopts = 1; // need token in response if (tok) { @@ -442,7 +442,7 @@ unsigned int coap_encode_var_bytes(unsigned char *buf, unsigned int val) { return n; } -static uint8_t _token_data[4]={'n','o','d','e'}; +static uint8_t _token_data[4] = {'n','o','d','e'}; coap_buffer_t the_token = { _token_data, 4 }; static unsigned short message_id; diff --git a/app/coap/coap.h b/app/coap/coap.h index 1c8827a6..3862f57b 100644 --- a/app/coap/coap.h +++ b/app/coap/coap.h @@ -18,13 +18,15 @@ extern "C" { #define COAP_RESPONSE_CLASS(C) (((C) >> 5) & 0xFF) -// http://tools.ietf.org/html/draft-ietf-core-coap-18#section-3 +//http://tools.ietf.org/html/rfc7252#section-3 typedef struct { - uint8_t ver; - uint8_t t; - uint8_t tkl; - uint8_t code; + uint8_t ver; /* CoAP version number */ + uint8_t t; /* CoAP Message Type */ + uint8_t tkl; /* Token length: indicates length of the Token field */ + uint8_t code; /* CoAP status code. Can be request (0.xx), success reponse (2.xx), + * client error response (4.xx), or rever error response (5.xx) + * For possible values, see http://tools.ietf.org/html/rfc7252#section-12.1 */ uint8_t id[2]; } coap_header_t; @@ -42,23 +44,24 @@ typedef struct typedef struct { - uint8_t num; - coap_buffer_t buf; + uint8_t num; /* Option number. See http://tools.ietf.org/html/rfc7252#section-5.10 */ + coap_buffer_t buf; /* Option value */ } coap_option_t; typedef struct { - coap_header_t hdr; - coap_buffer_t tok; - uint8_t numopts; - coap_option_t opts[MAXOPT]; - coap_buffer_t payload; - coap_rw_buffer_t scratch; // scratch->p = malloc(...) , and free it when done. + coap_header_t hdr; /* Header of the packet */ + coap_buffer_t tok; /* Token value, size as specified by hdr.tkl */ + uint8_t numopts; /* Number of options */ + coap_option_t opts[MAXOPT]; /* Options of the packet. For possible entries see + * http://tools.ietf.org/html/rfc7252#section-5.10 */ + coap_buffer_t payload; /* Payload carried by the packet */ + coap_rw_buffer_t content; // content->p = malloc(...) , and free it when done. } coap_packet_t; ///////////////////////////////////////// -//http://tools.ietf.org/html/draft-ietf-core-coap-18#section-12.2 +//http://tools.ietf.org/html/rfc7252#section-12.2 typedef enum { COAP_OPTION_IF_MATCH = 1, @@ -78,7 +81,7 @@ typedef enum COAP_OPTION_PROXY_SCHEME = 39 } coap_option_num_t; -//http://tools.ietf.org/html/draft-ietf-core-coap-18#section-12.1.1 +//http://tools.ietf.org/html/rfc7252#section-12.1.1 typedef enum { COAP_METHOD_GET = 1, @@ -87,7 +90,7 @@ typedef enum COAP_METHOD_DELETE = 4 } coap_method_t; -//http://tools.ietf.org/html/draft-ietf-core-coap-18#section-12.1.1 +//http://tools.ietf.org/html/rfc7252#section-12.1.1 typedef enum { COAP_TYPE_CON = 0, @@ -96,8 +99,8 @@ typedef enum COAP_TYPE_RESET = 3 } coap_msgtype_t; -//http://tools.ietf.org/html/draft-ietf-core-coap-18#section-5.2 -//http://tools.ietf.org/html/draft-ietf-core-coap-18#section-12.1.2 +//http://tools.ietf.org/html/rfc7252#section-5.2 +//http://tools.ietf.org/html/rfc7252#section-12.1.2 #define MAKE_RSPCODE(clas, det) ((clas << 5) | (det)) typedef enum { @@ -107,7 +110,7 @@ typedef enum COAP_RSPCODE_CHANGED = MAKE_RSPCODE(2, 4) } coap_responsecode_t; -//http://tools.ietf.org/html/draft-ietf-core-coap-18#section-12.3 +//http://tools.ietf.org/html/rfc7252#section-12.3 typedef enum { COAP_CONTENTTYPE_NONE = -1, // bodge to allow us not to send option block @@ -155,15 +158,21 @@ struct coap_luser_entry{ coap_luser_entry *next; }; -struct coap_endpoint_t -{ - coap_method_t method; - coap_endpoint_func handler; - const coap_endpoint_path_t *path; - const char *core_attr; - coap_luser_entry *user_entry; +struct coap_endpoint_t{ + coap_method_t method; /* (i.e. POST, PUT or GET) */ + coap_endpoint_func handler; /* callback function which handles this + * type of endpoint (and calls + * coap_make_response() at some point) */ + const coap_endpoint_path_t *path; /* path towards a resource (i.e. foo/bar/) */ + const char *core_attr; /* the 'ct' attribute, as defined in RFC7252, section 7.2.1.: + * "The Content-Format code "ct" attribute + * provides a hint about the + * Content-Formats this resource returns." + * (Section 12.3. lists possible ct values.) */ + coap_luser_entry *user_entry; }; + /////////////////////// void coap_dumpPacket(coap_packet_t *pkt); int coap_parse(coap_packet_t *pkt, const uint8_t *buf, size_t buflen); @@ -173,11 +182,11 @@ int coap_build(uint8_t *buf, size_t *buflen, const coap_packet_t *pkt); void coap_dump(const uint8_t *buf, size_t buflen, bool bare); int coap_make_response(coap_rw_buffer_t *scratch, coap_packet_t *pkt, const uint8_t *content, size_t content_len, uint8_t msgid_hi, uint8_t msgid_lo, const coap_buffer_t* tok, coap_responsecode_t rspcode, coap_content_type_t content_type); int coap_handle_req(coap_rw_buffer_t *scratch, const coap_packet_t *inpkt, coap_packet_t *outpkt); -void coap_option_nibble(uint16_t value, uint8_t *nibble); +void coap_option_nibble(uint32_t value, uint8_t *nibble); void coap_setup(void); void endpoint_setup(void); -int coap_buildOptionHeader(unsigned short optDelta, size_t length, uint8_t *buf, size_t buflen); +int coap_buildOptionHeader(uint32_t optDelta, size_t length, uint8_t *buf, size_t buflen); #ifdef __cplusplus } diff --git a/app/coap/coap_client.c b/app/coap/coap_client.c index 37a1a5f0..63caf074 100644 --- a/app/coap/coap_client.c +++ b/app/coap/coap_client.c @@ -11,6 +11,8 @@ void coap_client_response_handler(char *data, unsigned short len, unsigned short { NODE_DBG("coap_client_response_handler is called.\n"); coap_packet_t pkt; + pkt.content.p = NULL; + pkt.content.len = 0; int rc; if (0 != (rc = coap_parse(&pkt, data, len))){ diff --git a/app/coap/coap_client.h b/app/coap/coap_client.h index 5559adfe..7f0a457b 100644 --- a/app/coap/coap_client.h +++ b/app/coap/coap_client.h @@ -1,11 +1,11 @@ -#ifndef _COAP_SERVER_H -#define _COAP_SERVER_H 1 +#ifndef _COAP_CLIENT_H +#define _COAP_CLIENT_H 1 #ifdef __cplusplus extern "C" { #endif -size_t coap_server_respond(char *data, unsigned short len, unsigned short size); +void coap_client_response_handler(char *data, unsigned short len, unsigned short size, const uint32_t ip, const uint32_t port); #ifdef __cplusplus } diff --git a/app/coap/coap_server.c b/app/coap/coap_server.c index d87bd8f7..cbec01f9 100644 --- a/app/coap/coap_server.c +++ b/app/coap/coap_server.c @@ -1,53 +1,60 @@ #include "user_config.h" #include "c_types.h" +#include "c_stdlib.h" #include "coap.h" -size_t coap_server_respond(char *data, unsigned short len, unsigned short size) +size_t coap_server_respond(char *req, unsigned short reqlen, char *rsp, unsigned short rsplen) { NODE_DBG("coap_server_respond is called.\n"); - if(len>size){ - NODE_DBG("len:%d, size:%d\n",len,size); - return 0; - } - size_t rsplen = size; + size_t rlen = rsplen; coap_packet_t pkt; + pkt.content.p = NULL; + pkt.content.len = 0; uint8_t scratch_raw[4]; coap_rw_buffer_t scratch_buf = {scratch_raw, sizeof(scratch_raw)}; int rc; #ifdef COAP_DEBUG NODE_DBG("Received: "); - coap_dump(data, len, true); + coap_dump(req, reqlen, true); NODE_DBG("\n"); #endif - if (0 != (rc = coap_parse(&pkt, data, len))){ + if (0 != (rc = coap_parse(&pkt, req, reqlen))){ NODE_DBG("Bad packet rc=%d\n", rc); return 0; } else { coap_packet_t rsppkt; + rsppkt.content.p = NULL; + rsppkt.content.len = 0; #ifdef COAP_DEBUG coap_dumpPacket(&pkt); #endif coap_handle_req(&scratch_buf, &pkt, &rsppkt); - if (0 != (rc = coap_build(data, &rsplen, &rsppkt))){ + if (0 != (rc = coap_build(rsp, &rlen, &rsppkt))){ NODE_DBG("coap_build failed rc=%d\n", rc); - return 0; + // return 0; + rlen = 0; } else { #ifdef COAP_DEBUG NODE_DBG("Responding: "); - coap_dump(data, rsplen, true); + coap_dump(rsp, rlen, true); NODE_DBG("\n"); #endif #ifdef COAP_DEBUG coap_dumpPacket(&rsppkt); #endif } - return rsplen; + if(rsppkt.content.p){ + c_free(rsppkt.content.p); + rsppkt.content.p = NULL; + rsppkt.content.len = 0; + } + return rlen; } } diff --git a/app/coap/coap_server.h b/app/coap/coap_server.h index 5559adfe..7eb023ec 100644 --- a/app/coap/coap_server.h +++ b/app/coap/coap_server.h @@ -5,7 +5,7 @@ extern "C" { #endif -size_t coap_server_respond(char *data, unsigned short len, unsigned short size); +size_t coap_server_respond(char *req, unsigned short reqlen, char *rsp, unsigned short rsplen); #ifdef __cplusplus } diff --git a/app/coap/endpoints.c b/app/coap/endpoints.c index a3d2d9d6..1d7d48bb 100644 --- a/app/coap/endpoints.c +++ b/app/coap/endpoints.c @@ -1,5 +1,6 @@ #include "c_stdio.h" #include "c_string.h" +#include "c_stdlib.h" #include "coap.h" #include "lua.h" @@ -8,20 +9,24 @@ #include "os_type.h" -static char rsp[MAX_PAYLOAD_SIZE] = ""; -const uint16_t rsplen = MAX_PAYLOAD_SIZE; -void build_well_known_rsp(void); +void build_well_known_rsp(char *rsp, uint16_t rsplen); void endpoint_setup(void) { coap_setup(); - build_well_known_rsp(); } static const coap_endpoint_path_t path_well_known_core = {2, {".well-known", "core"}}; static int handle_get_well_known_core(const coap_endpoint_t *ep, coap_rw_buffer_t *scratch, const coap_packet_t *inpkt, coap_packet_t *outpkt, uint8_t id_hi, uint8_t id_lo) { - return coap_make_response(scratch, outpkt, (const uint8_t *)rsp, c_strlen(rsp), id_hi, id_lo, &inpkt->tok, COAP_RSPCODE_CONTENT, COAP_CONTENTTYPE_APPLICATION_LINKFORMAT); + outpkt->content.p = (uint8_t *)c_zalloc(MAX_PAYLOAD_SIZE); // this should be free-ed when outpkt is built in coap_server_respond() + if(outpkt->content.p == NULL){ + NODE_DBG("not enough memory\n"); + return COAP_ERR_BUFFER_TOO_SMALL; + } + outpkt->content.len = MAX_PAYLOAD_SIZE; + build_well_known_rsp(outpkt->content.p, outpkt->content.len); + return coap_make_response(scratch, outpkt, (const uint8_t *)outpkt->content.p, c_strlen(outpkt->content.p), id_hi, id_lo, &inpkt->tok, COAP_RSPCODE_CONTENT, COAP_CONTENTTYPE_APPLICATION_LINKFORMAT); } static const coap_endpoint_path_t path_variable = {2, {"v1", "v"}}; @@ -29,6 +34,7 @@ static int handle_get_variable(const coap_endpoint_t *ep, coap_rw_buffer_t *scra { const coap_option_t *opt; uint8_t count; + int n; if (NULL != (opt = coap_findOptions(inpkt, COAP_OPTION_URI_PATH, &count))) { if ((count != ep->path->count ) && (count != ep->path->count + 1)) // +1 for /f/[function], /v/[variable] @@ -54,14 +60,15 @@ static int handle_get_variable(const coap_endpoint_t *ep, coap_rw_buffer_t *scra return coap_make_response(scratch, outpkt, NULL, 0, id_hi, id_lo, &inpkt->tok, COAP_RSPCODE_NOT_FOUND, COAP_CONTENTTYPE_NONE); if(c_strlen(h->name)) { + n = lua_gettop(h->L); lua_getglobal(h->L, h->name); if (!lua_isnumber(h->L, -1)) { NODE_DBG ("should be a number.\n"); - lua_pop(h->L, 1); + lua_settop(h->L, n); return coap_make_response(scratch, outpkt, NULL, 0, id_hi, id_lo, &inpkt->tok, COAP_RSPCODE_NOT_FOUND, COAP_CONTENTTYPE_NONE); } else { const char *res = lua_tostring(h->L,-1); - lua_pop(h->L, 1); + lua_settop(h->L, n); return coap_make_response(scratch, outpkt, (const uint8_t *)res, c_strlen(res), id_hi, id_lo, &inpkt->tok, COAP_RSPCODE_CONTENT, COAP_CONTENTTYPE_TEXT_PLAIN); } } @@ -84,6 +91,7 @@ static int handle_post_function(const coap_endpoint_t *ep, coap_rw_buffer_t *scr { const coap_option_t *opt; uint8_t count; + int n; if (NULL != (opt = coap_findOptions(inpkt, COAP_OPTION_URI_PATH, &count))) { if ((count != ep->path->count ) && (count != ep->path->count + 1)) // +1 for /f/[function], /v/[variable] @@ -111,10 +119,11 @@ static int handle_post_function(const coap_endpoint_t *ep, coap_rw_buffer_t *scr if(c_strlen(h->name)) { + n = lua_gettop(h->L); lua_getglobal(h->L, h->name); if (lua_type(h->L, -1) != LUA_TFUNCTION) { NODE_DBG ("should be a function\n"); - lua_pop(h->L, 1); + lua_settop(h->L, n); return coap_make_response(scratch, outpkt, NULL, 0, id_hi, id_lo, &inpkt->tok, COAP_RSPCODE_NOT_FOUND, COAP_CONTENTTYPE_NONE); } else { lua_pushlstring(h->L, inpkt->payload.p, inpkt->payload.len); // make sure payload.p is filled with '\0' after payload.len, or use lua_pushlstring @@ -125,14 +134,17 @@ static int handle_post_function(const coap_endpoint_t *ep, coap_rw_buffer_t *scr size_t len = 0; const char *ret = luaL_checklstring( h->L, -1, &len ); if(len > MAX_PAYLOAD_SIZE){ + lua_settop(h->L, n); luaL_error( h->L, "return string:tok, COAP_RSPCODE_NOT_FOUND, COAP_CONTENTTYPE_NONE); } NODE_DBG((char *)ret); NODE_DBG("\n"); + lua_settop(h->L, n); return coap_make_response(scratch, outpkt, ret, len, id_hi, id_lo, &inpkt->tok, COAP_RSPCODE_CONTENT, COAP_CONTENTTYPE_TEXT_PLAIN); } } else { + lua_settop(h->L, n); return coap_make_response(scratch, outpkt, NULL, 0, id_hi, id_lo, &inpkt->tok, COAP_RSPCODE_CONTENT, COAP_CONTENTTYPE_TEXT_PLAIN); } } @@ -204,13 +216,13 @@ const coap_endpoint_t endpoints[] = {(coap_method_t)0, NULL, NULL, NULL, NULL} }; -void build_well_known_rsp(void) +void build_well_known_rsp(char *rsp, uint16_t rsplen) { const coap_endpoint_t *ep = endpoints; int i; uint16_t len = rsplen; - c_memset(rsp, 0, sizeof(rsp)); + c_memset(rsp, 0, len); len--; // Null-terminated string diff --git a/app/coap/pdu.c b/app/coap/pdu.c index 8313146c..e32f028d 100644 --- a/app/coap/pdu.c +++ b/app/coap/pdu.c @@ -24,6 +24,8 @@ coap_pdu_t * coap_new_pdu(void) { c_free(pdu); return NULL; } + pdu->pkt->content.p = NULL; + pdu->pkt->content.len = 0; pdu->msg.p = (uint8_t *)c_zalloc(MAX_REQUEST_SIZE+1); // +1 for string '\0' if(!pdu->msg.p){ diff --git a/app/include/user_config.h b/app/include/user_config.h index 26af62cc..96ad3322 100644 --- a/app/include/user_config.h +++ b/app/include/user_config.h @@ -10,6 +10,7 @@ // #define FLASH_8M // #define FLASH_16M #define FLASH_AUTOSIZE +#define FLASH_SAFE_API // #define DEVELOP_VERSION #define FULL_VERSION_FOR_USER diff --git a/app/include/user_modules.h b/app/include/user_modules.h index a21cee19..103b004f 100644 --- a/app/include/user_modules.h +++ b/app/include/user_modules.h @@ -27,7 +27,7 @@ #define LUA_USE_MODULES_OW #define LUA_USE_MODULES_BIT #define LUA_USE_MODULES_MQTT -// #define LUA_USE_MODULES_COAP // need about 4k more ram for now +#define LUA_USE_MODULES_COAP #define LUA_USE_MODULES_U8G #define LUA_USE_MODULES_WS2812 #endif /* LUA_USE_MODULES */ diff --git a/app/include/user_version.h b/app/include/user_version.h index ed2b0d6d..1576fbe3 100644 --- a/app/include/user_version.h +++ b/app/include/user_version.h @@ -7,6 +7,6 @@ #define NODE_VERSION_INTERNAL 0U #define NODE_VERSION "NodeMCU 0.9.5" -#define BUILD_DATE "build 20150311" +#define BUILD_DATE "build 20150315" #endif /* __USER_VERSION_H__ */ diff --git a/app/libc/c_stdio.c b/app/libc/c_stdio.c index 03e64581..a8e0956f 100644 --- a/app/libc/c_stdio.c +++ b/app/libc/c_stdio.c @@ -63,7 +63,7 @@ int c_stderr = 1001; #define ENDIAN_LITTLE 1234 #define ENDIAN_BIG 4321 #define ENDIAN_PDP 3412 -#define ENDIAN ENDIAN_BIG +#define ENDIAN ENDIAN_LITTLE /* $Id: strichr.c,v 1.1.1.1 2006/08/23 17:03:06 pefo Exp $ */ diff --git a/app/lua/lauxlib.c b/app/lua/lauxlib.c index 00e740be..e5c89ad5 100644 --- a/app/lua/lauxlib.c +++ b/app/lua/lauxlib.c @@ -659,13 +659,19 @@ typedef struct LoadFSF { static const char *getFSF (lua_State *L, void *ud, size_t *size) { LoadFSF *lf = (LoadFSF *)ud; (void)L; + + if (L == NULL && size == NULL) // Direct mode check + return NULL; + if (lf->extraline) { lf->extraline = 0; *size = 1; return "\n"; } + if (fs_eof(lf->f)) return NULL; *size = fs_read(lf->f, lf->buff, sizeof(lf->buff)); + return (*size > 0) ? lf->buff : NULL; } diff --git a/app/modules/coap.c b/app/modules/coap.c index 2afb9b54..8e1ba6c0 100644 --- a/app/modules/coap.c +++ b/app/modules/coap.c @@ -37,20 +37,20 @@ static void coap_received(void *arg, char *pdata, unsigned short len) 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' + // 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; - } else { - c_memcpy(buf, pdata, len); } + // c_memcpy(buf, pdata, len); - size_t rsplen = coap_server_respond(buf, len, MAX_MESSAGE_SIZE+1); + 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)); + // c_memset(buf, 0, sizeof(buf)); } static void coap_sent(void *arg) @@ -227,26 +227,19 @@ static void coap_response_handler(void *arg, char *pdata, unsigned short len) struct espconn *pesp_conn = arg; coap_packet_t pkt; - static uint8_t buf[MAX_MESSAGE_SIZE+1] = {0}; // +1 for string '\0' + 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 - static int n = 0; int rc; - if ((len == 1460) && (1460 <= MAX_MESSAGE_SIZE)){ - c_memcpy(buf, pdata, len); // max length is 1460, another part of data is coming in next callback - n = len; + if( len > MAX_MESSAGE_SIZE ) + { + NODE_DBG("Request Entity Too Large.\n"); // NOTE: should response 4.13 to client... return; - } else { - if( len > MAX_MESSAGE_SIZE ) - { - NODE_DBG("Request Entity Too Large.\n"); // NOTE: should response 4.13 to client... - c_memset(buf, 0, sizeof(buf)); // wipe prev data - n = 0; - return; - } - c_memcpy(buf + n, pdata, len); - len += n; // more than 1460 } + c_memcpy(buf, pdata, len); if (0 != (rc = coap_parse(&pkt, buf, len))){ NODE_DBG("Bad packet rc=%d\n", rc); @@ -306,8 +299,7 @@ end: if(pesp_conn->proto.udp->remote_port || pesp_conn->proto.udp->local_port) espconn_delete(pesp_conn); } - c_memset(buf, 0, sizeof(buf)); - n = 0; + // c_memset(buf, 0, sizeof(buf)); } // Lua: client:request( [CON], uri, [payload] ) @@ -431,7 +423,6 @@ static int coap_request( lua_State* L, coap_method_t m ) extern coap_luser_entry *variable_entry; extern coap_luser_entry *function_entry; -extern void build_well_known_rsp(void); // Lua: coap:var/func( string ) static int coap_regist( lua_State* L, const char* mt, int isvar ) { @@ -466,8 +457,6 @@ static int coap_regist( lua_State* L, const char* mt, int isvar ) h->L = L; h->name = name; - build_well_known_rsp(); // rebuild .well-known - NODE_DBG("coap_regist is called.\n"); return 0; } diff --git a/app/modules/node.c b/app/modules/node.c index 0384d798..7a3af5fd 100644 --- a/app/modules/node.c +++ b/app/modules/node.c @@ -80,9 +80,13 @@ static int node_info( lua_State* L ) lua_pushinteger(L, NODE_VERSION_REVISION); lua_pushinteger(L, system_get_chip_id()); // chip id lua_pushinteger(L, spi_flash_get_id()); // flash id - lua_pushinteger(L, flash_get_size_byte() / 1024); // flash size in KB - lua_pushinteger(L, flash_get_mode()); - lua_pushinteger(L, flash_get_speed()); + #if defined(FLASH_SAFE_API) + lua_pushinteger(L, flash_safe_get_size_byte() / 1024); // flash size in KB + #else + 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; } @@ -121,7 +125,11 @@ static int node_flashsize( lua_State* L ) // flash_set_size_byte(sz); // } //} - uint32_t sz = flash_get_size_byte(); +#if defined(FLASH_SAFE_API) + uint32_t sz = flash_safe_get_size_byte(); +#else + uint32_t sz = flash_rom_get_size_byte(); +#endif // defined(FLASH_SAFE_API) lua_pushinteger( L, sz ); return 1; } diff --git a/app/platform/cpu_esp8266.h b/app/platform/cpu_esp8266.h index 75a238dc..ec6440a7 100644 --- a/app/platform/cpu_esp8266.h +++ b/app/platform/cpu_esp8266.h @@ -30,7 +30,11 @@ #elif defined(FLASH_16M) #define FLASH_SEC_NUM 0x1000 #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 #define FLASH_SEC_NUM 0x80 #endif @@ -54,8 +58,14 @@ // SpiFlashOpResult spi_flash_erase_sector(uint16 sec); // SpiFlashOpResult spi_flash_write(uint32 des_addr, uint32 *src_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_erase spi_flash_erase_sector #define flash_read spi_flash_read +#endif // defined(FLASH_SAFE_API) #endif // #ifndef __CPU_ESP8266_H__ diff --git a/app/platform/flash_api.c b/app/platform/flash_api.c index c4ce6f57..6af6e31c 100644 --- a/app/platform/flash_api.c +++ b/app/platform/flash_api.c @@ -20,77 +20,160 @@ 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 }; -SPIFlashInfo flash_get_info(void) +uint32_t flash_detect_size_byte(void) { - volatile SPIFlashInfo spi_flash_info ICACHE_STORE_ATTR; - spi_flash_info = *((SPIFlashInfo *)(FLASH_MAP_START_ADDRESS)); - // spi_flash_read(0, (uint32 *)(& spi_flash_info), sizeof(spi_flash_info)); - return spi_flash_info; -} - -uint8_t flash_get_size(void) -{ - return flash_get_info().size; -} - -uint32_t flash_get_size_byte(void) -{ - uint32_t flash_size = 0; - switch (flash_get_info().size) +#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)) { - case SIZE_2MBIT: - // 2Mbit, 256kByte - flash_size = 256 * 1024; - break; - case SIZE_4MBIT: - // 4Mbit, 512kByte - flash_size = 512 * 1024; - break; - case SIZE_8MBIT: - // 8Mbit, 1MByte - flash_size = 1 * 1024 * 1024; - break; - case SIZE_16MBIT: - // 16Mbit, 2MByte - flash_size = 2 * 1024 * 1024; - break; - case SIZE_32MBIT: - // 32Mbit, 4MByte - flash_size = 4 * 1024 * 1024; - break; - case SIZE_64MBIT: - // 64Mbit, 8MByte - flash_size = 8 * 1024 * 1024; - break; - case SIZE_128MBIT: - // 128Mbit, 16MByte - flash_size = 16 * 1024 * 1024; - break; - default: - // Unknown flash size, fall back mode. - flash_size = 512 * 1024; - break; + 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; } -bool flash_set_size(uint8_t 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; + // 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; +} + +uint8_t flash_rom_get_size_type(void) +{ + return flash_rom_getinfo().size; +} + +uint32_t flash_rom_get_size_byte(void) +{ + static uint32_t flash_size = 0; + if (flash_size == 0) + { + switch (flash_rom_getinfo().size) + { + case SIZE_2MBIT: + // 2Mbit, 256kByte + flash_size = 256 * 1024; + break; + case SIZE_4MBIT: + // 4Mbit, 512kByte + flash_size = 512 * 1024; + break; + case SIZE_8MBIT: + // 8Mbit, 1MByte + flash_size = 1 * 1024 * 1024; + break; + case SIZE_16MBIT: + // 16Mbit, 2MByte + flash_size = 2 * 1024 * 1024; + break; + case SIZE_32MBIT: + // 32Mbit, 4MByte + flash_size = 4 * 1024 * 1024; + break; + case SIZE_64MBIT: + // 64Mbit, 8MByte + flash_size = 8 * 1024 * 1024; + break; + case SIZE_128MBIT: + // 128Mbit, 16MByte + flash_size = 16 * 1024 * 1024; + break; + default: + // Unknown flash size, fall back mode. + flash_size = 512 * 1024; + break; + } + } + return flash_size; +} + +bool flash_rom_set_size_type(uint8_t size) { // Dangerous, here are dinosaur infested!!!!! // Reboot required!!! // If you don't know what you're doing, your nodemcu may turn into stone ... +#if defined(FLASH_SAFE_API) + uint8_t data[SPI_FLASH_SEC_SIZE] ICACHE_STORE_ATTR; + flash_safe_read(0, (uint32 *)data, sizeof(data)); + SPIFlashInfo *p_spi_flash_info = (SPIFlashInfo *)(data); + p_spi_flash_info->size = size; + flash_safe_erase_sector(0); + flash_safe_write(0, (uint32 *)data, sizeof(data)); + // TODO: CHECKSUM Firmware + //p_spi_flash_info = flash_rom_getinfo(); + //p_spi_flash_info->size = size; +#else uint8_t data[SPI_FLASH_SEC_SIZE] ICACHE_STORE_ATTR; spi_flash_read(0, (uint32 *)data, sizeof(data)); SPIFlashInfo *p_spi_flash_info = (SPIFlashInfo *)(data); p_spi_flash_info->size = size; spi_flash_erase_sector(0); spi_flash_write(0, (uint32 *)data, sizeof(data)); - //p_spi_flash_info = flash_get_info(); + // TODO: CHECKSUM Firmware + //p_spi_flash_info = flash_rom_getinfo(); //p_spi_flash_info->size = size; +#endif // defined(FLASH_SAFE_API) return true; } -bool flash_set_size_byte(uint32_t size) +bool flash_rom_set_size_byte(uint32_t size) { // Dangerous, here are dinosaur infested!!!!! // Reboot required!!! @@ -102,27 +185,27 @@ bool flash_set_size_byte(uint32_t size) case 256 * 1024: // 2Mbit, 256kByte flash_size = SIZE_2MBIT; - flash_set_size(flash_size); + flash_rom_set_size_type(flash_size); break; case 512 * 1024: // 4Mbit, 512kByte flash_size = SIZE_4MBIT; - flash_set_size(flash_size); + flash_rom_set_size_type(flash_size); break; case 1 * 1024 * 1024: // 8Mbit, 1MByte flash_size = SIZE_8MBIT; - flash_set_size(flash_size); + flash_rom_set_size_type(flash_size); break; case 2 * 1024 * 1024: // 16Mbit, 2MByte flash_size = SIZE_16MBIT; - flash_set_size(flash_size); + flash_rom_set_size_type(flash_size); break; case 4 * 1024 * 1024: // 32Mbit, 4MByte flash_size = SIZE_32MBIT; - flash_set_size(flash_size); + flash_rom_set_size_type(flash_size); break; default: // Unknown flash size. @@ -132,22 +215,22 @@ bool flash_set_size_byte(uint32_t size) return result; } -uint16_t flash_get_sec_num(void) +uint16_t flash_rom_get_sec_num(void) { //static uint16_t sec_num = 0; - // return flash_get_size_byte() / (SPI_FLASH_SEC_SIZE); - // c_printf("\nflash_get_size_byte()=%d\n", ( flash_get_size_byte() / (SPI_FLASH_SEC_SIZE) )); + // 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_get_size_byte() / (SPI_FLASH_SEC_SIZE) ); + 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) { // Reserved for future use @@ -163,10 +246,10 @@ uint8_t flash_get_mode(void) return spi_flash_info.mode; } -uint32_t flash_get_speed(void) +uint32_t flash_rom_get_speed(void) { uint32_t speed = 0; - SPIFlashInfo spi_flash_info = flash_get_info(); + SPIFlashInfo spi_flash_info = flash_rom_getinfo(); switch (spi_flash_info.speed) { case SPEED_40MHZ: @@ -193,7 +276,11 @@ bool flash_init_data_written(void) { // FLASH SEC - 4 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) { @@ -210,13 +297,23 @@ bool flash_init_data_default(void) // Reboot required!!! // It will init system data to default! 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 == spi_flash_write((flash_get_sec_num() - 4) * SPI_FLASH_SEC_SIZE, (uint32 *)flash_init_data, 128)) + 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_rom_get_sec_num() - 4) * SPI_FLASH_SEC_SIZE, (uint32 *)flash_init_data, 128)) + { + result = true; + } + } +#endif // defined(FLASH_SAFE_API) return result; } @@ -227,8 +324,13 @@ bool flash_init_data_blank(void) // Reboot required!!! // It will init system config to blank! bool result = false; - if ((SPI_FLASH_RESULT_OK == spi_flash_erase_sector((flash_get_sec_num() - 2))) && - (SPI_FLASH_RESULT_OK == spi_flash_erase_sector((flash_get_sec_num() - 1)))) +#if defined(FLASH_SAFE_API) + 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; } diff --git a/app/platform/flash_api.h b/app/platform/flash_api.h index 038553a2..f912be41 100644 --- a/app/platform/flash_api.h +++ b/app/platform/flash_api.h @@ -4,34 +4,61 @@ #include "user_config.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 * Note: It is unsafe to use ROM function, but it may efficient. * SPIEraseSector - * unknown SPIEraseSector(uint16 sec); + * SpiFlashOpResult SPIEraseSector(uint16 sec); * The 1st parameter is flash sector number. + * Note: Must disable cache read before using it. - * SPIRead (Unsafe) - * unknown SPIRead(uint32_t src_addr, uint32_t *des_addr, uint32_t size); + * SPIRead + * SpiFlashOpResult SPIRead(uint32_t src_addr, uint32_t *des_addr, uint32_t size); * The 1st parameter is source addresses. * The 2nd parameter is destination addresses. * 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) - * unknown SPIWrite(uint32_t des_addr, uint32_t *src_addr, uint32_t size); + * SPIWrite + * SpiFlashOpResult SPIWrite(uint32_t des_addr, uint32_t *src_addr, uint32_t size); * The 1st parameter is destination addresses. * The 2nd parameter is source addresses. * 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 { - uint8_t unknown0; - uint8_t unknown1; + uint8_t magic_e9; + uint8_t segments; enum { MODE_QIO = 0, @@ -58,14 +85,20 @@ typedef struct } size : 4; } ICACHE_STORE_TYPEDEF_ATTR SPIFlashInfo; -SPIFlashInfo flash_get_info(void); -uint8_t flash_get_size(void); -uint32_t flash_get_size_byte(void); -bool flash_set_size(uint8_t); -bool flash_set_size_byte(uint32_t); -uint16_t flash_get_sec_num(void); -uint8_t flash_get_mode(void); -uint32_t flash_get_speed(void); +uint32_t flash_detect_size_byte(void); +uint32_t flash_safe_get_size_byte(void); +uint16_t flash_safe_get_sec_num(void); +SpiFlashOpResult flash_safe_read(uint32 src_addr, uint32 *des_addr, uint32 size); +SpiFlashOpResult flash_safe_write(uint32 des_addr, uint32 *src_addr, uint32 size); +SpiFlashOpResult flash_safe_erase_sector(uint16 sec); +SPIFlashInfo flash_rom_getinfo(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_default(void); bool flash_init_data_blank(void); diff --git a/examples/fragment.lua b/examples/fragment.lua index c1cc4fb7..a56e423a 100644 --- a/examples/fragment.lua +++ b/examples/fragment.lua @@ -355,8 +355,11 @@ cs:listen(5683) myvar=1 cs:var("myvar") -- get coap://192.168.18.103:5683/v1/v/myvar will return the value of myvar: 1 -function myfun() +-- function should tack one string, return one string. +function myfun(payload) print("myfun called") + respond = "hello" + return respond end cs:func("myfun") -- post coap://192.168.18.103:5683/v1/f/myfun will call myfun diff --git a/lua_modules/ds18b20/ds18b20.lua b/lua_modules/ds18b20/ds18b20.lua index c31addcf..138c10da 100644 --- a/lua_modules/ds18b20/ds18b20.lua +++ b/lua_modules/ds18b20/ds18b20.lua @@ -3,6 +3,7 @@ -- NODEMCU TEAM -- LICENCE: http://opensource.org/licenses/MIT -- Vowstar +-- 2015/02/14 sza2 Fix for negative values -------------------------------------------------------------------------------- -- Set module name as parameter of require @@ -96,12 +97,16 @@ function readNumber(addr, unit) crc = ow.crc8(string.sub(data,1,8)) -- print("CRC="..crc) if (crc == data:byte(9)) then + t = (data:byte(1) + data:byte(2) * 256) + if (t > 32767) then + t = t - 65536 + end if(unit == nil or unit == C) then - t = (data:byte(1) + data:byte(2) * 256) * 625 + t = t * 625 elseif(unit == F) then - t = (data:byte(1) + data:byte(2) * 256) * 1125 + 320000 + t = t * 1125 + 320000 elseif(unit == K) then - t = (data:byte(1) + data:byte(2) * 256) * 625 + 2731500 + t = t * 625 + 2731500 else return nil end