From 8a1e4638f791fe13123945931a4de9eeefd0f4ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Mon, 8 Jan 2024 13:36:56 +0100 Subject: [PATCH] LEDC - Allow custom channel selection (#9031) * feat(ledc): Allow custom channel selection * fix(ledc): Fix check of maximum channel * docs(ledc): Add ledcAttachChannel to docs * feat(ledc): Change channel to uint8_t + add log message --- cores/esp32/esp32-hal-ledc.c | 22 +++++++++++++++++----- cores/esp32/esp32-hal-ledc.h | 1 + docs/source/api/ledc.rst | 20 ++++++++++++++++++++ 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/cores/esp32/esp32-hal-ledc.c b/cores/esp32/esp32-hal-ledc.c index c96d1b0a650..76d522c2313 100644 --- a/cores/esp32/esp32-hal-ledc.c +++ b/cores/esp32/esp32-hal-ledc.c @@ -56,12 +56,11 @@ static bool ledcDetachBus(void * bus){ return true; } -bool ledcAttach(uint8_t pin, uint32_t freq, uint8_t resolution) +bool ledcAttachChannel(uint8_t pin, uint32_t freq, uint8_t resolution, uint8_t channel) { - int free_channel = ~ledc_handle.used_channels & (ledc_handle.used_channels+1); - if (free_channel == 0 || resolution > LEDC_MAX_BIT_WIDTH) + if (channel >= LEDC_CHANNELS || resolution > LEDC_MAX_BIT_WIDTH) { - log_e("No more LEDC channels available! (maximum %u) or bit width too big (maximum %u)", LEDC_CHANNELS, LEDC_MAX_BIT_WIDTH); + log_e("Channel %u is not available! (maximum %u) or bit width too big (maximum %u)", channel, LEDC_CHANNELS, LEDC_MAX_BIT_WIDTH); return false; } @@ -71,7 +70,6 @@ bool ledcAttach(uint8_t pin, uint32_t freq, uint8_t resolution) return false; } - int channel = log2(free_channel & -free_channel); uint8_t group=(channel/8), timer=((channel/2)%4); ledc_timer_config_t ledc_timer = { @@ -115,8 +113,22 @@ bool ledcAttach(uint8_t pin, uint32_t freq, uint8_t resolution) return false; } + log_i("LEDC attached to pin %u (channel %u, resolution %u)", pin, channel, resolution); return true; } + +bool ledcAttach(uint8_t pin, uint32_t freq, uint8_t resolution) +{ + uint8_t free_channel = ~ledc_handle.used_channels & (ledc_handle.used_channels+1); + if (free_channel == 0 || resolution > LEDC_MAX_BIT_WIDTH){ + log_e("No more LEDC channels available! (maximum %u) or bit width too big (maximum %u)", LEDC_CHANNELS, LEDC_MAX_BIT_WIDTH); + return false; + } + int channel = log2(free_channel & -free_channel); + + return ledcAttachChannel(pin, freq, resolution, channel); +} + bool ledcWrite(uint8_t pin, uint32_t duty) { ledc_channel_handle_t *bus = (ledc_channel_handle_t*)perimanGetPinBus(pin, ESP32_BUS_TYPE_LEDC); diff --git a/cores/esp32/esp32-hal-ledc.h b/cores/esp32/esp32-hal-ledc.h index ca172844247..c81da6dced2 100644 --- a/cores/esp32/esp32-hal-ledc.h +++ b/cores/esp32/esp32-hal-ledc.h @@ -45,6 +45,7 @@ typedef struct { //channel 0-15 resolution 1-16bits freq limits depend on resolution bool ledcAttach(uint8_t pin, uint32_t freq, uint8_t resolution); +bool ledcAttachChannel(uint8_t pin, uint32_t freq, uint8_t resolution, uint8_t channel); bool ledcWrite(uint8_t pin, uint32_t duty); uint32_t ledcWriteTone(uint8_t pin, uint32_t freq); uint32_t ledcWriteNote(uint8_t pin, note_t note, uint8_t octave); diff --git a/docs/source/api/ledc.rst b/docs/source/api/ledc.rst index b69f581f5bf..1abeea2f6ee 100644 --- a/docs/source/api/ledc.rst +++ b/docs/source/api/ledc.rst @@ -27,6 +27,7 @@ ledcAttach ********** This function is used to setup LEDC pin with given frequency and resolution. +LEDC channel will be selected automatically. .. code-block:: arduino @@ -41,6 +42,25 @@ This function is used to setup LEDC pin with given frequency and resolution. This function will return ``true`` if configuration is successful. If ``false`` is returned, error occurs and LEDC channel was not configured. +ledcAttachChannel +***************** + +This function is used to setup LEDC pin with given frequency, resolution and channel. + +.. code-block:: arduino + + bool ledcAttachChannel(uint8_t pin, uint32_t freq, uint8_t resolution, uint8_t channel); + +* ``pin`` select LEDC pin. +* ``freq`` select frequency of pwm. +* ``resolution`` select resolution for LEDC channel. +* ``channel`` select LEDC channel. + + * range is 1-14 bits (1-20 bits for ESP32). + +This function will return ``true`` if configuration is successful. +If ``false`` is returned, error occurs and LEDC channel was not configured. + ledcWrite *********