Kenji Arai / fc_GPS1PPS_f746_f4xx

Dependencies:   RingBuff

Dependents:   FreqCntr_GPS1PPS_F746F4xx_w_recipro Freq_Cntr_GPS1PPS_F746NG_GUI

Fork of Frq_cuntr_full by Kenji Arai

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers fc_common.cpp Source File

fc_common.cpp

00001 /*
00002  * mbed Library / Frequency Counter using GPS 1PPS gate pulse
00003  *      Frequency Counter program (Common part)
00004  *      Only for ST DISCO-F746NG and Nucleo-F411RE+F446RE
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  *      Re-started: October    5th, 2016    Change board -> DISCO-F746NG
00013  *      Re-started: October   17th, 2016    Continue F746 and back to F411
00014  *      Revised:    November  13th, 2016
00015  *
00016  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00017  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00018  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00019  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
00020  * DAMAGES OR OTHER  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
00021  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
00022  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00023  */
00024 
00025 #include    "fc_GPS1PPS.h"
00026 #include    "RingBuff.h"
00027 
00028 #define     ACTIVE_LED_TIMX     0
00029 #define     ACTIVE_LED_TIMZ     0
00030 
00031 #if ACTIVE_LED_TIMX || ACTIVE_LED_TIMZ
00032 DigitalOut irq_led1(LED1);
00033 #endif
00034 
00035 #if DEBUG
00036 #define PRINTF(...)     printf(__VA_ARGS__)
00037 #else
00038 #define PRINTF(...)     {;}
00039 #endif
00040 
00041 namespace Frequency_counter
00042 {
00043 
00044 // TIMxPy IC + OverFlow & TIMz IC
00045 static uint8_t  timxpy_ready_flg;
00046 static uint32_t timxpy_cnt_data;
00047 static uint16_t time_count;
00048 static uint16_t sw_ovrflw_timxpy;
00049 static uint32_t timz_cnt_data;
00050 static uint16_t time_count_onepps;
00051 // TIMz IC (Reciprocal) + OverFlow
00052 static uint16_t sw_ovrflw_timz;
00053 static uint8_t  recipro_step;
00054 static uint32_t recipro_start;
00055 static uint32_t recipro_stop;
00056 
00057 #include    "fc_hw_f411.h"
00058 #include    "fc_hw_f746.h"
00059 
00060 //------------------------------------------------------------------------------
00061 //  Frequency Counter Library
00062 //------------------------------------------------------------------------------
00063 FRQ_CUNTR::FRQ_CUNTR(void)
00064 {
00065     initialize_TIMxPy();    // Use for base functuion (FC based on 1PPS)
00066     initialize_TIMz();      // Use for reciprocal
00067 }
00068 
00069 // Read new frequency data
00070 double FRQ_CUNTR::read_freq_data(void)
00071 {
00072     return read_freq_w_gate_time(1);    // gate time is 1 second
00073 }
00074 
00075 // Read new frequency data with specific gate time
00076 double FRQ_CUNTR::read_freq_w_gate_time(uint16_t gt)
00077 {
00078     freq_one f_new, f_old;
00079 
00080     if (gt == 0){ return 0.0f;}
00081     f_new.f_1sec_dt = fdt_buffer.ring_get_newest_dt();   // newest data
00082     f_old.f_1sec_dt = fdt_buffer.ring_get_pointed_dt(gt);// gt[sec] before data
00083     uint32_t new_cnt = (uint32_t)f_new.t_cnt;
00084     uint32_t old_cnt = (uint32_t)f_old.t_cnt;
00085     if (old_cnt > new_cnt){
00086         new_cnt += 0x10000;
00087     }
00088     if ((new_cnt - old_cnt) == gt){  // make sure gt[sec]
00089         uint64_t dt = get_diff(f_new.f_1sec_dt, f_old.f_1sec_dt);
00090         return (double)dt / (double)gt; // Calculate a frequency value
00091     } else {
00092         return 0.0f;  // if gt isn't same as buffered number, cancel calculation
00093     }
00094 }
00095 
00096 // Read status (new frequency data is available or not)
00097 uint32_t FRQ_CUNTR::status_freq_update(void)
00098 {
00099     if (timxpy_ready_flg == 0){ // 1PPS is not comming yet
00100         return 0;
00101     } else {                    // Gate signal is comming
00102         timxpy_ready_flg = 0;
00103         return 1;
00104     }
00105 }
00106 
00107 // Calculate diff between new & old 48bit data
00108 uint64_t FRQ_CUNTR::get_diff(uint64_t new_dt, uint64_t old_dt){
00109     uint64_t nw,od;
00110 
00111     nw = new_dt & 0x0000ffffffffffff;   // select 48bit data
00112     od = old_dt & 0x0000ffffffffffff;
00113     if (nw < od){ // 48bits counter overflow!
00114         nw += 0x0001000000000000;
00115     }
00116     return (nw - od);
00117 }
00118 
00119 //------------------------------------------------------------------------------
00120 //  Frequency Counter / Reciprocal measurement
00121 //------------------------------------------------------------------------------
00122 /*  // Example
00123 int main(){
00124     static double       freq_recipro;
00125     static uint32_t     interval_recipro, base_clk,run2stop;
00126 
00127     while(1){
00128         fc.recipro_start_measure();                         // step1
00129         while (fc.recipro_check_trigger() == 0){            // step2
00130             run2stop = tmr.read_ms();
00131             if (run2stop >= 10000){  break;}
00132         }
00133         if (run2stop >= 100000){ // 10sec 0.01Hz
00134             freq_recipro = 0;
00135         } else {
00136             interval_recipro = fc.recipro_read_data();      // step3
00137             base_clk = fc.recipro_base_clk_data(1);         // step4
00138             if (interval_recipro >= 9000){// Measure less than 10KHz frequency
00139                                                             // step final
00140                 freq_recipro = (double)base_clk / (double)interval_recipro;
00141             } else {
00142                 freq_recipro = 0;
00143             }
00144         }
00145         printf("Freq: %11.5f [Hz]", freq_recipro);
00146         printf("Raw:  %11u", interval_recipro);
00147         wait(1.0f);  // next interval
00148     }
00149 }
00150  */
00151 // step1
00152 void FRQ_CUNTR::recipro_start_measure(void)
00153 {
00154     recipro_step = 0;               // initialize step
00155     start_action();
00156 }
00157 
00158 // step2
00159 uint32_t FRQ_CUNTR::recipro_check_trigger(void)
00160 {
00161     if (recipro_step == 2){         // check IC event happen or not
00162         return 1;                   // happen
00163     } else {
00164         return 0;                   // not yet
00165     }
00166 }
00167 
00168 // step3
00169 uint32_t FRQ_CUNTR::recipro_read_data(void)
00170 {
00171     uint64_t dt;
00172     if (recipro_stop < recipro_start){  // 32bit counter overflow
00173         dt =  0x100000000 +  recipro_stop;
00174         dt -=  recipro_stop;
00175     } else {
00176         dt = recipro_stop - recipro_start;
00177     }
00178     return (uint32_t)dt;
00179 }
00180 
00181 // step4
00182 uint32_t FRQ_CUNTR::recipro_base_clk_data(uint16_t gt)
00183 {
00184     freq_one f_new, f_old;
00185 
00186     if (gt == 0){ return 0.0f;}
00187     f_new.f_1sec_dt = onepps_buf.ring_get_newest_dt();   // newest data
00188     f_old.f_1sec_dt = onepps_buf.ring_get_pointed_dt(gt);// gt[sec] before data
00189     uint32_t new_cnt = (uint32_t)f_new.t_cnt;
00190     uint32_t old_cnt = (uint32_t)f_old.t_cnt;
00191     if (old_cnt > new_cnt){
00192         new_cnt += 0x10000;
00193     }
00194     if ((new_cnt - old_cnt) == gt){  // make sure gt
00195         uint64_t dt = get_diff(f_new.f_1sec_dt, f_old.f_1sec_dt);
00196         return (double)dt / (double)gt;
00197     } else {
00198         return 0.0f;
00199     }
00200 }
00201 
00202 }   // Frequency_counter