ESP32: Add GPIO support
This commit is contained in:
parent
946045075e
commit
650757bbf0
@ -163,7 +163,7 @@
|
||||
|
||||
/* Total number of peripherals */
|
||||
|
||||
#define NR_PERIPHERALS 69
|
||||
#define ESP32_NPERIPHERALS 69
|
||||
|
||||
/* Exceptions
|
||||
*
|
||||
@ -192,6 +192,7 @@
|
||||
#define XTENSA_IRQ_TIMER1 1 /* INTERRUPT, bit 15 */
|
||||
#define XTENSA_IRQ_TIMER2 2 /* INTERRUPT, bit 16 */
|
||||
|
||||
#define XTENSA_NIRQ_INTERNAL 3 /* Number of dispatch internal interrupts */
|
||||
#define XTENSA_IRQ_FIRSTPERIPH 3 /* First peripheral IRQ number */
|
||||
|
||||
/* IRQ numbers for peripheral interrupts coming throught the Interrupt
|
||||
@ -287,9 +288,26 @@
|
||||
#define ESP32_IRQ_SREG2 ESP32_IRQ_TG1_WDT_EDGE
|
||||
#define ESP32_NIRQS_SREG2 5
|
||||
|
||||
#define ESP32_NIRQ_PERIPH ESP32_NPERIPHERALS
|
||||
|
||||
/* Second level GPIO interrupts. GPIO interrupts are decoded and dispatched as
|
||||
* a second level of decoding: The first level dispatches to the GPIO interrupt
|
||||
* handler. The second to the decoded GPIO interrupt handler.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_ESP32_GPIO_IRQ
|
||||
# define ESP32_NIRQ_GPIO 40
|
||||
# define ESP32_FIRST_GPIOIRQ (XTENSA_NIRQ_INTERNAL+ESP32_NIRQ_PERIPH)
|
||||
# define ESP32_LAST_GPIOIRQ (ESP32_FIRST_GPIOIRQ+ESP32_NIRQ_GPIO-1)
|
||||
# define ESP32_PIN2IRQ(p) ((p) + ESP32_FIRST_GPIOIRQ)
|
||||
# define ESP32_IRQ2PIN(i) ((i) - ESP32_FIRST_GPIOIRQ)
|
||||
#else
|
||||
# define ESP32_NIRQ_GPIO 0
|
||||
#endif
|
||||
|
||||
/* Total number of interrupts */
|
||||
|
||||
#define NR_IRQS (ESP32_IRQ_CACHE_IA+1)
|
||||
#define NR_IRQS (XTENSA_NIRQ_INTERNAL+ESP32_NIRQ_PERIPH+ESP32_NIRQ_GPIO)
|
||||
|
||||
/* CPU Interrupts.
|
||||
*
|
||||
@ -347,23 +365,32 @@
|
||||
#define ESP32_CPUINT_LEVELPERIPH_18 26
|
||||
#define ESP32_CPUINT_LEVELPERIPH_19 27
|
||||
#define ESP32_CPUINT_LEVELPERIPH_20 31
|
||||
|
||||
#define ESP32_CPUINT_NLEVELPERIPHS 21
|
||||
#define EPS32_CPUINT_LEVELSET 0x8fbe333f
|
||||
|
||||
#define ESP32_CPUINT_EDGEPERIPH_0 10
|
||||
#define ESP32_CPUINT_EDGEPERIPH_1 22
|
||||
#define ESP32_CPUINT_EDGEPERIPH_2 28
|
||||
#define ESP32_CPUINT_EDGEPERIPH_3 30
|
||||
|
||||
#define ESP32_CPUINT_NEDGEPERIPHS 4
|
||||
#define EPS32_CPUINT_EDGESET 0x50400400
|
||||
|
||||
#define ESP32_CPUINT_NNMIPERIPHS 4
|
||||
#define EPS32_CPUINT_NMISET 0x00004000
|
||||
|
||||
#define ESP32_CPUINT_TIMER0 6
|
||||
#define ESP32_CPUINT_SOFTWARE0 7
|
||||
#define ESP32_CPUINT_PROFILING 11
|
||||
#define ESP32_CPUINT_TIMER1 15
|
||||
#define ESP32_CPUINT_TIMER2 16
|
||||
#define ESP32_CPUINT_SOFTWARE1 29
|
||||
|
||||
#define ESP32_CPUINT_NINTERNAL 5
|
||||
|
||||
#define ESP32_CPUINT_MAX 31
|
||||
#define EPS32_CPUINT_PERIPHSET 0xdffe7f3f
|
||||
#define EPS32_CPUINT_PERIPHSET 0xdffe6f3f
|
||||
#define EPS32_CPUINT_INTERNALSET 0x200180c0
|
||||
|
||||
/* Priority 1: 0-10, 12-13, 17-18 (15)
|
||||
|
@ -419,3 +419,4 @@ xtensa_context_restore:
|
||||
l32i a0, a2, (4 * REG_A0) /* Restore a0 */
|
||||
l32i a2, a2, (4 * REG_A2) /* Restore A2 */
|
||||
rfe /* And return from "exception" */
|
||||
|
||||
|
@ -193,6 +193,11 @@ config ESP32_WIRELESS
|
||||
|
||||
endmenu # ESP32 Peripheral Selection
|
||||
|
||||
config ESP32_GPIO_IRQ
|
||||
bool "GPIO pin interrupts"
|
||||
---help---
|
||||
Enable support for interrupting GPIO pins
|
||||
|
||||
config ESP32_BT_RESERVE_DRAM
|
||||
int "Reserved BT DRAM"
|
||||
default 0
|
||||
|
@ -377,18 +377,22 @@
|
||||
#define GPIO_PIN_INT_ENA_M ((GPIO_PIN_INT_ENA_V)<<(GPIO_PIN_INT_ENA_S))
|
||||
#define GPIO_PIN_INT_ENA_V 0x0000001F
|
||||
#define GPIO_PIN_INT_ENA_S 13
|
||||
|
||||
#define GPIO_PIN_CONFIG 0x00000003
|
||||
#define GPIO_PIN_CONFIG_M ((GPIO_PIN_CONFIG_V)<<(GPIO_PIN_CONFIG_S))
|
||||
#define GPIO_PIN_CONFIG_V 0x00000003
|
||||
#define GPIO_PIN_CONFIG_S 11
|
||||
|
||||
#define GPIO_PIN_WAKEUP_ENABLE (BIT(10))
|
||||
#define GPIO_PIN_WAKEUP_ENABLE_M (BIT(10))
|
||||
#define GPIO_PIN_WAKEUP_ENABLE_V 0x1
|
||||
#define GPIO_PIN_WAKEUP_ENABLE_S 10
|
||||
|
||||
#define GPIO_PIN_INT_TYPE 0x00000007
|
||||
#define GPIO_PIN_INT_TYPE_M ((GPIO_PIN_INT_TYPE_V)<<(GPIO_PIN_INT_TYPE_S))
|
||||
#define GPIO_PIN_INT_TYPE_V 0x00000007
|
||||
#define GPIO_PIN_INT_TYPE_S 7
|
||||
|
||||
#define GPIO_PIN_PAD_DRIVER (BIT(2))
|
||||
#define GPIO_PIN_PAD_DRIVER_M (BIT(2))
|
||||
#define GPIO_PIN_PAD_DRIVER_V 0x1
|
||||
|
288
arch/xtensa/src/esp32/chip/esp32_iomux.h
Normal file
288
arch/xtensa/src/esp32/chip/esp32_iomux.h
Normal file
@ -0,0 +1,288 @@
|
||||
/****************************************************************************
|
||||
* arch/xtensa/src/esp32/esp32_gpio.c
|
||||
*
|
||||
* Developed for NuttX by:
|
||||
*
|
||||
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Derivies from sample code provided by Expressif Systems:
|
||||
*
|
||||
* Copyright 2015-2016 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 __ARCH_XTENSA_SRC_ESP32_CHIP_ESP32_MUX_H
|
||||
#define __ARCH_XTENSA_SRC_ESP32_CHIP_ESP32_MUX_H 1
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include "chip/esp32_soc.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define SLP_OE (BIT(0))
|
||||
#define SLP_SEL (BIT(1))
|
||||
#define SLP_PD (BIT(2))
|
||||
#define SLP_PU (BIT(3))
|
||||
#define SLP_IE (BIT(4))
|
||||
#define SLP_DRV 0x3
|
||||
#define SLP_DRV_S 5
|
||||
#define FUN_PD (BIT(7))
|
||||
#define FUN_PU (BIT(8))
|
||||
#define FUN_IE (BIT(9))
|
||||
#define FUN_DRV 0x3
|
||||
#define FUN_DRV_S 10
|
||||
#define MCU_SEL 0x7
|
||||
#define MCU_SEL_S 12
|
||||
|
||||
#define PIN_INPUT_ENABLE(PIN_NAME) SET_PERI_REG_MASK(PIN_NAME,FUN_IE)
|
||||
#define PIN_INPUT_DISABLE(PIN_NAME) CLEAR_PERI_REG_MASK(PIN_NAME,FUN_IE)
|
||||
#define PIN_SET_DRV(PIN_NAME, drv) REG_SET_FIELD(PIN_NAME, FUN_DRV, (drv));
|
||||
#define PIN_PULLUP_DIS(PIN_NAME) REG_CLR_BIT(PIN_NAME, FUN_PU)
|
||||
#define PIN_PULLUP_EN(PIN_NAME) REG_SET_BIT(PIN_NAME, FUN_PU)
|
||||
#define PIN_PULLDWN_DIS(PIN_NAME) REG_CLR_BIT(PIN_NAME, FUN_PD)
|
||||
#define PIN_PULLDWN_EN(PIN_NAME) REG_SET_BIT(PIN_NAME, FUN_PD)
|
||||
#define PIN_FUNC_SELECT(PIN_NAME, FUNC) REG_SET_FIELD(PIN_NAME, MCU_SEL, FUNC)
|
||||
|
||||
#define PIN_FUNC_GPIO 2
|
||||
|
||||
#define PIN_CTRL (DR_REG_IO_MUX_BASE +0x00)
|
||||
#define CLK_OUT3 0xf
|
||||
#define CLK_OUT3_S 8
|
||||
#define CLK_OUT2 0xf
|
||||
#define CLK_OUT2_S 4
|
||||
#define CLK_OUT1 0xf
|
||||
#define CLK_OUT1_S 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO0_U (DR_REG_IO_MUX_BASE +0x44)
|
||||
#define FUNC_GPIO0_EMAC_TX_CLK 5
|
||||
#define FUNC_GPIO0_GPIO0 2
|
||||
#define FUNC_GPIO0_CLK_OUT1 1
|
||||
#define FUNC_GPIO0_GPIO0_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_U0TXD_U (DR_REG_IO_MUX_BASE +0x88)
|
||||
#define FUNC_U0TXD_EMAC_RXD2 3
|
||||
#define FUNC_U0TXD_GPIO1 2
|
||||
#define FUNC_U0TXD_CLK_OUT3 1
|
||||
#define FUNC_U0TXD_U0TXD 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO2_U (DR_REG_IO_MUX_BASE +0x40)
|
||||
#define FUNC_GPIO2_SD_DATA0 4
|
||||
#define FUNC_GPIO2_HS2_DATA0 3
|
||||
#define FUNC_GPIO2_GPIO2 2
|
||||
#define FUNC_GPIO2_HSPIWP 1
|
||||
#define FUNC_GPIO2_GPIO2_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_U0RXD_U (DR_REG_IO_MUX_BASE +0x84)
|
||||
#define FUNC_U0RXD_GPIO3 2
|
||||
#define FUNC_U0RXD_CLK_OUT2 1
|
||||
#define FUNC_U0RXD_U0RXD 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO4_U (DR_REG_IO_MUX_BASE +0x48)
|
||||
#define FUNC_GPIO4_EMAC_TX_ER 5
|
||||
#define FUNC_GPIO4_SD_DATA1 4
|
||||
#define FUNC_GPIO4_HS2_DATA1 3
|
||||
#define FUNC_GPIO4_GPIO4 2
|
||||
#define FUNC_GPIO4_HSPIHD 1
|
||||
#define FUNC_GPIO4_GPIO4_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO5_U (DR_REG_IO_MUX_BASE +0x6c)
|
||||
#define FUNC_GPIO5_EMAC_RX_CLK 5
|
||||
#define FUNC_GPIO5_HS1_DATA6 3
|
||||
#define FUNC_GPIO5_GPIO5 2
|
||||
#define FUNC_GPIO5_VSPICS0 1
|
||||
#define FUNC_GPIO5_GPIO5_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_SD_CLK_U (DR_REG_IO_MUX_BASE +0x60)
|
||||
#define FUNC_SD_CLK_U1CTS 4
|
||||
#define FUNC_SD_CLK_HS1_CLK 3
|
||||
#define FUNC_SD_CLK_GPIO6 2
|
||||
#define FUNC_SD_CLK_SPICLK 1
|
||||
#define FUNC_SD_CLK_SD_CLK 0
|
||||
|
||||
#define PERIPHS_IO_MUX_SD_DATA0_U (DR_REG_IO_MUX_BASE +0x64)
|
||||
#define FUNC_SD_DATA0_U2RTS 4
|
||||
#define FUNC_SD_DATA0_HS1_DATA0 3
|
||||
#define FUNC_SD_DATA0_GPIO7 2
|
||||
#define FUNC_SD_DATA0_SPIQ 1
|
||||
#define FUNC_SD_DATA0_SD_DATA0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_SD_DATA1_U (DR_REG_IO_MUX_BASE +0x68)
|
||||
#define FUNC_SD_DATA1_U2CTS 4
|
||||
#define FUNC_SD_DATA1_HS1_DATA1 3
|
||||
#define FUNC_SD_DATA1_GPIO8 2
|
||||
#define FUNC_SD_DATA1_SPID 1
|
||||
#define FUNC_SD_DATA1_SD_DATA1 0
|
||||
|
||||
#define PERIPHS_IO_MUX_SD_DATA2_U (DR_REG_IO_MUX_BASE +0x54)
|
||||
#define FUNC_SD_DATA2_U1RXD 4
|
||||
#define FUNC_SD_DATA2_HS1_DATA2 3
|
||||
#define FUNC_SD_DATA2_GPIO9 2
|
||||
#define FUNC_SD_DATA2_SPIHD 1
|
||||
#define FUNC_SD_DATA2_SD_DATA2 0
|
||||
|
||||
#define PERIPHS_IO_MUX_SD_DATA3_U (DR_REG_IO_MUX_BASE +0x58)
|
||||
#define FUNC_SD_DATA3_U1TXD 4
|
||||
#define FUNC_SD_DATA3_HS1_DATA3 3
|
||||
#define FUNC_SD_DATA3_GPIO10 2
|
||||
#define FUNC_SD_DATA3_SPIWP 1
|
||||
#define FUNC_SD_DATA3_SD_DATA3 0
|
||||
|
||||
#define PERIPHS_IO_MUX_SD_CMD_U (DR_REG_IO_MUX_BASE +0x5c)
|
||||
#define FUNC_SD_CMD_U1RTS 4
|
||||
#define FUNC_SD_CMD_HS1_CMD 3
|
||||
#define FUNC_SD_CMD_GPIO11 2
|
||||
#define FUNC_SD_CMD_SPICS0 1
|
||||
#define FUNC_SD_CMD_SD_CMD 0
|
||||
|
||||
#define PERIPHS_IO_MUX_MTDI_U (DR_REG_IO_MUX_BASE +0x34)
|
||||
#define FUNC_MTDI_EMAC_TXD3 5
|
||||
#define FUNC_MTDI_SD_DATA2 4
|
||||
#define FUNC_MTDI_HS2_DATA2 3
|
||||
#define FUNC_MTDI_GPIO12 2
|
||||
#define FUNC_MTDI_HSPIQ 1
|
||||
#define FUNC_MTDI_MTDI 0
|
||||
|
||||
#define PERIPHS_IO_MUX_MTCK_U (DR_REG_IO_MUX_BASE +0x38)
|
||||
#define FUNC_MTCK_EMAC_RX_ER 5
|
||||
#define FUNC_MTCK_SD_DATA3 4
|
||||
#define FUNC_MTCK_HS2_DATA3 3
|
||||
#define FUNC_MTCK_GPIO13 2
|
||||
#define FUNC_MTCK_HSPID 1
|
||||
#define FUNC_MTCK_MTCK 0
|
||||
|
||||
#define PERIPHS_IO_MUX_MTMS_U (DR_REG_IO_MUX_BASE +0x30)
|
||||
#define FUNC_MTMS_EMAC_TXD2 5
|
||||
#define FUNC_MTMS_SD_CLK 4
|
||||
#define FUNC_MTMS_HS2_CLk 3
|
||||
#define FUNC_MTMS_GPIO14 2
|
||||
#define FUNC_MTMS_HSPICLK 1
|
||||
#define FUNC_MTMS_MTMS 0
|
||||
|
||||
#define PERIPHS_IO_MUX_MTDO_U (DR_REG_IO_MUX_BASE +0x3c)
|
||||
#define FUNC_MTDO_EMAC_RXD3 5
|
||||
#define FUNC_MTDO_SD_CMD 4
|
||||
#define FUNC_MTDO_HS2_CMD 3
|
||||
#define FUNC_MTDO_GPIO15 2
|
||||
#define FUNC_MTDO_HSPICS0 1
|
||||
#define FUNC_MTDO_MTDO 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO16_U (DR_REG_IO_MUX_BASE +0x4c)
|
||||
#define FUNC_GPIO16_EMAC_CLK_OUT 5
|
||||
#define FUNC_GPIO16_U2RXD 4
|
||||
#define FUNC_GPIO16_HS1_DATA4 3
|
||||
#define FUNC_GPIO16_GPIO16 2
|
||||
#define FUNC_GPIO16_GPIO16_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO17_U (DR_REG_IO_MUX_BASE +0x50)
|
||||
#define FUNC_GPIO17_EMAC_CLK_OUT_180 5
|
||||
#define FUNC_GPIO17_U2TXD 4
|
||||
#define FUNC_GPIO17_HS1_DATA5 3
|
||||
#define FUNC_GPIO17_GPIO17 2
|
||||
#define FUNC_GPIO17_GPIO17_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO18_U (DR_REG_IO_MUX_BASE +0x70)
|
||||
#define FUNC_GPIO18_HS1_DATA7 3
|
||||
#define FUNC_GPIO18_GPIO18 2
|
||||
#define FUNC_GPIO18_VSPICLK 1
|
||||
#define FUNC_GPIO18_GPIO18_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO19_U (DR_REG_IO_MUX_BASE +0x74)
|
||||
#define FUNC_GPIO19_EMAC_TXD0 5
|
||||
#define FUNC_GPIO19_U0CTS 3
|
||||
#define FUNC_GPIO19_GPIO19 2
|
||||
#define FUNC_GPIO19_VSPIQ 1
|
||||
#define FUNC_GPIO19_GPIO19_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO20_U (DR_REG_IO_MUX_BASE +0x78)
|
||||
#define FUNC_GPIO20_GPIO20 2
|
||||
#define FUNC_GPIO20_GPIO20_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO21_U (DR_REG_IO_MUX_BASE +0x7c)
|
||||
#define FUNC_GPIO21_EMAC_TX_EN 5
|
||||
#define FUNC_GPIO21_GPIO21 2
|
||||
#define FUNC_GPIO21_VSPIHD 1
|
||||
#define FUNC_GPIO21_GPIO21_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO22_U (DR_REG_IO_MUX_BASE +0x80)
|
||||
#define FUNC_GPIO22_EMAC_TXD1 5
|
||||
#define FUNC_GPIO22_U0RTS 3
|
||||
#define FUNC_GPIO22_GPIO22 2
|
||||
#define FUNC_GPIO22_VSPIWP 1
|
||||
#define FUNC_GPIO22_GPIO22_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO23_U (DR_REG_IO_MUX_BASE +0x8c)
|
||||
#define FUNC_GPIO23_HS1_STROBE 3
|
||||
#define FUNC_GPIO23_GPIO23 2
|
||||
#define FUNC_GPIO23_VSPID 1
|
||||
#define FUNC_GPIO23_GPIO23_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO24_U (DR_REG_IO_MUX_BASE +0x90)
|
||||
#define FUNC_GPIO24_GPIO24 2
|
||||
#define FUNC_GPIO24_GPIO24_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO25_U (DR_REG_IO_MUX_BASE +0x24)
|
||||
#define FUNC_GPIO25_EMAC_RXD0 5
|
||||
#define FUNC_GPIO25_GPIO25 2
|
||||
#define FUNC_GPIO25_GPIO25_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO26_U (DR_REG_IO_MUX_BASE +0x28)
|
||||
#define FUNC_GPIO26_EMAC_RXD1 5
|
||||
#define FUNC_GPIO26_GPIO26 2
|
||||
#define FUNC_GPIO26_GPIO26_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO27_U (DR_REG_IO_MUX_BASE +0x2c)
|
||||
#define FUNC_GPIO27_EMAC_RX_DV 5
|
||||
#define FUNC_GPIO27_GPIO27 2
|
||||
#define FUNC_GPIO27_GPIO27_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO32_U (DR_REG_IO_MUX_BASE +0x1c)
|
||||
#define FUNC_GPIO32_GPIO32 2
|
||||
#define FUNC_GPIO32_GPIO32_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO33_U (DR_REG_IO_MUX_BASE +0x20)
|
||||
#define FUNC_GPIO33_GPIO33 2
|
||||
#define FUNC_GPIO33_GPIO33_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO34_U (DR_REG_IO_MUX_BASE +0x14)
|
||||
#define FUNC_GPIO34_GPIO34 2
|
||||
#define FUNC_GPIO34_GPIO34_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO35_U (DR_REG_IO_MUX_BASE +0x18)
|
||||
#define FUNC_GPIO35_GPIO35 2
|
||||
#define FUNC_GPIO35_GPIO35_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO36_U (DR_REG_IO_MUX_BASE +0x04)
|
||||
#define FUNC_GPIO36_GPIO36 2
|
||||
#define FUNC_GPIO36_GPIO36_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO37_U (DR_REG_IO_MUX_BASE +0x08)
|
||||
#define FUNC_GPIO37_GPIO37 2
|
||||
#define FUNC_GPIO37_GPIO37_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO38_U (DR_REG_IO_MUX_BASE +0x0c)
|
||||
#define FUNC_GPIO38_GPIO38 2
|
||||
#define FUNC_GPIO38_GPIO38_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO39_U (DR_REG_IO_MUX_BASE +0x10)
|
||||
#define FUNC_GPIO39_GPIO39 2
|
||||
#define FUNC_GPIO39_GPIO39_0 0
|
||||
|
||||
#endif /* __ARCH_XTENSA_SRC_ESP32_CHIP_ESP32_MUX_H */
|
@ -54,10 +54,6 @@
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define ESP32_INTSET(n) ((1 << (n)) - 1)
|
||||
#define ESP32_LEVEL_SET ESP32_INTSET(ESP32_CPUINT_NLEVELPERIPHS)
|
||||
#define ESP32_EDGE_SET ESP32_INTSET(ESP32_CPUINT_NEDGEPERIPHS)
|
||||
|
||||
/* Mapping Peripheral IDs to map register addresses
|
||||
*
|
||||
* PERIPHERAL ID DPORT REGISTER OFFSET
|
||||
@ -169,12 +165,11 @@ static uint32_t g_intenable[1];
|
||||
|
||||
/* Bitsets for free, unallocated CPU interrupts */
|
||||
|
||||
static uint32_t g_level_ints = ESP32_LEVEL_SET;
|
||||
static uint32_t g_edge_ints = ESP32_EDGE_SET;
|
||||
static uint32_t g_free_cpuints = 0xffffffff;
|
||||
|
||||
/* Bitsets for each interrupt priority 1-5 */
|
||||
|
||||
static uint32_t g_priority[5] =
|
||||
static const uint32_t g_priority[5] =
|
||||
{
|
||||
ESP32_INTPRI1_MASK,
|
||||
ESP32_INTPRI2_MASK,
|
||||
@ -187,6 +182,75 @@ static uint32_t g_priority[5] =
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32_alloc_cpuint
|
||||
*
|
||||
* Description:
|
||||
* Allocate a CPU interrupt
|
||||
*
|
||||
* Input Parameters:
|
||||
* mask - mask of candidate CPU interrupts. The CPU interrupt will be
|
||||
* be allocated from free interrupts within this set
|
||||
*
|
||||
* Returned Value:
|
||||
* On success, the allocated level-sensitive, CPU interrupt numbr is
|
||||
* returned. A negated errno is returned on failure. The only possible
|
||||
* failure is that all level-sensitive CPU interrupts have already been
|
||||
* allocated.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int esp32_alloc_levelint(uint32_t mask)
|
||||
{
|
||||
irqstate_t flags;
|
||||
uint32_t mask;
|
||||
uint32_t intset;
|
||||
int cpuint;
|
||||
int ret = -ENOMEM;
|
||||
|
||||
/* Check if there are is CPU interrupts with the requrested properties
|
||||
* available.
|
||||
*/
|
||||
|
||||
flags = enter_critical_section();
|
||||
|
||||
intset = g_free_cpuints & mask;
|
||||
if (intset != 0)
|
||||
{
|
||||
/* Skip over initial unavailable CPU interrupts quickly in groups
|
||||
* of 8 interrupt.
|
||||
*/
|
||||
|
||||
for (cpuint = 0, mask = 0xff;
|
||||
cpuint <= ESP32_CPUINT_MAX;
|
||||
cpuint += 8, mask <<= 8);
|
||||
|
||||
/* Search for an unallocated CPU interrupt number in the remaining
|
||||
* intset.
|
||||
*/
|
||||
|
||||
for (; cpuint <= ESP32_CPUINT_MAX; cpuint++)
|
||||
{
|
||||
/* If the bit corresponding to the CPU interrupt is '1', then
|
||||
* that CPU interrupt is available.
|
||||
*/
|
||||
|
||||
mask = (1ul << cpuint);
|
||||
if ((intset & mask) != 0)
|
||||
{
|
||||
/* Got it! */
|
||||
|
||||
g_free_cpuints &= ~mask;
|
||||
ret = cpuint;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@ -258,83 +322,17 @@ void up_enable_irq(int cpuint)
|
||||
|
||||
int esp32_alloc_levelint(int priority)
|
||||
{
|
||||
irqstate_t flags;
|
||||
uint32_t mask;
|
||||
uint32_t intset;
|
||||
int cpuint;
|
||||
int ret = -ENOMEM;
|
||||
|
||||
DEBUGASSERT(priority >= ESP32_MIN_PRIORITY && priority <= ESP32_MAX_PRIORITY)
|
||||
DEBUGASSERT(priority >= ESP32_MIN_PRIORITY &&
|
||||
priority <= ESP32_MAX_PRIORITY)
|
||||
|
||||
/* Check if there are any level CPU interrupts available */
|
||||
|
||||
flags = enter_critical_section();
|
||||
|
||||
intset = g_level_ints & g_priority[ESP32_PRIO_INDEX(priority)] & ESP32_LEVEL_SET;
|
||||
if (intset != 0)
|
||||
{
|
||||
/* Skip over initial zeroes as quickly in groups of 8 bits. */
|
||||
|
||||
for (cpuint = 0, mask = 0xff;
|
||||
cpuint <= ESP32_CPUINT_MAX && (intset & mask) == 0;
|
||||
cpuint += 8, mask <<= 8);
|
||||
|
||||
/* Search for an unallocated CPU interrupt number in the remaining intset. */
|
||||
|
||||
for (; cpuint <= ESP32_CPUINT_MAX && intset != 0; cpuint++)
|
||||
{
|
||||
/* If the bit corresponding to the CPU interrupt is '1', then
|
||||
* that CPU interrupt is available.
|
||||
/* Check if there are any level CPU interrupts available at the requested
|
||||
* interrupt priority.
|
||||
*/
|
||||
|
||||
mask = (1ul << cpuint);
|
||||
if ((intset & mask) != 0)
|
||||
{
|
||||
/* Got it! */
|
||||
|
||||
g_level_ints &= ~mask;
|
||||
ret = cpuint;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Clear the bit in intset so that we may exit the loop sooner */
|
||||
|
||||
intset &= ~mask;
|
||||
}
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32_free_levelint
|
||||
*
|
||||
* Description:
|
||||
* Free a previoulsy allocated level CPU interrupt
|
||||
*
|
||||
* Input Parameters:
|
||||
* The CPU interrupt number to be freed
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void esp32_free_levelint(int cpuint)
|
||||
{
|
||||
irqstate_t flags;
|
||||
uint32_t mask;
|
||||
|
||||
DEBUGASSERT(cpuint >= 0 && cpuint < ESP32_CPUINT_NLEVELPERIPHS);
|
||||
|
||||
/* Mark the CPU interrupt as available */
|
||||
|
||||
mask = (1ul << cpuint);
|
||||
flags = enter_critical_section();
|
||||
DEBUGASSERT((g_level_ints & mask) == 0);
|
||||
g_level_ints |= mask;
|
||||
leave_critical_section(flags);
|
||||
mask = g_priority[ESP32_PRIO_INDEX(priority)] & EPS32_CPUINT_LEVELSET;
|
||||
return esp_alloc_cpuint(mask);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -356,60 +354,24 @@ void esp32_free_levelint(int cpuint)
|
||||
|
||||
int esp32_alloc_edgeint(int priority)
|
||||
{
|
||||
irqstate_t flags;
|
||||
uint32_t mask;
|
||||
uint32_t intset;
|
||||
int cpuint;
|
||||
int ret = -ENOMEM;
|
||||
|
||||
DEBUGASSERT(priority >= ESP32_MIN_PRIORITY && priority <= ESP32_MAX_PRIORITY)
|
||||
DEBUGASSERT(priority >= ESP32_MIN_PRIORITY &&
|
||||
priority <= ESP32_MAX_PRIORITY)
|
||||
|
||||
/* Check if there are any level CPU interrupts available */
|
||||
|
||||
flags = enter_critical_section();
|
||||
|
||||
intset = g_edge_ints & g_priority[ESP32_PRIO_INDEX(priority)] & ESP32_EDGE_SET;
|
||||
if (intset != 0)
|
||||
{
|
||||
/* Skip over initial zeroes as quickly in groups of 8 bits. */
|
||||
|
||||
for (cpuint = 0, mask = 0xff;
|
||||
cpuint <= ESP32_CPUINT_MAX && (intset & mask) == 0;
|
||||
cpuint += 8, mask <<= 8);
|
||||
|
||||
/* Search for an unallocated CPU interrupt number in the remaining intset. */
|
||||
|
||||
for (; cpuint <= ESP32_CPUINT_MAX && intset != 0; cpuint++)
|
||||
{
|
||||
/* If the bit corresponding to the CPU interrupt is '1', then
|
||||
* that CPU interrupt is available.
|
||||
/* Check if there are any edge CPU interrupts available at the requested
|
||||
* interrupt priority.
|
||||
*/
|
||||
|
||||
mask = (1ul << cpuint);
|
||||
if ((intset & mask) != 0)
|
||||
{
|
||||
/* Got it! */
|
||||
|
||||
g_edge_ints &= ~mask;
|
||||
ret = cpuint;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Clear the bit in intset so that we may exit the loop sooner */
|
||||
|
||||
intset &= ~mask;
|
||||
}
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
return ret;
|
||||
mask = g_priority[ESP32_PRIO_INDEX(priority)] & EPS32_CPUINT_EDGESET;
|
||||
return esp_alloc_cpuint(mask);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32_free_edgeint
|
||||
* Name: esp32_free_cpuint
|
||||
*
|
||||
* Description:
|
||||
* Free a previoulsy allocated edge CPU interrupt
|
||||
* Free a previoulsy allocated CPU interrupt
|
||||
*
|
||||
* Input Parameters:
|
||||
* The CPU interrupt number to be freed
|
||||
@ -419,7 +381,7 @@ int esp32_alloc_edgeint(int priority)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void esp32_free_edgeint(int cpuint)
|
||||
void esp32_free_cpuint(int cpuint)
|
||||
{
|
||||
irqstate_t flags;
|
||||
uint32_t mask;
|
||||
@ -430,8 +392,8 @@ void esp32_free_edgeint(int cpuint)
|
||||
|
||||
mask = (1ul << cpuint);
|
||||
flags = enter_critical_section();
|
||||
DEBUGASSERT((g_edge_ints & mask) == 0);
|
||||
g_edge_ints |= mask;
|
||||
DEBUGASSERT((g_free_cpuints & mask) == 0);
|
||||
g_free_cpuints |= mask;
|
||||
leave_critical_section(flags);
|
||||
}
|
||||
|
||||
@ -455,7 +417,7 @@ void esp32_attach_peripheral(int cpu, int periphid, int cpuint)
|
||||
{
|
||||
uintptr_t regaddr;
|
||||
|
||||
DEBUGASSERT(periphid >= 0 && periphid < NR_PERIPHERALS);
|
||||
DEBUGASSERT(periphid >= 0 && periphid < ESP32_NPERIPHERALS);
|
||||
DEBUGASSERT(cpuint >= 0 && cpuint <= ESP32_CPUINT_MAX);
|
||||
#ifdef CONFIG_SMP
|
||||
DEBUGASSERT(cpu >= 0 && cpu < CONFIG_SMP_NCPUS);
|
||||
@ -492,7 +454,7 @@ void esp32_detach_peripheral(int cpu, int periphid)
|
||||
{
|
||||
uintptr_t regaddr;
|
||||
|
||||
DEBUGASSERT(periphid >= 0 && periphid < NR_PERIPHERALS);
|
||||
DEBUGASSERT(periphid >= 0 && periphid < ESP32_NPERIPHERALS);
|
||||
#ifdef CONFIG_SMP
|
||||
DEBUGASSERT(cpu >= 0 && cpu < CONFIG_SMP_NCPUS);
|
||||
|
||||
|
@ -65,22 +65,6 @@
|
||||
|
||||
int esp32_alloc_levelint(int priority);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32_free_levelint
|
||||
*
|
||||
* Description:
|
||||
* Free a previoulsy allocated level CPU interrupt
|
||||
*
|
||||
* Input Parameters:
|
||||
* cpuint - The CPU interrupt number to be freed
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void esp32_free_levelint(int cpuint);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32_alloc_edgeint
|
||||
*
|
||||
@ -101,10 +85,10 @@ void esp32_free_levelint(int cpuint);
|
||||
int esp32_alloc_edgeint(int priority);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32_free_edgeint
|
||||
* Name: esp32_free_cpuint
|
||||
*
|
||||
* Description:
|
||||
* Free a previoulsy allocated edge CPU interrupt
|
||||
* Free a previoulsy allocated CPU interrupt
|
||||
*
|
||||
* Input Parameters:
|
||||
* cpuint - The CPU interrupt number to be freed
|
||||
@ -114,7 +98,7 @@ int esp32_alloc_edgeint(int priority);
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void esp32_free_edgeint(int cpuint, int priority);
|
||||
void esp32_free_cpuint(int cpuint, int priority);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32_attach_peripheral
|
||||
|
@ -148,7 +148,7 @@ int xtensa_start_handler(int irq, FAR void *context)
|
||||
|
||||
/* Detach all peripheral sources APP CPU interrupts */
|
||||
|
||||
for (i = 0; i < NR_PERIPHERALS)
|
||||
for (i = 0; i < ESP32_NPERIPHERALS; i++)
|
||||
{
|
||||
esp32_detach_peripheral(1, i);;
|
||||
}
|
||||
|
423
arch/xtensa/src/esp32/esp32_gpio.c
Normal file
423
arch/xtensa/src/esp32/esp32_gpio.c
Normal file
@ -0,0 +1,423 @@
|
||||
/****************************************************************************
|
||||
* arch/xtensa/src/esp32/esp32_gpio.c
|
||||
*
|
||||
* Developed for NuttX by:
|
||||
*
|
||||
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Derivies from sample code provided by Expressif Systems:
|
||||
*
|
||||
* Copyright 2015-2016 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
#include <arch/irq.h>
|
||||
|
||||
#include "chip/esp32_iomux.h"
|
||||
#include "chip/esp32_gpio.h"
|
||||
#include "esp32_gpio.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define NGPIO_HPINS (ESP32_NIRQ_GPIO - 32)
|
||||
#define NGPIO_HMASK ((1ul << NGPIO_HPINS) - 1)
|
||||
#define _NA_ 0xff
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static uint8_t g_gpio_cpuint;
|
||||
|
||||
static const uint8_t g_pin2func[40] =
|
||||
{
|
||||
0x44, 0x88, 0x40, 0x84, 0x48, 0x6c, 0x60, 0x64, /* 0-7 */
|
||||
0x68, 0x54, 0x58, 0x5c, 0x34, 0x38, 0x30, 0x3c, /* 8-15 */
|
||||
0x4c, 0x50, 0x70, 0x74, 0x78, 0x7c, 0x80, 0x8c, /* 16-23 */
|
||||
_NA_, 0x24, 0x28, 0x2c, _NA_, _NA_, _NA_, _NA_, /* N/A, 25-27, N/A, N/A, N/A, N/A */
|
||||
0x1c, 0x20, 0x14, 0x18, 0x04, 0x08, 0x0c, 0x10 /* 32-39 */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: gpio_dispatch
|
||||
*
|
||||
* Description:
|
||||
* Second level dispatch for GPIO interrupt handling.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ESP32_GPIO_IRQ
|
||||
static void gpio_dispatch(int irq, uint32_t status, uint32_t *regs)
|
||||
{
|
||||
uint32_t mask;
|
||||
int i;
|
||||
|
||||
/* Check each bit in the status register */
|
||||
|
||||
for (i = 0; i < 32 && status != 0; i++)
|
||||
{
|
||||
/* Check if there is an interrupt pending for this pin */
|
||||
|
||||
mask = (1ul << i);
|
||||
if ((status & mask) != 0)
|
||||
{
|
||||
/* Yes... perform the second level dispatch */
|
||||
|
||||
irq_dispatch(irq + i, regs);
|
||||
|
||||
/* Clear the bit in the status so that we might execute this loop
|
||||
* sooner.
|
||||
*/
|
||||
|
||||
status &= ~mask;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: gpio_interrupt
|
||||
*
|
||||
* Description:
|
||||
* GPIO interrupt handler.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ESP32_GPIO_IRQ
|
||||
static int gpio_interrupt(int irq, FAR void *context)
|
||||
{
|
||||
uint32_t status;
|
||||
uint32_t gpio_intr_status_h = 0;
|
||||
|
||||
/* Read and clear the lower GPIO interrupt status */
|
||||
|
||||
status = getreg32(GPIO_STATUS_REG);
|
||||
putreg32(status, GPIO_STATUS_W1TC_REG);
|
||||
|
||||
/* Dispatch pending interrupts in the lower GPIO status register */
|
||||
|
||||
gpio_dispatch(ESP32_FIRST_GPIOIRQ, status, (uint32_t *)context);
|
||||
|
||||
/* Read and clear the upper GPIO interrupt status */
|
||||
|
||||
status = getreg32(GPIO_STATUS1_REG) & NGPIO_HMASK;
|
||||
putreg32(status, GPIO_STATUS1_W1TC_REG);
|
||||
|
||||
/* Dispatch pending interrupts in the lower GPIO status register */
|
||||
|
||||
gpio_dispatch(ESP32_FIRST_GPIOIRQ + 32, status, (uint32_t *)context);
|
||||
reutnr OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32_configgpio
|
||||
*
|
||||
* Description:
|
||||
* Configure a GPIO pin based on encoded pin attributes.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int esp32_configgpio(int pin, gpio_pinattr_t attr)
|
||||
{
|
||||
uintptr_t regaddr;
|
||||
uint32_t func;
|
||||
uint32_t cntl;
|
||||
|
||||
DEBUGASSERT(pin >=0 && pin <= ESP32_NIRQ_GPIO);
|
||||
DEBUGASSERT(pin >=0 && pin <= ESP32_NIRQ_GPIO);
|
||||
|
||||
/* Handle input pins */
|
||||
|
||||
func = 0;
|
||||
cntrl = 0;
|
||||
|
||||
if ((attr & INPUT) != 0)
|
||||
{
|
||||
if (pin < 32)
|
||||
{
|
||||
putreg32((1ul << pin), GPIO_ENABLE_W1TC_REG);
|
||||
}
|
||||
else
|
||||
{
|
||||
putreg32((1ul << (pin - 32), GPIO_ENABLE1_DATA_W1TC);
|
||||
}
|
||||
|
||||
if ((attr & PULLUP) != 0)
|
||||
{
|
||||
func |= FUN_PU;
|
||||
}
|
||||
else if (attr & PULLDOWN)
|
||||
{
|
||||
func |= FUN_PD;
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle output pins */
|
||||
|
||||
else if ((attr & OUTPUT) != 0)
|
||||
{
|
||||
if (pin < 32)
|
||||
{
|
||||
putreg32((1ul << pin), GPIO_ENABLE_DATA_W1TS);
|
||||
}
|
||||
else
|
||||
{
|
||||
putreg32((1ul << (pin - 32), GPIO_ENABLE1_DATA_W1TS);
|
||||
}
|
||||
}
|
||||
|
||||
/* Add drivers */
|
||||
|
||||
func |= ((uint32_t)(2ul << FUN_DRV_S);
|
||||
|
||||
/* Input enable... Required for output as well? */
|
||||
|
||||
func |= FUN_IE;
|
||||
|
||||
|
||||
if ((attr & (INPUT | OUTPUT)) != 0)
|
||||
{
|
||||
func |= ((uint32_t)(2 << MCU_SEL_S);
|
||||
}
|
||||
else if (attr == SPECIAL)
|
||||
{
|
||||
func |= ((uint32_t)(((pin) == 1 || (pin) == 3) ? 0 : 1) << MCU_SEL_S);
|
||||
}
|
||||
else
|
||||
{
|
||||
func |= ((uint32_t)(attr >> 5) << MCU_SEL_S);
|
||||
}
|
||||
|
||||
if ((attr & OPEN_DRAIN) != 0)
|
||||
{
|
||||
cntl = (1 << GPIO_PIN_PAD_DRIVER_S);
|
||||
}
|
||||
|
||||
regaddr = DR_REG_IO_MUX_BASE + g_pin2func[pin];
|
||||
putreg32(func, regaddr);
|
||||
|
||||
regaddr = GPIO_REG(pin);
|
||||
putreg32(cntl, regaddr);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32_gpiowrite
|
||||
*
|
||||
* Description:
|
||||
* Write one or zero to the selected GPIO pin
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void esp32_gpiowrite(int pin, bool value)
|
||||
{
|
||||
if (pin > 39)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (value)
|
||||
{
|
||||
if (pin < 32)
|
||||
{
|
||||
GPIO.out_w1ts = ((uint32_t) 1 << pin);
|
||||
}
|
||||
else
|
||||
{
|
||||
GPIO.out1_w1ts.val = ((uint32_t) 1 << (pin - 32));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pin < 32)
|
||||
{
|
||||
GPIO.out_w1tc = ((uint32_t) 1 << pin);
|
||||
}
|
||||
else
|
||||
{
|
||||
GPIO.out1_w1tc.val = ((uint32_t) 1 << (pin - 32));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32_gpioread
|
||||
*
|
||||
* Description:
|
||||
* Read one or zero from the selected GPIO pin
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
bool esp32_gpioread(int pin)
|
||||
{
|
||||
if (pin > 39)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (pin < 32)
|
||||
{
|
||||
return ((GPIO.in >> pin) & 1) != 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ((GPIO.in1.val >> (pin - 32)) & 1) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32_gpioirqinitialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize logic to support a second level of interrupt decoding for
|
||||
* GPIO pins.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ESP32_GPIO_IRQ
|
||||
void esp32_gpioirqinitialize(void)
|
||||
{
|
||||
int cpu;
|
||||
|
||||
/* Allocate a level-sensitive, priority 1 CPU interrupt */
|
||||
|
||||
g_gpio_cpuint = esp32_alloc_levelint(1);
|
||||
DEBUGASSERT(g_gpio_cpuint >= 0);
|
||||
|
||||
/* Attach the GPIO peripheral to the allocated CPU interrupt */
|
||||
|
||||
up_disable_irq(g_gpio_cpuint);
|
||||
cpu = up_cpu_index();
|
||||
esp32_attach_peripheral(cpu, ESP32_PERIPH_CPU_GPIO, g_gpio_cpuint);
|
||||
|
||||
/* Attach and enable the interrupt handler */
|
||||
|
||||
DEBUGVERIFY(irq_attach(ESP32_IRQ_CPU_GPIO, gpio_interrupt));
|
||||
up_enable_irq(g_gpio_cpuint);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32_gpioirqenable
|
||||
*
|
||||
* Description:
|
||||
* Enable the COPY interrupt for specified GPIO IRQ
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ESP32_GPIO_IRQ
|
||||
void esp32_gpioirqenable(int irq, gpio_intrtype_t intrtype)
|
||||
{
|
||||
uintptr_t regaddr;
|
||||
uint32_t regval;
|
||||
int cpu;
|
||||
int pin;
|
||||
|
||||
DEBUGASSERT(irq <= ESP32_FIRST_GPIOIRQ && irq <= ESP32_LAST_GPIOIRQ);
|
||||
|
||||
/* Convert the IRQ number to a pin number */
|
||||
|
||||
pin = ESP32_IRQ2PIN(irq);
|
||||
|
||||
/* Get the address of the GPIO PIN register for this pin */
|
||||
|
||||
up_disable_irq(g_gpio_cpuint);
|
||||
|
||||
regaddr = GPIO_REG(pin);
|
||||
regval = getreg32(regaddr);
|
||||
regval &= ~(GPIO_PIN_INT_ENA_M | GPIO_PIN_INT_TYPE_M);
|
||||
|
||||
/* Set the pin ENA field:
|
||||
*
|
||||
* Bit 0: APP CPU interrupt enable
|
||||
* Bit 1: APP CPU non-maskable interrupt enable
|
||||
* Bit 3: PRO CPU interrupt enable
|
||||
* Bit 4: PRO CPU non-maskable interrupt enable
|
||||
* Bit 5: SDIO's extent interrupt enable.
|
||||
*/
|
||||
|
||||
cpu = up_cpu_index();
|
||||
if (cpu == 0)
|
||||
{
|
||||
/* PRO_CPU */
|
||||
|
||||
regval |= ((1 << 2) << GPIO_PIN_INT_ENA_S);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* APP_CPU */
|
||||
|
||||
regval |= ((1 << 0) << GPIO_PIN_INT_ENA_S);
|
||||
}
|
||||
|
||||
regval |= (intrtype << GPIO_PIN_INT_TYPE_S);
|
||||
puttreg32(regval, regaddr);
|
||||
|
||||
up_enable_irq(g_gpio_cpuint);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32_gpioirqdisable
|
||||
*
|
||||
* Description:
|
||||
* Disable the interrupt for specified GPIO IRQ
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ESP32_GPIO_IRQ
|
||||
void esp32_gpioirqdisable(int irq)
|
||||
{
|
||||
uintptr_t regaddr;
|
||||
uint32_t regval;
|
||||
int pin;
|
||||
|
||||
DEBUGASSERT(irq <= ESP32_FIRST_GPIOIRQ && irq <= ESP32_LAST_GPIOIRQ);
|
||||
|
||||
/* Convert the IRQ number to a pin number */
|
||||
|
||||
pin = ESP32_IRQ2PIN(irq);
|
||||
|
||||
/* Get the address of the GPIO PIN register for this pin */
|
||||
|
||||
up_disable_irq(g_gpio_cpuint);
|
||||
|
||||
regaddr = GPIO_REG(pin);
|
||||
regval = getreg32(regaddr);
|
||||
regval &= ~(GPIO_PIN_INT_ENA_M | GPIO_PIN_INT_TYPE_M);
|
||||
puttreg32(regval, regaddr);
|
||||
|
||||
up_enable_irq(g_gpio_cpuint);
|
||||
}
|
||||
#endif
|
185
arch/xtensa/src/esp32/esp32_gpio.h
Normal file
185
arch/xtensa/src/esp32/esp32_gpio.h
Normal file
@ -0,0 +1,185 @@
|
||||
/****************************************************************************
|
||||
* arch/xtensa/src/esp32/esp32_gpio.h
|
||||
*
|
||||
* Developed for NuttX by:
|
||||
*
|
||||
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Derivies in part from sample code provided by Expressif Systems:
|
||||
*
|
||||
* Copyright 2015-2016 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 __ARCH_XTENSA_SRC_ESP32_ESP32_GPIO_H
|
||||
#define __ARCH_XTENSA_SRC_ESP32_ESP32_GPIO_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
/* Bit-encoded input to esp32_configgpio() **********************************/
|
||||
|
||||
/* Encoded pin attributes used with esp32_configgpio() */
|
||||
|
||||
#define INPUT 0x01
|
||||
#define OUTPUT 0x02
|
||||
#define PULLUP 0x04
|
||||
#define INPUT_PULLUP 0x05
|
||||
#define PULLDOWN 0x08
|
||||
#define INPUT_PULLDOWN 0x09
|
||||
#define OPEN_DRAIN 0x10
|
||||
#define OUTPUT_OPEN_DRAIN 0x12
|
||||
#define SPECIAL 0xf0
|
||||
#define FUNCTION_0 0x00
|
||||
#define FUNCTION_1 0x20
|
||||
#define FUNCTION_2 0x40
|
||||
#define FUNCTION_3 0x70
|
||||
#define FUNCTION_4 0x80
|
||||
|
||||
/* Interrupt type used with esp32_gpioirqenable() */
|
||||
|
||||
#define DISABLED 0x00
|
||||
#define RISING 0x01
|
||||
#define FALLING 0x02
|
||||
#define CHANGE 0x03
|
||||
#define ONLOW 0x04
|
||||
#define ONHIGH 0x05
|
||||
#define ONLOW_WE 0x0c
|
||||
#define ONHIGH_WE 0x0d
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
/* Must be big enough to hold the the above encodings */
|
||||
|
||||
typedef uint8_t gpio_pinattr_t;
|
||||
typedef uint8_t gpio_intrtype_t;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
#define EXTERN extern "C"
|
||||
extern "C"
|
||||
{
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Inline Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32_gpioirqinitialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize logic to support a second level of interrupt decoding for
|
||||
* GPIO pins.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ESP32_GPIO_IRQ
|
||||
void esp32_gpioirqinitialize(void);
|
||||
#else
|
||||
# define esp32_gpioirqinitialize()
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32_configgpio
|
||||
*
|
||||
* Description:
|
||||
* Configure a GPIO pin based on encoded pin attributes.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int esp32_configgpio(int pin, gpio_pinattr_t attr);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32_gpiowrite
|
||||
*
|
||||
* Description:
|
||||
* Write one or zero to the selected GPIO pin
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void esp32_gpiowrite(int pin, bool value);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32_gpioread
|
||||
*
|
||||
* Description:
|
||||
* Read one or zero from the selected GPIO pin
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
bool esp32_gpioread(int pin);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32_gpioirqenable
|
||||
*
|
||||
* Description:
|
||||
* Enable the interrupt for specified GPIO IRQ
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ESP32_GPIO_IRQ
|
||||
void esp32_gpioirqenable(int irq, gpio_intrtype_t intrtype);
|
||||
#else
|
||||
# define esp32_gpioirqenable(irq,intrtype)
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32_gpioirqdisable
|
||||
*
|
||||
* Description:
|
||||
* Disable the interrupt for specified GPIO IRQ
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ESP32_GPIO_IRQ
|
||||
void esp32_gpioirqdisable(int irq);
|
||||
#else
|
||||
# define esp32_gpioirqdisable(irq)
|
||||
#endif
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
int digitalRead(uint8_t pin);
|
||||
|
||||
void attachInterrupt(uint8_t pin, void (*)(void), int mode);
|
||||
void detachInterrupt(uint8_t pin);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ARCH_XTENSA_SRC_ESP32_ESP32_GPIO_H */
|
@ -128,9 +128,9 @@ void xtensa_irq_initialize(void)
|
||||
|
||||
/* Detach all peripheral sources PRO CPU interrupts */
|
||||
|
||||
for (i = 0; i < NR_PERIPHERALS)
|
||||
for (i = 0; i < ESP32_NPERIPHERALS; i++)
|
||||
{
|
||||
esp32_detach_peripheral(0, i);;
|
||||
esp32_detach_peripheral(0, i);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_STACK_COLORATION) && CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||
|
Loading…
Reference in New Issue
Block a user