altos: Signal continuity over radio in pad mode (trac #40)
authorKeith Packard <keithp@keithp.com>
Wed, 11 Jul 2012 03:35:19 +0000 (20:35 -0700)
committerKeith Packard <keithp@keithp.com>
Wed, 11 Jul 2012 03:35:19 +0000 (20:35 -0700)
This is especially useful for telemini which has no beeper, allowing
you to hear the continuity signal while at the pad over the air.

Signed-off-by: Keith Packard <keithp@keithp.com>
src/cc1111/ao_radio.c
src/core/ao.h
src/core/ao_report.c
src/core/ao_telemetry.c
src/drivers/ao_cc1120.c

index 2c4a661ec7883755b3448b0c709d10d8f5ea0dde..2071c47a432cae2c4f8d3c628fea19e8578a9c34 100644 (file)
@@ -200,7 +200,7 @@ static __code uint8_t rdf_setup[] = {
        RF_MDMCFG3_OFF,         (RDF_DRATE_M << RF_MDMCFG3_DRATE_M_SHIFT),
        RF_MDMCFG2_OFF,         (RF_MDMCFG2_DEM_DCFILT_OFF |
                                 RF_MDMCFG2_MOD_FORMAT_GFSK |
-                                RF_MDMCFG2_SYNC_MODE_15_16_THRES),
+                                RF_MDMCFG2_SYNC_MODE_NONE),
        RF_MDMCFG1_OFF,         (RF_MDMCFG1_FEC_DIS |
                                 RF_MDMCFG1_NUM_PREAMBLE_2 |
                                 (2 << RF_MDMCFG1_CHANSPC_E_SHIFT)),
@@ -366,29 +366,22 @@ ao_radio_recv_abort(void)
        ao_wakeup(&ao_radio_dma_done);
 }
 
-__xdata ao_radio_rdf_value = 0x55;
+__code ao_radio_rdf_value = 0x55;
 
-void
-ao_radio_rdf(uint8_t pkt_len)
+static void
+ao_radio_rdf_start(void)
 {
        uint8_t i;
-
        ao_radio_abort = 0;
-       ao_radio_get(pkt_len);
+       ao_radio_get(AO_RADIO_RDF_LEN);
        ao_radio_done = 0;
        for (i = 0; i < sizeof (rdf_setup); i += 2)
                RF[rdf_setup[i]] = rdf_setup[i+1];
+}
 
-       ao_dma_set_transfer(ao_radio_dma,
-                           &ao_radio_rdf_value,
-                           &RFDXADDR,
-                           pkt_len,
-                           DMA_CFG0_WORDSIZE_8 |
-                           DMA_CFG0_TMODE_SINGLE |
-                           DMA_CFG0_TRIGGER_RADIO,
-                           DMA_CFG1_SRCINC_0 |
-                           DMA_CFG1_DESTINC_0 |
-                           DMA_CFG1_PRIORITY_HIGH);
+static void
+ao_radio_rdf_run(void)
+{
        ao_dma_start(ao_radio_dma);
        RFST = RFST_STX;
        __critical while (!ao_radio_done && !ao_radio_abort)
@@ -401,6 +394,70 @@ ao_radio_rdf(uint8_t pkt_len)
        ao_radio_put();
 }
 
+void
+ao_radio_rdf(void)
+{
+       ao_radio_rdf_start();
+
+       ao_dma_set_transfer(ao_radio_dma,
+                           CODE_TO_XDATA(&ao_radio_rdf_value),
+                           &RFDXADDR,
+                           AO_RADIO_RDF_LEN,
+                           DMA_CFG0_WORDSIZE_8 |
+                           DMA_CFG0_TMODE_SINGLE |
+                           DMA_CFG0_TRIGGER_RADIO,
+                           DMA_CFG1_SRCINC_0 |
+                           DMA_CFG1_DESTINC_0 |
+                           DMA_CFG1_PRIORITY_HIGH);
+       ao_radio_rdf_run();
+}
+
+#define PA     0x00
+#define BE     0x55
+
+#define CONT_PAUSE_8   PA, PA, PA, PA, PA, PA, PA, PA
+#define CONT_PAUSE_16  CONT_PAUSE_8, CONT_PAUSE_8
+#define CONT_PAUSE_24  CONT_PAUSE_16, CONT_PAUSE_8
+
+#define CONT_BEEP_8    BE, BE, BE, BE, BE, BE, BE, BE
+
+#if AO_RADIO_CONT_PAUSE_LEN == 24
+#define CONT_PAUSE     CONT_PAUSE_24
+#endif
+
+#if AO_RADIO_CONT_TONE_LEN == 8
+#define CONT_BEEP              CONT_BEEP_8
+#define CONT_PAUSE_SHORT       CONT_PAUSE_8
+#endif
+
+#define CONT_ADDR(c)   CODE_TO_XDATA(&ao_radio_cont[(3-(c)) * (AO_RADIO_CONT_PAUSE_LEN + AO_RADIO_CONT_TONE_LEN)])
+
+__code uint8_t ao_radio_cont[] = {
+       CONT_PAUSE, CONT_BEEP,
+       CONT_PAUSE, CONT_BEEP,
+       CONT_PAUSE, CONT_BEEP,
+       CONT_PAUSE, CONT_PAUSE_SHORT,
+       CONT_PAUSE, CONT_PAUSE_SHORT,
+       CONT_PAUSE,
+};
+
+void
+ao_radio_continuity(uint8_t c)
+{
+       ao_radio_rdf_start();
+       ao_dma_set_transfer(ao_radio_dma,
+                           CONT_ADDR(c),
+                           &RFDXADDR,
+                           AO_RADIO_CONT_TOTAL_LEN,
+                           DMA_CFG0_WORDSIZE_8 |
+                           DMA_CFG0_TMODE_SINGLE |
+                           DMA_CFG0_TRIGGER_RADIO,
+                           DMA_CFG1_SRCINC_1 |
+                           DMA_CFG1_DESTINC_0 |
+                           DMA_CFG1_PRIORITY_HIGH);
+       ao_radio_rdf_run();
+}
+
 void
 ao_radio_rdf_abort(void)
 {
index 861a0fd479dc70aed5863cafb3591ec5a088b07b..2e012f083e597ed4ad2d252e2e773e6d3d523dae 100644 (file)
@@ -264,6 +264,26 @@ ao_cmd_filter(void);
  * ao_report.c
  */
 
+#define AO_RDF_INTERVAL_TICKS  AO_SEC_TO_TICKS(5)
+#define AO_RDF_LENGTH_MS       500
+#define AO_RDF_CONTINUITY_MS   32
+#define AO_RDF_CONTINUITY_PAUSE        96
+#define AO_RDF_CONTINUITY_TOTAL        ((AO_RDF_CONTINUITY_PAUSE + AO_RDF_CONTINUITY_MS) * 3 + AO_RDF_CONTINUITY_PAUSE)
+
+/* This assumes that we're generating a 1kHz tone, which
+ * modulates the carrier at 2kbps, or 250kBps
+ */
+#define AO_MS_TO_RDF_LEN(ms) ((ms) / 4)
+
+#define AO_RADIO_RDF_LEN       AO_MS_TO_RDF_LEN(AO_RDF_LENGTH_MS)
+#define AO_RADIO_CONT_TONE_LEN AO_MS_TO_RDF_LEN(AO_RDF_CONTINUITY_MS)
+#define AO_RADIO_CONT_PAUSE_LEN        AO_MS_TO_RDF_LEN(AO_RDF_CONTINUITY_PAUSE)
+#define AO_RADIO_CONT_TOTAL_LEN        AO_MS_TO_RDF_LEN(AO_RDF_CONTINUITY_TOTAL)
+
+/* returns a value 0-3 to indicate igniter continuity */
+uint8_t
+ao_report_igniter(void);
+
 void
 ao_report_init(void);
 
@@ -538,10 +558,11 @@ ao_radio_recv_abort(void);
  * 2 * ms bits, or ms / 4 bytes
  */
 
-#define AO_MS_TO_RDF_LEN(ms) ((ms) > 255 * 4 ? 255 : ((ms) >> 2))
+void
+ao_radio_rdf(void);
 
 void
-ao_radio_rdf(uint8_t pkt_len);
+ao_radio_continuity(uint8_t c);
 
 void
 ao_radio_rdf_abort(void);
index eb90a4f8c6eb99b62dc83dbb71d33c6b8530d528..1104cd82532ff8173334591ee06c534b968e1f42 100644 (file)
@@ -114,6 +114,13 @@ ao_report_igniter_ready(enum ao_igniter igniter)
        return ao_igniter_status(igniter) == ao_igniter_ready ? 1 : 0;
 }
 
+uint8_t
+ao_report_igniter(void)
+{
+       return (ao_report_igniter_ready(ao_igniter_drogue) |
+                    (ao_report_igniter_ready(ao_igniter_main) << 1));
+}
+
 static void
 ao_report_continuity(void) __reentrant
 {
@@ -123,8 +130,7 @@ ao_report_continuity(void) __reentrant
        if (!ao_igniter_present)
                return;
 #endif
-       c = (ao_report_igniter_ready(ao_igniter_drogue) |
-                    (ao_report_igniter_ready(ao_igniter_main) << 1));
+       c = ao_report_igniter();
        if (c) {
                while (c--) {
                        high(AO_MS_TO_TICKS(25));
index 3c747520ee2c227e2a77e30efdd84b4f6f48acd6..583a6636668fe764c0de48727e29a06056f3562f 100644 (file)
@@ -22,9 +22,6 @@ static __pdata uint16_t ao_telemetry_interval;
 static __pdata uint8_t ao_rdf = 0;
 static __pdata uint16_t ao_rdf_time;
 
-#define AO_RDF_INTERVAL_TICKS  AO_SEC_TO_TICKS(5)
-#define AO_RDF_LENGTH_MS       500
-
 #if defined(MEGAMETRUM)
 #define AO_SEND_MEGA   1
 #endif
@@ -317,8 +314,16 @@ ao_telemetry(void)
                        if (ao_rdf &&
                            (int16_t) (ao_time() - ao_rdf_time) >= 0)
                        {
+#if HAS_IGNITE_REPORT
+                               uint8_t c;
+#endif
                                ao_rdf_time = ao_time() + AO_RDF_INTERVAL_TICKS;
-                               ao_radio_rdf(AO_MS_TO_RDF_LEN(AO_RDF_LENGTH_MS));
+#if HAS_IGNITE_REPORT
+                               if (ao_flight_state == ao_flight_pad && (c = ao_report_igniter()))
+                                       ao_radio_continuity(c);
+                               else
+#endif
+                                       ao_radio_rdf();
                        }
 #endif
                        time += ao_telemetry_interval;
@@ -330,6 +335,7 @@ ao_telemetry(void)
                        }
                        else
                                time = ao_time();
+               bottom: ;
                }
        }
 }
index 1d28148ba2b4a74366a87c345cad72e6f9ebb02d..a36d922c15ac27bca4d28e75418e39665d2771d0 100644 (file)
@@ -160,7 +160,7 @@ ao_radio_fifo_read(uint8_t *data, uint8_t len)
 }
 
 static uint8_t
-ao_radio_fifo_write(uint8_t *data, uint8_t len)
+ao_radio_fifo_write_start(void)
 {
        uint8_t addr = ((0 << CC1120_READ)  |
                        (1 << CC1120_BURST) |
@@ -169,24 +169,28 @@ ao_radio_fifo_write(uint8_t *data, uint8_t len)
 
        ao_radio_select();
        ao_radio_duplex(&addr, &status, 1);
-       ao_radio_spi_send(data, len);
+       return status;
+}
+
+static inline uint8_t ao_radio_fifo_write_stop(uint8_t status) {
        ao_radio_deselect();
        return status;
 }
 
 static uint8_t
-ao_radio_fifo_write_fixed(uint8_t data, uint8_t len)
+ao_radio_fifo_write(uint8_t *data, uint8_t len)
 {
-       uint8_t addr = ((0 << CC1120_READ)  |
-                       (1 << CC1120_BURST) |
-                       CC1120_FIFO);
-       uint8_t status;
+       uint8_t status = ao_radio_fifo_write_start();
+       ao_radio_spi_send(data, len);
+       return ao_radio_fifo_write_stop(status);
+}
 
-       ao_radio_select();
-       ao_radio_duplex(&addr, &status, 1);
+static uint8_t
+ao_radio_fifo_write_fixed(uint8_t data, uint8_t len)
+{
+       uint8_t status = ao_radio_fifo_write_start();
        ao_radio_spi_send_fixed(data, len);
-       ao_radio_deselect();
-       return status;
+       return ao_radio_fifo_write_stop(status);
 }
 
 static uint8_t
@@ -446,19 +450,20 @@ ao_radio_get(uint8_t len)
 
 #define ao_radio_put() ao_mutex_put(&ao_radio_mutex)
 
-void
-ao_radio_rdf(uint8_t len)
+static void
+ao_rdf_start(uint8_t len)
 {
-       int i;
-
        ao_radio_abort = 0;
        ao_radio_get(len);
 
        ao_radio_set_mode(AO_RADIO_MODE_RDF);
        ao_radio_wake = 0;
 
-       ao_radio_fifo_write_fixed(ao_radio_rdf_value, len);
+}
 
+static void
+ao_rdf_run(void)
+{
        ao_radio_start_tx();
 
        cli();
@@ -470,6 +475,38 @@ ao_radio_rdf(uint8_t len)
        ao_radio_put();
 }
 
+void
+ao_radio_rdf(void)
+{
+       ao_rdf_start(AO_RADIO_RDF_LEN);
+
+       ao_radio_fifo_write_fixed(ao_radio_rdf_value, AO_RADIO_RDF_LEN);
+
+       ao_rdf_run();
+}
+
+void
+ao_radio_continuity(uint8_t c)
+{
+       uint8_t i;
+       uint8_t status;
+
+       ao_rdf_start(AO_RADIO_CONT_TOTAL_LEN);
+
+       status = ao_radio_fifo_write_start();
+       for (i = 0; i < 3; i++) {
+               ao_radio_spi_send_fixed(0x00, AO_RADIO_CONT_PAUSE_LEN);
+               if (i < c)
+                       ao_radio_spi_send_fixed(ao_radio_rdf_value, AO_RADIO_CONT_TONE_LEN);
+               else
+                       ao_radio_spi_send_fixed(0x00, AO_RADIO_CONT_TONE_LEN);
+       }
+       ao_radio_spi_send_fixed(0x00, AO_RADIO_CONT_PAUSE_LEN);
+       status = ao_radio_fifo_write_stop(status);
+       (void) status;
+       ao_rdf_run();
+}
+
 void
 ao_radio_rdf_abort(void)
 {