Add comments, clean up white space, etc.
authorKeith Packard <keithp@keithp.com>
Tue, 14 Apr 2009 17:02:19 +0000 (10:02 -0700)
committerKeith Packard <keithp@keithp.com>
Tue, 14 Apr 2009 17:02:19 +0000 (10:02 -0700)
Various clean ups now that the basic code appears to work.

Signed-off-by: Keith Packard <keithp@keithp.com>
ao.h
ao_adc.c
ao_panic.c
ao_task.c
ao_timer.c

diff --git a/ao.h b/ao.h
index 6de3339f605423ed8c617edf96e994ddda59ade1..7cb0fbfe7786c9ff7203a6443a01efb6823f5576 100644 (file)
--- a/ao.h
+++ b/ao.h
 #include <string.h>
 #include "cc1111.h"
 
+/* Convert a __data pointer into an __xdata pointer */
 #define DATA_TO_XDATA(a)       ((void __xdata *) ((uint8_t) (a) | 0xff00))
 
-#define AO_STACK_START 0x34
+/* Stack runs from above the allocated __data space to 0xfe, which avoids
+ * writing to 0xff as that triggers the stack overflow indicator
+ */
+#define AO_STACK_START 0x28
 #define AO_STACK_END   0xfe
 #define AO_STACK_SIZE  (AO_STACK_END - AO_STACK_START + 1)
 
+/* An AltOS task */
 struct ao_task {
-       __xdata void    *wchan;
-       uint8_t stack[AO_STACK_SIZE];
-       uint8_t stack_count;
+       __xdata void *wchan;            /* current wait channel (NULL if running) */
+       uint8_t stack_count;            /* amount of saved stack */
+       uint8_t stack[AO_STACK_SIZE];   /* saved stack */
 };
 
-#define AO_NUM_TASKS   10
-
-#define AO_ERROR_NO_TASK       1
+#define AO_NUM_TASKS           10      /* maximum number of tasks */
 
 #define ao_interrupt_disable() (EA = 0)
 #define ao_interrupt_enable()  (EA = 1)
 
-/* ao_task.c */
-int ao_sleep(__xdata void *wchan);
-int ao_wakeup(__xdata void *wchan);
-void ao_add_task(__xdata struct ao_task * task, void (*start)(void));
-void ao_start_scheduler(void);
-void ao_yield(void) _naked;
-void ao_panic(uint8_t reason);
+/*
+ ao_task.c
+ */
+
+/* Suspend the current task until wchan is awoken */
+int
+ao_sleep(__xdata void *wchan);
+
+/* Wake all tasks sleeping on wchan */
+int
+ao_wakeup(__xdata void *wchan);
+
+/* Yield the processor to another task */
+void
+ao_yield(void) _naked;
+
+/* Add a task to the run queue */
+void
+ao_add_task(__xdata struct ao_task * task, void (*start)(void));
+
+/* Start the scheduler. This will not return */
+void
+ao_start_scheduler(void);
+
+/*
+ * ao_panic.c
+ */
+
+#define AO_PANIC_NO_TASK       1       /* AO_NUM_TASKS is not large enough */
 
-/* ao_timer.c */
+/* Stop the operating system, beeping and blinking the reason */
+void
+ao_panic(uint8_t reason);
 
-volatile __data uint16_t ao_time;
+/*
+ * ao_timer.c
+ */
 
+/* Our timer runs at 100Hz */
 #define AO_MS_TO_TICKS(ms)     ((ms) / 10)
 #define AO_SEC_TO_TICKS(s)     ((s) * 100)
 
-void ao_timer_isr(void) interrupt 9;
-void ao_timer_init(void);
-uint16_t ao_time_atomic(void);
-void ao_delay(uint16_t ticks);
+/* Returns the current time in ticks */
+uint16_t
+ao_time(void);
+
+/* Suspend the current task until ticks time has passed */
+void
+ao_delay(uint16_t ticks);
+
+/* Timer interrupt */
+void
+ao_timer_isr(void) interrupt 9;
+
+/* Initialize the timer */
+void
+ao_timer_init(void);
 
-/* ao_adc.c */
+/*
+ * ao_adc.c
+ */
 
-#define ADC_RING       32
+#define ADC_RING       128
 
