Skip to content

Commit 69b1fcc

Browse files
committed
Merge pull request #6 from jlz3008/new_interrupt_example
Interrupt example
2 parents 132421c + 17e6530 commit 69b1fcc

File tree

4 files changed

+320
-0
lines changed

4 files changed

+320
-0
lines changed

interrupt_example/.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
build
2+
firmware
3+
testinterrupt.*

interrupt_example/Makefile

+149
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
# tnx to mamalala
2+
# Changelog
3+
# Changed the variables to include the header file directory
4+
# Added global var for the XTENSA tool root
5+
# Added variable for esptool bauds. Some modules don't work with default speed.
6+
#
7+
# This make file still needs some work.
8+
#
9+
# Updated for SDK 0.9.3
10+
#
11+
# Output directors to store intermediate compiled files
12+
# relative to the project directory
13+
BUILD_BASE = build
14+
FW_BASE = firmware
15+
16+
# Base directory for the compiler
17+
XTENSA_TOOLS_ROOT ?= /opt/Espressif/crosstool-NG/builds/xtensa-lx106-elf/bin
18+
19+
# base directory of the ESP8266 SDK package, absolute
20+
SDK_BASE ?= /opt/Espressif/ESP8266_SDK
21+
22+
#Esptool.py path and port
23+
ESPTOOL ?= esptool.py
24+
ESPPORT ?= /dev/ttyUSB0
25+
ESPBAUD ?= 115200
26+
27+
# name for the target project
28+
TARGET = app
29+
30+
# which modules (subdirectories) of the project to include in compiling
31+
MODULES = driver user
32+
EXTRA_INCDIR = include /opt/Espressif/include
33+
34+
# libraries used in this project, mainly provided by the SDK
35+
LIBS = c gcc hal pp phy net80211 lwip wpa main
36+
37+
# compiler flags using during compilation of source files
38+
CFLAGS = -Os -g -O2 -Wpointer-arith -Wundef -Werror -Wl,-EL -fno-inline-functions -nostdlib -mlongcalls -mtext-section-literals -D__ets__ -DICACHE_FLASH
39+
40+
# linker flags used to generate the main object file
41+
LDFLAGS = -nostdlib -Wl,--no-check-sections -u call_user_start -Wl,-static
42+
43+
# linker script used for the above linkier step
44+
LD_SCRIPT = eagle.app.v6.ld
45+
46+
# various paths from the SDK used in this project
47+
SDK_LIBDIR = lib
48+
SDK_LDDIR = ld
49+
SDK_INCDIR = include include/json
50+
51+
# we create two different files for uploading into the flash
52+
# these are the names and options to generate them
53+
FW_FILE_1 = 0x00000
54+
FW_FILE_1_ARGS = -bo $@ -bs .text -bs .data -bs .rodata -bc -ec
55+
FW_FILE_2 = 0x40000
56+
FW_FILE_2_ARGS = -es .irom0.text $@ -ec
57+
58+
# select which tools to use as compiler, librarian and linker
59+
CC := $(XTENSA_TOOLS_ROOT)/xtensa-lx106-elf-gcc
60+
AR := $(XTENSA_TOOLS_ROOT)/xtensa-lx106-elf-ar
61+
LD := $(XTENSA_TOOLS_ROOT)/xtensa-lx106-elf-gcc
62+
63+
64+
65+
####
66+
#### no user configurable options below here
67+
####
68+
FW_TOOL ?= /usr/bin/esptool
69+
SRC_DIR := $(MODULES)
70+
BUILD_DIR := $(addprefix $(BUILD_BASE)/,$(MODULES))
71+
72+
SDK_LIBDIR := $(addprefix $(SDK_BASE)/,$(SDK_LIBDIR))
73+
SDK_INCDIR := $(addprefix -I$(SDK_BASE)/,$(SDK_INCDIR))
74+
75+
SRC := $(foreach sdir,$(SRC_DIR),$(wildcard $(sdir)/*.c))
76+
OBJ := $(patsubst %.c,$(BUILD_BASE)/%.o,$(SRC))
77+
LIBS := $(addprefix -l,$(LIBS))
78+
APP_AR := $(addprefix $(BUILD_BASE)/,$(TARGET)_app.a)
79+
TARGET_OUT := $(addprefix $(BUILD_BASE)/,$(TARGET).out)
80+
81+
LD_SCRIPT := $(addprefix -T$(SDK_BASE)/$(SDK_LDDIR)/,$(LD_SCRIPT))
82+
83+
INCDIR := $(addprefix -I,$(SRC_DIR))
84+
EXTRA_INCDIR := $(addprefix -I,$(EXTRA_INCDIR))
85+
MODULE_INCDIR := $(addsuffix /include,$(INCDIR))
86+
87+
FW_FILE_1 := $(addprefix $(FW_BASE)/,$(FW_FILE_1).bin)
88+
FW_FILE_2 := $(addprefix $(FW_BASE)/,$(FW_FILE_2).bin)
89+
90+
V ?= $(VERBOSE)
91+
ifeq ("$(V)","1")
92+
Q :=
93+
vecho := @true
94+
else
95+
Q := @
96+
vecho := @echo
97+
endif
98+
99+
vpath %.c $(SRC_DIR)
100+
101+
define compile-objects
102+
$1/%.o: %.c
103+
$(vecho) "CC $$<"
104+
$(Q) $(CC) $(INCDIR) $(MODULE_INCDIR) $(EXTRA_INCDIR) $(SDK_INCDIR) $(CFLAGS) -c $$< -o $$@
105+
endef
106+
107+
.PHONY: all checkdirs flash clean
108+
109+
all: checkdirs $(TARGET_OUT) $(FW_FILE_1) $(FW_FILE_2)
110+
111+
$(FW_FILE_1): $(TARGET_OUT)
112+
$(vecho) "FW $@"
113+
$(Q) $(FW_TOOL) -eo $(TARGET_OUT) $(FW_FILE_1_ARGS)
114+
115+
$(FW_FILE_2): $(TARGET_OUT)
116+
$(vecho) "FW $@"
117+
$(Q) $(FW_TOOL) -eo $(TARGET_OUT) $(FW_FILE_2_ARGS)
118+
119+
$(TARGET_OUT): $(APP_AR)
120+
$(vecho) "LD $@"
121+
$(Q) $(LD) -L$(SDK_LIBDIR) $(LD_SCRIPT) $(LDFLAGS) -Wl,--start-group $(LIBS) $(APP_AR) -Wl,--end-group -o $@
122+
123+
$(APP_AR): $(OBJ)
124+
$(vecho) "AR $@"
125+
$(Q) $(AR) cru $@ $^
126+
127+
checkdirs: $(BUILD_DIR) $(FW_BASE)
128+
129+
$(BUILD_DIR):
130+
$(Q) mkdir -p $@
131+
132+
firmware:
133+
$(Q) mkdir -p $@
134+
135+
flash: firmware/0x00000.bin firmware/0x40000.bin
136+
-$(ESPTOOL) --baud $(ESPBAUD) --port $(ESPPORT) write_flash 0x00000 firmware/0x00000.bin 0x40000 firmware/0x40000.bin
137+
138+
clean:
139+
$(Q) rm -f $(APP_AR)
140+
$(Q) rm -f $(TARGET_OUT)
141+
$(Q) rm -rf $(BUILD_DIR)
142+
$(Q) rm -rf $(BUILD_BASE)
143+
144+
145+
$(Q) rm -f $(FW_FILE_1)
146+
$(Q) rm -f $(FW_FILE_2)
147+
$(Q) rm -rf $(FW_BASE)
148+
149+
$(foreach bdir,$(BUILD_DIR),$(eval $(call compile-objects,$(bdir))))

interrupt_example/user/user_config.h

Whitespace-only changes.

interrupt_example/user/user_main.c

+168
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
#include "ets_sys.h"
2+
#include "osapi.h"
3+
#include "gpio.h"
4+
#include "os_type.h"
5+
#include "user_interface.h"
6+
7+
#define user_procTaskPrio 0
8+
#define user_procTaskQueueLen 1
9+
os_event_t user_procTaskQueue[user_procTaskQueueLen];
10+
static void loop(os_event_t *events);
11+
12+
13+
// variable modified indirectly by interrupt handler
14+
volatile int whatyouwant;
15+
16+
// gpio interrupt handler. See below
17+
LOCAL void gpio_intr_handler(int * dummy);
18+
19+
//-------------------------------------------------------------------------------------------------
20+
// loop function will be execute by "os" periodically
21+
static void ICACHE_FLASH_ATTR loop(os_event_t *events)
22+
{
23+
static int level;
24+
25+
os_printf("What you want %d \r\n",whatyouwant);
26+
// change GPIO 2 level
27+
level = !level;
28+
GPIO_OUTPUT_SET(GPIO_ID_PIN(2), ((level) ? 1 : 0));
29+
// Delay
30+
os_delay_us(100000);
31+
// turn again
32+
system_os_post(user_procTaskPrio, 0, 0 );
33+
}
34+
35+
//-------------------------------------------------------------------------------------------------
36+
//Init function
37+
void ICACHE_FLASH_ATTR user_init()
38+
{
39+
40+
// Initialize UART0 to use as debug
41+
uart_div_modify(0, UART_CLK_FREQ / 9600);
42+
43+
os_printf(
44+
"GPIO Interrupt ESP8266 test\r\n"
45+
"---------------------------\r\n"
46+
" This program out a square wave on gpio2 and count edges for gpio0\r\n"
47+
" The program report count edges gpio0 periodically.\r\n"
48+
" You Can\r\n"
49+
" 1.- Connect GPIO0 to GPIO2 so you can see increment count edge periodically\r\n"
50+
" 2.- Unconnect GPIO0 from GPIO2 so you can see stop count edge\r\n"
51+
" 3.- Connect GPIO0 to ground to increment count edge\r\n"
52+
);
53+
54+
// Initialize the GPIO subsystem.
55+
gpio_init();
56+
57+
// =================================================
58+
// Initialize GPIO2 and GPIO0 as GPIO
59+
// =================================================
60+
//
61+
//
62+
// PIN_FUNC_SELECT() defined in eagle_soc.h
63+
// PERIPHS_IO_MUX_... for each pin defined in eagle_soc.h
64+
// FUNC_... for each PERIPHS macros defined in eagle_soc.h
65+
//
66+
// From eagle_soc.h:
67+
// GPIO0 only can be GPIO
68+
// GPIO2 can be GPIO, TXD from uart0, or TXD from uart1
69+
//
70+
// #define PERIPHS_IO_MUX_GPIO0_U (PERIPHS_IO_MUX + 0x34)
71+
// #define FUNC_GPIO0 0
72+
// #define PERIPHS_IO_MUX_GPIO2_U (PERIPHS_IO_MUX + 0x38)
73+
// #define FUNC_GPIO2 0
74+
// #define FUNC_U1TXD_BK 2
75+
// #define FUNC_U0TXD_BK 4
76+
//
77+
78+
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO0_U, FUNC_GPIO0);
79+
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_GPIO2);
80+
81+
// You can select enable/disable internal pullup/pulldown for each pin
82+
//
83+
// PIN_PULLUP_DIS(PIN_NAME)
84+
// PIN_PULLUP_EN(PIN_NAME)
85+
// PIN_PULLDWN_DIS(PIN_NAME)
86+
// PIN_PULLDWN_EN(PIN_NAME)
87+
88+
PIN_PULLUP_DIS(PERIPHS_IO_MUX_GPIO0_U);
89+
PIN_PULLDWN_DIS(PERIPHS_IO_MUX_GPIO0_U);
90+
PIN_PULLUP_EN(PERIPHS_IO_MUX_GPIO2_U);
91+
92+
//
93+
// void gpio_output_set(uint32 set_mask, uint32 clear_mask, uint32 enable_mask, uint32 disable_mask)
94+
//
95+
// set status and direction pin by mask gpio id pin.
96+
97+
gpio_output_set(0, GPIO_ID_PIN(2), GPIO_ID_PIN(2), GPIO_ID_PIN(0)); // set gpio 2 as output and low. set gpio 0 as input
98+
99+
// =================================================
100+
// Activate gpio interrupt for gpio2
101+
// =================================================
102+
103+
// Disable interrupts by GPIO
104+
ETS_GPIO_INTR_DISABLE();
105+
106+
// Attach interrupt handle to gpio interrupts.
107+
// You can set a void pointer that will be passed to interrupt handler each interrupt
108+
109+
ETS_GPIO_INTR_ATTACH(gpio_intr_handler, &whatyouwant);
110+
111+
// void gpio_register_set(uint32 reg_id, uint32 value);
112+
//
113+
// From include file
114+
// Set the specified GPIO register to the specified value.
115+
// This is a very general and powerful interface that is not
116+
// expected to be used during normal operation. It is intended
117+
// mainly for debug, or for unusual requirements.
118+
//
119+
// All people repeat this mantra but I don't know what it means
120+
//
121+
gpio_register_set(GPIO_PIN_ADDR(0),
122+
GPIO_PIN_INT_TYPE_SET(GPIO_PIN_INTR_DISABLE) |
123+
GPIO_PIN_PAD_DRIVER_SET(GPIO_PAD_DRIVER_DISABLE) |
124+
GPIO_PIN_SOURCE_SET(GPIO_AS_PIN_SOURCE));
125+
126+
// clear gpio status. Say ESP8266EX SDK Programming Guide in 5.1.6. GPIO interrupt handler
127+
128+
GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, BIT(0));
129+
130+
// enable interrupt for his GPIO
131+
// GPIO_PIN_INTR_... defined in gpio.h
132+
133+
gpio_pin_intr_state_set(GPIO_ID_PIN(0), GPIO_PIN_INTR_ANYEGDE);
134+
135+
ETS_GPIO_INTR_ENABLE();
136+
137+
//Start os task
138+
system_os_task(loop, user_procTaskPrio,user_procTaskQueue, user_procTaskQueueLen);
139+
140+
system_os_post(user_procTaskPrio, 0, 0 );
141+
}
142+
143+
//-------------------------------------------------------------------------------------------------
144+
// interrupt handler
145+
// this function will be executed on any edge of GPIO0
146+
LOCAL void gpio_intr_handler(int * dummy)
147+
{
148+
// clear gpio status. Say ESP8266EX SDK Programming Guide in 5.1.6. GPIO interrupt handler
149+
150+
uint32 gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS);
151+
152+
// if the interrupt was by GPIO0
153+
if (gpio_status & BIT(0))
154+
{
155+
// disable interrupt for GPIO0
156+
gpio_pin_intr_state_set(GPIO_ID_PIN(0), GPIO_PIN_INTR_DISABLE);
157+
158+
// Do something, for example, increment whatyouwant indirectly
159+
(*dummy)++;
160+
161+
//clear interrupt status for GPIO0
162+
GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, gpio_status & BIT(0));
163+
164+
// Reactivate interrupts for GPIO0
165+
gpio_pin_intr_state_set(GPIO_ID_PIN(0), GPIO_PIN_INTR_ANYEGDE);
166+
}
167+
}
168+

0 commit comments

Comments
 (0)