altos/cc1111: Adjust receive parameters to improve sensitivity
[fw/altos] / src / cc1111 / ao_radio.c
index 75f241d4d2391e3664181fc3a0b230919e283e89..fbdf7762633c65a4b382ef23490b1ad77708a945 100644 (file)
@@ -16,6 +16,9 @@
  */
 
 #include "ao.h"
+#if HAS_PAD
+#include <ao_pad.h>
+#endif
 
 /* Values from SmartRF® Studio for:
  *
@@ -123,9 +126,9 @@ static __code uint8_t radio_setup[] = {
                                 (CHANBW_M << RF_MDMCFG4_CHANBW_M_SHIFT) |
                                 (DRATE_E << RF_MDMCFG4_DRATE_E_SHIFT)),
        RF_MDMCFG3_OFF,         (DRATE_M << RF_MDMCFG3_DRATE_M_SHIFT),
-       RF_MDMCFG2_OFF,         (RF_MDMCFG2_DEM_DCFILT_OFF |
+       RF_MDMCFG2_OFF,         (RF_MDMCFG2_DEM_DCFILT_ON |
                                 RF_MDMCFG2_MOD_FORMAT_GFSK |
-                                RF_MDMCFG2_SYNC_MODE_15_16_THRES),
+                                RF_MDMCFG2_SYNC_MODE_15_16),
        RF_MDMCFG1_OFF,         (RF_MDMCFG1_FEC_EN |
                                 RF_MDMCFG1_NUM_PREAMBLE_4 |
                                 (2 << RF_MDMCFG1_CHANSPC_E_SHIFT)),
@@ -152,8 +155,8 @@ static __code uint8_t radio_setup[] = {
        RF_FSCAL1_OFF,          0x00,
        RF_FSCAL0_OFF,          0x1F,
 
-       RF_TEST2_OFF,           0x88,
-       RF_TEST1_OFF,           0x31,
+       RF_TEST2_OFF,           RF_TEST2_RX_LOW_DATA_RATE_MAGIC,
+       RF_TEST1_OFF,           RF_TEST1_RX_LOW_DATA_RATE_MAGIC,
        RF_TEST0_OFF,           0x09,
 
        /* default sync values */
@@ -184,10 +187,16 @@ static __code uint8_t radio_setup[] = {
                                 RF_BSCFG_BS_POST_KI_PRE_KI|
                                 RF_BSCFG_BS_POST_KP_PRE_KP|
                                 RF_BSCFG_BS_LIMIT_0),
-       RF_AGCCTRL2_OFF,        0x43,
-       RF_AGCCTRL1_OFF,        0x40,
-       RF_AGCCTRL0_OFF,        0x91,
-
+       RF_AGCCTRL2_OFF,        (RF_AGCCTRL2_MAX_DVGA_GAIN_ALL|
+                                RF_AGCCTRL2_MAX_LNA_GAIN_0|
+                                RF_AGCCTRL2_MAGN_TARGET_33dB),
+       RF_AGCCTRL1_OFF,        (RF_AGCCTRL1_AGC_LNA_PRIORITY_0 |
+                                RF_AGCCTRL1_CARRIER_SENSE_REL_THR_DISABLE |
+                                RF_AGCCTRL1_CARRIER_SENSE_ABS_THR_0DB),
+       RF_AGCCTRL0_OFF,        (RF_AGCCTRL0_HYST_LEVEL_NONE |
+                                RF_AGCCTRL0_WAIT_TIME_8 |
+                                RF_AGCCTRL0_AGC_FREEZE_NORMAL |
+                                RF_AGCCTRL0_FILTER_LENGTH_8),
        RF_IOCFG2_OFF,          0x00,
        RF_IOCFG1_OFF,          0x00,
        RF_IOCFG0_OFF,          0x00,
@@ -200,7 +209,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)),
@@ -209,7 +218,7 @@ static __code uint8_t rdf_setup[] = {
                                 (RDF_DEVIATION_M << RF_DEVIATN_DEVIATION_M_SHIFT)),
 
        /* packet length is set in-line */
