Sygaldry
Loading...
Searching...
No Matches
sygse-gpio.hpp
1#pragma once
2/*
3Copyright 2023 Travis J. West, https://traviswest.ca, Input Devices and Music Interaction Laboratory
4(IDMIL), Centre for Interdisciplinary Research in Music Media and Technology
5(CIRMMT), McGill University, Montréal, Canada, and Univ. Lille, Inria, CNRS,
6Centrale Lille, UMR 9189 CRIStAL, F-59000 Lille, France
7
8SPDX-License-Identifier: MIT
9*/
10
11#include <driver/gpio.h>
12#include <hal/gpio_types.h>
13#include <sygah-metadata.hpp>
14#include <sygah-endpoints.hpp>
15
16namespace sygaldry { namespace sygse {
22
23template<gpio_num_t pin_number>
24struct GPIO
25: name_<"GPIO Pin">
26, author_<"Travis J. West">
27, copyright_<"Travis J. West (C) 2023">
28, description_<"An ESP-IDF GPIO API wrapper as a message-based `sygaldry` component">
29{
30 #define gpio_function(c_name, esp_idf_func, ... )\
31 static auto c_name() noexcept\
32 {\
33 auto ret = esp_idf_func(__VA_ARGS__);\
34 ESP_ERROR_CHECK_WITHOUT_ABORT(ret);\
35 return ret;\
36 }
37 // all following input methods return esp_err_t, either ESP_OK or an error code
38 gpio_function(remove_interrupt_handler, gpio_isr_handler_remove, pin_number); // "remove interrupt handler", "remove the interrupt handler callback for this pin",
39 static auto interrupt_handler(void (*handler)(void*), void* args) noexcept
40 {
41 auto ret = gpio_isr_handler_add(pin_number, handler, args);
42 ESP_ERROR_CHECK_WITHOUT_ABORT(ret);
43 return ret;
44 }
45 static void uninstall_isr_service() noexcept
46 {
47 gpio_uninstall_isr_service();
48 }
49
50 // the installer must only be called once for all GPIO
51 static auto install_isr_service(int intr_alloc_flags) noexcept
52 {
53 auto ret = gpio_install_isr_service(intr_alloc_flags);
54 ESP_ERROR_CHECK_WITHOUT_ABORT(ret);
55 return ret;
56 }
57
58 // The documentation warns "ESP32: Please do not use the interrupt of GPIO36 and GPIO39 when using ADC or Wi-Fi and Bluetooth with sleep mode enabled."
59 gpio_function(enable_interrupt, gpio_intr_enable, pin_number); // "enable interrupt", "enable interrupt",
60 gpio_function(disable_interrupt, gpio_intr_disable, pin_number); // "disable interrupt", "disable interrupt",
61
62 gpio_function(reset, gpio_reset_pin, pin_number); // "reset", "reset pin and disconnect peripheral outputs",
63 gpio_function(rising_edge, gpio_set_intr_type, pin_number, GPIO_INTR_POSEDGE); // "rising edge", "interrupt on rising edge",
64 gpio_function(falling_edge, gpio_set_intr_type, pin_number, GPIO_INTR_NEGEDGE); // "falling edge", "interrupt on falling edge",
65 gpio_function(any_edge, gpio_set_intr_type, pin_number, GPIO_INTR_ANYEDGE); // "any edge", "interrupt on any edge",
66 gpio_function(low_level, gpio_set_intr_type, pin_number, GPIO_INTR_LOW_LEVEL); // "low level", "interrupt on low level trigger",
67 gpio_function(high_level, gpio_set_intr_type, pin_number, GPIO_INTR_HIGH_LEVEL); // "high level", "interrupt on high level trigger",
68 gpio_function(high, gpio_set_level, pin_number, 1); // "high", "set output level high",
69 gpio_function(low, gpio_set_level, pin_number, 0); // "low", "set output level low",
70
71 gpio_function(disable_pin, gpio_set_direction, pin_number, GPIO_MODE_DISABLE); // "disable pin", "disable input and output",
72 gpio_function(input_mode, gpio_set_direction, pin_number, GPIO_MODE_INPUT); // "input mode", "set pin mode to input",
73 gpio_function(output_mode, gpio_set_direction, pin_number, GPIO_MODE_OUTPUT); // "output mode", "set pin mode to output",
74 gpio_function(output_od_mode, gpio_set_direction, pin_number, GPIO_MODE_OUTPUT_OD); // "output od mode", "set pin mode to output with open-drain",
75 gpio_function(input_output_mode, gpio_set_direction, pin_number, GPIO_MODE_INPUT_OUTPUT); // "input output mode", "set pin mode to input/output",
76 gpio_function(input_output_od_mode, gpio_set_direction, pin_number, GPIO_MODE_INPUT_OUTPUT_OD); // "input output od mode", "set pin mode to input/output with open-drain",
77
78 // note: pins 34-39 have no pull resistors
79 gpio_function(enable_pullup, gpio_set_pull_mode, pin_number, GPIO_PULLUP_ONLY); // "enable pull-up", "enable internal pull-up resistor",
80 gpio_function(enable_pulldown, gpio_set_pull_mode, pin_number, GPIO_PULLDOWN_ONLY); // "enable pull-down", "enable internal pull-down resistor",
81 gpio_function(enable_pullup_and_pulldown, gpio_set_pull_mode, pin_number, GPIO_PULLUP_PULLDOWN); // "enable pull-up and pull-down", "enable both internal pull-up and pull-down resistors",
82 gpio_function(disable_pullup_and_pulldown, gpio_set_pull_mode, pin_number, GPIO_FLOATING); // "disable pull-up and pull-down", "disable both internal pull-up and pull-down resistors",
83 gpio_function(disable_pullup, gpio_pullup_dis, pin_number); // "disable pull-up", "disable internal pull-up resistor",
84 gpio_function(disable_pulldown, gpio_pulldown_dis, pin_number); // "disable pull-down", "disable internal pull-down resistor",
85
86 gpio_function(rising_edge_wakeup, gpio_wakeup_enable, pin_number, GPIO_INTR_POSEDGE); // "rising edge wake-up", "enable wake-up on rising edge",
87 gpio_function(falling_edge_wakeup, gpio_wakeup_enable, pin_number, GPIO_INTR_NEGEDGE); // "falling edge wake-up", "enable wake-up on falling edge",
88 gpio_function(any_edge_wakeup, gpio_wakeup_enable, pin_number, GPIO_INTR_ANYEDGE); // "any edge wake-up", "enable wake-up on any edge",
89 gpio_function(low_level_wakeup, gpio_wakeup_enable, pin_number, GPIO_INTR_LOW_LEVEL); // "low level wake-up", "enable wake-up on low level trigger",
90 gpio_function(high_level_wakeup, gpio_wakeup_enable, pin_number, GPIO_INTR_HIGH_LEVEL); // "high level wake-up", "enable wake-up on high level trigger",
91 gpio_function(disable_wakeup, gpio_wakeup_disable, pin_number); // "disable wake-up", "disable wake-up functionality",
92 gpio_function(wakeup_high, gpio_wakeup_enable, pin_number, GPIO_INTR_HIGH_LEVEL); // "wake-up high", "enable wake-up on high level",
93 gpio_function(wakeup_low, gpio_wakeup_enable, pin_number, GPIO_INTR_LOW_LEVEL); // "enable wake-up", "enable wake-up on low level",
94
95 gpio_function(set_drive_weakest, gpio_set_drive_capability, pin_number, GPIO_DRIVE_CAP_0); // "set drive weakest", "set drive capability",
96 gpio_function(set_drive_weak, gpio_set_drive_capability, pin_number, GPIO_DRIVE_CAP_1); // "set drive weak", "set drive capability",
97 gpio_function(set_drive_medium, gpio_set_drive_capability, pin_number, GPIO_DRIVE_CAP_2); // "set drive medium", "set drive capability",
98 gpio_function(set_drive_strong, gpio_set_drive_capability, pin_number, GPIO_DRIVE_CAP_DEFAULT); // "set drive strong", "set drive capability",
99 gpio_function(set_drive_strongest, gpio_set_drive_capability, pin_number, GPIO_DRIVE_CAP_3); // "set drive strongest", "set drive capability",
100
101 // TODO: hold, sleep hold, deep sleep hold, iomux, sleep sel, sleep dir, sleep pull, rtc pins, ...
102 static auto level() noexcept {
103 return gpio_get_level(pin_number);
104 }
105
106 static auto drive_capability() noexcept {
107 auto ret = GPIO_DRIVE_CAP_DEFAULT;
108 gpio_get_drive_capability(pin_number, &ret);
109 return ret;
110 }
111 #undef gpio_function
112 static void init()
113 {
114 static_assert(GPIO_NUM_0 <= pin_number && pin_number <= GPIO_NUM_39,
115 "pin number invalid");
116
117 // comment these out if you really know what you're doing!
118 static_assert(pin_number != GPIO_NUM_0, "GPIO0 is an important strapping pin"
119 "used during boot to determine SPI boot (pulled up, default) or"
120 "download boot (pulled down). It should not be used for GPIO");
121 static_assert(pin_number != GPIO_NUM_1, "GPIO1 is UART TXD, used for"
122 "programming, and should not be used for GPIO");
123 static_assert(pin_number != GPIO_NUM_2, "GPIO2 is an important strapping pin"
124 "that must be pulled down during boot to initiate firmware download."
125 "It should not be used for GPIO");
126 static_assert(pin_number != GPIO_NUM_3, "GPIO3 is UART_RXD, used for"
127 "programming, and should not be used for GPIO");
128 static_assert(!(GPIO_NUM_6 <= pin_number && pin_number <= GPIO_NUM_11)
129 && pin_number != GPIO_NUM_16 && pin_number != GPIO_NUM_17,
130 "GPIO6-11, 16, and 17 are used by SPI flash memory and shoult not be"
131 "used for GPIO");
132 static_assert(pin_number != GPIO_NUM_20 && !(GPIO_NUM_28 <= pin_number && pin_number <= GPIO_NUM_32),
133 "GPIO20, and 28-32 likely don't exist, and can't be used for GPIO");
134
135 reset();
136 }
137};
138
141} }
Document the author of an entity, e.g. a component or binding.
Definition sygah-metadata.hpp:39
Document the copyright statement of an entity, e.g. a component or binding.
Definition sygah-metadata.hpp:47
Document a textual description of an entity, e.g. an endpoint, component or binding.
Definition sygah-metadata.hpp:35
Document the name of an entity, e.g. an endpoint, component, or binding.
Definition sygah-metadata.hpp:33
Definition sygse-gpio.hpp:29