beep when GPS ready
[protos/xbee-avr.git] / spi_servo.c
index 6e1da05..7a85070 100644 (file)
@@ -4,7 +4,7 @@
 #include <aversive.h>
 #include <aversive/wait.h>
 
-#include <scheduler.h>
+#include <callout.h>
 
 #include "spi_servo.h"
 #include "main.h"
  * callback is unloaded.
  */
 
-/* 1ms */
-#define SPI_EVT_PERIOD (10000UL/SCHEDULER_UNIT)
-
-#define N_SERVO 6
-
 #define PPM_BIT    0x01
 #define BYPASS_BIT 0x02
 
@@ -46,6 +41,8 @@ struct spi_servo_rx {
 };
 static struct spi_servo_rx spi_servo_rx;
 
+static struct callout spi_timer;
+
 /*
  * SPI protocol:
  *
@@ -126,7 +123,7 @@ static void decode_rx_servo(union spi_byte0 byte0, union spi_byte1 byte1)
 }
 
 /* called by the scheduler */
-static void spi_servo_cb(void *arg)
+static void spi_servo_cb(struct callout_mgr *cm, struct callout *tim, void *arg)
 {
        uint8_t idx;
        union spi_byte0 byte0;
@@ -149,13 +146,13 @@ static void spi_servo_cb(void *arg)
        if (spi_servo_tx.next_byte != 0) {
                spi_send_byte(spi_servo_tx.next_byte);
                spi_servo_tx.next_byte = 0;
-               return;
+               goto reschedule;
        }
 
        /* if there is no updated servo, send 0 and return. */
        if (spi_servo_tx.cmd_mask == 0) {
                spi_send_byte(0);
-               return;
+               goto reschedule;
        }
 
        /* else find it and send it */
@@ -172,6 +169,11 @@ static void spi_servo_cb(void *arg)
        spi_send_one_servo(idx, spi_servo_tx.servo[idx]);
        spi_servo_tx.cmd_mask &= (~(1 << idx));
        spi_servo_tx.cur_idx = idx;
+
+ reschedule:
+       /* don't use callout_reschedule() here, we want to schedule in one tick
+        * relative to current time: 1 tick is 682us at 12Mhz */
+       callout_schedule(cm, tim, 0);
 }
 
 void spi_servo_init(void)
@@ -182,14 +184,14 @@ void spi_servo_init(void)
        /* remove power reduction on spi */
        PRR0 &= ~(1 << PRSPI);
 
-       /* Enable SPI, Master, set clock rate fck/64 */
-       SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR1);
+       /* Enable SPI, Master, set clock rate fck/16 */
+       SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
 
        SS_HIGH();
 
-       scheduler_add_periodical_event_priority(&spi_servo_cb, NULL,
-                                           SPI_EVT_PERIOD, SPI_PRIO);
-       spi_servo_bypass(1);
+       callout_init(&spi_timer, spi_servo_cb, NULL, SPI_PRIO);
+       callout_schedule(&xbeeboard.intr_cm, &spi_timer, 0); /* immediate */
+       spi_servo_set_bypass(1);
 }
 
 void spi_servo_set(uint8_t num, uint16_t val)
@@ -220,7 +222,17 @@ uint16_t spi_servo_get(uint8_t num)
        return val;
 }
 
-void spi_servo_bypass(uint8_t enable)
+uint8_t spi_servo_get_bypass(void)
+{
+       return !!(spi_servo_tx.servo[N_SERVO] & BYPASS_BIT);
+}
+
+uint8_t spi_servo_get_ppm(void)
+{
+       return !!(spi_servo_tx.servo[N_SERVO] & PPM_BIT);
+}
+
+void spi_servo_set_bypass(uint8_t enable)
 {
        uint8_t flags;
 
@@ -234,7 +246,7 @@ void spi_servo_bypass(uint8_t enable)
        IRQ_UNLOCK(flags);
 }
 
-void spi_servo_ppm(uint8_t enable)
+void spi_servo_set_ppm(uint8_t enable)
 {
        uint8_t flags;
 
@@ -247,3 +259,14 @@ void spi_servo_ppm(uint8_t enable)
        spi_servo_tx.cmd_mask |= (1 << N_SERVO);
        IRQ_UNLOCK(flags);
 }
+
+void spi_servo_dump(void)
+{
+       uint8_t i;
+
+       for (i = 0; i < N_SERVO; i++)
+               printf_P(PSTR("%d: rx=%4.4d tx=%4.4d\r\n"), i,
+                        spi_servo_get(i), spi_servo_tx.servo[i]);
+       printf_P(PSTR("bypass=%d ppm=%d\n"),
+                spi_servo_get_bypass(), spi_servo_get_ppm());
+}