Very simple but enough accuracy "Frequency Counter". Using GPS 1PPS signal for 1sec gate. CPU is F746, F446 and F411.

Dependencies:   fc_GPS1PPS_f746_f4xx iSerial mbed

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

Concept block are follows.
F746
/media/uploads/kenjiArai/block_diagram_fc_f746_wo_oven.pdf
F411&F446
/media/uploads/kenjiArai/block_diagram_fc_f411_wo_oven.pdf
Hardware Circuit(common F746,F446 and F411)
/media/uploads/kenjiArai/fc_f746ng_circuit.pdf
/media/uploads/kenjiArai/f746_fc_1.jpg

Files at this revision

API Documentation at this revision

Comitter:
kenjiArai
Date:
Wed Nov 16 13:22:00 2016 +0000
Commit message:
Frequency counter program. Using GPS 1PPS signal. ; Frequency measurement range 0.01 Hz to Over 1.5GHz (F746 & F446) or 0.8GHz.; This is very simple way but enough accuracy.

Changed in this revision

GPS_rcvr/GPSrcvr.cpp Show annotated file Show diff for this revision Revisions of this file
GPS_rcvr/GPSrcvr.h Show annotated file Show diff for this revision Revisions of this file
fc_GPS1PPS_f746_f4xx.lib Show annotated file Show diff for this revision Revisions of this file
iSerial.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/GPS_rcvr/GPSrcvr.cpp	Wed Nov 16 13:22:00 2016 +0000
@@ -0,0 +1,386 @@
+/*
+ * mbed Application program / GPS receiver control and 1PPS output
+ *
+ * Copyright (c) 2004,'09,'10,'16 Kenji Arai / JH1PJL
+ *  http://www.page.sannet.ne.jp/kenjia/index.html
+ *  http://mbed.org/users/kenjiArai/
+ *      Created: March     28th, 2004   Kenji Arai
+ *      updated: July      25th, 2009   for PIC24USB
+ *      updated: January   16th, 2010   change to GPS-GM318
+ *      updated: April     24th, 2010   for mbed / NXP LPC1768
+ *      Revised: Nomeber   14th, 2016
+ */
+
+//  Include --------------------------------------------------------------------
+#include    <string.h>
+#include    "mbed.h"
+#include    "GPSrcvr.h"
+#if defined(TARGET_NUCLEO_F411RE) || defined(TARGET_NUCLEO_F446RE)
+#include    "iSerial.h"
+#elif defined(TARGET_STM32F746NG)
+#include    "RingBuffer.h"
+#endif
+
+//  Definition -----------------------------------------------------------------
+//#define     USE_DEBUG
+
+#ifdef      USE_DEBUG
+#define     U_DEBUGBAUD(x)  pc.baud(x)
+#define     U_DEBUG(...)    pc.printf(__VA_ARGS__)
+#define     DBG(c)          pc.putc(c)
+#else
+#define     U_DEBUGBAUD(x)  {;}
+#define     U_DEBUG(...)    {;}
+#define     DBG(c)          {;}
+#endif
+
+#define     GSP_BUF_B       (128 * 3)
+#define     GPS_BUF_S       (128 * 2)
+
+//  Object ---------------------------------------------------------------------
+#if defined(TARGET_NUCLEO_F411RE) || defined(TARGET_NUCLEO_F446RE)
+DigitalIn   gps_rx(PC_7);       // for checking GPS RX line
+iSerial     gps(NC, PC_7, 0, 1024); // GPS Data receive
+#elif defined(TARGET_STM32F746NG)
+RingBuffer  rxbuf(1024);        // can receive all information every one sec
+DigitalIn   gps_rx(PF_6);       // for checking GPS RX line
+Serial      gps(NC, PF_6);      // GPS Data receive
+#else
+#error "Target is only Nucleo-F411RE(F446RE) or DISCO-F746NG!!!"
+#endif
+
+extern Serial pc;
+
+//  RAM ------------------------------------------------------------------------
+bool        gps_is_okay_flag;
+uint8_t     gps_ready;
+uint8_t     gps_status;
+uint8_t     gps_rmc_ready;
+char        GPS_Buffer[GSP_BUF_B];       //GPS data buffer
+char        MsgBuf_RMC[GPS_BUF_S];
+char        MsgBuf_GSA[GPS_BUF_S];
+char        MsgBuf_GGA[GPS_BUF_S];
+
+//  Function prototypes --------------------------------------------------------
+uint8_t     check_gps_3d(void);
+uint8_t     check_gps_ready(void);
+void        get_time_and_date(struct tm *pt);
+void        getline_gps(void);
+void        gps_data_rcv(void);
+#if defined(TARGET_STM32F746NG)
+void        iGPSrcv_initialize(void);
+int         iGPS_readable(void);
+int         iGPS_getc(void);
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+// Receive GPS data using Interrupt handler
+//
+// !!! Takes urgent and dirty solution by due to IRQ restriction
+//      on mbed library (reason is unknown as of today)
+// reference source file:stm32f746xx.h
+//     under /mbed-dev/targets/cmsis/TARGET_STM/TARGET_NUCLEO_F746ZG
+////////////////////////////////////////////////////////////////////////////////
+#if defined(TARGET_STM32F746NG)
+
+// ------ Interrupt Function ------
+void rx_handler(void)
+{
+    uint32_t reg = UART7->ISR;
+    if (reg && USART_ISR_RXNE){ // data is ready to read
+        UART7->ISR &= ~(USART_ISR_RXNE + USART_ISR_PE + USART_ISR_FE
+                        + USART_ISR_NE + USART_ISR_ORE);
+        rxbuf.save((unsigned char)UART7->RDR);   
+    }
+}
+
+void iGPSrcv_initialize(void)
+{
+    __disable_irq();
+    UART7->CR1 &= ~(USART_CR1_TE + USART_CR1_TCIE + USART_CR1_TXEIE
+                     + USART_CR1_PEIE + USART_CR1_IDLEIE);
+    UART7->CR1 |= (USART_CR1_RXNEIE + USART_CR1_RE + USART_CR1_UE);
+    NVIC_SetVector(UART7_IRQn, (uint32_t)rx_handler);
+    NVIC_ClearPendingIRQ(UART7_IRQn);
+    NVIC_EnableIRQ(UART7_IRQn);
+    __enable_irq();
+#if 0
+    printf("UART7->CR1  0x%08x:0x%08x\r\n", &UART7->CR1, UART7->CR1);
+    printf("UART7->CR2  0x%08x:0x%08x\r\n", &UART7->CR2, UART7->CR2);
+    printf("UART7->CR3  0x%08x:0x%08x\r\n", &UART7->CR3, UART7->CR3);
+    printf("UART7->BRR  0x%08x:0x%08x\r\n", &UART7->BRR, UART7->BRR);
+    printf("UART7->GTPR 0x%08x:0x%08x\r\n", &UART7->GTPR, UART7->GTPR);
+    printf("UART7->RTOR 0x%08x:0x%08x\r\n", &UART7->RTOR, UART7->RTOR);
+    printf("UART7->RQR  0x%08x:0x%08x\r\n", &UART7->RQR, UART7->RQR);
+    printf("UART7->ISR  0x%08x:0x%08x\r\n", &UART7->ISR, UART7->ISR);
+    printf("UART7->ICR  0x%08x:0x%08x\r\n", &UART7->ICR, UART7->ICR);
+#endif
+}
+
+int iGPS_readable(void)
+{
+    return rxbuf.check();
+}
+
+int iGPS_getc(void)
+{
+    while(!rxbuf.check()){;}    // wait receiving a character
+    return rxbuf.read();
+}
+
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+//  Parse GPS data
+//      Module Type: u-blux7 NEO-7M
+////////////////////////////////////////////////////////////////////////////////
+// Get RMC & GAA data
+void gps_data_rcv(void)
+{
+    int8_t i;
+    time_t old_ave_sec[2];
+    uint32_t diff = 0;
+    time_t seconds;
+    struct tm   t_gps;
+
+    seconds = time(NULL);
+    U_DEBUG("\r\nCurrent Time: %s\r\n", ctime(&seconds));
+    old_ave_sec[0] = 0;
+    old_ave_sec[1] = 0;
+    // Wait long interval (every 1sec)
+    for (uint32_t i = 0; i < 100000; i++){
+        if (gps_rx == 0){
+            i = 0;
+        }
+    }
+    U_DEBUG("GPS line is Hi\r\n");
+#if defined(TARGET_STM32F746NG)
+    //  Clear GPS RX line errors(over run)
+    UART7->ICR = 0;
+    UART7->CR1 = 0;
+    UART7->CR1 = 5;
+    iGPSrcv_initialize();
+#endif
+    U_DEBUG("Start GPS!!");
+    while(true) {
+        getline_gps();          // Get GPS data from UART
+        if (strncmp(GPS_Buffer, "$GPRMC",6) == 0) {
+            for (i=0; GPS_Buffer[i] != 0; i++) {// Copy msg to RMC buffer
+                MsgBuf_RMC[i] = GPS_Buffer[i];
+            }
+            MsgBuf_RMC[i+1] = 0;
+            DBG('2');
+            if (gps_ready == 3) {
+                DBG('3');
+                get_time_and_date(&t_gps);
+                seconds = mktime(&t_gps);
+                if (old_ave_sec[0] == 0){
+                    old_ave_sec[0] = seconds;
+                } else if (old_ave_sec[1] == 0){
+                    old_ave_sec[1] = seconds;
+                } else {
+                    if (old_ave_sec[0] >= old_ave_sec[1]){
+                        diff = old_ave_sec[0] - old_ave_sec[1];
+                    } else {
+                        diff = old_ave_sec[1] - old_ave_sec[0];
+                    }
+                    if (diff > 100 ){
+                        old_ave_sec[0] = seconds;
+                        old_ave_sec[1] = 0;
+                    } else {
+                        if (old_ave_sec[0] > old_ave_sec[1]){
+                            diff = seconds - old_ave_sec[0];
+                            if (diff < 100){
+                                old_ave_sec[1] = seconds;
+                            }
+                        } else {
+                            diff = seconds - old_ave_sec[1];
+                            if (diff < 100){
+                                old_ave_sec[0] = seconds;
+                            }
+                        }
+                        set_time(seconds);
+                        DBG('4');
+                        return;
+                    }
+                }
+            }
+        } else if (strncmp(GPS_Buffer, "$GPGSA",6) == 0) {
+            for (i=0; GPS_Buffer[i] != 0; i++) {// Copy msg to GSA buffer
+                MsgBuf_GSA[i] = GPS_Buffer[i];
+            }
+            MsgBuf_GSA[i+1] = 0;
+            gps_ready = check_gps_3d();
+            DBG('x');
+        } else if (strncmp(GPS_Buffer, "$GPGGA",6) == 0) {
+            for (i=0; GPS_Buffer[i] != 0; i++) {// Copy msg to GGA buffer
+                MsgBuf_GGA[i] = GPS_Buffer[i];
+            }
+            MsgBuf_GGA[i+1] = 0;
+            gps_status = check_gps_ready();
+            DBG('1');
+        }
+    }
+}
+
+bool check_gps_is_okay()
+{
+    return gps_is_okay_flag;
+}
+
+// Get line of data from GPS
+void getline_gps(void)
+{
+    char *p = GPS_Buffer;
+
+#if defined(TARGET_NUCLEO_F411RE) || defined(TARGET_NUCLEO_F446RE)
+    while (gps.getc()  != '$'){;} 
+#elif defined(TARGET_STM32F746NG)
+    while (iGPS_getc() != '$'){;}
+#endif
+    *p++ = '$';
+#if 0
+    U_DEBUG("\r\n");
+#else
+    pc.printf("\r\n");
+#endif
+    for (char i= 0;i < 150;i++){
+#if defined(TARGET_NUCLEO_F411RE) || defined(TARGET_NUCLEO_F446RE)
+        *p = gps.getc(); 
+#elif defined(TARGET_STM32F746NG)
+        *p = iGPS_getc();
+#endif
+#if 0
+        DBG(*p);
+#else
+        pc.putc(*p);
+#endif
+        if (*p == '\r'){
+            *++p = '\n';
+            *++p = 0;
+            *++p = 0;
+            U_DEBUG("Get one GPS data\r\n");
+            return;
+        } else {
+            p++;
+        }
+    }
+    *++p = 0;
+    *++p = 0;
+}
+
+// ASCII to hex
+uint8_t hex(char c){
+    if(c<= '/') return( ERR );
+    if(((c -= '0')<= 9 || 10 <= ( c -= 'A' - '0' - 10)) && c <= 15) {
+        return((uint8_t)c);
+    }
+    return(ERR);
+}
+
+// Search next ',' (comma)
+char *next_comma( char *p ){
+    while (1) {
+        if ( *p== ',' ) {
+            return ++p;
+        } else if ( *p == 0 ) {
+            return (char*)-1;
+        } else {
+            p++;
+        }
+    }
+}
+
+// 2 digits ASCII char to one byte hex
+unsigned char   change_acii_hex( char*p ){
+    unsigned char c;
+
+    c = hex(*p++);              /* No concern ERR condition! */
+    c = (c * 10) + hex(*p++);
+    return c;
+}
+
+// Skip number of comma
+char *num_of_comma( char *p, int8_t n ){
+    for (; n> 0; n--) {
+        if ( (p = next_comma(p)) == (char*) -1 ) {
+            return (char*)-1;
+        }
+    }
+    return p;
+}
+
+// Get GPS status (1=Not fix, 2=2D, 3=3D)
+uint8_t check_gps_3d(void){
+    char *p;
+    uint8_t x;
+    uint8_t d;
+
+    // pick-up time
+    p = MsgBuf_GSA;
+    p = num_of_comma(p,1);  // skip ','
+    // reach to "Position Fix Indicator"
+    if (*p == 'A') {
+        ++p; //','
+        ++p; // 1 or 2 or 3
+        d = hex(*p++);
+        if (d != ERR) {
+            x = d;
+        } else {
+            x = 1;
+        }
+    } else {
+        x = 1;
+    }
+    return x;
+}
+
+// Get GPS status and number of satelites
+uint8_t check_gps_ready(void){
+    char *p;
+    uint8_t x;
+    uint8_t d;
+
+    // pick-up time
+    p = MsgBuf_GGA;
+    p = num_of_comma(p,6);  // skip ','
+    // reach to "Position Fix Indicator"
+    if (*p == '1' || *p == '2') {
+        ++p; //','
+        ++p; // Number
+        d = hex(*p++);
+        if (d != ERR) {
+            x = d * 10;
+            x += (uint32_t)hex(*p++);
+            if (*p != ',') {
+                x = 0;
+            }
+        } else {
+            x = 0;
+        }
+    } else {
+        x = 0;
+    }
+    return x;
+}
+
+//  Get time(UTC) from GPS data
+void get_time_and_date(struct tm *pt){
+    char *p;
+
+    p = MsgBuf_RMC;
+    p = num_of_comma(p,1);  /* skip one ',' */
+    pt->tm_hour   = change_acii_hex(p);
+    p += 2;
+    pt->tm_min = change_acii_hex(p);
+    p += 2;
+    pt->tm_sec = change_acii_hex(p);
+    p = MsgBuf_RMC;
+    p = num_of_comma(p,9);  /* skip one ',' */
+    pt->tm_mday  = change_acii_hex(p);
+    p += 2;
+    pt->tm_mon = change_acii_hex(p) - 1;
+    p += 2;
+    pt->tm_year  = change_acii_hex(p) + 100;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/GPS_rcvr/GPSrcvr.h	Wed Nov 16 13:22:00 2016 +0000
@@ -0,0 +1,75 @@
+/*
+ * mbed Application program / GPS receiver control and 1PPS output
+ *
+ * Copyright (c) 2004,'09,'10,'16 Kenji Arai / JH1PJL
+ *  http://www.page.sannet.ne.jp/kenjia/index.html
+ *  http://mbed.org/users/kenjiArai/
+ *      Created: March     28th, 2004   Kenji Arai
+ *      updated: July      25th, 2009   for PIC24USB
+ *      updated: January   16th, 2010   change to GPS-GM318
+ *      updated: April     24th, 2010   for mbed / NXP LPC1768
+ *      Revised: Nomeber   14th, 2016
+ */
+
+//  Definition -----------------------------------------------------------------
+//  GPS data selection & buffer size
+/* $GPGAA,hhmmss.sss,ddmm.mmmmmm,N,dddmm.mmmmmm,
+        E,1,xx,xx.xx,xx.xxx,M,xx.xxx,M,s.ss,xxxx*sum<CR><LF>
+    ex. $GPGGA,060306.00,4344.77894,N,14223.38857,
+        E,2,11,0.9,128.4,M,28.8,M,5.0,0129*4C<CR><LF>
+    # of data (ex.) = 81
+*/
+#define     SIZE_BUF_GGA    96
+/*
+ $GPGSA,A,3,xx,xx,,,xx,xx,,,,,xx.x,xx.x,xx.x*sum<CR><LF>
+    ex. $GPGSA,A,3,03,06,13,16,21,23,24,25,29,31,42,50,1.9,0.9,1.7*3C
+    # of data (ex.) = 63
+*/
+#define     SIZE_BUF_GSA    80
+/*
+ $GPGSV,x,x,xx*sum<CR><LF>
+    ex. $GPGSV,3,1,12,03,39,225,47,06,55,217,48,13,21,314,48,16,74,342,50*76
+        $GPGSV,3,2,12,21,33,095,50,23,32,280,50,24,18,049,42,25,12,315,43*7E
+        $GPGSV,3,3,12,29,12,047,45,31,49,146,49,42,39,183,46,50,39,176,42*7C
+    # of data (ex.) = 70
+*/
+#define     SIZE_BUF_GSV    80
+/*
+ $GPRMC,hhmmss.sss,V,ddmm.mmmm,N,dddmm.mmmm,E,k.kkk,x.xx,ddmmyy,,,N*sum<CR><LF>
+    ex. $GPRMC,060309.00,A,4344.77571,N,14223.38879,
+            E,0.03,210.32,190808,06.2,W,D*51
+    # of data (ex.) = 84
+*/
+#define     SIZE_BUF_RMC    96
+/*
+ $GPVTG,xx.xx,T,,M,x.xx,N,x.xx,K,A*sum<CR><LF>
+    ex. $GPVTG,210.32,T,204.30,M,0.03,N,0.06,K,D*3F
+    # of data (ex.) = 43
+*/
+#define     SIZE_BUF_VTG    64
+/*
+ $GPZDA,hhmmss.sss,dd,mmm,yyyy,hh,mm*sum<CR><LF>
+    ex. $GPZDA,060307.00,19,08,2008,13,26*6E
+    # of data (ex.) = 36
+*/
+#define     SIZE_BUF_ZDA    48
+/*
+ $GPGLL,ddmm.mmmmmm,N,dddmm.mmmmmm,E,hhmmss.sss,V,D*sum<CR><LF>
+    ex. $GPGLL,4344.77956,N,14223.38863,E,060305.00,A,D*61
+    # of data (ex.) = 52
+*/
+#define     SIZE_BUF_GLL    64
+
+#define     ERR             0xff
+
+//------------------------------------------------------------------------------
+
+#ifndef _IGPSRCV_H
+#define _IGPSRCV_H
+
+void gps_data_rcv(void);    // make sure !! infinit loop on RTOS
+bool check_gps_is_okay(void);
+uint8_t check_gps_3d(void);
+
+#endif    /* _IGPSRCV_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/fc_GPS1PPS_f746_f4xx.lib	Wed Nov 16 13:22:00 2016 +0000
@@ -0,0 +1,1 @@
+https://developer.mbed.org/users/kenjiArai/code/fc_GPS1PPS_f746_f4xx/#be7123d400ae
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/iSerial.lib	Wed Nov 16 13:22:00 2016 +0000
@@ -0,0 +1,1 @@
+http://developer.mbed.org/users/kenjiArai/code/iSerial/#6bea021727a1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Wed Nov 16 13:22:00 2016 +0000
@@ -0,0 +1,285 @@
+/*
+ * mbed Application program / Frequency Counter using GPS 1PPS gate puls
+ *      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/
+ *      Created:    October   18th, 2014
+ *      Revised:    January    2nd, 2015
+ *      Re-started: June      25th, 2016    ported from F411 to F746
+ *      Re-started: October    5th, 2016    Change board -> DISCO-F746NG
+ *      Re-started: October   10th, 2016    back to F411
+ *      Revised:    Nobember  15th, 2016
+ *
+ * Base program: Frequency_counter_w_GPS_1PPS (only for Nucleo-F411RE board)
+ * https://developer.mbed.org/users/kenjiArai/code/Frequency_Counter_w_GPS_1PPS/
+ *
+ * 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)
+#define     USE_DEBUG
+
+//  Include --------------------------------------------------------------------
+#include    "mbed.h"
+#include    "GPSrcvr.h"
+#include    "fc_GPS1PPS.h"
+
+//  Definition -----------------------------------------------------------------
+#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
+
+#ifdef  USE_DEBUG
+#define U_DEBUGBAUD(x)      pc.baud(x)
+#define U_DEBUG(...)        pc.printf(__VA_ARGS__)
+#define DBG(c)              pc.putc(c)
+#else
+#define U_DEBUGBAUD(x)      {;}
+#define U_DEBUG(...)        {;}
+#define DBG(c)              {;}
+#endif
+
+#if defined(TARGET_NUCLEO_F411RE) || defined(TARGET_NUCLEO_F446RE)
+#define RECIPRO_LMT         4500
+#define RECIPRO_10KHZ       5000
+#elif defined(TARGET_STM32F746NG)
+#define RECIPRO_LMT         9000
+#define RECIPRO_10KHZ       10000
+#else
+#error "Target is only Nucleo-F411RE + F446RE or DISCO-F746NG!!!"
+#endif
+#define GSP_BUF_B           (128 * 3)
+#define GPS_BUF_S           (128 * 2)
+
+enum input_select {
+         BNC_NORMAL = 1,
+         RECIPRO_AC,
+         RECIPRO_DC,
+         SMA_10,
+         SMA_20
+};
+
+using namespace Frequency_counter;
+
+//  Object ---------------------------------------------------------------------
+#if defined(TARGET_NUCLEO_F411RE) || defined(TARGET_NUCLEO_F446RE)
+DigitalOut  input_frq_select(PA_4);
+DigitalInOut  prescaler10or20(PA_7);
+DigitalOut  recipro_select(PB_6);
+#elif defined(TARGET_STM32F746NG)
+DigitalOut  input_frq_select(PF_9);
+DigitalInOut  prescaler10or20(PB_15);
+DigitalOut  recipro_select(PA_8);
+#endif
+DigitalOut  led1(LED1);
+Serial      pc(USBTX, USBRX);
+Timer       tmr;
+
+//**** Req. Counter
+FRQ_CUNTR   fc;
+
+//  RAM ------------------------------------------------------------------------
+// Freq.
+double      new_frequency;
+double      f_10sec;
+double      f_100sec;
+double      f_1000sec;
+double      freq_recipro;
+// Operation mode
+uint8_t     input_mode;
+
+//  ROM / Constant data --------------------------------------------------------
+//                               12345678901234567890
+static char *const msg_msg0   = "Frequency Counter by JH1PJL K.Arai";
+#if   defined(TARGET_NUCLEO_F411RE)
+static char *const msg_msg1   = "on Nucleo-F411RE System";
+#elif defined(TARGET_NUCLEO_F446RE)
+static char *const msg_msg1   = "on Nucleo-F446RE System";
+#elif defined(TARGET_STM32F746NG)
+static char *const msg_msg1   = "on DISCO-F746NG System";
+#endif
+static char *const msg_msg2   = "    "__DATE__" ";
+static char *const msg_mode1  = "  BNC none-prescaler              ";
+static char *const msg_mode2  = "  BNC recipro(BNC none-prescaler) ";
+static char *const msg_mode3  = "  BNC recipro(dedicated BNC input)";
+static char *const msg_mode4  = "  SMA prescaler 1/10              ";
+static char *const msg_mode5  = "  SMA prescaler 1/20              ";
+
+//  Function prototypes --------------------------------------------------------
+void gps_data_rcv(void);
+
+//------------------------------------------------------------------------------
+//  Control Program
+//------------------------------------------------------------------------------
+void freq_measurement(uint8_t mode)
+{
+    uint16_t    n = 0;
+    char        buf[48];
+    time_t      seconds;
+    double      scale;
+
+    if (mode == SMA_20){
+        scale = 20.0f;
+    } else if(mode == SMA_10){
+        scale = 10.0f;
+    } else {
+        scale = 1.0f;
+    }
+    while(true){
+        tmr.reset();
+        tmr.start();
+        if (fc.status_freq_update() != 0) {
+            new_frequency = fc.read_freq_data() * scale;
+            f_10sec   = fc.read_freq_w_gate_time(10) * scale;
+            f_100sec  = fc.read_freq_w_gate_time(100) * scale;
+            f_1000sec = fc.read_freq_w_gate_time(1000) * scale;
+            PRINTF("%8d, Freq: %9.0f,", ++n, new_frequency);
+            PRINTF(" F10s: %10.1f, F100s: %11.2f,", f_10sec, f_100sec);
+            PRINTF(" F1000s: %12.3f,", f_1000sec);
+        } else {
+            PRINTF("%8d, No data,,,,", ++n);
+        }
+        if (mode == SMA_20){
+            PRINTF(" Div: 1/20,");
+        } else if(mode == SMA_10){
+            PRINTF(" Div: 1/10,");
+        } else {
+            PRINTF(" Div: 1/1 ,");
+        }             
+        seconds = time(NULL) + 32400; // Adjust UTC to JST
+        strftime(buf, 40, " %I:%M:%S %p JST (%m/%d)", localtime(&seconds));
+        PRINTF("%s\r\n", buf);
+        wait_ms(1000 - tmr.read_ms());      // 1sec interval
+    }
+}
+
+void recipro()
+{
+    uint16_t    n = 0;
+    char        buf[48];
+    time_t      seconds;
+    double      freq_recipro;
+    uint32_t    interval_recipro;
+    uint32_t    base_clk;
+    int32_t     run2stop;
+
+    while(true){
+        fc.recipro_start_measure();
+        PRINTF("Start measurement\r");
+        while (fc.recipro_check_trigger() == 0){
+            run2stop = tmr.read_ms();
+            if (run2stop >= 100000){ // 100sec 0.001Hz
+                break;
+            }
+        }
+        if (run2stop >= 1000000){ // 100sec 0.001Hz
+            freq_recipro = 0;
+        } else {
+            interval_recipro = fc.recipro_read_data();
+            base_clk = fc.recipro_base_clk_data(1);
+            if (interval_recipro >= 9000){// Measure less than 10KHz frequency
+                freq_recipro = (double)base_clk / (double)interval_recipro;
+                PRINTF("%8d, Freq: %11.5f [Hz] , ", n++, freq_recipro);
+                PRINTF("Raw:  %11u [cnt] , ", interval_recipro);
+                PRINTF("Base: %11u [Hz], ", base_clk);
+                seconds = time(NULL) + 32400;   // Adjust UTC to JST
+                strftime(buf, 40,
+                            " %I:%M:%S %p JST (%m/%d)", localtime(&seconds));
+                PRINTF("%s\r\n", buf);
+                run2stop = tmr.read_ms();
+                if (run2stop < 1000){ 
+                    run2stop = 1000 - run2stop;
+                    wait_ms(run2stop);          // 1sec interval
+                }
+            } else {
+                freq_recipro = 0;
+            }
+        }
+    }
+}
+
+int main()
+{
+    PRINTF("\r\n%s%s\r\n", msg_msg0, msg_msg2);
+    PRINTF("%s\r\n", msg_msg1);
+    PRINTF("Wait GPS 1PPS signal\r\n");
+    gps_data_rcv();
+    PRINTF("\r\nPlease select measurement mode.\r\n");
+    PRINTF("%s-> 1\r\n", msg_mode1);
+    PRINTF("%s-> 2\r\n", msg_mode2);
+    PRINTF("%s-> 3\r\n", msg_mode3);
+    PRINTF("%s-> 4\r\n", msg_mode4);
+    PRINTF("%s-> 5\r\n", msg_mode5);
+    PRINTF("Enter 1 to 5 (other input then 1)\r\n");
+    // Select operation mode
+    char c = GETC() - '0';
+    if ((c > 5) || (c <= 0)){   c = 1;}
+    input_mode = c;
+    PRINTF("If you want to change the input signal,");
+    PRINTF(" please restart the system (Enter Alt+B from your PC)\r\n");
+    PRINTF("\r\nStart measuring\r\nMeasureing mode = ");
+    switch(input_mode){
+        case RECIPRO_AC:
+            PRINTF("%s\r\n", msg_mode2);
+            input_frq_select = 1;
+            prescaler10or20.output();
+            prescaler10or20 = 0;
+            recipro_select = 0;
+            recipro();
+            break;
+        case RECIPRO_DC:
+            PRINTF("%s\r\n", msg_mode3);
+            input_frq_select = 1;
+            prescaler10or20.output();
+            prescaler10or20 = 0;
+            recipro_select = 1;
+            recipro();
+            break;
+        case SMA_10:
+            PRINTF("%s\r\n", msg_mode4);
+            input_frq_select = 0;
+            prescaler10or20.output();
+            prescaler10or20 = 0;
+            recipro_select = 0;
+            freq_measurement(input_mode);
+            break;
+        case SMA_20:
+            PRINTF("%s\r\n", msg_mode5);
+            input_frq_select = 0;
+            prescaler10or20.input();
+            recipro_select = 0;
+            freq_measurement(input_mode);
+            break;
+        case BNC_NORMAL:
+        default:
+            input_mode = BNC_NORMAL;
+            PRINTF("%s\r\n", msg_mode1);
+            input_frq_select = 1;
+            prescaler10or20.output();
+            prescaler10or20 = 0;
+            recipro_select = 0;
+            freq_measurement(input_mode);
+            break;
+    }
+    while(true){;}  // Just in case
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Wed Nov 16 13:22:00 2016 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/0ab6a29f35bf
\ No newline at end of file