From: Keith Packard Date: Tue, 14 Apr 2009 17:02:19 +0000 (-0700) Subject: Add comments, clean up white space, etc. X-Git-Tag: sn1-flight1~16 X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=commitdiff_plain;h=fb63262699d3a6fbf347d24efda8b01f75b7d0d3;ds=sidebyside Add comments, clean up white space, etc. Various clean ups now that the basic code appears to work. Signed-off-by: Keith Packard --- diff --git a/ao.h b/ao.h index 6de3339f..7cb0fbfe 100644 --- a/ao.h +++ b/ao.h @@ -23,118 +23,234 @@ #include #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); diff --git a/ao_adc.c b/ao_adc.c index f043b5a1..549cc944 100644 --- a/ao_adc.c +++ b/ao_adc.c @@ -21,7 +21,30 @@ 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)); -} - diff --git a/ao_panic.c b/ao_panic.c index 0f8433dc..30ccce60 100644 --- a/ao_panic.c +++ b/ao_panic.c @@ -17,8 +17,36 @@ #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); + } } diff --git a/ao_task.c b/ao_task.c index d03fa02a..24bd319a 100644 --- 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(); } diff --git a/ao_timer.c b/ao_timer.c index cb6255d2..9583a388 100644 --- a/ao_timer.c +++ b/ao_timer.c @@ -17,32 +17,38 @@ #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)); -}