HeapCrash / Challenges / Flow meter input capture

Flow meter input capture

A flow sensor outputs 5–500 Hz pulses into TIM3 channel 1 input capture: a 16-bit counter with the prescaler set for 1 MHz ticks. APB1 runs at half the core clock. Readings occasionally drop to 0 Hz for one sample, are wrong below about 16 Hz, and even the good ones are half the true value.

The code

Embedded C for Cortex-M. It compiles. There are 3 real bugs in it: the kind that pass a bench test and fail in the field.

#define TIMER_HZ  (SystemCoreClock / 2)        /* APB1 clock */

static volatile uint16_t last;
static volatile uint32_t period;

void flow_init(void)
{
    TIM3->PSC = TIMER_HZ / 1000000u - 1u;
    TIM3->CCMR1 |= TIM_CCMR1_CC1S_0;       /* CC1 = input, mapped to TI1 */
    TIM3->CCER |= TIM_CCER_CC1E;           /* capture enabled, rising edge */
    TIM3->EGR = TIM_EGR_UG;                /* load the prescaler now */
    TIM3->DIER |= TIM_DIER_CC1IE;
    NVIC_EnableIRQ(TIM3_IRQn);
    TIM3->CR1 |= TIM_CR1_CEN;
}

void TIM3_IRQHandler(void)
{
    if (TIM3->SR & TIM_SR_CC1IF) {
        uint16_t now = (uint16_t)TIM3->CCR1;
        period = now - last;
        last = now;
    }
}

uint32_t flow_hz(void)
{
    return 1000000u / period;
}

What an interviewer expects

The bugs, reference fixes and the follow-up question are in the practice app, after you've tried it.

Companies that test this

Matched on the skills each company's embedded roles emphasise.

Related challenges

Flag the lines, say what breaks, then fix it and build it with clang in your browser.

Find the bugs