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:
Tue Dec 23 23:26:49 2014 +0000
Revision:
3:339307e1dc0d
Parent:
2:194f82ad3041
Child:
4:9d3b3f0a3882
change clock input PA0, CH1 to ETR, change debug functions, add new functions

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kenjiArai 0:bfdc6ed58a06 1 /*
kenjiArai 1:102230f2879d 2 * mbed Library / Frequency Counter with GPS 1PPS Compensation
kenjiArai 0:bfdc6ed58a06 3 * Frequency Counter Hardware relataed program
kenjiArai 1:102230f2879d 4 * Only for ST Nucleo F411RE
kenjiArai 0:bfdc6ed58a06 5 *
kenjiArai 0:bfdc6ed58a06 6 * Copyright (c) 2014 Kenji Arai / JH1PJL
kenjiArai 0:bfdc6ed58a06 7 * http://www.page.sannet.ne.jp/kenjia/index.html
kenjiArai 0:bfdc6ed58a06 8 * http://mbed.org/users/kenjiArai/
kenjiArai 0:bfdc6ed58a06 9 * Additional functions and modification
kenjiArai 0:bfdc6ed58a06 10 * started: October 18th, 2014
kenjiArai 3:339307e1dc0d 11 * Revised: December 24th, 2014
kenjiArai 0:bfdc6ed58a06 12 *
kenjiArai 0:bfdc6ed58a06 13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
kenjiArai 0:bfdc6ed58a06 14 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
kenjiArai 0:bfdc6ed58a06 15 * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
kenjiArai 0:bfdc6ed58a06 16 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
kenjiArai 0:bfdc6ed58a06 17 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
kenjiArai 0:bfdc6ed58a06 18 */
kenjiArai 0:bfdc6ed58a06 19
kenjiArai 0:bfdc6ed58a06 20 #ifndef MBED_FRQ_CUNTR
kenjiArai 0:bfdc6ed58a06 21 #define MBED_FRQ_CUNTR
kenjiArai 0:bfdc6ed58a06 22
kenjiArai 0:bfdc6ed58a06 23 #include "mbed.h"
kenjiArai 0:bfdc6ed58a06 24
kenjiArai 3:339307e1dc0d 25 // please comment out when normal run mode
kenjiArai 2:194f82ad3041 26 //#define DEBUG // use Communication with PC(UART)
kenjiArai 2:194f82ad3041 27
kenjiArai 1:102230f2879d 28 /*
kenjiArai 1:102230f2879d 29 CAUTION:
kenjiArai 1:102230f2879d 30 If you select internal clock (100MHz), you need consider PLL clock behavior.
kenjiArai 2:194f82ad3041 31 PLL clock drifts over 70Hz (increase frequency) within 30 to 40 second
kenjiArai 1:102230f2879d 32 then suddenly back to low frequency and increase again.
kenjiArai 1:102230f2879d 33 Even you prepare precision external clock, this frequency drift cannot avoid.
kenjiArai 2:194f82ad3041 34 Comment out "BASE_EXTERNAL_CLOCK" is only for checking!!
kenjiArai 1:102230f2879d 35 */
kenjiArai 1:102230f2879d 36 #define BASE_EXTERNAL_CLOCK
kenjiArai 1:102230f2879d 37
kenjiArai 3:339307e1dc0d 38 // use avaraged 1pps data
kenjiArai 3:339307e1dc0d 39 #define ONEPPS_AVE
kenjiArai 3:339307e1dc0d 40
kenjiArai 3:339307e1dc0d 41 // External clock divided by 2
kenjiArai 3:339307e1dc0d 42 #define CLOCK_DIVIDED_BY_2
kenjiArai 3:339307e1dc0d 43
kenjiArai 0:bfdc6ed58a06 44 namespace Frequency_counter
kenjiArai 0:bfdc6ed58a06 45 {
kenjiArai 1:102230f2879d 46
kenjiArai 1:102230f2879d 47 #define CNT_BF_SIZE 120 // 1PPS data save size
kenjiArai 1:102230f2879d 48
kenjiArai 1:102230f2879d 49 /** Frequency Counter program
kenjiArai 1:102230f2879d 50 * Only for ST Nucleo F411RE Board
kenjiArai 1:102230f2879d 51 *
kenjiArai 1:102230f2879d 52 * @code
kenjiArai 1:102230f2879d 53 * #include "mbed.h"
kenjiArai 1:102230f2879d 54 *
kenjiArai 2:194f82ad3041 55 * using namespace Frequency_counter;
kenjiArai 2:194f82ad3041 56 *
kenjiArai 2:194f82ad3041 57 * // PC_6,PC_7 & PB_6 use for Timer3 & 4(16+16bit)
kenjiArai 2:194f82ad3041 58 * // PA_0,PA_1 & PB_10 use for Timer2(32bit)
kenjiArai 2:194f82ad3041 59 * // PA_8 & PC_7 use for MCO (Test purpose)
kenjiArai 2:194f82ad3041 60 * FRQ_CUNTR fc(PC_6, 1.0, 50.000000);// Input port, gate time[sec] and External clock freq.
kenjiArai 1:102230f2879d 61 *
kenjiArai 1:102230f2879d 62 * int main() {
kenjiArai 2:194f82ad3041 63 * uint32_t counter_1pps = 0;
kenjiArai 2:194f82ad3041 64 * double new_frequency = 0;
kenjiArai 1:102230f2879d 65 * // This is for test purpose
kenjiArai 1:102230f2879d 66 * fc.port_mco1_mco2_set(2); // Clk/2 ->1/1(100MHz) cannot measure!!
kenjiArai 1:102230f2879d 67 * fc.read_frequency_TIM2(1.0); // read TIM2 source frequency (test)
kenjiArai 1:102230f2879d 68 * fc.read_frequency_TIM3P4(1.0); // read TIM3 source frequency (test)
kenjiArai 1:102230f2879d 69 * while(true) {
kenjiArai 1:102230f2879d 70 * while (fc.status_1pps() == 0) {;}
kenjiArai 1:102230f2879d 71 * counter_1pps = fc.read_avarage_1pps();
kenjiArai 1:102230f2879d 72 * while (fc.status_freq_update() == 0) {;}
kenjiArai 1:102230f2879d 73 * new_frequency = fc.read_freq_data();
kenjiArai 2:194f82ad3041 74 * PRINTF("1PPS/ave = %9d , FREQUENCY = %11.3f\r\n", counter_1pps, new_frequency);
kenjiArai 1:102230f2879d 75 * }
kenjiArai 1:102230f2879d 76 * }
kenjiArai 1:102230f2879d 77 * @endcode
kenjiArai 1:102230f2879d 78 */
kenjiArai 1:102230f2879d 79
kenjiArai 1:102230f2879d 80 class FRQ_CUNTR
kenjiArai 1:102230f2879d 81 {
kenjiArai 1:102230f2879d 82 public:
kenjiArai 2:194f82ad3041 83
kenjiArai 1:102230f2879d 84 /** Configure data pin (Not changeable)
kenjiArai 2:194f82ad3041 85 * @param Freq. input pin + Gate time[sec] + External clock[MHz]
kenjiArai 1:102230f2879d 86 */
kenjiArai 2:194f82ad3041 87 FRQ_CUNTR(PinName f_in, double gt, double ex_clock);
kenjiArai 1:102230f2879d 88
kenjiArai 1:102230f2879d 89 /** Set gate time
kenjiArai 1:102230f2879d 90 * @param gate time [sec]
kenjiArai 2:194f82ad3041 91 * @return gate time (range 50mS to 1 minute)
kenjiArai 1:102230f2879d 92 */
kenjiArai 1:102230f2879d 93 double set_gate_time(double gt);
kenjiArai 1:102230f2879d 94
kenjiArai 2:194f82ad3041 95 /** Read gate time
kenjiArai 2:194f82ad3041 96 * @param none
kenjiArai 2:194f82ad3041 97 * @return gate time (range 50mS to 1 minute)
kenjiArai 2:194f82ad3041 98 */
kenjiArai 2:194f82ad3041 99 double read_gate_time(void);
kenjiArai 2:194f82ad3041 100
kenjiArai 1:102230f2879d 101 /** Read status (new frequency data is available or not)
kenjiArai 1:102230f2879d 102 * @param none
kenjiArai 1:102230f2879d 103 * @return !=0: new data is avairable, 0: not yet
kenjiArai 1:102230f2879d 104 */
kenjiArai 1:102230f2879d 105 uint32_t status_freq_update(void);
kenjiArai 1:102230f2879d 106
kenjiArai 1:102230f2879d 107 /** Read new frequency data
kenjiArai 1:102230f2879d 108 * @param none
kenjiArai 1:102230f2879d 109 * @return frequency data
kenjiArai 1:102230f2879d 110 */
kenjiArai 2:194f82ad3041 111 double read_freq_data(void);
kenjiArai 0:bfdc6ed58a06 112
kenjiArai 1:102230f2879d 113 /** Read avarage measued data GPS 1PPS
kenjiArai 1:102230f2879d 114 * @param none
kenjiArai 1:102230f2879d 115 * @return Frequency
kenjiArai 1:102230f2879d 116 */
kenjiArai 1:102230f2879d 117 uint32_t read_avarage_1pps(void);
kenjiArai 1:102230f2879d 118
kenjiArai 1:102230f2879d 119 /** Read status (new 1PPS data is available or not)
kenjiArai 1:102230f2879d 120 * @param none
kenjiArai 1:102230f2879d 121 * @return !=0: new data is avairable, 0: not yet
kenjiArai 1:102230f2879d 122 */
kenjiArai 1:102230f2879d 123 uint32_t status_1pps(void);
kenjiArai 1:102230f2879d 124
kenjiArai 2:194f82ad3041 125 /** Read GPS status
kenjiArai 2:194f82ad3041 126 * @param none
kenjiArai 2:194f82ad3041 127 * @return 1: GPS is ready
kenjiArai 2:194f82ad3041 128 */
kenjiArai 3:339307e1dc0d 129 uint8_t status_gps(void);
kenjiArai 2:194f82ad3041 130
kenjiArai 2:194f82ad3041 131 /** This is a "TEST PURPOSE" function
kenjiArai 1:102230f2879d 132 * Check PA0 pin input or internal clock frequency
kenjiArai 1:102230f2879d 133 * @param none
kenjiArai 1:102230f2879d 134 * @return Frequency
kenjiArai 1:102230f2879d 135 */
kenjiArai 1:102230f2879d 136 uint32_t read_frequency_TIM2(float gate_time);
kenjiArai 1:102230f2879d 137
kenjiArai 2:194f82ad3041 138 /** This is a "TEST PURPOSE" function
kenjiArai 1:102230f2879d 139 * Check PC6 pin input frequency
kenjiArai 1:102230f2879d 140 * @param none
kenjiArai 1:102230f2879d 141 * @return Frequency
kenjiArai 1:102230f2879d 142 */
kenjiArai 1:102230f2879d 143 uint32_t read_frequency_TIM3P4(float gate_time);
kenjiArai 1:102230f2879d 144
kenjiArai 2:194f82ad3041 145 /** This is a "TEST PURPOSE" function
kenjiArai 1:102230f2879d 146 * Output clock from pin PA8 & PC9 uses for MCO_1 & MCO_2
kenjiArai 1:102230f2879d 147 * @param none
kenjiArai 1:102230f2879d 148 * @return none
kenjiArai 1:102230f2879d 149 */
kenjiArai 1:102230f2879d 150 void port_mco1_mco2_set(uint8_t select);
kenjiArai 1:102230f2879d 151
kenjiArai 2:194f82ad3041 152 /** This is a "DEBUG PURPOSE" function
kenjiArai 2:194f82ad3041 153 * print internal data (need to define "DEBUG"
kenjiArai 2:194f82ad3041 154 * @param none
kenjiArai 2:194f82ad3041 155 * @return none
kenjiArai 2:194f82ad3041 156 */
kenjiArai 2:194f82ad3041 157 void debug_printf_internal_data(void);
kenjiArai 2:194f82ad3041 158
kenjiArai 1:102230f2879d 159 protected:
kenjiArai 1:102230f2879d 160 DigitalIn _pin;
kenjiArai 1:102230f2879d 161
kenjiArai 1:102230f2879d 162 void initialize_Freq_counter(void); // Initialize timers
kenjiArai 2:194f82ad3041 163 // Internal clock (100MHz) or External clock(?MHz) and IC2 for GPS 1pps signal measurement
kenjiArai 1:102230f2879d 164 void initialize_TIM2(void);
kenjiArai 1:102230f2879d 165 // Initialize TIM3 and TIM4 as 32bit counter (TIM3(16bit) + TIM4(16bit))
kenjiArai 1:102230f2879d 166 void initialize_TIM3P4(void);
kenjiArai 2:194f82ad3041 167 void set_external_clock(double ex_clock); // Set external clock data
kenjiArai 1:102230f2879d 168 uint32_t set_1PPS_data(void); // Set GPS 1PPS counter value
kenjiArai 1:102230f2879d 169 uint32_t read_ic2_counter_TIM2(void); // Read TIM2 captured counter value
kenjiArai 1:102230f2879d 170 uint32_t check_ic2_status_TIM2(void); // Check TIM2 IC2 status
kenjiArai 1:102230f2879d 171 uint32_t read_ic2_counter_TIM3P4(void); // Read TIM3+4(as 32bit) captured counter value
kenjiArai 1:102230f2879d 172 uint32_t check_ic2_status_TIM3P4(void); // Check TIM3 IC2 & TIM4 IC1 status
kenjiArai 1:102230f2879d 173 uint8_t read_oc_port_status(void); // Check TIM2 OC port
kenjiArai 1:102230f2879d 174
kenjiArai 1:102230f2879d 175 private:
kenjiArai 2:194f82ad3041 176 double newest_frequency;
kenjiArai 2:194f82ad3041 177 double gate_time;
kenjiArai 2:194f82ad3041 178 double ex_clock_freq;
kenjiArai 2:194f82ad3041 179 uint32_t ex_clk_base;
kenjiArai 2:194f82ad3041 180 uint32_t clk_hi_const;
kenjiArai 2:194f82ad3041 181 uint32_t clk_upper_limit;
kenjiArai 2:194f82ad3041 182 uint32_t clk_lower_limit;
kenjiArai 3:339307e1dc0d 183 uint8_t gps_ready;
kenjiArai 1:102230f2879d 184 // TIM2
kenjiArai 1:102230f2879d 185 uint32_t counter_tim2;
kenjiArai 1:102230f2879d 186 uint32_t old_cntr_tim2;
kenjiArai 1:102230f2879d 187 // TIM3+4
kenjiArai 1:102230f2879d 188 uint32_t counter_tim3p4;
kenjiArai 1:102230f2879d 189 uint32_t old_cntr_tim3p4;
kenjiArai 1:102230f2879d 190 // 1PPS data
kenjiArai 1:102230f2879d 191 uint32_t onepps_newest;
kenjiArai 1:102230f2879d 192 uint32_t onepps_cnt[CNT_BF_SIZE];
kenjiArai 1:102230f2879d 193 uint32_t onepps_num;
kenjiArai 1:102230f2879d 194 uint64_t onepps_cnt_avarage;
kenjiArai 1:102230f2879d 195 uint8_t onepps_buf_full;
kenjiArai 1:102230f2879d 196 uint8_t onepps_ready_flg;
kenjiArai 2:194f82ad3041 197
kenjiArai 1:102230f2879d 198 };
kenjiArai 1:102230f2879d 199
kenjiArai 1:102230f2879d 200 /*
kenjiArai 1:102230f2879d 201 Interrupt handler does NOT work following code
kenjiArai 1:102230f2879d 202 NVIC_SetVector(TIM2_IRQn, (uint32_t)FRQ_CUNTR::irq_ic2_TIM2);
kenjiArai 1:102230f2879d 203 From this reason, I wrote below code and set interrupt handler out side "FRQ_CUNTR" class
kenjiArai 1:102230f2879d 204 NVIC_SetVector(TIM2_IRQn, (uint32_t)irq_ic2_TIM2);
kenjiArai 1:102230f2879d 205 */
kenjiArai 1:102230f2879d 206 void irq_ic2_TIM2(void); // TIM2 IC2 Interrupt control
kenjiArai 1:102230f2879d 207 void irq_ic2_TIM3P4(void); // TIM3 IC2 Interrupt control (same signal connected to TIM4 IC1)
kenjiArai 1:102230f2879d 208
kenjiArai 0:bfdc6ed58a06 209 } // Frequency_counter
kenjiArai 0:bfdc6ed58a06 210
kenjiArai 1:102230f2879d 211 #endif // MBED_FRQ_CUNTR