Kenji Arai / Frq_cuntr_full

Dependents:   Frequency_Counter_w_GPS_1PPS

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers frq_cuntr_full.h Source File

frq_cuntr_full.h

00001 /*
00002  * mbed Library / Frequency Counter with GPS 1PPS Compensation
00003  *      Frequency Counter Hardware relataed program
00004  *      Only for ST Nucleo F411RE
00005  *
00006  * Copyright (c) 2014 Kenji Arai / JH1PJL
00007  *  http://www.page.sannet.ne.jp/kenjia/index.html
00008  *  http://mbed.org/users/kenjiArai/
00009  *      Additional functions and modification
00010  *      started: October   18th, 2014
00011  *      Revised: January    1st, 2015
00012  *
00013  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
00014  * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
00015  * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
00016  * DAMAGES OR OTHER  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00017  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00018  */
00019 
00020 #ifndef        MBED_FRQ_CUNTR
00021 #define        MBED_FRQ_CUNTR
00022 
00023 #include "mbed.h"
00024 
00025 // please comment out when normal run mode
00026 //#define DEBUG           // use Communication with PC(UART)
00027 
00028 /*
00029     CAUTION:
00030     If you select internal clock (100MHz), you need consider PLL clock behavior.
00031     PLL clock drifts over 70Hz (increase frequency) within 30 to 40 second
00032     then suddenly back to low frequency and increase again.
00033     Even you prepare precision external clock, this frequency drift cannot avoid.
00034     Comment out "BASE_EXTERNAL_CLOCK" is only for checking!!
00035  */
00036 #define BASE_EXTERNAL_CLOCK
00037 
00038 //  use avaraged 1pps data
00039 #define ONEPPS_AVE
00040 
00041 namespace Frequency_counter
00042 {
00043 
00044 #define CNT_BF_SIZE     120             // 1PPS data save size
00045 
00046 /** Frequency Counter program
00047  * Only for ST Nucleo F411RE Board
00048  *
00049  * @code
00050  * #include "mbed.h"
00051  *
00052  * using namespace Frequency_counter;
00053  *
00054  * // PC_6,PC_7 & PB_6 use for Timer3 & 4(16+16bit)
00055  * // PA_0,PA_1 & PB_10 use for Timer2(32bit)
00056  * // PA_8 & PC_7 use for MCO (Test purpose)
00057  * FRQ_CUNTR   fc(PC_6, 1.0, 24.999982f); //Input port, gate time[sec] & External clock freq.
00058  *
00059  * int main() {
00060  *   uint32_t counter_1pps = 0;
00061  *   double new_frequency = 0;
00062  *   // This is for test purpose
00063  *   fc.port_mco1_mco2_set(4);      // Clk/4 ->1/1(100MHz) cannot measure!!
00064  *   fc.read_frequency_TIM2(1.0);   // read TIM2 source frequency (test)
00065  *   fc.read_frequency_TIM3P4(1.0); // read TIM3 source frequency (test)
00066  *   while(true) {
00067  *      while (fc.status_1pps() == 0) {;}
00068  *      counter_1pps = fc.read_avarage_1pps();
00069  *      while (fc.status_freq_update() == 0) {;}
00070  *      new_frequency = fc.read_freq_data();
00071  *      printf("1PPS/ave = %9d , FREQUENCY = %11.3f\r\n", counter_1pps, new_frequency);
00072  *   }
00073  * }
00074  * @endcode
00075  */
00076 
00077 class FRQ_CUNTR
00078 {
00079 public:
00080 
00081     /** Configure data pin (Not changeable)
00082       * @param Freq. input pin + Gate time[sec] + External clock[MHz]
00083       */
00084     FRQ_CUNTR(PinName f_in, double gt, double ex_clock);
00085 
00086     /** Set gate time
00087       * @param gate time [sec]
00088       * @return gate time (range 50mS to 1 minute)
00089       */
00090     double set_gate_time(double gt);
00091 
00092     /** Set external clock frequency
00093       * @param frequency e.g. 25.000000 [MHz]
00094       * @return none
00095       */
00096     void set_external_clock(double ex_clock);
00097 
00098     /** Read gate time
00099       * @param none
00100       * @return gate time (range 50mS to 1 minute)
00101       */
00102     double read_gate_time(void);
00103 
00104     /** Read status (new frequency data is available or not)
00105       * @param none
00106       * @return !=0: new data is avairable, 0: not yet
00107       */
00108     uint32_t status_freq_update(void);
00109 
00110     /** Read new frequency data
00111       * @param none
00112       * @return frequency data
00113       */
00114     double read_freq_data(void);
00115 
00116     /** Read avarage measued data GPS 1PPS
00117       * @param none
00118       * @return Frequency
00119       */
00120     uint32_t read_avarage_1pps(void);
00121 
00122     /** Read newest measued data GPS 1PPS
00123       * @param none
00124       * @return Frequency
00125       */
00126     uint32_t read_newest_1pps(void);
00127 
00128     /** Read status (new 1PPS data is available or not)
00129       * @param none
00130       * @return !=0: new data is avairable, 0: not yet
00131       */
00132     uint32_t status_1pps(void);
00133 
00134     /** Read GPS status
00135       * @param none
00136       * @return 1: GPS is ready
00137       */
00138     uint8_t status_gps(void);
00139 
00140     /** This is a "TEST PURPOSE" function
00141       * Check PA0 pin input or internal clock frequency
00142       * @param none
00143       * @return Frequency
00144       */
00145     uint32_t read_frequency_TIM2(float gate_time);
00146 
00147     /** This is a "TEST PURPOSE" function
00148       * Check PC6 pin input frequency
00149       * @param none
00150       * @return Frequency
00151       */
00152     uint32_t read_frequency_TIM3P4(float gate_time);
00153 
00154     /** This is a "TEST PURPOSE" function
00155       * Output clock from pin PA8 & PC9 uses for MCO_1 & MCO_2
00156       * @param none
00157       * @return none
00158       */
00159     void port_mco1_mco2_set(uint8_t select);
00160 
00161     /** This is a "DEBUG PURPOSE" function
00162       * print internal data (need to define "DEBUG"
00163       * @param none
00164       * @return none
00165       */
00166     void debug_printf_internal_data(void);
00167 
00168 protected:
00169     DigitalIn _pin;
00170 
00171     void initialize_Freq_counter(void);     // Initialize timers
00172     // Internal clock (100MHz) or External clock(?MHz) and IC2 for GPS 1pps signal measurement
00173     void initialize_TIM2(void);
00174     // Initialize TIM3 and TIM4 as 32bit counter (TIM3(16bit) + TIM4(16bit))
00175     void initialize_TIM3P4(void);
00176     uint32_t set_1PPS_data(void);           // Set GPS 1PPS counter value
00177     uint32_t read_ic2_counter_TIM2(void);   // Read TIM2 captured counter value
00178     uint32_t check_ic2_status_TIM2(void);   // Check TIM2 IC2 status
00179     uint32_t read_ic2_counter_TIM3P4(void); // Read TIM3+4(as 32bit) captured counter value
00180     uint32_t check_ic2_status_TIM3P4(void); // Check TIM3 IC2 & TIM4 IC1 status
00181     uint8_t  read_oc_port_status(void);     // Check TIM2 OC port
00182 
00183 private:
00184     double   newest_frequency;
00185     double   gate_time;
00186     double   ex_clock_freq;
00187     uint32_t ex_clk_base;
00188     uint32_t clk_hi_const;
00189     uint32_t clk_upper_limit;
00190     uint32_t clk_lower_limit;
00191     uint8_t  gps_ready;
00192     // TIM2
00193     uint32_t counter_tim2;
00194     uint32_t old_cntr_tim2;
00195     // TIM3+4
00196     uint32_t counter_tim3p4;
00197     uint32_t old_cntr_tim3p4;
00198     // 1PPS data
00199     uint32_t onepps_newest;
00200     uint32_t onepps_cnt[CNT_BF_SIZE];
00201     uint32_t onepps_num;
00202     uint64_t onepps_cnt_avarage;
00203     uint8_t  onepps_buf_full;
00204     uint8_t  onepps_ready_flg;
00205 
00206 };
00207 
00208 /*
00209     Interrupt handler does NOT work following code
00210     NVIC_SetVector(TIM2_IRQn, (uint32_t)FRQ_CUNTR::irq_ic2_TIM2);
00211     From this reason, I wrote below code and set interrupt handler out side "FRQ_CUNTR" class
00212     NVIC_SetVector(TIM2_IRQn, (uint32_t)irq_ic2_TIM2);
00213  */
00214 void irq_ic2_TIM2(void);    // TIM2 IC2 Interrupt control
00215 void irq_ic2_TIM3P4(void);  // TIM3 IC2 Interrupt control (same signal connected to TIM4 IC1)
00216 
00217 }   // Frequency_counter
00218 
00219 #endif  // MBED_FRQ_CUNTR