+/*
+ * One set of samples read from the A/D converter
+ */
 struct ao_adc {
-       uint16_t        tick;
-       int16_t         accel;
-       int16_t         pres;
-       int16_t         temp;
-       int16_t         v_batt;
-       int16_t         sense_d;
-       int16_t         sense_m;
+       uint16_t        tick;           /* tick when the sample was read */
+       int16_t         accel;          /* accelerometer */
+       int16_t         pres;           /* pressure sensor */
+       int16_t         temp;           /* temperature sensor */
+       int16_t         v_batt;         /* battery voltage */
+       int16_t         sense_d;        /* drogue continuity sense */
+       int16_t         sense_m;        /* main continuity sense */
 };
 
+/*
+ * A/D data is stored in a ring, with the next sample to be written
+ * at ao_adc_head
+ */
 extern volatile __xdata struct ao_adc  ao_adc_ring[ADC_RING];
 extern volatile __data uint8_t         ao_adc_head;
 
-void ao_adc_isr(void) interrupt 1;
-void ao_adc_init(void);
-void ao_adc_poll(void);
-void ao_adc_get(__xdata struct ao_adc *packet);
+/* Trigger a conversion sequence (called from the timer interrupt) */
+void
+ao_adc_poll(void);
+/* Suspend the current task until another A/D sample is converted */
+void
+ao_adc_sleep(void);
 
-/* ao_beep.c */
+/* Get a copy of the last complete A/D sample set */
+void
+ao_adc_get(__xdata struct ao_adc *packet);
 
-#define AO_BEEP_LOW    150
-#define AO_BEEP_MID    94
-#define AO_BEEP_HIGH   75
-#define AO_BEEP_OFF    0
+/* The A/D interrupt handler */
+void
+ao_adc_isr(void) interrupt 1;
 
+/* Initialize the A/D converter */
 void
-ao_beep_init(void);
+ao_adc_init(void);
+
+/*
+ * ao_beep.c
+ */
+
+/*
+ * Various pre-defined beep frequencies
+ *
+ * frequency = 1/2 (24e6/32) / beep
+ */
 
+#define AO_BEEP_LOW    150     /* 2500Hz */
+#define AO_BEEP_MID    94      /* 3989Hz */
+#define AO_BEEP_HIGH   75      /* 5000Hz */
+#define AO_BEEP_OFF    0       /* off */
+
+#define AO_BEEP_g      240     /* 1562.5Hz */
+#define AO_BEEP_gs     227     /* 1652Hz (1655Hz) */
+#define AO_BEEP_aa     214     /* 1752Hz (1754Hz) */
+#define AO_BEEP_bbf    202     /* 1856Hz (1858Hz) */
+#define AO_BEEP_bb     190     /* 1974Hz (1969Hz) */
+#define AO_BEEP_cc     180     /* 2083Hz (2086Hz) */
+#define AO_BEEP_ccs    170     /* 2205Hz (2210Hz) */
+#define AO_BEEP_dd     160     /* 2344Hz (2341Hz) */
+#define AO_BEEP_eef    151     /* 2483Hz (2480Hz) */
+#define AO_BEEP_ee     143     /* 2622Hz (2628Hz) */
+#define AO_BEEP_ff     135     /* 2778Hz (2784Hz) */
+#define AO_BEEP_ffs    127     /* 2953Hz (2950Hz) */
+#define AO_BEEP_gg     120     /* 3125Hz */
+#define AO_BEEP_ggs    113     /* 3319Hz (3311Hz) */
+#define AO_BEEP_aaa    107     /* 3504Hz (3508Hz) */
+#define AO_BEEP_bbbf   101     /* 3713Hz (3716Hz) */
+#define AO_BEEP_bbb    95      /* 3947Hz (3937Hz) */
+#define AO_BEEP_ccc    90      /* 4167Hz (4171Hz) */
+#define AO_BEEP_cccs   85      /* 4412Hz (4419Hz) */
+#define AO_BEEP_ddd    80      /* 4688Hz (4682Hz) */
+#define AO_BEEP_eeef   76      /* 4934Hz (4961Hz) */
+#define AO_BEEP_eee    71      /* 5282Hz (5256Hz) */
+#define AO_BEEP_fff    67      /* 5597Hz (5568Hz) */
+#define AO_BEEP_fffs   64      /* 5859Hz (5899Hz) */
+#define AO_BEEP_ggg    60      /* 6250Hz */
+
+/* Set the beeper to the specified tone */
 void
 ao_beep(uint8_t beep);
 
