Fix ledc panic’ed when wrong setup of frequency and bit width (#6371)

* Fixed LEDC panic when wrong bit widht / frequency set.

* Fixed ledc example to be working on all SOCs
This commit is contained in:
P-R-O-C-H-Y
2022-03-10 14:30:57 +01:00
committed by GitHub
parent 02a3a71e7c
commit 66596fa581
2 changed files with 29 additions and 15 deletions

View File

@ -56,10 +56,11 @@ uint8_t channels_resolution[LEDC_CHANNELS] = {0};
double ledcSetup(uint8_t chan, double freq, uint8_t bit_num) double ledcSetup(uint8_t chan, double freq, uint8_t bit_num)
{ {
if(chan >= LEDC_CHANNELS){ if(chan >= LEDC_CHANNELS || bit_num > LEDC_MAX_BIT_WIDTH){
log_e("No more LEDC channels available! You can have maximum %u", LEDC_CHANNELS); 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 0;
} }
uint8_t group=(chan/8), timer=((chan/2)%4); uint8_t group=(chan/8), timer=((chan/2)%4);
ledc_timer_config_t ledc_timer = { ledc_timer_config_t ledc_timer = {
@ -69,9 +70,12 @@ double ledcSetup(uint8_t chan, double freq, uint8_t bit_num)
.freq_hz = freq, .freq_hz = freq,
.clk_cfg = LEDC_DEFAULT_CLK .clk_cfg = LEDC_DEFAULT_CLK
}; };
ledc_timer_config(&ledc_timer); if(ledc_timer_config(&ledc_timer) != ESP_OK)
{
log_e("ledc setup failed!");
return 0;
}
channels_resolution[chan] = bit_num; channels_resolution[chan] = bit_num;
return ledc_get_freq(group,timer); return ledc_get_freq(group,timer);
} }
@ -95,7 +99,7 @@ void ledcWrite(uint8_t chan, uint32_t duty)
uint32_t ledcRead(uint8_t chan) uint32_t ledcRead(uint8_t chan)
{ {
if(chan >= LEDC_CHANNELS){ if(chan >= LEDC_CHANNELS){
return 0; return 0;
} }
uint8_t group=(chan/8), channel=(chan%8); uint8_t group=(chan/8), channel=(chan%8);
@ -130,7 +134,12 @@ double ledcWriteTone(uint8_t chan, double freq)
.freq_hz = freq, .freq_hz = freq,
.clk_cfg = LEDC_DEFAULT_CLK .clk_cfg = LEDC_DEFAULT_CLK
}; };
ledc_timer_config(&ledc_timer);
if(ledc_timer_config(&ledc_timer) != ESP_OK)
{
log_e("ledcSetup failed!");
return 0;
}
channels_resolution[chan] = 10; channels_resolution[chan] = 10;
double res_freq = ledc_get_freq(group,timer); double res_freq = ledc_get_freq(group,timer);
@ -153,7 +162,7 @@ double ledcWriteNote(uint8_t chan, note_t note, uint8_t octave){
void ledcAttachPin(uint8_t pin, uint8_t chan) void ledcAttachPin(uint8_t pin, uint8_t chan)
{ {
if(chan >= LEDC_CHANNELS){ if(chan >= LEDC_CHANNELS){
return; return;
} }
uint8_t group=(chan/8), channel=(chan%8), timer=((chan/2)%4); uint8_t group=(chan/8), channel=(chan%8), timer=((chan/2)%4);
@ -177,7 +186,8 @@ void ledcDetachPin(uint8_t pin)
double ledcChangeFrequency(uint8_t chan, double freq, uint8_t bit_num) double ledcChangeFrequency(uint8_t chan, double freq, uint8_t bit_num)
{ {
if(chan >= LEDC_CHANNELS){ 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; return 0;
} }
uint8_t group=(chan/8), timer=((chan/2)%4); uint8_t group=(chan/8), timer=((chan/2)%4);
@ -189,9 +199,13 @@ double ledcChangeFrequency(uint8_t chan, double freq, uint8_t bit_num)
.freq_hz = freq, .freq_hz = freq,
.clk_cfg = LEDC_DEFAULT_CLK .clk_cfg = LEDC_DEFAULT_CLK
}; };
ledc_timer_config(&ledc_timer);
channels_resolution[chan] = bit_num;
if(ledc_timer_config(&ledc_timer) != ESP_OK)
{
log_e("ledcChangeFrequency failed!");
return 0;
}
channels_resolution[chan] = bit_num;
return ledc_get_freq(group,timer); return ledc_get_freq(group,timer);
} }

View File

@ -13,8 +13,8 @@
// use first channel of 16 channels (started from zero) // use first channel of 16 channels (started from zero)
#define LEDC_CHANNEL_0 0 #define LEDC_CHANNEL_0 0
// use 13 bit precission for LEDC timer // use 12 bit precission for LEDC timer
#define LEDC_TIMER_13_BIT 13 #define LEDC_TIMER_12_BIT 12
// use 5000 Hz as a LEDC base frequency // use 5000 Hz as a LEDC base frequency
#define LEDC_BASE_FREQ 5000 #define LEDC_BASE_FREQ 5000
@ -28,8 +28,8 @@ int fadeAmount = 5; // how many points to fade the LED by
// Arduino like analogWrite // Arduino like analogWrite
// value has to be between 0 and valueMax // value has to be between 0 and valueMax
void ledcAnalogWrite(uint8_t channel, uint32_t value, uint32_t valueMax = 255) { void ledcAnalogWrite(uint8_t channel, uint32_t value, uint32_t valueMax = 255) {
// calculate duty, 8191 from 2 ^ 13 - 1 // calculate duty, 4095 from 2 ^ 12 - 1
uint32_t duty = (8191 / valueMax) * min(value, valueMax); uint32_t duty = (4095 / valueMax) * min(value, valueMax);
// write duty to LEDC // write duty to LEDC
ledcWrite(channel, duty); ledcWrite(channel, duty);
@ -37,7 +37,7 @@ void ledcAnalogWrite(uint8_t channel, uint32_t value, uint32_t valueMax = 255) {
void setup() { void setup() {
// Setup timer and attach timer to a led pin // Setup timer and attach timer to a led pin
ledcSetup(LEDC_CHANNEL_0, LEDC_BASE_FREQ, LEDC_TIMER_13_BIT); ledcSetup(LEDC_CHANNEL_0, LEDC_BASE_FREQ, LEDC_TIMER_12_BIT);
ledcAttachPin(LED_PIN, LEDC_CHANNEL_0); ledcAttachPin(LED_PIN, LEDC_CHANNEL_0);
} }