Frequency Counter. User interface are used DISCO-F746NG GUI with touch panel.

Dependencies:   BSP_DISCO_F746NG F746_GUI LCD_DISCO_F746NG RingBuffer TS_DISCO_F746NG fc_GPS1PPS_f746_f4xx mbed

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

Revision:
0:52c5dc2b2b68
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/GPS_rcvr/GPSrcvr.cpp	Sat Nov 19 05:32:06 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   13th, 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
+#error "This is only on DISCO-F746NG!!"
+#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;
+}