+/* Turn on the beeper for the specified time */
 void
 ao_beep_for(uint8_t beep, uint16_t ticks);
 
-/* ao_led.c */
+/* Initialize the beeper */
+void
+ao_beep_init(void);
+
+/*
+ * ao_led.c
+ */
 
 #define AO_LED_NONE    0
 #define AO_LED_GREEN   1
 #define AO_LED_RED     2
 
-void
-ao_led_init(void);
-
+/* Turn on the specified LEDs */
 void
 ao_led_on(uint8_t colors);
 
+/* Turn off the specified LEDs */
 void
 ao_led_off(uint8_t colors);
 
+/* Set all of the LEDs to the specified state */
 void
 ao_led_set(uint8_t colors);
 
+/* Turn on the specified LEDs for the indicated interval */
 void
 ao_led_for(uint8_t colors, uint16_t ticks);
 
-/* ao_usb.c */
-
+/* Initialize the LEDs */
 void
-ao_usb_isr(void) interrupt 6;
+ao_led_init(void);
 
-void
-ao_usb_flush(void);
+/*
+ * ao_usb.c
+ */
 
+/* Put one character to the USB output queue */
 void
 ao_usb_putchar(uint8_t c);
 
+/* Get one character from the USB input queue */
 uint8_t
 ao_usb_getchar(void);
 
+/* Flush the USB output queue */
+void
+ao_usb_flush(void);
+
+/* USB interrupt handler */
+void
+ao_usb_isr(void) interrupt 6;
+
+/* Initialize the USB system */
 void
 ao_usb_init(void);
 
index f043b5a133a3d1b099e9793bcd02124ec14e9111..549cc9440847070868fa392d0423782e744da595 100644 (file)
--- a/ao_adc.c
+++ b/ao_adc.c
 volatile __xdata struct ao_adc ao_adc_ring[ADC_RING];
 volatile __data uint8_t                ao_adc_head;
 
-void ao_adc_isr(void) interrupt 1
+void
+ao_adc_poll(void)
+{
+       ADCCON3 = ADCCON3_EREF_VDD | ADCCON3_EDIV_512 | 0;
+}
+
+void
+ao_adc_sleep(void)
+{
+       ao_sleep(&ao_adc_ring);
+}
+
+void
+ao_adc_get(__xdata struct ao_adc *packet)
+{
+       uint8_t i = ao_adc_head;
+       if (i == 0)
+               i = ADC_RING;
+       i--;
+       memcpy(packet, &ao_adc_ring[i], sizeof (struct ao_adc));
+}
+
+void
+ao_adc_isr(void) interrupt 1
 {
        uint8_t sequence;
        uint8_t __xdata *a;
@@ -35,7 +58,7 @@ void ao_adc_isr(void) interrupt 1
                ADCCON3 = ADCCON3_EREF_VDD | ADCCON3_EDIV_512 | (sequence + 1);
        } else {
                /* record this conversion series */
-               ao_adc_ring[ao_adc_head].tick = ao_time;
+               ao_adc_ring[ao_adc_head].tick = ao_time();
                ao_adc_head++;
                if (ao_adc_head == ADC_RING)
                        ao_adc_head = 0;
@@ -43,7 +66,8 @@ void ao_adc_isr(void) interrupt 1
        }
 }
 
