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/
frq_cuntr_f746.h@5:bb04c4a3b5ba, 2016-11-23 (annotated)
- 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?
User | Revision | Line number | New 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 |