I'm not sure how I can use the pulse counter to do this. The pulse counter just counts edges, I need to correlate an edge with a time stamp.
I did end up figuring out how to use the mcpwm timer to achieve my goal.
Here's how I did it:
Code: Select all
//We are using a mcpwm timer in order to be able to query the time in microseconds since the last
//clock sync falling edge
mcpwm_timer_handle_t clock_sync_timer;
const mcpwm_timer_config_t mcpwm_timer_config = {
.group_id = 0,
//.clk_src
.resolution_hz = 1000000, //1us resolution
.count_mode = MCPWM_TIMER_COUNT_MODE_UP, //Count up
.period_ticks = 65536, //Set max period, we should be resetting this timer with the clock sync before we reach this
//.intr_priority
.flags.update_period_on_empty = 0,
.flags.update_period_on_sync = 0,
};
assert(ESP_OK == mcpwm_new_timer(&mcpwm_timer_config,&clock_sync_timer));
mcpwm_sync_handle_t gpio_sync_source;
const mcpwm_gpio_sync_src_config_t mcpwm_gpio_sync_src_config = {
.group_id = 0, // GPIO fault should be in the same group of the above timers
.gpio_num =GPIO_NUM_15,
.flags.pull_down = false,
.flags.active_neg = true, // negative edge pulse will trigger a sync event to load the timer with the count value
};
assert(ESP_OK == mcpwm_new_gpio_sync_src(&mcpwm_gpio_sync_src_config, &gpio_sync_source));
const mcpwm_timer_sync_phase_config_t mcpwm_timer_sync_phase_config = {
.sync_src = gpio_sync_source, //Use our gpio as the sync source for the timer
.count_value = 0, //Reset the timer to 0 on the sync
.direction = MCPWM_TIMER_DIRECTION_UP, //Continue counting up after the sync
};
assert(ESP_OK == mcpwm_timer_set_phase_on_sync(clock_sync_timer, &mcpwm_timer_sync_phase_config));
const mcpwm_timer_event_callbacks_t cbs = {
.on_empty = mcpwm_on_empty_cb, //Use this to get an interrupt when the clock sync falling edge occurs
.on_full = mcpwm_on_full_cb, //Use this to confirm we have a valid clock sync occuring
};
assert(ESP_OK == mcpwm_timer_register_event_callbacks(clock_sync_timer, &cbs, NULL));
assert(mcpwm_timer_enable(clock_sync_timer) == ESP_OK); //enable the timer
assert(mcpwm_timer_start_stop(clock_sync_timer, MCPWM_TIMER_START_NO_STOP) == ESP_OK); //Start the freerunning timer
uint32_t timer_val = mcpwm_timer_get_value(clock_sync_timer); //get the timer value which shows how many microseconds have elapsed since the last falling edge
Pretty lame though the api doesn't provide a way to read the current timer value (except through an ISR) so I had to modify the driver and add this function:
Code: Select all
uint32_t mcpwm_timer_get_value(mcpwm_timer_handle_t timer_channel)
{
mcpwm_timer_t *timer = timer_channel;
mcpwm_group_t *group = timer->group;
mcpwm_hal_context_t *hal = &group->hal;
int timer_id = timer->timer_id;
return mcpwm_ll_timer_get_count_value(hal->dev, timer_id);
}