Frequency counter library only for NucleoF411RE

Dependents:   Frequency_Counter_w_GPS_1PPS

Committer:
kenjiArai
Date:
Sat Nov 22 23:02:39 2014 +0000
Revision:
1:102230f2879d
Parent:
0:bfdc6ed58a06
Child:
2:194f82ad3041
Created library interface functions. Hardware related parts are almost done.

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 1:102230f2879d 11 * Revised: Nobember 23rd, 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 1:102230f2879d 25 #define DEBUG // use Communication with PC(UART)
kenjiArai 1:102230f2879d 26 /*
kenjiArai 1:102230f2879d 27 CAUTION:
kenjiArai 1:102230f2879d 28 If you select internal clock (100MHz), you need consider PLL clock behavior.
kenjiArai 1:102230f2879d 29 PLL clock drifts over 60Hz (increase frequency) within 30 to 40 second
kenjiArai 1:102230f2879d 30 then suddenly back to low frequency and increase again.
kenjiArai 1:102230f2879d 31 Even you prepare precision external clock, this frequency drift cannot avoid.
kenjiArai 1:102230f2879d 32 */
kenjiArai 1:102230f2879d 33 #define BASE_EXTERNAL_CLOCK
kenjiArai 1:102230f2879d 34
kenjiArai 0:bfdc6ed58a06 35 namespace Frequency_counter
kenjiArai 0:bfdc6ed58a06 36 {
kenjiArai 1:102230f2879d 37 #define CNT_BASE 29999978 // 30MHz
kenjiArai 1:102230f2879d 38 #define CNT_FIX_BASE 600000 // 0.03sec
kenjiArai 1:102230f2879d 39
kenjiArai 1:102230f2879d 40 #if defined(BASE_EXTERNAL_CLOCK)
kenjiArai 1:102230f2879d 41 #define CNT_UPPER (CNT_BASE + 20)
kenjiArai 1:102230f2879d 42 #define CNT_LOWER (CNT_BASE - 20)
kenjiArai 1:102230f2879d 43 #else
kenjiArai 1:102230f2879d 44 #define CNT_UPPER (0xffffffff - 100)
kenjiArai 1:102230f2879d 45 #define CNT_LOWER (0 + 100)
kenjiArai 1:102230f2879d 46 #endif
kenjiArai 1:102230f2879d 47
kenjiArai 1:102230f2879d 48 #if defined(BASE_EXTERNAL_CLOCK)
kenjiArai 1:102230f2879d 49 #define ONE_SECOND_COUNT (CNT_BASE - CNT_FIX_BASE)
kenjiArai 1:102230f2879d 50 #else
kenjiArai 1:102230f2879d 51 #define ONE_SECOND_COUNT 0x2faf080 // 50MHz
kenjiArai 1:102230f2879d 52 #endif
kenjiArai 1:102230f2879d 53
kenjiArai 1:102230f2879d 54 #define CNT_BF_SIZE 120 // 1PPS data save size
kenjiArai 1:102230f2879d 55
kenjiArai 1:102230f2879d 56 /** Frequency Counter program
kenjiArai 1:102230f2879d 57 * Only for ST Nucleo F411RE Board
kenjiArai 1:102230f2879d 58 *
kenjiArai 1:102230f2879d 59 * @code
kenjiArai 1:102230f2879d 60 * #include "mbed.h"
kenjiArai 1:102230f2879d 61 *
kenjiArai 1:102230f2879d 62 * // PC_6,PC_7 & PB6 use for Timer3 & 4(16+16bit)
kenjiArai 1:102230f2879d 63 * // PA_0,PA_1 & PB10 use for Timer2(32bit)
kenjiArai 1:102230f2879d 64 * FRQ_CUNTR fc(PC_6, 1.0); // Input port(Fixed) & gate time[sec]
kenjiArai 1:102230f2879d 65 *
kenjiArai 1:102230f2879d 66 * int main() {
kenjiArai 1:102230f2879d 67 * // This is for test purpose
kenjiArai 1:102230f2879d 68 * fc.port_mco1_mco2_set(2); // Clk/2 ->1/1(100MHz) cannot measure!!
kenjiArai 1:102230f2879d 69 * fc.read_frequency_TIM2(1.0); // read TIM2 source frequency (test)
kenjiArai 1:102230f2879d 70 * fc.read_frequency_TIM3P4(1.0); // read TIM3 source frequency (test)
kenjiArai 1:102230f2879d 71 * while(true) {
kenjiArai 1:102230f2879d 72 * while (fc.status_1pps() == 0) {;}
kenjiArai 1:102230f2879d 73 * counter_1pps = fc.read_avarage_1pps();
kenjiArai 1:102230f2879d 74 * while (fc.status_freq_update() == 0) {;}
kenjiArai 1:102230f2879d 75 * new_frequency = fc.read_freq_data();
kenjiArai 1:102230f2879d 76 * print("1PPS/ave = %9d , FREQUENCY = %9d\r\n", counter_1pps, new_frequency);
kenjiArai 1:102230f2879d 77 * }
kenjiArai 1:102230f2879d 78 * }
kenjiArai 1:102230f2879d 79 * @endcode
kenjiArai 1:102230f2879d 80 */
kenjiArai 1:102230f2879d 81
kenjiArai 1:102230f2879d 82 class FRQ_CUNTR
kenjiArai 1:102230f2879d 83 {
kenjiArai 1:102230f2879d 84 public:
kenjiArai 1:102230f2879d 85 /** Configure data pin (Not changeable)
kenjiArai 1:102230f2879d 86 * @param Freq. input pin
kenjiArai 1:102230f2879d 87 */
kenjiArai 1:102230f2879d 88 FRQ_CUNTR(PinName f_in, double gt);
kenjiArai 1:102230f2879d 89
kenjiArai 1:102230f2879d 90 /** Set gate time
kenjiArai 1:102230f2879d 91 * @param gate time [sec]
kenjiArai 1:102230f2879d 92 * @return !=0: new data is avairable, 0: not yet
kenjiArai 1:102230f2879d 93 */
kenjiArai 1:102230f2879d 94 double set_gate_time(double gt);
kenjiArai 1:102230f2879d 95
kenjiArai 1:102230f2879d 96 /** Read status (new frequency data is available or not)
kenjiArai 1:102230f2879d 97 * @param none
kenjiArai 1:102230f2879d 98 * @return !=0: new data is avairable, 0: not yet
kenjiArai 1:102230f2879d 99 */
kenjiArai 1:102230f2879d 100 uint32_t status_freq_update(void);
kenjiArai 1:102230f2879d 101
kenjiArai 1:102230f2879d 102 /** Read new frequency data
kenjiArai 1:102230f2879d 103 * @param none
kenjiArai 1:102230f2879d 104 * @return frequency data
kenjiArai 1:102230f2879d 105 */
kenjiArai 1:102230f2879d 106 uint32_t read_freq_data(void);
kenjiArai 0:bfdc6ed58a06 107
kenjiArai 1:102230f2879d 108 /** Read avarage measued data GPS 1PPS
kenjiArai 1:102230f2879d 109 * @param none
kenjiArai 1:102230f2879d 110 * @return Frequency
kenjiArai 1:102230f2879d 111 */
kenjiArai 1:102230f2879d 112 uint32_t read_avarage_1pps(void);
kenjiArai 1:102230f2879d 113
kenjiArai 1:102230f2879d 114 /** Read status (new 1PPS data is available or not)
kenjiArai 1:102230f2879d 115 * @param none
kenjiArai 1:102230f2879d 116 * @return !=0: new data is avairable, 0: not yet
kenjiArai 1:102230f2879d 117 */
kenjiArai 1:102230f2879d 118 uint32_t status_1pps(void);
kenjiArai 1:102230f2879d 119
kenjiArai 1:102230f2879d 120 /** This is a test purpose function
kenjiArai 1:102230f2879d 121 * Check PA0 pin input or internal clock frequency
kenjiArai 1:102230f2879d 122 * @param none
kenjiArai 1:102230f2879d 123 * @return Frequency
kenjiArai 1:102230f2879d 124 */
kenjiArai 1:102230f2879d 125 uint32_t read_frequency_TIM2(float gate_time);
kenjiArai 1:102230f2879d 126
kenjiArai 1:102230f2879d 127 /** This is a test purpose function
kenjiArai 1:102230f2879d 128 * Check PC6 pin input frequency
kenjiArai 1:102230f2879d 129 * @param none
kenjiArai 1:102230f2879d 130 * @return Frequency
kenjiArai 1:102230f2879d 131 */
kenjiArai 1:102230f2879d 132 uint32_t read_frequency_TIM3P4(float gate_time);
kenjiArai 1:102230f2879d 133
kenjiArai 1:102230f2879d 134 /** This is a test purpose function
kenjiArai 1:102230f2879d 135 * Output clock from pin PA8 & PC9 uses for MCO_1 & MCO_2
kenjiArai 1:102230f2879d 136 * @param none
kenjiArai 1:102230f2879d 137 * @return none
kenjiArai 1:102230f2879d 138 */
kenjiArai 1:102230f2879d 139 void port_mco1_mco2_set(uint8_t select);
kenjiArai 1:102230f2879d 140
kenjiArai 1:102230f2879d 141 protected:
kenjiArai 1:102230f2879d 142 DigitalIn _pin;
kenjiArai 1:102230f2879d 143
kenjiArai 1:102230f2879d 144 void initialize_Freq_counter(void); // Initialize timers
kenjiArai 1:102230f2879d 145 // Internal clock (50MHz) and IC2 for GPS 1pps signal measurement
kenjiArai 1:102230f2879d 146 void initialize_TIM2(void);
kenjiArai 1:102230f2879d 147 // Initialize TIM3 and TIM4 as 32bit counter (TIM3(16bit) + TIM4(16bit))
kenjiArai 1:102230f2879d 148 void initialize_TIM3P4(void);
kenjiArai 1:102230f2879d 149 uint32_t set_1PPS_data(void); // Set GPS 1PPS counter value
kenjiArai 1:102230f2879d 150 uint32_t read_ic2_counter_TIM2(void); // Read TIM2 captured counter value
kenjiArai 1:102230f2879d 151 uint32_t check_ic2_status_TIM2(void); // Check TIM2 IC2 status
kenjiArai 1:102230f2879d 152 uint32_t read_ic2_counter_TIM3P4(void); // Read TIM3+4(as 32bit) captured counter value
kenjiArai 1:102230f2879d 153 uint32_t check_ic2_status_TIM3P4(void); // Check TIM3 IC2 & TIM4 IC1 status
kenjiArai 1:102230f2879d 154 uint8_t read_oc_port_status(void); // Check TIM2 OC port
kenjiArai 1:102230f2879d 155
kenjiArai 1:102230f2879d 156 private:
kenjiArai 1:102230f2879d 157 // TIM2
kenjiArai 1:102230f2879d 158 double gate_time;
kenjiArai 1:102230f2879d 159 uint32_t counter_tim2;
kenjiArai 1:102230f2879d 160 uint32_t old_cntr_tim2;
kenjiArai 1:102230f2879d 161 // TIM3+4
kenjiArai 1:102230f2879d 162 uint32_t counter_tim3p4;
kenjiArai 1:102230f2879d 163 uint32_t old_cntr_tim3p4;
kenjiArai 1:102230f2879d 164 // 1PPS data
kenjiArai 1:102230f2879d 165 uint32_t onepps_newest;
kenjiArai 1:102230f2879d 166 uint32_t onepps_cnt[CNT_BF_SIZE];
kenjiArai 1:102230f2879d 167 uint32_t onepps_num;
kenjiArai 1:102230f2879d 168 uint64_t onepps_cnt_avarage;
kenjiArai 1:102230f2879d 169 uint8_t onepps_buf_full;
kenjiArai 1:102230f2879d 170 uint8_t onepps_ready_flg;
kenjiArai 1:102230f2879d 171 };
kenjiArai 1:102230f2879d 172
kenjiArai 1:102230f2879d 173 /*
kenjiArai 1:102230f2879d 174 Interrupt handler does NOT work following code
kenjiArai 1:102230f2879d 175 NVIC_SetVector(TIM2_IRQn, (uint32_t)FRQ_CUNTR::irq_ic2_TIM2);
kenjiArai 1:102230f2879d 176 From this reason, I wrote below code and set interrupt handler out side "FRQ_CUNTR" class
kenjiArai 1:102230f2879d 177 NVIC_SetVector(TIM2_IRQn, (uint32_t)irq_ic2_TIM2);
kenjiArai 1:102230f2879d 178 */
kenjiArai 1:102230f2879d 179 void irq_ic2_TIM2(void); // TIM2 IC2 Interrupt control
kenjiArai 1:102230f2879d 180 void irq_ic2_TIM3P4(void); // TIM3 IC2 Interrupt control (same signal connected to TIM4 IC1)
kenjiArai 1:102230f2879d 181
kenjiArai 0:bfdc6ed58a06 182 } // Frequency_counter
kenjiArai 0:bfdc6ed58a06 183
kenjiArai 1:102230f2879d 184 #endif // MBED_FRQ_CUNTR