-
Notifications
You must be signed in to change notification settings - Fork 7.6k
LEDC - AnalogWrite new API + ledcAttachPin duty fix #7346
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
Changes from 4 commits
f2273ef
e086ce4
397e745
f437fb0
a687671
760b77a
f5fdda6
82b9d18
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -166,14 +166,15 @@ void ledcAttachPin(uint8_t pin, uint8_t chan) | |
return; | ||
} | ||
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 = 0, | ||
.duty = duty, | ||
.hpoint = 0 | ||
}; | ||
ledc_channel_config(&ledc_channel); | ||
|
@@ -211,6 +212,8 @@ uint32_t ledcChangeFrequency(uint8_t chan, uint32_t freq, uint8_t bit_num) | |
|
||
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) { | ||
|
@@ -220,8 +223,8 @@ void analogWrite(uint8_t pin, int value) { | |
return; | ||
} | ||
pin_to_channel[pin] = cnt_channel--; | ||
ledcSetup(cnt_channel, analog_frequency, analog_resolution); | ||
ledcAttachPin(pin, cnt_channel); | ||
ledcSetup(cnt_channel, 1000, 8); | ||
} | ||
ledcWrite(pin_to_channel[pin] - 1, value); | ||
} | ||
|
@@ -230,3 +233,23 @@ void analogWrite(uint8_t pin, int value) { | |
int8_t analogGetChannel(uint8_t pin) { | ||
return pin_to_channel[pin] - 1; | ||
} | ||
|
||
void analogWriteFrequency(uint32_t freq) { | ||
if (cnt_channel == LEDC_CHANNELS) { | ||
return; //No channel used for analogWrite | ||
} | ||
for (int channel = LEDC_CHANNELS - 1; channel >= cnt_channel; channel--) { | ||
ledcChangeFrequency(channel, freq, analog_resolution); | ||
} | ||
analog_frequency = freq; | ||
} | ||
|
||
void analogWriteResolution(uint8_t bits) { | ||
if (cnt_channel == LEDC_CHANNELS) { | ||
return; //No channel used for analogWrite | ||
} | ||
for (int channel = LEDC_CHANNELS - 1; channel >= cnt_channel; channel--) { | ||
ledcChangeFrequency(channel, analog_frequency, bits); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is any uint8_t a valid resolution? What happens if we set it to 128 bits? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You will get an error that is not valid input. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I tested it with wrong value and I got no error message. But if I test it with pure IDF I get the error... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Check the comments below :) |
||
} | ||
analog_resolution = bits; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is any uint32_t a valid frequency? What happens if we set it to 1,000,000,000 Hz?
Should it be validated?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IDF is checking the frequency input and validating if its valid to set or not. Same with resolution. IDF will return error that is checked in Arduino.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tested it with wrong valus and I got no error message.
But if I test it with IDF I get the error...
E (30) ledc: requested frequency and duty resolution can not be achieved, try reducing freq_hz or duty_resolution. div_param=11
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Check the comments below :)