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

Figure 12-17. Frequency Measurement Function – CPU

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);