STMF4 get frequency of a signal on a input pin.

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderator: RoccoMarco

Joerg-SH
Posts: 29
Joined: Mon Feb 20, 2012 9:00 pm

Re: STMF4 get frequency of a signal on a input pin.

Post by Joerg-SH »

Now I spent again some time to understand the sample.
Basically, I understand the structure of the program. But there are connections that I do not really understand. I would have to understand the whole structure of each function. For that I would need days or weeks, I think. I can only say again. An example without shortcuts to other functions would be much easier to accomplish.

So as the I2C example I could use for my purposes without major problems, and could fit into the existing program.

I marvel at and admire what you've created here with a lot of work.I think that you would like to see that any of Chibios users can accomplish everything exactly. I would also like it. But I have not really the time to learn it all in my life. ;)

Joerg
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: STMF4 get frequency of a signal on a input pin.

Post by Giovanni »

Sorry I could not be of help.

Giovanni
billr
Posts: 12
Joined: Sun Feb 24, 2013 8:36 pm

Re: STMF4 get frequency of a signal on a input pin.

Post by billr »

Your choice of a 10 kHz clock is way way too slow to measure a 7000 kHz input signal (if that's what you really meant). The ICU works by using the input signal to gate a timer/counter that is driven by a fixed sample clock. By counting how many sample clocks there are in the width (or period) of the input signal, you can calculate the frequency. The frequency of choice for the sample clock is based on the nominal input frequency and range and how much resolution you need. For your 7000 kHz (7 MHz), you want something on the order of 70 MHz to get 10% resolution.

Here's the code I use for measuring the horizontal frequency of a video signal, which is in the 16-30 kHz range.

Code: Select all

static ICUConfig icucfg3a = {
    ICU_INPUT_ACTIVE_HIGH,
    48000000,                             /* 48MHz ICU clock frequency.   */
    NULL,
    icuperiodcb3,
    NULL,
    ICU_CHANNEL_1
};


Code: Select all

static void icuperiodcb3(ICUDriver *icup)
{
    float hf = (float)icup->config->frequency / icuGetPeriod(icup);

    icuDisableI (icup);
    hfreq1 = hf;
    icuStart(&ICUD3, &icucfg2b);
    icuEnable(&ICUD3);
    icuEnableI (icup);
}


Code: Select all

int chb_icu_init(void)
{

    /*
     * Initialize ICU driver 3.
     * GPIOA1 and GPIOA5 are the ICU input.
     */
    icuStart(&ICUD3, &icucfg3a);
    icuEnable(&ICUD3);

    return 0;
}
billr
Posts: 12
Joined: Sun Feb 24, 2013 8:36 pm

Re: STMF4 get frequency of a signal on a input pin.

Post by billr »

billr wrote:

Code: Select all

static void icuperiodcb3(ICUDriver *icup)
{
    float hf = (float)icup->config->frequency / icuGetPeriod(icup);

    icuDisableI (icup);
    hfreq1 = hf;
    icuStart(&ICUD3, &icucfg2b);
    icuEnable(&ICUD3);
    icuEnableI (icup);
}



I can't edit the original post, so I'll followup here. Two things about the code snippet above: 1) I had trimmed down the original code to make it simpler and in so doing left some extraneous calls. In my original code, I was using both channel 1 and channel 2 of the timer to measure two different signals. In the real callback, I switch the config structure from one channel to other, hence the disabling and re-enabling interrupts. No need to do that if you are not switching configs (as far as I know). Sorry for any confusion.
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: STMF4 get frequency of a signal on a input pin.

Post by Giovanni »

Hi Billr,

You can't call normal functions from a callback, only I-class and even those must be within chSysLockFromIsr() and chSysUnlockFromIsr(). I recommend to keep the state checker enabled during development because it is able to catch such problems.

In your callback you just need:

Code: Select all

    static void icuperiodcb3(ICUDriver *icup)
    {
        float hf = (float)icup->config->frequency / icuGetPeriod(icup);
        hfreq1 = hf;
    }


There is no need to stop or restart anything, the ICU driver operates continuously once enabled.

Giovanni
Joerg-SH
Posts: 29
Joined: Mon Feb 20, 2012 9:00 pm

Re: STMF4 get frequency of a signal on a input pin.

Post by Joerg-SH »

Thanks a lot, with Your help I get it work.

Joerg
billr
Posts: 12
Joined: Sun Feb 24, 2013 8:36 pm

Re: STMF4 get frequency of a signal on a input pin.

Post by billr »

Giovanni wrote:You can't call normal functions from a callback, only I-class and even those must be within chSysLockFromIsr() and chSysUnlockFromIsr(). I recommend to keep the state checker enabled during development because it is able to catch such problems.

There is no need to stop or restart anything, the ICU driver operates continuously once enabled.


Thanks, Giovanni. I use both channel 1 and channel 2 of three timers (1, 2 & 3). Since both channels are muxed into the same timer/counter, it appeared that I needed to reconfigure the ICU to switch between the two channels on every other measurement and can't just let the ICU free run. I thought I had seen the code snippet in the original post as a solution posted in this forum, but I could be wrong. If I can't stop, reconfigure and start the ICU from within the ISR, I will need to create a manager thread and set a flag in the ISR for thread to to the stop/reconfigure/start action.
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: STMF4 get frequency of a signal on a input pin.

Post by Giovanni »

Yes, that is a possible approach, it is important that you keep non i-class functions out of callbacks.

Giovanni
billr
Posts: 12
Joined: Sun Feb 24, 2013 8:36 pm

Re: STMF4 get frequency of a signal on a input pin.

Post by billr »

Got it - thanks!
Post Reply