Interrupts not firing at right time after switch from arduino framework to idf with arduino as component

matthew798
Posts: 16
Joined: Mon Jun 01, 2020 2:31 am

Interrupts not firing at right time after switch from arduino framework to idf with arduino as component

Postby matthew798 » Wed Aug 12, 2020 5:52 am

Recently I decided it was time to switch from using only the arduino framework to using IDF with arduino as a component. In my code I have an interrupt that performs 3 distinct action, one after the other, at very precise times:

Code: Select all

void IRAM_ATTR ControlPilot::Pulse(void* arg){
    TIMERG0.int_clr_timers.t0 = 1;
    TIMERG0.hw_timer[0].config.alarm_en = 1;

    short nextActionDelay = 0;

    switch(nextAction){
        case Action::PulseHigh:
            digitalWrite(CP_PWM_PIN, LOW);
            nextActionDelay = 30;
            nextAction = Action::Sample;
            break;
        
        case Action::Sample:
            digitalWrite(32, HIGH);
            lastCpValue = analogRead(CP_READ_PIN);
            digitalWrite(32, LOW);
            nextActionDelay = highTime - 30;
            nextAction = Action::PulseLow;
            break;

        case Action::PulseLow:
            digitalWrite(CP_PWM_PIN, HIGH);
            nextActionDelay = CP_PWM_FREQ - highTime;
            nextAction = Action::PulseHigh;
            break;
    }

    TIMERG0.hw_timer[0].alarm_low = nextActionDelay;
    TIMERG0.hw_timer[0].alarm_high = 0x0;
}
The timer is configured as such:

Code: Select all

    //Set up our timer. We use IDF here because arduino makes too many assumptions
    timer_config_t tConfig = {
        .alarm_en = true,
        .counter_en = false,
        .intr_type = TIMER_INTR_LEVEL,
        .counter_dir = TIMER_COUNT_UP,
        .auto_reload = true,
        .divider = 80, //Prescaler of 80 gives us a resolution of 1uS
    };
    ESP_ERROR_CHECK(timer_init(TIMER_GROUP_0, TIMER_0, &tConfig));
    ESP_ERROR_CHECK(timer_set_counter_value(TIMER_GROUP_0, TIMER_0, 0)); //Timer will reset to this value on alarm
My problem is, the interrupts are actually happening a lot faster (sooner than they are scheduled). In the code above, highTime = 200. Basically, there should be a difference of 200uS between running the PulseHigh case and the PulseLow case.

Currently there is only 107uS:
Image

Now you'll notice my prescaler is set to 80. This is because I was under the impression that the APB clock was running at 80MHz by default in the arduino framework. It worked just fine before IDF. Oddly enough, if I change the prescaler to 160, I get precisely half of the correct timing; that is to say the frequency of the square wave is 500Hz and the duration of the pulse is 100uS. Changing the frequency of the esp in menuconfig has no effect. I tried 160MHz and 80Mhz. Is there something I am missing? Something that is configured by default in arduino? Thanks.

Who is online

Users browsing this forum: No registered users and 128 guests