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

Dependencies:   QEI DRV8830 PID ADT7410 TextLCD Frq_cuntr_Nucleo-F746ZG RingBuffer

Fork of Frequency_Counter_w_GPS_1PPS by Kenji Arai

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

Revision:
13:1041596c416c
Child:
14:ba6ea409ab05
diff -r 05098414599b -r 1041596c416c User_IF/uif.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/User_IF/uif.cpp	Wed Nov 23 07:35:20 2016 +0000
@@ -0,0 +1,558 @@
+/*
+ * mbed Application program / User Interface subroutines
+ *
+ * Copyright (c) 2016 Kenji Arai / JH1PJL
+ *  http://www.page.sannet.ne.jp/kenjia/index.html
+ *  http://mbed.org/users/kenjiArai/
+ *      Created:    September 28th, 2016
+ *      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.
+ */
+
+#define     USE_COM         // use Communication with PC(UART)
+
+//  Include --------------------------------------------------------------------
+#include    "mbed.h"
+#include    "rtos.h"
+#include    "frq_cuntr_f746.h"
+#include    "TextLCD.h"
+#include    "QEI.h"
+#include    "uif.h"
+
+//  Definition -----------------------------------------------------------------
+#define ONLY_VALUE          1       // Uart (output only value)
+
+#ifdef  USE_COM
+#define BAUD(x)         pc.baud(x)
+#define GETC(x)         pc.getc(x)
+#define PUTC(x)         pc.putc(x)
+#define PRINTF(...)     pc.printf(__VA_ARGS__)
+#define READABLE(x)     pc.readable(x)
+#else
+#define BAUD(x)         {;}
+#define GETC(x)         {;}
+#define PUTC(x)         {;}
+#define PRINTF(...)     {;}
+#define READABLE(x)     {;}
+#endif
+
+//  Object ---------------------------------------------------------------------
+extern Serial       pc;
+extern Ticker       enter_irq;
+extern DigitalOut   in_frq_slct;
+extern DigitalInOut prescaler10or20;
+
+QEI         rotary(PE_9, PF_13, NC, 24, QEI::X4_ENCODING); //Rotary chB,chA
+TextLCD     lcd(PD_3, PC_3, PD_4, PD_5, PD_6, PD_7, TextLCD::LCD20x4);
+DigitalOut  led_R_gps1pps(PE_7);
+DigitalOut  led_G_temp_ok(PE_8);
+DigitalOut  led_B_recipro(PG_9);
+DigitalOut  led_W_prescaler(PG_14);
+DigitalOut  led_R_rotary(PF_15);
+DigitalOut  led_G_rotary(PE_13);
+DigitalOut  led_B_rotary(PF_14);
+DigitalIn   rotary_sw(PE_11);
+
+//  RAM ------------------------------------------------------------------------
+int8_t      function_num;
+// working area
+char        buf[40];
+// write mode control
+uint8_t     mode_change_flg = 0;
+// Prescaler selct
+uint8_t     prescaler_on = 0;
+uint8_t     prescaler_div20 = 0;
+// Rotary switch
+uint32_t    enter = 0;
+uint8_t     enter_first_flg = 0;
+// Time
+time_t      seconds;
+time_t      seconds_jst;
+// Reciprocal data
+extern
+uint8_t     recipro_new_data_ready;
+
+//  Function prototypes --------------------------------------------------------
+static int8_t rotary_sw_update(void);
+static void change_setting(void);
+static void uart_output(dispDef *dt);
+static void led_update(dispDef *dt);
+static void dsp_freq(dispDef *dt);
+static void dsp_1pps(dispDef *dt);
+static void dsp_detail(dispDef *dt);
+static void dsp_simple(dispDef *dt);
+static void dsp_recipro(dispDef *dt);
+static void dsp_gps_status(dispDef *dt);
+static void dsp_current_setting(dispDef *dt);
+
+//  ROM / Constant data --------------------------------------------------------
+                            //  12345678901234567890
+static char *const msg_clear = "                    ";
+static char *const msg_msg0  = "Frequency Counter   ";
+static char *const msg_msg1  = " mbed Nucleo F746ZG ";
+static char *const msg_msg2  = "   by JH1PJL K.Arai ";
+static char *const msg_msg3  = "   "__DATE__" UTC";
+static char *const msg_msg4  = "Getting GPS,pls wait";
+
+// function table
+void (*functptr[])(dispDef*) = {
+         dsp_freq,
+         dsp_1pps,
+         dsp_detail,
+         dsp_simple,
+         dsp_recipro,
+         dsp_gps_status,
+         dsp_current_setting
+};
+
+//------------------------------------------------------------------------------
+//  Control Program
+//------------------------------------------------------------------------------
+void dispay_LCD_and_UART(dispDef *dt)
+{
+    uint8_t  size;
+
+    uart_output(dt);
+    display_clear_all();
+    led_update(dt);
+    if (mode_change_flg == 0){
+        led_B_rotary = !led_B_rotary;
+        led_R_rotary = 0;
+        function_num += rotary_sw_update();
+        //size = sizeof(*functptr); // doesn't work
+        size = 7;
+        if (function_num >= size){
+            function_num = 0;
+        } else if (function_num < 0){
+            function_num = size - 1;
+        }
+        (*functptr[function_num])(dt);   // pick one function from a table
+    } else {
+        led_B_rotary = 0;
+        led_R_rotary = !led_R_rotary;
+        change_setting();
+    }
+}
+
+void change_setting()
+{
+    static int8_t  n;
+    static int8_t  old_mode_change_flg;
+    uint8_t  p;
+
+    lcd.locate(0, 0);
+            //  12345678901234567890
+    lcd.printf("            1/1  BNC");
+    lcd.locate(0, 1);
+            //  12345678901234567890
+    lcd.printf("            1/10 SMA");
+    lcd.locate(0, 2);
+            //  12345678901234567890
+    lcd.printf("            1/20 SMA");
+    lcd.locate(0, 3);
+            //  12345678901234567890
+    lcd.printf("Select then push SW!");
+    n += rotary_sw_update();
+    if (n < 0){
+        p = n * -1;
+    } else {
+        p = n;
+    }
+    p %= 3;
+    lcd.locate(0, p);
+            //  12345678901234567890
+    lcd.printf("--->>>");
+    if (old_mode_change_flg != mode_change_flg){
+        if (mode_change_flg == 1){
+            old_mode_change_flg = mode_change_flg;
+        } else {
+            select_input_div_1or10or20(p);
+            mode_change_flg = 0;
+            old_mode_change_flg = 0;
+        }
+    }
+}
+
+// Display LED's
+static void led_update(dispDef *dt)
+{
+    if (dt->ready_1pps == 3) {
+        led_R_gps1pps = 1;
+    } else {
+        led_R_gps1pps = 0;
+    }
+    if (prescaler_on){
+        if (prescaler_div20){
+            led_W_prescaler = !led_W_prescaler;
+        } else {
+            led_W_prescaler = 1;
+        }
+    } else {
+        led_W_prescaler = 0;
+    }
+    if (dt->recipro_of == 0){
+        led_B_recipro = 1;
+    } else {
+        led_B_recipro = 0;
+    }
+    if (dt->temp_is_okay == 1){
+        led_G_temp_ok = 1;
+    } else {
+        led_G_temp_ok = 0;
+    }
+}
+
+// Data output via VCOM line
+static void uart_output(dispDef *dt)
+{
+    static uint32_t n = 0;
+
+    PRINTF("%9.0f,", dt->m_frq);
+    PRINTF("%10d,", dt->b_1pps_new);
+    // compensated
+    PRINTF("%12.3f,", dt->m_frq_comp);
+    PRINTF("%13.3f,", dt->b_1pps_lng);
+    // 10sec data
+    PRINTF("%10.1f,", dt->m_frq_10);
+    // 100sec data
+    PRINTF("%11.2f,", dt->m_frq_100);
+    // 1000sec data
+    PRINTF("%12.3f,", dt->m_frq_1000);
+    if (recipro_new_data_ready){
+        recipro_new_data_ready = 0;
+        if (dt->recipro_of){
+            PRINTF("over5KHz   ,");
+        } else {
+            PRINTF("%12.6f,", dt->m_frq_recipro);
+        }
+    } else {
+        PRINTF("measuring   ,");
+    }
+    if (prescaler_on){
+        if (prescaler_div20){
+            PRINTF("Div20,");
+        } else {
+            PRINTF("Div10,");
+        }
+    } else {
+        PRINTF("Div1 ,");
+    }           
+    PRINTF("%+6.3f,", dt->box_tmp);
+    seconds = time(NULL);
+    seconds_jst = seconds + 32400;   // +9 hours ->JST
+    //                 13:12:11
+    strftime(buf, 40, "%H:%M:%S", localtime(&seconds_jst));
+    PRINTF("%s,", buf);
+    // Number
+    PRINTF("%08d\r\n", n++);
+}
+
+void select_input_div_1or10or20(uint8_t mode)
+{
+    if (mode == 2){             // 1/20
+        prescaler_on = 1;
+        prescaler_div20 = 1;
+        in_frq_slct = 0;    // Select SMA input with pre-scaler
+        prescaler10or20.input();
+    } else if (mode == 1){      // 1/10
+        prescaler_on = 1;
+        prescaler_div20 = 0;
+        in_frq_slct = 0;    // Select SMA input with pre-scaler
+        prescaler10or20.output();
+        prescaler10or20 = 0;
+    } else {
+        prescaler_on = 0;
+        prescaler_div20 = 0;
+        in_frq_slct = 1;    // Select BNC
+        //prescaler10or20 = 1;
+        prescaler10or20.output();
+        prescaler10or20 = 0;
+    }
+}
+
+// Interrupt handler for Rotary SW Push bottom
+void enter_action() {
+    if (rotary_sw == 1){
+        enter_first_flg = 1;
+    } else {
+        if (enter_first_flg){
+            if (enter++ > 2){
+                enter = 0;
+                mode_change_flg++;    // action trigger for SW on
+                enter_first_flg = 0;
+            }
+        }
+    }
+}
+
+// Detect rotary switch rotation
+static int8_t rotary_sw_update()
+{
+    static int8_t position_old;
+    int8_t pos, dt;
+
+    pos = rotary.getPulses()/4;
+    if (pos != position_old){
+        if (pos > position_old){
+            if (pos < 0){
+                dt = -1;
+            } else {
+                dt =  1;
+            }
+        } else {
+            if (pos < 0){
+                dt =  1;
+            } else {
+                dt = -1;
+            }
+        }
+    } else {
+        dt = 0;
+    }
+    position_old = pos;
+    return dt;      
+}
+
+//******************************************************************************
+static void dsp_freq(dispDef *dt)
+{
+    lcd.locate(0, 0);
+    if (prescaler_on == 0){
+        lcd.printf("Freq = %8.0f Hz", dt->m_frq);
+    } else if (prescaler_div20){
+        lcd.printf("Freq = %7.4fMHz", dt->m_frq * 20.0f);    // 1/20
+    } else {
+        lcd.printf("Freq = %8.5fMHz", dt->m_frq * 10.0f);    // 1/10
+    }
+    lcd.locate(0, 1);
+    if (dt->m_frq_10 == 0.0f){
+        lcd.printf("10s  =    not yet");
+    } else {
+        if (prescaler_on == 0){
+            lcd.printf("10s  = %9.1f", dt->m_frq_10);
+        } else if (prescaler_div20){
+            lcd.printf("10s  =  %8.5f", dt->m_frq_10 * 20.0f);    // 1/20
+        } else {
+            lcd.printf("10s  =  %9.6f", dt->m_frq_10 * 10.0f);    // 1/10
+        }
+    }
+    lcd.locate(0, 2);
+    if (dt->m_frq_100 == 0.0f){
+        lcd.printf("100s =    not yet");
+    } else {
+        if (prescaler_on == 0){
+            lcd.printf("100s = %10.2f",  dt->m_frq_100);
+        } else if (prescaler_div20){
+            lcd.printf("100s =  %9.6f",  dt->m_frq_100 * 20.0f);    // 1/20
+        } else {
+            lcd.printf("100s =  %10.7f", dt->m_frq_100 * 10.0f);    // 1/10
+        }
+    }
+    lcd.locate(0, 3);
+    if (dt->m_frq_1000 == 0.0f){
+        strftime(buf,40, "%I:%M:%S%p (%m/%d)", localtime(&seconds_jst));
+        lcd.printf("%s %d", buf, function_num);
+    } else {
+        if (prescaler_on == 0){
+            lcd.printf("1000s= %11.3f", dt->m_frq_1000);
+        } else if (prescaler_div20){
+            lcd.printf("1000s=  %10.7f", dt->m_frq_1000 * 20.0f);    // 1/20
+        } else {
+            lcd.printf("1000s=  %11.8f", dt->m_frq_1000 * 10.0f);    // 1/10
+        }
+    } 
+}
+
+static void dsp_1pps(dispDef *dt)
+{
+    lcd.locate(0, 0);
+    if (dt->m_frq_10 == 0.0f){
+        lcd.printf("10s  =    not yet");
+    } else {
+        if (prescaler_on == 0){
+            lcd.printf("10s  = %9.1f", dt->m_frq_10);
+        } else if (prescaler_div20){
+            lcd.printf("10s  =  %8.5f", dt->m_frq_10 * 20.0f);    // 1/20
+        } else {
+            lcd.printf("10s  =  %9.6f", dt->m_frq_10 * 10.0f);    // 1/10
+        }
+    }
+    lcd.locate(0, 1);
+    lcd.printf("1PPS = %8d Hz", dt->b_1pps_new);
+    lcd.locate(0, 2);
+    lcd.printf("Oven Temp= %+5.2f%cC", dt->box_tmp, 0xdf);
+    lcd.locate(0, 3);
+    strftime(buf,40, "%I:%M:%S%p (%m/%d)", localtime(&seconds_jst));
+    lcd.printf("%s %d", buf, function_num);
+}
+
+static void dsp_detail(dispDef *dt)
+{
+    lcd.locate(0, 0);
+    if (dt->m_frq_100 == 0.0f){
+        lcd.printf("100s =    not yet");
+    } else {    
+        if (prescaler_on == 0){
+            lcd.printf("100s = %11.2f",  dt->m_frq_100);
+        } else if (prescaler_div20){
+            lcd.printf("100s =  %9.6f",  dt->m_frq_100 * 20.0f);    // 1/20
+        } else {
+            lcd.printf("100s =  %10.7f", dt->m_frq_100 * 10.0f);    // 1/10
+        }
+    }
+    lcd.locate(0, 1);
+    if (dt->gps_1pps_ave == 1000){
+        lcd.printf("1PPS = %12.3f ", dt->b_1pps_lng);
+    } else if (dt->gps_1pps_ave == 100){
+        lcd.printf("1PPS = %11.2f ", dt->b_1pps_lng);
+    } else if (dt->gps_1pps_ave == 10){
+        lcd.printf("1PPS = %10.1f ", dt->b_1pps_lng);
+    } else {
+        lcd.printf("1PPS = %9.0f " , dt->b_1pps_lng);
+    }
+    lcd.locate(0, 2);
+    lcd.printf("Oven Temp= %+6.3f%cC", dt->box_tmp, 0xdf);
+    lcd.locate(0, 3);
+    strftime(buf,40, "%I:%M:%S%p (%m/%d)", localtime(&seconds_jst));
+    lcd.printf("%s %d", buf, function_num);
+}
+
+static void dsp_simple(dispDef *dt)
+{
+    lcd.locate(0, 0);
+    if (prescaler_on == 0){
+        lcd.printf("Freq =  %8.0f Hz", dt->m_frq);
+    } else if (prescaler_div20){
+        lcd.printf("Freq =  %7.4fMHz", dt->m_frq * 20.0f);    // 1/20
+    } else {
+        lcd.printf("Freq =  %8.5fMHz", dt->m_frq * 10.0f);    // 1/10
+    }
+    lcd.locate(0, 1);
+    lcd.printf("1PPS =  %8d Hz", dt->b_1pps_new);
+    lcd.locate(0, 2);
+    lcd.printf("Oven Temp= %+3.0f%cC", dt->box_tmp, 0xdf);
+    lcd.locate(0, 3);
+    strftime(buf,40, "%I:%M:%S%p (%m/%d)", localtime(&seconds_jst));
+    lcd.printf("%s %d", buf, function_num);
+}
+
+static void dsp_recipro(dispDef *dt)
+{
+    if ((prescaler_on != 0) || (dt->recipro_of == 1)){
+        display_clear_all();
+        lcd.locate(0, 0);
+        //          12345678901234567890
+        lcd.printf(" Reciprocal data is");
+        lcd.locate(0, 1);
+        lcd.printf("  Not avairable ");
+        lcd.locate(0, 3);
+        //          12345678901234567890
+        lcd.printf("                   %d", function_num);
+    } else {
+        lcd.locate(0, 0);
+        //          12345678901234567890
+        lcd.printf("Reciprocal [Hz]     ");
+        lcd.locate(0, 1);
+        if (dt->recipro_of){
+            //          12345678901234567890
+            lcd.printf("    5KHz over       ");
+        } else {
+            lcd.printf(" %11.6f,", dt->m_frq_recipro);
+        }
+        lcd.locate(0, 2);
+        lcd.printf("Oven Temp= %+6.3f%cC", dt->box_tmp, 0xdf);
+        lcd.locate(0, 3);
+        strftime(buf,40, "%I:%M:%S%p (%m/%d)", localtime(&seconds_jst));
+        lcd.printf("%s %d", buf, function_num);
+    }
+}
+
+static void dsp_current_setting(dispDef *dt)
+{
+    lcd.locate(0, 0);
+            //  12345678901234567890
+    lcd.printf("Current setting     ");
+    lcd.locate(0, 1);
+    if (prescaler_on == 1){
+        if (prescaler_div20 == 1){
+                    //  12345678901234567890
+            lcd.printf(" Prescaler =ON  1/20");
+        } else {
+                    //  12345678901234567890
+            lcd.printf(" Prescaler =ON  1/10");
+        }
+    } else {
+                //  12345678901234567890
+        lcd.printf(" None-Prescaler(BNC)");
+    }
+    lcd.locate(0, 2);
+            //  12345678901234567890
+    lcd.printf("Change parameter    ");
+    lcd.locate(0, 3);
+            //  12345678901234567890
+    lcd.printf(" -> Push Switch    %d", function_num);
+}
+
+static void dsp_gps_status(dispDef *dt)
+{
+    lcd.locate(0, 0);
+    //          12345678901234567890
+    lcd.printf("GPS status          ");
+    lcd.locate(0, 1);
+    //          12345678901234567890
+    lcd.printf("  3D or not --> %u  ", dt->ready_1pps);
+    lcd.locate(0, 2);
+    lcd.printf("Oven Temp= %+6.3f%cC", dt->box_tmp, 0xdf);
+    lcd.locate(0, 3);
+    strftime(buf,40, "%I:%M:%S%p (%m/%d)", localtime(&seconds_jst));
+    lcd.printf("%s %d", buf, function_num);
+}
+
+// Clear LCD screen
+void display_clear_all(void)
+{
+    lcd.locate(0, 0);
+    lcd.printf(msg_clear);
+    lcd.printf(msg_clear);
+    lcd.printf(msg_clear);
+    lcd.printf(msg_clear);
+}
+
+// Openning message on LCD & message via VCOM
+void disp_first_msg(void)
+{
+//    lcd.setCursor(LCDCursol 0);   // Cursol off
+    // LCD Initial screen
+    lcd.locate(0, 0);
+    lcd.printf(msg_msg0);
+    lcd.printf(msg_msg1);
+    lcd.printf(msg_msg2);
+    lcd.printf(msg_msg3);
+    // Clear all LED
+    led_R_gps1pps = 0;
+    led_W_prescaler = 0;
+    led_R_rotary = 0;
+    led_G_rotary = 0;
+    led_B_rotary = 0;
+    // VCOM message
+    BAUD(9600);
+    PRINTF("\r\nFrequency Counter by JH1PJL created on "__DATE__"\r\n");
+    PRINTF("\r\nStarted!\r\n");
+    PRINTF("SystemCoreClock = %d Hz\r\n", SystemCoreClock);
+    // Rotary switch control
+    enter_irq.attach_us(&enter_action, 5000);  // every 5mS
+}
+
+// GPS waiting message
+void disp_wait_gps(void)
+{
+    lcd.locate(0, 3);
+    lcd.printf(msg_msg4);
+}