-void ao_adc_init(void)
+void
+ao_adc_init(void)
 {
        ADCCFG = ((1 << 0) |    /* acceleration */
                  (1 << 1) |    /* pressure */
@@ -57,17 +81,3 @@ void ao_adc_init(void)
        IEN0 |= IEN0_ADCIE;
 }
 
-void ao_adc_poll(void)
-{
-       ADCCON3 = ADCCON3_EREF_VDD | ADCCON3_EDIV_512 | 0;
-}
-
-void ao_adc_get(__xdata struct ao_adc *packet)
-{
-       uint8_t i = ao_adc_head;
-       if (i == 0)
-               i = ADC_RING;
-       i--;
-       memcpy(packet, &ao_adc_ring[i], sizeof (struct ao_adc));
-}
-
index 0f8433dc03e9297a30dcefb7e4849fae26c72eb0..30ccce60bdc57ba2dd6a05c3d58a9e7466562e92 100644 (file)
 
 #include "ao.h"
 
+static void
+ao_panic_delay(uint8_t n)
+{
+       uint8_t i = 0;
+
+       while (n--)
+               while (--i)
+                       _asm nop _endasm;
+}
+
 void
 ao_panic(uint8_t reason)
 {
-       (void) reason;
+       uint8_t n;
+       
+       for (;;) {
+               ao_led_on(AO_LED_RED);
+               ao_beep(AO_BEEP_MID);
+               ao_panic_delay(2);
+               ao_led_off(AO_LED_RED);
+               ao_beep(AO_BEEP_OFF);
+               ao_panic_delay(2);
+               for (n = 0; n < reason; n++) {
+                       ao_led_on(AO_LED_RED);
+                       ao_beep(AO_BEEP_MID);
+                       ao_panic_delay(1);
+                       ao_led_off(AO_LED_RED);
+                       ao_beep(AO_BEEP_OFF);
+                       ao_panic_delay(1);
+               }
+               ao_panic_delay(2);
+       }
 }
index d03fa02aa90a21d76eafc99f4ea48b552dd2bf25..24bd319ac563b69d33dd77999a0a532763eaa592 100644 (file)
--- a/ao_task.c
+++ b/ao_task.c
@@ -29,7 +29,7 @@ ao_add_task(__xdata struct ao_task * task, void (*start)(void))
 {
        uint8_t __xdata *stack;
        if (ao_num_tasks == AO_NUM_TASKS)
-               ao_panic(AO_ERROR_NO_TASK);
+               ao_panic(AO_PANIC_NO_TASK);
        ao_tasks[ao_num_tasks++] = task;
        /*
         * Construct a stack frame so that it will 'return'
@@ -162,7 +162,9 @@ ao_yield(void) _naked
 int
 ao_sleep(__xdata void *wchan)
 {
+       ao_interrupt_disable();
        ao_cur_task->wchan = wchan;
+       ao_interrupt_enable();
        ao_yield();
 }
 
index cb6255d2f4c83f72719b1a30f959a42231c3ea69..9583a388d26983e01b0b9bdb2788ba3073d06f43 100644 (file)
 
 #include "ao.h"
 
-volatile __data uint16_t ao_time;
+static volatile __data uint16_t ao_tick_count;
 
-void ao_timer_isr(void) interrupt 9
+uint16_t ao_time(void)
 {
-       ++ao_time;
-       ao_adc_poll();
-       ao_wakeup(DATA_TO_XDATA(&ao_time));
+       volatile bit ea_save;
+       __data uint16_t ret;
+       
+       ea_save = EA;
+       ret = ao_tick_count;
+       EA = ea_save;
+       return ret;
 }
 
-uint16_t ao_time_atomic(void)
+void
+ao_delay(uint16_t ticks)
 {
-       uint8_t ret1;
-       uint16_t ret2;
-       
-       for (;;) {
-               ret1 = ao_time >> 8;
-               ret2 = ao_time;
-               if (ret1 == ((__xdata uint8_t *)(&ret2))[1])
-                       break;
-       }
-       return ret2;
+       uint16_t until = ao_time() + ticks;
+
+       while ((int16_t) (until - ao_time()) > 0)
+               ao_sleep(DATA_TO_XDATA(&ao_tick_count));
 }
 
 #define T1_CLOCK_DIVISOR       8       /* 24e6/8 = 3e6 */
 #define T1_SAMPLE_TIME         30000   /* 3e6/30000 = 100 */
 
+void ao_timer_isr(void) interrupt 9
+{
+       ++ao_tick_count;
+       ao_adc_poll();
+       ao_wakeup(DATA_TO_XDATA(&ao_tick_count));
+}
+
 void
 ao_timer_init(void)
 {
@@ -71,11 +77,3 @@ ao_timer_init(void)
        T1CTL = T1CTL_MODE_MODULO | T1CTL_DIV_8;
 }
 
-void
-ao_delay(uint16_t ticks)
-{
-       uint16_t until = ao_time_atomic() + ticks;
-
-       while ((int16_t) (until - ao_time_atomic()) > 0)
-               ao_sleep(DATA_TO_XDATA(&ao_time));
-}