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 #if !defined(TARGET_STM32F746ZG)
kenjiArai 5:bb04c4a3b5ba 24 #error "This function works only on F746ZG!!"
kenjiArai 5:bb04c4a3b5ba 25 #endif // !defined(TARGET_STM32F746ZG)
kenjiArai 5:bb04c4a3b5ba 26
kenjiArai 5:bb04c4a3b5ba 27 #include "frq_cuntr_f746.h"
kenjiArai 5:bb04c4a3b5ba 28 #include "RingBuff.h"
kenjiArai 5:bb04c4a3b5ba 29
kenjiArai 5:bb04c4a3b5ba 30 #define ACTIVE_LED 1
kenjiArai 5:bb04c4a3b5ba 31
kenjiArai 5:bb04c4a3b5ba 32 #if ACTIVE_LED
kenjiArai 5:bb04c4a3b5ba 33 DigitalOut irq_led1(LED1);
kenjiArai 5:bb04c4a3b5ba 34 DigitalOut irq_led2(LED2);
kenjiArai 5:bb04c4a3b5ba 35 DigitalOut irq_led3(LED3);
kenjiArai 5:bb04c4a3b5ba 36 #endif
kenjiArai 5:bb04c4a3b5ba 37
kenjiArai 5:bb04c4a3b5ba 38 #if DEBUG
kenjiArai 5:bb04c4a3b5ba 39 #define PRINTF(...) printf(__VA_ARGS__)
kenjiArai 5:bb04c4a3b5ba 40 #else
kenjiArai 5:bb04c4a3b5ba 41 #define PRINTF(...) {;}
kenjiArai 5:bb04c4a3b5ba 42 #endif
kenjiArai 5:bb04c4a3b5ba 43
kenjiArai 5:bb04c4a3b5ba 44 namespace Frequency_counter
kenjiArai 5:bb04c4a3b5ba 45 {
kenjiArai 5:bb04c4a3b5ba 46
kenjiArai 5:bb04c4a3b5ba 47 // Following ring buffers are very big!! 4096 x 8(bytes) x 2(buff) = 64KB
kenjiArai 5:bb04c4a3b5ba 48 RingBuff<uint64_t> onepps_buf; // RinBuffer for 1PPS (TIM2)
kenjiArai 5:bb04c4a3b5ba 49 freq_one onepps_dt; // frequency data in pack (interrupt)
kenjiArai 5:bb04c4a3b5ba 50 RingBuff<uint64_t> fdt_buffer; // RinBuffer for TIM8+4
kenjiArai 5:bb04c4a3b5ba 51 freq_one fdt; // frequency data in pack (interrupt)
kenjiArai 5:bb04c4a3b5ba 52
kenjiArai 5:bb04c4a3b5ba 53 // TIM2 IC2 + OverFlow
kenjiArai 5:bb04c4a3b5ba 54 static uint8_t tim2_ready_flg;
kenjiArai 5:bb04c4a3b5ba 55 static uint32_t tim2_cnt_data;
kenjiArai 5:bb04c4a3b5ba 56 static uint16_t time_count_onepps;
kenjiArai 5:bb04c4a3b5ba 57 static uint16_t sw_ovrflw_tim2;
kenjiArai 5:bb04c4a3b5ba 58 // TIM2 IC4 (Reciprocal)
kenjiArai 5:bb04c4a3b5ba 59 static uint8_t recipro_step;
kenjiArai 5:bb04c4a3b5ba 60 static uint32_t recipro_start;
kenjiArai 5:bb04c4a3b5ba 61 static uint32_t recipro_stop;
kenjiArai 5:bb04c4a3b5ba 62 // TIM2 OC
kenjiArai 5:bb04c4a3b5ba 63 static uint32_t oc_hi_time;
kenjiArai 5:bb04c4a3b5ba 64 static uint32_t oc_lo_time;
kenjiArai 5:bb04c4a3b5ba 65 // TIM4(TIM8) IC + OverFlow
kenjiArai 5:bb04c4a3b5ba 66 static uint8_t tim8p4_ready_flg;
kenjiArai 5:bb04c4a3b5ba 67 static uint32_t tim8p4_cnt_data;
kenjiArai 5:bb04c4a3b5ba 68 static uint16_t time_count;
kenjiArai 5:bb04c4a3b5ba 69 static uint16_t sw_ovrflw_tim8p4;
kenjiArai 5:bb04c4a3b5ba 70
kenjiArai 5:bb04c4a3b5ba 71 //------------------------------------------------------------------------------
kenjiArai 5:bb04c4a3b5ba 72 // Frequency Counter
kenjiArai 5:bb04c4a3b5ba 73 //------------------------------------------------------------------------------
kenjiArai 5:bb04c4a3b5ba 74 FRQ_CUNTR::FRQ_CUNTR(double ex_clock)
kenjiArai 5:bb04c4a3b5ba 75 {
kenjiArai 5:bb04c4a3b5ba 76 // Don't change calling sequence!!
kenjiArai 5:bb04c4a3b5ba 77 set_external_clock(ex_clock); // 1st
kenjiArai 5:bb04c4a3b5ba 78 set_1sec_gate_time(); // 2nd
kenjiArai 5:bb04c4a3b5ba 79 initialize_Freq_counter(); // 3rd
kenjiArai 5:bb04c4a3b5ba 80 }
kenjiArai 5:bb04c4a3b5ba 81
kenjiArai 5:bb04c4a3b5ba 82 // Set External Clock Frequency
kenjiArai 5:bb04c4a3b5ba 83 void FRQ_CUNTR::set_external_clock(double ex_clock)
kenjiArai 5:bb04c4a3b5ba 84 {
kenjiArai 5:bb04c4a3b5ba 85 ex_clock_freq = ex_clock;
kenjiArai 5:bb04c4a3b5ba 86 ex_clk_base = (uint32_t)(ex_clock_freq * 1000000.0f); // MHz->Hz
kenjiArai 5:bb04c4a3b5ba 87 clk_hi_const = (uint32_t)(ex_clock_freq * 1000000.0f * 0.2f);// Count=200mS
kenjiArai 5:bb04c4a3b5ba 88 // 100ppm error range
kenjiArai 5:bb04c4a3b5ba 89 uint32_t err = (uint32_t)(ex_clock_freq * 1000000.0f * 0.0001f);
kenjiArai 5:bb04c4a3b5ba 90 clk_upper_limit = ex_clk_base + err;
kenjiArai 5:bb04c4a3b5ba 91 clk_lower_limit = ex_clk_base - err;
kenjiArai 5:bb04c4a3b5ba 92 PRINTF("\r\nSet EXTERNAL Clock mode\r\n");
kenjiArai 5:bb04c4a3b5ba 93 }
kenjiArai 5:bb04c4a3b5ba 94
kenjiArai 5:bb04c4a3b5ba 95 // Set real gate time
kenjiArai 5:bb04c4a3b5ba 96 void FRQ_CUNTR::set_1sec_gate_time(void)
kenjiArai 5:bb04c4a3b5ba 97 {
kenjiArai 5:bb04c4a3b5ba 98 oc_hi_time = clk_hi_const; // 200mS
kenjiArai 5:bb04c4a3b5ba 99 double gt_tmp0 = ex_clk_base * 1.0f; // one sec
kenjiArai 5:bb04c4a3b5ba 100 uint32_t gt_tmp1 = (uint32_t)gt_tmp0;
kenjiArai 5:bb04c4a3b5ba 101 if ((gt_tmp0 - (double)gt_tmp1) >= 0.5f){
kenjiArai 5:bb04c4a3b5ba 102 ++gt_tmp1;
kenjiArai 5:bb04c4a3b5ba 103 if ((gt_tmp0 - (double)gt_tmp1) >= 0.5f){
kenjiArai 5:bb04c4a3b5ba 104 ++gt_tmp1;
kenjiArai 5:bb04c4a3b5ba 105 }
kenjiArai 5:bb04c4a3b5ba 106 }
kenjiArai 5:bb04c4a3b5ba 107 oc_lo_time = gt_tmp1 - clk_hi_const;
kenjiArai 5:bb04c4a3b5ba 108 }
kenjiArai 5:bb04c4a3b5ba 109
kenjiArai 5:bb04c4a3b5ba 110 void FRQ_CUNTR::initialize_Freq_counter(void)
kenjiArai 5:bb04c4a3b5ba 111 {
kenjiArai 5:bb04c4a3b5ba 112 initialize_TIM2();
kenjiArai 5:bb04c4a3b5ba 113 initialize_TIM8P4();
kenjiArai 5:bb04c4a3b5ba 114 }
kenjiArai 5:bb04c4a3b5ba 115
kenjiArai 5:bb04c4a3b5ba 116 // Read new frequency data
kenjiArai 5:bb04c4a3b5ba 117 double FRQ_CUNTR::read_freq_data(void)
kenjiArai 5:bb04c4a3b5ba 118 {
kenjiArai 5:bb04c4a3b5ba 119 return read_freq_w_gate_time(1);
kenjiArai 5:bb04c4a3b5ba 120 }
kenjiArai 5:bb04c4a3b5ba 121
kenjiArai 5:bb04c4a3b5ba 122 // Read compensated frequency data with suitable gate time
kenjiArai 5:bb04c4a3b5ba 123 /*
kenjiArai 5:bb04c4a3b5ba 124 yr: Measured 1PPS
kenjiArai 5:bb04c4a3b5ba 125 yi: Ideal 1PPS (expected value)
kenjiArai 5:bb04c4a3b5ba 126 xr: Measued unkown frequency data
kenjiArai 5:bb04c4a3b5ba 127 ---> xi: Compesated data
kenjiArai 5:bb04c4a3b5ba 128 comp = (yr-yi)/yi
kenjiArai 5:bb04c4a3b5ba 129 -> delta = comp * xr
kenjiArai 5:bb04c4a3b5ba 130 -> xi = xr + delta = compensated data
kenjiArai 5:bb04c4a3b5ba 131 */
kenjiArai 5:bb04c4a3b5ba 132 double FRQ_CUNTR::read_compensated_freq_data_w_gt(uint16_t gt)
kenjiArai 5:bb04c4a3b5ba 133 {
kenjiArai 5:bb04c4a3b5ba 134 freq_one f_new, f_old;
kenjiArai 5:bb04c4a3b5ba 135 freq_one one_new, one_old;
kenjiArai 5:bb04c4a3b5ba 136 uint32_t new_cnt, old_cnt;
kenjiArai 5:bb04c4a3b5ba 137 uint64_t temp0;
kenjiArai 5:bb04c4a3b5ba 138 double temp1, temp2;
kenjiArai 5:bb04c4a3b5ba 139
kenjiArai 5:bb04c4a3b5ba 140 f_new.f_1sec_dt = fdt_buffer.ring_get_newest_dt(); // newest data
kenjiArai 5:bb04c4a3b5ba 141 f_old.f_1sec_dt = fdt_buffer.ring_get_pointed_dt(gt);// gt[sec] before data
kenjiArai 5:bb04c4a3b5ba 142 one_new.f_1sec_dt = onepps_buf.ring_get_newest_dt();
kenjiArai 5:bb04c4a3b5ba 143 one_old.f_1sec_dt = onepps_buf.ring_get_pointed_dt(gt);
kenjiArai 5:bb04c4a3b5ba 144 new_cnt = (uint32_t)f_new.t_cnt;
kenjiArai 5:bb04c4a3b5ba 145 old_cnt = (uint32_t)f_old.t_cnt;
kenjiArai 5:bb04c4a3b5ba 146 if (old_cnt > new_cnt){
kenjiArai 5:bb04c4a3b5ba 147 new_cnt += 0x10000;
kenjiArai 5:bb04c4a3b5ba 148 }
kenjiArai 5:bb04c4a3b5ba 149 if ((new_cnt - old_cnt) != gt){
kenjiArai 5:bb04c4a3b5ba 150 return 0.0f;
kenjiArai 5:bb04c4a3b5ba 151 }
kenjiArai 5:bb04c4a3b5ba 152 new_cnt = (uint32_t)one_new.t_cnt;
kenjiArai 5:bb04c4a3b5ba 153 old_cnt = (uint32_t)one_old.t_cnt;
kenjiArai 5:bb04c4a3b5ba 154 if (old_cnt > new_cnt){
kenjiArai 5:bb04c4a3b5ba 155 new_cnt += 0x10000;
kenjiArai 5:bb04c4a3b5ba 156 }
kenjiArai 5:bb04c4a3b5ba 157 if ((new_cnt - old_cnt) != gt){
kenjiArai 5:bb04c4a3b5ba 158 return 0.0f;
kenjiArai 5:bb04c4a3b5ba 159 }
kenjiArai 5:bb04c4a3b5ba 160 // comp = (yr-yi)/yi
kenjiArai 5:bb04c4a3b5ba 161 temp0 = get_diff(one_new.f_1sec_dt, one_old.f_1sec_dt);
kenjiArai 5:bb04c4a3b5ba 162 temp1 = (double)temp0 - ex_clock_freq * 1000000.0f * (double)gt;
kenjiArai 5:bb04c4a3b5ba 163 temp2 = temp1 / (ex_clock_freq * 1000000.0f * (double)gt);
kenjiArai 5:bb04c4a3b5ba 164 // delta = comp * xr
kenjiArai 5:bb04c4a3b5ba 165 temp0 = get_diff(f_new.f_1sec_dt, f_old.f_1sec_dt);
kenjiArai 5:bb04c4a3b5ba 166 temp1 = temp2 * (double)temp0;
kenjiArai 5:bb04c4a3b5ba 167 // xi = xr + delta
kenjiArai 5:bb04c4a3b5ba 168 temp2 = (double)temp0 + temp1;
kenjiArai 5:bb04c4a3b5ba 169 return temp2 / (double)gt;
kenjiArai 5:bb04c4a3b5ba 170 }
kenjiArai 5:bb04c4a3b5ba 171
kenjiArai 5:bb04c4a3b5ba 172 // Read new frequency data with specific gate time
kenjiArai 5:bb04c4a3b5ba 173 double FRQ_CUNTR::read_freq_w_gate_time(uint16_t gt)
kenjiArai 5:bb04c4a3b5ba 174 {
kenjiArai 5:bb04c4a3b5ba 175 freq_one f_new, f_old;
kenjiArai 5:bb04c4a3b5ba 176
kenjiArai 5:bb04c4a3b5ba 177 if (gt == 0){ return 0.0f;}
kenjiArai 5:bb04c4a3b5ba 178 f_new.f_1sec_dt = fdt_buffer.ring_get_newest_dt(); // newest data
kenjiArai 5:bb04c4a3b5ba 179 f_old.f_1sec_dt = fdt_buffer.ring_get_pointed_dt(gt);// gt[sec] before data
kenjiArai 5:bb04c4a3b5ba 180 uint32_t new_cnt = (uint32_t)f_new.t_cnt;
kenjiArai 5:bb04c4a3b5ba 181 uint32_t old_cnt = (uint32_t)f_old.t_cnt;
kenjiArai 5:bb04c4a3b5ba 182 if (old_cnt > new_cnt){
kenjiArai 5:bb04c4a3b5ba 183 new_cnt += 0x10000;
kenjiArai 5:bb04c4a3b5ba 184 }
kenjiArai 5:bb04c4a3b5ba 185 if ((new_cnt - old_cnt) == gt){ // make sure gt[sec]
kenjiArai 5:bb04c4a3b5ba 186 uint64_t dt = get_diff(f_new.f_1sec_dt, f_old.f_1sec_dt);
kenjiArai 5:bb04c4a3b5ba 187 return (double)dt / (double)gt;
kenjiArai 5:bb04c4a3b5ba 188 } else {
kenjiArai 5:bb04c4a3b5ba 189 return 0.0f;
kenjiArai 5:bb04c4a3b5ba 190 }
kenjiArai 5:bb04c4a3b5ba 191 }
kenjiArai 5:bb04c4a3b5ba 192
kenjiArai 5:bb04c4a3b5ba 193 // Read status (new frequency data is available or not)
kenjiArai 5:bb04c4a3b5ba 194 uint32_t FRQ_CUNTR::status_freq_update(void)
kenjiArai 5:bb04c4a3b5ba 195 {
kenjiArai 5:bb04c4a3b5ba 196 return check_ic1_status_TIM8P4();
kenjiArai 5:bb04c4a3b5ba 197 }
kenjiArai 5:bb04c4a3b5ba 198
kenjiArai 5:bb04c4a3b5ba 199 // Read status (new 1PPS data is available or not)
kenjiArai 5:bb04c4a3b5ba 200 uint32_t FRQ_CUNTR::status_1pps(void)
kenjiArai 5:bb04c4a3b5ba 201 {
kenjiArai 5:bb04c4a3b5ba 202 return check_ic2_status_TIM2();
kenjiArai 5:bb04c4a3b5ba 203 }
kenjiArai 5:bb04c4a3b5ba 204
kenjiArai 5:bb04c4a3b5ba 205 // Read GPS 1PPS counter value
kenjiArai 5:bb04c4a3b5ba 206 uint32_t FRQ_CUNTR::calc_1PPS_newest(void)
kenjiArai 5:bb04c4a3b5ba 207 {
kenjiArai 5:bb04c4a3b5ba 208 freq_one f_new, f_old;
kenjiArai 5:bb04c4a3b5ba 209 uint64_t diff = 0;
kenjiArai 5:bb04c4a3b5ba 210
kenjiArai 5:bb04c4a3b5ba 211 f_new.f_1sec_dt = onepps_buf.ring_get_newest_dt(); // newest data
kenjiArai 5:bb04c4a3b5ba 212 f_old.f_1sec_dt = onepps_buf.ring_get_pointed_dt(1);
kenjiArai 5:bb04c4a3b5ba 213 uint32_t new_cnt = (uint32_t)f_new.t_cnt;
kenjiArai 5:bb04c4a3b5ba 214 uint32_t old_cnt = (uint32_t)f_old.t_cnt;
kenjiArai 5:bb04c4a3b5ba 215 if (old_cnt > new_cnt){
kenjiArai 5:bb04c4a3b5ba 216 new_cnt += 0x10000;
kenjiArai 5:bb04c4a3b5ba 217 }
kenjiArai 5:bb04c4a3b5ba 218 if ((new_cnt - old_cnt) == 1){ // make sure gt[sec]
kenjiArai 5:bb04c4a3b5ba 219 diff = get_diff(f_new.f_1sec_dt, f_old.f_1sec_dt);
kenjiArai 5:bb04c4a3b5ba 220 }
kenjiArai 5:bb04c4a3b5ba 221 if ((diff > clk_upper_limit) || (diff < clk_lower_limit)){
kenjiArai 5:bb04c4a3b5ba 222 // Missing 1PPS signal or Base clock is out of range
kenjiArai 5:bb04c4a3b5ba 223 gps_ready = 0;
kenjiArai 5:bb04c4a3b5ba 224 onepps_buf.ring_clear_buf(); // Clear ring buffer
kenjiArai 5:bb04c4a3b5ba 225 return 0;
kenjiArai 5:bb04c4a3b5ba 226 } else { // GPS 1pps is in good range
kenjiArai 5:bb04c4a3b5ba 227 gps_ready = 1;
kenjiArai 5:bb04c4a3b5ba 228 onepps_ready_flg = 0;
kenjiArai 5:bb04c4a3b5ba 229 onepps_newest = diff;
kenjiArai 5:bb04c4a3b5ba 230 return diff;
kenjiArai 5:bb04c4a3b5ba 231 }
kenjiArai 5:bb04c4a3b5ba 232 }
kenjiArai 5:bb04c4a3b5ba 233
kenjiArai 5:bb04c4a3b5ba 234 // Avarage measured data GPS 1PPS by External Base Clock
kenjiArai 5:bb04c4a3b5ba 235 double FRQ_CUNTR::read_avarage_1pps(void)
kenjiArai 5:bb04c4a3b5ba 236 {
kenjiArai 5:bb04c4a3b5ba 237 freq_one f_new, f_old;
kenjiArai 5:bb04c4a3b5ba 238 int16_t size = 0;
kenjiArai 5:bb04c4a3b5ba 239
kenjiArai 5:bb04c4a3b5ba 240 f_new.f_1sec_dt = onepps_buf.ring_get_newest_dt(); // newest data
kenjiArai 5:bb04c4a3b5ba 241 size = onepps_buf.ring_get_buf_size();
kenjiArai 5:bb04c4a3b5ba 242 if (size >= 1500){ // Not use old 500 data
kenjiArai 5:bb04c4a3b5ba 243 gate_time = 1000; // Gate Time = 16min40sec
kenjiArai 5:bb04c4a3b5ba 244 } else if (size >= 200){// Not use old 100 data
kenjiArai 5:bb04c4a3b5ba 245 gate_time = 100; // Gate Time = 1min40sec
kenjiArai 5:bb04c4a3b5ba 246 } else if (size >= 20){ // Not use old 10 data
kenjiArai 5:bb04c4a3b5ba 247 gate_time = 10; // Gate Time = 10sec
kenjiArai 5:bb04c4a3b5ba 248 } else if (size >= 10){ // Not use old 9 data
kenjiArai 5:bb04c4a3b5ba 249 gate_time = 1; // Gate Time = 1sec
kenjiArai 5:bb04c4a3b5ba 250 } else {
kenjiArai 5:bb04c4a3b5ba 251 gate_time = 1;
kenjiArai 5:bb04c4a3b5ba 252 return 0.0f; // data is not avairable
kenjiArai 5:bb04c4a3b5ba 253 }
kenjiArai 5:bb04c4a3b5ba 254 f_old.f_1sec_dt = onepps_buf.ring_get_pointed_dt(gate_time);
kenjiArai 5:bb04c4a3b5ba 255 uint32_t new_cnt = (uint32_t)f_new.t_cnt;
kenjiArai 5:bb04c4a3b5ba 256 uint32_t old_cnt = (uint32_t)f_old.t_cnt;
kenjiArai 5:bb04c4a3b5ba 257 if (old_cnt > new_cnt){
kenjiArai 5:bb04c4a3b5ba 258 new_cnt += 0x10000;
kenjiArai 5:bb04c4a3b5ba 259 }
kenjiArai 5:bb04c4a3b5ba 260 if ((new_cnt - old_cnt) == gate_time){ // make sure gt[sec]
kenjiArai 5:bb04c4a3b5ba 261 uint64_t dt = get_diff(f_new.f_1sec_dt, f_old.f_1sec_dt);
kenjiArai 5:bb04c4a3b5ba 262 return (double)dt / (double)gate_time;
kenjiArai 5:bb04c4a3b5ba 263 } else {
kenjiArai 5:bb04c4a3b5ba 264 return 0.0f;
kenjiArai 5:bb04c4a3b5ba 265 }
kenjiArai 5:bb04c4a3b5ba 266 }
kenjiArai 5:bb04c4a3b5ba 267
kenjiArai 5:bb04c4a3b5ba 268 // Read number of buffered data
kenjiArai 5:bb04c4a3b5ba 269 uint32_t FRQ_CUNTR::read_num_in_buffer(void)
kenjiArai 5:bb04c4a3b5ba 270 {
kenjiArai 5:bb04c4a3b5ba 271 return onepps_buf.ring_get_buf_size();
kenjiArai 5:bb04c4a3b5ba 272 }
kenjiArai 5:bb04c4a3b5ba 273
kenjiArai 5:bb04c4a3b5ba 274 // Newest measued data GPS 1PPS
kenjiArai 5:bb04c4a3b5ba 275 uint32_t FRQ_CUNTR::read_newest_1pps(void)
kenjiArai 5:bb04c4a3b5ba 276 {
kenjiArai 5:bb04c4a3b5ba 277 calc_1PPS_newest();
kenjiArai 5:bb04c4a3b5ba 278 return onepps_newest;
kenjiArai 5:bb04c4a3b5ba 279 }
kenjiArai 5:bb04c4a3b5ba 280
kenjiArai 5:bb04c4a3b5ba 281 // Check GPS condition
kenjiArai 5:bb04c4a3b5ba 282 uint32_t FRQ_CUNTR::status_gps(void)
kenjiArai 5:bb04c4a3b5ba 283 {
kenjiArai 5:bb04c4a3b5ba 284 if (gps_ready){
kenjiArai 5:bb04c4a3b5ba 285 return gate_time;
kenjiArai 5:bb04c4a3b5ba 286 } else {
kenjiArai 5:bb04c4a3b5ba 287 return 0; // 1PPS signal is not avarable
kenjiArai 5:bb04c4a3b5ba 288 }
kenjiArai 5:bb04c4a3b5ba 289 }
kenjiArai 5:bb04c4a3b5ba 290
kenjiArai 5:bb04c4a3b5ba 291 uint64_t FRQ_CUNTR::get_diff(uint64_t new_dt, uint64_t old_dt){
kenjiArai 5:bb04c4a3b5ba 292 uint64_t nw,od;
kenjiArai 5:bb04c4a3b5ba 293
kenjiArai 5:bb04c4a3b5ba 294 nw = new_dt & 0x0000ffffffffffff; // select 48bit data
kenjiArai 5:bb04c4a3b5ba 295 od = old_dt & 0x0000ffffffffffff;
kenjiArai 5:bb04c4a3b5ba 296 if (nw < od){ // 48bits counter overflow!
kenjiArai 5:bb04c4a3b5ba 297 nw += 0x0001000000000000;
kenjiArai 5:bb04c4a3b5ba 298 }
kenjiArai 5:bb04c4a3b5ba 299 return (nw - od);
kenjiArai 5:bb04c4a3b5ba 300 }
kenjiArai 5:bb04c4a3b5ba 301
kenjiArai 5:bb04c4a3b5ba 302 //------------------------------------------------------------------------------
kenjiArai 5:bb04c4a3b5ba 303 // Frequency Counter / Reciprocal measurement
kenjiArai 5:bb04c4a3b5ba 304 //------------------------------------------------------------------------------
kenjiArai 5:bb04c4a3b5ba 305 void FRQ_CUNTR::recipro_start_measure(void)
kenjiArai 5:bb04c4a3b5ba 306 {
kenjiArai 5:bb04c4a3b5ba 307 recipro_step = 0; // initialize step
kenjiArai 5:bb04c4a3b5ba 308 __disable_irq();
kenjiArai 5:bb04c4a3b5ba 309 TIM2->SR &= ~TIM_SR_CC4IF; // clear IC flag
kenjiArai 5:bb04c4a3b5ba 310 TIM2->DIER |= TIM_DIER_CC4IE; // Enable IC4
kenjiArai 5:bb04c4a3b5ba 311 __enable_irq();
kenjiArai 5:bb04c4a3b5ba 312 }
kenjiArai 5:bb04c4a3b5ba 313
kenjiArai 5:bb04c4a3b5ba 314 uint32_t FRQ_CUNTR::recipro_check_trigger(void)
kenjiArai 5:bb04c4a3b5ba 315 {
kenjiArai 5:bb04c4a3b5ba 316 if (recipro_step == 2){ // check IC event happan or not
kenjiArai 5:bb04c4a3b5ba 317 return 1; // happen
kenjiArai 5:bb04c4a3b5ba 318 } else {
kenjiArai 5:bb04c4a3b5ba 319 return 0; // not yet
kenjiArai 5:bb04c4a3b5ba 320 }
kenjiArai 5:bb04c4a3b5ba 321 }
kenjiArai 5:bb04c4a3b5ba 322
kenjiArai 5:bb04c4a3b5ba 323 uint32_t FRQ_CUNTR::recipro_read_data(void)
kenjiArai 5:bb04c4a3b5ba 324 {
kenjiArai 5:bb04c4a3b5ba 325 uint64_t dt;
kenjiArai 5:bb04c4a3b5ba 326 if (recipro_stop < recipro_start){ // 32bit counter overflow
kenjiArai 5:bb04c4a3b5ba 327 dt = 0x100000000 + recipro_stop;
kenjiArai 5:bb04c4a3b5ba 328 dt -= recipro_stop;
kenjiArai 5:bb04c4a3b5ba 329 } else {
kenjiArai 5:bb04c4a3b5ba 330 dt = recipro_stop - recipro_start;
kenjiArai 5:bb04c4a3b5ba 331 }
kenjiArai 5:bb04c4a3b5ba 332 return (uint32_t)dt;
kenjiArai 5:bb04c4a3b5ba 333 }
kenjiArai 5:bb04c4a3b5ba 334
kenjiArai 5:bb04c4a3b5ba 335 //------------------------------------------------------------------------------
kenjiArai 5:bb04c4a3b5ba 336 // TIM2 (32bit Counter + IC + OC)
kenjiArai 5:bb04c4a3b5ba 337 //------------------------------------------------------------------------------
kenjiArai 5:bb04c4a3b5ba 338 // Read TIM2 captured counter value
kenjiArai 5:bb04c4a3b5ba 339 uint32_t FRQ_CUNTR::read_ic2_counter_TIM2(void)
kenjiArai 5:bb04c4a3b5ba 340 {
kenjiArai 5:bb04c4a3b5ba 341 return tim2_cnt_data; // return TIM2->CCR2;
kenjiArai 5:bb04c4a3b5ba 342 }
kenjiArai 5:bb04c4a3b5ba 343
kenjiArai 5:bb04c4a3b5ba 344 // Check TIM2 IC2 status
kenjiArai 5:bb04c4a3b5ba 345 uint32_t FRQ_CUNTR::check_ic2_status_TIM2(void)
kenjiArai 5:bb04c4a3b5ba 346 {
kenjiArai 5:bb04c4a3b5ba 347 if (tim2_ready_flg == 0){
kenjiArai 5:bb04c4a3b5ba 348 return 0;
kenjiArai 5:bb04c4a3b5ba 349 } else { // GPS 1PPS is comming
kenjiArai 5:bb04c4a3b5ba 350 tim2_ready_flg = 0;
kenjiArai 5:bb04c4a3b5ba 351 return 1;
kenjiArai 5:bb04c4a3b5ba 352 }
kenjiArai 5:bb04c4a3b5ba 353 }
kenjiArai 5:bb04c4a3b5ba 354
kenjiArai 5:bb04c4a3b5ba 355 // Check OC port status
kenjiArai 5:bb04c4a3b5ba 356 uint8_t FRQ_CUNTR::read_oc_port_status(void)
kenjiArai 5:bb04c4a3b5ba 357 {
kenjiArai 5:bb04c4a3b5ba 358 uint32_t p = GPIOB->IDR;
kenjiArai 5:bb04c4a3b5ba 359 if (p & 0x0400){ // Check PB10 status
kenjiArai 5:bb04c4a3b5ba 360 return 1; // H level
kenjiArai 5:bb04c4a3b5ba 361 } else {
kenjiArai 5:bb04c4a3b5ba 362 return 0; // L level
kenjiArai 5:bb04c4a3b5ba 363 }
kenjiArai 5:bb04c4a3b5ba 364 }
kenjiArai 5:bb04c4a3b5ba 365
kenjiArai 5:bb04c4a3b5ba 366 //------------------------------------------------------------------------------
kenjiArai 5:bb04c4a3b5ba 367 // TIM8+TIM4 (32bit Counter + IC)
kenjiArai 5:bb04c4a3b5ba 368 //------------------------------------------------------------------------------
kenjiArai 5:bb04c4a3b5ba 369 // Read TIM8+4(as 32bit) captured counter value
kenjiArai 5:bb04c4a3b5ba 370 uint32_t FRQ_CUNTR::read_counter_TIM8P4(void)
kenjiArai 5:bb04c4a3b5ba 371 {
kenjiArai 5:bb04c4a3b5ba 372 return tim8p4_cnt_data;
kenjiArai 5:bb04c4a3b5ba 373 }
kenjiArai 5:bb04c4a3b5ba 374
kenjiArai 5:bb04c4a3b5ba 375 // Check TIM8 IC2 & TIM4 IC1 status
kenjiArai 5:bb04c4a3b5ba 376 uint32_t FRQ_CUNTR::check_ic1_status_TIM8P4(void)
kenjiArai 5:bb04c4a3b5ba 377 {
kenjiArai 5:bb04c4a3b5ba 378 if (tim8p4_ready_flg == 0){
kenjiArai 5:bb04c4a3b5ba 379 return 0;
kenjiArai 5:bb04c4a3b5ba 380 } else { // Gate signal is comming
kenjiArai 5:bb04c4a3b5ba 381 tim8p4_ready_flg = 0;
kenjiArai 5:bb04c4a3b5ba 382 return 1;
kenjiArai 5:bb04c4a3b5ba 383 }
kenjiArai 5:bb04c4a3b5ba 384 }
kenjiArai 5:bb04c4a3b5ba 385
kenjiArai 5:bb04c4a3b5ba 386 //------------------------------------------------------------------------------
kenjiArai 5:bb04c4a3b5ba 387 // Initialize TIM2 and TIM8+4
kenjiArai 5:bb04c4a3b5ba 388 //------------------------------------------------------------------------------
kenjiArai 5:bb04c4a3b5ba 389 // Initialize TIM2
kenjiArai 5:bb04c4a3b5ba 390 // External clock(50MHz)->PA_5 and
kenjiArai 5:bb04c4a3b5ba 391 // IC2->PA_1 for GPS 1pps signal measurement
kenjiArai 5:bb04c4a3b5ba 392 // IC4->PA_3 for Reciprocal frequency counting mode
kenjiArai 5:bb04c4a3b5ba 393 // OC3->PB_10 for Base gate time output(1 Second and other gate time)
kenjiArai 5:bb04c4a3b5ba 394 /*
kenjiArai 5:bb04c4a3b5ba 395 ????? Strange behavior :
kenjiArai 5:bb04c4a3b5ba 396 TIM2_ETR is assigned AF2 but following is assigned AF1!
kenjiArai 5:bb04c4a3b5ba 397 */
kenjiArai 5:bb04c4a3b5ba 398 void FRQ_CUNTR::initialize_TIM2(void)
kenjiArai 5:bb04c4a3b5ba 399 {
kenjiArai 5:bb04c4a3b5ba 400 // PA5 -> Counter frequency input pin as Timer2 ETR(CH1?)
kenjiArai 5:bb04c4a3b5ba 401 RCC->AHB1ENR |= (RCC_AHB1ENR_GPIOAEN);
kenjiArai 5:bb04c4a3b5ba 402 GPIOA->AFR[0] &= 0xff0fffff;
kenjiArai 5:bb04c4a3b5ba 403 GPIOA->AFR[0] |= GPIO_AF1_TIM2 << 20; // 5(PA5) x 4bits = AFSEL5
kenjiArai 5:bb04c4a3b5ba 404 // ??? AF3(TIM2_ETR) does NOT works!!
kenjiArai 5:bb04c4a3b5ba 405 //GPIOA->AFR[0] |= ((uint8_t)0x02) << 20;
kenjiArai 5:bb04c4a3b5ba 406 GPIOA->MODER &= ~(GPIO_MODER_MODER5); // AF
kenjiArai 5:bb04c4a3b5ba 407 GPIOA->MODER |= GPIO_MODER_MODER5_1; // alternate function mode
kenjiArai 5:bb04c4a3b5ba 408 GPIOA->PUPDR &= ~(GPIO_PUPDR_PUPDR5); // PU
kenjiArai 5:bb04c4a3b5ba 409 GPIOA->PUPDR |= GPIO_PUPDR_PUPDR5_0; // Pull-up mode
kenjiArai 5:bb04c4a3b5ba 410 // Initialize Timer2(32bit) for an external(ECE bit = 1) up counter mode
kenjiArai 5:bb04c4a3b5ba 411 RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
kenjiArai 5:bb04c4a3b5ba 412 // count_up + div by 1
kenjiArai 5:bb04c4a3b5ba 413 TIM2->CR1 &= (uint16_t)(~(TIM_CR1_DIR | TIM_CR1_CMS | TIM_CR1_CKD));
kenjiArai 5:bb04c4a3b5ba 414 // only counter overflow for interrupt
kenjiArai 5:bb04c4a3b5ba 415 TIM2->CR1 |= (uint16_t)TIM_CR1_URS;
kenjiArai 5:bb04c4a3b5ba 416 // Up counter uses from 0 to max(32bit)
kenjiArai 5:bb04c4a3b5ba 417 TIM2->ARR = 0xffffffff;
kenjiArai 5:bb04c4a3b5ba 418 TIM2->PSC = 0x0000; // 1/1
kenjiArai 5:bb04c4a3b5ba 419 TIM2->CCER &= (uint16_t)~TIM_CCER_CC1E; // Disable the CC1
kenjiArai 5:bb04c4a3b5ba 420 // input filter + input select
kenjiArai 5:bb04c4a3b5ba 421 TIM2->CCMR1 &= ~(TIM_CCMR1_IC1F | TIM_CCMR1_CC1S);
kenjiArai 5:bb04c4a3b5ba 422 TIM2->CCMR1 |= TIM_CCMR1_CC1S_0;
kenjiArai 5:bb04c4a3b5ba 423 TIM2->SMCR =
kenjiArai 5:bb04c4a3b5ba 424 (TIM_SMCR_ECE| TIM_ETRPRESCALER_DIV1 | TIM_CLOCKSOURCE_ETRMODE1);
kenjiArai 5:bb04c4a3b5ba 425 TIM2->CR1 |= (uint16_t)TIM_CR1_CEN; // Enable the TIM Counter
kenjiArai 5:bb04c4a3b5ba 426 // PA1 -> Input Capture pin as Timer2 IC2
kenjiArai 5:bb04c4a3b5ba 427 GPIOA->AFR[0] &= 0xffffff0f;
kenjiArai 5:bb04c4a3b5ba 428 GPIOA->AFR[0] |= GPIO_AF1_TIM2 << 4; // 1bit x 4
kenjiArai 5:bb04c4a3b5ba 429 GPIOA->MODER &= ~(GPIO_MODER_MODER1); // AF
kenjiArai 5:bb04c4a3b5ba 430 GPIOA->MODER |= GPIO_MODER_MODER1_1; // alternate function mode
kenjiArai 5:bb04c4a3b5ba 431 GPIOA->PUPDR &= ~(GPIO_PUPDR_PUPDR1); // PU
kenjiArai 5:bb04c4a3b5ba 432 GPIOA->PUPDR |= GPIO_PUPDR_PUPDR1_0; // Pull-up mode
kenjiArai 5:bb04c4a3b5ba 433 // Initialize Timer2 IC2
kenjiArai 5:bb04c4a3b5ba 434 TIM2->CCER &= (uint16_t)~TIM_CCER_CC2E; // Disable the CC2
kenjiArai 5:bb04c4a3b5ba 435 // input filter + input select
kenjiArai 5:bb04c4a3b5ba 436 TIM2->CCMR1 &= ~(TIM_CCMR1_IC2F | TIM_CCMR1_CC2S);
kenjiArai 5:bb04c4a3b5ba 437 TIM2->CCMR1 |= TIM_CCMR1_CC2S_0;
kenjiArai 5:bb04c4a3b5ba 438 // positive edge
kenjiArai 5:bb04c4a3b5ba 439 TIM2->CCER &= (uint16_t)~(TIM_CCER_CC2P | TIM_CCER_CC2NP);
kenjiArai 5:bb04c4a3b5ba 440 TIM2->CCER |= (uint16_t)TIM_CCER_CC2E; // enable capture
kenjiArai 5:bb04c4a3b5ba 441 // PA3 -> Input Capture pin as Timer2 IC4 for Reciprocal
kenjiArai 5:bb04c4a3b5ba 442 GPIOA->AFR[0] &= 0xffff0fff;
kenjiArai 5:bb04c4a3b5ba 443 GPIOA->AFR[0] |= GPIO_AF1_TIM2 << 12; // 3bit x 4
kenjiArai 5:bb04c4a3b5ba 444 GPIOA->MODER &= ~(GPIO_MODER_MODER3); // AF
kenjiArai 5:bb04c4a3b5ba 445 GPIOA->MODER |= GPIO_MODER_MODER3_1; // alternate function mode
kenjiArai 5:bb04c4a3b5ba 446 GPIOA->PUPDR &= ~(GPIO_PUPDR_PUPDR3); // PU
kenjiArai 5:bb04c4a3b5ba 447 GPIOA->PUPDR |= GPIO_PUPDR_PUPDR3_0; // Pull-up mode
kenjiArai 5:bb04c4a3b5ba 448 // Initialize Timer2 IC4
kenjiArai 5:bb04c4a3b5ba 449 TIM2->CCER &= (uint16_t)~TIM_CCER_CC4E; // Disable the CC
kenjiArai 5:bb04c4a3b5ba 450 TIM2->CCMR2 &= ~(TIM_CCMR2_IC4F | TIM_CCMR2_CC4S);
kenjiArai 5:bb04c4a3b5ba 451 TIM2->CCMR2 |= (TIM_CCMR2_CC4S_0 + TIM_CCMR2_IC4F_1); // filter = fCLK/4
kenjiArai 5:bb04c4a3b5ba 452 // positive edge
kenjiArai 5:bb04c4a3b5ba 453 TIM2->CCER &= (uint16_t)~(TIM_CCER_CC4P | TIM_CCER_CC4NP);
kenjiArai 5:bb04c4a3b5ba 454 TIM2->CCER |= (uint16_t)TIM_CCER_CC4E; // enable capture
kenjiArai 5:bb04c4a3b5ba 455 // PB10 -> Output Compare pin as Timer2 OC3
kenjiArai 5:bb04c4a3b5ba 456 GPIOB->AFR[1] &= 0xfffff0ff;
kenjiArai 5:bb04c4a3b5ba 457 GPIOB->AFR[1] |= GPIO_AF1_TIM2 << 8; // 10bit x 4 -> 2bit x 4(AFR[1])
kenjiArai 5:bb04c4a3b5ba 458 GPIOB->MODER &= ~(GPIO_MODER_MODER10); // AF
kenjiArai 5:bb04c4a3b5ba 459 GPIOB->MODER |= GPIO_MODER_MODER10_1; // alternate function mode
kenjiArai 5:bb04c4a3b5ba 460 GPIOB->OTYPER &= ~(GPIO_OTYPER_OT_10); // Output Push-Pull=0
kenjiArai 5:bb04c4a3b5ba 461 GPIOB->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR10; // Speed full=11
kenjiArai 5:bb04c4a3b5ba 462 GPIOB->PUPDR &= ~(GPIO_PUPDR_PUPDR10); // No Pull-up&down = 0
kenjiArai 5:bb04c4a3b5ba 463 // Initialize Timer2 OC3
kenjiArai 5:bb04c4a3b5ba 464 // Reset the CC3E Bit (Disable output)
kenjiArai 5:bb04c4a3b5ba 465 TIM2->CCER &= (uint16_t)~TIM_CCER_CC3E;
kenjiArai 5:bb04c4a3b5ba 466 TIM2->CCMR2 &= ~(TIM_CCMR2_OC3M | TIM_CCMR2_CC3S |
kenjiArai 5:bb04c4a3b5ba 467 TIM_CCMR2_OC3PE | TIM_CCMR2_OC3CE | TIM_CCMR2_OC3FE);
kenjiArai 5:bb04c4a3b5ba 468 TIM2->CCMR2 |= TIM_CCMR2_OC3M_2; // force to low level
kenjiArai 5:bb04c4a3b5ba 469 // Reset the Output Polarity level (active H)
kenjiArai 5:bb04c4a3b5ba 470 TIM2->CCER &= (uint16_t)~TIM_CCER_CC3P;
kenjiArai 5:bb04c4a3b5ba 471 // Set the CC3E Bit (Enable output)
kenjiArai 5:bb04c4a3b5ba 472 TIM2->CCER |= (uint16_t)TIM_CCER_CC3E;
kenjiArai 5:bb04c4a3b5ba 473 // Set the Capture Compare Register value
kenjiArai 5:bb04c4a3b5ba 474 TIM2->CCR3 = TIM2->CNT + oc_lo_time;
kenjiArai 5:bb04c4a3b5ba 475 // Up counter based on gate time period
kenjiArai 5:bb04c4a3b5ba 476 time_count_onepps = 0;
kenjiArai 5:bb04c4a3b5ba 477 // Only for Debug purpose
kenjiArai 5:bb04c4a3b5ba 478 // PA
kenjiArai 5:bb04c4a3b5ba 479 PRINTF("\r\n// Timer2(32bit) for an internal up counter mode\r\n");
kenjiArai 5:bb04c4a3b5ba 480 PRINTF("// Set GPIO for Timer2\r\n");
kenjiArai 5:bb04c4a3b5ba 481 PRINTF("// PA1 -> Input Capture pin as Timer2 CH2/TI2\r\n");
kenjiArai 5:bb04c4a3b5ba 482 PRINTF("// PA3 -> Input Capture pin as Timer2 CH4/TI4\r\n");
kenjiArai 5:bb04c4a3b5ba 483 PRINTF("GPIOA->AFRL 0x%08x:0x%08x\r\n",&GPIOA->AFR[0], GPIOA->AFR[0]);
kenjiArai 5:bb04c4a3b5ba 484 PRINTF("GPIOA->AFRH 0x%08x:0x%08x\r\n",&GPIOA->AFR[1], GPIOA->AFR[1]);
kenjiArai 5:bb04c4a3b5ba 485 PRINTF("GPIOA->MODER 0x%08x:0x%08x\r\n",&GPIOA->MODER, GPIOA->MODER);
kenjiArai 5:bb04c4a3b5ba 486 PRINTF("GPIOA->PUPDR 0x%08x:0x%08x\r\n",&GPIOA->PUPDR, GPIOA->PUPDR);
kenjiArai 5:bb04c4a3b5ba 487 // PB
kenjiArai 5:bb04c4a3b5ba 488 PRINTF("// PB10 -> Output Compare pin as Timer2 CH3/TI3\r\n");
kenjiArai 5:bb04c4a3b5ba 489 PRINTF("GPIOB->AFRL 0x%08x:0x%08x\r\n",&GPIOB->AFR[0], GPIOB->AFR[0]);
kenjiArai 5:bb04c4a3b5ba 490 PRINTF("GPIOB->AFRH 0x%08x:0x%08x\r\n",&GPIOB->AFR[1], GPIOB->AFR[1]);
kenjiArai 5:bb04c4a3b5ba 491 PRINTF("GPIOB->MODER 0x%08x:0x%08x\r\n",&GPIOB->MODER, GPIOB->MODER);
kenjiArai 5:bb04c4a3b5ba 492 PRINTF("GPIOB->PUPDR 0x%08x:0x%08x\r\n",&GPIOB->PUPDR, GPIOB->PUPDR);
kenjiArai 5:bb04c4a3b5ba 493 // TIM2
kenjiArai 5:bb04c4a3b5ba 494 PRINTF("// PA1 -> Timer2 IC2\r\n");
kenjiArai 5:bb04c4a3b5ba 495 PRINTF("// PA3 -> Timer2 IC4\r\n");
kenjiArai 5:bb04c4a3b5ba 496 PRINTF("// PB10-> Timer2 OC3\r\n");
kenjiArai 5:bb04c4a3b5ba 497 PRINTF("TIM2->CR1 0x%08x:0x%08x\r\n",&TIM2->CR1, TIM2->CR1);
kenjiArai 5:bb04c4a3b5ba 498 PRINTF("TIM2->ARR 0x%08x:0x%08x\r\n",&TIM2->ARR, TIM2->ARR);
kenjiArai 5:bb04c4a3b5ba 499 PRINTF("TIM2->PSC 0x%08x:0x%08x\r\n",&TIM2->PSC, TIM2->PSC);
kenjiArai 5:bb04c4a3b5ba 500 PRINTF("TIM2->CCMR1 0x%08x:0x%08x\r\n",&TIM2->CCMR1, TIM2->CCMR1);
kenjiArai 5:bb04c4a3b5ba 501 PRINTF("TIM2->CCMR2 0x%08x:0x%08x\r\n",&TIM2->CCMR2, TIM2->CCMR2);
kenjiArai 5:bb04c4a3b5ba 502 PRINTF("TIM2->CCER 0x%08x:0x%08x\r\n",&TIM2->CCER, TIM2->CCER);
kenjiArai 5:bb04c4a3b5ba 503 PRINTF("TIM2->SMCR 0x%08x:0x%08x\r\n",&TIM2->SMCR, TIM2->SMCR);
kenjiArai 5:bb04c4a3b5ba 504 PRINTF("TIM2->CCR3 0x%08x:0x%08x\r\n",&TIM2->CCR3, TIM2->CCR3);
kenjiArai 5:bb04c4a3b5ba 505 // Interrupt Timer2 IC2,OC3 & Overflow
kenjiArai 5:bb04c4a3b5ba 506 tim2_ready_flg = 0;
kenjiArai 5:bb04c4a3b5ba 507 tim2_cnt_data = 0;
kenjiArai 5:bb04c4a3b5ba 508 sw_ovrflw_tim2 = 0;
kenjiArai 5:bb04c4a3b5ba 509 TIM2->SR = 0; // clear all IC/OC flag
kenjiArai 5:bb04c4a3b5ba 510 TIM2->DIER = 0; // Reset all interrupt flag
kenjiArai 5:bb04c4a3b5ba 511 TIM2->DIER = TIM_DIER_CC2IE + TIM_DIER_CC3IE + TIM_DIER_UIE;
kenjiArai 5:bb04c4a3b5ba 512 NVIC_SetVector(TIM2_IRQn, (uint32_t)irq_ic2_TIM2);
kenjiArai 5:bb04c4a3b5ba 513 NVIC_ClearPendingIRQ(TIM2_IRQn);
kenjiArai 5:bb04c4a3b5ba 514 NVIC_EnableIRQ(TIM2_IRQn);
kenjiArai 5:bb04c4a3b5ba 515 PRINTF("TIM2->DIER 0x%08x:0x%08x\r\n\r\n",&TIM2->DIER, TIM2->DIER);
kenjiArai 5:bb04c4a3b5ba 516 }
kenjiArai 5:bb04c4a3b5ba 517
kenjiArai 5:bb04c4a3b5ba 518 // Initialize TIM8 & TIM4 as 32bit counter (TIM8(Low 16bit) + TIM4(High 16bit))
kenjiArai 5:bb04c4a3b5ba 519 // TIM8 clock input is unkown freq.(measuring freq.) and TIM4 is slave counter
kenjiArai 5:bb04c4a3b5ba 520 // 1sec gate signal connected both TIM8 IC2, TIM4 IC1 with TIM2 OC3
kenjiArai 5:bb04c4a3b5ba 521 void FRQ_CUNTR::initialize_TIM8P4(void)
kenjiArai 5:bb04c4a3b5ba 522 {
kenjiArai 5:bb04c4a3b5ba 523 // Timer8 input max freq.= 108MHz (@SystemCoreClock = 216MHz)
kenjiArai 5:bb04c4a3b5ba 524 // PC6 -> Unkown frequency input pin as Timer8 CH1/TI1
kenjiArai 5:bb04c4a3b5ba 525 RCC->AHB1ENR |= (RCC_AHB1ENR_GPIOCEN);
kenjiArai 5:bb04c4a3b5ba 526 GPIOC->AFR[0] &= 0xf0ffffff;
kenjiArai 5:bb04c4a3b5ba 527 GPIOC->AFR[0] |= GPIO_AF3_TIM8 << 24; // 6bit x 4
kenjiArai 5:bb04c4a3b5ba 528 GPIOC->MODER &= ~(GPIO_MODER_MODER6); // AF
kenjiArai 5:bb04c4a3b5ba 529 GPIOC->MODER |= GPIO_MODER_MODER6_1; // alternate function mode
kenjiArai 5:bb04c4a3b5ba 530 GPIOC->PUPDR &= ~(GPIO_PUPDR_PUPDR6); // PU
kenjiArai 5:bb04c4a3b5ba 531 GPIOC->PUPDR |= GPIO_PUPDR_PUPDR6_0; // Pull-up mode
kenjiArai 5:bb04c4a3b5ba 532 // Initialize Timer8(16bit) for an external up counter mode
kenjiArai 5:bb04c4a3b5ba 533 RCC->APB2ENR |= RCC_APB2ENR_TIM8EN;
kenjiArai 5:bb04c4a3b5ba 534 // count_up + div by 1
kenjiArai 5:bb04c4a3b5ba 535 TIM8->CR1 &= (uint16_t)(~(TIM_CR1_DIR | TIM_CR1_CMS | TIM_CR1_CKD));
kenjiArai 5:bb04c4a3b5ba 536 // update request only by overflow
kenjiArai 5:bb04c4a3b5ba 537 TIM8->CR1 |= (uint16_t)TIM_CR1_URS;
kenjiArai 5:bb04c4a3b5ba 538 TIM8->ARR = 0xffff; // Use 16bit full
kenjiArai 5:bb04c4a3b5ba 539 TIM8->CCER &= (uint16_t)~TIM_CCER_CC1E; // Disable the CC1
kenjiArai 5:bb04c4a3b5ba 540 // input filter + input select
kenjiArai 5:bb04c4a3b5ba 541 TIM8->CCMR1 &= ~(TIM_CCMR1_IC1F | TIM_CCMR1_CC1S);
kenjiArai 5:bb04c4a3b5ba 542 TIM8->CCMR1 |= TIM_CCMR1_CC1S_0;// CC1 channel = TI1
kenjiArai 5:bb04c4a3b5ba 543 // Not use IC1
kenjiArai 5:bb04c4a3b5ba 544 TIM8->CCER &=
kenjiArai 5:bb04c4a3b5ba 545 (uint16_t)~(TIM_CCER_CC1P | TIM_CCER_CC1NE | TIM_CCER_CC1NP);
kenjiArai 5:bb04c4a3b5ba 546 // external mode 1
kenjiArai 5:bb04c4a3b5ba 547 TIM8->SMCR &= ~(TIM_SMCR_ECE | TIM_SMCR_TS | TIM_SMCR_SMS);
kenjiArai 5:bb04c4a3b5ba 548 // ECE must be ZERO!!!!
kenjiArai 5:bb04c4a3b5ba 549 TIM8->SMCR |= ( TIM_TS_TI1FP1 | TIM_SLAVEMODE_EXTERNAL1);
kenjiArai 5:bb04c4a3b5ba 550 TIM8->CR2 &= (uint16_t)~(TIM_CR2_TI1S | TIM_CR2_MMS);
kenjiArai 5:bb04c4a3b5ba 551 TIM8->CR2 |= (uint16_t)TIM_CR2_MMS_1; // TRGO update
kenjiArai 5:bb04c4a3b5ba 552 TIM8->CR1 |= (uint16_t)TIM_CR1_CEN; // Enable the TIM Counter
kenjiArai 5:bb04c4a3b5ba 553 // PC7 -> Input Capture pin as Timer8 IC2
kenjiArai 5:bb04c4a3b5ba 554 GPIOC->AFR[0] &= 0x0fffffff;
kenjiArai 5:bb04c4a3b5ba 555 GPIOC->AFR[0] |= GPIO_AF3_TIM8 << 28; // 7bit x 4
kenjiArai 5:bb04c4a3b5ba 556 GPIOC->MODER &= ~(GPIO_MODER_MODER7); // AF
kenjiArai 5:bb04c4a3b5ba 557 GPIOC->MODER |= GPIO_MODER_MODER7_1; // alternate function mode
kenjiArai 5:bb04c4a3b5ba 558 GPIOC->PUPDR &= ~(GPIO_PUPDR_PUPDR7); // PU
kenjiArai 5:bb04c4a3b5ba 559 GPIOC->PUPDR |= GPIO_PUPDR_PUPDR7_0; // Pull-up mode
kenjiArai 5:bb04c4a3b5ba 560 // Initialize Timer8 IC2
kenjiArai 5:bb04c4a3b5ba 561 TIM8->CCER &= (uint16_t)~TIM_CCER_CC2E; // Disable the CC2
kenjiArai 5:bb04c4a3b5ba 562 // input filter + input select
kenjiArai 5:bb04c4a3b5ba 563 TIM8->CCMR1 &= ~(TIM_CCMR1_IC2F | TIM_CCMR1_CC2S);
kenjiArai 5:bb04c4a3b5ba 564 TIM8->CCMR1 |= TIM_CCMR1_CC2S_0;
kenjiArai 5:bb04c4a3b5ba 565 // positive edge
kenjiArai 5:bb04c4a3b5ba 566 TIM8->CCER &= (uint16_t)~(TIM_CCER_CC2P | TIM_CCER_CC2NP);
kenjiArai 5:bb04c4a3b5ba 567 TIM8->CCER |= (uint16_t)TIM_CCER_CC2E; // enable capture
kenjiArai 5:bb04c4a3b5ba 568 // Initialize Timer4(16bit) as slave counter of TIM8
kenjiArai 5:bb04c4a3b5ba 569 // TIM8 overflow event -> ITR3 as Timer4 clock
kenjiArai 5:bb04c4a3b5ba 570 RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;
kenjiArai 5:bb04c4a3b5ba 571 TIM4->CR1 &= (uint16_t)(~(TIM_CR1_DIR | TIM_CR1_CMS | TIM_CR1_CKD));
kenjiArai 5:bb04c4a3b5ba 572 // only counter overflow for interrupt
kenjiArai 5:bb04c4a3b5ba 573 TIM4->CR1 |= (uint16_t)TIM_CR1_URS;
kenjiArai 5:bb04c4a3b5ba 574 // Up counter uses from 0 to max(32bit)
kenjiArai 5:bb04c4a3b5ba 575 TIM4->ARR = 0xffff; // Use 16bit full
kenjiArai 5:bb04c4a3b5ba 576 TIM4->CCER &= (uint16_t)~TIM_CCER_CC1E; // Disable the CC1
kenjiArai 5:bb04c4a3b5ba 577 // input filter + input select
kenjiArai 5:bb04c4a3b5ba 578 TIM4->CCMR1 &= ~(TIM_CCMR1_IC1F | TIM_CCMR1_CC1S);
kenjiArai 5:bb04c4a3b5ba 579 TIM4->CCMR1 |= TIM_CCMR1_CC1S_0; // CC1 channel = TI1
kenjiArai 5:bb04c4a3b5ba 580 // Not use IC1
kenjiArai 5:bb04c4a3b5ba 581 TIM4->CCER &=
kenjiArai 5:bb04c4a3b5ba 582 (uint16_t)~(TIM_CCER_CC1P | TIM_CCER_CC1NE | TIM_CCER_CC1NP);
kenjiArai 5:bb04c4a3b5ba 583 // external mode 1
kenjiArai 5:bb04c4a3b5ba 584 TIM4->SMCR &= ~(TIM_SMCR_ECE | TIM_SMCR_TS | TIM_SMCR_SMS);
kenjiArai 5:bb04c4a3b5ba 585 TIM4->SMCR |= (TIM_TS_ITR3); // Set Internal Triger 3 (ITR3)
kenjiArai 5:bb04c4a3b5ba 586 TIM4->SMCR |= (TIM_SLAVEMODE_EXTERNAL1); // ECE must be ZERO!!!!
kenjiArai 5:bb04c4a3b5ba 587 TIM4->CR2 &= (uint16_t)~(TIM_CR2_TI1S | TIM_CR2_MMS);
kenjiArai 5:bb04c4a3b5ba 588 TIM4->CR2 |= (uint16_t)TIM_CR2_MMS_1; // TRGO update
kenjiArai 5:bb04c4a3b5ba 589 TIM4->CR1 |= (uint16_t)TIM_CR1_CEN; // Enable the TIM Counter
kenjiArai 5:bb04c4a3b5ba 590 // PB6 -> Input Capture pin as Timer4 IC1
kenjiArai 5:bb04c4a3b5ba 591 GPIOB->AFR[0] &= 0xf0ffffff;
kenjiArai 5:bb04c4a3b5ba 592 GPIOB->AFR[0] |= GPIO_AF2_TIM4 << 24; // 6bit x 4
kenjiArai 5:bb04c4a3b5ba 593 GPIOB->MODER &= ~(GPIO_MODER_MODER6); // AF
kenjiArai 5:bb04c4a3b5ba 594 GPIOB->MODER |= GPIO_MODER_MODER6_1; // alternate function mode
kenjiArai 5:bb04c4a3b5ba 595 GPIOB->PUPDR &= ~(GPIO_PUPDR_PUPDR6); // PU
kenjiArai 5:bb04c4a3b5ba 596 GPIOB->PUPDR |= GPIO_PUPDR_PUPDR6_0; // Pull-up mode
kenjiArai 5:bb04c4a3b5ba 597 // Initialize Timer4 IC1
kenjiArai 5:bb04c4a3b5ba 598 TIM4->CCER &= (uint16_t)~TIM_CCER_CC1E;
kenjiArai 5:bb04c4a3b5ba 599 TIM4->CCMR1 &= ~(TIM_CCMR1_CC1S | TIM_CCMR1_IC1F);
kenjiArai 5:bb04c4a3b5ba 600 TIM4->CCMR1 |= TIM_CCMR1_CC1S_0;
kenjiArai 5:bb04c4a3b5ba 601 // positive edge
kenjiArai 5:bb04c4a3b5ba 602 TIM4->CCER &= (uint16_t)~(TIM_CCER_CC1P | TIM_CCER_CC1NP);
kenjiArai 5:bb04c4a3b5ba 603 TIM4->CCER |= (uint16_t)TIM_CCER_CC1E; // enable capture
kenjiArai 5:bb04c4a3b5ba 604 // Up counter based on gate time period
kenjiArai 5:bb04c4a3b5ba 605 time_count = 0;
kenjiArai 5:bb04c4a3b5ba 606 // Only for Debug purpose
kenjiArai 5:bb04c4a3b5ba 607 PRINTF("\r\n// Timer8(16bit high(max106MHz) clock)\r\n");
kenjiArai 5:bb04c4a3b5ba 608 PRINTF("// and Timer4(16bit low clock) combined up counter\r\n");
kenjiArai 5:bb04c4a3b5ba 609 PRINTF("// Set GPIO for Timer8&4\r\n");
kenjiArai 5:bb04c4a3b5ba 610 // PB
kenjiArai 5:bb04c4a3b5ba 611 PRINTF("// PB6 -> Input Capture pin as Timer4 CH1/TI1\r\n");
kenjiArai 5:bb04c4a3b5ba 612 PRINTF("GPIOB->AFRL 0x%08x:0x%08x\r\n",&GPIOB->AFR[0], GPIOB->AFR[0]);
kenjiArai 5:bb04c4a3b5ba 613 PRINTF("GPIOB->AFRH 0x%08x:0x%08x\r\n",&GPIOB->AFR[1], GPIOB->AFR[1]);
kenjiArai 5:bb04c4a3b5ba 614 PRINTF("GPIOB->MODER 0x%08x:0x%08x\r\n",&GPIOB->MODER, GPIOB->MODER);
kenjiArai 5:bb04c4a3b5ba 615 PRINTF("GPIOB->PUPDR 0x%08x:0x%08x\r\n",&GPIOB->PUPDR, GPIOB->PUPDR);
kenjiArai 5:bb04c4a3b5ba 616 PRINTF("GPIOB->OTYPER 0x%08x:0x%08x\r\n",&GPIOB->OTYPER, GPIOB->OTYPER);
kenjiArai 5:bb04c4a3b5ba 617 PRINTF("GPIOB->OSPEEDR 0x%08x:0x%08x\r\n",&GPIOB->OSPEEDR, GPIOB->OSPEEDR);
kenjiArai 5:bb04c4a3b5ba 618 // PC
kenjiArai 5:bb04c4a3b5ba 619 PRINTF("// PC6 -> unkown frequency input pin as Timer8 CH1/TI1\r\n");
kenjiArai 5:bb04c4a3b5ba 620 PRINTF("// PC7 -> Input Capture pin as Timer8 CH2/TI2\r\n");
kenjiArai 5:bb04c4a3b5ba 621 PRINTF("GPIOC->AFRL 0x%08x:0x%08x\r\n",&GPIOC->AFR[0], GPIOC->AFR[0]);
kenjiArai 5:bb04c4a3b5ba 622 PRINTF("GPIOC->AFRH 0x%08x:0x%08x\r\n",&GPIOC->AFR[1], GPIOC->AFR[1]);
kenjiArai 5:bb04c4a3b5ba 623 PRINTF("GPIOC->MODER 0x%08x:0x%08x\r\n",&GPIOC->MODER, GPIOC->MODER);
kenjiArai 5:bb04c4a3b5ba 624 PRINTF("GPIOC->PUPDR 0x%08x:0x%08x\r\n",&GPIOC->PUPDR, GPIOC->PUPDR);
kenjiArai 5:bb04c4a3b5ba 625 PRINTF("GPIOC->OTYPER 0x%08x:0x%08x\r\n",&GPIOC->OTYPER, GPIOC->OTYPER);
kenjiArai 5:bb04c4a3b5ba 626 PRINTF("GPIOC->OSPEEDR 0x%08x:0x%08x\r\n",&GPIOC->OSPEEDR, GPIOC->OSPEEDR);
kenjiArai 5:bb04c4a3b5ba 627 // TIM8
kenjiArai 5:bb04c4a3b5ba 628 PRINTF("// PC6 -> Timer8(16bit) for an external up counter mode\r\n");
kenjiArai 5:bb04c4a3b5ba 629 PRINTF("// PC7 -> Timer8 IC2\r\n");
kenjiArai 5:bb04c4a3b5ba 630 PRINTF("TIM8->CR1 0x%08x:0x%08x\r\n",&TIM8->CR1, TIM8->CR1);
kenjiArai 5:bb04c4a3b5ba 631 PRINTF("TIM8->CR2 0x%08x:0x%08x\r\n",&TIM8->CR2, TIM8->CR2);
kenjiArai 5:bb04c4a3b5ba 632 PRINTF("TIM8->ARR 0x%08x:0x%08x\r\n",&TIM8->ARR, TIM8->ARR);
kenjiArai 5:bb04c4a3b5ba 633 PRINTF("TIM8->PSC 0x%08x:0x%08x\r\n",&TIM8->PSC, TIM8->PSC);
kenjiArai 5:bb04c4a3b5ba 634 PRINTF("TIM8->CCMR1 0x%08x:0x%08x\r\n",&TIM8->CCMR1, TIM8->CCMR1);
kenjiArai 5:bb04c4a3b5ba 635 PRINTF("TIM8->CCMR2 0x%08x:0x%08x\r\n",&TIM8->CCMR2, TIM8->CCMR2);
kenjiArai 5:bb04c4a3b5ba 636 PRINTF("TIM8->CCER 0x%08x:0x%08x\r\n",&TIM8->CCER, TIM8->CCER);
kenjiArai 5:bb04c4a3b5ba 637 PRINTF("TIM8->SMCR 0x%08x:0x%08x\r\n",&TIM8->SMCR, TIM8->SMCR);
kenjiArai 5:bb04c4a3b5ba 638 // TIM4
kenjiArai 5:bb04c4a3b5ba 639 PRINTF("// PB6 -> Timer4 IC1\r\n");
kenjiArai 5:bb04c4a3b5ba 640 PRINTF("TIM4->CR1 0x%08x:0x%08x\r\n",&TIM4->CR1, TIM4->CR1);
kenjiArai 5:bb04c4a3b5ba 641 PRINTF("TIM4->ARR 0x%08x:0x%08x\r\n",&TIM4->ARR, TIM4->ARR);
kenjiArai 5:bb04c4a3b5ba 642 PRINTF("TIM4->PSC 0x%08x:0x%08x\r\n",&TIM4->PSC, TIM4->PSC);
kenjiArai 5:bb04c4a3b5ba 643 PRINTF("TIM4->CCMR1 0x%08x:0x%08x\r\n",&TIM4->CCMR1, TIM4->CCMR1);
kenjiArai 5:bb04c4a3b5ba 644 PRINTF("TIM4->CCMR2 0x%08x:0x%08x\r\n",&TIM4->CCMR2, TIM4->CCMR2);
kenjiArai 5:bb04c4a3b5ba 645 PRINTF("TIM4->CCER 0x%08x:0x%08x\r\n",&TIM4->CCER, TIM4->CCER);
kenjiArai 5:bb04c4a3b5ba 646 PRINTF("TIM4->SMCR 0x%08x:0x%08x\r\n",&TIM4->SMCR, TIM4->SMCR);
kenjiArai 5:bb04c4a3b5ba 647 // Interrupt Timer4 IC1 (NOT Timer8 IC2) & Overflow
kenjiArai 5:bb04c4a3b5ba 648 tim8p4_ready_flg = 0;
kenjiArai 5:bb04c4a3b5ba 649 tim8p4_cnt_data = 0;
kenjiArai 5:bb04c4a3b5ba 650 sw_ovrflw_tim8p4 = 0;
kenjiArai 5:bb04c4a3b5ba 651 TIM8->SR = 0; // clear all IC/OC flag
kenjiArai 5:bb04c4a3b5ba 652 TIM4->SR = 0; // clear all IC/OC flag
kenjiArai 5:bb04c4a3b5ba 653 TIM4->DIER = 0; // Reset all interrupt flag
kenjiArai 5:bb04c4a3b5ba 654 TIM4->DIER = TIM_DIER_CC1IE + TIM_DIER_UIE;
kenjiArai 5:bb04c4a3b5ba 655 NVIC_SetVector(TIM4_IRQn, (uint32_t)irq_ic1_TIM8P4);
kenjiArai 5:bb04c4a3b5ba 656 NVIC_ClearPendingIRQ(TIM4_IRQn);
kenjiArai 5:bb04c4a3b5ba 657 NVIC_EnableIRQ(TIM4_IRQn);
kenjiArai 5:bb04c4a3b5ba 658 PRINTF("TIM4->DIER 0x%08x:0x%08x\r\n\r\n",&TIM4->DIER, TIM4->DIER);
kenjiArai 5:bb04c4a3b5ba 659 PRINTF("RCC->APB1ENR 0x%08x:0x%08x\r\n\r\n",&RCC->APB1ENR, RCC->APB1ENR);
kenjiArai 5:bb04c4a3b5ba 660 }
kenjiArai 5:bb04c4a3b5ba 661
kenjiArai 5:bb04c4a3b5ba 662 //------------------------------------------------------------------------------
kenjiArai 5:bb04c4a3b5ba 663 // Frequency check for test & debug purpose
kenjiArai 5:bb04c4a3b5ba 664 //------------------------------------------------------------------------------
kenjiArai 5:bb04c4a3b5ba 665 // Read TIM2 Clock frequency
kenjiArai 5:bb04c4a3b5ba 666 uint32_t FRQ_CUNTR::read_base_clock_frequency(double gatetime)
kenjiArai 5:bb04c4a3b5ba 667 {
kenjiArai 5:bb04c4a3b5ba 668 TIM2->CNT = 0;
kenjiArai 5:bb04c4a3b5ba 669 wait(gatetime); // Gate time for count
kenjiArai 5:bb04c4a3b5ba 670 uint32_t freq = TIM2->CNT; // read counter
kenjiArai 5:bb04c4a3b5ba 671 PRINTF("Clock freq.=%10d [Hz], gate= %4.2f [Sec]\r\n", freq, gatetime);
kenjiArai 5:bb04c4a3b5ba 672 return freq; // return counter data
kenjiArai 5:bb04c4a3b5ba 673 }
kenjiArai 5:bb04c4a3b5ba 674
kenjiArai 5:bb04c4a3b5ba 675 // Read TIM8(+TIM4) Input frequency
kenjiArai 5:bb04c4a3b5ba 676 uint32_t FRQ_CUNTR::read_input_frequency(double gatetime)
kenjiArai 5:bb04c4a3b5ba 677 {
kenjiArai 5:bb04c4a3b5ba 678 TIM8->CR1 &= ~(uint16_t)TIM_CR1_CEN; // disable the TIM8 Counter
kenjiArai 5:bb04c4a3b5ba 679 TIM4->CNT = 0;
kenjiArai 5:bb04c4a3b5ba 680 TIM8->CNT = 0;
kenjiArai 5:bb04c4a3b5ba 681 TIM8->CR1 |= (uint16_t)TIM_CR1_CEN; // Enable the TIM8 Counter
kenjiArai 5:bb04c4a3b5ba 682 wait(gatetime); // Gate time for count
kenjiArai 5:bb04c4a3b5ba 683 TIM8->CR1 &= ~(uint16_t)TIM_CR1_CEN; // disable the TIM8 Counter
kenjiArai 5:bb04c4a3b5ba 684 uint32_t freq = (TIM4->CNT << 16) + TIM8->CNT;
kenjiArai 5:bb04c4a3b5ba 685 TIM8->CR1 |= (uint16_t)TIM_CR1_CEN; // Enable the TIM8 Counter
kenjiArai 5:bb04c4a3b5ba 686 PRINTF("Input freq.=%10d [Hz], gate= %4.2f [Sec]\r\n", freq, gatetime);
kenjiArai 5:bb04c4a3b5ba 687 return freq; // read counter
kenjiArai 5:bb04c4a3b5ba 688 }
kenjiArai 5:bb04c4a3b5ba 689
kenjiArai 5:bb04c4a3b5ba 690 void FRQ_CUNTR::debug_printf_all_buffer(void)
kenjiArai 5:bb04c4a3b5ba 691 {
kenjiArai 5:bb04c4a3b5ba 692 fdt_buffer.debug_print_all_buffer();
kenjiArai 5:bb04c4a3b5ba 693 }
kenjiArai 5:bb04c4a3b5ba 694
kenjiArai 5:bb04c4a3b5ba 695 void FRQ_CUNTR::debug_printf_internal_data(void)
kenjiArai 5:bb04c4a3b5ba 696 {
kenjiArai 5:bb04c4a3b5ba 697 printf("Debug information\r\n");
kenjiArai 5:bb04c4a3b5ba 698 printf("ex_clock_freq %f\r\n", ex_clock_freq);
kenjiArai 5:bb04c4a3b5ba 699 printf("ex_clk_base %9d\r\n", ex_clk_base);
kenjiArai 5:bb04c4a3b5ba 700 printf("clk_hi_const %9d\r\n", clk_hi_const);
kenjiArai 5:bb04c4a3b5ba 701 printf("clk_upper_limit %9d\r\n", clk_upper_limit);
kenjiArai 5:bb04c4a3b5ba 702 printf("clk_lower_limit %9d\r\n", clk_lower_limit);
kenjiArai 5:bb04c4a3b5ba 703 printf("oc_hi_time %9d\r\n", oc_hi_time);
kenjiArai 5:bb04c4a3b5ba 704 printf("oc_lo_time %9d\r\n", oc_lo_time);
kenjiArai 5:bb04c4a3b5ba 705 printf("\r\n");
kenjiArai 5:bb04c4a3b5ba 706 }
kenjiArai 5:bb04c4a3b5ba 707
kenjiArai 5:bb04c4a3b5ba 708 //------------------------------------------------------------------------------
kenjiArai 5:bb04c4a3b5ba 709 // Interrupt Handlers
kenjiArai 5:bb04c4a3b5ba 710 //------------------------------------------------------------------------------
kenjiArai 5:bb04c4a3b5ba 711 void irq_ic2_TIM2(void)
kenjiArai 5:bb04c4a3b5ba 712 {
kenjiArai 5:bb04c4a3b5ba 713 // IC2 (By GPS 1PPS)
kenjiArai 5:bb04c4a3b5ba 714 if (TIM2->SR & TIM_SR_CC2IF){
kenjiArai 5:bb04c4a3b5ba 715 TIM2->SR &= ~TIM_SR_CC2IF; // clear IC flag
kenjiArai 5:bb04c4a3b5ba 716 tim2_cnt_data = TIM2->CCR2;
kenjiArai 5:bb04c4a3b5ba 717 tim2_ready_flg = 1;
kenjiArai 5:bb04c4a3b5ba 718 // data saves intto the ring buffer
kenjiArai 5:bb04c4a3b5ba 719 onepps_dt.freq_dt = tim2_cnt_data;
kenjiArai 5:bb04c4a3b5ba 720 onepps_dt.f_sw_dt = sw_ovrflw_tim2;
kenjiArai 5:bb04c4a3b5ba 721 onepps_dt.t_cnt = ++time_count_onepps;
kenjiArai 5:bb04c4a3b5ba 722 onepps_buf.ring_put_dt(onepps_dt.f_1sec_dt);
kenjiArai 5:bb04c4a3b5ba 723 #if ACTIVE_LED
kenjiArai 5:bb04c4a3b5ba 724 irq_led3 = !irq_led3;
kenjiArai 5:bb04c4a3b5ba 725 #endif // ACTIVE_LED
kenjiArai 5:bb04c4a3b5ba 726 }
kenjiArai 5:bb04c4a3b5ba 727 // Gate signal (every 1Sec)
kenjiArai 5:bb04c4a3b5ba 728 if (TIM2->SR & TIM_SR_CC3IF){ // Output Compare
kenjiArai 5:bb04c4a3b5ba 729 TIM2->SR &= ~TIM_SR_CC3IF; // clear OC flag
kenjiArai 5:bb04c4a3b5ba 730 TIM2->CCMR2 &= ~(TIM_CCMR2_OC3M); // Clear OC mode
kenjiArai 5:bb04c4a3b5ba 731 // Check PB10 status
kenjiArai 5:bb04c4a3b5ba 732 if (GPIOB->IDR & 0x0400){ // High level
kenjiArai 5:bb04c4a3b5ba 733 TIM2->CCR3 = TIM2->CCR3 + oc_hi_time;
kenjiArai 5:bb04c4a3b5ba 734 TIM2->CCMR2 |= TIM_CCMR2_OC3M_1; // to be low
kenjiArai 5:bb04c4a3b5ba 735 #if ACTIVE_LED
kenjiArai 5:bb04c4a3b5ba 736 irq_led2 = 1;
kenjiArai 5:bb04c4a3b5ba 737 #endif // ACTIVE_LED
kenjiArai 5:bb04c4a3b5ba 738 } else { // Low level
kenjiArai 5:bb04c4a3b5ba 739 TIM2->CCR3 = TIM2->CCR3 + oc_lo_time;
kenjiArai 5:bb04c4a3b5ba 740 TIM2->CCMR2 |= TIM_CCMR2_OC3M_0; // to be high
kenjiArai 5:bb04c4a3b5ba 741 #if ACTIVE_LED
kenjiArai 5:bb04c4a3b5ba 742 irq_led2 = 0;
kenjiArai 5:bb04c4a3b5ba 743 #endif // ACTIVE_LED
kenjiArai 5:bb04c4a3b5ba 744 }
kenjiArai 5:bb04c4a3b5ba 745 }
kenjiArai 5:bb04c4a3b5ba 746 // IC4 (for reciprocal measurement)
kenjiArai 5:bb04c4a3b5ba 747 if (TIM2->SR & TIM_SR_CC4IF){
kenjiArai 5:bb04c4a3b5ba 748 TIM2->SR &= ~TIM_SR_CC4IF; // clear IC flag
kenjiArai 5:bb04c4a3b5ba 749 uint32_t data = TIM2->CCR4;
kenjiArai 5:bb04c4a3b5ba 750 if (recipro_step == 0){
kenjiArai 5:bb04c4a3b5ba 751 recipro_start = data;
kenjiArai 5:bb04c4a3b5ba 752 recipro_step = 1;
kenjiArai 5:bb04c4a3b5ba 753 } else if (recipro_step == 1){
kenjiArai 5:bb04c4a3b5ba 754 TIM2->DIER &= ~TIM_DIER_CC4IE; // disable IC4 interrupt
kenjiArai 5:bb04c4a3b5ba 755 recipro_stop = data;
kenjiArai 5:bb04c4a3b5ba 756 recipro_step = 2;
kenjiArai 5:bb04c4a3b5ba 757 }
kenjiArai 5:bb04c4a3b5ba 758 }
kenjiArai 5:bb04c4a3b5ba 759 // TIM2 overflow
kenjiArai 5:bb04c4a3b5ba 760 if (TIM2->SR & TIM_SR_UIF){
kenjiArai 5:bb04c4a3b5ba 761 TIM2->SR &= ~TIM_SR_UIF;
kenjiArai 5:bb04c4a3b5ba 762 ++sw_ovrflw_tim2;
kenjiArai 5:bb04c4a3b5ba 763 }
kenjiArai 5:bb04c4a3b5ba 764 }
kenjiArai 5:bb04c4a3b5ba 765
kenjiArai 5:bb04c4a3b5ba 766 // TIM4 IC1 Interrupt control (same signal connected to TIM8 IC2)
kenjiArai 5:bb04c4a3b5ba 767 void irq_ic1_TIM8P4(void)
kenjiArai 5:bb04c4a3b5ba 768 {
kenjiArai 5:bb04c4a3b5ba 769 // IC1 (TIM2 Gate signal)
kenjiArai 5:bb04c4a3b5ba 770 if (TIM4->SR & TIM_SR_CC1IF){
kenjiArai 5:bb04c4a3b5ba 771 TIM8->SR &= ~TIM_SR_CC2IF; // clear IC flag
kenjiArai 5:bb04c4a3b5ba 772 TIM4->SR &= ~TIM_SR_CC1IF;
kenjiArai 5:bb04c4a3b5ba 773 tim8p4_cnt_data = (TIM4->CCR1 << 16) + TIM8->CCR2;
kenjiArai 5:bb04c4a3b5ba 774 tim8p4_ready_flg = 1;
kenjiArai 5:bb04c4a3b5ba 775 // data saves intto the ring buffer
kenjiArai 5:bb04c4a3b5ba 776 fdt.freq_dt = tim8p4_cnt_data;
kenjiArai 5:bb04c4a3b5ba 777 fdt.f_sw_dt = sw_ovrflw_tim8p4;
kenjiArai 5:bb04c4a3b5ba 778 fdt.t_cnt = ++time_count;
kenjiArai 5:bb04c4a3b5ba 779 fdt_buffer.ring_put_dt(fdt.f_1sec_dt);
kenjiArai 5:bb04c4a3b5ba 780 #if ACTIVE_LED
kenjiArai 5:bb04c4a3b5ba 781 irq_led1 = !irq_led1;
kenjiArai 5:bb04c4a3b5ba 782 #endif // ACTIVE_LED
kenjiArai 5:bb04c4a3b5ba 783 }
kenjiArai 5:bb04c4a3b5ba 784 // TIM4 overflow
kenjiArai 5:bb04c4a3b5ba 785 if (TIM4->SR & TIM_SR_UIF){
kenjiArai 5:bb04c4a3b5ba 786 TIM4->SR &= ~TIM_SR_UIF;
kenjiArai 5:bb04c4a3b5ba 787 ++sw_ovrflw_tim8p4;
kenjiArai 5:bb04c4a3b5ba 788 }
kenjiArai 5:bb04c4a3b5ba 789 }
kenjiArai 5:bb04c4a3b5ba 790
kenjiArai 5:bb04c4a3b5ba 791 } // Frequency_counter
kenjiArai 5:bb04c4a3b5ba 792
kenjiArai 5:bb04c4a3b5ba 793
kenjiArai 5:bb04c4a3b5ba 794
kenjiArai 5:bb04c4a3b5ba 795