Skip to content

[ISSUE-17]: simple GPIO button ISR example #18

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 9, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
20 changes: 20 additions & 0 deletions examples/0button/Makefile.am
Original file line number Diff line number Diff line change
@@ -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)
13 changes: 13 additions & 0 deletions examples/0button/README.md
Original file line number Diff line number Diff line change
@@ -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
```
108 changes: 108 additions & 0 deletions examples/0button/buttonisr.c
Original file line number Diff line number Diff line change
@@ -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 <https://www.gnu.org/licenses/> for full license details.
*/
#include <stdbool.h>
#include <inttypes.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>

#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);
}
36 changes: 36 additions & 0 deletions examples/0button/defines.h
Original file line number Diff line number Diff line change
@@ -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 <https://www.gnu.org/licenses/> 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 */

2 changes: 1 addition & 1 deletion examples/Makefile.am
Original file line number Diff line number Diff line change
@@ -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
16 changes: 15 additions & 1 deletion src/gpio.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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];
Expand Down
3 changes: 3 additions & 0 deletions src/iomux.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
Loading