Frequency counter library only for DISCO-F746NG & NucleoF411RE +F446RE
Dependents: FreqCntr_GPS1PPS_F746F4xx_w_recipro Freq_Cntr_GPS1PPS_F746NG_GUI
Fork of Frq_cuntr_full by
Diff: fc_common.cpp
- Revision:
- 5:783b039f9119
diff -r 9d3b3f0a3882 -r 783b039f9119 fc_common.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fc_common.cpp Wed Nov 16 13:13:09 2016 +0000 @@ -0,0 +1,202 @@ +/* + * mbed Library / Frequency Counter using GPS 1PPS gate pulse + * Frequency Counter program (Common part) + * Only for ST DISCO-F746NG and Nucleo-F411RE+F446RE + * + * Copyright (c) 2014,'15,'16 Kenji Arai / JH1PJL + * http://www.page.sannet.ne.jp/kenjia/index.html + * http://mbed.org/users/kenjiArai/ + * Started: October 18th, 2014 + * Revised: January 1st, 2015 + * Re-started: June 25th, 2016 ported from F411 board + * Re-started: October 5th, 2016 Change board -> DISCO-F746NG + * Re-started: October 17th, 2016 Continue F746 and back to F411 + * Revised: November 13th, 2016 + * + * 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 AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "fc_GPS1PPS.h" +#include "RingBuff.h" + +#define ACTIVE_LED_TIMX 0 +#define ACTIVE_LED_TIMZ 0 + +#if ACTIVE_LED_TIMX || ACTIVE_LED_TIMZ +DigitalOut irq_led1(LED1); +#endif + +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) {;} +#endif + +namespace Frequency_counter +{ + +// TIMxPy IC + OverFlow & TIMz IC +static uint8_t timxpy_ready_flg; +static uint32_t timxpy_cnt_data; +static uint16_t time_count; +static uint16_t sw_ovrflw_timxpy; +static uint32_t timz_cnt_data; +static uint16_t time_count_onepps; +// TIMz IC (Reciprocal) + OverFlow +static uint16_t sw_ovrflw_timz; +static uint8_t recipro_step; +static uint32_t recipro_start; +static uint32_t recipro_stop; + +#include "fc_hw_f411.h" +#include "fc_hw_f746.h" + +//------------------------------------------------------------------------------ +// Frequency Counter Library +//------------------------------------------------------------------------------ +FRQ_CUNTR::FRQ_CUNTR(void) +{ + initialize_TIMxPy(); // Use for base functuion (FC based on 1PPS) + initialize_TIMz(); // Use for reciprocal +} + +// Read new frequency data +double FRQ_CUNTR::read_freq_data(void) +{ + return read_freq_w_gate_time(1); // gate time is 1 second +} + +// Read new frequency data with specific gate time +double FRQ_CUNTR::read_freq_w_gate_time(uint16_t gt) +{ + freq_one f_new, f_old; + + if (gt == 0){ return 0.0f;} + f_new.f_1sec_dt = fdt_buffer.ring_get_newest_dt(); // newest data + f_old.f_1sec_dt = fdt_buffer.ring_get_pointed_dt(gt);// gt[sec] before data + uint32_t new_cnt = (uint32_t)f_new.t_cnt; + uint32_t old_cnt = (uint32_t)f_old.t_cnt; + if (old_cnt > new_cnt){ + new_cnt += 0x10000; + } + if ((new_cnt - old_cnt) == gt){ // make sure gt[sec] + uint64_t dt = get_diff(f_new.f_1sec_dt, f_old.f_1sec_dt); + return (double)dt / (double)gt; // Calculate a frequency value + } else { + return 0.0f; // if gt isn't same as buffered number, cancel calculation + } +} + +// Read status (new frequency data is available or not) +uint32_t FRQ_CUNTR::status_freq_update(void) +{ + if (timxpy_ready_flg == 0){ // 1PPS is not comming yet + return 0; + } else { // Gate signal is comming + timxpy_ready_flg = 0; + return 1; + } +} + +// Calculate diff between new & old 48bit data +uint64_t FRQ_CUNTR::get_diff(uint64_t new_dt, uint64_t old_dt){ + uint64_t nw,od; + + nw = new_dt & 0x0000ffffffffffff; // select 48bit data + od = old_dt & 0x0000ffffffffffff; + if (nw < od){ // 48bits counter overflow! + nw += 0x0001000000000000; + } + return (nw - od); +} + +//------------------------------------------------------------------------------ +// Frequency Counter / Reciprocal measurement +//------------------------------------------------------------------------------ +/* // Example +int main(){ + static double freq_recipro; + static uint32_t interval_recipro, base_clk,run2stop; + + while(1){ + fc.recipro_start_measure(); // step1 + while (fc.recipro_check_trigger() == 0){ // step2 + run2stop = tmr.read_ms(); + if (run2stop >= 10000){ break;} + } + if (run2stop >= 100000){ // 10sec 0.01Hz + freq_recipro = 0; + } else { + interval_recipro = fc.recipro_read_data(); // step3 + base_clk = fc.recipro_base_clk_data(1); // step4 + if (interval_recipro >= 9000){// Measure less than 10KHz frequency + // step final + freq_recipro = (double)base_clk / (double)interval_recipro; + } else { + freq_recipro = 0; + } + } + printf("Freq: %11.5f [Hz]", freq_recipro); + printf("Raw: %11u", interval_recipro); + wait(1.0f); // next interval + } +} + */ +// step1 +void FRQ_CUNTR::recipro_start_measure(void) +{ + recipro_step = 0; // initialize step + start_action(); +} + +// step2 +uint32_t FRQ_CUNTR::recipro_check_trigger(void) +{ + if (recipro_step == 2){ // check IC event happen or not + return 1; // happen + } else { + return 0; // not yet + } +} + +// step3 +uint32_t FRQ_CUNTR::recipro_read_data(void) +{ + uint64_t dt; + if (recipro_stop < recipro_start){ // 32bit counter overflow + dt = 0x100000000 + recipro_stop; + dt -= recipro_stop; + } else { + dt = recipro_stop - recipro_start; + } + return (uint32_t)dt; +} + +// step4 +uint32_t FRQ_CUNTR::recipro_base_clk_data(uint16_t gt) +{ + freq_one f_new, f_old; + + if (gt == 0){ return 0.0f;} + f_new.f_1sec_dt = onepps_buf.ring_get_newest_dt(); // newest data + f_old.f_1sec_dt = onepps_buf.ring_get_pointed_dt(gt);// gt[sec] before data + uint32_t new_cnt = (uint32_t)f_new.t_cnt; + uint32_t old_cnt = (uint32_t)f_old.t_cnt; + if (old_cnt > new_cnt){ + new_cnt += 0x10000; + } + if ((new_cnt - old_cnt) == gt){ // make sure gt + uint64_t dt = get_diff(f_new.f_1sec_dt, f_old.f_1sec_dt); + return (double)dt / (double)gt; + } else { + return 0.0f; + } +} + +} // Frequency_counter