Add GPIO config, interrupt registers, GPIO interrupt support, 'button' example
This commit is contained in:
parent
822533fd92
commit
0078252df3
7 changed files with 377 additions and 16 deletions
63
core/esp_gpio_interrupts.c
Normal file
63
core/esp_gpio_interrupts.c
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
/* ESP GPIO interrupts.
|
||||||
|
|
||||||
|
Use with gpio_set_interrupt(), defined in esp/gpio.h
|
||||||
|
|
||||||
|
|
||||||
|
These interrupt vectors are default implementations with weak
|
||||||
|
linkage. Override your own GPIO interrupt vectors in your program
|
||||||
|
and they will replace these.
|
||||||
|
|
||||||
|
Look in examples/button/ for a simple GPIO interrupt example.
|
||||||
|
|
||||||
|
You can implement your own interrupts in two ways:
|
||||||
|
|
||||||
|
- Implement gpXX_interrupt_handler() for the GPIO pin numbers that you want to attach interrupts to. This is simple but it may not be enough sometimes
|
||||||
|
|
||||||
|
- Implement a single gpio_interrupt_handler() and manually check GPIO_STATUS_REG
|
||||||
|
and clear any status bits after handling interrupts. This gives
|
||||||
|
you full control.
|
||||||
|
*/
|
||||||
|
#include "esp8266.h"
|
||||||
|
|
||||||
|
void gpio_interrupt_handler(void);
|
||||||
|
void gpio_noop_interrupt_handler(void) { }
|
||||||
|
void gpio00_interrupt_handler(void) __attribute__((weak, alias("gpio_noop_interrupt_handler")));
|
||||||
|
void gpio01_interrupt_handler(void) __attribute__((weak, alias("gpio_noop_interrupt_handler")));
|
||||||
|
void gpio02_interrupt_handler(void) __attribute__((weak, alias("gpio_noop_interrupt_handler")));
|
||||||
|
void gpio03_interrupt_handler(void) __attribute__((weak, alias("gpio_noop_interrupt_handler")));
|
||||||
|
void gpio04_interrupt_handler(void) __attribute__((weak, alias("gpio_noop_interrupt_handler")));
|
||||||
|
void gpio05_interrupt_handler(void) __attribute__((weak, alias("gpio_noop_interrupt_handler")));
|
||||||
|
void gpio06_interrupt_handler(void) __attribute__((weak, alias("gpio_noop_interrupt_handler")));
|
||||||
|
void gpio07_interrupt_handler(void) __attribute__((weak, alias("gpio_noop_interrupt_handler")));
|
||||||
|
void gpio08_interrupt_handler(void) __attribute__((weak, alias("gpio_noop_interrupt_handler")));
|
||||||
|
void gpio09_interrupt_handler(void) __attribute__((weak, alias("gpio_noop_interrupt_handler")));
|
||||||
|
void gpio10_interrupt_handler(void) __attribute__((weak, alias("gpio_noop_interrupt_handler")));
|
||||||
|
void gpio11_interrupt_handler(void) __attribute__((weak, alias("gpio_noop_interrupt_handler")));
|
||||||
|
void gpio12_interrupt_handler(void) __attribute__((weak, alias("gpio_noop_interrupt_handler")));
|
||||||
|
void gpio13_interrupt_handler(void) __attribute__((weak, alias("gpio_noop_interrupt_handler")));
|
||||||
|
void gpio14_interrupt_handler(void) __attribute__((weak, alias("gpio_noop_interrupt_handler")));
|
||||||
|
void gpio15_interrupt_handler(void) __attribute__((weak, alias("gpio_noop_interrupt_handler")));
|
||||||
|
|
||||||
|
typedef void (* gpio_interrupt_handler_t)(void);
|
||||||
|
|
||||||
|
const gpio_interrupt_handler_t gpio_interrupt_handlers[16] = {
|
||||||
|
gpio00_interrupt_handler, gpio01_interrupt_handler, gpio02_interrupt_handler,
|
||||||
|
gpio03_interrupt_handler, gpio04_interrupt_handler, gpio05_interrupt_handler,
|
||||||
|
gpio06_interrupt_handler, gpio07_interrupt_handler, gpio08_interrupt_handler,
|
||||||
|
gpio09_interrupt_handler, gpio10_interrupt_handler, gpio11_interrupt_handler,
|
||||||
|
gpio12_interrupt_handler, gpio13_interrupt_handler, gpio14_interrupt_handler,
|
||||||
|
gpio15_interrupt_handler };
|
||||||
|
|
||||||
|
void __attribute__((weak)) IRAM gpio_interrupt_handler(void)
|
||||||
|
{
|
||||||
|
uint32_t status_reg = GPIO_STATUS_REG;
|
||||||
|
GPIO_STATUS_CLEAR = status_reg;
|
||||||
|
uint8_t gpio_idx;
|
||||||
|
while((gpio_idx = __builtin_ffs(status_reg)))
|
||||||
|
{
|
||||||
|
gpio_idx--;
|
||||||
|
status_reg &= ~BIT(gpio_idx);
|
||||||
|
if(GPIO_CTRL_REG(gpio_idx) & GPIO_INT_MASK)
|
||||||
|
gpio_interrupt_handlers[gpio_idx]();
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,11 +10,14 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include "esp/registers.h"
|
#include "esp/registers.h"
|
||||||
#include "esp/iomux.h"
|
#include "esp/iomux.h"
|
||||||
|
#include "esp/cpu.h"
|
||||||
|
#include "xtensa_interrupts.h"
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
GPIO_INPUT = 0,
|
GPIO_INPUT,
|
||||||
GPIO_OUTPUT = IOMUX_OE,
|
GPIO_OUTPUT, /* "Standard" push-pull output */
|
||||||
GPIO_INPUT_PULLUP = IOMUX_PU,
|
GPIO_OUT_OPEN_DRAIN, /* Open drain output */
|
||||||
|
GPIO_INPUT_PULLUP,
|
||||||
} gpio_direction_t;
|
} gpio_direction_t;
|
||||||
|
|
||||||
/* Enable GPIO on the specified pin, and set it to input/output/ with
|
/* Enable GPIO on the specified pin, and set it to input/output/ with
|
||||||
|
@ -22,7 +25,28 @@ typedef enum {
|
||||||
*/
|
*/
|
||||||
INLINED void gpio_enable(const uint8_t gpio_num, const gpio_direction_t direction)
|
INLINED void gpio_enable(const uint8_t gpio_num, const gpio_direction_t direction)
|
||||||
{
|
{
|
||||||
iomux_set_gpio_function(gpio_num, (uint8_t)direction);
|
uint32_t iomux_flags;
|
||||||
|
uint32_t ctrl_val;
|
||||||
|
|
||||||
|
switch(direction) {
|
||||||
|
case GPIO_INPUT:
|
||||||
|
iomux_flags = 0;
|
||||||
|
ctrl_val = GPIO_SOURCE_GPIO;
|
||||||
|
break;
|
||||||
|
case GPIO_OUTPUT:
|
||||||
|
iomux_flags = IOMUX_OE;
|
||||||
|
ctrl_val = GPIO_DRIVE_PUSH_PULL|GPIO_SOURCE_GPIO;
|
||||||
|
break;
|
||||||
|
case GPIO_OUT_OPEN_DRAIN:
|
||||||
|
iomux_flags = IOMUX_OE;
|
||||||
|
ctrl_val = GPIO_DRIVE_OPEN_DRAIN|GPIO_SOURCE_GPIO;
|
||||||
|
break;
|
||||||
|
case GPIO_INPUT_PULLUP:
|
||||||
|
iomux_flags = IOMUX_PU;
|
||||||
|
ctrl_val = GPIO_SOURCE_GPIO;
|
||||||
|
}
|
||||||
|
iomux_set_gpio_function(gpio_num, iomux_flags);
|
||||||
|
GPIO_CTRL_REG(gpio_num) = (GPIO_CTRL_REG(gpio_num)&GPIO_INT_MASK) | ctrl_val;
|
||||||
if(direction == GPIO_OUTPUT)
|
if(direction == GPIO_OUTPUT)
|
||||||
GPIO_DIR_SET = BIT(gpio_num);
|
GPIO_DIR_SET = BIT(gpio_num);
|
||||||
else
|
else
|
||||||
|
@ -80,5 +104,27 @@ INLINED bool gpio_read(const uint8_t gpio_num)
|
||||||
return GPIO_IN_REG & BIT(gpio_num);
|
return GPIO_IN_REG & BIT(gpio_num);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
INT_NONE = 0,
|
||||||
|
INT_RISING = GPIO_INT_RISING,
|
||||||
|
INT_FALLING = GPIO_INT_FALLING,
|
||||||
|
INT_CHANGE = GPIO_INT_CHANGE,
|
||||||
|
INT_LOW = GPIO_INT_LOW,
|
||||||
|
INT_HIGH = GPIO_INT_HIGH,
|
||||||
|
} gpio_interrupt_t;
|
||||||
|
|
||||||
|
extern void gpio_interrupt_handler(void);
|
||||||
|
|
||||||
|
/* Set the interrupt type for a given pin
|
||||||
|
*/
|
||||||
|
INLINED void gpio_set_interrupt(const uint8_t gpio_num, const gpio_interrupt_t int_type)
|
||||||
|
{
|
||||||
|
GPIO_CTRL_REG(gpio_num) = (GPIO_CTRL_REG(gpio_num)&~GPIO_INT_MASK)
|
||||||
|
| (int_type & GPIO_INT_MASK);
|
||||||
|
if(int_type != INT_NONE) {
|
||||||
|
_xt_isr_attach(INUM_GPIO, gpio_interrupt_handler);
|
||||||
|
_xt_isr_unmask(1<<INUM_GPIO);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -17,6 +17,9 @@
|
||||||
|
|
||||||
typedef volatile uint32_t *esp_reg_t;
|
typedef volatile uint32_t *esp_reg_t;
|
||||||
|
|
||||||
|
/* Internal macro, only defined in header body */
|
||||||
|
#define _REG(BASE, OFFSET) (*(esp_reg_t)((BASE)+(OFFSET)))
|
||||||
|
|
||||||
/* Register base addresses
|
/* Register base addresses
|
||||||
|
|
||||||
You shouldn't need to use these directly.
|
You shouldn't need to use these directly.
|
||||||
|
@ -43,7 +46,7 @@ typedef volatile uint32_t *esp_reg_t;
|
||||||
* Note that IOMUX register order is _not_ the same as GPIO order. See
|
* Note that IOMUX register order is _not_ the same as GPIO order. See
|
||||||
* esp_iomux.h for programmer-friendly IOMUX configuration options
|
* esp_iomux.h for programmer-friendly IOMUX configuration options
|
||||||
*/
|
*/
|
||||||
#define IOMUX_REG(X) *(esp_reg_t)(IOMUX_BASE+4*(X+1))
|
#define IOMUX_REG(X) _REG(IOMUX_BASE,0x04+4*X)
|
||||||
|
|
||||||
#define IOMUX_OE BIT(0) /* iomux Output enable bit */
|
#define IOMUX_OE BIT(0) /* iomux Output enable bit */
|
||||||
#define IOMUX_OE_SLEEP BIT(1) /* iomux Output during sleep bit */
|
#define IOMUX_OE_SLEEP BIT(1) /* iomux Output during sleep bit */
|
||||||
|
@ -85,25 +88,59 @@ typedef volatile uint32_t *esp_reg_t;
|
||||||
*
|
*
|
||||||
* ... are equivalent, but latter uses less CPU cycles.
|
* ... are equivalent, but latter uses less CPU cycles.
|
||||||
*/
|
*/
|
||||||
#define GPIO_OUT_REG *(esp_reg_t)(GPIO0_BASE)
|
#define GPIO_OUT_REG _REG(GPIO0_BASE, 0x00)
|
||||||
#define GPIO_OUT_SET *(esp_reg_t)(GPIO0_BASE+0x04)
|
#define GPIO_OUT_SET _REG(GPIO0_BASE, 0x04)
|
||||||
#define GPIO_OUT_CLEAR *(esp_reg_t)(GPIO0_BASE+0x08)
|
#define GPIO_OUT_CLEAR _REG(GPIO0_BASE, 0x08)
|
||||||
|
|
||||||
/* GPIO DIR registers GPIO_DIR_REG, GPIO_DIR_SET, GPIO_DIR_CLEAR
|
/* GPIO DIR registers GPIO_DIR_REG, GPIO_DIR_SET, GPIO_DIR_CLEAR
|
||||||
*
|
*
|
||||||
* Set bit in DIR register for output pins. Writing to _SET and _CLEAR
|
* Set bit in DIR register for output pins. Writing to _SET and _CLEAR
|
||||||
* registers set and clear bits in _REG, respectively.
|
* registers set and clear bits in _REG, respectively.
|
||||||
*/
|
*/
|
||||||
#define GPIO_DIR_REG *(esp_reg_t)(GPIO0_BASE+0x0C)
|
#define GPIO_DIR_REG _REG(GPIO0_BASE, 0x0C)
|
||||||
#define GPIO_DIR_SET *(esp_reg_t)(GPIO0_BASE+0x10)
|
#define GPIO_DIR_SET _REG(GPIO0_BASE, 0x10)
|
||||||
#define GPIO_DIR_CLEAR *(esp_reg_t)(GPIO0_BASE+0x14)
|
#define GPIO_DIR_CLEAR _REG(GPIO0_BASE, 0x14)
|
||||||
|
|
||||||
|
|
||||||
/* GPIO IN register GPIO_IN_REG
|
/* GPIO IN register GPIO_IN_REG
|
||||||
*
|
*
|
||||||
* Reads current input values.
|
* Reads current input values.
|
||||||
*/
|
*/
|
||||||
#define GPIO_IN_REG *(esp_reg_t)(GPIO0_BASE+0x18)
|
#define GPIO_IN_REG _REG(GPIO0_BASE, 0x18)
|
||||||
|
|
||||||
|
/* GPIO interrupt 'status' flag
|
||||||
|
|
||||||
|
Bit set if interrupt has fired (see below for interrupt config
|
||||||
|
registers.
|
||||||
|
|
||||||
|
Lower 16 bits only are used.
|
||||||
|
*/
|
||||||
|
#define GPIO_STATUS_REG _REG(GPIO0_BASE,0x1c)
|
||||||
|
#define GPIO_STATUS_SET _REG(GPIO0_BASE,0x20)
|
||||||
|
#define GPIO_STATUS_CLEAR _REG(GPIO0_BASE,0x24)
|
||||||
|
|
||||||
|
#define GPIO_STATUS_MASK 0x0000FFFFL
|
||||||
|
|
||||||
|
/* GPIO pin control registers for GPIOs 0-15
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define GPIO_CTRL_REG(GPNUM) _REG(GPIO0_BASE, 0x28+(GPNUM*4))
|
||||||
|
|
||||||
|
#define GPIO_SOURCE_GPIO 0
|
||||||
|
#define GPIO_SOURCE_DAC BIT(0) /* "Sigma-Delta" */
|
||||||
|
#define GPIO_SOURCE_MASK BIT(0
|
||||||
|
|
||||||
|
#define GPIO_DRIVE_PUSH_PULL 0
|
||||||
|
#define GPIO_DRIVE_OPEN_DRAIN BIT(2)
|
||||||
|
#define GPIO_DRIVE_MASK BIT(2)
|
||||||
|
|
||||||
|
#define GPIO_INT_NONE 0
|
||||||
|
#define GPIO_INT_RISING BIT(7)
|
||||||
|
#define GPIO_INT_FALLING BIT(8)
|
||||||
|
#define GPIO_INT_CHANGE (BIT(7)|BIT(8))
|
||||||
|
#define GPIO_INT_LOW BIT(9)
|
||||||
|
#define GPIO_INT_HIGH (BIT(7)|BIT(9))
|
||||||
|
#define GPIO_INT_MASK (BIT(7)|BIT(8)|BIT(9))
|
||||||
|
|
||||||
/* WDT register(s)
|
/* WDT register(s)
|
||||||
|
|
||||||
|
@ -111,6 +148,6 @@ typedef volatile uint32_t *esp_reg_t;
|
||||||
|
|
||||||
See ROM functions esp_wdt_xxx
|
See ROM functions esp_wdt_xxx
|
||||||
*/
|
*/
|
||||||
#define WDT_CTRL *(esp_reg_t)(WDT_BASE)
|
#define WDT_CTRL _REG(WDT_BASE, 0x00)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -13,7 +13,8 @@ const int gpio = 14;
|
||||||
/* This task uses the high level GPIO API (esp_gpio.h) to blink an LED.
|
/* This task uses the high level GPIO API (esp_gpio.h) to blink an LED.
|
||||||
*
|
*
|
||||||
* Even though it reads better than the register-level version in blinkenRegisterTask,
|
* Even though it reads better than the register-level version in blinkenRegisterTask,
|
||||||
* they compile to the exact same instructions.
|
* they compile to the exact same instructions (except gpio_enable also set the output type in
|
||||||
|
* the GPIO control register).
|
||||||
*/
|
*/
|
||||||
void blinkenTask(void *pvParameters)
|
void blinkenTask(void *pvParameters)
|
||||||
{
|
{
|
||||||
|
@ -32,8 +33,9 @@ void blinkenTask(void *pvParameters)
|
||||||
It's not fully parameterised, as the IOMUX_SET macro requires the pin number
|
It's not fully parameterised, as the IOMUX_SET macro requires the pin number
|
||||||
as part of the GPxx value.
|
as part of the GPxx value.
|
||||||
|
|
||||||
This code compiles to the exact same instructions as blinkenTask,
|
There is no significant performance benefit to this way over the
|
||||||
so it's probably better to use the blinkenTask version.
|
blinkenTask version, so it's probably better to use the blinkenTask
|
||||||
|
version.
|
||||||
|
|
||||||
NOTE: This task isn't enabled by default, see the commented out line in user_init.
|
NOTE: This task isn't enabled by default, see the commented out line in user_init.
|
||||||
*/
|
*/
|
||||||
|
|
127
examples/button/FreeRTOSConfig.h
Normal file
127
examples/button/FreeRTOSConfig.h
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that has become a de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly and support the FreeRTOS *
|
||||||
|
* project by purchasing a FreeRTOS tutorial book, reference *
|
||||||
|
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
* Thank you! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to distribute
|
||||||
|
>>! a combined work that includes FreeRTOS without being obliged to provide
|
||||||
|
>>! the source code for proprietary components outside of the FreeRTOS
|
||||||
|
>>! kernel.
|
||||||
|
|
||||||
|
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. Full license text is available from the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, books, training, latest versions,
|
||||||
|
license and Real Time Engineers Ltd. contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
||||||
|
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FREERTOS_CONFIG_H
|
||||||
|
#define FREERTOS_CONFIG_H
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Application specific definitions.
|
||||||
|
*
|
||||||
|
* These definitions should be adjusted for your particular hardware and
|
||||||
|
* application requirements.
|
||||||
|
*
|
||||||
|
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
|
||||||
|
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
|
||||||
|
*
|
||||||
|
* See http://www.freertos.org/a00110.html.
|
||||||
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define configUSE_PREEMPTION 1
|
||||||
|
#define configUSE_IDLE_HOOK 0
|
||||||
|
#define configUSE_TICK_HOOK 0
|
||||||
|
#define configCPU_CLOCK_HZ ( ( unsigned long ) 80000000 )
|
||||||
|
#define configTICK_RATE_HZ ( ( portTickType ) 100 )
|
||||||
|
#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 15 )
|
||||||
|
#define configMINIMAL_STACK_SIZE ( ( unsigned short )156 )
|
||||||
|
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 32 * 1024 ) )
|
||||||
|
#define configMAX_TASK_NAME_LEN ( 16 )
|
||||||
|
#define configUSE_TRACE_FACILITY 0
|
||||||
|
#define configUSE_STATS_FORMATTING_FUNCTIONS 0
|
||||||
|
#define configUSE_16_BIT_TICKS 0
|
||||||
|
#define configIDLE_SHOULD_YIELD 1
|
||||||
|
|
||||||
|
#define INCLUDE_xTaskGetIdleTaskHandle 1
|
||||||
|
#define INCLUDE_xTimerGetTimerDaemonTaskHandle 1
|
||||||
|
|
||||||
|
#define configCHECK_FOR_STACK_OVERFLOW 2
|
||||||
|
#define configUSE_MUTEXES 1
|
||||||
|
#define configUSE_TIMERS 1
|
||||||
|
|
||||||
|
#if configUSE_TIMERS
|
||||||
|
#define configTIMER_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
|
||||||
|
#define configTIMER_QUEUE_LENGTH (10)
|
||||||
|
#define configTIMER_TASK_STACK_DEPTH ( ( unsigned short ) 512 )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Co-routine definitions. */
|
||||||
|
#define configUSE_CO_ROUTINES 0
|
||||||
|
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
|
||||||
|
|
||||||
|
/* Set the following definitions to 1 to include the API function, or zero
|
||||||
|
to exclude the API function. */
|
||||||
|
|
||||||
|
#define INCLUDE_vTaskPrioritySet 1
|
||||||
|
#define INCLUDE_uxTaskPriorityGet 1
|
||||||
|
#define INCLUDE_vTaskDelete 1
|
||||||
|
#define INCLUDE_vTaskCleanUpResources 0
|
||||||
|
#define INCLUDE_vTaskSuspend 1
|
||||||
|
#define INCLUDE_vTaskDelayUntil 1
|
||||||
|
#define INCLUDE_vTaskDelay 1
|
||||||
|
|
||||||
|
/*set the #define for debug info*/
|
||||||
|
#define INCLUDE_xTaskGetCurrentTaskHandle 1
|
||||||
|
#define INCLUDE_uxTaskGetStackHighWaterMark 1
|
||||||
|
|
||||||
|
#endif /* FREERTOS_CONFIG_H */
|
||||||
|
|
2
examples/button/Makefile
Normal file
2
examples/button/Makefile
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
TARGET=button
|
||||||
|
include ../../common.mk
|
84
examples/button/button.c
Normal file
84
examples/button/button.c
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
/* Respond to a button press.
|
||||||
|
*
|
||||||
|
* This code combines two ways of checking for a button press -
|
||||||
|
* busy polling (the bad way) and button interrupt (the good way).
|
||||||
|
*
|
||||||
|
* This sample code is in the public domain.
|
||||||
|
*/
|
||||||
|
#include "espressif/esp_common.h"
|
||||||
|
#include "espressif/sdk_private.h"
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "queue.h"
|
||||||
|
#include "esp8266.h"
|
||||||
|
|
||||||
|
/* pin config */
|
||||||
|
const int gpio = 0; /* gpio 0 usually has "PROGRAM" button attached */
|
||||||
|
const int active = 0; /* active == 0 for active low */
|
||||||
|
const gpio_interrupt_t int_type = INT_FALLING;
|
||||||
|
#define GPIO_HANDLER gpio00_interrupt_handler
|
||||||
|
|
||||||
|
|
||||||
|
/* This task polls for the button and prints the tick
|
||||||
|
count when it's seen.
|
||||||
|
|
||||||
|
Debounced to 200ms with a simple vTaskDelay.
|
||||||
|
|
||||||
|
This is not a good example of how to wait for button input!
|
||||||
|
*/
|
||||||
|
void buttonPollTask(void *pvParameters)
|
||||||
|
{
|
||||||
|
printf("Polling for button press on gpio %d...\r\n", gpio);
|
||||||
|
while(1) {
|
||||||
|
while(gpio_read(gpio) != active)
|
||||||
|
{
|
||||||
|
taskYIELD();
|
||||||
|
}
|
||||||
|
printf("Polled for button press at %dms\r\n", xTaskGetTickCount()*portTICK_RATE_MS);
|
||||||
|
vTaskDelay(200 / portTICK_RATE_MS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This task configures the GPIO interrupt and uses it to tell
|
||||||
|
when the button is pressed.
|
||||||
|
|
||||||
|
The interrupt handler communicates the exact button press time to
|
||||||
|
the task via a queue.
|
||||||
|
|
||||||
|
This is a better example of how to wait for button input!
|
||||||
|
*/
|
||||||
|
void buttonIntTask(void *pvParameters)
|
||||||
|
{
|
||||||
|
printf("Waiting for button press interrupt on gpio %d...\r\n", gpio);
|
||||||
|
xQueueHandle *tsqueue = (xQueueHandle *)pvParameters;
|
||||||
|
gpio_set_interrupt(gpio, int_type);
|
||||||
|
|
||||||
|
uint32_t last = 0;
|
||||||
|
while(1) {
|
||||||
|
uint32_t button_ts;
|
||||||
|
xQueueReceive(*tsqueue, &button_ts, portMAX_DELAY);
|
||||||
|
button_ts *= portTICK_RATE_MS;
|
||||||
|
if(last < button_ts-200) {
|
||||||
|
printf("Button interrupt fired at %dms\r\n", button_ts);
|
||||||
|
last = button_ts;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static xQueueHandle tsqueue;
|
||||||
|
|
||||||
|
void GPIO_HANDLER(void)
|
||||||
|
{
|
||||||
|
uint32_t now = xTaskGetTickCountFromISR();
|
||||||
|
xQueueSendToBackFromISR(tsqueue, &now, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void user_init(void)
|
||||||
|
{
|
||||||
|
sdk_uart_div_modify(0, UART_CLK_FREQ / 115200);
|
||||||
|
gpio_enable(gpio, GPIO_INPUT);
|
||||||
|
|
||||||
|
tsqueue = xQueueCreate(2, sizeof(uint32_t));
|
||||||
|
xTaskCreate(buttonIntTask, (signed char *)"buttonIntTask", 256, &tsqueue, 2, NULL);
|
||||||
|
xTaskCreate(buttonPollTask, (signed char*)"buttonPollTask", 256, NULL, 1, NULL);
|
||||||
|
}
|
Loading…
Reference in a new issue