Hi,
I tried following the example here Using the CMU on the MPC5744 for IRCOSC Measurement and reading Application Note AN12080.
I seem to be getting different readings for each different Measurement Duration.
//---------------------------------------------------
F_CLKMN0_RMT (FXOSC) = 40 MHz
CMU.MDR.B.MD: 0x000FFFFF 1048575
CLKMT0_RMN (FIRC) (IRCOSC)
fd: 0x81BD6 531414
f_sel: 78927168.000000
CLKMT1 (SIRC)
fd: 0xFB2FA 1028858
f_sel: 40766560.000000
CLKMT2 (SXOSC)
fd: 0x7DA59 514649
f_sel: 81498264.000000
//---------------------------------------------------
F_CLKMN0_RMT (FXOSC) = 40 MHz
CMU.MDR.B.MD: 0x0001FFFF 131071
CLKMT0_RMN (FIRC) (IRCOSC)
fd: 0x5039F 328607
f_sel: 15954742.000000
CLKMT1 (SIRC)
fd: 0xA9831 694321
f_sel: 7551031.500000
CLKMT2 (SXOSC)
fd: 0x8F701 587521
f_sel: 8923664.000000
//---------------------------------------------------
F_CLKMN0_RMT (FXOSC) = 40 MHz
CMU.MDR.B.MD: 0x0000FFFF 65535
CLKMT0_RMN (FIRC) (IRCOSC)
fd: 0x281E4 164324
f_sel: 15952630.000000
CLKMT1 (SIRC)
fd: 0x4F55C 324956
f_sel: 8066938.500000
CLKMT2 (SXOSC)
fd: 0x4792A 293162
f_sel: 8941814.000000
void CMU_test(void)
{
float f_sel, diff;
unsigned long MD = 0xFFFF; //(0..1048575)
//---------------------------------------------------------------------------
// CLKMT0_RMN
//---------------------------------------------------------------------------
//1. Program the CMU_MDR[MD] (Measure Duration) value.
// (20 bits = 2^20 - 1 = 1048576 - 1 = 1048575)
CMU.MDR.B.MD = MD;
//2. Program the CMU_CSR[CKSEL1] bit to the CLKMT0_RMN you wish to measure.
CMU.CSR.B.CKSEL1 = CLKMT0_RMN;
//3. Enable the monitor by setting the CMU_CSR[SFM] bit.
CMU.CSR.B.SFM = 1;
//4. When the CMU_CSR[SMF] bit is clear read the CMD_FDR[FD] value and calculate the IRCOSC frequency.
while(CMU.CSR.B.SFM){}
f_sel = (float)F_CLKMN0_RMT * ((float)CMU.MDR.B.MD / (float)CMU.FDR.B.FD);
//---------------------------------------------------------------------------
// CLKMT1
//---------------------------------------------------------------------------
//1. Program the CMU_MDR[MD] value.
// (20 bits = 2^20 - 1 = 1048576 - 1 = 1048575)
CMU.MDR.B.MD = MD;
//2. Program the CMU_CSR[CKSEL1] bit to the CLKMT0_RMN you wish to measure.
CMU.CSR.B.CKSEL1 = CLKMT1;
//3. Enable the monitor by setting the CMU_CSR[SFM] bit.
CMU.CSR.B.SFM = 1;
//4. When the CMU_CSR[SMF] bit is clear read the CMD_FDR[FD] value and calculate the IRCOSC frequency.
while(CMU.CSR.B.SFM){}
f_sel = (float)F_CLKMN0_RMT * ((float)CMU.MDR.B.MD / (float)CMU.FDR.B.FD);
//---------------------------------------------------------------------------
// CLKMT2
//---------------------------------------------------------------------------
//1. Program the CMU_MDR[MD] value.
// (20 bits = 2^20 - 1 = 1048576 - 1 = 1048575)
CMU.MDR.B.MD = MD;
//2. Program the CMU_CSR[CKSEL1] bit to the CLKMT0_RMN you wish to measure.
CMU.CSR.B.CKSEL1 = CLKMT2;
//3. Enable the monitor by setting the CMU_CSR[SFM] bit.
CMU.CSR.B.SFM = 1;
//4. When the CMU_CSR[SMF] bit is clear read the CMD_FDR[FD] value and calculate the IRCOSC frequency.
while(CMU.CSR.B.SFM){}
f_sel = (float)F_CLKMN0_RMT * ((float)CMU.MDR.B.MD / (float)CMU.FDR.B.FD);
}
Thanks,
Hi,
you should use proper MD value to ensure the FD does not overflow as there is no internal status of the FD overflow.
Thus the theoretical max MD value for each measured clock can be (assuming 40MHz reference clock)
- FIRC: maxMD = 16MHz/40MHz*1048575 = 419430
- SIRC: maxMD = 128KHz/40MHz*1048575 = 3355
- SXOSC: maxMD = 32KHz/40MHz*1048575 = 834
Use even smaller value to have some boundary if clock is not accurate.
BR, Petr