Commit dceed526 authored by Vowstar's avatar Vowstar
Browse files

Merge pull request #470 from nodemcu/dev096

* Update SDK to 0.9.6
* Fix some bugs
* Update examples
* Add crypto module by @creationix 
parents 0ad57470 b0a4e4d3
No preview for this file type
No preview for this file type
--
-- Light sensor on ADC(0), RGB LED connected to gpio12(6) Green, gpio13(7) Blue & gpio15(8) Red.
-- This works out of the box on the typical ESP8266 evaluation boards with Battery Holder
--
-- It uses the input from the sensor to drive a "rainbow" effect on the RGB LED
-- Includes a very "pseudoSin" function
--
function led(r,Sg,b)
pwm.setduty(8,r)
pwm.setduty(6,g)
pwm.setduty(7,b)
end
-- this is perhaps the lightest weight sin function in existance
-- Given an integer from 0..128, 0..512 appximating 256 + 256 * sin(idx*Pi/256)
-- This is first order square approximation of sin, it's accurate around 0 and any multiple of 128 (Pi/2),
-- 92% accurate at 64 (Pi/4).
function pseudoSin (idx)
idx = idx % 128
lookUp = 32 - idx % 64
val = 256 - (lookUp * lookUp) / 4
if (idx > 64) then
val = - val;
end
return 256+val
end
pwm.setup(6,500,512)
pwm.setup(7,500,512)
pwm.setup(8,500,512)
pwm.start(6)
pwm.start(7)
pwm.start(8)
tmr.alarm(1,20,1,function()
idx = 3 * adc.read(0) / 2
r = pseudoSin(idx)
g = pseudoSin(idx + 43)
b = pseudoSin(idx + 85)
led(r,g,b)
idx = (idx + 1) % 128
end)
--
-- Simple NodeMCU web server (done is a not so nodeie fashion :-)
--
-- Highly modified by Bruce Meacham, based on work by Scott Beasley 2015
-- Open and free to change and use. Enjoy. [Beasley/Meacham 2015]
--
-- Meacham Update: I streamlined/improved the parsing to focus on simple HTTP GET request and their simple parameters
-- Also added the code to drive a servo/light. Comment out as you see fit.
--
-- Usage:
-- Change SSID and SSID_PASSPHRASE for your wifi network
-- Download to NodeMCU
-- node.compile("http_server.lua")
-- dofile("http_server.lc")
-- When the server is esablished it will output the IP address.
-- http://{ip address}/?s0=1200&light=1
-- s0 is the servo position (actually the PWM hertz), 500 - 2000 are all good values
-- light chanel high(1)/low(0), some evaluation boards have LEDs pre-wired in a "pulled high" confguration, so '0' ground the emitter and turns it on backwards.
--
-- Add to init.lua if you want it to autoboot.
--
-- Your Wifi connection data
local SSID = "YOUR WIFI SSID"
local SSID_PASSWORD = "YOUR SSID PASSPHRASE"
-- General setup
local pinLight = 2 -- this is GPIO4
gpio.mode(pinLight,gpio.OUTPUT)
gpio.write(pinLight,gpio.HIGH)
servo = {}
servo.pin = 4 --this is GPIO2
servo.value = 1500
servo.id = "servo"
gpio.mode(servo.pin, gpio.OUTPUT)
gpio.write(servo.pin, gpio.LOW)
-- This alarm drives the servo
tmr.alarm(0,10,1,function() -- 50Hz
if servo.value then -- generate pulse
gpio.write(servo.pin, gpio.HIGH)
tmr.delay(servo.value)
gpio.write(servo.pin, gpio.LOW)
end
end)
local function connect (conn, data)
local query_data
conn:on ("receive",
function (cn, req_data)
params = get_http_req (req_data)
cn:send("HTTP/1.1 200/OK\r\nServer: NodeLuau\r\nContent-Type: text/html\r\n\r\n")
cn:send ("<h1>ESP8266 Servo &amp; Light Server</h1>\r\n")
if (params["light"] ~= nil) then
if ("0" == params["light"]) then
gpio.write(pinLight, gpio.LOW)
else
gpio.write(pinLight, gpio.HIGH)
end
end
if (params["s0"] ~= nil) then
servo.value = tonumber(params["s0"]);
end
-- Close the connection for the request
cn:close ( )
end)
end
-- Build and return a table of the http request data
function get_http_req (instr)
local t = {}
local str = string.sub(instr, 0, 200)
local v = string.gsub(split(str, ' ')[2], '+', ' ')
parts = split(v, '?')
local params = {}
if (table.maxn(parts) > 1) then
for idx,part in ipairs(split(parts[2], '&')) do
parmPart = split(part, '=')
params[parmPart[1]] = parmPart[2]
end
end
return params
end
-- Source: http://lua-users.org/wiki/MakingLuaLikePhp
-- Credit: http://richard.warburton.it/
function split(str, splitOn)
if (splitOn=='') then return false end
local pos,arr = 0,{}
for st,sp in function() return string.find(str,splitOn,pos,true) end do
table.insert(arr,string.sub(str,pos,st-1))
pos = sp + 1
end
table.insert(arr,string.sub(str,pos))
return arr
end
-- Configure the ESP as a station (client)
wifi.setmode (wifi.STATION)
wifi.sta.config (SSID, SSID_PASSWORD)
wifi.sta.autoconnect (1)
-- Hang out until we get a wifi connection before the httpd server is started.
tmr.alarm (1, 800, 1, function ( )
if wifi.sta.getip ( ) == nil then
print ("Waiting for Wifi connection")
else
tmr.stop (1)
print ("Config done, IP is " .. wifi.sta.getip ( ))
end
end)
-- Create the httpd server
svr = net.createServer (net.TCP, 30)
-- Server listening on port 80, call connect function if a request is received
svr:listen (80, connect)
--[[
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]]--
-- Your access point's SSID and password
local SSID = "xxxxxx"
local SSID_PASSWORD = "xxxxxx"
-- configure ESP as a station
wifi.setmode(wifi.STATION)
wifi.sta.config(SSID,SSID_PASSWORD)
wifi.sta.autoconnect(1)
local TWILIO_ACCOUNT_SID = "xxxxxx"
local TWILIO_TOKEN = "xxxxxx"
local HOST = "iot-https-relay.appspot.com" -- visit http://iot-https-relay.appspot.com/ to learn more about this service
-- Please be sure to understand the security issues of using this relay app and use at your own risk.
local URI = "/twilio/Calls.json"
function build_post_request(host, uri, data_table)
local data = ""
for param,value in pairs(data_table) do
data = data .. param.."="..value.."&"
end
request = "POST "..uri.." HTTP/1.1\r\n"..
"Host: "..host.."\r\n"..
"Connection: close\r\n"..
"Content-Type: application/x-www-form-urlencoded\r\n"..
"Content-Length: "..string.len(data).."\r\n"..
"\r\n"..
data
print(request)
return request
end
local function display(sck,response)
print(response)
end
-- When using send_sms: the "from" number HAS to be your twilio number.
-- If you have a free twilio account the "to" number HAS to be your twilio verified number.
local function make_call(from,to,body)
local data = {
sid = TWILIO_ACCOUNT_SID,
token = TWILIO_TOKEN,
Body = string.gsub(body," ","+"),
From = from,
To = to
}
socket = net.createConnection(net.TCP,0)
socket:on("receive",display)
socket:connect(80,HOST)
socket:on("connection",function(sck)
local post_request = build_post_request(HOST,URI,data)
sck:send(post_request)
end)
end
function check_wifi()
local ip = wifi.sta.getip()
if(ip==nil) then
print("Connecting...")
else
tmr.stop(0)
print("Connected to AP!")
print(ip)
-- make a call with a voice message "your house is on fire"
make_call("15558976687","1334856679","Your house is on fire!")
end
end
tmr.alarm(0,2000,1,check_wifi)
-- test with cloudmqtt.com
m_dis={}
function dispatch(m,t,pl)
if pl~=nil and m_dis[t] then
m_dis[t](m,pl)
end
end
function topic1func(m,pl)
print("get1: "..pl)
end
function topic2func(m,pl)
print("get2: "..pl)
end
m_dis["/topic1"]=topic1func
m_dis["/topic2"]=topic2func
-- Lua: mqtt.Client(clientid, keepalive, user, pass)
m=mqtt.Client("nodemcu1",60,"test","test123")
m:on("connect",function(m)
print("connection "..node.heap())
m:subscribe("/topic1",0,function(m) print("sub done") end)
m:subscribe("/topic2",0,function(m) print("sub done") end)
m:publish("/topic1","hello",0,0) m:publish("/topic2","world",0,0)
end )
m:on("offline", function(conn)
print("disconnect to broker...")
print(node.heap())
end)
m:on("message",dispatch )
-- Lua: mqtt:connect( host, port, secure, auto_reconnect, function(client) )
m:connect("m11.cloudmqtt.com",11214,0,1)
tmr.alarm(0,10000,1,function() local pl = "time: "..tmr.time()
m:publish("/topic1",pl,0,0)
end)
-- test transfer files over mqtt.
m_dis={}
function dispatch(m,t,pl)
if pl~=nil and m_dis[t] then
m_dis[t](m,pl)
end
end
function pubfile(m,filename)
file.close()
file.open(filename)
repeat
local pl=file.read(1024)
if pl then m:publish("/topic2",pl,0,0) end
until not pl
file.close()
end
-- payload(json): {"cmd":xxx,"content":xxx}
function topic1func(m,pl)
print("get1: "..pl)
local pack = cjson.decode(pl)
if pack.content then
if pack.cmd == "open" then file.open(pack.content,"w+")
elseif pack.cmd == "write" then file.write(pack.content)
elseif pack.cmd == "close" then file.close()
elseif pack.cmd == "remove" then file.remove(pack.content)
elseif pack.cmd == "run" then dofile(pack.content)
elseif pack.cmd == "read" then pubfile(m, pack.content)
end
end
end
m_dis["/topic1"]=topic1func
-- Lua: mqtt.Client(clientid, keepalive, user, pass)
m=mqtt.Client()
m:on("connect",function(m)
print("connection "..node.heap())
m:subscribe("/topic1",0,function(m) print("sub done") end)
end )
m:on("offline", function(conn)
print("disconnect to broker...")
print(node.heap())
end)
m:on("message",dispatch )
-- Lua: mqtt:connect( host, port, secure, auto_reconnect, function(client) )
m:connect(192.168.18.88,1883,0,1)
-- usage:
-- another client(pc) subscribe to /topic2, will receive the test.lua content.
-- and publish below message to /topic1
-- {"cmd":"open","content":"test.lua"}
-- {"cmd":"write","content":"print([[hello world]])\n"}
-- {"cmd":"write","content":"print(\"hello2 world2\")\n"}
-- {"cmd":"write","content":"test.lua"}
-- {"cmd":"run","content":"test.lua"}
-- {"cmd":"read","content":"test.lua"}
--[[
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]]--
-- Your access point's SSID and password
local SSID = "xxxxxx"
local SSID_PASSWORD = "xxxxxx"
-- configure ESP as a station
wifi.setmode(wifi.STATION)
wifi.sta.config(SSID,SSID_PASSWORD)
wifi.sta.autoconnect(1)
local TWILIO_ACCOUNT_SID = "xxxxxx"
local TWILIO_TOKEN = "xxxxxx"
local HOST = "iot-https-relay.appspot.com" -- visit http://iot-https-relay.appspot.com/ to learn more about this service
-- Please be sure to understand the security issues of using this relay app and use at your own risk.
local URI = "/twilio/Messages.json"
function build_post_request(host, uri, data_table)
local data = ""
for param,value in pairs(data_table) do
data = data .. param.."="..value.."&"
end
request = "POST "..uri.." HTTP/1.1\r\n"..
"Host: "..host.."\r\n"..
"Connection: close\r\n"..
"Content-Type: application/x-www-form-urlencoded\r\n"..
"Content-Length: "..string.len(data).."\r\n"..
"\r\n"..
data
print(request)
return request
end
local function display(sck,response)
print(response)
end
-- When using send_sms: the "from" number HAS to be your twilio number.
-- If you have a free twilio account the "to" number HAS to be your twilio verified number.
local function send_sms(from,to,body)
local data = {
sid = TWILIO_ACCOUNT_SID,
token = TWILIO_TOKEN,
Body = string.gsub(body," ","+"),
From = from,
To = to
}
socket = net.createConnection(net.TCP,0)
socket:on("receive",display)
socket:connect(80,HOST)
socket:on("connection",function(sck)
local post_request = build_post_request(HOST,URI,data)
sck:send(post_request)
end)
end
function check_wifi()
local ip = wifi.sta.getip()
if(ip==nil) then
print("Connecting...")
else
tmr.stop(0)
print("Connected to AP!")
print(ip)
-- send a text message with the text "Hello from your esp8266"
send_sms("15558889944","15559998845","Hello from your ESP8266")
end
end
tmr.alarm(0,7000,1,check_wifi)
...@@ -2,9 +2,9 @@ ...@@ -2,9 +2,9 @@
-- setup I2c and connect display -- setup I2c and connect display
function init_i2c_display() function init_i2c_display()
-- SDA and SCL can be assigned freely to available GPIOs -- SDA and SCL can be assigned freely to available GPIOs
sda = 5 -- GPIO14 local sda = 5 -- GPIO14
scl = 6 -- GPIO12 local scl = 6 -- GPIO12
sla = 0x3c local sla = 0x3c
i2c.setup(0, sda, scl, i2c.SLOW) i2c.setup(0, sda, scl, i2c.SLOW)
disp = u8g.ssd1306_128x64_i2c(sla) disp = u8g.ssd1306_128x64_i2c(sla)
end end
...@@ -15,9 +15,9 @@ function init_spi_display() ...@@ -15,9 +15,9 @@ function init_spi_display()
-- Hardware SPI MOSI = GPIO13 -- Hardware SPI MOSI = GPIO13
-- Hardware SPI MISO = GPIO12 (not used) -- Hardware SPI MISO = GPIO12 (not used)
-- CS, D/C, and RES can be assigned freely to available GPIOs -- CS, D/C, and RES can be assigned freely to available GPIOs
cs = 8 -- GPIO15, pull-down 10k to GND local cs = 8 -- GPIO15, pull-down 10k to GND
dc = 4 -- GPIO2 local dc = 4 -- GPIO2
res = 0 -- GPIO16 local res = 0 -- GPIO16
spi.setup(1, spi.MASTER, spi.CPOL_LOW, spi.CPHA_LOW, spi.DATABITS_8, 0) spi.setup(1, spi.MASTER, spi.CPOL_LOW, spi.CPHA_LOW, spi.DATABITS_8, 0)
disp = u8g.ssd1306_128x64_spi(cs, dc, res) disp = u8g.ssd1306_128x64_spi(cs, dc, res)
......
...@@ -2,9 +2,9 @@ ...@@ -2,9 +2,9 @@
-- setup I2c and connect display -- setup I2c and connect display
function init_i2c_display() function init_i2c_display()
-- SDA and SCL can be assigned freely to available GPIOs -- SDA and SCL can be assigned freely to available GPIOs
sda = 5 -- GPIO14 local sda = 5 -- GPIO14
scl = 6 -- GPIO12 local scl = 6 -- GPIO12
sla = 0x3c local sla = 0x3c
i2c.setup(0, sda, scl, i2c.SLOW) i2c.setup(0, sda, scl, i2c.SLOW)
disp = u8g.ssd1306_128x64_i2c(sla) disp = u8g.ssd1306_128x64_i2c(sla)
end end
...@@ -15,9 +15,9 @@ function init_spi_display() ...@@ -15,9 +15,9 @@ function init_spi_display()
-- Hardware SPI MOSI = GPIO13 -- Hardware SPI MOSI = GPIO13
-- Hardware SPI MISO = GPIO12 (not used) -- Hardware SPI MISO = GPIO12 (not used)
-- CS, D/C, and RES can be assigned freely to available GPIOs -- CS, D/C, and RES can be assigned freely to available GPIOs
cs = 8 -- GPIO15, pull-down 10k to GND local cs = 8 -- GPIO15, pull-down 10k to GND
dc = 4 -- GPIO2 local dc = 4 -- GPIO2
res = 0 -- GPIO16 local res = 0 -- GPIO16
spi.setup(1, spi.MASTER, spi.CPOL_LOW, spi.CPHA_LOW, spi.DATABITS_8, 0) spi.setup(1, spi.MASTER, spi.CPOL_LOW, spi.CPHA_LOW, spi.DATABITS_8, 0)
disp = u8g.ssd1306_128x64_spi(cs, dc, res) disp = u8g.ssd1306_128x64_spi(cs, dc, res)
...@@ -91,17 +91,6 @@ function ascii_1() ...@@ -91,17 +91,6 @@ function ascii_1()
end end
end end
function ascii_2()
local x, y, s
disp:drawStr(0, 0, "ASCII page 2")
for y = 0, 5, 1 do
for x = 0, 15, 1 do
s = y*16 + x + 160
disp:drawStr(x*7, y*10+10, string.char(s))
end
end
end
function extra_page(a) function extra_page(a)
disp:drawStr(0, 12, "setScale2x2") disp:drawStr(0, 12, "setScale2x2")
disp:setScale2x2() disp:setScale2x2()
...@@ -131,8 +120,6 @@ function draw(draw_state) ...@@ -131,8 +120,6 @@ function draw(draw_state)
elseif (component == 6) then elseif (component == 6) then
ascii_1() ascii_1()
elseif (component == 7) then elseif (component == 7) then
ascii_2()
elseif (component == 8) then
extra_page(bit.band(draw_state, 7)) extra_page(bit.band(draw_state, 7))
end end
end end
......
...@@ -2,9 +2,9 @@ ...@@ -2,9 +2,9 @@
-- setup I2c and connect display -- setup I2c and connect display
function init_i2c_display() function init_i2c_display()
-- SDA and SCL can be assigned freely to available GPIOs -- SDA and SCL can be assigned freely to available GPIOs
sda = 5 -- GPIO14 local sda = 5 -- GPIO14
scl = 6 -- GPIO12 local scl = 6 -- GPIO12
sla = 0x3c local sla = 0x3c
i2c.setup(0, sda, scl, i2c.SLOW) i2c.setup(0, sda, scl, i2c.SLOW)
disp = u8g.ssd1306_128x64_i2c(sla) disp = u8g.ssd1306_128x64_i2c(sla)
end end
...@@ -15,9 +15,9 @@ function init_spi_display() ...@@ -15,9 +15,9 @@ function init_spi_display()
-- Hardware SPI MOSI = GPIO13 -- Hardware SPI MOSI = GPIO13
-- Hardware SPI MISO = GPIO12 (not used) -- Hardware SPI MISO = GPIO12 (not used)
-- CS, D/C, and RES can be assigned freely to available GPIOs -- CS, D/C, and RES can be assigned freely to available GPIOs
cs = 8 -- GPIO15, pull-down 10k to GND local cs = 8 -- GPIO15, pull-down 10k to GND
dc = 4 -- GPIO2 local dc = 4 -- GPIO2
res = 0 -- GPIO16 local res = 0 -- GPIO16
spi.setup(1, spi.MASTER, spi.CPOL_LOW, spi.CPHA_LOW, spi.DATABITS_8, 0) spi.setup(1, spi.MASTER, spi.CPOL_LOW, spi.CPHA_LOW, spi.DATABITS_8, 0)
disp = u8g.ssd1306_128x64_spi(cs, dc, res) disp = u8g.ssd1306_128x64_spi(cs, dc, res)
......
# DHTxx module # DHTxx module
This module is compatible with DHT11, DHT21 and DHT22. This module is compatible with DHT11, DHT21 and DHT22.
And is able to auto-select wheather you are using DHT11 or DHT2x
No need to use a resistor to connect the pin data of DHT22 to ESP8266. No need to use a resistor to connect the pin data of DHT22 to ESP8266.
##Integer Verison[When using DHT11, Float version is useless...] ##Integer Verison[When using DHT11, Float version is useless...]
...@@ -10,14 +12,13 @@ PIN = 4 -- data pin, GPIO2 ...@@ -10,14 +12,13 @@ PIN = 4 -- data pin, GPIO2
DHT= require("dht_lib") DHT= require("dht_lib")
--dht.read11(PIN) DHT.read(PIN)
DHT.read22(PIN)
t = DHT.getTemperature() t = DHT.getTemperature()
h = DHT.getHumidity() h = DHT.getHumidity()
if h == nil then if h == nil then
print("Error reading from DHT11/22") print("Error reading from DHTxx")
else else
-- temperature in degrees Celsius and Farenheit -- temperature in degrees Celsius and Farenheit
...@@ -41,8 +42,7 @@ PIN = 4 -- data pin, GPIO2 ...@@ -41,8 +42,7 @@ PIN = 4 -- data pin, GPIO2
DHT= require("dht_lib") DHT= require("dht_lib")
--dht.read11(PIN) DHT.read(PIN)
DHT.read22(PIN)
t = DHT.getTemperature() t = DHT.getTemperature()
h = DHT.getHumidity() h = DHT.getHumidity()
...@@ -52,11 +52,12 @@ if h == nil then ...@@ -52,11 +52,12 @@ if h == nil then
else else
-- temperature in degrees Celsius and Farenheit -- temperature in degrees Celsius and Farenheit
-- floating point and integer version: -- floating point and integer version:
print("Temperature: "..t.." deg C")
print("Temperature: "..(t/10).." deg C")
print("Temperature: "..(9 * t / 50 + 32).." deg F") print("Temperature: "..(9 * t / 50 + 32).." deg F")
-- humidity -- humidity
print("Humidity: "..h.."%") print("Humidity: "..(h/10).."%")
end end
-- release module -- release module
...@@ -64,12 +65,10 @@ DHT = nil ...@@ -64,12 +65,10 @@ DHT = nil
package.loaded["dht_lib"]=nil package.loaded["dht_lib"]=nil
``` ```
## Functions ## Functions
### read11
read11(pin) ###read
Read humidity and temperature from DHT11. read(pin)
###read22 Read humidity and temperature from DHTxx(11,21,22...).
read22(pin)
Read humidity and temperature from DHT22/21.
**Parameters:** **Parameters:**
* pin - ESP8266 pin connect to data pin * pin - ESP8266 pin connect to data pin
...@@ -88,4 +87,3 @@ Returns the temperature of the last reading. ...@@ -88,4 +87,3 @@ Returns the temperature of the last reading.
**Returns:** **Returns:**
* last temperature reading in(dht22) 0.1ºC (dht11)1ºC * last temperature reading in(dht22) 0.1ºC (dht11)1ºC
* *
...@@ -8,10 +8,13 @@ ...@@ -8,10 +8,13 @@
-- *************************************************************************** -- ***************************************************************************
--Support list: --Support list:
--DHT11 Tested ->read11
--DHT21 Not Tested->read22
--DHT22 Tested->read22
--DHT11 Tested
--DHT21 Not Test yet
--DHT22(AM2302) Tested
--AM2320 Not Test yet
--Output format-> Real temperature times 10(or DHT22 will miss it float part in Int Version)
--==========================Module Part====================== --==========================Module Part======================
local moduleName = ... local moduleName = ...
local M = {} local M = {}
...@@ -37,8 +40,6 @@ local function read(pin) ...@@ -37,8 +40,6 @@ local function read(pin)
bitStream[j] = 0 bitStream[j] = 0
end end
-- Step 1: send out start signal to DHT22 -- Step 1: send out start signal to DHT22
gpio.mode(pin, gpio.OUTPUT) gpio.mode(pin, gpio.OUTPUT)
gpio.write(pin, gpio.HIGH) gpio.write(pin, gpio.HIGH)
...@@ -69,68 +70,79 @@ local function read(pin) ...@@ -69,68 +70,79 @@ local function read(pin)
while (gpio_read(pin) == 0) do end while (gpio_read(pin) == 0) do end
end end
end end
---------------------------Convert the bitStream into Number through DHT11 Ways--------------------------
function M.read11(pin) ---------------------------Check out the data--------------------------
--As for DHT11 40Bit is consisit of 5Bytes ----Auto Select the DHT11/DHT22 By check the byte[1] && byte[3] -------
--First byte->Humidity Data's Int part ---------------Which is empty when using DHT11-------------------------
--Sencond byte->Humidity Data's Float Part(Which should be empty) function M.read(pin)
--Third byte->Temp Data;s Intpart
--Forth byte->Temp Data's Float Part(Which should be empty)
--Fifth byte->SUM Byte, Humi+Temp
read(pin) read(pin)
local checksum = 0
local checksumTest local byte_0 = 0
--DHT data acquired, process. local byte_1 = 0
local byte_2 = 0
local byte_3 = 0
local byte_4 = 0
for i = 1, 8, 1 do -- Byte[0] for i = 1, 8, 1 do -- Byte[0]
if (bitStream[i] > 3) then if (bitStream[i] > 3) then
humidity = humidity + 2 ^ (8 - i) byte_0 = byte_0 + 2 ^ (8 - i)
end end
end end
for i = 1, 8, 1 do -- Byte[2]
if (bitStream[i + 16] > 3) then for i = 1, 8, 1 do -- Byte[1]
temperature = temperature + 2 ^ (8 - i) if (bitStream[i+8] > 3) then
end byte_1 = byte_1 + 2 ^ (8 - i)
end
for i = 1, 8, 1 do --Byte[4]
if (bitStream[i + 32] > 3) then
checksum = checksum + 2 ^ (8 - i)
end end
end end
if(checksum ~= humidity+temperature) then for i = 1, 8, 1 do -- Byte[2]
humidity = nil if (bitStream[i+16] > 3) then
temperature = nil byte_2 = byte_2 + 2 ^ (8 - i)
end end
end
---------------------------Convert the bitStream into Number through DHT22 Ways--------------------------
function M.read22( pin )
--As for DHT22 40Bit is consisit of 5Bytes
--First byte->Humidity Data's High Bit
--Sencond byte->Humidity Data's Low Bit(And if over 0x8000, use complement)
--Third byte->Temp Data's High Bit
--Forth byte->Temp Data's Low Bit
--Fifth byte->SUM Byte
read(pin)
local checksum = 0
local checksumTest
--DHT data acquired, process.
for i = 1, 16, 1 do
if (bitStream[i] > 3) then
humidity = humidity + 2 ^ (16 - i)
end end
for i = 1, 8, 1 do -- Byte[3]
if (bitStream[i+24] > 3) then
byte_2 = byte_2 + 2 ^ (8 - i)
end end
for i = 1, 16, 1 do
if (bitStream[i + 16] > 3) then
temperature = temperature + 2 ^ (16 - i)
end end
for i = 1, 8, 1 do -- Byte[4]
if (bitStream[i+32] > 3) then
byte_4 = byte_4 + 2 ^ (8 - i)
end end
for i = 1, 8, 1 do
if (bitStream[i + 32] > 3) then
checksum = checksum + 2 ^ (8 - i)
end end
if byte_1==0 and byte_3 == 0 then
---------------------------Convert the bitStream into Number through DHT11's Way--------------------------
--As for DHT11 40Bit is consisit of 5Bytes
--First byte->Humidity Data's Int part
--Sencond byte->Humidity Data's Float Part(Which should be empty)
--Third byte->Temp Data;s Intpart
--Forth byte->Temp Data's Float Part(Which should be empty)
--Fifth byte->SUM Byte, Humi+Temp
if(byte_4 ~= byte_0+byte_2) then
humidity = nil
temperature = nil
else
humidity = byte_0 *10 -- In order to universe with the DHT22
temperature = byte_2 *10
end end
else ---------------------------Convert the bitStream into Number through DHT22's Way--------------------------
--As for DHT22 40Bit is consisit of 5Bytes
--First byte->Humidity Data's High Bit
--Sencond byte->Humidity Data's Low Bit(And if over 0x8000, use complement)
--Third byte->Temp Data's High Bit
--Forth byte->Temp Data's Low Bit
--Fifth byte->SUM Byte
humidity = byte_0 * 256 + byte_1
temperature = byte_2 * 256 + byte_3
checksum = byte_4
checksumTest = (bit.band(humidity, 0xFF) + bit.rshift(humidity, 8) + bit.band(temperature, 0xFF) + bit.rshift(temperature, 8)) checksumTest = (bit.band(humidity, 0xFF) + bit.rshift(humidity, 8) + bit.band(temperature, 0xFF) + bit.rshift(temperature, 8))
checksumTest = bit.band(checksumTest, 0xFF) checksumTest = bit.band(checksumTest, 0xFF)
...@@ -143,9 +155,18 @@ function M.read22( pin ) ...@@ -143,9 +155,18 @@ function M.read22( pin )
if (checksumTest - checksum >= 1) or (checksum - checksumTest >= 1) then if (checksumTest - checksum >= 1) or (checksum - checksumTest >= 1) then
humidity = nil humidity = nil
end end
end
byte_0 = nil
byte_1 = nil
byte_2 = nil
byte_3 = nil
byte_4 = nil
end end
--------------API for geting the data out------------------
---------------------------Check out the data--------------------------
function M.getTemperature() function M.getTemperature()
return temperature return temperature
end end
...@@ -153,5 +174,5 @@ end ...@@ -153,5 +174,5 @@ end
function M.getHumidity() function M.getHumidity()
return humidity return humidity
end end
-------------Return Index------------------------------------
return M return M
# LM92 module
This module adds basic support for the LM92 +-0.33C 12bit+sign temperature sensor. More details in the [datasheet](http://www.ti.com/lit/ds/symlink/lm92.pdf).
Works:
- getting the temperature
- entering the chip's to shutdown mode (350uA -> 5uA power consumption)
- waking up the chip from shutdown
##Require
```lua
LM92 = require("lm92")
```
## Release
```lua
LM92 = nil
package.loaded["lm92"]=nil
```
##init()
####Description
Setting the i2c pins and address for lm92.
####Syntax
init(sda, scl, address)
####Parameters
sda: 1~12, IO index.<br />
scl: 1~12, IO index.<br />
address: 0x48~0x4b, i2c address (depends on tha A0~A1 pins)
####Returns
nil
####Example
```lua
LM92 = require("lm92")
gpio0 = 3
gpio2 = 4
sda = gpio0
scl = gpio2
addr = 0x48
LM92.init(sda, scl,addr)
```
##getTemperature()
####Description
Returns the temperature register's content.
####Syntax
getTemperature()
####Parameters
-
####Returns
Temperature in degree Celsius.
####Example
```lua
t = LM92.getTemperature()
print("Got temperature: "..t.." C")
```
##wakeup()
####Description
Makes the chip exit the low power shutdown mode.
####Syntax
wakeup()
####Parameters
-
####Returns
-
####Example
```lua
LM92.wakeup()
tmr.delay( 1 * 1000 * 1000 )
```
##shutdown()
####Description
Makes the chip enter the low power shutdown mode.
####Syntax
shutdown()
####Parameters
-
####Returns
-
####Example
```lua
LM92.shutdown()
```
#### TODO:
- add full support of the features, including interrupt and critical alert support
-- ******************************************************
-- LM92 module for ESP8266 with nodeMCU
--
-- Written by Levente Tamas <levente.tamas@navicron.com>
--
-- GNU LGPL, see https://www.gnu.org/copyleft/lesser.html
-- ******************************************************
-- Module Bits
local moduleName = ...
local M = {}
_G[moduleName] = M
-- Default ID
local id = 0
-- Local vars
local address = 0
-- read regs for len number of bytes
-- return table with data
local function read_reg(reg_addr, len)
local ret={}
local c
local x
i2c.start(id)
i2c.address(id, address ,i2c.TRANSMITTER)
i2c.write(id,reg_addr)
i2c.stop(id)
i2c.start(id)
i2c.address(id, address,i2c.RECEIVER)
c=i2c.read(id,len)
for x=1,len,1 do
tc=string.byte(c,x)
table.insert(ret,tc)
end
i2c.stop(id)
return ret
end
--write reg with data table
local function write_reg(reg_addr, data)
i2c.start(id)
i2c.address(id, address, i2c.TRANSMITTER)
i2c.write(id, reg_addr)
i2c.write(id, data)
i2c.stop(id)
end
-- initialize i2c
-- d: sda
-- c: scl
-- a: i2c addr 0x48|A1<<1|A0 (A0-A1: chip pins)
function M.init(d,c,a)
if (d ~= nil) and (c ~= nil) and (d >= 0) and (d <= 11) and (c >= 0) and ( c <= 11) and (d ~= l) and (a ~= nil) and (a >= 0x48) and (a <= 0x4b ) then
sda = d
scl = c
address = a
i2c.start(id)
res = i2c.address(id, address, i2c.TRANSMITTER) --verify that the address is valid
i2c.stop(id)
if (res == false) then
print("device not found")
return nil
end
else
print("i2c configuration failed") return nil
end
i2c.setup(id,sda,scl,i2c.SLOW)
end
-- Return the temperature data
function M.getTemperature()
local temperature
local tmp=read_reg(0x00,2) --read 2 bytes from the temperature register
temperature=bit.rshift(tmp[1]*256+tmp[2],3) --lower 3 bits are status bits
if (temperature>=0x1000) then
temperature= temperature-0x2000 --convert the two's complement
end
return temperature * 0.0625
end
-- Put the LM92 into shutdown mode
function M.shutdown()
write_reg(0x01,0x01)
end
-- Bring the LM92 out of shutdown mode
function M.wakeup()
write_reg(0x01,0x00)
end
return M
\ No newline at end of file
-- ***************************************************************************
-- Example for Yeelink Lib
--
-- Written by Martin
--
--
-- MIT license, http://opensource.org/licenses/MIT
-- ***************************************************************************
wifi.setmode(wifi.STATION) --Step1: Connect to Wifi
wifi.sta.config("SSID","Password")
dht = require("dht_lib") --Step2: "Require" the libs
yeelink = require("yeelink_lib")
yeelink.init(23333,23333,"You api-key",function() --Step3: Register the callback function
print("Yeelink Init OK...")
tmr.alarm(1,60000,1,function() --Step4: Have fun~ (Update your data)
dht.read(4)
yeelink.update(dht.getTemperature())
end)
end)
-- ***************************************************************************
-- Yeelink Updata Libiary Version 0.1.2 r1
--
-- Written by Martin
-- but based on a script of zhouxu_o from bbs.nodemcu.com
--
-- MIT license, http://opensource.org/licenses/MIT
-- ***************************************************************************
--==========================Module Part======================
local moduleName = ...
local M = {}
_G[moduleName] = M
--=========================Local Args=======================
local dns = "0.0.0.0"
local device = ""
local sensor = ""
local apikey = ""
--================================
local debug = true --<<<<<<<<<<<<< Don't forget to "false" it before using
--================================
local sk=net.createConnection(net.TCP, 0)
local datapoint = 0
--====DNS the yeelink ip advance(in order to save RAM)=====
if wifi.sta.getip() == nil then
print("Please Connect WIFI First")
tmr.alarm(1,1000,1,function ()
if wifi.sta.getip() ~= nil then
tmr.stop(1)
sk:dns("api.yeelink.net",function(conn,ip)
dns=ip
print("DNS YEELINK OK... IP: "..dns)
end)
end
end)
end
sk:dns("api.yeelink.net",function(conn,ip)
dns=ip
print("DNS YEELINK OK... IP: "..dns)
end)
--========Set the init function===========
--device->number
--sensor->number
-- apikey must be -> string <-
-- e.g. xxx.init(00000,00000,"123j12b3jkb12k4b23bv54i2b5b3o4")
--========================================
function M.init(_device, _sensor, _apikey)
device = tostring(_device)
sensor = tostring(_sensor)
apikey = _apikey
if dns == "0.0.0.0" then
tmr.alarm(2,5000,1,function ()
if dns == "0.0.0.0" then
print("Waiting for DNS...")
end
end)
return false
else
return dns
end
end
--========Check the DNS Status===========
--if DNS success, return the address(string)
--if DNS fail(or processing), return nil
--
--
--========================================
function M.getDNS()
if dns == "0.0.0.0" then
return nil
else
return dns
end
end
--=====Update to Yeelink Sever(At least 10s per sencods))=====
-- datapoint->number
--
--e.g. xxx.update(233.333)
--============================================================
function M.update(_datapoint)
datapoint = tostring(_datapoint)
sk:on("connection", function(conn)
print("connect OK...")
local a=[[{"value":]]
local b=[[}]]
local st=a..datapoint..b
sk:send("POST /v1.0/device/"..device.."/sensor/"..sensor.."/datapoints HTTP/1.1\r\n"
.."Host: www.yeelink.net\r\n"
.."Content-Length: "..string.len(st).."\r\n"--the length of json is important
.."Content-Type: application/x-www-form-urlencoded\r\n"
.."U-ApiKey:"..apikey.."\r\n"
.."Cache-Control: no-cache\r\n\r\n"
..st.."\r\n" )
end)
sk:on("receive", function(sck, content)
if debug then
print("\r\n"..content.."\r\n")
else
print("Date Receive")
end
end)
sk:connect(80,dns)
end
--================end==========================
return M
...@@ -41,7 +41,7 @@ class ESPROM: ...@@ -41,7 +41,7 @@ class ESPROM:
# Maximum block sized for RAM and Flash writes, respectively. # Maximum block sized for RAM and Flash writes, respectively.
ESP_RAM_BLOCK = 0x1800 ESP_RAM_BLOCK = 0x1800
ESP_FLASH_BLOCK = 0x100 ESP_FLASH_BLOCK = 0x400
# Default baudrate. The ROM auto-bauds, so we can use more or less whatever we want. # Default baudrate. The ROM auto-bauds, so we can use more or less whatever we want.
ESP_ROM_BAUD = 115200 ESP_ROM_BAUD = 115200
...@@ -56,6 +56,12 @@ class ESPROM: ...@@ -56,6 +56,12 @@ class ESPROM:
ESP_OTP_MAC0 = 0x3ff00050 ESP_OTP_MAC0 = 0x3ff00050
ESP_OTP_MAC1 = 0x3ff00054 ESP_OTP_MAC1 = 0x3ff00054
# Sflash stub: an assembly routine to read from spi flash and send to host
SFLASH_STUB = "\x80\x3c\x00\x40\x1c\x4b\x00\x40\x21\x11\x00\x40\x00\x80" \
"\xfe\x3f\xc1\xfb\xff\xd1\xf8\xff\x2d\x0d\x31\xfd\xff\x41\xf7\xff\x4a" \
"\xdd\x51\xf9\xff\xc0\x05\x00\x21\xf9\xff\x31\xf3\xff\x41\xf5\xff\xc0" \
"\x04\x00\x0b\xcc\x56\xec\xfd\x06\xff\xff\x00\x00"
def __init__(self, port = 0, baud = ESP_ROM_BAUD): def __init__(self, port = 0, baud = ESP_ROM_BAUD):
self._port = serial.Serial(port, baud) self._port = serial.Serial(port, baud)
...@@ -78,15 +84,7 @@ class ESPROM: ...@@ -78,15 +84,7 @@ class ESPROM:
""" Write bytes to the serial port while performing SLIP escaping """ """ Write bytes to the serial port while performing SLIP escaping """
def write(self, packet): def write(self, packet):
buf = '\xc0' buf = '\xc0'+(packet.replace('\xdb','\xdb\xdd').replace('\xc0','\xdb\xdc'))+'\xc0'
for b in packet:
if b == '\xc0':
buf += '\xdb\xdc'
elif b == '\xdb':
buf += '\xdb\xdd'
else:
buf += b
buf += '\xc0'
self._port.write(buf) self._port.write(buf)
""" Calculate checksum of a blob, as it is defined by the ROM """ """ Calculate checksum of a blob, as it is defined by the ROM """
...@@ -132,11 +130,25 @@ class ESPROM: ...@@ -132,11 +130,25 @@ class ESPROM:
# RTS = CH_PD (i.e reset) # RTS = CH_PD (i.e reset)
# DTR = GPIO0 # DTR = GPIO0
# self._port.setRTS(True)
# self._port.setDTR(True)
# self._port.setRTS(False)
# time.sleep(0.1)
# self._port.setDTR(False)
# NodeMCU devkit
self._port.setRTS(True) self._port.setRTS(True)
self._port.setDTR(True) self._port.setDTR(True)
self._port.setRTS(False)
time.sleep(0.1) time.sleep(0.1)
self._port.setRTS(False)
self._port.setDTR(False) self._port.setDTR(False)
time.sleep(0.1)
self._port.setRTS(True)
time.sleep(0.1)
self._port.setDTR(True)
self._port.setRTS(False)
time.sleep(0.3)
self._port.setDTR(True)
self._port.timeout = 0.5 self._port.timeout = 0.5
for i in xrange(10): for i in xrange(10):
...@@ -209,16 +221,78 @@ class ESPROM: ...@@ -209,16 +221,78 @@ class ESPROM:
self.flash_begin(0, 0) self.flash_begin(0, 0)
self.flash_finish(reboot) self.flash_finish(reboot)
""" Read MAC from OTP ROM """
def read_mac(self):
mac0 = esp.read_reg(esp.ESP_OTP_MAC0)
mac1 = esp.read_reg(esp.ESP_OTP_MAC1)
if ((mac1 >> 16) & 0xff) == 0:
oui = (0x18, 0xfe, 0x34)
elif ((mac1 >> 16) & 0xff) == 1:
oui = (0xac, 0xd0, 0x74)
else:
raise Exception("Unknown OUI")
return oui + ((mac1 >> 8) & 0xff, mac1 & 0xff, (mac0 >> 24) & 0xff)
""" Read SPI flash manufacturer and device id """
def flash_id(self):
self.flash_begin(0, 0)
self.write_reg(0x60000240, 0x0, 0xffffffff)
self.write_reg(0x60000200, 0x10000000, 0xffffffff)
flash_id = esp.read_reg(0x60000240)
self.flash_finish(False)
return flash_id
""" Read SPI flash """
def flash_read(self, offset, size, count = 1):
# Create a custom stub
stub = struct.pack('<III', offset, size, count) + self.SFLASH_STUB
# Trick ROM to initialize SFlash
self.flash_begin(0, 0)
# Download stub
self.mem_begin(len(stub), 1, len(stub), 0x40100000)
self.mem_block(stub, 0)
self.mem_finish(0x4010001c)
# Fetch the data
data = ''
for _ in xrange(count):
if self._port.read(1) != '\xc0':
raise Exception('Invalid head of packet (sflash read)')
data += self.read(size)
if self._port.read(1) != chr(0xc0):
raise Exception('Invalid end of packet (sflash read)')
return data
""" Perform a chip erase of SPI flash """
def flash_erase(self):
# Trick ROM to initialize SFlash
self.flash_begin(0, 0)
# This is hacky: we don't have a custom stub, instead we trick
# the bootloader to jump to the SPIEraseChip() routine and then halt/crash
# when it tries to boot an unconfigured system.
self.mem_begin(0,0,0,0x40100000)
self.mem_finish(0x40004984)
# Yup - there's no good way to detect if we succeeded.
# It it on the other hand unlikely to fail.
class ESPFirmwareImage: class ESPFirmwareImage:
def __init__(self, filename = None): def __init__(self, filename = None):
self.segments = [] self.segments = []
self.entrypoint = 0 self.entrypoint = 0
self.flash_mode = 0
self.flash_size_freq = 0
if filename is not None: if filename is not None:
f = file(filename, 'rb') f = file(filename, 'rb')
(magic, segments, _, _, self.entrypoint) = struct.unpack('<BBBBI', f.read(8)) (magic, segments, self.flash_mode, self.flash_size_freq, self.entrypoint) = struct.unpack('<BBBBI', f.read(8))
# some sanity check # some sanity check
if magic != ESPROM.ESP_IMAGE_MAGIC or segments > 16: if magic != ESPROM.ESP_IMAGE_MAGIC or segments > 16:
...@@ -246,7 +320,8 @@ class ESPFirmwareImage: ...@@ -246,7 +320,8 @@ class ESPFirmwareImage:
def save(self, filename): def save(self, filename):
f = file(filename, 'wb') f = file(filename, 'wb')
f.write(struct.pack('<BBBBI', ESPROM.ESP_IMAGE_MAGIC, len(self.segments), 0, 0, self.entrypoint)) f.write(struct.pack('<BBBBI', ESPROM.ESP_IMAGE_MAGIC, len(self.segments),
self.flash_mode, self.flash_size_freq, self.entrypoint))
checksum = ESPROM.ESP_CHECKSUM_MAGIC checksum = ESPROM.ESP_CHECKSUM_MAGIC
for (offset, size, data) in self.segments: for (offset, size, data) in self.segments:
...@@ -346,6 +421,12 @@ if __name__ == '__main__': ...@@ -346,6 +421,12 @@ if __name__ == '__main__':
'write_flash', 'write_flash',
help = 'Write a binary blob to flash') help = 'Write a binary blob to flash')
parser_write_flash.add_argument('addr_filename', nargs = '+', help = 'Address and binary file to write there, separated by space') parser_write_flash.add_argument('addr_filename', nargs = '+', help = 'Address and binary file to write there, separated by space')
parser_write_flash.add_argument('--flash_freq', '-ff', help = 'SPI Flash frequency',
choices = ['40m', '26m', '20m', '80m'], default = '40m')
parser_write_flash.add_argument('--flash_mode', '-fm', help = 'SPI Flash mode',
choices = ['qio', 'qout', 'dio', 'dout'], default = 'qio')
parser_write_flash.add_argument('--flash_size', '-fs', help = 'SPI Flash size in Mbit',
choices = ['4m', '2m', '8m', '16m', '32m'], default = '4m')
parser_run = subparsers.add_parser( parser_run = subparsers.add_parser(
'run', 'run',
...@@ -369,11 +450,32 @@ if __name__ == '__main__': ...@@ -369,11 +450,32 @@ if __name__ == '__main__':
help = 'Create an application image from ELF file') help = 'Create an application image from ELF file')
parser_elf2image.add_argument('input', help = 'Input ELF file') parser_elf2image.add_argument('input', help = 'Input ELF file')
parser_elf2image.add_argument('--output', '-o', help = 'Output filename prefix', type = str) parser_elf2image.add_argument('--output', '-o', help = 'Output filename prefix', type = str)
parser_elf2image.add_argument('--flash_freq', '-ff', help = 'SPI Flash frequency',
choices = ['40m', '26m', '20m', '80m'], default = '40m')
parser_elf2image.add_argument('--flash_mode', '-fm', help = 'SPI Flash mode',
choices = ['qio', 'qout', 'dio', 'dout'], default = 'qio')
parser_elf2image.add_argument('--flash_size', '-fs', help = 'SPI Flash size in Mbit',
choices = ['4m', '2m', '8m', '16m', '32m'], default = '4m')
parser_read_mac = subparsers.add_parser( parser_read_mac = subparsers.add_parser(
'read_mac', 'read_mac',
help = 'Read MAC address from OTP ROM') help = 'Read MAC address from OTP ROM')
parser_flash_id = subparsers.add_parser(
'flash_id',
help = 'Read SPI flash manufacturer and device ID')
parser_read_flash = subparsers.add_parser(
'read_flash',
help = 'Read SPI flash content')
parser_read_flash.add_argument('address', help = 'Start address', type = arg_auto_int)
parser_read_flash.add_argument('size', help = 'Size of region to dump', type = arg_auto_int)
parser_read_flash.add_argument('filename', help = 'Name of binary dump')
parser_erase_flash = subparsers.add_parser(
'erase_flash',
help = 'Perform Chip Erase on SPI flash')
args = parser.parse_args() args = parser.parse_args()
# Create the ESPROM connection object, if needed # Create the ESPROM connection object, if needed
...@@ -421,6 +523,12 @@ if __name__ == '__main__': ...@@ -421,6 +523,12 @@ if __name__ == '__main__':
elif args.operation == 'write_flash': elif args.operation == 'write_flash':
assert len(args.addr_filename) % 2 == 0 assert len(args.addr_filename) % 2 == 0
flash_mode = {'qio':0, 'qout':1, 'dio':2, 'dout': 3}[args.flash_mode]
flash_size_freq = {'4m':0x00, '2m':0x10, '8m':0x20, '16m':0x30, '32m':0x40}[args.flash_size]
flash_size_freq += {'40m':0, '26m':1, '20m':2, '80m': 0xf}[args.flash_freq]
flash_info = struct.pack('BB', flash_mode, flash_size_freq)
while args.addr_filename: while args.addr_filename:
address = int(args.addr_filename[0], 0) address = int(args.addr_filename[0], 0)
filename = args.addr_filename[1] filename = args.addr_filename[1]
...@@ -434,7 +542,11 @@ if __name__ == '__main__': ...@@ -434,7 +542,11 @@ if __name__ == '__main__':
print '\rWriting at 0x%08x... (%d %%)' % (address + seq*esp.ESP_FLASH_BLOCK, 100*(seq+1)/blocks), print '\rWriting at 0x%08x... (%d %%)' % (address + seq*esp.ESP_FLASH_BLOCK, 100*(seq+1)/blocks),
sys.stdout.flush() sys.stdout.flush()
block = image[0:esp.ESP_FLASH_BLOCK] block = image[0:esp.ESP_FLASH_BLOCK]
block = block + '\xe0' * (esp.ESP_FLASH_BLOCK-len(block)) # Fix sflash config data
if address == 0 and seq == 0 and block[0] == '\xe9':
block = block[0:2] + flash_info + block[4:]
# Pad the last block
block = block + '\xff' * (esp.ESP_FLASH_BLOCK-len(block))
esp.flash_block(block, seq) esp.flash_block(block, seq)
image = image[esp.ESP_FLASH_BLOCK:] image = image[esp.ESP_FLASH_BLOCK:]
seq += 1 seq += 1
...@@ -478,6 +590,11 @@ if __name__ == '__main__': ...@@ -478,6 +590,11 @@ if __name__ == '__main__':
for section, start in ((".text", "_text_start"), (".data", "_data_start"), (".rodata", "_rodata_start")): for section, start in ((".text", "_text_start"), (".data", "_data_start"), (".rodata", "_rodata_start")):
data = e.load_section(section) data = e.load_section(section)
image.add_segment(e.get_symbol_addr(start), data) image.add_segment(e.get_symbol_addr(start), data)
image.flash_mode = {'qio':0, 'qout':1, 'dio':2, 'dout': 3}[args.flash_mode]
image.flash_size_freq = {'4m':0x00, '2m':0x10, '8m':0x20, '16m':0x30, '32m':0x40}[args.flash_size]
image.flash_size_freq += {'40m':0, '26m':1, '20m':2, '80m': 0xf}[args.flash_freq]
image.save(args.output + "0x00000.bin") image.save(args.output + "0x00000.bin")
data = e.load_section(".irom0.text") data = e.load_section(".irom0.text")
off = e.get_symbol_addr("_irom0_text_start") - 0x40200000 off = e.get_symbol_addr("_irom0_text_start") - 0x40200000
...@@ -487,6 +604,17 @@ if __name__ == '__main__': ...@@ -487,6 +604,17 @@ if __name__ == '__main__':
f.close() f.close()
elif args.operation == 'read_mac': elif args.operation == 'read_mac':
mac0 = esp.read_reg(esp.ESP_OTP_MAC0) mac = esp.read_mac()
mac1 = esp.read_reg(esp.ESP_OTP_MAC1) print 'MAC: %s' % ':'.join(map(lambda x: '%02x'%x, mac))
print 'MAC: 18:fe:34:%02x:%02x:%02x' % ((mac1 >> 8) & 0xff, mac1 & 0xff, (mac0 >> 24) & 0xff)
elif args.operation == 'flash_id':
flash_id = esp.flash_id()
print 'Manufacturer: %02x' % (flash_id & 0xff)
print 'Device: %02x%02x' % ((flash_id >> 8) & 0xff, (flash_id >> 16) & 0xff)
elif args.operation == 'read_flash':
print 'Please wait...'
file(args.filename, 'wb').write(esp.flash_read(args.address, 1024, int(math.ceil(args.size / 1024.)))[:args.size])
elif args.operation == 'erase_flash':
esp.flash_erase()
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment