I have the code working, but the edge value (event_data->cap_edge) in the interrupt callback does not always seem to be correct!
Here's the code which sets up the MCPWM:
Code: Select all
void MCPWMInit(void)
{
mcpwm_capture_timer_config_t cap_conf =
{
.clk_src = MCPWM_CAPTURE_CLK_SRC_DEFAULT,
.group_id = 0,
};
ESP_ERROR_CHECK( mcpwm_new_capture_timer(&cap_conf, &l_mcpwm_cap_timer) );
mcpwm_cap_channel_handle_t cap_chan = NULL;
mcpwm_capture_channel_config_t cap_ch_conf =
{
.gpio_num = GPIO_SIGNAL,
.intr_priority = 3, // 0 = Auto (low); Other options 1 - 3 (3 = highest).
.prescale = 1,
.flags.pos_edge = true,
.flags.neg_edge = true,
.flags.pull_up = false,
.flags.pull_down = true,
};
ESP_ERROR_CHECK( mcpwm_new_capture_channel(l_mcpwm_cap_timer, &cap_ch_conf, &cap_chan) );
TaskHandle_t cur_task = xTaskGetCurrentTaskHandle();
mcpwm_capture_event_callbacks_t cbs =
{
.on_cap = CaptureInterruptHandler,
};
ESP_ERROR_CHECK( mcpwm_capture_channel_register_event_callbacks(cap_chan, &cbs, cur_task) );
ESP_ERROR_CHECK( mcpwm_capture_channel_enable(cap_chan) );
}
Code: Select all
static bool IRAM_ATTR CaptureInterruptHandler(
mcpwm_cap_channel_handle_t cap_channel,
const mcpwm_capture_event_data_t *event_data,
void *user_ctx
)
{
UNUSED(cap_channel);
UNUSED(user_ctx);
gpio_set_level(GPIO_DEBUG_1, event_data->cap_edge);
static uint8_t dbg_toggle = 0;
gpio_set_level(GPIO_DEBUG_2, dbg_toggle);
dbg_toggle ^= 1;
return false;
}
- Yellow trace is the input signal.
- White trace is GPIO_DEBUG_1 (supposed to be capture edge).
- Brown trace is GPIO_DEBUG_2 (toggled when the capture interrupt occurs).
The plot shows that the capture interrupt is occurring for each edge (brown trace toggles as expected), but sometimes the "edge" value doesn't change (i.e. it doesn't match the captured edge??) (White trace). Note that the shortest pulses are about 100 uS, and I have captured pulses down to about 2-3 uS in the past, so I don't think it's an interrupt latency problem.
The second plot shows another capture with more detail, so you can see the edge capture interrupt is being reliably called on rising and falling edges, but sometimes the "edge" value is wrong. The time between the cursors in the second plot is 92 uS.
What is going on here?
(ESP-IDF 5.1.2)