Merge branch 'master' into vfd16lf01
This commit is contained in:
commit
5577ff8b28
10 changed files with 156 additions and 42 deletions
12
common.mk
12
common.mk
|
@ -48,6 +48,13 @@ ESPTOOL ?= esptool.py
|
||||||
ESPPORT ?= /dev/ttyUSB0
|
ESPPORT ?= /dev/ttyUSB0
|
||||||
ESPBAUD ?= 115200
|
ESPBAUD ?= 115200
|
||||||
|
|
||||||
|
# set this to 0 if you don't need floating point support in printf/scanf
|
||||||
|
# this will save approx 14.5KB flash space and 448 bytes of statically allocated
|
||||||
|
# data RAM
|
||||||
|
#
|
||||||
|
# NB: Setting the value to 0 requires a recent esptool.py (Feb 2016 / commit ebf02c9)
|
||||||
|
PRINTF_SCANF_FLOAT_SUPPORT ?= 1
|
||||||
|
|
||||||
# Set OTA to 1 to build an image that supports rBoot OTA bootloader
|
# Set OTA to 1 to build an image that supports rBoot OTA bootloader
|
||||||
#
|
#
|
||||||
# Currently only works with 16mbit or more flash sizes, with 8mbit
|
# Currently only works with 16mbit or more flash sizes, with 8mbit
|
||||||
|
@ -109,7 +116,7 @@ CXXFLAGS ?= $(C_CXX_FLAGS) -fno-exceptions -fno-rtti $(EXTRA_CXXFLAGS)
|
||||||
# these aren't technically preprocesor args, but used by all 3 of C, C++, assembler
|
# these aren't technically preprocesor args, but used by all 3 of C, C++, assembler
|
||||||
CPPFLAGS += -mlongcalls -mtext-section-literals
|
CPPFLAGS += -mlongcalls -mtext-section-literals
|
||||||
|
|
||||||
LDFLAGS = -nostdlib -Wl,--no-check-sections -L$(BUILD_DIR)sdklib -L$(ROOT)lib -u $(ENTRY_SYMBOL) -Wl,-static -Wl,-Map=$(BUILD_DIR)$(PROGRAM).map $(EXTRA_LDFLAGS)
|
LDFLAGS = -nostdlib -Wl,--no-check-sections -L$(BUILD_DIR)sdklib -L$(ROOT)lib -u $(ENTRY_SYMBOL) -Wl,-static -Wl,-Map=$(BUILD_DIR)$(PROGRAM).map $(EXTRA_LDFLAGS)
|
||||||
|
|
||||||
ifeq ($(SPLIT_SECTIONS),1)
|
ifeq ($(SPLIT_SECTIONS),1)
|
||||||
C_CXX_FLAGS += -ffunction-sections -fdata-sections
|
C_CXX_FLAGS += -ffunction-sections -fdata-sections
|
||||||
|
@ -202,6 +209,9 @@ INC_DIRS = $(PROGRAM_DIR) $(PROGRAM_DIR)include $(ROOT)include
|
||||||
ifeq ($(OWN_LIBC),1)
|
ifeq ($(OWN_LIBC),1)
|
||||||
INC_DIRS += $(ROOT)libc/xtensa-lx106-elf/include
|
INC_DIRS += $(ROOT)libc/xtensa-lx106-elf/include
|
||||||
LDFLAGS += -L$(ROOT)libc/xtensa-lx106-elf/lib
|
LDFLAGS += -L$(ROOT)libc/xtensa-lx106-elf/lib
|
||||||
|
ifeq ($(PRINTF_SCANF_FLOAT_SUPPORT),1)
|
||||||
|
LDFLAGS += -u _printf_float -u _scanf_float
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ("$(V)","1")
|
ifeq ("$(V)","1")
|
||||||
|
|
|
@ -250,7 +250,7 @@ void IRAM sdk_user_start(void) {
|
||||||
|
|
||||||
// .text+0x3a8
|
// .text+0x3a8
|
||||||
void IRAM vApplicationStackOverflowHook(xTaskHandle task, char *task_name) {
|
void IRAM vApplicationStackOverflowHook(xTaskHandle task, char *task_name) {
|
||||||
printf("\"%s\"(stack_size = %lu) overflow the heap_size.\n", task_name, uxTaskGetStackHighWaterMark(task));
|
printf("Task stack overflow (high water mark=%lu name=\"%s\")\n", uxTaskGetStackHighWaterMark(task), task_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// .text+0x3d8
|
// .text+0x3d8
|
||||||
|
|
|
@ -8,32 +8,34 @@
|
||||||
|
|
||||||
void gpio_enable(const uint8_t gpio_num, const gpio_direction_t direction)
|
void gpio_enable(const uint8_t gpio_num, const gpio_direction_t direction)
|
||||||
{
|
{
|
||||||
uint32_t iomux_flags;
|
switch (direction) {
|
||||||
|
|
||||||
switch(direction) {
|
|
||||||
case GPIO_INPUT:
|
case GPIO_INPUT:
|
||||||
iomux_flags = 0;
|
GPIO.ENABLE_OUT_CLEAR = BIT(gpio_num);
|
||||||
|
iomux_set_gpio_function(gpio_num, false);
|
||||||
break;
|
break;
|
||||||
case GPIO_OUTPUT:
|
case GPIO_OUTPUT:
|
||||||
iomux_flags = IOMUX_PIN_OUTPUT_ENABLE;
|
GPIO.CONF[gpio_num] &= ~GPIO_CONF_OPEN_DRAIN;
|
||||||
|
GPIO.ENABLE_OUT_SET = BIT(gpio_num);
|
||||||
|
iomux_set_gpio_function(gpio_num, true);
|
||||||
break;
|
break;
|
||||||
case GPIO_OUT_OPEN_DRAIN:
|
case GPIO_OUT_OPEN_DRAIN:
|
||||||
iomux_flags = IOMUX_PIN_OUTPUT_ENABLE;
|
|
||||||
break;
|
|
||||||
case GPIO_INPUT_PULLUP:
|
|
||||||
iomux_flags = IOMUX_PIN_PULLUP;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return; /* Invalid direction flag */
|
|
||||||
}
|
|
||||||
iomux_set_gpio_function(gpio_num, iomux_flags);
|
|
||||||
if(direction == GPIO_OUT_OPEN_DRAIN)
|
|
||||||
GPIO.CONF[gpio_num] |= GPIO_CONF_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)
|
|
||||||
GPIO.ENABLE_OUT_SET = BIT(gpio_num);
|
GPIO.ENABLE_OUT_SET = BIT(gpio_num);
|
||||||
else
|
iomux_set_gpio_function(gpio_num, true);
|
||||||
GPIO.ENABLE_OUT_CLEAR = BIT(gpio_num);
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void gpio_set_pullup(uint8_t gpio_num, bool enabled, bool enabled_during_sleep)
|
||||||
|
{
|
||||||
|
uint32_t flags = 0;
|
||||||
|
|
||||||
|
if (enabled) {
|
||||||
|
flags |= IOMUX_PIN_PULLUP;
|
||||||
|
}
|
||||||
|
if (enabled_during_sleep) {
|
||||||
|
flags |= IOMUX_PIN_PULLUP_SLEEP;
|
||||||
|
}
|
||||||
|
iomux_set_pullup_flags(gpio_to_iomux(gpio_num), flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,14 +17,24 @@ typedef enum {
|
||||||
GPIO_INPUT,
|
GPIO_INPUT,
|
||||||
GPIO_OUTPUT, /* "Standard" push-pull output */
|
GPIO_OUTPUT, /* "Standard" push-pull output */
|
||||||
GPIO_OUT_OPEN_DRAIN, /* Open drain output */
|
GPIO_OUT_OPEN_DRAIN, /* Open drain output */
|
||||||
GPIO_INPUT_PULLUP,
|
|
||||||
} gpio_direction_t;
|
} gpio_direction_t;
|
||||||
|
|
||||||
/* Enable GPIO on the specified pin, and set it to input/output/ with
|
/* Enable GPIO on the specified pin, and set it to input or output mode
|
||||||
* pullup as needed
|
|
||||||
*/
|
*/
|
||||||
void gpio_enable(const uint8_t gpio_num, const gpio_direction_t direction);
|
void gpio_enable(const uint8_t gpio_num, const gpio_direction_t direction);
|
||||||
|
|
||||||
|
/* Enable/disable internal pullup resistor for a particular GPIO
|
||||||
|
*
|
||||||
|
* Note: According to Espressif, pullup resistor values are between 30K and
|
||||||
|
* 100K ohms (see http://bbs.espressif.com/viewtopic.php?t=1079#p4097)
|
||||||
|
* However, measured values suggest that the actual value is likely to be close
|
||||||
|
* to 47K in reality.
|
||||||
|
*
|
||||||
|
* NOTE: The enabled_during_sleep setting is currently untested (please send
|
||||||
|
* feedback if you give it a try)
|
||||||
|
*/
|
||||||
|
void gpio_set_pullup(uint8_t gpio_num, bool enabled, bool enabled_during_sleep);
|
||||||
|
|
||||||
/* Disable GPIO on the specified pin, and set it Hi-Z.
|
/* Disable GPIO on the specified pin, and set it Hi-Z.
|
||||||
*
|
*
|
||||||
* If later muxing this pin to a different function, make sure to set
|
* If later muxing this pin to a different function, make sure to set
|
||||||
|
@ -36,13 +46,37 @@ static inline void gpio_disable(const uint8_t gpio_num)
|
||||||
*gpio_iomux_reg(gpio_num) &= ~IOMUX_PIN_OUTPUT_ENABLE;
|
*gpio_iomux_reg(gpio_num) &= ~IOMUX_PIN_OUTPUT_ENABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set whether the specified pin continues to drive its output when the ESP8266
|
||||||
|
* goes into sleep mode. Note that this setting is reset to off whenever
|
||||||
|
* gpio_enable is called, so this must be called after calling that function.
|
||||||
|
*
|
||||||
|
* NOTE: This functionality is currently untested (please send feedback if you
|
||||||
|
* give it a try)
|
||||||
|
*/
|
||||||
|
static inline void gpio_set_output_on_sleep(const uint8_t gpio_num, bool enabled)
|
||||||
|
{
|
||||||
|
if (enabled) {
|
||||||
|
IOMUX.PIN[gpio_to_iomux(gpio_num)] |= IOMUX_PIN_OUTPUT_ENABLE_SLEEP;
|
||||||
|
} else {
|
||||||
|
IOMUX.PIN[gpio_to_iomux(gpio_num)] &= ~IOMUX_PIN_OUTPUT_ENABLE_SLEEP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Set output of a pin high or low.
|
/* Set output of a pin high or low.
|
||||||
*
|
*
|
||||||
* Only works if pin has been set to GPIO_OUTPUT via gpio_enable()
|
* Only works if pin has been set to GPIO_OUTPUT or GPIO_OUT_OPEN_DRAIN via
|
||||||
|
* gpio_enable()
|
||||||
|
*
|
||||||
|
* If the mode is GPIO_OUT_OPEN_DRAIN, setting it low (false) will pull the pin
|
||||||
|
* down to ground, but setting it high (true) will allow it to float. Note
|
||||||
|
* that even in GPIO_OUT_OPEN_DRAIN mode, the input gates are still physically
|
||||||
|
* connected to the pin, and can be damaged if the voltage is not in either the
|
||||||
|
* "low" or "high" range. Make sure there is some sort of pull-up resistor on
|
||||||
|
* the line to avoid floating logic lines!
|
||||||
*/
|
*/
|
||||||
static inline void gpio_write(const uint8_t gpio_num, const bool set)
|
static inline void gpio_write(const uint8_t gpio_num, const bool set)
|
||||||
{
|
{
|
||||||
if(set)
|
if (set)
|
||||||
GPIO.OUT_SET = BIT(gpio_num);
|
GPIO.OUT_SET = BIT(gpio_num);
|
||||||
else
|
else
|
||||||
GPIO.OUT_CLEAR = BIT(gpio_num);
|
GPIO.OUT_CLEAR = BIT(gpio_num);
|
||||||
|
@ -50,7 +84,10 @@ static inline void gpio_write(const uint8_t gpio_num, const bool set)
|
||||||
|
|
||||||
/* Toggle output of a pin
|
/* Toggle output of a pin
|
||||||
*
|
*
|
||||||
* Only works if pin has been set to GPIO_OUTPUT via gpio_enable()
|
* Only works if pin has been set to GPIO_OUTPUT or GPIO_OUT_OPEN_DRAIN via
|
||||||
|
* gpio_enable()
|
||||||
|
*
|
||||||
|
* See notes in gpio_write() about GPIO_OUT_OPEN_DRAIN mode.
|
||||||
*/
|
*/
|
||||||
static inline void gpio_toggle(const uint8_t gpio_num)
|
static inline void gpio_toggle(const uint8_t gpio_num)
|
||||||
{
|
{
|
||||||
|
@ -68,8 +105,12 @@ static inline void gpio_toggle(const uint8_t gpio_num)
|
||||||
|
|
||||||
/* Read input value of a GPIO pin.
|
/* 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 GPIO_INPUT, this reads the level on the pin.
|
||||||
* If pin is set as an output, this reads the last value written to the pin.
|
* If pin is set GPIO_OUTPUT, this reads the level at which the pin is
|
||||||
|
* currently being driven (i.e. the last value written).
|
||||||
|
* If pin is set GPIO_OUT_OPEN_DRAIN, when the pin is written low, this will
|
||||||
|
* return low (false), when the pin is written high, this will behave like
|
||||||
|
* GPIO_INPUT.
|
||||||
*/
|
*/
|
||||||
static inline bool gpio_read(const uint8_t gpio_num)
|
static inline bool gpio_read(const uint8_t gpio_num)
|
||||||
{
|
{
|
||||||
|
@ -80,7 +121,8 @@ extern void gpio_interrupt_handler(void);
|
||||||
|
|
||||||
/* Set the interrupt type for a given pin
|
/* Set the interrupt type for a given pin
|
||||||
*
|
*
|
||||||
* If int_type is not GPIO_INTTYPE_NONE, the gpio_interrupt_handler will be attached and unmasked.
|
* If int_type is not GPIO_INTTYPE_NONE, the gpio_interrupt_handler will be
|
||||||
|
* attached and unmasked.
|
||||||
*/
|
*/
|
||||||
static inline void gpio_set_interrupt(const uint8_t gpio_num, const gpio_inttype_t int_type)
|
static inline void gpio_set_interrupt(const uint8_t gpio_num, const gpio_inttype_t int_type)
|
||||||
{
|
{
|
||||||
|
|
|
@ -43,25 +43,41 @@ inline static esp_reg_t gpio_iomux_reg(const uint8_t gpio_number)
|
||||||
return &(IOMUX.PIN[gpio_to_iomux(gpio_number)]);
|
return &(IOMUX.PIN[gpio_to_iomux(gpio_number)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline static void iomux_set_function(uint8_t iomux_num, uint32_t func)
|
||||||
|
{
|
||||||
|
uint32_t prev = IOMUX.PIN[iomux_num] & ~IOMUX_PIN_FUNC_MASK;
|
||||||
|
IOMUX.PIN[iomux_num] = IOMUX_FUNC(func) | prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static void iomux_set_direction_flags(uint8_t iomux_num, uint32_t dir_flags)
|
||||||
|
{
|
||||||
|
uint32_t mask = IOMUX_PIN_OUTPUT_ENABLE | IOMUX_PIN_OUTPUT_ENABLE_SLEEP;
|
||||||
|
uint32_t prev = IOMUX.PIN[iomux_num] & ~mask;
|
||||||
|
IOMUX.PIN[iomux_num] = dir_flags | prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static void iomux_set_pullup_flags(uint8_t iomux_num, uint32_t pullup_flags)
|
||||||
|
{
|
||||||
|
uint32_t mask = IOMUX_PIN_PULLUP | IOMUX_PIN_PULLDOWN | IOMUX_PIN_PULLUP_SLEEP | IOMUX_PIN_PULLDOWN_SLEEP;
|
||||||
|
uint32_t prev = IOMUX.PIN[iomux_num] & ~mask;
|
||||||
|
IOMUX.PIN[iomux_num] = pullup_flags | prev;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set a pin to the GPIO function.
|
* Set a pin to the GPIO function.
|
||||||
*
|
*
|
||||||
* This allows you to set pins to GPIO without knowing in advance the
|
* This allows you to set pins to GPIO without knowing in advance the
|
||||||
* exact register masks to use.
|
* exact register masks to use.
|
||||||
*
|
*
|
||||||
* flags can be any of IOMUX_PIN_OUTPUT_ENABLE, IOMUX_PIN_PULLUP, IOMUX_PIN_PULLDOWN, etc. Any other flags will be cleared.
|
* Sets the function and direction, but leaves the pullup configuration the
|
||||||
*
|
* same as before.
|
||||||
* 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_PIN_OUTPUT_ENABLE);
|
|
||||||
* IOMUX_GPIO12 = IOMUX_GPIO12_FUNC_GPIO | IOMUX_PIN_OUTPUT_ENABLE;
|
|
||||||
*/
|
*/
|
||||||
inline static void iomux_set_gpio_function(const uint8_t gpio_number, const uint32_t flags)
|
inline static void iomux_set_gpio_function(uint8_t gpio_number, bool output_enable)
|
||||||
{
|
{
|
||||||
const uint8_t reg_idx = gpio_to_iomux(gpio_number);
|
const uint8_t iomux_num = gpio_to_iomux(gpio_number);
|
||||||
const uint32_t func = (reg_idx > 11 ? IOMUX_FUNC(0) : IOMUX_FUNC(3)) | flags;
|
const uint32_t func = iomux_num > 11 ? 0 : 3;
|
||||||
IOMUX.PIN[reg_idx] = func | flags;
|
iomux_set_function(iomux_num, func);
|
||||||
|
iomux_set_direction_flags(iomux_num, output_enable ? IOMUX_PIN_OUTPUT_ENABLE : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define _ESP_TYPES_H
|
#define _ESP_TYPES_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
typedef volatile uint32_t *esp_reg_t;
|
typedef volatile uint32_t *esp_reg_t;
|
||||||
|
|
||||||
|
|
43
libc/xtensa-lx106-elf/include/config.h
Normal file
43
libc/xtensa-lx106-elf/include/config.h
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
#ifndef __SYS_CONFIG_H__
|
||||||
|
#define __SYS_CONFIG_H__
|
||||||
|
|
||||||
|
#include <machine/ieeefp.h> /* floating point macros */
|
||||||
|
#include <sys/features.h> /* POSIX defs */
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
esp8266-specific xtensa stuff
|
||||||
|
*************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _REENT_SMALL
|
||||||
|
#define _REENT_SMALL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* esp8266 hardware FIFO buffers are 128 bytes */
|
||||||
|
#define __BUFSIZ__ 128
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
end of esp8266-specific stuff
|
||||||
|
*************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __EXPORT
|
||||||
|
#define __EXPORT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __IMPORT
|
||||||
|
#define __IMPORT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Define return type of read/write routines. In POSIX, the return type
|
||||||
|
for read()/write() is "ssize_t" but legacy newlib code has been using
|
||||||
|
"int" for some time. If not specified, "int" is defaulted. */
|
||||||
|
#ifndef _READ_WRITE_RETURN_TYPE
|
||||||
|
#define _READ_WRITE_RETURN_TYPE int
|
||||||
|
#endif
|
||||||
|
/* Define `count' parameter of read/write routines. In POSIX, the `count'
|
||||||
|
parameter is "size_t" but legacy newlib code has been using "int" for some
|
||||||
|
time. If not specified, "int" is defaulted. */
|
||||||
|
#ifndef _READ_WRITE_BUFSIZE_TYPE
|
||||||
|
#define _READ_WRITE_BUFSIZE_TYPE int
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __SYS_CONFIG_H__ */
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in a new issue