This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Issues with using Timer1 in counter mode after SDK migration.

Hi!

I have inherited a large codebase that I'm trying to migrate to SDKv10 from SDKv6.

The project also uses an A4960 BLDC motor controller. To bring the motor up to speed, we count the number of rising edges on the TACHO pin of the controller, but for some reason this no longer works as it used to.

The following piece of code initializes the counter.

void freqcntr_init() {
    uint8_t softdevice_enabled;
    uint32_t err_code;

    /* Stop and clear the timer */
    NRF_TIMER1->TASKS_STOP = 1;
    NRF_TIMER1->TASKS_CLEAR = 1;

    /* Disable the TIMER1 interrupt vector */
    NVIC_DisableIRQ(TIMER1_IRQn);

    /* Disable interrupts on all compare channels */
    NRF_TIMER1->INTENCLR = TIMER_INTENCLR_COMPARE0_Msk
            | TIMER_INTENCLR_COMPARE1_Msk
            | TIMER_INTENCLR_COMPARE2_Msk
            | TIMER_INTENCLR_COMPARE3_Msk;

    NVIC_ClearPendingIRQ(TIMER1_IRQn);

    /* Select counter mode */
    NRF_TIMER1->MODE = (TIMER_MODE_MODE_Counter << TIMER_MODE_MODE_Pos);

    /* 32-bit width so that we minimize risk of overflowing counter. */
    NRF_TIMER1->BITMODE = (TIMER_BITMODE_BITMODE_32Bit << TIMER_BITMODE_BITMODE_Pos);

    /* Make the BLDCTACHO pin an input will a pull-down resistor to keep it
     * from floating unpredictably. */
    nrf_gpio_cfg_input(BLDCTACHO_PIN_NO, NRF_GPIO_PIN_PULLDOWN);

    /* Configure GPIO task/event block to generate an event for every low-to-
     * high transition of the input signal. */
    nrf_gpiote_event_configure(FREQCNTR_GPIOTE_CHANNEL, BLDCTACHO_PIN_NO, NRF_GPIOTE_POLARITY_LOTOHI);

    /* Whether or not the soft device is enabled determines how we configure
     * the PPI block. */
    err_code = sd_softdevice_is_enabled(&softdevice_enabled);
    APP_ERROR_CHECK(err_code);

    /* Connect the rising-edge GPIOTE event to the counter's count task so that
     * we count the number of rising edges and then enable the PPI channel. */
    if (softdevice_enabled) {
        err_code = sd_ppi_channel_assign(FREQCNTR_PPI_CHANNEL,
                &(NRF_GPIOTE->EVENTS_IN[FREQCNTR_GPIOTE_CHANNEL]),
                &(NRF_TIMER1->TASKS_COUNT));
        APP_ERROR_CHECK(err_code);

        err_code = sd_ppi_channel_enable_set(FREQCNTR_PPI_CHENSET_MASK);
        APP_ERROR_CHECK(err_code);
    } else {
        NRF_PPI->CH[FREQCNTR_PPI_CHANNEL].EEP = (uint32_t)&(NRF_GPIOTE->EVENTS_IN[FREQCNTR_GPIOTE_CHANNEL]);
        NRF_PPI->CH[FREQCNTR_PPI_CHANNEL].TEP = (uint32_t)&(NRF_TIMER1->TASKS_COUNT);
        NRF_PPI->CHENSET = FREQCNTR_PPI_CHENSET_MASK;
    }

    /* Enable counting */
    NRF_TIMER1->TASKS_START = 1;
}

And this function is called every once in a while to get the count:

void freqcntr_updateFreq() {
    /* Capture the count */
    NRF_TIMER1->TASKS_CAPTURE[0] = 1;

    SEGGER_RTT_printf("Count: %lu\r\n", NRF_TIMER1->CC[0]);

    /* Reset the count as soon as we have saved the old count */
    NRF_TIMER1->TASKS_CLEAR = 1;
}

Unfortunately, this always prints 0 for the counter value. I know that the problem can be from somewhere else, but wanted to check if there is anything glaringly wrong with the code above.

Thanks!

Related