Merge branch 'feature/refactor_gpio_driver' into 'master'

refactor(gpio): Refactor gpio driver for esp8266 idf

See merge request sdk/ESP8266_RTOS_SDK!223
This commit is contained in:
Wu Jian Gang
2018-08-09 15:01:07 +08:00
12 changed files with 1022 additions and 337 deletions

View File

@ -18,7 +18,7 @@ endif
#Linker scripts used to link the final application.
#Warning: These linker scripts are only used when the normal app is compiled; the bootloader
#specifies its own scripts.
LINKER_SCRIPTS += esp8266.common.ld esp8266.rom.ld
LINKER_SCRIPTS += esp8266.common.ld esp8266.rom.ld esp8266.peripherals.ld
COMPONENT_ADD_LDFLAGS += -L$(COMPONENT_PATH)/lib \
$(addprefix -l,$(LIBS)) \

View File

@ -1,4 +1,4 @@
// Copyright 2018 Espressif Systems (Shanghai) PTE LTD
// Copyright 2018-2025 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -12,198 +12,477 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdint.h>
#include <stdlib.h>
#include "esp8266/eagle_soc.h"
#include "esp8266/pin_mux_register.h"
#include "esp8266/gpio_struct.h"
#include "rom/ets_sys.h"
#include "driver/gpio.h"
#include "esp_err.h"
#include "esp_log.h" //TODO:No dependence on RTOS
// Temporary use the FreeRTOS critical function
#include "FreeRTOS.h"
#define ENTER_CRITICAL() portENTER_CRITICAL()
#define EXIT_CRITICAL() portEXIT_CRITICAL()
#include "gpio.h"
static const char *GPIO_TAG = "gpio";
void gpio_config(GPIO_ConfigTypeDef* pGPIOConfig)
#define GPIO_CHECK(a, str, ret_val) \
if (!(a)) { \
ESP_LOGE(GPIO_TAG,"%s(%d): %s", __FUNCTION__, __LINE__, str); \
return (ret_val); \
}
#define GPIO_PIN_REG_0 PERIPHS_IO_MUX_GPIO0_U
#define GPIO_PIN_REG_1 PERIPHS_IO_MUX_U0TXD_U
#define GPIO_PIN_REG_2 PERIPHS_IO_MUX_GPIO2_U
#define GPIO_PIN_REG_3 PERIPHS_IO_MUX_U0RXD_U
#define GPIO_PIN_REG_4 PERIPHS_IO_MUX_GPIO4_U
#define GPIO_PIN_REG_5 PERIPHS_IO_MUX_GPIO5_U
#define GPIO_PIN_REG_6 PERIPHS_IO_MUX_SD_CLK_U
#define GPIO_PIN_REG_7 PERIPHS_IO_MUX_SD_DATA0_U
#define GPIO_PIN_REG_8 PERIPHS_IO_MUX_SD_DATA1_U
#define GPIO_PIN_REG_9 PERIPHS_IO_MUX_SD_DATA2_U
#define GPIO_PIN_REG_10 PERIPHS_IO_MUX_SD_DATA3_U
#define GPIO_PIN_REG_11 PERIPHS_IO_MUX_SD_CMD_U
#define GPIO_PIN_REG_12 PERIPHS_IO_MUX_MTDI_U
#define GPIO_PIN_REG_13 PERIPHS_IO_MUX_MTCK_U
#define GPIO_PIN_REG_14 PERIPHS_IO_MUX_MTMS_U
#define GPIO_PIN_REG_15 PERIPHS_IO_MUX_MTDO_U
#define GPIO_PIN_REG_16 PAD_XPD_DCDC_CONF
#define GPIO_PIN_REG(i) \
(i==0) ? GPIO_PIN_REG_0: \
(i==1) ? GPIO_PIN_REG_1: \
(i==2) ? GPIO_PIN_REG_2: \
(i==3) ? GPIO_PIN_REG_3: \
(i==4) ? GPIO_PIN_REG_4: \
(i==5) ? GPIO_PIN_REG_5: \
(i==6) ? GPIO_PIN_REG_6: \
(i==7) ? GPIO_PIN_REG_7: \
(i==8) ? GPIO_PIN_REG_8: \
(i==9) ? GPIO_PIN_REG_9: \
(i==10)? GPIO_PIN_REG_10: \
(i==11)? GPIO_PIN_REG_11: \
(i==12)? GPIO_PIN_REG_12: \
(i==13)? GPIO_PIN_REG_13: \
(i==14)? GPIO_PIN_REG_14: \
(i==15)? GPIO_PIN_REG_15: \
GPIO_PIN_REG_16
typedef struct {
gpio_isr_t fn; /*!< isr function */
void *args; /*!< isr function args */
} gpio_isr_func_t;
static gpio_isr_func_t *gpio_isr_func = NULL;
esp_err_t gpio_pullup_en(gpio_num_t gpio_num)
{
uint16_t gpio_pin_mask = pGPIOConfig->GPIO_Pin;
uint32_t io_reg;
uint8_t io_num = 0;
uint32_t pin_reg;
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
GPIO_CHECK(!RTC_GPIO_IS_VALID_GPIO(gpio_num), "The RTC GPIO of esp8266 can not be pulled up.", ESP_ERR_INVALID_ARG);
if (pGPIOConfig->GPIO_Mode == GPIO_Mode_Input) {
GPIO_AS_INPUT(gpio_pin_mask);
} else if (pGPIOConfig->GPIO_Mode == GPIO_Mode_Output) {
GPIO_AS_OUTPUT(gpio_pin_mask);
gpio_pin_reg_t pin_reg;
pin_reg.val = READ_PERI_REG(GPIO_PIN_REG(gpio_num));
pin_reg.pullup = 1;
WRITE_PERI_REG(GPIO_PIN_REG(gpio_num), pin_reg.val);
return ESP_OK;
}
esp_err_t gpio_pullup_dis(gpio_num_t gpio_num)
{
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
GPIO_CHECK(!RTC_GPIO_IS_VALID_GPIO(gpio_num), "The RTC GPIO of esp8266 can not be pulled up.", ESP_ERR_INVALID_ARG);
gpio_pin_reg_t pin_reg;
pin_reg.val = READ_PERI_REG(GPIO_PIN_REG(gpio_num));
pin_reg.pullup = 0;
WRITE_PERI_REG(GPIO_PIN_REG(gpio_num), pin_reg.val);
return ESP_OK;
}
esp_err_t gpio_pulldown_en(gpio_num_t gpio_num)
{
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
GPIO_CHECK(RTC_GPIO_IS_VALID_GPIO(gpio_num), "The GPIO of esp8266 can not be pulled down except RTC GPIO.", ESP_ERR_INVALID_ARG);
gpio_pin_reg_t pin_reg;
pin_reg.val = READ_PERI_REG(GPIO_PIN_REG(gpio_num));
pin_reg.rtc_pin.pulldown = 1;
WRITE_PERI_REG(GPIO_PIN_REG(gpio_num), pin_reg.val);
return ESP_OK;
}
esp_err_t gpio_pulldown_dis(gpio_num_t gpio_num)
{
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
GPIO_CHECK(RTC_GPIO_IS_VALID_GPIO(gpio_num), "The GPIO of esp8266 can not be pulled down except RTC GPIO.", ESP_ERR_INVALID_ARG);
gpio_pin_reg_t pin_reg;
pin_reg.val = READ_PERI_REG(GPIO_PIN_REG(gpio_num));
pin_reg.rtc_pin.pulldown = 0;
WRITE_PERI_REG(GPIO_PIN_REG(gpio_num), pin_reg.val);
return ESP_OK;
}
esp_err_t gpio_set_intr_type(gpio_num_t gpio_num, gpio_int_type_t intr_type)
{
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
GPIO_CHECK(!RTC_GPIO_IS_VALID_GPIO(gpio_num), "GPIO is RTC GPIO", ESP_ERR_INVALID_ARG);
GPIO_CHECK(intr_type < GPIO_INTR_MAX, "GPIO interrupt type error", ESP_ERR_INVALID_ARG);
GPIO.pin[gpio_num].int_type = intr_type;
return ESP_OK;
}
esp_err_t gpio_intr_enable(gpio_num_t gpio_num)
{
_xt_isr_unmask(0x1 << ETS_GPIO_INUM);
return ESP_OK;
}
esp_err_t gpio_intr_disable(gpio_num_t gpio_num)
{
_xt_isr_mask(0x1 << ETS_GPIO_INUM);
return ESP_OK;
}
static esp_err_t gpio_output_disable(gpio_num_t gpio_num)
{
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
if (RTC_GPIO_IS_VALID_GPIO(gpio_num)) {
WRITE_PERI_REG(PAD_XPD_DCDC_CONF, ((READ_PERI_REG(PAD_XPD_DCDC_CONF) & (uint32_t)0xffffffbc)) | (uint32_t)0x1); // mux configuration for XPD_DCDC and rtc_gpio0 connection
CLEAR_PERI_REG_MASK(RTC_GPIO_CONF, 0x1); //mux configuration for out enable
CLEAR_PERI_REG_MASK(RTC_GPIO_ENABLE, 0x1); //out disable
} else {
GPIO.enable_w1tc |= (0x1 << gpio_num);
}
return ESP_OK;
}
static esp_err_t gpio_output_enable(gpio_num_t gpio_num)
{
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
if (RTC_GPIO_IS_VALID_GPIO(gpio_num)) {
WRITE_PERI_REG(PAD_XPD_DCDC_CONF, ((READ_PERI_REG(PAD_XPD_DCDC_CONF) & (uint32_t)0xffffffbc)) | (uint32_t)0x1); // mux configuration for XPD_DCDC and rtc_gpio0 connection
CLEAR_PERI_REG_MASK(RTC_GPIO_CONF, 0x1); //mux configuration for out enable
SET_PERI_REG_MASK(RTC_GPIO_ENABLE, 0x1); //out enable
} else {
GPIO.enable_w1ts |= (0x1 << gpio_num);
}
return ESP_OK;
}
esp_err_t gpio_set_level(gpio_num_t gpio_num, uint32_t level)
{
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
if (RTC_GPIO_IS_VALID_GPIO(gpio_num)) {
if (level) {
SET_PERI_REG_MASK(RTC_GPIO_OUT, 0x1); //set_high_level
} else {
CLEAR_PERI_REG_MASK(RTC_GPIO_OUT, 0x1); //set_low_level
}
} else {
if (level) {
GPIO.out_w1ts |= (0x1 << gpio_num);
} else {
GPIO.out_w1tc |= (0x1 << gpio_num);
}
}
return ESP_OK;
}
int gpio_get_level(gpio_num_t gpio_num)
{
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
if (RTC_GPIO_IS_VALID_GPIO(gpio_num)) {
return READ_PERI_REG(RTC_GPIO_IN_DATA) & 0x1;
} else {
return (GPIO.in >> gpio_num) & 0x1;
}
}
esp_err_t gpio_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull)
{
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
GPIO_CHECK(pull <= GPIO_FLOATING, "GPIO pull mode error", ESP_ERR_INVALID_ARG);
esp_err_t ret = ESP_OK;
switch (pull) {
case GPIO_PULLUP_ONLY:
gpio_pulldown_dis(gpio_num);
gpio_pullup_en(gpio_num);
break;
case GPIO_PULLDOWN_ONLY:
gpio_pulldown_en(gpio_num);
gpio_pullup_dis(gpio_num);
break;
case GPIO_FLOATING:
gpio_pulldown_dis(gpio_num);
gpio_pullup_dis(gpio_num);
break;
default:
ESP_LOGE(GPIO_TAG, "Unknown pull up/down mode,gpio_num=%u,pull=%u", gpio_num, pull);
ret = ESP_ERR_INVALID_ARG;
break;
}
return ret;
}
esp_err_t gpio_set_direction(gpio_num_t gpio_num, gpio_mode_t mode)
{
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
// esp8266 input is always connected
if (mode & GPIO_MODE_DEF_OUTPUT) {
gpio_output_enable(gpio_num);
} else {
gpio_output_disable(gpio_num);
}
if ((mode & GPIO_MODE_DEF_OD) && !RTC_GPIO_IS_VALID_GPIO(gpio_num)) {
GPIO.pin[gpio_num].driver = 1;
} else {
GPIO.pin[gpio_num].driver = 0;
}
return ESP_OK;
}
esp_err_t gpio_config(const gpio_config_t *gpio_cfg)
{
uint32_t gpio_pin_mask = (gpio_cfg->pin_bit_mask);
uint32_t io_reg = 0;
uint32_t io_num = 0;
uint8_t input_en = 0;
uint8_t output_en = 0;
uint8_t od_en = 0;
uint8_t pu_en = 0;
uint8_t pd_en = 0;
gpio_pin_reg_t pin_reg;
if (gpio_cfg->pin_bit_mask == 0 || gpio_cfg->pin_bit_mask >= (((uint32_t) 1) << GPIO_PIN_COUNT)) {
ESP_LOGE(GPIO_TAG, "GPIO_PIN mask error ");
return ESP_ERR_INVALID_ARG;
}
do {
if ((gpio_pin_mask >> io_num) & 0x1) {
io_reg = GPIO_PIN_REG(io_num);
io_reg = GPIO_PIN_REG(io_num);
if (((gpio_pin_mask >> io_num) & BIT(0))) {
if (!io_reg) {
ESP_LOGE(GPIO_TAG, "IO%d is not a valid GPIO", io_num);
return ESP_ERR_INVALID_ARG;
}
if (gpio_cfg->mode & GPIO_MODE_OUTPUT) {
output_en = 1;
} else {
input_en = 1;
}
if ((gpio_cfg->mode & GPIO_MODE_DEF_OD) && !RTC_GPIO_IS_VALID_GPIO(io_num)) {
od_en = 1;
}
gpio_set_direction(io_num, gpio_cfg->mode);
if (!RTC_GPIO_IS_VALID_GPIO(io_num)) {
if (gpio_cfg->pull_up_en) {
pu_en = 1;
gpio_pullup_en(io_num);
} else {
gpio_pullup_dis(io_num);
}
}
if (RTC_GPIO_IS_VALID_GPIO(io_num)) {
if (gpio_cfg->pull_down_en) {
pd_en = 1;
gpio_pulldown_en(io_num);
} else {
gpio_pulldown_dis(io_num);
}
}
ESP_LOGI(GPIO_TAG, "GPIO[%d]| InputEn: %d| OutputEn: %d| OpenDrain: %d| Pullup: %d| Pulldown: %d| Intr:%d ", io_num, input_en, output_en, od_en, pu_en, pd_en, gpio_cfg->intr_type);
if (!RTC_GPIO_IS_VALID_GPIO(io_num)) {
gpio_set_intr_type(io_num, gpio_cfg->intr_type);
if (gpio_cfg->intr_type) {
gpio_intr_enable(io_num);
} else {
gpio_intr_disable(io_num);
}
}
pin_reg.val = READ_PERI_REG(GPIO_PIN_REG(io_num));
// It should be noted that GPIO0, 2, 4, and 5 need to set the func register to 0,
// and the other GPIO needs to be set to 3 so that IO can be GPIO function.
if ((0x1 << io_num) & (GPIO_Pin_0 | GPIO_Pin_2 | GPIO_Pin_4 | GPIO_Pin_5)) {
PIN_FUNC_SELECT(io_reg, 0);
pin_reg.rtc_pin.func_low_bit = 0;
pin_reg.rtc_pin.func_high_bit = 0;
} else {
PIN_FUNC_SELECT(io_reg, 3);
pin_reg.func_low_bit = 3;
pin_reg.func_high_bit = 0;
}
if (pGPIOConfig->GPIO_Pullup) {
PIN_PULLUP_EN(io_reg);
} else {
PIN_PULLUP_DIS(io_reg);
}
if (pGPIOConfig->GPIO_Mode == GPIO_Mode_Out_OD) {
portENTER_CRITICAL();
pin_reg = GPIO_REG_READ(GPIO_PIN_ADDR(io_num));
pin_reg &= (~GPIO_PIN_DRIVER_MASK);
pin_reg |= (GPIO_PAD_DRIVER_ENABLE << GPIO_PIN_DRIVER_LSB);
GPIO_REG_WRITE(GPIO_PIN_ADDR(io_num), pin_reg);
portEXIT_CRITICAL();
} else if (pGPIOConfig->GPIO_Mode == GPIO_Mode_Sigma_Delta) {
portENTER_CRITICAL();
pin_reg = GPIO_REG_READ(GPIO_PIN_ADDR(io_num));
pin_reg &= (~GPIO_PIN_SOURCE_MASK);
pin_reg |= (0x1 << GPIO_PIN_SOURCE_LSB);
GPIO_REG_WRITE(GPIO_PIN_ADDR(io_num), pin_reg);
GPIO_REG_WRITE(GPIO_SIGMA_DELTA_ADDRESS, SIGMA_DELTA_ENABLE);
portEXIT_CRITICAL();
}
gpio_pin_intr_state_set(io_num, pGPIOConfig->GPIO_IntrType);
WRITE_PERI_REG(GPIO_PIN_REG(io_num), pin_reg.val);
}
io_num++;
} while (io_num < 16);
} while (io_num < GPIO_PIN_COUNT);
return ESP_OK;
}
/*
* Change GPIO pin output by setting, clearing, or disabling pins.
* In general, it is expected that a bit will be set in at most one
* of these masks. If a bit is clear in all masks, the output state
* remains unchanged.
*
* There is no particular ordering guaranteed; so if the order of
* writes is significant, calling code should divide a single call
* into multiple calls.
*/
void gpio_output_conf(uint32_t set_mask, uint32_t clear_mask, uint32_t enable_mask, uint32_t disable_mask)
void gpio_intr_service(void *arg)
{
GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, set_mask);
GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, clear_mask);
GPIO_REG_WRITE(GPIO_ENABLE_W1TS_ADDRESS, enable_mask);
GPIO_REG_WRITE(GPIO_ENABLE_W1TC_ADDRESS, disable_mask);
}
//GPIO intr process
uint32_t gpio_num = 0;
//read status to get interrupt status for GPIO0-15
uint32_t gpio_intr_status = GPIO.status;
/*
* Sample the value of GPIO input pins and returns a bitmask.
*/
uint32_t gpio_input_get(void)
{
return GPIO_REG_READ(GPIO_IN_ADDRESS);
}
/*
* Register an application-specific interrupt handler for GPIO pin
* interrupts. Once the interrupt handler is called, it will not
* be called again until after a call to gpio_intr_ack. Any GPIO
* interrupts that occur during the interim are masked.
*
* The application-specific handler is called with a mask of
* pending GPIO interrupts. After processing pin interrupts, the
* application-specific handler may wish to use gpio_intr_pending
* to check for any additional pending interrupts before it returns.
*/
void gpio_intr_handler_register(void* fn, void* arg)
{
_xt_isr_attach(ETS_GPIO_INUM, fn, arg);
}
/*
only highlevel and lowlevel intr can use for wakeup
*/
void gpio_pin_wakeup_enable(uint32_t i, GPIO_INT_TYPE intr_state)
{
uint32_t pin_reg;
if ((intr_state == GPIO_PIN_INTR_LOLEVEL) || (intr_state == GPIO_PIN_INTR_HILEVEL)) {
portENTER_CRITICAL();
pin_reg = GPIO_REG_READ(GPIO_PIN_ADDR(i));
pin_reg &= (~GPIO_PIN_INT_TYPE_MASK);
pin_reg |= (intr_state << GPIO_PIN_INT_TYPE_LSB);
pin_reg |= GPIO_PIN_WAKEUP_ENABLE_SET(GPIO_WAKEUP_ENABLE);
GPIO_REG_WRITE(GPIO_PIN_ADDR(i), pin_reg);
portEXIT_CRITICAL();
if (gpio_isr_func == NULL) {
return;
}
}
void gpio_pin_wakeup_disable(void)
{
uint8_t i;
uint32_t pin_reg;
do {
if (gpio_num < GPIO_PIN_COUNT - 1) {
if (gpio_intr_status & BIT(gpio_num)) { //gpio0-gpio15
if (gpio_isr_func[gpio_num].fn != NULL) {
gpio_isr_func[gpio_num].fn(gpio_isr_func[gpio_num].args);
}
for (i = 0; i < GPIO_PIN_COUNT; i++) {
pin_reg = GPIO_REG_READ(GPIO_PIN_ADDR(i));
if (pin_reg & GPIO_PIN_WAKEUP_ENABLE_MASK) {
pin_reg &= (~GPIO_PIN_INT_TYPE_MASK);
pin_reg |= (GPIO_PIN_INTR_DISABLE << GPIO_PIN_INT_TYPE_LSB);
pin_reg &= ~(GPIO_PIN_WAKEUP_ENABLE_SET(GPIO_WAKEUP_ENABLE));
GPIO_REG_WRITE(GPIO_PIN_ADDR(i), pin_reg);
GPIO.status_w1tc = BIT(gpio_num);
}
}
} while (++gpio_num < GPIO_PIN_COUNT - 1);
}
esp_err_t gpio_isr_handler_add(gpio_num_t gpio_num, gpio_isr_t isr_handler, void *args)
{
GPIO_CHECK(gpio_isr_func != NULL, "GPIO isr service is not installed, call gpio_install_isr_service() first", ESP_ERR_INVALID_STATE);
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
GPIO_CHECK(!RTC_GPIO_IS_VALID_GPIO(gpio_num), "GPIO is RTC GPIO", ESP_ERR_INVALID_ARG);
ENTER_CRITICAL();
_xt_isr_mask(1 << ETS_GPIO_INUM);
if (gpio_isr_func) {
gpio_isr_func[gpio_num].fn = isr_handler;
gpio_isr_func[gpio_num].args = args;
}
_xt_isr_unmask(1 << ETS_GPIO_INUM);
EXIT_CRITICAL();
return ESP_OK;
}
void gpio_pin_intr_state_set(uint32_t i, GPIO_INT_TYPE intr_state)
esp_err_t gpio_isr_handler_remove(gpio_num_t gpio_num)
{
uint32_t pin_reg;
GPIO_CHECK(gpio_isr_func != NULL, "GPIO isr service is not installed, call gpio_install_isr_service() first", ESP_ERR_INVALID_STATE);
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
GPIO_CHECK(!RTC_GPIO_IS_VALID_GPIO(gpio_num), "GPIO is RTC GPIO", ESP_ERR_INVALID_ARG);
portENTER_CRITICAL();
ENTER_CRITICAL();
_xt_isr_mask(1 << ETS_GPIO_INUM);
pin_reg = GPIO_REG_READ(GPIO_PIN_ADDR(i));
pin_reg &= (~GPIO_PIN_INT_TYPE_MASK);
pin_reg |= (intr_state << GPIO_PIN_INT_TYPE_LSB);
GPIO_REG_WRITE(GPIO_PIN_ADDR(i), pin_reg);
if (gpio_isr_func) {
gpio_isr_func[gpio_num].fn = NULL;
gpio_isr_func[gpio_num].args = NULL;
}
portEXIT_CRITICAL();
_xt_isr_unmask(1 << ETS_GPIO_INUM);
EXIT_CRITICAL();
return ESP_OK;
}
void gpio16_output_conf(void)
esp_err_t gpio_isr_register(void (*fn)(void *), void *arg, int no_use, gpio_isr_handle_t *handle)
{
WRITE_PERI_REG(PAD_XPD_DCDC_CONF,
(READ_PERI_REG(PAD_XPD_DCDC_CONF) & 0xffffffbc) | (uint32_t)0x1); // mux configuration for XPD_DCDC to output rtc_gpio0
GPIO_CHECK(fn, "GPIO ISR null", ESP_ERR_INVALID_ARG);
WRITE_PERI_REG(RTC_GPIO_CONF,
(READ_PERI_REG(RTC_GPIO_CONF) & (uint32_t)0xfffffffe) | (uint32_t)0x0); //mux configuration for out enable
WRITE_PERI_REG(RTC_GPIO_ENABLE,
(READ_PERI_REG(RTC_GPIO_ENABLE) & (uint32_t)0xfffffffe) | (uint32_t)0x1); //out enable
_xt_isr_attach(ETS_GPIO_INUM, gpio_intr_service, NULL);
return ESP_OK;
}
void gpio16_output_set(uint8_t value)
esp_err_t gpio_install_isr_service(int no_use)
{
WRITE_PERI_REG(RTC_GPIO_OUT,
(READ_PERI_REG(RTC_GPIO_OUT) & (uint32_t)0xfffffffe) | (uint32_t)(value & 1));
GPIO_CHECK(gpio_isr_func == NULL, "GPIO isr service already installed", ESP_FAIL);
esp_err_t ret;
ENTER_CRITICAL();
gpio_isr_func = (gpio_isr_func_t *) calloc(GPIO_PIN_COUNT - 1, sizeof(gpio_isr_func_t));
if (gpio_isr_func == NULL) {
ret = ESP_ERR_NO_MEM;
} else {
ret = gpio_isr_register(gpio_intr_service, NULL, 0, NULL);
}
EXIT_CRITICAL();
return ret;
}
void gpio16_input_conf(void)
void gpio_uninstall_isr_service()
{
WRITE_PERI_REG(PAD_XPD_DCDC_CONF,
(READ_PERI_REG(PAD_XPD_DCDC_CONF) & 0xffffffbc) | (uint32_t)0x1); // mux configuration for XPD_DCDC and rtc_gpio0 connection
if (gpio_isr_func == NULL) {
return;
}
WRITE_PERI_REG(RTC_GPIO_CONF,
(READ_PERI_REG(RTC_GPIO_CONF) & (uint32_t)0xfffffffe) | (uint32_t)0x0); //mux configuration for out enable
WRITE_PERI_REG(RTC_GPIO_ENABLE,
READ_PERI_REG(RTC_GPIO_ENABLE) & (uint32_t)0xfffffffe); //out disable
ENTER_CRITICAL();
_xt_isr_mask(1 << ETS_GPIO_INUM);
_xt_isr_attach(ETS_GPIO_INUM, NULL, NULL);
free(gpio_isr_func);
gpio_isr_func = NULL;
EXIT_CRITICAL();
return;
}
uint8_t gpio16_input_get(void)
/*only level interrupt can be used for wake-up function*/
esp_err_t gpio_wakeup_enable(gpio_num_t gpio_num, gpio_int_type_t intr_type)
{
return (uint8_t)(READ_PERI_REG(RTC_GPIO_IN_DATA) & 1);
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
GPIO_CHECK(!RTC_GPIO_IS_VALID_GPIO(gpio_num), "RTC IO can not use the wakeup function", ESP_ERR_INVALID_ARG);
esp_err_t ret = ESP_OK;
if ((intr_type == GPIO_INTR_LOW_LEVEL) || (intr_type == GPIO_INTR_HIGH_LEVEL)) {
GPIO.pin[gpio_num].int_type = intr_type;
GPIO.pin[gpio_num].wakeup_enable = 0x1;
} else {
ret = ESP_ERR_INVALID_ARG;
}
return ret;
}
esp_err_t gpio_wakeup_disable(gpio_num_t gpio_num)
{
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
GPIO_CHECK(!RTC_GPIO_IS_VALID_GPIO(gpio_num), "RTC IO can not use the wakeup function", ESP_ERR_INVALID_ARG);
GPIO.pin[gpio_num].wakeup_enable = 0;
return ESP_OK;
}

View File

@ -16,7 +16,7 @@
#include <stdbool.h>
#include "rom/ets_sys.h"
#if 0
#include "gpio.h"
#include "i2c_master.h"
@ -315,3 +315,5 @@ void i2c_master_writeByte(uint8_t wrdata)
i2c_master_wait(5);
}
}
#endif

View File

@ -1,4 +1,4 @@
// Copyright 2018 Espressif Systems (Shanghai) PTE LTD
// Copyright 2018-2025 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -16,19 +16,19 @@
#define __GPIO_H__
#include <stdint.h>
#include "esp_err.h"
#include "esp8266/eagle_soc.h"
#include "esp8266/gpio_register.h"
#include "esp8266/pin_mux_register.h"
#include "freertos/portmacro.h"
#include "esp8266/gpio_register.h"
#ifdef __cplusplus
extern "C" {
#endif
#define ETS_GPIO_INTR_ENABLE() _xt_isr_unmask(1 << ETS_GPIO_INUM)
#define ETS_GPIO_INTR_DISABLE() _xt_isr_mask(1 << ETS_GPIO_INUM)
#ifndef BIT
#define BIT(x) (1 << (x))
#endif
#define GPIO_Pin_0 (BIT(0)) /* Pin 0 selected */
#define GPIO_Pin_1 (BIT(1)) /* Pin 1 selected */
@ -46,263 +46,347 @@ extern "C" {
#define GPIO_Pin_13 (BIT(13)) /* Pin 13 selected */
#define GPIO_Pin_14 (BIT(14)) /* Pin 14 selected */
#define GPIO_Pin_15 (BIT(15)) /* Pin 15 selected */
#define GPIO_Pin_All (0xFFFF) /* All pins selected */
#define GPIO_Pin_16 (BIT(16)) /* Pin 16 selected */
#define GPIO_Pin_All (0x1FFFF) /* All pins selected */
#define GPIO_PIN_REG_0 PERIPHS_IO_MUX_GPIO0_U
#define GPIO_PIN_REG_1 PERIPHS_IO_MUX_U0TXD_U
#define GPIO_PIN_REG_2 PERIPHS_IO_MUX_GPIO2_U
#define GPIO_PIN_REG_3 PERIPHS_IO_MUX_U0RXD_U
#define GPIO_PIN_REG_4 PERIPHS_IO_MUX_GPIO4_U
#define GPIO_PIN_REG_5 PERIPHS_IO_MUX_GPIO5_U
#define GPIO_PIN_REG_6 PERIPHS_IO_MUX_SD_CLK_U
#define GPIO_PIN_REG_7 PERIPHS_IO_MUX_SD_DATA0_U
#define GPIO_PIN_REG_8 PERIPHS_IO_MUX_SD_DATA1_U
#define GPIO_PIN_REG_9 PERIPHS_IO_MUX_SD_DATA2_U
#define GPIO_PIN_REG_10 PERIPHS_IO_MUX_SD_DATA3_U
#define GPIO_PIN_REG_11 PERIPHS_IO_MUX_SD_CMD_U
#define GPIO_PIN_REG_12 PERIPHS_IO_MUX_MTDI_U
#define GPIO_PIN_REG_13 PERIPHS_IO_MUX_MTCK_U
#define GPIO_PIN_REG_14 PERIPHS_IO_MUX_MTMS_U
#define GPIO_PIN_REG_15 PERIPHS_IO_MUX_MTDO_U
#define GPIO_MODE_DEF_DISABLE (0)
#define GPIO_MODE_DEF_INPUT (BIT(0))
#define GPIO_MODE_DEF_OUTPUT (BIT(1))
#define GPIO_MODE_DEF_OD (BIT(2))
#define GPIO_PIN_REG(i) \
(i==0) ? GPIO_PIN_REG_0: \
(i==1) ? GPIO_PIN_REG_1: \
(i==2) ? GPIO_PIN_REG_2: \
(i==3) ? GPIO_PIN_REG_3: \
(i==4) ? GPIO_PIN_REG_4: \
(i==5) ? GPIO_PIN_REG_5: \
(i==6) ? GPIO_PIN_REG_6: \
(i==7) ? GPIO_PIN_REG_7: \
(i==8) ? GPIO_PIN_REG_8: \
(i==9) ? GPIO_PIN_REG_9: \
(i==10)? GPIO_PIN_REG_10: \
(i==11)? GPIO_PIN_REG_11: \
(i==12)? GPIO_PIN_REG_12: \
(i==13)? GPIO_PIN_REG_13: \
(i==14)? GPIO_PIN_REG_14: \
GPIO_PIN_REG_15
#define GPIO_PIN_COUNT 17
#define GPIO_PIN_ADDR(i) (GPIO_PIN0_ADDRESS + i*4)
#define GPIO_ID_IS_PIN_REGISTER(reg_id) \
((reg_id >= GPIO_ID_PIN0) && (reg_id <= GPIO_ID_PIN(GPIO_PIN_COUNT-1)))
#define GPIO_REGID_TO_PINIDX(reg_id) ((reg_id) - GPIO_ID_PIN0)
#define GPIO_IS_VALID_GPIO(gpio_num) ((gpio_num < GPIO_PIN_COUNT)) /*!< Check whether it is a valid GPIO number */
#define RTC_GPIO_IS_VALID_GPIO(gpio_num) ((gpio_num == 16)) /*!< Check whether it is a valid RTC GPIO number */
typedef enum {
GPIO_PIN_INTR_DISABLE = 0, /**< disable GPIO interrupt */
GPIO_PIN_INTR_POSEDGE = 1, /**< GPIO interrupt type : rising edge */
GPIO_PIN_INTR_NEGEDGE = 2, /**< GPIO interrupt type : falling edge */
GPIO_PIN_INTR_ANYEDGE = 3, /**< GPIO interrupt type : bothe rising and falling edge */
GPIO_PIN_INTR_LOLEVEL = 4, /**< GPIO interrupt type : low level */
GPIO_PIN_INTR_HILEVEL = 5 /**< GPIO interrupt type : high level */
} GPIO_INT_TYPE;
GPIO_NUM_0 = 0, /*!< GPIO0, input and output */
GPIO_NUM_1 = 1, /*!< GPIO1, input and output */
GPIO_NUM_2 = 2, /*!< GPIO2, input and output */
GPIO_NUM_3 = 3, /*!< GPIO3, input and output */
GPIO_NUM_4 = 4, /*!< GPIO4, input and output */
GPIO_NUM_5 = 5, /*!< GPIO5, input and output */
GPIO_NUM_6 = 6, /*!< GPIO6, input and output */
GPIO_NUM_7 = 7, /*!< GPIO7, input and output */
GPIO_NUM_8 = 8, /*!< GPIO8, input and output */
GPIO_NUM_9 = 9, /*!< GPIO9, input and output */
GPIO_NUM_10 = 10, /*!< GPIO10, input and output */
GPIO_NUM_11 = 11, /*!< GPIO11, input and output */
GPIO_NUM_12 = 12, /*!< GPIO12, input and output */
GPIO_NUM_13 = 13, /*!< GPIO13, input and output */
GPIO_NUM_14 = 14, /*!< GPIO14, input and output */
GPIO_NUM_15 = 15, /*!< GPIO15, input and output */
GPIO_NUM_16 = 16, /*!< GPIO15, input and output */
GPIO_NUM_MAX = 17,
/** @endcond */
} gpio_num_t;
typedef enum {
GPIO_Mode_Input = 0x0, /**< GPIO mode : Input */
GPIO_Mode_Out_OD, /**< GPIO mode : Output_OD */
GPIO_Mode_Output, /**< GPIO mode : Output */
GPIO_Mode_Sigma_Delta, /**< GPIO mode : Sigma_Delta */
} GPIOMode_TypeDef;
GPIO_INTR_DISABLE = 0, /*!< Disable GPIO interrupt */
GPIO_INTR_POSEDGE = 1, /*!< GPIO interrupt type : rising edge */
GPIO_INTR_NEGEDGE = 2, /*!< GPIO interrupt type : falling edge */
GPIO_INTR_ANYEDGE = 3, /*!< GPIO interrupt type : both rising and falling edge */
GPIO_INTR_LOW_LEVEL = 4, /*!< GPIO interrupt type : input low level trigger */
GPIO_INTR_HIGH_LEVEL = 5, /*!< GPIO interrupt type : input high level trigger */
GPIO_INTR_MAX,
} gpio_int_type_t;
typedef enum {
GPIO_PullUp_DIS = 0x0, /**< disable GPIO pullup */
GPIO_PullUp_EN = 0x1, /**< enable GPIO pullup */
} GPIO_Pullup_IF;
GPIO_MODE_DISABLE = GPIO_MODE_DEF_DISABLE, /*!< GPIO mode : disable input and output */
GPIO_MODE_INPUT = GPIO_MODE_DEF_INPUT, /*!< GPIO mode : input only */
GPIO_MODE_OUTPUT = GPIO_MODE_DEF_OUTPUT, /*!< GPIO mode : output only mode */
GPIO_MODE_OUTPUT_OD = ((GPIO_MODE_DEF_OUTPUT) | (GPIO_MODE_DEF_OD)), /*!< GPIO mode : output only with open-drain mode */
} gpio_mode_t;
typedef enum {
GPIO_PULLUP_ONLY, /*!< Pad pull up */
GPIO_PULLDOWN_ONLY, /*!< Pad pull down */
GPIO_FLOATING, /*!< Pad floating */
} gpio_pull_mode_t;
typedef enum {
GPIO_PULLUP_DISABLE = 0x0, /*!< Disable GPIO pull-up resistor */
GPIO_PULLUP_ENABLE = 0x1, /*!< Enable GPIO pull-up resistor */
} gpio_pullup_t;
typedef enum {
GPIO_PULLDOWN_DISABLE = 0x0, /*!< Disable GPIO pull-down resistor */
GPIO_PULLDOWN_ENABLE = 0x1, /*!< Enable GPIO pull-down resistor */
} gpio_pulldown_t;
/**
* @brief Configuration parameters of GPIO pad for gpio_config function
*/
typedef struct {
uint16_t GPIO_Pin; /**< GPIO pin */
GPIOMode_TypeDef GPIO_Mode; /**< GPIO mode */
GPIO_Pullup_IF GPIO_Pullup; /**< GPIO pullup */
GPIO_INT_TYPE GPIO_IntrType; /**< GPIO interrupt type */
} GPIO_ConfigTypeDef;
uint32_t pin_bit_mask; /*!< GPIO pin: set with bit mask, each bit maps to a GPIO */
gpio_mode_t mode; /*!< GPIO mode: set input/output mode */
gpio_pullup_t pull_up_en; /*!< GPIO pull-up */
gpio_pulldown_t pull_down_en; /*!< GPIO pull-down */
gpio_int_type_t intr_type; /*!< GPIO interrupt type */
} gpio_config_t;
/** \defgroup Driver_APIs Driver APIs
* @brief Driver APIs
*/
/** @addtogroup Driver_APIs
* @{
*/
/** \defgroup GPIO_Driver_APIs GPIO Driver APIs
* @brief GPIO APIs
*/
/** @addtogroup GPIO_Driver_APIs
* @{
*/
typedef void (*gpio_isr_t)(void *);
typedef void *gpio_isr_handle_t;
/**
* @brief Set GPIO pin output level.
*
* @param gpio_no : The GPIO sequence number.
* @param bit_value : GPIO pin output level.
*
* @return null
*/
#define GPIO_OUTPUT_SET(gpio_no, bit_value) \
gpio_output_conf(bit_value<<gpio_no, ((~bit_value)&0x01)<<gpio_no, 1<<gpio_no, 0)
* @brief GPIO common configuration
*
* Configure GPIO's Mode,pull-up,PullDown,IntrType
*
* @param gpio_config Pointer to GPIO configure struct
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t gpio_config(const gpio_config_t *gpio_cfg);
/**
* @brief Set GPIO pin output level.
*
* @param gpio_bits : The GPIO bit number.
* @param bit_value : GPIO pin output level.
*
* @return null
*/
#define GPIO_OUTPUT(gpio_bits, bit_value) \
if(bit_value) gpio_output_conf(gpio_bits, 0, gpio_bits, 0);\
else gpio_output_conf(0, gpio_bits, gpio_bits, 0)
* @brief GPIO set interrupt trigger type
*
* @param gpio_num GPIO number. If you want to set the trigger type of e.g. of GPIO12, gpio_num should be GPIO_NUM_12 (12);
* @param intr_type Interrupt type, select from gpio_int_type_t
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t gpio_set_intr_type(gpio_num_t gpio_num, gpio_int_type_t intr_type);
/**
* @brief Disable GPIO pin output.
*
* @param gpio_no : The GPIO sequence number.
*
* @return null
*/
#define GPIO_DIS_OUTPUT(gpio_no) gpio_output_conf(0, 0, 0, 1<<gpio_no)
* @brief Enable GPIO module interrupt signal
*
* @param gpio_num GPIO number. If you want to enable an interrupt on e.g. GPIO12, gpio_num should be GPIO_NUM_12 (12);
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t gpio_intr_enable(gpio_num_t gpio_num);
/**
* @brief Enable GPIO pin intput.
*
* @param gpio_bits : The GPIO bit number.
*
* @return null
*/
#define GPIO_AS_INPUT(gpio_bits) gpio_output_conf(0, 0, 0, gpio_bits)
* @brief Disable GPIO module interrupt signal
*
* @param gpio_num GPIO number. If you want to disable the interrupt of e.g. GPIO12, gpio_num should be GPIO_NUM_12 (12);
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t gpio_intr_disable(gpio_num_t gpio_num);
/**
* @brief Enable GPIO pin output.
*
* @param gpio_bits : The GPIO bit number.
*
* @return null
*/
#define GPIO_AS_OUTPUT(gpio_bits) gpio_output_conf(0, 0, gpio_bits, 0)
* @brief GPIO set output level
*
* @param gpio_num GPIO number. If you want to set the output level of e.g. GPIO16, gpio_num should be GPIO_NUM_16 (16);
* @param level Output level. 0: low ; 1: high
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG GPIO number error
*/
esp_err_t gpio_set_level(gpio_num_t gpio_num, uint32_t level);
/**
* @brief Sample the level of GPIO input.
*
* @param gpio_no : The GPIO sequence number.
*
* @return the level of GPIO input
*/
#define GPIO_INPUT_GET(gpio_no) ((gpio_input_get()>>gpio_no)&BIT(0))
* @brief GPIO get input level
*
* @note If the pad is not configured for input (or input and output) the returned value is always 0.
*
* @param gpio_num GPIO number. If you want to get the logic level of e.g. pin GPIO16, gpio_num should be GPIO_NUM_16 (16);
*
* @return
* - 0 the GPIO input level is 0
* - 1 the GPIO input level is 1
*/
int gpio_get_level(gpio_num_t gpio_num);
/**
* @brief Enable GPIO16 output.
*
* @param null
*
* @return null
*/
void gpio16_output_conf(void);
* @brief GPIO set direction
*
* Configure GPIO direction,such as output_only,input_only
*
* @param gpio_num Configure GPIO pins number, it should be GPIO number. If you want to set direction of e.g. GPIO16, gpio_num should be GPIO_NUM_16 (16);
* @param mode GPIO direction
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG GPIO error
*/
esp_err_t gpio_set_direction(gpio_num_t gpio_num, gpio_mode_t mode);
/**
* @brief Set GPIO16 output level.
*
* @param uint8_t value : GPIO16 output level.
*
* @return null
*/
void gpio16_output_set(uint8_t value);
* @brief Configure GPIO pull-up/pull-down resistors
*
* @param gpio_num GPIO number. If you want to set pull up or down mode for e.g. GPIO16, gpio_num should be GPIO_NUM_16 (16);
* @param pull GPIO pull up/down mode.
*
* @note The GPIO of esp8266 can not be pulled down except RTC GPIO which can not be pulled up.
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG : Parameter error
*/
esp_err_t gpio_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull);
/**
* @brief Enable GPIO pin intput.
* @brief Enable GPIO wake-up function.
*
* @note RTC IO can not use the wakeup function
*
* @param null
* @param gpio_num GPIO number.
*
* @return null
* @param intr_type GPIO wake-up type. Only GPIO_INTR_LOW_LEVEL or GPIO_INTR_HIGH_LEVEL can be used.
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
void gpio16_input_conf(void);
esp_err_t gpio_wakeup_enable(gpio_num_t gpio_num, gpio_int_type_t intr_type);
/**
* @brief Sample the value of GPIO16 input.
* @brief Disable GPIO wake-up function.
*
* @param null
* @note RTC IO can not use the wakeup function
*
* @param gpio_num GPIO number
*
* @return the level of GPIO16 input.
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
uint8_t gpio16_input_get(void);
esp_err_t gpio_wakeup_disable(gpio_num_t gpio_num);
/**
* @brief Configure Gpio pins out or input.
*
* @param uint32_t set_mask : Set the output for the high bit, the
* corresponding bit is 1, the output of high,
* the corresponding bit is 0, do not change the state.
* @param uint32_t set_mask : Set the output for the high bit, the
* corresponding bit is 1, the output of low,
* the corresponding bit is 0, do not change the state.
* @param uint32_t enable_mask : Enable Output
* @param uint32_t disable_mask : Enable Input
*
* @return null
*/
void gpio_output_conf(uint32_t set_mask, uint32_t clear_mask, uint32_t enable_mask, uint32_t disable_mask);
* @brief Register GPIO interrupt handler, the handler is an ISR.
*
* This ISR function is called whenever any GPIO interrupt occurs. See
* the alternative gpio_install_isr_service() and
* gpio_isr_handler_add() API in order to have the driver support
* per-GPIO ISRs.
*
* @param fn Interrupt handler function.
* @param no_use In order to be compatible with esp32, the parameter has no practical meaning and can be filled with 0.
* @param arg Parameter for handler function
* @param handle Pointer to return handle. In order to be compatible with esp32,the parameter has no practical meaning and can be filled with NULL.
*
* @return
* - ESP_OK Success ;
* - ESP_ERR_INVALID_ARG GPIO error
* - ESP_ERR_NOT_FOUND No free interrupt found with the specified flags
*/
esp_err_t gpio_isr_register(void (*fn)(void *), void *arg, int no_use, gpio_isr_handle_t *handle);
/**
* @brief Register an application-specific interrupt handler for GPIO pin interrupts.
* @brief Enable pull-up on GPIO.
*
* @param void *fn:interrupt handler for GPIO pin interrupts.
* @param void *arg:interrupt handler's arg
* @param gpio_num GPIO number
*
* @return null
* @note The GPIO of esp8266 can not be pulled down except RTC GPIO which can not be pulled up.
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
void gpio_intr_handler_register(void* fn, void* arg);
esp_err_t gpio_pullup_en(gpio_num_t gpio_num);
/**
* @brief Configure GPIO wake up to light sleep,Only level way is effective.
* @brief Disable pull-up on GPIO.
*
* @param uint32_t i : Gpio sequence number
* @param GPIO_INT_TYPE intr_state : the level of wake up to light sleep
* @param gpio_num GPIO number
*
* @return null
* @note The GPIO of esp8266 can not be pulled down except RTC GPIO which can not be pulled up.
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
void gpio_pin_wakeup_enable(uint32_t i, GPIO_INT_TYPE intr_state);
esp_err_t gpio_pullup_dis(gpio_num_t gpio_num);
/**
* @brief Disable GPIO wake up to light sleep.
* @brief Enable pull-down on GPIO.
*
* @param null
* @param gpio_num GPIO number
*
* @return null
* @note The GPIO of esp8266 can not be pulled down except RTC GPIO which can not be pulled up.
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
void gpio_pin_wakeup_disable();
esp_err_t gpio_pulldown_en(gpio_num_t gpio_num);
/**
* @brief Config interrupt types of GPIO pin.
* @brief Disable pull-down on GPIO.
*
* @param uint32_t i : The GPIO sequence number.
* @param GPIO_INT_TYPE intr_state : GPIO interrupt types.
* @param gpio_num GPIO number
*
* @return null
* @note The GPIO of esp8266 can not be pulled down except RTC GPIO which can not be pulled up.
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_ARG Parameter error
*/
void gpio_pin_intr_state_set(uint32_t i, GPIO_INT_TYPE intr_state);
esp_err_t gpio_pulldown_dis(gpio_num_t gpio_num);
/**
* @brief Sample the value of GPIO input pins and returns a bitmask.
* @brief Install the driver's GPIO ISR handler service, which allows per-pin GPIO interrupt handlers.
*
* @param null
* This function is incompatible with gpio_isr_register() - if that function is used, a single global ISR is registered for all GPIO interrupts. If this function is used, the ISR service provides a global GPIO ISR and individual pin handlers are registered via the gpio_isr_handler_add() function.
*
* @return bitmask of GPIO pins input
* @param no_use In order to be compatible with esp32, the parameter has no practical meaning and can be filled with 0.
*
* @return
* - ESP_OK Success
* - ESP_ERR_NO_MEM No memory to install this service
* - ESP_ERR_INVALID_STATE ISR service already installed.
* - ESP_ERR_NOT_FOUND No free interrupt found with the specified flags
* - ESP_ERR_INVALID_ARG GPIO error
*/
uint32_t gpio_input_get(void);
esp_err_t gpio_install_isr_service(int no_use);
/**
* @}
* @brief Uninstall the driver's GPIO ISR service, freeing related resources.
*/
void gpio_uninstall_isr_service();
/**
* @}
* @brief Add ISR handler for the corresponding GPIO pin.
*
* Call this function after using gpio_install_isr_service() to
* install the driver's GPIO ISR handler service.
*
* This ISR handler will be called from an ISR. So there is a stack
* size limit (configurable as "ISR stack size" in menuconfig). This
* limit is smaller compared to a global GPIO interrupt handler due
* to the additional level of indirection.
*
* @param gpio_num GPIO number
* @param isr_handler ISR handler function for the corresponding GPIO number.
* @param args parameter for ISR handler.
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_STATE Wrong state, the ISR service has not been initialized.
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t gpio_isr_handler_add(gpio_num_t gpio_num, gpio_isr_t isr_handler, void *args);
/**
* @brief Remove ISR handler for the corresponding GPIO pin.
*
* @param gpio_num GPIO number
*
* @return
* - ESP_OK Success
* - ESP_ERR_INVALID_STATE Wrong state, the ISR service has not been initialized.
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t gpio_isr_handler_remove(gpio_num_t gpio_num);
#ifdef __cplusplus
}
#endif
#endif
#endif /* _DRIVER_GPIO_H_ */

