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.cpp@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 | #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 |