altoslib: fix computation of TeleGPS battery voltage
[fw/altos] / src / cc1111 / ao_timer.c
index aadee71e239e324a8b7644fe70872148e615f5d9..a3d454da252a75385bd0b5e30136dd3e92da5ffd 100644 (file)
@@ -3,7 +3,8 @@
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful, but
  * WITHOUT ANY WARRANTY; without even the implied warranty of
 
 #include "ao.h"
 
-static volatile __data uint16_t ao_tick_count;
+volatile __data uint16_t ao_tick_count;
 
 uint16_t ao_time(void) __critical
 {
        return ao_tick_count;
 }
 
-static __xdata uint8_t ao_forever;
-
-void
-ao_delay(uint16_t ticks)
-{
-       ao_alarm(ticks);
-       ao_sleep(&ao_forever);
-       ao_clear_alarm();
-}
-
 #define T1_CLOCK_DIVISOR       8       /* 24e6/8 = 3e6 */
 #define T1_SAMPLE_TIME         30000   /* 3e6/30000 = 100 */
 
@@ -49,6 +40,9 @@ void ao_timer_isr(void) __interrupt 9
        if (++ao_adc_count == ao_adc_interval) {
                ao_adc_count = 0;
                ao_adc_poll();
+#if (AO_DATA_ALL & ~(AO_DATA_ADC))
+               ao_wakeup(DATA_TO_XDATA(&ao_adc_count));
+#endif
        }
 #endif
 }
@@ -68,7 +62,7 @@ ao_timer_init(void)
        /* NOTE:  This uses a timer only present on cc1111 architecture. */
 
        /* disable timer 1 */
-       T1CTL = 0;
+/*     T1CTL = 0; */
 
        /* set the sample rate */
        T1CC0H = T1_SAMPLE_TIME >> 8;
@@ -90,18 +84,57 @@ ao_timer_init(void)
        T1CTL = T1CTL_MODE_MODULO | T1CTL_DIV_8;
 }
 
+#ifndef NEEDS_CC1111_CLOCK_HACK
+#define NEEDS_CC1111_CLOCK_HACK                1
+#endif
+
+#if NEEDS_CC1111_CLOCK_HACK
+static void
+ao_clock_delay(void)
+{
+       uint16_t        i = 0;
+
+       while (--i)
+               ao_arch_nop();
+}
+#endif
+
 /*
  * AltOS always cranks the clock to the max frequency
  */
 void
 ao_clock_init(void)
 {
+#if NEEDS_CC1111_CLOCK_HACK
+       /* Power up both oscillators */
+       SLEEP &= ~(SLEEP_OSC_PD);
+
+       /* 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();
+#endif
+
        /* Switch system clock to crystal oscilator */
        CLKCON = (CLKCON & ~CLKCON_OSC_MASK) | (CLKCON_OSC_XTAL);
 
+       /* Wait for the HFRC oscillator to be stable */
        while (!(SLEEP & SLEEP_XOSC_STB))
                ;
 
+       /* Power down the unused HFRC oscillator */
+       SLEEP |= SLEEP_OSC_PD;
+
        /* Crank up the timer tick and system clock speed */
        CLKCON = ((CLKCON & ~(CLKCON_TICKSPD_MASK | CLKCON_CLKSPD_MASK)) |
                  (CLKCON_TICKSPD_1 | CLKCON_CLKSPD_1));