Add esp/gpio_regs.h
This commit is contained in:
parent
2ffd3da71e
commit
fc1a1a7d0a
6 changed files with 167 additions and 114 deletions
|
@ -25,7 +25,7 @@
|
||||||
OR
|
OR
|
||||||
|
|
||||||
- Implement a single function named gpio_interrupt_handler(). This
|
- Implement a single function named gpio_interrupt_handler(). This
|
||||||
will need to manually check GPIO_STATUS_REG and clear any status
|
will need to manually check GPIO.STATUS and clear any status
|
||||||
bits after handling interrupts. This gives you full control, but
|
bits after handling interrupts. This gives you full control, but
|
||||||
you can't combine it with the first approach.
|
you can't combine it with the first approach.
|
||||||
|
|
||||||
|
@ -67,14 +67,14 @@ const gpio_interrupt_handler_t gpio_interrupt_handlers[16] = {
|
||||||
|
|
||||||
void __attribute__((weak)) IRAM gpio_interrupt_handler(void)
|
void __attribute__((weak)) IRAM gpio_interrupt_handler(void)
|
||||||
{
|
{
|
||||||
uint32_t status_reg = GPIO_STATUS_REG;
|
uint32_t status_reg = GPIO.STATUS;
|
||||||
GPIO_STATUS_CLEAR = status_reg;
|
GPIO.STATUS_CLEAR = status_reg;
|
||||||
uint8_t gpio_idx;
|
uint8_t gpio_idx;
|
||||||
while((gpio_idx = __builtin_ffs(status_reg)))
|
while((gpio_idx = __builtin_ffs(status_reg)))
|
||||||
{
|
{
|
||||||
gpio_idx--;
|
gpio_idx--;
|
||||||
status_reg &= ~BIT(gpio_idx);
|
status_reg &= ~BIT(gpio_idx);
|
||||||
if(GPIO_CTRL_REG(gpio_idx) & GPIO_INT_MASK)
|
if(FIELD2VAL(GPIO_CONF_INTTYPE, GPIO.CONF[gpio_idx]))
|
||||||
gpio_interrupt_handlers[gpio_idx]();
|
gpio_interrupt_handlers[gpio_idx]();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,8 @@
|
||||||
#define VAL2FIELD(fieldname, value) (((value) & fieldname##_M) << fieldname##_S)
|
#define VAL2FIELD(fieldname, value) (((value) & fieldname##_M) << fieldname##_S)
|
||||||
#define FIELD2VAL(fieldname, regbits) (((regbits) >> fieldname##_S) & fieldname##_M)
|
#define FIELD2VAL(fieldname, regbits) (((regbits) >> fieldname##_S) & fieldname##_M)
|
||||||
|
|
||||||
#define SETFIELD(regbits, fieldname, value) (((regbits) & ~(fieldname##_M << fieldname##_S)) | VAL2FIELD(fieldname, value))
|
#define FIELD_MASK(fieldname) (fieldname##_M << fieldname##_S)
|
||||||
|
#define SET_FIELD(regbits, fieldname, value) (((regbits) & ~FIELD_MASK(fieldname)) | VAL2FIELD(fieldname, value))
|
||||||
|
|
||||||
/* Use this macro to store constant values in IROM flash instead
|
/* Use this macro to store constant values in IROM flash instead
|
||||||
of having them loaded into rodata (which resides in DRAM)
|
of having them loaded into rodata (which resides in DRAM)
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#ifndef _ESP_GPIO_H
|
#ifndef _ESP_GPIO_H
|
||||||
#define _ESP_GPIO_H
|
#define _ESP_GPIO_H
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include "esp/registers.h"
|
#include "esp/gpio_regs.h"
|
||||||
#include "esp/iomux.h"
|
#include "esp/iomux.h"
|
||||||
#include "esp/cpu.h"
|
#include "esp/cpu.h"
|
||||||
#include "xtensa_interrupts.h"
|
#include "xtensa_interrupts.h"
|
||||||
|
@ -32,26 +32,27 @@ INLINED void gpio_enable(const uint8_t gpio_num, const gpio_direction_t directio
|
||||||
switch(direction) {
|
switch(direction) {
|
||||||
case GPIO_INPUT:
|
case GPIO_INPUT:
|
||||||
iomux_flags = 0;
|
iomux_flags = 0;
|
||||||
ctrl_val = GPIO_SOURCE_GPIO;
|
ctrl_val = 0;
|
||||||
break;
|
break;
|
||||||
case GPIO_OUTPUT:
|
case GPIO_OUTPUT:
|
||||||
iomux_flags = IOMUX_PIN_OUTPUT_ENABLE;
|
iomux_flags = IOMUX_PIN_OUTPUT_ENABLE;
|
||||||
ctrl_val = GPIO_DRIVE_PUSH_PULL|GPIO_SOURCE_GPIO;
|
ctrl_val = GPIO_CONF_DRIVER_ENABLE;
|
||||||
break;
|
break;
|
||||||
case GPIO_OUT_OPEN_DRAIN:
|
case GPIO_OUT_OPEN_DRAIN:
|
||||||
iomux_flags = IOMUX_PIN_OUTPUT_ENABLE;
|
iomux_flags = IOMUX_PIN_OUTPUT_ENABLE;
|
||||||
ctrl_val = GPIO_DRIVE_OPEN_DRAIN|GPIO_SOURCE_GPIO;
|
ctrl_val = 0;
|
||||||
break;
|
break;
|
||||||
case GPIO_INPUT_PULLUP:
|
case GPIO_INPUT_PULLUP:
|
||||||
iomux_flags = IOMUX_PIN_PULLUP;
|
iomux_flags = IOMUX_PIN_PULLUP;
|
||||||
ctrl_val = GPIO_SOURCE_GPIO;
|
ctrl_val = 0;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
iomux_set_gpio_function(gpio_num, iomux_flags);
|
iomux_set_gpio_function(gpio_num, iomux_flags);
|
||||||
GPIO_CTRL_REG(gpio_num) = (GPIO_CTRL_REG(gpio_num)&GPIO_INT_MASK) | ctrl_val;
|
GPIO.CONF[gpio_num] = (GPIO.CONF[gpio_num] & FIELD_MASK(GPIO_CONF_INTTYPE)) | ctrl_val;
|
||||||
if(direction == GPIO_OUTPUT)
|
if (iomux_flags & IOMUX_PIN_OUTPUT_ENABLE)
|
||||||
GPIO_DIR_SET = BIT(gpio_num);
|
GPIO.ENABLE_OUT_SET = BIT(gpio_num);
|
||||||
else
|
else
|
||||||
GPIO_DIR_CLEAR = BIT(gpio_num);
|
GPIO.ENABLE_OUT_CLEAR = BIT(gpio_num);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Disable GPIO on the specified pin, and set it Hi-Z.
|
/* Disable GPIO on the specified pin, and set it Hi-Z.
|
||||||
|
@ -61,7 +62,7 @@ INLINED void gpio_enable(const uint8_t gpio_num, const gpio_direction_t directio
|
||||||
*/
|
*/
|
||||||
INLINED void gpio_disable(const uint8_t gpio_num)
|
INLINED void gpio_disable(const uint8_t gpio_num)
|
||||||
{
|
{
|
||||||
GPIO_DIR_CLEAR = BIT(gpio_num);
|
GPIO.ENABLE_OUT_CLEAR = BIT(gpio_num);
|
||||||
*gpio_iomux_reg(gpio_num) &= ~IOMUX_PIN_OUTPUT_ENABLE;
|
*gpio_iomux_reg(gpio_num) &= ~IOMUX_PIN_OUTPUT_ENABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,9 +73,9 @@ INLINED void gpio_disable(const uint8_t gpio_num)
|
||||||
INLINED void gpio_write(const uint8_t gpio_num, const bool set)
|
INLINED void gpio_write(const uint8_t gpio_num, const bool set)
|
||||||
{
|
{
|
||||||
if(set)
|
if(set)
|
||||||
GPIO_OUT_SET = BIT(gpio_num);
|
GPIO.OUT_SET = BIT(gpio_num);
|
||||||
else
|
else
|
||||||
GPIO_OUT_CLEAR = BIT(gpio_num);
|
GPIO.OUT_CLEAR = BIT(gpio_num);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Toggle output of a pin
|
/* Toggle output of a pin
|
||||||
|
@ -89,10 +90,10 @@ INLINED void gpio_toggle(const uint8_t gpio_num)
|
||||||
get an invalid value. Prevents one task from clobbering another
|
get an invalid value. Prevents one task from clobbering another
|
||||||
task's pins, without needing to disable/enable interrupts.
|
task's pins, without needing to disable/enable interrupts.
|
||||||
*/
|
*/
|
||||||
if(GPIO_OUT_REG & BIT(gpio_num))
|
if(GPIO.OUT & BIT(gpio_num))
|
||||||
GPIO_OUT_CLEAR = BIT(gpio_num);
|
GPIO.OUT_CLEAR = BIT(gpio_num);
|
||||||
else
|
else
|
||||||
GPIO_OUT_SET = BIT(gpio_num);
|
GPIO.OUT_SET = BIT(gpio_num);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read input value of a GPIO pin.
|
/* Read input value of a GPIO pin.
|
||||||
|
@ -102,38 +103,28 @@ INLINED void gpio_toggle(const uint8_t gpio_num)
|
||||||
*/
|
*/
|
||||||
INLINED bool gpio_read(const uint8_t gpio_num)
|
INLINED bool gpio_read(const uint8_t gpio_num)
|
||||||
{
|
{
|
||||||
return GPIO_IN_REG & BIT(gpio_num);
|
return GPIO.IN & 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);
|
extern void gpio_interrupt_handler(void);
|
||||||
|
|
||||||
/* Set the interrupt type for a given pin
|
/* Set the interrupt type for a given pin
|
||||||
*
|
*
|
||||||
* If int_type is not INT_NONE, the gpio_interrupt_handler will be attached and unmasked.
|
* If int_type is not GPIO_INTTYPE_NONE, the gpio_interrupt_handler will be attached and unmasked.
|
||||||
*/
|
*/
|
||||||
INLINED void gpio_set_interrupt(const uint8_t gpio_num, const gpio_interrupt_t int_type)
|
INLINED void gpio_set_interrupt(const uint8_t gpio_num, const gpio_inttype_t int_type)
|
||||||
{
|
{
|
||||||
GPIO_CTRL_REG(gpio_num) = (GPIO_CTRL_REG(gpio_num)&~GPIO_INT_MASK)
|
GPIO.CONF[gpio_num] = SET_FIELD(GPIO.CONF[gpio_num], GPIO_CONF_INTTYPE, int_type);
|
||||||
| (int_type & GPIO_INT_MASK);
|
if(int_type != GPIO_INTTYPE_NONE) {
|
||||||
if(int_type != INT_NONE) {
|
|
||||||
_xt_isr_attach(INUM_GPIO, gpio_interrupt_handler);
|
_xt_isr_attach(INUM_GPIO, gpio_interrupt_handler);
|
||||||
_xt_isr_unmask(1<<INUM_GPIO);
|
_xt_isr_unmask(1<<INUM_GPIO);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the interrupt type set for a pin */
|
/* Return the interrupt type set for a pin */
|
||||||
INLINED gpio_interrupt_t gpio_get_interrupt(const uint8_t gpio_num)
|
INLINED gpio_inttype_t gpio_get_interrupt(const uint8_t gpio_num)
|
||||||
{
|
{
|
||||||
return (gpio_interrupt_t)(GPIO_CTRL_REG(gpio_num) & GPIO_INT_MASK);
|
return FIELD2VAL(GPIO_CONF_INTTYPE, GPIO.CONF[gpio_num]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
133
core/include/esp/gpio_regs.h
Normal file
133
core/include/esp/gpio_regs.h
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
/* esp/iomux_regs.h
|
||||||
|
*
|
||||||
|
* ESP8266 GPIO register definitions
|
||||||
|
*
|
||||||
|
* Not compatible with ESP SDK register access code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _ESP_GPIO_REGS_H
|
||||||
|
#define _ESP_GPIO_REGS_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "common_macros.h"
|
||||||
|
|
||||||
|
#define GPIO_BASE 0x60000300
|
||||||
|
#define GPIO (*(struct GPIO_REGS *)(GPIO_BASE))
|
||||||
|
|
||||||
|
/** GPIO output registers GPIO.OUT, GPIO.OUT_SET, GPIO.OUT_CLEAR:
|
||||||
|
*
|
||||||
|
* _SET and _CLEAR write-only registers set and clear bits in the main register,
|
||||||
|
* respectively.
|
||||||
|
*
|
||||||
|
* i.e.
|
||||||
|
* GPIO.OUT_SET = BIT(3);
|
||||||
|
* and
|
||||||
|
* GPIO.OUT |= BIT(3);
|
||||||
|
*
|
||||||
|
* ... are equivalent, but the former uses fewer CPU cycles.
|
||||||
|
*
|
||||||
|
* ENABLE_OUT / ENABLE_OUT_SET / ENABLE_OUT_CLEAR:
|
||||||
|
*
|
||||||
|
* Determine whether the corresponding GPIO has its output enabled or not.
|
||||||
|
* When clear, GPIO can function as an input. When set, GPIO will drive its
|
||||||
|
* output (and IN register will simply reflect the output state).
|
||||||
|
*
|
||||||
|
* (_SET/_CLEAR function similarly to OUT registers)
|
||||||
|
*
|
||||||
|
* STATUS / STATUS_SET / STATUS_CLEAR:
|
||||||
|
*
|
||||||
|
* Indicates which GPIOs have triggered an interrupt. Interrupt status should
|
||||||
|
* be reset by writing to STATUS or STATUS_CLEAR.
|
||||||
|
*
|
||||||
|
* (_SET/_CLEAR function similarly to OUT registers)
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct GPIO_REGS {
|
||||||
|
uint32_t volatile OUT; // 0x00
|
||||||
|
uint32_t volatile OUT_SET; // 0x04
|
||||||
|
uint32_t volatile OUT_CLEAR; // 0x08
|
||||||
|
uint32_t volatile ENABLE_OUT; // 0x0c
|
||||||
|
uint32_t volatile ENABLE_OUT_SET; // 0x10
|
||||||
|
uint32_t volatile ENABLE_OUT_CLEAR; // 0x14
|
||||||
|
uint32_t volatile IN; // 0x18
|
||||||
|
uint32_t volatile STATUS; // 0x1c
|
||||||
|
uint32_t volatile STATUS_SET; // 0x20
|
||||||
|
uint32_t volatile STATUS_CLEAR; // 0x24
|
||||||
|
uint32_t volatile CONF[16]; // 0x28 - 0x64
|
||||||
|
uint32_t volatile PWM; // 0x68
|
||||||
|
uint32_t volatile RTC_CALIB; // 0x6c
|
||||||
|
uint32_t volatile RTC_CALIB_RESULT; // 0x70
|
||||||
|
} __attribute__ (( packed ));
|
||||||
|
|
||||||
|
/* Double-check the structure size to make sure the compiler hasn't done
|
||||||
|
* something strange (or somebody typoed in the struct definition, etc)
|
||||||
|
*/
|
||||||
|
_Static_assert(sizeof(struct GPIO_REGS) == 0x74, "GPIO_REGS is the wrong size");
|
||||||
|
|
||||||
|
/* Bit mapping for CONF[i] registers */
|
||||||
|
|
||||||
|
/* GPIO.CONF[i] control the pin behavior for the corresponding GPIO in/output.
|
||||||
|
*
|
||||||
|
* GPIO_CONF_CONFIG (multi-value)
|
||||||
|
* FIXME: Unclear what these do. Need to find a better name.
|
||||||
|
*
|
||||||
|
* GPIO_CONF_WAKEUP_ENABLE (boolean)
|
||||||
|
* Can an interrupt contion on this pin wake the processor from a sleep
|
||||||
|
* state?
|
||||||
|
*
|
||||||
|
* GPIO_CONF_INTTYPE (multi-value)
|
||||||
|
* Under what conditions this GPIO input should generate an interrupt.
|
||||||
|
* (see gpio_inttype_t enum below for values)
|
||||||
|
*
|
||||||
|
* GPIO_CONF_DRIVER_ENABLE (boolean)
|
||||||
|
* When set, a high output state will pull the pin up to +Vcc (3.3V). When
|
||||||
|
* cleared, output functions in "open drain" mode (low state will pull down
|
||||||
|
* to ground, but high state allows output to "float").
|
||||||
|
*
|
||||||
|
* GPIO_CONF_SOURCE_PWM (boolean)
|
||||||
|
* When set, GPIO pin output will be connected to the sigma-delta PWM
|
||||||
|
* generator (controlled by the GPIO.PWM register). When cleared, pin
|
||||||
|
* output will function as a normal GPIO output (controlled by the
|
||||||
|
* GPIO.OUT* registers).
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define GPIO_CONF_CONFIG_M 0x00000003
|
||||||
|
#define GPIO_CONF_CONFIG_S 11
|
||||||
|
#define GPIO_CONF_WAKEUP_ENABLE BIT(10)
|
||||||
|
#define GPIO_CONF_INTTYPE_M 0x00000007
|
||||||
|
#define GPIO_CONF_INTTYPE_S 7
|
||||||
|
#define GPIO_CONF_DRIVER_ENABLE BIT(2)
|
||||||
|
#define GPIO_CONF_SOURCE_PWM BIT(0)
|
||||||
|
|
||||||
|
/* Valid values for the GPIO_CONF_INTTYPE field */
|
||||||
|
typedef enum {
|
||||||
|
GPIO_INTTYPE_NONE = 0,
|
||||||
|
GPIO_INTTYPE_EDGE_POS = 1,
|
||||||
|
GPIO_INTTYPE_EDGE_NEG = 2,
|
||||||
|
GPIO_INTTYPE_EDGE_ANY = 3,
|
||||||
|
GPIO_INTTYPE_LEVEL_LOW = 4,
|
||||||
|
GPIO_INTTYPE_LEVEL_HIGH = 5,
|
||||||
|
} gpio_inttype_t;
|
||||||
|
|
||||||
|
/* Bit mapping for PWM register */
|
||||||
|
|
||||||
|
#define GPIO_PWM_ENABLE BIT(16)
|
||||||
|
#define GPIO_PWM_PRESCALER_M 0x000000ff
|
||||||
|
#define GPIO_PWM_PRESCALER_S 8
|
||||||
|
#define GPIO_PWM_TARGET_M 0x000000ff
|
||||||
|
#define GPIO_PWM_TARGET_S 0
|
||||||
|
|
||||||
|
/* Bit mapping for RTC_CALIB register */
|
||||||
|
|
||||||
|
#define GPIO_RTC_CALIB_START BIT(31)
|
||||||
|
#define GPIO_RTC_CALIB_PERIOD_M 0x000003ff
|
||||||
|
#define GPIO_RTC_CALIB_PERIOD_S 0
|
||||||
|
|
||||||
|
/* Bit mapping for RTC_CALIB_RESULT register */
|
||||||
|
|
||||||
|
#define GPIO_RTC_CALIB_RESULT_READY BIT(31)
|
||||||
|
#define GPIO_RTC_CALIB_RESULT_READY_REAL BIT(30)
|
||||||
|
#define GPIO_RTC_CALIB_RESULT_VALUE_M 0x000fffff
|
||||||
|
#define GPIO_RTC_CALIB_RESULT_VALUE_S 0
|
||||||
|
|
||||||
|
#endif /* _ESP_GPIO_REGS_H */
|
|
@ -17,6 +17,7 @@
|
||||||
#include "esp/types.h"
|
#include "esp/types.h"
|
||||||
|
|
||||||
#include "esp/iomux_regs.h"
|
#include "esp/iomux_regs.h"
|
||||||
|
#include "esp/gpio_regs.h"
|
||||||
|
|
||||||
/* Internal macro, only defined in header body */
|
/* Internal macro, only defined in header body */
|
||||||
#define _REG(BASE, OFFSET) (*(esp_reg_t)((BASE)+(OFFSET)))
|
#define _REG(BASE, OFFSET) (*(esp_reg_t)((BASE)+(OFFSET)))
|
||||||
|
@ -31,7 +32,7 @@
|
||||||
#define UART0_BASE (MMIO_BASE + 0)
|
#define UART0_BASE (MMIO_BASE + 0)
|
||||||
#define SPI1_BASE (MMIO_BASE + 0x0100)
|
#define SPI1_BASE (MMIO_BASE + 0x0100)
|
||||||
#define SPI_BASE (MMIO_BASE + 0x0200)
|
#define SPI_BASE (MMIO_BASE + 0x0200)
|
||||||
#define GPIO0_BASE (MMIO_BASE + 0x0300)
|
//#define GPIO0_BASE (MMIO_BASE + 0x0300)
|
||||||
#define TIMER_BASE (MMIO_BASE + 0x0600)
|
#define TIMER_BASE (MMIO_BASE + 0x0600)
|
||||||
#define RTC_BASE (MMIO_BASE + 0x0700)
|
#define RTC_BASE (MMIO_BASE + 0x0700)
|
||||||
//#define IOMUX_BASE (MMIO_BASE + 0x0800)
|
//#define IOMUX_BASE (MMIO_BASE + 0x0800)
|
||||||
|
@ -42,79 +43,6 @@
|
||||||
#define RTCS_BASE (MMIO_BASE + 0x1100)
|
#define RTCS_BASE (MMIO_BASE + 0x1100)
|
||||||
#define RTCU_BASE (MMIO_BASE + 0x1200)
|
#define RTCU_BASE (MMIO_BASE + 0x1200)
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Based on descriptions by mamalala at https://github.com/esp8266/esp8266-wiki/wiki/gpio-registers
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** GPIO OUTPUT registers GPIO_OUT_REG, GPIO_OUT_SET, GPIO_OUT_CLEAR
|
|
||||||
*
|
|
||||||
* Registers for pin outputs.
|
|
||||||
*
|
|
||||||
* _SET and _CLEAR write-only registers set and clear bits in _REG,
|
|
||||||
* respectively.
|
|
||||||
*
|
|
||||||
* ie
|
|
||||||
* GPIO_OUT_REG |= BIT(3);
|
|
||||||
* and
|
|
||||||
* GPIO_OUT_SET = BIT(3);
|
|
||||||
*
|
|
||||||
* ... are equivalent, but latter uses less CPU cycles.
|
|
||||||
*/
|
|
||||||
#define GPIO_OUT_REG _REG(GPIO0_BASE, 0x00)
|
|
||||||
#define GPIO_OUT_SET _REG(GPIO0_BASE, 0x04)
|
|
||||||
#define GPIO_OUT_CLEAR _REG(GPIO0_BASE, 0x08)
|
|
||||||
|
|
||||||
/* GPIO DIR registers GPIO_DIR_REG, GPIO_DIR_SET, GPIO_DIR_CLEAR
|
|
||||||
*
|
|
||||||
* Set bit in DIR register for output pins. Writing to _SET and _CLEAR
|
|
||||||
* registers set and clear bits in _REG, respectively.
|
|
||||||
*/
|
|
||||||
#define GPIO_DIR_REG _REG(GPIO0_BASE, 0x0C)
|
|
||||||
#define GPIO_DIR_SET _REG(GPIO0_BASE, 0x10)
|
|
||||||
#define GPIO_DIR_CLEAR _REG(GPIO0_BASE, 0x14)
|
|
||||||
|
|
||||||
|
|
||||||
/* GPIO IN register GPIO_IN_REG
|
|
||||||
*
|
|
||||||
* Reads current input values.
|
|
||||||
*/
|
|
||||||
#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))
|
|
||||||
|
|
||||||
/* TIMER registers
|
/* TIMER registers
|
||||||
*
|
*
|
||||||
* ESP8266 has two hardware(?) timer counters, FRC1 and FRC2.
|
* ESP8266 has two hardware(?) timer counters, FRC1 and FRC2.
|
||||||
|
|
|
@ -41,12 +41,12 @@ void blinkenTask(void *pvParameters)
|
||||||
*/
|
*/
|
||||||
void blinkenRegisterTask(void *pvParameters)
|
void blinkenRegisterTask(void *pvParameters)
|
||||||
{
|
{
|
||||||
GPIO_DIR_SET = BIT(gpio);
|
GPIO.ENABLE_OUT_SET = BIT(gpio);
|
||||||
IOMUX_GPIO14 = IOMUX_GPIO14_FUNC_GPIO | IOMUX_PIN_OUTPUT_ENABLE; /* change this line if you change 'gpio' */
|
IOMUX_GPIO14 = IOMUX_GPIO14_FUNC_GPIO | IOMUX_PIN_OUTPUT_ENABLE; /* change this line if you change 'gpio' */
|
||||||
while(1) {
|
while(1) {
|
||||||
GPIO_OUT_SET = BIT(gpio);
|
GPIO.OUT_SET = BIT(gpio);
|
||||||
vTaskDelay(1000 / portTICK_RATE_MS);
|
vTaskDelay(1000 / portTICK_RATE_MS);
|
||||||
GPIO_OUT_CLEAR = BIT(gpio);
|
GPIO.OUT_CLEAR = BIT(gpio);
|
||||||
vTaskDelay(1000 / portTICK_RATE_MS);
|
vTaskDelay(1000 / portTICK_RATE_MS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue