Do radio settings solely by frequency
[fw/altos] / src / core / ao.h
index 9b0bb54531de8ded23dee1e674b5b6c2118b1abd..ce9a1f70e0ce4ff39673cb2eef6ea395730d023d 100644 (file)
 #ifndef DATA_TO_XDATA
 #define DATA_TO_XDATA(a)       (a)
 #endif
+#ifndef PDATA_TO_XDATA
+#define PDATA_TO_XDATA(a)      (a)
+#endif
+#ifndef CODE_TO_XDATA
+#define CODE_TO_XDATA(a)       (a)
+#endif
 
 /* An AltOS task */
 struct ao_task {
        __xdata void *wchan;            /* current wait channel (NULL if running) */
        uint16_t alarm;                 /* abort ao_sleep time */
-       uint8_t stack_count;            /* amount of saved stack */
+       ao_arch_task_members            /* any architecture-specific fields */
        uint8_t task_id;                /* unique id */
        __code char *name;              /* task name */
        uint8_t stack[AO_STACK_SIZE];   /* saved stack */
@@ -68,6 +74,10 @@ ao_wakeup(__xdata void *wchan);
 void
 ao_alarm(uint16_t delay);
 
+/* Clear any pending alarm */
+void
+ao_clear_alarm(void);
+
 /* Yield the processor to another task */
 void
 ao_yield(void) ao_arch_naked_declare;
@@ -144,15 +154,6 @@ ao_clock_init(void);
 /*
  * One set of samples read from the A/D converter or telemetry
  */
-struct ao_adc {
-       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 */
-};
 
 #if HAS_ADC
 
@@ -160,7 +161,6 @@ struct ao_adc {
  * ao_adc.c
  */
 
-#define AO_ADC_RING    32
 #define ao_adc_ring_next(n)    (((n) + 1) & (AO_ADC_RING - 1))
 #define ao_adc_ring_prev(n)    (((n) - 1) & (AO_ADC_RING - 1))
 
@@ -321,6 +321,10 @@ ao_usb_disable(void);
 void
 ao_usb_init(void);
 
+#if HAS_USB
+extern __code __at (0x00aa) uint8_t ao_usb_descriptors [];
+#endif
+
 /*
  * ao_cmd.c
  */
@@ -345,9 +349,18 @@ ao_cmd_put8(uint8_t v);
 void
 ao_cmd_put16(uint16_t v);
 
+uint8_t
+ao_cmd_is_white(void);
+
 void
 ao_cmd_white(void);
 
+int8_t
+ao_cmd_hexchar(char c);
+
+void
+ao_cmd_hexbyte(void);
+
 void
 ao_cmd_hex(void);
 
@@ -363,7 +376,7 @@ struct ao_cmds {
 };
 
 void
-ao_cmd_register(__code struct ao_cmds *cmds);
+ao_cmd_register(const __code struct ao_cmds *cmds);
 
 void
 ao_cmd_init(void);
@@ -925,6 +938,39 @@ void
 ao_serial_init(void);
 #endif
 
+#ifndef HAS_SERIAL_0
+#define HAS_SERIAL_0 0
+#endif
+
+#if HAS_SERIAL_0
+
+extern volatile __xdata struct ao_fifo ao_usart0_rx_fifo;
+extern volatile __xdata struct ao_fifo ao_usart0_tx_fifo;
+
+void
+ao_serial0_rx0_isr(void) ao_arch_interrupt(2);
+
+void
+ao_serial0_tx0_isr(void) ao_arch_interrupt(7);
+
+char
+ao_serial0_getchar(void) __critical;
+
+void
+ao_serial0_putchar(char c) __critical;
+
+void
+ao_serial0_drain(void) __critical;
+
+void
+ao_serial0_set_speed(uint8_t speed);
+
+void
+ao_serial0_init(void);
+
+#endif
+
+
 /*
  * ao_spi.c
  */
@@ -966,12 +1012,37 @@ ao_spi_recv(void __xdata *block, uint16_t len) __reentrant;
 void
 ao_spi_init(void);
 
+/*
+ * ao_spi_slave.c
+ */
+
+uint8_t
+ao_spi_slave_recv(uint8_t *buf, uint8_t len);
+
+void
+ao_spi_slave_send(uint8_t *buf, uint8_t len);
+
+void
+ao_spi_slave_init(void);
+
+/* This must be defined by the product; it will get called when chip
+ * select goes low, at which point it should use ao_spi_read and
+ * ao_spi_write to deal with the request
+ */
+
+void
+ao_spi_slave(void);
+
 /*
  * ao_telemetry.c
  */
 #define AO_MAX_CALLSIGN                        8
 #define AO_MAX_VERSION                 8
+#if LEGACY_MONITOR
 #define AO_MAX_TELEMETRY               128
+#else
+#define AO_MAX_TELEMETRY               32
+#endif
 
 struct ao_telemetry_generic {
        uint16_t        serial;         /* 0 */
@@ -1097,6 +1168,30 @@ struct ao_telemetry_companion {
        /* 32 */
 };
        
+/* #define AO_SEND_ALL_BARO */
+
+#define AO_TELEMETRY_BARO              0x80
+
+/*
+ * This packet allows the full sampling rate baro
+ * data to be captured over the RF link so that the
+ * flight software can be tested using 'real' data.
+ *
+ * Along with this telemetry packet, the flight
+ * code is modified to send full-rate telemetry all the time
+ * and never send an RDF tone; this ensure that the full radio
+ * link is available.
+ */
+struct ao_telemetry_baro {
+       uint16_t                                serial;         /*  0 */
+       uint16_t                                tick;           /*  2 */
+       uint8_t                                 type;           /*  4 */
+       uint8_t                                 samples;        /*  5 number samples */
+
+       int16_t                                 baro[12];       /* 6 samples */
+       /* 32 */
+};
+
 union ao_telemetry_all {
        struct ao_telemetry_generic             generic;
        struct ao_telemetry_sensor              sensor;
@@ -1104,6 +1199,13 @@ union ao_telemetry_all {
        struct ao_telemetry_location            location;
        struct ao_telemetry_satellite           satellite;
        struct ao_telemetry_companion           companion;
+       struct ao_telemetry_baro                baro;
+};
+
+struct ao_telemetry_all_recv {
+       union ao_telemetry_all          telemetry;
+       int8_t                          rssi;
+       uint8_t                         status;
 };
 
 /*
@@ -1237,9 +1339,15 @@ struct ao_telemetry_raw_recv {
 
 /* Set delay between telemetry reports (0 to disable) */
 
+#ifdef AO_SEND_ALL_BARO
+#define AO_TELEMETRY_INTERVAL_PAD      AO_MS_TO_TICKS(100)
+#define AO_TELEMETRY_INTERVAL_FLIGHT   AO_MS_TO_TICKS(100)
+#define AO_TELEMETRY_INTERVAL_RECOVER  AO_MS_TO_TICKS(100)
+#else
 #define AO_TELEMETRY_INTERVAL_PAD      AO_MS_TO_TICKS(1000)
 #define AO_TELEMETRY_INTERVAL_FLIGHT   AO_MS_TO_TICKS(100)
 #define AO_TELEMETRY_INTERVAL_RECOVER  AO_MS_TO_TICKS(1000)
+#endif
 
 void
 ao_telemetry_set_interval(uint16_t interval);
@@ -1277,16 +1385,26 @@ void
 ao_radio_set_packet(void);
 
 void
-ao_radio_send(__xdata void *data, uint8_t size) __reentrant;
+ao_radio_send(__xdata void *d, uint8_t size) __reentrant;
 
 uint8_t
-ao_radio_recv(__xdata void *data, uint8_t size) __reentrant;
+ao_radio_recv(__xdata void *d, uint8_t size) __reentrant;
 
 void
 ao_radio_recv_abort(void);
 
+/*
+ * Compute the packet length as follows:
+ *
+ * 2000 bps (for a 1kHz tone)
+ * so, for 'ms' milliseconds, we need
+ * 2 * ms bits, or ms / 4 bytes
+ */
+
+#define AO_MS_TO_RDF_LEN(ms) ((ms) > 255 * 4 ? 255 : ((ms) >> 2))
+
 void
-ao_radio_rdf(int ms);
+ao_radio_rdf(uint8_t pkt_len);
 
 void
 ao_radio_rdf_abort(void);
@@ -1303,18 +1421,39 @@ ao_radio_init(void);
 
 extern const char const * const ao_state_names[];
 
+#define AO_MONITOR_RING        8
+
+union ao_monitor {
+       struct ao_telemetry_raw_recv    raw;
+       struct ao_telemetry_all_recv    all;
+       struct ao_telemetry_orig_recv   orig;
+       struct ao_telemetry_tiny_recv   tiny;
+};
+
+extern __xdata union ao_monitor ao_monitor_ring[AO_MONITOR_RING];
+
+#define ao_monitor_ring_next(n)        (((n) + 1) & (AO_MONITOR_RING - 1))
+
+extern __data uint8_t ao_monitoring;
+extern __data uint8_t ao_monitor_head;
+
 void
 ao_monitor(void);
 
 #define AO_MONITORING_OFF      0
 #define AO_MONITORING_ORIG     1
-#define AO_MONITORING_TINY     2
 
 void
-ao_set_monitor(uint8_t monitoring);
+ao_monitor_set(uint8_t monitoring);
+
+void
+ao_monitor_disable(void);
 
 void
-ao_monitor_init(uint8_t led, uint8_t monitoring) __reentrant;
+ao_monitor_enable(void);
+
+void
+ao_monitor_init(void) __reentrant;
 
 /*
  * ao_stdio.c
@@ -1365,9 +1504,19 @@ enum ao_igniter_status {
        ao_igniter_open,        /* open circuit detected */
 };
 
+struct ao_ignition {
+       uint8_t request;
+       uint8_t fired;
+       uint8_t firing;
+};
+
+extern __xdata struct ao_ignition ao_ignition[2];
+
 enum ao_igniter_status
 ao_igniter_status(enum ao_igniter igniter);
 
+extern __pdata uint8_t ao_igniter_present;
+
 void
 ao_ignite_set_pins(void);
 
@@ -1379,7 +1528,19 @@ ao_igniter_init(void);
  */
 
 #define AO_CONFIG_MAJOR        1
-#define AO_CONFIG_MINOR        8
+#define AO_CONFIG_MINOR        10
+#define AO_AES_LEN 16
+
+#if HAS_RADIO_CHANNELS
+#define AO_CHANNEL_NAME_LEN    10
+
+#define AO_NUM_CHANNELS                10
+
+struct ao_radio_channel {
+       char            name[AO_CHANNEL_NAME_LEN];
+       uint32_t        kHz;
+};
+#endif
 
 struct ao_config {
        uint8_t         major;
@@ -1396,6 +1557,11 @@ struct ao_config {
        uint8_t         pad_orientation;        /* minor version 6 */
        uint32_t        radio_setting;          /* minor version 7 */
        uint8_t         radio_enable;           /* minor version 8 */
+       uint8_t         aes_key[AO_AES_LEN];    /* minor version 9 */
+       uint32_t        frequency;              /* minor version 10 */
+#if HAS_RADIO_CHANNELS
+       struct ao_radio_channel radio_channels[AO_NUM_CHANNELS];        /* minor version 10 */
+#endif
 };
 
 #define AO_IGNITE_MODE_DUAL            0
@@ -1564,11 +1730,239 @@ struct ao_companion_setup {
 };
 
 extern __pdata uint8_t                         ao_companion_running;
-extern __xdata struct ao_companion_setup       ao_companion_setup;
 extern __xdata uint8_t                         ao_companion_mutex;
+extern __xdata struct ao_companion_command     ao_companion_command;
+extern __xdata struct ao_companion_setup       ao_companion_setup;
 extern __xdata uint16_t                                ao_companion_data[AO_COMPANION_MAX_CHANNELS];
 
 void
 ao_companion_init(void);
 
+/* ao_lcd.c */
+  
+void
+ao_lcd_putchar(uint8_t d);
+
+void
+ao_lcd_putstring(char *string);
+
+void
+ao_lcd_contrast_set(uint8_t contrast);
+
+void
+ao_lcd_clear(void);
+
+void
+ao_lcd_cursor_on(void);
+
+void
+ao_lcd_cursor_off(void);
+
+#define AO_LCD_ADDR(row,col)   ((row << 6) | (col))
+
+void
+ao_lcd_goto(uint8_t addr);
+
+void
+ao_lcd_start(void);
+
+void
+ao_lcd_init(void);
+
+/* ao_lcd_port.c */
+
+void
+ao_lcd_port_put_nibble(uint8_t rs, uint8_t d);
+
+void
+ao_lcd_port_init(void);
+
+/* ao_aes.c */
+
+extern __xdata uint8_t ao_aes_mutex;
+
+/* AES keys and blocks are 128 bits */
+
+enum ao_aes_mode {
+       ao_aes_mode_cbc_mac
+};
+
+#if HAS_AES
+void
+ao_aes_isr(void) __interrupt 4;
+#endif
+
+void
+ao_aes_set_mode(enum ao_aes_mode mode);
+
+void
+ao_aes_set_key(__xdata uint8_t *in);
+
+void
+ao_aes_zero_iv(void);
+
+void
+ao_aes_run(__xdata uint8_t *in,
+          __xdata uint8_t *out);
+
+void
+ao_aes_init(void);
+
+/* ao_radio_cmac.c */
+
+int8_t
+ao_radio_cmac_send(__xdata void *packet, uint8_t len) __reentrant;
+
+#define AO_RADIO_CMAC_OK       0
+#define AO_RADIO_CMAC_LEN_ERROR        -1
+#define AO_RADIO_CMAC_CRC_ERROR        -2
+#define AO_RADIO_CMAC_MAC_ERROR        -3
+#define AO_RADIO_CMAC_TIMEOUT  -4
+
+int8_t
+ao_radio_cmac_recv(__xdata void *packet, uint8_t len, uint16_t timeout) __reentrant;
+
+void
+ao_radio_cmac_init(void);
+
+/* ao_launch.c */
+
+struct ao_launch_command {
+       uint16_t        tick;
+       uint16_t        serial;
+       uint8_t         cmd;
+       uint8_t         channel;
+       uint16_t        unused;
+};
+
+#define AO_LAUNCH_QUERY                1
+
+struct ao_launch_query {
+       uint16_t        tick;
+       uint16_t        serial;
+       uint8_t         channel;
+       uint8_t         valid;
+       uint8_t         arm_status;
+       uint8_t         igniter_status;
+};
+
+#define AO_LAUNCH_ARM          2
+#define AO_LAUNCH_FIRE         3
+
+void
+ao_launch_init(void);
+
+/*
+ * ao_log_single.c
+ */
+
+#define AO_LOG_TELESCIENCE_START       ((uint8_t) 's')
+#define AO_LOG_TELESCIENCE_DATA                ((uint8_t) 'd')
+
+#define AO_LOG_TELESCIENCE_NUM_ADC     12
+
+struct ao_log_telescience {
+       uint8_t         type;
+       uint8_t         csum;
+       uint16_t        tick;
+       uint16_t        tm_tick;
+       uint8_t         tm_state;
+       uint8_t         unused;
+       uint16_t        adc[AO_LOG_TELESCIENCE_NUM_ADC];
+};
+
+#define AO_LOG_SINGLE_SIZE             32
+
+union ao_log_single {
+       struct ao_log_telescience       telescience;
+       union ao_telemetry_all          telemetry;
+       uint8_t                         bytes[AO_LOG_SINGLE_SIZE];
+};
+
+extern __xdata union ao_log_single     ao_log_single_write_data;
+extern __xdata union ao_log_single     ao_log_single_read_data;
+
+void
+ao_log_single_extra_query(void);
+
+void
+ao_log_single_list(void);
+
+void
+ao_log_single_main(void);
+
+uint8_t
+ao_log_single_write(void);
+
+uint8_t
+ao_log_single_read(uint32_t pos);
+
+void
+ao_log_single_start(void);
+
+void
+ao_log_single_stop(void);
+
+void
+ao_log_single_restart(void);
+
+void
+ao_log_single_set(void);
+
+void
+ao_log_single_delete(void);
+
+void
+ao_log_single_init(void);
+
+void
+ao_log_single(void);
+
+/*
+ * ao_pyro_slave.c
+ */
+
+#define AO_TELEPYRO_NUM_ADC    9
+
+#ifndef ao_xmemcpy
+#define ao_xmemcpy(d,s,c) memcpy(d,s,c)
+#define ao_xmemset(d,v,c) memset(d,v,c)
+#define ao_xmemcmp(d,s,c) memcmp(d,s,c)
+#endif
+
+/*
+ * ao_terraui.c
+ */
+
+void
+ao_terraui_init(void);
+
+/*
+ * ao_battery.c
+ */
+
+#ifdef BATTERY_PIN
+void
+ao_battery_isr(void) ao_arch_interrupt(1);
+
+uint16_t
+ao_battery_get(void);
+
+void
+ao_battery_init(void);
+#endif /* BATTERY_PIN */
+
+/*
+ * ao_sqrt.c
+ */
+
+uint32_t
+ao_sqrt(uint32_t op);
+
+/*
+ * ao_freq.c
+ */
+
+int32_t ao_freq_to_set(int32_t freq, int32_t cal);
+
 #endif /* _AO_H_ */