Skip to content

Commit

Permalink
light: fix out-of-bounds access when using GPIO16
Browse files Browse the repository at this point in the history
As noticed in the xoseperez#2472

Internal implemementation still lacks the support for the GPIO16,
as it needs to use 'special' IO16 registers (and due to the fact that the 'normal'
registers only fit in an u16[16], from 0 to 15, so internals need to change as well)
One possible way is to attach certain implementation funcs to the
struct handling the isr, avoiding a bunch of in-line checks for `pin == 16`

Another option is to just use Core's `analogWrite`, which hides the
implementation from us and should work pretty seamlessly.
(...but, currently has 2 different waveform generator types, and it is
not really clear which one is a better default, as it needs to be set at
build-time)
  • Loading branch information
mcspr committed Oct 3, 2021
1 parent 6f132ef commit b9db535
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 5 deletions.
5 changes: 5 additions & 0 deletions code/espurna/compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,11 @@ constexpr const T& clamp(const T& value, const T& low, const T& high) {
return (value < low) ? low : (high < value) ? high : value;
}

template <typename T, size_t Size>
constexpr size_t size(const T (&)[Size]) {
return Size;
}

} // namespace std

#endif
Expand Down
14 changes: 9 additions & 5 deletions code/espurna/light.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2906,20 +2906,24 @@ void lightTransition(LightTransition transition) {
namespace {

#if LIGHT_PROVIDER == LIGHT_PROVIDER_DIMMER
const unsigned long _light_iomux[16] PROGMEM = {
const unsigned long _light_iomux[] PROGMEM = {
PERIPHS_IO_MUX_GPIO0_U, PERIPHS_IO_MUX_U0TXD_U, PERIPHS_IO_MUX_GPIO2_U, PERIPHS_IO_MUX_U0RXD_U,
PERIPHS_IO_MUX_GPIO4_U, PERIPHS_IO_MUX_GPIO5_U, PERIPHS_IO_MUX_SD_CLK_U, PERIPHS_IO_MUX_SD_DATA0_U,
PERIPHS_IO_MUX_SD_DATA1_U, PERIPHS_IO_MUX_SD_DATA2_U, PERIPHS_IO_MUX_SD_DATA3_U, PERIPHS_IO_MUX_SD_CMD_U,
PERIPHS_IO_MUX_MTDI_U, PERIPHS_IO_MUX_MTCK_U, PERIPHS_IO_MUX_MTMS_U, PERIPHS_IO_MUX_MTDO_U
};

const unsigned long _light_iofunc[16] PROGMEM = {
const unsigned long _light_iofunc[] PROGMEM = {
FUNC_GPIO0, FUNC_GPIO1, FUNC_GPIO2, FUNC_GPIO3,
FUNC_GPIO4, FUNC_GPIO5, FUNC_GPIO6, FUNC_GPIO7,
FUNC_GPIO8, FUNC_GPIO9, FUNC_GPIO10, FUNC_GPIO11,
FUNC_GPIO12, FUNC_GPIO13, FUNC_GPIO14, FUNC_GPIO15
};

bool _lightIoMuxPin(unsigned char pin) {
return (pin < std::size(_light_iofunc)) && (pin < std::size(_light_iomux));
}

#endif

inline bool _lightUseGamma(size_t channels, size_t index) {
Expand Down Expand Up @@ -3162,14 +3166,14 @@ void lightSetup() {

// Load up until first GPIO_NONE. Allow settings to override, but not remove values
const auto pin = Light::settings::channelPin(index);
if (!gpioValid(pin)) {
if (!gpioValid(pin) || !_lightIoMuxPin(pin)) {
break;
}

_light_channels.emplace_back(pin);

io_info[index][0] = pgm_read_dword(&_light_iomux[pin]);
io_info[index][1] = pgm_read_dword(&_light_iofunc[pin]);
io_info[index][0] = _light_iomux[pin];
io_info[index][1] = _light_iofunc[pin];
io_info[index][2] = pin;
pinMode(pin, OUTPUT);

Expand Down

0 comments on commit b9db535

Please sign in to comment.