-       RF_PKTCTRL1_OFF,        ((1 << PKTCTRL1_PQT_SHIFT)|
+       RF_PKTCTRL1_OFF,        ((0 << PKTCTRL1_PQT_SHIFT)|
                                 PKTCTRL1_ADR_CHK_NONE),
        RF_PKTCTRL0_OFF,        (RF_PKTCTRL0_PKT_FORMAT_NORMAL|
                                 RF_PKTCTRL0_LENGTH_CONFIG_FIXED),
@@ -220,9 +229,9 @@ static __code uint8_t fixed_pkt_setup[] = {
                                 (CHANBW_M << RF_MDMCFG4_CHANBW_M_SHIFT) |
                                 (DRATE_E << RF_MDMCFG4_DRATE_E_SHIFT)),
        RF_MDMCFG3_OFF,         (DRATE_M << RF_MDMCFG3_DRATE_M_SHIFT),
-       RF_MDMCFG2_OFF,         (RF_MDMCFG2_DEM_DCFILT_OFF |
+       RF_MDMCFG2_OFF,         (RF_MDMCFG2_DEM_DCFILT_ON |
                                 RF_MDMCFG2_MOD_FORMAT_GFSK |
-                                RF_MDMCFG2_SYNC_MODE_15_16_THRES),
+                                RF_MDMCFG2_SYNC_MODE_15_16),
        RF_MDMCFG1_OFF,         (RF_MDMCFG1_FEC_EN |
                                 RF_MDMCFG1_NUM_PREAMBLE_4 |
                                 (2 << RF_MDMCFG1_CHANSPC_E_SHIFT)),
@@ -246,6 +255,18 @@ __xdata uint8_t ao_radio_done;
 __xdata uint8_t ao_radio_abort;
 __xdata uint8_t ao_radio_mutex;
 
+#if PACKET_HAS_MASTER || HAS_AES
+#define NEED_RADIO_RSSI 1
+#endif
+
+#ifndef NEED_RADIO_RSSI
+#define NEED_RADIO_RSSI 0
+#endif
+
+#if NEED_RADIO_RSSI
+__xdata int8_t ao_radio_rssi;
+#endif
+
 void
 ao_radio_general_isr(void) __interrupt 16
 {
@@ -260,7 +281,7 @@ ao_radio_general_isr(void) __interrupt 16
        }
 }
 
-void
+static void
 ao_radio_set_packet(void)
 {
        uint8_t i;
@@ -268,7 +289,7 @@ ao_radio_set_packet(void)
                RF[fixed_pkt_setup[i]] = fixed_pkt_setup[i+1];
 }
 
-void
+static void
 ao_radio_idle(void)
 {
        if (RF_MARCSTATE != RF_MARCSTATE_IDLE)
@@ -280,13 +301,15 @@ ao_radio_idle(void)
        }
 }
 
-void
+#define ao_radio_put() ao_mutex_put(&ao_radio_mutex)
+
+static void
 ao_radio_get(uint8_t len)
 {
        ao_config_get();
        ao_mutex_get(&ao_radio_mutex);
        ao_radio_idle();
-       RF_CHANNR = ao_config.radio_channel;
+       RF_CHANNR = 0;
        RF_FREQ2 = (uint8_t) (ao_config.radio_setting >> 16);
        RF_FREQ1 = (uint8_t) (ao_config.radio_setting >> 8);
        RF_FREQ0 = (uint8_t) (ao_config.radio_setting);
@@ -317,7 +340,7 @@ ao_radio_send(__xdata void *packet, uint8_t size) __reentrant
 }
 
 uint8_t
