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

Please refer following.
/users/kenjiArai/notebook/frequency-counters/

Committer:
kenjiArai
Date:
Wed Nov 23 07:30:55 2016 +0000
Revision:
5:bb04c4a3b5ba
Frequency counter library using GPS 1PPS signal and temperature controlled 50MHz Base clock. Ported from F411 Frequency Counter.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kenjiArai 5:bb04c4a3b5ba 1 /*
kenjiArai 5:bb04c4a3b5ba 2 * mbed Library / Frequency Counter with GPS 1PPS Compensation
kenjiArai 5:bb04c4a3b5ba 3 * Frequency Counter Hardware relataed program
kenjiArai 5:bb04c4a3b5ba 4 * Only for ST Nucleo-F746ZG
kenjiArai 5:bb04c4a3b5ba 5 *
kenjiArai 5:bb04c4a3b5ba 6 * Copyright (c) 2014,'15,'16 Kenji Arai / JH1PJL
kenjiArai 5:bb04c4a3b5ba 7 * http://www.page.sannet.ne.jp/kenjia/index.html
kenjiArai 5:bb04c4a3b5ba 8 * http://mbed.org/users/kenjiArai/
kenjiArai 5:bb04c4a3b5ba 9 * Started: October 18th, 2014
kenjiArai 5:bb04c4a3b5ba 10 * Revised: January 1st, 2015
kenjiArai 5:bb04c4a3b5ba 11 * Re-started: June 25th, 2016 ported from F411 board
kenjiArai 5:bb04c4a3b5ba 12 * Revised: Novemeber 23rd, 2016
kenjiArai 5:bb04c4a3b5ba 13 *
kenjiArai 5:bb04c4a3b5ba 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
kenjiArai 5:bb04c4a3b5ba 15 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
kenjiArai 5:bb04c4a3b5ba 16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
kenjiArai 5:bb04c4a3b5ba 17 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
kenjiArai 5:bb04c4a3b5ba 18 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
kenjiArai 5:bb04c4a3b5ba 19 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
kenjiArai 5:bb04c4a3b5ba 20 * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
kenjiArai 5:bb04c4a3b5ba 21 */
kenjiArai 5:bb04c4a3b5ba 22
kenjiArai 5:bb04c4a3b5ba 23 #ifndef MBED_FRQ_CUNTR
kenjiArai 5:bb04c4a3b5ba 24 #define MBED_FRQ_CUNTR
kenjiArai 5:bb04c4a3b5ba 25
kenjiArai 5:bb04c4a3b5ba 26 #include "mbed.h"
kenjiArai 5:bb04c4a3b5ba 27
kenjiArai 5:bb04c4a3b5ba 28 #define DEBUG 0 // use Communication with PC(UART)
kenjiArai 5:bb04c4a3b5ba 29
kenjiArai 5:bb04c4a3b5ba 30 typedef union
kenjiArai 5:bb04c4a3b5ba 31 {
kenjiArai 5:bb04c4a3b5ba 32 struct {
kenjiArai 5:bb04c4a3b5ba 33 uint64_t f_1sec_dt;
kenjiArai 5:bb04c4a3b5ba 34 };
kenjiArai 5:bb04c4a3b5ba 35 struct {
kenjiArai 5:bb04c4a3b5ba 36 uint32_t freq_dt;
kenjiArai 5:bb04c4a3b5ba 37 uint16_t f_sw_dt;
kenjiArai 5:bb04c4a3b5ba 38 uint16_t t_cnt;
kenjiArai 5:bb04c4a3b5ba 39 };
kenjiArai 5:bb04c4a3b5ba 40 } freq_one;
kenjiArai 5:bb04c4a3b5ba 41
kenjiArai 5:bb04c4a3b5ba 42 namespace Frequency_counter
kenjiArai 5:bb04c4a3b5ba 43 {
kenjiArai 5:bb04c4a3b5ba 44
kenjiArai 5:bb04c4a3b5ba 45 /** Frequency Counter program
kenjiArai 5:bb04c4a3b5ba 46 * Only for ST Nucleo-F746ZG Board
kenjiArai 5:bb04c4a3b5ba 47 *
kenjiArai 5:bb04c4a3b5ba 48 * @code
kenjiArai 5:bb04c4a3b5ba 49 * #include "mbed.h"
kenjiArai 5:bb04c4a3b5ba 50 * #include "frq_cuntr_f746.h"
kenjiArai 5:bb04c4a3b5ba 51 *
kenjiArai 5:bb04c4a3b5ba 52 * using namespace Frequency_counter;
kenjiArai 5:bb04c4a3b5ba 53 *
kenjiArai 5:bb04c4a3b5ba 54 * // frequency input -> PC_6 & PA_3
kenjiArai 5:bb04c4a3b5ba 55 * // 50MHz base clock -> PA_5, GPS 1PPS -> PA_1
kenjiArai 5:bb04c4a3b5ba 56 * // Connect -> three ports,PA_7,PB_10 and PC_7 connected together
kenjiArai 5:bb04c4a3b5ba 57 * // CAUTION!!: SB13 & SB181 must remove from Nucleo-F746ZG board
kenjiArai 5:bb04c4a3b5ba 58 *
kenjiArai 5:bb04c4a3b5ba 59 * FRQ_CUNTR fc(49.999992f); // External base clock freq.
kenjiArai 5:bb04c4a3b5ba 60 *
kenjiArai 5:bb04c4a3b5ba 61 * int main() {
kenjiArai 5:bb04c4a3b5ba 62 * double cntr_1pps = 0;
kenjiArai 5:bb04c4a3b5ba 63 * double frequency = 0;
kenjiArai 5:bb04c4a3b5ba 64 * while(true) {
kenjiArai 5:bb04c4a3b5ba 65 * while (fc.status_1pps() == 0) {;}
kenjiArai 5:bb04c4a3b5ba 66 * cntr_1pps = fc.read_avarage_1pps();
kenjiArai 5:bb04c4a3b5ba 67 * while (fc.status_freq_update() == 0) {;}
kenjiArai 5:bb04c4a3b5ba 68 * frequency = fc.read_compensated_freq_data_w_gt(1); // 1sec gate
kenjiArai 5:bb04c4a3b5ba 69 * printf("1PPS/ave = %%11.3f, FREQ. = %11.1f\r\n", cntr_1pps, frequency);
kenjiArai 5:bb04c4a3b5ba 70 * }
kenjiArai 5:bb04c4a3b5ba 71 * }
kenjiArai 5:bb04c4a3b5ba 72 * @endcode
kenjiArai 5:bb04c4a3b5ba 73 */
kenjiArai 5:bb04c4a3b5ba 74
kenjiArai 5:bb04c4a3b5ba 75 class FRQ_CUNTR
kenjiArai 5:bb04c4a3b5ba 76 {
kenjiArai 5:bb04c4a3b5ba 77
kenjiArai 5:bb04c4a3b5ba 78 public:
kenjiArai 5:bb04c4a3b5ba 79
kenjiArai 5:bb04c4a3b5ba 80 /** Configure counter
kenjiArai 5:bb04c4a3b5ba 81 * @param Base clock Frequency [MHz]
kenjiArai 5:bb04c4a3b5ba 82 */
kenjiArai 5:bb04c4a3b5ba 83 FRQ_CUNTR(double ex_clock);
kenjiArai 5:bb04c4a3b5ba 84
kenjiArai 5:bb04c4a3b5ba 85 /** Read new frequency data (gate time = 1sec)
kenjiArai 5:bb04c4a3b5ba 86 * @param none
kenjiArai 5:bb04c4a3b5ba 87 * @return frequency data
kenjiArai 5:bb04c4a3b5ba 88 */
kenjiArai 5:bb04c4a3b5ba 89 double read_freq_data(void);
kenjiArai 5:bb04c4a3b5ba 90
kenjiArai 5:bb04c4a3b5ba 91 /** Read new frequency data with specific gate time
kenjiArai 5:bb04c4a3b5ba 92 * @param gate time [sec] (1 sec to over 1 hour)
kenjiArai 5:bb04c4a3b5ba 93 * @return frequency data
kenjiArai 5:bb04c4a3b5ba 94 */
kenjiArai 5:bb04c4a3b5ba 95 double read_compensated_freq_data_w_gt(uint16_t gt);
kenjiArai 5:bb04c4a3b5ba 96 // get raw data
kenjiArai 5:bb04c4a3b5ba 97 double read_freq_w_gate_time(uint16_t gt);
kenjiArai 5:bb04c4a3b5ba 98
kenjiArai 5:bb04c4a3b5ba 99 /** Read status (new frequency data is available or not)
kenjiArai 5:bb04c4a3b5ba 100 * @param none
kenjiArai 5:bb04c4a3b5ba 101 * @return !=0: new data is avairable, 0: not yet
kenjiArai 5:bb04c4a3b5ba 102 */
kenjiArai 5:bb04c4a3b5ba 103 uint32_t status_freq_update(void);
kenjiArai 5:bb04c4a3b5ba 104
kenjiArai 5:bb04c4a3b5ba 105 /** Read avarage measured data GPS 1PPS
kenjiArai 5:bb04c4a3b5ba 106 * @param none
kenjiArai 5:bb04c4a3b5ba 107 * @return Base clock frequency(average 1(not ave!), 10, 100 & 1000)
kenjiArai 5:bb04c4a3b5ba 108 */
kenjiArai 5:bb04c4a3b5ba 109 double read_avarage_1pps(void);
kenjiArai 5:bb04c4a3b5ba 110
kenjiArai 5:bb04c4a3b5ba 111 /** Read number of buffered data
kenjiArai 5:bb04c4a3b5ba 112 * @param none
kenjiArai 5:bb04c4a3b5ba 113 * @return number of data in the buffer
kenjiArai 5:bb04c4a3b5ba 114 */
kenjiArai 5:bb04c4a3b5ba 115 uint32_t read_num_in_buffer(void);
kenjiArai 5:bb04c4a3b5ba 116
kenjiArai 5:bb04c4a3b5ba 117 /** Read newest measured data GPS 1PPS
kenjiArai 5:bb04c4a3b5ba 118 * @param none
kenjiArai 5:bb04c4a3b5ba 119 * @return Base clock frequency (newest(no avaraging value))
kenjiArai 5:bb04c4a3b5ba 120 */
kenjiArai 5:bb04c4a3b5ba 121 uint32_t read_newest_1pps(void);
kenjiArai 5:bb04c4a3b5ba 122
kenjiArai 5:bb04c4a3b5ba 123 /** Read status (new 1PPS data is available or not)
kenjiArai 5:bb04c4a3b5ba 124 * @param none
kenjiArai 5:bb04c4a3b5ba 125 * @return !=0: new data is avairable, 0: not yet
kenjiArai 5:bb04c4a3b5ba 126 */
kenjiArai 5:bb04c4a3b5ba 127 uint32_t status_1pps(void);
kenjiArai 5:bb04c4a3b5ba 128
kenjiArai 5:bb04c4a3b5ba 129 /** Read GPS status
kenjiArai 5:bb04c4a3b5ba 130 * @param none
kenjiArai 5:bb04c4a3b5ba 131 * @return 0: GPS is NOT ready
kenjiArai 5:bb04c4a3b5ba 132 * not 0: 1PPS data is avairable & show gate_time for avarage
kenjiArai 5:bb04c4a3b5ba 133 */
kenjiArai 5:bb04c4a3b5ba 134 uint32_t status_gps(void);
kenjiArai 5:bb04c4a3b5ba 135
kenjiArai 5:bb04c4a3b5ba 136 /** Reciprocal measurement
kenjiArai 5:bb04c4a3b5ba 137 * preparation for Reciprocal measurement -> recipro_start_measure
kenjiArai 5:bb04c4a3b5ba 138 * check frequency input as IC trigger -> recipro_check_trigger
kenjiArai 5:bb04c4a3b5ba 139 * read IC data -> recipro_read_data
kenjiArai 5:bb04c4a3b5ba 140 */
kenjiArai 5:bb04c4a3b5ba 141 void recipro_start_measure(void);
kenjiArai 5:bb04c4a3b5ba 142 uint32_t recipro_check_trigger(void);
kenjiArai 5:bb04c4a3b5ba 143 uint32_t recipro_read_data(void);
kenjiArai 5:bb04c4a3b5ba 144
kenjiArai 5:bb04c4a3b5ba 145 /** This is a "DEBUG PURPOSE" function
kenjiArai 5:bb04c4a3b5ba 146 * Check Base clock frequency on TIM2 or/and TIM8+4
kenjiArai 5:bb04c4a3b5ba 147 * print internal data (need to define "DEBUG")
kenjiArai 5:bb04c4a3b5ba 148 * @param gate time e.g. 1sec = 1.0f
kenjiArai 5:bb04c4a3b5ba 149 * @return Frequency
kenjiArai 5:bb04c4a3b5ba 150 * read_base_clock_frequency -> TIM2 data
kenjiArai 5:bb04c4a3b5ba 151 * read_input_frequency -> TIM8+4 data
kenjiArai 5:bb04c4a3b5ba 152 */
kenjiArai 5:bb04c4a3b5ba 153 uint32_t read_base_clock_frequency(double gatetime);
kenjiArai 5:bb04c4a3b5ba 154 uint32_t read_input_frequency(double gatetime);
kenjiArai 5:bb04c4a3b5ba 155
kenjiArai 5:bb04c4a3b5ba 156 /** This is a "DEBUG PURPOSE" function
kenjiArai 5:bb04c4a3b5ba 157 * print internal data (No need to define "DEBUG")
kenjiArai 5:bb04c4a3b5ba 158 * @param none
kenjiArai 5:bb04c4a3b5ba 159 * @return none (just print tha data)
kenjiArai 5:bb04c4a3b5ba 160 */
kenjiArai 5:bb04c4a3b5ba 161 void debug_printf_internal_data(void);
kenjiArai 5:bb04c4a3b5ba 162 void debug_printf_all_buffer(void);
kenjiArai 5:bb04c4a3b5ba 163
kenjiArai 5:bb04c4a3b5ba 164 protected:
kenjiArai 5:bb04c4a3b5ba 165 void initialize_Freq_counter(void); // Initialize timers
kenjiArai 5:bb04c4a3b5ba 166 void initialize_TIM2(void); // Initialize Timer2 (32bit)
kenjiArai 5:bb04c4a3b5ba 167 void initialize_TIM8P4(void); // Initialize Timer8 + 4 (16+16bit)
kenjiArai 5:bb04c4a3b5ba 168 void set_external_clock(double ex_clock); // Set OC data
kenjiArai 5:bb04c4a3b5ba 169 uint32_t calc_1PPS_newest(void); // Calculate GPS 1PPS newest data
kenjiArai 5:bb04c4a3b5ba 170 uint32_t read_ic2_counter_TIM2(void); // Read TIM2 captured counter data
kenjiArai 5:bb04c4a3b5ba 171 uint32_t check_ic2_status_TIM2(void); // Check TIM2 IC2 status
kenjiArai 5:bb04c4a3b5ba 172 uint32_t read_counter_TIM8P4(void); // Read TIM8+4 captured counter data
kenjiArai 5:bb04c4a3b5ba 173 uint32_t check_ic1_status_TIM8P4(void); // Check TIM8 IC2 & TIM4 IC1 status
kenjiArai 5:bb04c4a3b5ba 174 uint8_t read_oc_port_status(void); // Check TIM2 OC port
kenjiArai 5:bb04c4a3b5ba 175 void set_1sec_gate_time(void); // Set one second gate time
kenjiArai 5:bb04c4a3b5ba 176 uint64_t get_diff(uint64_t new_dt, uint64_t old_dt);
kenjiArai 5:bb04c4a3b5ba 177
kenjiArai 5:bb04c4a3b5ba 178 private:
kenjiArai 5:bb04c4a3b5ba 179 double newest_frequency;
kenjiArai 5:bb04c4a3b5ba 180 double ex_clock_freq;
kenjiArai 5:bb04c4a3b5ba 181 uint32_t gate_time;
kenjiArai 5:bb04c4a3b5ba 182 uint32_t ex_clk_base;
kenjiArai 5:bb04c4a3b5ba 183 uint32_t clk_hi_const;
kenjiArai 5:bb04c4a3b5ba 184 uint32_t clk_upper_limit;
kenjiArai 5:bb04c4a3b5ba 185 uint32_t clk_lower_limit;
kenjiArai 5:bb04c4a3b5ba 186 uint32_t gps_ready;
kenjiArai 5:bb04c4a3b5ba 187 // TIM2
kenjiArai 5:bb04c4a3b5ba 188 uint32_t counter_tim2;
kenjiArai 5:bb04c4a3b5ba 189 uint32_t old_cntr_tim2;
kenjiArai 5:bb04c4a3b5ba 190 // TIM8+4
kenjiArai 5:bb04c4a3b5ba 191 uint32_t counter_tim8p4;
kenjiArai 5:bb04c4a3b5ba 192 uint32_t old_cntr_tim8p4;
kenjiArai 5:bb04c4a3b5ba 193 uint16_t sw_ovrflw_tim8p4;
kenjiArai 5:bb04c4a3b5ba 194 // 1PPS data
kenjiArai 5:bb04c4a3b5ba 195 uint32_t onepps_newest;
kenjiArai 5:bb04c4a3b5ba 196 uint8_t onepps_ready_flg;
kenjiArai 5:bb04c4a3b5ba 197
kenjiArai 5:bb04c4a3b5ba 198 };
kenjiArai 5:bb04c4a3b5ba 199
kenjiArai 5:bb04c4a3b5ba 200 /*
kenjiArai 5:bb04c4a3b5ba 201 Interrupt handler does NOT work following code
kenjiArai 5:bb04c4a3b5ba 202 NVIC_SetVector(TIM2_IRQn, (uint32_t)FRQ_CUNTR::irq_ic2_TIM2);
kenjiArai 5:bb04c4a3b5ba 203 From this reason, I wrote below code and set interrupt handler
kenjiArai 5:bb04c4a3b5ba 204 out side "FRQ_CUNTR" class
kenjiArai 5:bb04c4a3b5ba 205 NVIC_SetVector(TIM2_IRQn, (uint32_t)irq_ic2_TIM2);
kenjiArai 5:bb04c4a3b5ba 206 */
kenjiArai 5:bb04c4a3b5ba 207 void irq_ic2_TIM2(void); // TIM2 IC2 Interrupt control
kenjiArai 5:bb04c4a3b5ba 208 void irq_ic1_TIM8P4(void); // TIM4 IC1 Interrupt control (also TIM8 IC2)
kenjiArai 5:bb04c4a3b5ba 209
kenjiArai 5:bb04c4a3b5ba 210 } // Frequency_counter
kenjiArai 5:bb04c4a3b5ba 211
kenjiArai 5:bb04c4a3b5ba 212 #endif // MBED_FRQ_CUNTR
kenjiArai 5:bb04c4a3b5ba 213