1919#include "esp32-hal-ledc.h"
2020#include "driver/ledc.h"
2121#include "esp32-hal-periman.h"
22+ #include "soc/gpio_sig_map.h"
23+ #include "esp_rom_gpio.h"
2224
2325#ifdef SOC_LEDC_SUPPORT_HS_MODE
2426#define LEDC_CHANNELS (SOC_LEDC_CHANNEL_NUM<<1)
@@ -40,7 +42,7 @@ typedef struct {
4042 int used_channels : LEDC_CHANNELS ; // Used channels as a bits
4143} ledc_periph_t ;
4244
43- ledc_periph_t ledc_handle ;
45+ ledc_periph_t ledc_handle = { 0 } ;
4446
4547static bool fade_initialized = false;
4648
@@ -58,15 +60,25 @@ static bool ledcDetachBus(void * bus){
5860
5961bool ledcAttachChannel (uint8_t pin , uint32_t freq , uint8_t resolution , uint8_t channel )
6062{
61- if (channel >= LEDC_CHANNELS || resolution > LEDC_MAX_BIT_WIDTH )
62- {
63- log_e ("Channel %u is not available! (maximum %u) or bit width too big (maximum %u)" , channel , LEDC_CHANNELS , LEDC_MAX_BIT_WIDTH );
63+ if (channel >= LEDC_CHANNELS || ledc_handle .used_channels & (1UL << channel )){
64+ log_e ("Channel %u is not available (maximum %u) or already used!" , channel , LEDC_CHANNELS );
65+ return false;
66+ }
67+
68+ if (resolution > LEDC_MAX_BIT_WIDTH ){
69+ log_e ("LEDC resolution too big (maximum %u)" , LEDC_MAX_BIT_WIDTH );
6470 return false;
6571 }
6672
6773 perimanSetBusDeinit (ESP32_BUS_TYPE_LEDC , ledcDetachBus );
6874 ledc_channel_handle_t * bus = (ledc_channel_handle_t * )perimanGetPinBus (pin , ESP32_BUS_TYPE_LEDC );
69- if (bus != NULL && !perimanClearPinBus (pin )){
75+ if (bus != NULL ){
76+ log_e ("Pin %u is already attached to LEDC (channel %u, resolution %u)" , pin , bus -> channel , bus -> channel_resolution );
77+ return false;
78+ }
79+
80+ if (!perimanClearPinBus (pin )){
81+ log_e ("Pin %u is already attached to another bus and failed to detach" , pin );
7082 return false;
7183 }
7284
@@ -120,11 +132,11 @@ bool ledcAttachChannel(uint8_t pin, uint32_t freq, uint8_t resolution, uint8_t c
120132bool ledcAttach (uint8_t pin , uint32_t freq , uint8_t resolution )
121133{
122134 uint8_t free_channel = ~ledc_handle .used_channels & (ledc_handle .used_channels + 1 );
123- if (free_channel == 0 || resolution > LEDC_MAX_BIT_WIDTH ){
124- log_e ("No more LEDC channels available! (maximum %u) or bit width too big (maximum %u )" , LEDC_CHANNELS , LEDC_MAX_BIT_WIDTH );
135+ if (free_channel == 0 ){
136+ log_e ("No more LEDC channels available! (maximum is %u channels )" , LEDC_CHANNELS );
125137 return false;
126138 }
127- int channel = log2 (free_channel & - free_channel );
139+ uint8_t channel = log2 (free_channel & - free_channel );
128140
129141 return ledcAttachChannel (pin , freq , resolution , channel );
130142}
@@ -265,6 +277,21 @@ uint32_t ledcChangeFrequency(uint8_t pin, uint32_t freq, uint8_t resolution)
265277 return 0 ;
266278}
267279
280+ bool ledcOutputInvert (uint8_t pin , bool out_invert )
281+ {
282+ ledc_channel_handle_t * bus = (ledc_channel_handle_t * )perimanGetPinBus (pin , ESP32_BUS_TYPE_LEDC );
283+ if (bus != NULL ){
284+ gpio_set_level (pin , out_invert );
285+ #ifdef SOC_LEDC_SUPPORT_HS_MODE
286+ esp_rom_gpio_connect_out_signal (pin , ((bus -> channel /8 == 0 ) ? LEDC_HS_SIG_OUT0_IDX : LEDC_LS_SIG_OUT0_IDX ) + ((bus -> channel )%8 ), out_invert , 0 );
287+ #else
288+ esp_rom_gpio_connect_out_signal (pin , LEDC_LS_SIG_OUT0_IDX + ((bus -> channel )%8 ), out_invert , 0 );
289+ #endif
290+ return true;
291+ }
292+ return false;
293+ }
294+
268295static IRAM_ATTR bool ledcFnWrapper (const ledc_cb_param_t * param , void * user_arg )
269296{
270297 if (param -> event == LEDC_FADE_END_EVT ) {
@@ -373,7 +400,7 @@ void analogWrite(uint8_t pin, int value) {
373400 if (pin < SOC_GPIO_PIN_COUNT ) {
374401 ledc_channel_handle_t * bus = (ledc_channel_handle_t * )perimanGetPinBus (pin , ESP32_BUS_TYPE_LEDC );
375402 if (bus == NULL && perimanClearPinBus (pin )){
376- if (ledcAttach (pin , analog_frequency , analog_resolution ) == 0 ){
403+ if (ledcAttach (pin , analog_frequency , analog_resolution , LEDC_CHANNEL_AUTO ) == 0 ){
377404 log_e ("analogWrite setup failed (freq = %u, resolution = %u). Try setting different resolution or frequency" );
378405 return ;
379406 }
0 commit comments