Frequency counter library using GPS 1PPS signal and temperature controlled 50MHz Base clock. Ported from F411 Frequency Counter.

Dependencies:   RingBuff

Dependents:   Frequency_Cntr_1PPS_F746ZG

Fork of Frq_cuntr_full by Kenji Arai

Please refer following.
/users/kenjiArai/notebook/frequency-counters/

Revision:
5:bb04c4a3b5ba
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/frq_cuntr_f746.h	Wed Nov 23 07:30:55 2016 +0000
@@ -0,0 +1,213 @@
+/*
+ * mbed Library / Frequency Counter with GPS 1PPS Compensation
+ *      Frequency Counter Hardware relataed program
+ *      Only for ST Nucleo-F746ZG
+ *
+ * Copyright (c) 2014,'15,'16 Kenji Arai / JH1PJL
+ *  http://www.page.sannet.ne.jp/kenjia/index.html
+ *  http://mbed.org/users/kenjiArai/
+ *      Started:    October   18th, 2014
+ *      Revised:    January    1st, 2015
+ *      Re-started: June      25th, 2016    ported from F411 board
+ *      Revised:    Novemeber 23rd, 2016
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef         MBED_FRQ_CUNTR
+#define         MBED_FRQ_CUNTR
+
+#include "mbed.h"
+
+#define DEBUG   0  // use Communication with PC(UART)
+
+typedef union
+{
+    struct {
+        uint64_t    f_1sec_dt;
+    };
+    struct {
+        uint32_t    freq_dt;
+        uint16_t    f_sw_dt;
+        uint16_t    t_cnt;
+    };
+} freq_one;
+
+namespace Frequency_counter
+{
+
+/** Frequency Counter program
+ *  Only for ST Nucleo-F746ZG Board
+ *
+ * @code
+ * #include "mbed.h"
+ * #include "frq_cuntr_f746.h"
+ *
+ * using namespace Frequency_counter;
+ *
+ * // frequency input  -> PC_6 & PA_3
+ * // 50MHz base clock -> PA_5, GPS 1PPS -> PA_1
+ * // Connect -> three ports,PA_7,PB_10 and PC_7 connected together
+ * // CAUTION!!: SB13 & SB181 must remove from Nucleo-F746ZG board
+ *
+ * FRQ_CUNTR    fc(49.999992f); // External base clock freq.
+ *
+ * int main() {
+ *   double   cntr_1pps = 0;
+ *   double   frequency = 0;
+ *   while(true) {
+ *      while (fc.status_1pps() == 0) {;}
+ *      cntr_1pps = fc.read_avarage_1pps();
+ *      while (fc.status_freq_update() == 0) {;}
+ *      frequency = fc.read_compensated_freq_data_w_gt(1); // 1sec gate
+ *      printf("1PPS/ave = %%11.3f, FREQ. = %11.1f\r\n", cntr_1pps, frequency);
+ *   }
+ * }
+ * @endcode
+ */
+
+class FRQ_CUNTR
+{
+
+public:
+
+    /** Configure counter
+      * @param Base clock Frequency [MHz]
+      */
+    FRQ_CUNTR(double ex_clock);
+
+    /** Read new frequency data (gate time = 1sec)
+      * @param none
+      * @return frequency data
+      */
+    double read_freq_data(void);
+
+    /** Read new frequency data with specific gate time
+      * @param gate time [sec] (1 sec to over 1 hour)
+      * @return frequency data
+      */
+    double read_compensated_freq_data_w_gt(uint16_t gt);
+    // get raw data
+    double read_freq_w_gate_time(uint16_t gt);
+
+    /** Read status (new frequency data is available or not)
+      * @param none
+      * @return !=0: new data is avairable, 0: not yet
+      */
+    uint32_t status_freq_update(void);
+    
+    /** Read avarage measured data GPS 1PPS
+      * @param none
+      * @return Base clock frequency(average 1(not ave!), 10, 100 & 1000)
+      */
+    double read_avarage_1pps(void);
+
+    /** Read number of buffered data
+      * @param none
+      * @return number of data in the buffer
+      */
+    uint32_t read_num_in_buffer(void);
+
+    /** Read newest measured data GPS 1PPS
+      * @param none
+      * @return Base clock frequency (newest(no avaraging value))
+      */
+    uint32_t read_newest_1pps(void);
+
+    /** Read status (new 1PPS data is available or not)
+      * @param none
+      * @return !=0: new data is avairable, 0: not yet
+      */
+    uint32_t status_1pps(void);
+
+    /** Read GPS status
+      * @param none
+      * @return     0: GPS is NOT ready
+      *         not 0: 1PPS data is avairable & show gate_time for avarage
+      */
+    uint32_t status_gps(void);
+
+    /** Reciprocal measurement
+      * preparation for Reciprocal measurement -> recipro_start_measure
+      * check frequency input as IC trigger -> recipro_check_trigger
+      * read IC data -> recipro_read_data
+      */
+    void     recipro_start_measure(void);
+    uint32_t recipro_check_trigger(void);
+    uint32_t recipro_read_data(void);
+
+    /** This is a "DEBUG PURPOSE" function
+      * Check Base clock frequency on TIM2 or/and TIM8+4
+      * print internal data (need to define "DEBUG")
+      * @param gate time e.g. 1sec = 1.0f
+      * @return Frequency
+      *     read_base_clock_frequency -> TIM2 data
+      *     read_input_frequency      -> TIM8+4 data
+      */
+    uint32_t read_base_clock_frequency(double gatetime);
+    uint32_t read_input_frequency(double gatetime);
+
+    /** This is a "DEBUG PURPOSE" function
+      * print internal data (No need to define "DEBUG")
+      * @param none
+      * @return none (just print tha data)
+      */
+    void debug_printf_internal_data(void);      
+    void debug_printf_all_buffer(void);
+
+protected:
+    void     initialize_Freq_counter(void); // Initialize timers
+    void     initialize_TIM2(void);         // Initialize Timer2 (32bit)
+    void     initialize_TIM8P4(void);       // Initialize Timer8 + 4 (16+16bit)
+    void     set_external_clock(double ex_clock); // Set OC data
+    uint32_t calc_1PPS_newest(void);        // Calculate GPS 1PPS newest data
+    uint32_t read_ic2_counter_TIM2(void);   // Read TIM2 captured counter data
+    uint32_t check_ic2_status_TIM2(void);   // Check TIM2 IC2 status
+    uint32_t read_counter_TIM8P4(void);     // Read TIM8+4 captured counter data
+    uint32_t check_ic1_status_TIM8P4(void); // Check TIM8 IC2 & TIM4 IC1 status
+    uint8_t  read_oc_port_status(void);     // Check TIM2 OC port
+    void     set_1sec_gate_time(void);      // Set one second gate time
+    uint64_t get_diff(uint64_t new_dt, uint64_t old_dt);
+
+private:
+    double   newest_frequency;
+    double   ex_clock_freq;
+    uint32_t gate_time;
+    uint32_t ex_clk_base;
+    uint32_t clk_hi_const;
+    uint32_t clk_upper_limit;
+    uint32_t clk_lower_limit;
+    uint32_t  gps_ready;
+    // TIM2
+    uint32_t counter_tim2;
+    uint32_t old_cntr_tim2;
+    // TIM8+4
+    uint32_t counter_tim8p4;
+    uint32_t old_cntr_tim8p4;
+    uint16_t sw_ovrflw_tim8p4;
+    // 1PPS data
+    uint32_t onepps_newest;
+    uint8_t  onepps_ready_flg;
+
+};
+
+/*
+    Interrupt handler does NOT work following code
+    NVIC_SetVector(TIM2_IRQn, (uint32_t)FRQ_CUNTR::irq_ic2_TIM2);
+    From this reason, I wrote below code and set interrupt handler
+    out side "FRQ_CUNTR" class
+    NVIC_SetVector(TIM2_IRQn, (uint32_t)irq_ic2_TIM2);
+ */
+void irq_ic2_TIM2(void);    // TIM2 IC2 Interrupt control
+void irq_ic1_TIM8P4(void);  // TIM4 IC1 Interrupt control (also TIM8 IC2)
+
+}   // Frequency_counter
+
+#endif  // MBED_FRQ_CUNTR
+