Frequency counter library only for NucleoF411RE

Dependents:   Frequency_Counter_w_GPS_1PPS

Revision:
2:194f82ad3041
Parent:
1:102230f2879d
Child:
3:339307e1dc0d
diff -r 102230f2879d -r 194f82ad3041 frq_cuntr_full.cpp
--- a/frq_cuntr_full.cpp	Sat Nov 22 23:02:39 2014 +0000
+++ b/frq_cuntr_full.cpp	Sun Dec 21 12:14:46 2014 +0000
@@ -8,7 +8,7 @@
  *  http://mbed.org/users/kenjiArai/
  *      Additional functions and modification
  *      started: October   18th, 2014
- *      Revised: Nobember  23rd, 2014
+ *      Revised: December  21st, 2014
  *
  * 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
@@ -41,11 +41,11 @@
 namespace Frequency_counter
 {
 // TIM2 OC
-uint32_t oc_set_time0;
-uint32_t oc_set_time1;
-uint8_t  new_gt_value;
-uint32_t oc_hi_time;
-uint32_t oc_lo_time;
+static uint32_t oc_set_time0;
+static uint32_t oc_set_time1;
+static uint8_t  new_gt_value;
+static uint32_t oc_hi_time;
+static uint32_t oc_lo_time;
 // TIM2 IC
 static uint8_t  tim2_ready_flg;
 static uint32_t tim2_cnt_data;
@@ -55,7 +55,7 @@
 static uint32_t tim3p4_cnt_data;
 
 //-------------------------------------------------------------------------------------------------
-//  Control Program
+//  Interrupt Handlers
 //-------------------------------------------------------------------------------------------------
 // TIM2 IC2 Interrupt control
 void irq_ic2_TIM2(void)
@@ -67,9 +67,12 @@
         tim2_old_cnt_data = tim2_cnt_data;
         tim2_cnt_data = TIM2->CCR2;
         tim2_ready_flg = 1;
-    } else if (reg & TIM_SR_CC3IF) {
+#if defined(DEBUG)
+        debug_led = !debug_led;
+#endif
+    } else if (reg & TIM_SR_CC3IF) {    // Output Compare
         TIM2->SR &= ~TIM_SR_CC3IF;      // clear IC flag
-        if (GPIOB->IDR & 0x0400) {   // Check PB10 status
+        if (GPIOB->IDR & 0x0400) {      // Check PB10 status
             TIM2->CCR3 = TIM2->CCR3 + oc_hi_time;
         } else {
             TIM2->CCR3 = TIM2->CCR3 + oc_lo_time;
@@ -80,7 +83,7 @@
             }
         }
 #if defined(DEBUG)
-        debug_led = !debug_led;
+//        debug_led = !debug_led;
 #endif
     }
 }
@@ -93,17 +96,19 @@
     tim3p4_cnt_data = (TIM4->CCR1 << 16) + TIM3->CCR2;
     tim3p4_ready_flg = 1;
 #if defined(DEBUG)
-    debug_led = !debug_led;
+//    debug_led = !debug_led;
 #endif
 }
 
 //---------------------------------------------------------------------------------------
 //  Frequency Counter
 //---------------------------------------------------------------------------------------
-FRQ_CUNTR::FRQ_CUNTR(PinName f_in, double gt): _pin(f_in)
+FRQ_CUNTR::FRQ_CUNTR(PinName f_in, double gt, double ex_clock): _pin(f_in)
 {
-    set_gate_time(gt);
-    initialize_Freq_counter();
+    // Don't change calling sequence!!
+    set_external_clock(ex_clock);   // 1st
+    set_gate_time(gt);              // 2nd
+    initialize_Freq_counter();      // 3rd
 }
 
 // Set gate time
@@ -116,23 +121,52 @@
     } else {
         gate_time = gt;
     }
-    oc_set_time0 = CNT_FIX_BASE;
-    double gt_tmp0 = CNT_BASE * gate_time;
+    oc_set_time0 = clk_hi_const;
+    double gt_tmp0 = ex_clk_base * gate_time;
     uint32_t gt_tmp1 = (uint32_t)gt_tmp0;
     if ((gt_tmp0 - (double)gt_tmp1) >= 0.5) {
         ++gt_tmp1;
     }
-    oc_set_time1 = gt_tmp1 - CNT_FIX_BASE;
+    oc_set_time1 = gt_tmp1 - clk_hi_const;
     new_gt_value = 1;
     return gate_time;
 }
 
