Reciprocal Frequency counter only for STM32F401、F411 and F466. Reciprocal Mode -> Pulse width measurement
Dependents: Frequency_Counter_Recipro_for_STM32F4xx
fc_recipro.cpp@8:c9ed197ce270, 2020-01-19 (annotated)
- Committer:
- kenjiArai
- Date:
- Sun Jan 19 06:54:38 2020 +0000
- Revision:
- 8:c9ed197ce270
- Parent:
- 7:7fdff925855e
modified uint to int and others
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
kenjiArai | 7:7fdff925855e | 1 | /* |
kenjiArai | 7:7fdff925855e | 2 | * mbed Library / Frequency Counter / Recipro type |
kenjiArai | 7:7fdff925855e | 3 | * Frequency Counter program |
kenjiArai | 7:7fdff925855e | 4 | * Only for Nucleo-F401RE,-F411RE,-F446RE |
kenjiArai | 7:7fdff925855e | 5 | * |
kenjiArai | 7:7fdff925855e | 6 | * Copyright (c) 2014,'15,'16,'20 Kenji Arai / JH1PJL |
kenjiArai | 7:7fdff925855e | 7 | * http://www7b.biglobe.ne.jp/~kenjia/ |
kenjiArai | 7:7fdff925855e | 8 | * https://os.mbed.com/users/kenjiArai/ |
kenjiArai | 7:7fdff925855e | 9 | * Started: October 18th, 2014 |
kenjiArai | 7:7fdff925855e | 10 | * Revised: January 19th, 2020 |
kenjiArai | 7:7fdff925855e | 11 | */ |
kenjiArai | 7:7fdff925855e | 12 | |
kenjiArai | 7:7fdff925855e | 13 | #include "fc_recipro.h" |
kenjiArai | 7:7fdff925855e | 14 | |
kenjiArai | 7:7fdff925855e | 15 | #if (MBED_MAJOR_VERSION == 2) |
kenjiArai | 7:7fdff925855e | 16 | # define WAIT(x) wait_ms(x) |
kenjiArai | 7:7fdff925855e | 17 | #elif (MBED_MAJOR_VERSION == 5) |
kenjiArai | 7:7fdff925855e | 18 | # define WAIT(x) ThisThread::sleep_for(x) |
kenjiArai | 7:7fdff925855e | 19 | #endif |
kenjiArai | 7:7fdff925855e | 20 | |
kenjiArai | 7:7fdff925855e | 21 | #if DEBUG |
kenjiArai | 7:7fdff925855e | 22 | #define PRINTF(...) printf(__VA_ARGS__) |
kenjiArai | 7:7fdff925855e | 23 | #define SET0 {tstp0=1;} |
kenjiArai | 7:7fdff925855e | 24 | #define CLR0 {tstp0=0;} |
kenjiArai | 7:7fdff925855e | 25 | #define SET1 {tstp1=1;} |
kenjiArai | 7:7fdff925855e | 26 | #define CLR1 {tstp1=0;} |
kenjiArai | 7:7fdff925855e | 27 | #define SET2 {tstp2=1;} |
kenjiArai | 7:7fdff925855e | 28 | #define CLR2 {tstp2=0;} |
kenjiArai | 7:7fdff925855e | 29 | #else |
kenjiArai | 7:7fdff925855e | 30 | #define PRINTF(...) {;} |
kenjiArai | 7:7fdff925855e | 31 | #define SET0 {;} |
kenjiArai | 7:7fdff925855e | 32 | #define CLR0 {;} |
kenjiArai | 7:7fdff925855e | 33 | #define SET1 {;} |
kenjiArai | 7:7fdff925855e | 34 | #define CLR1 {;} |
kenjiArai | 7:7fdff925855e | 35 | #define SET2 {;} |
kenjiArai | 7:7fdff925855e | 36 | #define CLR2 {;} |
kenjiArai | 7:7fdff925855e | 37 | #endif |
kenjiArai | 7:7fdff925855e | 38 | |
kenjiArai | 7:7fdff925855e | 39 | typedef union { |
kenjiArai | 7:7fdff925855e | 40 | struct { |
kenjiArai | 7:7fdff925855e | 41 | int64_t f_64bit_dt; // not uint but int |
kenjiArai | 7:7fdff925855e | 42 | }; |
kenjiArai | 7:7fdff925855e | 43 | struct { |
kenjiArai | 7:7fdff925855e | 44 | uint32_t freq_dt; |
kenjiArai | 7:7fdff925855e | 45 | int32_t f_sw_dt; // not uint but int |
kenjiArai | 7:7fdff925855e | 46 | }; |
kenjiArai | 7:7fdff925855e | 47 | } freq_one; |
kenjiArai | 7:7fdff925855e | 48 | |
kenjiArai | 7:7fdff925855e | 49 | namespace Frequency_counter |
kenjiArai | 7:7fdff925855e | 50 | { |
kenjiArai | 7:7fdff925855e | 51 | |
kenjiArai | 7:7fdff925855e | 52 | #if DEBUG |
kenjiArai | 7:7fdff925855e | 53 | // Check interrupt handler processing time |
kenjiArai | 7:7fdff925855e | 54 | DigitalOut tstp0(D13, 1); |
kenjiArai | 7:7fdff925855e | 55 | DigitalOut tstp1(D12, 1); |
kenjiArai | 7:7fdff925855e | 56 | DigitalOut tstp2(D11, 1); |
kenjiArai | 7:7fdff925855e | 57 | #endif |
kenjiArai | 7:7fdff925855e | 58 | |
kenjiArai | 7:7fdff925855e | 59 | // TIM2 IC (Reciprocal) + OverFlow |
kenjiArai | 7:7fdff925855e | 60 | static int32_t sw_ovrflw_tim2; |
kenjiArai | 7:7fdff925855e | 61 | static uint8_t rise_cnt; |
kenjiArai | 7:7fdff925855e | 62 | static uint8_t fall_cnt; |
kenjiArai | 7:7fdff925855e | 63 | |
kenjiArai | 7:7fdff925855e | 64 | // buffer for captured data |
kenjiArai | 7:7fdff925855e | 65 | freq_one captured_dt; // frequency data in pack (interrupt) |
kenjiArai | 8:c9ed197ce270 | 66 | int64_t rise_buf[2]; |
kenjiArai | 8:c9ed197ce270 | 67 | int64_t fall_buf[2]; |
kenjiArai | 7:7fdff925855e | 68 | uint32_t rise_pointer; |
kenjiArai | 7:7fdff925855e | 69 | uint32_t fall_pointer; |
kenjiArai | 7:7fdff925855e | 70 | |
kenjiArai | 7:7fdff925855e | 71 | //------------------------------------------------------------------------------ |
kenjiArai | 7:7fdff925855e | 72 | // Frequency Counter Library |
kenjiArai | 7:7fdff925855e | 73 | //------------------------------------------------------------------------------ |
kenjiArai | 7:7fdff925855e | 74 | FRQ_CUNTR::FRQ_CUNTR(PinName pin) : _input_pin(pin) |
kenjiArai | 7:7fdff925855e | 75 | { |
kenjiArai | 7:7fdff925855e | 76 | rise_pointer = 0; |
kenjiArai | 7:7fdff925855e | 77 | fall_pointer = 0; |
kenjiArai | 7:7fdff925855e | 78 | initialize_TIM2(); // Use for reciprocal |
kenjiArai | 7:7fdff925855e | 79 | } |
kenjiArai | 7:7fdff925855e | 80 | |
kenjiArai | 7:7fdff925855e | 81 | //------------------------------------------------------------------------------ |
kenjiArai | 7:7fdff925855e | 82 | // Initialize TIM2 |
kenjiArai | 7:7fdff925855e | 83 | //------------------------------------------------------------------------------ |
kenjiArai | 7:7fdff925855e | 84 | // IC1->PA0 for Reciprocal frequency counting mode (Interrupt) ->Rising Edge |
kenjiArai | 7:7fdff925855e | 85 | // IC2->PA1 for Reciprocal frequency counting mode (Interrupt) ->Falling Edge |
kenjiArai | 7:7fdff925855e | 86 | void FRQ_CUNTR::initialize_TIM2(void) |
kenjiArai | 7:7fdff925855e | 87 | { |
kenjiArai | 7:7fdff925855e | 88 | // Initialize Timer2(32bit) for an internal(90MHz/F446) up counter mode |
kenjiArai | 7:7fdff925855e | 89 | RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; |
kenjiArai | 7:7fdff925855e | 90 | // count_up + div by 1 |
kenjiArai | 7:7fdff925855e | 91 | TIM2->CR1 &= (uint16_t)(~(TIM_CR1_DIR | TIM_CR1_CMS | TIM_CR1_CKD)); |
kenjiArai | 7:7fdff925855e | 92 | // only counter overflow for interrupt |
kenjiArai | 7:7fdff925855e | 93 | TIM2->CR1 |= (uint16_t)TIM_CR1_URS; |
kenjiArai | 7:7fdff925855e | 94 | // Up counter uses from 0 to max(32bit) |
kenjiArai | 7:7fdff925855e | 95 | TIM2->ARR = 0xffffffff; |
kenjiArai | 7:7fdff925855e | 96 | TIM2->PSC = 0x0000; // 1/1 |
kenjiArai | 7:7fdff925855e | 97 | TIM2->CCER = 0; // Reset all |
kenjiArai | 7:7fdff925855e | 98 | // PA0 -> Input Capture pin as Timer2 IC1 for Reciprocal |
kenjiArai | 7:7fdff925855e | 99 | GPIOA->AFR[0] &= 0xfffffff0; |
kenjiArai | 7:7fdff925855e | 100 | GPIOA->AFR[0] |= GPIO_AF1_TIM2 << 0; // 0bit x 4 |
kenjiArai | 7:7fdff925855e | 101 | GPIOA->MODER &= ~(GPIO_MODER_MODER0); // AF |
kenjiArai | 7:7fdff925855e | 102 | GPIOA->MODER |= GPIO_MODER_MODER0_1; // alternate function mode |
kenjiArai | 7:7fdff925855e | 103 | GPIOA->PUPDR &= ~(GPIO_PUPDR_PUPDR0); // PU |
kenjiArai | 7:7fdff925855e | 104 | GPIOA->PUPDR |= GPIO_PUPDR_PUPDR0_0; // Pull-up mode |
kenjiArai | 7:7fdff925855e | 105 | // Initialize Timer2 IC1 |
kenjiArai | 7:7fdff925855e | 106 | // input filter + input select |
kenjiArai | 7:7fdff925855e | 107 | TIM2->CCMR1 &= ~(TIM_CCMR1_IC1F | TIM_CCMR1_CC1S); |
kenjiArai | 7:7fdff925855e | 108 | TIM2->CCMR1 |= (TIM_CCMR1_CC1S_0 + TIM_CCMR1_IC1F_0); // filter -> N=2 |
kenjiArai | 7:7fdff925855e | 109 | // Rising Edge <------------------------------ |
kenjiArai | 7:7fdff925855e | 110 | TIM2->CCER &= (uint16_t)~(TIM_CCER_CC1P | TIM_CCER_CC1NP); |
kenjiArai | 7:7fdff925855e | 111 | // enable capture + Rising Edge(0) |
kenjiArai | 7:7fdff925855e | 112 | TIM2->CCER |= (uint16_t)TIM_CCER_CC1E; |
kenjiArai | 7:7fdff925855e | 113 | // PA1 -> Input Capture pin as Timer2 IC2 |
kenjiArai | 7:7fdff925855e | 114 | GPIOA->AFR[0] &= 0xffffff0f; |
kenjiArai | 7:7fdff925855e | 115 | GPIOA->AFR[0] |= GPIO_AF1_TIM2 << 4; // 1bit x 4 |
kenjiArai | 7:7fdff925855e | 116 | GPIOA->MODER &= ~(GPIO_MODER_MODER1); // AF |
kenjiArai | 7:7fdff925855e | 117 | GPIOA->MODER |= GPIO_MODER_MODER1_1; // alternate function mode |
kenjiArai | 7:7fdff925855e | 118 | GPIOA->PUPDR &= ~(GPIO_PUPDR_PUPDR1); // PU |
kenjiArai | 7:7fdff925855e | 119 | GPIOA->PUPDR |= GPIO_PUPDR_PUPDR1_0; // Pull-up mode |
kenjiArai | 7:7fdff925855e | 120 | // Initialize Timer2 IC2 |
kenjiArai | 7:7fdff925855e | 121 | // input filter + input select |
kenjiArai | 7:7fdff925855e | 122 | TIM2->CCMR1 &= ~(TIM_CCMR1_IC2F | TIM_CCMR1_CC2S); |
kenjiArai | 7:7fdff925855e | 123 | TIM2->CCMR1 |= (TIM_CCMR1_CC2S_0 + TIM_CCMR1_IC2F_0); // filter -> N=2 |
kenjiArai | 7:7fdff925855e | 124 | // Falling Edge <------------------------------ |
kenjiArai | 7:7fdff925855e | 125 | TIM2->CCER &= (uint16_t)~(TIM_CCER_CC2P | TIM_CCER_CC2NP); |
kenjiArai | 7:7fdff925855e | 126 | // enable capture + Falling Edge(1) |
kenjiArai | 7:7fdff925855e | 127 | TIM2->CCER |= (uint16_t)TIM_CCER_CC2E | TIM_CCER_CC2P; |
kenjiArai | 7:7fdff925855e | 128 | // Only for Debug purpose |
kenjiArai | 7:7fdff925855e | 129 | // PA |
kenjiArai | 7:7fdff925855e | 130 | PRINTF("\r\n// Timer2(32bit) for an internal up counter mode\r\n"); |
kenjiArai | 7:7fdff925855e | 131 | PRINTF("// Set GPIO for Timer2\r\n"); |
kenjiArai | 7:7fdff925855e | 132 | PRINTF("// PA0 -> Input Capture pin as Timer2 CH1/TI1\r\n"); |
kenjiArai | 7:7fdff925855e | 133 | PRINTF("// PA1 -> Input Capture pin as Timer2 CH2/TI2\r\n"); |
kenjiArai | 7:7fdff925855e | 134 | PRINTF("GPIOA->AFRL 0x%08x:0x%08x\r\n",&GPIOA->AFR[0], GPIOA->AFR[0]); |
kenjiArai | 7:7fdff925855e | 135 | PRINTF("GPIOA->AFRH 0x%08x:0x%08x\r\n",&GPIOA->AFR[1], GPIOA->AFR[1]); |
kenjiArai | 7:7fdff925855e | 136 | PRINTF("GPIOA->MODER 0x%08x:0x%08x\r\n",&GPIOA->MODER, GPIOA->MODER); |
kenjiArai | 7:7fdff925855e | 137 | PRINTF("GPIOA->PUPDR 0x%08x:0x%08x\r\n",&GPIOA->PUPDR, GPIOA->PUPDR); |
kenjiArai | 7:7fdff925855e | 138 | // TIM2 |
kenjiArai | 7:7fdff925855e | 139 | PRINTF("// PA0 -> Timer2 IC1\r\n"); |
kenjiArai | 7:7fdff925855e | 140 | PRINTF("// PA1 -> Timer2 IC2\r\n"); |
kenjiArai | 7:7fdff925855e | 141 | PRINTF("TIM2->CR1 0x%08x:0x%08x\r\n",&TIM2->CR1, TIM2->CR1); |
kenjiArai | 7:7fdff925855e | 142 | PRINTF("TIM2->CR2 0x%08x:0x%08x\r\n",&TIM2->CR2, TIM2->CR2); |
kenjiArai | 7:7fdff925855e | 143 | PRINTF("TIM2->ARR 0x%08x:0x%08x\r\n",&TIM2->ARR, TIM2->ARR); |
kenjiArai | 7:7fdff925855e | 144 | PRINTF("TIM2->PSC 0x%08x:0x%08x\r\n",&TIM2->PSC, TIM2->PSC); |
kenjiArai | 7:7fdff925855e | 145 | PRINTF("TIM2->CCMR1 0x%08x:0x%08x\r\n",&TIM2->CCMR1, TIM2->CCMR1); |
kenjiArai | 7:7fdff925855e | 146 | PRINTF("TIM2->CCMR2 0x%08x:0x%08x\r\n",&TIM2->CCMR2, TIM2->CCMR2); |
kenjiArai | 7:7fdff925855e | 147 | PRINTF("TIM2->CCER 0x%08x:0x%08x\r\n",&TIM2->CCER, TIM2->CCER); |
kenjiArai | 7:7fdff925855e | 148 | PRINTF("TIM2->SMCR 0x%08x:0x%08x\r\n",&TIM2->SMCR, TIM2->SMCR); |
kenjiArai | 7:7fdff925855e | 149 | // Timer2 Overflow |
kenjiArai | 7:7fdff925855e | 150 | TIM2->DIER = 0; // Disable all interrupt |
kenjiArai | 7:7fdff925855e | 151 | sw_ovrflw_tim2 = 0; |
kenjiArai | 7:7fdff925855e | 152 | TIM2->CCR1 = 0; |
kenjiArai | 7:7fdff925855e | 153 | TIM2->CCR2 = 0; |
kenjiArai | 7:7fdff925855e | 154 | uint32_t dummy = TIM2->CCR1; |
kenjiArai | 7:7fdff925855e | 155 | dummy = TIM2->CCR1; |
kenjiArai | 7:7fdff925855e | 156 | dummy = TIM2->CCR2; |
kenjiArai | 7:7fdff925855e | 157 | dummy = TIM2->CCR2; |
kenjiArai | 7:7fdff925855e | 158 | TIM2->CNT = 0; |
kenjiArai | 7:7fdff925855e | 159 | TIM2->SR = 0; // clear all IC/OC flag |
kenjiArai | 7:7fdff925855e | 160 | // set clock source then enable |
kenjiArai | 7:7fdff925855e | 161 | TIM2->SMCR = 0; // Internal clock |
kenjiArai | 7:7fdff925855e | 162 | TIM2->CR1 |= (uint16_t)TIM_CR1_CEN; // Enable the TIM Counter |
kenjiArai | 7:7fdff925855e | 163 | // interrupt |
kenjiArai | 7:7fdff925855e | 164 | NVIC_SetVector(TIM2_IRQn, (uint32_t)irq_ic_TIM2); |
kenjiArai | 7:7fdff925855e | 165 | NVIC_ClearPendingIRQ(TIM2_IRQn); |
kenjiArai | 7:7fdff925855e | 166 | NVIC_EnableIRQ(TIM2_IRQn); |
kenjiArai | 7:7fdff925855e | 167 | PRINTF("TIM2->DIER 0x%08x:0x%08x\r\n\r\n",&TIM2->DIER, TIM2->DIER); |
kenjiArai | 7:7fdff925855e | 168 | } |
kenjiArai | 7:7fdff925855e | 169 | |
kenjiArai | 7:7fdff925855e | 170 | //------------------------------------------------------------------------------ |
kenjiArai | 7:7fdff925855e | 171 | // Reciprocal measuremt |
kenjiArai | 7:7fdff925855e | 172 | //------------------------------------------------------------------------------ |
kenjiArai | 7:7fdff925855e | 173 | void FRQ_CUNTR::start_action(void) |
kenjiArai | 7:7fdff925855e | 174 | { |
kenjiArai | 7:7fdff925855e | 175 | __disable_irq(); |
kenjiArai | 7:7fdff925855e | 176 | TIM2->SR &= ~(TIM_SR_CC1IF | TIM_SR_CC2IF); // clear IC flag |
kenjiArai | 7:7fdff925855e | 177 | TIM2->DIER |= TIM_DIER_CC1IE | TIM_DIER_CC2IE; // Enable IC1+IC2 |
kenjiArai | 7:7fdff925855e | 178 | __enable_irq(); |
kenjiArai | 7:7fdff925855e | 179 | } |
kenjiArai | 7:7fdff925855e | 180 | |
kenjiArai | 7:7fdff925855e | 181 | void FRQ_CUNTR::stop_action(void) |
kenjiArai | 7:7fdff925855e | 182 | { |
kenjiArai | 7:7fdff925855e | 183 | __disable_irq(); |
kenjiArai | 7:7fdff925855e | 184 | TIM2->SR &= ~(TIM_SR_CC1IF | TIM_SR_CC2IF); // clear IC flag |
kenjiArai | 7:7fdff925855e | 185 | __enable_irq(); |
kenjiArai | 7:7fdff925855e | 186 | } |
kenjiArai | 7:7fdff925855e | 187 | |
kenjiArai | 7:7fdff925855e | 188 | void FRQ_CUNTR::recipro_start_measurement() |
kenjiArai | 7:7fdff925855e | 189 | { |
kenjiArai | 7:7fdff925855e | 190 | SystemCoreClockUpdate(); |
kenjiArai | 7:7fdff925855e | 191 | _base_clock = (float)read_base_clock_frequency(); |
kenjiArai | 7:7fdff925855e | 192 | rise_cnt = 0; |
kenjiArai | 7:7fdff925855e | 193 | fall_cnt = 0; |
kenjiArai | 7:7fdff925855e | 194 | _data_ready = false; |
kenjiArai | 7:7fdff925855e | 195 | rise_buf[0] = 0; |
kenjiArai | 7:7fdff925855e | 196 | rise_buf[1] = 0; |
kenjiArai | 7:7fdff925855e | 197 | fall_buf[0] = 0; |
kenjiArai | 7:7fdff925855e | 198 | fall_buf[1] = 0; |
kenjiArai | 7:7fdff925855e | 199 | start_action(); |
kenjiArai | 7:7fdff925855e | 200 | _t.reset(); |
kenjiArai | 7:7fdff925855e | 201 | _t.start(); |
kenjiArai | 7:7fdff925855e | 202 | } |
kenjiArai | 7:7fdff925855e | 203 | |
kenjiArai | 7:7fdff925855e | 204 | void FRQ_CUNTR::recipro_stop_measurement() |
kenjiArai | 7:7fdff925855e | 205 | { |
kenjiArai | 7:7fdff925855e | 206 | _t.reset(); |
kenjiArai | 7:7fdff925855e | 207 | _t.stop(); |
kenjiArai | 7:7fdff925855e | 208 | stop_action(); |
kenjiArai | 7:7fdff925855e | 209 | } |
kenjiArai | 7:7fdff925855e | 210 | |
kenjiArai | 7:7fdff925855e | 211 | bool FRQ_CUNTR::recipro_check_status(Recipro_status_TypeDef *status) |
kenjiArai | 7:7fdff925855e | 212 | { |
kenjiArai | 8:c9ed197ce270 | 213 | freq_one _temp; |
kenjiArai | 7:7fdff925855e | 214 | |
kenjiArai | 7:7fdff925855e | 215 | bool _ready = false; |
kenjiArai | 7:7fdff925855e | 216 | _data_buf[0] = rise_buf[0]; |
kenjiArai | 7:7fdff925855e | 217 | _data_buf[1] = rise_buf[1]; |
kenjiArai | 7:7fdff925855e | 218 | _data_buf[2] = fall_buf[0]; |
kenjiArai | 7:7fdff925855e | 219 | _data_buf[3] = fall_buf[1]; |
kenjiArai | 7:7fdff925855e | 220 | uint8_t sum = 0; |
kenjiArai | 7:7fdff925855e | 221 | if (_data_buf[0] == 0) { ++sum;} |
kenjiArai | 7:7fdff925855e | 222 | if (_data_buf[1] == 0) { ++sum;} |
kenjiArai | 7:7fdff925855e | 223 | if (_data_buf[2] == 0) { ++sum;} |
kenjiArai | 7:7fdff925855e | 224 | if (_data_buf[3] == 0) { ++sum;} |
kenjiArai | 7:7fdff925855e | 225 | if (sum != 4) { |
kenjiArai | 7:7fdff925855e | 226 | _ready = true; |
kenjiArai | 7:7fdff925855e | 227 | // change order |
kenjiArai | 7:7fdff925855e | 228 | if (_data_buf[0] > _data_buf[1]){ |
kenjiArai | 8:c9ed197ce270 | 229 | _temp.f_64bit_dt = _data_buf[0]; |
kenjiArai | 7:7fdff925855e | 230 | _data_buf[0] = _data_buf[1]; |
kenjiArai | 8:c9ed197ce270 | 231 | _data_buf[1] = _temp.f_64bit_dt; |
kenjiArai | 7:7fdff925855e | 232 | } |
kenjiArai | 7:7fdff925855e | 233 | _tp0 = _data_buf[1] - _data_buf[0]; |
kenjiArai | 7:7fdff925855e | 234 | if (_tp0 < 0) { |
kenjiArai | 7:7fdff925855e | 235 | _tp0 = 0; |
kenjiArai | 7:7fdff925855e | 236 | } |
kenjiArai | 7:7fdff925855e | 237 | if (_data_buf[2] > _data_buf[3]){ |
kenjiArai | 8:c9ed197ce270 | 238 | _temp.f_64bit_dt = _data_buf[2]; |
kenjiArai | 7:7fdff925855e | 239 | _data_buf[2] = _data_buf[3]; |
kenjiArai | 8:c9ed197ce270 | 240 | _data_buf[3] = _temp.f_64bit_dt; |
kenjiArai | 7:7fdff925855e | 241 | } |
kenjiArai | 7:7fdff925855e | 242 | _tp1 = _data_buf[3] - _data_buf[2]; |
kenjiArai | 7:7fdff925855e | 243 | if (_tp1 < 0) { |
kenjiArai | 7:7fdff925855e | 244 | _tp1 = 0; |
kenjiArai | 7:7fdff925855e | 245 | } |
kenjiArai | 7:7fdff925855e | 246 | // calculate diff |
kenjiArai | 7:7fdff925855e | 247 | if (_data_buf[3] > _data_buf[1]) { |
kenjiArai | 7:7fdff925855e | 248 | //type A |
kenjiArai | 7:7fdff925855e | 249 | _tp2 = _data_buf[2] - _data_buf[0]; |
kenjiArai | 7:7fdff925855e | 250 | _tp3 = _data_buf[1] - _data_buf[2]; |
kenjiArai | 7:7fdff925855e | 251 | } else { |
kenjiArai | 7:7fdff925855e | 252 | //type B |
kenjiArai | 7:7fdff925855e | 253 | _tp2 = _data_buf[3] - _data_buf[0]; |
kenjiArai | 7:7fdff925855e | 254 | _tp3 = _data_buf[0] - _data_buf[2]; |
kenjiArai | 7:7fdff925855e | 255 | } |
kenjiArai | 7:7fdff925855e | 256 | if (_tp2 < 0) { |
kenjiArai | 7:7fdff925855e | 257 | _tp2 = 0; |
kenjiArai | 7:7fdff925855e | 258 | } |
kenjiArai | 7:7fdff925855e | 259 | if (_tp3 < 0) { |
kenjiArai | 7:7fdff925855e | 260 | _tp3 = 0; |
kenjiArai | 7:7fdff925855e | 261 | } |
kenjiArai | 7:7fdff925855e | 262 | } |
kenjiArai | 7:7fdff925855e | 263 | PRINTF("rise_buf[0] = %.0f\r\n", (float)rise_buf[0]); |
kenjiArai | 7:7fdff925855e | 264 | PRINTF("rise_buf[1] = %.0f\r\n", (float)rise_buf[1]); |
kenjiArai | 7:7fdff925855e | 265 | PRINTF("fall_buf[0] = %.0f\r\n", (float)fall_buf[0]); |
kenjiArai | 7:7fdff925855e | 266 | PRINTF("fall_buf[1] = %.0f\r\n", (float)fall_buf[1]); |
kenjiArai | 7:7fdff925855e | 267 | PRINTF("data_buf0[0]= %.0f\r\n", (float)_data_buf[0]); |
kenjiArai | 7:7fdff925855e | 268 | PRINTF("data_buf0[1]= %.0f\r\n", (float)_data_buf[1]); |
kenjiArai | 7:7fdff925855e | 269 | PRINTF("data_buf1[0]= %.0f\r\n", (float)_data_buf[2]); |
kenjiArai | 7:7fdff925855e | 270 | PRINTF("data_buf1[1]= %.0f\r\n", (float)_data_buf[3]); |
kenjiArai | 7:7fdff925855e | 271 | PRINTF("tp0= %.0f\r\n", (float)_tp0); |
kenjiArai | 7:7fdff925855e | 272 | PRINTF("tp1= %.0f\r\n", (float)_tp1); |
kenjiArai | 7:7fdff925855e | 273 | PRINTF("tp2= %.0f\r\n", (float)_tp2); |
kenjiArai | 7:7fdff925855e | 274 | PRINTF("tp3= %.0f\r\n", (float)_tp3); |
kenjiArai | 7:7fdff925855e | 275 | if (_ready == true) { |
kenjiArai | 7:7fdff925855e | 276 | _freq_rise2rise = _base_clock / (float)_tp0; |
kenjiArai | 7:7fdff925855e | 277 | _freq_fall2fall = _base_clock / (float)_tp1; |
kenjiArai | 7:7fdff925855e | 278 | _time_us_rise2fall = (float)_tp2 / _base_clock * 1.0e3; |
kenjiArai | 7:7fdff925855e | 279 | _time_us_fall2rise = (float)_tp3 / _base_clock * 1.0e3; |
kenjiArai | 7:7fdff925855e | 280 | _data_ready = true; |
kenjiArai | 7:7fdff925855e | 281 | PRINTF("freq_rise2rise= %f [Hz]\r\n", _freq_rise2rise); |
kenjiArai | 7:7fdff925855e | 282 | PRINTF("freq_fall2fall= %f [Hz]\r\n", _freq_fall2fall); |
kenjiArai | 7:7fdff925855e | 283 | PRINTF("time_us_rise2fall= %f [mS]\r\n", _time_us_rise2fall); |
kenjiArai | 7:7fdff925855e | 284 | PRINTF("time_us_fall2rise= %f [mS]\r\n", _time_us_fall2rise); |
kenjiArai | 7:7fdff925855e | 285 | } |
kenjiArai | 7:7fdff925855e | 286 | status->rise_cnt = rise_cnt; |
kenjiArai | 7:7fdff925855e | 287 | status->fall_cnt = fall_cnt; |
kenjiArai | 7:7fdff925855e | 288 | status->input_level = _input_pin.read(); |
kenjiArai | 7:7fdff925855e | 289 | status->passed_time = (float)_t.read_us() / 1.0e6; |
kenjiArai | 7:7fdff925855e | 290 | return _data_ready; |
kenjiArai | 7:7fdff925855e | 291 | } |
kenjiArai | 7:7fdff925855e | 292 | |
kenjiArai | 7:7fdff925855e | 293 | void FRQ_CUNTR::recipro_get_result(Recipro_result_TypeDef *fq) |
kenjiArai | 7:7fdff925855e | 294 | { |
kenjiArai | 7:7fdff925855e | 295 | fq->freq_rise2rise = _freq_rise2rise; |
kenjiArai | 7:7fdff925855e | 296 | fq->freq_fall2fall = _freq_fall2fall; |
kenjiArai | 7:7fdff925855e | 297 | fq->time_us_rise2fall = _time_us_rise2fall; |
kenjiArai | 7:7fdff925855e | 298 | fq->time_us_fall2rise = _time_us_fall2rise; |
kenjiArai | 7:7fdff925855e | 299 | } |
kenjiArai | 7:7fdff925855e | 300 | |
kenjiArai | 7:7fdff925855e | 301 | void FRQ_CUNTR::recipro_get_raw_data(int64_t *buf) |
kenjiArai | 7:7fdff925855e | 302 | { |
kenjiArai | 7:7fdff925855e | 303 | int64_t *pointer = buf; |
kenjiArai | 7:7fdff925855e | 304 | *pointer++ = rise_buf[0]; |
kenjiArai | 7:7fdff925855e | 305 | *pointer++ = fall_buf[0]; |
kenjiArai | 7:7fdff925855e | 306 | *pointer++ = rise_buf[1]; |
kenjiArai | 7:7fdff925855e | 307 | *pointer++ = fall_buf[1]; |
kenjiArai | 7:7fdff925855e | 308 | pointer = buf; |
kenjiArai | 7:7fdff925855e | 309 | for (uint32_t i = 0; i < 4; i++) { |
kenjiArai | 7:7fdff925855e | 310 | float dt = (float)*pointer++; |
kenjiArai | 7:7fdff925855e | 311 | PRINTF("%2d = %12.0f \r\n", i, dt); |
kenjiArai | 7:7fdff925855e | 312 | } |
kenjiArai | 7:7fdff925855e | 313 | } |
kenjiArai | 7:7fdff925855e | 314 | |
kenjiArai | 7:7fdff925855e | 315 | //------------------------------------------------------------------------------ |
kenjiArai | 7:7fdff925855e | 316 | // Interrupt Handlers |
kenjiArai | 7:7fdff925855e | 317 | //------------------------------------------------------------------------------ |
kenjiArai | 7:7fdff925855e | 318 | // Reciprocal data (TIM2 IC1+IC2) |
kenjiArai | 7:7fdff925855e | 319 | void irq_ic_TIM2(void) |
kenjiArai | 7:7fdff925855e | 320 | { |
kenjiArai | 7:7fdff925855e | 321 | // IC1 (for reciprocal measurement / Rising edge) |
kenjiArai | 7:7fdff925855e | 322 | uint32_t reg = TIM2->SR; |
kenjiArai | 7:7fdff925855e | 323 | if (reg & TIM_SR_CC1IF) { |
kenjiArai | 7:7fdff925855e | 324 | SET0; |
kenjiArai | 7:7fdff925855e | 325 | TIM2->SR &= ~TIM_SR_CC1IF; // clear IC flag |
kenjiArai | 7:7fdff925855e | 326 | captured_dt.freq_dt = TIM2->CCR1; |
kenjiArai | 7:7fdff925855e | 327 | captured_dt.f_sw_dt = sw_ovrflw_tim2; |
kenjiArai | 7:7fdff925855e | 328 | rise_buf[rise_pointer % 2] = captured_dt.f_64bit_dt; |
kenjiArai | 7:7fdff925855e | 329 | ++rise_pointer; |
kenjiArai | 7:7fdff925855e | 330 | ++rise_cnt; |
kenjiArai | 7:7fdff925855e | 331 | CLR0; |
kenjiArai | 7:7fdff925855e | 332 | } |
kenjiArai | 7:7fdff925855e | 333 | // IC2 (for reciprocal measurement / Falling edge) |
kenjiArai | 7:7fdff925855e | 334 | if (reg & TIM_SR_CC2IF) { |
kenjiArai | 7:7fdff925855e | 335 | SET1; |
kenjiArai | 7:7fdff925855e | 336 | TIM2->SR &= ~TIM_SR_CC2IF; // clear IC flag |
kenjiArai | 7:7fdff925855e | 337 | captured_dt.freq_dt = TIM2->CCR2; |
kenjiArai | 7:7fdff925855e | 338 | captured_dt.f_sw_dt = sw_ovrflw_tim2; |
kenjiArai | 7:7fdff925855e | 339 | fall_buf[fall_pointer % 2] = captured_dt.f_64bit_dt; |
kenjiArai | 7:7fdff925855e | 340 | ++fall_pointer; |
kenjiArai | 7:7fdff925855e | 341 | ++fall_cnt; |
kenjiArai | 7:7fdff925855e | 342 | CLR1; |
kenjiArai | 7:7fdff925855e | 343 | } |
kenjiArai | 7:7fdff925855e | 344 | // TIM2 overflow |
kenjiArai | 7:7fdff925855e | 345 | if (reg & TIM_SR_UIF) { // 32bit counter overflow |
kenjiArai | 7:7fdff925855e | 346 | SET2; |
kenjiArai | 7:7fdff925855e | 347 | TIM2->SR &= ~TIM_SR_UIF; // clear UIF(overflow) flag |
kenjiArai | 7:7fdff925855e | 348 | ++sw_ovrflw_tim2; |
kenjiArai | 7:7fdff925855e | 349 | CLR2 |
kenjiArai | 7:7fdff925855e | 350 | } |
kenjiArai | 7:7fdff925855e | 351 | } |
kenjiArai | 7:7fdff925855e | 352 | |
kenjiArai | 7:7fdff925855e | 353 | //------------------------------------------------------------------------------ |
kenjiArai | 7:7fdff925855e | 354 | // Frequency check for test & debug purpose |
kenjiArai | 7:7fdff925855e | 355 | //------------------------------------------------------------------------------ |
kenjiArai | 7:7fdff925855e | 356 | // Read TIM2 Clock frequency |
kenjiArai | 7:7fdff925855e | 357 | uint32_t FRQ_CUNTR::read_base_clock_frequency(void) |
kenjiArai | 7:7fdff925855e | 358 | { |
kenjiArai | 7:7fdff925855e | 359 | TIM2->CNT = 0; |
kenjiArai | 7:7fdff925855e | 360 | wait_us(1000000); // Gate time = 1seconds |
kenjiArai | 7:7fdff925855e | 361 | uint32_t freq = TIM2->CNT; // read counter |
kenjiArai | 7:7fdff925855e | 362 | PRINTF("Clock Frequency= %10d, gate= %4.2f [Sec]\r\n", freq); |
kenjiArai | 7:7fdff925855e | 363 | return freq; // return counter data |
kenjiArai | 7:7fdff925855e | 364 | } |
kenjiArai | 7:7fdff925855e | 365 | |
kenjiArai | 7:7fdff925855e | 366 | // |
kenjiArai | 7:7fdff925855e | 367 | uint32_t FRQ_CUNTR::read_tm2_overflow(void) |
kenjiArai | 7:7fdff925855e | 368 | { |
kenjiArai | 7:7fdff925855e | 369 | return sw_ovrflw_tim2; |
kenjiArai | 7:7fdff925855e | 370 | } |
kenjiArai | 7:7fdff925855e | 371 | |
kenjiArai | 7:7fdff925855e | 372 | } // Frequency_counter |