mirror of
https://github.com/espressif/arduino-esp32
synced 2024-09-21 10:28:04 +00:00
99e68a0518
* fix(rgbled): fixes core rgbledWrite() * fix(rgbled): fixes examples - rgbledWrite() * fix(rgbled): fixes variants commetaries - rgbledWrite() * fix(rgbled): examples and doc - use RGB_LED naming * fix(rgbled): variants - use RGB_LED naming * fix(rgbled): other places for RGB LED naming * fix(typo): cores - rgbLed instead of rgbled * fix(typo): examples - rgbLed instead of rgbled * fix(typo): variants commentaties - rgbLed instead of rgbled * fix(rgbled): bad file name * fix(typo): typo and commentaries Co-authored-by: Lucas Saavedra Vaz <32426024+lucasssvaz@users.noreply.github.com> * fix(rgbled): deprecating neopixelWrite() * fix(rgbled): use RGB LED naming * fix(rgbled): document formatting * fix(rgbled): neopixelWrite() is now deprecated * fix(rgbled): removed attribute in wrong place * just a git push test * restart git bash test * ci(pre-commit): Apply automatic fixes * removed wrong test file * fix(rgbled): new Arduino style depreacted attribute --------- Co-authored-by: Lucas Saavedra Vaz <32426024+lucasssvaz@users.noreply.github.com> Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
282 lines
8.7 KiB
C
282 lines
8.7 KiB
C
// 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.
|
|
|
|
#include "esp32-hal-gpio.h"
|
|
#include "esp32-hal-periman.h"
|
|
#include "hal/gpio_hal.h"
|
|
#include "soc/soc_caps.h"
|
|
|
|
// RGB_BUILTIN is defined in pins_arduino.h
|
|
// If RGB_BUILTIN is defined, it will be used as a pin number for the RGB LED
|
|
// If RGB_BUILTIN has a side effect that prevents using RMT Legacy driver in IDF 5.1
|
|
// Define ESP32_ARDUINO_NO_RGB_BUILTIN in build_opt.h or through CLI to disable RGB_BUILTIN
|
|
#ifdef ESP32_ARDUINO_NO_RGB_BUILTIN
|
|
#ifdef RGB_BUILTIN
|
|
#undef RGB_BUILTIN
|
|
#endif
|
|
#endif
|
|
|
|
// It fixes lack of pin definition for S3 and for any future SoC
|
|
// this function works for ESP32, ESP32-S2 and ESP32-S3 - including the C3, it will return -1 for any pin
|
|
#if SOC_TOUCH_SENSOR_NUM > 0
|
|
#include "soc/touch_sensor_periph.h"
|
|
|
|
int8_t digitalPinToTouchChannel(uint8_t pin) {
|
|
int8_t ret = -1;
|
|
if (pin < SOC_GPIO_PIN_COUNT) {
|
|
for (uint8_t i = 0; i < SOC_TOUCH_SENSOR_NUM; i++) {
|
|
if (touch_sensor_channel_io_map[i] == pin) {
|
|
ret = i;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
#else
|
|
// No Touch Sensor available
|
|
int8_t digitalPinToTouchChannel(uint8_t pin) {
|
|
return -1;
|
|
}
|
|
#endif
|
|
|
|
#ifdef SOC_ADC_SUPPORTED
|
|
#include "soc/adc_periph.h"
|
|
|
|
int8_t digitalPinToAnalogChannel(uint8_t pin) {
|
|
uint8_t channel = 0;
|
|
if (pin < SOC_GPIO_PIN_COUNT) {
|
|
for (uint8_t i = 0; i < SOC_ADC_PERIPH_NUM; i++) {
|
|
for (uint8_t j = 0; j < SOC_ADC_MAX_CHANNEL_NUM; j++) {
|
|
if (adc_channel_io_map[i][j] == pin) {
|
|
return channel;
|
|
}
|
|
channel++;
|
|
}
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
int8_t analogChannelToDigitalPin(uint8_t channel) {
|
|
if (channel >= (SOC_ADC_PERIPH_NUM * SOC_ADC_MAX_CHANNEL_NUM)) {
|
|
return -1;
|
|
}
|
|
uint8_t adc_unit = (channel / SOC_ADC_MAX_CHANNEL_NUM);
|
|
uint8_t adc_chan = (channel % SOC_ADC_MAX_CHANNEL_NUM);
|
|
return adc_channel_io_map[adc_unit][adc_chan];
|
|
}
|
|
#else
|
|
// No Analog channels available
|
|
int8_t analogChannelToDigitalPin(uint8_t channel) {
|
|
return -1;
|
|
}
|
|
#endif
|
|
|
|
typedef void (*voidFuncPtr)(void);
|
|
typedef void (*voidFuncPtrArg)(void *);
|
|
typedef struct {
|
|
voidFuncPtr fn;
|
|
void *arg;
|
|
bool functional;
|
|
} InterruptHandle_t;
|
|
static InterruptHandle_t __pinInterruptHandlers[SOC_GPIO_PIN_COUNT] = {
|
|
0,
|
|
};
|
|
|
|
#include "driver/rtc_io.h"
|
|
|
|
static bool gpioDetachBus(void *bus) {
|
|
return true;
|
|
}
|
|
|
|
extern void ARDUINO_ISR_ATTR __pinMode(uint8_t pin, uint8_t mode) {
|
|
#ifdef RGB_BUILTIN
|
|
if (pin == RGB_BUILTIN) {
|
|
__pinMode(RGB_BUILTIN - SOC_GPIO_PIN_COUNT, mode);
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
if (pin >= SOC_GPIO_PIN_COUNT) {
|
|
log_e("Invalid IO %i selected", pin);
|
|
return;
|
|
}
|
|
|
|
if (perimanGetPinBus(pin, ESP32_BUS_TYPE_GPIO) == NULL) {
|
|
perimanSetBusDeinit(ESP32_BUS_TYPE_GPIO, gpioDetachBus);
|
|
if (!perimanClearPinBus(pin)) {
|
|
log_e("Deinit of previous bus from IO %i failed", pin);
|
|
return;
|
|
}
|
|
}
|
|
|
|
gpio_hal_context_t gpiohal;
|
|
gpiohal.dev = GPIO_LL_GET_HW(GPIO_PORT_0);
|
|
|
|
gpio_config_t conf = {
|
|
.pin_bit_mask = (1ULL << pin), /*!< GPIO pin: set with bit mask, each bit maps to a GPIO */
|
|
.mode = GPIO_MODE_DISABLE, /*!< GPIO mode: set input/output mode */
|
|
.pull_up_en = GPIO_PULLUP_DISABLE, /*!< GPIO pull-up */
|
|
.pull_down_en = GPIO_PULLDOWN_DISABLE, /*!< GPIO pull-down */
|
|
.intr_type = gpiohal.dev->pin[pin].int_type /*!< GPIO interrupt type - previously set */
|
|
};
|
|
if (mode < 0x20) { //io
|
|
conf.mode = mode & (INPUT | OUTPUT);
|
|
if (mode & OPEN_DRAIN) {
|
|
conf.mode |= GPIO_MODE_DEF_OD;
|
|
}
|
|
if (mode & PULLUP) {
|
|
conf.pull_up_en = GPIO_PULLUP_ENABLE;
|
|
}
|
|
if (mode & PULLDOWN) {
|
|
conf.pull_down_en = GPIO_PULLDOWN_ENABLE;
|
|
}
|
|
}
|
|
if (gpio_config(&conf) != ESP_OK) {
|
|
log_e("IO %i config failed", pin);
|
|
return;
|
|
}
|
|
if (perimanGetPinBus(pin, ESP32_BUS_TYPE_GPIO) == NULL) {
|
|
if (!perimanSetPinBus(pin, ESP32_BUS_TYPE_GPIO, (void *)(pin + 1), -1, -1)) {
|
|
//gpioDetachBus((void *)(pin+1));
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
#ifdef RGB_BUILTIN
|
|
uint8_t RGB_BUILTIN_storage = 0;
|
|
#endif
|
|
|
|
extern void ARDUINO_ISR_ATTR __digitalWrite(uint8_t pin, uint8_t val) {
|
|
#ifdef RGB_BUILTIN
|
|
if (pin == RGB_BUILTIN) {
|
|
//use RMT to set all channels on/off
|
|
RGB_BUILTIN_storage = val;
|
|
const uint8_t comm_val = val != 0 ? RGB_BRIGHTNESS : 0;
|
|
rgbLedWrite(RGB_BUILTIN, comm_val, comm_val, comm_val);
|
|
return;
|
|
}
|
|
#endif // RGB_BUILTIN
|
|
if (perimanGetPinBus(pin, ESP32_BUS_TYPE_GPIO) != NULL) {
|
|
gpio_set_level((gpio_num_t)pin, val);
|
|
} else {
|
|
log_e("IO %i is not set as GPIO.", pin);
|
|
}
|
|
}
|
|
|
|
extern int ARDUINO_ISR_ATTR __digitalRead(uint8_t pin) {
|
|
#ifdef RGB_BUILTIN
|
|
if (pin == RGB_BUILTIN) {
|
|
return RGB_BUILTIN_storage;
|
|
}
|
|
#endif
|
|
|
|
if (perimanGetPinBus(pin, ESP32_BUS_TYPE_GPIO) != NULL) {
|
|
return gpio_get_level((gpio_num_t)pin);
|
|
} else {
|
|
log_e("IO %i is not set as GPIO.", pin);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
static void ARDUINO_ISR_ATTR __onPinInterrupt(void *arg) {
|
|
InterruptHandle_t *isr = (InterruptHandle_t *)arg;
|
|
if (isr->fn) {
|
|
if (isr->arg) {
|
|
((voidFuncPtrArg)isr->fn)(isr->arg);
|
|
} else {
|
|
isr->fn();
|
|
}
|
|
}
|
|
}
|
|
|
|
extern void cleanupFunctional(void *arg);
|
|
|
|
extern void __attachInterruptFunctionalArg(uint8_t pin, voidFuncPtrArg userFunc, void *arg, int intr_type, bool functional) {
|
|
static bool interrupt_initialized = false;
|
|
|
|
// makes sure that pin -1 (255) will never work -- this follows Arduino standard
|
|
if (pin >= SOC_GPIO_PIN_COUNT) {
|
|
return;
|
|
}
|
|
|
|
if (!interrupt_initialized) {
|
|
esp_err_t err = gpio_install_isr_service((int)ARDUINO_ISR_FLAG);
|
|
interrupt_initialized = (err == ESP_OK) || (err == ESP_ERR_INVALID_STATE);
|
|
}
|
|
if (!interrupt_initialized) {
|
|
log_e("IO %i ISR Service Failed To Start", pin);
|
|
return;
|
|
}
|
|
|
|
// if new attach without detach remove old info
|
|
if (__pinInterruptHandlers[pin].functional && __pinInterruptHandlers[pin].arg) {
|
|
cleanupFunctional(__pinInterruptHandlers[pin].arg);
|
|
}
|
|
__pinInterruptHandlers[pin].fn = (voidFuncPtr)userFunc;
|
|
__pinInterruptHandlers[pin].arg = arg;
|
|
__pinInterruptHandlers[pin].functional = functional;
|
|
|
|
gpio_set_intr_type((gpio_num_t)pin, (gpio_int_type_t)(intr_type & 0x7));
|
|
if (intr_type & 0x8) {
|
|
gpio_wakeup_enable((gpio_num_t)pin, (gpio_int_type_t)(intr_type & 0x7));
|
|
}
|
|
gpio_isr_handler_add((gpio_num_t)pin, __onPinInterrupt, &__pinInterruptHandlers[pin]);
|
|
|
|
//FIX interrupts on peripherals outputs (eg. LEDC,...)
|
|
//Enable input in GPIO register
|
|
gpio_hal_context_t gpiohal;
|
|
gpiohal.dev = GPIO_LL_GET_HW(GPIO_PORT_0);
|
|
gpio_hal_input_enable(&gpiohal, pin);
|
|
}
|
|
|
|
extern void __attachInterruptArg(uint8_t pin, voidFuncPtrArg userFunc, void *arg, int intr_type) {
|
|
__attachInterruptFunctionalArg(pin, userFunc, arg, intr_type, false);
|
|
}
|
|
|
|
extern void __attachInterrupt(uint8_t pin, voidFuncPtr userFunc, int intr_type) {
|
|
__attachInterruptFunctionalArg(pin, (voidFuncPtrArg)userFunc, NULL, intr_type, false);
|
|
}
|
|
|
|
extern void __detachInterrupt(uint8_t pin) {
|
|
gpio_isr_handler_remove((gpio_num_t)pin); //remove handle and disable isr for pin
|
|
gpio_wakeup_disable((gpio_num_t)pin);
|
|
|
|
if (__pinInterruptHandlers[pin].functional && __pinInterruptHandlers[pin].arg) {
|
|
cleanupFunctional(__pinInterruptHandlers[pin].arg);
|
|
}
|
|
__pinInterruptHandlers[pin].fn = NULL;
|
|
__pinInterruptHandlers[pin].arg = NULL;
|
|
__pinInterruptHandlers[pin].functional = false;
|
|
|
|
gpio_set_intr_type((gpio_num_t)pin, GPIO_INTR_DISABLE);
|
|
}
|
|
|
|
extern void enableInterrupt(uint8_t pin) {
|
|
gpio_intr_enable((gpio_num_t)pin);
|
|
}
|
|
|
|
extern void disableInterrupt(uint8_t pin) {
|
|
gpio_intr_disable((gpio_num_t)pin);
|
|
}
|
|
|
|
extern void pinMode(uint8_t pin, uint8_t mode) __attribute__((weak, alias("__pinMode")));
|
|
extern void digitalWrite(uint8_t pin, uint8_t val) __attribute__((weak, alias("__digitalWrite")));
|
|
extern int digitalRead(uint8_t pin) __attribute__((weak, alias("__digitalRead")));
|
|
extern void attachInterrupt(uint8_t pin, voidFuncPtr handler, int mode) __attribute__((weak, alias("__attachInterrupt")));
|
|
extern void attachInterruptArg(uint8_t pin, voidFuncPtrArg handler, void *arg, int mode) __attribute__((weak, alias("__attachInterruptArg")));
|
|
extern void detachInterrupt(uint8_t pin) __attribute__((weak, alias("__detachInterrupt")));
|