+// Read gate time
+double FRQ_CUNTR::read_gate_time(void)
+{
+    return gate_time;
+}
+
+// Set External Clock Frequency
+void FRQ_CUNTR::set_external_clock(double ex_clock)
+{
+#if defined(BASE_EXTERNAL_CLOCK)
+    ex_clock_freq = ex_clock;
+    ex_clk_base = (uint32_t)(ex_clock_freq * 1000000); // MHz->Hz
+    clk_hi_const = (uint32_t)(ex_clock_freq * 1000000 * 0.04);  // 40mS
+//    uint32_t err = (uint32_t)(ex_clock_freq * 1000000 * 0.00001);  // 10ppm error range
+    uint32_t err = (uint32_t)(ex_clock_freq * 1000000 * 0.1);
+    clk_upper_limit = ex_clk_base + err;
+    clk_lower_limit = ex_clk_base - err;
+#else
+    ex_clock_freq = 100;      // Internal 100MHz
+    ex_clk_base = 100000000; // MHz->Hz
+    clk_hi_const = 4000000;  // 40mS
+    uint32_t err = 100;  // 10ppm error range
+    clk_upper_limit = ex_clk_base + err;
+    clk_lower_limit = ex_clk_base - err;
+#endif
+}
+
 // Read new frequency data
-uint32_t FRQ_CUNTR::read_freq_data(void)
+double FRQ_CUNTR::read_freq_data(void)
 {
     old_cntr_tim3p4 = counter_tim3p4;
     counter_tim3p4 = read_ic2_counter_TIM3P4();
-    return (counter_tim3p4 - old_cntr_tim3p4);
+    double freq0 = (double)(counter_tim3p4 - old_cntr_tim3p4);
+    newest_frequency = freq0 / gate_time;
+    return newest_frequency;
 }
 
 // Read status (new frequency data is available or not)
@@ -151,9 +185,12 @@
 uint32_t FRQ_CUNTR::set_1PPS_data(void)
 {
     uint32_t diff = tim2_cnt_data - tim2_old_cnt_data;
-    if ((diff > CNT_UPPER) || (diff < CNT_LOWER)) {
+    if ((diff > clk_upper_limit) || (diff < clk_lower_limit)) {
+//        PRINTF("IC0 %d %d %d \r\n", diff, clk_upper_limit, clk_lower_limit);
+        gps_ready = 0;
         return 0;
     } else {
+        gps_ready = 1;
         onepps_cnt[onepps_num] = diff;
         if (++onepps_num >= CNT_BF_SIZE) {
             onepps_num = 0;
@@ -173,16 +210,26 @@
             total += (uint64_t)onepps_cnt[i];
         }
         onepps_cnt_avarage = total / CNT_BF_SIZE;
-        PRINTF("buf");
+//        PRINTF("buf");
     } else {
         for (uint32_t i = 0; i < onepps_num; i++) {
             total += (uint64_t)onepps_cnt[i];
         }
         onepps_cnt_avarage = total / onepps_num;
-        PRINTF("not");
+//        PRINTF("not");
     }
-    PRINTF(" full, num= %3d , 1PPS/new= %9d , ", onepps_num, onepps_newest);
+//    PRINTF(" full, num= %3d , 1PPS/new= %9d\r\n", onepps_num, onepps_newest);
+#if defined(ONEPPS_AVE)
     return onepps_cnt_avarage;
+#else
+    return onepps_newest;
+#endif
+}
+
+// Check GPS condition
+uint8_t FRQ_CUNTR::gps_status(void)
+{
+    return gps_ready;
 }
 
 //---------------------------------------------------------------------------------------
@@ -247,7 +294,7 @@
     TIM2->CNT = 0;
     wait(gate_time);                // Gate time for count
     freq = TIM2->CNT;               // read counter
-    PRINTF("Clock freq.=%10d [Hz], gate= %4.2f [Sec]\r\n", freq, gate_time);
+//    PRINTF("Clock freq.=%10d [Hz], gate= %4.2f [Sec]\r\n", freq, gate_time);
     return freq;                    // return counter data
 }
 
@@ -263,7 +310,7 @@
     freq0 = TIM3->CNT;
     freq1 = TIM4->CNT;
     freq0 = (freq1 << 16) + freq0;
-    PRINTF("Input freq.=%10d [Hz], gate= %4.2f [Sec]\r\n", freq0, gate_time);
+//    PRINTF("Input freq.=%10d [Hz], gate= %4.2f [Sec]\r\n", freq0, gate_time);
     return freq0;                   // read counter
 }
 
@@ -297,17 +344,17 @@
         // MC01 output HSE 1/1, MCO2 output SYSCLK 1/1
         //             MCO2          MCO2PRE       MCO1PRE       MCO1
         RCC->CFGR |= (0x0 << 30) + (0x0 << 27) + (0x0 << 24) + (0x2 << 21);
