Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: FreqCntr_GPS1PPS_F746F4xx_w_recipro Freq_Cntr_GPS1PPS_F746NG_GUI
Fork of Frq_cuntr_full by
Diff: frq_cuntr_full.cpp
- Revision:
- 2:194f82ad3041
- Parent:
- 1:102230f2879d
- Child:
- 3:339307e1dc0d
--- 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
