Merge branch 'master' into open-startup
This commit is contained in:
commit
ba7492756c
62 changed files with 1933 additions and 288 deletions
|
@ -178,6 +178,9 @@ void xPortSysTickHandle (void)
|
||||||
//OpenNMI();
|
//OpenNMI();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool sdk_compat_initialised;
|
||||||
|
void sdk_compat_initialise(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* See header file for description.
|
* See header file for description.
|
||||||
*/
|
*/
|
||||||
|
@ -186,6 +189,14 @@ portBASE_TYPE xPortStartScheduler( void )
|
||||||
_xt_isr_attach(INUM_SOFT, SV_ISR);
|
_xt_isr_attach(INUM_SOFT, SV_ISR);
|
||||||
_xt_isr_unmask(BIT(INUM_SOFT));
|
_xt_isr_unmask(BIT(INUM_SOFT));
|
||||||
|
|
||||||
|
/* ENORMOUS HACK: Call the sdk_compat_initialise() function.
|
||||||
|
This can be removed happily once we have open source startup code.
|
||||||
|
*/
|
||||||
|
if(!sdk_compat_initialised) {
|
||||||
|
sdk_compat_initialised = true;
|
||||||
|
sdk_compat_initialise();
|
||||||
|
}
|
||||||
|
|
||||||
/* Initialize system tick timer interrupt and schedule the first tick. */
|
/* Initialize system tick timer interrupt and schedule the first tick. */
|
||||||
sdk__xt_tick_timer_init();
|
sdk__xt_tick_timer_init();
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
|
|
||||||
INC_DIRS += $(freertos_MAIN)/include $(freertos_MAIN)/portable/esp8266
|
INC_DIRS += $(freertos_MAIN)include $(freertos_MAIN)portable/esp8266
|
||||||
|
|
||||||
# args for passing into compile rule generation
|
# args for passing into compile rule generation
|
||||||
freertos_ROOT = $(ROOT)FreeRTOS/
|
|
||||||
freertos_MAIN = $(freertos_ROOT)Source/
|
freertos_MAIN = $(freertos_ROOT)Source/
|
||||||
freertos_INC_DIR = $(freertos_MAIN)include $(freertos_MAIN)portable/esp8266
|
freertos_INC_DIR = $(freertos_MAIN)include $(freertos_MAIN)portable/esp8266
|
||||||
freertos_SRC_DIR = $(freertos_MAIN) $(freertos_MAIN)portable/esp8266
|
freertos_SRC_DIR = $(freertos_MAIN) $(freertos_MAIN)portable/esp8266
|
||||||
|
|
40
README.md
40
README.md
|
@ -4,8 +4,16 @@ A community developed open source [FreeRTOS](http://www.freertos.org/)-based fra
|
||||||
|
|
||||||
Originally based on, but substantially different from, the [Espressif IOT RTOS SDK](https://github.com/espressif/esp_iot_rtos_sdk).
|
Originally based on, but substantially different from, the [Espressif IOT RTOS SDK](https://github.com/espressif/esp_iot_rtos_sdk).
|
||||||
|
|
||||||
|
## Resources
|
||||||
|
|
||||||
[![Build Status](https://travis-ci.org/SuperHouse/esp-open-rtos.svg?branch=master)](https://travis-ci.org/SuperHouse/esp-open-rtos)
|
[![Build Status](https://travis-ci.org/SuperHouse/esp-open-rtos.svg?branch=master)](https://travis-ci.org/SuperHouse/esp-open-rtos)
|
||||||
|
|
||||||
|
Email discussion list: https://groups.google.com/d/forum/esp-open-rtos
|
||||||
|
|
||||||
|
Github issues list/bugtracker: http://github.com/superhouse/esp-open-rtos/issues
|
||||||
|
|
||||||
|
Please note that this project is released with a [Contributor Code of Conduct](https://github.com/SuperHouse/esp-open-rtos/blob/master/code_of_conduct.md). By participating in this project you agree to abide by its terms.
|
||||||
|
|
||||||
## Quick Start
|
## Quick Start
|
||||||
|
|
||||||
* Install [esp-open-sdk](https://github.com/pfalcon/esp-open-sdk/), build it with `make STANDALONE=n`, then edit your PATH and add the generated toolchain `bin` directory. (Despite the similar name esp-open-sdk has different maintainers - but we think it's fantastic!)
|
* Install [esp-open-sdk](https://github.com/pfalcon/esp-open-sdk/), build it with `make STANDALONE=n`, then edit your PATH and add the generated toolchain `bin` directory. (Despite the similar name esp-open-sdk has different maintainers - but we think it's fantastic!)
|
||||||
|
@ -14,7 +22,7 @@ Originally based on, but substantially different from, the [Espressif IOT RTOS S
|
||||||
|
|
||||||
* Install [esptool.py](https://github.com/themadinventor/esptool) and make it available on your PATH. If you used esp-open-sdk then this is done already.
|
* Install [esptool.py](https://github.com/themadinventor/esptool) and make it available on your PATH. If you used esp-open-sdk then this is done already.
|
||||||
|
|
||||||
* The esp-open-rtos build process uses `GNU Make`, and the utilities `sed` and `grep`. If you built esp-open-sdk then you probably have these already.
|
* The esp-open-rtos build process uses `GNU Make`, and the utilities `sed` and `grep`. If you built esp-open-sdk then you have these already.
|
||||||
|
|
||||||
* Use git to clone the esp-open-rtos project (note the `--recursive`):
|
* Use git to clone the esp-open-rtos project (note the `--recursive`):
|
||||||
|
|
||||||
|
@ -30,7 +38,7 @@ cd esp-open-rtos
|
||||||
#define WIFI_PASS "my secret password"
|
#define WIFI_PASS "my secret password"
|
||||||
```
|
```
|
||||||
|
|
||||||
Remove the `#warning` and follow the git ignore instructions to keep your credentials from being pushed to Github.
|
Remove the `#warning` line and follow the git ignore instructions written in the header file to keep your credentials from being pushed to Github.
|
||||||
|
|
||||||
* Build an example project (found in the 'examples' directory) and flash it to a serial port:
|
* Build an example project (found in the 'examples' directory) and flash it to a serial port:
|
||||||
|
|
||||||
|
@ -40,6 +48,8 @@ make flash -j4 -C examples/http_get ESPPORT=/dev/ttyUSB0
|
||||||
|
|
||||||
Run `make help -C examples/http_get` for a summary of other Make targets.
|
Run `make help -C examples/http_get` for a summary of other Make targets.
|
||||||
|
|
||||||
|
(Note: the `-C` option to make is the same as changing to that directory, then running make.)
|
||||||
|
|
||||||
The [Build Process wiki page](https://github.com/SuperHouse/esp-open-rtos/wiki/Build-Process) has in-depth details of the build process.
|
The [Build Process wiki page](https://github.com/SuperHouse/esp-open-rtos/wiki/Build-Process) has in-depth details of the build process.
|
||||||
|
|
||||||
## Goals
|
## Goals
|
||||||
|
@ -49,7 +59,20 @@ The [Build Process wiki page](https://github.com/SuperHouse/esp-open-rtos/wiki/B
|
||||||
* Leave upstream source clean, for easy interaction with upstream projects.
|
* Leave upstream source clean, for easy interaction with upstream projects.
|
||||||
* Flexible build and compilation settings.
|
* Flexible build and compilation settings.
|
||||||
|
|
||||||
Current status is alpha quality, under development. AP STATION mode (ie wifi client mode) and UDP/TCP client modes are tested. Other functionality should work. Contributors and testers are welcome!
|
Current status is alpha quality, actively developed. AP STATION mode (ie wifi client mode) and UDP/TCP client modes are tested. Other functionality should work. Contributors and testers are welcome!
|
||||||
|
|
||||||
|
## Code Structure
|
||||||
|
|
||||||
|
* `examples` contains a range of example projects (one per subdirectory). Check them out!
|
||||||
|
* `include` contains header files from Espressif RTOS SDK, relating to the binary libraries & Xtensa core.
|
||||||
|
* `core` contains source & headers for low-level ESP8266 functions & peripherals. `core/include/esp` contains useful headers for peripheral access, etc. Minimal to no FreeRTOS dependencies.
|
||||||
|
* `extras` is a directory that contains optional components that can be added to your project. Most 'extras' components will have a corresponding example in the `examples` directory. Extras include:
|
||||||
|
- i2c - software i2c driver ([upstream project](https://github.com/kanflo/esp-open-rtos-driver-i2c))
|
||||||
|
- rboot-ota - OTA support (over-the-air updates) including a TFTP server for receiving updates ([for rboot by @raburton](http://richard.burtons.org/2015/05/18/rboot-a-new-boot-loader-for-esp8266/))
|
||||||
|
- bmp180 driver for digital pressure sensor ([upstream project](https://github.com/Angus71/esp-open-rtos-driver-bmp180))
|
||||||
|
* `FreeRTOS` contains FreeRTOS implementation, subdirectory structure is the standard FreeRTOS structure. `FreeRTOS/source/portable/esp8266/` contains the ESP8266 port.
|
||||||
|
* `lwip` and `axtls` contain the lwIP TCP/IP library and the axTLS TLS library ('libssl' in the esp8266 SDKs), respectively. See [Third Party Libraries](https://github.com/SuperHouse/esp-open-rtos/wiki/Third-Party-Libraries) wiki page for details.
|
||||||
|
* `libc` contains the newlib libc. [Libc details here](https://github.com/SuperHouse/esp-open-rtos/wiki/libc-configuration).
|
||||||
|
|
||||||
## Open Source Components
|
## Open Source Components
|
||||||
|
|
||||||
|
@ -71,15 +94,6 @@ Some binary libraries appear to contain unattributed open source code:
|
||||||
* libnet80211.a & libwpa.a appear to be based on FreeBSD net80211/wpa, or forks of them. ([See this issue](https://github.com/SuperHouse/esp-open-rtos/issues/4)).
|
* libnet80211.a & libwpa.a appear to be based on FreeBSD net80211/wpa, or forks of them. ([See this issue](https://github.com/SuperHouse/esp-open-rtos/issues/4)).
|
||||||
* libudhcp has been removed from esp-open-rtos. It was released with the Espressif RTOS SDK but udhcp is GPL licensed.
|
* libudhcp has been removed from esp-open-rtos. It was released with the Espressif RTOS SDK but udhcp is GPL licensed.
|
||||||
|
|
||||||
## Code Structure
|
|
||||||
|
|
||||||
* `examples` contains a range of example projects (one per subdirectory). Check them out!
|
|
||||||
* `include` contains header files from Espressif RTOS SDK, relating to the binary libraries & Xtensa core.
|
|
||||||
* `core` contains source & headers for low-level ESP8266 functions & peripherals. `core/include/esp` contains useful headers for peripheral access, etc. Still being fleshed out. Minimal to no FreeRTOS dependencies.
|
|
||||||
* `FreeRTOS` contains FreeRTOS implementation, subdirectory structure is the standard FreeRTOS structure. `FreeRTOS/source/portable/esp8266/` contains the ESP8266 port.
|
|
||||||
* `lwip` and `axtls` contain the lwIP TCP/IP library and the axTLS TLS library ('libssl' in the esp8266 SDKs), respectively. See [Third Party Libraries](https://github.com/SuperHouse/esp-open-rtos/wiki/Third-Party-Libraries) wiki page for details.
|
|
||||||
|
|
||||||
|
|
||||||
## Licensing
|
## Licensing
|
||||||
|
|
||||||
* BSD license (as described in LICENSE) applies to original source files, [lwIP](http://lwip.wikia.com/wiki/LwIP_Wiki), and [axTLS](http://axtls.sourceforge.net/). lwIP is Copyright (C) Swedish Institute of Computer Science. axTLS is Copyright (C) Cameron Rich.
|
* BSD license (as described in LICENSE) applies to original source files, [lwIP](http://lwip.wikia.com/wiki/LwIP_Wiki), and [axTLS](http://axtls.sourceforge.net/). lwIP is Copyright (C) Swedish Institute of Computer Science. axTLS is Copyright (C) Cameron Rich.
|
||||||
|
@ -90,6 +104,8 @@ Some binary libraries appear to contain unattributed open source code:
|
||||||
|
|
||||||
* Newlib is covered by several copyrights and licenses, as per the files in the `libc` directory.
|
* Newlib is covered by several copyrights and licenses, as per the files in the `libc` directory.
|
||||||
|
|
||||||
|
Components under `extras/` may contain different licenses, please see those directories for details.
|
||||||
|
|
||||||
## Contributions
|
## Contributions
|
||||||
|
|
||||||
Contributions are very welcome!
|
Contributions are very welcome!
|
||||||
|
|
|
@ -6,13 +6,12 @@
|
||||||
|
|
||||||
# We supply our own hand tweaked config.h in the external 'include' dir.
|
# We supply our own hand tweaked config.h in the external 'include' dir.
|
||||||
|
|
||||||
AXTLS_DIR = $(ROOT)axtls/axtls/
|
AXTLS_DIR = $(axtls_ROOT)axtls/
|
||||||
INC_DIRS += $(ROOT)axtls/include $(AXTLS_DIR)ssl $(AXTLS_DIR)crypto
|
INC_DIRS += $(axtls_ROOT)include $(AXTLS_DIR)ssl $(AXTLS_DIR)crypto
|
||||||
|
|
||||||
# args for passing into compile rule generation
|
# args for passing into compile rule generation
|
||||||
axtls_ROOT = $(ROOT)axtls
|
|
||||||
axtls_INC_DIR = $(AXTLS_DIR)include $(AXTLS_DIR)
|
axtls_INC_DIR = $(AXTLS_DIR)include $(AXTLS_DIR)
|
||||||
axtls_SRC_DIR = $(AXTLS_DIR)crypto $(AXTLS_DIR)ssl $(ROOT)axtls
|
axtls_SRC_DIR = $(AXTLS_DIR)crypto $(AXTLS_DIR)ssl $(axtls_ROOT)
|
||||||
|
|
||||||
#axtls_CFLAGS = $(CFLAGS) -Wno-address
|
#axtls_CFLAGS = $(CFLAGS) -Wno-address
|
||||||
|
|
||||||
|
|
22
code_of_conduct.md
Normal file
22
code_of_conduct.md
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
# Contributor Code of Conduct
|
||||||
|
|
||||||
|
As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
|
||||||
|
|
||||||
|
We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality.
|
||||||
|
|
||||||
|
Examples of unacceptable behavior by participants include:
|
||||||
|
|
||||||
|
* The use of sexualized language or imagery
|
||||||
|
* Personal attacks
|
||||||
|
* Trolling or insulting/derogatory comments
|
||||||
|
* Public or private harassment
|
||||||
|
* Publishing other's private information, such as physical or electronic addresses, without explicit permission
|
||||||
|
* Other unethical or unprofessional conduct.
|
||||||
|
|
||||||
|
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project. Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team.
|
||||||
|
|
||||||
|
This code of conduct applies both within project spaces and in public spaces when an individual is representing the project or its community.
|
||||||
|
|
||||||
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
|
||||||
|
|
||||||
|
This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.2.0, available at [http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/)
|
53
common.mk
53
common.mk
|
@ -80,7 +80,7 @@ OBJDUMP = $(CROSS)objdump
|
||||||
|
|
||||||
# Source components to compile and link. Each of these are subdirectories
|
# Source components to compile and link. Each of these are subdirectories
|
||||||
# of the root, with a 'component.mk' file.
|
# of the root, with a 'component.mk' file.
|
||||||
COMPONENTS ?= core FreeRTOS lwip axtls $(EXTRA_COMPONENTS)
|
COMPONENTS ?= $(EXTRA_COMPONENTS) FreeRTOS lwip axtls core
|
||||||
|
|
||||||
# binary esp-iot-rtos SDK libraries to link. These are pre-processed prior to linking.
|
# binary esp-iot-rtos SDK libraries to link. These are pre-processed prior to linking.
|
||||||
SDK_LIBS ?= main net80211 phy pp wpa
|
SDK_LIBS ?= main net80211 phy pp wpa
|
||||||
|
@ -94,11 +94,16 @@ OWN_LIBC ?= 1
|
||||||
# Note: you will need a recent esp
|
# Note: you will need a recent esp
|
||||||
ENTRY_SYMBOL ?= call_user_start
|
ENTRY_SYMBOL ?= call_user_start
|
||||||
|
|
||||||
CFLAGS = -Wall -Werror -Wl,-EL -nostdlib -mlongcalls -mtext-section-literals -std=gnu99 $(CPPFLAGS)
|
# Common flags for both C & C++_
|
||||||
|
C_CXX_FLAGS = -Wall -Werror -Wl,-EL -nostdlib -mlongcalls -mtext-section-literals $(CPPFLAGS)
|
||||||
|
# Flags for C only
|
||||||
|
CFLAGS = $(C_CXX_FLAGS) -std=gnu99
|
||||||
|
# Flags for C++ only
|
||||||
|
CXXFLAGS = $(C_CXX_FLAGS) -fno-exceptions -fno-rtti
|
||||||
LDFLAGS = -nostdlib -Wl,--no-check-sections -Wl,-L$(BUILD_DIR)sdklib -Wl,-L$(ROOT)lib -u $(ENTRY_SYMBOL) -Wl,-static -Wl,-Map=build/${PROGRAM}.map $(EXTRA_LDFLAGS)
|
LDFLAGS = -nostdlib -Wl,--no-check-sections -Wl,-L$(BUILD_DIR)sdklib -Wl,-L$(ROOT)lib -u $(ENTRY_SYMBOL) -Wl,-static -Wl,-Map=build/${PROGRAM}.map $(EXTRA_LDFLAGS)
|
||||||
|
|
||||||
ifeq ($(FLAVOR),debug)
|
ifeq ($(FLAVOR),debug)
|
||||||
CFLAGS += -g -O0
|
C_CXX_FLAGS += -g -O0
|
||||||
LDFLAGS += -g -O0
|
LDFLAGS += -g -O0
|
||||||
else ifeq ($(FLAVOR),sdklike)
|
else ifeq ($(FLAVOR),sdklike)
|
||||||
# These are flags intended to produce object code as similar as possible to
|
# These are flags intended to produce object code as similar as possible to
|
||||||
|
@ -108,7 +113,7 @@ else ifeq ($(FLAVOR),sdklike)
|
||||||
CFLAGS += -O2 -Os -fno-inline -fno-ipa-cp -fno-toplevel-reorder
|
CFLAGS += -O2 -Os -fno-inline -fno-ipa-cp -fno-toplevel-reorder
|
||||||
LDFLAGS += -O2
|
LDFLAGS += -O2
|
||||||
else
|
else
|
||||||
CFLAGS += -g -O2
|
C_CXX_FLAGS += -g -O2
|
||||||
LDFLAGS += -g -O2
|
LDFLAGS += -g -O2
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -201,42 +206,45 @@ all: $(PROGRAM_OUT) $(FW_FILE_1) $(FW_FILE_2) $(FW_FILE)
|
||||||
# component_compile_rules: Produces compilation rules for a given
|
# component_compile_rules: Produces compilation rules for a given
|
||||||
# component
|
# component
|
||||||
#
|
#
|
||||||
|
# For user-facing documentation, see:
|
||||||
|
# https://github.com/SuperHouse/esp-open-rtos/wiki/Build-Process#adding-a-new-component
|
||||||
|
#
|
||||||
# Call arguments are:
|
# Call arguments are:
|
||||||
# $(1) - component name
|
# $(1) - component name
|
||||||
#
|
#
|
||||||
# Expects that the following component-specific variables are defined:
|
# Expects that the following component-specific variables are defined:
|
||||||
#
|
#
|
||||||
# $(1)_ROOT = Top-level dir containing component. Can be in-tree or out-of-tree.
|
# $(1)_ROOT = Top-level dir containing component. Can be in-tree or out-of-tree.
|
||||||
|
# (if this variable isn't defined, directory containing component.mk is used)
|
||||||
# $(1)_SRC_DIR = List of source directories for the component. All must be under $(1)_ROOT
|
# $(1)_SRC_DIR = List of source directories for the component. All must be under $(1)_ROOT
|
||||||
# $(1)_INC_DIR = List of include directories specific for the component
|
# $(1)_INC_DIR = List of include directories specific for the component
|
||||||
#
|
#
|
||||||
# As an alternative to $(1)_SRC_DIR, you can specify source filenames
|
|
||||||
# as $(1)_SRC_FILES. If you want to specify both directories and
|
|
||||||
# some additional files, specify directories in $(1)_SRC_DIR and
|
|
||||||
# additional files in $(1)_EXTRA_SRC_FILES.
|
|
||||||
#
|
|
||||||
# Optional variables:
|
|
||||||
# $(1)_CFLAGS = CFLAGS to override the default CFLAGS for this component only.
|
|
||||||
#
|
#
|
||||||
# Each call appends to COMPONENT_ARS which is a list of archive files for compiled components
|
# Each call appends to COMPONENT_ARS which is a list of archive files for compiled components
|
||||||
COMPONENT_ARS =
|
COMPONENT_ARS =
|
||||||
define component_compile_rules
|
define component_compile_rules
|
||||||
|
$(1)_DEFAULT_ROOT := $(dir $(lastword $(MAKEFILE_LIST)))
|
||||||
|
$(1)_ROOT ?= $$($(1)_DEFAULT_ROOT)
|
||||||
$(1)_OBJ_DIR = $(call lc,$(BUILD_DIR)$(1)/)
|
$(1)_OBJ_DIR = $(call lc,$(BUILD_DIR)$(1)/)
|
||||||
### determine source files and object files ###
|
### determine source files and object files ###
|
||||||
$(1)_SRC_FILES ?= $$(foreach sdir,$$($(1)_SRC_DIR), \
|
$(1)_SRC_FILES ?= $$(foreach sdir,$$($(1)_SRC_DIR), \
|
||||||
$$(wildcard $$(sdir)/*.c) $$(wildcard $$(sdir)/*.S)) \
|
$$(wildcard $$(sdir)/*.c) $$(wildcard $$(sdir)/*.S) \
|
||||||
|
$$(wildcard $$(sdir)/*.cpp)) \
|
||||||
$$($(1)_EXTRA_SRC_FILES)
|
$$($(1)_EXTRA_SRC_FILES)
|
||||||
$(1)_REAL_SRC_FILES = $$(foreach sfile,$$($(1)_SRC_FILES),$$(realpath $$(sfile)))
|
$(1)_REAL_SRC_FILES = $$(foreach sfile,$$($(1)_SRC_FILES),$$(realpath $$(sfile)))
|
||||||
$(1)_REAL_ROOT = $$(realpath $$($(1)_ROOT))
|
$(1)_REAL_ROOT = $$(realpath $$($(1)_ROOT))
|
||||||
# patsubst here substitutes real component root path for the relative OBJ_DIR path, making things short again
|
# patsubst here substitutes real component root path for the relative OBJ_DIR path, making things short again
|
||||||
$(1)_OBJ_FILES_C = $$(patsubst $$($(1)_REAL_ROOT)%.c,$$($(1)_OBJ_DIR)%.o,$$($(1)_REAL_SRC_FILES))
|
$(1)_OBJ_FILES_CXX = $$(patsubst $$($(1)_REAL_ROOT)%.cpp,$$($(1)_OBJ_DIR)%.o,$$($(1)_REAL_SRC_FILES))
|
||||||
|
$(1)_OBJ_FILES_C = $$(patsubst $$($(1)_REAL_ROOT)%.c,$$($(1)_OBJ_DIR)%.o,$$($(1)_OBJ_FILES_CXX))
|
||||||
$(1)_OBJ_FILES = $$(patsubst $$($(1)_REAL_ROOT)%.S,$$($(1)_OBJ_DIR)%.o,$$($(1)_OBJ_FILES_C))
|
$(1)_OBJ_FILES = $$(patsubst $$($(1)_REAL_ROOT)%.S,$$($(1)_OBJ_DIR)%.o,$$($(1)_OBJ_FILES_C))
|
||||||
# the last included makefile is our component's component.mk makefile (rebuild the component if it changes)
|
# the last included makefile is our component's component.mk makefile (rebuild the component if it changes)
|
||||||
$(1)_MAKEFILE ?= $(lastword $(MAKEFILE_LIST))
|
$(1)_MAKEFILE ?= $(lastword $(MAKEFILE_LIST))
|
||||||
|
|
||||||
### determine compiler arguments ###
|
### determine compiler arguments ###
|
||||||
$(1)_CFLAGS ?= $(CFLAGS)
|
$(1)_CFLAGS ?= $(CFLAGS)
|
||||||
|
$(1)_CXXFLAGS ?= $(CXXFLAGS)
|
||||||
$(1)_CC_ARGS = $(Q) $(CC) $$(addprefix -I,$$(INC_DIRS)) $$(addprefix -I,$$($(1)_INC_DIR)) $$($(1)_CFLAGS)
|
$(1)_CC_ARGS = $(Q) $(CC) $$(addprefix -I,$$(INC_DIRS)) $$(addprefix -I,$$($(1)_INC_DIR)) $$($(1)_CFLAGS)
|
||||||
|
$(1)_CXX_ARGS = $(Q) $(C++) $$(addprefix -I,$$(INC_DIRS)) $$(addprefix -I,$$($(1)_INC_DIR)) $$($(1)_CXXFLAGS)
|
||||||
$(1)_AR = $(call lc,$(BUILD_DIR)$(1).a)
|
$(1)_AR = $(call lc,$(BUILD_DIR)$(1).a)
|
||||||
|
|
||||||
$$($(1)_OBJ_DIR)%.o: $$($(1)_REAL_ROOT)%.c $$($(1)_MAKEFILE) $(wildcard $(ROOT)*.mk) | $$($(1)_SRC_DIR)
|
$$($(1)_OBJ_DIR)%.o: $$($(1)_REAL_ROOT)%.c $$($(1)_MAKEFILE) $(wildcard $(ROOT)*.mk) | $$($(1)_SRC_DIR)
|
||||||
|
@ -245,6 +253,12 @@ $$($(1)_OBJ_DIR)%.o: $$($(1)_REAL_ROOT)%.c $$($(1)_MAKEFILE) $(wildcard $(ROOT)*
|
||||||
$$($(1)_CC_ARGS) -c $$< -o $$@
|
$$($(1)_CC_ARGS) -c $$< -o $$@
|
||||||
$$($(1)_CC_ARGS) -MM -MT $$@ -MF $$(@:.o=.d) $$<
|
$$($(1)_CC_ARGS) -MM -MT $$@ -MF $$(@:.o=.d) $$<
|
||||||
|
|
||||||
|
$$($(1)_OBJ_DIR)%.o: $$($(1)_REAL_ROOT)%.cpp $$($(1)_MAKEFILE) $(wildcard $(ROOT)*.mk) | $$($(1)_SRC_DIR)
|
||||||
|
$(vecho) "C++ $$<"
|
||||||
|
$(Q) mkdir -p $$(dir $$@)
|
||||||
|
$$($(1)_CXX_ARGS) -c $$< -o $$@
|
||||||
|
$$($(1)_CXX_ARGS) -MM -MT $$@ -MF $$(@:.o=.d) $$<
|
||||||
|
|
||||||
$$($(1)_OBJ_DIR)%.o: $$($(1)_REAL_ROOT)%.S $$($(1)_MAKEFILE) $(wildcard $(ROOT)*.mk) | $$($(1)_SRC_DIR)
|
$$($(1)_OBJ_DIR)%.o: $$($(1)_REAL_ROOT)%.S $$($(1)_MAKEFILE) $(wildcard $(ROOT)*.mk) | $$($(1)_SRC_DIR)
|
||||||
$(vecho) "AS $$<"
|
$(vecho) "AS $$<"
|
||||||
$(Q) mkdir -p $$(dir $$@)
|
$(Q) mkdir -p $$(dir $$@)
|
||||||
|
@ -299,8 +313,15 @@ PROGRAM_MAKEFILE = $(firstword $(MAKEFILE_LIST))
|
||||||
$(eval $(call component_compile_rules,PROGRAM))
|
$(eval $(call component_compile_rules,PROGRAM))
|
||||||
|
|
||||||
## Include other components (this is where the actual compiler sections are generated)
|
## Include other components (this is where the actual compiler sections are generated)
|
||||||
$(foreach component,$(COMPONENTS), $(eval include $(ROOT)$(component)/component.mk))
|
##
|
||||||
|
## if component directory exists relative to $(ROOT), use that.
|
||||||
|
## otherwise try to resolve it as an absolute path
|
||||||
|
$(foreach component,$(COMPONENTS), \
|
||||||
|
$(if $(wildcard $(ROOT)$(component)), \
|
||||||
|
$(eval include $(ROOT)$(component)/component.mk), \
|
||||||
|
$(eval include $(component)/component.mk) \
|
||||||
|
) \
|
||||||
|
)
|
||||||
|
|
||||||
## Run linker scripts via C preprocessor to evaluate macros
|
## Run linker scripts via C preprocessor to evaluate macros
|
||||||
$(LD_DIR)%.ld: $(ROOT)ld/%.ld | $(LD_DIR)
|
$(LD_DIR)%.ld: $(ROOT)ld/%.ld | $(LD_DIR)
|
||||||
|
@ -309,7 +330,7 @@ $(LD_DIR)%.ld: $(ROOT)ld/%.ld | $(LD_DIR)
|
||||||
# final linking step to produce .elf
|
# final linking step to produce .elf
|
||||||
$(PROGRAM_OUT): $(COMPONENT_ARS) $(SDK_PROCESSED_LIBS) $(LINKER_SCRIPTS_PROCESSED)
|
$(PROGRAM_OUT): $(COMPONENT_ARS) $(SDK_PROCESSED_LIBS) $(LINKER_SCRIPTS_PROCESSED)
|
||||||
$(vecho) "LD $@"
|
$(vecho) "LD $@"
|
||||||
$(Q) $(LD) $(LDFLAGS) -Wl,--start-group $(LIB_ARGS) $(SDK_LIB_ARGS) $(COMPONENT_ARS) -Wl,--end-group -o $@
|
$(Q) $(LD) $(LDFLAGS) -Wl,--start-group $(COMPONENT_ARS) $(LIB_ARGS) $(SDK_LIB_ARGS) -Wl,--end-group -o $@
|
||||||
|
|
||||||
$(BUILD_DIR) $(FW_BASE) $(BUILD_DIR)sdklib $(LD_DIR):
|
$(BUILD_DIR) $(FW_BASE) $(BUILD_DIR)sdklib $(LD_DIR):
|
||||||
$(Q) mkdir -p $@
|
$(Q) mkdir -p $@
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
INC_DIRS += $(core_ROOT)include
|
INC_DIRS += $(core_ROOT)include
|
||||||
|
|
||||||
# args for passing into compile rule generation
|
# args for passing into compile rule generation
|
||||||
core_ROOT = $(ROOT)core/
|
|
||||||
core_SRC_DIR = $(core_ROOT)
|
core_SRC_DIR = $(core_ROOT)
|
||||||
|
|
||||||
$(eval $(call component_compile_rules,core))
|
$(eval $(call component_compile_rules,core))
|
||||||
|
|
25
core/cplusplus_operators.cpp
Normal file
25
core/cplusplus_operators.cpp
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
/* Part of esp-open-rtos
|
||||||
|
* BSD Licensed as described in the file LICENSE
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
void *operator new(size_t size)
|
||||||
|
{
|
||||||
|
return malloc(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *operator new[](size_t size)
|
||||||
|
{
|
||||||
|
return malloc(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator delete(void * ptr)
|
||||||
|
{
|
||||||
|
free(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator delete[](void * ptr)
|
||||||
|
{
|
||||||
|
free(ptr);
|
||||||
|
}
|
|
@ -10,6 +10,8 @@
|
||||||
#ifndef _COMMON_MACROS_H
|
#ifndef _COMMON_MACROS_H
|
||||||
#define _COMMON_MACROS_H
|
#define _COMMON_MACROS_H
|
||||||
|
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
|
||||||
#define UNUSED __attributed((unused))
|
#define UNUSED __attributed((unused))
|
||||||
|
|
||||||
#ifndef BIT
|
#ifndef BIT
|
||||||
|
@ -45,7 +47,11 @@
|
||||||
Important to note: IROM flash can only be accessed via 32-bit word
|
Important to note: IROM flash can only be accessed via 32-bit word
|
||||||
aligned reads. It's up to the user of this attribute to ensure this.
|
aligned reads. It's up to the user of this attribute to ensure this.
|
||||||
*/
|
*/
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#define IROM __attribute__((section(".irom0.literal")))
|
||||||
|
#else
|
||||||
#define IROM __attribute__((section(".irom0.literal"))) const
|
#define IROM __attribute__((section(".irom0.literal"))) const
|
||||||
|
#endif
|
||||||
|
|
||||||
#define INLINED inline static __attribute__((always_inline)) __attribute__((unused))
|
#define INLINED inline static __attribute__((always_inline)) __attribute__((unused))
|
||||||
|
|
||||||
|
|
|
@ -27,28 +27,26 @@ typedef enum {
|
||||||
INLINED void gpio_enable(const uint8_t gpio_num, const gpio_direction_t direction)
|
INLINED void gpio_enable(const uint8_t gpio_num, const gpio_direction_t direction)
|
||||||
{
|
{
|
||||||
uint32_t iomux_flags;
|
uint32_t iomux_flags;
|
||||||
uint32_t ctrl_val;
|
|
||||||
|
|
||||||
switch(direction) {
|
switch(direction) {
|
||||||
case GPIO_INPUT:
|
case GPIO_INPUT:
|
||||||
iomux_flags = 0;
|
iomux_flags = 0;
|
||||||
ctrl_val = 0;
|
|
||||||
break;
|
break;
|
||||||
case GPIO_OUTPUT:
|
case GPIO_OUTPUT:
|
||||||
iomux_flags = IOMUX_PIN_OUTPUT_ENABLE;
|
iomux_flags = IOMUX_PIN_OUTPUT_ENABLE;
|
||||||
ctrl_val = GPIO_CONF_PUSH_PULL;
|
|
||||||
break;
|
break;
|
||||||
case GPIO_OUT_OPEN_DRAIN:
|
case GPIO_OUT_OPEN_DRAIN:
|
||||||
iomux_flags = IOMUX_PIN_OUTPUT_ENABLE;
|
iomux_flags = IOMUX_PIN_OUTPUT_ENABLE;
|
||||||
ctrl_val = 0;
|
|
||||||
break;
|
break;
|
||||||
case GPIO_INPUT_PULLUP:
|
case GPIO_INPUT_PULLUP:
|
||||||
iomux_flags = IOMUX_PIN_PULLUP;
|
iomux_flags = IOMUX_PIN_PULLUP;
|
||||||
ctrl_val = 0;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
iomux_set_gpio_function(gpio_num, iomux_flags);
|
iomux_set_gpio_function(gpio_num, iomux_flags);
|
||||||
GPIO.CONF[gpio_num] = (GPIO.CONF[gpio_num] & FIELD_MASK(GPIO_CONF_INTTYPE)) | ctrl_val;
|
if(direction == GPIO_OUT_OPEN_DRAIN)
|
||||||
|
GPIO.CONF[gpio_num] |= GPIO_CONF_OPEN_DRAIN;
|
||||||
|
else
|
||||||
|
GPIO.CONF[gpio_num] &= ~GPIO_CONF_OPEN_DRAIN;
|
||||||
if (iomux_flags & IOMUX_PIN_OUTPUT_ENABLE)
|
if (iomux_flags & IOMUX_PIN_OUTPUT_ENABLE)
|
||||||
GPIO.ENABLE_OUT_SET = BIT(gpio_num);
|
GPIO.ENABLE_OUT_SET = BIT(gpio_num);
|
||||||
else
|
else
|
||||||
|
@ -124,7 +122,7 @@ INLINED void gpio_set_interrupt(const uint8_t gpio_num, const gpio_inttype_t int
|
||||||
/* Return the interrupt type set for a pin */
|
/* Return the interrupt type set for a pin */
|
||||||
INLINED gpio_inttype_t gpio_get_interrupt(const uint8_t gpio_num)
|
INLINED gpio_inttype_t gpio_get_interrupt(const uint8_t gpio_num)
|
||||||
{
|
{
|
||||||
return FIELD2VAL(GPIO_CONF_INTTYPE, GPIO.CONF[gpio_num]);
|
return (gpio_inttype_t)FIELD2VAL(GPIO_CONF_INTTYPE, GPIO.CONF[gpio_num]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -76,10 +76,15 @@ _Static_assert(sizeof(struct GPIO_REGS) == 0x74, "GPIO_REGS is the wrong size");
|
||||||
* Under what conditions this GPIO input should generate an interrupt.
|
* Under what conditions this GPIO input should generate an interrupt.
|
||||||
* (see gpio_inttype_t enum below for values)
|
* (see gpio_inttype_t enum below for values)
|
||||||
*
|
*
|
||||||
* GPIO_CONF_PUSH_PULL (boolean)
|
* GPIO_CONF_OPEN_DRAIN (boolean)
|
||||||
* When set, a high output state will pull the pin up to +Vcc (3.3V). When
|
* If this bit is set, the pin is in "open drain" mode - a high output state
|
||||||
* cleared, output functions in "open drain" mode (low state will pull down
|
* will leave the pin floating but not source any current. If bit is cleared,
|
||||||
* to ground, but high state allows output to "float").
|
* the pin is in push/pull mode so a high output state will drive the pin up
|
||||||
|
* to +Vcc (3.3V). In either case, a low output state will pull the pin down
|
||||||
|
* to ground.
|
||||||
|
*
|
||||||
|
* GPIO_CONF_OPEN_DRAIN does not appear to work on all pins.
|
||||||
|
*
|
||||||
*
|
*
|
||||||
* GPIO_CONF_SOURCE_PWM (boolean)
|
* GPIO_CONF_SOURCE_PWM (boolean)
|
||||||
* When set, GPIO pin output will be connected to the sigma-delta PWM
|
* When set, GPIO pin output will be connected to the sigma-delta PWM
|
||||||
|
@ -93,7 +98,7 @@ _Static_assert(sizeof(struct GPIO_REGS) == 0x74, "GPIO_REGS is the wrong size");
|
||||||
#define GPIO_CONF_WAKEUP_ENABLE BIT(10)
|
#define GPIO_CONF_WAKEUP_ENABLE BIT(10)
|
||||||
#define GPIO_CONF_INTTYPE_M 0x00000007
|
#define GPIO_CONF_INTTYPE_M 0x00000007
|
||||||
#define GPIO_CONF_INTTYPE_S 7
|
#define GPIO_CONF_INTTYPE_S 7
|
||||||
#define GPIO_CONF_PUSH_PULL BIT(2)
|
#define GPIO_CONF_OPEN_DRAIN BIT(2)
|
||||||
#define GPIO_CONF_SOURCE_PWM BIT(0)
|
#define GPIO_CONF_SOURCE_PWM BIT(0)
|
||||||
|
|
||||||
/* Valid values for the GPIO_CONF_INTTYPE field */
|
/* Valid values for the GPIO_CONF_INTTYPE field */
|
||||||
|
|
|
@ -45,7 +45,7 @@ _Static_assert(sizeof(struct IOMUX_REGS) == 0x44, "IOMUX_REGS is the wrong size"
|
||||||
#define IOMUX_PIN_FUNC_MASK 0x00001030
|
#define IOMUX_PIN_FUNC_MASK 0x00001030
|
||||||
|
|
||||||
/* WARNING: Macro evaluates argument twice */
|
/* WARNING: Macro evaluates argument twice */
|
||||||
#define IOMUX_FUNC(val) (VAL2FIELD(IOMUX_PIN_FUNC_LOW, val) | VAL2FIELD(IOMUX_PIN_FUNC_HIGH, val))
|
#define IOMUX_FUNC(val) (VAL2FIELD_M(IOMUX_PIN_FUNC_LOW, val) | VAL2FIELD_M(IOMUX_PIN_FUNC_HIGH, val))
|
||||||
|
|
||||||
/* WARNING: Macro evaluates argument twice */
|
/* WARNING: Macro evaluates argument twice */
|
||||||
#define IOMUX_FUNC_VALUE(regbits) (FIELD2VAL(IOMUX_PIN_FUNC_LOW, regbits) | FIELD2VAL(IOMUX_PIN_FUNC_HIGH, regbits))
|
#define IOMUX_FUNC_VALUE(regbits) (FIELD2VAL(IOMUX_PIN_FUNC_LOW, regbits) | FIELD2VAL(IOMUX_PIN_FUNC_HIGH, regbits))
|
||||||
|
|
|
@ -193,7 +193,7 @@ INLINED bool _timer_set_frequency_impl(const timer_frc_t frc, uint32_t freq)
|
||||||
counts = timer_freq_to_count(frc, freq, div);
|
counts = timer_freq_to_count(frc, freq, div);
|
||||||
if(counts == 0)
|
if(counts == 0)
|
||||||
{
|
{
|
||||||
printf("ABORT: No counter for timer %u frequency %lu\r\n", frc, freq);
|
printf("ABORT: No counter for timer %u frequency %u\r\n", frc, freq);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
*/
|
*/
|
||||||
#include <sys/reent.h>
|
#include <sys/reent.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <sys/errno.h>
|
||||||
#include <espressif/sdk_private.h>
|
#include <espressif/sdk_private.h>
|
||||||
#include <common_macros.h>
|
#include <common_macros.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -37,6 +38,10 @@ IRAM caddr_t _sbrk_r (struct _reent *r, int incr)
|
||||||
*/
|
*/
|
||||||
long _write_r(struct _reent *r, int fd, const char *ptr, int len )
|
long _write_r(struct _reent *r, int fd, const char *ptr, int len )
|
||||||
{
|
{
|
||||||
|
if(fd != r->_stdout->_file) {
|
||||||
|
r->_errno = EBADF;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
for(int i = 0; i < len; i++)
|
for(int i = 0; i < len; i++)
|
||||||
sdk_os_putc(ptr[i]);
|
sdk_os_putc(ptr[i]);
|
||||||
return len;
|
return len;
|
||||||
|
@ -48,29 +53,31 @@ long _write_r(struct _reent *r, int fd, const char *ptr, int len )
|
||||||
*/
|
*/
|
||||||
long _read_r( struct _reent *r, int fd, char *ptr, int len )
|
long _read_r( struct _reent *r, int fd, char *ptr, int len )
|
||||||
{
|
{
|
||||||
|
if(fd != r->_stdin->_file) {
|
||||||
|
r->_errno = EBADF;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
for(int i = 0; i < len; i++) {
|
for(int i = 0; i < len; i++) {
|
||||||
char ch;
|
char ch;
|
||||||
while (sdk_uart_rx_one_char(&ch)) ;
|
while (sdk_uart_rx_one_char(&ch)) ;
|
||||||
ptr[i] = ch;
|
ptr[i] = ch;
|
||||||
|
|
||||||
}
|
}
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* These are stub implementations for the reentrant syscalls that
|
/* Stub syscall implementations follow, to allow compiling newlib functions that
|
||||||
* newlib is configured to expect */
|
pull these in via various codepaths
|
||||||
int _fstat_r(struct _reent *r, int fd, void *buf)
|
*/
|
||||||
|
__attribute__((alias("syscall_returns_enosys"))) int _open_r(struct _reent *r, const char *pathname, int flags, int mode);
|
||||||
|
__attribute__((alias("syscall_returns_enosys"))) int _fstat_r(struct _reent *r, int fd, void *buf);
|
||||||
|
__attribute__((alias("syscall_returns_enosys"))) int _close_r(struct _reent *r, int fd);
|
||||||
|
__attribute__((alias("syscall_returns_enosys"))) off_t _lseek_r(struct _reent *r, int fd, off_t offset, int whence);
|
||||||
|
|
||||||
|
/* Generic stub for any newlib syscall that fails with errno ENOSYS
|
||||||
|
("Function not implemented") and a return value equivalent to
|
||||||
|
(int)-1. */
|
||||||
|
static int syscall_returns_enosys(struct _reent *r)
|
||||||
{
|
{
|
||||||
|
r->_errno=ENOSYS;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _close_r(struct _reent *r, int fd)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
off_t _lseek_r(struct _reent *r, int fd, off_t offset, int whence)
|
|
||||||
{
|
|
||||||
return (off_t)-1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -14,3 +14,18 @@ void IRAM *zalloc(size_t nbytes)
|
||||||
{
|
{
|
||||||
return calloc(1, nbytes);
|
return calloc(1, nbytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern void (*__init_array_start)(void);
|
||||||
|
extern void (*__init_array_end)(void);
|
||||||
|
|
||||||
|
/* Do things which should be done as part of the startup code, but aren't.
|
||||||
|
|
||||||
|
Can be replaced with _start() once we have open source startup code.
|
||||||
|
*/
|
||||||
|
void sdk_compat_initialise()
|
||||||
|
{
|
||||||
|
/* Call C++ constructors or C functions marked with __attribute__((constructor)) */
|
||||||
|
void (**p)(void);
|
||||||
|
for ( p = &__init_array_start; p != &__init_array_end; ++p)
|
||||||
|
(*p)();
|
||||||
|
}
|
||||||
|
|
|
@ -22,10 +22,10 @@ build-examples: $(EXAMPLES_BUILD)
|
||||||
rebuild-examples: $(EXAMPLES_REBUILD)
|
rebuild-examples: $(EXAMPLES_REBUILD)
|
||||||
|
|
||||||
%.dummybuild:
|
%.dummybuild:
|
||||||
make -C $(dir $@)
|
$(MAKE) -C $(dir $@)
|
||||||
|
|
||||||
%.dummyrebuild:
|
%.dummyrebuild:
|
||||||
make -C $(dir $@) rebuild
|
$(MAKE) -C $(dir $@) rebuild
|
||||||
|
|
||||||
.PHONY: warning rebuild-examples build-examples
|
.PHONY: warning rebuild-examples build-examples
|
||||||
.NOTPARALLEL:
|
.NOTPARALLEL:
|
||||||
|
|
3
examples/bmp180_i2c/Makefile
Normal file
3
examples/bmp180_i2c/Makefile
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
PROGRAM=BMP180_Reader
|
||||||
|
EXTRA_COMPONENTS = extras/i2c extras/bmp180
|
||||||
|
include ../../common.mk
|
7
examples/bmp180_i2c/README.md
Normal file
7
examples/bmp180_i2c/README.md
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
# I2C / BMP180 Example
|
||||||
|
|
||||||
|
This example references two addtional drivers [i2c](https://github.com/kanflo/esp-open-rtos-driver-i2c) and [bmp180](https://github.com/Angus71/esp-open-rtos-driver-bmp180), which are provided in the `../../extras` folder.
|
||||||
|
|
||||||
|
If you plan to use one or both of this drivers in your own projects, please check the main development pages for updated versions or reported issues.
|
||||||
|
|
||||||
|
To run this example connect the BMP085/BMP180 SCL to GPIO0 and SDA to GPIO2.
|
132
examples/bmp180_i2c/bmp180_i2c.c
Normal file
132
examples/bmp180_i2c/bmp180_i2c.c
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
/* Simple example for I2C / BMP180 / Timer & Event Handling
|
||||||
|
*
|
||||||
|
* This sample code is in the public domain.
|
||||||
|
*/
|
||||||
|
#include "espressif/esp_common.h"
|
||||||
|
#include "espressif/sdk_private.h"
|
||||||
|
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "timers.h"
|
||||||
|
#include "queue.h"
|
||||||
|
|
||||||
|
// BMP180 driver
|
||||||
|
#include "bmp180/bmp180.h"
|
||||||
|
|
||||||
|
#define MY_EVT_TIMER 0x01
|
||||||
|
#define MY_EVT_BMP180 0x02
|
||||||
|
|
||||||
|
#define SCL_PIN GPIO_ID_PIN((0))
|
||||||
|
#define SDA_PIN GPIO_ID_PIN((2))
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint8_t event_type;
|
||||||
|
bmp180_result_t bmp180_data;
|
||||||
|
} my_event_t;
|
||||||
|
|
||||||
|
// Communication Queue
|
||||||
|
static xQueueHandle mainqueue;
|
||||||
|
static xTimerHandle timerHandle;
|
||||||
|
|
||||||
|
// Own BMP180 User Inform Implementation
|
||||||
|
bool bmp180_i2c_informUser(const xQueueHandle* resultQueue, uint8_t cmd, bmp180_temp_t temperature, bmp180_press_t pressure)
|
||||||
|
{
|
||||||
|
my_event_t ev;
|
||||||
|
|
||||||
|
ev.event_type = MY_EVT_BMP180;
|
||||||
|
ev.bmp180_data.cmd = cmd;
|
||||||
|
ev.bmp180_data.temperature = temperature;
|
||||||
|
ev.bmp180_data.pressure = pressure;
|
||||||
|
|
||||||
|
return (xQueueSend(*resultQueue, &ev, 0) == pdTRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Timer call back
|
||||||
|
static void bmp180_i2c_timer_cb(xTimerHandle xTimer)
|
||||||
|
{
|
||||||
|
my_event_t ev;
|
||||||
|
ev.event_type = MY_EVT_TIMER;
|
||||||
|
|
||||||
|
xQueueSend(mainqueue, &ev, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for communiction events
|
||||||
|
void bmp180_task(void *pvParameters)
|
||||||
|
{
|
||||||
|
// Received pvParameters is communication queue
|
||||||
|
xQueueHandle *com_queue = (xQueueHandle *)pvParameters;
|
||||||
|
|
||||||
|
printf("%s: Started user interface task\n", __FUNCTION__);
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
my_event_t ev;
|
||||||
|
|
||||||
|
xQueueReceive(*com_queue, &ev, portMAX_DELAY);
|
||||||
|
|
||||||
|
switch(ev.event_type)
|
||||||
|
{
|
||||||
|
case MY_EVT_TIMER:
|
||||||
|
printf("%s: Received Timer Event\n", __FUNCTION__);
|
||||||
|
|
||||||
|
bmp180_trigger_measurement(com_queue);
|
||||||
|
break;
|
||||||
|
case MY_EVT_BMP180:
|
||||||
|
printf("%s: Received BMP180 Event temp:=%d.%d°C press=%d.%02dhPa\n", __FUNCTION__, \
|
||||||
|
(int32_t)ev.bmp180_data.temperature, abs((int32_t)(ev.bmp180_data.temperature*10)%10), \
|
||||||
|
ev.bmp180_data.pressure/100, ev.bmp180_data.pressure%100 );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup HW
|
||||||
|
void user_setup(void)
|
||||||
|
{
|
||||||
|
// Set UART Parameter
|
||||||
|
sdk_uart_div_modify(0, UART_CLK_FREQ / 115200);
|
||||||
|
|
||||||
|
// Give the UART some time to settle
|
||||||
|
sdk_os_delay_us(500);
|
||||||
|
}
|
||||||
|
|
||||||
|
void user_init(void)
|
||||||
|
{
|
||||||
|
// Setup HW
|
||||||
|
user_setup();
|
||||||
|
|
||||||
|
// Just some infomations
|
||||||
|
printf("\n");
|
||||||
|
printf("SDK version : %s\n", sdk_system_get_sdk_version());
|
||||||
|
printf("GIT version : %s\n", GITSHORTREV);
|
||||||
|
|
||||||
|
// Use our user inform implementation
|
||||||
|
bmp180_informUser = bmp180_i2c_informUser;
|
||||||
|
|
||||||
|
// Init BMP180 Interface
|
||||||
|
bmp180_init(SCL_PIN, SDA_PIN);
|
||||||
|
|
||||||
|
// Create Main Communication Queue
|
||||||
|
mainqueue = xQueueCreate(10, sizeof(my_event_t));
|
||||||
|
|
||||||
|
// Create user interface task
|
||||||
|
xTaskCreate(bmp180_task, (signed char *)"bmp180_task", 256, &mainqueue, 2, NULL);
|
||||||
|
|
||||||
|
// Create Timer (Trigger a measurement every second)
|
||||||
|
timerHandle = xTimerCreate((signed char *)"BMP180 Trigger", 1000/portTICK_RATE_MS, pdTRUE, NULL, bmp180_i2c_timer_cb);
|
||||||
|
|
||||||
|
if (timerHandle != NULL)
|
||||||
|
{
|
||||||
|
if (xTimerStart(timerHandle, 0) != pdPASS)
|
||||||
|
{
|
||||||
|
printf("%s: Unable to start Timer ...\n", __FUNCTION__);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("%s: Unable to create Timer ...\n", __FUNCTION__);
|
||||||
|
}
|
||||||
|
}
|
|
@ -34,7 +34,7 @@ void buttonPollTask(void *pvParameters)
|
||||||
{
|
{
|
||||||
taskYIELD();
|
taskYIELD();
|
||||||
}
|
}
|
||||||
printf("Polled for button press at %ldms\r\n", xTaskGetTickCount()*portTICK_RATE_MS);
|
printf("Polled for button press at %dms\r\n", xTaskGetTickCount()*portTICK_RATE_MS);
|
||||||
vTaskDelay(200 / portTICK_RATE_MS);
|
vTaskDelay(200 / portTICK_RATE_MS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ void buttonIntTask(void *pvParameters)
|
||||||
xQueueReceive(*tsqueue, &button_ts, portMAX_DELAY);
|
xQueueReceive(*tsqueue, &button_ts, portMAX_DELAY);
|
||||||
button_ts *= portTICK_RATE_MS;
|
button_ts *= portTICK_RATE_MS;
|
||||||
if(last < button_ts-200) {
|
if(last < button_ts-200) {
|
||||||
printf("Button interrupt fired at %ldms\r\n", button_ts);
|
printf("Button interrupt fired at %dms\r\n", button_ts);
|
||||||
last = button_ts;
|
last = button_ts;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
5
examples/cpp_01_tasks/Makefile
Normal file
5
examples/cpp_01_tasks/Makefile
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
# Simple makefile for simple example
|
||||||
|
PROGRAM=cpp_01_tasks
|
||||||
|
OTA=0
|
||||||
|
EXTRA_COMPONENTS=extras/cpp_support
|
||||||
|
include ../../common.mk
|
106
examples/cpp_01_tasks/cpp_tasks.cpp
Normal file
106
examples/cpp_01_tasks/cpp_tasks.cpp
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
/*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* ESP8266 FreeRTOS Firmware
|
||||||
|
* Copyright (c) 2015 Michael Jacobsen (github.com/mikejac)
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* https://github.com/SuperHouse/esp-open-rtos
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "task.hpp"
|
||||||
|
#include "queue.hpp"
|
||||||
|
|
||||||
|
#include "espressif/esp_common.h"
|
||||||
|
|
||||||
|
/******************************************************************************************************************
|
||||||
|
* task_1_t
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class task_1_t: public esp_open_rtos::thread::task_t
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
esp_open_rtos::thread::queue_t<uint32_t> queue;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void task()
|
||||||
|
{
|
||||||
|
printf("task_1_t::task(): start\n");
|
||||||
|
|
||||||
|
uint32_t count = 0;
|
||||||
|
|
||||||
|
while(true) {
|
||||||
|
sleep(1000);
|
||||||
|
queue.post(count);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
/******************************************************************************************************************
|
||||||
|
* task_2_t
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class task_2_t: public esp_open_rtos::thread::task_t
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
esp_open_rtos::thread::queue_t<uint32_t> queue;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void task()
|
||||||
|
{
|
||||||
|
printf("task_2_t::task(): start\n");
|
||||||
|
|
||||||
|
while(true) {
|
||||||
|
uint32_t count;
|
||||||
|
|
||||||
|
if(queue.receive(count, 1500) == 0) {
|
||||||
|
printf("task_2_t::task(): got %u\n", count);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("task_2_t::task(): no msg\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
/******************************************************************************************************************
|
||||||
|
* globals
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
task_1_t task_1;
|
||||||
|
task_2_t task_2;
|
||||||
|
|
||||||
|
esp_open_rtos::thread::queue_t<uint32_t> MyQueue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
extern "C" void user_init(void)
|
||||||
|
{
|
||||||
|
sdk_uart_div_modify(0, UART_CLK_FREQ / 115200);
|
||||||
|
|
||||||
|
MyQueue.queue_create(10);
|
||||||
|
|
||||||
|
task_1.queue = MyQueue;
|
||||||
|
task_2.queue = MyQueue;
|
||||||
|
|
||||||
|
task_1.task_create("tsk1");
|
||||||
|
task_2.task_create("tsk2");
|
||||||
|
}
|
|
@ -20,8 +20,8 @@ IRAM void dump_frc1_seq(void)
|
||||||
uint32_t f1_a = TIMER(0).COUNT;
|
uint32_t f1_a = TIMER(0).COUNT;
|
||||||
uint32_t f1_b = TIMER(0).COUNT;
|
uint32_t f1_b = TIMER(0).COUNT;
|
||||||
uint32_t f1_c = TIMER(0).COUNT;
|
uint32_t f1_c = TIMER(0).COUNT;
|
||||||
printf("FRC1 sequence 0x%08lx 0x%08lx 0x%08lx\r\n", f1_a, f1_b, f1_c);
|
printf("FRC1 sequence 0x%08x 0x%08x 0x%08x\r\n", f1_a, f1_b, f1_c);
|
||||||
printf("FRC1 deltas %ld %ld \r\n", f1_b-f1_a, f1_c-f1_b);
|
printf("FRC1 deltas %d %d \r\n", f1_b-f1_a, f1_c-f1_b);
|
||||||
}
|
}
|
||||||
|
|
||||||
IRAM void dump_frc2_seq(void)
|
IRAM void dump_frc2_seq(void)
|
||||||
|
@ -37,8 +37,8 @@ IRAM void dump_frc2_seq(void)
|
||||||
uint32_t f2_a = TIMER(1).COUNT;
|
uint32_t f2_a = TIMER(1).COUNT;
|
||||||
uint32_t f2_b = TIMER(1).COUNT;
|
uint32_t f2_b = TIMER(1).COUNT;
|
||||||
uint32_t f2_c = TIMER(1).COUNT;
|
uint32_t f2_c = TIMER(1).COUNT;
|
||||||
printf("FRC2 sequence 0x%08lx 0x%08lx 0x%08lx\r\n", f2_a, f2_b, f2_c);
|
printf("FRC2 sequence 0x%08x 0x%08x 0x%08x\r\n", f2_a, f2_b, f2_c);
|
||||||
printf("FRC2 deltas %ld %ld \r\n", f2_b-f2_a, f2_c-f2_b);
|
printf("FRC2 deltas %d %d \r\n", f2_b-f2_a, f2_c-f2_b);
|
||||||
}
|
}
|
||||||
|
|
||||||
IRAM void dump_timer_regs(const char *msg)
|
IRAM void dump_timer_regs(const char *msg)
|
||||||
|
@ -56,7 +56,7 @@ IRAM void dump_timer_regs(const char *msg)
|
||||||
for(int i = 0; i < DUMP_SZ; i++) {
|
for(int i = 0; i < DUMP_SZ; i++) {
|
||||||
if(i % 4 == 0)
|
if(i % 4 == 0)
|
||||||
printf("%s0x%02x: ", i ? "\r\n" : "", i*4);
|
printf("%s0x%02x: ", i ? "\r\n" : "", i*4);
|
||||||
printf("%08lx ", chunk[i]);
|
printf("%08x ", chunk[i]);
|
||||||
}
|
}
|
||||||
printf("\r\n");
|
printf("\r\n");
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ static volatile uint32_t frc1_last_count_val;
|
||||||
void timerRegTask(void *pvParameters)
|
void timerRegTask(void *pvParameters)
|
||||||
{
|
{
|
||||||
while(1) {
|
while(1) {
|
||||||
printf("state at task tick count %ld:\r\n", xTaskGetTickCount());
|
printf("state at task tick count %d:\r\n", xTaskGetTickCount());
|
||||||
dump_timer_regs("");
|
dump_timer_regs("");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -87,10 +87,10 @@ void timerRegTask(void *pvParameters)
|
||||||
printf("INUM_MAX count %d\r\n", max_count);
|
printf("INUM_MAX count %d\r\n", max_count);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
printf("frc1 handler called %ld times, last value 0x%08lx\r\n", frc1_handler_call_count,
|
printf("frc1 handler called %d times, last value 0x%08x\r\n", frc1_handler_call_count,
|
||||||
frc1_last_count_val);
|
frc1_last_count_val);
|
||||||
|
|
||||||
printf("frc2 handler called %ld times, last value 0x%08lx\r\n", frc2_handler_call_count,
|
printf("frc2 handler called %d times, last value 0x%08x\r\n", frc2_handler_call_count,
|
||||||
frc2_last_count_val);
|
frc2_last_count_val);
|
||||||
|
|
||||||
vTaskDelay(500 / portTICK_RATE_MS);
|
vTaskDelay(500 / portTICK_RATE_MS);
|
||||||
|
|
|
@ -26,7 +26,7 @@ void user_init(void)
|
||||||
|
|
||||||
printf("Image addresses in flash:\r\n");
|
printf("Image addresses in flash:\r\n");
|
||||||
for(int i = 0; i <conf.count; i++) {
|
for(int i = 0; i <conf.count; i++) {
|
||||||
printf("%c%d: offset 0x%08lx\r\n", i == conf.current_rom ? '*':' ', i, conf.roms[i]);
|
printf("%c%d: offset 0x%08x\r\n", i == conf.current_rom ? '*':' ', i, conf.roms[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sdk_station_config config = {
|
struct sdk_station_config config = {
|
||||||
|
|
|
@ -25,7 +25,7 @@ void task2(void *pvParameters)
|
||||||
while(1) {
|
while(1) {
|
||||||
uint32_t count;
|
uint32_t count;
|
||||||
if(xQueueReceive(*queue, &count, 1000)) {
|
if(xQueueReceive(*queue, &count, 1000)) {
|
||||||
printf("Got %lu\n", count);
|
printf("Got %u\n", count);
|
||||||
} else {
|
} else {
|
||||||
printf("No msg :(\n");
|
printf("No msg :(\n");
|
||||||
}
|
}
|
||||||
|
|
3
examples/simple_cplusplus/Makefile
Normal file
3
examples/simple_cplusplus/Makefile
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# Simple makefile for simple example
|
||||||
|
PROGRAM=simple
|
||||||
|
include ../../common.mk
|
64
examples/simple_cplusplus/simple.cpp
Normal file
64
examples/simple_cplusplus/simple.cpp
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
/* A very basic C++ example, really just proof of concept for C++
|
||||||
|
|
||||||
|
This sample code is in the public domain.
|
||||||
|
*/
|
||||||
|
#include "espressif/esp_common.h"
|
||||||
|
#include "espressif/sdk_private.h"
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "queue.h"
|
||||||
|
|
||||||
|
class Counter
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
uint32_t _count;
|
||||||
|
public:
|
||||||
|
Counter(uint32_t initial_count)
|
||||||
|
{
|
||||||
|
this->_count = initial_count;
|
||||||
|
printf("Counter initialised with count %d\r\n", initial_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Increment()
|
||||||
|
{
|
||||||
|
_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t getCount()
|
||||||
|
{
|
||||||
|
return _count;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static Counter static_counter(99);
|
||||||
|
|
||||||
|
void task1(void *pvParameters)
|
||||||
|
{
|
||||||
|
Counter local_counter = Counter(12);
|
||||||
|
Counter *new_counter = new Counter(24);
|
||||||
|
while(1) {
|
||||||
|
Counter *counter = NULL;
|
||||||
|
switch(rand() % 3) {
|
||||||
|
case 0:
|
||||||
|
counter = &local_counter;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
counter = &static_counter;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
counter = new_counter;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
counter->Increment();
|
||||||
|
printf("local counter %d static counter %d newly allocated counter %d\r\n", local_counter.getCount(),
|
||||||
|
static_counter.getCount(), new_counter->getCount());
|
||||||
|
vTaskDelay(100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void user_init(void)
|
||||||
|
{
|
||||||
|
sdk_uart_div_modify(0, UART_CLK_FREQ / 115200);
|
||||||
|
printf("SDK version:%s\n", sdk_system_get_sdk_version());
|
||||||
|
xTaskCreate(task1, (signed char *)"tsk1", 256, NULL, 2, NULL);
|
||||||
|
}
|
22
extras/bmp180/LICENSE
Normal file
22
extras/bmp180/LICENSE
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2015 Frank Bargstedt
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
56
extras/bmp180/README.md
Normal file
56
extras/bmp180/README.md
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
# Driver for BMP085/BMP180 digital pressure sensor
|
||||||
|
|
||||||
|
This driver is written for usage with the ESP8266 and FreeRTOS ([esp-open-rtos](https://github.com/SuperHouse/esp-open-rtos) and [esp-open-rtos-driver-i2c](https://github.com/kanflo/esp-open-rtos-driver-i2c)).
|
||||||
|
|
||||||
|
### Usage
|
||||||
|
|
||||||
|
Before using the BMP180 module, the function `bmp180_init(SCL_PIN, SDA_PIN)` needs to be called to setup the I2C interface and do validation if the BMP180/BMP085 is accessible.
|
||||||
|
|
||||||
|
If the setup is sucessfully and a measurement is triggered, the result of the measurement is provided to the user as an event send via the `qQueue` provided with `bmp180_trigger_*measurement(pQueue);`
|
||||||
|
|
||||||
|
#### Example
|
||||||
|
|
||||||
|
```
|
||||||
|
#define SCL_PIN GPIO_ID_PIN(0)
|
||||||
|
#define SDA_PIN GPIO_ID_PIN(2)
|
||||||
|
...
|
||||||
|
|
||||||
|
if (!bmp180_init(SCL_PIN, SDA_PIN)) {
|
||||||
|
// An error occured, while dong the init (E.g device not found etc.)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trigger a measurement
|
||||||
|
bmp180_trigger_measurement(pQueue);
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Change queue event
|
||||||
|
|
||||||
|
Per default the event send to the user via the provided queue is of the type `bmp180_result_t`. As this might not always be desired, a way is provided so that the user can provide a function, which creates and sends the event via the provided queue.
|
||||||
|
|
||||||
|
As all data aqquired from the BMP180/BMP085 is provided to the `bmp180_informUser` function, it is also possible to calculate new informations (E.g altitude etc.)
|
||||||
|
|
||||||
|
##### Example
|
||||||
|
|
||||||
|
```
|
||||||
|
// Own BMP180 User Inform Implementation
|
||||||
|
bool my_informUser(const xQueueHandle* resultQueue, uint8_t cmd, bmp180_temp_t temperatue, bmp180_press_t pressure) {
|
||||||
|
my_event_t ev;
|
||||||
|
|
||||||
|
ev.event_type = MY_EVT_BMP180;
|
||||||
|
ev.bmp180_data.cmd = cmd;
|
||||||
|
ev.bmp180_data.temperatue = temperatue;
|
||||||
|
ev.bmp180_data.pressure = pressure;
|
||||||
|
|
||||||
|
return (xQueueSend(*resultQueue, &ev, 0) == pdTRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
// Use our user inform implementation
|
||||||
|
// needs to be set before first measurement is triggered
|
||||||
|
bmp180_informUser = my_informUser;
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
|
351
extras/bmp180/bmp180.c
Normal file
351
extras/bmp180/bmp180.c
Normal file
|
@ -0,0 +1,351 @@
|
||||||
|
#include "bmp180.h"
|
||||||
|
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "queue.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
#include "espressif/esp_common.h"
|
||||||
|
#include "espressif/sdk_private.h"
|
||||||
|
|
||||||
|
#include "i2c/i2c.h"
|
||||||
|
|
||||||
|
#define BMP180_RX_QUEUE_SIZE 10
|
||||||
|
#define BMP180_TASK_PRIORITY 9
|
||||||
|
|
||||||
|
#define BMP180_DEVICE_ADDRESS 0x77
|
||||||
|
|
||||||
|
#define BMP180_VERSION_REG 0xD0
|
||||||
|
#define BMP180_CONTROL_REG 0xF4
|
||||||
|
#define BMP180_RESET_REG 0xE0
|
||||||
|
#define BMP180_OUT_MSB_REG 0xF6
|
||||||
|
#define BMP180_OUT_LSB_REG 0xF7
|
||||||
|
#define BMP180_OUT_XLSB_REG 0xF8
|
||||||
|
|
||||||
|
#define BMP180_CALIBRATION_REG 0xAA
|
||||||
|
|
||||||
|
//
|
||||||
|
// Values for BMP180_CONTROL_REG
|
||||||
|
//
|
||||||
|
#define BMP180_MEASURE_TEMP 0x2E
|
||||||
|
#define BMP180_MEASURE_PRESS_OSS0 0x34
|
||||||
|
#define BMP180_MEASURE_PRESS_OSS1 0x74
|
||||||
|
#define BMP180_MEASURE_PRESS_OSS2 0xB4
|
||||||
|
#define BMP180_MEASURE_PRESS_OSS3 0xF4
|
||||||
|
|
||||||
|
#define BMP180_DEFAULT_CONV_TIME 5000
|
||||||
|
|
||||||
|
//
|
||||||
|
// CHIP ID stored in BMP180_VERSION_REG
|
||||||
|
//
|
||||||
|
#define BMP180_CHIP_ID 0x55
|
||||||
|
|
||||||
|
//
|
||||||
|
// Reset value for BMP180_RESET_REG
|
||||||
|
//
|
||||||
|
#define BMP180_RESET_VALUE 0xB6
|
||||||
|
|
||||||
|
|
||||||
|
// BMP180_Event_Command
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint8_t cmd;
|
||||||
|
const xQueueHandle* resultQueue;
|
||||||
|
} bmp180_command_t;
|
||||||
|
|
||||||
|
// Just works due to the fact that xQueueHandle is a "void *"
|
||||||
|
static xQueueHandle bmp180_rx_queue = NULL;
|
||||||
|
static xTaskHandle bmp180_task_handle = NULL;
|
||||||
|
|
||||||
|
// Calibration constants
|
||||||
|
static int16_t AC1;
|
||||||
|
static int16_t AC2;
|
||||||
|
static int16_t AC3;
|
||||||
|
static uint16_t AC4;
|
||||||
|
static uint16_t AC5;
|
||||||
|
static uint16_t AC6;
|
||||||
|
|
||||||
|
static int16_t B1;
|
||||||
|
static int16_t B2;
|
||||||
|
|
||||||
|
static int16_t MB;
|
||||||
|
static int16_t MC;
|
||||||
|
static int16_t MD;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Forward declarations
|
||||||
|
//
|
||||||
|
static void bmp180_meassure(const bmp180_command_t* command);
|
||||||
|
static bool bmp180_informUser_Impl(const xQueueHandle* resultQueue, uint8_t cmd, bmp180_temp_t temperature, bmp180_press_t pressure);
|
||||||
|
|
||||||
|
// Set default implementation .. User gets result as bmp180_result_t event
|
||||||
|
bool (*bmp180_informUser)(const xQueueHandle* resultQueue, uint8_t cmd, bmp180_temp_t temperature, bmp180_press_t pressure) = bmp180_informUser_Impl;
|
||||||
|
|
||||||
|
// I2C Driver Task
|
||||||
|
static void bmp180_driver_task(void *pvParameters)
|
||||||
|
{
|
||||||
|
// Data to be received from user
|
||||||
|
bmp180_command_t current_command;
|
||||||
|
|
||||||
|
#ifdef BMP180_DEBUG
|
||||||
|
// Wait for commands from the outside
|
||||||
|
printf("%s: Started Task\n", __FUNCTION__);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
// Wait for user to insert commands
|
||||||
|
if (xQueueReceive(bmp180_rx_queue, ¤t_command, portMAX_DELAY) == pdTRUE)
|
||||||
|
{
|
||||||
|
#ifdef BMP180_DEBUG
|
||||||
|
printf("%s: Received user command %d 0x%p\n", __FUNCTION__, current_command.cmd, current_command.resultQueue);
|
||||||
|
#endif
|
||||||
|
// use user provided queue
|
||||||
|
if (current_command.resultQueue != NULL)
|
||||||
|
{
|
||||||
|
// Work on it ...
|
||||||
|
bmp180_meassure(¤t_command);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t bmp180_readRegister8(uint8_t reg)
|
||||||
|
{
|
||||||
|
uint8_t r = 0;
|
||||||
|
|
||||||
|
if (!i2c_slave_read(BMP180_DEVICE_ADDRESS, reg, &r, 1))
|
||||||
|
{
|
||||||
|
r = 0;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int16_t bmp180_readRegister16(uint8_t reg)
|
||||||
|
{
|
||||||
|
uint8_t d[] = { 0, 0 };
|
||||||
|
int16_t r = 0;
|
||||||
|
|
||||||
|
if (i2c_slave_read(BMP180_DEVICE_ADDRESS, reg, d, 2))
|
||||||
|
{
|
||||||
|
r = ((int16_t)d[0]<<8) | (d[1]);
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bmp180_start_Messurement(uint8_t cmd)
|
||||||
|
{
|
||||||
|
uint8_t d[] = { BMP180_CONTROL_REG, cmd };
|
||||||
|
|
||||||
|
i2c_slave_write(BMP180_DEVICE_ADDRESS, d, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int16_t bmp180_getUncompensatedMessurement(uint8_t cmd)
|
||||||
|
{
|
||||||
|
// Write Start Code into reg 0xF4 (Currently without oversampling ...)
|
||||||
|
bmp180_start_Messurement((cmd==BMP180_TEMPERATURE)?BMP180_MEASURE_TEMP:BMP180_MEASURE_PRESS_OSS0);
|
||||||
|
|
||||||
|
// Wait 5ms Datasheet states 4.5ms
|
||||||
|
sdk_os_delay_us(BMP180_DEFAULT_CONV_TIME);
|
||||||
|
|
||||||
|
return (int16_t)bmp180_readRegister16(BMP180_OUT_MSB_REG);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bmp180_fillInternalConstants(void)
|
||||||
|
{
|
||||||
|
AC1 = bmp180_readRegister16(BMP180_CALIBRATION_REG+0);
|
||||||
|
AC2 = bmp180_readRegister16(BMP180_CALIBRATION_REG+2);
|
||||||
|
AC3 = bmp180_readRegister16(BMP180_CALIBRATION_REG+4);
|
||||||
|
AC4 = bmp180_readRegister16(BMP180_CALIBRATION_REG+6);
|
||||||
|
AC5 = bmp180_readRegister16(BMP180_CALIBRATION_REG+8);
|
||||||
|
AC6 = bmp180_readRegister16(BMP180_CALIBRATION_REG+10);
|
||||||
|
|
||||||
|
B1 = bmp180_readRegister16(BMP180_CALIBRATION_REG+12);
|
||||||
|
B2 = bmp180_readRegister16(BMP180_CALIBRATION_REG+14);
|
||||||
|
|
||||||
|
MB = bmp180_readRegister16(BMP180_CALIBRATION_REG+16);
|
||||||
|
MC = bmp180_readRegister16(BMP180_CALIBRATION_REG+18);
|
||||||
|
MD = bmp180_readRegister16(BMP180_CALIBRATION_REG+20);
|
||||||
|
|
||||||
|
#ifdef BMP180_DEBUG
|
||||||
|
printf("%s: AC1:=%d AC2:=%d AC3:=%d AC4:=%u AC5:=%u AC6:=%u \n", __FUNCTION__, AC1, AC2, AC3, AC4, AC5, AC6);
|
||||||
|
printf("%s: B1:=%d B2:=%d\n", __FUNCTION__, B1, B2);
|
||||||
|
printf("%s: MB:=%d MC:=%d MD:=%d\n", __FUNCTION__, MB, MC, MD);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool bmp180_create_communication_queues()
|
||||||
|
{
|
||||||
|
// Just create them once
|
||||||
|
if (bmp180_rx_queue==NULL)
|
||||||
|
{
|
||||||
|
bmp180_rx_queue = xQueueCreate(BMP180_RX_QUEUE_SIZE, sizeof(bmp180_result_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
return (bmp180_rx_queue!=NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool bmp180_is_avaialble()
|
||||||
|
{
|
||||||
|
return (bmp180_readRegister8(BMP180_VERSION_REG)==BMP180_CHIP_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool bmp180_createTask()
|
||||||
|
{
|
||||||
|
// We already have a task
|
||||||
|
portBASE_TYPE x = pdPASS;
|
||||||
|
|
||||||
|
if (bmp180_task_handle==NULL)
|
||||||
|
{
|
||||||
|
x = xTaskCreate(bmp180_driver_task, (signed char *)"bmp180_driver_task", 256, NULL, BMP180_TASK_PRIORITY, &bmp180_task_handle);
|
||||||
|
}
|
||||||
|
return (x==pdPASS);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bmp180_meassure(const bmp180_command_t* command)
|
||||||
|
{
|
||||||
|
int32_t T, P;
|
||||||
|
|
||||||
|
// Init result to 0
|
||||||
|
T = P = 0;
|
||||||
|
|
||||||
|
if (command->resultQueue != NULL)
|
||||||
|
{
|
||||||
|
int32_t UT, X1, X2, B5;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Temperature is always needed ... Also required for pressure only
|
||||||
|
//
|
||||||
|
// Calculation taken from BMP180 Datasheet
|
||||||
|
UT = (int32_t)bmp180_getUncompensatedMessurement(BMP180_TEMPERATURE);
|
||||||
|
|
||||||
|
X1 = (UT - (int32_t)AC6) * ((int32_t)AC5) >> 15;
|
||||||
|
X2 = ((int32_t)MC << 11) / (X1 + (int32_t)MD);
|
||||||
|
B5 = X1 + X2;
|
||||||
|
|
||||||
|
T = (B5 + 8) >> 4;
|
||||||
|
|
||||||
|
#ifdef BMP180_DEBUG
|
||||||
|
printf("%s: T:= %ld.%d\n", __FUNCTION__, T/10, abs(T%10));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Do we also need pressure?
|
||||||
|
if (command->cmd & BMP180_PRESSURE)
|
||||||
|
{
|
||||||
|
int32_t X3, B3, B6;
|
||||||
|
uint32_t B4, B7, UP;
|
||||||
|
|
||||||
|
UP = ((uint32_t)bmp180_getUncompensatedMessurement(BMP180_PRESSURE) & 0xFFFF);
|
||||||
|
|
||||||
|
// Calculation taken from BMP180 Datasheet
|
||||||
|
B6 = B5 - 4000;
|
||||||
|
X1 = ((int32_t)B2 * ((B6 * B6) >> 12)) >> 11;
|
||||||
|
X2 = ((int32_t)AC2 * B6) >> 11;
|
||||||
|
X3 = X1 + X2;
|
||||||
|
|
||||||
|
B3 = (((int32_t)AC1 * 4 + X3) + 2) >> 2;
|
||||||
|
X1 = ((int32_t)AC3 * B6) >> 13;
|
||||||
|
X2 = ((int32_t)B1 * ((B6 * B6) >> 12)) >> 16;
|
||||||
|
X3 = ((X1 + X2) + 2) >> 2;
|
||||||
|
B4 = ((uint32_t)AC4 * (uint32_t)(X3 + 32768)) >> 15;
|
||||||
|
B7 = (UP - B3) * (uint32_t)(50000UL);
|
||||||
|
|
||||||
|
if (B7 < 0x80000000)
|
||||||
|
{
|
||||||
|
P = (B7 * 2) / B4;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
P = (B7 / B4) * 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
X1 = (P >> 8) * (P >> 8);
|
||||||
|
X1 = (X1 * 3038) >> 16;
|
||||||
|
X2 = (-7357 * P) >> 16;
|
||||||
|
P = P + ((X1 + X2 + (int32_t)3791) >> 4);
|
||||||
|
|
||||||
|
#ifdef BMP180_DEBUG
|
||||||
|
printf("%s: P:= %ld\n", __FUNCTION__, P);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inform the user ...
|
||||||
|
if (!bmp180_informUser(command->resultQueue, command->cmd, ((bmp180_temp_t)T)/10.0, (bmp180_press_t)P))
|
||||||
|
{
|
||||||
|
// Failed to send info to user
|
||||||
|
printf("%s: Unable to inform user bmp180_informUser returned \"false\"\n", __FUNCTION__);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default user inform implementation
|
||||||
|
static bool bmp180_informUser_Impl(const xQueueHandle* resultQueue, uint8_t cmd, bmp180_temp_t temperature, bmp180_press_t pressure)
|
||||||
|
{
|
||||||
|
bmp180_result_t result;
|
||||||
|
|
||||||
|
result.cmd = cmd;
|
||||||
|
result.temperature = temperature;
|
||||||
|
result.pressure = pressure;
|
||||||
|
|
||||||
|
return (xQueueSend(*resultQueue, &result, 0) == pdTRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Just init all needed queues
|
||||||
|
bool bmp180_init(uint8_t scl, uint8_t sda)
|
||||||
|
{
|
||||||
|
// 1. Create required queues
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
if (bmp180_create_communication_queues())
|
||||||
|
{
|
||||||
|
// 2. Init i2c driver
|
||||||
|
i2c_init(scl, sda);
|
||||||
|
|
||||||
|
// 3. Check for bmp180 ...
|
||||||
|
if (bmp180_is_avaialble())
|
||||||
|
{
|
||||||
|
// 4. Init all internal constants ...
|
||||||
|
bmp180_fillInternalConstants();
|
||||||
|
|
||||||
|
// 5. Start driver task
|
||||||
|
if (bmp180_createTask())
|
||||||
|
{
|
||||||
|
// We are finished
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void bmp180_trigger_measurement(const xQueueHandle* resultQueue)
|
||||||
|
{
|
||||||
|
bmp180_command_t c;
|
||||||
|
|
||||||
|
c.cmd = BMP180_PRESSURE + BMP180_TEMPERATURE;
|
||||||
|
c.resultQueue = resultQueue;
|
||||||
|
|
||||||
|
xQueueSend(bmp180_rx_queue, &c, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void bmp180_trigger_pressure_measurement(const xQueueHandle* resultQueue)
|
||||||
|
{
|
||||||
|
bmp180_command_t c;
|
||||||
|
|
||||||
|
c.cmd = BMP180_PRESSURE;
|
||||||
|
c.resultQueue = resultQueue;
|
||||||
|
|
||||||
|
xQueueSend(bmp180_rx_queue, &c, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void bmp180_trigger_temperature_measurement(const xQueueHandle* resultQueue)
|
||||||
|
{
|
||||||
|
bmp180_command_t c;
|
||||||
|
|
||||||
|
c.cmd = BMP180_TEMPERATURE;
|
||||||
|
c.resultQueue = resultQueue;
|
||||||
|
|
||||||
|
xQueueSend(bmp180_rx_queue, &c, 0);
|
||||||
|
}
|
55
extras/bmp180/bmp180.h
Normal file
55
extras/bmp180/bmp180.h
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* bmp180.h
|
||||||
|
*
|
||||||
|
* Created on: 23.08.2015
|
||||||
|
* Author: fbargste
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DRIVER_BMP180_H_
|
||||||
|
#define DRIVER_BMP180_H_
|
||||||
|
|
||||||
|
#include "stdint.h"
|
||||||
|
#include "stdbool.h"
|
||||||
|
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "queue.h"
|
||||||
|
|
||||||
|
// Uncomment to enable debug output
|
||||||
|
//#define BMP180_DEBUG
|
||||||
|
|
||||||
|
#define BMP180_TEMPERATURE (1<<0)
|
||||||
|
#define BMP180_PRESSURE (1<<1)
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create bmp180_types
|
||||||
|
//
|
||||||
|
|
||||||
|
// temperature in °C
|
||||||
|
typedef float bmp180_temp_t;
|
||||||
|
// pressure in mPa (To get hPa divide by 100)
|
||||||
|
typedef uint32_t bmp180_press_t;
|
||||||
|
|
||||||
|
// BMP180_Event_Result
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint8_t cmd;
|
||||||
|
bmp180_temp_t temperature;
|
||||||
|
bmp180_press_t pressure;
|
||||||
|
} bmp180_result_t;
|
||||||
|
|
||||||
|
// Init bmp180 driver ...
|
||||||
|
bool bmp180_init(uint8_t scl, uint8_t sda);
|
||||||
|
|
||||||
|
// Trigger a "complete" measurement (temperature and pressure will be valid when given to "bmp180_informUser)
|
||||||
|
void bmp180_trigger_measurement(const xQueueHandle* resultQueue);
|
||||||
|
|
||||||
|
// Trigger a "temperature only" measurement (only temperature will be valid when given to "bmp180_informUser)
|
||||||
|
void bmp180_trigger_temperature_measurement(const xQueueHandle* resultQueue);
|
||||||
|
|
||||||
|
// Trigger a "pressure only" measurement (only pressure will be valid when given to "bmp180_informUser)
|
||||||
|
void bmp180_trigger_pressure_measurement(const xQueueHandle* resultQueue);
|
||||||
|
|
||||||
|
// Give the user the chance to create it's own handler
|
||||||
|
extern bool (*bmp180_informUser)(const xQueueHandle* resultQueue, uint8_t cmd, bmp180_temp_t temperature, bmp180_press_t pressure);
|
||||||
|
|
||||||
|
#endif /* DRIVER_BMP180_H_ */
|
9
extras/bmp180/component.mk
Normal file
9
extras/bmp180/component.mk
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
# Component makefile for extras/bmp180
|
||||||
|
|
||||||
|
# expected anyone using bmp driver includes it as 'bmp180/bmp180.h'
|
||||||
|
INC_DIRS += $(bmp180_ROOT)..
|
||||||
|
|
||||||
|
# args for passing into compile rule generation
|
||||||
|
bmp180_SRC_DIR = $(bmp180_ROOT)
|
||||||
|
|
||||||
|
$(eval $(call component_compile_rules,bmp180))
|
8
extras/cpp_support/component.mk
Normal file
8
extras/cpp_support/component.mk
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
# Component makefile for extras/cpp_support
|
||||||
|
INC_DIRS += $(ROOT)extras/cpp_support/include
|
||||||
|
|
||||||
|
# args for passing into compile rule generation
|
||||||
|
# extras/mqtt-client_INC_DIR = $(ROOT)extras/mqtt-client
|
||||||
|
# extras/mqtt-client_SRC_DIR = $(ROOT)extras/mqtt-client
|
||||||
|
|
||||||
|
# $(eval $(call component_compile_rules,extras/mqtt-client))
|
102
extras/cpp_support/include/countdown.hpp
Normal file
102
extras/cpp_support/include/countdown.hpp
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
/*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* ESP8266 FreeRTOS Firmware
|
||||||
|
* Copyright (c) 2015 Michael Jacobsen (github.com/mikejac)
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* https://github.com/SuperHouse/esp-open-rtos
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ESP_OPEN_RTOS_TIMER_HPP
|
||||||
|
#define ESP_OPEN_RTOS_TIMER_HPP
|
||||||
|
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
namespace esp_open_rtos {
|
||||||
|
namespace timer {
|
||||||
|
|
||||||
|
#define __millis() (xTaskGetTickCount() * portTICK_RATE_MS)
|
||||||
|
|
||||||
|
/******************************************************************************************************************
|
||||||
|
* countdown_t
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class countdown_t
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
countdown_t()
|
||||||
|
{
|
||||||
|
interval_end_ms = 0L;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param ms
|
||||||
|
*/
|
||||||
|
countdown_t(int ms)
|
||||||
|
{
|
||||||
|
countdown_ms(ms);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
bool expired()
|
||||||
|
{
|
||||||
|
return (interval_end_ms > 0L) && (__millis() >= interval_end_ms);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param ms
|
||||||
|
*/
|
||||||
|
void countdown_ms(unsigned long ms)
|
||||||
|
{
|
||||||
|
interval_end_ms = __millis() + ms;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param seconds
|
||||||
|
*/
|
||||||
|
void countdown(int seconds)
|
||||||
|
{
|
||||||
|
countdown_ms((unsigned long)seconds * 1000L);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
int left_ms()
|
||||||
|
{
|
||||||
|
return interval_end_ms - __millis();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
portTickType interval_end_ms;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace timer {
|
||||||
|
} // namespace esp_open_rtos {
|
||||||
|
|
||||||
|
#endif
|
113
extras/cpp_support/include/mutex.hpp
Normal file
113
extras/cpp_support/include/mutex.hpp
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
/*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* ESP8266 FreeRTOS Firmware
|
||||||
|
* Copyright (c) 2015 Michael Jacobsen (github.com/mikejac)
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* https://github.com/SuperHouse/esp-open-rtos
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ESP_OPEN_RTOS_MUTEX_HPP
|
||||||
|
#define ESP_OPEN_RTOS_MUTEX_HPP
|
||||||
|
|
||||||
|
#include "semphr.h"
|
||||||
|
|
||||||
|
namespace esp_open_rtos {
|
||||||
|
namespace thread {
|
||||||
|
|
||||||
|
/******************************************************************************************************************
|
||||||
|
* class mutex_t
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class mutex_t
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
inline mutex_t()
|
||||||
|
{
|
||||||
|
mutex = 0;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
inline int mutex_create()
|
||||||
|
{
|
||||||
|
mutex = xSemaphoreCreateMutex();
|
||||||
|
|
||||||
|
if(mutex == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
inline void mutex_destroy()
|
||||||
|
{
|
||||||
|
vQueueDelete(mutex);
|
||||||
|
mutex = 0;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
inline int lock()
|
||||||
|
{
|
||||||
|
return (xSemaphoreTake(mutex, portMAX_DELAY) == pdTRUE) ? 0 : -1;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param ms
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
inline int try_lock(unsigned long ms)
|
||||||
|
{
|
||||||
|
return (xSemaphoreTake(mutex, ms / portTICK_RATE_MS) == pdTRUE) ? 0 : -1;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
inline int unlock()
|
||||||
|
{
|
||||||
|
return (xSemaphoreGive(mutex) == pdTRUE) ? 0 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
xSemaphoreHandle mutex;
|
||||||
|
|
||||||
|
// Disable copy construction and assignment.
|
||||||
|
mutex_t (const mutex_t&);
|
||||||
|
const mutex_t &operator = (const mutex_t&);
|
||||||
|
};
|
||||||
|
|
||||||
|
} //namespace thread {
|
||||||
|
} //namespace esp_open_rtos {
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* ESP_OPEN_RTOS_MUTEX_HPP */
|
||||||
|
|
124
extras/cpp_support/include/queue.hpp
Normal file
124
extras/cpp_support/include/queue.hpp
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
/*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* ESP8266 FreeRTOS Firmware
|
||||||
|
* Copyright (c) 2015 Michael Jacobsen (github.com/mikejac)
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* https://github.com/SuperHouse/esp-open-rtos
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ESP_OPEN_RTOS_QUEUE_HPP
|
||||||
|
#define ESP_OPEN_RTOS_QUEUE_HPP
|
||||||
|
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "queue.h"
|
||||||
|
|
||||||
|
namespace esp_open_rtos {
|
||||||
|
namespace thread {
|
||||||
|
|
||||||
|
/******************************************************************************************************************
|
||||||
|
* class queue_t
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
template<class Data>
|
||||||
|
class queue_t
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
inline queue_t()
|
||||||
|
{
|
||||||
|
queue = 0;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param uxQueueLength
|
||||||
|
* @param uxItemSize
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
inline int queue_create(unsigned portBASE_TYPE uxQueueLength)
|
||||||
|
{
|
||||||
|
queue = xQueueCreate(uxQueueLength, sizeof(Data));
|
||||||
|
|
||||||
|
if(queue == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
inline void queue_destroy()
|
||||||
|
{
|
||||||
|
vQueueDelete(queue);
|
||||||
|
queue = 0;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param data
|
||||||
|
* @param ms
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
inline int post(const Data& data, unsigned long ms = 0)
|
||||||
|
{
|
||||||
|
return (xQueueSend(queue, &data, ms / portTICK_RATE_MS) == pdTRUE) ? 0 : -1;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param data
|
||||||
|
* @param ms
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
inline int receive(Data& data, unsigned long ms = 0)
|
||||||
|
{
|
||||||
|
return (xQueueReceive(queue, &data, ms / portTICK_RATE_MS) == pdTRUE) ? 0 : -1;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param other
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
const queue_t &operator = (const queue_t& other)
|
||||||
|
{
|
||||||
|
if(this != &other) { // protect against invalid self-assignment
|
||||||
|
queue = other.queue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
xQueueHandle queue;
|
||||||
|
|
||||||
|
// Disable copy construction.
|
||||||
|
queue_t (const queue_t&);
|
||||||
|
};
|
||||||
|
|
||||||
|
} //namespace thread {
|
||||||
|
} //namespace esp_open_rtos {
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* ESP_OPEN_RTOS_QUEUE_HPP */
|
||||||
|
|
106
extras/cpp_support/include/task.hpp
Normal file
106
extras/cpp_support/include/task.hpp
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
/*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* ESP8266 FreeRTOS Firmware
|
||||||
|
* Copyright (c) 2015 Michael Jacobsen (github.com/mikejac)
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* https://github.com/SuperHouse/esp-open-rtos
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ESP_OPEN_RTOS_TASK_HPP
|
||||||
|
#define ESP_OPEN_RTOS_TASK_HPP
|
||||||
|
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
namespace esp_open_rtos {
|
||||||
|
namespace thread {
|
||||||
|
|
||||||
|
/******************************************************************************************************************
|
||||||
|
* task_t
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class task_t
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
task_t()
|
||||||
|
{}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param pcName
|
||||||
|
* @param usStackDepth
|
||||||
|
* @param uxPriority
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
int task_create(const char* const pcName, unsigned short usStackDepth = 256, unsigned portBASE_TYPE uxPriority = 2)
|
||||||
|
{
|
||||||
|
return xTaskCreate(task_t::_task, (signed char *)pcName, usStackDepth, this, uxPriority, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param ms
|
||||||
|
*/
|
||||||
|
void sleep(unsigned long ms)
|
||||||
|
{
|
||||||
|
vTaskDelay(ms / portTICK_RATE_MS);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
inline unsigned long millis()
|
||||||
|
{
|
||||||
|
return xTaskGetTickCount() * portTICK_RATE_MS;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
virtual void task() = 0;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param pvParameters
|
||||||
|
*/
|
||||||
|
static void _task(void* pvParameters)
|
||||||
|
{
|
||||||
|
if(pvParameters != 0) {
|
||||||
|
((task_t*)(pvParameters))->task();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// no copy and no = operator
|
||||||
|
task_t(const task_t&);
|
||||||
|
task_t &operator=(const task_t&);
|
||||||
|
};
|
||||||
|
|
||||||
|
} //namespace thread {
|
||||||
|
} //namespace esp_open_rtos {
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* ESP_OPEN_RTOS_TASK_HPP */
|
||||||
|
|
22
extras/i2c/LICENSE
Normal file
22
extras/i2c/LICENSE
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2015 Johan Kanflo
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
40
extras/i2c/README.md
Normal file
40
extras/i2c/README.md
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
# Yet another I2C driver for the ESP8266
|
||||||
|
|
||||||
|
This time a driver for the excellent esp-open-rtos. This is a bit banging I2C driver based on the Wikipedia pesudo C code [1].
|
||||||
|
|
||||||
|
### Adding to your project
|
||||||
|
|
||||||
|
Add the driver to your project as a submodule rather than cloning it:
|
||||||
|
|
||||||
|
````
|
||||||
|
% git submodule add https://github.com/kanflo/esp-open-rtos-driver-i2c.git i2c
|
||||||
|
````
|
||||||
|
The esp-open-rtos makefile-fu will make sure the driver is built.
|
||||||
|
|
||||||
|
### Usage
|
||||||
|
|
||||||
|
|
||||||
|
````
|
||||||
|
#include <i2c.h>
|
||||||
|
|
||||||
|
#define SCL_PIN (0)
|
||||||
|
#define SDA_PIN (2)
|
||||||
|
|
||||||
|
uint8_t slave_addr = 0x20;
|
||||||
|
uint8_t reg_addr = 0x1f;
|
||||||
|
uint8_t reg_data;
|
||||||
|
uint8_t data[] = {reg_addr, 0xc8};
|
||||||
|
|
||||||
|
i2c_init(SCL_PIN, SDA_PIN);
|
||||||
|
|
||||||
|
// Write data to slave
|
||||||
|
bool success = i2c_slave_write(slave_addr, data, sizeof(data));
|
||||||
|
|
||||||
|
// Issue write to slave, sending reg_addr, followed by reading 1 byte
|
||||||
|
success = i2c_slave_read(slave_addr, ®_addr, reg_data, 1);
|
||||||
|
|
||||||
|
````
|
||||||
|
|
||||||
|
The driver is released under the MIT license.
|
||||||
|
|
||||||
|
[1] https://en.wikipedia.org/wiki/I²C#Example_of_bit-banging_the_I.C2.B2C_Master_protocol
|
10
extras/i2c/component.mk
Normal file
10
extras/i2c/component.mk
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
# Component makefile for extras/i2c
|
||||||
|
|
||||||
|
# expected anyone using i2c driver includes it as 'i2c/i2c.h'
|
||||||
|
INC_DIRS += $(i2c_ROOT)..
|
||||||
|
|
||||||
|
# args for passing into compile rule generation
|
||||||
|
i2c_INC_DIR =
|
||||||
|
i2c_SRC_DIR = $(i2c_ROOT)
|
||||||
|
|
||||||
|
$(eval $(call component_compile_rules,i2c))
|
229
extras/i2c/i2c.c
Normal file
229
extras/i2c/i2c.c
Normal file
|
@ -0,0 +1,229 @@
|
||||||
|
/*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015 Johan Kanflo (github.com/kanflo)
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <esp8266.h>
|
||||||
|
#include <espressif/esp_misc.h> // sdk_os_delay_us
|
||||||
|
#include "i2c.h"
|
||||||
|
|
||||||
|
|
||||||
|
// I2C driver for ESP8266 written for use with esp-open-rtos
|
||||||
|
// Based on https://en.wikipedia.org/wiki/I²C#Example_of_bit-banging_the_I.C2.B2C_Master_protocol
|
||||||
|
|
||||||
|
// With calling overhead, we end up at ~100kbit/s
|
||||||
|
#define CLK_HALF_PERIOD_US (1)
|
||||||
|
|
||||||
|
#define CLK_STRETCH (10)
|
||||||
|
|
||||||
|
static bool started;
|
||||||
|
static uint8_t g_scl_pin;
|
||||||
|
static uint8_t g_sda_pin;
|
||||||
|
|
||||||
|
void i2c_init(uint8_t scl_pin, uint8_t sda_pin)
|
||||||
|
{
|
||||||
|
started = false;
|
||||||
|
g_scl_pin = scl_pin;
|
||||||
|
g_sda_pin = sda_pin;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void i2c_delay(void)
|
||||||
|
{
|
||||||
|
sdk_os_delay_us(CLK_HALF_PERIOD_US);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set SCL as input and return current level of line, 0 or 1
|
||||||
|
static bool read_scl(void)
|
||||||
|
{
|
||||||
|
gpio_enable(g_scl_pin, GPIO_INPUT);
|
||||||
|
return gpio_read(g_scl_pin); // Clock high, valid ACK
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set SDA as input and return current level of line, 0 or 1
|
||||||
|
static bool read_sda(void)
|
||||||
|
{
|
||||||
|
gpio_enable(g_sda_pin, GPIO_INPUT);
|
||||||
|
// TODO: Without this delay we get arbitration lost in i2c_stop
|
||||||
|
i2c_delay();
|
||||||
|
return gpio_read(g_sda_pin); // Clock high, valid ACK
|
||||||
|
}
|
||||||
|
|
||||||
|
// Actively drive SCL signal low
|
||||||
|
static void clear_scl(void)
|
||||||
|
{
|
||||||
|
gpio_enable(g_scl_pin, GPIO_OUTPUT);
|
||||||
|
gpio_write(g_scl_pin, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Actively drive SDA signal low
|
||||||
|
static void clear_sda(void)
|
||||||
|
{
|
||||||
|
gpio_enable(g_sda_pin, GPIO_OUTPUT);
|
||||||
|
gpio_write(g_sda_pin, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output start condition
|
||||||
|
void i2c_start(void)
|
||||||
|
{
|
||||||
|
uint32_t clk_stretch = CLK_STRETCH;
|
||||||
|
if (started) { // if started, do a restart cond
|
||||||
|
// Set SDA to 1
|
||||||
|
(void) read_sda();
|
||||||
|
i2c_delay();
|
||||||
|
while (read_scl() == 0 && clk_stretch--) ;
|
||||||
|
// Repeated start setup time, minimum 4.7us
|
||||||
|
i2c_delay();
|
||||||
|
}
|
||||||
|
if (read_sda() == 0) {
|
||||||
|
printf("I2C: arbitration lost in i2c_start\n");
|
||||||
|
}
|
||||||
|
// SCL is high, set SDA from 1 to 0.
|
||||||
|
clear_sda();
|
||||||
|
i2c_delay();
|
||||||
|
clear_scl();
|
||||||
|
started = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output stop condition
|
||||||
|
void i2c_stop(void)
|
||||||
|
{
|
||||||
|
uint32_t clk_stretch = CLK_STRETCH;
|
||||||
|
// Set SDA to 0
|
||||||
|
clear_sda();
|
||||||
|
i2c_delay();
|
||||||
|
// Clock stretching
|
||||||
|
while (read_scl() == 0 && clk_stretch--) ;
|
||||||
|
// Stop bit setup time, minimum 4us
|
||||||
|
i2c_delay();
|
||||||
|
// SCL is high, set SDA from 0 to 1
|
||||||
|
if (read_sda() == 0) {
|
||||||
|
printf("I2C: arbitration lost in i2c_stop\n");
|
||||||
|
}
|
||||||
|
i2c_delay();
|
||||||
|
started = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write a bit to I2C bus
|
||||||
|
static void i2c_write_bit(bool bit)
|
||||||
|
{
|
||||||
|
uint32_t clk_stretch = CLK_STRETCH;
|
||||||
|
if (bit) {
|
||||||
|
(void) read_sda();
|
||||||
|
} else {
|
||||||
|
clear_sda();
|
||||||
|
}
|
||||||
|
i2c_delay();
|
||||||
|
// Clock stretching
|
||||||
|
while (read_scl() == 0 && clk_stretch--) ;
|
||||||
|
// SCL is high, now data is valid
|
||||||
|
// If SDA is high, check that nobody else is driving SDA
|
||||||
|
if (bit && read_sda() == 0) {
|
||||||
|
printf("I2C: arbitration lost in i2c_write_bit\n");
|
||||||
|
}
|
||||||
|
i2c_delay();
|
||||||
|
clear_scl();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read a bit from I2C bus
|
||||||
|
static bool i2c_read_bit(void)
|
||||||
|
{
|
||||||
|
uint32_t clk_stretch = CLK_STRETCH;
|
||||||
|
bool bit;
|
||||||
|
// Let the slave drive data
|
||||||
|
(void) read_sda();
|
||||||
|
i2c_delay();
|
||||||
|
// Clock stretching
|
||||||
|
while (read_scl() == 0 && clk_stretch--) ;
|
||||||
|
// SCL is high, now data is valid
|
||||||
|
bit = read_sda();
|
||||||
|
i2c_delay();
|
||||||
|
clear_scl();
|
||||||
|
return bit;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool i2c_write(uint8_t byte)
|
||||||
|
{
|
||||||
|
bool nack;
|
||||||
|
uint8_t bit;
|
||||||
|
for (bit = 0; bit < 8; bit++) {
|
||||||
|
i2c_write_bit((byte & 0x80) != 0);
|
||||||
|
byte <<= 1;
|
||||||
|
}
|
||||||
|
nack = i2c_read_bit();
|
||||||
|
return !nack;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t i2c_read(bool ack)
|
||||||
|
{
|
||||||
|
uint8_t byte = 0;
|
||||||
|
uint8_t bit;
|
||||||
|
for (bit = 0; bit < 8; bit++) {
|
||||||
|
byte = (byte << 1) | i2c_read_bit();
|
||||||
|
}
|
||||||
|
i2c_write_bit(ack);
|
||||||
|
return byte;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool i2c_slave_write(uint8_t slave_addr, uint8_t *data, uint8_t len)
|
||||||
|
{
|
||||||
|
bool success = false;
|
||||||
|
do {
|
||||||
|
i2c_start();
|
||||||
|
if (!i2c_write(slave_addr << 1))
|
||||||
|
break;
|
||||||
|
while (len--) {
|
||||||
|
if (!i2c_write(*data++))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i2c_stop();
|
||||||
|
success = true;
|
||||||
|
} while(0);
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool i2c_slave_read(uint8_t slave_addr, uint8_t data, uint8_t *buf, uint32_t len)
|
||||||
|
{
|
||||||
|
bool success = false;
|
||||||
|
do {
|
||||||
|
i2c_start();
|
||||||
|
if (!i2c_write(slave_addr << 1)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i2c_write(data);
|
||||||
|
i2c_stop();
|
||||||
|
i2c_start();
|
||||||
|
if (!i2c_write(slave_addr << 1 | 1)) { // Slave address + read
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
while(len) {
|
||||||
|
*buf = i2c_read(len == 1);
|
||||||
|
buf++;
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
success = true;
|
||||||
|
} while(0);
|
||||||
|
i2c_stop();
|
||||||
|
if (!success) {
|
||||||
|
printf("I2C: write error\n");
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
51
extras/i2c/i2c.h
Normal file
51
extras/i2c/i2c.h
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015 Johan Kanflo (github.com/kanflo)
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __I2C_H__
|
||||||
|
#define __I2C_H__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
// Init bitbanging I2C driver on given pins
|
||||||
|
void i2c_init(uint8_t scl_pin, uint8_t sda_pin);
|
||||||
|
|
||||||
|
// Write a byte to I2C bus. Return true if slave acked.
|
||||||
|
bool i2c_write(uint8_t byte);
|
||||||
|
|
||||||
|
// Read a byte from I2C bus. Return true if slave acked.
|
||||||
|
uint8_t i2c_read(bool ack);
|
||||||
|
|
||||||
|
// Write 'len' bytes from 'buf' to slave. Return true if slave acked.
|
||||||
|
bool i2c_slave_write(uint8_t slave_addr, uint8_t *buf, uint8_t len);
|
||||||
|
|
||||||
|
// Issue a read operation and send 'data', followed by reading 'len' bytes
|
||||||
|
// from slave into 'buf'. Return true if slave acked.
|
||||||
|
bool i2c_slave_read(uint8_t slave_addr, uint8_t data, uint8_t *buf, uint32_t len);
|
||||||
|
|
||||||
|
// Send start and stop conditions. Only needed when implementing protocols for
|
||||||
|
// devices where the i2c_slave_[read|write] functions above are of no use.
|
||||||
|
void i2c_start(void);
|
||||||
|
void i2c_stop(void);
|
|
@ -1,9 +1,9 @@
|
||||||
# Component makefile for extras/rboot-ota
|
# Component makefile for extras/rboot-ota
|
||||||
|
|
||||||
INC_DIRS += $(ROOT)extras/rboot-ota
|
INC_DIRS += $(rboot-ota_ROOT)
|
||||||
|
|
||||||
# args for passing into compile rule generation
|
# args for passing into compile rule generation
|
||||||
extras/rboot-ota_INC_DIR = $(ROOT)extras/rboot-ota
|
rboot-ota_SRC_DIR = $(rboot-ota_ROOT)
|
||||||
extras/rboot-ota_SRC_DIR = $(ROOT)extras/rboot-ota
|
|
||||||
|
$(eval $(call component_compile_rules,rboot-ota))
|
||||||
|
|
||||||
$(eval $(call component_compile_rules,extras/rboot-ota))
|
|
||||||
|
|
3
extras/thread/component.mk
Normal file
3
extras/thread/component.mk
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# Component makefile for extras/thread
|
||||||
|
|
||||||
|
INC_DIRS += $(ROOT)extras
|
3
extras/timer/component.mk
Normal file
3
extras/timer/component.mk
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# Component makefile for extras/timer
|
||||||
|
|
||||||
|
INC_DIRS += $(ROOT)extras
|
|
@ -6,6 +6,10 @@
|
||||||
#ifndef __ESP8266_H__
|
#ifndef __ESP8266_H__
|
||||||
#define __ESP8266_H__
|
#define __ESP8266_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "ets_sys.h"
|
#include "ets_sys.h"
|
||||||
#include "eagle_soc.h"
|
#include "eagle_soc.h"
|
||||||
#include "gpio_register.h"
|
#include "gpio_register.h"
|
||||||
|
@ -14,5 +18,9 @@
|
||||||
#include "timer_register.h"
|
#include "timer_register.h"
|
||||||
#include "uart_register.h"
|
#include "uart_register.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,10 @@
|
||||||
|
|
||||||
#include "lwip/ip_addr.h"
|
#include "lwip/ip_addr.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
|
#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
|
||||||
#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
|
#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
|
||||||
|
|
||||||
|
@ -23,4 +27,8 @@ void sdk_os_delay_us(uint16_t us);
|
||||||
void sdk_os_install_putc1(void (*p)(char c));
|
void sdk_os_install_putc1(void (*p)(char c));
|
||||||
void sdk_os_putc(char c);
|
void sdk_os_putc(char c);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -6,6 +6,10 @@
|
||||||
#ifndef __ESP_SOFTAP_H__
|
#ifndef __ESP_SOFTAP_H__
|
||||||
#define __ESP_SOFTAP_H__
|
#define __ESP_SOFTAP_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
struct sdk_softap_config {
|
struct sdk_softap_config {
|
||||||
uint8_t ssid[32];
|
uint8_t ssid[32];
|
||||||
uint8_t password[64];
|
uint8_t password[64];
|
||||||
|
@ -20,4 +24,8 @@ struct sdk_softap_config {
|
||||||
bool sdk_wifi_softap_get_config(struct sdk_softap_config *config);
|
bool sdk_wifi_softap_get_config(struct sdk_softap_config *config);
|
||||||
bool sdk_wifi_softap_set_config(struct sdk_softap_config *config);
|
bool sdk_wifi_softap_set_config(struct sdk_softap_config *config);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -10,6 +10,10 @@
|
||||||
|
|
||||||
#include "queue.h"
|
#include "queue.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
struct sdk_station_config {
|
struct sdk_station_config {
|
||||||
uint8_t ssid[32];
|
uint8_t ssid[32];
|
||||||
uint8_t password[64];
|
uint8_t password[64];
|
||||||
|
@ -68,4 +72,8 @@ enum {
|
||||||
|
|
||||||
uint8_t sdk_wifi_station_get_connect_status(void);
|
uint8_t sdk_wifi_station_get_connect_status(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -6,6 +6,10 @@
|
||||||
#ifndef __ESP_SYSTEM_H__
|
#ifndef __ESP_SYSTEM_H__
|
||||||
#define __ESP_SYSTEM_H__
|
#define __ESP_SYSTEM_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
enum sdk_rst_reason {
|
enum sdk_rst_reason {
|
||||||
DEFAULT_RST = 0,
|
DEFAULT_RST = 0,
|
||||||
WDT_RST = 1,
|
WDT_RST = 1,
|
||||||
|
@ -54,4 +58,8 @@ bool sdk_system_rtc_mem_write(uint8_t dst, const void *src, uint16_t n);
|
||||||
|
|
||||||
void sdk_system_uart_swap(void);
|
void sdk_system_uart_swap(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -6,6 +6,10 @@
|
||||||
#ifndef __ESP_TIMER_H__
|
#ifndef __ESP_TIMER_H__
|
||||||
#define __ESP_TIMER_H__
|
#define __ESP_TIMER_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
/* timer related */
|
/* timer related */
|
||||||
typedef void sdk_os_timer_func_t(void *timer_arg);
|
typedef void sdk_os_timer_func_t(void *timer_arg);
|
||||||
|
|
||||||
|
@ -19,4 +23,8 @@ typedef struct _os_timer_t {
|
||||||
void *timer_arg;
|
void *timer_arg;
|
||||||
} sdk_os_timer_t;
|
} sdk_os_timer_t;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -13,6 +13,10 @@
|
||||||
|
|
||||||
#include <lwip/ip_addr.h>
|
#include <lwip/ip_addr.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
NULL_MODE = 0,
|
NULL_MODE = 0,
|
||||||
STATION_MODE,
|
STATION_MODE,
|
||||||
|
@ -67,7 +71,11 @@ enum sdk_phy_mode {
|
||||||
PHY_MODE_11N = 3
|
PHY_MODE_11N = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
enum phy_mode sdk_wifi_get_phy_mode(void);
|
enum sdk_phy_mode sdk_wifi_get_phy_mode(void);
|
||||||
bool sdk_wifi_set_phy_mode(enum sdk_phy_mode mode);
|
bool sdk_wifi_set_phy_mode(enum sdk_phy_mode mode);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -15,6 +15,11 @@
|
||||||
#define SDK_PRIVATE_H
|
#define SDK_PRIVATE_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
struct ip_addr;
|
struct ip_addr;
|
||||||
|
|
||||||
/*********************************************
|
/*********************************************
|
||||||
|
@ -49,4 +54,8 @@ void sdk_system_station_got_ip_set(struct ip_addr *ip_addr, struct ip_addr *sn_m
|
||||||
*/
|
*/
|
||||||
void sdk_system_pp_recycle_rx_pkt(void *eb);
|
void sdk_system_pp_recycle_rx_pkt(void *eb);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -6,6 +6,10 @@
|
||||||
#ifndef __SPI_FLASH_H__
|
#ifndef __SPI_FLASH_H__
|
||||||
#define __SPI_FLASH_H__
|
#define __SPI_FLASH_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
SPI_FLASH_RESULT_OK,
|
SPI_FLASH_RESULT_OK,
|
||||||
SPI_FLASH_RESULT_ERR,
|
SPI_FLASH_RESULT_ERR,
|
||||||
|
@ -21,6 +25,7 @@ sdk_SpiFlashOpResult sdk_spi_flash_erase_sector(uint16_t sec);
|
||||||
sdk_SpiFlashOpResult sdk_spi_flash_write(uint32_t des_addr, uint32_t *src_addr, uint32_t size);
|
sdk_SpiFlashOpResult sdk_spi_flash_write(uint32_t des_addr, uint32_t *src_addr, uint32_t size);
|
||||||
sdk_SpiFlashOpResult sdk_spi_flash_read(uint32_t src_addr, uint32_t *des_addr, uint32_t size);
|
sdk_SpiFlashOpResult sdk_spi_flash_read(uint32_t src_addr, uint32_t *des_addr, uint32_t size);
|
||||||
|
|
||||||
|
|
||||||
/* SDK uses this structure internally to account for flash size.
|
/* SDK uses this structure internally to account for flash size.
|
||||||
|
|
||||||
chip_size field is initialised during startup from the flash size
|
chip_size field is initialised during startup from the flash size
|
||||||
|
@ -42,4 +47,9 @@ typedef struct {
|
||||||
|
|
||||||
extern sdk_flashchip_t sdk_flashchip;
|
extern sdk_flashchip_t sdk_flashchip;
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -166,11 +166,14 @@ SECTIONS
|
||||||
*(.gnu.linkonce.e.*)
|
*(.gnu.linkonce.e.*)
|
||||||
*(.gnu.version_r)
|
*(.gnu.version_r)
|
||||||
*(.eh_frame)
|
*(.eh_frame)
|
||||||
|
. = (. + 3) & ~ 3;
|
||||||
/* C++ constructor and destructor tables, properly ordered: */
|
/* C++ constructor and destructor tables, properly ordered: */
|
||||||
|
__init_array_start = ABSOLUTE(.);
|
||||||
KEEP (*crtbegin.o(.ctors))
|
KEEP (*crtbegin.o(.ctors))
|
||||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
||||||
KEEP (*(SORT(.ctors.*)))
|
KEEP (*(SORT(.ctors.*)))
|
||||||
KEEP (*(.ctors))
|
KEEP (*(.ctors))
|
||||||
|
__init_array_end = ABSOLUTE(.);
|
||||||
KEEP (*crtbegin.o(.dtors))
|
KEEP (*crtbegin.o(.dtors))
|
||||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
|
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
|
||||||
KEEP (*(SORT(.dtors.*)))
|
KEEP (*(SORT(.dtors.*)))
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
/*
|
/*
|
||||||
* $Id$
|
* _default_types implementation for xtensa lx106 arch
|
||||||
|
*
|
||||||
|
* Simplified version of generic _default_types.h, ignores gcc
|
||||||
|
* built-in standard types.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _MACHINE__DEFAULT_TYPES_H
|
#ifndef _MACHINE__DEFAULT_TYPES_H
|
||||||
|
@ -7,211 +10,44 @@
|
||||||
|
|
||||||
#include <sys/features.h>
|
#include <sys/features.h>
|
||||||
|
|
||||||
/*
|
|
||||||
* Guess on types by examining *_MIN / *_MAX defines.
|
|
||||||
*/
|
|
||||||
#if __GNUC_PREREQ (3, 3)
|
|
||||||
/* GCC >= 3.3.0 has __<val>__ implicitly defined. */
|
|
||||||
#define __EXP(x) __##x##__
|
|
||||||
#else
|
|
||||||
/* Fall back to POSIX versions from <limits.h> */
|
|
||||||
#define __EXP(x) x
|
|
||||||
#include <limits.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __INT8_TYPE__
|
|
||||||
typedef __INT8_TYPE__ __int8_t;
|
|
||||||
#ifdef __UINT8_TYPE__
|
|
||||||
typedef __UINT8_TYPE__ __uint8_t;
|
|
||||||
#else
|
|
||||||
typedef unsigned __INT8_TYPE__ __uint8_t;
|
|
||||||
#endif
|
|
||||||
#define ___int8_t_defined 1
|
|
||||||
#elif __EXP(SCHAR_MAX) == 0x7f
|
|
||||||
typedef signed char __int8_t ;
|
typedef signed char __int8_t ;
|
||||||
typedef unsigned char __uint8_t ;
|
typedef unsigned char __uint8_t ;
|
||||||
#define ___int8_t_defined 1
|
#define ___int8_t_defined 1
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __INT16_TYPE__
|
|
||||||
typedef __INT16_TYPE__ __int16_t;
|
|
||||||
#ifdef __UINT16_TYPE__
|
|
||||||
typedef __UINT16_TYPE__ __uint16_t;
|
|
||||||
#else
|
|
||||||
typedef unsigned __INT16_TYPE__ __uint16_t;
|
|
||||||
#endif
|
|
||||||
#define ___int16_t_defined 1
|
|
||||||
#elif __EXP(INT_MAX) == 0x7fff
|
|
||||||
typedef signed int __int16_t;
|
|
||||||
typedef unsigned int __uint16_t;
|
|
||||||
#define ___int16_t_defined 1
|
|
||||||
#elif __EXP(SHRT_MAX) == 0x7fff
|
|
||||||
typedef signed short __int16_t;
|
typedef signed short __int16_t;
|
||||||
typedef unsigned short __uint16_t;
|
typedef unsigned short __uint16_t;
|
||||||
#define ___int16_t_defined 1
|
#define ___int16_t_defined 1
|
||||||
#elif __EXP(SCHAR_MAX) == 0x7fff
|
|
||||||
typedef signed char __int16_t;
|
|
||||||
typedef unsigned char __uint16_t;
|
|
||||||
#define ___int16_t_defined 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __INT32_TYPE__
|
|
||||||
typedef __INT32_TYPE__ __int32_t;
|
|
||||||
#ifdef __UINT32_TYPE__
|
|
||||||
typedef __UINT32_TYPE__ __uint32_t;
|
|
||||||
#else
|
|
||||||
typedef unsigned __INT32_TYPE__ __uint32_t;
|
|
||||||
#endif
|
|
||||||
#define ___int32_t_defined 1
|
|
||||||
#elif __EXP(INT_MAX) == 0x7fffffffL
|
|
||||||
typedef signed int __int32_t;
|
typedef signed int __int32_t;
|
||||||
typedef unsigned int __uint32_t;
|
typedef unsigned int __uint32_t;
|
||||||
#define ___int32_t_defined 1
|
#define ___int32_t_defined 1
|
||||||
#elif __EXP(LONG_MAX) == 0x7fffffffL
|
|
||||||
typedef signed long __int32_t;
|
|
||||||
typedef unsigned long __uint32_t;
|
|
||||||
#define ___int32_t_defined 1
|
|
||||||
#elif __EXP(SHRT_MAX) == 0x7fffffffL
|
|
||||||
typedef signed short __int32_t;
|
|
||||||
typedef unsigned short __uint32_t;
|
|
||||||
#define ___int32_t_defined 1
|
|
||||||
#elif __EXP(SCHAR_MAX) == 0x7fffffffL
|
|
||||||
typedef signed char __int32_t;
|
|
||||||
typedef unsigned char __uint32_t;
|
|
||||||
#define ___int32_t_defined 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __INT64_TYPE__
|
|
||||||
typedef __INT64_TYPE__ __int64_t;
|
|
||||||
#ifdef __UINT64_TYPE__
|
|
||||||
typedef __UINT64_TYPE__ __uint64_t;
|
|
||||||
#else
|
|
||||||
typedef unsigned __INT64_TYPE__ __uint64_t;
|
|
||||||
#endif
|
|
||||||
#define ___int64_t_defined 1
|
|
||||||
#elif __EXP(LONG_MAX) > 0x7fffffff
|
|
||||||
typedef signed long __int64_t;
|
|
||||||
typedef unsigned long __uint64_t;
|
|
||||||
#define ___int64_t_defined 1
|
|
||||||
|
|
||||||
/* GCC has __LONG_LONG_MAX__ */
|
|
||||||
#elif defined(__LONG_LONG_MAX__) && (__LONG_LONG_MAX__ > 0x7fffffff)
|
|
||||||
typedef signed long long __int64_t;
|
typedef signed long long __int64_t;
|
||||||
typedef unsigned long long __uint64_t;
|
typedef unsigned long long __uint64_t;
|
||||||
#define ___int64_t_defined 1
|
#define ___int64_t_defined 1
|
||||||
|
|
||||||
/* POSIX mandates LLONG_MAX in <limits.h> */
|
|
||||||
#elif defined(LLONG_MAX) && (LLONG_MAX > 0x7fffffff)
|
|
||||||
typedef signed long long __int64_t;
|
|
||||||
typedef unsigned long long __uint64_t;
|
|
||||||
#define ___int64_t_defined 1
|
|
||||||
|
|
||||||
#elif __EXP(INT_MAX) > 0x7fffffff
|
|
||||||
typedef signed int __int64_t;
|
|
||||||
typedef unsigned int __uint64_t;
|
|
||||||
#define ___int64_t_defined 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __INT_LEAST8_TYPE__
|
|
||||||
typedef __INT_LEAST8_TYPE__ __int_least8_t;
|
|
||||||
#ifdef __UINT_LEAST8_TYPE__
|
|
||||||
typedef __UINT_LEAST8_TYPE__ __uint_least8_t;
|
|
||||||
#else
|
|
||||||
typedef unsigned __INT_LEAST8_TYPE__ __uint_least8_t;
|
|
||||||
#endif
|
|
||||||
#define ___int_least8_t_defined 1
|
|
||||||
#elif defined(___int8_t_defined)
|
|
||||||
typedef __int8_t __int_least8_t;
|
typedef __int8_t __int_least8_t;
|
||||||
typedef __uint8_t __uint_least8_t;
|
typedef __uint8_t __uint_least8_t;
|
||||||
#define ___int_least8_t_defined 1
|
#define ___int_least8_t_defined
|
||||||
#elif defined(___int16_t_defined)
|
|
||||||
typedef __int16_t __int_least8_t;
|
|
||||||
typedef __uint16_t __uint_least8_t;
|
|
||||||
#define ___int_least8_t_defined 1
|
|
||||||
#elif defined(___int32_t_defined)
|
|
||||||
typedef __int32_t __int_least8_t;
|
|
||||||
typedef __uint32_t __uint_least8_t;
|
|
||||||
#define ___int_least8_t_defined 1
|
|
||||||
#elif defined(___int64_t_defined)
|
|
||||||
typedef __int64_t __int_least8_t;
|
|
||||||
typedef __uint64_t __uint_least8_t;
|
|
||||||
#define ___int_least8_t_defined 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __INT_LEAST16_TYPE__
|
|
||||||
typedef __INT_LEAST16_TYPE__ __int_least16_t;
|
|
||||||
#ifdef __UINT_LEAST16_TYPE__
|
|
||||||
typedef __UINT_LEAST16_TYPE__ __uint_least16_t;
|
|
||||||
#else
|
|
||||||
typedef unsigned __INT_LEAST16_TYPE__ __uint_least16_t;
|
|
||||||
#endif
|
|
||||||
#define ___int_least16_t_defined 1
|
|
||||||
#elif defined(___int16_t_defined)
|
|
||||||
typedef __int16_t __int_least16_t;
|
typedef __int16_t __int_least16_t;
|
||||||
typedef __uint16_t __uint_least16_t;
|
typedef __uint16_t __uint_least16_t;
|
||||||
#define ___int_least16_t_defined 1
|
#define ___int_least16_t_defined
|
||||||
#elif defined(___int32_t_defined)
|
|
||||||
typedef __int32_t __int_least16_t;
|
|
||||||
typedef __uint32_t __uint_least16_t;
|
|
||||||
#define ___int_least16_t_defined 1
|
|
||||||
#elif defined(___int64_t_defined)
|
|
||||||
typedef __int64_t __int_least16_t;
|
|
||||||
typedef __uint64_t __uint_least16_t;
|
|
||||||
#define ___int_least16_t_defined 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __INT_LEAST32_TYPE__
|
|
||||||
typedef __INT_LEAST32_TYPE__ __int_least32_t;
|
|
||||||
#ifdef __UINT_LEAST32_TYPE__
|
|
||||||
typedef __UINT_LEAST32_TYPE__ __uint_least32_t;
|
|
||||||
#else
|
|
||||||
typedef unsigned __INT_LEAST32_TYPE__ __uint_least32_t;
|
|
||||||
#endif
|
|
||||||
#define ___int_least32_t_defined 1
|
|
||||||
#elif defined(___int32_t_defined)
|
|
||||||
typedef __int32_t __int_least32_t;
|
typedef __int32_t __int_least32_t;
|
||||||
typedef __uint32_t __uint_least32_t;
|
typedef __uint32_t __uint_least32_t;
|
||||||
#define ___int_least32_t_defined 1
|
#define ___int_least32_t_defined
|
||||||
#elif defined(___int64_t_defined)
|
|
||||||
typedef __int64_t __int_least32_t;
|
|
||||||
typedef __uint64_t __uint_least32_t;
|
|
||||||
#define ___int_least32_t_defined 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __INT_LEAST64_TYPE__
|
|
||||||
typedef __INT_LEAST64_TYPE__ __int_least64_t;
|
|
||||||
#ifdef __UINT_LEAST64_TYPE__
|
|
||||||
typedef __UINT_LEAST64_TYPE__ __uint_least64_t;
|
|
||||||
#else
|
|
||||||
typedef unsigned __INT_LEAST64_TYPE__ __uint_least64_t;
|
|
||||||
#endif
|
|
||||||
#define ___int_least64_t_defined 1
|
|
||||||
#elif defined(___int64_t_defined)
|
|
||||||
typedef __int64_t __int_least64_t;
|
typedef __int64_t __int_least64_t;
|
||||||
typedef __uint64_t __uint_least64_t;
|
typedef __uint64_t __uint_least64_t;
|
||||||
#define ___int_least64_t_defined 1
|
#define ___int_least64_t_defined
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __INTPTR_TYPE__
|
|
||||||
typedef __INTPTR_TYPE__ __intptr_t;
|
typedef __INTPTR_TYPE__ __intptr_t;
|
||||||
#ifdef __UINTPTR_TYPE__
|
|
||||||
typedef __UINTPTR_TYPE__ __uintptr_t;
|
typedef __UINTPTR_TYPE__ __uintptr_t;
|
||||||
#else
|
|
||||||
typedef unsigned __INTPTR_TYPE__ __uintptr_t;
|
|
||||||
#endif
|
|
||||||
#elif defined(__PTRDIFF_TYPE__)
|
|
||||||
typedef __PTRDIFF_TYPE__ __intptr_t;
|
|
||||||
typedef unsigned __PTRDIFF_TYPE__ __uintptr_t;
|
|
||||||
#else
|
|
||||||
typedef long __intptr_t;
|
|
||||||
typedef unsigned long __uintptr_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#undef __EXP
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software
|
* Permission to use, copy, modify, and distribute this software
|
||||||
* is freely granted, provided that this notice is preserved.
|
* is freely granted, provided that this notice is preserved.
|
||||||
|
*
|
||||||
|
* Modified for xtensa arch & non-long int32_t, removes automatic setting of __have_long32.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _SYS__INTSUP_H
|
#ifndef _SYS__INTSUP_H
|
||||||
|
@ -11,26 +13,8 @@
|
||||||
|
|
||||||
#include <sys/features.h>
|
#include <sys/features.h>
|
||||||
|
|
||||||
#if __GNUC_PREREQ (3, 2)
|
|
||||||
/* gcc > 3.2 implicitly defines the values we are interested */
|
|
||||||
#define __STDINT_EXP(x) __##x##__
|
#define __STDINT_EXP(x) __##x##__
|
||||||
#else
|
|
||||||
#define __STDINT_EXP(x) x
|
|
||||||
#include <limits.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Check if "long long" is 64bit wide */
|
|
||||||
/* Modern GCCs provide __LONG_LONG_MAX__, SUSv3 wants LLONG_MAX */
|
|
||||||
#if ( defined(__LONG_LONG_MAX__) && (__LONG_LONG_MAX__ > 0x7fffffff) ) \
|
|
||||||
|| ( defined(LLONG_MAX) && (LLONG_MAX > 0x7fffffff) )
|
|
||||||
#define __have_longlong64 1
|
#define __have_longlong64 1
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Check if "long" is 64bit or 32bit wide */
|
|
||||||
#if __STDINT_EXP(LONG_MAX) > 0x7fffffff
|
|
||||||
#define __have_long64 1
|
|
||||||
#elif __STDINT_EXP(LONG_MAX) == 0x7fffffff && !defined(__SPU__)
|
|
||||||
#define __have_long32 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* _SYS__INTSUP_H */
|
#endif /* _SYS__INTSUP_H */
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,12 +1,11 @@
|
||||||
# Component makefile for LWIP
|
# Component makefile for LWIP
|
||||||
|
|
||||||
LWIP_DIR = $(ROOT)lwip/lwip/src/
|
LWIP_DIR = $(lwip_ROOT)lwip/src/
|
||||||
INC_DIRS += $(LWIP_DIR)include $(ROOT)lwip/include $(ROOT)lwip/include $(LWIP_DIR)include/ipv4 $(LWIP_DIR)include/ipv4/lwip $(LWIP_DIR)include/lwip
|
INC_DIRS += $(LWIP_DIR)include $(ROOT)lwip/include $(lwip_ROOT)include $(LWIP_DIR)include/ipv4 $(LWIP_DIR)include/ipv4/lwip $(LWIP_DIR)include/lwip
|
||||||
|
|
||||||
# args for passing into compile rule generation
|
# args for passing into compile rule generation
|
||||||
lwip_ROOT = $(ROOT)/lwip
|
|
||||||
lwip_INC_DIR = # all in INC_DIRS, needed for normal operation
|
lwip_INC_DIR = # all in INC_DIRS, needed for normal operation
|
||||||
lwip_SRC_DIR = $(ROOT)/lwip $(LWIP_DIR)api $(LWIP_DIR)core $(LWIP_DIR)core/ipv4 $(LWIP_DIR)netif
|
lwip_SRC_DIR = $(lwip_ROOT) $(LWIP_DIR)api $(LWIP_DIR)core $(LWIP_DIR)core/ipv4 $(LWIP_DIR)netif
|
||||||
|
|
||||||
# LWIP 1.4.1 generates a single warning so we need to disable -Werror when building it
|
# LWIP 1.4.1 generates a single warning so we need to disable -Werror when building it
|
||||||
lwip_CFLAGS = $(CFLAGS) -Wno-address
|
lwip_CFLAGS = $(CFLAGS) -Wno-address
|
||||||
|
|
Loading…
Reference in a new issue