Hi frankgigeur,
this is the code I am using. Note: I am also using the ISR handler on the PCNT, but it should also work without.
On first glance I don't see a lot of difference between your and my code...
Please let me know if you figured out, what it was.
Initialization:
Code: Select all
ledc_timer_config_t ledc_timer;
ledc_timer.timer_num = LEDC_TIMER_0; // timer index
ledc_timer.speed_mode = LEDC_HIGH_SPEED_MODE; // timer mode
ledc_timer.freq_hz = 4000; // frequency of PWM signal
ledc_timer.duty_resolution = LEDC_TIMER_8_BIT; // resolution of PWM duty
ledc_timer.clk_cfg = LEDC_AUTO_CLK; // Auto select the source clock
// Set configuration of timer for high speed channels
esp_err_t err = ledc_timer_config(&ledc_timer);
if (err != ESP_OK)
{
mLogger->log(Logger::ERROR) << "Error configuring ledc_timer_config: " << esp_err_to_name(err);
}
ledc_channel_config_t ledc_conf;
ledc_conf.channel = LEDC_CHANNEL_0;
ledc_conf.gpio_num = GPIO_NUM_23;
ledc_conf.duty = 0; // don't run off right away :-)
ledc_conf.hpoint = 0; // where in the clock interval the level will be set to high; like a phase shift
ledc_conf.intr_type = LEDC_INTR_DISABLE;
ledc_conf.speed_mode = LEDC_HIGH_SPEED_MODE;
ledc_conf.timer_sel = LEDC_TIMER_0;
err = ledc_channel_config(&ledc_conf);
if (err != ESP_OK)
{
mLogger->log(Logger::ERROR) << "Error configuring ledc_channel_config: " << esp_err_to_name(err);
}
pcnt_config_t pcnt_config =
{
// Set PCNT input signal and control GPIOs
.pulse_gpio_num = GPIO_NUM_23,
.ctrl_gpio_num = -1,
.lctrl_mode = PCNT_MODE_KEEP, // Keep the primary counter mode if high
.hctrl_mode = PCNT_MODE_KEEP, // Keep the primary counter mode if high
.pos_mode = PCNT_COUNT_INC, // Count up on the positive edge
.neg_mode = PCNT_COUNT_DIS, // Ignore
// Set the maximum and minimum limit values to watch
.counter_h_lim = 32760,
.counter_l_lim = -1,
.unit = PCNT_UNIT_0,
.channel = PCNT_CHANNEL_0,
};
/* Initialize PCNT unit */
pcnt_unit_config(&pcnt_config);
/* Configure and enable the input filter */
pcnt_set_filter_value(PCNT_UNIT_0, 100);
pcnt_filter_enable(PCNT_UNIT_0);
pcnt_event_enable(PCNT_UNIT_0, PCNT_EVT_H_LIM);
pcnt_event_enable(PCNT_UNIT_0, PCNT_EVT_THRES_0);
pcnt_counter_pause(PCNT_UNIT_0);
pcnt_counter_clear(PCNT_UNIT_0);
/* Register ISR handler and enable interrupts for PCNT unit */
pcnt_isr_register(pcnt_intr_handler, &PCNT_UNIT_0, 0, &user_isr_handle);
pcnt_intr_enable(PCNT_UNIT_0);
pcnt_counter_resume(PCNT_UNIT_0);
gpio_set_direction(GPIO_NUM_23, GPIO_MODE_INPUT_OUTPUT);
// NOTE: the following line assumes that we use LEDC_HIGH_SPEED_MODE
gpio_matrix_out(GPIO_NUM_23, LEDC_HS_SIG_OUT0_IDX + LEDC_CHANNEL_0, 0, 0);
Start the signal:
Code: Select all
ledc_set_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_0, (1 << LEDC_TIMER_8_BIT) / 2);
ledc_update_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_0);
Query the counter value:
Code: Select all
int16_t count;
esp_err_t err = pcnt_get_counter_value(PCNT_UNIT_0, &count);
if (err != ESP_OK)
{
mLogger->log(Logger::ERROR) << "Error calling pcnt_get_counter_value";
}
Good luck!