Commit be047ff7 authored by Marcel Stör's avatar Marcel Stör
Browse files

Merge branch 'dev', 1.5.4.1 master drop

parents b580bfe7 a8d984ae
...@@ -34,6 +34,8 @@ If you also want to verify that all is well with your Markdown files you can ins ...@@ -34,6 +34,8 @@ If you also want to verify that all is well with your Markdown files you can ins
A note on Markdown *syntax*. As Mkdocs is Python-based it's no surprise it uses a [Python Markdown implementation](https://pythonhosted.org/Markdown/). The good news is that it sticks pretty closely to John Gruber's Markdown and also [supports tables and fenced code blocks](http://www.mkdocs.org/user-guide/writing-your-docs/#markdown-extensions) just like GitHub does. A note on Markdown *syntax*. As Mkdocs is Python-based it's no surprise it uses a [Python Markdown implementation](https://pythonhosted.org/Markdown/). The good news is that it sticks pretty closely to John Gruber's Markdown and also [supports tables and fenced code blocks](http://www.mkdocs.org/user-guide/writing-your-docs/#markdown-extensions) just like GitHub does.
A collection of doc-writing hints and tips is maintained on the [wiki](https://github.com/nodemcu/nodemcu-firmware/wiki/Notes-about-writing-docs).
If you're interested in some NodeMCU history you're welcome to read [issue #774](https://github.com/nodemcu/nodemcu-firmware/issues/774) If you're interested in some NodeMCU history you're welcome to read [issue #774](https://github.com/nodemcu/nodemcu-firmware/issues/774)
## Working with Git and GitHub ## Working with Git and GitHub
......
...@@ -3,10 +3,21 @@ ...@@ -3,10 +3,21 @@
.NOTPARALLEL: .NOTPARALLEL:
# SDK version NodeMCU is locked to # SDK version NodeMCU is locked to
SDK_VER:=1.5.1 SDK_VER:=1.5.4.1
SDK_FILE_VER:=$(SDK_VER)_16_01_08
SDK_FILE_ID:=1046 # no patch: SDK_BASE_VER equals SDK_VER and sdk dir depends on sdk_extracted
SDK_FILE_SHA1:=374f689a5f9e47690d7b4cd2fc1a1094f3fd5a4f #SDK_BASE_VER:=SDK_VER
#SDK_DIR_DEPENDS:=sdk_extracted
# with patch: SDK_BASE_VER differs from SDK_VER and sdk dir depends on sdk_patched
SDK_BASE_VER:=1.5.4
SDK_DIR_DEPENDS:=sdk_patched
SDK_FILE_VER:=$(SDK_BASE_VER)_16_05_20
SDK_FILE_ID:=1469
SDK_FILE_SHA1:=868784bd37d47f31d52b81f133aa1fb70c58e17d
SDK_PATCH_VER:=$(SDK_VER)_patch_20160704
SDK_PATCH_ID:=1572
SDK_PATCH_SHA1:=388d9e91df74e3b49fca126da482cf822cf1ebf1
# Ensure we search "our" SDK before the tool-chain's SDK (if any) # Ensure we search "our" SDK before the tool-chain's SDK (if any)
TOP_DIR:=$(abspath $(dir $(lastword $(MAKEFILE_LIST)))) TOP_DIR:=$(abspath $(dir $(lastword $(MAKEFILE_LIST))))
SDK_DIR:=$(TOP_DIR)/sdk/esp_iot_sdk_v$(SDK_VER) SDK_DIR:=$(TOP_DIR)/sdk/esp_iot_sdk_v$(SDK_VER)
...@@ -90,7 +101,7 @@ ESPTOOL ?= ../tools/esptool.py ...@@ -90,7 +101,7 @@ ESPTOOL ?= ../tools/esptool.py
CSRCS ?= $(wildcard *.c) CSRCS ?= $(wildcard *.c)
ASRCs ?= $(wildcard *.s) ASRCs ?= $(wildcard *.s)
ASRCS ?= $(wildcard *.S) ASRCS ?= $(wildcard *.S)
SUBDIRS ?= $(patsubst %/,%,$(dir $(wildcard */Makefile))) SUBDIRS ?= $(patsubst %/,%,$(dir $(filter-out tools/Makefile,$(wildcard */Makefile))))
ODIR := .output ODIR := .output
OBJODIR := $(ODIR)/$(TARGET)/$(FLAVOR)/obj OBJODIR := $(ODIR)/$(TARGET)/$(FLAVOR)/obj
...@@ -112,6 +123,14 @@ OIMAGES := $(GEN_IMAGES:%=$(IMAGEODIR)/%) ...@@ -112,6 +123,14 @@ OIMAGES := $(GEN_IMAGES:%=$(IMAGEODIR)/%)
BINODIR := $(ODIR)/$(TARGET)/$(FLAVOR)/bin BINODIR := $(ODIR)/$(TARGET)/$(FLAVOR)/bin
OBINS := $(GEN_BINS:%=$(BINODIR)/%) OBINS := $(GEN_BINS:%=$(BINODIR)/%)
ifndef PDIR
ifneq ($(wildcard $(TOP_DIR)/local/fs/*),)
SPECIAL_MKTARGETS += spiffs-image
else
SPECIAL_MKTARGETS += spiffs-image-remove
endif
endif
# #
# Note: # Note:
# https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html # https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
...@@ -171,15 +190,25 @@ $(BINODIR)/%.bin: $(IMAGEODIR)/%.out ...@@ -171,15 +190,25 @@ $(BINODIR)/%.bin: $(IMAGEODIR)/%.out
# Should be done in top-level makefile only # Should be done in top-level makefile only
# #
all: sdk_extracted pre_build .subdirs $(OBJS) $(OLIBS) $(OIMAGES) $(OBINS) $(SPECIAL_MKTARGETS) all: $(SDK_DIR_DEPENDS) pre_build .subdirs $(OBJS) $(OLIBS) $(OIMAGES) $(OBINS) $(SPECIAL_MKTARGETS)
.PHONY: sdk_extracted .PHONY: sdk_extracted
.PHONY: sdk_patched
sdk_extracted: $(TOP_DIR)/sdk/.extracted-$(SDK_VER) sdk_extracted: $(TOP_DIR)/sdk/.extracted-$(SDK_BASE_VER)
sdk_patched: sdk_extracted $(TOP_DIR)/sdk/.patched-$(SDK_VER)
$(TOP_DIR)/sdk/.extracted-$(SDK_VER): $(TOP_DIR)/cache/esp_iot_sdk_v$(SDK_FILE_VER).zip $(TOP_DIR)/sdk/.extracted-$(SDK_BASE_VER): $(TOP_DIR)/cache/esp_iot_sdk_v$(SDK_FILE_VER).zip
mkdir -p "$(dir $@)" mkdir -p "$(dir $@)"
(cd "$(dir $@)" && rm -fr esp_iot_sdk_v$(SDK_VER) && unzip $(TOP_DIR)/cache/esp_iot_sdk_v$(SDK_VER)*.zip esp_iot_sdk_v$(SDK_VER)/lib/* esp_iot_sdk_v$(SDK_VER)/ld/eagle.rom.addr.v6.ld esp_iot_sdk_v$(SDK_VER)/include/* ) (cd "$(dir $@)" && rm -fr esp_iot_sdk_v$(SDK_VER) ESP8266_NONOS_SDK && unzip $(TOP_DIR)/cache/esp_iot_sdk_v$(SDK_FILE_VER).zip ESP8266_NONOS_SDK/lib/* ESP8266_NONOS_SDK/ld/eagle.rom.addr.v6.ld ESP8266_NONOS_SDK/include/* )
mv $(dir $@)/ESP8266_NONOS_SDK $(dir $@)/esp_iot_sdk_v$(SDK_VER)
rm -f $(SDK_DIR)/lib/liblwip.a
touch $@
$(TOP_DIR)/sdk/.patched-$(SDK_VER): $(TOP_DIR)/cache/esp_iot_sdk_v$(SDK_PATCH_VER).zip
mkdir -p "$(dir $@)/patch"
(cd "$(dir $@)/patch" && unzip $(TOP_DIR)/cache/esp_iot_sdk_v$(SDK_PATCH_VER)*.zip *.a && mv *.a $(SDK_DIR)/lib/)
rmdir $(dir $@)/patch
rm -f $(SDK_DIR)/lib/liblwip.a rm -f $(SDK_DIR)/lib/liblwip.a
touch $@ touch $@
...@@ -188,6 +217,11 @@ $(TOP_DIR)/cache/esp_iot_sdk_v$(SDK_FILE_VER).zip: ...@@ -188,6 +217,11 @@ $(TOP_DIR)/cache/esp_iot_sdk_v$(SDK_FILE_VER).zip:
wget --tries=10 --timeout=15 --waitretry=30 --read-timeout=20 --retry-connrefused http://bbs.espressif.com/download/file.php?id=$(SDK_FILE_ID) -O $@ || { rm -f "$@"; exit 1; } wget --tries=10 --timeout=15 --waitretry=30 --read-timeout=20 --retry-connrefused http://bbs.espressif.com/download/file.php?id=$(SDK_FILE_ID) -O $@ || { rm -f "$@"; exit 1; }
(echo "$(SDK_FILE_SHA1) $@" | sha1sum -c -) || { rm -f "$@"; exit 1; } (echo "$(SDK_FILE_SHA1) $@" | sha1sum -c -) || { rm -f "$@"; exit 1; }
$(TOP_DIR)/cache/esp_iot_sdk_v$(SDK_PATCH_VER).zip:
mkdir -p "$(dir $@)"
wget --tries=10 --timeout=15 --waitretry=30 --read-timeout=20 --retry-connrefused http://bbs.espressif.com/download/file.php?id=$(SDK_PATCH_ID) -O $@ || { rm -f "$@"; exit 1; }
(echo "$(SDK_PATCH_SHA1) $@" | sha1sum -c -) || { rm -f "$@"; exit 1; }
clean: clean:
$(foreach d, $(SUBDIRS), $(MAKE) -C $(d) clean;) $(foreach d, $(SUBDIRS), $(MAKE) -C $(d) clean;)
$(RM) -r $(ODIR)/$(TARGET)/$(FLAVOR) $(RM) -r $(ODIR)/$(TARGET)/$(FLAVOR)
...@@ -218,11 +252,24 @@ endif ...@@ -218,11 +252,24 @@ endif
endif endif
endif endif
.PHONY: spiffs-image-remove
spiffs-image-remove:
$(MAKE) -C tools remove-image
.PHONY: spiffs-image
spiffs-image: bin/0x10000.bin
$(MAKE) -C tools
.PHONY: pre_build .PHONY: pre_build
ifneq ($(wildcard $(TOP_DIR)/server-ca.crt),) ifneq ($(wildcard $(TOP_DIR)/server-ca.crt),)
pre_build: pre_build: $(TOP_DIR)/app/modules/server-ca.crt.h
$(TOP_DIR)/app/modules/server-ca.crt.h: $(TOP_DIR)/server-ca.crt
python $(TOP_DIR)/tools/make_server_cert.py $(TOP_DIR)/server-ca.crt > $(TOP_DIR)/app/modules/server-ca.crt.h python $(TOP_DIR)/tools/make_server_cert.py $(TOP_DIR)/server-ca.crt > $(TOP_DIR)/app/modules/server-ca.crt.h
DEFINES += -DHAVE_SSL_SERVER_CRT=\"server-ca.crt.h\" DEFINES += -DHAVE_SSL_SERVER_CRT=\"server-ca.crt.h\"
else else
pre_build: pre_build:
......
# **NodeMCU 1.5.1** # # **NodeMCU 1.5.4.1** #
[![Join the chat at https://gitter.im/nodemcu/nodemcu-firmware](https://img.shields.io/gitter/room/badges/shields.svg)](https://gitter.im/nodemcu/nodemcu-firmware?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Join the chat at https://gitter.im/nodemcu/nodemcu-firmware](https://img.shields.io/gitter/room/badges/shields.svg)](https://gitter.im/nodemcu/nodemcu-firmware?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Build Status](https://travis-ci.org/nodemcu/nodemcu-firmware.svg)](https://travis-ci.org/nodemcu/nodemcu-firmware) [![Build Status](https://travis-ci.org/nodemcu/nodemcu-firmware.svg)](https://travis-ci.org/nodemcu/nodemcu-firmware)
[![Documentation Status](https://img.shields.io/badge/docs-master-yellow.svg?style=flat)](http://nodemcu.readthedocs.io/) [![Documentation Status](https://img.shields.io/badge/docs-latest-yellow.svg?style=flat)](http://nodemcu.readthedocs.io/en/latest/)
[![License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)](https://github.com/nodemcu/nodemcu-firmware/blob/master/LICENSE) [![License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)](https://github.com/nodemcu/nodemcu-firmware/blob/master/LICENSE)
### A Lua based firmware for ESP8266 WiFi SOC ### A Lua based firmware for ESP8266 WiFi SOC
NodeMCU is an [eLua](http://www.eluaproject.net/) based firmware for the [ESP8266 WiFi SOC from Espressif](http://espressif.com/en/products/esp8266/). The firmware is based on the [Espressif NON-OS SDK 1.5.1](http://bbs.espressif.com/viewtopic.php?f=46&p=5315) and uses a file system based on [spiffs](https://github.com/pellepl/spiffs). The code repository consists of 98.1% C-code that glues the thin Lua veneer to the SDK. NodeMCU is an [eLua](http://www.eluaproject.net/) based firmware for the [ESP8266 WiFi SOC from Espressif](http://espressif.com/en/products/esp8266/). The firmware is based on the [Espressif NON-OS SDK 1.5.4.1](http://bbs.espressif.com/viewtopic.php?f=46&t=2376) and uses a file system based on [spiffs](https://github.com/pellepl/spiffs). The code repository consists of 98.1% C-code that glues the thin Lua veneer to the SDK.
The NodeMCU *firmware* is a companion project to the popular [NodeMCU dev kits](https://github.com/nodemcu/nodemcu-devkit-v1.0), ready-made open source development boards with ESP8266-12E chips. The NodeMCU *firmware* is a companion project to the popular [NodeMCU dev kits](https://github.com/nodemcu/nodemcu-devkit-v1.0), ready-made open source development boards with ESP8266-12E chips.
...@@ -28,11 +28,11 @@ The NodeMCU programming model is similar to that of [Node.js](https://en.wikiped ...@@ -28,11 +28,11 @@ The NodeMCU programming model is similar to that of [Node.js](https://en.wikiped
-- a simple HTTP server -- a simple HTTP server
srv = net.createServer(net.TCP) srv = net.createServer(net.TCP)
srv:listen(80, function(conn) srv:listen(80, function(conn)
conn:on("receive", function(conn, payload) conn:on("receive", function(sck, payload)
print(payload) print(payload)
conn:send("<h1> Hello, NodeMCU.</h1>") sck:send("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n<h1> Hello, NodeMCU.</h1>")
end) end)
conn:on("sent", function(conn) conn:close() end) conn:on("sent", function(sck) sck:close() end)
end) end)
``` ```
```lua ```lua
...@@ -46,6 +46,7 @@ wifi.sta.config("SSID", "password") ...@@ -46,6 +46,7 @@ wifi.sta.config("SSID", "password")
The entire [NodeMCU documentation](https://nodemcu.readthedocs.io) is maintained right in this repository at [/docs](docs). The fact that the API documentation is mainted in the same repository as the code that *provides* the API ensures consistency between the two. With every commit the documentation is rebuilt by Read the Docs and thus transformed from terse Markdown into a nicely browsable HTML site at [https://nodemcu.readthedocs.io](https://nodemcu.readthedocs.io). The entire [NodeMCU documentation](https://nodemcu.readthedocs.io) is maintained right in this repository at [/docs](docs). The fact that the API documentation is mainted in the same repository as the code that *provides* the API ensures consistency between the two. With every commit the documentation is rebuilt by Read the Docs and thus transformed from terse Markdown into a nicely browsable HTML site at [https://nodemcu.readthedocs.io](https://nodemcu.readthedocs.io).
- How to [build the firmware](https://nodemcu.readthedocs.io/en/dev/en/build/) - How to [build the firmware](https://nodemcu.readthedocs.io/en/dev/en/build/)
- How to [build the filesystem](https://nodemcu.readthedocs.io/en/dev/en/spiffs/)
- How to [flash the firmware](https://nodemcu.readthedocs.io/en/dev/en/flash/) - How to [flash the firmware](https://nodemcu.readthedocs.io/en/dev/en/flash/)
- How to [upload code and NodeMCU IDEs](https://nodemcu.readthedocs.io/en/dev/en/upload/) - How to [upload code and NodeMCU IDEs](https://nodemcu.readthedocs.io/en/dev/en/upload/)
- API documentation for every module - API documentation for every module
...@@ -54,7 +55,7 @@ The entire [NodeMCU documentation](https://nodemcu.readthedocs.io) is maintained ...@@ -54,7 +55,7 @@ The entire [NodeMCU documentation](https://nodemcu.readthedocs.io) is maintained
Due to the ever-growing number of modules available within NodeMCU, pre-built binaries are no longer made available. Use the automated [custom firmware build service](http://nodemcu-build.com/) to get the specific firmware configuration you need, or consult the [documentation](http://nodemcu.readthedocs.io/en/dev/en/build/) for other options to build your own firmware. Due to the ever-growing number of modules available within NodeMCU, pre-built binaries are no longer made available. Use the automated [custom firmware build service](http://nodemcu-build.com/) to get the specific firmware configuration you need, or consult the [documentation](http://nodemcu.readthedocs.io/en/dev/en/build/) for other options to build your own firmware.
This projects uses two main branches, `master` and `dev`. `dev` is actively worked on and it's also where PRs should be created against. `master` thus can be considered "stable" even though there are no automated regression tests. The goal is to merge back to `master` roughly every 2 months. Depending on the current "heat" (issues, PRs) we accept changes to `dev` for 5-6 weeks and then hold back for 2-3 weeks before the next snap is completed. This project uses two main branches, `master` and `dev`. `dev` is actively worked on and it's also where PRs should be created against. `master` thus can be considered "stable" even though there are no automated regression tests. The goal is to merge back to `master` roughly every 2 months. Depending on the current "heat" (issues, PRs) we accept changes to `dev` for 5-6 weeks and then hold back for 2-3 weeks before the next snap is completed.
A new tag is created every time `dev` is merged back to `master`. They are listed in the [releases section here on GitHub](https://github.com/nodemcu/nodemcu-firmware/releases). Tag names follow the \<SDK-version\>-master_yyyymmdd pattern. A new tag is created every time `dev` is merged back to `master`. They are listed in the [releases section here on GitHub](https://github.com/nodemcu/nodemcu-firmware/releases). Tag names follow the \<SDK-version\>-master_yyyymmdd pattern.
...@@ -89,7 +90,7 @@ Edit `app/include/user_modules.h` and comment-out the `#define` statement for mo ...@@ -89,7 +90,7 @@ Edit `app/include/user_modules.h` and comment-out the `#define` statement for mo
Identify your firmware builds by editing `app/include/user_version.h` Identify your firmware builds by editing `app/include/user_version.h`
```c ```c
#define NODE_VERSION "NodeMCU 1.5.1+myname" #define NODE_VERSION "NodeMCU 1.5.4.1+myname"
#ifndef BUILD_DATE #ifndef BUILD_DATE
#define BUILD_DATE "YYYYMMDD" #define BUILD_DATE "YYYYMMDD"
#endif #endif
......
...@@ -24,6 +24,7 @@ SPECIAL_MKTARGETS=$(APP_MKTARGETS) ...@@ -24,6 +24,7 @@ SPECIAL_MKTARGETS=$(APP_MKTARGETS)
SUBDIRS= \ SUBDIRS= \
user \ user \
driver \ driver \
pcm \
platform \ platform \
libc \ libc \
lua \ lua \
...@@ -69,6 +70,7 @@ LD_FILE = $(LDDIR)/nodemcu.ld ...@@ -69,6 +70,7 @@ LD_FILE = $(LDDIR)/nodemcu.ld
COMPONENTS_eagle.app.v6 = \ COMPONENTS_eagle.app.v6 = \
user/libuser.a \ user/libuser.a \
driver/libdriver.a \ driver/libdriver.a \
pcm/pcm.a \
platform/libplatform.a \ platform/libplatform.a \
task/libtask.a \ task/libtask.a \
libc/liblibc.a \ libc/liblibc.a \
......
...@@ -98,7 +98,7 @@ int coap_buildToken(const coap_buffer_t *tokbuf, const coap_header_t *hdr, uint8 ...@@ -98,7 +98,7 @@ int coap_buildToken(const coap_buffer_t *tokbuf, const coap_header_t *hdr, uint8
p = buf + 4; p = buf + 4;
if ((hdr->tkl > 0) && (hdr->tkl != tokbuf->len)) if ((hdr->tkl > 0) && (hdr->tkl != tokbuf->len))
return COAP_ERR_UNSUPPORTED; return COAP_ERR_UNSUPPORTED;
if (hdr->tkl > 0) if (hdr->tkl > 0)
c_memcpy(p, tokbuf->p, hdr->tkl); c_memcpy(p, tokbuf->p, hdr->tkl);
...@@ -483,7 +483,7 @@ int coap_make_request(coap_rw_buffer_t *scratch, coap_packet_t *pkt, coap_msgtyp ...@@ -483,7 +483,7 @@ int coap_make_request(coap_rw_buffer_t *scratch, coap_packet_t *pkt, coap_msgtyp
if (uri->port != COAP_DEFAULT_PORT) { if (uri->port != COAP_DEFAULT_PORT) {
pkt->opts[pkt->numopts].num = COAP_OPTION_URI_PORT; pkt->opts[pkt->numopts].num = COAP_OPTION_URI_PORT;
res = coap_encode_var_bytes(scratch->p, uri->port); res = coap_encode_var_bytes(scratch->p, uri->port);
pkt->opts[pkt->numopts].buf.len = res; pkt->opts[pkt->numopts].buf.len = res;
pkt->opts[pkt->numopts].buf.p = scratch->p; pkt->opts[pkt->numopts].buf.p = scratch->p;
scratch->p += res; scratch->p += res;
...@@ -496,7 +496,7 @@ int coap_make_request(coap_rw_buffer_t *scratch, coap_packet_t *pkt, coap_msgtyp ...@@ -496,7 +496,7 @@ int coap_make_request(coap_rw_buffer_t *scratch, coap_packet_t *pkt, coap_msgtyp
} }
if (uri->query.length) { if (uri->query.length) {
res = coap_split_query(scratch, pkt, uri->query.s, uri->query.length); res = coap_split_query(scratch, pkt, uri->query.s, uri->query.length);
} }
pkt->payload.p = payload; pkt->payload.p = payload;
...@@ -546,7 +546,7 @@ next: ...@@ -546,7 +546,7 @@ next:
void coap_setup(void) void coap_setup(void)
{ {
message_id = (unsigned short)rand(); // calculate only once message_id = (unsigned short)os_random(); // calculate only once
} }
inline int inline int
......
...@@ -107,7 +107,6 @@ uint8_t onewire_reset(uint8_t pin) ...@@ -107,7 +107,6 @@ uint8_t onewire_reset(uint8_t pin)
noInterrupts(); noInterrupts();
DIRECT_WRITE_LOW(pin); DIRECT_WRITE_LOW(pin);
DIRECT_MODE_OUTPUT(pin); // drive output low
interrupts(); interrupts();
delayMicroseconds(480); delayMicroseconds(480);
noInterrupts(); noInterrupts();
...@@ -126,19 +125,12 @@ uint8_t onewire_reset(uint8_t pin) ...@@ -126,19 +125,12 @@ uint8_t onewire_reset(uint8_t pin)
static void onewire_write_bit(uint8_t pin, uint8_t v) static void onewire_write_bit(uint8_t pin, uint8_t v)
{ {
if (v & 1) { if (v & 1) {
noInterrupts(); onewire_read_bit(pin);
DIRECT_WRITE_LOW(pin);
DIRECT_MODE_OUTPUT(pin); // drive output low
delayMicroseconds(10);
DIRECT_WRITE_HIGH(pin); // drive output high
interrupts();
delayMicroseconds(55);
} else { } else {
noInterrupts(); noInterrupts();
DIRECT_WRITE_LOW(pin); DIRECT_WRITE_LOW(pin);
DIRECT_MODE_OUTPUT(pin); // drive output low
delayMicroseconds(65); delayMicroseconds(65);
DIRECT_WRITE_HIGH(pin); // drive output high DIRECT_MODE_INPUT(pin); // drive output high by the pull-up
interrupts(); interrupts();
delayMicroseconds(5); delayMicroseconds(5);
} }
...@@ -153,14 +145,14 @@ static uint8_t onewire_read_bit(uint8_t pin) ...@@ -153,14 +145,14 @@ static uint8_t onewire_read_bit(uint8_t pin)
uint8_t r; uint8_t r;
noInterrupts(); noInterrupts();
DIRECT_MODE_OUTPUT(pin);
DIRECT_WRITE_LOW(pin); DIRECT_WRITE_LOW(pin);
delayMicroseconds(3);
delayMicroseconds(5);
DIRECT_MODE_INPUT(pin); // let pin float, pull up will raise DIRECT_MODE_INPUT(pin); // let pin float, pull up will raise
delayMicroseconds(10); delayMicroseconds(8);
r = DIRECT_READ(pin); r = DIRECT_READ(pin);
interrupts(); interrupts();
delayMicroseconds(53); delayMicroseconds(52);
return r; return r;
} }
...@@ -177,10 +169,10 @@ void onewire_write(uint8_t pin, uint8_t v, uint8_t power /* = 0 */) { ...@@ -177,10 +169,10 @@ void onewire_write(uint8_t pin, uint8_t v, uint8_t power /* = 0 */) {
for (bitMask = 0x01; bitMask; bitMask <<= 1) { for (bitMask = 0x01; bitMask; bitMask <<= 1) {
onewire_write_bit(pin, (bitMask & v)?1:0); onewire_write_bit(pin, (bitMask & v)?1:0);
} }
if ( !power) { if ( power ) {
noInterrupts(); noInterrupts();
DIRECT_MODE_INPUT(pin); DIRECT_WRITE_HIGH(pin);
DIRECT_WRITE_LOW(pin);
interrupts(); interrupts();
} }
} }
...@@ -189,10 +181,10 @@ void onewire_write_bytes(uint8_t pin, const uint8_t *buf, uint16_t count, bool p ...@@ -189,10 +181,10 @@ void onewire_write_bytes(uint8_t pin, const uint8_t *buf, uint16_t count, bool p
uint16_t i; uint16_t i;
for (i = 0 ; i < count ; i++) for (i = 0 ; i < count ; i++)
onewire_write(pin, buf[i], owDefaultPower); onewire_write(pin, buf[i], owDefaultPower);
if (!power) { if ( power ) {
noInterrupts(); noInterrupts();
DIRECT_MODE_INPUT(pin); DIRECT_WRITE_HIGH(pin);
DIRECT_WRITE_LOW(pin);
interrupts(); interrupts();
} }
} }
...@@ -474,7 +466,7 @@ uint8_t onewire_crc8(const uint8_t *addr, uint8_t len) ...@@ -474,7 +466,7 @@ uint8_t onewire_crc8(const uint8_t *addr, uint8_t len)
uint8_t onewire_crc8(const uint8_t *addr, uint8_t len) uint8_t onewire_crc8(const uint8_t *addr, uint8_t len)
{ {
uint8_t crc = 0; uint8_t crc = 0;
while (len--) { while (len--) {
uint8_t inbyte = *addr++; uint8_t inbyte = *addr++;
uint8_t i; uint8_t i;
...@@ -501,8 +493,8 @@ uint8_t onewire_crc8(const uint8_t *addr, uint8_t len) ...@@ -501,8 +493,8 @@ uint8_t onewire_crc8(const uint8_t *addr, uint8_t len)
// ReadBytes(net, buf+3, 10); // Read 6 data bytes, 2 0xFF, 2 CRC16 // ReadBytes(net, buf+3, 10); // Read 6 data bytes, 2 0xFF, 2 CRC16
// if (!CheckCRC16(buf, 11, &buf[11])) { // if (!CheckCRC16(buf, 11, &buf[11])) {
// // Handle error. // // Handle error.
// } // }
// //
// @param input - Array of bytes to checksum. // @param input - Array of bytes to checksum.
// @param len - How many bytes to use. // @param len - How many bytes to use.
// @param inverted_crc - The two CRC16 bytes in the received data. // @param inverted_crc - The two CRC16 bytes in the received data.
......
#include "platform.h"
#include "driver/sigma_delta.h" #include "driver/sigma_delta.h"
...@@ -18,7 +19,7 @@ void sigma_delta_stop( void ) ...@@ -18,7 +19,7 @@ void sigma_delta_stop( void )
GPIO_SIGMA_DELTA_PRESCALE_SET(0x00) ); GPIO_SIGMA_DELTA_PRESCALE_SET(0x00) );
} }
void sigma_delta_set_prescale_target( sint16 prescale, sint16 target ) void ICACHE_RAM_ATTR sigma_delta_set_prescale_target( sint16 prescale, sint16 target )
{ {
uint32_t prescale_mask, target_mask; uint32_t prescale_mask, target_mask;
......
...@@ -70,7 +70,7 @@ void spi_master_init(uint8 spi_no, unsigned cpol, unsigned cpha, uint32_t clock_ ...@@ -70,7 +70,7 @@ void spi_master_init(uint8 spi_no, unsigned cpol, unsigned cpha, uint32_t clock_
if(spi_no>1) return; //handle invalid input number if(spi_no>1) return; //handle invalid input number
SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_CS_SETUP|SPI_CS_HOLD|SPI_RD_BYTE_ORDER|SPI_WR_BYTE_ORDER|SPI_DOUTDIN); SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_CS_SETUP|SPI_CS_HOLD|SPI_RD_BYTE_ORDER|SPI_WR_BYTE_ORDER);
// set clock polarity (Reference: http://bbs.espressif.com/viewtopic.php?f=49&t=1570) // set clock polarity (Reference: http://bbs.espressif.com/viewtopic.php?f=49&t=1570)
// phase is dependent on polarity. See Issue #1161 // phase is dependent on polarity. See Issue #1161
...@@ -85,12 +85,10 @@ void spi_master_init(uint8 spi_no, unsigned cpol, unsigned cpha, uint32_t clock_ ...@@ -85,12 +85,10 @@ void spi_master_init(uint8 spi_no, unsigned cpol, unsigned cpha, uint32_t clock_
// Mode 3: MOSI is set on falling edge of clock // Mode 3: MOSI is set on falling edge of clock
// Mode 0: MOSI is set on falling edge of clock // Mode 0: MOSI is set on falling edge of clock
CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_CK_OUT_EDGE); CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_CK_OUT_EDGE);
SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_CK_I_EDGE);
} else { } else {
// Mode 2: MOSI is set on rising edge of clock // Mode 2: MOSI is set on rising edge of clock
// Mode 1: MOSI is set on rising edge of clock // Mode 1: MOSI is set on rising edge of clock
SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_CK_OUT_EDGE); SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_CK_OUT_EDGE);
CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_CK_I_EDGE);
} }
CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_FLASH_MODE|SPI_USR_MISO|SPI_USR_ADDR|SPI_USR_COMMAND|SPI_USR_DUMMY); CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_FLASH_MODE|SPI_USR_MISO|SPI_USR_ADDR|SPI_USR_COMMAND|SPI_USR_DUMMY);
...@@ -98,31 +96,28 @@ void spi_master_init(uint8 spi_no, unsigned cpol, unsigned cpha, uint32_t clock_ ...@@ -98,31 +96,28 @@ void spi_master_init(uint8 spi_no, unsigned cpol, unsigned cpha, uint32_t clock_
//clear Dual or Quad lines transmission mode //clear Dual 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); CLEAR_PERI_REG_MASK(SPI_CTRL(spi_no), SPI_QIO_MODE|SPI_DIO_MODE|SPI_DOUT_MODE|SPI_QOUT_MODE);
// SPI clock = CPU clock / clock_div if (clock_div > 1) {
// the divider needs to be a multiple of 2 to get a proper waveform shape uint8 i, k;
if ((clock_div & 0x01) != 0) { i = (clock_div / 40) ? (clock_div / 40) : 1;
// bump the divider to the next N*2 k = clock_div / i;
clock_div += 0x02; WRITE_PERI_REG(SPI_CLOCK(spi_no),
(((i - 1) & SPI_CLKDIV_PRE) << SPI_CLKDIV_PRE_S) |
(((k - 1) & SPI_CLKCNT_N) << SPI_CLKCNT_N_S) |
((((k + 1) / 2 - 1) & SPI_CLKCNT_H) << SPI_CLKCNT_H_S) |
(((k - 1) & SPI_CLKCNT_L) << SPI_CLKCNT_L_S)); //clear bit 31,set SPI clock div
} else {
WRITE_PERI_REG(SPI_CLOCK(spi_no), SPI_CLK_EQU_SYSCLK); // 80Mhz speed
} }
clock_div >>= 1;
// clip to maximum possible CLKDIV_PRE
clock_div = clock_div > SPI_CLKDIV_PRE ? SPI_CLKDIV_PRE : clock_div - 1;
WRITE_PERI_REG(SPI_CLOCK(spi_no),
((clock_div&SPI_CLKDIV_PRE)<<SPI_CLKDIV_PRE_S)|
((1&SPI_CLKCNT_N)<<SPI_CLKCNT_N_S)|
((0&SPI_CLKCNT_H)<<SPI_CLKCNT_H_S)|
((1&SPI_CLKCNT_L)<<SPI_CLKCNT_L_S)); //clear bit 31,set SPI clock div
if(spi_no==SPI){ if(spi_no==SPI){
WRITE_PERI_REG(PERIPHS_IO_MUX, 0x005); WRITE_PERI_REG(PERIPHS_IO_MUX, 0x005 | (clock_div <= 1 ? 0x100 : 0));
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, 1);//configure io to spi mode PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, 1);//configure io to spi mode
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CMD_U, 1);//configure io to spi mode PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CMD_U, 1);//configure io to spi mode
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA0_U, 1);//configure io to spi mode PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA0_U, 1);//configure io to spi mode
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA1_U, 1);//configure io to spi mode PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA1_U, 1);//configure io to spi mode
} }
else if(spi_no==HSPI){ else if(spi_no==HSPI){
WRITE_PERI_REG(PERIPHS_IO_MUX, 0x105); WRITE_PERI_REG(PERIPHS_IO_MUX, 0x105 | (clock_div <= 1 ? 0x200 : 0));
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, 2);//configure io to spi mode PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, 2);//configure io to spi mode
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, 2);//configure io to spi mode PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, 2);//configure io to spi mode
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, 2);//configure io to spi mode PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, 2);//configure io to spi mode
......
/*
* Module for interfacing with Switec instrument steppers (and
* similar devices). These are the steppers that are used in automotive
* instrument panels and the like. Run off 5 volts at low current.
*
* Code inspired by:
*
* SwitecX25 Arduino Library
* Guy Carpenter, Clearwater Software - 2012
*
* Licensed under the BSD2 license, see license.txt for details.
*
* NodeMcu integration by Philip Gladstone, N1DQ
*/
#include "platform.h"
#include "c_types.h"
#include "../libc/c_stdlib.h"
#include "../libc/c_stdio.h"
#include "driver/switec.h"
#include "ets_sys.h"
#include "os_type.h"
#include "osapi.h"
#include "hw_timer.h"
#include "user_interface.h"
#include "task/task.h"
#define N_STATES 6
//
// First pin passed to setup corresponds to bit 3
// On the motor, the pins are arranged
//
// 4 1
//
// 3 2
//
// The direction of rotation can be reversed by reordering the pins
//
// State 3 2 1 0 A B Value
// 0 1 0 0 1 - - 0x9
// 1 0 0 0 1 . - 0x1
// 2 0 1 1 1 + . 0x7
// 3 0 1 1 0 + + 0x6
// 4 1 1 1 0 . + 0xE
// 5 1 0 0 0 - . 0x8
static const uint8_t stateMap[N_STATES] = {0x9, 0x1, 0x7, 0x6, 0xE, 0x8};
typedef struct {
uint8_t current_state;
uint8_t stopped;
int8_t dir;
uint32_t mask;
uint32_t pinstate[N_STATES];
uint32_t next_time;
int16_t target_step;
int16_t current_step;
uint16_t vel;
uint16_t max_vel;
uint16_t min_delay;
task_handle_t task_number;
} DATA;
static DATA *data[SWITEC_CHANNEL_COUNT];
static volatile char timer_active;
#define MAXVEL 255
// Note that this has to be global so that the compiler does not
// put it into ROM.
uint8_t switec_accel_table[][2] = {
{ 20, 3000 >> 4},
{ 50, 1500 >> 4},
{ 100, 1000 >> 4},
{ 150, 800 >> 4},
{ MAXVEL, 600 >> 4}
};
static void ICACHE_RAM_ATTR timer_interrupt(os_param_t);
#define TIMER_OWNER ((os_param_t) 'S')
// Just takes the channel number
int switec_close(uint32_t channel)
{
if (channel >= sizeof(data) / sizeof(data[0])) {
return -1;
}
DATA *d = data[channel];
if (!d) {
return 0;
}
if (!d->stopped) {
return -1;
}
// Set pins as input
gpio_output_set(0, 0, 0, d->mask);
data[channel] = NULL;
c_free(d);
// See if there are any other channels active
for (channel = 0; channel < sizeof(data)/sizeof(data[0]); channel++) {
if (data[channel]) {
break;
}
}
// If not, then disable the interrupt
if (channel >= sizeof(data) / sizeof(data[0])) {
platform_hw_timer_close(TIMER_OWNER);
}
return 0;
}
static __attribute__((always_inline)) inline void write_io(DATA *d)
{
uint32_t pin_state = d->pinstate[d->current_state];
gpio_output_set(pin_state, d->mask & ~pin_state, 0, 0);
}
static __attribute__((always_inline)) inline void step_up(DATA *d)
{
d->current_step++;
d->current_state = (d->current_state + 1) % N_STATES;
write_io(d);
}
static __attribute__((always_inline)) inline void step_down(DATA *d)
{
d->current_step--;
d->current_state = (d->current_state + N_STATES - 1) % N_STATES;
write_io(d);
}
static void ICACHE_RAM_ATTR timer_interrupt(os_param_t p)
{
// This function really is running at interrupt level with everything
// else masked off. It should take as little time as necessary.
//
(void) p;
int i;
uint32_t delay = 0xffffffff;
// Loop over the channels to figure out which one needs action
for (i = 0; i < sizeof(data) / sizeof(data[0]); i++) {
DATA *d = data[i];
if (!d || d->stopped) {
continue;
}
uint32_t now = system_get_time();
if (now < d->next_time) {
int need_to_wait = d->next_time - now;
if (need_to_wait < delay) {
delay = need_to_wait;
}
continue;
}
// This channel is past it's action time. Need to process it
// Are we done yet?
if (d->current_step == d->target_step && d->vel == 0) {
d->stopped = 1;
d->dir = 0;
task_post_low(d->task_number, 0);
continue;
}
// if stopped, determine direction
if (d->vel == 0) {
d->dir = d->current_step < d->target_step ? 1 : -1;
// do not set to 0 or it could go negative in case 2 below
d->vel = 1;
}
// Move the pointer by one step in the correct direction
if (d->dir > 0) {
step_up(d);
} else {
step_down(d);
}
// determine delta, number of steps in current direction to target.
// may be negative if we are headed away from target
int delta = d->dir > 0 ? d->target_step - d->current_step : d->current_step - d->target_step;
if (delta > 0) {
// case 1 : moving towards target (maybe under accel or decel)
if (delta <= d->vel) {
// time to declerate
d->vel--;
} else if (d->vel < d->max_vel) {
// accelerating
d->vel++;
} else {
// at full speed - stay there
}
} else {
// case 2 : at or moving away from target (slow down!)
d->vel--;
}
// vel now defines delay
uint8_t row = 0;
// this is why vel must not be greater than the last vel in the table.
while (switec_accel_table[row][0] < d->vel) {
row++;
}
uint32_t micro_delay = switec_accel_table[row][1] << 4;
if (micro_delay < d->min_delay) {
micro_delay = d->min_delay;
}
// Figure out when we next need to take action
d->next_time = d->next_time + micro_delay;
if (d->next_time < now) {
d->next_time = now + micro_delay;
}
// Figure out how long to wait
int need_to_wait = d->next_time - now;
if (need_to_wait < delay) {
delay = need_to_wait;
}
}
if (delay < 1000000) {
if (delay < 50) {
delay = 50;
}
timer_active = 1;
platform_hw_timer_arm_us(TIMER_OWNER, delay);
} else {
timer_active = 0;
}
}
// The pin numbers are actual platform GPIO numbers
int switec_setup(uint32_t channel, int *pin, int max_deg_per_sec, task_handle_t task_number )
{
if (channel >= sizeof(data) / sizeof(data[0])) {
return -1;
}
if (data[channel]) {
if (switec_close(channel)) {
return -1;
}
}
DATA *d = (DATA *) c_zalloc(sizeof(DATA));
if (!d) {
return -1;
}
if (!data[0] && !data[1] && !data[2]) {
// We need to stup the timer as no channel was active before
// no autoreload
if (!platform_hw_timer_init(TIMER_OWNER, FRC1_SOURCE, FALSE)) {
// Failed to get the timer
c_free(d);
return -1;
}
}
data[channel] = d;
int i;
for (i = 0; i < 4; i++) {
// Build the mask for the pins to be output pins
d->mask |= 1 << pin[i];
int j;
// Now build the hi states for the pins according to the 6 phases above
for (j = 0; j < N_STATES; j++) {
if (stateMap[j] & (1 << (3 - i))) {
d->pinstate[j] |= 1 << pin[i];
}
}
}
d->max_vel = MAXVEL;
if (max_deg_per_sec == 0) {
max_deg_per_sec = 400;
}
d->min_delay = 1000000 / (3 * max_deg_per_sec);
d->task_number = task_number;
#ifdef SWITEC_DEBUG
for (i = 0; i < 4; i++) {
c_printf("pin[%d]=%d\n", i, pin[i]);
}
c_printf("Mask=0x%x\n", d->mask);
for (i = 0; i < N_STATES; i++) {
c_printf("pinstate[%d]=0x%x\n", i, d->pinstate[i]);
}
#endif
// Set all pins as outputs
gpio_output_set(0, 0, d->mask, 0);
platform_hw_timer_set_func(TIMER_OWNER, timer_interrupt, 0);
return 0;
}
// All this does is to assert that the current position is 0
int switec_reset(uint32_t channel)
{
if (channel >= sizeof(data) / sizeof(data[0])) {
return -1;
}
DATA *d = data[channel];
if (!d || !d->stopped) {
return -1;
}
d->current_step = d->target_step = 0;
return 0;
}
// Just takes the channel number and the position
int switec_moveto(uint32_t channel, int pos)
{
if (channel >= sizeof(data) / sizeof(data[0])) {
return -1;
}
DATA *d = data[channel];
if (!d) {
return -1;
}
if (pos < 0) {
// This ensures that we don't slam into the endstop
d->max_vel = 50;
} else {
d->max_vel = MAXVEL;
}
d->target_step = pos;
// If the pointer is not moving, setup so that we start it
if (d->stopped) {
// reset the timer to avoid possible time overflow giving spurious deltas
d->next_time = system_get_time() + 1000;
d->stopped = false;
if (!timer_active) {
timer_interrupt(0);
}
}
return 0;
}
// Get the current position, direction and target position
int switec_getpos(uint32_t channel, int32_t *pos, int32_t *dir, int32_t *target)
{
if (channel >= sizeof(data) / sizeof(data[0])) {
return -1;
}
DATA *d = data[channel];
if (!d) {
return -1;
}
*pos = d->current_step;
*dir = d->stopped ? 0 : d->dir;
*target = d->target_step;
return 0;
}
...@@ -181,7 +181,7 @@ static void ICACHE_FLASH_ATTR http_connect_callback( void * arg ) ...@@ -181,7 +181,7 @@ static void ICACHE_FLASH_ATTR http_connect_callback( void * arg )
HTTPCLIENT_DEBUG( "Connected\n" ); HTTPCLIENT_DEBUG( "Connected\n" );
struct espconn * conn = (struct espconn *) arg; struct espconn * conn = (struct espconn *) arg;
request_args_t * req = (request_args_t *) conn->reverse; request_args_t * req = (request_args_t *) conn->reverse;
int len;
espconn_regist_recvcb( conn, http_receive_callback ); espconn_regist_recvcb( conn, http_receive_callback );
espconn_regist_sentcb( conn, http_send_callback ); espconn_regist_sentcb( conn, http_send_callback );
...@@ -200,16 +200,29 @@ static void ICACHE_FLASH_ATTR http_connect_callback( void * arg ) ...@@ -200,16 +200,29 @@ static void ICACHE_FLASH_ATTR http_connect_callback( void * arg )
char buf[69 + strlen( req->method ) + strlen( req->path ) + strlen( req->hostname ) + char buf[69 + strlen( req->method ) + strlen( req->path ) + strlen( req->hostname ) +
strlen( req->headers ) + strlen( post_headers )]; strlen( req->headers ) + strlen( post_headers )];
int len = os_sprintf( buf,
"%s %s HTTP/1.1\r\n"
"Host: %s:%d\r\n"
"Connection: close\r\n"
"User-Agent: ESP8266\r\n"
"%s"
"%s"
"\r\n",
req->method, req->path, req->hostname, req->port, req->headers, post_headers );
if ((req->port == 80) || ((req->port == 443) && ( req->secure )))
{
len = os_sprintf( buf,
"%s %s HTTP/1.1\r\n"
"Host: %s\r\n"
"Connection: close\r\n"
"User-Agent: ESP8266\r\n"
"%s"
"%s"
"\r\n",
req->method, req->path, req->hostname, req->headers, post_headers );
} else {
len = os_sprintf( buf,
"%s %s HTTP/1.1\r\n"
"Host: %s:%d\r\n"
"Connection: close\r\n"
"User-Agent: ESP8266\r\n"
"%s"
"%s"
"\r\n",
req->method, req->path, req->hostname, req->port, req->headers, post_headers );
}
if ( req->secure ) if ( req->secure )
espconn_secure_send( conn, (uint8_t *) buf, len ); espconn_secure_send( conn, (uint8_t *) buf, len );
else else
...@@ -220,6 +233,22 @@ static void ICACHE_FLASH_ATTR http_connect_callback( void * arg ) ...@@ -220,6 +233,22 @@ static void ICACHE_FLASH_ATTR http_connect_callback( void * arg )
HTTPCLIENT_DEBUG( "Sending request header\n" ); HTTPCLIENT_DEBUG( "Sending request header\n" );
} }
static void http_free_req( request_args_t * req)
{
if (req->buffer) {
os_free( req->buffer );
}
if (req->post_data) {
os_free( req->post_data );
}
if (req->headers) {
os_free( req->headers );
}
os_free( req->hostname );
os_free( req->method );
os_free( req->path );
os_free( req );
}
static void ICACHE_FLASH_ATTR http_disconnect_callback( void * arg ) static void ICACHE_FLASH_ATTR http_disconnect_callback( void * arg )
{ {
...@@ -288,13 +317,7 @@ static void ICACHE_FLASH_ATTR http_disconnect_callback( void * arg ) ...@@ -288,13 +317,7 @@ static void ICACHE_FLASH_ATTR http_disconnect_callback( void * arg )
{ {
req->callback_handle( body, http_status, req->buffer ); req->callback_handle( body, http_status, req->buffer );
} }
if (req->buffer) { http_free_req( req );
os_free( req->buffer );
}
os_free( req->hostname );
os_free( req->method );
os_free( req->path );
os_free( req );
} }
/* Fix memory leak. */ /* Fix memory leak. */
espconn_delete( conn ); espconn_delete( conn );
...@@ -341,7 +364,7 @@ static void ICACHE_FLASH_ATTR http_dns_callback( const char * hostname, ip_addr_ ...@@ -341,7 +364,7 @@ static void ICACHE_FLASH_ATTR http_dns_callback( const char * hostname, ip_addr_
{ {
req->callback_handle( "", -1, "" ); req->callback_handle( "", -1, "" );
} }
os_free( req ); http_free_req( req );
} }
else else
{ {
......
...@@ -41,7 +41,7 @@ ...@@ -41,7 +41,7 @@
// Platform specific I/O definitions // Platform specific I/O definitions
#define DIRECT_READ(pin) (0x1 & GPIO_INPUT_GET(GPIO_ID_PIN(pin_num[pin]))) #define DIRECT_READ(pin) (0x1 & GPIO_INPUT_GET(GPIO_ID_PIN(pin_num[pin])))
#define DIRECT_MODE_INPUT(pin) GPIO_DIS_OUTPUT(pin_num[pin]) #define DIRECT_MODE_INPUT(pin) GPIO_DIS_OUTPUT(GPIO_ID_PIN(pin_num[pin]))
#define DIRECT_MODE_OUTPUT(pin) #define DIRECT_MODE_OUTPUT(pin)
#define DIRECT_WRITE_LOW(pin) (GPIO_OUTPUT_SET(GPIO_ID_PIN(pin_num[pin]), 0)) #define DIRECT_WRITE_LOW(pin) (GPIO_OUTPUT_SET(GPIO_ID_PIN(pin_num[pin]), 0))
#define DIRECT_WRITE_HIGH(pin) (GPIO_OUTPUT_SET(GPIO_ID_PIN(pin_num[pin]), 1)) #define DIRECT_WRITE_HIGH(pin) (GPIO_OUTPUT_SET(GPIO_ID_PIN(pin_num[pin]), 1))
...@@ -74,10 +74,10 @@ void onewire_read_bytes(uint8_t pin, uint8_t *buf, uint16_t count); ...@@ -74,10 +74,10 @@ void onewire_read_bytes(uint8_t pin, uint8_t *buf, uint16_t count);
// Write a bit. The bus is always left powered at the end, see // Write a bit. The bus is always left powered at the end, see
// note in write() about that. // note in write() about that.
// void onewire_write_bit(uint8_t pin, uint8_t v); static void onewire_write_bit(uint8_t pin, uint8_t v);
// Read a bit. // Read a bit.
// uint8_t onewire_read_bit(uint8_t pin); static uint8_t onewire_read_bit(uint8_t pin);
// Stop forcing power onto the bus. You only need to do this if // Stop forcing power onto the bus. You only need to do this if
// you used the 'power' flag to write() or used a write_bit() call // you used the 'power' flag to write() or used a write_bit() call
...@@ -120,8 +120,8 @@ uint8_t onewire_crc8(const uint8_t *addr, uint8_t len); ...@@ -120,8 +120,8 @@ uint8_t onewire_crc8(const uint8_t *addr, uint8_t len);
// ReadBytes(net, buf+3, 10); // Read 6 data bytes, 2 0xFF, 2 CRC16 // ReadBytes(net, buf+3, 10); // Read 6 data bytes, 2 0xFF, 2 CRC16
// if (!CheckCRC16(buf, 11, &buf[11])) { // if (!CheckCRC16(buf, 11, &buf[11])) {
// // Handle error. // // Handle error.
// } // }
// //
// @param input - Array of bytes to checksum. // @param input - Array of bytes to checksum.
// @param len - How many bytes to use. // @param len - How many bytes to use.
// @param inverted_crc - The two CRC16 bytes in the received data. // @param inverted_crc - The two CRC16 bytes in the received data.
......
/*
* Definitions to access the Switec driver
*/
#ifndef __SWITEC_H__
#define __SWITEC_H__
#include "c_types.h"
#define SWITEC_CHANNEL_COUNT 3
int switec_setup(uint32_t channel, int *pin, int max_deg_per_sec, task_handle_t taskNumber );
int switec_close(uint32_t channel);
int switec_moveto(uint32_t channel, int pos);
int switec_reset(uint32_t channel);
int switec_getpos(uint32_t channel, int32_t *pos, int32_t *dir, int32_t *target);
#endif
...@@ -49,6 +49,17 @@ struct rtc_timeval ...@@ -49,6 +49,17 @@ struct rtc_timeval
}; };
#endif #endif
struct rtc_tm{
int tm_sec; /* Seconds. [0-60] (1 leap second) */
int tm_min; /* Minutes. [0-59] */
int tm_hour; /* Hours. [0-23] */
int tm_mday; /* Day. [1-31] */
int tm_mon; /* Month. [0-11] */
int tm_year; /* Year - 1900. */
int tm_wday; /* Day of week. [0-6] */
int tm_yday; /* Days in year.[0-365] */
};
void TEXT_SECTION_ATTR rtctime_early_startup (void); void TEXT_SECTION_ATTR rtctime_early_startup (void);
void rtctime_late_startup (void); void rtctime_late_startup (void);
void rtctime_gettimeofday (struct rtc_timeval *tv); void rtctime_gettimeofday (struct rtc_timeval *tv);
...@@ -56,5 +67,6 @@ void rtctime_settimeofday (const struct rtc_timeval *tv); ...@@ -56,5 +67,6 @@ void rtctime_settimeofday (const struct rtc_timeval *tv);
bool rtctime_have_time (void); bool rtctime_have_time (void);
void rtctime_deep_sleep_us (uint32_t us); void rtctime_deep_sleep_us (uint32_t us);
void rtctime_deep_sleep_until_aligned_us (uint32_t align_us, uint32_t min_us); void rtctime_deep_sleep_until_aligned_us (uint32_t align_us, uint32_t min_us);
void rtctime_gmtime (const int32 stamp, struct rtc_tm *r);
#endif #endif
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "ets_sys.h" #include "ets_sys.h"
#include "osapi.h" #include "osapi.h"
#include "os_type.h" #include "os_type.h"
#include "user_interface.h"
/* use LOW / MEDIUM / HIGH since it isn't clear from the docs which is higher */ /* use LOW / MEDIUM / HIGH since it isn't clear from the docs which is higher */
......
...@@ -69,6 +69,17 @@ extern void luaL_assertfail(const char *file, int line, const char *message); ...@@ -69,6 +69,17 @@ extern void luaL_assertfail(const char *file, int line, const char *message);
#define BUILD_SPIFFS 1 #define BUILD_SPIFFS 1
#define SPIFFS_CACHE 1 #define SPIFFS_CACHE 1
// Uncomment this next line for fastest startup
// It reduces the format time dramatically
// #define SPIFFS_MAX_FILESYSTEM_SIZE 32768
//
// You can force the spiffs file system to be at a fixed location
// #define SPIFFS_FIXED_LOCATION 0x100000
//
// You can force the SPIFFS file system to end on the next !M boundary
// (minus the 16k parameter space). THis is useful for certain OTA scenarios
// #define SPIFFS_SIZE_1M_BOUNDARY
// #define LUA_NUMBER_INTEGRAL // #define LUA_NUMBER_INTEGRAL
#define READLINE_INTERVAL 80 #define READLINE_INTERVAL 80
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
// See https://github.com/nodemcu/nodemcu-firmware/pull/1127 for discussions. // See https://github.com/nodemcu/nodemcu-firmware/pull/1127 for discussions.
// New modules should be disabled by default and added in alphabetical order. // New modules should be disabled by default and added in alphabetical order.
#define LUA_USE_MODULES_ADC #define LUA_USE_MODULES_ADC
//#define LUA_USE_MODULES_ADXL345
//#define LUA_USE_MODULES_AM2320 //#define LUA_USE_MODULES_AM2320
//#define LUA_USE_MODULES_APA102 //#define LUA_USE_MODULES_APA102
#define LUA_USE_MODULES_BIT #define LUA_USE_MODULES_BIT
...@@ -31,14 +32,17 @@ ...@@ -31,14 +32,17 @@
//#define LUA_USE_MODULES_ENDUSER_SETUP // USE_DNS in dhcpserver.h needs to be enabled for this module to work. //#define LUA_USE_MODULES_ENDUSER_SETUP // USE_DNS in dhcpserver.h needs to be enabled for this module to work.
#define LUA_USE_MODULES_FILE #define LUA_USE_MODULES_FILE
#define LUA_USE_MODULES_GPIO #define LUA_USE_MODULES_GPIO
//#define LUA_USE_MODULES_HMC5883L
//#define LUA_USE_MODULES_HTTP //#define LUA_USE_MODULES_HTTP
//#define LUA_USE_MODULES_HX711 //#define LUA_USE_MODULES_HX711
#define LUA_USE_MODULES_I2C #define LUA_USE_MODULES_I2C
//#define LUA_USE_MODULES_L3G4200D
//#define LUA_USE_MODULES_MDNS //#define LUA_USE_MODULES_MDNS
#define LUA_USE_MODULES_MQTT #define LUA_USE_MODULES_MQTT
#define LUA_USE_MODULES_NET #define LUA_USE_MODULES_NET
#define LUA_USE_MODULES_NODE #define LUA_USE_MODULES_NODE
#define LUA_USE_MODULES_OW #define LUA_USE_MODULES_OW
//#define LUA_USE_MODULES_PCM
//#define LUA_USE_MODULES_PERF //#define LUA_USE_MODULES_PERF
//#define LUA_USE_MODULES_PWM //#define LUA_USE_MODULES_PWM
//#define LUA_USE_MODULES_RC //#define LUA_USE_MODULES_RC
...@@ -50,6 +54,8 @@ ...@@ -50,6 +54,8 @@
//#define LUA_USE_MODULES_SNTP //#define LUA_USE_MODULES_SNTP
#define LUA_USE_MODULES_SPI #define LUA_USE_MODULES_SPI
//#define LUA_USE_MODULES_STRUCT //#define LUA_USE_MODULES_STRUCT
//#define LUA_USE_MODULES_SWITEC
//#define LUA_USE_MODULES_TM1829
#define LUA_USE_MODULES_TMR #define LUA_USE_MODULES_TMR
//#define LUA_USE_MODULES_TSL2561 //#define LUA_USE_MODULES_TSL2561
//#define LUA_USE_MODULES_U8G //#define LUA_USE_MODULES_U8G
...@@ -59,6 +65,5 @@ ...@@ -59,6 +65,5 @@
//#define LUA_USE_MODULES_WS2801 //#define LUA_USE_MODULES_WS2801
//#define LUA_USE_MODULES_WS2812 //#define LUA_USE_MODULES_WS2812
#endif /* LUA_CROSS_COMPILER */ #endif /* LUA_CROSS_COMPILER */
#endif /* __USER_MODULES_H__ */ #endif /* __USER_MODULES_H__ */
...@@ -3,10 +3,10 @@ ...@@ -3,10 +3,10 @@
#define NODE_VERSION_MAJOR 1U #define NODE_VERSION_MAJOR 1U
#define NODE_VERSION_MINOR 5U #define NODE_VERSION_MINOR 5U
#define NODE_VERSION_REVISION 1U #define NODE_VERSION_REVISION 4U
#define NODE_VERSION_INTERNAL 0U #define NODE_VERSION_INTERNAL 1U
#define NODE_VERSION "NodeMCU 1.5.1" #define NODE_VERSION "NodeMCU 1.5.4.1"
#ifndef BUILD_DATE #ifndef BUILD_DATE
#define BUILD_DATE "unspecified" #define BUILD_DATE "unspecified"
#endif #endif
......
...@@ -227,7 +227,7 @@ static ip_addr_t dns_servers[DNS_MAX_SERVERS]; ...@@ -227,7 +227,7 @@ static ip_addr_t dns_servers[DNS_MAX_SERVERS];
/** Contiguous buffer for processing responses */ /** Contiguous buffer for processing responses */
//static u8_t dns_payload_buffer[LWIP_MEM_ALIGN_BUFFER(DNS_MSG_SIZE)]; //static u8_t dns_payload_buffer[LWIP_MEM_ALIGN_BUFFER(DNS_MSG_SIZE)];
static u8_t* dns_payload; static u8_t* dns_payload;
static u8_t dns_random; static u16_t dns_random;
/** /**
* Initialize the resolver: set up the UDP pcb and configure the default server * Initialize the resolver: set up the UDP pcb and configure the default server
* (DNS_SERVER_ADDRESS). * (DNS_SERVER_ADDRESS).
...@@ -570,7 +570,7 @@ dns_send(u8_t numdns, const char* name, u8_t id) ...@@ -570,7 +570,7 @@ dns_send(u8_t numdns, const char* name, u8_t id)
char *query, *nptr; char *query, *nptr;
const char *pHostname; const char *pHostname;
u8_t n; u8_t n;
dns_random = os_random()%250; dns_random = (u16_t)os_random();
LWIP_DEBUGF(DNS_DEBUG, ("dns_send: dns_servers[%"U16_F"] \"%s\": request\n", LWIP_DEBUGF(DNS_DEBUG, ("dns_send: dns_servers[%"U16_F"] \"%s\": request\n",
(u16_t)(numdns), name)); (u16_t)(numdns), name));
LWIP_ASSERT("dns server out of array", numdns < DNS_MAX_SERVERS); LWIP_ASSERT("dns server out of array", numdns < DNS_MAX_SERVERS);
......
...@@ -46,6 +46,7 @@ INCLUDES += -I ../mqtt ...@@ -46,6 +46,7 @@ INCLUDES += -I ../mqtt
INCLUDES += -I ../u8glib INCLUDES += -I ../u8glib
INCLUDES += -I ../ucglib INCLUDES += -I ../ucglib
INCLUDES += -I ../lua INCLUDES += -I ../lua
INCLUDES += -I ../pcm
INCLUDES += -I ../platform INCLUDES += -I ../platform
INCLUDES += -I ../spiffs INCLUDES += -I ../spiffs
INCLUDES += -I ../smart INCLUDES += -I ../smart
......
/*
* Driver for Analog Devices ADXL345 accelerometer.
*
* Code based on BMP085 driver.
*/
#include "module.h"
#include "lauxlib.h"
#include "platform.h"
#include "c_stdlib.h"
#include "c_string.h"
static const uint32_t adxl345_i2c_id = 0;
static const uint8_t adxl345_i2c_addr = 0x53;
static uint8_t ICACHE_FLASH_ATTR r8u(uint32_t id, uint8_t reg) {
uint8_t ret;
platform_i2c_send_start(id);
platform_i2c_send_address(id, adxl345_i2c_addr, PLATFORM_I2C_DIRECTION_TRANSMITTER);
platform_i2c_send_byte(id, reg);
platform_i2c_send_stop(id);
platform_i2c_send_start(id);
platform_i2c_send_address(id, adxl345_i2c_addr, PLATFORM_I2C_DIRECTION_RECEIVER);
ret = platform_i2c_recv_byte(id, 0);
platform_i2c_send_stop(id);
return ret;
}
static int ICACHE_FLASH_ATTR adxl345_init(lua_State* L) {
uint32_t sda;
uint32_t scl;
uint8_t devid;
sda = luaL_checkinteger(L, 1);
scl = luaL_checkinteger(L, 2);
luaL_argcheck(L, sda > 0 && scl > 0, 1, "no i2c for D0");
platform_i2c_setup(adxl345_i2c_id, sda, scl, PLATFORM_I2C_SPEED_SLOW);
devid = r8u(adxl345_i2c_id, 0x00);
if (devid != 229) {
return luaL_error(L, "device not found");
}
// Enable sensor
platform_i2c_send_start(adxl345_i2c_id);
platform_i2c_send_address(adxl345_i2c_id, adxl345_i2c_addr, PLATFORM_I2C_DIRECTION_TRANSMITTER);
platform_i2c_send_byte(adxl345_i2c_id, 0x2D);
platform_i2c_send_byte(adxl345_i2c_id, 0x08);
platform_i2c_send_stop(adxl345_i2c_id);
return 0;
}
static int ICACHE_FLASH_ATTR adxl345_read(lua_State* L) {
uint8_t data[6];
int x,y,z;
int i;
platform_i2c_send_start(adxl345_i2c_id);
platform_i2c_send_address(adxl345_i2c_id, adxl345_i2c_addr, PLATFORM_I2C_DIRECTION_TRANSMITTER);
platform_i2c_send_byte(adxl345_i2c_id, 0x32);
platform_i2c_send_start(adxl345_i2c_id);
platform_i2c_send_address(adxl345_i2c_id, adxl345_i2c_addr, PLATFORM_I2C_DIRECTION_RECEIVER);
for (i=0; i<5; i++) {
data[i] = platform_i2c_recv_byte(adxl345_i2c_id, 1);
}
data[5] = platform_i2c_recv_byte(adxl345_i2c_id, 0);
platform_i2c_send_stop(adxl345_i2c_id);
x = (int16_t) ((data[1] << 8) | data[0]);
y = (int16_t) ((data[3] << 8) | data[2]);
z = (int16_t) ((data[5] << 8) | data[4]);
lua_pushinteger(L, x);
lua_pushinteger(L, y);
lua_pushinteger(L, z);
return 3;
}
static const LUA_REG_TYPE adxl345_map[] = {
{ LSTRKEY( "read" ), LFUNCVAL( adxl345_read )},
{ LSTRKEY( "init" ), LFUNCVAL( adxl345_init )},
{ LNILKEY, LNILVAL}
};
NODEMCU_MODULE(ADXL345, "adxl345", adxl345_map, NULL);
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