-ao_radio_recv(__xdata void *packet, uint8_t size) __reentrant
+ao_radio_recv(__xdata void *packet, uint8_t size, uint8_t timeout) __reentrant
 {
        ao_radio_abort = 0;
        ao_radio_get(size - 2);
@@ -337,9 +360,13 @@ ao_radio_recv(__xdata void *packet, uint8_t size) __reentrant
        /* Wait for DMA to be done, for the radio receive process to
         * get aborted or for a receive timeout to fire
         */
+       if (timeout)
+               ao_alarm(timeout);
        __critical while (!ao_radio_dma_done && !ao_radio_abort)
                           if (ao_sleep(&ao_radio_dma_done))
                                   break;
+       if (timeout)
+               ao_clear_alarm();
 
        /* If recv was aborted, clean up by stopping the DMA engine
         * and idling the radio
@@ -347,7 +374,14 @@ ao_radio_recv(__xdata void *packet, uint8_t size) __reentrant
        if (!ao_radio_dma_done) {
                ao_dma_abort(ao_radio_dma);
                ao_radio_idle();
+#if NEED_RADIO_RSSI
+               ao_radio_rssi = 0;
+#endif
        }
+#if NEED_RADIO_RSSI
+       else
+               ao_radio_rssi = AO_RSSI_FROM_RADIO(((uint8_t *)packet)[size - 2]);
+#endif
        ao_radio_put();
        return ao_radio_dma_done;
 }
@@ -364,29 +398,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)
@@ -399,6 +426,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)
 {
@@ -408,8 +499,44 @@ ao_radio_rdf_abort(void)
 
 
 /* Output carrier */
+
+static __xdata ao_radio_test_on;
+
 void
-ao_radio_test(void)
+ao_radio_test(uint8_t on)
+{
+       if (on) {
+               if (!ao_radio_test_on) {
+#if HAS_MONITOR
+                       ao_monitor_disable();
+#endif
+#if PACKET_HAS_SLAVE
+                       ao_packet_slave_stop();
+#endif
+#if HAS_PAD
+                       ao_pad_disable();
+#endif
+                       ao_radio_get(0xff);
+                       RFST = RFST_STX;
+                       ao_radio_test_on = 1;
+               }
+       } else  {
+               if (ao_radio_test_on) {
+                       ao_radio_idle();
+                       ao_radio_put();
+                       ao_radio_test_on = 0;
+#if HAS_MONITOR
+                       ao_monitor_enable();
+#endif
+#if HAS_PAD
+                       ao_pad_enable();
+#endif
+               }
+       }
+}
+
+static void
+ao_radio_test_cmd(void)
 {
        uint8_t mode = 2;
        static __xdata radio_on;
@@ -419,31 +546,42 @@ ao_radio_test(void)
                mode = (uint8_t) ao_cmd_lex_u32;
        }
        mode++;
-       if ((mode & 2) && !radio_on) {
-#if HAS_MONITOR
-               ao_set_monitor(0);
-#endif
-#if PACKET_HAS_SLAVE
-               ao_packet_slave_stop();
-#endif
-               ao_radio_get(0xff);
-               RFST = RFST_STX;
-               radio_on = 1;
-       }
+       if ((mode & 2))
+               ao_radio_test(1);
        if (mode == 3) {
                printf ("Hit a character to stop..."); flush();
                getchar();
                putchar('\n');
        }
-       if ((mode & 1) && radio_on) {
-               ao_radio_idle();
-               ao_radio_put();
-               radio_on = 0;
+       if ((mode & 1))
+               ao_radio_test(0);
+}
+
+#if AO_RADIO_REG_TEST
+static void
+ao_radio_set_reg(void)
+{
+       uint8_t offset;
+       ao_cmd_hex();
+       offset = ao_cmd_lex_i;
+       if (ao_cmd_status != ao_cmd_success)
+               return;
+       ao_cmd_hex();
+       printf("RF[%x] %x", offset, RF[offset]);
+       if (ao_cmd_status == ao_cmd_success) {
+               RF[offset] = ao_cmd_lex_i;
+               printf (" -> %x", RF[offset]);
        }
+       ao_cmd_status = ao_cmd_success;
+       printf("\n");
 }
+#endif
 
 __code struct ao_cmds ao_radio_cmds[] = {
-       { ao_radio_test,        "C <1 start, 0 stop, none both>\0Radio carrier test" },
+       { ao_radio_test_cmd,    "C <1 start, 0 stop, none both>\0Radio carrier test" },
+#if AO_RADIO_REG_TEST
+       { ao_radio_set_reg,     "V <offset> <value>\0Set radio register" },
+#endif
        { 0,    NULL },
 };