diff --git a/configure.ac b/configure.ac index 6b7774e..81c3c3b 100644 --- a/configure.ac +++ b/configure.ac @@ -31,6 +31,7 @@ AC_CONFIG_FILES([ modules/Makefile examples/Makefile examples/0blink/Makefile + examples/0button/Makefile examples/0hello/Makefile examples/0ledctrl/Makefile examples/1rmtblink/Makefile diff --git a/examples/0button/Makefile.am b/examples/0button/Makefile.am new file mode 100644 index 0000000..cacaaf1 --- /dev/null +++ b/examples/0button/Makefile.am @@ -0,0 +1,20 @@ +include $(top_srcdir)/scripts/elf2bin.mk +include $(top_srcdir)/ld/flags.mk + +noinst_HEADERS = defines.h + +AM_CFLAGS = -std=c11 -flto +AM_CPPFLAGS = -I$(top_srcdir)/src -I$(srcdir) +AM_LDFLAGS += -T $(top_srcdir)/ld/esp32.rom.ld \ + -T $(top_srcdir)/ld/esp32.rom.redefined.ld +LDADD = $(top_builddir)/src/libesp32basic.a + +bin_PROGRAMS = \ + buttonisr.elf + +if WITH_BINARIES +CLEANFILES = \ + buttonisr.bin +endif + +BUILT_SOURCES = $(CLEANFILES) diff --git a/examples/0button/README.md b/examples/0button/README.md new file mode 100644 index 0000000..fa38d1a --- /dev/null +++ b/examples/0button/README.md @@ -0,0 +1,13 @@ +### Listening on button press event + +This example demonstrates how to set up an ISR on GPIO event. + +#### Hardware components + +B0: BOOT button + +#### Connections + +``` +ESP32.GPIO0 -- B0 (builtin) -- ESP32.GND +``` diff --git a/examples/0button/buttonisr.c b/examples/0button/buttonisr.c new file mode 100644 index 0000000..2aabbc9 --- /dev/null +++ b/examples/0button/buttonisr.c @@ -0,0 +1,108 @@ +/* + * Copyright 2024 SZIGETI János + * + * This file is part of Bilis ESP32 Basic, which is released under GNU General Public License.version 3. + * See LICENSE or for full license details. + */ +#include +#include +#include +#include +#include + +#include "esp_attr.h" +#include "dport.h" +#include "gpio.h" +#include "iomux.h" +#include "main.h" +#include "defines.h" +#include "romfunctions.h" +#include "typeaux.h" +#include "uart.h" +#include "utils/uartutils.h" + +// =================== Hard constants ================= + +#define BUTTON_GPIO 0U +#define INT_CH 22U + +// ============= Local types =============== + +// ================ Local function declarations ================= +static void _button_init(); +static void _button_cycle(uint64_t u64Ticks); + +// =================== Global constants ================ +const bool gbStartAppCpu = START_APP_CPU; +const uint16_t gu16Tim00Divisor = TIM0_0_DIVISOR; +const uint64_t gu64tckSchedulePeriod = (CLK_FREQ_HZ / SCHEDULE_FREQ_HZ); + +// ==================== Local Data ================ +static volatile bool gbLedOn = false; +static const char acMessage[] = "Button pressed.\n"; + +// Implementation + +IRAM_ATTR static void _button_isr(void *pvParam) { + bool bButtonEvent = gsGPIO.STATUS & (1 << BUTTON_GPIO); + if (bButtonEvent) { + gsGPIO.STATUS_W1TC = (1 << BUTTON_GPIO); + bool bLevel = gsGPIO.IN & (1 << BUTTON_GPIO); + if (!bLevel) { + for (int i = 0; i < ARRAY_SIZE(acMessage) - 1; ++i) { + gsUART0.FIFO = acMessage[i]; + } + } + } +} + +static void _button_init() { + IomuxGpioConfReg rIOMux; + rIOMux.raw = iomux_get_gpioconf(BUTTON_GPIO); + rIOMux.u1FunIE = 1; + iomux_set_gpioconf(BUTTON_GPIO, rIOMux); + SGpioPinReg sPinReg = { + .u3PinIntType = 3, + .u5PinIntEn = 5 + }; + gsGPIO.PIN[BUTTON_GPIO] = sPinReg; + + // register ISR and enable it + ECpu eCpu = CPU_PRO; + RegAddr prDportIntMap = (eCpu == CPU_PRO ? &dport_regs()->PRO_GPIO_INTERRUPT_MAP : &dport_regs()->APP_GPIO_INTERRUPT_MAP); + + *prDportIntMap = INT_CH; + _xtos_set_interrupt_handler_arg(INT_CH, _button_isr, 0); + ets_isr_unmask(1 << INT_CH); + +} + +static void _button_cycle(uint64_t u64Ticks) { + static uint64_t u64tckNext = 0; + + if (u64tckNext < u64Ticks) { + bool bLevel = gsGPIO.IN & (1 << BUTTON_GPIO); + gsUART0.FIFO = bLevel ? '^' : '_'; + u64tckNext += MS2TICKS(2000); + } +} + +// ====================== Interface functions ========================= + +void prog_init_pro_pre() { + gsUART0.CLKDIV = APB_FREQ_HZ / 115200; + _button_init(); +} + +void prog_init_app() { +} + +void prog_init_pro_post() { +} + +void prog_cycle_app(uint64_t u64tckNow) { +} + +void prog_cycle_pro(uint64_t u64tckNow) { + _button_cycle(u64tckNow); +} diff --git a/examples/0button/defines.h b/examples/0button/defines.h new file mode 100644 index 0000000..d61d4d7 --- /dev/null +++ b/examples/0button/defines.h @@ -0,0 +1,36 @@ +/* + * Copyright 2024 SZIGETI János + * + * This file is part of Bilis ESP32 Basic, which is released under GNU General Public License.version 3. + * See LICENSE or for full license details. + */ +#ifndef DEFINES_H +#define DEFINES_H + +#ifdef __cplusplus +extern "C" { +#endif + + // TIMINGS + // const -- do not change this value +#define APB_FREQ_HZ 80000000U // 80 MHz + + // variables +#define TIM0_0_DIVISOR 2U +#define START_APP_CPU 0U +#define SCHEDULE_FREQ_HZ 1000U // 10KHz + + // derived invariants +#define CLK_FREQ_HZ (APB_FREQ_HZ / TIM0_0_DIVISOR) // 40 MHz +#define TICKS_PER_MS (CLK_FREQ_HZ / 1000U) // 40000 +#define TICKS_PER_US (CLK_FREQ_HZ / 1000000U) // 40 + +#define MS2TICKS(X) ((X) * TICKS_PER_MS) +#define HZ2APBTICKS(X) (APB_FREQ_HZ / (X)) + +#ifdef __cplusplus +} +#endif + +#endif /* DEFINES_H */ + diff --git a/examples/Makefile.am b/examples/Makefile.am index 87db8b2..7c3e446 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -1,2 +1,2 @@ AUTOMAKE_OPTIONS = -SUBDIRS=0blink 0hello 0ledctrl 1rmtblink 1rmtmorse 1rmtmusic 3prog1 1rmtws2812 +SUBDIRS=0blink 0button 0hello 0ledctrl 1rmtblink 1rmtmorse 1rmtmusic 3prog1 1rmtws2812 diff --git a/src/gpio.h b/src/gpio.h index 62b433d..9aa35fc 100644 --- a/src/gpio.h +++ b/src/gpio.h @@ -15,6 +15,20 @@ extern "C" { // Based on: // https://github.com/espressif/esp-idf/blob/6b3da6b1882f3b72e904cc90be67e9c4e3f369a9/components/soc/esp32/include/soc/gpio_reg.h + typedef volatile union { + + volatile struct { + uint32_t rsvd0 : 2; + uint32_t u1PinPadDriver : 1; + uint32_t rsvd4 : 4; + uint32_t u3PinIntType : 3; + uint32_t bWakeUpEn : 1; + uint32_t rsvd11 : 2; + uint32_t u5PinIntEn : 5; + uint32_t rsvd18 : 14; + }; + volatile uint32_t raw; + } SGpioPinReg; typedef struct { Reg BT_SELECT; @@ -51,7 +65,7 @@ extern "C" { Reg PCPU_INT1; Reg PCPU_NMI_INT1; Reg CPUSDIO_INT1; - Reg PIN[40]; + SGpioPinReg PIN[40]; Reg cali_conf; Reg cali_data; Reg FUNC_IN_SEL_CFG[256]; diff --git a/src/iomux.h b/src/iomux.h index d317ade..e66dd74 100644 --- a/src/iomux.h +++ b/src/iomux.h @@ -54,6 +54,9 @@ extern "C" { static inline void iomux_set_gpioconf(uint8_t u8GpioNum, IomuxGpioConfReg rGpioConf) { register_set(&grIOMUX + gau8IomuxGpioIdx[u8GpioNum], rGpioConf.raw); } + static inline Reg iomux_get_gpioconf(uint8_t u8GpioNum) { + return register_read(&grIOMUX + gau8IomuxGpioIdx[u8GpioNum]); + } #ifdef __cplusplus }