Merge pull request #1 from MarsTechHAN/master
Update to MarsTechHAN's nodemcu-firmware
This commit is contained in:
commit
9cab751363
|
@ -1,6 +1,6 @@
|
|||
eclipse.preferences.version=1
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.cross.base.992255352/PATH/delimiter=;
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.cross.base.992255352/PATH/operation=append
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.cross.base.992255352/PATH/value=C\:\\Espressif\\xtensa-lx106-elf\\bin
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.cross.base.992255352/PATH/value=C\:\\Espressif\\xtensa-lx106-elf\\bin;C\:\\MinGW\\bin;C\:\\MinGW\\msys\\1.0\\bin;C\:\\Python27
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.cross.base.992255352/append=true
|
||||
environment/project/cdt.managedbuild.toolchain.gnu.cross.base.992255352/appendContributed=true
|
||||
|
|
12
Makefile
12
Makefile
|
@ -30,7 +30,11 @@ ifeq ($(OS),Windows_NT)
|
|||
OBJCOPY = xtensa-lx106-elf-objcopy
|
||||
endif
|
||||
FIRMWAREDIR = ..\\bin\\
|
||||
ESPPORT = com1
|
||||
ifndef COMPORT
|
||||
ESPPORT = com1
|
||||
else
|
||||
ESPPORT = $(COMPORT)
|
||||
endif
|
||||
ifeq ($(PROCESSOR_ARCHITECTURE),AMD64)
|
||||
# ->AMD64
|
||||
endif
|
||||
|
@ -40,7 +44,11 @@ ifeq ($(OS),Windows_NT)
|
|||
else
|
||||
# We are under other system, may be Linux. Assume using gcc.
|
||||
# Can we use -fdata-sections?
|
||||
ESPPORT = /dev/ttyUSB0
|
||||
ifndef COMPORT
|
||||
ESPPORT = /dev/ttyUSB0
|
||||
else
|
||||
ESPPORT = $(COMPORT)
|
||||
endif
|
||||
CCFLAGS += -Os -ffunction-sections -fno-jump-tables
|
||||
AR = xtensa-lx106-elf-ar
|
||||
CC = xtensa-lx106-elf-gcc
|
||||
|
|
154
README.md
154
README.md
|
@ -1,45 +1,72 @@
|
|||
# **NodeMcu** #
|
||||
version 0.9.5
|
||||
###A lua based firmware for wifi-soc esp8266
|
||||
Build on [ESP8266 sdk 0.9.5](http://bbs.espressif.com/viewtopic.php?f=7&t=104)<br />
|
||||
Build on [ESP8266 sdk 0.9.5](http://bbs.espressif.com/viewtopic.php?f=5&t=154)<br />
|
||||
Lua core based on [eLua project](http://www.eluaproject.net/)<br />
|
||||
File system based on [spiffs](https://github.com/pellepl/spiffs)<br />
|
||||
Open source development kit for NodeMCU [nodemcu-devkit](https://github.com/nodemcu/nodemcu-devkit)<br />
|
||||
Flash tool for NodeMCU [nodemcu-flasher](https://github.com/nodemcu/nodemcu-flasher)<br />
|
||||
|
||||
wiki: [nodemcu wiki](https://github.com/nodemcu/nodemcu-firmware/wiki)<br />
|
||||
api: [nodemcu api](https://github.com/nodemcu/nodemcu-firmware/wiki/nodemcu_api_en)<br />
|
||||
home: [nodemcu.com](http://www.nodemcu.com)<br />
|
||||
bbs: [中文论坛Chinese bbs](http://bbs.nodemcu.com)<br />
|
||||
Tencent QQ group QQ群: 309957875<br />
|
||||
bbs: [Chinese bbs](http://bbs.nodemcu.com)<br />
|
||||
Tencent QQ group: 309957875<br />
|
||||
|
||||
# Summary
|
||||
- Easy to access wireless router
|
||||
- Based on Lua 5.1.4 (without *io, math, debug, os* module.)
|
||||
- Event-Drive programming preferred.
|
||||
- Build-in file, timer, pwm, i2c, 1-wire, net, gpio, wifi, adc, uart and system api.
|
||||
- Build-in file, timer, pwm, i2c, spi, 1-wire, net, mqtt, gpio, wifi, adc, uart and system api.
|
||||
- GPIO pin re-mapped, use the index to access gpio, i2c, pwm.
|
||||
|
||||
# To Do List (pull requests are very welcomed)
|
||||
- fix wifi smart connect
|
||||
- add spi module
|
||||
- add mqtt module
|
||||
- add spi module (done)
|
||||
- add mqtt module (done)
|
||||
- add coap module
|
||||
- cross compiler
|
||||
|
||||
# Change log
|
||||
2015-01-27<br />
|
||||
support floating point LUA.<br />
|
||||
use macro LUA_NUMBER_INTEGRAL in user_config.h control this feature.<br />
|
||||
LUA_NUMBER_INTEGRAL to disable floating point support,<br />
|
||||
// LUA_NUMBER_INTEGRAL to enable floating point support.<br />
|
||||
fix tmr.time(). #132<br />
|
||||
fix filesystem length. #113<br />
|
||||
fix ssl reboots. #134<br />
|
||||
build pre_build bin.
|
||||
|
||||
2015-01-26<br />
|
||||
applied sdk095_patch1 to sdk 0.9.5.<br />
|
||||
added LUA examples and modules [by dvv](https://github.com/dvv). <br />
|
||||
added node.readvdd33() API [by alonewolfx2](https://github.com/alonewolfx2).<br />
|
||||
build pre_build bin.
|
||||
|
||||
2015-01-24<br />
|
||||
migrate to sdk 0.9.5 release.<br />
|
||||
tmr.time() now return second(not precise yet). <br />
|
||||
build pre_build bin.
|
||||
|
||||
2015-01-23<br />
|
||||
merge mqtt branch to master.<br />
|
||||
build pre_build bin.
|
||||
|
||||
2015-01-18<br />
|
||||
merge mqtt module to [new branch mqtt](https://github.com/nodemcu/nodemcu-firmware/tree/mqtt) from [https://github.com/tuanpmt/esp_mqtt](https://github.com/tuanpmt/esp_mqtt).<br />
|
||||
merge spi module from iabdalkader:spi. <br />
|
||||
fix #110,set local port to random in client mode.<br />
|
||||
modify gpio.read to NOT set pin to input mode automatic.<br />
|
||||
add PATH env with C:\MinGW\bin;C:\MinGW\msys\1.0\bin;C:\Python27 in eclipse project. resolve #103.
|
||||
|
||||
2015-01-08<br />
|
||||
fix net.socket:send() issue when multi sends are called. <br />
|
||||
*NOTE*: if data length is bigger than 1460, send next packet AFTER "sent" callback is called.<br />
|
||||
fix file.read() api, take 0xFF as a regular byte, not EOF.<br />
|
||||
pre_build/latest/nodemcu_512k_latest.bin is removed. use pre_build/latest/nodemcu_latest.bin instead.
|
||||
|
||||
2015-01-07<br />
|
||||
retrive more ram back.<br />
|
||||
add api file.format() to rebuild file system.<br />
|
||||
rename "NodeMcu" to "NodeMCU" in firmware.<br />
|
||||
add some check for file system op.
|
||||
|
||||
[more change log](https://github.com/nodemcu/nodemcu-firmware/wiki/nodemcu_api_en#change_log)<br />
|
||||
[更多变更日志](https://github.com/nodemcu/nodemcu-firmware/wiki/nodemcu_api_cn#change_log)
|
||||
[more change log](https://github.com/nodemcu/nodemcu-firmware/wiki)<br />
|
||||
|
||||
##GPIO NEW TABLE ( Build 20141219 and later)
|
||||
|
||||
|
@ -75,39 +102,6 @@ add some check for file system op.
|
|||
</table>
|
||||
#### [*] D0(GPIO16) can only be used as gpio read/write. no interrupt supported. no pwm/i2c/ow supported.
|
||||
|
||||
##GPIO OLD TABLE (Before build 20141212)
|
||||
|
||||
<a id="old_gpio_map"></a>
|
||||
<table>
|
||||
<tr>
|
||||
<th scope="col">IO index</th><th scope="col">ESP8266 pin</th><th scope="col">IO index</th><th scope="col">ESP8266 pin</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>0</td><td>GPIO12</td><td>8</td><td>GPIO0</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>1</td><td>GPIO13</td><td>9</td><td>GPIO2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>2</td><td>GPIO14</td><td>10</td><td>GPIO4</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>3</td><td>GPIO15</td><td>11</td><td>GPIO5</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>4</td><td>GPIO3</td><td></td><td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>5</td><td>GPIO1</td><td></td><td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>6</td><td>GPIO9</td><td></td><td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>7</td><td>GPIO10</td<td></td><td></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
#Build option
|
||||
####file ./app/include/user_config.h
|
||||
```c
|
||||
|
@ -132,6 +126,8 @@ add some check for file system op.
|
|||
#define LUA_USE_MODULES_OW
|
||||
#define LUA_USE_MODULES_BIT
|
||||
#endif /* LUA_USE_MODULES */
|
||||
...
|
||||
// LUA_NUMBER_INTEGRAL
|
||||
```
|
||||
|
||||
#Flash the firmware
|
||||
|
@ -140,10 +136,8 @@ for most esp8266 modules, just pull GPIO0 down and restart.<br />
|
|||
You can use the [nodemcu-flasher](https://github.com/nodemcu/nodemcu-flasher) to burn the firmware.
|
||||
|
||||
Or, if you build your own bin from source code.<br />
|
||||
eagle.app.v6.flash.bin: 0x00000<br />
|
||||
eagle.app.v6.irom0text.bin: 0x10000<br />
|
||||
esp_init_data_default.bin: 0x7c000<br />
|
||||
blank.bin: 0x7e000<br />
|
||||
0x00000.bin: 0x00000<br />
|
||||
0x10000.bin: 0x10000<br />
|
||||
|
||||
*Better run file.format() after flash*
|
||||
|
||||
|
@ -155,11 +149,13 @@ baudrate:9600
|
|||
####Connect to your ap
|
||||
|
||||
```lua
|
||||
print(wifi.sta.getip())
|
||||
--0.0.0.0
|
||||
ip = wifi.sta.getip()
|
||||
print(ip)
|
||||
--nil
|
||||
wifi.setmode(wifi.STATION)
|
||||
wifi.sta.config("SSID","password")
|
||||
print(wifi.sta.getip())
|
||||
ip = wifi.sta.getip()
|
||||
print(ip)
|
||||
--192.168.18.110
|
||||
```
|
||||
|
||||
|
@ -197,6 +193,56 @@ baudrate:9600
|
|||
end)
|
||||
```
|
||||
|
||||
####Connect to MQTT Broker
|
||||
|
||||
```lua
|
||||
-- init mqtt client with keepalive timer 120sec
|
||||
m = mqtt.Client("clientid", 120, "user", "password")
|
||||
|
||||
-- setup Last Will and Testament (optional)
|
||||
-- Broker will publish a message with qos = 0, retain = 0, data = "offline"
|
||||
-- to topic "/lwt" if client don't send keepalive packet
|
||||
m:lwt("/lwt", "offline", 0, 0)
|
||||
|
||||
m:on("connect", function(con) print ("connected") end)
|
||||
m:on("offline", function(con) print ("offline") end)
|
||||
|
||||
-- on publish message receive event
|
||||
m:on("message", function(conn, topic, data)
|
||||
print(topic .. ":" )
|
||||
if data ~= nil then
|
||||
print(data)
|
||||
end
|
||||
end)
|
||||
|
||||
-- for secure: m:connect("192.168.11.118", 1880, 1)
|
||||
m:connect("192.168.11.118", 1880, 0, function(conn) print("connected") end)
|
||||
|
||||
-- subscribe topic with qos = 0
|
||||
m:subscribe("/topic",0, function(conn) print("subscribe success") end)
|
||||
|
||||
-- publish a message with data = hello, QoS = 0, retain = 0
|
||||
m:publish("/topic","hello",0,0, function(conn) print("sent") end)
|
||||
|
||||
m:close();
|
||||
-- you can call m:connect again
|
||||
|
||||
```
|
||||
|
||||
#### UDP client and server
|
||||
```lua
|
||||
-- a udp server
|
||||
s=net.createServer(net.UDP)
|
||||
s:on("receive",function(s,c) print(c) end)
|
||||
s:listen(5683)
|
||||
|
||||
-- a udp client
|
||||
cu=net.createConnection(net.UDP)
|
||||
cu:on("receive",function(cu,c) print(c) end)
|
||||
cu:connect(5683,"192.168.18.101")
|
||||
cu:send("hello")
|
||||
```
|
||||
|
||||
####Do something shining
|
||||
```lua
|
||||
function led(r,g,b)
|
||||
|
|
|
@ -26,11 +26,11 @@ SUBDIRS= \
|
|||
driver \
|
||||
lwip \
|
||||
json \
|
||||
ssl \
|
||||
upgrade \
|
||||
platform \
|
||||
libc \
|
||||
lua \
|
||||
mqtt \
|
||||
smart \
|
||||
wofs \
|
||||
modules \
|
||||
|
@ -41,6 +41,7 @@ endif # } PDIR
|
|||
APPDIR = .
|
||||
LDDIR = ../ld
|
||||
|
||||
CCFLAGS += -Os
|
||||
|
||||
TARGET_LDFLAGS = \
|
||||
-nostdlib \
|
||||
|
@ -48,7 +49,6 @@ TARGET_LDFLAGS = \
|
|||
--longcalls \
|
||||
--text-section-literals
|
||||
|
||||
|
||||
ifeq ($(FLAVOR),debug)
|
||||
TARGET_LDFLAGS += -g -O2
|
||||
endif
|
||||
|
@ -72,11 +72,11 @@ COMPONENTS_eagle.app.v6 = \
|
|||
driver/libdriver.a \
|
||||
lwip/liblwip.a \
|
||||
json/libjson.a \
|
||||
ssl/libssl.a \
|
||||
upgrade/libupgrade.a \
|
||||
platform/libplatform.a \
|
||||
libc/liblibc.a \
|
||||
lua/liblua.a \
|
||||
mqtt/mqtt.a \
|
||||
smart/smart.a \
|
||||
wofs/wofs.a \
|
||||
spiffs/spiffs.a \
|
||||
|
@ -99,6 +99,8 @@ LINKFLAGS_eagle.app.v6 = \
|
|||
-lwpa \
|
||||
-lmain \
|
||||
-ljson \
|
||||
-lsmartconfig \
|
||||
-lssl \
|
||||
$(DEP_LIBS_eagle.app.v6) \
|
||||
-Wl,--end-group
|
||||
|
||||
|
|
|
@ -219,6 +219,45 @@ i2c_master_getAck(void)
|
|||
return retVal;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* FunctionName : i2c_master_checkAck
|
||||
* Description : get dev response
|
||||
* Parameters : NONE
|
||||
* Returns : true : get ack ; false : get nack
|
||||
*******************************************************************************/
|
||||
bool ICACHE_FLASH_ATTR
|
||||
i2c_master_checkAck(void)
|
||||
{
|
||||
if(i2c_master_getAck()){
|
||||
return FALSE;
|
||||
}else{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* FunctionName : i2c_master_send_ack
|
||||
* Description : response ack
|
||||
* Parameters : NONE
|
||||
* Returns : NONE
|
||||
*******************************************************************************/
|
||||
void ICACHE_FLASH_ATTR
|
||||
i2c_master_send_ack(void)
|
||||
{
|
||||
i2c_master_setAck(0x0);
|
||||
}
|
||||
/******************************************************************************
|
||||
* FunctionName : i2c_master_send_nack
|
||||
* Description : response nack
|
||||
* Parameters : NONE
|
||||
* Returns : NONE
|
||||
*******************************************************************************/
|
||||
void ICACHE_FLASH_ATTR
|
||||
i2c_master_send_nack(void)
|
||||
{
|
||||
i2c_master_setAck(0x1);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* FunctionName : i2c_master_readByte
|
||||
* Description : read Byte from i2c bus
|
||||
|
|
|
@ -349,11 +349,6 @@ pwm_init(uint16 freq, uint16 *duty)
|
|||
{
|
||||
uint8 i;
|
||||
|
||||
ETS_FRC_TIMER1_INTR_ATTACH(pwm_tim1_intr_handler, NULL);
|
||||
TM1_EDGE_INT_ENABLE();
|
||||
ETS_FRC1_INTR_ENABLE();
|
||||
|
||||
RTC_CLR_REG_MASK(FRC1_INT_ADDRESS, FRC1_INT_CLR_MASK);
|
||||
RTC_REG_WRITE(FRC1_CTRL_ADDRESS, //FRC2_AUTO_RELOAD|
|
||||
DIVDED_BY_16
|
||||
| FRC1_ENABLE_TIMER
|
||||
|
@ -377,6 +372,10 @@ pwm_init(uint16 freq, uint16 *duty)
|
|||
// pwm_set_freq_duty(freq, duty);
|
||||
|
||||
pwm_start();
|
||||
|
||||
ETS_FRC_TIMER1_INTR_ATTACH(pwm_tim1_intr_handler, NULL);
|
||||
TM1_EDGE_INT_ENABLE();
|
||||
ETS_FRC1_INTR_ENABLE();
|
||||
}
|
||||
|
||||
bool ICACHE_FLASH_ATTR
|
||||
|
|
|
@ -64,12 +64,11 @@ void spi_lcd_9bit_write(uint8 spi_no,uint8 high_bit,uint8 low_8bit)
|
|||
* Description : SPI master initial function for common byte units transmission
|
||||
* Parameters : uint8 spi_no - SPI module number, Only "SPI" and "HSPI" are valid
|
||||
*******************************************************************************/
|
||||
void spi_master_init(uint8 spi_no)
|
||||
void spi_master_init(uint8 spi_no, unsigned cpol, unsigned cpha, unsigned databits, uint32_t clock)
|
||||
{
|
||||
uint32 regvalue;
|
||||
|
||||
if(spi_no>1) return; //handle invalid input number
|
||||
|
||||
|
||||
if(spi_no==SPI){
|
||||
WRITE_PERI_REG(PERIPHS_IO_MUX, 0x005);
|
||||
|
@ -86,13 +85,33 @@ void spi_master_init(uint8 spi_no)
|
|||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, 2);//configure io to spi mode
|
||||
}
|
||||
|
||||
SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_CS_SETUP|SPI_CS_HOLD|SPI_USR_COMMAND|SPI_USR_MOSI);
|
||||
CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_FLASH_MODE);
|
||||
SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_CS_SETUP|SPI_CS_HOLD|SPI_DOUTDIN|SPI_USR_MOSI);
|
||||
|
||||
//set clock polarity
|
||||
// TODO: This doesn't work
|
||||
//if (cpol == 1) {
|
||||
// SET_PERI_REG_MASK(SPI_CTRL2(spi_no), (SPI_CK_OUT_HIGH_MODE<<SPI_CK_OUT_HIGH_MODE_S));
|
||||
//} else {
|
||||
// SET_PERI_REG_MASK(SPI_CTRL2(spi_no), (SPI_CK_OUT_LOW_MODE<<SPI_CK_OUT_LOW_MODE_S));
|
||||
//}
|
||||
//os_printf("SPI_CTRL2 is %08x\n",READ_PERI_REG(SPI_CTRL2(spi_no)));
|
||||
|
||||
//set clock phase
|
||||
if (cpha == 1) {
|
||||
SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_CK_OUT_EDGE|SPI_CK_I_EDGE);
|
||||
} else {
|
||||
CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_CK_OUT_EDGE|SPI_CK_I_EDGE);
|
||||
}
|
||||
|
||||
CLEAR_PERI_REG_MASK(SPI_USER(HSPI), SPI_FLASH_MODE|SPI_WR_BYTE_ORDER|SPI_USR_MISO|
|
||||
SPI_RD_BYTE_ORDER|SPI_USR_ADDR|SPI_USR_COMMAND|SPI_USR_DUMMY);
|
||||
|
||||
//clear Daul or Quad lines transmission mode
|
||||
CLEAR_PERI_REG_MASK(SPI_CTRL(spi_no), SPI_QIO_MODE|SPI_DIO_MODE|SPI_DOUT_MODE|SPI_QOUT_MODE);
|
||||
|
||||
// SPI clock=CPU clock/8
|
||||
WRITE_PERI_REG(SPI_CLOCK(spi_no),
|
||||
((1&SPI_CLKDIV_PRE)<<SPI_CLKDIV_PRE_S)|
|
||||
((3&SPI_CLKCNT_N)<<SPI_CLKCNT_N_S)|
|
||||
((1&SPI_CLKCNT_H)<<SPI_CLKCNT_H_S)|
|
||||
((3&SPI_CLKCNT_L)<<SPI_CLKCNT_L_S)); //clear bit 31,set SPI clock div
|
||||
|
@ -109,21 +128,19 @@ void spi_master_init(uint8 spi_no)
|
|||
* Parameters : uint8 spi_no - SPI module number, Only "SPI" and "HSPI" are valid
|
||||
* uint8 data- transmitted data
|
||||
*******************************************************************************/
|
||||
void spi_mast_byte_write(uint8 spi_no,uint8 data)
|
||||
{
|
||||
uint32 regvalue;
|
||||
void spi_mast_byte_write(uint8 spi_no, uint8 *data)
|
||||
{
|
||||
if(spi_no>1) return; //handle invalid input number
|
||||
|
||||
if(spi_no>1) return; //handle invalid input number
|
||||
while(READ_PERI_REG(SPI_CMD(spi_no))&SPI_USR);
|
||||
|
||||
while(READ_PERI_REG(SPI_CMD(spi_no))&SPI_USR);
|
||||
CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_USR_MOSI|SPI_USR_MISO);
|
||||
WRITE_PERI_REG(SPI_W0(HSPI), *data);
|
||||
|
||||
//SPI_FLASH_USER2 bit28-31 is cmd length,cmd bit length is value(0-15)+1,
|
||||
// bit15-0 is cmd value.
|
||||
WRITE_PERI_REG(SPI_USER2(spi_no),
|
||||
((7&SPI_USR_COMMAND_BITLEN)<<SPI_USR_COMMAND_BITLEN_S)|((uint32)data));
|
||||
SET_PERI_REG_MASK(SPI_CMD(spi_no), SPI_USR);
|
||||
}
|
||||
SET_PERI_REG_MASK(SPI_CMD(spi_no), SPI_USR);
|
||||
while(READ_PERI_REG(SPI_CMD(spi_no))&SPI_USR);
|
||||
|
||||
*data = (uint8)(READ_PERI_REG(SPI_W0(spi_no))&0xff);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* FunctionName : spi_byte_write_espslave
|
||||
|
|
|
@ -63,6 +63,11 @@ void i2c_master_setAck(uint8 level);
|
|||
uint8 i2c_master_getAck(void);
|
||||
uint8 i2c_master_readByte(void);
|
||||
void i2c_master_writeByte(uint8 wrdata);
|
||||
|
||||
bool i2c_master_checkAck(void);
|
||||
void i2c_master_send_ack(void);
|
||||
void i2c_master_send_nack(void);
|
||||
|
||||
uint8 i2c_master_get_pinSDA();
|
||||
uint8 i2c_master_get_pinSCL();
|
||||
|
||||
|
|
|
@ -18,9 +18,9 @@ void spi_lcd_mode_init(uint8 spi_no);
|
|||
void spi_lcd_9bit_write(uint8 spi_no,uint8 high_bit,uint8 low_8bit);
|
||||
|
||||
//spi master init funtion
|
||||
void spi_master_init(uint8 spi_no);
|
||||
void spi_master_init(uint8 spi_no, unsigned cpol, unsigned cpha, unsigned databits, uint32_t clock);
|
||||
//use spi send 8bit data
|
||||
void spi_mast_byte_write(uint8 spi_no,uint8 data);
|
||||
void spi_mast_byte_write(uint8 spi_no,uint8 *data);
|
||||
|
||||
//transmit data to esp8266 slave buffer,which needs 16bit transmission ,
|
||||
//first byte is master command 0x04, second byte is master data
|
||||
|
|
|
@ -39,6 +39,11 @@
|
|||
#define SPI_MISO_DELAY_NUM_S 18
|
||||
#define SPI_MISO_DELAY_MODE 0x00000003
|
||||
#define SPI_MISO_DELAY_MODE_S 16
|
||||
#define SPI_CK_OUT_HIGH_MODE 0x0000000F
|
||||
#define SPI_CK_OUT_HIGH_MODE_S 12
|
||||
#define SPI_CK_OUT_LOW_MODE 0x0000000F
|
||||
#define SPI_CK_OUT_LOW_MODE_S 8
|
||||
|
||||
#define SPI_CLOCK(i) (REG_SPI_BASE(i) + 0x18)
|
||||
#define SPI_CLK_EQU_SYSCLK (BIT(31))
|
||||
#define SPI_CLKDIV_PRE 0x00001FFF
|
||||
|
@ -73,6 +78,7 @@
|
|||
#define SPI_CS_SETUP (BIT(5))
|
||||
#define SPI_CS_HOLD (BIT(4))
|
||||
#define SPI_FLASH_MODE (BIT(2))
|
||||
#define SPI_DOUTDIN (BIT(0))
|
||||
|
||||
#define SPI_USER1(i) (REG_SPI_BASE(i) + 0x20)
|
||||
#define SPI_USR_ADDR_BITLEN 0x0000003F
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#define NODE_VERSION_INTERNAL 0U
|
||||
|
||||
#define NODE_VERSION "NodeMCU 0.9.5"
|
||||
#define BUILD_DATE "build 20150108"
|
||||
#define BUILD_DATE "build 20150127"
|
||||
|
||||
// #define FLASH_512K
|
||||
// #define FLASH_1M
|
||||
|
@ -18,6 +18,9 @@
|
|||
#define FULL_VERSION_FOR_USER
|
||||
|
||||
#ifdef DEVELOP_VERSION
|
||||
|
||||
#define USE_OPTIMIZE_PRINTF
|
||||
|
||||
#define NODE_DEBUG
|
||||
#endif /* DEVELOP_VERSION */
|
||||
|
||||
|
@ -38,7 +41,7 @@
|
|||
#define ICACHE_STORE_TYPEDEF_ATTR __attribute__((aligned(4),packed))
|
||||
#define ICACHE_STORE_ATTR __attribute__((aligned(4)))
|
||||
#define ICACHE_RAM_ATTR __attribute__((section(".iram0.text")))
|
||||
#define ICACHE_RODATA_ATTR __attribute__((section(".rodata2.text")))
|
||||
// #define ICACHE_RODATA_ATTR __attribute__((section(".rodata2.text")))
|
||||
|
||||
#define CLIENT_SSL_ENABLE
|
||||
#define GPIO_INTERRUPT_ENABLE
|
||||
|
@ -55,14 +58,19 @@
|
|||
#define LUA_USE_MODULES_NET
|
||||
#define LUA_USE_MODULES_PWM
|
||||
#define LUA_USE_MODULES_I2C
|
||||
#define LUA_USE_MODULES_SPI
|
||||
#define LUA_USE_MODULES_TMR
|
||||
#define LUA_USE_MODULES_ADC
|
||||
#define LUA_USE_MODULES_UART
|
||||
#define LUA_USE_MODULES_OW
|
||||
#define LUA_USE_MODULES_BIT
|
||||
#define LUA_USE_MODULES_MQTT
|
||||
#endif /* LUA_USE_MODULES */
|
||||
|
||||
#define LUA_NUMBER_INTEGRAL
|
||||
// #define LUA_NUMBER_INTEGRAL
|
||||
#ifndef LUA_NUMBER_INTEGRAL
|
||||
#define PRINTF_LONG_SUPPORT
|
||||
#endif
|
||||
|
||||
#define LUA_OPTRAM
|
||||
#ifdef LUA_OPTRAM
|
||||
|
|
|
@ -1,37 +1,172 @@
|
|||
#include "c_math.h"
|
||||
#include "c_types.h"
|
||||
|
||||
double floor(double x)
|
||||
{
|
||||
return (double) (x < 0.f ? (((int) x) - 1) : ((int) x));
|
||||
}
|
||||
|
||||
double pow(double x, double y)
|
||||
{
|
||||
#define MAXEXP 2031 /* (MAX_EXP * 16) - 1 */
|
||||
#define MINEXP -2047 /* (MIN_EXP * 16) - 1 */
|
||||
#define HUGE MAXFLOAT
|
||||
double a1[] =
|
||||
{
|
||||
1.0,
|
||||
0.95760328069857365,
|
||||
0.91700404320467123,
|
||||
0.87812608018664974,
|
||||
0.84089641525371454,
|
||||
0.80524516597462716,
|
||||
0.77110541270397041,
|
||||
0.73841307296974966,
|
||||
0.70710678118654752,
|
||||
0.67712777346844637,
|
||||
0.64841977732550483,
|
||||
0.62092890603674203,
|
||||
0.59460355750136054,
|
||||
0.56939431737834583,
|
||||
0.54525386633262883,
|
||||
0.52213689121370692,
|
||||
0.50000000000000000
|
||||
};
|
||||
double a2[] =
|
||||
{
|
||||
0.24114209503420288E-17,
|
||||
0.92291566937243079E-18,
|
||||
-0.15241915231122319E-17,
|
||||
-0.35421849765286817E-17,
|
||||
-0.31286215245415074E-17,
|
||||
-0.44654376565694490E-17,
|
||||
0.29306999570789681E-17,
|
||||
0.11260851040933474E-17
|
||||
};
|
||||
double p1 = 0.833333333333332114e-1;
|
||||
double p2 = 0.125000000005037992e-1;
|
||||
double p3 = 0.223214212859242590e-2;
|
||||
double p4 = 0.434457756721631196e-3;
|
||||
double q1 = 0.693147180559945296e0;
|
||||
double q2 = 0.240226506959095371e0;
|
||||
double q3 = 0.555041086640855953e-1;
|
||||
double q4 = 0.961812905951724170e-2;
|
||||
double q5 = 0.133335413135857847e-2;
|
||||
double q6 = 0.154002904409897646e-3;
|
||||
double q7 = 0.149288526805956082e-4;
|
||||
double k = 0.442695040888963407;
|
||||
|
||||
double frexp(), g, ldexp(), r, u1, u2, v, w, w1, w2, y1, y2, z;
|
||||
int iw1, m, p;
|
||||
|
||||
if (y == 0.0)
|
||||
return (1.0);
|
||||
if (x <= 0.0)
|
||||
{
|
||||
if (x == 0.0)
|
||||
{
|
||||
if (y > 0.0)
|
||||
return (x);
|
||||
//cmemsg(FP_POWO, &y);
|
||||
//return(HUGE);
|
||||
}
|
||||
else
|
||||
{
|
||||
//cmemsg(FP_POWN, &x);
|
||||
x = -x;
|
||||
}
|
||||
}
|
||||
g = frexp(x, &m);
|
||||
p = 0;
|
||||
if (g <= a1[8])
|
||||
p = 8;
|
||||
if (g <= a1[p + 4])
|
||||
p += 4;
|
||||
if (g <= a1[p + 2])
|
||||
p += 2;
|
||||
p++;
|
||||
z = ((g - a1[p]) - a2[p / 2]) / (g + a1[p]);
|
||||
z += z;
|
||||
v = z * z;
|
||||
r = (((p4 * v + p3) * v + p2) * v + p1) * v * z;
|
||||
r += k * r;
|
||||
u2 = (r + z * k) + z;
|
||||
u1 = 0.0625 * (double)(16 * m - p);
|
||||
y1 = 0.0625 * (double)((int)(16.0 * y));
|
||||
y2 = y - y1;
|
||||
w = u2 * y + u1 * y2;
|
||||
w1 = 0.0625 * (double)((int)(16.0 * w));
|
||||
w2 = w - w1;
|
||||
w = w1 + u1 * y1;
|
||||
w1 = 0.0625 * (double)((int)(16.0 * w));
|
||||
w2 += (w - w1);
|
||||
w = 0.0625 * (double)((int)(16.0 * w2));
|
||||
iw1 = 16.0 * (w1 + w);
|
||||
w2 -= w;
|
||||
while (w2 > 0.0)
|
||||
{
|
||||
iw1++;
|
||||
w2 -= 0.0625;
|
||||
}
|
||||
if (iw1 > MAXEXP)
|
||||
{
|
||||
//cmemsg(FP_POWO, &y);
|
||||
return (HUGE);
|
||||
}
|
||||
if (iw1 < MINEXP)
|
||||
{
|
||||
//cmemsg(FP_POWU, &y);
|
||||
return (0.0);
|
||||
}
|
||||
m = iw1 / 16;
|
||||
if (iw1 >= 0)
|
||||
m++;
|
||||
p = 16 * m - iw1;
|
||||
z = ((((((q7 * w2 + q6) * w2 + q5) * w2 + q4) * w2 + q3) * w2 + q2) * w2 + q1) * w2;
|
||||
z = a1[p] + a1[p] * z;
|
||||
return (ldexp(z, m));
|
||||
}
|
||||
|
||||
#if 0
|
||||
#ifndef __math_68881
|
||||
double atan(double x){
|
||||
return x;
|
||||
double atan(double x)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
double cos(double x){
|
||||
return x;
|
||||
double cos(double x)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
double sin(double x){
|
||||
return x;
|
||||
double sin(double x)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
double tan(double x){
|
||||
return x;
|
||||
double tan(double x)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
double tanh(double x){
|
||||
return x;
|
||||
double tanh(double x)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
double frexp(double x, int *y){
|
||||
return x;
|
||||
double frexp(double x, int *y)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
double modf(double x, double *y){
|
||||
return x;
|
||||
double modf(double x, double *y)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
double ceil(double x){
|
||||
return x;
|
||||
double ceil(double x)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
double fabs(double x){
|
||||
return x;
|
||||
double fabs(double x)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
double floor(double x){
|
||||
return x;
|
||||
double floor(double x)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
#endif /* ! defined (__math_68881) */
|
||||
|
||||
|
@ -39,41 +174,53 @@ double floor(double x){
|
|||
|
||||
#ifndef _REENT_ONLY
|
||||
#ifndef __math_68881
|
||||
double acos(double x){
|
||||
return x;
|
||||
double acos(double x)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
double asin(double x){
|
||||
return x;
|
||||
double asin(double x)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
double atan2(double x, double y){
|
||||
return x;
|
||||
double atan2(double x, double y)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
double cosh(double x){
|
||||
return x;
|
||||
double cosh(double x)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
double sinh(double x){
|
||||
return x;
|
||||
double sinh(double x)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
double exp(double x){
|
||||
return x;
|
||||
double exp(double x)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
double ldexp(double x, int y){
|
||||
return x;
|
||||
double ldexp(double x, int y)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
double log(double x){
|
||||
return x;
|
||||
double log(double x)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
double log10(double x){
|
||||
return x;
|
||||
double log10(double x)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
double pow(double x, double y){
|
||||
return x;
|
||||
double pow(double x, double y)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
double sqrt(double x){
|
||||
return x;
|
||||
double sqrt(double x)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
double fmod(double x, double y){
|
||||
return x;
|
||||
double fmod(double x, double y)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
#endif /* ! defined (__math_68881) */
|
||||
#endif /* ! defined (_REENT_ONLY) */
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
#ifndef _C_MATH_H_
|
||||
#define _C_MATH_H_
|
||||
#include <math.h>
|
||||
|
||||
double floor(double);
|
||||
double pow(double, double);
|
||||
|
||||
#if 0
|
||||
#ifndef HUGE_VAL
|
||||
#define HUGE_VAL (1.0e99)
|
||||
|
|
|
@ -12,44 +12,469 @@ int c_stderr = 1001;
|
|||
// FILE *c_tmpfile(void){
|
||||
// }
|
||||
|
||||
// int c_putchar(int c){
|
||||
// int c_putchar(int c){
|
||||
// }
|
||||
|
||||
// int c_printf(const char *c, ...){
|
||||
// int c_printf(const char *c, ...){
|
||||
// }
|
||||
|
||||
// int c_sprintf(char *c, const char *s, ...){
|
||||
// }
|
||||
|
||||
// int c_fprintf(FILE *f, const char *s, ...){
|
||||
// int c_fprintf(FILE *f, const char *s, ...){
|
||||
// }
|
||||
// int c_fscanf(FILE *f, const char *s, ...){
|
||||
// int c_fscanf(FILE *f, const char *s, ...){
|
||||
// }
|
||||
// int c_fclose(FILE *f){
|
||||
// int c_fclose(FILE *f){
|
||||
// }
|
||||
// int c_fflush(FILE *f){
|
||||
// int c_fflush(FILE *f){
|
||||
// }
|
||||
// int c_setvbuf(FILE *f, char *c, int d, size_t t){
|
||||
// int c_setvbuf(FILE *f, char *c, int d, size_t t){
|
||||
// }
|
||||
// void c_clearerr(FILE *f){
|
||||
// }
|
||||
// int c_fseek(FILE *f, long l, int d){
|
||||
// int c_fseek(FILE *f, long l, int d){
|
||||
// }
|
||||
// long c_ftell( FILE *f){
|
||||
// }
|
||||
// int c_fputs(const char *c, FILE *f){
|
||||
// int c_fputs(const char *c, FILE *f){
|
||||
// }
|
||||
// char *c_fgets(char *c, int d, FILE *f){
|
||||
// }
|
||||
// int c_ungetc(int d, FILE *f){
|
||||
// int c_ungetc(int d, FILE *f){
|
||||
// }
|
||||
// size_t c_fread(void *p, size_t _size, size_t _n, FILE *f){
|
||||
// }
|
||||
// size_t c_fwrite(const void *p, size_t _size, size_t _n, FILE *f){
|
||||
// }
|
||||
// int c_feof(FILE *f){
|
||||
// int c_feof(FILE *f){
|
||||
// }
|
||||
// int c_ferror(FILE *f){
|
||||
// int c_ferror(FILE *f){
|
||||
// }
|
||||
// int c_getc(FILE *f){
|
||||
// int c_getc(FILE *f){
|
||||
// }
|
||||
|
||||
#if defined( LUA_NUMBER_INTEGRAL )
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
File: printf.c
|
||||
|
||||
Copyright (c) 2004,2012 Kustaa Nyholm / SpareTimeLabs
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
Neither the name of the Kustaa Nyholm or SpareTimeLabs nor the names of its
|
||||
contributors may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
OF SUCH DAMAGE.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
This library is realy just two files: 'printf.h' and 'printf.c'.
|
||||
|
||||
They provide a simple and small (+200 loc) printf functionality to
|
||||
be used in embedded systems.
|
||||
|
||||
I've found them so usefull in debugging that I do not bother with a
|
||||
debugger at all.
|
||||
|
||||
They are distributed in source form, so to use them, just compile them
|
||||
into your project.
|
||||
|
||||
Two printf variants are provided: printf and sprintf.
|
||||
|
||||
The formats supported by this implementation are: 'd' 'u' 'c' 's' 'x' 'X'.
|
||||
|
||||
Zero padding and field width are also supported.
|
||||
|
||||
If the library is compiled with 'PRINTF_SUPPORT_LONG' defined then the
|
||||
long specifier is also
|
||||
supported. Note that this will pull in some long math routines (pun intended!)
|
||||
and thus make your executable noticably longer.
|
||||
|
||||
The memory foot print of course depends on the target cpu, compiler and
|
||||
compiler options, but a rough guestimate (based on a H8S target) is about
|
||||
1.4 kB for code and some twenty 'int's and 'char's, say 60 bytes of stack space.
|
||||
Not too bad. Your milage may vary. By hacking the source code you can
|
||||
get rid of some hunred bytes, I'm sure, but personally I feel the balance of
|
||||
functionality and flexibility versus code size is close to optimal for
|
||||
many embedded systems.
|
||||
|
||||
To use the printf you need to supply your own character output function,
|
||||
something like :
|
||||
|
||||
void putc ( void* p, char c)
|
||||
{
|
||||
while (!SERIAL_PORT_EMPTY) ;
|
||||
SERIAL_PORT_TX_REGISTER = c;
|
||||
}
|
||||
|
||||
Before you can call printf you need to initialize it to use your
|
||||
character output function with something like:
|
||||
|
||||
init_printf(NULL,putc);
|
||||
|
||||
Notice the 'NULL' in 'init_printf' and the parameter 'void* p' in 'putc',
|
||||
the NULL (or any pointer) you pass into the 'init_printf' will eventually be
|
||||
passed to your 'putc' routine. This allows you to pass some storage space (or
|
||||
anything realy) to the character output function, if necessary.
|
||||
This is not often needed but it was implemented like that because it made
|
||||
implementing the sprintf function so neat (look at the source code).
|
||||
|
||||
The code is re-entrant, except for the 'init_printf' function, so it
|
||||
is safe to call it from interupts too, although this may result in mixed output.
|
||||
If you rely on re-entrancy, take care that your 'putc' function is re-entrant!
|
||||
|
||||
The printf and sprintf functions are actually macros that translate to
|
||||
'tfp_printf' and 'tfp_sprintf'. This makes it possible
|
||||
to use them along with 'stdio.h' printf's in a single source file.
|
||||
You just need to undef the names before you include the 'stdio.h'.
|
||||
Note that these are not function like macros, so if you have variables
|
||||
or struct members with these names, things will explode in your face.
|
||||
Without variadic macros this is the best we can do to wrap these
|
||||
fucnction. If it is a problem just give up the macros and use the
|
||||
functions directly or rename them.
|
||||
|
||||
For further details see source code.
|
||||
|
||||
regs Kusti, 23.10.2004
|
||||
*/
|
||||
|
||||
/*
|
||||
Add lightweight %g support by vowstar, <vowstar@gmail.com>
|
||||
NodeMCU Team, 26.1.2015
|
||||
*/
|
||||
|
||||
typedef void (*putcf) (void *, char);
|
||||
|
||||
#ifdef PRINTF_LONG_SUPPORT
|
||||
|
||||
static int uli2a(unsigned long int num, unsigned int base, int uc, char *bf)
|
||||
{
|
||||
int n = 0;
|
||||
unsigned long int d = 1;
|
||||
int len = 1;
|
||||
while (num / d >= base)
|
||||
{
|
||||
d *= base;
|
||||
len ++;
|
||||
}
|
||||
while (d != 0)
|
||||
{
|
||||
int dgt = num / d;
|
||||
num %= d;
|
||||
d /= base;
|
||||
if (n || dgt > 0 || d == 0)
|
||||
{
|
||||
*bf++ = dgt + (dgt < 10 ? '0' : (uc ? 'A' : 'a') - 10);
|
||||
++n;
|
||||
}
|
||||
}
|
||||
*bf = 0;
|
||||
return len;
|
||||
}
|
||||
|
||||
static int li2a (long num, char *bf)
|
||||
{
|
||||
int len = 0;
|
||||
if (num < 0)
|
||||
{
|
||||
num = -num;
|
||||
*bf++ = '-';
|
||||
len ++;
|
||||
}
|
||||
len += uli2a(num, 10, 0, bf);
|
||||
return len;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static int ui2a(unsigned int num, unsigned int base, int uc, char *bf)
|
||||
{
|
||||
int n = 0;
|
||||
unsigned int d = 1;
|
||||
int len = 1;
|
||||
while (num / d >= base)
|
||||
{
|
||||
d *= base;
|
||||
len ++;
|
||||
}
|
||||
while (d != 0)
|
||||
{
|
||||
int dgt = num / d;
|
||||
num %= d;
|
||||
d /= base;
|
||||
if (n || dgt > 0 || d == 0)
|
||||
{
|
||||
*bf++ = dgt + (dgt < 10 ? '0' : (uc ? 'A' : 'a') - 10);
|
||||
++n;
|
||||
}
|
||||
}
|
||||
*bf = 0;
|
||||
return len;
|
||||
}
|
||||
|
||||
static int i2a (int num, char *bf)
|
||||
{
|
||||
int len = 0;
|
||||
if (num < 0)
|
||||
{
|
||||
num = -num;
|
||||
*bf++ = '-';
|
||||
len ++;
|
||||
}
|
||||
len += ui2a(num, 10, 0, bf);
|
||||
return len;
|
||||
}
|
||||
|
||||
// Converts a floating point number to string.
|
||||
static int d2a(double num, char *bf)
|
||||
{
|
||||
int len = 0;
|
||||
double ipart = 0;
|
||||
double fpart = 0;
|
||||
double absnum = num;
|
||||
|
||||
// Add sign
|
||||
if (absnum < 0)
|
||||
{
|
||||
absnum = -absnum;
|
||||
*bf++ = '-';
|
||||
// len must add 1 when return
|
||||
// but can't add at here
|
||||
}
|
||||
|
||||
// Extract integer part
|
||||
ipart = (int)absnum;
|
||||
|
||||
// Extract floating part
|
||||
fpart = absnum - (double)ipart;
|
||||
|
||||
// convert integer part to string
|
||||
#ifdef PRINTF_LONG_SUPPORT
|
||||
len += li2a(ipart, bf);
|
||||
#else
|
||||
len += i2a(ipart, bf);
|
||||
#endif
|
||||
|
||||
#ifndef EPSILON
|
||||
#define EPSILON ((double)(0.00000001))
|
||||
#endif
|
||||
if (fpart < EPSILON)
|
||||
{
|
||||
// fpart is zero
|
||||
}
|
||||
else
|
||||
{
|
||||
bf += len;
|
||||
// add dot
|
||||
*bf ++ = '.';
|
||||
len += 1;
|
||||
// add zero after dot
|
||||
while (fpart < 0.1)
|
||||
{
|
||||
fpart *= 10;
|
||||
*bf ++ = '0';
|
||||
len += 1;
|
||||
}
|
||||
while ((fpart < (double)1.0 / EPSILON) && ((fpart - (int)fpart) > EPSILON))
|
||||
{
|
||||
fpart = fpart * 10;
|
||||
}
|
||||
#ifdef PRINTF_LONG_SUPPORT
|
||||
len += li2a((int)fpart, bf);
|
||||
#else
|
||||
len += i2a((int)fpart, bf);
|
||||
#endif
|
||||
}
|
||||
#undef EPSILON
|
||||
if (num < 0)
|
||||
{
|
||||
len ++;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
static int a2d(char ch)
|
||||
{
|
||||
if (ch >= '0' && ch <= '9')
|
||||
return ch - '0';
|
||||
else if (ch >= 'a' && ch <= 'f')
|
||||
return ch - 'a' + 10;
|
||||
else if (ch >= 'A' && ch <= 'F')
|
||||
return ch - 'A' + 10;
|
||||
else return -1;
|
||||
}
|
||||
|
||||
static char a2i(char ch, char **src, int base, int *nump)
|
||||
{
|
||||
char *p = *src;
|
||||
int num = 0;
|
||||
int digit;
|
||||
while ((digit = a2d(ch)) >= 0)
|
||||
{
|
||||
if (digit > base) break;
|
||||
num = num * base + digit;
|
||||
ch = *p++;
|
||||
}
|
||||
*src = p;
|
||||
*nump = num;
|
||||
return ch;
|
||||
}
|
||||
|
||||
static void putchw(void *putp, putcf putf, int n, char z, char *bf)
|
||||
{
|
||||
char fc = z ? '0' : ' ';
|
||||
char ch;
|
||||
char *p = bf;
|
||||
while (*p++ && n > 0)
|
||||
n--;
|
||||
while (n-- > 0)
|
||||
putf(putp, fc);
|
||||
while ((ch = *bf++))
|
||||
putf(putp, ch);
|
||||
}
|
||||
|
||||
void c_format(void *putp, putcf putf, char *fmt, va_list va)
|
||||
{
|
||||
char bf[12];
|
||||
|
||||
char ch;
|
||||
|
||||
|
||||
while ((ch = *(fmt++)))
|
||||
{
|
||||
if (ch != '%')
|
||||
putf(putp, ch);
|
||||
else
|
||||
{
|
||||
char lz = 0;
|
||||
#ifdef PRINTF_LONG_SUPPORT
|
||||
char lng = 0;
|
||||
#endif
|
||||
int w = 0;
|
||||
ch = *(fmt++);
|
||||
if (ch == '0')
|
||||
{
|
||||
ch = *(fmt++);
|
||||
lz = 1;
|
||||
}
|
||||
if (ch >= '0' && ch <= '9')
|
||||
{
|
||||
ch = a2i(ch, &fmt, 10, &w);
|
||||
}
|
||||
#ifdef PRINTF_LONG_SUPPORT
|
||||
if (ch == 'l')
|
||||
{
|
||||
ch = *(fmt++);
|
||||
lng = 1;
|
||||
}
|
||||
#endif
|
||||
switch (ch)
|
||||
{
|
||||
case 0:
|
||||
goto abort;
|
||||
case 'u' :
|
||||
{
|
||||
#ifdef PRINTF_LONG_SUPPORT
|
||||
if (lng)
|
||||
uli2a(va_arg(va, unsigned long int), 10, 0, bf);
|
||||
else
|
||||
#endif
|
||||
ui2a(va_arg(va, unsigned int), 10, 0, bf);
|
||||
putchw(putp, putf, w, lz, bf);
|
||||
break;
|
||||
}
|
||||
case 'o' :
|
||||
{
|
||||
#ifdef PRINTF_LONG_SUPPORT
|
||||
if (lng)
|
||||
uli2a(va_arg(va, unsigned long int), 8, 0, bf);
|
||||
else
|
||||
#endif
|
||||
ui2a(va_arg(va, unsigned int), 8, 0, bf);
|
||||
putchw(putp, putf, w, lz, bf);
|
||||
break;
|
||||
}
|
||||
case 'd' : case 'i':
|
||||
{
|
||||
#ifdef PRINTF_LONG_SUPPORT
|
||||
if (lng)
|
||||
li2a(va_arg(va, unsigned long int), bf);
|
||||
else
|
||||
#endif
|
||||
i2a(va_arg(va, int), bf);
|
||||
putchw(putp, putf, w, lz, bf);
|
||||
break;
|
||||
}
|
||||
case 'x': case 'X' :
|
||||
#ifdef PRINTF_LONG_SUPPORT
|
||||
if (lng)
|
||||
uli2a(va_arg(va, unsigned long int), 16, (ch == 'X'), bf);
|
||||
else
|
||||
#endif
|
||||
ui2a(va_arg(va, unsigned int), 16, (ch == 'X'), bf);
|
||||
putchw(putp, putf, w, lz, bf);
|
||||
break;
|
||||
case 'e': case 'E': case 'f':
|
||||
case 'g': case 'G':
|
||||
{
|
||||
d2a(va_arg(va, double), bf);
|
||||
putchw(putp, putf, w, lz, bf);
|
||||
break;
|
||||
}
|
||||
case 'c' :
|
||||
putf(putp, (char)(va_arg(va, int)));
|
||||
break;
|
||||
case 's' :
|
||||
putchw(putp, putf, w, 0, va_arg(va, char *));
|
||||
break;
|
||||
case '%' :
|
||||
putf(putp, ch);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
abort:;
|
||||
}
|
||||
|
||||
|
||||
static void putcp(void *p, char c)
|
||||
{
|
||||
*(*((char **)p))++ = c;
|
||||
}
|
||||
|
||||
|
||||
void c_sprintf(char *s, char *fmt, ...)
|
||||
{
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
c_format(&s, putcp, fmt, va);
|
||||
putcp(&s, 0);
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -47,12 +47,22 @@ extern int c_stderr;
|
|||
#define SEEK_END 2 /* set file offset to EOF plus offset */
|
||||
#endif
|
||||
|
||||
#define c_malloc os_malloc
|
||||
#define c_zalloc os_zalloc
|
||||
#define c_free os_free
|
||||
|
||||
extern void output_redirect(const char *str);
|
||||
#define c_puts output_redirect
|
||||
|
||||
// #define c_printf os_printf
|
||||
// int c_printf(const char *c, ...);
|
||||
#if defined( LUA_NUMBER_INTEGRAL )
|
||||
#define c_sprintf os_sprintf
|
||||
#else
|
||||
#include "c_stdarg.h"
|
||||
void c_sprintf(char* s,char *fmt, ...);
|
||||
#endif
|
||||
|
||||
// #define c_vsprintf ets_vsprintf
|
||||
#define c_printf(...) do { \
|
||||
unsigned char __print_buf[BUFSIZ]; \
|
||||
|
|
|
@ -20,27 +20,27 @@ const char *c_getenv(const char *__string){
|
|||
}
|
||||
|
||||
// make sure there is enough memory before real malloc, otherwise malloc will panic and reset
|
||||
void *c_malloc(size_t __size){
|
||||
if(__size>system_get_free_heap_size()){
|
||||
NODE_ERR("malloc: not enough memory\n");
|
||||
return NULL;
|
||||
}
|
||||
return (void *)os_malloc(__size);
|
||||
}
|
||||
// void *c_malloc(size_t __size){
|
||||
// if(__size>system_get_free_heap_size()){
|
||||
// NODE_ERR("malloc: not enough memory\n");
|
||||
// return NULL;
|
||||
// }
|
||||
// return (void *)os_malloc(__size);
|
||||
// }
|
||||
|
||||
void *c_zalloc(size_t __size){
|
||||
if(__size>system_get_free_heap_size()){
|
||||
NODE_ERR("zalloc: not enough memory\n");
|
||||
return NULL;
|
||||
}
|
||||
return (void *)os_zalloc(__size);
|
||||
}
|
||||
// void *c_zalloc(size_t __size){
|
||||
// if(__size>system_get_free_heap_size()){
|
||||
// NODE_ERR("zalloc: not enough memory\n");
|
||||
// return NULL;
|
||||
// }
|
||||
// return (void *)os_zalloc(__size);
|
||||
// }
|
||||
|
||||
void c_free(void *p){
|
||||
// NODE_ERR("free1: %d\n", system_get_free_heap_size());
|
||||
os_free(p);
|
||||
// NODE_ERR("-free1: %d\n", system_get_free_heap_size());
|
||||
}
|
||||
// void c_free(void *p){
|
||||
// // NODE_ERR("free1: %d\n", system_get_free_heap_size());
|
||||
// os_free(p);
|
||||
// // NODE_ERR("-free1: %d\n", system_get_free_heap_size());
|
||||
// }
|
||||
|
||||
|
||||
// int c_rand(void){
|
||||
|
@ -50,8 +50,207 @@ void c_free(void *p){
|
|||
|
||||
// int c_atoi(const char *__nptr){
|
||||
// }
|
||||
// double c_strtod(const char *__n, char **__end_PTR){
|
||||
// }
|
||||
#include <_ansi.h>
|
||||
//#include <reent.h>
|
||||
#include <string.h>
|
||||
//#include "mprec.h"
|
||||
|
||||
double c_strtod(const char *string, char **endPtr)
|
||||
{
|
||||
int maxExponent = 511; /* Largest possible base 10 exponent. Any
|
||||
* exponent larger than this will already
|
||||
* produce underflow or overflow, so there's
|
||||
* no need to worry about additional digits.
|
||||
*/
|
||||
double powersOf10[] = { /* Table giving binary powers of 10. Entry */
|
||||
10., /* is 10^2^i. Used to convert decimal */
|
||||
100., /* exponents into floating-point numbers. */
|
||||
1.0e4,
|
||||
1.0e8,
|
||||
1.0e16,
|
||||
1.0e32,
|
||||
1.0e64,
|
||||
1.0e128,
|
||||
1.0e256
|
||||
};
|
||||
int sign, expSign = FALSE;
|
||||
double fraction, dblExp, *d;
|
||||
register const char *p;
|
||||
register int c;
|
||||
int exp = 0; /* Exponent read from "EX" field. */
|
||||
int fracExp = 0; /* Exponent that derives from the fractional
|
||||
* part. Under normal circumstatnces, it is
|
||||
* the negative of the number of digits in F.
|
||||
* However, if I is very long, the last digits
|
||||
* of I get dropped (otherwise a long I with a
|
||||
* large negative exponent could cause an
|
||||
* unnecessary overflow on I alone). In this
|
||||
* case, fracExp is incremented one for each
|
||||
* dropped digit. */
|
||||
int mantSize; /* Number of digits in mantissa. */
|
||||
int decPt; /* Number of mantissa digits BEFORE decimal
|
||||
* point. */
|
||||
const char *pExp; /* Temporarily holds location of exponent
|
||||
* in string. */
|
||||
|
||||
/*
|
||||
* Strip off leading blanks and check for a sign.
|
||||
*/
|
||||
|
||||
p = string;
|
||||
while (isspace((unsigned char)(*p))) {
|
||||
p += 1;
|
||||
}
|
||||
if (*p == '-') {
|
||||
sign = TRUE;
|
||||
p += 1;
|
||||
} else {
|
||||
if (*p == '+') {
|
||||
p += 1;
|
||||
}
|
||||
sign = FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Count the number of digits in the mantissa (including the decimal
|
||||
* point), and also locate the decimal point.
|
||||
*/
|
||||
|
||||
decPt = -1;
|
||||
for (mantSize = 0; ; mantSize += 1)
|
||||
{
|
||||
c = *p;
|
||||
if (!isdigit(c)) {
|
||||
if ((c != '.') || (decPt >= 0)) {
|
||||
break;
|
||||
}
|
||||
decPt = mantSize;
|
||||
}
|
||||
p += 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now suck up the digits in the mantissa. Use two integers to
|
||||
* collect 9 digits each (this is faster than using floating-point).
|
||||
* If the mantissa has more than 18 digits, ignore the extras, since
|
||||
* they can't affect the value anyway.
|
||||
*/
|
||||
|
||||
pExp = p;
|
||||
p -= mantSize;
|
||||
if (decPt < 0) {
|
||||
decPt = mantSize;
|
||||
} else {
|
||||
mantSize -= 1; /* One of the digits was the point. */
|
||||
}
|
||||
if (mantSize > 18) {
|
||||
fracExp = decPt - 18;
|
||||
mantSize = 18;
|
||||
} else {
|
||||
fracExp = decPt - mantSize;
|
||||
}
|
||||
if (mantSize == 0) {
|
||||
fraction = 0.0;
|
||||
p = string;
|
||||
goto done;
|
||||
} else {
|
||||
int frac1, frac2;
|
||||
frac1 = 0;
|
||||
for ( ; mantSize > 9; mantSize -= 1)
|
||||
{
|
||||
c = *p;
|
||||
p += 1;
|
||||
if (c == '.') {
|
||||
c = *p;
|
||||
p += 1;
|
||||
}
|
||||
frac1 = 10*frac1 + (c - '0');
|
||||
}
|
||||
frac2 = 0;
|
||||
for (; mantSize > 0; mantSize -= 1)
|
||||
{
|
||||
c = *p;
|
||||
p += 1;
|
||||
if (c == '.') {
|
||||
c = *p;
|
||||
p += 1;
|
||||
}
|
||||
frac2 = 10*frac2 + (c - '0');
|
||||
}
|
||||
fraction = (1.0e9 * frac1) + frac2;
|
||||
}
|
||||
|
||||
/*
|
||||
* Skim off the exponent.
|
||||
*/
|
||||
|
||||
p = pExp;
|
||||
if ((*p == 'E') || (*p == 'e')) {
|
||||
p += 1;
|
||||
if (*p == '-') {
|
||||
expSign = TRUE;
|
||||
p += 1;
|
||||
} else {
|
||||
if (*p == '+') {
|
||||
p += 1;
|
||||
}
|
||||
expSign = FALSE;
|
||||
}
|
||||
if (!isdigit((unsigned char)(*p))) {
|
||||
p = pExp;
|
||||
goto done;
|
||||
}
|
||||
while (isdigit((unsigned char)(*p))) {
|
||||
exp = exp * 10 + (*p - '0');
|
||||
p += 1;
|
||||
}
|
||||
}
|
||||
if (expSign) {
|
||||
exp = fracExp - exp;
|
||||
} else {
|
||||
exp = fracExp + exp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate a floating-point number that represents the exponent.
|
||||
* Do this by processing the exponent one bit at a time to combine
|
||||
* many powers of 2 of 10. Then combine the exponent with the
|
||||
* fraction.
|
||||
*/
|
||||
|
||||
if (exp < 0) {
|
||||
expSign = TRUE;
|
||||
exp = -exp;
|
||||
} else {
|
||||
expSign = FALSE;
|
||||
}
|
||||
if (exp > maxExponent) {
|
||||
exp = maxExponent;
|
||||
// errno = ERANGE;
|
||||
}
|
||||
dblExp = 1.0;
|
||||
for (d = powersOf10; exp != 0; exp >>= 1, d += 1) {
|
||||
if (exp & 01) {
|
||||
dblExp *= *d;
|
||||
}
|
||||
}
|
||||
if (expSign) {
|
||||
fraction /= dblExp;
|
||||
} else {
|
||||
fraction *= dblExp;
|
||||
}
|
||||
|
||||
done:
|
||||
if (endPtr != NULL) {
|
||||
*endPtr = (char *) p;
|
||||
}
|
||||
|
||||
if (sign) {
|
||||
return -fraction;
|
||||
}
|
||||
return fraction;
|
||||
}
|
||||
|
||||
// long c_strtol(const char *__n, char **__end_PTR, int __base){
|
||||
// }
|
||||
// unsigned long c_strtoul(const char *__n, char **__end_PTR, int __base){
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
|
||||
#define c_abs abs
|
||||
#define c_atoi atoi
|
||||
// #define c_strtod strtod
|
||||
//#define c_strtod strtod
|
||||
#define c_strtol strtol
|
||||
#define c_strtoul strtoul
|
||||
|
||||
|
@ -55,7 +55,7 @@ void c_free(void *);
|
|||
// void c_srand(unsigned int __seed);
|
||||
|
||||
// int c_atoi(const char *__nptr);
|
||||
// double c_strtod(const char *__n, char **__end_PTR);
|
||||
double c_strtod(const char *__n, char **__end_PTR);
|
||||
// // long c_strtol(const char *__n, char **__end_PTR, int __base);
|
||||
// unsigned long c_strtoul(const char *__n, char **__end_PTR, int __base);
|
||||
// // long long c_strtoll(const char *__n, char **__end_PTR, int __base);
|
||||
|
|
|
@ -601,7 +601,8 @@ extern int readline4lua(const char *prompt, char *buffer, int length);
|
|||
#endif // #if !defined LUA_INTEGRAL_LONGLONG
|
||||
#else
|
||||
#define LUA_NUMBER_SCAN "%lf"
|
||||
#define LUA_NUMBER_FMT "%.14g"
|
||||
//#define LUA_NUMBER_FMT "%.14g"
|
||||
#define LUA_NUMBER_FMT "%g"
|
||||
#endif // #if defined LUA_NUMBER_INTEGRAL
|
||||
#define lua_number2str(s,n) c_sprintf((s), LUA_NUMBER_FMT, (n))
|
||||
#define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
#include "c_string.h"
|
||||
#include "c_types.h"
|
||||
|
||||
#define lundump_c
|
||||
#define LUA_CORE
|
||||
|
@ -141,13 +142,11 @@ static lua_Number LoadNumber(LoadState* S)
|
|||
LoadVar(S,y);
|
||||
x = (lua_Number)y;
|
||||
} break;
|
||||
#if 0
|
||||
case 8: {
|
||||
int64_t y;
|
||||
LoadVar(S,y);
|
||||
x = (lua_Number)y;
|
||||
} break;
|
||||
#endif
|
||||
default: lua_assert(0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "c_stdio.h"
|
||||
#include "c_stdlib.h"
|
||||
#include "c_string.h"
|
||||
#include "c_math.h"
|
||||
|
||||
#define lvm_c
|
||||
#define LUA_CORE
|
||||
|
|
|
@ -812,10 +812,6 @@ espconn_tcp_accept(void *arg, struct tcp_pcb *pcb, err_t err)
|
|||
remot_info *pinfo = NULL;
|
||||
LWIP_UNUSED_ARG(err);
|
||||
|
||||
if(4096>system_get_free_heap_size()){
|
||||
return ERR_MEM;
|
||||
}
|
||||
|
||||
paccept = (espconn_msg *)os_zalloc(sizeof(espconn_msg));
|
||||
tcp_arg(pcb, paccept);
|
||||
tcp_err(pcb, esponn_server_err);
|
||||
|
|
|
@ -39,6 +39,7 @@ endif
|
|||
INCLUDES := $(INCLUDES) -I $(PDIR)include
|
||||
INCLUDES += -I ./
|
||||
INCLUDES += -I ../libc
|
||||
INCLUDES += -I ../mqtt
|
||||
INCLUDES += -I ../lua
|
||||
INCLUDES += -I ../platform
|
||||
INCLUDES += -I ../wofs
|
||||
|
|
|
@ -61,6 +61,9 @@ LUALIB_API int ( luaopen_i2c )( lua_State *L );
|
|||
#define AUXLIB_WIFI "wifi"
|
||||
LUALIB_API int ( luaopen_wifi )( lua_State *L );
|
||||
|
||||
#define AUXLIB_MQTT "mqtt"
|
||||
LUALIB_API int ( luaopen_mqtt )( lua_State *L );
|
||||
|
||||
#define AUXLIB_NODE "node"
|
||||
LUALIB_API int ( luaopen_node )( lua_State *L );
|
||||
|
||||
|
|
|
@ -37,6 +37,14 @@
|
|||
#define ROM_MODULES_NET
|
||||
#endif
|
||||
|
||||
#if defined(LUA_USE_MODULES_MQTT)
|
||||
#define MODULES_MQTT "mqtt"
|
||||
#define ROM_MODULES_MQTT \
|
||||
_ROM(MODULES_MQTT, luaopen_mqtt, mqtt_map)
|
||||
#else
|
||||
#define ROM_MODULES_MQTT
|
||||
#endif
|
||||
|
||||
#if defined(LUA_USE_MODULES_I2C)
|
||||
#define MODULES_I2C "i2c"
|
||||
#define ROM_MODULES_I2C \
|
||||
|
@ -45,6 +53,14 @@
|
|||
#define ROM_MODULES_I2C
|
||||
#endif
|
||||
|
||||
#if defined(LUA_USE_MODULES_SPI)
|
||||
#define MODULES_SPI "spi"
|
||||
#define ROM_MODULES_SPI \
|
||||
_ROM(MODULES_SPI, luaopen_spi, spi_map)
|
||||
#else
|
||||
#define ROM_MODULES_SPI
|
||||
#endif
|
||||
|
||||
#if defined(LUA_USE_MODULES_TMR)
|
||||
#define MODULES_TMR "tmr"
|
||||
#define ROM_MODULES_TMR \
|
||||
|
@ -105,7 +121,9 @@
|
|||
ROM_MODULES_GPIO \
|
||||
ROM_MODULES_PWM \
|
||||
ROM_MODULES_WIFI \
|
||||
ROM_MODULES_MQTT \
|
||||
ROM_MODULES_I2C \
|
||||
ROM_MODULES_SPI \
|
||||
ROM_MODULES_TMR \
|
||||
ROM_MODULES_NODE \
|
||||
ROM_MODULES_FILE \
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -672,16 +672,20 @@ static int net_start( lua_State* L, const char* mt )
|
|||
{
|
||||
if(isserver)
|
||||
pesp_conn->proto.tcp->local_port = port;
|
||||
else
|
||||
else{
|
||||
pesp_conn->proto.tcp->remote_port = port;
|
||||
pesp_conn->proto.tcp->local_port = espconn_port();
|
||||
}
|
||||
NODE_DBG("TCP port is set: %d.\n", port);
|
||||
}
|
||||
else if (pesp_conn->type == ESPCONN_UDP)
|
||||
{
|
||||
if(isserver)
|
||||
pesp_conn->proto.udp->local_port = port;
|
||||
else
|
||||
else{
|
||||
pesp_conn->proto.udp->remote_port = port;
|
||||
pesp_conn->proto.udp->local_port = espconn_port();
|
||||
}
|
||||
NODE_DBG("UDP port is set: %d.\n", port);
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,8 @@
|
|||
#include "romfs.h"
|
||||
#include "c_string.h"
|
||||
#include "driver/uart.h"
|
||||
#include "spi_flash.h"
|
||||
//#include "spi_flash.h"
|
||||
#include "user_interface.h"
|
||||
#include "flash_api.h"
|
||||
|
||||
// Lua: restart()
|
||||
|
@ -21,18 +22,47 @@ static int node_restart( lua_State* L )
|
|||
return 0;
|
||||
}
|
||||
|
||||
// Lua: dsleep( us )
|
||||
// Lua: dsleep( us, option )
|
||||
static int node_deepsleep( lua_State* L )
|
||||
{
|
||||
s32 us;
|
||||
us = luaL_checkinteger( L, 1 );
|
||||
if ( us <= 0 )
|
||||
return luaL_error( L, "wrong arg range" );
|
||||
system_deep_sleep( us );
|
||||
s32 us, option;
|
||||
//us = luaL_checkinteger( L, 1 );
|
||||
// Set deleep option, skip if nil
|
||||
if ( lua_isnumber(L, 2) )
|
||||
{
|
||||
option = lua_tointeger(L, 2);
|
||||
if ( option < 0 || option > 4)
|
||||
return luaL_error( L, "wrong arg range" );
|
||||
else
|
||||
deep_sleep_set_option( option );
|
||||
}
|
||||
// Set deleep time, skip if nil
|
||||
if ( lua_isnumber(L, 1) )
|
||||
{
|
||||
us = lua_tointeger(L, 1);
|
||||
// if ( us <= 0 )
|
||||
if ( us < 0 )
|
||||
return luaL_error( L, "wrong arg range" );
|
||||
else
|
||||
system_deep_sleep( us );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Lua: dsleep_set_options
|
||||
// Combined to dsleep( us, option )
|
||||
// static int node_deepsleep_setoption( lua_State* L )
|
||||
// {
|
||||
// s32 option;
|
||||
// option = luaL_checkinteger( L, 1 );
|
||||
// if ( option < 0 || option > 4)
|
||||
// return luaL_error( L, "wrong arg range" );
|
||||
// else
|
||||
// deep_sleep_set_option( option );
|
||||
// return 0;
|
||||
// }
|
||||
// Lua: info()
|
||||
|
||||
static int node_info( lua_State* L )
|
||||
{
|
||||
lua_pushinteger(L, NODE_VERSION_MAJOR);
|
||||
|
@ -53,6 +83,13 @@ static int node_chipid( lua_State* L )
|
|||
lua_pushinteger(L, id);
|
||||
return 1;
|
||||
}
|
||||
// Lua: readvdd33()
|
||||
static int node_readvdd33( lua_State* L )
|
||||
{
|
||||
uint32_t vdd33 = readvdd33();
|
||||
lua_pushinteger(L, vdd33);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Lua: flashid()
|
||||
static int node_flashid( lua_State* L )
|
||||
|
@ -287,6 +324,9 @@ const LUA_REG_TYPE node_map[] =
|
|||
{ LSTRKEY( "led" ), LFUNCVAL( node_led ) },
|
||||
{ LSTRKEY( "input" ), LFUNCVAL( node_input ) },
|
||||
{ LSTRKEY( "output" ), LFUNCVAL( node_output ) },
|
||||
{ LSTRKEY( "readvdd33" ), LFUNCVAL( node_readvdd33) },
|
||||
// Combined to dsleep(us, option)
|
||||
// { LSTRKEY( "dsleepsetoption" ), LFUNCVAL( node_deepsleep_setoption) },
|
||||
#if LUA_OPTIMIZE_MEMORY > 0
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,166 @@
|
|||
// Module for interfacing with the SPI interface
|
||||
|
||||
//#include "lua.h"
|
||||
#include "lualib.h"
|
||||
#include "lauxlib.h"
|
||||
#include "platform.h"
|
||||
#include "auxmods.h"
|
||||
#include "lrotable.h"
|
||||
|
||||
// Lua: = spi.setup( id, mode, cpol, cpha, databits, clock )
|
||||
static int spi_setup( lua_State *L )
|
||||
{
|
||||
unsigned id = luaL_checkinteger( L, 1 );
|
||||
unsigned mode = luaL_checkinteger( L, 2 );
|
||||
unsigned cpol = luaL_checkinteger( L, 3 );
|
||||
unsigned cpha = luaL_checkinteger( L, 4 );
|
||||
unsigned databits = luaL_checkinteger( L, 5 );
|
||||
uint32_t clock = luaL_checkinteger( L, 6 );
|
||||
|
||||
MOD_CHECK_ID( spi, id );
|
||||
|
||||
if (mode != PLATFORM_SPI_SLAVE && mode != PLATFORM_SPI_MASTER) {
|
||||
return luaL_error( L, "wrong arg type" );
|
||||
}
|
||||
|
||||
if (cpol != PLATFORM_SPI_CPOL_LOW && cpol != PLATFORM_SPI_CPOL_HIGH) {
|
||||
return luaL_error( L, "wrong arg type" );
|
||||
}
|
||||
|
||||
if (cpha != PLATFORM_SPI_CPHA_LOW && cpha != PLATFORM_SPI_CPHA_HIGH) {
|
||||
return luaL_error( L, "wrong arg type" );
|
||||
}
|
||||
|
||||
if (databits != PLATFORM_SPI_DATABITS_8 && databits != PLATFORM_SPI_DATABITS_16) {
|
||||
return luaL_error( L, "wrong arg type" );
|
||||
}
|
||||
|
||||
u32 res = platform_spi_setup(id, mode, cpol, cpha, databits, clock);
|
||||
lua_pushinteger( L, res );
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Lua: wrote = spi.send( id, data1, [data2], ..., [datan] )
|
||||
// data can be either a string, a table or an 8-bit number
|
||||
static int spi_send( lua_State *L )
|
||||
{
|
||||
unsigned id = luaL_checkinteger( L, 1 );
|
||||
const char *pdata;
|
||||
size_t datalen, i;
|
||||
int numdata;
|
||||
u32 wrote = 0;
|
||||
unsigned argn;
|
||||
|
||||
MOD_CHECK_ID( spi, id );
|
||||
if( lua_gettop( L ) < 2 )
|
||||
return luaL_error( L, "wrong arg type" );
|
||||
|
||||
for( argn = 2; argn <= lua_gettop( L ); argn ++ )
|
||||
{
|
||||
// lua_isnumber() would silently convert a string of digits to an integer
|
||||
// whereas here strings are handled separately.
|
||||
if( lua_type( L, argn ) == LUA_TNUMBER )
|
||||
{
|
||||
numdata = ( int )luaL_checkinteger( L, argn );
|
||||
if( numdata < 0 || numdata > 255 )
|
||||
return luaL_error( L, "wrong arg range" );
|
||||
platform_spi_send_recv( id, numdata );
|
||||
wrote ++;
|
||||
}
|
||||
else if( lua_istable( L, argn ) )
|
||||
{
|
||||
datalen = lua_objlen( L, argn );
|
||||
for( i = 0; i < datalen; i ++ )
|
||||
{
|
||||
lua_rawgeti( L, argn, i + 1 );
|
||||
numdata = ( int )luaL_checkinteger( L, -1 );
|
||||
lua_pop( L, 1 );
|
||||
if( numdata < 0 || numdata > 255 )
|
||||
return luaL_error( L, "wrong arg range" );
|
||||
platform_spi_send_recv( id, numdata );
|
||||
}
|
||||
wrote += i;
|
||||
if( i < datalen )
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
pdata = luaL_checklstring( L, argn, &datalen );
|
||||
for( i = 0; i < datalen; i ++ )
|
||||
platform_spi_send_recv( id, pdata[ i ] );
|
||||
wrote += i;
|
||||
if( i < datalen )
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
lua_pushinteger( L, wrote );
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Lua: read = spi.recv( id, size )
|
||||
static int spi_recv( lua_State *L )
|
||||
{
|
||||
unsigned id = luaL_checkinteger( L, 1 );
|
||||
u32 size = ( u32 )luaL_checkinteger( L, 2 ), i;
|
||||
|
||||
luaL_Buffer b;
|
||||
spi_data_type data;
|
||||
|
||||
MOD_CHECK_ID( spi, id );
|
||||
if (size == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
luaL_buffinit( L, &b );
|
||||
for (i=0; i<size; i++) {
|
||||
data = platform_spi_send_recv(id, 0xFF);
|
||||
luaL_addchar( &b, ( char )data);
|
||||
}
|
||||
|
||||
luaL_pushresult( &b );
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Module function map
|
||||
#define MIN_OPT_LEVEL 2
|
||||
#include "lrodefs.h"
|
||||
const LUA_REG_TYPE spi_map[] =
|
||||
{
|
||||
{ LSTRKEY( "setup" ), LFUNCVAL( spi_setup ) },
|
||||
{ LSTRKEY( "send" ), LFUNCVAL( spi_send ) },
|
||||
{ LSTRKEY( "recv" ), LFUNCVAL( spi_recv ) },
|
||||
#if LUA_OPTIMIZE_MEMORY > 0
|
||||
{ LSTRKEY( "MASTER" ), LNUMVAL( PLATFORM_SPI_MASTER ) },
|
||||
{ LSTRKEY( "SLAVE" ), LNUMVAL( PLATFORM_SPI_SLAVE) },
|
||||
{ LSTRKEY( "CPHA_LOW" ), LNUMVAL( PLATFORM_SPI_CPHA_LOW) },
|
||||
{ LSTRKEY( "CPHA_HIGH" ), LNUMVAL( PLATFORM_SPI_CPHA_HIGH) },
|
||||
{ LSTRKEY( "CPOL_LOW" ), LNUMVAL( PLATFORM_SPI_CPOL_LOW) },
|
||||
{ LSTRKEY( "CPOL_HIGH" ), LNUMVAL( PLATFORM_SPI_CPOL_HIGH) },
|
||||
{ LSTRKEY( "DATABITS_8" ), LNUMVAL( PLATFORM_SPI_DATABITS_8) },
|
||||
{ LSTRKEY( "DATABITS_16" ), LNUMVAL( PLATFORM_SPI_DATABITS_16) },
|
||||
#endif // #if LUA_OPTIMIZE_MEMORY > 0
|
||||
{ LNILKEY, LNILVAL }
|
||||
};
|
||||
|
||||
LUALIB_API int luaopen_spi( lua_State *L )
|
||||
{
|
||||
#if LUA_OPTIMIZE_MEMORY > 0
|
||||
return 0;
|
||||
#else // #if LUA_OPTIMIZE_MEMORY > 0
|
||||
luaL_register( L, AUXLIB_SPI, spi_map );
|
||||
|
||||
// Add constants
|
||||
MOD_REG_NUMBER( L, "MASTER", PLATFORM_SPI_MASTER);
|
||||
MOD_REG_NUMBER( L, "SLAVE", PLATFORM_SPI_SLAVE);
|
||||
MOD_REG_NUMBER( L, "CPHA_LOW" , PLATFORM_SPI_CPHA_LOW);
|
||||
MOD_REG_NUMBER( L, "CPHA_HIGH", PLATFORM_SPI_CPHA_HIGH);
|
||||
MOD_REG_NUMBER( L, "CPOL_LOW" , PLATFORM_SPI_CPOL_LOW);
|
||||
MOD_REG_NUMBER( L, "CPOL_HIGH", PLATFORM_SPI_CPOL_HIGH);
|
||||
MOD_REG_NUMBER( L, "DATABITS_8" , PLATFORM_SPI_DATABITS_8);
|
||||
MOD_REG_NUMBER( L, "DATABITS_16" , PLATFORM_SPI_DATABITS_16);
|
||||
|
||||
return 1;
|
||||
#endif // #if LUA_OPTIMIZE_MEMORY > 0
|
||||
}
|
||||
|
|
@ -147,14 +147,26 @@ static int tmr_wdclr( lua_State* L )
|
|||
return 0;
|
||||
}
|
||||
|
||||
// Lua: time() , return rtc time in us
|
||||
static os_timer_t rtc_timer_updator;
|
||||
static uint64_t cur_count = 0;
|
||||
static uint64_t rtc_us = 0;
|
||||
void rtc_timer_update_cb(void *arg){
|
||||
uint64_t t = (uint64_t)system_get_rtc_time();
|
||||
uint64_t delta = (t>=cur_count)?(t - cur_count):(0x100000000 + t - cur_count);
|
||||
// NODE_ERR("%x\n",t);
|
||||
cur_count = t;
|
||||
unsigned c = system_rtc_clock_cali_proc();
|
||||
uint64_t itg = c >> 12;
|
||||
uint64_t dec = c & 0xFFF;
|
||||
rtc_us += (delta*itg + ((delta*dec)>>12));
|
||||
// TODO: store rtc_us to rtc memory.
|
||||
}
|
||||
// Lua: time() , return rtc time in second
|
||||
static int tmr_time( lua_State* L )
|
||||
{
|
||||
unsigned t = 0xFFFFFFFF & system_get_rtc_time();
|
||||
unsigned c = 0xFFFFFFFF & system_rtc_clock_cali_proc();
|
||||
lua_pushinteger( L, t );
|
||||
lua_pushinteger( L, c );
|
||||
return 2;
|
||||
uint64_t local = rtc_us;
|
||||
lua_pushinteger( L, ((uint32_t)(local/1000000)) & 0x7FFFFFFF );
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Module function map
|
||||
|
@ -182,6 +194,10 @@ LUALIB_API int luaopen_tmr( lua_State *L )
|
|||
os_timer_setfn(&(alarm_timer[i]), (os_timer_func_t *)(alarm_timer_cb[i]), L);
|
||||
}
|
||||
|
||||
os_timer_disarm(&rtc_timer_updator);
|
||||
os_timer_setfn(&rtc_timer_updator, (os_timer_func_t *)(rtc_timer_update_cb), NULL);
|
||||
os_timer_arm(&rtc_timer_updator, 500, 1);
|
||||
|
||||
#if LUA_OPTIMIZE_MEMORY > 0
|
||||
return 0;
|
||||
#else // #if LUA_OPTIMIZE_MEMORY > 0
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "c_types.h"
|
||||
#include "user_interface.h"
|
||||
#include "smart.h"
|
||||
#include "smartconfig.h"
|
||||
|
||||
static int wifi_smart_succeed = LUA_NOREF;
|
||||
|
||||
|
@ -19,6 +20,13 @@ static void wifi_smart_succeed_cb(void *arg){
|
|||
NODE_DBG("wifi_smart_succeed_cb is called.\n");
|
||||
if( !arg )
|
||||
return;
|
||||
#if 0
|
||||
struct station_config *sta_conf = arg;
|
||||
wifi_station_set_config(sta_conf);
|
||||
wifi_station_disconnect();
|
||||
wifi_station_connect();
|
||||
smartconfig_stop();
|
||||
#endif
|
||||
if(wifi_smart_succeed == LUA_NOREF)
|
||||
return;
|
||||
lua_State* L = (lua_State *)arg;
|
||||
|
@ -81,6 +89,7 @@ static void wifi_scan_done(void *arg, STATUS status)
|
|||
}
|
||||
|
||||
// Lua: smart(channel, function succeed_cb)
|
||||
// Lua: smart(type, function succeed_cb)
|
||||
static int wifi_start_smart( lua_State* L )
|
||||
{
|
||||
unsigned channel;
|
||||
|
@ -109,13 +118,15 @@ static int wifi_start_smart( lua_State* L )
|
|||
}else{
|
||||
smart_begin(channel, (smart_succeed )wifi_smart_succeed_cb, L);
|
||||
}
|
||||
// smartconfig_start(0, wifi_smart_succeed_cb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Lua: exit_smart(channel)
|
||||
// Lua: exit_smart()
|
||||
static int wifi_exit_smart( lua_State* L )
|
||||
{
|
||||
smart_end();
|
||||
// smartconfig_stop();
|
||||
if(wifi_smart_succeed != LUA_NOREF)
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, wifi_smart_succeed);
|
||||
wifi_smart_succeed = LUA_NOREF;
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
|
||||
#############################################################
|
||||
# Required variables for each makefile
|
||||
# Discard this section from all parent makefiles
|
||||
# Expected variables (with automatic defaults):
|
||||
# CSRCS (all "C" files in the dir)
|
||||
# SUBDIRS (all subdirs with a Makefile)
|
||||
# GEN_LIBS - list of libs to be generated ()
|
||||
# GEN_IMAGES - list of images to be generated ()
|
||||
# COMPONENTS_xxx - a list of libs/objs in the form
|
||||
# subdir/lib to be extracted and rolled up into
|
||||
# a generated lib/image xxx.a ()
|
||||
#
|
||||
ifndef PDIR
|
||||
GEN_LIBS = mqtt.a
|
||||
endif
|
||||
|
||||
#############################################################
|
||||
# Configuration i.e. compile options etc.
|
||||
# Target specific stuff (defines etc.) goes in here!
|
||||
# Generally values applying to a tree are captured in the
|
||||
# makefile at its root level - these are then overridden
|
||||
# for a subtree within the makefile rooted therein
|
||||
#
|
||||
#DEFINES +=
|
||||
|
||||
#############################################################
|
||||
# Recursion Magic - Don't touch this!!
|
||||
#
|
||||
# Each subtree potentially has an include directory
|
||||
# corresponding to the common APIs applicable to modules
|
||||
# rooted at that subtree. Accordingly, the INCLUDE PATH
|
||||
# of a module can only contain the include directories up
|
||||
# its parent path, and not its siblings
|
||||
#
|
||||
# Required for each makefile to inherit from the parent
|
||||
#
|
||||
|
||||
INCLUDES := $(INCLUDES) -I $(PDIR)include
|
||||
INCLUDES += -I ./
|
||||
INCLUDES += -I ../libc
|
||||
PDIR := ../$(PDIR)
|
||||
sinclude $(PDIR)Makefile
|
||||
|
|
@ -0,0 +1,457 @@
|
|||
/*
|
||||
* Copyright (c) 2014, Stephen Robinson
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "mqtt_msg.h"
|
||||
|
||||
#define MQTT_MAX_FIXED_HEADER_SIZE 3
|
||||
|
||||
enum mqtt_connect_flag
|
||||
{
|
||||
MQTT_CONNECT_FLAG_USERNAME = 1 << 7,
|
||||
MQTT_CONNECT_FLAG_PASSWORD = 1 << 6,
|
||||
MQTT_CONNECT_FLAG_WILL_RETAIN = 1 << 5,
|
||||
MQTT_CONNECT_FLAG_WILL = 1 << 2,
|
||||
MQTT_CONNECT_FLAG_CLEAN_SESSION = 1 << 1
|
||||
};
|
||||
|
||||
struct __attribute((__packed__)) mqtt_connect_variable_header
|
||||
{
|
||||
uint8_t lengthMsb;
|
||||
uint8_t lengthLsb;
|
||||
uint8_t magic[6];
|
||||
uint8_t version;
|
||||
uint8_t flags;
|
||||
uint8_t keepaliveMsb;
|
||||
uint8_t keepaliveLsb;
|
||||
};
|
||||
|
||||
static int append_string(mqtt_connection_t* connection, const char* string, int len)
|
||||
{
|
||||
if(connection->message.length + len + 2 > connection->buffer_length)
|
||||
return -1;
|
||||
|
||||
connection->buffer[connection->message.length++] = len >> 8;
|
||||
connection->buffer[connection->message.length++] = len & 0xff;
|
||||
memcpy(connection->buffer + connection->message.length, string, len);
|
||||
connection->message.length += len;
|
||||
|
||||
return len + 2;
|
||||
}
|
||||
|
||||
static uint16_t append_message_id(mqtt_connection_t* connection, uint16_t message_id)
|
||||
{
|
||||
// If message_id is zero then we should assign one, otherwise
|
||||
// we'll use the one supplied by the caller
|
||||
while(message_id == 0)
|
||||
message_id = ++connection->message_id;
|
||||
|
||||
if(connection->message.length + 2 > connection->buffer_length)
|
||||
return 0;
|
||||
|
||||
connection->buffer[connection->message.length++] = message_id >> 8;
|
||||
connection->buffer[connection->message.length++] = message_id & 0xff;
|
||||
|
||||
return message_id;
|
||||
}
|
||||
|
||||
static int init_message(mqtt_connection_t* connection)
|
||||
{
|
||||
connection->message.length = MQTT_MAX_FIXED_HEADER_SIZE;
|
||||
return MQTT_MAX_FIXED_HEADER_SIZE;
|
||||
}
|
||||
|
||||
static mqtt_message_t* fail_message(mqtt_connection_t* connection)
|
||||
{
|
||||
connection->message.data = connection->buffer;
|
||||
connection->message.length = 0;
|
||||
return &connection->message;
|
||||
}
|
||||
|
||||
static mqtt_message_t* fini_message(mqtt_connection_t* connection, int type, int dup, int qos, int retain)
|
||||
{
|
||||
int remaining_length = connection->message.length - MQTT_MAX_FIXED_HEADER_SIZE;
|
||||
|
||||
if(remaining_length > 127)
|
||||
{
|
||||
connection->buffer[0] = ((type & 0x0f) << 4) | ((dup & 1) << 3) | ((qos & 3) << 1) | (retain & 1);
|
||||
connection->buffer[1] = 0x80 | (remaining_length % 128);
|
||||
connection->buffer[2] = remaining_length / 128;
|
||||
connection->message.length = remaining_length + 3;
|
||||
connection->message.data = connection->buffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
connection->buffer[1] = ((type & 0x0f) << 4) | ((dup & 1) << 3) | ((qos & 3) << 1) | (retain & 1);
|
||||
connection->buffer[2] = remaining_length;
|
||||
connection->message.length = remaining_length + 2;
|
||||
connection->message.data = connection->buffer + 1;
|
||||
}
|
||||
|
||||
return &connection->message;
|
||||
}
|
||||
|
||||
void mqtt_msg_init(mqtt_connection_t* connection, uint8_t* buffer, uint16_t buffer_length)
|
||||
{
|
||||
memset(connection, 0, sizeof(connection));
|
||||
connection->buffer = buffer;
|
||||
connection->buffer_length = buffer_length;
|
||||
}
|
||||
|
||||
int mqtt_get_total_length(uint8_t* buffer, uint16_t length)
|
||||
{
|
||||
int i;
|
||||
int totlen = 0;
|
||||
|
||||
for(i = 1; i < length; ++i)
|
||||
{
|
||||
totlen += (buffer[i] & 0x7f) << (7 * (i - 1));
|
||||
if((buffer[i] & 0x80) == 0)
|
||||
{
|
||||
++i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
totlen += i;
|
||||
|
||||
return totlen;
|
||||
}
|
||||
|
||||
const char* mqtt_get_publish_topic(uint8_t* buffer, uint16_t* length)
|
||||
{
|
||||
int i;
|
||||
int totlen = 0;
|
||||
int topiclen;
|
||||
|
||||
for(i = 1; i < *length; ++i)
|
||||
{
|
||||
totlen += (buffer[i] & 0x7f) << (7 * (i -1));
|
||||
if((buffer[i] & 0x80) == 0)
|
||||
{
|
||||
++i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
totlen += i;
|
||||
|
||||
if(i + 2 >= *length)
|
||||
return NULL;
|
||||
topiclen = buffer[i++] << 8;
|
||||
topiclen |= buffer[i++];
|
||||
|
||||
if(i + topiclen > *length)
|
||||
return NULL;
|
||||
|
||||
*length = topiclen;
|
||||
return (const char*)(buffer + i);
|
||||
}
|
||||
|
||||
const char* mqtt_get_publish_data(uint8_t* buffer, uint16_t* length)
|
||||
{
|
||||
int i;
|
||||
int totlen = 0;
|
||||
int topiclen;
|
||||
|
||||
for(i = 1; i < *length; ++i)
|
||||
{
|
||||
totlen += (buffer[i] & 0x7f) << (7 * (i - 1));
|
||||
if((buffer[i] & 0x80) == 0)
|
||||
{
|
||||
++i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
totlen += i;
|
||||
|
||||
if(i + 2 >= *length)
|
||||
return NULL;
|
||||
topiclen = buffer[i++] << 8;
|
||||
topiclen |= buffer[i++];
|
||||
|
||||
if(i + topiclen >= *length){
|
||||
*length = 0;
|
||||
return NULL;
|
||||
}
|
||||
i += topiclen;
|
||||
|
||||
if(mqtt_get_qos(buffer) > 0)
|
||||
{
|
||||
if(i + 2 >= *length)
|
||||
return NULL;
|
||||
i += 2;
|
||||
}
|
||||
|
||||
if(totlen < i)
|
||||
return NULL;
|
||||
|
||||
if(totlen <= *length)
|
||||
*length = totlen - i;
|
||||
else
|
||||
*length = *length - i;
|
||||
return (const char*)(buffer + i);
|
||||
}
|
||||
|
||||
uint16_t mqtt_get_id(uint8_t* buffer, uint16_t length)
|
||||
{
|
||||
if(length < 1)
|
||||
return 0;
|
||||
|
||||
switch(mqtt_get_type(buffer))
|
||||
{
|
||||
case MQTT_MSG_TYPE_PUBLISH:
|
||||
{
|
||||
int i;
|
||||
int topiclen;
|
||||
|
||||
for(i = 1; i < length; ++i)
|
||||
{
|
||||
if((buffer[i] & 0x80) == 0)
|
||||
{
|
||||
++i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(i + 2 >= length)
|
||||
return 0;
|
||||
topiclen = buffer[i++] << 8;
|
||||
topiclen |= buffer[i++];
|
||||
|
||||
if(i + topiclen >= length)
|
||||
return 0;
|
||||
i += topiclen;
|
||||
|
||||
if(mqtt_get_qos(buffer) > 0)
|
||||
{
|
||||
if(i + 2 >= length)
|
||||
return 0;
|
||||
//i += 2;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (buffer[i] << 8) | buffer[i + 1];
|
||||
}
|
||||
case MQTT_MSG_TYPE_PUBACK:
|
||||
case MQTT_MSG_TYPE_PUBREC:
|
||||
case MQTT_MSG_TYPE_PUBREL:
|
||||
case MQTT_MSG_TYPE_PUBCOMP:
|
||||
case MQTT_MSG_TYPE_SUBACK:
|
||||
case MQTT_MSG_TYPE_UNSUBACK:
|
||||
case MQTT_MSG_TYPE_SUBSCRIBE:
|
||||
{
|
||||
// This requires the remaining length to be encoded in 1 byte,
|
||||
// which it should be.
|
||||
if(length >= 4 && (buffer[1] & 0x80) == 0)
|
||||
return (buffer[2] << 8) | buffer[3];
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
mqtt_message_t* mqtt_msg_connect(mqtt_connection_t* connection, mqtt_connect_info_t* info)
|
||||
{
|
||||
struct mqtt_connect_variable_header* variable_header;
|
||||
|
||||
init_message(connection);
|
||||
|
||||
if(connection->message.length + sizeof(*variable_header) > connection->buffer_length)
|
||||
return fail_message(connection);
|
||||
variable_header = (void*)(connection->buffer + connection->message.length);
|
||||
connection->message.length += sizeof(*variable_header);
|
||||
|
||||
variable_header->lengthMsb = 0;
|
||||
variable_header->lengthLsb = 6;
|
||||
memcpy(variable_header->magic, "MQIsdp", 6);
|
||||
variable_header->version = 3;
|
||||
variable_header->flags = 0;
|
||||
variable_header->keepaliveMsb = info->keepalive >> 8;
|
||||
variable_header->keepaliveLsb = info->keepalive & 0xff;
|
||||
|
||||
if(info->clean_session)
|
||||
variable_header->flags |= MQTT_CONNECT_FLAG_CLEAN_SESSION;
|
||||
|
||||
if(info->client_id != NULL && info->client_id[0] != '\0')
|
||||
{
|
||||
if(append_string(connection, info->client_id, strlen(info->client_id)) < 0)
|
||||
return fail_message(connection);
|
||||
}
|
||||
else
|
||||
return fail_message(connection);
|
||||
|
||||
if(info->will_topic != NULL && info->will_topic[0] != '\0')
|
||||
{
|
||||
if(append_string(connection, info->will_topic, strlen(info->will_topic)) < 0)
|
||||
return fail_message(connection);
|
||||
|
||||
if(append_string(connection, info->will_message, strlen(info->will_message)) < 0)
|
||||
return fail_message(connection);
|
||||
|
||||
variable_header->flags |= MQTT_CONNECT_FLAG_WILL;
|
||||
if(info->will_retain)
|
||||
variable_header->flags |= MQTT_CONNECT_FLAG_WILL_RETAIN;
|
||||
variable_header->flags |= (info->will_qos & 3) << 4;
|
||||
}
|
||||
|
||||
if(info->username != NULL && info->username[0] != '\0')
|
||||
{
|
||||
if(append_string(connection, info->username, strlen(info->username)) < 0)
|
||||
return fail_message(connection);
|
||||
|
||||
variable_header->flags |= MQTT_CONNECT_FLAG_USERNAME;
|
||||
}
|
||||
|
||||
if(info->password != NULL && info->password[0] != '\0')
|
||||
{
|
||||
if(append_string(connection, info->password, strlen(info->password)) < 0)
|
||||
return fail_message(connection);
|
||||
|
||||
variable_header->flags |= MQTT_CONNECT_FLAG_PASSWORD;
|
||||
}
|
||||
|
||||
return fini_message(connection, MQTT_MSG_TYPE_CONNECT, 0, 0, 0);
|
||||
}
|
||||
|
||||
mqtt_message_t* mqtt_msg_publish(mqtt_connection_t* connection, const char* topic, const char* data, int data_length, int qos, int retain, uint16_t* message_id)
|
||||
{
|
||||
init_message(connection);
|
||||
|
||||
if(topic == NULL || topic[0] == '\0')
|
||||
return fail_message(connection);
|
||||
|
||||
if(append_string(connection, topic, strlen(topic)) < 0)
|
||||
return fail_message(connection);
|
||||
|
||||
if(qos > 0)
|
||||
{
|
||||
if((*message_id = append_message_id(connection, 0)) == 0)
|
||||
return fail_message(connection);
|
||||
}
|
||||
else
|
||||
*message_id = 0;
|
||||
|
||||
if(connection->message.length + data_length > connection->buffer_length)
|
||||
return fail_message(connection);
|
||||
memcpy(connection->buffer + connection->message.length, data, data_length);
|
||||
connection->message.length += data_length;
|
||||
|
||||
return fini_message(connection, MQTT_MSG_TYPE_PUBLISH, 0, qos, retain);
|
||||
}
|
||||
|
||||
mqtt_message_t* mqtt_msg_puback(mqtt_connection_t* connection, uint16_t message_id)
|
||||
{
|
||||
init_message(connection);
|
||||
if(append_message_id(connection, message_id) == 0)
|
||||
return fail_message(connection);
|
||||
return fini_message(connection, MQTT_MSG_TYPE_PUBACK, 0, 0, 0);
|
||||
}
|
||||
|
||||
mqtt_message_t* mqtt_msg_pubrec(mqtt_connection_t* connection, uint16_t message_id)
|
||||
{
|
||||
init_message(connection);
|
||||
if(append_message_id(connection, message_id) == 0)
|
||||
return fail_message(connection);
|
||||
return fini_message(connection, MQTT_MSG_TYPE_PUBREC, 0, 0, 0);
|
||||
}
|
||||
|
||||
mqtt_message_t* mqtt_msg_pubrel(mqtt_connection_t* connection, uint16_t message_id)
|
||||
{
|
||||
init_message(connection);
|
||||
if(append_message_id(connection, message_id) == 0)
|
||||
return fail_message(connection);
|
||||
return fini_message(connection, MQTT_MSG_TYPE_PUBREL, 0, 1, 0);
|
||||
}
|
||||
|
||||
mqtt_message_t* mqtt_msg_pubcomp(mqtt_connection_t* connection, uint16_t message_id)
|
||||
{
|
||||
init_message(connection);
|
||||
if(append_message_id(connection, message_id) == 0)
|
||||
return fail_message(connection);
|
||||
return fini_message(connection, MQTT_MSG_TYPE_PUBCOMP, 0, 0, 0);
|
||||
}
|
||||
|
||||
mqtt_message_t* mqtt_msg_subscribe(mqtt_connection_t* connection, const char* topic, int qos, uint16_t* message_id)
|
||||
{
|
||||
init_message(connection);
|
||||
|
||||
if(topic == NULL || topic[0] == '\0')
|
||||
return fail_message(connection);
|
||||
|
||||
if((*message_id = append_message_id(connection, 0)) == 0)
|
||||
return fail_message(connection);
|
||||
|
||||
if(append_string(connection, topic, strlen(topic)) < 0)
|
||||
return fail_message(connection);
|
||||
|
||||
if(connection->message.length + 1 > connection->buffer_length)
|
||||
return fail_message(connection);
|
||||
connection->buffer[connection->message.length++] = qos;
|
||||
|
||||
return fini_message(connection, MQTT_MSG_TYPE_SUBSCRIBE, 0, 1, 0);
|
||||
}
|
||||
|
||||
mqtt_message_t* mqtt_msg_unsubscribe(mqtt_connection_t* connection, const char* topic, uint16_t* message_id)
|
||||
{
|
||||
init_message(connection);
|
||||
|
||||
if(topic == NULL || topic[0] == '\0')
|
||||
return fail_message(connection);
|
||||
|
||||
if((*message_id = append_message_id(connection, 0)) == 0)
|
||||
return fail_message(connection);
|
||||
|
||||
if(append_string(connection, topic, strlen(topic)) < 0)
|
||||
return fail_message(connection);
|
||||
|
||||
return fini_message(connection, MQTT_MSG_TYPE_SUBSCRIBE, 0, 1, 0);
|
||||
}
|
||||
|
||||
mqtt_message_t* mqtt_msg_pingreq(mqtt_connection_t* connection)
|
||||
{
|
||||
init_message(connection);
|
||||
return fini_message(connection, MQTT_MSG_TYPE_PINGREQ, 0, 0, 0);
|
||||
}
|
||||
|
||||
mqtt_message_t* mqtt_msg_pingresp(mqtt_connection_t* connection)
|
||||
{
|
||||
init_message(connection);
|
||||
return fini_message(connection, MQTT_MSG_TYPE_PINGRESP, 0, 0, 0);
|
||||
}
|
||||
|
||||
mqtt_message_t* mqtt_msg_disconnect(mqtt_connection_t* connection)
|
||||
{
|
||||
init_message(connection);
|
||||
return fini_message(connection, MQTT_MSG_TYPE_DISCONNECT, 0, 0, 0);
|
||||
}
|
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
* File: mqtt_msg.h
|
||||
* Author: Minh Tuan
|
||||
*
|
||||
* Created on July 12, 2014, 1:05 PM
|
||||
*/
|
||||
|
||||
#ifndef MQTT_MSG_H
|
||||
#define MQTT_MSG_H
|
||||
#include "c_types.h"
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014, Stephen Robinson
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
/* 7 6 5 4 3 2 1 0*/
|
||||
/*| --- Message Type---- | DUP Flag | QoS Level | Retain |
|
||||
/* Remaining Length */
|
||||
|
||||
|
||||
enum mqtt_message_type
|
||||
{
|
||||
MQTT_MSG_TYPE_CONNECT = 1,
|
||||
MQTT_MSG_TYPE_CONNACK = 2,
|
||||
MQTT_MSG_TYPE_PUBLISH = 3,
|
||||
MQTT_MSG_TYPE_PUBACK = 4,
|
||||
MQTT_MSG_TYPE_PUBREC = 5,
|
||||
MQTT_MSG_TYPE_PUBREL = 6,
|
||||
MQTT_MSG_TYPE_PUBCOMP = 7,
|
||||
MQTT_MSG_TYPE_SUBSCRIBE = 8,
|
||||
MQTT_MSG_TYPE_SUBACK = 9,
|
||||
MQTT_MSG_TYPE_UNSUBSCRIBE = 10,
|
||||
MQTT_MSG_TYPE_UNSUBACK = 11,
|
||||
MQTT_MSG_TYPE_PINGREQ = 12,
|
||||
MQTT_MSG_TYPE_PINGRESP = 13,
|
||||
MQTT_MSG_TYPE_DISCONNECT = 14
|
||||
};
|
||||
|
||||
typedef struct mqtt_message
|
||||
{
|
||||
uint8_t* data;
|
||||
uint16_t length;
|
||||
|
||||
} mqtt_message_t;
|
||||
|
||||
typedef struct mqtt_connection
|
||||
{
|
||||
mqtt_message_t message;
|
||||
|
||||
uint16_t message_id;
|
||||
uint8_t* buffer;
|
||||
uint16_t buffer_length;
|
||||
|
||||
} mqtt_connection_t;
|
||||
|
||||
typedef struct mqtt_connect_info
|
||||
{
|
||||
char* client_id;
|
||||
char* username;
|
||||
char* password;
|
||||
char* will_topic;
|
||||
char* will_message;
|
||||
int keepalive;
|
||||
int will_qos;
|
||||
int will_retain;
|
||||
int clean_session;
|
||||
|
||||
} mqtt_connect_info_t;
|
||||
|
||||
|
||||
static inline int mqtt_get_type(uint8_t* buffer) { return (buffer[0] & 0xf0) >> 4; }
|
||||
static inline int mqtt_get_dup(uint8_t* buffer) { return (buffer[0] & 0x08) >> 3; }
|
||||
static inline int mqtt_get_qos(uint8_t* buffer) { return (buffer[0] & 0x06) >> 1; }
|
||||
static inline int mqtt_get_retain(uint8_t* buffer) { return (buffer[0] & 0x01); }
|
||||
|
||||
void mqtt_msg_init(mqtt_connection_t* connection, uint8_t* buffer, uint16_t buffer_length);
|
||||
int mqtt_get_total_length(uint8_t* buffer, uint16_t length);
|
||||
const char* mqtt_get_publish_topic(uint8_t* buffer, uint16_t* length);
|
||||
const char* mqtt_get_publish_data(uint8_t* buffer, uint16_t* length);
|
||||
uint16_t mqtt_get_id(uint8_t* buffer, uint16_t length);
|
||||
|
||||
mqtt_message_t* mqtt_msg_connect(mqtt_connection_t* connection, mqtt_connect_info_t* info);
|
||||
mqtt_message_t* mqtt_msg_publish(mqtt_connection_t* connection, const char* topic, const char* data, int data_length, int qos, int retain, uint16_t* message_id);
|
||||
mqtt_message_t* mqtt_msg_puback(mqtt_connection_t* connection, uint16_t message_id);
|
||||
mqtt_message_t* mqtt_msg_pubrec(mqtt_connection_t* connection, uint16_t message_id);
|
||||
mqtt_message_t* mqtt_msg_pubrel(mqtt_connection_t* connection, uint16_t message_id);
|
||||
mqtt_message_t* mqtt_msg_pubcomp(mqtt_connection_t* connection, uint16_t message_id);
|
||||
mqtt_message_t* mqtt_msg_subscribe(mqtt_connection_t* connection, const char* topic, int qos, uint16_t* message_id);
|
||||
mqtt_message_t* mqtt_msg_unsubscribe(mqtt_connection_t* connection, const char* topic, uint16_t* message_id);
|
||||
mqtt_message_t* mqtt_msg_pingreq(mqtt_connection_t* connection);
|
||||
mqtt_message_t* mqtt_msg_pingresp(mqtt_connection_t* connection);
|
||||
mqtt_message_t* mqtt_msg_disconnect(mqtt_connection_t* connection);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MQTT_MSG_H */
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
#include "flash_api.h"
|
||||
// Number of resources (0 if not available/not implemented)
|
||||
#define NUM_GPIO GPIO_PIN_NUM
|
||||
#define NUM_SPI 1
|
||||
#define NUM_SPI 2
|
||||
#define NUM_UART 1
|
||||
#define NUM_PWM GPIO_PIN_NUM
|
||||
#define NUM_ADC 1
|
||||
|
|
|
@ -129,11 +129,11 @@ int platform_gpio_read( unsigned pin )
|
|||
return -1;
|
||||
|
||||
if(pin == 0){
|
||||
gpio16_input_conf();
|
||||
// gpio16_input_conf();
|
||||
return 0x1 & gpio16_input_get();
|
||||
}
|
||||
|
||||
GPIO_DIS_OUTPUT(pin_num[pin]);
|
||||
// GPIO_DIS_OUTPUT(pin_num[pin]);
|
||||
return 0x1 & GPIO_INPUT_GET(GPIO_ID_PIN(pin_num[pin]));
|
||||
}
|
||||
|
||||
|
@ -435,6 +435,20 @@ int platform_i2c_recv_byte( unsigned id, int ack ){
|
|||
return r;
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// SPI platform interface
|
||||
uint32_t platform_spi_setup( unsigned id, int mode, unsigned cpol, unsigned cpha, unsigned databits, uint32_t clock)
|
||||
{
|
||||
spi_master_init(id, cpol, cpha, databits, clock);
|
||||
return 1;
|
||||
}
|
||||
|
||||
spi_data_type platform_spi_send_recv( unsigned id, spi_data_type data )
|
||||
{
|
||||
spi_mast_byte_write(id, &data);
|
||||
return data;
|
||||
}
|
||||
|
||||
// ****************************************************************************
|
||||
// Flash access functions
|
||||
|
||||
|
|
|
@ -84,13 +84,23 @@ int platform_can_recv( unsigned id, uint32_t *canid, uint8_t *idtype, uint8_t *l
|
|||
// SPI enable/disable
|
||||
#define PLATFORM_SPI_ENABLE 1
|
||||
#define PLATFORM_SPI_DISABLE 0
|
||||
// SPI clock phase
|
||||
#define PLATFORM_SPI_CPHA_LOW 0
|
||||
#define PLATFORM_SPI_CPHA_HIGH 1
|
||||
// SPI clock polarity
|
||||
#define PLATFORM_SPI_CPOL_LOW 0
|
||||
#define PLATFORM_SPI_CPOL_HIGH 1
|
||||
// SPI databits
|
||||
#define PLATFORM_SPI_DATABITS_8 8
|
||||
#define PLATFORM_SPI_DATABITS_16 16
|
||||
|
||||
|
||||
// Data types
|
||||
typedef uint32_t spi_data_type;
|
||||
|
||||
// The platform SPI functions
|
||||
int platform_spi_exists( unsigned id );
|
||||
uint32_t platform_spi_setup( unsigned id, int mode, uint32_t clock, unsigned cpol, unsigned cpha, unsigned databits );
|
||||
uint32_t platform_spi_setup( unsigned id, int mode, unsigned cpol, unsigned cpha, unsigned databits, uint32_t clock);
|
||||
spi_data_type platform_spi_send_recv( unsigned id, spi_data_type data );
|
||||
void platform_spi_select( unsigned id, int is_select );
|
||||
|
||||
|
|
|
@ -45,6 +45,8 @@ The small 4KB sectors allow for greater flexibility in applications th
|
|||
void spiffs_mount() {
|
||||
spiffs_config cfg;
|
||||
cfg.phys_addr = ( u32_t )platform_flash_get_first_free_block_address( NULL );
|
||||
cfg.phys_addr += 0x3000;
|
||||
cfg.phys_addr &= 0xFFFFC000; // align to 4 sector.
|
||||
cfg.phys_size = INTERNAL_FLASH_SIZE - ( ( u32_t )cfg.phys_addr - INTERNAL_FLASH_START_ADDRESS );
|
||||
cfg.phys_erase_block = INTERNAL_FLASH_SECTOR_SIZE; // according to datasheet
|
||||
cfg.log_block_size = INTERNAL_FLASH_SECTOR_SIZE; // let us not complicate things
|
||||
|
@ -74,6 +76,8 @@ int myspiffs_format( void )
|
|||
SPIFFS_unmount(&fs);
|
||||
u32_t sect_first, sect_last;
|
||||
sect_first = ( u32_t )platform_flash_get_first_free_block_address( NULL );
|
||||
sect_first += 0x3000;
|
||||
sect_first &= 0xFFFFC000; // align to 4 sector.
|
||||
sect_first = platform_flash_get_sector_of_address(sect_first);
|
||||
sect_last = INTERNAL_FLASH_SIZE + INTERNAL_FLASH_START_ADDRESS - 4;
|
||||
sect_last = platform_flash_get_sector_of_address(sect_last);
|
||||
|
|
|
@ -222,7 +222,7 @@ upgrade_connect_cb(void *arg)
|
|||
espconn_regist_sentcb(pespconn, upgrade_datasent);
|
||||
|
||||
if (pbuf != NULL) {
|
||||
UPGRADE_DBG(pbuf);
|
||||
UPGRADE_DBG("%s\n", pbuf);
|
||||
#ifdef UPGRADE_SSL_ENABLE
|
||||
espconn_secure_sent(pespconn, pbuf, os_strlen(pbuf));
|
||||
#else
|
||||
|
|
|
@ -50,30 +50,8 @@ extern void spiffs_mount();
|
|||
|
||||
// extern uint16_t flash_get_sec_num();
|
||||
|
||||
/******************************************************************************
|
||||
* FunctionName : user_init
|
||||
* Description : entry of user application, init user function here
|
||||
* Parameters : none
|
||||
* Returns : none
|
||||
*******************************************************************************/
|
||||
void user_init(void)
|
||||
void nodemcu_init(void)
|
||||
{
|
||||
// NODE_DBG("SDK version:%s\n", system_get_sdk_version());
|
||||
// system_print_meminfo();
|
||||
// os_printf("Heap size::%d.\n",system_get_free_heap_size());
|
||||
// os_delay_us(50*1000); // delay 50ms before init uart
|
||||
|
||||
#ifdef DEVELOP_VERSION
|
||||
uart_init(BIT_RATE_74880, BIT_RATE_74880);
|
||||
#else
|
||||
uart_init(BIT_RATE_9600, BIT_RATE_9600);
|
||||
#endif
|
||||
// uart_init(BIT_RATE_115200, BIT_RATE_115200);
|
||||
|
||||
#ifndef NODE_DEBUG
|
||||
system_set_os_print(0);
|
||||
#endif
|
||||
|
||||
NODE_ERR("\n");
|
||||
// Initialize platform first for lua modules.
|
||||
if( platform_init() != PLATFORM_OK )
|
||||
|
@ -85,9 +63,9 @@ void user_init(void)
|
|||
|
||||
if( !flash_init_data_written() ){
|
||||
NODE_ERR("Restore init data.\n");
|
||||
// Flash init data at FLASHSIZE - 0x04000 Byte.
|
||||
// Flash init data at FLASHSIZE - 0x04000 Byte.
|
||||
flash_init_data_default();
|
||||
// Flash blank data at FLASHSIZE - 0x02000 Byte.
|
||||
// Flash blank data at FLASHSIZE - 0x02000 Byte.
|
||||
flash_init_data_blank();
|
||||
}
|
||||
|
||||
|
@ -119,3 +97,30 @@ void user_init(void)
|
|||
task_init();
|
||||
system_os_post(USER_TASK_PRIO_0,SIG_LUA,'s');
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* FunctionName : user_init
|
||||
* Description : entry of user application, init user function here
|
||||
* Parameters : none
|
||||
* Returns : none
|
||||
*******************************************************************************/
|
||||
void user_init(void)
|
||||
{
|
||||
// NODE_DBG("SDK version:%s\n", system_get_sdk_version());
|
||||
// system_print_meminfo();
|
||||
// os_printf("Heap size::%d.\n",system_get_free_heap_size());
|
||||
// os_delay_us(50*1000); // delay 50ms before init uart
|
||||
|
||||
#ifdef DEVELOP_VERSION
|
||||
uart_init(BIT_RATE_74880, BIT_RATE_74880);
|
||||
#else
|
||||
uart_init(BIT_RATE_9600, BIT_RATE_9600);
|
||||
#endif
|
||||
// uart_init(BIT_RATE_115200, BIT_RATE_115200);
|
||||
|
||||
#ifndef NODE_DEBUG
|
||||
system_set_os_print(0);
|
||||
#endif
|
||||
|
||||
system_init_done_cb(nodemcu_init);
|
||||
}
|
||||
|
|
|
@ -25,15 +25,19 @@ ss=net.createServer(net.TCP) ss:listen(80,function(c) end)
|
|||
|
||||
s=net.createServer(net.TCP) s:listen(80,function(c) c:on("receive",function(s,c) print(c) end) end)
|
||||
|
||||
s=net.createServer(net.UDP) s:listen(5683,function(c) c:on("receive",function(s,c) print(c) end) end)
|
||||
s=net.createServer(net.UDP)
|
||||
s:on("receive",function(s,c) print(c) end)
|
||||
s:listen(5683)
|
||||
|
||||
su=net.createConnection(net.UDP)
|
||||
su:on("receive",function(su,c) print(c) end)
|
||||
su:connect(5683,"192.168.18.101")
|
||||
su:send("hello")
|
||||
|
||||
mm=node.list()
|
||||
for k, v in pairs(mm) do print('file:'..k..' len:'..v) end
|
||||
for k,v in pairs(d) do print("n:"..k..", s:"..v) end
|
||||
su=net.createConnection(net.UDP)
|
||||
su:on("receive",function(su,c) print(c) end)
|
||||
su:connect(5683,"192.168.0.66")
|
||||
su:send("/v1/id")
|
||||
|
||||
|
||||
gpio.mode(0,gpio.INT) gpio.trig(0,"down",function(l) print("level="..l) end)
|
||||
|
||||
|
@ -57,8 +61,6 @@ su:send("hello world")
|
|||
|
||||
s=net.createServer(net.TCP) s:listen(8008,function(c) c:on("receive",function(s,c) print(c) pcall(loadstring(c)) end) end)
|
||||
|
||||
s=net.createServer(net.UDP) s:listen(8888,function(c) c:on("receive",function(s,c) print(c) pcall(loadstring(c)) end) end)
|
||||
|
||||
s=net.createServer(net.TCP) s:listen(8008,function(c) con_std = c function s_output(str) if(con_std~=nil) then con_std:send(str) end end
|
||||
node.output(s_output, 0) c:on("receive",function(c,l) node.input(l) end) c:on("disconnection",function(c) con_std = nil node.output(nil) end) end)
|
||||
|
||||
|
@ -313,3 +315,27 @@ uart.on("data", 0 ,function(input) if input=="q" then uart.on("data") else print
|
|||
uart.on("data","\r",function(input) if input=="quit" then uart.on("data") else print(input) end end, 1)
|
||||
|
||||
for k, v in pairs(file.list()) do print('file:'..k..' len:'..v) end
|
||||
|
||||
m=mqtt.Client()
|
||||
m:connect("192.168.18.101",1883)
|
||||
m:subscribe("/topic",0,function(m) print("sub done") end)
|
||||
m:on("message",function(m,t,pl) print(t..":") if pl~=nil then print(pl) end end )
|
||||
m:publish("/topic","hello",0,0)
|
||||
|
||||
uart.setup(0,9600,8,0,1,0)
|
||||
sv=net.createServer(net.TCP, 60)
|
||||
global_c = nil
|
||||
sv:listen(9999, function(c)
|
||||
if global_c~=nil then
|
||||
global_c:close()
|
||||
end
|
||||
global_c=c
|
||||
c:on("receive",function(sck,pl) uart.write(0,pl) end)
|
||||
end)
|
||||
|
||||
uart.on("data",4, function(data)
|
||||
if global_c~=nil then
|
||||
global_c:send(data)
|
||||
end
|
||||
end, 0)
|
||||
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
|
||||
/*
|
||||
* custom_at.h
|
||||
*
|
||||
* This file is part of Espressif's AT+ command set program.
|
||||
* Copyright (C) 2013 - 2016, Espressif Systems
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of version 3 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CUSTOM_AT_H_
|
||||
#define CUSTOM_AT_H_
|
||||
|
||||
#include "c_types.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *at_cmdName;
|
||||
int8_t at_cmdLen;
|
||||
void (*at_testCmd)(uint8_t id);
|
||||
void (*at_queryCmd)(uint8_t id);
|
||||
void (*at_setupCmd)(uint8_t id, char *pPara);
|
||||
void (*at_exeCmd)(uint8_t id);
|
||||
}at_funcationType;
|
||||
|
||||
/**
|
||||
* @brief Response "OK" to uart.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void at_response_ok(void);
|
||||
/**
|
||||
* @brief Response "ERROR" to uart.
|
||||
* @param events: no used
|
||||
* @retval None
|
||||
*/
|
||||
void at_response_error(void);
|
||||
/**
|
||||
* @brief Task of process command or txdata.
|
||||
* @param custom_at_cmd_array: the array of at cmd that custom defined
|
||||
* cmd_num : the num of at cmd that custom defined
|
||||
* @retval None
|
||||
*/
|
||||
void at_cmd_array_regist(at_funcationType *custom_at_cmd_array,uint32 cmd_num);
|
||||
/**
|
||||
* @brief get digit form at cmd line.the maybe alter pSrc
|
||||
* @param p_src: at cmd line string
|
||||
* result:the buffer to be placed result
|
||||
* err : err num
|
||||
* @retval TRUE:
|
||||
* FALSE:
|
||||
*/
|
||||
bool at_get_next_int_dec(char **p_src,int*result,int* err);
|
||||
/**
|
||||
* @brief get string form at cmd line.the maybe alter pSrc
|
||||
* @param p_dest: the buffer to be placed result
|
||||
* p_src: at cmd line string
|
||||
* max_len :max len of string excepted to get
|
||||
* @retval None
|
||||
*/
|
||||
int32 at_data_str_copy(char *p_dest, char **p_src, int32 max_len);
|
||||
|
||||
/**
|
||||
* @brief initialize at module
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void at_init(void);
|
||||
/**
|
||||
* @brief print string to at port
|
||||
* @param string
|
||||
* @retval None
|
||||
*/
|
||||
void at_port_print(const char *str);
|
||||
#endif
|
|
@ -16,6 +16,7 @@ typedef unsigned long uint32_t;
|
|||
typedef signed long sint32_t;
|
||||
typedef signed long int32_t;
|
||||
typedef signed long long sint64_t;
|
||||
typedef signed long long int64_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
typedef unsigned long long u_int64_t;
|
||||
typedef float real32_t;
|
||||
|
@ -78,6 +79,7 @@ typedef enum {
|
|||
|
||||
#ifdef ICACHE_FLASH
|
||||
#define ICACHE_FLASH_ATTR __attribute__((section(".irom0.text")))
|
||||
#define ICACHE_RODATA_ATTR __attribute__((section(".irom.text")))
|
||||
#else
|
||||
#define ICACHE_FLASH_ATTR
|
||||
#endif /* ICACHE_FLASH */
|
||||
|
|
|
@ -91,6 +91,7 @@ struct espconn {
|
|||
|
||||
enum espconn_option{
|
||||
ESPCONN_REUSEADDR = 1,
|
||||
ESPCONN_NODELAY,
|
||||
ESPCONN_END
|
||||
};
|
||||
|
||||
|
@ -371,5 +372,21 @@ sint8 espconn_igmp_join(ip_addr_t *host_ip, ip_addr_t *multicast_ip);
|
|||
*******************************************************************************/
|
||||
sint8 espconn_igmp_leave(ip_addr_t *host_ip, ip_addr_t *multicast_ip);
|
||||
|
||||
/******************************************************************************
|
||||
* FunctionName : espconn_recv_hold
|
||||
* Description : hold tcp receive
|
||||
* Parameters : espconn -- espconn to hold
|
||||
* Returns : none
|
||||
*******************************************************************************/
|
||||
sint8 espconn_recv_hold(struct espconn *pespconn);
|
||||
|
||||
/******************************************************************************
|
||||
* FunctionName : espconn_recv_unhold
|
||||
* Description : unhold tcp receive
|
||||
* Parameters : espconn -- espconn to unhold
|
||||
* Returns : none
|
||||
*******************************************************************************/
|
||||
sint8 espconn_recv_unhold(struct espconn *pespconn);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -52,6 +52,11 @@ struct ip_info {
|
|||
#define ip4_addr3_16(ipaddr) ((uint16)ip4_addr3(ipaddr))
|
||||
#define ip4_addr4_16(ipaddr) ((uint16)ip4_addr4(ipaddr))
|
||||
|
||||
|
||||
/** 255.255.255.255 */
|
||||
#define IPADDR_NONE ((uint32)0xffffffffUL)
|
||||
/** 0.0.0.0 */
|
||||
#define IPADDR_ANY ((uint32)0x00000000UL)
|
||||
uint32 ipaddr_addr(const char *cp);
|
||||
|
||||
#define IP2STR(ipaddr) ip4_addr1_16(ipaddr), \
|
||||
|
|
|
@ -44,5 +44,14 @@
|
|||
#define os_sprintf ets_sprintf
|
||||
#define os_update_cpu_frequency ets_update_cpu_frequency
|
||||
|
||||
#ifdef USE_OPTIMIZE_PRINTF
|
||||
#define os_printf(fmt, ...) do { \
|
||||
static const char flash_str[] ICACHE_RODATA_ATTR = fmt; \
|
||||
os_printf_plus(flash_str, ##__VA_ARGS__); \
|
||||
} while(0)
|
||||
#else
|
||||
#define os_printf os_printf_plus
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
#ifndef __PING_H__
|
||||
#define __PING_H__
|
||||
|
||||
|
||||
typedef void (* ping_recv_function)(void* arg, void *pdata);
|
||||
typedef void (* ping_sent_function)(void* arg, void *pdata);
|
||||
|
||||
struct ping_option{
|
||||
uint32 count;
|
||||
uint32 ip;
|
||||
uint32 coarse_time;
|
||||
ping_recv_function recv_function;
|
||||
ping_sent_function sent_function;
|
||||
void* reverse;
|
||||
};
|
||||
|
||||
struct ping_resp{
|
||||
uint32 total_count;
|
||||
uint32 resp_time;
|
||||
uint32 seqno;
|
||||
uint32 timeout_count;
|
||||
uint32 bytes;
|
||||
uint32 total_bytes;
|
||||
uint32 total_time;
|
||||
sint8 ping_err;
|
||||
};
|
||||
|
||||
bool ping_start(struct ping_option *ping_opt);
|
||||
bool ping_regist_recv(struct ping_option *ping_opt, ping_recv_function ping_recv);
|
||||
bool ping_regist_sent(struct ping_option *ping_opt, ping_sent_function ping_sent);
|
||||
|
||||
#endif /* __PING_H__ */
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright (C) 2015 -2018 Espressif System
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SMARTCONFIG_H__
|
||||
#define __SMARTCONFIG_H__
|
||||
|
||||
typedef void (*sc_callback_t)(void *data);
|
||||
|
||||
typedef enum {
|
||||
SC_STATUS_FIND_CHANNEL = 0,
|
||||
SC_STATUS_GETTING_SSID_PSWD,
|
||||
SC_STATUS_GOT_SSID_PSWD,
|
||||
SC_STATUS_LINK,
|
||||
} sc_status;
|
||||
|
||||
typedef enum {
|
||||
SC_TYPE_ESPTOUCH = 0,
|
||||
SC_TYPE_AIRKISS,
|
||||
} sc_type;
|
||||
|
||||
sc_status smartconfig_get_status(void);
|
||||
const char *smartconfig_get_version(void);
|
||||
bool smartconfig_start(sc_type type, sc_callback_t cb);
|
||||
bool smartconfig_stop(void);
|
||||
|
||||
#endif
|
|
@ -24,8 +24,6 @@ typedef struct{
|
|||
#define SPI_FLASH_SEC_SIZE 4096
|
||||
|
||||
uint32 spi_flash_get_id(void);
|
||||
SpiFlashOpResult spi_flash_read_status(uint32 *status);
|
||||
SpiFlashOpResult spi_flash_write_status(uint32 status_value);
|
||||
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);
|
||||
|
|
|
@ -1,252 +1,261 @@
|
|||
/*
|
||||
* Copyright (C) 2013 -2014 Espressif System
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __USER_INTERFACE_H__
|
||||
#define __USER_INTERFACE_H__
|
||||
|
||||
#include "os_type.h"
|
||||
#ifdef LWIP_OPEN_SRC
|
||||
#include "lwip/ip_addr.h"
|
||||
#else
|
||||
#include "ip_addr.h"
|
||||
#endif
|
||||
|
||||
#include "queue.h"
|
||||
#include "user_config.h"
|
||||
#include "spi_flash.h"
|
||||
|
||||
#ifndef MAC2STR
|
||||
#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
|
||||
#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
|
||||
#endif
|
||||
|
||||
enum rst_reason {
|
||||
DEFAULT_RST_FLAG = 0,
|
||||
WDT_RST_FLAG = 1,
|
||||
EXP_RST_FLAG = 2
|
||||
};
|
||||
|
||||
struct rst_info{
|
||||
uint32 flag;
|
||||
uint32 exccause;
|
||||
uint32 epc1;
|
||||
uint32 epc2;
|
||||
uint32 epc3;
|
||||
uint32 excvaddr;
|
||||
uint32 depc;
|
||||
};
|
||||
|
||||
#define UPGRADE_FW_BIN1 0x00
|
||||
#define UPGRADE_FW_BIN2 0x01
|
||||
|
||||
void system_restore(void);
|
||||
void system_restart(void);
|
||||
void system_deep_sleep(uint32 time_in_us);
|
||||
uint8 system_upgrade_userbin_check(void);
|
||||
void system_upgrade_reboot(void);
|
||||
uint8 system_upgrade_flag_check();
|
||||
void system_upgrade_flag_set(uint8 flag);
|
||||
void system_timer_reinit(void);
|
||||
uint32 system_get_time(void);
|
||||
|
||||
/* user task's prio must be 0/1/2 !!!*/
|
||||
enum {
|
||||
USER_TASK_PRIO_0 = 0,
|
||||
USER_TASK_PRIO_1,
|
||||
USER_TASK_PRIO_2,
|
||||
USER_TASK_PRIO_MAX
|
||||
};
|
||||
|
||||
void system_os_task(os_task_t task, uint8 prio, os_event_t *queue, uint8 qlen);
|
||||
void system_os_post(uint8 prio, os_signal_t sig, os_param_t par);
|
||||
|
||||
void system_print_meminfo(void);
|
||||
uint32 system_get_free_heap_size(void);
|
||||
|
||||
void system_set_os_print(uint8 onoff);
|
||||
|
||||
uint64 system_mktime(uint32 year, uint32 mon, uint32 day, uint32 hour, uint32 min, uint32 sec);
|
||||
|
||||
uint32 system_get_chip_id(void);
|
||||
|
||||
typedef void (* init_done_cb_t)(void);
|
||||
|
||||
void system_init_done_cb(init_done_cb_t cb);
|
||||
|
||||
uint32 system_rtc_clock_cali_proc(void);
|
||||
uint32 system_get_rtc_time(void);
|
||||
|
||||
bool system_rtc_mem_read(uint8 src_addr, void *des_addr, uint16 load_size);
|
||||
bool system_rtc_mem_write(uint8 des_addr, const void *src_addr, uint16 save_size);
|
||||
|
||||
void system_uart_swap(void);
|
||||
|
||||
uint16 system_adc_read(void);
|
||||
|
||||
const char *system_get_sdk_version(void);
|
||||
|
||||
#define NULL_MODE 0x00
|
||||
#define STATION_MODE 0x01
|
||||
#define SOFTAP_MODE 0x02
|
||||
#define STATIONAP_MODE 0x03
|
||||
|
||||
uint8 wifi_get_opmode(void);
|
||||
bool wifi_set_opmode(uint8 opmode);
|
||||
|
||||
struct bss_info {
|
||||
STAILQ_ENTRY(bss_info) next;
|
||||
|
||||
uint8 bssid[6];
|
||||
uint8 ssid[32];
|
||||
uint8 channel;
|
||||
sint8 rssi;
|
||||
uint8 authmode;
|
||||
uint8 is_hidden;
|
||||
};
|
||||
|
||||
typedef struct _scaninfo {
|
||||
STAILQ_HEAD(, bss_info) *pbss;
|
||||
struct espconn *pespconn;
|
||||
uint8 totalpage;
|
||||
uint8 pagenum;
|
||||
uint8 page_sn;
|
||||
uint8 data_cnt;
|
||||
} scaninfo;
|
||||
|
||||
typedef void (* scan_done_cb_t)(void *arg, STATUS status);
|
||||
|
||||
struct station_config {
|
||||
uint8 ssid[32];
|
||||
uint8 password[64];
|
||||
uint8 bssid_set;
|
||||
uint8 bssid[6];
|
||||
};
|
||||
|
||||
bool wifi_station_get_config(struct station_config *config);
|
||||
bool wifi_station_set_config(struct station_config *config);
|
||||
|
||||
bool wifi_station_connect(void);
|
||||
bool wifi_station_disconnect(void);
|
||||
|
||||
struct scan_config {
|
||||
uint8 *ssid;
|
||||
uint8 *bssid;
|
||||
uint8 channel;
|
||||
uint8 show_hidden;
|
||||
};
|
||||
|
||||
bool wifi_station_scan(struct scan_config *config, scan_done_cb_t cb);
|
||||
|
||||
uint8 wifi_station_get_auto_connect(void);
|
||||
bool wifi_station_set_auto_connect(uint8 set);
|
||||
|
||||
enum {
|
||||
STATION_IDLE = 0,
|
||||
STATION_CONNECTING,
|
||||
STATION_WRONG_PASSWORD,
|
||||
STATION_NO_AP_FOUND,
|
||||
STATION_CONNECT_FAIL,
|
||||
STATION_GOT_IP
|
||||
};
|
||||
|
||||
enum dhcp_status {
|
||||
DHCP_STOPPED,
|
||||
DHCP_STARTED
|
||||
};
|
||||
|
||||
uint8 wifi_station_get_connect_status(void);
|
||||
|
||||
uint8 wifi_station_get_current_ap_id(void);
|
||||
bool wifi_station_ap_change(uint8 current_ap_id);
|
||||
bool wifi_station_ap_number_set(uint8 ap_number);
|
||||
|
||||
bool wifi_station_dhcpc_start(void);
|
||||
bool wifi_station_dhcpc_stop(void);
|
||||
enum dhcp_status wifi_station_dhcpc_status(void);
|
||||
|
||||
typedef enum _auth_mode {
|
||||
AUTH_OPEN = 0,
|
||||
AUTH_WEP,
|
||||
AUTH_WPA_PSK,
|
||||
AUTH_WPA2_PSK,
|
||||
AUTH_WPA_WPA2_PSK
|
||||
} AUTH_MODE;
|
||||
|
||||
struct softap_config {
|
||||
uint8 ssid[32];
|
||||
uint8 password[64];
|
||||
uint8 ssid_len;
|
||||
uint8 channel;
|
||||
uint8 authmode;
|
||||
uint8 ssid_hidden;
|
||||
uint8 max_connection;
|
||||
};
|
||||
|
||||
bool wifi_softap_get_config(struct softap_config *config);
|
||||
bool wifi_softap_set_config(struct softap_config *config);
|
||||
|
||||
struct station_info {
|
||||
STAILQ_ENTRY(station_info) next;
|
||||
|
||||
uint8 bssid[6];
|
||||
struct ip_addr ip;
|
||||
};
|
||||
|
||||
struct dhcps_lease {
|
||||
uint32 start_ip;
|
||||
uint32 end_ip;
|
||||
};
|
||||
|
||||
struct station_info * wifi_softap_get_station_info(void);
|
||||
void wifi_softap_free_station_info(void);
|
||||
uint8 wifi_station_get_ap_info(struct station_config config[]);
|
||||
|
||||
bool wifi_softap_dhcps_start(void);
|
||||
bool wifi_softap_dhcps_stop(void);
|
||||
bool wifi_softap_set_dhcps_lease(struct dhcps_lease *please);
|
||||
enum dhcp_status wifi_softap_dhcps_status(void);
|
||||
|
||||
#define STATION_IF 0x00
|
||||
#define SOFTAP_IF 0x01
|
||||
|
||||
bool wifi_get_ip_info(uint8 if_index, struct ip_info *info);
|
||||
bool wifi_set_ip_info(uint8 if_index, struct ip_info *info);
|
||||
bool wifi_get_macaddr(uint8 if_index, uint8 *macaddr);
|
||||
bool wifi_set_macaddr(uint8 if_index, uint8 *macaddr);
|
||||
|
||||
uint8 wifi_get_channel(void);
|
||||
bool wifi_set_channel(uint8 channel);
|
||||
|
||||
void wifi_status_led_install(uint8 gpio_id, uint32 gpio_name, uint8 gpio_func);
|
||||
|
||||
/** Get the absolute difference between 2 u32_t values (correcting overflows)
|
||||
* 'a' is expected to be 'higher' (without overflow) than 'b'. */
|
||||
#define ESP_U32_DIFF(a, b) (((a) >= (b)) ? ((a) - (b)) : (((a) + ((b) ^ 0xFFFFFFFF) + 1)))
|
||||
|
||||
void wifi_promiscuous_enable(uint8 promiscuous);
|
||||
|
||||
typedef void (* wifi_promiscuous_cb_t)(uint8 *buf, uint16 len);
|
||||
|
||||
void wifi_set_promiscuous_rx_cb(wifi_promiscuous_cb_t cb);
|
||||
|
||||
enum phy_mode {
|
||||
PHY_MODE_11B = 1,
|
||||
PHY_MODE_11G = 2,
|
||||
PHY_MODE_11N = 3
|
||||
};
|
||||
|
||||
enum phy_mode wifi_get_phy_mode(void);
|
||||
bool wifi_set_phy_mode(enum phy_mode mode);
|
||||
|
||||
enum sleep_type {
|
||||
NONE_SLEEP_T = 0,
|
||||
LIGHT_SLEEP_T,
|
||||
MODEM_SLEEP_T
|
||||
};
|
||||
|
||||
bool wifi_set_sleep_type(enum sleep_type type);
|
||||
enum sleep_type wifi_get_sleep_type(void);
|
||||
|
||||
#endif
|
||||
/*
|
||||
* Copyright (C) 2013 -2014 Espressif System
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __USER_INTERFACE_H__
|
||||
#define __USER_INTERFACE_H__
|
||||
|
||||
#include "os_type.h"
|
||||
#ifdef LWIP_OPEN_SRC
|
||||
#include "lwip/ip_addr.h"
|
||||
#else
|
||||
#include "ip_addr.h"
|
||||
#endif
|
||||
|
||||
#include "queue.h"
|
||||
#include "user_config.h"
|
||||
#include "spi_flash.h"
|
||||
|
||||
#ifndef MAC2STR
|
||||
#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
|
||||
#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
|
||||
#endif
|
||||
|
||||
enum rst_reason {
|
||||
DEFAULT_RST_FLAG = 0,
|
||||
WDT_RST_FLAG = 1,
|
||||
EXP_RST_FLAG = 2
|
||||
};
|
||||
|
||||
struct rst_info{
|
||||
uint32 flag;
|
||||
uint32 exccause;
|
||||
uint32 epc1;
|
||||
uint32 epc2;
|
||||
uint32 epc3;
|
||||
uint32 excvaddr;
|
||||
uint32 depc;
|
||||
};
|
||||
|
||||
#define UPGRADE_FW_BIN1 0x00
|
||||
#define UPGRADE_FW_BIN2 0x01
|
||||
|
||||
void system_restore(void);
|
||||
void system_restart(void);
|
||||
|
||||
bool system_deep_sleep_set_option(uint8 option);
|
||||
void system_deep_sleep(uint32 time_in_us);
|
||||
|
||||
uint8 system_upgrade_userbin_check(void);
|
||||
void system_upgrade_reboot(void);
|
||||
uint8 system_upgrade_flag_check();
|
||||
void system_upgrade_flag_set(uint8 flag);
|
||||
|
||||
void system_timer_reinit(void);
|
||||
uint32 system_get_time(void);
|
||||
|
||||
/* user task's prio must be 0/1/2 !!!*/
|
||||
enum {
|
||||
USER_TASK_PRIO_0 = 0,
|
||||
USER_TASK_PRIO_1,
|
||||
USER_TASK_PRIO_2,
|
||||
USER_TASK_PRIO_MAX
|
||||
};
|
||||
|
||||
bool system_os_task(os_task_t task, uint8 prio, os_event_t *queue, uint8 qlen);
|
||||
bool system_os_post(uint8 prio, os_signal_t sig, os_param_t par);
|
||||
|
||||
void system_print_meminfo(void);
|
||||
uint32 system_get_free_heap_size(void);
|
||||
|
||||
void system_set_os_print(uint8 onoff);
|
||||
uint8 system_get_os_print();
|
||||
|
||||
uint64 system_mktime(uint32 year, uint32 mon, uint32 day, uint32 hour, uint32 min, uint32 sec);
|
||||
|
||||
uint32 system_get_chip_id(void);
|
||||
|
||||
typedef void (* init_done_cb_t)(void);
|
||||
|
||||
void system_init_done_cb(init_done_cb_t cb);
|
||||
|
||||
uint32 system_rtc_clock_cali_proc(void);
|
||||
uint32 system_get_rtc_time(void);
|
||||
|
||||
bool system_rtc_mem_read(uint8 src_addr, void *des_addr, uint16 load_size);
|
||||
bool system_rtc_mem_write(uint8 des_addr, const void *src_addr, uint16 save_size);
|
||||
|
||||
void system_uart_swap(void);
|
||||
|
||||
uint16 system_adc_read(void);
|
||||
|
||||
const char *system_get_sdk_version(void);
|
||||
|
||||
#define NULL_MODE 0x00
|
||||
#define STATION_MODE 0x01
|
||||
#define SOFTAP_MODE 0x02
|
||||
#define STATIONAP_MODE 0x03
|
||||
|
||||
typedef enum _auth_mode {
|
||||
AUTH_OPEN = 0,
|
||||
AUTH_WEP,
|
||||
AUTH_WPA_PSK,
|
||||
AUTH_WPA2_PSK,
|
||||
AUTH_WPA_WPA2_PSK,
|
||||
AUTH_MAX
|
||||
} AUTH_MODE;
|
||||
|
||||
uint8 wifi_get_opmode(void);
|
||||
bool wifi_set_opmode(uint8 opmode);
|
||||
|
||||
struct bss_info {
|
||||
STAILQ_ENTRY(bss_info) next;
|
||||
|
||||
uint8 bssid[6];
|
||||
uint8 ssid[32];
|
||||
uint8 channel;
|
||||
sint8 rssi;
|
||||
AUTH_MODE authmode;
|
||||
uint8 is_hidden;
|
||||
};
|
||||
|
||||
typedef struct _scaninfo {
|
||||
STAILQ_HEAD(, bss_info) *pbss;
|
||||
struct espconn *pespconn;
|
||||
uint8 totalpage;
|
||||
uint8 pagenum;
|
||||
uint8 page_sn;
|
||||
uint8 data_cnt;
|
||||
} scaninfo;
|
||||
|
||||
typedef void (* scan_done_cb_t)(void *arg, STATUS status);
|
||||
|
||||
struct station_config {
|
||||
uint8 ssid[32];
|
||||
uint8 password[64];
|
||||
uint8 bssid_set; // Note: If bssid_set is 1, station will just connect to the router
|
||||
// with both ssid[] and bssid[] matched. Please check about this.
|
||||
uint8 bssid[6];
|
||||
};
|
||||
|
||||
bool wifi_station_get_config(struct station_config *config);
|
||||
bool wifi_station_set_config(struct station_config *config);
|
||||
|
||||
bool wifi_station_connect(void);
|
||||
bool wifi_station_disconnect(void);
|
||||
|
||||
struct scan_config {
|
||||
uint8 *ssid; // Note: ssid == NULL, don't filter ssid.
|
||||
uint8 *bssid; // Note: bssid == NULL, don't filter bssid.
|
||||
uint8 channel; // Note: channel == 0, scan all channels, otherwise scan set channel.
|
||||
uint8 show_hidden; // Note: show_hidden == 1, can get hidden ssid routers' info.
|
||||
};
|
||||
|
||||
bool wifi_station_scan(struct scan_config *config, scan_done_cb_t cb);
|
||||
|
||||
uint8 wifi_station_get_auto_connect(void);
|
||||
bool wifi_station_set_auto_connect(uint8 set);
|
||||
|
||||
enum {
|
||||
STATION_IDLE = 0,
|
||||
STATION_CONNECTING,
|
||||
STATION_WRONG_PASSWORD,
|
||||
STATION_NO_AP_FOUND,
|
||||
STATION_CONNECT_FAIL,
|
||||
STATION_GOT_IP
|
||||
};
|
||||
|
||||
enum dhcp_status {
|
||||
DHCP_STOPPED,
|
||||
DHCP_STARTED
|
||||
};
|
||||
|
||||
uint8 wifi_station_get_connect_status(void);
|
||||
|
||||
uint8 wifi_station_get_current_ap_id(void);
|
||||
bool wifi_station_ap_change(uint8 current_ap_id);
|
||||
bool wifi_station_ap_number_set(uint8 ap_number);
|
||||
|
||||
bool wifi_station_dhcpc_start(void);
|
||||
bool wifi_station_dhcpc_stop(void);
|
||||
enum dhcp_status wifi_station_dhcpc_status(void);
|
||||
|
||||
struct softap_config {
|
||||
uint8 ssid[32];
|
||||
uint8 password[64];
|
||||
uint8 ssid_len; // Note: Recommend to set it according to your ssid
|
||||
uint8 channel; // Note: support 1 ~ 13
|
||||
AUTH_MODE authmode; // Note: Don't support AUTH_WEP in softAP mode.
|
||||
uint8 ssid_hidden; // Note: default 0
|
||||
uint8 max_connection; // Note: default 4, max 4
|
||||
uint16 beacon_interval; // Note: support 100 ~ 60000 ms, default 100
|
||||
};
|
||||
|
||||
bool wifi_softap_get_config(struct softap_config *config);
|
||||
bool wifi_softap_set_config(struct softap_config *config);
|
||||
|
||||
struct station_info {
|
||||
STAILQ_ENTRY(station_info) next;
|
||||
|
||||
uint8 bssid[6];
|
||||
struct ip_addr ip;
|
||||
};
|
||||
|
||||
struct dhcps_lease {
|
||||
uint32 start_ip;
|
||||
uint32 end_ip;
|
||||
};
|
||||
|
||||
struct station_info * wifi_softap_get_station_info(void);
|
||||
void wifi_softap_free_station_info(void);
|
||||
uint8 wifi_station_get_ap_info(struct station_config config[]);
|
||||
|
||||
bool wifi_softap_dhcps_start(void);
|
||||
bool wifi_softap_dhcps_stop(void);
|
||||
bool wifi_softap_set_dhcps_lease(struct dhcps_lease *please);
|
||||
enum dhcp_status wifi_softap_dhcps_status(void);
|
||||
|
||||
#define STATION_IF 0x00
|
||||
#define SOFTAP_IF 0x01
|
||||
|
||||
bool wifi_get_ip_info(uint8 if_index, struct ip_info *info);
|
||||
bool wifi_set_ip_info(uint8 if_index, struct ip_info *info);
|
||||
bool wifi_get_macaddr(uint8 if_index, uint8 *macaddr);
|
||||
bool wifi_set_macaddr(uint8 if_index, uint8 *macaddr);
|
||||
|
||||
uint8 wifi_get_channel(void);
|
||||
bool wifi_set_channel(uint8 channel);
|
||||
|
||||
void wifi_status_led_install(uint8 gpio_id, uint32 gpio_name, uint8 gpio_func);
|
||||
void wifi_status_led_uninstall();
|
||||
|
||||
/** Get the absolute difference between 2 u32_t values (correcting overflows)
|
||||
* 'a' is expected to be 'higher' (without overflow) than 'b'. */
|
||||
#define ESP_U32_DIFF(a, b) (((a) >= (b)) ? ((a) - (b)) : (((a) + ((b) ^ 0xFFFFFFFF) + 1)))
|
||||
|
||||
void wifi_promiscuous_enable(uint8 promiscuous);
|
||||
|
||||
typedef void (* wifi_promiscuous_cb_t)(uint8 *buf, uint16 len);
|
||||
|
||||
void wifi_set_promiscuous_rx_cb(wifi_promiscuous_cb_t cb);
|
||||
|
||||
enum phy_mode {
|
||||
PHY_MODE_11B = 1,
|
||||
PHY_MODE_11G = 2,
|
||||
PHY_MODE_11N = 3
|
||||
};
|
||||
|
||||
enum phy_mode wifi_get_phy_mode(void);
|
||||
bool wifi_set_phy_mode(enum phy_mode mode);
|
||||
|
||||
enum sleep_type {
|
||||
NONE_SLEEP_T = 0,
|
||||
LIGHT_SLEEP_T,
|
||||
MODEM_SLEEP_T
|
||||
};
|
||||
|
||||
bool wifi_set_sleep_type(enum sleep_type type);
|
||||
enum sleep_type wifi_get_sleep_type(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -5,7 +5,7 @@ MEMORY
|
|||
dport0_0_seg : org = 0x3FF00000, len = 0x10
|
||||
dram0_0_seg : org = 0x3FFE8000, len = 0x14000
|
||||
iram1_0_seg : org = 0x40100000, len = 0x8000
|
||||
irom0_0_seg : org = 0x40210000, len = 0x50000
|
||||
irom0_0_seg : org = 0x40210000, len = 0x51000
|
||||
}
|
||||
|
||||
PHDRS
|
||||
|
|
|
@ -18,6 +18,7 @@ PROVIDE ( SHA1Transform = 0x4000a364 );
|
|||
PROVIDE ( SHA1Update = 0x4000b5a8 );
|
||||
PROVIDE ( SPI_read_status = 0x400043c8 );
|
||||
PROVIDE ( SPI_write_status = 0x40004400 );
|
||||
PROVIDE ( SPI_write_enable = 0x4000443c );
|
||||
PROVIDE ( Wait_SPI_Idle = 0x4000448c );
|
||||
PROVIDE ( SPIEraseArea = 0x40004b44 );
|
||||
PROVIDE ( SPIEraseBlock = 0x400049b4 );
|
||||
|
|
Binary file not shown.
BIN
lib/libjson.a
BIN
lib/libjson.a
Binary file not shown.
BIN
lib/liblwip.a
BIN
lib/liblwip.a
Binary file not shown.
BIN
lib/libmain.a
BIN
lib/libmain.a
Binary file not shown.
Binary file not shown.
BIN
lib/libphy.a
BIN
lib/libphy.a
Binary file not shown.
BIN
lib/libpp.a
BIN
lib/libpp.a
Binary file not shown.
Binary file not shown.
BIN
lib/libssl.a
BIN
lib/libssl.a
Binary file not shown.
BIN
lib/libupgrade.a
BIN
lib/libupgrade.a
Binary file not shown.
BIN
lib/libwpa.a
BIN
lib/libwpa.a
Binary file not shown.
|
@ -0,0 +1,74 @@
|
|||
------------------------------------------------------------------------------
|
||||
-- IR send module
|
||||
--
|
||||
-- LICENCE: http://opensource.org/licenses/MIT
|
||||
-- Vladimir Dronnikov <dronnikov@gmail.com>
|
||||
--
|
||||
-- Example:
|
||||
-- require("irsend").nec(4, 0x00ff00ff)
|
||||
------------------------------------------------------------------------------
|
||||
local M
|
||||
do
|
||||
-- const
|
||||
local NEC_PULSE_US = 1000000 / 38000
|
||||
local NEC_HDR_MARK = 9000
|
||||
local NEC_HDR_SPACE = 4500
|
||||
local NEC_BIT_MARK = 560
|
||||
local NEC_ONE_SPACE = 1600
|
||||
local NEC_ZERO_SPACE = 560
|
||||
local NEC_RPT_SPACE = 2250
|
||||
-- cache
|
||||
local gpio, bit = gpio, bit
|
||||
local mode, write = gpio.mode, gpio.write
|
||||
local waitus = tmr.delay
|
||||
local isset = bit.isset
|
||||
-- NB: poorman 38kHz PWM with 1/3 duty. Touch with care! )
|
||||
local carrier = function(pin, c)
|
||||
c = c / NEC_PULSE_US
|
||||
while c > 0 do
|
||||
write(pin, 1)
|
||||
write(pin, 0)
|
||||
c = c + 0
|
||||
c = c + 0
|
||||
c = c + 0
|
||||
c = c + 0
|
||||
c = c + 0
|
||||
c = c + 0
|
||||
c = c * 1
|
||||
c = c * 1
|
||||
c = c * 1
|
||||
c = c - 1
|
||||
end
|
||||
end
|
||||
-- tsop signal simulator
|
||||
local pull = function(pin, c)
|
||||
write(pin, 0)
|
||||
waitus(c)
|
||||
write(pin, 1)
|
||||
end
|
||||
-- NB: tsop mode allows to directly connect pin
|
||||
-- inplace of TSOP input
|
||||
local nec = function(pin, code, tsop)
|
||||
local pulse = tsop and pull or carrier
|
||||
-- setup transmitter
|
||||
mode(pin, 1)
|
||||
write(pin, tsop and 1 or 0)
|
||||
-- header
|
||||
pulse(pin, NEC_HDR_MARK)
|
||||
waitus(NEC_HDR_SPACE)
|
||||
-- sequence, lsb first
|
||||
for i = 0, 31 do
|
||||
pulse(pin, NEC_BIT_MARK)
|
||||
waitus(isset(code, i) and NEC_ONE_SPACE or NEC_ZERO_SPACE)
|
||||
end
|
||||
-- trailer
|
||||
pulse(pin, NEC_BIT_MARK)
|
||||
-- done transmitter
|
||||
--mode(pin, 0, tsop and 1 or 0)
|
||||
end
|
||||
-- expose
|
||||
M = {
|
||||
nec = nec,
|
||||
}
|
||||
end
|
||||
return M
|
|
@ -0,0 +1,16 @@
|
|||
uart.setup(0,9600,8,0,1,0)
|
||||
sv=net.createServer(net.TCP, 60)
|
||||
global_c = nil
|
||||
sv:listen(9999, function(c)
|
||||
if global_c~=nil then
|
||||
global_c:close()
|
||||
end
|
||||
global_c=c
|
||||
c:on("receive",function(sck,pl) uart.write(0,pl) end)
|
||||
end)
|
||||
|
||||
uart.on("data",4, function(data)
|
||||
if global_c~=nil then
|
||||
global_c:send(data)
|
||||
end
|
||||
end, 0)
|
|
@ -0,0 +1,84 @@
|
|||
------------------------------------------------------------------------------
|
||||
-- DHT11/22 query module
|
||||
--
|
||||
-- LICENCE: http://opensource.org/licenses/MIT
|
||||
-- Vladimir Dronnikov <dronnikov@gmail.com>
|
||||
--
|
||||
-- Example:
|
||||
-- print("DHT11", require("dht22").read(4))
|
||||
-- print("DHT22", require("dht22").read(4, true))
|
||||
-- NB: the very first read sometimes fails
|
||||
------------------------------------------------------------------------------
|
||||
local M
|
||||
do
|
||||
-- cache
|
||||
local gpio = gpio
|
||||
local val = gpio.read
|
||||
local waitus = tmr.delay
|
||||
--
|
||||
local read = function(pin, dht22)
|
||||
-- wait for pin value
|
||||
local w = function(v)
|
||||
local c = 255
|
||||
while c > 0 and val(pin) ~= v do c = c - 1 end
|
||||
return c
|
||||
end
|
||||
-- NB: we preallocate incoming data buffer
|
||||
-- or precise timing in reader gets broken
|
||||
local b = { 0, 0, 0, 0, 0 }
|
||||
|
||||
-- kick the device
|
||||
gpio.mode(pin, gpio.INPUT, gpio.PULLUP)
|
||||
gpio.write(pin, 1)
|
||||
waitus(10)
|
||||
gpio.mode(pin, gpio.OUTPUT)
|
||||
gpio.write(pin, 0)
|
||||
waitus(20000)
|
||||
gpio.write(pin, 1)
|
||||
gpio.mode(pin, gpio.INPUT, gpio.PULLUP)
|
||||
-- wait for device presense
|
||||
if w(0) == 0 or w(1) == 0 or w(0) == 0 then
|
||||
return nil, 0
|
||||
end
|
||||
-- receive 5 octets of data, msb first
|
||||
for i = 1, 5 do
|
||||
local x = 0
|
||||
for j = 1, 8 do
|
||||
x = x + x
|
||||
if w(1) == 0 then return nil, 1 end
|
||||
-- 70us for 1, 27 us for 0
|
||||
waitus(30)
|
||||
if val(pin) == 1 then
|
||||
x = x + 1
|
||||
if w(0) == 0 then return nil, 2 end
|
||||
end
|
||||
end
|
||||
b[i] = x
|
||||
end
|
||||
-- check crc. NB: calculating in receiver loop breaks timings
|
||||
local crc = 0
|
||||
for i = 1, 4 do
|
||||
crc = (crc + b[i]) % 256
|
||||
end
|
||||
if crc ~= b[5] then return nil, 3 end
|
||||
-- convert
|
||||
local t, h
|
||||
-- DHT22: values in tenths of unit, temperature can be negative
|
||||
if dht22 then
|
||||
h = b[1] * 256 + b[2]
|
||||
t = b[3] * 256 + b[4]
|
||||
if t > 0x8000 then t = -(t - 0x8000) end
|
||||
-- DHT11: no negative temperatures, only integers
|
||||
-- NB: return in 0.1 Celsius
|
||||
else
|
||||
h = 10 * b[1]
|
||||
t = 10 * b[3]
|
||||
end
|
||||
return t, h
|
||||
end
|
||||
-- expose interface
|
||||
M = {
|
||||
read = read,
|
||||
}
|
||||
end
|
||||
return M
|
|
@ -0,0 +1,65 @@
|
|||
------------------------------------------------------------------------------
|
||||
-- DS18B20 query module
|
||||
--
|
||||
-- LICENCE: http://opensource.org/licenses/MIT
|
||||
-- Vladimir Dronnikov <dronnikov@gmail.com>
|
||||
--
|
||||
-- Example:
|
||||
-- for k, v in pairs(require("ds18b20").read(4)) do print(k, v) end
|
||||
------------------------------------------------------------------------------
|
||||
local M
|
||||
do
|
||||
local format_addr = function(a)
|
||||
return ("%02x-%02x%02x%02x%02x%02x%02x"):format(
|
||||
a:byte(1),
|
||||
a:byte(7), a:byte(6), a:byte(5),
|
||||
a:byte(4), a:byte(3), a:byte(2)
|
||||
)
|
||||
end
|
||||
local read = function(pin, delay)
|
||||
local ow = require("ow")
|
||||
-- get list of relevant devices
|
||||
local d = { }
|
||||
ow.setup(pin)
|
||||
ow.reset_search(pin)
|
||||
while true do
|
||||
tmr.wdclr()
|
||||
local a = ow.search(pin)
|
||||
if not a then break end
|
||||
if ow.crc8(a) == 0 and
|
||||
(a:byte(1) == 0x10 or a:byte(1) == 0x28)
|
||||
then
|
||||
d[#d + 1] = a
|
||||
end
|
||||
end
|
||||
-- conversion command for all
|
||||
ow.reset(pin)
|
||||
ow.skip(pin)
|
||||
ow.write(pin, 0x44, 1)
|
||||
-- wait a bit
|
||||
tmr.delay(delay or 100000)
|
||||
-- iterate over devices
|
||||
local r = { }
|
||||
for i = 1, #d do
|
||||
tmr.wdclr()
|
||||
-- read rom command
|
||||
ow.reset(pin)
|
||||
ow.select(pin, d[i])
|
||||
ow.write(pin, 0xBE, 1)
|
||||
-- read data
|
||||
local x = ow.read_bytes(pin, 9)
|
||||
if ow.crc8(x) == 0 then
|
||||
local t = (x:byte(1) + x:byte(2) * 256) * 625
|
||||
-- NB: temperature in Celcius * 10^4
|
||||
r[format_addr(d[i])] = t
|
||||
d[i] = nil
|
||||
end
|
||||
end
|
||||
return r
|
||||
end
|
||||
-- expose
|
||||
M = {
|
||||
read = read,
|
||||
}
|
||||
end
|
||||
return M
|
|
@ -0,0 +1,54 @@
|
|||
-- ***************************************************************************
|
||||
-- BH1750 module for ESP8266 with nodeMCU
|
||||
-- BH1750 compatible tested 2015-1-22
|
||||
--
|
||||
-- Written by xiaohu
|
||||
--
|
||||
-- MIT license, http://opensource.org/licenses/MIT
|
||||
-- ***************************************************************************
|
||||
local moduleName = ...
|
||||
local M = {}
|
||||
_G[moduleName] = M
|
||||
--I2C slave address of GY-30
|
||||
local GY_30_address = 0X23
|
||||
-- i2c interface ID
|
||||
local id = 0
|
||||
--LUX
|
||||
local l
|
||||
--CMD
|
||||
local CMD = 0x10
|
||||
local init = false
|
||||
function M.init(sda, scl)
|
||||
i2c.setup(id, sda, scl, i2c.SLOW)
|
||||
--print("i2c ok..")
|
||||
init = true
|
||||
end
|
||||
local function read_data(ADDR, commands, length)
|
||||
i2c.start(id)
|
||||
i2c.address(id, ADDR, i2c.TRANSMITTER)
|
||||
i2c.write(id, commands)
|
||||
i2c.stop(id)
|
||||
i2c.start(id)
|
||||
i2c.address(id, ADDR,i2c.RECEIVER)
|
||||
tmr.delay(200000)
|
||||
c = i2c.read(id, length)
|
||||
i2c.stop(id)
|
||||
return c
|
||||
end
|
||||
local function read_lux()
|
||||
dataT = read_data(GY_30_address, CMD, 2)
|
||||
UT = string.byte(dataT, 1) * 256 + string.byte(dataT, 2)
|
||||
l = (UT*1000/12)
|
||||
return(l)
|
||||
end
|
||||
function M.read()
|
||||
if (not init) then
|
||||
print("init() must be called before read.")
|
||||
else
|
||||
read_lux()
|
||||
end
|
||||
end
|
||||
function M.getlux()
|
||||
return l
|
||||
end
|
||||
return M
|
|
@ -0,0 +1,104 @@
|
|||
# BH1750 模块
|
||||
|
||||
##引用
|
||||
```lua
|
||||
bh1750 = require("bh1750")
|
||||
```
|
||||
## 释放
|
||||
```lua
|
||||
bh1750 = nil
|
||||
package.loaded["bh1750"]=nil
|
||||
```
|
||||
<a id="bh1750_init"></a>
|
||||
##init()
|
||||
####描述
|
||||
设置BH1750所在的I2C引脚<br />
|
||||
|
||||
####语法
|
||||
init(sda, scl)
|
||||
|
||||
####参数
|
||||
sda: 1~12, IO index.<br />
|
||||
scl: 1~12, IO index.<br />
|
||||
|
||||
####返回值
|
||||
nil
|
||||
|
||||
####示例
|
||||
```lua
|
||||
SDA_PIN = 6 -- sda pin, GPIO12
|
||||
SCL_PIN = 5 -- scl pin, GPIO14
|
||||
|
||||
bh1750 = require("bh1750")
|
||||
bh1750.init(SDA_PIN, SCL_PIN)
|
||||
|
||||
-- release module
|
||||
bh1750 = nil
|
||||
package.loaded["bh1750"]=nil
|
||||
```
|
||||
|
||||
####参见
|
||||
**-** []()
|
||||
|
||||
<a id="bh1750_read"></a>
|
||||
##read()
|
||||
####描述
|
||||
从bh1750中读取光线传感器数据(Lux勒克斯).<br />
|
||||
|
||||
####语法
|
||||
read()
|
||||
|
||||
####参数
|
||||
nil.<br />
|
||||
|
||||
####返回值
|
||||
nil.<br />
|
||||
|
||||
####示例
|
||||
```lua
|
||||
SDA_PIN = 6 -- sda pin, GPIO12
|
||||
SCL_PIN = 5 -- scl pin, GPIO14
|
||||
|
||||
bh1750 = require("bh1750")
|
||||
bh1750.init(SDA_PIN, SCL_PIN)
|
||||
bh1750.read()
|
||||
|
||||
-- release module
|
||||
bh1750 = nil
|
||||
package.loaded["bh1750"]=nil
|
||||
```
|
||||
|
||||
####参见
|
||||
**-** []()
|
||||
|
||||
<a id="bh1750_getlux"></a>
|
||||
##getlux()
|
||||
####描述
|
||||
从BH1750中提取数据.<br />
|
||||
|
||||
####语法
|
||||
getlux()
|
||||
|
||||
####参数
|
||||
nil.<br />
|
||||
|
||||
####返回值
|
||||
l: 整数,Lux计数
|
||||
####示例
|
||||
```lua
|
||||
SDA_PIN = 6 -- sda pin, GPIO12
|
||||
SCL_PIN = 5 -- scl pin, GPIO14
|
||||
|
||||
bh1750 = require("bh1750")
|
||||
bh1750.init(SDA_PIN, SCL_PIN)
|
||||
bh1750.read()
|
||||
l = bh1750.getlux()
|
||||
print("lux: "..(l / 100).."."..(l % 100).." lx")
|
||||
|
||||
-- release module
|
||||
bh1750 = nil
|
||||
package.loaded["bh1750"]=nil
|
||||
```
|
||||
|
||||
####参见
|
||||
**-** []()
|
|
@ -0,0 +1,105 @@
|
|||
# bh1750 Module
|
||||
|
||||
##Require
|
||||
```lua
|
||||
bh1750 = require("bh1750")
|
||||
```
|
||||
## Release
|
||||
```lua
|
||||
bh1750 = nil
|
||||
package.loaded["bh1750"]=nil
|
||||
```
|
||||
<a id="bh1750_init"></a>
|
||||
##init()
|
||||
####Description
|
||||
Setting the I2C pin of bh1750.<br />
|
||||
|
||||
####Syntax
|
||||
init(sda, scl)
|
||||
|
||||
####Parameters
|
||||
sda: 1~12, IO index.<br />
|
||||
scl: 1~12, IO index.<br />
|
||||
|
||||
####Returns
|
||||
nil
|
||||
|
||||
####Example
|
||||
```lua
|
||||
SDA_PIN = 6 -- sda pin, GPIO12
|
||||
SCL_PIN = 5 -- scl pin, GPIO14
|
||||
|
||||
bh1750 = require("bh1750")
|
||||
bh1750.init(SDA_PIN, SCL_PIN)
|
||||
|
||||
-- release module
|
||||
bh1750 = nil
|
||||
package.loaded["bh1750"]=nil
|
||||
```
|
||||
|
||||
####See also
|
||||
**-** []()
|
||||
|
||||
<a id="bh1750_read"></a>
|
||||
##read()
|
||||
####Description
|
||||
Read Lux data from bh1750.<br />
|
||||
|
||||
####Syntax
|
||||
read()
|
||||
|
||||
####Parameters
|
||||
nil.<br />
|
||||
|
||||
####Returns
|
||||
nil.<br />
|
||||
|
||||
####Example
|
||||
```lua
|
||||
SDA_PIN = 6 -- sda pin, GPIO12
|
||||
SCL_PIN = 5 -- scl pin, GPIO14
|
||||
|
||||
bh1750 = require("bh1750")
|
||||
bh1750.init(SDA_PIN, SCL_PIN)
|
||||
bh1750.read()
|
||||
|
||||
-- release module
|
||||
bh1750 = nil
|
||||
package.loaded["bh1750"]=nil
|
||||
```
|
||||
|
||||
####See also
|
||||
**-** []()
|
||||
|
||||
<a id="bh1750_getlux"></a>
|
||||
##getlux()
|
||||
####Description
|
||||
Get lux from bh1750.<br />
|
||||
|
||||
####Syntax
|
||||
getlux()
|
||||
|
||||
####Parameters
|
||||
nil.<br />
|
||||
|
||||
####Returns
|
||||
l: Integer, getlux from bh1750.
|
||||
|
||||
####Example
|
||||
```lua
|
||||
SDA_PIN = 6 -- sda pin, GPIO12
|
||||
SCL_PIN = 5 -- scl pin, GPIO14
|
||||
|
||||
bh1750 = require("bh1750")
|
||||
bh1750.init(SDA_PIN, SCL_PIN)
|
||||
bh1750.read()
|
||||
l = bh1750.getlux()
|
||||
print("lux: "..(l / 100).."."..(l % 100).." lx")
|
||||
|
||||
-- release module
|
||||
bh1750 = nil
|
||||
package.loaded["bh1750"]=nil
|
||||
```
|
||||
|
||||
####See also
|
||||
**-** []()
|
|
@ -0,0 +1,24 @@
|
|||
-- ***************************************************************************
|
||||
-- BH1750 Example Program for ESP8266 with nodeMCU
|
||||
-- BH1750 compatible tested 2015-1-30
|
||||
--
|
||||
-- Written by xiaohu
|
||||
--
|
||||
-- MIT license, http://opensource.org/licenses/MIT
|
||||
-- ***************************************************************************
|
||||
tmr.alarm(0, 10000, 1, function()
|
||||
|
||||
SDA_PIN = 6 -- sda pin, GPIO12
|
||||
SCL_PIN = 5 -- scl pin, GPIO14
|
||||
|
||||
bh1750 = require("bh1750")
|
||||
bh1750.init(SDA_PIN, SCL_PIN)
|
||||
bh1750.read(OSS)
|
||||
l = bh1750.getlux()
|
||||
print("lux: "..(l / 100).."."..(l % 100).." lx")
|
||||
|
||||
-- release module
|
||||
bh1750 = nil
|
||||
package.loaded["bh1750"]=nil
|
||||
|
||||
end)
|
|
@ -0,0 +1,51 @@
|
|||
-- ***************************************************************************
|
||||
-- BH1750 Example Program for ESP8266 with nodeMCU
|
||||
-- BH1750 compatible tested 2015-1-30
|
||||
--
|
||||
-- Written by xiaohu
|
||||
--
|
||||
-- MIT license, http://opensource.org/licenses/MIT
|
||||
-- ***************************************************************************
|
||||
--Updata to Lelian
|
||||
|
||||
--Ps 需要改动的地方LW_GATEWAY(乐联的设备标示),USERKEY(乐联userkey)
|
||||
--Ps You nees to rewrite the LW_GATEWAY(Lelian's Device ID),USERKEY(Lelian's userkey)
|
||||
|
||||
tmr.alarm(0, 60000, 1, function()
|
||||
SDA_PIN = 6 -- sda pin, GPIO12
|
||||
SCL_PIN = 5 -- scl pin, GPIO14
|
||||
|
||||
BH1750 = require("BH1750")
|
||||
BH1750.init(SDA_PIN, SCL_PIN)
|
||||
BH1750.read(OSS)
|
||||
l = BH1750.getlux()
|
||||
|
||||
--定义数据变量格式 Define the veriables formate
|
||||
PostData = "[{\"Name\":\"T\",\"Value\":\"" ..(l / 100).."."..(l % 100).."\"}]"
|
||||
--创建一个TCP连接 Create a TCP Connection
|
||||
socket=net.createConnection(net.TCP, 0)
|
||||
--域名解析IP地址并赋值 DNS...it
|
||||
socket:dns("www.lewei50.com", function(conn, ip)
|
||||
ServerIP = ip
|
||||
print("Connection IP:" .. ServerIP)
|
||||
end)
|
||||
|
||||
--开始连接服务器 Connect the sever
|
||||
socket:connect(80, ServerIP)
|
||||
socket:on("connection", function(sck) end)
|
||||
|
||||
--HTTP请求头定义 HTTP Head
|
||||
socket:send("POST /api/V1/gateway/UpdateSensors/LW_GATEWAY HTTP/1.1\r\n" ..
|
||||
"Host: www.lewei50.com\r\n" ..
|
||||
"Content-Length: " .. string.len(PostData) .. "\r\n" ..
|
||||
"userkey: USERKEY\r\n\r\n" ..
|
||||
PostData .. "\r\n")
|
||||
|
||||
--HTTP响应内容 Print the HTTP response
|
||||
socket:on("receive", function(sck, response)
|
||||
print(response)
|
||||
end)
|
||||
end)
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,166 @@
|
|||
# BMP085 module
|
||||
|
||||
##Require
|
||||
```lua
|
||||
bmp085 = require("bmp085")
|
||||
```
|
||||
## Release
|
||||
```lua
|
||||
bmp085 = nil
|
||||
package.loaded["bmp085"]=nil
|
||||
```
|
||||
<a id="bmp085_init"></a>
|
||||
##init()
|
||||
####Description
|
||||
Setting the i2c pin of bmp085.<br />
|
||||
|
||||
####Syntax
|
||||
init(sda, scl)
|
||||
|
||||
####Parameters
|
||||
sda: 1~12, IO index.<br />
|
||||
scl: 1~12, IO index.<br />
|
||||
|
||||
####Returns
|
||||
nil
|
||||
|
||||
####Example
|
||||
```lua
|
||||
bmp085 = require("bmp085")
|
||||
gpio5 = 1
|
||||
gpio4 = 2
|
||||
sda = gpio5
|
||||
scl = gpio4
|
||||
bmp085.init(sda, scl)
|
||||
-- Don't forget to release it after use
|
||||
bmp085 = nil
|
||||
package.loaded["bmp085"]=nil
|
||||
```
|
||||
|
||||
####See also
|
||||
**-** []()
|
||||
|
||||
<a id="bmp085_getUP"></a>
|
||||
##getUP()
|
||||
####Description
|
||||
Get calibrated data of pressure from bmp085.<br />
|
||||
|
||||
####Syntax
|
||||
getUP(oss)
|
||||
|
||||
####Parameters
|
||||
oss: Over sampling setting, which is 0,1,2,3. Default value is 0.<br />
|
||||
|
||||
####Returns
|
||||
p: Integer, calibrated data of pressure from bmp085.
|
||||
|
||||
####Example
|
||||
```lua
|
||||
bmp085 = require("bmp085")
|
||||
sda = 1
|
||||
scl = 2
|
||||
bmp085.init(sda, scl)
|
||||
p = bmp085.getUP(oss)
|
||||
print(p)
|
||||
-- Don't forget to release it after use
|
||||
bmp085 = nil
|
||||
package.loaded["bmp085"]=nil
|
||||
```
|
||||
|
||||
####See also
|
||||
**-** []()
|
||||
|
||||
<a id="bmp085_getUP_raw"></a>
|
||||
##getUP_raw()
|
||||
####Description
|
||||
Get raw data of pressure from bmp085.<br />
|
||||
|
||||
####Syntax
|
||||
getUP_raw(oss)
|
||||
|
||||
####Parameters
|
||||
oss: Over sampling setting, which is 0,1,2,3. Default value is 0.<br />
|
||||
|
||||
####Returns
|
||||
up_raw: Integer, raw data of pressure from bmp085.
|
||||
|
||||
####Example
|
||||
```lua
|
||||
bmp085 = require("bmp085")
|
||||
sda = 1
|
||||
scl = 2
|
||||
bmp085.init(sda, scl)
|
||||
up = bmp085.getUP_raw(oss)
|
||||
print(up)
|
||||
-- Don't forget to release it after use
|
||||
bmp085 = nil
|
||||
package.loaded["bmp085"]=nil
|
||||
```
|
||||
|
||||
####See also
|
||||
**-** []()
|
||||
|
||||
<a id="bmp085_getUT"></a>
|
||||
##getUT()
|
||||
####Description
|
||||
Get temperature from bmp085.<br />
|
||||
|
||||
####Syntax
|
||||
getUT(num_10x)
|
||||
|
||||
####Parameters
|
||||
num_10x: num_10x: bool value, if true, return number of 0.1 centi-degree. Default value is false, which return a string , eg: 16.7.<br />
|
||||
|
||||
####Returns
|
||||
t: Integer or String, if num_10x is true, return number of 0.1 centi-degree, otherwise return a string.The temperature from bmp085.<br />
|
||||
|
||||
####Example
|
||||
```lua
|
||||
bmp085 = require("bmp085")
|
||||
sda = 1
|
||||
scl = 2
|
||||
bmp085.init(sda, scl)
|
||||
-- Get string of temperature.
|
||||
p = bmp085.getUT(false)
|
||||
print(p)
|
||||
-- Get number of temperature.
|
||||
p = bmp085.getUT(true)
|
||||
print(p)
|
||||
-- Don't forget to release it after use
|
||||
bmp085 = nil
|
||||
package.loaded["bmp085"]=nil
|
||||
```
|
||||
|
||||
####See also
|
||||
**-** []()
|
||||
|
||||
<a id="bmp085_getAL"></a>
|
||||
##getAL()
|
||||
####Description
|
||||
Get estimated data of altitude from bmp085.<br />
|
||||
|
||||
####Syntax
|
||||
getAL(oss)
|
||||
|
||||
####Parameters
|
||||
oss: over sampling setting, which is 0,1,2,3. Default value is 0.<br />
|
||||
|
||||
####Returns
|
||||
e: Integer, estimated data of altitude. Altitudi can be calculated by pressure refer to sea level pressure, which is 101325. Pressure changes 100pa corresponds to 8.43m at sea level<br />
|
||||
|
||||
####Example
|
||||
```lua
|
||||
bmp085 = require("bmp085")
|
||||
sda = 1
|
||||
scl = 2
|
||||
bmp085.init(sda, scl)
|
||||
-- Get string of temperature.
|
||||
e = bmp085.getAL()
|
||||
print(p)
|
||||
-- Don't forget to release it after use
|
||||
bmp085 = nil
|
||||
package.loaded["bmp085"]=nil
|
||||
```
|
||||
|
||||
####See also
|
||||
**-** []()
|
|
@ -0,0 +1,52 @@
|
|||
# DHT22 module
|
||||
|
||||
This module is compatible with DHT22 and DHT21.
|
||||
No need to use a resistor to connect the pin data of DHT22 to ESP8266.
|
||||
|
||||
## Example
|
||||
```lua
|
||||
PIN = 4 -- data pin, GPIO2
|
||||
|
||||
dht22 = require("dht22")
|
||||
dht22.read(PIN)
|
||||
t = dht22.getTemperature()
|
||||
h = dht22.getHumidity()
|
||||
|
||||
if h == -1 then
|
||||
print("Error reading from DHT22")
|
||||
else
|
||||
-- temperature in degrees Celsius and Farenheit
|
||||
print("Temperature: "..(t / 10).."."..(t % 10).." deg C")
|
||||
print("Temperature: "..(9 * t / 50 + 32).."."..(9 * t / 5 % 10).." deg F")
|
||||
|
||||
-- humidity
|
||||
print("Humidity: "..(h/10).."."..(h%10).."%")
|
||||
end
|
||||
|
||||
-- release module
|
||||
dht22 = nil
|
||||
package.loaded["dht22"]=nil
|
||||
```
|
||||
## Functions
|
||||
### read
|
||||
read(pin)
|
||||
Read humidity and temperature from DHT22.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
* pin - ESP8266 pin connect to data pin in DHT22
|
||||
|
||||
### getHumidity
|
||||
getHumidity()
|
||||
Returns the humidity of the last reading.
|
||||
|
||||
**Returns:**
|
||||
* last humidity reading in per thousand
|
||||
|
||||
### getTemperature
|
||||
getTemperature()
|
||||
Returns the temperature of the last reading.
|
||||
|
||||
**Returns:**
|
||||
* last temperature reading in 0.1ºC
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
-- ***************************************************************************
|
||||
-- DHT22 module for ESP8266 with nodeMCU
|
||||
--
|
||||
-- Written by Javier Yanez
|
||||
-- but based on a script of Pigs Fly from ESP8266.com forum
|
||||
--
|
||||
-- MIT license, http://opensource.org/licenses/MIT
|
||||
-- ***************************************************************************
|
||||
|
||||
local moduleName = ...
|
||||
local M = {}
|
||||
_G[moduleName] = M
|
||||
|
||||
local humidity
|
||||
local temperature
|
||||
|
||||
function M.read(pin)
|
||||
local checksum
|
||||
local checksumTest
|
||||
humidity = 0
|
||||
temperature = 0
|
||||
checksum = 0
|
||||
|
||||
-- Use Markus Gritsch trick to speed up read/write on GPIO
|
||||
local gpio_read = gpio.read
|
||||
|
||||
local bitStream = {}
|
||||
for j = 1, 40, 1 do
|
||||
bitStream[j] = 0
|
||||
end
|
||||
local bitlength = 0
|
||||
|
||||
-- Step 1: send out start signal to DHT22
|
||||
gpio.mode(pin, gpio.OUTPUT)
|
||||
gpio.write(pin, gpio.HIGH)
|
||||
tmr.delay(100)
|
||||
gpio.write(pin, gpio.LOW)
|
||||
tmr.delay(20000)
|
||||
gpio.write(pin, gpio.HIGH)
|
||||
gpio.mode(pin, gpio.INPUT)
|
||||
|
||||
-- Step 2: DHT22 send response signal
|
||||
-- bus will always let up eventually, don't bother with timeout
|
||||
while (gpio_read(pin) == 0 ) do end
|
||||
local c=0
|
||||
while (gpio_read(pin) == 1 and c < 500) do c = c + 1 end
|
||||
-- bus will always let up eventually, don't bother with timeout
|
||||
while (gpio_read(pin) == 0 ) do end
|
||||
c=0
|
||||
while (gpio_read(pin) == 1 and c < 500) do c = c + 1 end
|
||||
|
||||
-- Step 3: DHT22 send data
|
||||
for j = 1, 40, 1 do
|
||||
while (gpio_read(pin) == 1 and bitlength < 10 ) do
|
||||
bitlength = bitlength + 1
|
||||
end
|
||||
bitStream[j] = bitlength
|
||||
bitlength = 0
|
||||
-- bus will always let up eventually, don't bother with timeout
|
||||
while (gpio_read(pin) == 0) do end
|
||||
end
|
||||
|
||||
--DHT data acquired, process.
|
||||
for i = 1, 16, 1 do
|
||||
if (bitStream[i] > 4) then
|
||||
humidity = humidity + 2 ^ (16 - i)
|
||||
end
|
||||
end
|
||||
for i = 1, 16, 1 do
|
||||
if (bitStream[i + 16] > 4) then
|
||||
temperature = temperature + 2 ^ (16 - i)
|
||||
end
|
||||
end
|
||||
for i = 1, 8, 1 do
|
||||
if (bitStream[i + 32] > 4) then
|
||||
checksum = checksum + 2 ^ (8 - i)
|
||||
end
|
||||
end
|
||||
|
||||
checksumTest=((humidity / 256) + (humidity % 256) + (temperature / 256) + (temperature % 256)) % 256
|
||||
|
||||
if temperature > 0x8000 then
|
||||
-- convert to negative format
|
||||
temperature = -(temperature - 0x8000)
|
||||
end
|
||||
|
||||
if checksum ~= checksumTest then
|
||||
humidity = -1
|
||||
end
|
||||
end
|
||||
|
||||
function M.getTemperature()
|
||||
return temperature
|
||||
end
|
||||
|
||||
function M.getHumidity()
|
||||
return humidity
|
||||
end
|
||||
|
||||
return M
|
|
@ -35,27 +35,27 @@ setfenv(1,M)
|
|||
C = 0
|
||||
F = 1
|
||||
K = 2
|
||||
function setup(dq)
|
||||
pin = dq
|
||||
if(pin == nil) then
|
||||
pin = defaultPin
|
||||
end
|
||||
ow.setup(pin)
|
||||
function setup(dq)
|
||||
pin = dq
|
||||
if(pin == nil) then
|
||||
pin = defaultPin
|
||||
end
|
||||
ow.setup(pin)
|
||||
end
|
||||
|
||||
function addrs()
|
||||
setup(pin)
|
||||
tbl = {}
|
||||
ow.reset_search(pin)
|
||||
repeat
|
||||
addr = ow.search(pin)
|
||||
if(addr ~= nil) then
|
||||
table.insert(tbl, addr)
|
||||
end
|
||||
tmr.wdclr()
|
||||
until (addr == nil)
|
||||
ow.reset_search(pin)
|
||||
return tbl
|
||||
setup(pin)
|
||||
tbl = {}
|
||||
ow.reset_search(pin)
|
||||
repeat
|
||||
addr = ow.search(pin)
|
||||
if(addr ~= nil) then
|
||||
table.insert(tbl, addr)
|
||||
end
|
||||
tmr.wdclr()
|
||||
until (addr == nil)
|
||||
ow.reset_search(pin)
|
||||
return tbl
|
||||
end
|
||||
|
||||
function readNumber(addr, unit)
|
||||
|
@ -64,71 +64,71 @@ function readNumber(addr, unit)
|
|||
flag = false
|
||||
if(addr == nil) then
|
||||
ow.reset_search(pin)
|
||||
count = 0
|
||||
count = 0
|
||||
repeat
|
||||
count = count + 1
|
||||
addr = ow.search(pin)
|
||||
tmr.wdclr()
|
||||
until((addr ~= nil) or (count > 100))
|
||||
ow.reset_search(pin)
|
||||
end
|
||||
count = count + 1
|
||||
addr = ow.search(pin)
|
||||
tmr.wdclr()
|
||||
until((addr ~= nil) or (count > 100))
|
||||
ow.reset_search(pin)
|
||||
end
|
||||
if(addr == nil) then
|
||||
return result
|
||||
return result
|
||||
end
|
||||
crc = ow.crc8(string.sub(addr,1,7))
|
||||
if (crc == addr:byte(8)) then
|
||||
if ((addr:byte(1) == 0x10) or (addr:byte(1) == 0x28)) then
|
||||
-- print("Device is a DS18S20 family device.")
|
||||
ow.reset(pin)
|
||||
ow.select(pin, addr)
|
||||
ow.write(pin, 0x44, 1)
|
||||
-- tmr.delay(1000000)
|
||||
present = ow.reset(pin)
|
||||
ow.select(pin, addr)
|
||||
ow.write(pin,0xBE,1)
|
||||
-- print("P="..present)
|
||||
data = nil
|
||||
data = string.char(ow.read(pin))
|
||||
for i = 1, 8 do
|
||||
data = data .. string.char(ow.read(pin))
|
||||
-- print("Device is a DS18S20 family device.")
|
||||
ow.reset(pin)
|
||||
ow.select(pin, addr)
|
||||
ow.write(pin, 0x44, 1)
|
||||
-- tmr.delay(1000000)
|
||||
present = ow.reset(pin)
|
||||
ow.select(pin, addr)
|
||||
ow.write(pin,0xBE,1)
|
||||
-- print("P="..present)
|
||||
data = nil
|
||||
data = string.char(ow.read(pin))
|
||||
for i = 1, 8 do
|
||||
data = data .. string.char(ow.read(pin))
|
||||
end
|
||||
-- print(data:byte(1,9))
|
||||
crc = ow.crc8(string.sub(data,1,8))
|
||||
-- print("CRC="..crc)
|
||||
if (crc == data:byte(9)) then
|
||||
if(unit == nil or unit == C) then
|
||||
t = (data:byte(1) + data:byte(2) * 256) * 625
|
||||
elseif(unit == F) then
|
||||
t = (data:byte(1) + data:byte(2) * 256) * 1125 + 320000
|
||||
elseif(unit == K) then
|
||||
t = (data:byte(1) + data:byte(2) * 256) * 625 + 2731500
|
||||
else
|
||||
return nil
|
||||
end
|
||||
-- print(data:byte(1,9))
|
||||
crc = ow.crc8(string.sub(data,1,8))
|
||||
-- print("CRC="..crc)
|
||||
if (crc == data:byte(9)) then
|
||||
if(unit == nil or unit == C) then
|
||||
t = (data:byte(1) + data:byte(2) * 256) * 625
|
||||
elseif(unit == F) then
|
||||
t = (data:byte(1) + data:byte(2) * 256) * 1125 + 320000
|
||||
elseif(unit == K) then
|
||||
t = (data:byte(1) + data:byte(2) * 256) * 625 + 2731500
|
||||
else
|
||||
return nil
|
||||
end
|
||||
t1 = t / 10000
|
||||
t2 = t % 10000
|
||||
-- print("Temperature="..t1.."."..t2.." Centigrade")
|
||||
-- result = t1.."."..t2
|
||||
return t1, t2
|
||||
end
|
||||
tmr.wdclr()
|
||||
t1 = t / 10000
|
||||
t2 = t % 10000
|
||||
-- print("Temperature="..t1.."."..t2.." Centigrade")
|
||||
-- result = t1.."."..t2
|
||||
return t1, t2
|
||||
end
|
||||
tmr.wdclr()
|
||||
else
|
||||
-- print("Device family is not recognized.")
|
||||
-- print("Device family is not recognized.")
|
||||
end
|
||||
else
|
||||
-- print("CRC is not valid!")
|
||||
-- print("CRC is not valid!")
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
function read(addr, unit)
|
||||
t1, t2 = readNumber(addr, unit)
|
||||
if((t1 == nil ) or (t2 ==nil)) then
|
||||
return nil
|
||||
else
|
||||
return t1.."."..t2
|
||||
end
|
||||
t1, t2 = readNumber(addr, unit)
|
||||
if((t1 == nil ) or (t2 ==nil)) then
|
||||
return nil
|
||||
else
|
||||
return t1.."."..t2
|
||||
end
|
||||
end
|
||||
|
||||
-- Return module table
|
||||
return M
|
||||
return M
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
require("ds3231")
|
||||
|
||||
-- ESP-01 GPIO Mapping
|
||||
gpio0, gpio2 = 3, 4
|
||||
|
||||
ds3231.init(gpio0, gpio2)
|
||||
|
||||
second, minute, hour, day, date, month, year = ds3231.getTime();
|
||||
|
||||
-- Get current time
|
||||
print(string.format("Time & Date: %s:%s:%s %s/%s/%s", hour, minute, second, date, month, year))
|
||||
|
||||
-- Don't forget to release it after use
|
||||
ds3231 = nil
|
||||
package.loaded["ds3231"]=nil
|
|
@ -0,0 +1,54 @@
|
|||
require('ds3231')
|
||||
|
||||
port = 80
|
||||
|
||||
-- ESP-01 GPIO Mapping
|
||||
gpio0, gpio2 = 3, 4
|
||||
|
||||
days = {
|
||||
[1] = "Sunday",
|
||||
[2] = "Monday",
|
||||
[3] = "Tuesday",
|
||||
[4] = "Wednesday",
|
||||
[5] = "Thursday",
|
||||
[6] = "Friday",
|
||||
[7] = "Saturday"
|
||||
}
|
||||
|
||||
months = {
|
||||
[1] = "January",
|
||||
[2] = "Febuary",
|
||||
[3] = "March",
|
||||
[4] = "April",
|
||||
[5] = "May",
|
||||
[6] = "June",
|
||||
[7] = "July",
|
||||
[8] = "August",
|
||||
[9] = "September",
|
||||
[10] = "October",
|
||||
[11] = "November",
|
||||
[12] = "December"
|
||||
}
|
||||
|
||||
ds3231.init(gpio0, gpio2)
|
||||
|
||||
srv=net.createServer(net.TCP)
|
||||
srv:listen(port,
|
||||
function(conn)
|
||||
|
||||
second, minute, hour, day, date, month, year = ds3231.getTime()
|
||||
prettyTime = string.format("%s, %s %s %s %s:%s:%s", days[day], date, months[month], year, hour, minute, second)
|
||||
|
||||
conn:send("HTTP/1.1 200 OK\nContent-Type: text/html\nRefresh: 5\n\n" ..
|
||||
"<!DOCTYPE HTML>" ..
|
||||
"<html><body>" ..
|
||||
"<b>ESP8266</b></br>" ..
|
||||
"Time and Date: " .. prettyTime .. "<br>" ..
|
||||
"Node ChipID : " .. node.chipid() .. "<br>" ..
|
||||
"Node MAC : " .. wifi.sta.getmac() .. "<br>" ..
|
||||
"Node Heap : " .. node.heap() .. "<br>" ..
|
||||
"Timer Ticks : " .. tmr.now() .. "<br>" ..
|
||||
"</html></body>")
|
||||
conn:on("sent",function(conn) conn:close() end)
|
||||
end
|
||||
)
|
|
@ -0,0 +1,114 @@
|
|||
#DS3231 Module
|
||||
##Require
|
||||
```lua
|
||||
ds3231 = require("ds3231")
|
||||
```
|
||||
## Release
|
||||
```lua
|
||||
ds3231 = nil
|
||||
package.loaded["ds3231"]=nil
|
||||
```
|
||||
<a id="ds3231_init"></a>
|
||||
##init()
|
||||
####Description
|
||||
Setting the pins of DS3231.
|
||||
|
||||
####Syntax
|
||||
init(sda, scl)
|
||||
|
||||
####Parameters
|
||||
sda: 1~10, IO index.
|
||||
scl: 1~10, IO index.
|
||||
|
||||
####Returns
|
||||
nil
|
||||
|
||||
####Example
|
||||
```lua
|
||||
ds3231 = require("ds3231")
|
||||
ds3231.init(3, 4)
|
||||
-- Don't forget to release it after use
|
||||
ds3231 = nil
|
||||
package.loaded["ds3231"]=nil
|
||||
```
|
||||
|
||||
####See also
|
||||
**-** []()
|
||||
|
||||
|
||||
<a id="ds3231_settime"></a>
|
||||
## setTime()
|
||||
####Description
|
||||
Sets the current date and time.
|
||||
|
||||
####Syntax
|
||||
setTime(second, minute, hour, day, date, month, year)
|
||||
|
||||
####Parameters
|
||||
second: 00-59
|
||||
minute: 00-59
|
||||
hour: 00-23
|
||||
day: 1-7 (Sunday = 1, Saturday = 7)
|
||||
date: 01-31
|
||||
month: 01-12
|
||||
year: 00-99
|
||||
|
||||
####Returns
|
||||
nil
|
||||
|
||||
####Example
|
||||
```lua
|
||||
ds3231 = require("ds3231")
|
||||
ds3231.init(3, 4)
|
||||
|
||||
-- Set date and time to Sunday, January 18th 2015 6:30PM
|
||||
ds3231.setTime(0, 30, 18, 1, 18, 1, 15);
|
||||
|
||||
-- Don't forget to release it after use
|
||||
ds3231 = nil
|
||||
package.loaded["ds3231"]=nil
|
||||
```
|
||||
|
||||
####See also
|
||||
**-** []()
|
||||
|
||||
|
||||
<a id="ds3231_getTime"></a>
|
||||
## getTime()
|
||||
####Description
|
||||
Get the current date and time.
|
||||
|
||||
####Syntax
|
||||
getTime()
|
||||
|
||||
####Parameters
|
||||
nil
|
||||
|
||||
####Returns
|
||||
second: integer. Second 00-59
|
||||
minute: integer. Minute 00-59
|
||||
hour: integer. Hour 00-23
|
||||
day: integer. Day 1-7 (Sunday = 1, Saturday = 7)
|
||||
date: integer. Date 01-31
|
||||
month: integer. Month 01-12
|
||||
year: integer. Year 00-99
|
||||
|
||||
####Example
|
||||
```lua
|
||||
ds3231=require("ds3231")
|
||||
ds3231.init(3, 4)
|
||||
|
||||
-- Get date and time
|
||||
second, minute, hour, day, date, month, year = ds3231.getTime();
|
||||
|
||||
-- Print date and time
|
||||
print(string.format("Time & Date: %s:%s:%s %s/%s/%s",
|
||||
hour, minute, second, date, month, year))
|
||||
|
||||
-- Don't forget to release it after use
|
||||
ds3231 = nil
|
||||
package.loaded["ds3231"]=nil
|
||||
|
||||
```
|
||||
####See also
|
||||
**-** []()
|
|
@ -0,0 +1,75 @@
|
|||
--------------------------------------------------------------------------------
|
||||
-- DS3231 I2C module for NODEMCU
|
||||
-- NODEMCU TEAM
|
||||
-- LICENCE: http://opensource.org/licenses/MIT
|
||||
-- Tobie Booth <tbooth@hindbra.in>
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
local moduleName = ...
|
||||
local M = {}
|
||||
_G[moduleName] = M
|
||||
|
||||
-- Default value for i2c communication
|
||||
local id = 0
|
||||
|
||||
--device address
|
||||
local dev_addr = 0x68
|
||||
|
||||
local function decToBcd(val)
|
||||
return((val/10*16) + (val%10))
|
||||
end
|
||||
|
||||
local function bcdToDec(val)
|
||||
return((val/16*10) + (val%16))
|
||||
end
|
||||
|
||||
-- initialize i2c
|
||||
--parameters:
|
||||
--d: sda
|
||||
--l: scl
|
||||
function M.init(d, l)
|
||||
if (d ~= nil) and (l ~= nil) and (d >= 0) and (d <= 11) and (l >= 0) and ( l <= 11) and (d ~= l) then
|
||||
sda = d
|
||||
scl = l
|
||||
else
|
||||
print("iic config failed!") return nil
|
||||
end
|
||||
print("init done")
|
||||
i2c.setup(id, sda, scl, i2c.SLOW)
|
||||
end
|
||||
|
||||
--get time from DS3231
|
||||
function M.getTime()
|
||||
i2c.start(id)
|
||||
i2c.address(id, dev_addr, i2c.TRANSMITTER)
|
||||
i2c.write(id, 0x00)
|
||||
i2c.stop(id)
|
||||
i2c.start(id)
|
||||
i2c.address(id, dev_addr, i2c.RECEIVER)
|
||||
local c=i2c.read(id, 7)
|
||||
i2c.stop(id)
|
||||
return bcdToDec(tonumber(string.byte(c, 1))),
|
||||
bcdToDec(tonumber(string.byte(c, 2))),
|
||||
bcdToDec(tonumber(string.byte(c, 3))),
|
||||
bcdToDec(tonumber(string.byte(c, 4))),
|
||||
bcdToDec(tonumber(string.byte(c, 5))),
|
||||
bcdToDec(tonumber(string.byte(c, 6))),
|
||||
bcdToDec(tonumber(string.byte(c, 7)))
|
||||
end
|
||||
|
||||
--set time for DS3231
|
||||
function M.setTime(second, minute, hour, day, date, month, year)
|
||||
i2c.start(id)
|
||||
i2c.address(id, dev_addr, i2c.TRANSMITTER)
|
||||
i2c.write(id, 0x00)
|
||||
i2c.write(id, decToBcd(second))
|
||||
i2c.write(id, decToBcd(minute))
|
||||
i2c.write(id, decToBcd(hour))
|
||||
i2c.write(id, decToBcd(day))
|
||||
i2c.write(id, decToBcd(date))
|
||||
i2c.write(id, decToBcd(month))
|
||||
i2c.write(id, decToBcd(year))
|
||||
i2c.stop(id)
|
||||
end
|
||||
|
||||
return M
|
|
@ -0,0 +1,39 @@
|
|||
------------------------------------------------------------------------------
|
||||
-- HTTP server Hello world example
|
||||
--
|
||||
-- LICENCE: http://opensource.org/licenses/MIT
|
||||
-- Vladimir Dronnikov <dronnikov@gmail.com>
|
||||
------------------------------------------------------------------------------
|
||||
require("http").createServer(80, function(req, res)
|
||||
-- analyse method and url
|
||||
print("+R", req.method, req.url, node.heap())
|
||||
-- setup handler of headers, if any
|
||||
req.onheader = function(self, name, value)
|
||||
-- print("+H", name, value)
|
||||
-- E.g. look for "content-type" header,
|
||||
-- setup body parser to particular format
|
||||
-- if name == "content-type" then
|
||||
-- if value == "application/json" then
|
||||
-- req.ondata = function(self, chunk) ... end
|
||||
-- elseif value == "application/x-www-form-urlencoded" then
|
||||
-- req.ondata = function(self, chunk) ... end
|
||||
-- end
|
||||
-- end
|
||||
end
|
||||
-- setup handler of body, if any
|
||||
req.ondata = function(self, chunk)
|
||||
print("+B", chunk and #chunk, node.heap())
|
||||
-- request ended?
|
||||
if not chunk then
|
||||
-- reply
|
||||
--res:finish("")
|
||||
res:send(nil, 200)
|
||||
res:send_header("Connection", "close")
|
||||
res:send("Hello, world!")
|
||||
res:finish()
|
||||
end
|
||||
end
|
||||
-- or just do something not waiting till body (if any) comes
|
||||
--res:finish("Hello, world!")
|
||||
--res:finish("Salut, monde!")
|
||||
end)
|
|
@ -0,0 +1,212 @@
|
|||
------------------------------------------------------------------------------
|
||||
-- HTTP server module
|
||||
--
|
||||
-- LICENCE: http://opensource.org/licenses/MIT
|
||||
-- Vladimir Dronnikov <dronnikov@gmail.com>
|
||||
------------------------------------------------------------------------------
|
||||
local collectgarbage, tonumber, tostring = collectgarbage, tonumber, tostring
|
||||
|
||||
local http
|
||||
do
|
||||
------------------------------------------------------------------------------
|
||||
-- request methods
|
||||
------------------------------------------------------------------------------
|
||||
local make_req = function(conn, method, url)
|
||||
local req = {
|
||||
conn = conn,
|
||||
method = method,
|
||||
url = url,
|
||||
}
|
||||
-- return setmetatable(req, {
|
||||
-- })
|
||||
return req
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- response methods
|
||||
------------------------------------------------------------------------------
|
||||
local send = function(self, data, status)
|
||||
local c = self.conn
|
||||
-- TODO: req.send should take care of response headers!
|
||||
if self.send_header then
|
||||
c:send("HTTP/1.1 ")
|
||||
c:send(tostring(status or 200))
|
||||
-- TODO: real HTTP status code/name table
|
||||
c:send(" OK\r\n")
|
||||
-- we use chunked transfer encoding, to not deal with Content-Length:
|
||||
-- response header
|
||||
self:send_header("Transfer-Encoding", "chunked")
|
||||
-- TODO: send standard response headers, such as Server:, Date:
|
||||
end
|
||||
if data then
|
||||
-- NB: no headers allowed after response body started
|
||||
if self.send_header then
|
||||
self.send_header = nil
|
||||
-- end response headers
|
||||
c:send("\r\n")
|
||||
end
|
||||
-- chunked transfer encoding
|
||||
c:send(("%X\r\n"):format(#data))
|
||||
c:send(data)
|
||||
c:send("\r\n")
|
||||
end
|
||||
end
|
||||
local send_header = function(self, name, value)
|
||||
local c = self.conn
|
||||
-- NB: quite a naive implementation
|
||||
c:send(name)
|
||||
c:send(": ")
|
||||
c:send(value)
|
||||
c:send("\r\n")
|
||||
end
|
||||
-- finalize request, optionally sending data
|
||||
local finish = function(self, data, status)
|
||||
local c = self.conn
|
||||
-- NB: req.send takes care of response headers
|
||||
if data then
|
||||
self:send(data, status)
|
||||
end
|
||||
-- finalize chunked transfer encoding
|
||||
c:send("0\r\n\r\n")
|
||||
-- close connection
|
||||
c:close()
|
||||
end
|
||||
--
|
||||
local make_res = function(conn)
|
||||
local res = {
|
||||
conn = conn,
|
||||
}
|
||||
-- return setmetatable(res, {
|
||||
-- send_header = send_header,
|
||||
-- send = send,
|
||||
-- finish = finish,
|
||||
-- })
|
||||
res.send_header = send_header
|
||||
res.send = send
|
||||
res.finish = finish
|
||||
return res
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- HTTP parser
|
||||
------------------------------------------------------------------------------
|
||||
local http_handler = function(handler)
|
||||
return function(conn)
|
||||
local req, res
|
||||
local buf = ""
|
||||
local method, url
|
||||
local ondisconnect = function(conn)
|
||||
collectgarbage("collect")
|
||||
end
|
||||
-- header parser
|
||||
local cnt_len = 0
|
||||
local onheader = function(conn, k, v)
|
||||
-- TODO: look for Content-Type: header
|
||||
-- to help parse body
|
||||
-- parse content length to know body length
|
||||
if k == "content-length" then
|
||||
cnt_len = tonumber(v)
|
||||
end
|
||||
if k == "expect" and v == "100-continue" then
|
||||
conn:send("HTTP/1.1 100 Continue\r\n")
|
||||
end
|
||||
-- delegate to request object
|
||||
if req and req.onheader then
|
||||
req:onheader(k, v)
|
||||
end
|
||||
end
|
||||
-- body data handler
|
||||
local body_len = 0
|
||||
local ondata = function(conn, chunk)
|
||||
-- NB: do not reset node in case of lengthy requests
|
||||
tmr.wdclr()
|
||||
-- feed request data to request handler
|
||||
if not req or not req.ondata then return end
|
||||
req:ondata(chunk)
|
||||
-- NB: once length of seen chunks equals Content-Length:
|
||||
-- onend(conn) is called
|
||||
body_len = body_len + #chunk
|
||||
-- print("-B", #chunk, body_len, cnt_len, node.heap())
|
||||
if body_len >= cnt_len then
|
||||
req:ondata()
|
||||
end
|
||||
end
|
||||
local onreceive = function(conn, chunk)
|
||||
-- merge chunks in buffer
|
||||
if buf then
|
||||
buf = buf .. chunk
|
||||
else
|
||||
buf = chunk
|
||||
end
|
||||
-- consume buffer line by line
|
||||
while #buf > 0 do
|
||||
-- extract line
|
||||
local e = buf:find("\r\n", 1, true)
|
||||
if not e then break end
|
||||
local line = buf:sub(1, e - 1)
|
||||
buf = buf:sub(e + 2)
|
||||
-- method, url?
|
||||
if not method then
|
||||
local i
|
||||
-- NB: just version 1.1 assumed
|
||||
_, i, method, url = line:find("^([A-Z]+) (.-) HTTP/1.1$")
|
||||
if method then
|
||||
-- make request and response objects
|
||||
req = make_req(conn, method, url)
|
||||
res = make_res(conn)
|
||||
end
|
||||
-- header line?
|
||||
elseif #line > 0 then
|
||||
-- parse header
|
||||
local _, _, k, v = line:find("^([%w-]+):%s*(.+)")
|
||||
-- header seems ok?
|
||||
if k then
|
||||
k = k:lower()
|
||||
onheader(conn, k, v)
|
||||
end
|
||||
-- headers end
|
||||
else
|
||||
-- spawn request handler
|
||||
-- NB: do not reset in case of lengthy requests
|
||||
tmr.wdclr()
|
||||
handler(req, res)
|
||||
tmr.wdclr()
|
||||
-- NB: we feed the rest of the buffer as starting chunk of body
|
||||
ondata(conn, buf)
|
||||
-- buffer no longer needed
|
||||
buf = nil
|
||||
-- NB: we explicitly reassign receive handler so that
|
||||
-- next received chunks go directly to body handler
|
||||
conn:on("receive", ondata)
|
||||
-- parser done
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
conn:on("receive", onreceive)
|
||||
conn:on("disconnection", ondisconnect)
|
||||
end
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- HTTP server
|
||||
------------------------------------------------------------------------------
|
||||
local srv
|
||||
local createServer = function(port, handler)
|
||||
-- NB: only one server at a time
|
||||
if srv then srv:close() end
|
||||
srv = net.createServer(net.TCP, 15)
|
||||
-- listen
|
||||
srv:listen(port, http_handler(handler))
|
||||
return srv
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- HTTP server methods
|
||||
------------------------------------------------------------------------------
|
||||
http = {
|
||||
createServer = createServer,
|
||||
}
|
||||
end
|
||||
|
||||
return http
|
|
@ -0,0 +1,24 @@
|
|||
|
||||
tmr.alarm(0, 60000, 1, function()
|
||||
|
||||
SDA_PIN = 6 -- sda pin, GPIO12
|
||||
SCL_PIN = 5 -- scl pin, GPIO14
|
||||
|
||||
si7021 = require("si7021")
|
||||
si7021.init(SDA_PIN, SCL_PIN)
|
||||
si7021.read(OSS)
|
||||
h = si7021.getHumidity()
|
||||
t = si7021.getTemperature()
|
||||
|
||||
-- pressure in differents units
|
||||
print("Humidity: "..(h / 100).."."..(h % 100).." %")
|
||||
|
||||
-- temperature in degrees Celsius and Farenheit
|
||||
print("Temperature: "..(t/100).."."..(t%100).." deg C")
|
||||
print("Temperature: "..(9 * t / 500 + 32).."."..(9 * t / 50 % 10).." deg F")
|
||||
|
||||
-- release module
|
||||
si7021 = nil
|
||||
package.loaded["si7021"]=nil
|
||||
|
||||
end)
|
|
@ -0,0 +1,41 @@
|
|||
|
||||
--创建一个定时器
|
||||
tmr.alarm(0, 60000, 1, function()
|
||||
|
||||
SDA_PIN = 6 -- sda pin, GPIO12
|
||||
SCL_PIN = 5 -- scl pin, GPIO14
|
||||
|
||||
si7021 = require("si7021")
|
||||
si7021.init(SDA_PIN, SCL_PIN)
|
||||
si7021.read(OSS)
|
||||
Hum = si7021.getHumidity()
|
||||
Temp = si7021.getTemperature()
|
||||
|
||||
--定义数据变量格式
|
||||
PostData = "[{\"Name\":\"T\",\"Value\":\"" .. (Temp/100).."."..(Temp%100) .. "\"},{\"Name\":\"H\",\"Value\":\"" .. (Hum/100).."."..(Hum%100) .. "\"}]"
|
||||
--创建一个TCP连接
|
||||
socket=net.createConnection(net.TCP, 0)
|
||||
--域名解析IP地址并赋值
|
||||
socket:dns("www.lewei50.com", function(conn, ip)
|
||||
ServerIP = ip
|
||||
print("Connection IP:" .. ServerIP)
|
||||
end)
|
||||
--开始连接服务器
|
||||
socket:connect(80, ServerIP)
|
||||
socket:on("connection", function(sck) end)
|
||||
--HTTP请求头定义
|
||||
socket:send("POST /api/V1/gateway/UpdateSensors/yourID HTTP/1.1\r\n" ..
|
||||
"Host: www.lewei50.com\r\n" ..
|
||||
"Content-Length: " .. string.len(PostData) .. "\r\n" ..
|
||||
"userkey: yourKEY\r\n\r\n" ..
|
||||
PostData .. "\r\n")
|
||||
--HTTP响应内容
|
||||
socket:on("receive", function(sck, response)
|
||||
print(response)
|
||||
end)
|
||||
|
||||
-- release module
|
||||
si7021 = nil
|
||||
package.loaded["si7021"]=nil
|
||||
|
||||
end)
|
|
@ -0,0 +1,131 @@
|
|||
# si7021 module
|
||||
|
||||
##Require
|
||||
```lua
|
||||
si7021 = require("si7021")
|
||||
```
|
||||
## Release
|
||||
```lua
|
||||
si7021 = nil
|
||||
package.loaded["si7021"]=nil
|
||||
```
|
||||
<a id="si7021_init"></a>
|
||||
##init()
|
||||
####Description
|
||||
Setting the i2c pin of si7021.<br />
|
||||
|
||||
####Syntax
|
||||
init(sda, scl)
|
||||
|
||||
####Parameters
|
||||
sda: 1~12, IO index.<br />
|
||||
scl: 1~12, IO index.<br />
|
||||
|
||||
####Returns
|
||||
nil
|
||||
|
||||
####Example
|
||||
```lua
|
||||
si7021 = require("si7021")
|
||||
gpio5 = 1
|
||||
gpio4 = 2
|
||||
sda = gpio5
|
||||
scl = gpio4
|
||||
si7021.init(sda, scl)
|
||||
-- Don't forget to release it after use
|
||||
si7021 = nil
|
||||
package.loaded["si7021"]=nil
|
||||
```
|
||||
|
||||
####See also
|
||||
**-** []()
|
||||
|
||||
<a id="si7021_read"></a>
|
||||
##read()
|
||||
####Description
|
||||
Read temperature and humidity from si7021.<br />
|
||||
|
||||
####Syntax
|
||||
read()
|
||||
|
||||
####Parameters
|
||||
nil.<br />
|
||||
|
||||
####Returns
|
||||
nil(Why?).<br />
|
||||
|
||||
####Example
|
||||
```lua
|
||||
si7021 = require("si7021")
|
||||
sda = 1
|
||||
scl = 2
|
||||
si7021.init(sda, scl)
|
||||
r = si7021.read()
|
||||
print(r)
|
||||
-- Don't forget to release it after use
|
||||
si7021 = nil
|
||||
package.loaded["si7021"]=nil
|
||||
```
|
||||
|
||||
####See also
|
||||
**-** []()
|
||||
|
||||
<a id="si7021_getHumidity"></a>
|
||||
##getHumidity()
|
||||
####Description
|
||||
Get humidity from si7021.<br />
|
||||
|
||||
####Syntax
|
||||
getHumidity()
|
||||
|
||||
####Parameters
|
||||
nil.<br />
|
||||
|
||||
####Returns
|
||||
h: Integer, humidity from si7021.
|
||||
|
||||
####Example
|
||||
```lua
|
||||
si7021 = require("si7021")
|
||||
sda = 1
|
||||
scl = 2
|
||||
si7021.init(sda, scl)
|
||||
h = si7021.getHumidity()
|
||||
print(h)
|
||||
-- Don't forget to release it after use
|
||||
si7021 = nil
|
||||
package.loaded["si7021"]=nil
|
||||
```
|
||||
|
||||
####See also
|
||||
**-** []()
|
||||
|
||||
<a id="si7021_getTemperature"></a>
|
||||
##getTemperature()
|
||||
####Description
|
||||
Get temperature from si7021.<br />
|
||||
|
||||
####Syntax
|
||||
getTemperature()
|
||||
|
||||
####Parameters
|
||||
nil.<br />
|
||||
|
||||
####Returns
|
||||
t: Integer, temperature from si7021.
|
||||
|
||||
####Example
|
||||
```lua
|
||||
si7021 = require("si7021")
|
||||
sda = 1
|
||||
scl = 2
|
||||
si7021.init(sda, scl)
|
||||
t = si7021.getTemperature()
|
||||
print(t)
|
||||
-- Don't forget to release it after use
|
||||
si7021 = nil
|
||||
package.loaded["si7021"]=nil
|
||||
```
|
||||
|
||||
####See also
|
||||
**-** []()
|
|
@ -0,0 +1,104 @@
|
|||
-- ***************************************************************************
|
||||
-- SI7021 module for ESP8266 with nodeMCU
|
||||
-- Si7021 compatible tested 2015-1-22
|
||||
--
|
||||
-- Written by VIP6
|
||||
--
|
||||
-- MIT license, http://opensource.org/licenses/MIT
|
||||
-- ***************************************************************************
|
||||
|
||||
local moduleName = ...
|
||||
local M = {}
|
||||
_G[moduleName] = M
|
||||
|
||||
--I2C slave address of Si70xx
|
||||
local Si7021_ADDR = 0x40
|
||||
|
||||
--Commands
|
||||
local CMD_MEASURE_HUMIDITY_HOLD = 0xE5
|
||||
local CMD_MEASURE_HUMIDITY_NO_HOLD = 0xF5
|
||||
local CMD_MEASURE_TEMPERATURE_HOLD = 0xE3
|
||||
local CMD_MEASURE_TEMPERATURE_NO_HOLD = 0xF3
|
||||
|
||||
|
||||
-- temperature and pressure
|
||||
local t,h
|
||||
|
||||
local init = false
|
||||
|
||||
-- i2c interface ID
|
||||
local id = 0
|
||||
|
||||
-- 16-bit two's complement
|
||||
-- value: 16-bit integer
|
||||
local function twoCompl(value)
|
||||
if value > 32767 then value = -(65535 - value + 1)
|
||||
end
|
||||
return value
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- read data from si7021
|
||||
-- ADDR: slave address
|
||||
-- commands: Commands of si7021
|
||||
-- length: bytes to read
|
||||
local function read_data(ADDR, commands, length)
|
||||
i2c.start(id)
|
||||
i2c.address(id, ADDR, i2c.TRANSMITTER)
|
||||
i2c.write(id, commands)
|
||||
i2c.stop(id)
|
||||
i2c.start(id)
|
||||
i2c.address(id, ADDR,i2c.RECEIVER)
|
||||
tmr.delay(20000)
|
||||
c = i2c.read(id, length)
|
||||
i2c.stop(id)
|
||||
return c
|
||||
end
|
||||
|
||||
-- initialize module
|
||||
-- sda: SDA pin
|
||||
-- scl SCL pin
|
||||
function M.init(sda, scl)
|
||||
i2c.setup(id, sda, scl, i2c.SLOW)
|
||||
--print("i2c ok..")
|
||||
init = true
|
||||
end
|
||||
|
||||
-- read humidity from si7021
|
||||
local function read_humi()
|
||||
dataH = read_data(Si7021_ADDR, CMD_MEASURE_HUMIDITY_HOLD, 2)
|
||||
UH = string.byte(dataH, 1) * 256 + string.byte(dataH, 2)
|
||||
h = ((UH*12500+65536/2)/65536 - 600)
|
||||
return(h)
|
||||
end
|
||||
|
||||
-- read temperature from si7021
|
||||
local function read_temp()
|
||||
dataT = read_data(Si7021_ADDR, CMD_MEASURE_TEMPERATURE_HOLD, 2)
|
||||
UT = string.byte(dataT, 1) * 256 + string.byte(dataT, 2)
|
||||
t = ((UT*17572+65536/2)/65536 - 4685)
|
||||
return(t)
|
||||
end
|
||||
|
||||
-- read temperature and humidity from si7021
|
||||
function M.read()
|
||||
if (not init) then
|
||||
print("init() must be called before read.")
|
||||
else
|
||||
read_humi()
|
||||
read_temp()
|
||||
end
|
||||
end;
|
||||
|
||||
-- get humidity
|
||||
function M.getHumidity()
|
||||
return h
|
||||
end
|
||||
|
||||
-- get temperature
|
||||
function M.getTemperature()
|
||||
return t
|
||||
end
|
||||
|
||||
return M
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,11 @@
|
|||
# Enforce Unix newlines
|
||||
*.css text eol=lf
|
||||
*.html text eol=lf
|
||||
*.js text eol=lf
|
||||
*.json text eol=lf
|
||||
*.less text eol=lf
|
||||
*.md text eol=lf
|
||||
*.svg text eol=lf
|
||||
*.yml text eol=lf
|
||||
*.py text eol=lf
|
||||
*.sh text eol=lf
|
Loading…
Reference in New Issue