View File

@ -27,6 +27,12 @@
#include <stdint.h>
/* IO definitions (access restrictions to peripheral registers) */
#define __RO__ volatile const /*!< Defines 'read only' permissions */
#define __WO__ volatile /*!< Defines 'write only' permissions */
#define __RW__ volatile /*!< Defines 'read / write' permissions */
//Register Bits{{
#define BIT31 0x80000000
#define BIT30 0x40000000

View File

@ -83,7 +83,6 @@
#define GPIO_ID_PIN(n) (GPIO_ID_PIN0+(n))
#define GPIO_LAST_REGISTER_ID GPIO_ID_PIN(15)
#define GPIO_ID_NONE 0xffffffff
#define GPIO_PIN_COUNT 16
#define GPIO_PIN_CONFIG_MSB 12
#define GPIO_PIN_CONFIG_LSB 11

View File

@ -0,0 +1,93 @@
/*
* Copyright 2018 Espressif Systems (Shanghai) PTE LTD
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef _GPIO_STRUCT_H_
#define _GPIO_STRUCT_H_
#include <stdint.h>
#include "esp8266/eagle_soc.h"
#ifdef __cplusplus
extern "C" {
#endif
/* ESP8266 GPIO Register Definitions */
typedef union {
__RW__ struct {
uint32_t sleep_oe: 1;
uint32_t sleep_sel: 1;
uint32_t reserved1: 1;
uint32_t sleep_pullup: 1;
uint32_t func_low_bit: 2;
uint32_t reserved2: 1;
uint32_t pullup: 1;
uint32_t func_high_bit: 1;
};
__RW__ struct {
uint32_t func_low_bit: 2;
uint32_t reserved1: 1;
uint32_t pulldown: 1;
uint32_t reserved2: 1;
uint32_t sleep_pulldown: 1;
uint32_t func_high_bit: 1;
} rtc_pin;
__RW__ uint32_t val;
} gpio_pin_reg_t;
typedef struct {
__RO__ uint32_t out;
__WO__ uint32_t out_w1ts;
__WO__ uint32_t out_w1tc;
__RO__ uint32_t enable;
__WO__ uint32_t enable_w1ts;
__WO__ uint32_t enable_w1tc;
__RO__ uint32_t in;
__RO__ uint32_t status;
__WO__ uint32_t status_w1ts;
__WO__ uint32_t status_w1tc;
__RW__ union {
struct {
uint32_t source: 1;
uint32_t reserved1: 1;
uint32_t driver: 1;
uint32_t reserved2: 4;
uint32_t int_type: 3;
uint32_t wakeup_enable: 1;
uint32_t reserved3: 21;
};
uint32_t val;
} pin[16];
__RW__ uint32_t sigma_delta;
__RW__ uint32_t rtc_calib_sync;
__RW__ uint32_t rtc_calib_value;
} gpio_struct_t;
extern volatile gpio_struct_t GPIO;
#ifdef __cplusplus
}
#endif /* end of __cplusplus */
#endif /* _GPIO_STRUCT_H_ */

View File

@ -0,0 +1 @@
PROVIDE ( GPIO = 0x60000300);