diff --git a/FreeRTOS/Source/portable/esp8266/sdk_compat.c b/FreeRTOS/Source/portable/esp8266/sdk_compat.c index b965e5c..3b94345 100644 --- a/FreeRTOS/Source/portable/esp8266/sdk_compat.c +++ b/FreeRTOS/Source/portable/esp8266/sdk_compat.c @@ -2,7 +2,7 @@ * Stub functions called by binary espressif libraries * * Part of esp-open-rtos - * Copyright (C) 2105 Superhouse Automation Pty Ltd + * Copyright (C) 2015 Superhouse Automation Pty Ltd * BSD Licensed as described in the file LICENSE */ #include diff --git a/README.md b/README.md index 430de90..c6d716b 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,15 @@ 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)). * 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 * 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. diff --git a/axtls/axtls_esp_stubs.c b/axtls/axtls_esp_stubs.c index ffb5404..3182594 100644 --- a/axtls/axtls_esp_stubs.c +++ b/axtls/axtls_esp_stubs.c @@ -4,7 +4,7 @@ * ESPTODO: Revisit these ASAP as gettimeofday() is used for entropy * * Part of esp-open-rtos - * Copyright (C) 2105 Superhouse Automation Pty Ltd + * Copyright (C) 2015 Superhouse Automation Pty Ltd * BSD Licensed as described in the file LICENSE */ #include diff --git a/common.mk b/common.mk index dabc76d..26dcfbf 100644 --- a/common.mk +++ b/common.mk @@ -59,7 +59,7 @@ OBJDUMP = $(CROSS)objdump # Source components to compile and link. Each of these are subdirectories # of the root, with a 'component.mk' file. -COMPONENTS ?= FreeRTOS lwip axtls +COMPONENTS ?= core FreeRTOS lwip axtls # binary esp-iot-rtos SDK libraries to link. These are pre-processed prior to linking. SDK_LIBS ?= main net80211 phy pp wpa diff --git a/core/component.mk b/core/component.mk new file mode 100644 index 0000000..b4eca35 --- /dev/null +++ b/core/component.mk @@ -0,0 +1,6 @@ +INC_DIRS += $(core_ROOT)include + +# args for passing into compile rule generation +core_ROOT = $(ROOT)core/ +core_SRC_DIR = $(core_ROOT) +$(eval $(call component_compile_rules,core)) diff --git a/core/esp_iomux.c b/core/esp_iomux.c new file mode 100644 index 0000000..fb4ec67 --- /dev/null +++ b/core/esp_iomux.c @@ -0,0 +1,20 @@ +/* Compiler-level implementation for esp/iomux.h and esp/iomux_private.h + * + * Part of esp-open-rtos + * Copyright (C) 2015 Superhouse Automation Pty Ltd + * BSD Licensed as described in the file LICENSE + */ +#include "esp/iomux.h" +#include "common_macros.h" + +/* These are non-static versions of the GPIO mapping tables in + iomux.h, so if they need to be linked only one copy is linked for + the entire program. + + These are only ever linked in if the arguments to gpio_to_ionum + or ionum_to_gpio are not known at compile time. + + Arrays are declared as 32-bit integers in IROM to save RAM. +*/ +const IROM uint32_t GPIO_TO_IOMUX_MAP[] = _GPIO_TO_IOMUX; +const IROM uint32_t IOMUX_TO_GPIO_MAP[] = _IOMUX_TO_GPIO; diff --git a/include/esp8266.h b/core/include/common_macros.h similarity index 60% rename from include/esp8266.h rename to core/include/common_macros.h index 503f5cc..b72229f 100644 --- a/include/esp8266.h +++ b/core/include/common_macros.h @@ -1,15 +1,20 @@ -/* esp8266.h +/* Some common compiler macros * - * ESP-specific SoC-level addresses, macros, etc. + * Not esp8266-specific. * * Part of esp-open-rtos - * Copyright (C) 2105 Superhouse Automation Pty Ltd + * Copyright (C) 2015 Superhouse Automation Pty Ltd * BSD Licensed as described in the file LICENSE */ -#include -#ifndef _ESP8266_H -#define _ESP8266_H +#ifndef _COMMON_MACROS_H +#define _COMMON_MACROS_H + +#define UNUSED __attributed((unused)) + +#ifndef BIT +#define BIT(X) (1< +#include "esp/registers.h" +#include "esp/iomux.h" + +typedef enum { + GPIO_INPUT = 0, + GPIO_OUTPUT = IOMUX_OE, + GPIO_INPUT_PULLUP = IOMUX_PU, +} gpio_direction_t; + +/* Enable GPIO on the specified pin, and set it to input/output/ with + * pullup as needed + */ +INLINED void gpio_enable(const uint8_t gpio_num, const gpio_direction_t direction) +{ + iomux_set_gpio_function(gpio_num, (uint8_t)direction); + if(direction == GPIO_OUTPUT) + GPIO_DIR_SET = BIT(gpio_num); + else + GPIO_DIR_CLEAR = BIT(gpio_num); +} + +/* Disable GPIO on the specified pin, and set it Hi-Z. + * + * If later muxing this pin to a different function, make sure to set + * IOMUX_OE if necessary to enable the output buffer. + */ +INLINED void gpio_disable(const uint8_t gpio_num) +{ + GPIO_DIR_CLEAR = BIT(gpio_num); + *gpio_iomux_reg(gpio_num) &= ~IOMUX_OE; +} + +/* Set output of a pin high or low. + * + * Only works if pin has been set to GPIO_OUTPUT via gpio_enable() + */ +INLINED void gpio_write(const uint8_t gpio_num, const uint32_t set) +{ + if(set) + GPIO_OUT_SET = BIT(gpio_num); + else + GPIO_OUT_CLEAR = BIT(gpio_num); +} + +/* Toggle output of a pin + * + * Only works if pin has been set to GPIO_OUTPUT via gpio_enable() + */ +INLINED void gpio_toggle(const uint8_t gpio_num) +{ + /* Why implement like this instead of GPIO_OUT_REG ^= xxx? + Concurrency. If an interrupt or higher priority task writes to + GPIO_OUT between reading and writing, only the gpio_num pin can + get an invalid value. Prevents one task from clobbering another + task's pins, without needing to disable/enable interrupts. + */ + if(GPIO_OUT_REG & BIT(gpio_num)) + GPIO_OUT_CLEAR = BIT(gpio_num); + else + GPIO_OUT_SET = BIT(gpio_num); +} + +/* Read input value of a GPIO pin. + * + * If pin is set as an input, this reads the value on the pin. + * If pin is set as an output, this reads the last value written to the pin. + */ +INLINED bool gpio_read(const uint8_t gpio_num) +{ + return GPIO_IN_REG & BIT(gpio_num); +} + + +#endif diff --git a/core/include/esp/iomux.h b/core/include/esp/iomux.h new file mode 100644 index 0000000..fd5a51d --- /dev/null +++ b/core/include/esp/iomux.h @@ -0,0 +1,199 @@ +/** esp/iomux.h + * + * Configuration of iomux registers. + * + * Part of esp-open-rtos + * Copyright (C) 2015 Superhouse Automation Pty Ltd + * BSD Licensed as described in the file LICENSE + */ +#ifndef _ESP_IOMUX_H +#define _ESP_IOMUX_H +#include +#include "esp/registers.h" + +/** + * Convert a GPIO pin number to an iomux register index. + * + * This function should evaluate to a constant if the gpio_number is + * known at compile time, or return the result from a lookup table if not. + * + */ +inline static uint8_t gpio_to_iomux(const uint8_t gpio_number); + +/** + * Convert an iomux register index to a GPIO pin number. + * + * This function should evaluate to a constant if the iomux_num is + * known at compile time, or return the result from a lookup table if not. + * + */ +inline static uint8_t iomux_to_gpio(const uint8_t iomux_num); + +/** + * Directly get the IOMUX register for a particular gpio number + * + * ie *gpio_iomux_reg(3) is equivalent to IOMUX_GP03 + */ +inline static esp_reg_t gpio_iomux_reg(const uint8_t gpio_number) +{ + return &IOMUX_REG(gpio_to_iomux(gpio_number)); +} + +/** + * Set a pin to the GPIO function. + * + * This allows you to set pins to GPIO without knowing in advance the + * exact register masks to use. + * + * flags can be any of IOMUX_OE, IOMUX_PU, IOMUX_PD, etc. Any other flags will be cleared. + * + * Equivalent to a direct register operation if gpio_number is known at compile time. + * ie the following are equivalent: + * + * iomux_set_gpio_function(12, IOMUX_OE); + * IOMUX_GP12 = (IOMUX_GP12 & ~IOMUX_FUNC_MASK) | IOMUX_GP12_GPIO | IOMUX_OE; + */ +inline static void iomux_set_gpio_function(const uint8_t gpio_number, const uint8_t flags) +{ + const uint8_t reg_idx = gpio_to_iomux(gpio_number); + const esp_reg_t reg = &IOMUX_REG(reg_idx); + const uint32_t func = (reg_idx > 11 ? IOMUX_FUNC_A : IOMUX_FUNC_D) | flags; + const uint32_t val = *reg & ~(IOMUX_FUNC_MASK | IOMUX_FLAG_MASK); + *reg = val | func; +} + +/** + * Set an IOMUX register directly + * + * Shortcut for + * IOMUX_GPxx = (IOMUX_GPxx & ~IOMUX_FUNC_MASK) | IOMUX_GPxx_func + * + * instead call + * IOMUX_SET_FN(GPxx, func); + * can also do + * IOMUX_SET_FN(GP12, GPIO)|IOMUX_OE; + * ... to set the OE flag if it was previously cleared. + * + * but a better option is: + * IOMUX_SET(GP12, GPIO, IOMUX_OE); + * ...which clears any other flags at the same time. + */ +#define IOMUX_SET_FN(GP,FN) IOMUX_##GP = ((IOMUX_##GP & ~IOMUX_FUNC_MASK) | IOMUX_##GP##_##FN) +#define IOMUX_SET(GP,FN,FLAGS) IOMUX_##GP = ((IOMUX_##GP & ~(IOMUX_FUNC_MASK|IOMUX_FLAG_MASK)) | IOMUX_##GP##_##FN|FLAGS) + +/* IOMUX register index 0, GPIO 12 */ +#define IOMUX_GP12 IOMUX_REG(0) +#define IOMUX_GP12_MTDI IOMUX_FUNC_A +#define IOMUX_GP12_I2S_DIN IOMUX_FUNC_B +#define IOMUX_GP12_HSPI_MISO IOMUX_FUNC_C +#define IOMUX_GP12_GPIO IOMUX_FUNC_D +#define IOMUX_GP12_UART0_DTR IOMUX_FUNC_E + +/* IOMUX register index 1, GPIO 13 */ +#define IOMUX_GP13 IOMUX_REG(1) +#define IOMUX_GP13_MTCK IOMUX_FUNC_A +#define IOMUX_GP13_I2SI_BCK IOMUX_FUNC_B +#define IOMUX_GP13_HSPI_MOSI IOMUX_FUNC_C +#define IOMUX_GP13_GPIO IOMUX_FUNC_D +#define IOMUX_GP13_UART0_CTS IOMUX_FUNC_E + +/* IOMUX register index 2, GPIO 14 */ +#define IOMUX_GP14 IOMUX_REG(2) +#define IOMUX_GP14_MTMS IOMUX_FUNC_A +#define IOMUX_GP14_I2SI_WS IOMUX_FUNC_B +#define IOMUX_GP14_HSPI_CLK IOMUX_FUNC_C +#define IOMUX_GP14_GPIO IOMUX_FUNC_D +#define IOMUX_GP14_UART0_DSR IOMUX_FUNC_E + +/* IOMUX register index 3, GPIO 15 */ +#define IOMUX_GP15 IOMUX_REG(3) +#define IOMUX_GP15_MTDO IOMUX_FUNC_A +#define IOMUX_GP15_I2SO_BCK IOMUX_FUNC_B +#define IOMUX_GP15_HSPI_CS0 IOMUX_FUNC_C +#define IOMUX_GP15_GPIO IOMUX_FUNC_D +#define IOMUX_GP15_UART0_RTS IOMUX_FUNC_E + +/* IOMUX register index 4, GPIO 3 */ +#define IOMUX_GP03 IOMUX_REG(4) +#define IOMUX_GP03_UART0_RX IOMUX_FUNC_A +#define IOMUX_GP03_I2SO_DATA IOMUX_FUNC_B +#define IOMUX_GP03_GPIO IOMUX_FUNC_D +#define IOMUX_GP03_CLK_XTAL_BK IOMUX_FUNC_E + +/* IOMUX register index 5, GPIO 1 */ +#define IOMUX_GP01 IOMUX_REG(5) +#define IOMUX_GP01_UART0_TX IOMUX_FUNC_A +#define IOMUX_GP01_SPICS1 IOMUX_FUNC_B +#define IOMUX_GP01_GPIO IOMUX_FUNC_D +#define IOMUX_GP01_CLK_RTC_BK IOMUX_FUNC_E + +/* IOMUX register index 6, GPIO 6 */ +#define IOMUX_GP06 IOMUX_REG(6) +#define IOMUX_GP06_SD_CLK IOMUX_FUNC_A +#define IOMUX_GP06_SP_ICLK IOMUX_FUNC_B +#define IOMUX_GP06_GPIO IOMUX_FUNC_D +#define IOMUX_GP06_UART1_CTS IOMUX_FUNC_E + +/* IOMUX register index 7, GPIO 7 */ +#define IOMUX_GP07 IOMUX_REG(7) +#define IOMUX_GP07_SD_DATA0 IOMUX_FUNC_A +#define IOMUX_GP07_SPIQ_MISO IOMUX_FUNC_B +#define IOMUX_GP07_GPIO IOMUX_FUNC_D +#define IOMUX_GP07_UART1_TX IOMUX_FUNC_E + +/* IOMUX register index 8, GPIO 8 */ +#define IOMUX_GP08 IOMUX_REG(8) +#define IOMUX_GP08_SD_DATA1 IOMUX_FUNC_A +#define IOMUX_GP08_SPID_MOSI IOMUX_FUNC_B +#define IOMUX_GP08_GPIO IOMUX_FUNC_D +#define IOMUX_GP08_UART1_RX IOMUX_FUNC_E + +/* IOMUX register index 9, GPIO 9 */ +#define IOMUX_GP09 IOMUX_REG(9) +#define IOMUX_GP09_SD_DATA2 IOMUX_FUNC_A +#define IOMUX_GP09_SPI_HD IOMUX_FUNC_B +#define IOMUX_GP09_GPIO IOMUX_FUNC_D +#define IOMUX_GP09_UFNC_HSPIHD IOMUX_FUNC_E + +/* IOMUX register index 10, GPIO 10 */ +#define IOMUX_GP10 IOMUX_REG(10) +#define IOMUX_GP10_SD_DATA3 IOMUX_FUNC_A +#define IOMUX_GP10_SPI_WP IOMUX_FUNC_B +#define IOMUX_GP10_GPIO IOMUX_FUNC_D +#define IOMUX_GP10_HSPIWP IOMUX_FUNC_E + +/* IOMUX register index 11, GPIO 11 */ +#define IOMUX_GP11 IOMUX_REG(11) +#define IOMUX_GP11_SD_CMD IOMUX_FUNC_A +#define IOMUX_GP11_SPI_CS0 IOMUX_FUNC_B +#define IOMUX_GP11_GPIO IOMUX_FUNC_D +#define IOMUX_GP11_UART1_RTS IOMUX_FUNC_E + +/* IOMUX register index 12, GPIO 0 */ +#define IOMUX_GP00 IOMUX_REG(12) +#define IOMUX_GP00_GPIO IOMUX_FUNC_A +#define IOMUX_GP00_SPI_CS2 IOMUX_FUNC_B +#define IOMUX_GP00_CLK_OUT IOMUX_FUNC_E + +/* IOMUX register index 13, GPIO 2 */ +#define IOMUX_GP02 IOMUX_REG(13) +#define IOMUX_GP02_GPIO IOMUX_FUNC_A +#define IOMUX_GP02_I2SO_WS IOMUX_FUNC_B +#define IOMUX_GP02_UART1_TX IOMUX_FUNC_C +#define IOMUX_GP02_UART0_TX IOMUX_FUNC_E + +/* IOMUX register index 14, GPIO 4 */ +#define IOMUX_GP04 IOMUX_REG(14) +#define IOMUX_GP04_GPIO4 IOMUX_FUNC_A +#define IOMUX_GP04_CLK_XTAL IOMUX_FUNC_B + +/* IOMUX register index 15, GPIO 5 */ +#define IOMUX_GP05 IOMUX_REG(15) +#define IOMUX_GP05_GPIO5 IOMUX_FUNC_A +#define IOMUX_GP05_CLK_RTC IOMUX_FUNC_B + +/* esp_iomux_private contains implementation parts of the inline functions + declared above */ +#include "esp/iomux_private.h" + +#endif diff --git a/core/include/esp/iomux_private.h b/core/include/esp/iomux_private.h new file mode 100644 index 0000000..56b92c0 --- /dev/null +++ b/core/include/esp/iomux_private.h @@ -0,0 +1,47 @@ +/** esp/iomux_private.h + * + * Private implementation parts of iomux registers. In headers to + * allow compile-time optimisations. + * + * Part of esp-open-rtos + * Copyright (C) 2015 Superhouse Automation Pty Ltd + * BSD Licensed as described in the file LICENSE +*/ + +/* Mapping from register index to GPIO and from GPIO index to register + number. DO NOT USE THESE IN YOUR CODE, call gpio_to_iomux(xxx) or + iomux_to_gpio(xxx) instead. +*/ +#ifndef _IOMUX_PRIVATE +#define _IOMUX_PRIVATE + +#include "common_macros.h" + +#define _IOMUX_TO_GPIO { 12, 13, 14, 15, 3, 1, 6, 7, 8, 9, 10, 11, 0, 2, 4, 5 } +#define _GPIO_TO_IOMUX { 12, 5, 13, 4, 14, 15, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3 } + +extern const IROM uint32_t GPIO_TO_IOMUX_MAP[]; +extern const IROM uint32_t IOMUX_TO_GPIO_MAP[]; + +INLINED uint8_t gpio_to_iomux(const uint8_t gpio_number) +{ + if(__builtin_constant_p(gpio_number)) { + static const uint8_t _regs[] = _GPIO_TO_IOMUX; + return _regs[gpio_number]; + } else { + return GPIO_TO_IOMUX_MAP[gpio_number]; + } +} + +INLINED uint8_t iomux_to_gpio(const uint8_t iomux_number) +{ + if(__builtin_constant_p(iomux_number)) { + static const uint8_t _regs[] = _IOMUX_TO_GPIO; + return _regs[iomux_number]; + } else { + return IOMUX_TO_GPIO_MAP[iomux_number]; + } +} + +#endif + diff --git a/core/include/esp/registers.h b/core/include/esp/registers.h new file mode 100644 index 0000000..fc20888 --- /dev/null +++ b/core/include/esp/registers.h @@ -0,0 +1,116 @@ +/* esp/registers.h + * + * ESP8266 register addresses and bitmasks. + * + * Not compatible with ESP SDK register access code. + * + * Based on register map documentation: + * https://github.com/esp8266/esp8266-wiki/wiki/Memory-Map + * + * Part of esp-open-rtos + * Copyright (C) 2015 Superhouse Automation Pty Ltd + * BSD Licensed as described in the file LICENSE + */ +#ifndef _ESP_REGISTERS +#define _ESP_REGISTERS +#include "common_macros.h" + +typedef volatile uint32_t *esp_reg_t; + +/* Register base addresses + + You shouldn't need to use these directly. + */ +#define MMIO_BASE 0x60000000 + +#define UART0_BASE (MMIO_BASE + 0) +#define SPI1_BASE (MMIO_BASE + 0x0100) +#define SPI_BASE (MMIO_BASE + 0x0200) +#define GPIO0_BASE (MMIO_BASE + 0x0300) +#define TIMER_BASE (MMIO_BASE + 0x0600) +#define RTC_BASE (MMIO_BASE + 0x0700) +#define IOMUX_BASE (MMIO_BASE + 0x0800) +#define WDT_BASE (MMIO_BASE + 0x0900) +#define I2C_BASE (MMIO_BASE + 0x0d00) +#define UART1_BASE (MMIO_BASE + 0x0F00) +#define RTCB_BASE (MMIO_BASE + 0x1000) +#define RTCS_BASE (MMIO_BASE + 0x1100) +#define RTCU_BASE (MMIO_BASE + 0x1200) + +/* + * iomux registers, apply to pin functions. + * + * Note that IOMUX register order is _not_ the same as GPIO order. See + * esp_iomux.h for programmer-friendly IOMUX configuration options + */ +#define IOMUX_REG(X) *(esp_reg_t)(IOMUX_BASE+4*(X+1)) + +#define IOMUX_OE BIT(0) /* iomux Output enable bit */ +#define IOMUX_OE_SLEEP BIT(1) /* iomux Output during sleep bit */ + +#define IOMUX_PD BIT(6) /* iomux soft pulldown bit */ +#define IOMUX_PD_SLEEP BIT(2) /* iomux soft pulldown during sleep bit */ +#define IOMUX_PU BIT(7) /* iomux soft pullup bit */ +#define IOMUX_PU_SLEEP BIT(3) /* iomux soft pullup during sleep bit */ + +#define IOMUX_FLAG_WAKE_MASK (IOMUX_OE|IOMUX_PD|IOMUX_PU) +#define IOMUX_FLAG_SLEEP_MASK (IOMUX_OE_SLEEP|IOMUX_PD_SLEEP|IOMUX_PU_SLEEP) +#define IOMUX_FLAG_MASK (IOMUX_FLAG_WAKE_MASK|IOMUX_FLAG_SLEEP_MASK) + +#define IOMUX_FUNC_MASK (BIT(4)|BIT(5)|BIT(12)) + +/* All pins have FUNC_A on reset (unconfirmed) */ +#define IOMUX_FUNC_A (0) +#define IOMUX_FUNC_B BIT(4) +#define IOMUX_FUNC_C BIT(5) +#define IOMUX_FUNC_D BIT(4)|BIT(5) +#define IOMUX_FUNC_E BIT(12) + + +/* + * Based on descriptions by mamalala at https://github.com/esp8266/esp8266-wiki/wiki/gpio-registers + */ + +/** GPIO OUTPUT registers GPIO_OUT_REG, GPIO_OUT_SET, GPIO_OUT_CLEAR + * + * Registers for pin outputs. + * + * _SET and _CLEAR write-only registers set and clear bits in _REG, + * respectively. + * + * ie + * GPIO_OUT_REG |= BIT(3); + * and + * GPIO_OUT_SET = BIT(3); + * + * ... are equivalent, but latter uses less CPU cycles. + */ +#define GPIO_OUT_REG *(esp_reg_t)(GPIO0_BASE) +#define GPIO_OUT_SET *(esp_reg_t)(GPIO0_BASE+0x04) +#define GPIO_OUT_CLEAR *(esp_reg_t)(GPIO0_BASE+0x08) + +/* GPIO DIR registers GPIO_DIR_REG, GPIO_DIR_SET, GPIO_DIR_CLEAR + * + * Set bit in DIR register for output pins. Writing to _SET and _CLEAR + * registers set and clear bits in _REG, respectively. +*/ +#define GPIO_DIR_REG *(esp_reg_t)(GPIO0_BASE+0x0C) +#define GPIO_DIR_SET *(esp_reg_t)(GPIO0_BASE+0x10) +#define GPIO_DIR_CLEAR *(esp_reg_t)(GPIO0_BASE+0x14) + +/* GPIO IN register GPIO_IN_REG + * + * Reads current input values. + */ +#define GPIO_IN_REG *(esp_reg_t)(GPIO0_BASE+0x18) + + +/* WDT register(s) + + Not fully understood yet. Writing 0 here disables wdt. + + See ROM functions esp_wdt_xxx + */ +#define WDT_CTRL *(esp_reg_t)(WDT_BASE) + +#endif diff --git a/core/include/esp8266.h b/core/include/esp8266.h new file mode 100644 index 0000000..ce7a4c7 --- /dev/null +++ b/core/include/esp8266.h @@ -0,0 +1,19 @@ +/* esp8266.h + * + * ESP-specific SoC-level addresses, macros, etc. + * + * Part of esp-open-rtos + * Copyright (C) 2015 Superhouse Automation Pty Ltd + * BSD Licensed as described in the file LICENSE + */ +#include + +#ifndef _ESP8266_H +#define _ESP8266_H + +#include "common_macros.h" +#include "esp/registers.h" +#include "esp/iomux.h" +#include "esp/gpio.h" + +#endif diff --git a/examples/blink/FreeRTOSConfig.h b/examples/blink/FreeRTOSConfig.h new file mode 100644 index 0000000..82ed83d --- /dev/null +++ b/examples/blink/FreeRTOSConfig.h @@ -0,0 +1,127 @@ +/* + FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd. + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to distribute + >>! a combined work that includes FreeRTOS without being obliged to provide + >>! the source code for proprietary components outside of the FreeRTOS + >>! kernel. + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +#define configUSE_PREEMPTION 1 +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configCPU_CLOCK_HZ ( ( unsigned long ) 80000000 ) +#define configTICK_RATE_HZ ( ( portTickType ) 100 ) +#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 15 ) +#define configMINIMAL_STACK_SIZE ( ( unsigned short )156 ) +#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 32 * 1024 ) ) +#define configMAX_TASK_NAME_LEN ( 16 ) +#define configUSE_TRACE_FACILITY 0 +#define configUSE_STATS_FORMATTING_FUNCTIONS 0 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 + +#define INCLUDE_xTaskGetIdleTaskHandle 1 +#define INCLUDE_xTimerGetTimerDaemonTaskHandle 1 + +#define configCHECK_FOR_STACK_OVERFLOW 2 +#define configUSE_MUTEXES 1 +#define configUSE_TIMERS 1 + +#if configUSE_TIMERS +#define configTIMER_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) +#define configTIMER_QUEUE_LENGTH (10) +#define configTIMER_TASK_STACK_DEPTH ( ( unsigned short ) 512 ) +#endif + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) + +/* Set the following definitions to 1 to include the API function, or zero +to exclude the API function. */ + +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 + +/*set the #define for debug info*/ +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 1 + +#endif /* FREERTOS_CONFIG_H */ + diff --git a/examples/blink/Makefile b/examples/blink/Makefile new file mode 100644 index 0000000..1ae57a3 --- /dev/null +++ b/examples/blink/Makefile @@ -0,0 +1,2 @@ +TARGET=blink +include ../../common.mk diff --git a/examples/blink/blink.c b/examples/blink/blink.c new file mode 100644 index 0000000..bb4abdb --- /dev/null +++ b/examples/blink/blink.c @@ -0,0 +1,60 @@ +/* The classic "blink" example + * + * 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 "esp8266.h" + +const int gpio = 14; + +/* This task uses the high level GPIO API (esp_gpio.h) to blink an LED. + * + * Even though it reads better than the register-level version in blinkenRegisterTask, + * they compile to the exact same instructions. + */ +void blinkenTask(void *pvParameters) +{ + gpio_enable(gpio, GPIO_OUTPUT); + while(1) { + gpio_write(gpio, 1); + vTaskDelay(1000 / portTICK_RATE_MS); + gpio_write(gpio, 0); + vTaskDelay(1000 / portTICK_RATE_MS); + } +} + + +/* This task uses all raw register operations to set the pins. + + It's not fully parameterised, as the IOMUX_SET macro requires the pin number + as part of the GPxx value. + + This code compiles to the exact same instructions as blinkenTask, + so it's probably better to use the blinkenTask version. + + NOTE: This task isn't enabled by default, see the commented out line in user_init. +*/ +void blinkenRegisterTask(void *pvParameters) +{ + GPIO_DIR_SET = BIT(gpio); + IOMUX_SET(GP14,GPIO,IOMUX_OE); /* change this line if you change 'gpio' */ + while(1) { + GPIO_OUT_SET = BIT(gpio); + vTaskDelay(1000 / portTICK_RATE_MS); + GPIO_OUT_CLEAR = BIT(gpio); + vTaskDelay(1000 / portTICK_RATE_MS); + } +} + + +void user_init(void) +{ + gpio_enable(13, GPIO_OUTPUT); + + sdk_uart_div_modify(0, UART_CLK_FREQ / 115200); + xTaskCreate(blinkenTask, (signed char *)"blinkenTask", 256, NULL, 2, NULL); + //xTaskCreate(blinkenRegisterTask, (signed char *)"blinkenRegisterTask", 256, NULL, 2, NULL); +}