-        PRINTF("Set MCO1(PA8):HSE/1, MCO2(PC9):SYSCLK/1\r\n");
+//        PRINTF("Set MCO1(PA8):HSE/1, MCO2(PC9):SYSCLK/1\r\n");
     } else if (select == 2) {
         // MC01 output HSE 1/2, MCO2 output SYSCLK 1/2
         //             MCO2          MCO2PRE       MCO1PRE       MCO1
         RCC->CFGR |= (0x0 << 30) + (0x4 << 27) + (0x4 << 24) + (0x2 << 21);
-        PRINTF("Set MCO1(PA8):HSE/2, MCO2(PC9):SYSCLK/2\r\n");
+//        PRINTF("Set MCO1(PA8):HSE/2, MCO2(PC9):SYSCLK/2\r\n");
     } else { // select = 4 and other wrong order
         // MC01 output HSE 1/4, MCO2 output SYSCLK 1/4
         //             MCO2          MCO2PRE       MCO1PRE       MCO1
         RCC->CFGR |= (0x0 << 30) + (0x6 << 27) + (0x6 << 24) + (0x2 << 21);
-        PRINTF("Set MCO1(PA8):HSE/4, MCO2(PC9):SYSCLK/4\r\n");
+//        PRINTF("Set MCO1(PA8):HSE/4, MCO2(PC9):SYSCLK/4\r\n");
     }
 }
 
@@ -347,7 +394,7 @@
     TIM2->SMCR |= (uint16_t)( TIM_TS_TI1FP1 | TIM_SLAVEMODE_EXTERNAL1);     // ECE must be ZERO!!!!
     TIM2->CR1 |= (uint16_t)TIM_CR1_CEN;          // Enable the TIM Counter
 #else
-    // Initialize Timer2(32bit) for an external up counter mode
+    // Initialize Timer2(32bit) for an internal up counter mode
     RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
     TIM2->CR1 &= (uint16_t)(~(TIM_CR1_DIR | TIM_CR1_CMS | TIM_CR1_CKD));  // count_up + div by 1
     TIM2->CR1 |= TIM_CR1_URS;
@@ -391,6 +438,7 @@
     oc_hi_time = oc_set_time0;
     oc_lo_time = oc_set_time1;
     TIM2->CCR3 = TIM2->CNT + oc_hi_time;// Set the Capture Compare Register value
+#if 0
     // Only for Debug purpose
     BAUD(9600);
     //  PA
@@ -417,6 +465,7 @@
     PRINTF("TIM2->CCER   0x%08x:0x%08x\r\n",&TIM2->CCER, TIM2->CCER);
     PRINTF("TIM2->SMCR   0x%08x:0x%08x\r\n",&TIM2->SMCR, TIM2->SMCR);
     PRINTF("TIM2->CCR3   0x%08x:0x%08x\r\n\r\n",&TIM2->CCR3, TIM2->CCR3);
+#endif
     // Interrupt Timer2 IC2
     for (uint32_t i = 0; i < CNT_BF_SIZE; i++) {
         onepps_cnt[i] = 0;
@@ -498,6 +547,7 @@
     TIM4->CCMR1 |= (uint16_t)TIM_CCMR1_CC1S_0;
     TIM4->CCER  &= (uint16_t)~(TIM_CCER_CC1P | TIM_CCER_CC1NP); // positive edge
     TIM4->CCER  |= (uint16_t)TIM_CCER_CC1E;     // enable capture
+#if 0
     // Only for Debug purpose
     //  PB
     PRINTF("// PB6 -> Input Capture pin as Timer4 CH1/TI1\r\n");
@@ -537,6 +587,7 @@
     PRINTF("TIM4->CCER   0x%08x:0x%08x\r\n",&TIM4->CCER, TIM4->CCER);
     PRINTF("TIM4->SMCR   0x%08x:0x%08x\r\n\r\n",&TIM4->SMCR, TIM4->SMCR);
     PRINTF("RCC->APB1ENR 0x%08x:0x%08x\r\n\r\n",&RCC->APB1ENR, RCC->APB1ENR);
+#endif
     // Interrupt Timer3 IC2
     tim3p4_ready_flg = 0;
     tim3p4_cnt_data = 0;
@@ -548,4 +599,21 @@
     NVIC_EnableIRQ(TIM3_IRQn);
 }
 
+//---------------------------------------------------------------------------------------
+//  Only for Debug purpose
+//---------------------------------------------------------------------------------------
+void FRQ_CUNTR::debug_printf_internal_data(void)
+{
+#if 0
+    PRINTF("Debug information\r\n");
+    PRINTF("gate_time       %f\r\n", gate_time);
+    PRINTF("ex_clock_freq   %f\r\n", ex_clock_freq);
+    PRINTF("ex_clk_base     %9d\r\n", ex_clk_base);
+    PRINTF("clk_hi_const    %9d\r\n", clk_hi_const);
+    PRINTF("clk_upper_limit %9d\r\n", clk_upper_limit);
+    PRINTF("clk_lower_limit %9d\r\n", clk_lower_limit);
+    PRINTF("\r\n");
+#endif
+}
+
 }   // Frequency_counter