12.4.7.3.1 Software Assisted Frequency Measurement
By allowing the CPU access to the accumulated results, firmware can convert the measured counts into frequencies based on existing knowledge of the reference clock frequency or period. The captured count’s corresponding register, CMxBUF, is therefore memory mapped in this peripheral. Figure 12-17 shows the basic block diagram of this mode of operation.
Clocking Configurations
Reference Clock ≥ Time Window Generator
Monitored Clock ≥ Counter
If Reference clock is Clock generator 6 FRC 8 MHz Monitor Clock is Clock generator 5 EC 8 MHz Accumulation Time = 0x8000 cycles of reference clock. Monitor clock is divided by 2, its 4MHz Time window = 0x8000/8M = 4ms
So, for 4ms with 4MHz clock speed what is the expected accumulation.
0.004096 * 4M = 0x4000
The CMxBUF is expected to hold 0x4000 value on every time window interval.
If Reference clock is Clock generator 6
FRC 8MHz
Monitor Clock is Clock generator 5
EC 8MHz
Accumulation Time = 0x8000 cycles of reference clock
Monitor clock is divided by 2, its 4MHz
Time window = 0x8000/8M = 4ms
So, for 4ms with 4MHz clock speed what is the expected accumulation.
0.004096 * 4M = 0x4000
The CMxBUF is expected to hold 0x4000 value on every time window interval.
Frequency Measurement Function
//Configure clock generators before enabling monitoring
IFS0bits.C2FAILIF = 0; // enable clock Monitor2 failure interrupt
IEC0bits.C2FAILIE = 1;
IFS0bits.C2MONIF = 0; // enable clock saturation failure interrupt
IEC0bits.C2MONIE = 1;
IFS0bits.C2WARMIF = 0; // enable clock Warning failure interrupt
IEC0bits.C2WARMIE = 1;
IFS0bits.C2RDYIF = 0; // enable clock ready failure interrupt
IEC0bits.C2RDYIE = 1;
CM2CONbits.ON = 0; // disable clock monitor
//Select monitor clock source
CM2SELbits.CNTSEL = 4; //Monitoring clock clock-gen-5
//[0] = clkgen_clk[1] = System clocks
//[1] = clkgen_clk[2]
//...
//[10] = clkgen_clk[11]
//[11] = pll_fout_clk[1]
//[12] = pll_vcodiv_clk[1]
//[13] = pll_fout_clk[2]
//[14] = pll_vcodiv_clk[2]
//[15] = 1?b0 (reserved)
//[16] = Serial Test Mode clock (PGC)
//[17] = FRC - Internal 8 MHz RC oscillator
//[18] = BFRC - Internal Backup 8 MHz RC oscillator
//[19] = POSC - Primary crystal oscillator (4-32 MHz)
//[25] = REFI1 - user definable clock source
//[26] = REFI2 - user definable clock source
//Select reference clock source
CM2SELbits.WINSEL = 5; //reference clock clock-gen-6
//[0] = clkgen_clk[1] = System clocks
//[1] = clkgen_clk[2]
//...
//[10] = clkgen_clk[11]
//[11] = pll_fout_clk[1]
//[12] = pll_vcodiv_clk[1]
//[13] = pll_fout_clk[2]
//[14] = pll_vcodiv_clk[2]
//[15] = 1?b0 (reserved)
//[16] = Serial Test Mode clock (PGC)
//[17] = FRC - Internal 8 MHz RC oscillator
//[18] = BFRC - Internal Backup 8 MHz RC oscillator
//[19] = POSC - Primary crystal oscillator (4-32 MHz)
//[25] = REFI1 - user definable clock source
//[26] = REFI2 - user definable clock source
//Counter Divider Selection
CM2CONbits.CNTDIV = 1;
// 10 = Divide-by 4
// 01 = Divide-by 2
// 00 = Divide-by 1
CM2WINPR = 0x8000; //monitor clock pre scale
//Accumulation Time (in cycles) = WINPR[31:0] + 1
CM2HFAIL = 0x4500; //CLOCK MONITOR HIGH THRESHOLD FAILING
CM2LFAIL = 0x3500; //CLOCK MONITOR LOW THRESHOLD FAILING
CM2HWARN = 0x4100; //CLOCK MONITOR HIGH THRESHOLD WARNING
CM2LWARN = 0x3600; //CLOCK MONITOR LOW THRESHOLD WARNING
CM2SAT = 0x5000; //CLOCK MONITOR COUNTER SATURATION
CM2CONbits.WIDTH = 0; // 0 - Frequency Measurement
// 1 - Pulse Width and Duty Cycle Measurement
CM2CONbits.ON = 1; //enable clock monitor
while (CM2CONbits.ON);