Frequency counter library using GPS 1PPS signal and temperature controlled 50MHz Base clock. Ported from F411 Frequency Counter.

Dependencies:   RingBuff

Dependents:   Frequency_Cntr_1PPS_F746ZG

Fork of Frq_cuntr_full by Kenji Arai

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers frq_cuntr_f746.h Source File

frq_cuntr_f746.h

00001 /*
00002  * mbed Library / Frequency Counter with GPS 1PPS Compensation
00003  *      Frequency Counter Hardware relataed program
00004  *      Only for ST Nucleo-F746ZG
00005  *
00006  * Copyright (c) 2014,'15,'16 Kenji Arai / JH1PJL
00007  *  http://www.page.sannet.ne.jp/kenjia/index.html
00008  *  http://mbed.org/users/kenjiArai/
00009  *      Started:    October   18th, 2014
00010  *      Revised:    January    1st, 2015
00011  *      Re-started: June      25th, 2016    ported from F411 board
00012  *      Revised:    Novemeber 23rd, 2016
00013  *
00014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00015  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00016  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00017  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
00018  * DAMAGES OR OTHER  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
00019  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
00020  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00021  */
00022 
00023 #ifndef         MBED_FRQ_CUNTR
00024 #define         MBED_FRQ_CUNTR
00025 
00026 #include "mbed.h"
00027 
00028 #define DEBUG   0  // use Communication with PC(UART)
00029 
00030 typedef union
00031 {
00032     struct {
00033         uint64_t    f_1sec_dt;
00034     };
00035     struct {
00036         uint32_t    freq_dt;
00037         uint16_t    f_sw_dt;
00038         uint16_t    t_cnt;
00039     };
00040 } freq_one;
00041 
00042 namespace Frequency_counter
00043 {
00044 
00045 /** Frequency Counter program
00046  *  Only for ST Nucleo-F746ZG Board
00047  *
00048  * @code
00049  * #include "mbed.h"
00050  * #include "frq_cuntr_f746.h"
00051  *
00052  * using namespace Frequency_counter;
00053  *
00054  * // frequency input  -> PC_6 & PA_3
00055  * // 50MHz base clock -> PA_5, GPS 1PPS -> PA_1
00056  * // Connect -> three ports,PA_7,PB_10 and PC_7 connected together
00057  * // CAUTION!!: SB13 & SB181 must remove from Nucleo-F746ZG board
00058  *
00059  * FRQ_CUNTR    fc(49.999992f); // External base clock freq.
00060  *
00061  * int main() {
00062  *   double   cntr_1pps = 0;
00063  *   double   frequency = 0;
00064  *   while(true) {
00065  *      while (fc.status_1pps() == 0) {;}
00066  *      cntr_1pps = fc.read_avarage_1pps();
00067  *      while (fc.status_freq_update() == 0) {;}
00068  *      frequency = fc.read_compensated_freq_data_w_gt(1); // 1sec gate
00069  *      printf("1PPS/ave = %%11.3f, FREQ. = %11.1f\r\n", cntr_1pps, frequency);
00070  *   }
00071  * }
00072  * @endcode
00073  */
00074 
00075 class FRQ_CUNTR
00076 {
00077 
00078 public:
00079 
00080     /** Configure counter
00081       * @param Base clock Frequency [MHz]
00082       */
00083     FRQ_CUNTR(double ex_clock);
00084 
00085     /** Read new frequency data (gate time = 1sec)
00086       * @param none
00087       * @return frequency data
00088       */
00089     double read_freq_data(void);
00090 
00091     /** Read new frequency data with specific gate time
00092       * @param gate time [sec] (1 sec to over 1 hour)
00093       * @return frequency data
00094       */
00095     double read_compensated_freq_data_w_gt(uint16_t gt);
00096     // get raw data
00097     double read_freq_w_gate_time(uint16_t gt);
00098 
00099     /** Read status (new frequency data is available or not)
00100       * @param none
00101       * @return !=0: new data is avairable, 0: not yet
00102       */
00103     uint32_t status_freq_update(void);
00104     
00105     /** Read avarage measured data GPS 1PPS
00106       * @param none
00107       * @return Base clock frequency(average 1(not ave!), 10, 100 & 1000)
00108       */
00109     double read_avarage_1pps(void);
00110 
00111     /** Read number of buffered data
00112       * @param none
00113       * @return number of data in the buffer
00114       */
00115     uint32_t read_num_in_buffer(void);
00116 
00117     /** Read newest measured data GPS 1PPS
00118       * @param none
00119       * @return Base clock frequency (newest(no avaraging value))
00120       */
00121     uint32_t read_newest_1pps(void);
00122 
00123     /** Read status (new 1PPS data is available or not)
00124       * @param none
00125       * @return !=0: new data is avairable, 0: not yet
00126       */
00127     uint32_t status_1pps(void);
00128 
00129     /** Read GPS status
00130       * @param none
00131       * @return     0: GPS is NOT ready
00132       *         not 0: 1PPS data is avairable & show gate_time for avarage
00133       */
00134     uint32_t status_gps(void);
00135 
00136     /** Reciprocal measurement
00137       * preparation for Reciprocal measurement -> recipro_start_measure
00138       * check frequency input as IC trigger -> recipro_check_trigger
00139       * read IC data -> recipro_read_data
00140       */
00141     void     recipro_start_measure(void);
00142     uint32_t recipro_check_trigger(void);
00143     uint32_t recipro_read_data(void);
00144 
00145     /** This is a "DEBUG PURPOSE" function
00146       * Check Base clock frequency on TIM2 or/and TIM8+4
00147       * print internal data (need to define "DEBUG")
00148       * @param gate time e.g. 1sec = 1.0f
00149       * @return Frequency
00150       *     read_base_clock_frequency -> TIM2 data
00151       *     read_input_frequency      -> TIM8+4 data
00152       */
00153     uint32_t read_base_clock_frequency(double gatetime);
00154     uint32_t read_input_frequency(double gatetime);
00155 
00156     /** This is a "DEBUG PURPOSE" function
00157       * print internal data (No need to define "DEBUG")
00158       * @param none
00159       * @return none (just print tha data)
00160       */
00161     void debug_printf_internal_data(void);      
00162     void debug_printf_all_buffer(void);
00163 
00164 protected:
00165     void     initialize_Freq_counter(void); // Initialize timers
00166     void     initialize_TIM2(void);         // Initialize Timer2 (32bit)
00167     void     initialize_TIM8P4(void);       // Initialize Timer8 + 4 (16+16bit)
00168     void     set_external_clock(double ex_clock); // Set OC data
00169     uint32_t calc_1PPS_newest(void);        // Calculate GPS 1PPS newest data
00170     uint32_t read_ic2_counter_TIM2(void);   // Read TIM2 captured counter data
00171     uint32_t check_ic2_status_TIM2(void);   // Check TIM2 IC2 status
00172     uint32_t read_counter_TIM8P4(void);     // Read TIM8+4 captured counter data
00173     uint32_t check_ic1_status_TIM8P4(void); // Check TIM8 IC2 & TIM4 IC1 status
00174     uint8_t  read_oc_port_status(void);     // Check TIM2 OC port
00175     void     set_1sec_gate_time(void);      // Set one second gate time
00176     uint64_t get_diff(uint64_t new_dt, uint64_t old_dt);
00177 
00178 private:
00179     double   newest_frequency;
00180     double   ex_clock_freq;
00181     uint32_t gate_time;
00182     uint32_t ex_clk_base;
00183     uint32_t clk_hi_const;
00184     uint32_t clk_upper_limit;
00185     uint32_t clk_lower_limit;
00186     uint32_t  gps_ready;
00187     // TIM2
00188     uint32_t counter_tim2;
00189     uint32_t old_cntr_tim2;
00190     // TIM8+4
00191     uint32_t counter_tim8p4;
00192     uint32_t old_cntr_tim8p4;
00193     uint16_t sw_ovrflw_tim8p4;
00194     // 1PPS data
00195     uint32_t onepps_newest;
00196     uint8_t  onepps_ready_flg;
00197 
00198 };
00199 
00200 /*
00201     Interrupt handler does NOT work following code
00202     NVIC_SetVector(TIM2_IRQn, (uint32_t)FRQ_CUNTR::irq_ic2_TIM2);
00203     From this reason, I wrote below code and set interrupt handler
00204     out side "FRQ_CUNTR" class
00205     NVIC_SetVector(TIM2_IRQn, (uint32_t)irq_ic2_TIM2);
00206  */
00207 void irq_ic2_TIM2(void);    // TIM2 IC2 Interrupt control
00208 void irq_ic1_TIM8P4(void);  // TIM4 IC1 Interrupt control (also TIM8 IC2)
00209 
00210 }   // Frequency_counter
00211 
00212 #endif  // MBED_FRQ_CUNTR
00213