Reciprocal Frequency counter only for STM32F401、F411 and F466. Reciprocal Mode -> Pulse width measurement

Dependents:   Frequency_Counter_Recipro_for_STM32F4xx

fc_recipro.h

Committer:
kenjiArai
Date:
2020-01-19
Revision:
7:7fdff925855e
Child:
8:c9ed197ce270

File content as of revision 7:7fdff925855e:

/*
 * mbed Library / Frequency Counter / Recipro type
 *      Frequency Counter program
 *      Only for Nucleo-F401RE,-F411RE,-F446RE
 *
 * Copyright (c) 2014,'15,'16,'20 Kenji Arai / JH1PJL
 *      http://www7b.biglobe.ne.jp/~kenjia/
 *      https://os.mbed.com/users/kenjiArai/
 *      Started:    October   18th, 2014
 *      Revised:    January   19th, 2020
 *
 */

#ifndef     MBED_FRQ_CUNTR
#define     MBED_FRQ_CUNTR

#include    "mbed.h"

#define     DEBUG       0  // use Communication with PC(UART) & port output

typedef struct {
    float freq_rise2rise;
    float freq_fall2fall;
    float time_us_rise2fall;
    float time_us_fall2rise;
} Recipro_result_TypeDef;

typedef struct {
    uint8_t rise_cnt;
    uint8_t fall_cnt;
    uint8_t input_level;
    float   passed_time;
} Recipro_status_TypeDef;

namespace Frequency_counter
{
/** Frequency Counter program
 *  Only for Nucleo-F411RE & F446RE
 *
 * @code
 * #include "mbed.h"
 * #include "fc_recipro.h"
 *
 * using namespace Frequency_counter;
 *
 * // frequency input  -> PA_0 & PA_1
 * //       PA_0(for reciprocal)  Timer2 Input Capture #1
 * //       PA_1(for reciprocal)  Timer2 Input Capture #2
 *
 * FRQ_CUNTR    fc;
 *
 * Recipro_result_TypeDef freq;
 *
 * int main()
 * {
 *     //pc.printf("\r\nStart Frequency Counter\r\n");
 *     fc.recipro_start_measurement();
 *     while(true) {
 *         t.reset();
 *         t.start();
 *         if (fc.recipro_check_status(&status) == true) {
 *             fc.recipro_get_result(&freq);
 *             pc.printf("freq = %.3f [Hz], time(rise_fall) = %.6f [mS]\r\n",
 *                       freq.freq_rise2rise, freq.time_us_rise2fall);
 *         } else {
 *             pc.printf("------   data is NOT ready -------\r\n");
 *         }
 *         uint32_t pass = t.read_ms();
 *         if (pass < 990) {
 *             WAIT(1000 - pass);
 *         }
 *     }
 * }
 * @endcode
 */

class FRQ_CUNTR
{

public:

    /** Configure counter
      * @param pin (Fixed A0 & A1) No other choice!!
      */
    FRQ_CUNTR(PinName pin = A0);

//----------- Reciprocal measurement -------------------------------------------
    /** start Reciprocal measurement
      * @param none
      * @return none
      */
    void recipro_start_measurement(void);

    /** stop Reciprocal measurement
      * @param none
      * @return none
      */
    void recipro_stop_measurement(void);

    /** check status
      * @param pointer for saving status
      * @return ready = true, not ready = false
      */
    bool recipro_check_status(Recipro_status_TypeDef *status);

    /** read data
      * @param pointer for saving data
      * @return none
      */
    void recipro_get_result(Recipro_result_TypeDef *fq);

    /** read raw data
      * @param pointer for saving raw data
      * @return none
      */
    void recipro_get_raw_data(int64_t *buf);

    /** Check input frequency on TIM2
      * @param none
      * @return frequency data
      */
    uint32_t read_base_clock_frequency(void);

    /** Check overflow counter data on TIM2
      * @param none
      * @return overflow data
      */
    uint32_t read_tm2_overflow(void);

protected:
    Timer _t;
    DigitalIn _input_pin;

    void start_action(void);        // Start trigger for reciprocal
    void stop_action(void);         // Stop reciprocal
    void initialize_TIM2(void);     // Initialize Timer_2 (32bit)
    uint64_t get_diff(uint64_t new_dt, uint64_t old_dt);

private:
    uint64_t _data_buf[4];
    uint64_t _tp0;
    uint64_t _tp1;
    uint64_t _tp2;
    uint64_t _tp3;

    float _base_clock;

    float _freq_rise2rise;
    float _freq_fall2fall;
    float _time_us_rise2fall;
    float _time_us_fall2rise;
    float _passed_time;
    uint8_t _sample_num;
    bool _data_ready;

};

/*
    Interrupt handler does NOT work following code
    NVIC_SetVector(TIM2_IRQn, (uint32_t)FRQ_CUNTR::irq_ic_TIM2);
    From this reason, I wrote below code and set interrupt handler
    out side "FRQ_CUNTR" class
    NVIC_SetVector(TIM2_IRQn, (uint32_t)irq_ic_TIM2);
 */
void irq_ic_TIM2(void);    // TIM2(F4xx) IC1 & IC2 Interrupt

}   // Frequency_counter

#endif  // MBED_FRQ_CUNTR