In my project, I need to toggle an IO pin at speeds up to 20khz, while the wifi is running...
I have setup a 50µs clock using a GP timer (see code bellow), and in the IRQ routine, I will set/clear the pin as needed...
However, adding this in my code make the Wifi unreliable....
The IRQ code is short, it will compare time with a reference time and, if needed, issue a pulse and increment some counters...
I tried moving this code out of an IRQ, but it did not work as my motor movements became not-smooth...
Any advices on how to fix this?
Thanks,
Cyrille
Code: Select all
void IRAM_ATTR next(uint32_t now)
{
if (currentSpd==0) return;
if (int32_t(now-nextStepmus)<0) return; // nothing to do. we wait
nextStepmus+= deltaBetweenSteps; // program allarm
if (stpVal==0) { CGPIO::set(stp); stpVal= 1; } else { CGPIO::clear(stp); stpVal= 0; }
if (currentSpd>=0) pos+= 1; else pos-= 1; // increase pos
if (pos==dst) { pos= dst; currentSpd= requestedSpd=0; return; } // destination reached!
}
static bool IRAM_ATTR stepperTick(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_data)
{
uint32_t now= micros(); next(now);
return pdFALSE;
}
void initSteppers()
{
gptimer_handle_t gptimer;
gptimer_config_t timer_config = {
.clk_src = GPTIMER_CLK_SRC_DEFAULT,
.direction = GPTIMER_COUNT_UP,
.resolution_hz = 1000000, // 1MHz, 1 tick=1us
};
ESP_ERROR_CHECK(gptimer_new_timer(&timer_config, &gptimer));
gptimer_event_callbacks_t cbs = { .on_alarm = stepperTick, };
ESP_ERROR_CHECK(gptimer_register_event_callbacks(gptimer, &cbs, nullptr));
gptimer_alarm_config_t alarm_config1; memset(&alarm_config1, 0, sizeof(alarm_config1));
alarm_config1.reload_count = 0;
alarm_config1.alarm_count = 50; // period = 50us or 20k spets/s!
alarm_config1.flags.auto_reload_on_alarm = true;
ESP_ERROR_CHECK(gptimer_set_alarm_action(gptimer, &alarm_config1));
ESP_ERROR_CHECK(gptimer_enable(gptimer));
ESP_ERROR_CHECK(gptimer_start(gptimer));
}