Initial commit
This commit is contained in:
commit
c3ff7276a9
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
build/
|
||||
|
||||
143
Makefile
Normal file
143
Makefile
Normal file
@ -0,0 +1,143 @@
|
||||
# Makefile for ESP8266 projects
|
||||
#
|
||||
# Thanks to:
|
||||
# - zarya
|
||||
# - Jeroen Domburg (Sprite_tm)
|
||||
# - Christian Klippel (mamalala)
|
||||
# - Tommie Gannert (tommie)
|
||||
#
|
||||
# Changelog:
|
||||
# - 2014-10-06: Changed the variables to include the header file directory
|
||||
# - 2014-10-06: Added global var for the Xtensa tool root
|
||||
# - 2014-11-23: Updated for SDK 0.9.3
|
||||
# - 2014-12-25: Replaced esptool by esptool.py
|
||||
|
||||
BUILD_AREA = /Volumes/case-sensitive/esp8266-dev
|
||||
|
||||
# Output directors to store intermediate compiled files
|
||||
# relative to the project directory
|
||||
BUILD_BASE = build
|
||||
FW_BASE = firmware
|
||||
|
||||
# base directory for the compiler
|
||||
XTENSA_TOOLS_ROOT ?= $(BUILD_AREA)/esp-open-sdk/xtensa-lx106-elf/bin
|
||||
|
||||
# # base directory of the ESP8266 SDK package, absolute
|
||||
SDK_BASE ?= $(BUILD_AREA)/esp-open-sdk/sdk
|
||||
|
||||
# # esptool.py path and port
|
||||
ESPTOOL ?= $(BUILD_AREA)/esp-open-sdk/esptool/esptool.py
|
||||
#ESPTOOL ?= /home/martin/.local/bin/esptool.py
|
||||
ESPPORT ?= /dev/tty.wchusbserial1420
|
||||
ESPTOOLBAUD ?= 115200
|
||||
ESPTOOLOPTS = -ff 40m -fm dio -fs 32m
|
||||
|
||||
# name for the target project
|
||||
TARGET = app
|
||||
|
||||
# which modules (subdirectories) of the project to include in compiling
|
||||
MODULES = driver user easygpio
|
||||
EXTRA_INCDIR = include $(BUILD_AREA)/esp-open-sdk/esp-open-lwip/include
|
||||
#EXTRA_INCDIR = include
|
||||
|
||||
# libraries used in this project, mainly provided by the SDK
|
||||
LIBS = c gcc hal pp phy net80211 lwip_open_napt wpa main
|
||||
|
||||
# compiler flags using during compilation of source files
|
||||
CFLAGS = -Os -g -O2 -Wpointer-arith -Wundef -Werror -Wl,-EL -fno-inline-functions -nostdlib -mlongcalls -mtext-section-literals -D__ets__ -DICACHE_FLASH -DLWIP_OPEN_SRC -DUSE_OPTIMIZE_PRINTF
|
||||
|
||||
# linker flags used to generate the main object file
|
||||
LDFLAGS = -nostdlib -Wl,--no-check-sections -u call_user_start -Wl,-static -L.
|
||||
|
||||
# linker script used for the above linkier step
|
||||
LD_SCRIPT = eagle.app.v6.ld
|
||||
|
||||
# various paths from the SDK used in this project
|
||||
SDK_LIBDIR = lib
|
||||
SDK_LDDIR = ld
|
||||
SDK_INCDIR = include include/json
|
||||
|
||||
# we create two different files for uploading into the flash
|
||||
# these are the names and options to generate them
|
||||
FW_FILE_1_ADDR = 0x00000
|
||||
FW_FILE_2_ADDR = 0x10000
|
||||
|
||||
# select which tools to use as compiler, librarian and linker
|
||||
CC := $(XTENSA_TOOLS_ROOT)/xtensa-lx106-elf-gcc
|
||||
AR := $(XTENSA_TOOLS_ROOT)/xtensa-lx106-elf-ar
|
||||
LD := $(XTENSA_TOOLS_ROOT)/xtensa-lx106-elf-gcc
|
||||
|
||||
|
||||
|
||||
####
|
||||
#### no user configurable options below here
|
||||
####
|
||||
SRC_DIR := $(MODULES)
|
||||
BUILD_DIR := $(addprefix $(BUILD_BASE)/,$(MODULES))
|
||||
|
||||
SDK_LIBDIR := $(addprefix $(SDK_BASE)/,$(SDK_LIBDIR))
|
||||
SDK_INCDIR := $(addprefix -I$(SDK_BASE)/,$(SDK_INCDIR))
|
||||
|
||||
SRC := $(foreach sdir,$(SRC_DIR),$(wildcard $(sdir)/*.c))
|
||||
OBJ := $(patsubst %.c,$(BUILD_BASE)/%.o,$(SRC))
|
||||
LIBS := $(addprefix -l,$(LIBS))
|
||||
APP_AR := $(addprefix $(BUILD_BASE)/,$(TARGET)_app.a)
|
||||
TARGET_OUT := $(addprefix $(BUILD_BASE)/,$(TARGET).out)
|
||||
|
||||
LD_SCRIPT := $(addprefix -T$(SDK_BASE)/$(SDK_LDDIR)/,$(LD_SCRIPT))
|
||||
|
||||
INCDIR := $(addprefix -I,$(SRC_DIR))
|
||||
EXTRA_INCDIR := $(addprefix -I,$(EXTRA_INCDIR))
|
||||
MODULE_INCDIR := $(addsuffix /include,$(INCDIR))
|
||||
|
||||
FW_FILE_1 := $(addprefix $(FW_BASE)/,$(FW_FILE_1_ADDR).bin)
|
||||
FW_FILE_2 := $(addprefix $(FW_BASE)/,$(FW_FILE_2_ADDR).bin)
|
||||
|
||||
V ?= $(VERBOSE)
|
||||
ifeq ("$(V)","1")
|
||||
Q :=
|
||||
vecho := @true
|
||||
else
|
||||
Q := @
|
||||
vecho := @echo
|
||||
endif
|
||||
|
||||
vpath %.c $(SRC_DIR)
|
||||
|
||||
define compile-objects
|
||||
$1/%.o: %.c
|
||||
$(vecho) "CC $$<"
|
||||
$(Q) $(CC) $(INCDIR) $(MODULE_INCDIR) $(EXTRA_INCDIR) $(SDK_INCDIR) $(CFLAGS) -c $$< -o $$@
|
||||
endef
|
||||
|
||||
.PHONY: all checkdirs flash clean
|
||||
|
||||
all: checkdirs $(TARGET_OUT) $(FW_FILE_1) $(FW_FILE_2)
|
||||
|
||||
$(FW_BASE)/%.bin: $(TARGET_OUT) | $(FW_BASE)
|
||||
$(vecho) "FW $(FW_BASE)/"
|
||||
$(Q) $(ESPTOOL) elf2image -o $(FW_BASE)/ $(TARGET_OUT)
|
||||
|
||||
$(TARGET_OUT): $(APP_AR)
|
||||
$(vecho) "LD $@"
|
||||
$(Q) $(LD) -L$(SDK_LIBDIR) $(LD_SCRIPT) $(LDFLAGS) -Wl,--start-group $(LIBS) $(APP_AR) -Wl,--end-group -o $@
|
||||
|
||||
$(APP_AR): $(OBJ)
|
||||
$(vecho) "AR $@"
|
||||
$(Q) $(AR) cru $@ $^
|
||||
|
||||
checkdirs: $(BUILD_DIR) $(FW_BASE)
|
||||
|
||||
$(BUILD_DIR):
|
||||
$(Q) mkdir -p $@
|
||||
|
||||
$(FW_BASE):
|
||||
$(Q) mkdir -p $@
|
||||
|
||||
flash: $(FW_FILE_1) $(FW_FILE_2)
|
||||
$(ESPTOOL) --port $(ESPPORT) --baud $(ESPTOOLBAUD) write_flash $(ESPTOOLOPTS) $(FW_FILE_1_ADDR) $(FW_FILE_1) $(FW_FILE_2_ADDR) $(FW_FILE_2)
|
||||
|
||||
clean:
|
||||
$(Q) rm -rf $(FW_BASE) $(BUILD_BASE)
|
||||
|
||||
$(foreach bdir,$(BUILD_DIR),$(eval $(call compile-objects,$(bdir))))
|
||||
14
README.md
Normal file
14
README.md
Normal file
@ -0,0 +1,14 @@
|
||||
# ESPerPass
|
||||
A 3DS HomePass implementation for the ESP8266 programmable WiFi chip.
|
||||
Inspired by [this reddit post](https://www.reddit.com/r/3DS/comments/80k0qb/homepass_for_cheap_using_an_esp8266/)
|
||||
and largely based on the great work done by [Martin Ger's ESP WiFi Repeater](https://github.com/martin-ger/esp_wifi_repeater).
|
||||
|
||||
## Instructions (need improvement)
|
||||
1. Flash firmware.
|
||||
2. Connect ESP8266 to USB and connect with terminal program.
|
||||
3. Power cycle ESP8266.
|
||||
3. Follow instructions in terminal program.
|
||||
|
||||
## TODO
|
||||
* Implement firewall rules to restrict connections to official servers.
|
||||
* Implement mac address list management through console.
|
||||
471
driver/new_uart.c
Normal file
471
driver/new_uart.c
Normal file
@ -0,0 +1,471 @@
|
||||
/*
|
||||
* File : uart.c
|
||||
* Copyright (C) 2013 - 2016, Espressif Systems
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of version 3 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program 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. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "ets_sys.h"
|
||||
#include "osapi.h"
|
||||
#include "driver/uart.h"
|
||||
#include "osapi.h"
|
||||
#include "driver/uart_register.h"
|
||||
#include "mem.h"
|
||||
#include "os_type.h"
|
||||
|
||||
#ifdef _ENABLE_RING_BUFFER
|
||||
static ringbuf_t rxBuff;
|
||||
static ringbuf_t txBuff;
|
||||
#endif
|
||||
|
||||
#ifdef _ENABLE_CONSOLE_INTEGRATION
|
||||
uint8_t linked_to_console = 0;
|
||||
#endif
|
||||
|
||||
extern UartDevice UartDev;
|
||||
|
||||
/* Local variables */
|
||||
static uint8 uart_recvTaskPrio = 0;
|
||||
|
||||
/* Internal Functions */
|
||||
static void ICACHE_FLASH_ATTR uart_config(uint8 uart_no);
|
||||
static void uart0_rx_intr_handler(void *para);
|
||||
|
||||
/* Public APIs */
|
||||
void ICACHE_FLASH_ATTR UART_init(UartBautRate uart0_br, UartBautRate uart1_br, uint8 recv_task_priority);
|
||||
|
||||
#define ENABLE_DEBUG
|
||||
|
||||
#ifdef ENABLE_DEBUG
|
||||
#define DBG
|
||||
#define DBG1 os_printf
|
||||
#define DBG2 os_printf
|
||||
#else
|
||||
#define DBG
|
||||
#define DBG1
|
||||
#define DBG2
|
||||
#endif
|
||||
|
||||
#if _ENABLE_CONSOLE_INTEGRATION == 1
|
||||
void ICACHE_FLASH_ATTR UART_init_console(UartBautRate uart0_br,
|
||||
uint8 recv_task_priority,
|
||||
ringbuf_t rxbuffer,
|
||||
ringbuf_t txBuffer)
|
||||
{
|
||||
/* Set the task which should receive the signals once the data is received */
|
||||
uart_recvTaskPrio = recv_task_priority;
|
||||
|
||||
UartDev.baut_rate = uart0_br;
|
||||
rxBuff = rxbuffer;
|
||||
txBuff = txBuffer;
|
||||
linked_to_console = 1;
|
||||
|
||||
uart_config(UART0);
|
||||
UART_SetPrintPort(UART0);
|
||||
|
||||
UartDev.baut_rate = uart0_br;
|
||||
uart_config(UART1);
|
||||
|
||||
ETS_UART_INTR_ENABLE();
|
||||
}
|
||||
#endif
|
||||
|
||||
void ICACHE_FLASH_ATTR UART_init(UartBautRate uart0_br, UartBautRate uart1_br, uint8 recv_task_priority)
|
||||
{
|
||||
/* Set the task which should receive the signals once the data is received */
|
||||
uart_recvTaskPrio = recv_task_priority;
|
||||
|
||||
UartDev.baut_rate = uart0_br;
|
||||
uart_config(UART0);
|
||||
|
||||
UART_SetPrintPort(UART0);
|
||||
|
||||
UartDev.baut_rate = uart1_br;
|
||||
uart_config(UART1);
|
||||
|
||||
ETS_UART_INTR_ENABLE();
|
||||
|
||||
#if _ENABLE_CONSOLE_INTEGRATION == 0
|
||||
#if _ENABLE_RING_BUFFER == 1
|
||||
rxBuff = ringbuf_new(RX_RING_BUFFER_SIZE);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* FunctionName : uart_config
|
||||
* Description : Internal used function
|
||||
* UART0 used for data TX/RX, RX buffer size is 0x100, interrupt enabled
|
||||
* UART1 just used for debug output
|
||||
* Parameters : uart_no, use UART0 or UART1 defined ahead
|
||||
* Returns : NONE
|
||||
*******************************************************************************/
|
||||
LOCAL void ICACHE_FLASH_ATTR uart_config(uint8 uart_no)
|
||||
{
|
||||
if (uart_no == UART1)
|
||||
{
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_U1TXD_BK);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* rcv_buff size if 0x100 */
|
||||
ETS_UART_INTR_ATTACH(uart0_rx_intr_handler, &(UartDev.rcv_buff));
|
||||
PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U);
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD);
|
||||
|
||||
#if UART_HW_RTS
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_U0RTS); //HW FLOW CONTROL RTS PIN
|
||||
#endif
|
||||
|
||||
#if UART_HW_CTS
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_U0CTS); //HW FLOW CONTROL CTS PIN
|
||||
#endif
|
||||
}
|
||||
uart_div_modify(uart_no, UART_CLK_FREQ / (UartDev.baut_rate));//SET BAUDRATE
|
||||
|
||||
WRITE_PERI_REG(UART_CONF0(uart_no), ((UartDev.exist_parity & UART_PARITY_EN_M) << UART_PARITY_EN_S) //SET BIT AND PARITY MODE
|
||||
| ((UartDev.parity & UART_PARITY_M) <<UART_PARITY_S )
|
||||
| ((UartDev.stop_bits & UART_STOP_BIT_NUM) << UART_STOP_BIT_NUM_S)
|
||||
| ((UartDev.data_bits & UART_BIT_NUM) << UART_BIT_NUM_S));
|
||||
|
||||
//clear rx and tx fifo,not ready
|
||||
SET_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST); //RESET FIFO
|
||||
CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST);
|
||||
|
||||
if (uart_no == UART0)
|
||||
{
|
||||
int rx_threshold = 10;
|
||||
|
||||
#if _ENABLE_CONSOLE_INTEGRATION == 1
|
||||
rx_threshold = 1;
|
||||
#endif
|
||||
|
||||
//set rx fifo trigger
|
||||
WRITE_PERI_REG(UART_CONF1(uart_no),
|
||||
((rx_threshold & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S) |
|
||||
#if UART_HW_RTS
|
||||
((110 & UART_RX_FLOW_THRHD) << UART_RX_FLOW_THRHD_S) |
|
||||
UART_RX_FLOW_EN | //enbale rx flow control
|
||||
#endif
|
||||
// (0x02 & UART_RX_TOUT_THRHD) << UART_RX_TOUT_THRHD_S |
|
||||
// UART_RX_TOUT_EN|
|
||||
((0x10 & UART_TXFIFO_EMPTY_THRHD)<<UART_TXFIFO_EMPTY_THRHD_S));//wjl
|
||||
#if UART_HW_CTS
|
||||
SET_PERI_REG_MASK( UART_CONF0(uart_no),UART_TX_FLOW_EN); //add this sentense to add a tx flow control via MTCK( CTS )
|
||||
#endif
|
||||
SET_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_RXFIFO_TOUT_INT_ENA |UART_FRM_ERR_INT_ENA);
|
||||
}
|
||||
else
|
||||
{
|
||||
WRITE_PERI_REG(UART_CONF1(uart_no),((UartDev.rcv_buff.TrigLvl & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S));//TrigLvl default val == 1
|
||||
}
|
||||
//clear all interrupt
|
||||
WRITE_PERI_REG(UART_INT_CLR(uart_no), 0xffff);
|
||||
|
||||
//enable rx_interrupt
|
||||
SET_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_RXFIFO_FULL_INT_ENA|UART_RXFIFO_OVF_INT_ENA);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* FunctionName : UART_Recv
|
||||
* Description : Public API, unloads the contents of the Rx FIFO for specified
|
||||
* uart into the buffer specified. Will unload upto buffer size
|
||||
* only
|
||||
* Parameters : IN uart number (uart_no)
|
||||
* IN/OUT char *buffer
|
||||
* IN int max_buf_len
|
||||
* Returns : int (number of bytes unloaded ) 0 if FIFO is empty
|
||||
*******************************************************************************/
|
||||
int UART_Recv(uint8 uart_no, char *buffer, int max_buf_len)
|
||||
{
|
||||
uint8 max_unload, index = -1;
|
||||
|
||||
#if _ENABLE_RING_BUFFER == 1
|
||||
/* If the ring buffer is enabled, then unload from Rx Ring Buffer */
|
||||
uint8 bytes_ringbuffer = ringbuf_bytes_used(rxBuff);
|
||||
|
||||
//ring_buffer_dump(rxBuff);
|
||||
if (bytes_ringbuffer)
|
||||
{
|
||||
max_unload = (bytes_ringbuffer<max_buf_len ? bytes_ringbuffer: max_buf_len);
|
||||
|
||||
ringbuf_memcpy_from(buffer, rxBuff, max_unload);
|
||||
}
|
||||
#else
|
||||
/* If the ring buffer is not enabled, then unload from Rx FIFO */
|
||||
uint8 fifo_len = (READ_PERI_REG(UART_STATUS(uart_no))>>UART_RXFIFO_CNT_S)&UART_RXFIFO_CNT;
|
||||
|
||||
if (fifo_len)
|
||||
{
|
||||
max_unload = (fifo_len<max_buf_len ? fifo_len : max_buf_len);
|
||||
DBG1("Rx Fifo contains %d characters have to unload %d\r\n", fifo_len , max_unload);
|
||||
|
||||
for (index=0;index<max_unload; index++)
|
||||
{
|
||||
*(buffer+index) = READ_PERI_REG(UART_FIFO(UART0)) & 0xFF;
|
||||
}
|
||||
//return index;
|
||||
WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_RXFIFO_FULL_INT_CLR);
|
||||
uart_rx_intr_enable(uart_no);
|
||||
}
|
||||
#endif
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
int UART_Send(uint8 uart_no, char *buffer, int len)
|
||||
{
|
||||
int index = 0;
|
||||
char ch ;
|
||||
|
||||
//DBG1("Sending: %s\n", buffer);
|
||||
for (index=0; index <len; index ++)
|
||||
{
|
||||
ch = *(buffer+index);
|
||||
uart_tx_one_char(uart_no, ch);
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
* Internal Functions
|
||||
*---------------------------------------------------------------------------*/
|
||||
/******************************************************************************
|
||||
* FunctionName : uart_rx_intr_disable
|
||||
* Description : Internal used function disables the uart interrupts
|
||||
* Parameters : IN uart number (uart_no)
|
||||
* Returns : NONE
|
||||
*******************************************************************************/
|
||||
void uart_rx_intr_disable(uint8 uart_no)
|
||||
{
|
||||
//DBG1("RxIntr Disabled\r\n");
|
||||
#if 1
|
||||
CLEAR_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_RXFIFO_FULL_INT_ENA|UART_RXFIFO_TOUT_INT_ENA);
|
||||
#else
|
||||
ETS_UART_INTR_DISABLE();
|
||||
#endif
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* FunctionName : uart_rx_intr_enable
|
||||
* Description : Internal used function enables the uart interrupts
|
||||
* Parameters : IN uart number (uart_no)
|
||||
* Returns : NONE
|
||||
*******************************************************************************/
|
||||
void uart_rx_intr_enable(uint8 uart_no)
|
||||
{
|
||||
//DBG1("RxIntr Enabled\r\n");
|
||||
#if 1
|
||||
SET_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_RXFIFO_FULL_INT_ENA|UART_RXFIFO_TOUT_INT_ENA);
|
||||
#else
|
||||
ETS_UART_INTR_ENABLE();
|
||||
#endif
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* FunctionName : uart0_rx_intr_handler
|
||||
* Description : Internal used function
|
||||
* UART0 interrupt handler, add self handle code inside
|
||||
* Parameters : void *para - point to ETS_UART_INTR_ATTACH's arg
|
||||
* Returns : NONE
|
||||
*******************************************************************************/
|
||||
static void uart0_rx_intr_handler(void *para)
|
||||
{
|
||||
uint8 uart_no = UART0;//UartDev.buff_uart_no;
|
||||
|
||||
/* Is the frame Error interrupt set ? */
|
||||
if(UART_FRM_ERR_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_FRM_ERR_INT_ST))
|
||||
{
|
||||
/* The Frame Error (UART_FRM_ERR_INT_ST) has bee set */
|
||||
DBG1("Frame Error\r\n");
|
||||
WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_FRM_ERR_INT_CLR);
|
||||
goto end_int_handler;
|
||||
}
|
||||
|
||||
if(UART_RXFIFO_FULL_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_FULL_INT_ST))
|
||||
{
|
||||
/* Rx FIFO is full, hence the interrupt */
|
||||
#if _ENABLE_RING_BUFFER == 1
|
||||
uint16_t index;
|
||||
uint16_t fifo_len = (READ_PERI_REG(UART_STATUS(uart_no))>>UART_RXFIFO_CNT_S)&UART_RXFIFO_CNT;
|
||||
//DBG1("RX FIFO FULL [%d]\r\n", fifo_len );
|
||||
|
||||
if (fifo_len)
|
||||
{
|
||||
//DBG1("Rx Fifo contains %d characters have to unload\r\n", fifo_len);
|
||||
|
||||
for (index=0;index<fifo_len; index++)
|
||||
{
|
||||
uint8_t ch = (READ_PERI_REG(UART_FIFO(UART0)) & 0xFF);
|
||||
|
||||
//if (ch == '\r') ch = '\n';
|
||||
ringbuf_memcpy_into(rxBuff, &ch, 1);
|
||||
#if _ENABLE_CONSOLE_INTEGRATION == 1
|
||||
uart_tx_one_char(uart_no, ch);
|
||||
if (ch == '\r')
|
||||
{
|
||||
system_os_post(0, SIG_CONSOLE_RX, 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_RXFIFO_FULL_INT_CLR);
|
||||
uart_rx_intr_enable(uart_no);
|
||||
#if _ENABLE_CONSOLE_INTEGRATION == 0
|
||||
system_os_post(uart_recvTaskPrio, SIG_UART0, 0);
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
DBG1("RX FIFO FULL [%d]\r\n", (READ_PERI_REG(UART_STATUS(uart_no))>>UART_RXFIFO_CNT_S)& UART_RXFIFO_CNT);
|
||||
uart_rx_intr_disable(UART0);
|
||||
WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_FULL_INT_CLR);
|
||||
system_os_post(uart_recvTaskPrio, SIG_UART0, 0);
|
||||
#endif
|
||||
|
||||
goto end_int_handler;
|
||||
}
|
||||
|
||||
if(UART_RXFIFO_TOUT_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_TOUT_INT_ST))
|
||||
{
|
||||
/* The Time out threshold for Rx/Tx is being execeeded */
|
||||
DBG1("Rx Timeout Threshold not being met \r\n");
|
||||
uart_rx_intr_disable(UART0);
|
||||
WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_TOUT_INT_CLR);
|
||||
|
||||
system_os_post(uart_recvTaskPrio, SIG_UART0, 0);
|
||||
goto end_int_handler;
|
||||
}
|
||||
|
||||
if(UART_TXFIFO_EMPTY_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_TXFIFO_EMPTY_INT_ST))
|
||||
{
|
||||
/* The Tx FIFO is empty, the FIFO needs to be fed with new data */
|
||||
DBG1("Tx FIFO is empty\r\n");
|
||||
CLEAR_PERI_REG_MASK(UART_INT_ENA(UART0), UART_TXFIFO_EMPTY_INT_ENA);
|
||||
|
||||
#if UART_BUFF_EN
|
||||
tx_start_uart_buffer(UART0);
|
||||
#endif
|
||||
//system_os_post(uart_recvTaskPrio, 1, 0);
|
||||
WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_TXFIFO_EMPTY_INT_CLR);
|
||||
}
|
||||
|
||||
end_int_handler:
|
||||
return;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* FunctionName : uart_tx_one_char_no_wait
|
||||
* Description : uart tx a single char without waiting for fifo
|
||||
* Parameters : uint8 uart - uart port
|
||||
* uint8 TxChar - char to tx
|
||||
* Returns : STATUS
|
||||
*******************************************************************************/
|
||||
STATUS uart_tx_one_char(uint8 uart, uint8 TxChar)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
uint32 fifo_cnt = READ_PERI_REG(UART_STATUS(uart)) & (UART_TXFIFO_CNT<<UART_TXFIFO_CNT_S);
|
||||
if ((fifo_cnt >> UART_TXFIFO_CNT_S & UART_TXFIFO_CNT) < 126) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
WRITE_PERI_REG(UART_FIFO(uart) , TxChar);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* FunctionName : uart_tx_one_char_no_wait
|
||||
* Description : uart tx a single char without waiting for fifo
|
||||
* Parameters : uint8 uart - uart port
|
||||
* uint8 TxChar - char to tx
|
||||
* Returns : STATUS
|
||||
*******************************************************************************/
|
||||
STATUS uart_tx_one_char_no_wait(uint8 uart, uint8 TxChar)
|
||||
{
|
||||
uint8 fifo_cnt = (( READ_PERI_REG(UART_STATUS(uart))>>UART_TXFIFO_CNT_S)& UART_TXFIFO_CNT);
|
||||
if (fifo_cnt < 126)
|
||||
{
|
||||
WRITE_PERI_REG(UART_FIFO(uart) , TxChar);
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* FunctionName : uart0_write_char_no_wait
|
||||
* Description : tx a single char without waiting for uart 0.
|
||||
helper function for os_printf output to fifo or tx buffer
|
||||
* Parameters : uint8 uart - uart port
|
||||
* uint8 TxChar - char to tx
|
||||
* Returns : STATUS
|
||||
*******************************************************************************/
|
||||
LOCAL void ICACHE_FLASH_ATTR uart0_write_char_no_wait(char c)
|
||||
{
|
||||
#if UART_BUFF_EN //send to uart0 fifo but do not wait
|
||||
uint8 chr;
|
||||
if (c == '\n'){
|
||||
chr = '\r';
|
||||
tx_buff_enq(&chr, 1);
|
||||
chr = '\n';
|
||||
tx_buff_enq(&chr, 1);
|
||||
}else if (c == '\r'){
|
||||
|
||||
}else{
|
||||
tx_buff_enq(&c,1);
|
||||
}
|
||||
#else //send to uart tx buffer
|
||||
if (c == '\n')
|
||||
{
|
||||
uart_tx_one_char(UART0, '\r');
|
||||
uart_tx_one_char(UART0, '\n');
|
||||
|
||||
//uart_tx_one_char_no_wait(UART0, '\r');
|
||||
//uart_tx_one_char_no_wait(UART0, '\n');
|
||||
}
|
||||
else
|
||||
if (c == '\r')
|
||||
{
|
||||
uart_tx_one_char(UART0, c);
|
||||
}
|
||||
else
|
||||
{
|
||||
uart_tx_one_char(UART0, c);
|
||||
//uart_tx_one_char_no_wait(UART0, c);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* FunctionName : UART_SetPrintPort
|
||||
* Description :
|
||||
*
|
||||
* Parameters :
|
||||
* Returns : NONE
|
||||
*******************************************************************************/
|
||||
void ICACHE_FLASH_ATTR UART_SetPrintPort(uint8 uart_no)
|
||||
{
|
||||
if(uart_no==1)
|
||||
{
|
||||
//os_install_putc1(uart1_write_char);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*option 1: do not wait if uart fifo is full,drop current character*/
|
||||
//os_install_putc1(uart0_write_char_no_wait);
|
||||
/*option 2: wait for a while if uart fifo is full*/
|
||||
//os_install_putc1(uart0_write_char);
|
||||
}
|
||||
}
|
||||
|
||||
343
easygpio/easygpio.c
Normal file
343
easygpio/easygpio.c
Normal file
@ -0,0 +1,343 @@
|
||||
/*
|
||||
* easygpio.c
|
||||
*
|
||||
* Copyright (c) 2015, eadf (https://github.com/eadf)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of Redis nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "easygpio.h"
|
||||
#include "gpio.h"
|
||||
#include "osapi.h"
|
||||
#include "ets_sys.h"
|
||||
|
||||
#define EASYGPIO_USE_GPIO_INPUT_GET
|
||||
|
||||
static void ICACHE_FLASH_ATTR
|
||||
gpio16_output_conf(void) {
|
||||
WRITE_PERI_REG(PAD_XPD_DCDC_CONF,
|
||||
(READ_PERI_REG(PAD_XPD_DCDC_CONF) & 0xffffffbcUL) | 0x1UL); // mux configuration for XPD_DCDC to output rtc_gpio0
|
||||
|
||||
WRITE_PERI_REG(RTC_GPIO_CONF,
|
||||
(READ_PERI_REG(RTC_GPIO_CONF) & 0xfffffffeUL) | 0x0UL); //mux configuration for out enable
|
||||
|
||||
WRITE_PERI_REG(RTC_GPIO_ENABLE,
|
||||
(READ_PERI_REG(RTC_GPIO_ENABLE) & 0xfffffffeUL) | 0x1UL); //out enable
|
||||
}
|
||||
|
||||
static void ICACHE_FLASH_ATTR
|
||||
gpio16_input_conf(void) {
|
||||
WRITE_PERI_REG(PAD_XPD_DCDC_CONF,
|
||||
(READ_PERI_REG(PAD_XPD_DCDC_CONF) & 0xffffffbcUL) | 0x1UL); // mux configuration for XPD_DCDC and rtc_gpio0 connection
|
||||
|
||||
WRITE_PERI_REG(RTC_GPIO_CONF,
|
||||
(READ_PERI_REG(RTC_GPIO_CONF) & 0xfffffffeUL) | 0x0UL); //mux configuration for out enable
|
||||
|
||||
WRITE_PERI_REG(RTC_GPIO_ENABLE,
|
||||
READ_PERI_REG(RTC_GPIO_ENABLE) & 0xfffffffeUL); //out disable
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of active pins in the gpioMask.
|
||||
*/
|
||||
uint8_t ICACHE_FLASH_ATTR
|
||||
easygpio_countBits(uint32_t gpioMask) {
|
||||
|
||||
uint8_t i=0;
|
||||
uint8_t numberOfPins=0;
|
||||
for (i=0; i<32; i++){
|
||||
numberOfPins += (gpioMask & BIT(i))?1:0;
|
||||
}
|
||||
return numberOfPins;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the gpio name and func for a specific pin.
|
||||
*/
|
||||
bool ICACHE_FLASH_ATTR
|
||||
easygpio_getGPIONameFunc(uint8_t gpio_pin, uint32_t *gpio_name, uint8_t *gpio_func) {
|
||||
|
||||
if (gpio_pin == 6 || gpio_pin == 7 || gpio_pin == 8 || gpio_pin == 11 || gpio_pin >= 17) {
|
||||
os_printf("easygpio_getGPIONameFunc Error: There is no GPIO%d, check your code\n", gpio_pin);
|
||||
return false;
|
||||
}
|
||||
if (gpio_pin == 16) {
|
||||
os_printf("easygpio_getGPIONameFunc Error: GPIO16 does not have gpio_name and gpio_func\n");
|
||||
return false;
|
||||
}
|
||||
switch ( gpio_pin ) {
|
||||
case 0:
|
||||
*gpio_func = FUNC_GPIO0;
|
||||
*gpio_name = PERIPHS_IO_MUX_GPIO0_U;
|
||||
return true;
|
||||
case 1:
|
||||
*gpio_func = FUNC_GPIO1;
|
||||
*gpio_name = PERIPHS_IO_MUX_U0TXD_U;
|
||||
return true;
|
||||
case 2:
|
||||
*gpio_func = FUNC_GPIO2;
|
||||
*gpio_name = PERIPHS_IO_MUX_GPIO2_U;
|
||||
return true;
|
||||
case 3:
|
||||
*gpio_func = FUNC_GPIO3;
|
||||
*gpio_name = PERIPHS_IO_MUX_U0RXD_U;
|
||||
return true;
|
||||
case 4:
|
||||
*gpio_func = FUNC_GPIO4;
|
||||
*gpio_name = PERIPHS_IO_MUX_GPIO4_U;
|
||||
return true;
|
||||
case 5:
|
||||
*gpio_func = FUNC_GPIO5;
|
||||
*gpio_name = PERIPHS_IO_MUX_GPIO5_U;
|
||||
return true;
|
||||
case 9:
|
||||
*gpio_func = FUNC_GPIO9;
|
||||
*gpio_name = PERIPHS_IO_MUX_SD_DATA2_U;
|
||||
return true;
|
||||
case 10:
|
||||
*gpio_func = FUNC_GPIO10;
|
||||
*gpio_name = PERIPHS_IO_MUX_SD_DATA3_U;
|
||||
return true;
|
||||
case 12:
|
||||
*gpio_func = FUNC_GPIO12;
|
||||
*gpio_name = PERIPHS_IO_MUX_MTDI_U;
|
||||
return true;
|
||||
case 13:
|
||||
*gpio_func = FUNC_GPIO13;
|
||||
*gpio_name = PERIPHS_IO_MUX_MTCK_U;
|
||||
return true;
|
||||
case 14:
|
||||
*gpio_func = FUNC_GPIO14;
|
||||
*gpio_name = PERIPHS_IO_MUX_MTMS_U;
|
||||
return true;
|
||||
case 15:
|
||||
*gpio_func = FUNC_GPIO15;
|
||||
*gpio_name = PERIPHS_IO_MUX_MTDO_U;
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the pull up registers for a pin.
|
||||
*/
|
||||
static void ICACHE_FLASH_ATTR
|
||||
easygpio_setupPullsByName(uint32_t gpio_name, EasyGPIO_PullStatus pullStatus) {
|
||||
|
||||
if (EASYGPIO_PULLUP == pullStatus) {
|
||||
PIN_PULLUP_EN(gpio_name);
|
||||
} else {
|
||||
PIN_PULLUP_DIS(gpio_name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the pull registers for a pin.
|
||||
*/
|
||||
bool ICACHE_FLASH_ATTR
|
||||
easygpio_pullMode(uint8_t gpio_pin, EasyGPIO_PullStatus pullStatus) {
|
||||
uint32_t gpio_name;
|
||||
uint8_t gpio_func;
|
||||
|
||||
if (!easygpio_getGPIONameFunc(gpio_pin, &gpio_name, &gpio_func) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
easygpio_setupPullsByName(gpio_name, pullStatus);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the 'gpio_pin' pin as a GPIO and sets the pull register for that pin.
|
||||
* 'pullStatus' has no effect on output pins or GPIO16
|
||||
*/
|
||||
bool ICACHE_FLASH_ATTR
|
||||
easygpio_pinMode(uint8_t gpio_pin, EasyGPIO_PullStatus pullStatus, EasyGPIO_PinMode pinMode) {
|
||||
uint32_t gpio_name;
|
||||
uint8_t gpio_func;
|
||||
|
||||
if (16==gpio_pin) {
|
||||
// ignoring pull status on GPIO16 for now
|
||||
if (EASYGPIO_OUTPUT == pinMode) {
|
||||
gpio16_output_conf();
|
||||
} else {
|
||||
gpio16_input_conf();
|
||||
}
|
||||
return true;
|
||||
} else if (!easygpio_getGPIONameFunc(gpio_pin, &gpio_name, &gpio_func) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
PIN_FUNC_SELECT(gpio_name, gpio_func);
|
||||
easygpio_setupPullsByName(gpio_name, pullStatus);
|
||||
|
||||
if (EASYGPIO_OUTPUT != pinMode) {
|
||||
GPIO_DIS_OUTPUT(GPIO_ID_PIN(gpio_pin));
|
||||
} else {
|
||||
// must enable the pin or else the WRITE_PERI_REG won't work
|
||||
gpio_output_set(0, 0, BIT(GPIO_ID_PIN(gpio_pin)),0);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the 'gpio_pin' pin as a GPIO and sets the interrupt to trigger on that pin.
|
||||
* The 'interruptArg' is the function argument that will be sent to your interruptHandler
|
||||
*/
|
||||
bool ICACHE_FLASH_ATTR
|
||||
easygpio_attachInterrupt(uint8_t gpio_pin, EasyGPIO_PullStatus pullStatus, void (*interruptHandler)(void *arg), void *interruptArg) {
|
||||
uint32_t gpio_name;
|
||||
uint8_t gpio_func;
|
||||
|
||||
if (gpio_pin == 16) {
|
||||
os_printf("easygpio_setupInterrupt Error: GPIO16 does not have interrupts\n");
|
||||
return false;
|
||||
}
|
||||
if (!easygpio_getGPIONameFunc(gpio_pin, &gpio_name, &gpio_func) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ETS_GPIO_INTR_ATTACH(interruptHandler, interruptArg);
|
||||
ETS_GPIO_INTR_DISABLE();
|
||||
|
||||
PIN_FUNC_SELECT(gpio_name, gpio_func);
|
||||
|
||||
easygpio_setupPullsByName(gpio_name, pullStatus);
|
||||
|
||||
// disable output
|
||||
GPIO_DIS_OUTPUT(gpio_pin);
|
||||
|
||||
gpio_register_set(GPIO_PIN_ADDR(gpio_pin), GPIO_PIN_INT_TYPE_SET(GPIO_PIN_INTR_DISABLE)
|
||||
| GPIO_PIN_PAD_DRIVER_SET(GPIO_PAD_DRIVER_DISABLE)
|
||||
| GPIO_PIN_SOURCE_SET(GPIO_AS_PIN_SOURCE));
|
||||
|
||||
//clear gpio14 status
|
||||
GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, BIT(gpio_pin));
|
||||
ETS_GPIO_INTR_ENABLE();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detach the interrupt handler from the 'gpio_pin' pin.
|
||||
*/
|
||||
bool ICACHE_FLASH_ATTR
|
||||
easygpio_detachInterrupt(uint8_t gpio_pin) {
|
||||
|
||||
if (gpio_pin == 16) {
|
||||
os_printf("easygpio_setupInterrupt Error: GPIO16 does not have interrupts\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Don't know how to detach interrupt, yet.
|
||||
// Quick and dirty fix - just disable the interrupt
|
||||
gpio_pin_intr_state_set(GPIO_ID_PIN(gpio_pin), GPIO_PIN_INTR_DISABLE);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uniform way of setting GPIO output value. Handles GPIO 0-16.
|
||||
*
|
||||
* You can not rely on that this function will switch the gpio to an output like GPIO_OUTPUT_SET does.
|
||||
* Use easygpio_outputEnable() to change an input gpio to output mode.
|
||||
*/
|
||||
void
|
||||
easygpio_outputSet(uint8_t gpio_pin, uint8_t value) {
|
||||
if (16==gpio_pin) {
|
||||
WRITE_PERI_REG(RTC_GPIO_OUT,
|
||||
(READ_PERI_REG(RTC_GPIO_OUT) & 0xfffffffeUL) | (0x1UL & value));
|
||||
} else {
|
||||
#ifdef EASYGPIO_USE_GPIO_OUTPUT_SET
|
||||
GPIO_OUTPUT_SET(GPIO_ID_PIN(gpio_pin), value);
|
||||
#else
|
||||
if (value&1){
|
||||
WRITE_PERI_REG( PERIPHS_GPIO_BASEADDR, READ_PERI_REG(PERIPHS_GPIO_BASEADDR) | BIT(gpio_pin));
|
||||
} else {
|
||||
WRITE_PERI_REG( PERIPHS_GPIO_BASEADDR, READ_PERI_REG(PERIPHS_GPIO_BASEADDR) & ~BIT(gpio_pin));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Uniform way of getting GPIO input value. Handles GPIO 0-16.
|
||||
* The pin must be initiated with easygpio_pinMode() so that the pin mux is setup as a gpio in the first place.
|
||||
* If you know that you won't be using GPIO16 then you'd better off by just using GPIO_INPUT_GET().
|
||||
*/
|
||||
uint8_t
|
||||
easygpio_inputGet(uint8_t gpio_pin) {
|
||||
if (16==gpio_pin) {
|
||||
return (READ_PERI_REG(RTC_GPIO_IN_DATA) & 1UL);
|
||||
} else {
|
||||
#ifdef EASYGPIO_USE_GPIO_INPUT_GET
|
||||
return GPIO_INPUT_GET(GPIO_ID_PIN(gpio_pin));
|
||||
#else
|
||||
// this does *not* work, maybe GPIO_IN_ADDRESS is the wrong address
|
||||
return ((GPIO_REG_READ(GPIO_IN_ADDRESS) > gpio_pin) & 1UL);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Uniform way of turning an output GPIO pin into input mode. Handles GPIO 0-16.
|
||||
* The pin must be initiated with easygpio_pinMode() so that the pin mux is setup as a gpio in the first place.
|
||||
* This function does the same thing as GPIO_DIS_OUTPUT, but works on GPIO16 too.
|
||||
*/
|
||||
void easygpio_outputDisable(uint8_t gpio_pin) {
|
||||
if (16==gpio_pin) {
|
||||
WRITE_PERI_REG(RTC_GPIO_ENABLE,
|
||||
READ_PERI_REG(RTC_GPIO_ENABLE) & 0xfffffffeUL); //out disable
|
||||
} else {
|
||||
GPIO_DIS_OUTPUT(GPIO_ID_PIN(gpio_pin));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Uniform way of turning an input GPIO pin into output mode. Handles GPIO 0-16.
|
||||
* The pin must be initiated with easygpio_pinMode() so that the pin mux is setup as a gpio in the first place.
|
||||
*
|
||||
* This function:
|
||||
* - should only be used to convert a input pin into an output pin.
|
||||
* - is a little bit slower than easygpio_outputSet() so you should use that
|
||||
* function to just change output value.
|
||||
* - does the same thing as GPIO_OUTPUT_SET, but works on GPIO16 too.
|
||||
*/
|
||||
void easygpio_outputEnable(uint8_t gpio_pin, uint8_t value) {
|
||||
if (16==gpio_pin) {
|
||||
// write the value before flipping to output
|
||||
// - so we don't flash previous value for a few ns.
|
||||
WRITE_PERI_REG(RTC_GPIO_OUT,
|
||||
(READ_PERI_REG(RTC_GPIO_OUT) & 0xfffffffeUL) | (0x1UL & value));
|
||||
|
||||
WRITE_PERI_REG(RTC_GPIO_ENABLE,
|
||||
(READ_PERI_REG(RTC_GPIO_ENABLE) & 0xfffffffeUL) | 0x1UL); //out enable
|
||||
|
||||
} else {
|
||||
GPIO_OUTPUT_SET(GPIO_ID_PIN(gpio_pin), value);
|
||||
}
|
||||
}
|
||||
114
easygpio/easygpio.h
Normal file
114
easygpio/easygpio.h
Normal file
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* easygpio.h
|
||||
*
|
||||
* Copyright (c) 2015, eadf (https://github.com/eadf)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of Redis nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef EASYGPIO_INCLUDE_EASYGPIO_EASYGPIO_H_
|
||||
#define EASYGPIO_INCLUDE_EASYGPIO_EASYGPIO_H_
|
||||
|
||||
#include "c_types.h"
|
||||
|
||||
typedef enum {
|
||||
EASYGPIO_INPUT=0,
|
||||
EASYGPIO_OUTPUT=1
|
||||
} EasyGPIO_PinMode;
|
||||
|
||||
typedef enum {
|
||||
EASYGPIO_PULLUP=3,
|
||||
EASYGPIO_NOPULL=4
|
||||
} EasyGPIO_PullStatus;
|
||||
|
||||
/**
|
||||
* Returns the gpio name and func for a specific pin.
|
||||
*/
|
||||
bool easygpio_getGPIONameFunc(uint8_t gpio_pin, uint32_t *gpio_name, uint8_t *gpio_func);
|
||||
|
||||
/**
|
||||
* Sets the 'gpio_pin' pin as a GPIO and sets the interrupt to trigger on that pin.
|
||||
* The 'interruptArg' is the function argument that will be sent to your interruptHandler
|
||||
* (this way you can several interrupts with one interruptHandler)
|
||||
*/
|
||||
bool easygpio_attachInterrupt(uint8_t gpio_pin, EasyGPIO_PullStatus pullStatus, void (*interruptHandler)(void *arg), void *interruptArg);
|
||||
|
||||
/**
|
||||
* Deatach the interrupt handler from the 'gpio_pin' pin.
|
||||
*/
|
||||
bool easygpio_detachInterrupt(uint8_t gpio_pin);
|
||||
|
||||
/**
|
||||
* Returns the number of active pins in the gpioMask.
|
||||
*/
|
||||
uint8_t easygpio_countBits(uint32_t gpioMask);
|
||||
|
||||
/**
|
||||
* Sets the 'gpio_pin' pin as a GPIO and enables/disables the pull-up on that pin.
|
||||
* 'pullStatus' has no effect on output pins or GPIO16
|
||||
*/
|
||||
bool easygpio_pinMode(uint8_t gpio_pin, EasyGPIO_PullStatus pullStatus, EasyGPIO_PinMode pinMode);
|
||||
|
||||
/**
|
||||
* Enable or disable the internal pull up for a pin.
|
||||
*/
|
||||
bool easygpio_pullMode(uint8_t gpio_pin, EasyGPIO_PullStatus pullStatus);
|
||||
|
||||
/**
|
||||
* Uniform way of getting GPIO input value. Handles GPIO 0-16.
|
||||
* The pin must be initiated with easygpio_pinMode() so that the pin mux is setup as a gpio in the first place.
|
||||
* If you know that you won't be using GPIO16 then you'd better off by just using GPIO_INPUT_GET().
|
||||
*/
|
||||
uint8_t easygpio_inputGet(uint8_t gpio_pin);
|
||||
|
||||
/**
|
||||
* Uniform way of setting GPIO output value. Handles GPIO 0-16.
|
||||
*
|
||||
* You can not rely on that this function will switch the gpio to an output like GPIO_OUTPUT_SET does.
|
||||
* Use easygpio_outputEnable() to change an input gpio to output mode.
|
||||
*/
|
||||
void easygpio_outputSet(uint8_t gpio_pin, uint8_t value);
|
||||
|
||||
/**
|
||||
* Uniform way of turning an output GPIO pin into input mode. Handles GPIO 0-16.
|
||||
* The pin must be initiated with easygpio_pinMode() so that the pin mux is setup as a gpio in the first place.
|
||||
* This function does the same thing as GPIO_DIS_OUTPUT, but works on GPIO16 too.
|
||||
*/
|
||||
void easygpio_outputDisable(uint8_t gpio_pin);
|
||||
|
||||
/**
|
||||
* Uniform way of turning an input GPIO pin into output mode. Handles GPIO 0-16.
|
||||
* The pin must be initiated with easygpio_pinMode() so that the pin mux is setup as a gpio in the first place.
|
||||
*
|
||||
* This function:
|
||||
* - should only be used to convert a input pin into an output pin.
|
||||
* - is a little bit slower than easygpio_outputSet() so you should use that
|
||||
* function to just change output value.
|
||||
* - does the same thing as GPIO_OUTPUT_SET, but works on GPIO16 too.
|
||||
*/
|
||||
void easygpio_outputEnable(uint8_t gpio_pin, uint8_t value);
|
||||
|
||||
#endif /* EASYGPIO_INCLUDE_EASYGPIO_EASYGPIO_H_ */
|
||||
14
firewall.txt
Normal file
14
firewall.txt
Normal file
@ -0,0 +1,14 @@
|
||||
# Scrapbook of firewall rules to restrict connections only
|
||||
# to official servers.
|
||||
|
||||
# Clear outging rules
|
||||
acl from_sta clear
|
||||
|
||||
# Allow outgoing connections to specified IP
|
||||
acl from_sta IP any 185.43.124.6 allow
|
||||
|
||||
# Allow outgoing DNS requests
|
||||
acl from_sta UDP any any any 53 allow
|
||||
|
||||
# Deny everything else
|
||||
acl from_sta IP any any deny
|
||||
BIN
firmware/0x00000.bin
Normal file
BIN
firmware/0x00000.bin
Normal file
Binary file not shown.
BIN
firmware/0x10000.bin
Normal file
BIN
firmware/0x10000.bin
Normal file
Binary file not shown.
233
include/driver/uart.h
Normal file
233
include/driver/uart.h
Normal file
@ -0,0 +1,233 @@
|
||||
/*
|
||||
* File : uart.h
|
||||
* Copyright (C) 2013 - 2016, Espressif Systems
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of version 3 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program 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. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef UART_APP_H
|
||||
#define UART_APP_H
|
||||
|
||||
#include "uart_register.h"
|
||||
#include "eagle_soc.h"
|
||||
#include "c_types.h"
|
||||
|
||||
#define UART_TX_BUFFER_SIZE 256 //Ring buffer length of tx buffer
|
||||
#define UART_RX_BUFFER_SIZE 256 //Ring buffer length of rx buffer
|
||||
|
||||
#define UART_BUFF_EN 0 //use uart buffer , FOR UART0
|
||||
#define UART_SELFTEST 0 //set 1:enable the loop test demo for uart buffer, FOR UART0
|
||||
|
||||
#define UART_HW_RTS 0 //set 1: enable uart hw flow control RTS, PIN MTDO, FOR UART0
|
||||
#define UART_HW_CTS 0 //set1: enable uart hw flow contrl CTS , PIN MTCK, FOR UART0
|
||||
|
||||
#define _ENABLE_CONSOLE_INTEGRATION 1
|
||||
#define _ENABLE_RING_BUFFER 1
|
||||
|
||||
#ifdef _ENABLE_RING_BUFFER
|
||||
#include "ringbuf.h"
|
||||
#define RX_RING_BUFFER_SIZE 250
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#define UART0 0
|
||||
#define UART1 1
|
||||
|
||||
|
||||
typedef enum {
|
||||
FIVE_BITS = 0x0,
|
||||
SIX_BITS = 0x1,
|
||||
SEVEN_BITS = 0x2,
|
||||
EIGHT_BITS = 0x3
|
||||
} UartBitsNum4Char;
|
||||
|
||||
typedef enum {
|
||||
ONE_STOP_BIT = 0x1,
|
||||
ONE_HALF_STOP_BIT = 0x2,
|
||||
TWO_STOP_BIT = 0x3
|
||||
} UartStopBitsNum;
|
||||
|
||||
typedef enum {
|
||||
NONE_BITS = 0x2,
|
||||
ODD_BITS = 1,
|
||||
EVEN_BITS = 0
|
||||
} UartParityMode;
|
||||
|
||||
typedef enum {
|
||||
STICK_PARITY_DIS = 0,
|
||||
STICK_PARITY_EN = 1
|
||||
} UartExistParity;
|
||||
|
||||
typedef enum {
|
||||
UART_None_Inverse = 0x0,
|
||||
UART_Rxd_Inverse = UART_RXD_INV,
|
||||
UART_CTS_Inverse = UART_CTS_INV,
|
||||
UART_Txd_Inverse = UART_TXD_INV,
|
||||
UART_RTS_Inverse = UART_RTS_INV,
|
||||
} UART_LineLevelInverse;
|
||||
|
||||
|
||||
typedef enum {
|
||||
BIT_RATE_300 = 300,
|
||||
BIT_RATE_600 = 600,
|
||||
BIT_RATE_1200 = 1200,
|
||||
BIT_RATE_2400 = 2400,
|
||||
BIT_RATE_4800 = 4800,
|
||||
BIT_RATE_9600 = 9600,
|
||||
BIT_RATE_19200 = 19200,
|
||||
BIT_RATE_38400 = 38400,
|
||||
BIT_RATE_57600 = 57600,
|
||||
BIT_RATE_74880 = 74880,
|
||||
BIT_RATE_115200 = 115200,
|
||||
BIT_RATE_230400 = 230400,
|
||||
BIT_RATE_460800 = 460800,
|
||||
BIT_RATE_921600 = 921600,
|
||||
BIT_RATE_1843200 = 1843200,
|
||||
BIT_RATE_3686400 = 3686400,
|
||||
} UartBautRate;
|
||||
|
||||
typedef enum {
|
||||
NONE_CTRL,
|
||||
HARDWARE_CTRL,
|
||||
XON_XOFF_CTRL
|
||||
} UartFlowCtrl;
|
||||
|
||||
typedef enum {
|
||||
USART_HardwareFlowControl_None = 0x0,
|
||||
USART_HardwareFlowControl_RTS = 0x1,
|
||||
USART_HardwareFlowControl_CTS = 0x2,
|
||||
USART_HardwareFlowControl_CTS_RTS = 0x3
|
||||
} UART_HwFlowCtrl;
|
||||
|
||||
typedef enum {
|
||||
EMPTY,
|
||||
UNDER_WRITE,
|
||||
WRITE_OVER
|
||||
} RcvMsgBuffState;
|
||||
|
||||
typedef struct {
|
||||
uint32 RcvBuffSize;
|
||||
uint8 *pRcvMsgBuff;
|
||||
uint8 *pWritePos;
|
||||
uint8 *pReadPos;
|
||||
uint8 TrigLvl; //JLU: may need to pad
|
||||
RcvMsgBuffState BuffState;
|
||||
} RcvMsgBuff;
|
||||
|
||||
typedef struct {
|
||||
uint32 TrxBuffSize;
|
||||
uint8 *pTrxBuff;
|
||||
} TrxMsgBuff;
|
||||
|
||||
typedef enum {
|
||||
BAUD_RATE_DET,
|
||||
WAIT_SYNC_FRM,
|
||||
SRCH_MSG_HEAD,
|
||||
RCV_MSG_BODY,
|
||||
RCV_ESC_CHAR,
|
||||
} RcvMsgState;
|
||||
|
||||
typedef struct {
|
||||
UartBautRate baut_rate;
|
||||
UartBitsNum4Char data_bits;
|
||||
UartExistParity exist_parity;
|
||||
UartParityMode parity;
|
||||
UartStopBitsNum stop_bits;
|
||||
UartFlowCtrl flow_ctrl;
|
||||
RcvMsgBuff rcv_buff;
|
||||
TrxMsgBuff trx_buff;
|
||||
RcvMsgState rcv_state;
|
||||
int received;
|
||||
int buff_uart_no; //indicate which uart use tx/rx buffer
|
||||
} UartDevice;
|
||||
|
||||
void uart_init(UartBautRate uart0_br, UartBautRate uart1_br);
|
||||
void uart0_sendStr(const char *str);
|
||||
|
||||
|
||||
///////////////////////////////////////
|
||||
#define UART_FIFO_LEN 128 //define the tx fifo length
|
||||
#define UART_TX_EMPTY_THRESH_VAL 0x10
|
||||
|
||||
|
||||
struct UartBuffer{
|
||||
uint32 UartBuffSize;
|
||||
uint8 *pUartBuff;
|
||||
uint8 *pInPos;
|
||||
uint8 *pOutPos;
|
||||
STATUS BuffState;
|
||||
uint16 Space; //remanent space of the buffer
|
||||
uint8 TcpControl;
|
||||
struct UartBuffer * nextBuff;
|
||||
};
|
||||
|
||||
struct UartRxBuff{
|
||||
uint32 UartRxBuffSize;
|
||||
uint8 *pUartRxBuff;
|
||||
uint8 *pWritePos;
|
||||
uint8 *pReadPos;
|
||||
STATUS RxBuffState;
|
||||
uint32 Space; //remanent space of the buffer
|
||||
} ;
|
||||
|
||||
typedef enum {
|
||||
RUN = 0,
|
||||
BLOCK = 1,
|
||||
} TCPState;
|
||||
|
||||
//void ICACHE_FLASH_ATTR uart_test_rx();
|
||||
STATUS uart_tx_one_char(uint8 uart, uint8 TxChar);
|
||||
STATUS uart_tx_one_char_no_wait(uint8 uart, uint8 TxChar);
|
||||
void uart1_sendStr_no_wait(const char *str);
|
||||
struct UartBuffer* Uart_Buf_Init();
|
||||
|
||||
|
||||
#if UART_BUFF_EN
|
||||
LOCAL void Uart_Buf_Cpy(struct UartBuffer* pCur, char* pdata , uint16 data_len);
|
||||
void uart_buf_free(struct UartBuffer* pBuff);
|
||||
void tx_buff_enq(char* pdata, uint16 data_len );
|
||||
LOCAL void tx_fifo_insert(struct UartBuffer* pTxBuff, uint8 data_len, uint8 uart_no);
|
||||
void tx_start_uart_buffer(uint8 uart_no);
|
||||
uint16 rx_buff_deq(char* pdata, uint16 data_len );
|
||||
void Uart_rx_buff_enq();
|
||||
#endif
|
||||
void uart_rx_intr_enable(uint8 uart_no);
|
||||
void uart_rx_intr_disable(uint8 uart_no);
|
||||
void uart0_tx_buffer(uint8 *buf, uint16 len);
|
||||
|
||||
//==============================================
|
||||
#define FUNC_UART0_CTS 4
|
||||
#define FUNC_U0CTS 4
|
||||
#define FUNC_U1TXD_BK 2
|
||||
#define UART_LINE_INV_MASK (0x3f<<19)
|
||||
void UART_SetWordLength(uint8 uart_no, UartBitsNum4Char len);
|
||||
void UART_SetStopBits(uint8 uart_no, UartStopBitsNum bit_num);
|
||||
void UART_SetLineInverse(uint8 uart_no, UART_LineLevelInverse inverse_mask);
|
||||
void UART_SetParity(uint8 uart_no, UartParityMode Parity_mode);
|
||||
void UART_SetBaudrate(uint8 uart_no,uint32 baud_rate);
|
||||
void UART_SetFlowCtrl(uint8 uart_no,UART_HwFlowCtrl flow_ctrl,uint8 rx_thresh);
|
||||
void UART_WaitTxFifoEmpty(uint8 uart_no , uint32 time_out_us); //do not use if tx flow control enabled
|
||||
void UART_ResetFifo(uint8 uart_no);
|
||||
void UART_ClearIntrStatus(uint8 uart_no,uint32 clr_mask);
|
||||
void UART_SetIntrEna(uint8 uart_no,uint32 ena_mask);
|
||||
void UART_SetPrintPort(uint8 uart_no);
|
||||
bool UART_CheckOutputFinished(uint8 uart_no, uint32 time_out_us);
|
||||
//==============================================
|
||||
|
||||
void UART_init_console(UartBautRate uart0_br,
|
||||
uint8 recv_task_priority,
|
||||
ringbuf_t rxbuffer,
|
||||
ringbuf_t txBuffer);
|
||||
|
||||
#endif
|
||||
|
||||
156
include/driver/uart_register.h
Normal file
156
include/driver/uart_register.h
Normal file
@ -0,0 +1,156 @@
|
||||
/*
|
||||
* File : uart_register.h
|
||||
* Copyright (C) 2013 - 2016, Espressif Systems
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of version 3 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program 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. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2010 - 2011 Espressif System
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef UART_REGISTER_H_
|
||||
#define UART_REGISTER_H_
|
||||
|
||||
#define REG_UART_BASE(i) (0x60000000 + (i)*0xf00)
|
||||
//version value:32'h062000
|
||||
|
||||
#define UART_FIFO(i) (REG_UART_BASE(i) + 0x0)
|
||||
#define UART_RXFIFO_RD_BYTE 0x000000FF
|
||||
#define UART_RXFIFO_RD_BYTE_S 0
|
||||
|
||||
#define UART_INT_RAW(i) (REG_UART_BASE(i) + 0x4)
|
||||
#define UART_RXFIFO_TOUT_INT_RAW (BIT(8))
|
||||
#define UART_BRK_DET_INT_RAW (BIT(7))
|
||||
#define UART_CTS_CHG_INT_RAW (BIT(6))
|
||||
#define UART_DSR_CHG_INT_RAW (BIT(5))
|
||||
#define UART_RXFIFO_OVF_INT_RAW (BIT(4))
|
||||
#define UART_FRM_ERR_INT_RAW (BIT(3))
|
||||
#define UART_PARITY_ERR_INT_RAW (BIT(2))
|
||||
#define UART_TXFIFO_EMPTY_INT_RAW (BIT(1))
|
||||
#define UART_RXFIFO_FULL_INT_RAW (BIT(0))
|
||||
|
||||
#define UART_INT_ST(i) (REG_UART_BASE(i) + 0x8)
|
||||
#define UART_RXFIFO_TOUT_INT_ST (BIT(8))
|
||||
#define UART_BRK_DET_INT_ST (BIT(7))
|
||||
#define UART_CTS_CHG_INT_ST (BIT(6))
|
||||
#define UART_DSR_CHG_INT_ST (BIT(5))
|
||||
#define UART_RXFIFO_OVF_INT_ST (BIT(4))
|
||||
#define UART_FRM_ERR_INT_ST (BIT(3))
|
||||
#define UART_PARITY_ERR_INT_ST (BIT(2))
|
||||
#define UART_TXFIFO_EMPTY_INT_ST (BIT(1))
|
||||
#define UART_RXFIFO_FULL_INT_ST (BIT(0))
|
||||
|
||||
#define UART_INT_ENA(i) (REG_UART_BASE(i) + 0xC)
|
||||
#define UART_RXFIFO_TOUT_INT_ENA (BIT(8))
|
||||
#define UART_BRK_DET_INT_ENA (BIT(7))
|
||||
#define UART_CTS_CHG_INT_ENA (BIT(6))
|
||||
#define UART_DSR_CHG_INT_ENA (BIT(5))
|
||||
#define UART_RXFIFO_OVF_INT_ENA (BIT(4))
|
||||
#define UART_FRM_ERR_INT_ENA (BIT(3))
|
||||
#define UART_PARITY_ERR_INT_ENA (BIT(2))
|
||||
#define UART_TXFIFO_EMPTY_INT_ENA (BIT(1))
|
||||
#define UART_RXFIFO_FULL_INT_ENA (BIT(0))
|
||||
|
||||
#define UART_INT_CLR(i) (REG_UART_BASE(i) + 0x10)
|
||||
#define UART_RXFIFO_TOUT_INT_CLR (BIT(8))
|
||||
#define UART_BRK_DET_INT_CLR (BIT(7))
|
||||
#define UART_CTS_CHG_INT_CLR (BIT(6))
|
||||
#define UART_DSR_CHG_INT_CLR (BIT(5))
|
||||
#define UART_RXFIFO_OVF_INT_CLR (BIT(4))
|
||||
#define UART_FRM_ERR_INT_CLR (BIT(3))
|
||||
#define UART_PARITY_ERR_INT_CLR (BIT(2))
|
||||
#define UART_TXFIFO_EMPTY_INT_CLR (BIT(1))
|
||||
#define UART_RXFIFO_FULL_INT_CLR (BIT(0))
|
||||
|
||||
#define UART_CLKDIV(i) (REG_UART_BASE(i) + 0x14)
|
||||
#define UART_CLKDIV_CNT 0x000FFFFF
|
||||
#define UART_CLKDIV_S 0
|
||||
|
||||
#define UART_AUTOBAUD(i) (REG_UART_BASE(i) + 0x18)
|
||||
#define UART_GLITCH_FILT 0x000000FF
|
||||
#define UART_GLITCH_FILT_S 8
|
||||
#define UART_AUTOBAUD_EN (BIT(0))
|
||||
|
||||
#define UART_STATUS(i) (REG_UART_BASE(i) + 0x1C)
|
||||
#define UART_TXD (BIT(31))
|
||||
#define UART_RTSN (BIT(30))
|
||||
#define UART_DTRN (BIT(29))
|
||||
#define UART_TXFIFO_CNT 0x000000FF
|
||||
#define UART_TXFIFO_CNT_S 16
|
||||
#define UART_RXD (BIT(15))
|
||||
#define UART_CTSN (BIT(14))
|
||||
#define UART_DSRN (BIT(13))
|
||||
#define UART_RXFIFO_CNT 0x000000FF
|
||||
#define UART_RXFIFO_CNT_S 0
|
||||
|
||||
#define UART_CONF0(i) (REG_UART_BASE(i) + 0x20)
|
||||
#define UART_DTR_INV (BIT(24))
|
||||
#define UART_RTS_INV (BIT(23))
|
||||
#define UART_TXD_INV (BIT(22))
|
||||
#define UART_DSR_INV (BIT(21))
|
||||
#define UART_CTS_INV (BIT(20))
|
||||
#define UART_RXD_INV (BIT(19))
|
||||
#define UART_TXFIFO_RST (BIT(18))
|
||||
#define UART_RXFIFO_RST (BIT(17))
|
||||
#define UART_IRDA_EN (BIT(16))
|
||||
#define UART_TX_FLOW_EN (BIT(15))
|
||||
#define UART_LOOPBACK (BIT(14))
|
||||
#define UART_IRDA_RX_INV (BIT(13))
|
||||
#define UART_IRDA_TX_INV (BIT(12))
|
||||
#define UART_IRDA_WCTL (BIT(11))
|
||||
#define UART_IRDA_TX_EN (BIT(10))
|
||||
#define UART_IRDA_DPLX (BIT(9))
|
||||
#define UART_TXD_BRK (BIT(8))
|
||||
#define UART_SW_DTR (BIT(7))
|
||||
#define UART_SW_RTS (BIT(6))
|
||||
#define UART_STOP_BIT_NUM 0x00000003
|
||||
#define UART_STOP_BIT_NUM_S 4
|
||||
#define UART_BIT_NUM 0x00000003
|
||||
#define UART_BIT_NUM_S 2
|
||||
#define UART_PARITY_EN (BIT(1))
|
||||
#define UART_PARITY_EN_M 0x00000001
|
||||
#define UART_PARITY_EN_S 1
|
||||
#define UART_PARITY (BIT(0))
|
||||
#define UART_PARITY_M 0x00000001
|
||||
#define UART_PARITY_S 0
|
||||
|
||||
#define UART_CONF1(i) (REG_UART_BASE(i) + 0x24)
|
||||
#define UART_RX_TOUT_EN (BIT(31))
|
||||
#define UART_RX_TOUT_THRHD 0x0000007F
|
||||
#define UART_RX_TOUT_THRHD_S 24
|
||||
#define UART_RX_FLOW_EN (BIT(23))
|
||||
#define UART_RX_FLOW_THRHD 0x0000007F
|
||||
#define UART_RX_FLOW_THRHD_S 16
|
||||
#define UART_TXFIFO_EMPTY_THRHD 0x0000007F
|
||||
#define UART_TXFIFO_EMPTY_THRHD_S 8
|
||||
#define UART_RXFIFO_FULL_THRHD 0x0000007F
|
||||
#define UART_RXFIFO_FULL_THRHD_S 0
|
||||
|
||||
#define UART_LOWPULSE(i) (REG_UART_BASE(i) + 0x28)
|
||||
#define UART_LOWPULSE_MIN_CNT 0x000FFFFF
|
||||
#define UART_LOWPULSE_MIN_CNT_S 0
|
||||
|
||||
#define UART_HIGHPULSE(i) (REG_UART_BASE(i) + 0x2C)
|
||||
#define UART_HIGHPULSE_MIN_CNT 0x000FFFFF
|
||||
#define UART_HIGHPULSE_MIN_CNT_S 0
|
||||
|
||||
#define UART_PULSE_NUM(i) (REG_UART_BASE(i) + 0x30)
|
||||
#define UART_PULSE_NUM_CNT 0x0003FF
|
||||
#define UART_PULSE_NUM_CNT_S 0
|
||||
|
||||
#define UART_DATE(i) (REG_UART_BASE(i) + 0x78)
|
||||
#define UART_ID(i) (REG_UART_BASE(i) + 0x7C)
|
||||
|
||||
#endif // UART_REGISTER_H_INCLUDED
|
||||
|
||||
106
include/lwip/app/dhcpserver.h
Normal file
106
include/lwip/app/dhcpserver.h
Normal file
@ -0,0 +1,106 @@
|
||||
#ifndef __DHCPS_H__
|
||||
#define __DHCPS_H__
|
||||
|
||||
#define USE_DNS
|
||||
|
||||
typedef struct dhcps_state{
|
||||
sint16_t state;
|
||||
} dhcps_state;
|
||||
|
||||
// <20><><EFBFBD><EFBFBD>dhcpclient<6E>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>DHCP msg<73>ṹ<EFBFBD><E1B9B9>
|
||||
typedef struct dhcps_msg {
|
||||
uint8_t op, htype, hlen, hops;
|
||||
uint8_t xid[4];
|
||||
uint16_t secs, flags;
|
||||
uint8_t ciaddr[4];
|
||||
uint8_t yiaddr[4];
|
||||
uint8_t siaddr[4];
|
||||
uint8_t giaddr[4];
|
||||
uint8_t chaddr[16];
|
||||
uint8_t sname[64];
|
||||
uint8_t file[128];
|
||||
uint8_t options[312];
|
||||
}dhcps_msg;
|
||||
|
||||
#ifndef LWIP_OPEN_SRC
|
||||
struct dhcps_lease {
|
||||
bool enable;
|
||||
struct ip_addr start_ip;
|
||||
struct ip_addr end_ip;
|
||||
};
|
||||
|
||||
enum dhcps_offer_option{
|
||||
OFFER_START = 0x00,
|
||||
OFFER_ROUTER = 0x01,
|
||||
OFFER_END
|
||||
};
|
||||
#endif
|
||||
|
||||
struct dhcps_pool{
|
||||
struct ip_addr ip;
|
||||
uint8 mac[6];
|
||||
uint32 lease_timer;
|
||||
};
|
||||
|
||||
typedef struct _list_node{
|
||||
void *pnode;
|
||||
struct _list_node *pnext;
|
||||
}list_node;
|
||||
|
||||
extern uint32 dhcps_lease_time;
|
||||
#define DHCPS_LEASE_TIMER dhcps_lease_time //0x05A0
|
||||
#define DHCPS_MAX_LEASE 0x64
|
||||
#define BOOTP_BROADCAST 0x8000
|
||||
|
||||
#define DHCP_REQUEST 1
|
||||
#define DHCP_REPLY 2
|
||||
#define DHCP_HTYPE_ETHERNET 1
|
||||
#define DHCP_HLEN_ETHERNET 6
|
||||
#define DHCP_MSG_LEN 236
|
||||
|
||||
#define DHCPS_SERVER_PORT 67
|
||||
#define DHCPS_CLIENT_PORT 68
|
||||
|
||||
#define DHCPDISCOVER 1
|
||||
#define DHCPOFFER 2
|
||||
#define DHCPREQUEST 3
|
||||
#define DHCPDECLINE 4
|
||||
#define DHCPACK 5
|
||||
#define DHCPNAK 6
|
||||
#define DHCPRELEASE 7
|
||||
|
||||
#define DHCP_OPTION_SUBNET_MASK 1
|
||||
#define DHCP_OPTION_ROUTER 3
|
||||
#define DHCP_OPTION_DNS_SERVER 6
|
||||
#define DHCP_OPTION_REQ_IPADDR 50
|
||||
#define DHCP_OPTION_LEASE_TIME 51
|
||||
#define DHCP_OPTION_MSG_TYPE 53
|
||||
#define DHCP_OPTION_SERVER_ID 54
|
||||
#define DHCP_OPTION_INTERFACE_MTU 26
|
||||
#define DHCP_OPTION_PERFORM_ROUTER_DISCOVERY 31
|
||||
#define DHCP_OPTION_BROADCAST_ADDRESS 28
|
||||
#define DHCP_OPTION_REQ_LIST 55
|
||||
#define DHCP_OPTION_END 255
|
||||
|
||||
//#define USE_CLASS_B_NET 1
|
||||
#define DHCPS_DEBUG 0
|
||||
#define MAX_STATION_NUM 8
|
||||
|
||||
#define DHCPS_STATE_OFFER 1
|
||||
#define DHCPS_STATE_DECLINE 2
|
||||
#define DHCPS_STATE_ACK 3
|
||||
#define DHCPS_STATE_NAK 4
|
||||
#define DHCPS_STATE_IDLE 5
|
||||
#define DHCPS_STATE_RELEASE 6
|
||||
|
||||
#define dhcps_router_enabled(offer) ((offer & OFFER_ROUTER) != 0)
|
||||
|
||||
void dhcps_start(struct ip_info *info);
|
||||
void dhcps_stop(void);
|
||||
|
||||
void dhcps_set_DNS(struct ip_addr *dns_ip) ICACHE_FLASH_ATTR;
|
||||
struct dhcps_pool *dhcps_get_mapping(uint16_t no) ICACHE_FLASH_ATTR;
|
||||
void dhcps_set_mapping(struct ip_addr *addr, uint8 *mac, uint32 lease_time) ICACHE_FLASH_ATTR;
|
||||
|
||||
#endif
|
||||
|
||||
115
include/lwip/lwip_napt.h
Normal file
115
include/lwip/lwip_napt.h
Normal file
@ -0,0 +1,115 @@
|
||||
#ifndef __LWIP_NAPT_H__
|
||||
#define __LWIP_NAPT_H__
|
||||
|
||||
#include "lwip/opt.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if IP_FORWARD
|
||||
#if IP_NAPT
|
||||
|
||||
/* Default size of the tables used for NAPT */
|
||||
#define IP_NAPT_MAX 512
|
||||
#define IP_PORTMAP_MAX 32
|
||||
|
||||
/* Timeouts in sec for the various protocol types */
|
||||
#define IP_NAPT_TIMEOUT_MS_TCP (30*60*1000)
|
||||
#define IP_NAPT_TIMEOUT_MS_TCP_DISCON (20*1000)
|
||||
#define IP_NAPT_TIMEOUT_MS_UDP (2*1000)
|
||||
#define IP_NAPT_TIMEOUT_MS_ICMP (2*1000)
|
||||
|
||||
#define IP_NAPT_PORT_RANGE_START 49152
|
||||
#define IP_NAPT_PORT_RANGE_END 61439
|
||||
|
||||
struct napt_table {
|
||||
u32_t last;
|
||||
u32_t src;
|
||||
u32_t dest;
|
||||
u16_t sport;
|
||||
u16_t dport;
|
||||
u16_t mport;
|
||||
u8_t proto;
|
||||
u8_t fin1 : 1;
|
||||
u8_t fin2 : 1;
|
||||
u8_t finack1 : 1;
|
||||
u8_t finack2 : 1;
|
||||
u8_t synack : 1;
|
||||
u8_t rst : 1;
|
||||
u16_t next, prev;
|
||||
};
|
||||
|
||||
struct portmap_table {
|
||||
u32_t maddr;
|
||||
u32_t daddr;
|
||||
u16_t mport;
|
||||
u16_t dport;
|
||||
u8_t proto;
|
||||
u8 valid;
|
||||
};
|
||||
|
||||
extern struct portmap_table *ip_portmap_table;
|
||||
|
||||
/**
|
||||
* Allocates and initializes the NAPT tables.
|
||||
*
|
||||
* @param max_nat max number of enties in the NAPT table (use IP_NAPT_MAX if in doubt)
|
||||
* @param max_portmap max number of enties in the NAPT table (use IP_PORTMAP_MAX if in doubt)
|
||||
*/
|
||||
void ICACHE_FLASH_ATTR
|
||||
ip_napt_init(uint16_t max_nat, uint8_t max_portmap);
|
||||
|
||||
|
||||
/**
|
||||
* Enable/Disable NAPT for a specified interface.
|
||||
*
|
||||
* @param addr ip address of the interface
|
||||
* @param enable non-zero to enable NAPT, or 0 to disable.
|
||||
*/
|
||||
void ICACHE_FLASH_ATTR
|
||||
ip_napt_enable(u32_t addr, int enable);
|
||||
|
||||
|
||||
/**
|
||||
* Enable/Disable NAPT for a specified interface.
|
||||
*
|
||||
* @param netif number of the interface
|
||||
* @param enable non-zero to enable NAPT, or 0 to disable.
|
||||
*/
|
||||
void ICACHE_FLASH_ATTR
|
||||
ip_napt_enable_no(u8_t number, int enable);
|
||||
|
||||
|
||||
/**
|
||||
* Register port mapping on the external interface to internal interface.
|
||||
* When the same port mapping is registered again, the old mapping is overwritten.
|
||||
* In this implementation, only 1 unique port mapping can be defined for each target address/port.
|
||||
*
|
||||
* @param proto target protocol
|
||||
* @param maddr ip address of the external interface
|
||||
* @param mport mapped port on the external interface, in host byte order.
|
||||
* @param daddr destination ip address
|
||||
* @param dport destination port, in host byte order.
|
||||
*/
|
||||
u8_t ICACHE_FLASH_ATTR
|
||||
ip_portmap_add(u8_t proto, u32_t maddr, u16_t mport, u32_t daddr, u16_t dport);
|
||||
|
||||
|
||||
/**
|
||||
* Unregister port mapping on the external interface to internal interface.
|
||||
*
|
||||
* @param proto target protocol
|
||||
* @param maddr ip address of the external interface
|
||||
*/
|
||||
u8_t ICACHE_FLASH_ATTR
|
||||
ip_portmap_remove(u8_t proto, u16_t mport);
|
||||
|
||||
#endif /* IP_NAPT */
|
||||
#endif /* IP_FORWARD */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __LWIP_NAPT_H__ */
|
||||
323
include/lwip/netif.h
Normal file
323
include/lwip/netif.h
Normal file
@ -0,0 +1,323 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
#ifndef __LWIP_NETIF_H__
|
||||
#define __LWIP_NETIF_H__
|
||||
|
||||
#include "lwip/opt.h"
|
||||
|
||||
#define ENABLE_LOOPBACK (LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF)
|
||||
|
||||
#include "lwip/err.h"
|
||||
|
||||
#include "lwip/ip_addr.h"
|
||||
|
||||
#include "lwip/def.h"
|
||||
#include "lwip/pbuf.h"
|
||||
#if LWIP_DHCP
|
||||
struct dhcp;
|
||||
#endif
|
||||
#if LWIP_AUTOIP
|
||||
struct autoip;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Throughout this file, IP addresses are expected to be in
|
||||
* the same byte order as in IP_PCB. */
|
||||
|
||||
/** must be the maximum of all used hardware address lengths
|
||||
across all types of interfaces in use */
|
||||
#define NETIF_MAX_HWADDR_LEN 6U
|
||||
|
||||
/** Whether the network interface is 'up'. This is
|
||||
* a software flag used to control whether this network
|
||||
* interface is enabled and processes traffic.
|
||||
* It is set by the startup code (for static IP configuration) or
|
||||
* by dhcp/autoip when an address has been assigned.
|
||||
*/
|
||||
#define NETIF_FLAG_UP 0x01U
|
||||
/** If set, the netif has broadcast capability.
|
||||
* Set by the netif driver in its init function. */
|
||||
#define NETIF_FLAG_BROADCAST 0x02U
|
||||
/** If set, the netif is one end of a point-to-point connection.
|
||||
* Set by the netif driver in its init function. */
|
||||
#define NETIF_FLAG_POINTTOPOINT 0x04U
|
||||
/** If set, the interface is configured using DHCP.
|
||||
* Set by the DHCP code when starting or stopping DHCP. */
|
||||
#define NETIF_FLAG_DHCP 0x08U
|
||||
/** If set, the interface has an active link
|
||||
* (set by the network interface driver).
|
||||
* Either set by the netif driver in its init function (if the link
|
||||
* is up at that time) or at a later point once the link comes up
|
||||
* (if link detection is supported by the hardware). */
|
||||
#define NETIF_FLAG_LINK_UP 0x10U
|
||||
/** If set, the netif is an ethernet device using ARP.
|
||||
* Set by the netif driver in its init function.
|
||||
* Used to check input packet types and use of DHCP. */
|
||||
#define NETIF_FLAG_ETHARP 0x20U
|
||||
/** If set, the netif is an ethernet device. It might not use
|
||||
* ARP or TCP/IP if it is used for PPPoE only.
|
||||
*/
|
||||
#define NETIF_FLAG_ETHERNET 0x40U
|
||||
/** If set, the netif has IGMP capability.
|
||||
* Set by the netif driver in its init function. */
|
||||
#define NETIF_FLAG_IGMP 0x80U
|
||||
|
||||
/** Function prototype for netif init functions. Set up flags and output/linkoutput
|
||||
* callback functions in this function.
|
||||
*
|
||||
* @param netif The netif to initialize
|
||||
*/
|
||||
typedef err_t (*netif_init_fn)(struct netif *netif);
|
||||
/** Function prototype for netif->input functions. This function is saved as 'input'
|
||||
* callback function in the netif struct. Call it when a packet has been received.
|
||||
*
|
||||
* @param p The received packet, copied into a pbuf
|
||||
* @param inp The netif which received the packet
|
||||
*/
|
||||
typedef err_t (*netif_input_fn)(struct pbuf *p, struct netif *inp);
|
||||
/** Function prototype for netif->output functions. Called by lwIP when a packet
|
||||
* shall be sent. For ethernet netif, set this to 'etharp_output' and set
|
||||
* 'linkoutput'.
|
||||
*
|
||||
* @param netif The netif which shall send a packet
|
||||
* @param p The packet to send (p->payload points to IP header)
|
||||
* @param ipaddr The IP address to which the packet shall be sent
|
||||
*/
|
||||
typedef err_t (*netif_output_fn)(struct netif *netif, struct pbuf *p,
|
||||
ip_addr_t *ipaddr);
|
||||
/** Function prototype for netif->linkoutput functions. Only used for ethernet
|
||||
* netifs. This function is called by ARP when a packet shall be sent.
|
||||
*
|
||||
* @param netif The netif which shall send a packet
|
||||
* @param p The packet to send (raw ethernet packet)
|
||||
*/
|
||||
typedef err_t (*netif_linkoutput_fn)(struct netif *netif, struct pbuf *p);
|
||||
/** Function prototype for netif status- or link-callback functions. */
|
||||
typedef void (*netif_status_callback_fn)(struct netif *netif);
|
||||
/** Function prototype for netif igmp_mac_filter functions */
|
||||
typedef err_t (*netif_igmp_mac_filter_fn)(struct netif *netif,
|
||||
ip_addr_t *group, u8_t action);
|
||||
|
||||
/*add DHCP event processing by LiuHan*/
|
||||
typedef void (*dhcp_event_fn)(void);
|
||||
|
||||
/** Generic data structure used for all lwIP network interfaces.
|
||||
* The following fields should be filled in by the initialization
|
||||
* function for the device driver: hwaddr_len, hwaddr[], mtu, flags */
|
||||
struct netif {
|
||||
/** pointer to next in linked list */
|
||||
struct netif *next;
|
||||
|
||||
/** IP address configuration in network byte order */
|
||||
ip_addr_t ip_addr;
|
||||
ip_addr_t netmask;
|
||||
ip_addr_t gw;
|
||||
|
||||
/** This function is called by the network device driver
|
||||
* to pass a packet up the TCP/IP stack. 向IP层输入数据包*/
|
||||
netif_input_fn input;
|
||||
/** This function is called by the IP module when it wants
|
||||
* to send a packet on the interface. This function typically
|
||||
* first resolves the hardware address, then sends the packet. 发送IP数据包*/
|
||||
netif_output_fn output;
|
||||
/** This function is called by the ARP module when it wants
|
||||
* to send a packet on the interface. This function outputs
|
||||
* the pbuf as-is on the link medium. 底层数据包发送*/
|
||||
netif_linkoutput_fn linkoutput;
|
||||
#if LWIP_NETIF_STATUS_CALLBACK
|
||||
/** This function is called when the netif state is set to up or down
|
||||
*/
|
||||
netif_status_callback_fn status_callback;
|
||||
#endif /* LWIP_NETIF_STATUS_CALLBACK */
|
||||
#if LWIP_NETIF_LINK_CALLBACK
|
||||
/** This function is called when the netif link is set to up or down
|
||||
*/
|
||||
netif_status_callback_fn link_callback;
|
||||
#endif /* LWIP_NETIF_LINK_CALLBACK */
|
||||
/** This field can be set by the device driver and could point
|
||||
* to state information for the device. 自由设置字段,比如指向底层设备相关信息*/
|
||||
void *state;
|
||||
#if LWIP_DHCP
|
||||
/** the DHCP client state information for this netif */
|
||||
struct dhcp *dhcp;
|
||||
struct udp_pcb *dhcps_pcb; //dhcps
|
||||
dhcp_event_fn dhcp_event;
|
||||
#endif /* LWIP_DHCP */
|
||||
#if LWIP_AUTOIP
|
||||
/** the AutoIP client state information for this netif */
|
||||
struct autoip *autoip;
|
||||
#endif
|
||||
#if LWIP_NETIF_HOSTNAME
|
||||
/* the hostname for this netif, NULL is a valid value */
|
||||
char* hostname;
|
||||
#endif /* LWIP_NETIF_HOSTNAME */
|
||||
/** maximum transfer unit (in bytes) 该接口允许的最大数据包长度,多是1500*/
|
||||
u16_t mtu;
|
||||
/** number of bytes used in hwaddr该接口物理地址长度 */
|
||||
u8_t hwaddr_len;
|
||||
/** link level hardware address of this interface 该接口物理地址*/
|
||||
u8_t hwaddr[NETIF_MAX_HWADDR_LEN];
|
||||
/** flags (see NETIF_FLAG_ above) 该接口状态、属性字段*/
|
||||
u8_t flags;
|
||||
/** descriptive abbreviation 该接口的名字*/
|
||||
char name[2];
|
||||
/** number of this interface 该接口的编号*/
|
||||
u8_t num;
|
||||
#if LWIP_SNMP
|
||||
/** link type (from "snmp_ifType" enum from snmp.h) */
|
||||
u8_t link_type;
|
||||
/** (estimate) link speed */
|
||||
u32_t link_speed;
|
||||
/** timestamp at last change made (up/down) */
|
||||
u32_t ts;
|
||||
/** counters */
|
||||
u32_t ifinoctets;
|
||||
u32_t ifinucastpkts;
|
||||
u32_t ifinnucastpkts;
|
||||
u32_t ifindiscards;
|
||||
u32_t ifoutoctets;
|
||||
u32_t ifoutucastpkts;
|
||||
u32_t ifoutnucastpkts;
|
||||
u32_t ifoutdiscards;
|
||||
#endif /* LWIP_SNMP */
|
||||
#if LWIP_IGMP
|
||||
/** This function could be called to add or delete a entry in the multicast
|
||||
filter table of the ethernet MAC.*/
|
||||
netif_igmp_mac_filter_fn igmp_mac_filter;
|
||||
#endif /* LWIP_IGMP */
|
||||
#if LWIP_NETIF_HWADDRHINT
|
||||
u8_t *addr_hint;
|
||||
#endif /* LWIP_NETIF_HWADDRHINT */
|
||||
#if ENABLE_LOOPBACK
|
||||
/* List of packets to be queued for ourselves. 指向发送给自己的数据包的pbuf*/
|
||||
struct pbuf *loop_first;//第一个
|
||||
struct pbuf *loop_last;//最后一个
|
||||
#if LWIP_LOOPBACK_MAX_PBUFS
|
||||
u16_t loop_cnt_current;
|
||||
#endif /* LWIP_LOOPBACK_MAX_PBUFS */
|
||||
#endif /* ENABLE_LOOPBACK */
|
||||
#if IP_NAPT
|
||||
u8_t napt;
|
||||
#endif
|
||||
};
|
||||
|
||||
#if LWIP_SNMP
|
||||
#define NETIF_INIT_SNMP(netif, type, speed) \
|
||||
/* use "snmp_ifType" enum from snmp.h for "type", snmp_ifType_ethernet_csmacd by example */ \
|
||||
(netif)->link_type = (type); \
|
||||
/* your link speed here (units: bits per second) */ \
|
||||
(netif)->link_speed = (speed); \
|
||||
(netif)->ts = 0; \
|
||||
(netif)->ifinoctets = 0; \
|
||||
(netif)->ifinucastpkts = 0; \
|
||||
(netif)->ifinnucastpkts = 0; \
|
||||
(netif)->ifindiscards = 0; \
|
||||
(netif)->ifoutoctets = 0; \
|
||||
(netif)->ifoutucastpkts = 0; \
|
||||
(netif)->ifoutnucastpkts = 0; \
|
||||
(netif)->ifoutdiscards = 0
|
||||
#else /* LWIP_SNMP */
|
||||
#define NETIF_INIT_SNMP(netif, type, speed)
|
||||
#endif /* LWIP_SNMP */
|
||||
|
||||
|
||||
/** The list of network interfaces. */
|
||||
extern struct netif *netif_list;
|
||||
/** The default network interface. */
|
||||
extern struct netif *netif_default;
|
||||
|
||||
void netif_init(void)ICACHE_FLASH_ATTR;
|
||||
|
||||
struct netif *netif_add(struct netif *netif, ip_addr_t *ipaddr, ip_addr_t *netmask,
|
||||
ip_addr_t *gw, void *state, netif_init_fn init, netif_input_fn input)ICACHE_FLASH_ATTR;
|
||||
|
||||
void
|
||||
netif_set_addr(struct netif *netif, ip_addr_t *ipaddr, ip_addr_t *netmask,
|
||||
ip_addr_t *gw)ICACHE_FLASH_ATTR;
|
||||
void netif_remove(struct netif * netif)ICACHE_FLASH_ATTR;
|
||||
|
||||
/* Returns a network interface given its name. The name is of the form
|
||||
"et0", where the first two letters are the "name" field in the
|
||||
netif structure, and the digit is in the num field in the same
|
||||
structure. */
|
||||
struct netif *netif_find(char *name)ICACHE_FLASH_ATTR;
|
||||
|
||||
void netif_set_default(struct netif *netif)ICACHE_FLASH_ATTR;
|
||||
|
||||
void netif_set_ipaddr(struct netif *netif, ip_addr_t *ipaddr)ICACHE_FLASH_ATTR;
|
||||
void netif_set_netmask(struct netif *netif, ip_addr_t *netmask)ICACHE_FLASH_ATTR;
|
||||
void netif_set_gw(struct netif *netif, ip_addr_t *gw)ICACHE_FLASH_ATTR;
|
||||
|
||||
void netif_set_up(struct netif *netif)ICACHE_FLASH_ATTR;
|
||||
void netif_set_down(struct netif *netif)ICACHE_FLASH_ATTR;
|
||||
/** Ask if an interface is up */
|
||||
#define netif_is_up(netif) (((netif)->flags & NETIF_FLAG_UP) ? (u8_t)1 : (u8_t)0)
|
||||
|
||||
#if LWIP_NETIF_STATUS_CALLBACK
|
||||
void netif_set_status_callback(struct netif *netif, netif_status_callback_fn status_callback)ICACHE_FLASH_ATTR;
|
||||
#endif /* LWIP_NETIF_STATUS_CALLBACK */
|
||||
|
||||
void netif_set_link_up(struct netif *netif)ICACHE_FLASH_ATTR;
|
||||
void netif_set_link_down(struct netif *netif)ICACHE_FLASH_ATTR;
|
||||
/** Ask if a link is up */
|
||||
#define netif_is_link_up(netif) (((netif)->flags & NETIF_FLAG_LINK_UP) ? (u8_t)1 : (u8_t)0)
|
||||
|
||||
#if LWIP_NETIF_LINK_CALLBACK
|
||||
void netif_set_link_callback(struct netif *netif, netif_status_callback_fn link_callback)ICACHE_FLASH_ATTR;
|
||||
#endif /* LWIP_NETIF_LINK_CALLBACK */
|
||||
|
||||
#if LWIP_NETIF_HOSTNAME
|
||||
#define netif_set_hostname(netif, name) do { if((netif) != NULL) { (netif)->hostname = name; }}while(0)
|
||||
#define netif_get_hostname(netif) (((netif) != NULL) ? ((netif)->hostname) : NULL)
|
||||
#endif /* LWIP_NETIF_HOSTNAME */
|
||||
|
||||
#if LWIP_IGMP
|
||||
#define netif_set_igmp_mac_filter(netif, function) do { if((netif) != NULL) { (netif)->igmp_mac_filter = function; }}while(0)
|
||||
#define netif_get_igmp_mac_filter(netif) (((netif) != NULL) ? ((netif)->igmp_mac_filter) : NULL)
|
||||
#endif /* LWIP_IGMP */
|
||||
|
||||
#if ENABLE_LOOPBACK
|
||||
err_t netif_loop_output(struct netif *netif, struct pbuf *p, ip_addr_t *dest_ip)ICACHE_FLASH_ATTR;
|
||||
void netif_poll(struct netif *netif)ICACHE_FLASH_ATTR;
|
||||
#if !LWIP_NETIF_LOOPBACK_MULTITHREADING
|
||||
void netif_poll_all(void)ICACHE_FLASH_ATTR;
|
||||
#endif /* !LWIP_NETIF_LOOPBACK_MULTITHREADING */
|
||||
#endif /* ENABLE_LOOPBACK */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __LWIP_NETIF_H__ */
|
||||
2054
include/lwip/opt.h
Normal file
2054
include/lwip/opt.h
Normal file
File diff suppressed because it is too large
Load Diff
2097
include/lwipopts.h
Normal file
2097
include/lwipopts.h
Normal file
File diff suppressed because it is too large
Load Diff
1
include/string.h
Normal file
1
include/string.h
Normal file
@ -0,0 +1 @@
|
||||
//Nothing here.
|
||||
BIN
liblwip_open_napt.a
Normal file
BIN
liblwip_open_napt.a
Normal file
Binary file not shown.
310
user/acl.c
Normal file
310
user/acl.c
Normal file
@ -0,0 +1,310 @@
|
||||
#include "c_types.h"
|
||||
#include "mem.h"
|
||||
#include "ets_sys.h"
|
||||
#include "osapi.h"
|
||||
#include "os_type.h"
|
||||
#include "lwip/ip.h"
|
||||
#include "lwip/udp.h"
|
||||
#include "lwip/tcp_impl.h"
|
||||
#include "netif/etharp.h"
|
||||
|
||||
#include "user_interface.h"
|
||||
#include "string.h"
|
||||
|
||||
#include "acl.h"
|
||||
|
||||
acl_entry acl[MAX_NO_ACLS][MAX_ACL_ENTRIES];
|
||||
uint8_t acl_freep[MAX_NO_ACLS];
|
||||
uint32_t acl_allow_count;
|
||||
uint32_t acl_deny_count;
|
||||
static packet_deny_cb my_deny_cb;
|
||||
|
||||
void ICACHE_FLASH_ATTR
|
||||
acl_init()
|
||||
{
|
||||
int i;
|
||||
acl_allow_count = acl_deny_count = 0;
|
||||
my_deny_cb = NULL;
|
||||
for(i=0; i< MAX_NO_ACLS; i++)
|
||||
{
|
||||
acl_freep[i] = 0;
|
||||
acl_clear_stats(i);
|
||||
}
|
||||
}
|
||||
|
||||
bool ICACHE_FLASH_ATTR
|
||||
acl_is_empty(uint8_t acl_no)
|
||||
{
|
||||
if (acl_no >= MAX_NO_ACLS)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return acl_freep[acl_no] == 0;
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR
|
||||
acl_clear(uint8_t acl_no)
|
||||
{
|
||||
if (acl_no >= MAX_NO_ACLS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
acl_freep[acl_no] = 0;
|
||||
acl_clear_stats(acl_no);
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR
|
||||
acl_clear_stats(uint8_t acl_no)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (acl_no >= MAX_NO_ACLS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
my_deny_cb = NULL;
|
||||
for(i=0; i< MAX_ACL_ENTRIES; i++)
|
||||
acl[acl_no][i].hit_count = 0;
|
||||
}
|
||||
|
||||
bool ICACHE_FLASH_ATTR
|
||||
acl_add(uint8_t acl_no,
|
||||
uint32_t src,
|
||||
uint32_t s_mask,
|
||||
uint32_t dest,
|
||||
uint32_t d_mask,
|
||||
uint8_t proto,
|
||||
uint16_t s_port,
|
||||
uint16_t d_port,
|
||||
uint8_t allow)
|
||||
{
|
||||
acl_entry *my_entry;
|
||||
|
||||
if (acl_no >= MAX_NO_ACLS || acl_freep[acl_no] >= MAX_ACL_ENTRIES)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
my_entry = &acl[acl_no][acl_freep[acl_no]];
|
||||
my_entry->src = src & s_mask;
|
||||
my_entry->s_mask = s_mask;
|
||||
my_entry->dest = dest & d_mask;
|
||||
my_entry->d_mask = d_mask;
|
||||
my_entry->proto = proto;
|
||||
my_entry->s_port = s_port;
|
||||
my_entry->d_port = d_port;
|
||||
my_entry->allow = allow;
|
||||
my_entry->hit_count = 0;
|
||||
|
||||
acl_freep[acl_no]++;
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t ICACHE_FLASH_ATTR
|
||||
acl_check_packet(uint8_t acl_no, struct pbuf *p)
|
||||
{
|
||||
struct eth_hdr *mac_h;
|
||||
struct ip_hdr *ip_h;
|
||||
uint8_t proto;
|
||||
struct udp_hdr *udp_h;
|
||||
struct tcp_hdr *tcp_h;
|
||||
uint16_t src_port, dest_port;
|
||||
uint8_t *packet;
|
||||
int i;
|
||||
acl_entry *my_entry;
|
||||
uint8_t allow;
|
||||
|
||||
if (acl_no >= MAX_NO_ACLS)
|
||||
{
|
||||
return ACL_DENY;
|
||||
}
|
||||
|
||||
if (p->len < sizeof(struct eth_hdr))
|
||||
{
|
||||
return ACL_DENY;
|
||||
}
|
||||
|
||||
mac_h = (struct eth_hdr *)p->payload;
|
||||
|
||||
// Allow ARP
|
||||
if (ntohs(mac_h->type) == ETHTYPE_ARP)
|
||||
{
|
||||
acl_allow_count++;
|
||||
return ACL_ALLOW;
|
||||
}
|
||||
|
||||
// Drop anything else if not IPv4
|
||||
if (ntohs(mac_h->type) != ETHTYPE_IP)
|
||||
{
|
||||
acl_deny_count++;
|
||||
return ACL_DENY;
|
||||
}
|
||||
|
||||
if (p->len < sizeof(struct eth_hdr)+sizeof(struct ip_hdr))
|
||||
{
|
||||
acl_deny_count++;
|
||||
return ACL_DENY;
|
||||
}
|
||||
|
||||
allow = ACL_DENY;
|
||||
packet = (uint8_t*)p->payload;
|
||||
ip_h = (struct ip_hdr *)&packet[sizeof(struct eth_hdr)];
|
||||
proto = IPH_PROTO(ip_h);
|
||||
|
||||
switch (proto) {
|
||||
case IP_PROTO_UDP:
|
||||
{
|
||||
if (p->len < sizeof(struct eth_hdr)+sizeof(struct ip_hdr)+sizeof(struct udp_hdr))
|
||||
{
|
||||
return;
|
||||
}
|
||||
udp_h = (struct udp_hdr *)&packet[sizeof(struct eth_hdr)+sizeof(struct ip_hdr)];
|
||||
src_port = ntohs(udp_h->src);
|
||||
dest_port = ntohs(udp_h->dest);
|
||||
} break;
|
||||
|
||||
case IP_PROTO_TCP:
|
||||
{
|
||||
if (p->len < sizeof(struct eth_hdr)+sizeof(struct ip_hdr)+sizeof(struct tcp_hdr))
|
||||
{
|
||||
return;
|
||||
}
|
||||
tcp_h = (struct tcp_hdr *)&packet[sizeof(struct eth_hdr)+sizeof(struct ip_hdr)];
|
||||
src_port = ntohs(tcp_h->src);
|
||||
dest_port = ntohs(tcp_h->dest);
|
||||
} break;
|
||||
|
||||
case IP_PROTO_ICMP:
|
||||
{
|
||||
src_port = dest_port = 0;
|
||||
} break;
|
||||
|
||||
// Drop anything that is not UDP, TCP, or ICMP
|
||||
default:
|
||||
{
|
||||
acl_deny_count++;
|
||||
return ACL_DENY;
|
||||
} break;
|
||||
}
|
||||
|
||||
// os_printf("Src: %d.%d.%d.%d Dst: %d.%d.%d.%d Proto: %s SP:%d DP:%d\n",
|
||||
// IP2STR(&ip_h->src), IP2STR(&ip_h->dest),
|
||||
// proto==IP_PROTO_TCP?"TCP":proto==IP_PROTO_UDP?"UDP":"IP4", src_port, dest_port);
|
||||
|
||||
for(i=0; i<acl_freep[acl_no]; i++)
|
||||
{
|
||||
my_entry = &acl[acl_no][i];
|
||||
if ((my_entry->proto == 0 || proto == my_entry->proto) &&
|
||||
(my_entry->src == 0 || my_entry->src == (ip_h->src.addr&my_entry->s_mask)) &&
|
||||
(my_entry->dest == 0 || my_entry->dest == (ip_h->dest.addr&my_entry->d_mask)) &&
|
||||
(my_entry->s_port == 0 || my_entry->s_port == src_port) &&
|
||||
(my_entry->d_port == 0 || my_entry->d_port == dest_port))
|
||||
{
|
||||
allow = my_entry->allow;
|
||||
my_entry->hit_count++;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
if (!(allow & ACL_ALLOW) && my_deny_cb != NULL)
|
||||
{
|
||||
allow = my_deny_cb(proto, ip_h->src.addr, src_port,
|
||||
ip_h->dest.addr, dest_port, allow);
|
||||
}
|
||||
if (allow & ACL_ALLOW)
|
||||
{
|
||||
acl_allow_count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
acl_deny_count++;
|
||||
}
|
||||
|
||||
// os_printf(" allow: %d\r\n", allow);
|
||||
return allow;
|
||||
}
|
||||
|
||||
void
|
||||
acl_set_deny_cb(packet_deny_cb cb)
|
||||
{
|
||||
my_deny_cb = cb;
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR
|
||||
addr2str(uint8_t *buf, uint32_t addr, uint32_t mask)
|
||||
{
|
||||
uint8_t clidr;
|
||||
|
||||
if (addr == 0)
|
||||
{
|
||||
os_sprintf(buf, "any");
|
||||
return;
|
||||
}
|
||||
|
||||
mask = ntohl(mask);
|
||||
for (clidr = 0; mask; mask <<= 1,clidr++);
|
||||
if (clidr < 32)
|
||||
{
|
||||
os_sprintf(buf, "%d.%d.%d.%d/%d", IP2STR((ip_addr_t*)&addr), clidr);
|
||||
}
|
||||
else
|
||||
{
|
||||
os_sprintf(buf, "%d.%d.%d.%d", IP2STR((ip_addr_t*)&addr));
|
||||
}
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR
|
||||
port2str(uint8_t *buf, uint16_t port)
|
||||
{
|
||||
if (port == 0)
|
||||
{
|
||||
os_sprintf(buf, "any");
|
||||
}
|
||||
else
|
||||
{
|
||||
os_sprintf(buf, "%d", port);
|
||||
}
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR
|
||||
acl_show(uint8_t acl_no, uint8_t *buf)
|
||||
{
|
||||
int i;
|
||||
acl_entry *my_entry;
|
||||
uint8_t line[80], addr1[21], addr2[21], port1[6], port2[6];
|
||||
|
||||
buf[0] = 0;
|
||||
|
||||
if (acl_no >= MAX_NO_ACLS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for(i = 0; i < acl_freep[acl_no]; i++)
|
||||
{
|
||||
my_entry = &acl[acl_no][i];
|
||||
addr2str(addr1, my_entry->src, my_entry->s_mask);
|
||||
port2str(port1, my_entry->s_port);
|
||||
addr2str(addr2, my_entry->dest, my_entry->d_mask);
|
||||
port2str(port2, my_entry->d_port);
|
||||
if (my_entry->proto != 0)
|
||||
{
|
||||
os_sprintf(line, "%s %s:%s %s:%s %s%s (%d hits)\r\n",
|
||||
my_entry->proto==IP_PROTO_TCP?"TCP":"UDP",
|
||||
addr1, port1, addr2, port2,
|
||||
(my_entry->allow & ACL_ALLOW)?"allow":"deny",
|
||||
(my_entry->allow & ACL_MONITOR)?"_monitor":"",
|
||||
my_entry->hit_count);
|
||||
}
|
||||
else
|
||||
{
|
||||
os_sprintf(line, "IP %s %s %s%s (%d hits)\r\n",
|
||||
addr1, addr2,
|
||||
(my_entry->allow & ACL_ALLOW)?"allow":"deny",
|
||||
(my_entry->allow & ACL_MONITOR)?"_monitor":"",
|
||||
my_entry->hit_count);
|
||||
}
|
||||
os_memcpy(&buf[os_strlen(buf)], line, os_strlen(line)+1);
|
||||
}
|
||||
}
|
||||
51
user/acl.h
Normal file
51
user/acl.h
Normal file
@ -0,0 +1,51 @@
|
||||
#ifndef _ACL_H_
|
||||
#define _ACL_H_
|
||||
|
||||
#include "lwip/ip.h"
|
||||
#include "lwip/pbuf.h"
|
||||
|
||||
#define MAX_NO_ACLS 4
|
||||
#define MAX_ACL_ENTRIES 16
|
||||
|
||||
#define ACL_DENY 0x0
|
||||
#define ACL_ALLOW 0x1
|
||||
#define ACL_MONITOR 0x2
|
||||
|
||||
typedef struct _acl_entry
|
||||
{
|
||||
uint32_t src;
|
||||
uint32_t s_mask;
|
||||
uint32_t dest;
|
||||
uint32_t d_mask;
|
||||
uint16_t s_port;
|
||||
uint16_t d_port;
|
||||
uint8_t proto;
|
||||
uint8_t allow;
|
||||
uint32_t hit_count;
|
||||
} acl_entry;
|
||||
|
||||
extern acl_entry acl[MAX_NO_ACLS][MAX_ACL_ENTRIES];
|
||||
extern uint8_t acl_freep[MAX_NO_ACLS];
|
||||
extern uint32_t acl_allow_count;
|
||||
extern uint32_t acl_deny_count;
|
||||
|
||||
typedef uint8_t (*packet_deny_cb)(uint8_t proto, uint32_t saddr, uint16_t s_port, uint32_t daddr, uint16_t d_port, uint8_t allow);
|
||||
|
||||
void acl_init();
|
||||
bool acl_is_empty(uint8_t acl_no);
|
||||
void acl_clear(uint8_t acl_no);
|
||||
void acl_clear_stats(uint8_t acl_no);
|
||||
bool acl_add(uint8_t acl_no,
|
||||
uint32_t src,
|
||||
uint32_t s_mask,
|
||||
uint32_t dest,
|
||||
uint32_t d_mask,
|
||||
uint8_t proto,
|
||||
uint16_t s_port,
|
||||
uint16_t d_port,
|
||||
uint8_t allow);
|
||||
uint8_t acl_check_packet(uint8_t acl_no, struct pbuf *p);
|
||||
void acl_set_deny_cb(packet_deny_cb cb);
|
||||
void acl_show(uint8_t acl_no, uint8_t *buf);
|
||||
|
||||
#endif /* _ACL_H_ */
|
||||
153
user/config_flash.c
Normal file
153
user/config_flash.c
Normal file
@ -0,0 +1,153 @@
|
||||
#include "user_interface.h"
|
||||
#include "lwip/ip.h"
|
||||
#include "config_flash.h"
|
||||
|
||||
|
||||
/* From the document 99A-SDK-Espressif IOT Flash RW Operation_v0.2 *
|
||||
* -------------------------------------------------------------------------*
|
||||
* Flash is erased sector by sector, which means it has to erase 4Kbytes one
|
||||
* time at least. When you want to change some data in flash, you have to
|
||||
* erase the whole sector, and then write it back with the new data.
|
||||
*--------------------------------------------------------------------------*/
|
||||
void
|
||||
config_load_default(sysconfig_p config)
|
||||
{
|
||||
uint8_t mac[6];
|
||||
|
||||
wifi_get_macaddr(STATION_IF, mac);
|
||||
|
||||
os_memset(config, 0, sizeof(sysconfig_t));
|
||||
os_printf("Loading default configuration\r\n");
|
||||
config->magic_number = MAGIC_NUMBER;
|
||||
config->length = sizeof(sysconfig_t);
|
||||
os_sprintf(config->ssid,"%s", WIFI_SSID);
|
||||
os_sprintf(config->password,"%s", WIFI_PASSWORD);
|
||||
config->auto_connect = 0;
|
||||
os_memset(config->bssid, 0, 6);
|
||||
os_sprintf(config->sta_hostname, "ESP_%02x%02x%02x", mac[3], mac[4], mac[5]);
|
||||
os_sprintf(config->ap_ssid,"%s", WIFI_AP_SSID);
|
||||
|
||||
config->first_run = 1;
|
||||
config->ap_watchdog = -1;
|
||||
config->client_watchdog = -1;
|
||||
|
||||
IP4_ADDR(&config->network_addr, 192, 168, 4, 1);
|
||||
config->dns_addr.addr = 0; // use DHCP
|
||||
config->my_addr.addr = 0; // use DHCP
|
||||
config->my_netmask.addr = 0; // use DHCP
|
||||
config->my_gw.addr = 0; // use DHCP
|
||||
#ifdef PHY_MODE
|
||||
config->phy_mode = 3; // mode n
|
||||
#endif
|
||||
config->clock_speed = 80;
|
||||
config->status_led = STATUS_LED_GPIO;
|
||||
|
||||
wifi_get_macaddr(STATION_IF, config->STA_MAC_address);
|
||||
|
||||
config->dhcps_entries = 0;
|
||||
#ifdef ACLS
|
||||
acl_init(); // initializes the ACLs, written in config during save
|
||||
#endif
|
||||
|
||||
config->current_mac_address = 0;
|
||||
// Interval to change mac address in seconds
|
||||
// Default: 28800 (8 hours)
|
||||
config->mac_change_interval = 600;
|
||||
|
||||
// list of mac addresses
|
||||
// from https://docs.google.com/spreadsheets/d/1su5u-vPrQwkTixR6YnOTWSi_Ls9lV-_XNJHaWIJspv4/edit#gid=0
|
||||
ets_str2macaddr(config->mac_list[0], "4E:53:50:4F:4F:40");
|
||||
ets_str2macaddr(config->mac_list[1], "4E:53:50:4F:4F:41");
|
||||
ets_str2macaddr(config->mac_list[2], "4E:53:50:4F:4F:42");
|
||||
ets_str2macaddr(config->mac_list[3], "4E:53:50:4F:4F:43");
|
||||
ets_str2macaddr(config->mac_list[4], "4E:53:50:4F:4F:44");
|
||||
ets_str2macaddr(config->mac_list[5], "4E:53:50:4F:4F:45");
|
||||
ets_str2macaddr(config->mac_list[6], "4E:53:50:4F:4F:46");
|
||||
ets_str2macaddr(config->mac_list[7], "4E:53:50:4F:4F:47");
|
||||
ets_str2macaddr(config->mac_list[8], "4E:53:50:4F:4F:48");
|
||||
ets_str2macaddr(config->mac_list[9], "4E:53:50:4F:4F:49");
|
||||
ets_str2macaddr(config->mac_list[10], "4E:53:50:4F:4F:4A");
|
||||
ets_str2macaddr(config->mac_list[11], "4E:53:50:4F:4F:4B");
|
||||
ets_str2macaddr(config->mac_list[12], "4E:53:50:4F:4F:4C");
|
||||
ets_str2macaddr(config->mac_list[13], "4E:53:50:4F:4F:4D");
|
||||
ets_str2macaddr(config->mac_list[14], "4E:53:50:4F:4F:4E");
|
||||
ets_str2macaddr(config->mac_list[15], "4E:53:50:4F:4F:4F");
|
||||
}
|
||||
|
||||
int
|
||||
config_load(sysconfig_p config)
|
||||
{
|
||||
if (config == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
uint16_t base_address = FLASH_BLOCK_NO;
|
||||
|
||||
spi_flash_read(base_address* SPI_FLASH_SEC_SIZE, &config->magic_number, 4);
|
||||
|
||||
if((config->magic_number != MAGIC_NUMBER))
|
||||
{
|
||||
os_printf("\r\nNo config found, saving default in flash\r\n");
|
||||
config_load_default(config);
|
||||
config_save(config);
|
||||
return -1;
|
||||
}
|
||||
|
||||
os_printf("\r\nConfig found and loaded\r\n");
|
||||
spi_flash_read(base_address * SPI_FLASH_SEC_SIZE,
|
||||
(uint32 *) config,
|
||||
sizeof(sysconfig_t));
|
||||
if (config->length != sizeof(sysconfig_t))
|
||||
{
|
||||
os_printf("Length Mismatch, probably old version of config, loading defaults\r\n");
|
||||
config_load_default(config);
|
||||
config_save(config);
|
||||
return -1;
|
||||
}
|
||||
#ifdef ACLS
|
||||
os_memcpy(&acl, &(config->acl), sizeof(acl));
|
||||
os_memcpy(&acl_freep, &(config->acl_freep), sizeof(acl_freep));
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
config_save(sysconfig_p config)
|
||||
{
|
||||
uint16_t base_address = FLASH_BLOCK_NO;
|
||||
#ifdef ACLS
|
||||
os_memcpy(&(config->acl), &acl, sizeof(acl));
|
||||
os_memcpy(&(config->acl_freep), &acl_freep, sizeof(acl_freep));
|
||||
#endif
|
||||
os_printf("Saving configuration\r\n");
|
||||
spi_flash_erase_sector(base_address);
|
||||
spi_flash_write(base_address * SPI_FLASH_SEC_SIZE,
|
||||
(uint32 *)config,
|
||||
sizeof(sysconfig_t));
|
||||
}
|
||||
|
||||
void
|
||||
blob_save(uint8_t blob_no, uint32_t *data, uint16_t len)
|
||||
{
|
||||
uint16_t base_address = FLASH_BLOCK_NO + 1 + blob_no;
|
||||
spi_flash_erase_sector(base_address);
|
||||
spi_flash_write(base_address * SPI_FLASH_SEC_SIZE, data, len);
|
||||
}
|
||||
|
||||
void
|
||||
blob_load(uint8_t blob_no, uint32_t *data, uint16_t len)
|
||||
{
|
||||
uint16_t base_address = FLASH_BLOCK_NO + 1 + blob_no;
|
||||
spi_flash_read(base_address * SPI_FLASH_SEC_SIZE, data, len);
|
||||
}
|
||||
|
||||
void
|
||||
blob_zero(uint8_t blob_no, uint16_t len)
|
||||
{
|
||||
int i;
|
||||
uint8_t z[len];
|
||||
os_memset(z, 0,len);
|
||||
uint16_t base_address = FLASH_BLOCK_NO + 1 + blob_no;
|
||||
spi_flash_erase_sector(base_address);
|
||||
spi_flash_write(base_address * SPI_FLASH_SEC_SIZE, (uint32_t *)z, len);
|
||||
}
|
||||
81
user/config_flash.h
Normal file
81
user/config_flash.h
Normal file
@ -0,0 +1,81 @@
|
||||
#ifndef _CONFIG_FLASH_H_
|
||||
#define _CONFIG_FLASH_H_
|
||||
|
||||
#include "c_types.h"
|
||||
#include "mem.h"
|
||||
#include "ets_sys.h"
|
||||
#include "osapi.h"
|
||||
#include "gpio.h"
|
||||
#include "os_type.h"
|
||||
#include "spi_flash.h"
|
||||
#include "lwip/app/dhcpserver.h"
|
||||
|
||||
#include "user_config.h"
|
||||
#include "acl.h"
|
||||
|
||||
#define FLASH_BLOCK_NO 0xc
|
||||
|
||||
#define MAGIC_NUMBER 0x112005fc
|
||||
|
||||
#define MAX_MAC_LIST_LENGTH 15
|
||||
|
||||
typedef struct
|
||||
{
|
||||
// To check if the structure is initialized or not in flash
|
||||
uint32_t magic_number;
|
||||
|
||||
// Length of the structure, since this is a evolving library,
|
||||
// the variant may change hence used for verification
|
||||
uint16_t length;
|
||||
|
||||
/* Below variables are specific to my code */
|
||||
uint8_t ssid[32]; // SSID of the AP to connect to
|
||||
uint8_t password[64]; // Password of the network
|
||||
uint8_t auto_connect; // Should we auto connect
|
||||
uint8_t bssid[6]; // Optional: BSSID the AP
|
||||
uint8_t sta_hostname[32]; // Name of the station
|
||||
uint8_t ap_ssid[32]; // SSID of the own AP
|
||||
uint8_t first_run; // Has ESPerPass been configured yet?
|
||||
uint8_t current_mac_address; // Holds currently broadcasted HomePass mac address index
|
||||
int32_t mac_change_interval; // Interval to rotate HomePass mac address (in seconds)
|
||||
|
||||
// Seconds without ap traffic will cause reset (-1 off, default)
|
||||
int32_t ap_watchdog;
|
||||
// Seconds without client traffic will cause reset (-1 off, default)
|
||||
int32_t client_watchdog;
|
||||
|
||||
ip_addr_t network_addr; // Address of the internal network
|
||||
ip_addr_t dns_addr; // Optional: address of the dns server
|
||||
|
||||
ip_addr_t my_addr; // Optional (if not DHCP): IP address of the uplink side
|
||||
ip_addr_t my_netmask; // Optional (if not DHCP): IP netmask of the uplink side
|
||||
ip_addr_t my_gw; // Optional (if not DHCP): Gateway of the uplink side
|
||||
#ifdef PHY_MODE
|
||||
uint16_t phy_mode; // WiFi PHY mode
|
||||
#endif
|
||||
uint16_t clock_speed; // Freq of the CPU
|
||||
uint16_t status_led; // GPIO pin os the status LED (>16 disabled)
|
||||
|
||||
uint8_t STA_MAC_address[6]; // MAC address of the STA
|
||||
|
||||
uint16_t dhcps_entries; // number of allocated entries in the following table
|
||||
struct dhcps_pool dhcps_p[MAX_DHCP]; // DHCP entries
|
||||
#ifdef ACLS
|
||||
acl_entry acl[MAX_NO_ACLS][MAX_ACL_ENTRIES]; // ACL entries
|
||||
uint8_t acl_freep[MAX_NO_ACLS]; // ACL free pointers
|
||||
#endif
|
||||
|
||||
// HomePass mac list
|
||||
// Allow 20 slots
|
||||
uint8_t mac_list[19][6];
|
||||
|
||||
} sysconfig_t, *sysconfig_p;
|
||||
|
||||
int config_load(sysconfig_p config);
|
||||
void config_save(sysconfig_p config);
|
||||
|
||||
void blob_save(uint8_t blob_no, uint32_t *data, uint16_t len);
|
||||
void blob_load(uint8_t blob_no, uint32_t *data, uint16_t len);
|
||||
void blob_zero(uint8_t blob_no, uint16_t len);
|
||||
|
||||
#endif
|
||||
250
user/ringbuf.c
Normal file
250
user/ringbuf.c
Normal file
@ -0,0 +1,250 @@
|
||||
/*
|
||||
* ringbuf.c - C ring buffer (FIFO) implementation.
|
||||
*
|
||||
* Written in 2011 by Drew Hess <dhess-src@bothan.net>.
|
||||
*
|
||||
* To the extent possible under law, the author(s) have dedicated all
|
||||
* copyright and related and neighboring rights to this software to
|
||||
* the public domain worldwide. This software is distributed without
|
||||
* any warranty.
|
||||
*
|
||||
* You should have received a copy of the CC0 Public Domain Dedication
|
||||
* along with this software. If not, see
|
||||
* <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
#include "ringbuf.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#include "osapi.h"
|
||||
#include "mem.h"
|
||||
|
||||
#define assert(x)
|
||||
|
||||
/*
|
||||
* The code is written for clarity, not cleverness or performance, and
|
||||
* contains many assert()s to enforce invariant assumptions and catch
|
||||
* bugs. Feel free to optimize the code and to remove asserts for use
|
||||
* in your own projects, once you're comfortable that it functions as
|
||||
* intended.
|
||||
*/
|
||||
|
||||
struct ringbuf_t
|
||||
{
|
||||
uint8_t *buf;
|
||||
uint8_t *head, *tail;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
ringbuf_t
|
||||
ringbuf_new(size_t capacity)
|
||||
{
|
||||
ringbuf_t rb = (ringbuf_t)os_malloc(sizeof(struct ringbuf_t));
|
||||
if (rb) {
|
||||
|
||||
/* One byte is used for detecting the full condition. */
|
||||
rb->size = capacity + 1;
|
||||
rb->buf = (uint8_t *)os_malloc(rb->size);
|
||||
if (rb->buf)
|
||||
ringbuf_reset(rb);
|
||||
else {
|
||||
os_free(rb);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return rb;
|
||||
}
|
||||
|
||||
size_t
|
||||
ringbuf_buffer_size(const struct ringbuf_t *rb)
|
||||
{
|
||||
return rb->size;
|
||||
}
|
||||
|
||||
void
|
||||
ringbuf_reset(ringbuf_t rb)
|
||||
{
|
||||
rb->head = rb->tail = rb->buf;
|
||||
}
|
||||
|
||||
void
|
||||
ringbuf_free(ringbuf_t *rb)
|
||||
{
|
||||
assert(rb && *rb);
|
||||
os_free((*rb)->buf);
|
||||
os_free(*rb);
|
||||
*rb = 0;
|
||||
}
|
||||
|
||||
size_t
|
||||
ringbuf_capacity(const struct ringbuf_t *rb)
|
||||
{
|
||||
return ringbuf_buffer_size(rb) - 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a pointer to one-past-the-end of the ring buffer's
|
||||
* contiguous buffer. You shouldn't normally need to use this function
|
||||
* unless you're writing a new ringbuf_* function.
|
||||
*/
|
||||
static const uint8_t *
|
||||
ringbuf_end(const struct ringbuf_t *rb)
|
||||
{
|
||||
return rb->buf + ringbuf_buffer_size(rb);
|
||||
}
|
||||
|
||||
size_t
|
||||
ringbuf_bytes_free(const struct ringbuf_t *rb)
|
||||
{
|
||||
if (rb->head >= rb->tail)
|
||||
return ringbuf_capacity(rb) - (rb->head - rb->tail);
|
||||
else
|
||||
return rb->tail - rb->head - 1;
|
||||
}
|
||||
|
||||
size_t
|
||||
ringbuf_bytes_used(const struct ringbuf_t *rb)
|
||||
{
|
||||
return ringbuf_capacity(rb) - ringbuf_bytes_free(rb);
|
||||
}
|
||||
|
||||
int
|
||||
ringbuf_is_full(const struct ringbuf_t *rb)
|
||||
{
|
||||
return ringbuf_bytes_free(rb) == 0;
|
||||
}
|
||||
|
||||
int
|
||||
ringbuf_is_empty(const struct ringbuf_t *rb)
|
||||
{
|
||||
return ringbuf_bytes_free(rb) == ringbuf_capacity(rb);
|
||||
}
|
||||
|
||||
const void *
|
||||
ringbuf_tail(const struct ringbuf_t *rb)
|
||||
{
|
||||
return rb->tail;
|
||||
}
|
||||
|
||||
const void *
|
||||
ringbuf_head(const struct ringbuf_t *rb)
|
||||
{
|
||||
return rb->head;
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a ring buffer rb and a pointer to a location within its
|
||||
* contiguous buffer, return the a pointer to the next logical
|
||||
* location in the ring buffer.
|
||||
*/
|
||||
static uint8_t *
|
||||
ringbuf_nextp(ringbuf_t rb, const uint8_t *p)
|
||||
{
|
||||
/*
|
||||
* The assert guarantees the expression (++p - rb->buf) is
|
||||
* non-negative; therefore, the modulus operation is safe and
|
||||
* portable.
|
||||
*/
|
||||
assert((p >= rb->buf) && (p < ringbuf_end(rb)));
|
||||
return rb->buf + ((++p - rb->buf) % ringbuf_buffer_size(rb));
|
||||
}
|
||||
|
||||
void *
|
||||
ringbuf_memcpy_into(ringbuf_t dst, const void *src, size_t count)
|
||||
{
|
||||
const uint8_t *u8src = src;
|
||||
const uint8_t *bufend = ringbuf_end(dst);
|
||||
int overflow = count > ringbuf_bytes_free(dst);
|
||||
size_t nread = 0;
|
||||
|
||||
while (nread != count) {
|
||||
/* don't copy beyond the end of the buffer */
|
||||
assert(bufend > dst->head);
|
||||
size_t n = MIN(bufend - dst->head, count - nread);
|
||||
os_memcpy(dst->head, u8src + nread, n);
|
||||
dst->head += n;
|
||||
nread += n;
|
||||
|
||||
/* wrap? */
|
||||
if (dst->head == bufend)
|
||||
dst->head = dst->buf;
|
||||
}
|
||||
|
||||
if (overflow) {
|
||||
dst->tail = ringbuf_nextp(dst, dst->head);
|
||||
assert(ringbuf_is_full(dst));
|
||||
}
|
||||
|
||||
return dst->head;
|
||||
}
|
||||
|
||||
void *
|
||||
ringbuf_memcpy_from(void *dst, ringbuf_t src, size_t count)
|
||||
{
|
||||
size_t bytes_used = ringbuf_bytes_used(src);
|
||||
if (count > bytes_used)
|
||||
return 0;
|
||||
|
||||
uint8_t *u8dst = dst;
|
||||
const uint8_t *bufend = ringbuf_end(src);
|
||||
size_t nwritten = 0;
|
||||
while (nwritten != count) {
|
||||
assert(bufend > src->tail);
|
||||
size_t n = MIN(bufend - src->tail, count - nwritten);
|
||||
os_memcpy(u8dst + nwritten, src->tail, n);
|
||||
src->tail += n;
|
||||
nwritten += n;
|
||||
|
||||
/* wrap ? */
|
||||
if (src->tail == bufend)
|
||||
src->tail = src->buf;
|
||||
}
|
||||
|
||||
assert(count + ringbuf_bytes_used(src) == bytes_used);
|
||||
return src->tail;
|
||||
}
|
||||
|
||||
void *
|
||||
ringbuf_copy(ringbuf_t dst, ringbuf_t src, size_t count)
|
||||
{
|
||||
size_t src_bytes_used = ringbuf_bytes_used(src);
|
||||
if (count > src_bytes_used)
|
||||
return 0;
|
||||
int overflow = count > ringbuf_bytes_free(dst);
|
||||
|
||||
const uint8_t *src_bufend = ringbuf_end(src);
|
||||
const uint8_t *dst_bufend = ringbuf_end(dst);
|
||||
size_t ncopied = 0;
|
||||
while (ncopied != count) {
|
||||
assert(src_bufend > src->tail);
|
||||
size_t nsrc = MIN(src_bufend - src->tail, count - ncopied);
|
||||
assert(dst_bufend > dst->head);
|
||||
size_t n = MIN(dst_bufend - dst->head, nsrc);
|
||||
os_memcpy(dst->head, src->tail, n);
|
||||
src->tail += n;
|
||||
dst->head += n;
|
||||
ncopied += n;
|
||||
|
||||
/* wrap ? */
|
||||
if (src->tail == src_bufend)
|
||||
src->tail = src->buf;
|
||||
if (dst->head == dst_bufend)
|
||||
dst->head = dst->buf;
|
||||
}
|
||||
|
||||
assert(count + ringbuf_bytes_used(src) == src_bytes_used);
|
||||
|
||||
if (overflow) {
|
||||
dst->tail = ringbuf_nextp(dst, dst->head);
|
||||
assert(ringbuf_is_full(dst));
|
||||
}
|
||||
|
||||
return dst->head;
|
||||
}
|
||||
|
||||
167
user/ringbuf.h
Normal file
167
user/ringbuf.h
Normal file
@ -0,0 +1,167 @@
|
||||
#ifndef INCLUDED_RINGBUF_H
|
||||
#define INCLUDED_RINGBUF_H
|
||||
|
||||
/*
|
||||
* ringbuf.h - C ring buffer (FIFO) interface.
|
||||
*
|
||||
* Written in 2011 by Drew Hess <dhess-src@bothan.net>.
|
||||
*
|
||||
* To the extent possible under law, the author(s) have dedicated all
|
||||
* copyright and related and neighboring rights to this software to
|
||||
* the public domain worldwide. This software is distributed without
|
||||
* any warranty.
|
||||
*
|
||||
* You should have received a copy of the CC0 Public Domain Dedication
|
||||
* along with this software. If not, see
|
||||
* <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* A byte-addressable ring buffer FIFO implementation.
|
||||
*
|
||||
* The ring buffer's head pointer points to the starting location
|
||||
* where data should be written when copying data *into* the buffer
|
||||
* (e.g., with ringbuf_read). The ring buffer's tail pointer points to
|
||||
* the starting location where data should be read when copying data
|
||||
* *from* the buffer (e.g., with ringbuf_write).
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
typedef struct ringbuf_t *ringbuf_t;
|
||||
|
||||
/*
|
||||
* Create a new ring buffer with the given capacity (usable
|
||||
* bytes). Note that the actual internal buffer size may be one or
|
||||
* more bytes larger than the usable capacity, for bookkeeping.
|
||||
*
|
||||
* Returns the new ring buffer object, or 0 if there's not enough
|
||||
* memory to fulfill the request for the given capacity.
|
||||
*/
|
||||
ringbuf_t
|
||||
ringbuf_new(size_t capacity);
|
||||
|
||||
/*
|
||||
* The size of the internal buffer, in bytes. One or more bytes may be
|
||||
* unusable in order to distinguish the "buffer full" state from the
|
||||
* "buffer empty" state.
|
||||
*
|
||||
* For the usable capacity of the ring buffer, use the
|
||||
* ringbuf_capacity function.
|
||||
*/
|
||||
size_t
|
||||
ringbuf_buffer_size(const struct ringbuf_t *rb);
|
||||
|
||||
/*
|
||||
* Deallocate a ring buffer, and, as a side effect, set the pointer to
|
||||
* 0.
|
||||
*/
|
||||
void
|
||||
ringbuf_free(ringbuf_t *rb);
|
||||
|
||||
/*
|
||||
* Reset a ring buffer to its initial state (empty).
|
||||
*/
|
||||
void
|
||||
ringbuf_reset(ringbuf_t rb);
|
||||
|
||||
/*
|
||||
* The usable capacity of the ring buffer, in bytes. Note that this
|
||||
* value may be less than the ring buffer's internal buffer size, as
|
||||
* returned by ringbuf_buffer_size.
|
||||
*/
|
||||
size_t
|
||||
ringbuf_capacity(const struct ringbuf_t *rb);
|
||||
|
||||
/*
|
||||
* The number of free/available bytes in the ring buffer. This value
|
||||
* is never larger than the ring buffer's usable capacity.
|
||||
*/
|
||||
size_t
|
||||
ringbuf_bytes_free(const struct ringbuf_t *rb);
|
||||
|
||||
/*
|
||||
* The number of bytes currently being used in the ring buffer. This
|
||||
* value is never larger than the ring buffer's usable capacity.
|
||||
*/
|
||||
size_t
|
||||
ringbuf_bytes_used(const struct ringbuf_t *rb);
|
||||
|
||||
int
|
||||
ringbuf_is_full(const struct ringbuf_t *rb);
|
||||
|
||||
int
|
||||
ringbuf_is_empty(const struct ringbuf_t *rb);
|
||||
|
||||
/*
|
||||
* Const access to the head and tail pointers of the ring buffer.
|
||||
*/
|
||||
const void *
|
||||
ringbuf_tail(const struct ringbuf_t *rb);
|
||||
|
||||
const void *
|
||||
ringbuf_head(const struct ringbuf_t *rb);
|
||||
|
||||
/*
|
||||
* Copy n bytes from a contiguous memory area src into the ring buffer
|
||||
* dst. Returns the ring buffer's new head pointer.
|
||||
*
|
||||
* It is possible to copy more data from src than is available in the
|
||||
* buffer; i.e., it's possible to overflow the ring buffer using this
|
||||
* function. When an overflow occurs, the state of the ring buffer is
|
||||
* guaranteed to be consistent, including the head and tail pointers;
|
||||
* old data will simply be overwritten in FIFO fashion, as
|
||||
* needed. However, note that, if calling the function results in an
|
||||
* overflow, the value of the ring buffer's tail pointer may be
|
||||
* different than it was before the function was called.
|
||||
*/
|
||||
void *
|
||||
ringbuf_memcpy_into(ringbuf_t dst, const void *src, size_t count);
|
||||
|
||||
/*
|
||||
* Copy n bytes from the ring buffer src, starting from its tail
|
||||
* pointer, into a contiguous memory area dst. Returns the value of
|
||||
* src's tail pointer after the copy is finished.
|
||||
*
|
||||
* Note that this copy is destructive with respect to the ring buffer:
|
||||
* the n bytes copied from the ring buffer are no longer available in
|
||||
* the ring buffer after the copy is complete, and the ring buffer
|
||||
* will have n more free bytes than it did before the function was
|
||||
* called.
|
||||
*
|
||||
* This function will *not* allow the ring buffer to underflow. If
|
||||
* count is greater than the number of bytes used in the ring buffer,
|
||||
* no bytes are copied, and the function will return 0.
|
||||
*/
|
||||
void *
|
||||
ringbuf_memcpy_from(void *dst, ringbuf_t src, size_t count);
|
||||
|
||||
/*
|
||||
* Copy count bytes from ring buffer src, starting from its tail
|
||||
* pointer, into ring buffer dst. Returns dst's new head pointer after
|
||||
* the copy is finished.
|
||||
*
|
||||
* Note that this copy is destructive with respect to the ring buffer
|
||||
* src: any bytes copied from src into dst are no longer available in
|
||||
* src after the copy is complete, and src will have 'count' more free
|
||||
* bytes than it did before the function was called.
|
||||
*
|
||||
* It is possible to copy more data from src than is available in dst;
|
||||
* i.e., it's possible to overflow dst using this function. When an
|
||||
* overflow occurs, the state of dst is guaranteed to be consistent,
|
||||
* including the head and tail pointers; old data will simply be
|
||||
* overwritten in FIFO fashion, as needed. However, note that, if
|
||||
* calling the function results in an overflow, the value dst's tail
|
||||
* pointer may be different than it was before the function was
|
||||
* called.
|
||||
*
|
||||
* It is *not* possible to underflow src; if count is greater than the
|
||||
* number of bytes used in src, no bytes are copied, and the function
|
||||
* returns 0.
|
||||
*/
|
||||
void *
|
||||
ringbuf_copy(ringbuf_t dst, ringbuf_t src, size_t count);
|
||||
|
||||
#endif /* INCLUDED_RINGBUF_H */
|
||||
|
||||
36
user/sys_time.c
Normal file
36
user/sys_time.c
Normal file
@ -0,0 +1,36 @@
|
||||
#include "c_types.h"
|
||||
#include "osapi.h"
|
||||
|
||||
typedef union _timer {
|
||||
uint32_t time_s[2];
|
||||
uint64_t time_l;
|
||||
} long_time_t;
|
||||
|
||||
static long_time_t time;
|
||||
static uint32_t old;
|
||||
|
||||
uint64_t ICACHE_FLASH_ATTR
|
||||
get_long_systime()
|
||||
{
|
||||
uint32_t now = system_get_time();
|
||||
if (now < old)
|
||||
{
|
||||
time.time_s[1]++;
|
||||
}
|
||||
old = now;
|
||||
time.time_s[0] = now;
|
||||
return time.time_l;
|
||||
}
|
||||
|
||||
uint64_t ICACHE_FLASH_ATTR
|
||||
get_low_systime()
|
||||
{
|
||||
get_long_systime();
|
||||
return time.time_s[0];
|
||||
}
|
||||
|
||||
void init_long_systime()
|
||||
{
|
||||
old = system_get_time();
|
||||
time.time_l = (uint64_t)old;
|
||||
}
|
||||
13
user/sys_time.h
Normal file
13
user/sys_time.h
Normal file
@ -0,0 +1,13 @@
|
||||
#include "c_types.h"
|
||||
|
||||
// returns time until boot in us
|
||||
uint64_t ICACHE_FLASH_ATTR
|
||||
get_long_systime();
|
||||
|
||||
// returns lower half of time until boot in us
|
||||
uint64_t ICACHE_FLASH_ATTR
|
||||
get_low_systime();
|
||||
|
||||
// initializes the timer
|
||||
void
|
||||
init_long_systime();
|
||||
38
user/user_config.h
Normal file
38
user/user_config.h
Normal file
@ -0,0 +1,38 @@
|
||||
#ifndef _USER_CONFIG_
|
||||
#define _USER_CONFIG_
|
||||
|
||||
#define ESPERPASS_VERSION "V0.0.1"
|
||||
|
||||
#define WIFI_SSID "ssid"
|
||||
#define WIFI_PASSWORD "password"
|
||||
|
||||
#define WIFI_AP_SSID "attwifi"
|
||||
|
||||
#define MAX_CLIENTS 8
|
||||
#define MAX_DHCP 8
|
||||
|
||||
//
|
||||
// Size of the console buffers
|
||||
//
|
||||
#define MAX_CON_SEND_SIZE 1024
|
||||
#define MAX_CON_CMD_SIZE 80
|
||||
|
||||
//
|
||||
// Define this if you have a status LED connected to a GPIO pin
|
||||
//
|
||||
#define STATUS_LED_GPIO 2
|
||||
|
||||
//
|
||||
// Define this to support the setting of the WiFi PHY mode
|
||||
//
|
||||
#define PHY_MODE 1
|
||||
|
||||
//
|
||||
// Define this if you want to have ACLs for the SoftAP.
|
||||
//
|
||||
#define ACLS 1
|
||||
|
||||
// Internal
|
||||
typedef enum {SIG_DO_NOTHING=0, SIG_START_SERVER=1, SIG_SEND_DATA, SIG_UART0, SIG_CONSOLE_RX, SIG_CONSOLE_TX, SIG_CONSOLE_TX_RAW, SIG_GPIO_INT} USER_SIGNALS;
|
||||
|
||||
#endif
|
||||
1494
user/user_main.c
Normal file
1494
user/user_main.c
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user