Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ledc): max resolution review #11226

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from
Draft
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 33 additions & 21 deletions cores/esp32/esp32-hal-ledc.c
Original file line number Diff line number Diff line change
Expand Up @@ -183,14 +183,13 @@ bool ledcWrite(uint8_t pin, uint32_t duty) {
if (bus != NULL) {

uint8_t group = (bus->channel / 8), channel = (bus->channel % 8);
uint32_t max_duty = (1 << bus->channel_resolution); // Max LEDC duty

//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;
if (duty > max_duty) {
log_w("Target duty %d was adjusted to the maximum duty %d", duty, max_duty);
duty = max_duty;
}

ledc_set_duty(group, channel, duty);
ledc_update_duty(group, channel);

Expand All @@ -210,13 +209,12 @@ bool ledcWriteChannel(uint8_t channel, uint32_t duty) {
//Fixing if all bits in resolution is set = LEDC FULL ON
uint32_t resolution = 0;
ledc_ll_get_duty_resolution(LEDC_LL_GET_HW(), group, timer, &resolution);
uint32_t max_duty = (1 << resolution); // Max LEDC duty

uint32_t max_duty = (1 << resolution) - 1;

if ((duty == max_duty) && (max_duty != 1)) {
duty = max_duty + 1;
if (duty > max_duty) {
log_w("Target duty %d was adjusted to the maximum duty %d", duty, max_duty);
duty = max_duty;
}

ledc_set_duty(group, channel, duty);
ledc_update_duty(group, channel);

Expand Down Expand Up @@ -265,15 +263,16 @@ uint32_t ledcWriteTone(uint8_t pin, uint32_t freq) {
bus->channel_resolution = 10;

uint32_t res_freq = ledc_get_freq(group, timer);
ledcWrite(pin, 0x1FF);
ledcWrite(pin, 0x200); // LEDC 50% duty is 2^10 / 2 = 0x200
return res_freq;
}
return 0;
}

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
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
};

if (octave > 8 || note >= NOTE_MAX) {
Expand Down Expand Up @@ -391,13 +390,15 @@ static bool ledcFadeConfig(uint8_t pin, uint32_t start_duty, uint32_t target_dut
ledc_cbs_t callbacks = {.fade_cb = ledcFnWrapper};
ledc_cb_register(group, channel, &callbacks, (void *)bus);

//Fixing if all bits in resolution is set = LEDC FULL ON
uint32_t max_duty = (1 << bus->channel_resolution) - 1;
uint32_t max_duty = (1 << bus->channel_resolution); // Max LEDC duty

if ((target_duty == max_duty) && (max_duty != 1)) {
target_duty = max_duty + 1;
} else if ((start_duty == max_duty) && (max_duty != 1)) {
start_duty = max_duty + 1;
if (target_duty > max_duty) {
log_w("Target duty %d was adjusted to the maximum duty %d", target_duty, max_duty);
target_duty = max_duty;
}
if (start_duty > max_duty) {
log_w("Starting duty %d was adjusted to the maximum duty %d", start_duty, max_duty);
start_duty = max_duty;
}

#if SOC_LEDC_SUPPORT_FADE_STOP
Expand All @@ -411,7 +412,7 @@ static bool ledcFadeConfig(uint8_t pin, uint32_t start_duty, uint32_t target_dut
// Wait for LEDCs next PWM cycle to update duty (~ 1-2 ms)
while (ledc_get_duty(group, channel) != start_duty);

if (ledc_set_fade_time_and_start(group, channel, target_duty, max_fade_time_ms, LEDC_FADE_NO_WAIT) != ESP_OK) {
if (ledc_set_fade_time_and_start(group, channel, target_duty, _fade_time_ms, LEDC_FADE_NO_WAIT) != ESP_OK) {
log_e("ledc_set_fade_time_and_start failed");
return false;
}
Expand Down Expand Up @@ -446,6 +447,17 @@ void analogWrite(uint8_t pin, int value) {
return;
}
}
// Arduino API says that duty goes from 0 to (2^resolution) - 1
// But LEDC works with duty from 0 to (2^resolution)
// Therefore, it will adjust Arduino MAX Duty to be the LEDC MAx Duty
uint32_t max_duty = (1 << bus->channel_resolution) - 1;
if (value < 0 || value > max_duty) {
log_w("Duty is out of range. Valid duty range for pin d is 0 to %d", pin, max_duty);
return;
}
if ((value == max_duty) && (max_duty != 1)) {
value = max_duty + 1;
}
ledcWrite(pin, value);
}
}
Expand Down
Loading