74 lines
2.9 KiB
C
74 lines
2.9 KiB
C
#ifndef VELXIO_COMPAT_H
|
|
#define VELXIO_COMPAT_H
|
|
|
|
// Compatibility shims for sketches written against arduino-esp32 3.x running
|
|
// on the toolchain pinned to 2.0.17. Only kept until we bump the toolchain.
|
|
//
|
|
// arduino-esp32 3.x reshaped the LEDC API around pins:
|
|
// - ledcAttach(pin, freq, res) // auto-allocates a channel
|
|
// - ledcAttachChannel(pin, freq, res, channel)
|
|
// - ledcWrite(pin, duty) // takes pin, looks up channel
|
|
//
|
|
// arduino-esp32 2.x is channel-centric:
|
|
// - ledcSetup(channel, freq, res)
|
|
// - ledcAttachPin(pin, channel)
|
|
// - ledcWrite(channel, duty)
|
|
//
|
|
// We shim the 3.x calls onto the 2.x pair so unmodified 3.x sketches both
|
|
// compile AND drive the LEDC peripheral correctly. A pin-to-channel table
|
|
// keeps `ledcWrite(pin, ...)` working — without that translation
|
|
// `ledcWrite(16, ...)` writes to LEDC channel 16 (invalid; channels are
|
|
// 0-15) and the duty register never changes, so qemu-lcgamboa never emits
|
|
// a duty event and the LED stays dark.
|
|
|
|
#if defined(ARDUINO_ARCH_ESP32) && !defined(ledcAttach)
|
|
#include "Arduino.h"
|
|
|
|
// ESP32 / S2 / S3 / C3 all have <40 usable GPIOs. Sentinel 0xFF = unmapped.
|
|
static uint8_t _velxio_pin_to_channel[40] = {
|
|
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
|
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
|
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
|
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
|
};
|
|
|
|
static inline bool ledcAttach(uint8_t pin, uint32_t freq, uint8_t resolution) {
|
|
static uint8_t _velxio_next_channel = 0;
|
|
if (_velxio_next_channel >= 16) return false;
|
|
uint8_t ch = _velxio_next_channel++;
|
|
ledcSetup(ch, freq, resolution);
|
|
ledcAttachPin(pin, ch);
|
|
if (pin < 40) _velxio_pin_to_channel[pin] = ch;
|
|
return true;
|
|
}
|
|
|
|
static inline bool ledcAttachChannel(uint8_t pin, uint32_t freq, uint8_t resolution, uint8_t channel) {
|
|
if (channel >= 16) return false;
|
|
ledcSetup(channel, freq, resolution);
|
|
ledcAttachPin(pin, channel);
|
|
if (pin < 40) _velxio_pin_to_channel[pin] = channel;
|
|
return true;
|
|
}
|
|
|
|
// 3.x-style ledcWrite(pin, duty). Translate pin→channel via the table if
|
|
// we know about this pin; otherwise fall through to 2.x channel semantics
|
|
// so plain 2.x sketches keep working unchanged.
|
|
static inline void _velxio_ledc_write(uint32_t pin_or_channel, uint32_t duty) {
|
|
if (pin_or_channel < 40) {
|
|
uint8_t ch = _velxio_pin_to_channel[pin_or_channel];
|
|
if (ch != 0xFF) {
|
|
// The extra parentheses around `ledcWrite` block macro expansion
|
|
// (function-like macros only expand when followed by `(`), so
|
|
// this calls the real 2.x ledcWrite from esp32-hal-ledc.h.
|
|
(ledcWrite)((uint8_t)ch, duty);
|
|
return;
|
|
}
|
|
}
|
|
(ledcWrite)((uint8_t)pin_or_channel, duty);
|
|
}
|
|
|
|
#define ledcWrite(pin_or_channel, duty) _velxio_ledc_write((pin_or_channel), (duty))
|
|
#endif
|
|
|
|
#endif // VELXIO_COMPAT_H
|