Frequency counter library only for NucleoF411RE

Dependents:   Frequency_Counter_w_GPS_1PPS

Committer:
kenjiArai
Date:
Thu Jan 01 05:04:20 2015 +0000
Revision:
4:9d3b3f0a3882
Parent:
3:339307e1dc0d
Modified comments

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 4:9d3b3f0a3882 11 * Revised: January 1st, 2015
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 0:bfdc6ed58a06 41 namespace Frequency_counter
kenjiArai 0:bfdc6ed58a06 42 {
kenjiArai 1:102230f2879d 43
kenjiArai 1:102230f2879d 44 #define CNT_BF_SIZE 120 // 1PPS data save size
kenjiArai 1:102230f2879d 45
kenjiArai 1:102230f2879d 46 /** Frequency Counter program
kenjiArai 1:102230f2879d 47 * Only for ST Nucleo F411RE Board
kenjiArai 1:102230f2879d 48 *
kenjiArai 1:102230f2879d 49 * @code
kenjiArai 1:102230f2879d 50 * #include "mbed.h"
kenjiArai 1:102230f2879d 51 *
kenjiArai 2:194f82ad3041 52 * using namespace Frequency_counter;
kenjiArai 2:194f82ad3041 53 *
kenjiArai 2:194f82ad3041 54 * // PC_6,PC_7 & PB_6 use for Timer3 & 4(16+16bit)
kenjiArai 2:194f82ad3041 55 * // PA_0,PA_1 & PB_10 use for Timer2(32bit)
kenjiArai 2:194f82ad3041 56 * // PA_8 & PC_7 use for MCO (Test purpose)
kenjiArai 4:9d3b3f0a3882 57 * FRQ_CUNTR fc(PC_6, 1.0, 24.999982f); //Input port, gate time[sec] & External clock freq.
kenjiArai 1:102230f2879d 58 *
kenjiArai 1:102230f2879d 59 * int main() {
kenjiArai 2:194f82ad3041 60 * uint32_t counter_1pps = 0;
kenjiArai 2:194f82ad3041 61 * double new_frequency = 0;
kenjiArai 1:102230f2879d 62 * // This is for test purpose
kenjiArai 4:9d3b3f0a3882 63 * fc.port_mco1_mco2_set(4); // Clk/4 ->1/1(100MHz) cannot measure!!
kenjiArai 1:102230f2879d 64 * fc.read_frequency_TIM2(1.0); // read TIM2 source frequency (test)
kenjiArai 1:102230f2879d 65 * fc.read_frequency_TIM3P4(1.0); // read TIM3 source frequency (test)
kenjiArai 1:102230f2879d 66 * while(true) {
kenjiArai 1:102230f2879d 67 * while (fc.status_1pps() == 0) {;}
kenjiArai 1:102230f2879d 68 * counter_1pps = fc.read_avarage_1pps();
kenjiArai 1:102230f2879d 69 * while (fc.status_freq_update() == 0) {;}
kenjiArai 1:102230f2879d 70 * new_frequency = fc.read_freq_data();
kenjiArai 4:9d3b3f0a3882 71 * printf("1PPS/ave = %9d , FREQUENCY = %11.3f\r\n", counter_1pps, new_frequency);
kenjiArai 1:102230f2879d 72 * }
kenjiArai 1:102230f2879d 73 * }
kenjiArai 1:102230f2879d 74 * @endcode
kenjiArai 1:102230f2879d 75 */
kenjiArai 1:102230f2879d 76
kenjiArai 1:102230f2879d 77 class FRQ_CUNTR
kenjiArai 1:102230f2879d 78 {
kenjiArai 1:102230f2879d 79 public:
kenjiArai 2:194f82ad3041 80
kenjiArai 1:102230f2879d 81 /** Configure data pin (Not changeable)
kenjiArai 2:194f82ad3041 82 * @param Freq. input pin + Gate time[sec] + External clock[MHz]
kenjiArai 1:102230f2879d 83 */
kenjiArai 2:194f82ad3041 84 FRQ_CUNTR(PinName f_in, double gt, double ex_clock);
kenjiArai 1:102230f2879d 85
kenjiArai 1:102230f2879d 86 /** Set gate time
kenjiArai 1:102230f2879d 87 * @param gate time [sec]
kenjiArai 2:194f82ad3041 88 * @return gate time (range 50mS to 1 minute)
kenjiArai 1:102230f2879d 89 */
kenjiArai 1:102230f2879d 90 double set_gate_time(double gt);
kenjiArai 1:102230f2879d 91
kenjiArai 4:9d3b3f0a3882 92 /** Set external clock frequency
kenjiArai 4:9d3b3f0a3882 93 * @param frequency e.g. 25.000000 [MHz]
kenjiArai 4:9d3b3f0a3882 94 * @return none
kenjiArai 4:9d3b3f0a3882 95 */
kenjiArai 4:9d3b3f0a3882 96 void set_external_clock(double ex_clock);
kenjiArai 4:9d3b3f0a3882 97
kenjiArai 2:194f82ad3041 98 /** Read gate time
kenjiArai 2:194f82ad3041 99 * @param none
kenjiArai 2:194f82ad3041 100 * @return gate time (range 50mS to 1 minute)
kenjiArai 2:194f82ad3041 101 */
kenjiArai 2:194f82ad3041 102 double read_gate_time(void);
kenjiArai 2:194f82ad3041 103
kenjiArai 1:102230f2879d 104 /** Read status (new frequency data is available or not)
kenjiArai 1:102230f2879d 105 * @param none
kenjiArai 1:102230f2879d 106 * @return !=0: new data is avairable, 0: not yet
kenjiArai 1:102230f2879d 107 */
kenjiArai 1:102230f2879d 108 uint32_t status_freq_update(void);
kenjiArai 1:102230f2879d 109
kenjiArai 1:102230f2879d 110 /** Read new frequency data
kenjiArai 1:102230f2879d 111 * @param none
kenjiArai 1:102230f2879d 112 * @return frequency data
kenjiArai 1:102230f2879d 113 */
kenjiArai 2:194f82ad3041 114 double read_freq_data(void);
kenjiArai 0:bfdc6ed58a06 115
kenjiArai 1:102230f2879d 116 /** Read avarage measued data GPS 1PPS
kenjiArai 1:102230f2879d 117 * @param none
kenjiArai 1:102230f2879d 118 * @return Frequency
kenjiArai 1:102230f2879d 119 */
kenjiArai 1:102230f2879d 120 uint32_t read_avarage_1pps(void);
kenjiArai 1:102230f2879d 121
kenjiArai 4:9d3b3f0a3882 122 /** Read newest measued data GPS 1PPS
kenjiArai 4:9d3b3f0a3882 123 * @param none
kenjiArai 4:9d3b3f0a3882 124 * @return Frequency
kenjiArai 4:9d3b3f0a3882 125 */
kenjiArai 4:9d3b3f0a3882 126 uint32_t read_newest_1pps(void);
kenjiArai 4:9d3b3f0a3882 127
kenjiArai 1:102230f2879d 128 /** Read status (new 1PPS data is available or not)
kenjiArai 1:102230f2879d 129 * @param none
kenjiArai 1:102230f2879d 130 * @return !=0: new data is avairable, 0: not yet
kenjiArai 1:102230f2879d 131 */
kenjiArai 1:102230f2879d 132 uint32_t status_1pps(void);
kenjiArai 1:102230f2879d 133
kenjiArai 2:194f82ad3041 134 /** Read GPS status
kenjiArai 2:194f82ad3041 135 * @param none
kenjiArai 2:194f82ad3041 136 * @return 1: GPS is ready
kenjiArai 2:194f82ad3041 137 */
kenjiArai 3:339307e1dc0d 138 uint8_t status_gps(void);
kenjiArai 2:194f82ad3041 139
kenjiArai 2:194f82ad3041 140 /** This is a "TEST PURPOSE" function
kenjiArai 1:102230f2879d 141 * Check PA0 pin input or internal clock frequency
kenjiArai 1:102230f2879d 142 * @param none
kenjiArai 1:102230f2879d 143 * @return Frequency
kenjiArai 1:102230f2879d 144 */
kenjiArai 1:102230f2879d 145 uint32_t read_frequency_TIM2(float gate_time);
kenjiArai 1:102230f2879d 146
kenjiArai 2:194f82ad3041 147 /** This is a "TEST PURPOSE" function
kenjiArai 1:102230f2879d 148 * Check PC6 pin input frequency
kenjiArai 1:102230f2879d 149 * @param none
kenjiArai 1:102230f2879d 150 * @return Frequency
kenjiArai 1:102230f2879d 151 */
kenjiArai 1:102230f2879d 152 uint32_t read_frequency_TIM3P4(float gate_time);
kenjiArai 1:102230f2879d 153
kenjiArai 2:194f82ad3041 154 /** This is a "TEST PURPOSE" function
kenjiArai 1:102230f2879d 155 * Output clock from pin PA8 & PC9 uses for MCO_1 & MCO_2
kenjiArai 1:102230f2879d 156 * @param none
kenjiArai 1:102230f2879d 157 * @return none
kenjiArai 1:102230f2879d 158 */
kenjiArai 1:102230f2879d 159 void port_mco1_mco2_set(uint8_t select);
kenjiArai 1:102230f2879d 160
kenjiArai 2:194f82ad3041 161 /** This is a "DEBUG PURPOSE" function
kenjiArai 2:194f82ad3041 162 * print internal data (need to define "DEBUG"
kenjiArai 2:194f82ad3041 163 * @param none
kenjiArai 2:194f82ad3041 164 * @return none
kenjiArai 2:194f82ad3041 165 */
kenjiArai 2:194f82ad3041 166 void debug_printf_internal_data(void);
kenjiArai 2:194f82ad3041 167
kenjiArai 1:102230f2879d 168 protected:
kenjiArai 1:102230f2879d 169 DigitalIn _pin;
kenjiArai 1:102230f2879d 170
kenjiArai 1:102230f2879d 171 void initialize_Freq_counter(void); // Initialize timers
kenjiArai 2:194f82ad3041 172 // Internal clock (100MHz) or External clock(?MHz) and IC2 for GPS 1pps signal measurement
kenjiArai 1:102230f2879d 173 void initialize_TIM2(void);
kenjiArai 1:102230f2879d 174 // Initialize TIM3 and TIM4 as 32bit counter (TIM3(16bit) + TIM4(16bit))
kenjiArai 1:102230f2879d 175 void initialize_TIM3P4(void);
kenjiArai 1:102230f2879d 176 uint32_t set_1PPS_data(void); // Set GPS 1PPS counter value
kenjiArai 1:102230f2879d 177 uint32_t read_ic2_counter_TIM2(void); // Read TIM2 captured counter value
kenjiArai 1:102230f2879d 178 uint32_t check_ic2_status_TIM2(void); // Check TIM2 IC2 status
kenjiArai 1:102230f2879d 179 uint32_t read_ic2_counter_TIM3P4(void); // Read TIM3+4(as 32bit) captured counter value
kenjiArai 1:102230f2879d 180 uint32_t check_ic2_status_TIM3P4(void); // Check TIM3 IC2 & TIM4 IC1 status
kenjiArai 1:102230f2879d 181 uint8_t read_oc_port_status(void); // Check TIM2 OC port
kenjiArai 1:102230f2879d 182
kenjiArai 1:102230f2879d 183 private:
kenjiArai 2:194f82ad3041 184 double newest_frequency;
kenjiArai 2:194f82ad3041 185 double gate_time;
kenjiArai 2:194f82ad3041 186 double ex_clock_freq;
kenjiArai 2:194f82ad3041 187 uint32_t ex_clk_base;
kenjiArai 2:194f82ad3041 188 uint32_t clk_hi_const;
kenjiArai 2:194f82ad3041 189 uint32_t clk_upper_limit;
kenjiArai 2:194f82ad3041 190 uint32_t clk_lower_limit;
kenjiArai 3:339307e1dc0d 191 uint8_t gps_ready;
kenjiArai 1:102230f2879d 192 // TIM2
kenjiArai 1:102230f2879d 193 uint32_t counter_tim2;
kenjiArai 1:102230f2879d 194 uint32_t old_cntr_tim2;
kenjiArai 1:102230f2879d 195 // TIM3+4
kenjiArai 1:102230f2879d 196 uint32_t counter_tim3p4;
kenjiArai 1:102230f2879d 197 uint32_t old_cntr_tim3p4;
kenjiArai 1:102230f2879d 198 // 1PPS data
kenjiArai 1:102230f2879d 199 uint32_t onepps_newest;
kenjiArai 1:102230f2879d 200 uint32_t onepps_cnt[CNT_BF_SIZE];
kenjiArai 1:102230f2879d 201 uint32_t onepps_num;
kenjiArai 1:102230f2879d 202 uint64_t onepps_cnt_avarage;
kenjiArai 1:102230f2879d 203 uint8_t onepps_buf_full;
kenjiArai 1:102230f2879d 204 uint8_t onepps_ready_flg;
kenjiArai 2:194f82ad3041 205
kenjiArai 1:102230f2879d 206 };
kenjiArai 1:102230f2879d 207
kenjiArai 1:102230f2879d 208 /*
kenjiArai 1:102230f2879d 209 Interrupt handler does NOT work following code
kenjiArai 1:102230f2879d 210 NVIC_SetVector(TIM2_IRQn, (uint32_t)FRQ_CUNTR::irq_ic2_TIM2);
kenjiArai 1:102230f2879d 211 From this reason, I wrote below code and set interrupt handler out side "FRQ_CUNTR" class
kenjiArai 1:102230f2879d 212 NVIC_SetVector(TIM2_IRQn, (uint32_t)irq_ic2_TIM2);
kenjiArai 1:102230f2879d 213 */
kenjiArai 1:102230f2879d 214 void irq_ic2_TIM2(void); // TIM2 IC2 Interrupt control
kenjiArai 1:102230f2879d 215 void irq_ic2_TIM3P4(void); // TIM3 IC2 Interrupt control (same signal connected to TIM4 IC1)
kenjiArai 1:102230f2879d 216
kenjiArai 0:bfdc6ed58a06 217 } // Frequency_counter
kenjiArai 0:bfdc6ed58a06 218
kenjiArai 1:102230f2879d 219 #endif // MBED_FRQ_CUNTR