16#include "gpio_esp8266.h"
20using namespace _IO_MUX_;
27const uint8_t gpio_esp8266::GPIO_TO_IOMUX[] = { 12,5,13,4,14,15,6,7,8,9,10,11,0,1,2,3 };
29gpio_esp8266::gpio_esp8266(gpio_pin_t gpio)
32 for (
int i = 0; i < 16; ++i) {
34 intMode[i] = _GPIO_::PIN_INT_TYPE__DISABLE;
36 ETS_GPIO_INTR_ATTACH(gpio_irq_handler,
this);
37 ETS_GPIO_INTR_ENABLE();
40void gpio_esp8266::setGpio(gpio_pin_t gpio) {
46gpio_pin_t gpio_esp8266::getGpio()
const {
50void gpio_esp8266::gpioMode(uint16_t mode) {
54 uint8_t mux_idx = GPIO_TO_IOMUX[_gpio];
55 IO_MUX.ENTRY[mux_idx].FUNC = (mux_idx > 11) ? 1 : 4;
58 if (mode & GPIO::INPUT) {
59 IO_MUX.ENTRY[mux_idx].OE = 0;
60 _GPIO_::GPIO.ENABLE_W1TC = _mask;
62 else if (mode & GPIO::OUTPUT) {
63 IO_MUX.ENTRY[mux_idx].OE = 1;
64 _GPIO_::GPIO.ENABLE_W1TS = _mask;
65 _GPIO_::GPIO.PIN[_gpio].DRIVER = _GPIO_::PIN_DRIVER__PUSH_PULL;
67 else if (mode & GPIO::OUTPUT_OPEN_DRAIN) {
68 IO_MUX.ENTRY[mux_idx].OE = 1;
69 _GPIO_::GPIO.ENABLE_W1TS = _mask;
70 _GPIO_::GPIO.PIN[_gpio].DRIVER = _GPIO_::PIN_DRIVER__OPEN_DRAIN;
74 IO_MUX.ENTRY[mux_idx].PULLUP = (mode & GPIO::PULLUP) ? 1 : 0;
75 IO_MUX.ENTRY[mux_idx].PULLDOWN = (mode & GPIO::PULLDOWN) ? 1 : 0;
76 if (mode & GPIO::INIT_HIGH) {
77 _GPIO_::GPIO.OUT_W1TS = _mask;
79 if (mode & GPIO::INIT_LOW) {
80 _GPIO_::GPIO.OUT_W1TC = _mask;
84bool gpio_esp8266::gpioRead()
const {
86 return (_GPIO_::GPIO.IN.DATA & _mask);
89void gpio_esp8266::gpioWrite(
bool value) {
92 _GPIO_::GPIO.OUT_W1TS = _mask;
94 _GPIO_::GPIO.OUT_W1TC = _mask;;
98void gpio_esp8266::gpioToggle() {
100 _GPIO_::GPIO.OUT ^= _mask;
103void gpio_esp8266::gpioAttachIrq(uint16_t irq_mode,
104 function<
void()> handler) {
106 intHandler[_gpio] = handler;
107 int esp_mode = _GPIO_::PIN_INT_TYPE__DISABLE;
111 esp_mode = _GPIO_::PIN_INT_TYPE__RAISING_EDGE;
114 esp_mode = _GPIO_::PIN_INT_TYPE__FALLING_EDGE;
116 case GPIO::RISING | GPIO::FALLING:
117 esp_mode = _GPIO_::PIN_INT_TYPE__BOTH_EDGES;
119 case GPIO::LEVEL_HIGH:
120 esp_mode = _GPIO_::PIN_INT_TYPE__LEVEL_HIGH;
122 case GPIO::LEVEL_LOW:
123 esp_mode = _GPIO_::PIN_INT_TYPE__LEVEL_LOW;
128 intMode[_gpio] = esp_mode;
129 _GPIO_::GPIO.PIN[_gpio].INT_TYPE = esp_mode;
132void gpio_esp8266::gpioDetachIrq() {
135 intMode[_gpio] = _GPIO_::PIN_INT_TYPE__DISABLE;
136 intHandler[_gpio] =
nullptr;
139void gpio_esp8266::gpioEnableIrq() {
142 _GPIO_::GPIO.STATUS_W1TC = (1 << _gpio);
143 _GPIO_::GPIO.PIN[_gpio].INT_TYPE = intMode[_gpio];
146void gpio_esp8266::gpioDisableIrq() {
148 _GPIO_::GPIO.PIN[_gpio].INT_TYPE = _GPIO_::PIN_INT_TYPE__DISABLE;
151void gpio_esp8266::handleInterrupt() {
153 uint16_t status = _GPIO_::GPIO.STATUS;
154 _GPIO_::GPIO.STATUS_W1TC = status;
157 while (uint8_t gpio = __builtin_ffs(status)) {
159 status &= ~(1 << gpio);
160 if (intHandler[gpio])
166 gpio->handleInterrupt();
169void gpio_esp8266::brightnessControl(
bool on) {
172 _GPIO_::GPIO.PIN[_gpio].SOURCE = _GPIO_::PIN_SOURCE__SIGMA_DELTA;
174 _GPIO_::GPIO.PIN[_gpio].SOURCE = _GPIO_::PIN_SOURCE__GPIO;
178void gpio_esp8266::setBrightness(uint8_t value) {
179 _GPIO_::GPIO.SIGMA_DELTA.ENABLE = 1;
180 _GPIO_::GPIO.SIGMA_DELTA.PRESCALE = 0x80;
181 _GPIO_::GPIO.SIGMA_DELTA.TARGET = value;