LPC1768 RTC frequency check with WDT. Compare RTC against MCU's microsecond Timer.

Dependencies:   mbed

Check LPC1768 RTC crystal frequency using WDT. Measure with MCU's microsecond Timer. The MCU's crystal may be off a bit as well. I measured the RTC frequency error at 22 ppm. The spec for the RTC crystal is 20 ppm. Using NTP and a GPS, I had measured the MCU's crystal frequency error at -2 ppm.

Frequency measurements for other MCU/RTC cyrstals at

https://github.com/manitou48/crystals/blob/master/crystals.txt

Committer:
manitou
Date:
Mon Nov 16 16:56:32 2015 +0000
Revision:
0:11cc29f22037
LPC1768 RTC freq check with WDT

Who changed what in which revision?

UserRevisionLine numberNew contents of line
manitou 0:11cc29f22037 1 // use WDT to measure drift of RTC and IRC
manitou 0:11cc29f22037 2 // seems WDT ISR will only fire once
manitou 0:11cc29f22037 3 #include "mbed.h"
manitou 0:11cc29f22037 4
manitou 0:11cc29f22037 5 DigitalOut led1(LED1);
manitou 0:11cc29f22037 6 uint32_t ticks;
manitou 0:11cc29f22037 7
manitou 0:11cc29f22037 8 void kick() {
manitou 0:11cc29f22037 9 __disable_irq();
manitou 0:11cc29f22037 10 LPC_WDT->WDFEED = 0xAA;
manitou 0:11cc29f22037 11 LPC_WDT->WDFEED = 0x55;
manitou 0:11cc29f22037 12 __enable_irq();
manitou 0:11cc29f22037 13 }
manitou 0:11cc29f22037 14
manitou 0:11cc29f22037 15 void isr_wdt(void) {
manitou 0:11cc29f22037 16 ticks++;
manitou 0:11cc29f22037 17 led1 = 1;
manitou 0:11cc29f22037 18 LPC_WDT->WDMOD |= (1<<3);
manitou 0:11cc29f22037 19 // LPC_WDT->WDMOD &= ~(1<<2);
manitou 0:11cc29f22037 20 // kick();
manitou 0:11cc29f22037 21 }
manitou 0:11cc29f22037 22
manitou 0:11cc29f22037 23 void wdt_init() {
manitou 0:11cc29f22037 24 LPC_WDT->WDCLKSEL = 0x2; // Set CLK src 0 IRC 1 PCLK 2 RTC
manitou 0:11cc29f22037 25 // uint32_t clk = SystemCoreClock / 16; // WD has a fixed /4 prescaler, PCLK default is /4
manitou 0:11cc29f22037 26 LPC_WDT->WDTC = 0xfffffff; // max countdown
manitou 0:11cc29f22037 27 LPC_WDT->WDMOD = 0x01; // enable but no reset
manitou 0:11cc29f22037 28 NVIC_SetVector(WDT_IRQn, (uint32_t)&isr_wdt);
manitou 0:11cc29f22037 29 NVIC_ClearPendingIRQ(WDT_IRQn);
manitou 0:11cc29f22037 30 NVIC_EnableIRQ(WDT_IRQn);
manitou 0:11cc29f22037 31 kick();
manitou 0:11cc29f22037 32 }
manitou 0:11cc29f22037 33
manitou 0:11cc29f22037 34 int main() {
manitou 0:11cc29f22037 35 uint32_t t,t0=0,us,us0,prev;
manitou 0:11cc29f22037 36 int ppm;
manitou 0:11cc29f22037 37 Timer tmr;
manitou 0:11cc29f22037 38 tmr.start();
manitou 0:11cc29f22037 39 printf("hello %x\n",LPC_WDT->WDMOD);
manitou 0:11cc29f22037 40 wait(1.0);
manitou 0:11cc29f22037 41 wdt_init();
manitou 0:11cc29f22037 42 prev=LPC_WDT->WDTV;
manitou 0:11cc29f22037 43 while(1) {
manitou 0:11cc29f22037 44 t=LPC_WDT->WDTV;
manitou 0:11cc29f22037 45 us = tmr.read_us();
manitou 0:11cc29f22037 46 if (t0==0 || t0 == 255) {
manitou 0:11cc29f22037 47 t0 = t;
manitou 0:11cc29f22037 48 us0 = us;
manitou 0:11cc29f22037 49 }
manitou 0:11cc29f22037 50 double tf = (t0-t)/8192.; // /8192 for rtc 1000000 for IRC
manitou 0:11cc29f22037 51 double secs = 1.e-6*(us-us0);
manitou 0:11cc29f22037 52 ppm = 1.e6*(tf-secs)/secs;
manitou 0:11cc29f22037 53 printf("ticks %d %d %u %d us %x %d ppm \n",ticks,prev-t,t0-t,us-us0,t,ppm);
manitou 0:11cc29f22037 54 prev=t;
manitou 0:11cc29f22037 55 wait(2.0);
manitou 0:11cc29f22037 56 }
manitou 0:11cc29f22037 57 }