Frequency counter library only for DISCO-F746NG & NucleoF411RE +F446RE

Dependencies:   RingBuff

Dependents:   FreqCntr_GPS1PPS_F746F4xx_w_recipro Freq_Cntr_GPS1PPS_F746NG_GUI

Fork of Frq_cuntr_full by Kenji Arai

Revision:
5:783b039f9119
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/fc_GPS1PPS.h	Wed Nov 16 13:13:09 2016 +0000
@@ -0,0 +1,205 @@
+/*
+ * mbed Library / Frequency Counter using GPS 1PPS gate pulse
+ *      Frequency Counter program
+ *      Only for ST DISCO-F746NG and Nucleo-F411RE+F446RE
+ *
+ * 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
+ *      Re-started: October    5th, 2016    Change board -> DISCO-F746NG
+ *      Re-started: October   17th, 2016    Continue F746 and back to F411
+ *      Revised:    November  13th, 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.
+ */
+
+/*
+--------------------------------------------------------------------------------
+********* Frequency Counter Functions *********
+Mesurement frequency:  1Hz to 100MHz
+Extended range:        Up to 1GHz (1/10 prescaler) or more over (1/20)
+Gate time:             1 sec to 4095sec (extend to more if RAM is avairable)
+1 PPS:                 GPS receiver(u-blux7/NEO-7) with an external antenna
+Additional function:   Reciprocal measurement (less tha 10KHz)
+
+********* Hardware Configration (Board is only ST DISCO-F746NG) *********
+frequency input:       PC_6(D1) & PB10(No assign to connector!)
+GPS 1PPS:              PA_15(D9), PB_8(D15) & PC_7(D0)
+
+********* Hardware Configration (Board is only ST Nucleo-F411RE) *********
+RESTRICTION -> Max input freqency is 48MHz due to system clock limitation
+frequency input:       PA_8(D7) & PA_0(A0)
+GPS 1PPS:              PA_9(D8), PB_0(A3) & PA_1(A1)
+--------------------------------------------------------------------------------
+*/
+
+#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 DISCO-F746NG Board(Nucleo-F411RE & F446RE also)
+ *
+ * @code
+ * #include "mbed.h"
+ * #include "fc_GPS1PPS.h"
+ *
+ * using namespace Frequency_counter;
+ *
+ * //----F746---- max input f=100MHz
+ * // frequency input  -> PC_6 & PA15(for reciprocal)
+ * // GPS 1PPS -> PB_8,PC_7 & PB_10(for reciprocal)
+ * //----F411---- max input f=48MHz
+ * //----F446---- max input f=90MHz
+ * // frequency input  -> PA_8 & PA_0(for reciprocal)
+ * // GPS 1PPS -> PA_9, PB_0 & PA_1(for reciprocal)
+ *
+ * FRQ_CUNTR    fc;
+ *
+ * int main() {
+ *   double   frequency = 0;
+ *   while(true) {
+ *      while (fc.status_freq_update() == 0) {;}
+ *      frequency = fc.read_freq_data(); // 1sec gate
+ *      printf("FREQ. = %11.1f\r\n", frequency);
+ *   }
+ * }
+ * @endcode
+ */
+
+class FRQ_CUNTR
+{
+
+public:
+
+    /** Configure counter
+      * @param none
+      */
+    FRQ_CUNTR(void);
+
+    /** 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(F746) or 17 minutes)
+      * @return frequency 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);
+
+    /** Reset buffered data
+      * @param none
+      * @return none
+      */
+    void reset_buffered_data(void);
+
+    /** Reciprocal measurement (Step1)
+      * preparation for Reciprocal measurement
+      * @param none
+      * @return none
+      */
+    void recipro_start_measure(void);
+
+    /** Reciprocal measurement (Step2)
+      * check frequency input as IC trigger
+      * @param none
+      * @return 1: done, 0: not yet
+      */
+    uint32_t recipro_check_trigger(void);
+
+    /** Reciprocal measurement (Step3)
+      * read period data
+      * @param none
+      * @return frequency data
+      */
+    uint32_t recipro_read_data(void);
+
+    /** Reciprocal measurement (Step4)
+      * read period data
+      * @param gate time [sec] (1 sec to over 1 hour)
+      * @return time base clock frequency data
+      */
+    uint32_t recipro_base_clk_data(uint16_t gt);
+
+    /** "DEBUG PURPOSE" function
+      * Check input frequency on TIM8+4 or TIM1+3
+      * print internal data (need to define "DEBUG")
+      * @param gate time e.g. 1sec = 1.0f
+      * @return frequency data
+      */
+    uint32_t debug_read_input_frequency(double gatetime);
+
+    /** "DEBUG PURPOSE" function
+      * Check input frequency on TIM2
+      * print internal data (need to define "DEBUG")
+      * @param gate time e.g. 1sec = 1.0f
+      * @return frequency data
+      */
+    uint32_t debug_read_base_clock_frequency(double gatetime);
+
+    /** "DEBUG PURPOSE" function
+      * print internal data (No need to define "DEBUG")
+      * @param none
+      * @return none (just print tha data)
+      */     
+    void debug_printf_all_buffer(void);
+
+protected:
+    void     start_action(void);        // Start trigger for reciprocal
+    void     initialize_TIMxPy(void);   // Initialize Timer_x + _y (16+16bit)
+    void     initialize_TIMz(void);     // Initialize Timer_z (32bit)
+    uint64_t get_diff(uint64_t new_dt, uint64_t old_dt);
+
+private:
+    double   newest_frequency;
+
+};
+
+/*
+    Interrupt handler does NOT work following code
+    NVIC_SetVector(TIM4_IRQn, (uint32_t)FRQ_CUNTR::irq_ic_TIMxPy);
+    From this reason, I wrote below code and set interrupt handler
+    out side "FRQ_CUNTR" class
+    NVIC_SetVector(TIM4_IRQn, (uint32_t)irq_ic_TIMxPy);
+ */
+    void irq_ic_TIMxPy(void);  // TIM4(F746) or TIM3(F411) IC Interrupt
+    void irq_ic_TIMz(void);    // TIM2(F746 & F411) IC Interrupt
+
+}   // Frequency_counter
+
+#endif  // MBED_FRQ_CUNTR