Hi,
In my project I need to be able to read the current output state of a PWM pin (configured using LEDC). I've looked through the datasheet and can't seem to find a register which holds this value.
I'd like to avoid a digitalRead as I'm running a time critical loop, and want this to be programmatically as efficient as possible. I've also had very mixed results with using a hardware interrupt, which triggers spuriously when the PWM signal is at 0 V. As such, directly accessing the value within the registers of the device is preferable to looping the signal back round to an input.
Does anybody know if this is possible?
Thanks in advance.
LEDC Output Value - Register Access
Re: LEDC Output Value - Register Access
Any luck with this? I need to do the exact same thing in order to sample a current reading when the drive line is asserted.
-
- Posts: 8
- Joined: Fri Apr 01, 2022 3:06 pm
Re: LEDC Output Value - Register Access
Pretty late to this party, but I found a solution. After you make your call to ledc_channel_config() you need to set the GPIO direction as input/output. Unfortunately setting the direction will break the IOMUX mapping for the pin so you must then restore the mapping using esp_rom_gpio_connect_out_signal(). With the GPIO now configured as an input/output you can monitor its state using gpio_get_level() or by directly monitoring the input register (GPIO_IN_REG).
So the pseudo code looks like this:
Maybe there's a better way to remap the LEDC peripheral function to the GPIO pin, but that method worked for me.
edit: It occurred to me that this is the Arduino flavor of the forum. The above example is written for the ESP-IDF, but the concept is all the same.
So the pseudo code looks like this:
Code: Select all
#include <driver/gpio.h>
#include <driver/ledc.h>
#include "soc/ledc_periph.h"
#include "esp_rom_gpio.h"
// Prepare and then apply the LEDC PWM channel configuration
ledc_channel_config_t _ledc_channel_config = {
.gpio_num = this->Pin,
.speed_mode = this->speedMode,
.channel = this->ledc_channel,
.intr_type = hal::pwm::dflt_intrType,
.timer_sel = this->ledc_timer,
.duty = 0, // Set duty to 0%
.hpoint = 0,
{
.output_invert = 0
}
};
ESP_ERROR_CHECK(ledc_channel_config(&_ledc_channel_config));
// set to be an input as well to allow for output diagnostics
// this will reset the IOMUX routing to GPIO so it has to be restored to LEDC
gpio_set_direction(this->Pin, GPIO_MODE_INPUT_OUTPUT);
esp_rom_gpio_connect_out_signal(
this->Pin,
ledc_periph_signal[this->speedMode].sig_out0_idx + this->ledc_channel,
_ledc_channel_config.flags.output_invert,
0
);
edit: It occurred to me that this is the Arduino flavor of the forum. The above example is written for the ESP-IDF, but the concept is all the same.
Last edited by Maxzillian on Mon Nov 06, 2023 9:47 pm, edited 1 time in total.
-
- Posts: 828
- Joined: Mon Jul 22, 2019 3:20 pm
Re: LEDC Output Value - Register Access
The timer registers are shown in the technical reference manual. You will need to calculate the frequency from the clock and divider. I assure you it is much easier and faster to store this when you set it, and just reference that value than querying the hardware to read this setting.
In v3.0.0, arduino-esp32 will use the peripheral manager (tied to the IDF HAL), so this info can be read directly from the manager. https://docs.espressif.com/projects/ard ... l#ledcread
In v3.0.0, arduino-esp32 will use the peripheral manager (tied to the IDF HAL), so this info can be read directly from the manager. https://docs.espressif.com/projects/ard ... l#ledcread
-
- Posts: 8
- Joined: Fri Apr 01, 2022 3:06 pm
Re: LEDC Output Value - Register Access
I think you're misunderstanding what I'm aiming to do. In my case I have an input configured to measure the output state of a driver being controlled by PWM. By checking if the output is low while I'm commanding it to be high I can detect a driver failure or a short-to-ground.
I could check the counter values and calculate what the pin should be at, but with what I proposed a single register read can tell me right away what the output state should be. Since my output checking code is operating in an ISR I opted for what could be performed the quickest.
I could check the counter values and calculate what the pin should be at, but with what I proposed a single register read can tell me right away what the output state should be. Since my output checking code is operating in an ISR I opted for what could be performed the quickest.
Who is online
Users browsing this forum: egionet and 117 guests