diff --git a/cores/esp32/Tone.cpp b/cores/esp32/Tone.cpp index cb5a3c6d9d7..77a254cd1d1 100644 --- a/cores/esp32/Tone.cpp +++ b/cores/esp32/Tone.cpp @@ -6,12 +6,11 @@ static TaskHandle_t _tone_task = NULL; static QueueHandle_t _tone_queue = NULL; -static uint8_t _channel = 0; +static int8_t _pin = -1; typedef enum{ TONE_START, - TONE_END, - TONE_SET_CHANNEL + TONE_END } tone_cmd_t; typedef struct{ @@ -19,7 +18,6 @@ typedef struct{ uint8_t pin; unsigned int frequency; unsigned long duration; - uint8_t channel; } tone_msg_t; static void tone_task(void*){ @@ -28,28 +26,28 @@ static void tone_task(void*){ xQueueReceive(_tone_queue, &tone_msg, portMAX_DELAY); switch(tone_msg.tone_cmd){ case TONE_START: - log_d("Task received from queue TONE_START: _pin=%d, frequency=%u Hz, duration=%lu ms", tone_msg.pin, tone_msg.frequency, tone_msg.duration); + log_d("Task received from queue TONE_START: pin=%d, frequency=%u Hz, duration=%lu ms", tone_msg.pin, tone_msg.frequency, tone_msg.duration); - log_d("Setup LED controll on channel %d", _channel); - ledcAttachPin(tone_msg.pin, _channel); - ledcWriteTone(_channel, tone_msg.frequency); + if (_pin == -1) { + if (ledcAttach(tone_msg.pin, tone_msg.frequency, 10) == 0) { + log_e("Tone start failed"); + break; + } + _pin = tone_msg.pin; + } + ledcWriteTone(tone_msg.pin, tone_msg.frequency); if(tone_msg.duration){ delay(tone_msg.duration); - ledcDetachPin(tone_msg.pin); - ledcWriteTone(_channel, 0); + ledcWriteTone(tone_msg.pin, 0); } break; case TONE_END: log_d("Task received from queue TONE_END: pin=%d", tone_msg.pin); - ledcDetachPin(tone_msg.pin); - ledcWriteTone(_channel, 0); - break; - - case TONE_SET_CHANNEL: - log_d("Task received from queue TONE_SET_CHANNEL: channel=%d", tone_msg.channel); - _channel = tone_msg.channel; + ledcWriteTone(tone_msg.pin, 0); + ledcDetach(tone_msg.pin); + _pin = -1; break; default: ; // do nothing @@ -87,49 +85,45 @@ static int tone_init(){ return 1; // OK } -void setToneChannel(uint8_t channel){ - log_d("channel=%d", channel); - if(tone_init()){ - tone_msg_t tone_msg = { - .tone_cmd = TONE_SET_CHANNEL, - .pin = 0, // Ignored - .frequency = 0, // Ignored - .duration = 0, // Ignored - .channel = channel - }; - xQueueSend(_tone_queue, &tone_msg, portMAX_DELAY); - } -} - -void noTone(uint8_t _pin){ +void noTone(uint8_t pin){ log_d("noTone was called"); - if(tone_init()){ - tone_msg_t tone_msg = { - .tone_cmd = TONE_END, - .pin = _pin, - .frequency = 0, // Ignored - .duration = 0, // Ignored - .channel = 0 // Ignored - }; - xQueueSend(_tone_queue, &tone_msg, portMAX_DELAY); + if(_pin == pin) { + if(tone_init()){ + tone_msg_t tone_msg = { + .tone_cmd = TONE_END, + .pin = pin, + .frequency = 0, // Ignored + .duration = 0, // Ignored + }; + xQueueSend(_tone_queue, &tone_msg, portMAX_DELAY); + } + } + else { + log_e("Tone is not running on given pin %d", pin); } } // parameters: -// _pin - pin number which will output the signal +// pin - pin number which will output the signal // frequency - PWM frequency in Hz // duration - time in ms - how long will the signal be outputted. // If not provided, or 0 you must manually call noTone to end output -void tone(uint8_t _pin, unsigned int frequency, unsigned long duration){ - log_d("_pin=%d, frequency=%u Hz, duration=%lu ms", _pin, frequency, duration); - if(tone_init()){ - tone_msg_t tone_msg = { - .tone_cmd = TONE_START, - .pin = _pin, - .frequency = frequency, - .duration = duration, - .channel = 0 // Ignored - }; - xQueueSend(_tone_queue, &tone_msg, portMAX_DELAY); +void tone(uint8_t pin, unsigned int frequency, unsigned long duration){ + log_d("pin=%d, frequency=%u Hz, duration=%lu ms", pin, frequency, duration); + if(_pin == -1 || _pin == pin) { + if(tone_init()){ + tone_msg_t tone_msg = { + .tone_cmd = TONE_START, + .pin = pin, + .frequency = frequency, + .duration = duration, + }; + xQueueSend(_tone_queue, &tone_msg, portMAX_DELAY); + return; + } + } + else { + log_e("Tone is still running on pin %d, call noTone(%d) first!", _pin, _pin); + return; } } diff --git a/cores/esp32/esp32-hal-ledc.c b/cores/esp32/esp32-hal-ledc.c index 75f90294f86..5bee6deba4c 100644 --- a/cores/esp32/esp32-hal-ledc.c +++ b/cores/esp32/esp32-hal-ledc.c @@ -15,6 +15,7 @@ #include "esp32-hal.h" #include "soc/soc_caps.h" #include "driver/ledc.h" +#include "esp32-hal-periman.h" #ifdef SOC_LEDC_SUPPORT_HS_MODE #define LEDC_CHANNELS (SOC_LEDC_CHANNEL_NUM<<1) @@ -32,6 +33,10 @@ #define LEDC_MAX_BIT_WIDTH SOC_LEDC_TIMER_BIT_WIDTH +typedef struct { + int used_channels : LEDC_CHANNELS; // Used channels as a bits +} ledc_periph_t; + /* * LEDC Chan to Group/Channel/Timer Mapping ** ledc: 0 => Group: 0, Channel: 0, Timer: 0 @@ -52,102 +57,156 @@ ** ledc: 15 => Group: 1, Channel: 7, Timer: 3 */ -uint8_t channels_resolution[LEDC_CHANNELS] = {0}; +ledc_periph_t ledc_handle; + +static bool ledcDetachBus(void * bus){ + ledc_channel_handle_t handle = (ledc_channel_handle_t)bus; + ledc_handle.used_channels &= ~(1UL << handle->channel); + pinMatrixOutDetach(handle->pin, false, false); + return true; +} -uint32_t ledcSetup(uint8_t chan, uint32_t freq, uint8_t bit_num) +bool ledcAttach(uint8_t pin, uint32_t freq, uint8_t resolution) { - if(chan >= LEDC_CHANNELS || bit_num > LEDC_MAX_BIT_WIDTH){ + int 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 0; + return false; + } + + perimanSetBusDeinit(ESP32_BUS_TYPE_LEDC, ledcDetachBus); + ledc_channel_handle_t bus = (ledc_channel_handle_t)perimanGetPinBus(pin, ESP32_BUS_TYPE_LEDC); + if(bus != NULL && !perimanSetPinBus(pin, ESP32_BUS_TYPE_INIT, NULL)){ + return false; } - uint8_t group=(chan/8), timer=((chan/2)%4); + int channel = log2(free_channel & -free_channel); + uint8_t group=(channel/8), timer=((channel/2)%4); ledc_timer_config_t ledc_timer = { .speed_mode = group, .timer_num = timer, - .duty_resolution = bit_num, + .duty_resolution = resolution, .freq_hz = freq, .clk_cfg = LEDC_DEFAULT_CLK }; if(ledc_timer_config(&ledc_timer) != ESP_OK) { log_e("ledc setup failed!"); - return 0; + return false; } - channels_resolution[chan] = bit_num; - return ledc_get_freq(group,timer); -} -void ledcWrite(uint8_t chan, uint32_t duty) -{ - if(chan >= LEDC_CHANNELS){ - return; - } - uint8_t group=(chan/8), channel=(chan%8); + uint32_t duty = ledc_get_duty(group,channel); + + ledc_channel_config_t ledc_channel = { + .speed_mode = group, + .channel = (channel%8), + .timer_sel = timer, + .intr_type = LEDC_INTR_DISABLE, + .gpio_num = pin, + .duty = duty, + .hpoint = 0 + }; + ledc_channel_config(&ledc_channel); + + ledc_channel_handle_t handle = malloc(sizeof(ledc_channel_handle_t)); - //Fixing if all bits in resolution is set = LEDC FULL ON - uint32_t max_duty = (1 << channels_resolution[chan]) - 1; + handle->pin = pin, + handle->channel = channel, + handle->channel_resolution = resolution, - if((duty == max_duty) && (max_duty != 1)){ - duty = max_duty + 1; + ledc_handle.used_channels |= 1UL << channel; + + if(!perimanSetPinBus(pin, ESP32_BUS_TYPE_LEDC, (void *)handle)){ + ledcDetachBus((void *)handle); + return false; } - ledc_set_duty(group, channel, duty); - ledc_update_duty(group, channel); + return true; } - -uint32_t ledcRead(uint8_t chan) +bool ledcWrite(uint8_t pin, uint32_t duty) { - if(chan >= LEDC_CHANNELS){ - return 0; + ledc_channel_handle_t bus = (ledc_channel_handle_t)perimanGetPinBus(pin, ESP32_BUS_TYPE_LEDC); + if(bus != NULL){ + + uint8_t group=(bus->channel/8), channel=(bus->channel%8); + + //Fixing if all bits in resolution is set = LEDC FULL ON + uint32_t max_duty = (1 << bus->channel_resolution) - 1; + + if((duty == max_duty) && (max_duty != 1)){ + duty = max_duty + 1; + } + + ledc_set_duty(group, channel, duty); + ledc_update_duty(group, channel); + + return true; } - uint8_t group=(chan/8), channel=(chan%8); - return ledc_get_duty(group,channel); + return false; } -uint32_t ledcReadFreq(uint8_t chan) +uint32_t ledcRead(uint8_t pin) { - if(!ledcRead(chan)){ - return 0; + ledc_channel_handle_t bus = (ledc_channel_handle_t)perimanGetPinBus(pin, ESP32_BUS_TYPE_LEDC); + if(bus != NULL){ + + uint8_t group=(bus->channel/8), channel=(bus->channel%8); + return ledc_get_duty(group,channel); } - uint8_t group=(chan/8), timer=((chan/2)%4); - return ledc_get_freq(group,timer); + return 0; } -uint32_t ledcWriteTone(uint8_t chan, uint32_t freq) +uint32_t ledcReadFreq(uint8_t pin) { - if(chan >= LEDC_CHANNELS){ - return 0; - } - if(!freq){ - ledcWrite(chan, 0); - return 0; - } + ledc_channel_handle_t bus = (ledc_channel_handle_t)perimanGetPinBus(pin, ESP32_BUS_TYPE_LEDC); + if(bus != NULL){ + if(!ledcRead(pin)){ + return 0; + } + uint8_t group=(bus->channel/8), timer=((bus->channel/2)%4); + return ledc_get_freq(group,timer); + } + return 0; +} - uint8_t group=(chan/8), timer=((chan/2)%4); - ledc_timer_config_t ledc_timer = { - .speed_mode = group, - .timer_num = timer, - .duty_resolution = 10, - .freq_hz = freq, - .clk_cfg = LEDC_DEFAULT_CLK - }; +uint32_t ledcWriteTone(uint8_t pin, uint32_t freq) +{ + ledc_channel_handle_t bus = (ledc_channel_handle_t)perimanGetPinBus(pin, ESP32_BUS_TYPE_LEDC); + if(bus != NULL){ - if(ledc_timer_config(&ledc_timer) != ESP_OK) - { - log_e("ledcSetup failed!"); - return 0; - } - channels_resolution[chan] = 10; + if(!freq){ + ledcWrite(pin, 0); + return 0; + } - uint32_t res_freq = ledc_get_freq(group,timer); - ledcWrite(chan, 0x1FF); - return res_freq; + uint8_t group=(bus->channel/8), timer=((bus->channel/2)%4); + + ledc_timer_config_t ledc_timer = { + .speed_mode = group, + .timer_num = timer, + .duty_resolution = 10, + .freq_hz = freq, + .clk_cfg = LEDC_DEFAULT_CLK + }; + + if(ledc_timer_config(&ledc_timer) != ESP_OK) + { + log_e("ledcWriteTone configuration failed!"); + return 0; + } + bus->channel_resolution = 10; + + uint32_t res_freq = ledc_get_freq(group,timer); + ledcWrite(pin, 0x1FF); + return res_freq; + } + return 0; } -uint32_t ledcWriteNote(uint8_t chan, note_t note, uint8_t octave){ +uint32_t ledcWriteNote(uint8_t pin, note_t note, uint8_t octave){ const uint16_t noteFrequencyBase[12] = { // C C# D Eb E F F# G G# A Bb B 4186, 4435, 4699, 4978, 5274, 5588, 5920, 6272, 6645, 7040, 7459, 7902 @@ -157,116 +216,79 @@ uint32_t ledcWriteNote(uint8_t chan, note_t note, uint8_t octave){ return 0; } uint32_t noteFreq = (uint32_t)noteFrequencyBase[note] / (uint32_t)(1 << (8-octave)); - return ledcWriteTone(chan, noteFreq); + return ledcWriteTone(pin, noteFreq); } -void ledcAttachPin(uint8_t pin, uint8_t chan) +bool ledcDetach(uint8_t pin) { - if(chan >= LEDC_CHANNELS){ - return; + ledc_channel_handle_t bus = (ledc_channel_handle_t)perimanGetPinBus(pin, ESP32_BUS_TYPE_LEDC); + if(bus != NULL){ + // will call ledcDetachBus + return perimanSetPinBus(pin, ESP32_BUS_TYPE_INIT, NULL); + } else { + log_e("pin %u is not attached to LEDC", pin); } - uint8_t group=(chan/8), channel=(chan%8), timer=((chan/2)%4); - uint32_t duty = ledc_get_duty(group,channel); - - ledc_channel_config_t ledc_channel = { - .speed_mode = group, - .channel = channel, - .timer_sel = timer, - .intr_type = LEDC_INTR_DISABLE, - .gpio_num = pin, - .duty = duty, - .hpoint = 0 - }; - ledc_channel_config(&ledc_channel); + return false; } -void ledcDetachPin(uint8_t pin) +uint32_t ledcChangeFrequency(uint8_t pin, uint32_t freq, uint8_t resolution) { - pinMatrixOutDetach(pin, false, false); -} + ledc_channel_handle_t bus = (ledc_channel_handle_t)perimanGetPinBus(pin, ESP32_BUS_TYPE_LEDC); + if(bus != NULL){ -uint32_t ledcChangeFrequency(uint8_t chan, uint32_t freq, uint8_t bit_num) -{ - if(chan >= LEDC_CHANNELS || bit_num > LEDC_MAX_BIT_WIDTH){ - log_e("LEDC channel not available! (maximum %u) or bit width too big (maximum %u)", LEDC_CHANNELS, LEDC_MAX_BIT_WIDTH); - return 0; - } - uint8_t group=(chan/8), timer=((chan/2)%4); - - ledc_timer_config_t ledc_timer = { - .speed_mode = group, - .timer_num = timer, - .duty_resolution = bit_num, - .freq_hz = freq, - .clk_cfg = LEDC_DEFAULT_CLK - }; - - if(ledc_timer_config(&ledc_timer) != ESP_OK) - { - log_e("ledcChangeFrequency failed!"); - return 0; + if(resolution > LEDC_MAX_BIT_WIDTH){ + log_e("LEDC resolution too big (maximum %u)", LEDC_MAX_BIT_WIDTH); + return 0; + } + uint8_t group=(bus->channel/8), timer=((bus->channel/2)%4); + + ledc_timer_config_t ledc_timer = { + .speed_mode = group, + .timer_num = timer, + .duty_resolution = resolution, + .freq_hz = freq, + .clk_cfg = LEDC_DEFAULT_CLK + }; + + if(ledc_timer_config(&ledc_timer) != ESP_OK) + { + log_e("ledcChangeFrequency failed!"); + return 0; + } + bus->channel_resolution = resolution; + return ledc_get_freq(group,timer); } - channels_resolution[chan] = bit_num; - return ledc_get_freq(group,timer); + return 0; } -static int8_t pin_to_channel[SOC_GPIO_PIN_COUNT] = { 0 }; -static int cnt_channel = LEDC_CHANNELS; static uint8_t analog_resolution = 8; static int analog_frequency = 1000; void analogWrite(uint8_t pin, int value) { - // Use ledc hardware for internal pins - if (pin < SOC_GPIO_PIN_COUNT) { - int8_t channel = -1; - if (pin_to_channel[pin] == 0) { - if (!cnt_channel) { - log_e("No more analogWrite channels available! You can have maximum %u", LEDC_CHANNELS); - return; - } - cnt_channel--; - channel = cnt_channel; - } else { - channel = analogGetChannel(pin); - } - log_v("GPIO %d - Using Channel %d, Value = %d", pin, channel, value); - if(ledcSetup(channel, analog_frequency, analog_resolution) == 0){ + // Use ledc hardware for internal pins + if (pin < SOC_GPIO_PIN_COUNT) { + ledc_channel_handle_t bus = (ledc_channel_handle_t)perimanGetPinBus(pin, ESP32_BUS_TYPE_LEDC); + if(bus == NULL && perimanSetPinBus(pin, ESP32_BUS_TYPE_INIT, NULL)){ + if(ledcAttach(pin, analog_frequency, analog_resolution) == 0){ log_e("analogWrite setup failed (freq = %u, resolution = %u). Try setting different resolution or frequency"); return; } - ledcAttachPin(pin, channel); - pin_to_channel[pin] = channel; - ledcWrite(channel, value); } + ledcWrite(pin, value); + } } -int8_t analogGetChannel(uint8_t pin) { - return pin_to_channel[pin]; -} - -void analogWriteFrequency(uint32_t freq) { - if (cnt_channel != LEDC_CHANNELS) { - for (int channel = LEDC_CHANNELS - 1; channel >= cnt_channel; channel--) { - if (ledcChangeFrequency(channel, freq, analog_resolution) == 0){ - log_e("analogWrite frequency cant be set due to selected resolution! Try to adjust resolution first"); - return; - } - } +void analogWriteFrequency(uint8_t pin, uint32_t freq) { + if (ledcChangeFrequency(pin, freq, analog_resolution) == 0){ + log_e("analogWrite frequency cant be set due to selected resolution! Try to adjust resolution first"); + return; } analog_frequency = freq; } -void analogWriteResolution(uint8_t bits) { - if(bits > LEDC_MAX_BIT_WIDTH) { - log_w("analogWrite resolution width too big! Setting to maximum %u bits)", LEDC_MAX_BIT_WIDTH); - bits = LEDC_MAX_BIT_WIDTH; - } - if (cnt_channel != LEDC_CHANNELS) { - for (int channel = LEDC_CHANNELS - 1; channel >= cnt_channel; channel--) { - if (ledcChangeFrequency(channel, analog_frequency, bits) == 0){ - log_e("analogWrite resolution cant be set due to selected frequency! Try to adjust frequency first"); - return; - } - } +void analogWriteResolution(uint8_t pin, uint8_t resolution) { + if (ledcChangeFrequency(pin, analog_frequency, resolution) == 0){ + log_e("analogWrite resolution cant be set due to selected frequency! Try to adjust frequency first"); + return; } - analog_resolution = bits; + analog_resolution = resolution; } diff --git a/cores/esp32/esp32-hal-ledc.h b/cores/esp32/esp32-hal-ledc.h index 4b8bc7d712a..18142659587 100644 --- a/cores/esp32/esp32-hal-ledc.h +++ b/cores/esp32/esp32-hal-ledc.h @@ -26,16 +26,21 @@ typedef enum { NOTE_C, NOTE_Cs, NOTE_D, NOTE_Eb, NOTE_E, NOTE_F, NOTE_Fs, NOTE_G, NOTE_Gs, NOTE_A, NOTE_Bb, NOTE_B, NOTE_MAX } note_t; +typedef struct { + uint8_t pin; // Pin assigned to channel + uint8_t channel; // Channel number + uint8_t channel_resolution; // Resolution of channel +} *ledc_channel_handle_t; + //channel 0-15 resolution 1-16bits freq limits depend on resolution -uint32_t ledcSetup(uint8_t channel, uint32_t freq, uint8_t resolution_bits); -void ledcWrite(uint8_t channel, uint32_t duty); -uint32_t ledcWriteTone(uint8_t channel, uint32_t freq); -uint32_t ledcWriteNote(uint8_t channel, note_t note, uint8_t octave); -uint32_t ledcRead(uint8_t channel); -uint32_t ledcReadFreq(uint8_t channel); -void ledcAttachPin(uint8_t pin, uint8_t channel); -void ledcDetachPin(uint8_t pin); -uint32_t ledcChangeFrequency(uint8_t channel, uint32_t freq, uint8_t resolution_bits); +bool ledcAttach(uint8_t pin, uint32_t freq, uint8_t resolution); +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); +uint32_t ledcRead(uint8_t pin); +uint32_t ledcReadFreq(uint8_t pin); +bool ledcDetach(uint8_t pin); +uint32_t ledcChangeFrequency(uint8_t pin, uint32_t freq, uint8_t resolution); #ifdef __cplusplus diff --git a/cores/esp32/esp32-hal.h b/cores/esp32/esp32-hal.h index e6dc0277935..f71788e9399 100644 --- a/cores/esp32/esp32-hal.h +++ b/cores/esp32/esp32-hal.h @@ -88,9 +88,8 @@ void yield(void); #include "esp32-hal-cpu.h" void analogWrite(uint8_t pin, int value); -int8_t analogGetChannel(uint8_t pin); -void analogWriteFrequency(uint32_t freq); -void analogWriteResolution(uint8_t bits); +void analogWriteFrequency(uint8_t pin, uint32_t freq); +void analogWriteResolution(uint8_t pin, uint8_t bits); //returns chip temperature in Celsius float temperatureRead(); diff --git a/docs/source/api/ledc.rst b/docs/source/api/ledc.rst index d3ee885a474..1f81c03a5ef 100644 --- a/docs/source/api/ledc.rst +++ b/docs/source/api/ledc.rst @@ -21,48 +21,48 @@ ESP32-S3 8 Arduino-ESP32 LEDC API ---------------------- -ledcSetup -********* +ledcAttach +********** -This function is used to setup the LEDC channel frequency and resolution. +This function is used to setup LEDC pin with given frequency and resolution. .. code-block:: arduino - uint32_t ledcSetup(uint8_t channel, uint32_t freq, uint8_t resolution_bits); + bool ledcAttach(uint8_t pin, uint32_t freq, uint8_t resolution); -* ``channel`` select LEDC channel to config. +* ``pin`` select LEDC pin. * ``freq`` select frequency of pwm. -* ``resolution_bits`` select resolution for ledc channel. +* ``resolution`` select resolution for LEDC channel. * range is 1-14 bits (1-20 bits for ESP32). -This function will return ``frequency`` configured for LEDC channel. -If ``0`` is returned, error occurs and ledc channel was not configured. +This function will return ``true`` if configuration is successful. +If ``false`` is returned, error occurs and LEDC channel was not configured. ledcWrite ********* -This function is used to set duty for the LEDC channel. +This function is used to set duty for the LEDC pin. .. code-block:: arduino - void ledcWrite(uint8_t chan, uint32_t duty); + void ledcWrite(uint8_t pin, uint32_t duty); -* ``chan`` select the LEDC channel for writing duty. -* ``duty`` select duty to be set for selected channel. +* ``pin`` select LEDC pin. +* ``duty`` select duty to be set for selected LEDC pin. ledcRead ******** -This function is used to get configured duty for the LEDC channel. +This function is used to get configured duty for the LEDC pin. .. code-block:: arduino - uint32_t ledcRead(uint8_t chan); + uint32_t ledcRead(uint8_t pin); -* ``chan`` select LEDC channel to read the configured duty. +* ``pin`` select LEDC pin to read the configured LEDC duty. -This function will return ``duty`` set for selected LEDC channel. +This function will return ``duty`` set for selected LEDC pin. ledcReadFreq ************ @@ -71,37 +71,37 @@ This function is used to get configured frequency for the LEDC channel. .. code-block:: arduino - uint32_t ledcReadFreq(uint8_t chan); + uint32_t ledcReadFreq(uint8_t pin); -* ``chan`` select the LEDC channel to read the configured frequency. +* ``pin`` select LEDC pin to read the configured frequency. -This function will return ``frequency`` configured for selected LEDC channel. +This function will return ``frequency`` configured for selected LEDC pin. ledcWriteTone ************* -This function is used to setup the LEDC channel to 50 % PWM tone on selected frequency. +This function is used to setup the LEDC pin to 50 % PWM tone on selected frequency. .. code-block:: arduino - uint32_t ledcWriteTone(uint8_t chan, uint32_t freq); + uint32_t ledcWriteTone(uint8_t pin, uint32_t freq); -* ``chan`` select LEDC channel. -* ``freq`` select frequency of pwm signal. +* ``pin`` select LEDC pin. +* ``freq`` select frequency of pwm signal. If frequency is ``0``, duty will be set to 0. -This function will return ``frequency`` set for channel. -If ``0`` is returned, error occurs and ledc cahnnel was not configured. +This function will return ``frequency`` set for LEDC pin. +If ``0`` is returned, error occurs and LEDC pin was not configured. ledcWriteNote ************* -This function is used to setup the LEDC channel to specific note. +This function is used to setup the LEDC pin to specific note. .. code-block:: arduino - uint32_t ledcWriteNote(uint8_t chan, note_t note, uint8_t octave); + uint32_t ledcWriteNote(uint8_t pin, note_t note, uint8_t octave); -* ``chan`` select LEDC channel. +* ``pin`` select LEDC pin. * ``note`` select note to be set. ======= ======= ======= ======= ======= ====== @@ -111,44 +111,32 @@ NOTE_Fs NOTE_G NOTE_Gs NOTE_A NOTE_Bb NOTE_B * ``octave`` select octave for note. -This function will return ``frequency`` configured for the LEDC channel according to note and octave inputs. +This function will return ``frequency`` configured for the LEDC pin according to note and octave inputs. If ``0`` is returned, error occurs and the LEDC channel was not configured. - -ledcAttachPin -************* - -This function is used to attach the pin to the LEDC channel. - -.. code-block:: arduino - void ledcAttachPin(uint8_t pin, uint8_t chan); - -* ``pin`` select GPIO pin. -* ``chan`` select LEDC channel. - -ledcDetachPin -************* +ledcDetach +********** This function is used to detach the pin from LEDC. .. code-block:: arduino - void ledcDetachPin(uint8_t pin); + void ledcDetach(uint8_t pin); -* ``pin`` select GPIO pin. +* ``pin`` select LEDC pin. ledcChangeFrequency ******************* -This function is used to set frequency for the LEDC channel. +This function is used to set frequency for the LEDC pin. .. code-block:: arduino - uint32_t ledcChangeFrequency(uint8_t chan, uint32_t freq, uint8_t bit_num); + uint32_t ledcChangeFrequency(uint8_t pin, uint32_t freq, uint8_t resolution); -* ``channel`` select LEDC channel. +* ``pin`` select LEDC pin. * ``freq`` select frequency of pwm. -* ``bit_num`` select resolution for LEDC channel. +* ``resolution`` select resolution for LEDC channel. * range is 1-14 bits (1-20 bits for ESP32). @@ -172,23 +160,25 @@ It is compatible with Arduinos analogWrite function. analogWriteResolution ********************* -This function is used to set resolution for all analogWrite channels. +This function is used to set resolution for selected analogWrite pin. .. code-block:: arduino - void analogWriteResolution(uint8_t bits); + void analogWriteResolution(uint8_t pin, uint8_t resolution); -* ``bits`` select resolution for analog channels. +* ``pin`` select the GPIO pin. +* ``resolution`` select resolution for analog channel. analogWriteFrequency ******************** -This function is used to set frequency for all analogWrite channels. +This function is used to set frequency for selected analogWrite pin. .. code-block:: arduino - void analogWriteFrequency(uint32_t freq); + void analogWriteFrequency(uint8_t pin, uint32_t freq); +* ``pin`` select the GPIO pin. * ``freq`` select frequency of pwm. Example Applications diff --git a/libraries/ESP32/examples/AnalogOut/LEDCSoftwareFade/LEDCSoftwareFade.ino b/libraries/ESP32/examples/AnalogOut/LEDCSoftwareFade/LEDCSoftwareFade.ino index c8b3e139396..239e37f3615 100644 --- a/libraries/ESP32/examples/AnalogOut/LEDCSoftwareFade/LEDCSoftwareFade.ino +++ b/libraries/ESP32/examples/AnalogOut/LEDCSoftwareFade/LEDCSoftwareFade.ino @@ -10,9 +10,6 @@ This example code is in the public domain. */ -// use first channel of 16 channels (started from zero) -#define LEDC_CHANNEL_0 0 - // use 12 bit precission for LEDC timer #define LEDC_TIMER_12_BIT 12 @@ -27,23 +24,22 @@ int fadeAmount = 5; // how many points to fade the LED by // Arduino like analogWrite // value has to be between 0 and valueMax -void ledcAnalogWrite(uint8_t channel, uint32_t value, uint32_t valueMax = 255) { +void ledcAnalogWrite(uint8_t pin, uint32_t value, uint32_t valueMax = 255) { // calculate duty, 4095 from 2 ^ 12 - 1 uint32_t duty = (4095 / valueMax) * min(value, valueMax); // write duty to LEDC - ledcWrite(channel, duty); + ledcWrite(pin, duty); } void setup() { // Setup timer and attach timer to a led pin - ledcSetup(LEDC_CHANNEL_0, LEDC_BASE_FREQ, LEDC_TIMER_12_BIT); - ledcAttachPin(LED_PIN, LEDC_CHANNEL_0); + ledcAttach(LED_PIN, LEDC_BASE_FREQ, LEDC_TIMER_12_BIT); } void loop() { // set the brightness on LEDC channel 0 - ledcAnalogWrite(LEDC_CHANNEL_0, brightness); + ledcAnalogWrite(LED_PIN, brightness); // change the brightness for next time through the loop: brightness = brightness + fadeAmount; @@ -54,4 +50,4 @@ void loop() { } // wait for 30 milliseconds to see the dimming effect delay(30); -} +} \ No newline at end of file diff --git a/libraries/ESP32/examples/AnalogOut/ledcFrequency/ledcFrequency.ino b/libraries/ESP32/examples/AnalogOut/ledcFrequency/ledcFrequency.ino index 8edd9712290..772e5da7e39 100644 --- a/libraries/ESP32/examples/AnalogOut/ledcFrequency/ledcFrequency.ino +++ b/libraries/ESP32/examples/AnalogOut/ledcFrequency/ledcFrequency.ino @@ -14,7 +14,7 @@ #define PIN 2 void setup() { - analogWrite(PIN,128); + ledcAttach(PIN,1000,8); uint32_t min_frequency; uint32_t max_frequency; @@ -31,7 +31,7 @@ void setup() { successful_frequency = 0; while(min_frequency != max_frequency && min_frequency+1 != max_frequency){ frequency = min_frequency + ((max_frequency-min_frequency)/2); - if(ledcChangeFrequency(analogGetChannel(PIN), frequency, resolution)){ + if(ledcChangeFrequency(PIN, frequency, resolution)){ min_frequency = frequency; successful_frequency = frequency; }else{ @@ -49,7 +49,7 @@ void setup() { successful_frequency = max_frequency; while(min_frequency != max_frequency && min_frequency+1 != max_frequency){ frequency = min_frequency + ((max_frequency-min_frequency)/2); - if(ledcChangeFrequency(analogGetChannel(PIN), frequency, resolution)){ + if(ledcChangeFrequency(PIN, frequency, resolution)){ max_frequency = frequency; successful_frequency = frequency; }else{ @@ -69,6 +69,8 @@ void setup() { std::string (max_len - std::to_string(max_freq_array[r-1]).length(), ' ').c_str(), max_freq_array[r-1]); } + + ledcDetach(PIN); } void loop() diff --git a/libraries/ESP32/examples/AnalogOut/ledcWrite_RGB/ledcWrite_RGB.ino b/libraries/ESP32/examples/AnalogOut/ledcWrite_RGB/ledcWrite_RGB.ino index c2697bc9c15..1104a6b4c63 100644 --- a/libraries/ESP32/examples/AnalogOut/ledcWrite_RGB/ledcWrite_RGB.ino +++ b/libraries/ESP32/examples/AnalogOut/ledcWrite_RGB/ledcWrite_RGB.ino @@ -9,11 +9,9 @@ */ // Set up the rgb led names -uint8_t ledR = 2; -uint8_t ledG = 4; -uint8_t ledB = 5; - -uint8_t ledArray[3] = {1, 2, 3}; // three led channels +uint8_t ledR = 0; +uint8_t ledG = 2; +uint8_t ledB = 4; const boolean invert = true; // set true if common anode, false if common cathode @@ -27,16 +25,11 @@ void setup() Serial.begin(115200); delay(10); - ledcAttachPin(ledR, 1); // assign RGB led pins to channels - ledcAttachPin(ledG, 2); - ledcAttachPin(ledB, 3); - - // Initialize channels - // channels 0-15, resolution 1-16 bits, freq limits depend on resolution - // ledcSetup(uint8_t channel, uint32_t freq, uint8_t resolution_bits); - ledcSetup(1, 12000, 8); // 12 kHz PWM, 8-bit resolution - ledcSetup(2, 12000, 8); - ledcSetup(3, 12000, 8); + // Initialize pins as LEDC channels + // resolution 1-16 bits, freq limits depend on resolution + ledcAttach(ledR, 12000, 8); // 12 kHz PWM, 8-bit resolution + ledcAttach(ledG, 12000, 8); + ledcAttach(ledB, 12000, 8); } // void loop runs over and over again @@ -45,14 +38,14 @@ void loop() Serial.println("Send all LEDs a 255 and wait 2 seconds."); // If your RGB LED turns off instead of on here you should check if the LED is common anode or cathode. // If it doesn't fully turn off and is common anode try using 256. - ledcWrite(1, 255); - ledcWrite(2, 255); - ledcWrite(3, 255); + ledcWrite(ledR, 255); + ledcWrite(ledG, 255); + ledcWrite(ledB, 255); delay(2000); Serial.println("Send all LEDs a 0 and wait 2 seconds."); - ledcWrite(1, 0); - ledcWrite(2, 0); - ledcWrite(3, 0); + ledcWrite(ledR, 0); + ledcWrite(ledG, 0); + ledcWrite(ledB, 0); delay(2000); Serial.println("Starting color fade loop."); @@ -62,9 +55,9 @@ void loop() hueToRGB(color, brightness); // call function to convert hue to RGB // write the RGB values to the pins - ledcWrite(1, R); // write red component to channel 1, etc. - ledcWrite(2, G); - ledcWrite(3, B); + ledcWrite(ledR, R); // write red component to channel 1, etc. + ledcWrite(ledG, G); + ledcWrite(ledB, B); delay(100); // full cycle of rgb over 256 colors takes 26 seconds } diff --git a/libraries/ESP32/examples/Camera/CameraWebServer/app_httpd.cpp b/libraries/ESP32/examples/Camera/CameraWebServer/app_httpd.cpp index af0fd7a856c..ff02152d101 100644 --- a/libraries/ESP32/examples/Camera/CameraWebServer/app_httpd.cpp +++ b/libraries/ESP32/examples/Camera/CameraWebServer/app_httpd.cpp @@ -78,7 +78,7 @@ // LED FLASH setup #if CONFIG_LED_ILLUMINATOR_ENABLED -#define LED_LEDC_CHANNEL 2 //Using different ledc channel/timer than camera +#define LED_LEDC_GPIO 22 //configure LED pin #define CONFIG_LED_MAX_INTENSITY 255 int led_duty = 0; @@ -290,7 +290,7 @@ void enable_led(bool en) { duty = CONFIG_LED_MAX_INTENSITY; } - ledcWrite(LED_LEDC_CHANNEL, duty); + ledcWrite(LED_LEDC_GPIO, duty); //ledc_set_duty(CONFIG_LED_LEDC_SPEED_MODE, CONFIG_LED_LEDC_CHANNEL, duty); //ledc_update_duty(CONFIG_LED_LEDC_SPEED_MODE, CONFIG_LED_LEDC_CHANNEL); log_i("Set LED intensity to %d", duty); @@ -1390,8 +1390,7 @@ void startCameraServer() void setupLedFlash(int pin) { #if CONFIG_LED_ILLUMINATOR_ENABLED - ledcSetup(LED_LEDC_CHANNEL, 5000, 8); - ledcAttachPin(pin, LED_LEDC_CHANNEL); + ledcAttach(pin, 5000, 8); #else log_i("LED flash is disabled -> CONFIG_LED_ILLUMINATOR_ENABLED = 0"); #endif diff --git a/libraries/ESP32/examples/I2S/HiFreq_ADC/HiFreq_ADC.ino b/libraries/ESP32/examples/I2S/HiFreq_ADC/HiFreq_ADC.ino index db94960f205..a1f5c3088c3 100644 --- a/libraries/ESP32/examples/I2S/HiFreq_ADC/HiFreq_ADC.ino +++ b/libraries/ESP32/examples/I2S/HiFreq_ADC/HiFreq_ADC.ino @@ -82,13 +82,14 @@ void setup() { #ifdef GENERATE_PWM // PWM setup Serial.printf("Setting up PWM: frequency = %d; resolution bits %d; Duty cycle = %d; duty value = %d, Output pin = %d\n", PWM_FREQUENCY, PWM_RESOLUTION_BITS, PWM_DUTY_PERCENT, PWM_DUTY_VALUE, OUTPUT_PIN); - uint32_t freq = ledcSetup(0, PWM_FREQUENCY, PWM_RESOLUTION_BITS); + ledcAttach(OUTPUT_PIN, PWM_FREQUENCY, PWM_RESOLUTION_BITS); + uint32_t freq = ledcReadFreq(OUTPUT_PIN); + if(freq != PWM_FREQUENCY){ Serial.printf("Error setting up PWM. Halt!"); while(1); } - ledcAttachPin(OUTPUT_PIN, 0); - ledcWrite(0, PWM_DUTY_VALUE); + ledcWrite(OUTPUT_PIN, PWM_DUTY_VALUE); Serial.printf("PWM setup ok\n"); #endif