altos/cc1111: Wait for xtal to be stable
authorKeith Packard <keithp@keithp.com>
Wed, 14 May 2014 00:30:47 +0000 (17:30 -0700)
committerKeith Packard <keithp@keithp.com>
Wed, 14 May 2014 00:30:47 +0000 (17:30 -0700)
Errata http://www.ti.com/lit/er/swrz022c/swrz022c.pdf says that the
xtal is stable bit is bogus and that you need to just delay for a while.

Signed-off-by: Keith Packard <keithp@keithp.com>
src/cc1111/ao_timer.c

index 75cc4ce8b562e6f339d76451a103b9e3bdd73fc0..d681f51bb6689e224bbf2aa259f230a4fd182801 100644 (file)
@@ -83,25 +83,48 @@ ao_timer_init(void)
        T1CTL = T1CTL_MODE_MODULO | T1CTL_DIV_8;
 }
 
        T1CTL = T1CTL_MODE_MODULO | T1CTL_DIV_8;
 }
 
+static void
+ao_clock_delay(void)
+{
+       uint16_t        i = 0;
+
+       while (--i)
+               ao_arch_nop();
+}
+
 /*
  * AltOS always cranks the clock to the max frequency
  */
 void
 ao_clock_init(void)
 {
 /*
  * AltOS always cranks the clock to the max frequency
  */
 void
 ao_clock_init(void)
 {
-       /* Switch system clock to crystal oscilator */
-       CLKCON = (CLKCON & ~CLKCON_OSC_MASK) | (CLKCON_OSC_XTAL);
+       /* Power up both oscillators */
+       SLEEP &= ~(SLEEP_OSC_PD);
 
 
-       while (!(SLEEP & SLEEP_XOSC_STB))
+       /* Switch to the HFRC oscillator */
+       CLKCON = (CLKCON & ~CLKCON_OSC_MASK) | (CLKCON_OSC_RC);
+
+       /* Wait for the HFRC oscillator to be stable */
+       while (!(SLEEP & SLEEP_HFRC_STB))
                ;
 
                ;
 
+       /* Delay for 'a while' waiting for the crystal to
+        * stabilize -- the XOSC_STB bit isn't reliable
+        *
+        *  http://www.ti.com/lit/er/swrz022c/swrz022c.pdf
+        */
+
+       ao_clock_delay();
+
+       /* Switch system clock to crystal oscilator */
+       CLKCON = (CLKCON & ~CLKCON_OSC_MASK) | (CLKCON_OSC_XTAL);
+
        /* Power down the unused HFRC oscillator */
        SLEEP |= SLEEP_OSC_PD;
 
        /* Wait for HFRC to power down */
        while ((SLEEP & SLEEP_HFRC_STB) != 0)
                ;
        /* Power down the unused HFRC oscillator */
        SLEEP |= SLEEP_OSC_PD;
 
        /* Wait for HFRC to power down */
        while ((SLEEP & SLEEP_HFRC_STB) != 0)
                ;
-       
        /* Crank up the timer tick and system clock speed */
        CLKCON = ((CLKCON & ~(CLKCON_TICKSPD_MASK | CLKCON_CLKSPD_MASK)) |
                  (CLKCON_TICKSPD_1 | CLKCON_CLKSPD_1));
        /* Crank up the timer tick and system clock speed */
        CLKCON = ((CLKCON & ~(CLKCON_TICKSPD_MASK | CLKCON_CLKSPD_MASK)) |
                  (CLKCON_TICKSPD_1 | CLKCON_CLKSPD_1));