Frequency counter library using GPS 1PPS signal and temperature controlled 50MHz Base clock. Ported from F411 Frequency Counter.
Dependents: Frequency_Cntr_1PPS_F746ZG
Fork of Frq_cuntr_full by
Please refer following.
/users/kenjiArai/notebook/frequency-counters/
Diff: frq_cuntr_f746.h
- Revision:
- 5:bb04c4a3b5ba
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/frq_cuntr_f746.h Wed Nov 23 07:30:55 2016 +0000 @@ -0,0 +1,213 @@ +/* + * mbed Library / Frequency Counter with GPS 1PPS Compensation + * Frequency Counter Hardware relataed program + * Only for ST Nucleo-F746ZG + * + * 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 + * Revised: Novemeber 23rd, 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. + */ + +#ifndef MBED_FRQ_CUNTR +#define MBED_FRQ_CUNTR + +#include "mbed.h" + +#define DEBUG 0 // use Communication with PC(UART) + +typedef union +{ + struct { + uint64_t f_1sec_dt; + }; + struct { + uint32_t freq_dt; + uint16_t f_sw_dt; + uint16_t t_cnt; + }; +} freq_one; + +namespace Frequency_counter +{ + +/** Frequency Counter program + * Only for ST Nucleo-F746ZG Board + * + * @code + * #include "mbed.h" + * #include "frq_cuntr_f746.h" + * + * using namespace Frequency_counter; + * + * // frequency input -> PC_6 & PA_3 + * // 50MHz base clock -> PA_5, GPS 1PPS -> PA_1 + * // Connect -> three ports,PA_7,PB_10 and PC_7 connected together + * // CAUTION!!: SB13 & SB181 must remove from Nucleo-F746ZG board + * + * FRQ_CUNTR fc(49.999992f); // External base clock freq. + * + * int main() { + * double cntr_1pps = 0; + * double frequency = 0; + * while(true) { + * while (fc.status_1pps() == 0) {;} + * cntr_1pps = fc.read_avarage_1pps(); + * while (fc.status_freq_update() == 0) {;} + * frequency = fc.read_compensated_freq_data_w_gt(1); // 1sec gate + * printf("1PPS/ave = %%11.3f, FREQ. = %11.1f\r\n", cntr_1pps, frequency); + * } + * } + * @endcode + */ + +class FRQ_CUNTR +{ + +public: + + /** Configure counter + * @param Base clock Frequency [MHz] + */ + FRQ_CUNTR(double ex_clock); + + /** Read new frequency data (gate time = 1sec) + * @param none + * @return frequency data + */ + double read_freq_data(void); + + /** Read new frequency data with specific gate time + * @param gate time [sec] (1 sec to over 1 hour) + * @return frequency data + */ + double read_compensated_freq_data_w_gt(uint16_t gt); + // get raw data + double read_freq_w_gate_time(uint16_t gt); + + /** Read status (new frequency data is available or not) + * @param none + * @return !=0: new data is avairable, 0: not yet + */ + uint32_t status_freq_update(void); + + /** Read avarage measured data GPS 1PPS + * @param none + * @return Base clock frequency(average 1(not ave!), 10, 100 & 1000) + */ + double read_avarage_1pps(void); + + /** Read number of buffered data + * @param none + * @return number of data in the buffer + */ + uint32_t read_num_in_buffer(void); + + /** Read newest measured data GPS 1PPS + * @param none + * @return Base clock frequency (newest(no avaraging value)) + */ + uint32_t read_newest_1pps(void); + + /** Read status (new 1PPS data is available or not) + * @param none + * @return !=0: new data is avairable, 0: not yet + */ + uint32_t status_1pps(void); + + /** Read GPS status + * @param none + * @return 0: GPS is NOT ready + * not 0: 1PPS data is avairable & show gate_time for avarage + */ + uint32_t status_gps(void); + + /** Reciprocal measurement + * preparation for Reciprocal measurement -> recipro_start_measure + * check frequency input as IC trigger -> recipro_check_trigger + * read IC data -> recipro_read_data + */ + void recipro_start_measure(void); + uint32_t recipro_check_trigger(void); + uint32_t recipro_read_data(void); + + /** This is a "DEBUG PURPOSE" function + * Check Base clock frequency on TIM2 or/and TIM8+4 + * print internal data (need to define "DEBUG") + * @param gate time e.g. 1sec = 1.0f + * @return Frequency + * read_base_clock_frequency -> TIM2 data + * read_input_frequency -> TIM8+4 data + */ + uint32_t read_base_clock_frequency(double gatetime); + uint32_t read_input_frequency(double gatetime); + + /** This is a "DEBUG PURPOSE" function + * print internal data (No need to define "DEBUG") + * @param none + * @return none (just print tha data) + */ + void debug_printf_internal_data(void); + void debug_printf_all_buffer(void); + +protected: + void initialize_Freq_counter(void); // Initialize timers + void initialize_TIM2(void); // Initialize Timer2 (32bit) + void initialize_TIM8P4(void); // Initialize Timer8 + 4 (16+16bit) + void set_external_clock(double ex_clock); // Set OC data + uint32_t calc_1PPS_newest(void); // Calculate GPS 1PPS newest data + uint32_t read_ic2_counter_TIM2(void); // Read TIM2 captured counter data + uint32_t check_ic2_status_TIM2(void); // Check TIM2 IC2 status + uint32_t read_counter_TIM8P4(void); // Read TIM8+4 captured counter data + uint32_t check_ic1_status_TIM8P4(void); // Check TIM8 IC2 & TIM4 IC1 status + uint8_t read_oc_port_status(void); // Check TIM2 OC port + void set_1sec_gate_time(void); // Set one second gate time + uint64_t get_diff(uint64_t new_dt, uint64_t old_dt); + +private: + double newest_frequency; + double ex_clock_freq; + uint32_t gate_time; + uint32_t ex_clk_base; + uint32_t clk_hi_const; + uint32_t clk_upper_limit; + uint32_t clk_lower_limit; + uint32_t gps_ready; + // TIM2 + uint32_t counter_tim2; + uint32_t old_cntr_tim2; + // TIM8+4 + uint32_t counter_tim8p4; + uint32_t old_cntr_tim8p4; + uint16_t sw_ovrflw_tim8p4; + // 1PPS data + uint32_t onepps_newest; + uint8_t onepps_ready_flg; + +}; + +/* + Interrupt handler does NOT work following code + NVIC_SetVector(TIM2_IRQn, (uint32_t)FRQ_CUNTR::irq_ic2_TIM2); + From this reason, I wrote below code and set interrupt handler + out side "FRQ_CUNTR" class + NVIC_SetVector(TIM2_IRQn, (uint32_t)irq_ic2_TIM2); + */ +void irq_ic2_TIM2(void); // TIM2 IC2 Interrupt control +void irq_ic1_TIM8P4(void); // TIM4 IC1 Interrupt control (also TIM8 IC2) + +} // Frequency_counter + +#endif // MBED_FRQ_CUNTR +