Skip to content

Commit 66596fa

Browse files
authored
Fix ledc panic’ed when wrong setup of frequency and bit width (espressif#6371)
* Fixed LEDC panic when wrong bit widht / frequency set. * Fixed ledc example to be working on all SOCs
1 parent 02a3a71 commit 66596fa

File tree

2 files changed

+29
-15
lines changed

2 files changed

+29
-15
lines changed

cores/esp32/esp32-hal-ledc.c

+24-10
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,11 @@ uint8_t channels_resolution[LEDC_CHANNELS] = {0};
5656

5757
double ledcSetup(uint8_t chan, double freq, uint8_t bit_num)
5858
{
59-
if(chan >= LEDC_CHANNELS){
60-
log_e("No more LEDC channels available! You can have maximum %u", LEDC_CHANNELS);
59+
if(chan >= LEDC_CHANNELS || bit_num > LEDC_MAX_BIT_WIDTH){
60+
log_e("No more LEDC channels available! (maximum %u) or bit width too big (maximum %u)", LEDC_CHANNELS, LEDC_MAX_BIT_WIDTH);
6161
return 0;
6262
}
63+
6364
uint8_t group=(chan/8), timer=((chan/2)%4);
6465

6566
ledc_timer_config_t ledc_timer = {
@@ -69,9 +70,12 @@ double ledcSetup(uint8_t chan, double freq, uint8_t bit_num)
6970
.freq_hz = freq,
7071
.clk_cfg = LEDC_DEFAULT_CLK
7172
};
72-
ledc_timer_config(&ledc_timer);
73+
if(ledc_timer_config(&ledc_timer) != ESP_OK)
74+
{
75+
log_e("ledc setup failed!");
76+
return 0;
77+
}
7378
channels_resolution[chan] = bit_num;
74-
7579
return ledc_get_freq(group,timer);
7680
}
7781

@@ -95,7 +99,7 @@ void ledcWrite(uint8_t chan, uint32_t duty)
9599

96100
uint32_t ledcRead(uint8_t chan)
97101
{
98-
if(chan >= LEDC_CHANNELS){
102+
if(chan >= LEDC_CHANNELS){
99103
return 0;
100104
}
101105
uint8_t group=(chan/8), channel=(chan%8);
@@ -130,7 +134,12 @@ double ledcWriteTone(uint8_t chan, double freq)
130134
.freq_hz = freq,
131135
.clk_cfg = LEDC_DEFAULT_CLK
132136
};
133-
ledc_timer_config(&ledc_timer);
137+
138+
if(ledc_timer_config(&ledc_timer) != ESP_OK)
139+
{
140+
log_e("ledcSetup failed!");
141+
return 0;
142+
}
134143
channels_resolution[chan] = 10;
135144

136145
double res_freq = ledc_get_freq(group,timer);
@@ -153,7 +162,7 @@ double ledcWriteNote(uint8_t chan, note_t note, uint8_t octave){
153162

154163
void ledcAttachPin(uint8_t pin, uint8_t chan)
155164
{
156-
if(chan >= LEDC_CHANNELS){
165+
if(chan >= LEDC_CHANNELS){
157166
return;
158167
}
159168
uint8_t group=(chan/8), channel=(chan%8), timer=((chan/2)%4);
@@ -177,7 +186,8 @@ void ledcDetachPin(uint8_t pin)
177186

178187
double ledcChangeFrequency(uint8_t chan, double freq, uint8_t bit_num)
179188
{
180-
if(chan >= LEDC_CHANNELS){
189+
if(chan >= LEDC_CHANNELS || bit_num > LEDC_MAX_BIT_WIDTH){
190+
log_e("LEDC channel not available! (maximum %u) or bit width too big (maximum %u)", LEDC_CHANNELS, LEDC_MAX_BIT_WIDTH);
181191
return 0;
182192
}
183193
uint8_t group=(chan/8), timer=((chan/2)%4);
@@ -189,9 +199,13 @@ double ledcChangeFrequency(uint8_t chan, double freq, uint8_t bit_num)
189199
.freq_hz = freq,
190200
.clk_cfg = LEDC_DEFAULT_CLK
191201
};
192-
ledc_timer_config(&ledc_timer);
193-
channels_resolution[chan] = bit_num;
194202

203+
if(ledc_timer_config(&ledc_timer) != ESP_OK)
204+
{
205+
log_e("ledcChangeFrequency failed!");
206+
return 0;
207+
}
208+
channels_resolution[chan] = bit_num;
195209
return ledc_get_freq(group,timer);
196210
}
197211

libraries/ESP32/examples/AnalogOut/LEDCSoftwareFade/LEDCSoftwareFade.ino

+5-5
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
// use first channel of 16 channels (started from zero)
1414
#define LEDC_CHANNEL_0 0
1515

16-
// use 13 bit precission for LEDC timer
17-
#define LEDC_TIMER_13_BIT 13
16+
// use 12 bit precission for LEDC timer
17+
#define LEDC_TIMER_12_BIT 12
1818

1919
// use 5000 Hz as a LEDC base frequency
2020
#define LEDC_BASE_FREQ 5000
@@ -28,16 +28,16 @@ int fadeAmount = 5; // how many points to fade the LED by
2828
// Arduino like analogWrite
2929
// value has to be between 0 and valueMax
3030
void ledcAnalogWrite(uint8_t channel, uint32_t value, uint32_t valueMax = 255) {
31-
// calculate duty, 8191 from 2 ^ 13 - 1
32-
uint32_t duty = (8191 / valueMax) * min(value, valueMax);
31+
// calculate duty, 4095 from 2 ^ 12 - 1
32+
uint32_t duty = (4095 / valueMax) * min(value, valueMax);
3333

3434
// write duty to LEDC
3535
ledcWrite(channel, duty);
3636
}
3737

3838
void setup() {
3939
// Setup timer and attach timer to a led pin
40-
ledcSetup(LEDC_CHANNEL_0, LEDC_BASE_FREQ, LEDC_TIMER_13_BIT);
40+
ledcSetup(LEDC_CHANNEL_0, LEDC_BASE_FREQ, LEDC_TIMER_12_BIT);
4141
ledcAttachPin(LED_PIN, LEDC_CHANNEL_0);
4242
}
4343

0 commit comments

Comments
 (0)