cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L4 Timer: External clock count both edges

PKulh
Associate II

Hello,

I need to count the number of (positive and negative) edges in a signal within certain time period. For that I use a timer on STM32L452. The AN4776 says that External Clock Mode 1 is able to update the counter on both edges (for the price of not being able to trigger). I tried this (see the code below) and figured out that with a 50% duty cycle square test signal of 100mHz the CNT register is incremented every 10 seconds by 2. I would expect the CNT to increment by 1 every 5 seconds.

What am I doing wrong?

Thanks

Petr

Below is my code using TIM2 CH1 for clock and CH3 for capture (without clock, DMA and interrupt initialization):

// ---------- initialize GPIO ------------
    GPIO_InitTypeDef GpioInitStruct;
 
    // initialize the bitstream pin
    GpioInitStruct.Pin = GPIO_PIN_5;
    GpioInitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    GpioInitStruct.Mode = GPIO_MODE_AF_PP;
    GpioInitStruct.Pull = GPIO_NOPULL;
    GpioInitStruct.Alternate = GPIO_AF1_TIM2;
    HAL_GPIO_Init(GPIOA, &GpioInitStruct);
 
    // initialize the sync pin
    GpioInitStruct.Pin = GPIO_PIN_2;
    GpioInitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    GpioInitStruct.Mode = GPIO_MODE_AF_PP;
    GpioInitStruct.Pull = GPIO_NOPULL;
    GpioInitStruct.Alternate = GPIO_AF1_TIM2;
    HAL_GPIO_Init(GPIOA, &GpioInitStruct);
 
    // ------------ initialize timer -------------
    // basic initialization of the structure
    TIM_HandleTypeDef *pTmrHandle;
    pTmrHandle->Instance = TIM2;
    pTmrHandle->Init.Prescaler = 0;
    pTmrHandle->Init.CounterMode = TIM_COUNTERMODE_UP;
    pTmrHandle->Init.Period = 0xffff;
    pTmrHandle->Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    pTmrHandle->Init.RepetitionCounter = 0;
    pTmrHandle->Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
 
    // configure the clock source
    TIM_ClockConfigTypeDef ClockSourceConfig;
    ClockSourceConfig.ClockFilter = 0;                           // no filter
    ClockSourceConfig.ClockPrescaler = TIM_CLOCKPRESCALER_DIV1;  // no prescaler
    ClockSourceConfig.ClockPolarity = TIM_CLOCKPOLARITY_BOTHEDGE;   // trigger on both edges
    ClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_TI1ED;          // both edges
 
    // select the clock using the above clock configuration
    if (HAL_TIM_ConfigClockSource(pTmrHandle, &ClockSourceConfig) != HAL_OK) {
        return false;
    }
 
    // initialize input capture time base
    if (HAL_TIM_IC_Init(pTmrHandle) != HAL_OK) {
        return false;
    }
 
    // configure the input-capture channel (triggered by the sync signal) to trigger on both edges
    TIM_IC_InitTypeDef InputCaptureConfig = {
            .ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING,          // trigger on the rising edge
            .ICSelection = TIM_ICSELECTION_DIRECTTI,                // direct mapping of timer inputs
            .ICPrescaler = TIM_ICPSC_DIV1,                          // no divider - we want to count all edges
            .ICFilter = 0,                                          // no filter
    };
    // trigger on the rising edge of CH3 (sync)
    if (HAL_TIM_IC_ConfigChannel(pTmrHandle, &InputCaptureConfig, TIM_CHANNEL_3) != HAL_OK) {
        return false;
    }
 
    // configure both edges on CH1 (clock)
    InputCaptureConfig.ICPolarity = TIM_INPUTCHANNELPOLARITY_BOTHEDGE;
    if (HAL_TIM_IC_ConfigChannel(pTmrHandle, &InputCaptureConfig, TIM_CHANNEL_1) != HAL_OK) {
        return false;
    }
 
 
// to start reception:
    if (HAL_TIM_IC_Start_DMA(pTmrHandle, TIM_CHANNEL_3,  (uint32_t*)dmaBuffer_, 2 * dmaBlockSize_) != HAL_OK) {
        return false;
    }

20 REPLIES 20

At this moment, I am inclined to believe you've hit a genuine silicon bug.

You may want to contact ST directly, perhaps through the web support form. If I guess your nationality correctly based on your name, you can also try to describe the problem on hw-list at list.hw.cz .

You may want to try other pins, and/or other TIM, meantime.

JW