summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2012-04-17 11:01:18 -0700
committerKeith Packard <keithp@keithp.com>2012-04-17 11:01:18 -0700
commit1489263b895a2a825e29d0560c9b1dbba8a3f431 (patch)
treeac77be0da392ca7a130fa24a6ce050c48022f116 /src
parentcc305ea231ae22278abf91c0d9925f5992945369 (diff)
altos: Starting to write cc1120 driver
This does "something" in radio test mode, appearing to generate a 730MHz signal. Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'src')
-rw-r--r--src/drivers/ao_cc1120.c534
-rw-r--r--src/drivers/ao_cc1120.h320
-rw-r--r--src/drivers/ao_cc1120_CC1120.h191
-rw-r--r--src/drivers/ao_packet.c (renamed from src/cc1111/ao_packet.c)2
-rw-r--r--src/drivers/ao_packet_master.c (renamed from src/cc1111/ao_packet_master.c)0
-rw-r--r--src/drivers/ao_packet_slave.c (renamed from src/cc1111/ao_packet_slave.c)0
-rw-r--r--src/megametrum-v0.1/Makefile5
-rw-r--r--src/megametrum-v0.1/ao_megametrum.c5
-rw-r--r--src/megametrum-v0.1/ao_pins.h13
-rw-r--r--src/stm/Makefile.defs2
-rw-r--r--src/stm/ao_arch_funcs.h44
-rw-r--r--src/stm/ao_dma_stm.c1
-rw-r--r--src/stm/ao_exti.h38
-rw-r--r--src/stm/ao_exti_stm.c109
-rw-r--r--src/stm/ao_spi_stm.c113
-rw-r--r--src/stm/ao_usb_stm.c4
-rw-r--r--src/stm/stm32l.h16
17 files changed, 1373 insertions, 24 deletions
diff --git a/src/drivers/ao_cc1120.c b/src/drivers/ao_cc1120.c
index 9470fa87..272371d0 100644
--- a/src/drivers/ao_cc1120.c
+++ b/src/drivers/ao_cc1120.c
@@ -16,10 +16,544 @@
*/
#include <ao.h>
+#include <ao_cc1120.h>
+#include <ao_exti.h>
+
+uint8_t ao_radio_done;
+uint8_t ao_radio_mutex;
+uint8_t ao_radio_abort;
+
+#define CC1120_DEBUG 1
uint32_t ao_radio_cal = 1186611;
+#define ao_radio_select() ao_spi_get_mask(AO_CC1120_SPI_CS_PORT,(1 << AO_CC1120_SPI_CS_PIN),AO_CC1120_SPI_BUS)
+#define ao_radio_deselect() ao_spi_put_mask(AO_CC1120_SPI_CS_PORT,(1 << AO_CC1120_SPI_CS_PIN),AO_CC1120_SPI_BUS)
+#define ao_radio_spi_send(d,l) ao_spi_send((d), (l), AO_CC1120_SPI_BUS)
+#define ao_radio_spi_send_fixed(d,l) ao_spi_send_fixed((d), (l), AO_CC1120_SPI_BUS)
+#define ao_radio_spi_recv(d,l) ao_spi_recv((d), (l), AO_CC1120_SPI_BUS)
+#define ao_radio_duplex(o,i,l) ao_spi_duplex((o), (i), (l), AO_CC1120_SPI_BUS)
+
+static uint8_t
+ao_radio_reg_read(uint16_t addr)
+{
+ uint8_t data[2];
+ uint8_t d;
+
+#if CC1120_DEBUG
+ printf("ao_radio_reg_read (%04x): ", addr); flush();
+#endif
+ if (CC1120_IS_EXTENDED(addr)) {
+ data[0] = ((1 << CC1120_READ) |
+ (0 << CC1120_BURST) |
+ CC1120_EXTENDED);
+ data[1] = addr;
+ d = 2;
+ } else {
+ data[0] = ((1 << CC1120_READ) |
+ (0 << CC1120_BURST) |
+ addr);
+ d = 1;
+ }
+ ao_radio_select();
+ ao_radio_spi_send(data, d);
+ ao_radio_spi_recv(data, 1);
+ ao_radio_deselect();
+#if CC1120_DEBUG
+ printf (" %02x\n", data[0]);
+#endif
+ return data[0];
+}
+
+static void
+ao_radio_reg_write(uint16_t addr, uint8_t value)
+{
+ uint8_t data[3];
+ uint8_t d;
+
+#if CC1120_DEBUG
+ printf("ao_radio_reg_write (%04x): %02x\n", addr, value);
+#endif
+ if (CC1120_IS_EXTENDED(addr)) {
+ data[0] = ((1 << CC1120_READ) |
+ (0 << CC1120_BURST) |
+ CC1120_EXTENDED);
+ data[1] = addr;
+ d = 2;
+ } else {
+ data[0] = ((1 << CC1120_READ) |
+ (0 << CC1120_BURST) |
+ addr);
+ d = 1;
+ }
+ data[d] = value;
+ ao_radio_select();
+ ao_radio_spi_send(data, d+1);
+ ao_radio_deselect();
+}
+
+static uint8_t
+ao_radio_strobe(uint8_t addr)
+{
+ uint8_t in;
+
+ ao_radio_select();
+ ao_radio_duplex(&addr, &in, 1);
+ ao_radio_deselect();
+ return in;
+}
+
+static uint8_t
+ao_radio_fifo_read(uint8_t *data, uint8_t len)
+{
+ uint8_t addr = ((1 << CC1120_READ) |
+ (1 << CC1120_BURST) |
+ CC1120_FIFO);
+ uint8_t status;
+
+ ao_radio_select();
+ ao_radio_duplex(&addr, &status, 1);
+ ao_radio_spi_recv(data, len);
+ ao_radio_deselect();
+ return status;
+}
+
+static uint8_t
+ao_radio_fifo_write(uint8_t *data, uint8_t len)
+{
+ uint8_t addr = ((0 << CC1120_READ) |
+ (1 << CC1120_BURST) |
+ CC1120_FIFO);
+ uint8_t status;
+
+ ao_radio_select();
+ ao_radio_duplex(&addr, &status, 1);
+ ao_radio_spi_send(data, len);
+ ao_radio_deselect();
+ return status;
+}
+
+static uint8_t
+ao_radio_fifo_write_fixed(uint8_t data, uint8_t len)
+{
+ uint8_t addr = ((0 << CC1120_READ) |
+ (1 << CC1120_BURST) |
+ CC1120_FIFO);
+ uint8_t status;
+
+ ao_radio_select();
+ ao_radio_duplex(&addr, &status, 1);
+ ao_radio_spi_send_fixed(data, len);
+ ao_radio_deselect();
+ return status;
+}
+
+static uint8_t
+ao_radio_status(void)
+{
+ return ao_radio_strobe (CC1120_SNOP);
+}
+
void
ao_radio_recv_abort(void)
{
+ ao_radio_abort = 1;
+ ao_wakeup(&ao_radio_done);
+}
+
+#define ao_radio_rdf_value 0x55
+
+static const uint16_t rdf_setup[] = {
+};
+
+void
+ao_radio_rdf(uint8_t len)
+{
+ int i;
+
+ ao_radio_abort = 0;
+ ao_radio_get(len);
+ ao_radio_done = 0;
+ for (i = 0; i < sizeof (rdf_setup) / sizeof (rdf_setup[0]); i += 2)
+ ao_radio_reg_write(rdf_setup[i], rdf_setup[i+1]);
+ ao_radio_fifo_write_fixed(ao_radio_rdf_value, len);
+ ao_radio_reg_write(CC1120_IOCFG2, CC1120_IOCFG_GPIO_CFG_RX0TX1_CFG);
+ ao_exti_enable(&AO_CC1120_INT_PORT, AO_CC1120_INT_PIN);
+ ao_radio_strobe(CC1120_STX);
+ cli();
+ while (!ao_radio_done)
+ ao_sleep(&ao_radio_done);
+ sei();
+ ao_radio_set_packet();
+ ao_radio_put();
+}
+
+void
+ao_radio_rdf_abort(void)
+{
+}
+
+static void
+ao_radio_test(void)
+{
+ uint8_t mode = 2;
+ uint8_t radio_on;
+ ao_cmd_white();
+ if (ao_cmd_lex_c != '\n') {
+ ao_cmd_decimal();
+ mode = (uint8_t) ao_cmd_lex_u32;
+ }
+ mode++;
+ if ((mode & 2) && !radio_on) {
+#if HAS_MONITOR
+ ao_monitor_disable();
+#endif
+#if PACKET_HAS_SLAVE
+ ao_packet_slave_stop();
+#endif
+ ao_radio_get(0xff);
+ ao_radio_strobe(CC1120_STX);
+ radio_on = 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 HAS_MONITOR
+ ao_monitor_enable();
+#endif
+ }
+}
+
+void
+ao_radio_send(void *d, uint8_t size)
+{
+ ao_radio_get(size);
+ ao_radio_done = 0;
+ ao_radio_fifo_write(d, size);
+ ao_radio_reg_write(CC1120_IOCFG2, CC1120_IOCFG_GPIO_CFG_RX0TX1_CFG);
+ ao_exti_enable(&AO_CC1120_INT_PORT, AO_CC1120_INT_PIN);
+ ao_radio_strobe(CC1120_STX);
+ cli();
+ while (!ao_radio_done)
+ ao_sleep(&ao_radio_done);
+ sei();
+ ao_radio_put();
+}
+
+uint8_t
+ao_radio_recv(__xdata void *d, uint8_t size)
+{
+ /* configure interrupt pin */
+ ao_radio_get(size);
+ ao_radio_done = 0;
+ ao_radio_reg_write(CC1120_IOCFG2, CC1120_IOCFG_GPIO_CFG_RXFIFO_THR_PKT);
+ ao_exti_enable(&AO_CC1120_INT_PORT, AO_CC1120_INT_PIN);
+ ao_radio_strobe(CC1120_SRX);
+ cli();
+ while (!ao_radio_done && !ao_radio_abort)
+ ao_sleep(&ao_radio_done);
+ sei();
+ if (ao_radio_done)
+ ao_radio_fifo_read(d, size);
+ ao_radio_put();
+ return 0;
+}
+
+static const uint16_t packet_setup[] = {
+};
+
+void
+ao_radio_set_packet(void)
+{
+ int i;
+
+ for (i = 0; i < sizeof (rdf_setup) / sizeof (rdf_setup[0]); i += 2)
+ ao_radio_reg_write(packet_setup[i], packet_setup[i+1]);
+}
+
+void
+ao_radio_idle(void)
+{
+ for (;;) {
+ uint8_t state = ao_radio_strobe(CC1120_SIDLE);
+ if ((state >> CC1120_STATUS_STATE) == CC1120_STATUS_STATE_IDLE)
+ break;
+ }
+}
+
+static const uint16_t radio_setup[] = {
+#include "ao_cc1120_CC1120.h"
+};
+
+static uint8_t ao_radio_configured = 0;
+
+static void
+ao_radio_isr(void)
+{
+ ao_exti_disable(&AO_CC1120_INT_PORT, AO_CC1120_INT_PIN);
+ ao_radio_done = 1;
+ ao_wakeup(&ao_radio_done);
+}
+
+static void
+ao_radio_setup(void)
+{
+ int i;
+
+ for (i = 0; i < sizeof (radio_setup) / sizeof (radio_setup[0]); i += 2)
+ ao_radio_reg_write(radio_setup[i], radio_setup[i+1]);
+
+ /* Disable GPIO2 pin (radio_int) */
+ ao_radio_reg_write(CC1120_IOCFG2, CC1120_IOCFG_GPIO_CFG_HIGHZ);
+
+ /* Enable the EXTI interrupt for the appropriate pin */
+ ao_enable_port(AO_CC1120_INT_PORT);
+ ao_exti_setup(&AO_CC1120_INT_PORT, AO_CC1120_INT_PIN, AO_EXTI_MODE_RISING, ao_radio_isr);
+
+ ao_radio_set_packet();
+ ao_radio_configured = 1;
+}
+
+void
+ao_radio_get(uint8_t len)
+{
+ ao_mutex_get(&ao_radio_mutex);
+ if (!ao_radio_configured)
+ ao_radio_setup();
+ ao_radio_reg_write(CC1120_PKT_LEN, len);
+}
+
+#if CC1120_DEBUG
+static char *cc1120_state_name[] = {
+ [CC1120_STATUS_STATE_IDLE] = "IDLE",
+ [CC1120_STATUS_STATE_RX] = "RX",
+ [CC1120_STATUS_STATE_TX] = "TX",
+ [CC1120_STATUS_STATE_FSTXON] = "FSTXON",
+ [CC1120_STATUS_STATE_CALIBRATE] = "CALIBRATE",
+ [CC1120_STATUS_STATE_SETTLING] = "SETTLING",
+ [CC1120_STATUS_STATE_RX_FIFO_ERROR] = "RX_FIFO_ERROR",
+ [CC1120_STATUS_STATE_TX_FIFO_ERROR] = "TX_FIFO_ERROR",
+};
+
+struct ao_cc1120_reg {
+ uint16_t addr;
+ char *name;
+};
+
+const static struct ao_cc1120_reg ao_cc1120_reg[] = {
+ { .addr = CC1120_IOCFG3, .name = "IOCFG3" },
+ { .addr = CC1120_IOCFG2, .name = "IOCFG2" },
+ { .addr = CC1120_IOCFG1, .name = "IOCFG1" },
+ { .addr = CC1120_IOCFG0, .name = "IOCFG0" },
+ { .addr = CC1120_SYNC3, .name = "SYNC3" },
+ { .addr = CC1120_SYNC2, .name = "SYNC2" },
+ { .addr = CC1120_SYNC1, .name = "SYNC1" },
+ { .addr = CC1120_SYNC0, .name = "SYNC0" },
+ { .addr = CC1120_SYNC_CFG1, .name = "SYNC_CFG1" },
+ { .addr = CC1120_SYNC_CFG0, .name = "SYNC_CFG0" },
+ { .addr = CC1120_DEVIATION_M, .name = "DEVIATION_M" },
+ { .addr = CC1120_MODCFG_DEV_E, .name = "MODCFG_DEV_E" },
+ { .addr = CC1120_DCFILT_CFG, .name = "DCFILT_CFG" },
+ { .addr = CC1120_PREAMBLE_CFG1, .name = "PREAMBLE_CFG1" },
+ { .addr = CC1120_PREAMBLE_CFG0, .name = "PREAMBLE_CFG0" },
+ { .addr = CC1120_FREQ_IF_CFG, .name = "FREQ_IF_CFG" },
+ { .addr = CC1120_IQIC, .name = "IQIC" },
+ { .addr = CC1120_CHAN_BW, .name = "CHAN_BW" },
+ { .addr = CC1120_MDMCFG1, .name = "MDMCFG1" },
+ { .addr = CC1120_MDMCFG0, .name = "MDMCFG0" },
+ { .addr = CC1120_DRATE2, .name = "DRATE2" },
+ { .addr = CC1120_DRATE1, .name = "DRATE1" },
+ { .addr = CC1120_DRATE0, .name = "DRATE0" },
+ { .addr = CC1120_AGC_REF, .name = "AGC_REF" },
+ { .addr = CC1120_AGC_CS_THR, .name = "AGC_CS_THR" },
+ { .addr = CC1120_AGC_GAIN_ADJUST, .name = "AGC_GAIN_ADJUST" },
+ { .addr = CC1120_AGC_CFG3, .name = "AGC_CFG3" },
+ { .addr = CC1120_AGC_CFG2, .name = "AGC_CFG2" },
+ { .addr = CC1120_AGC_CFG1, .name = "AGC_CFG1" },
+ { .addr = CC1120_AGC_CFG0, .name = "AGC_CFG0" },
+ { .addr = CC1120_FIFO_CFG, .name = "FIFO_CFG" },
+ { .addr = CC1120_DEV_ADDR, .name = "DEV_ADDR" },
+ { .addr = CC1120_SETTLING_CFG, .name = "SETTLING_CFG" },
+ { .addr = CC1120_FS_CFG, .name = "FS_CFG" },
+ { .addr = CC1120_WOR_CFG1, .name = "WOR_CFG1" },
+ { .addr = CC1120_WOR_CFG0, .name = "WOR_CFG0" },
+ { .addr = CC1120_WOR_EVENT0_MSB, .name = "WOR_EVENT0_MSB" },
+ { .addr = CC1120_WOR_EVENT0_LSB, .name = "WOR_EVENT0_LSB" },
+ { .addr = CC1120_PKT_CFG2, .name = "PKT_CFG2" },
+ { .addr = CC1120_PKT_CFG1, .name = "PKT_CFG1" },
+ { .addr = CC1120_PKT_CFG0, .name = "PKT_CFG0" },
+ { .addr = CC1120_RFEND_CFG1, .name = "RFEND_CFG1" },
+ { .addr = CC1120_RFEND_CFG0, .name = "RFEND_CFG0" },
+ { .addr = CC1120_PA_CFG2, .name = "PA_CFG2" },
+ { .addr = CC1120_PA_CFG1, .name = "PA_CFG1" },
+ { .addr = CC1120_PA_CFG0, .name = "PA_CFG0" },
+ { .addr = CC1120_PKT_LEN, .name = "PKT_LEN" },
+ { .addr = CC1120_IF_MIX_CFG, .name = "IF_MIX_CFG" },
+ { .addr = CC1120_FREQOFF_CFG, .name = "FREQOFF_CFG" },
+ { .addr = CC1120_TOC_CFG, .name = "TOC_CFG" },
+ { .addr = CC1120_MARC_SPARE, .name = "MARC_SPARE" },
+ { .addr = CC1120_ECG_CFG, .name = "ECG_CFG" },
+ { .addr = CC1120_SOFT_TX_DATA_CFG, .name = "SOFT_TX_DATA_CFG" },
+ { .addr = CC1120_EXT_CTRL, .name = "EXT_CTRL" },
+ { .addr = CC1120_RCCAL_FINE, .name = "RCCAL_FINE" },
+ { .addr = CC1120_RCCAL_COARSE, .name = "RCCAL_COARSE" },
+ { .addr = CC1120_RCCAL_OFFSET, .name = "RCCAL_OFFSET" },
+ { .addr = CC1120_FREQOFF1, .name = "FREQOFF1" },
+ { .addr = CC1120_FREQOFF0, .name = "FREQOFF0" },
+ { .addr = CC1120_FREQ2, .name = "FREQ2" },
+ { .addr = CC1120_FREQ1, .name = "FREQ1" },
+ { .addr = CC1120_FREQ0, .name = "FREQ0" },
+ { .addr = CC1120_IF_ADC2, .name = "IF_ADC2" },
+ { .addr = CC1120_IF_ADC1, .name = "IF_ADC1" },
+ { .addr = CC1120_IF_ADC0, .name = "IF_ADC0" },
+ { .addr = CC1120_FS_DIG1, .name = "FS_DIG1" },
+ { .addr = CC1120_FS_DIG0, .name = "FS_DIG0" },
+ { .addr = CC1120_FS_CAL3, .name = "FS_CAL3" },
+ { .addr = CC1120_FS_CAL2, .name = "FS_CAL2" },
+ { .addr = CC1120_FS_CAL1, .name = "FS_CAL1" },
+ { .addr = CC1120_FS_CAL0, .name = "FS_CAL0" },
+ { .addr = CC1120_FS_CHP, .name = "FS_CHP" },
+ { .addr = CC1120_FS_DIVTWO, .name = "FS_DIVTWO" },
+ { .addr = CC1120_FS_DSM1, .name = "FS_DSM1" },
+ { .addr = CC1120_FS_DSM0, .name = "FS_DSM0" },
+ { .addr = CC1120_FS_DVC1, .name = "FS_DVC1" },
+ { .addr = CC1120_FS_DVC0, .name = "FS_DVC0" },
+ { .addr = CC1120_FS_LBI, .name = "FS_LBI" },
+ { .addr = CC1120_FS_PFD, .name = "FS_PFD" },
+ { .addr = CC1120_FS_PRE, .name = "FS_PRE" },
+ { .addr = CC1120_FS_REG_DIV_CML, .name = "FS_REG_DIV_CML" },
+ { .addr = CC1120_FS_SPARE, .name = "FS_SPARE" },
+ { .addr = CC1120_FS_VCO4, .name = "FS_VCO4" },
+ { .addr = CC1120_FS_VCO3, .name = "FS_VCO3" },
+ { .addr = CC1120_FS_VCO2, .name = "FS_VCO2" },
+ { .addr = CC1120_FS_VCO1, .name = "FS_VCO1" },
+ { .addr = CC1120_FS_VCO0, .name = "FS_VCO0" },
+ { .addr = CC1120_GBIAS6, .name = "GBIAS6" },
+ { .addr = CC1120_GBIAS5, .name = "GBIAS5" },
+ { .addr = CC1120_GBIAS4, .name = "GBIAS4" },
+ { .addr = CC1120_GBIAS3, .name = "GBIAS3" },
+ { .addr = CC1120_GBIAS2, .name = "GBIAS2" },
+ { .addr = CC1120_GBIAS1, .name = "GBIAS1" },
+ { .addr = CC1120_GBIAS0, .name = "GBIAS0" },
+ { .addr = CC1120_IFAMP, .name = "IFAMP" },
+ { .addr = CC1120_LNA, .name = "LNA" },
+ { .addr = CC1120_RXMIX, .name = "RXMIX" },
+ { .addr = CC1120_XOSC5, .name = "XOSC5" },
+ { .addr = CC1120_XOSC4, .name = "XOSC4" },
+ { .addr = CC1120_XOSC3, .name = "XOSC3" },
+ { .addr = CC1120_XOSC2, .name = "XOSC2" },
+ { .addr = CC1120_XOSC1, .name = "XOSC1" },
+ { .addr = CC1120_XOSC0, .name = "XOSC0" },
+ { .addr = CC1120_ANALOG_SPARE, .name = "ANALOG_SPARE" },
+ { .addr = CC1120_PA_CFG3, .name = "PA_CFG3" },
+ { .addr = CC1120_WOR_TIME1, .name = "WOR_TIME1" },
+ { .addr = CC1120_WOR_TIME0, .name = "WOR_TIME0" },
+ { .addr = CC1120_WOR_CAPTURE1, .name = "WOR_CAPTURE1" },
+ { .addr = CC1120_WOR_CAPTURE0, .name = "WOR_CAPTURE0" },
+ { .addr = CC1120_BIST, .name = "BIST" },
+ { .addr = CC1120_DCFILTOFFSET_I1, .name = "DCFILTOFFSET_I1" },
+ { .addr = CC1120_DCFILTOFFSET_I0, .name = "DCFILTOFFSET_I0" },
+ { .addr = CC1120_DCFILTOFFSET_Q1, .name = "DCFILTOFFSET_Q1" },
+ { .addr = CC1120_DCFILTOFFSET_Q0, .name = "DCFILTOFFSET_Q0" },
+ { .addr = CC1120_IQIE_I1, .name = "IQIE_I1" },
+ { .addr = CC1120_IQIE_I0, .name = "IQIE_I0" },
+ { .addr = CC1120_IQIE_Q1, .name = "IQIE_Q1" },
+ { .addr = CC1120_IQIE_Q0, .name = "IQIE_Q0" },
+ { .addr = CC1120_RSSI1, .name = "RSSI1" },
+ { .addr = CC1120_RSSI0, .name = "RSSI0" },
+ { .addr = CC1120_MARCSTATE, .name = "MARCSTATE" },
+ { .addr = CC1120_LQI_VAL, .name = "LQI_VAL" },
+ { .addr = CC1120_PQT_SYNC_ERR, .name = "PQT_SYNC_ERR" },
+ { .addr = CC1120_DEM_STATUS, .name = "DEM_STATUS" },
+ { .addr = CC1120_FREQOFF_EST1, .name = "FREQOFF_EST1" },
+ { .addr = CC1120_FREQOFF_EST0, .name = "FREQOFF_EST0" },
+ { .addr = CC1120_AGC_GAIN3, .name = "AGC_GAIN3" },
+ { .addr = CC1120_AGC_GAIN2, .name = "AGC_GAIN2" },
+ { .addr = CC1120_AGC_GAIN1, .name = "AGC_GAIN1" },
+ { .addr = CC1120_AGC_GAIN0, .name = "AGC_GAIN0" },
+ { .addr = CC1120_SOFT_RX_DATA_OUT, .name = "SOFT_RX_DATA_OUT" },
+ { .addr = CC1120_SOFT_TX_DATA_IN, .name = "SOFT_TX_DATA_IN" },
+ { .addr = CC1120_ASK_SOFT_RX_DATA, .name = "ASK_SOFT_RX_DATA" },
+ { .addr = CC1120_RNDGEN, .name = "RNDGEN" },
+ { .addr = CC1120_MAGN2, .name = "MAGN2" },
+ { .addr = CC1120_MAGN1, .name = "MAGN1" },
+ { .addr = CC1120_MAGN0, .name = "MAGN0" },
+ { .addr = CC1120_ANG1, .name = "ANG1" },
+ { .addr = CC1120_ANG0, .name = "ANG0" },
+ { .addr = CC1120_CHFILT_I2, .name = "CHFILT_I2" },
+ { .addr = CC1120_CHFILT_I1, .name = "CHFILT_I1" },
+ { .addr = CC1120_CHFILT_I0, .name = "CHFILT_I0" },
+ { .addr = CC1120_CHFILT_Q2, .name = "CHFILT_Q2" },
+ { .addr = CC1120_CHFILT_Q1, .name = "CHFILT_Q1" },
+ { .addr = CC1120_CHFILT_Q0, .name = "CHFILT_Q0" },
+ { .addr = CC1120_GPIO_STATUS, .name = "GPIO_STATUS" },
+ { .addr = CC1120_FSCAL_CTRL, .name = "FSCAL_CTRL" },
+ { .addr = CC1120_PHASE_ADJUST, .name = "PHASE_ADJUST" },
+ { .addr = CC1120_PARTNUMBER, .name = "PARTNUMBER" },
+ { .addr = CC1120_PARTVERSION, .name = "PARTVERSION" },
+ { .addr = CC1120_SERIAL_STATUS, .name = "SERIAL_STATUS" },
+ { .addr = CC1120_RX_STATUS, .name = "RX_STATUS" },
+ { .addr = CC1120_TX_STATUS, .name = "TX_STATUS" },
+ { .addr = CC1120_MARC_STATUS1, .name = "MARC_STATUS1" },
+ { .addr = CC1120_MARC_STATUS0, .name = "MARC_STATUS0" },
+ { .addr = CC1120_PA_IFAMP_TEST, .name = "PA_IFAMP_TEST" },
+ { .addr = CC1120_FSRF_TEST, .name = "FSRF_TEST" },
+ { .addr = CC1120_PRE_TEST, .name = "PRE_TEST" },
+ { .addr = CC1120_PRE_OVR, .name = "PRE_OVR" },
+ { .addr = CC1120_ADC_TEST, .name = "ADC_TEST" },
+ { .addr = CC1120_DVC_TEST, .name = "DVC_TEST" },
+ { .addr = CC1120_ATEST, .name = "ATEST" },
+ { .addr = CC1120_ATEST_LVDS, .name = "ATEST_LVDS" },
+ { .addr = CC1120_ATEST_MODE, .name = "ATEST_MODE" },
+ { .addr = CC1120_XOSC_TEST1, .name = "XOSC_TEST1" },
+ { .addr = CC1120_XOSC_TEST0, .name = "XOSC_TEST0" },
+ { .addr = CC1120_RXFIRST, .name = "RXFIRST" },
+ { .addr = CC1120_TXFIRST, .name = "TXFIRST" },
+ { .addr = CC1120_RXLAST, .name = "RXLAST" },
+ { .addr = CC1120_TXLAST, .name = "TXLAST" },
+ { .addr = CC1120_NUM_TXBYTES, .name = "NUM_TXBYTES" },
+ { .addr = CC1120_NUM_RXBYTES, .name = "NUM_RXBYTES" },
+ { .addr = CC1120_FIFO_NUM_TXBYTES, .name = "FIFO_NUM_TXBYTES" },
+ { .addr = CC1120_FIFO_NUM_RXBYTES, .name = "FIFO_NUM_RXBYTES" },
+};
+
+#define AO_NUM_CC1120_REG (sizeof ao_cc1120_reg / sizeof ao_cc1120_reg[0])
+
+static void ao_radio_show(void) {
+ uint8_t status = ao_radio_status();
+ int i;
+
+ ao_radio_get(0xff);
+ status = ao_radio_status();
+ printf ("Status: %02x\n", status);
+ printf ("CHIP_RDY: %d\n", (status >> CC1120_STATUS_CHIP_RDY) & 1);
+ printf ("STATE: %s\n", cc1120_state_name[(status >> CC1120_STATUS_STATE) & CC1120_STATUS_STATE_MASK]);
+
+ for (i = 0; i < AO_NUM_CC1120_REG; i++)
+ printf ("\t%02x %-20.20s\n", ao_radio_reg_read(ao_cc1120_reg[i].addr), ao_cc1120_reg[i].name);
+ ao_radio_put();
+}
+#endif
+
+static const struct ao_cmds ao_radio_cmds[] = {
+ { ao_radio_test, "C <1 start, 0 stop, none both>\0Radio carrier test" },
+#if CC1120_DEBUG
+ { ao_radio_show, "R\0Show CC1120 status" },
+#endif
+ { 0, NULL }
+};
+
+void
+ao_radio_init(void)
+{
+ ao_radio_configured = 0;
+ ao_spi_init_cs (AO_CC1120_SPI_CS_PORT, (1 << AO_CC1120_SPI_CS_PIN));
+
+ ao_cmd_register(&ao_radio_cmds[0]);
}
diff --git a/src/drivers/ao_cc1120.h b/src/drivers/ao_cc1120.h
new file mode 100644
index 00000000..67c0a1b8
--- /dev/null
+++ b/src/drivers/ao_cc1120.h
@@ -0,0 +1,320 @@
+/*
+ * Copyright © 2012 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#ifndef _AO_CC1120_H_
+#define _AO_CC1120_H_
+
+#define CC1120_READ (7)
+#define CC1120_BURST (6)
+
+/* Register space */
+#define CC1120_IOCFG3 0x00
+#define CC1120_IOCFG_GPIO_ATRAN 7
+#define CC1120_IOCFG_GPIO_INV 6
+#define CC1120_IOCFG_GPIO_CFG 0
+#define CC1120_IOCFG_GPIO_CFG_RXFIFO_THR 0
+#define CC1120_IOCFG_GPIO_CFG_RXFIFO_THR_PKT 1
+#define CC1120_IOCFG_GPIO_CFG_TXFIFO_THR 2
+#define CC1120_IOCFG_GPIO_CFG_TXFIFO_THR_PKT 3
+#define CC1120_IOCFG_GPIO_CFG_RXFIFO_OVERFLOW 4
+#define CC1120_IOCFG_GPIO_CFG_TXFIFO_UNDERFLOW 5
+#define CC1120_IOCFG_GPIO_CFG_PKT_SYNC_RXTX 6
+#define CC1120_IOCFG_GPIO_CFG_CRC_OK 7
+#define CC1120_IOCFG_GPIO_CFG_SERIAL_CLK 8
+#define CC1120_IOCFG_GPIO_CFG_SERIAL_RX 9
+#define CC1120_IOCFG_GPIO_CFG_PQT_REACHED 11
+#define CC1120_IOCFG_GPIO_CFG_PQT_VALID 12
+#define CC1120_IOCFG_GPIO_CFG_RSSI_VALID 13
+#define CC1120_IOCFG_GPIO3_CFG_RSSI_UPDATE 14
+#define CC1120_IOCFG_GPIO2_CFG_RSSI_UPDATE 14
+#define CC1120_IOCFG_GPIO1_CFG_AGC_HOLD 14
+#define CC1120_IOCFG_GPIO0_CFG_AGC_UPDATE 14
+#define CC1120_IOCFG_GPIO3_CFG_CGA_STATUS 15
+#define CC1120_IOCFG_GPIO2_CFG_TXONCCA_DONE 15
+#define CC1120_IOCFG_GPIO1_CFG_CCA_STATUS 15
+#define CC1120_IOCFG_GPIO0_CFG_TXONCCA_FAILED 15
+#define CC1120_IOCFG_GPIO_CFG_CARRIER_SENSE_VALID 16
+#define CC1120_IOCFG_GPIO_CFG_CARRIER_SENSE 17
+#define CC1120_IOCFG_GPIO3_CFG_DSSS_CLK 18
+#define CC1120_IOCFG_GPIO2_CFG_DSSS_DATA0 18
+#define CC1120_IOCFG_GPIO1_CFG_DSSS_CLK 18
+#define CC1120_IOCFG_GPIO0_CFG_DSSS_DATA1 18
+#define CC1120_IOCFG_GPIO_CFG_PKT_CRC_OK 19
+#define CC1120_IOCFG_GPIO_CFG_MARC_MCU_WAKEUP 20
+#define CC1120_IOCFG_GPIO_CFG_SYNC_LOW0_HIGH1 21
+#define CC1120_IOCFG_GPIO_CFG_LNA_PA_REG_PD 23
+#define CC1120_IOCFG_GPIO_CFG_LNA_PD 24
+#define CC1120_IOCFG_GPIO_CFG_PA_RD 25
+#define CC1120_IOCFG_GPIO_CFG_RX0TX1_CFG 26
+#define CC1120_IOCFG_GPIO_CFG_IMAGE_FOUND 28
+#define CC1120_IOCFG_GPIO_CFG_CLKEN_SOFT 29
+#define CC1120_IOCFG_GPIO_CFG_SOFT_TX_DATA_CLK 30
+#define CC1120_IOCFG_GPIO_CFG_RSSI_STEP_FOUND 33
+#define CC1120_IOCFG_GPIO_CFG_RSSI_STEP_EVENT 34
+#define CC1120_IOCFG_GPIO_CFG_ANTENNA_SELECT 36
+#define CC1120_IOCFG_GPIO_CFG_MARC_2PIN_STATUS1 37
+#define CC1120_IOCFG_GPIO_CFG_MARC_2PIN_STATUS0 38
+#define CC1120_IOCFG_GPIO2_CFG_TXFIFO_OVERFLOW 39
+#define CC1120_IOCFG_GPIO0_CFG_RXFIFO_UNDERFLOW 39
+#define CC1120_IOCFG_GPIO3_CFG_MAGN_VALID 40
+#define CC1120_IOCFG_GPIO2_CFG_CHFILT_VALID 40
+#define CC1120_IOCFG_GPIO1_CFG_RCC_CAL_VALID 40
+#define CC1120_IOCFG_GPIO0_CFG_CHFILTER_STARTUP_VALID 40
+#define CC1120_IOCFG_GPIO3_CFG_COLLISION_FOUND 41
+#define CC1120_IOCFG_GPIO2_CFG_SYNC_EVENT 41
+#define CC1120_IOCFG_GPIO1_CFG_COLLISION_FOUND 41
+#define CC1120_IOCFG_GPIO0_CFG_COLLISION_EVENT 41
+#define CC1120_IOCFG_GPIO_CFG_PA_RAMP_UP 42
+#define CC1120_IOCFG_GPIO3_CFG_CRC_FAILED 43
+#define CC1120_IOCFG_GPIO2_CFG_LENGTH_FAILED 43
+#define CC1120_IOCFG_GPIO1_CFG_ADDR_FAILED 43
+#define CC1120_IOCFG_GPIO0_CFG_UART_FRAMING_ERROR 43
+#define CC1120_IOCFG_GPIO_CFG_AGC_STABLE_GAIN 44
+#define CC1120_IOCFG_GPIO_CFG_AGC_UPDATE 45
+#define CC1120_IOCFG_GPIO3_CFG_ADC_CLOCK 46
+#define CC1120_IOCFG_GPIO2_CFG_ADC_Q_DATA_SAMPLE 46
+#define CC1120_IOCFG_GPIO1_CFG_ADC_CLOCK 46
+#define CC1120_IOCFG_GPIO0_CFG_ADC_I_DATA_SAMPLE 46
+#define CC1120_IOCFG_GPIO_CFG_HIGHZ 48
+#define CC1120_IOCFG_GPIO_CFG_EXT_CLOCK 49
+#define CC1120_IOCFG_GPIO_CFG_CHIP_RDY 50
+#define CC1120_IOCFG_GPIO_CFG_HW0 51
+#define CC1120_IOCFG_GPIO_CFG_CLOCK_32K 54
+#define CC1120_IOCFG_GPIO_CFG_WOR_EVENT0 55
+#define CC1120_IOCFG_GPIO_CFG_WOR_EVENT1 56
+#define CC1120_IOCFG_GPIO_CFG_WOR_EVENT2 57
+#define CC1120_IOCFG_GPIO_CFG_XOSC_STABLE 59
+#define CC1120_IOCFG_GPIO_CFG_EXT_OSC_EN 60
+#define CC1120_IOCFG_GPIO_CFG_MASK 0x3f
+
+#define CC1120_IOCFG3 0x00
+#define CC1120_IOCFG2 0x01
+#define CC1120_IOCFG1 0x02
+#define CC1120_IOCFG0 0x03
+#define CC1120_SYNC3 0x04
+#define CC1120_SYNC2 0x05
+#define CC1120_SYNC1 0x06
+#define CC1120_SYNC0 0x07
+#define CC1120_SYNC_CFG1 0x08
+#define CC1120_SYNC_CFG0 0x09
+#define CC1120_DEVIATION_M 0x0a
+#define CC1120_MODCFG_DEV_E 0x0b
+#define CC1120_DCFILT_CFG 0x0c
+#define CC1120_PREAMBLE_CFG1 0x0d
+#define CC1120_PREAMBLE_CFG0 0x0e
+#define CC1120_FREQ_IF_CFG 0x0f
+#define CC1120_IQIC 0x10
+#define CC1120_CHAN_BW 0x11
+#define CC1120_MDMCFG1 0x12
+#define CC1120_MDMCFG0 0x13
+#define CC1120_DRATE2 0x14
+#define CC1120_DRATE1 0x15
+#define CC1120_DRATE0 0x16
+#define CC1120_AGC_REF 0x17
+#define CC1120_AGC_CS_THR 0x18
+#define CC1120_AGC_GAIN_ADJUST 0x19
+#define CC1120_AGC_CFG3 0x1a
+#define CC1120_AGC_CFG2 0x1b
+#define CC1120_AGC_CFG1 0x1c
+#define CC1120_AGC_CFG0 0x1d
+#define CC1120_FIFO_CFG 0x1e
+#define CC1120_DEV_ADDR 0x1f
+#define CC1120_SETTLING_CFG 0x20
+#define CC1120_FS_CFG 0x21
+#define CC1120_WOR_CFG1 0x22
+#define CC1120_WOR_CFG0 0x23
+#define CC1120_WOR_EVENT0_MSB 0x24
+#define CC1120_WOR_EVENT0_LSB 0x25
+#define CC1120_PKT_CFG2 0x26
+#define CC1120_PKT_CFG1 0x27
+#define CC1120_PKT_CFG0 0x28
+#define CC1120_RFEND_CFG1 0x29
+#define CC1120_RFEND_CFG0 0x2a
+#define CC1120_PA_CFG2 0x2b
+#define CC1120_PA_CFG1 0x2c
+#define CC1120_PA_CFG0 0x2d
+#define CC1120_PKT_LEN 0x2e
+
+#define CC1120_EXTENDED 0x2f
+
+/* Command strobes */
+#define CC1120_SRES 0x30
+#define CC1120_SFSTXON 0x31
+#define CC1120_SXOFF 0x32
+#define CC1120_SCAL 0x33
+#define CC1120_SRX 0x34
+#define CC1120_STX 0x35
+#define CC1120_SIDLE 0x36
+#define CC1120_SAFC 0x37
+#define CC1120_SWOR 0x38
+#define CC1120_SPWD 0x39
+#define CC1120_SFRX 0x3a
+#define CC1120_SFTX 0x3b
+#define CC1120_SWORRST 0x3c
+#define CC1120_SNOP 0x3d
+
+#define CC1120_DIRECT_FIFO 0x3e
+#define CC1120_FIFO 0x3f
+
+/* Extended register space */
+
+#define CC1120_EXTENDED_BIT 0x8000
+
+#define CC1120_IS_EXTENDED(r) ((r) & CC1120_EXTENDED_BIT)
+
+#define CC1120_IF_MIX_CFG (CC1120_EXTENDED_BIT | 0x00)
+#define CC1120_FREQOFF_CFG (CC1120_EXTENDED_BIT | 0x01)
+#define CC1120_TOC_CFG (CC1120_EXTENDED_BIT | 0x02)
+#define CC1120_MARC_SPARE (CC1120_EXTENDED_BIT | 0x03)
+#define CC1120_ECG_CFG (CC1120_EXTENDED_BIT | 0x04)
+#define CC1120_SOFT_TX_DATA_CFG (CC1120_EXTENDED_BIT | 0x05)
+#define CC1120_EXT_CTRL (CC1120_EXTENDED_BIT | 0x06)
+#define CC1120_RCCAL_FINE (CC1120_EXTENDED_BIT | 0x07)
+#define CC1120_RCCAL_COARSE (CC1120_EXTENDED_BIT | 0x08)
+#define CC1120_RCCAL_OFFSET (CC1120_EXTENDED_BIT | 0x09)
+#define CC1120_FREQOFF1 (CC1120_EXTENDED_BIT | 0x0A)
+#define CC1120_FREQOFF0 (CC1120_EXTENDED_BIT | 0x0B)
+#define CC1120_FREQ2 (CC1120_EXTENDED_BIT | 0x0C)
+#define CC1120_FREQ1 (CC1120_EXTENDED_BIT | 0x0D)
+#define CC1120_FREQ0 (CC1120_EXTENDED_BIT | 0x0E)
+#define CC1120_IF_ADC2 (CC1120_EXTENDED_BIT | 0x0F)
+#define CC1120_IF_ADC1 (CC1120_EXTENDED_BIT | 0x10)
+#define CC1120_IF_ADC0 (CC1120_EXTENDED_BIT | 0x11)
+#define CC1120_FS_DIG1 (CC1120_EXTENDED_BIT | 0x12)
+#define CC1120_FS_DIG0 (CC1120_EXTENDED_BIT | 0x13)
+#define CC1120_FS_CAL3 (CC1120_EXTENDED_BIT | 0x14)
+#define CC1120_FS_CAL2 (CC1120_EXTENDED_BIT | 0x15)
+#define CC1120_FS_CAL1 (CC1120_EXTENDED_BIT | 0x16)
+#define CC1120_FS_CAL0 (CC1120_EXTENDED_BIT | 0x17)
+#define CC1120_FS_CHP (CC1120_EXTENDED_BIT | 0x18)
+#define CC1120_FS_DIVTWO (CC1120_EXTENDED_BIT | 0x19)
+#define CC1120_FS_DSM1 (CC1120_EXTENDED_BIT | 0x1A)
+#define CC1120_FS_DSM0 (CC1120_EXTENDED_BIT | 0x1B)
+#define CC1120_FS_DVC1 (CC1120_EXTENDED_BIT | 0x1C)
+#define CC1120_FS_DVC0 (CC1120_EXTENDED_BIT | 0x1D)
+#define CC1120_FS_LBI (CC1120_EXTENDED_BIT | 0x1E)
+#define CC1120_FS_PFD (CC1120_EXTENDED_BIT | 0x1F)
+#define CC1120_FS_PRE (CC1120_EXTENDED_BIT | 0x20)
+#define CC1120_FS_REG_DIV_CML (CC1120_EXTENDED_BIT | 0x21)
+#define CC1120_FS_SPARE (CC1120_EXTENDED_BIT | 0x22)
+#define CC1120_FS_VCO4 (CC1120_EXTENDED_BIT | 0x23)
+#define CC1120_FS_VCO3 (CC1120_EXTENDED_BIT | 0x24)
+#define CC1120_FS_VCO2 (CC1120_EXTENDED_BIT | 0x25)
+#define CC1120_FS_VCO1 (CC1120_EXTENDED_BIT | 0x26)
+#define CC1120_FS_VCO0 (CC1120_EXTENDED_BIT | 0x27)
+#define CC1120_GBIAS6 (CC1120_EXTENDED_BIT | 0x28)
+#define CC1120_GBIAS5 (CC1120_EXTENDED_BIT | 0x29)
+#define CC1120_GBIAS4 (CC1120_EXTENDED_BIT | 0x2A)
+#define CC1120_GBIAS3 (CC1120_EXTENDED_BIT | 0x2B)
+#define CC1120_GBIAS2 (CC1120_EXTENDED_BIT | 0x2C)
+#define CC1120_GBIAS1 (CC1120_EXTENDED_BIT | 0x2D)
+#define CC1120_GBIAS0 (CC1120_EXTENDED_BIT | 0x2E)
+#define CC1120_IFAMP (CC1120_EXTENDED_BIT | 0x2F)
+#define CC1120_LNA (CC1120_EXTENDED_BIT | 0x30)
+#define CC1120_RXMIX (CC1120_EXTENDED_BIT | 0x31)
+#define CC1120_XOSC5 (CC1120_EXTENDED_BIT | 0x32)
+#define CC1120_XOSC4 (CC1120_EXTENDED_BIT | 0x33)
+#define CC1120_XOSC3 (CC1120_EXTENDED_BIT | 0x34)
+#define CC1120_XOSC2 (CC1120_EXTENDED_BIT | 0x35)
+#define CC1120_XOSC1 (CC1120_EXTENDED_BIT | 0x36)
+#define CC1120_XOSC0 (CC1120_EXTENDED_BIT | 0x37)
+#define CC1120_ANALOG_SPARE (CC1120_EXTENDED_BIT | 0x38)
+#define CC1120_PA_CFG3 (CC1120_EXTENDED_BIT | 0x39)
+#define CC1120_WOR_TIME1 (CC1120_EXTENDED_BIT | 0x64)
+#define CC1120_WOR_TIME0 (CC1120_EXTENDED_BIT | 0x65)
+#define CC1120_WOR_CAPTURE1 (CC1120_EXTENDED_BIT | 0x66)
+#define CC1120_WOR_CAPTURE0 (CC1120_EXTENDED_BIT | 0x67)
+#define CC1120_BIST (CC1120_EXTENDED_BIT | 0x68)
+#define CC1120_DCFILTOFFSET_I1 (CC1120_EXTENDED_BIT | 0x69)
+#define CC1120_DCFILTOFFSET_I0 (CC1120_EXTENDED_BIT | 0x6A)
+#define CC1120_DCFILTOFFSET_Q1 (CC1120_EXTENDED_BIT | 0x6B)
+#define CC1120_DCFILTOFFSET_Q0 (CC1120_EXTENDED_BIT | 0x6C)
+#define CC1120_IQIE_I1 (CC1120_EXTENDED_BIT | 0x6D)
+#define CC1120_IQIE_I0 (CC1120_EXTENDED_BIT | 0x6E)
+#define CC1120_IQIE_Q1 (CC1120_EXTENDED_BIT | 0x6f)
+#define CC1120_IQIE_Q0 (CC1120_EXTENDED_BIT | 0x70)
+#define CC1120_RSSI1 (CC1120_EXTENDED_BIT | 0x71)
+#define CC1120_RSSI0 (CC1120_EXTENDED_BIT | 0x72)
+#define CC1120_MARCSTATE (CC1120_EXTENDED_BIT | 0x73)
+#define CC1120_LQI_VAL (CC1120_EXTENDED_BIT | 0x74)
+#define CC1120_PQT_SYNC_ERR (CC1120_EXTENDED_BIT | 0x75)
+#define CC1120_DEM_STATUS (CC1120_EXTENDED_BIT | 0x76)
+#define CC1120_FREQOFF_EST1 (CC1120_EXTENDED_BIT | 0x77)
+#define CC1120_FREQOFF_EST0 (CC1120_EXTENDED_BIT | 0x78)
+#define CC1120_AGC_GAIN3 (CC1120_EXTENDED_BIT | 0x79)
+#define CC1120_AGC_GAIN2 (CC1120_EXTENDED_BIT | 0x7a)
+#define CC1120_AGC_GAIN1 (CC1120_EXTENDED_BIT | 0x7b)
+#define CC1120_AGC_GAIN0 (CC1120_EXTENDED_BIT | 0x7c)
+#define CC1120_SOFT_RX_DATA_OUT (CC1120_EXTENDED_BIT | 0x7d)
+#define CC1120_SOFT_TX_DATA_IN (CC1120_EXTENDED_BIT | 0x7e)
+#define CC1120_ASK_SOFT_RX_DATA (CC1120_EXTENDED_BIT | 0x7f)
+#define CC1120_RNDGEN (CC1120_EXTENDED_BIT | 0x80)
+#define CC1120_MAGN2 (CC1120_EXTENDED_BIT | 0x81)
+#define CC1120_MAGN1 (CC1120_EXTENDED_BIT | 0x82)
+#define CC1120_MAGN0 (CC1120_EXTENDED_BIT | 0x83)
+#define CC1120_ANG1 (CC1120_EXTENDED_BIT | 0x84)
+#define CC1120_ANG0 (CC1120_EXTENDED_BIT | 0x85)
+#define CC1120_CHFILT_I2 (CC1120_EXTENDED_BIT | 0x86)
+#define CC1120_CHFILT_I1 (CC1120_EXTENDED_BIT | 0x87)
+#define CC1120_CHFILT_I0 (CC1120_EXTENDED_BIT | 0x88)
+#define CC1120_CHFILT_Q2 (CC1120_EXTENDED_BIT | 0x89)
+#define CC1120_CHFILT_Q1 (CC1120_EXTENDED_BIT | 0x8a)
+#define CC1120_CHFILT_Q0 (CC1120_EXTENDED_BIT | 0x8b)
+#define CC1120_GPIO_STATUS (CC1120_EXTENDED_BIT | 0x8c)
+#define CC1120_FSCAL_CTRL (CC1120_EXTENDED_BIT | 0x8d)
+#define CC1120_PHASE_ADJUST (CC1120_EXTENDED_BIT | 0x8e)
+#define CC1120_PARTNUMBER (CC1120_EXTENDED_BIT | 0x8f)
+#define CC1120_PARTVERSION (CC1120_EXTENDED_BIT | 0x90)
+#define CC1120_SERIAL_STATUS (CC1120_EXTENDED_BIT | 0x91)
+#define CC1120_RX_STATUS (CC1120_EXTENDED_BIT | 0x92)
+#define CC1120_TX_STATUS (CC1120_EXTENDED_BIT | 0x93)
+#define CC1120_MARC_STATUS1 (CC1120_EXTENDED_BIT | 0x94)
+#define CC1120_MARC_STATUS0 (CC1120_EXTENDED_BIT | 0x95)
+#define CC1120_PA_IFAMP_TEST (CC1120_EXTENDED_BIT | 0x96)
+#define CC1120_FSRF_TEST (CC1120_EXTENDED_BIT | 0x97)
+#define CC1120_PRE_TEST (CC1120_EXTENDED_BIT | 0x98)
+#define CC1120_PRE_OVR (CC1120_EXTENDED_BIT | 0x99)
+#define CC1120_ADC_TEST (CC1120_EXTENDED_BIT | 0x9a)
+#define CC1120_DVC_TEST (CC1120_EXTENDED_BIT | 0x9b)
+#define CC1120_ATEST (CC1120_EXTENDED_BIT | 0x9c)
+#define CC1120_ATEST_LVDS (CC1120_EXTENDED_BIT | 0x9d)
+#define CC1120_ATEST_MODE (CC1120_EXTENDED_BIT | 0x9e)
+#define CC1120_XOSC_TEST1 (CC1120_EXTENDED_BIT | 0x9f)
+#define CC1120_XOSC_TEST0 (CC1120_EXTENDED_BIT | 0xa0)
+#define CC1120_RXFIRST (CC1120_EXTENDED_BIT | 0xd2)
+#define CC1120_TXFIRST (CC1120_EXTENDED_BIT | 0xd3)
+#define CC1120_RXLAST (CC1120_EXTENDED_BIT | 0xd4)
+#define CC1120_TXLAST (CC1120_EXTENDED_BIT | 0xd5)
+#define CC1120_NUM_TXBYTES (CC1120_EXTENDED_BIT | 0xd6)
+#define CC1120_NUM_RXBYTES (CC1120_EXTENDED_BIT | 0xd7)
+#define CC1120_FIFO_NUM_TXBYTES (CC1120_EXTENDED_BIT | 0xd8)
+#define CC1120_FIFO_NUM_RXBYTES (CC1120_EXTENDED_BIT | 0xd9)
+
+/* Status byte */
+#define CC1120_STATUS_CHIP_RDY 7
+#define CC1120_STATUS_STATE 4
+#define CC1120_STATUS_STATE_IDLE 0
+#define CC1120_STATUS_STATE_RX 1
+#define CC1120_STATUS_STATE_TX 2
+#define CC1120_STATUS_STATE_FSTXON 3
+#define CC1120_STATUS_STATE_CALIBRATE 4
+#define CC1120_STATUS_STATE_SETTLING 5
+#define CC1120_STATUS_STATE_RX_FIFO_ERROR 6
+#define CC1120_STATUS_STATE_TX_FIFO_ERROR 7
+#define CC1120_STATUS_STATE_MASK 7
+
+#endif /* _AO_CC1120_H_ */
diff --git a/src/drivers/ao_cc1120_CC1120.h b/src/drivers/ao_cc1120_CC1120.h
new file mode 100644
index 00000000..a96c22fc
--- /dev/null
+++ b/src/drivers/ao_cc1120_CC1120.h
@@ -0,0 +1,191 @@
+/* RX filter BW = 100.000000 */
+/* Address config = No address check */
+/* Packet length = 255 */
+/* Symbol rate = 38.3606 */
+/* PA ramping = false */
+/* Carrier frequency = 434.549988 */
+/* Bit rate = 38.3606 */
+/* Whitening = true */
+/* Manchester enable = false */
+/* Modulation format = 2-GFSK */
+/* Packet length mode = Variable */
+/* Device address = 0 */
+/* TX power = 15 */
+/* Deviation = 20.507812 */
+/***************************************************************
+ * SmartRF Studio(tm) Export
+ *
+ * Radio register settings specifed with address, value
+ *
+ * RF device: CC1120
+ *
+ ***************************************************************/
+
+
+ CC1120_SYNC3, 0x93, /* Sync Word Configuration [31:24] */
+ CC1120_SYNC2, 0x0b, /* Sync Word Configuration [23:16] */
+ CC1120_SYNC1, 0x51, /* Sync Word Configuration [15:8] */
+ CC1120_SYNC0, 0xde, /* Sync Word Configuration [7:0] */
+ CC1120_SYNC_CFG1, 0x08, /* Sync Word Detection Configuration */
+ CC1120_SYNC_CFG0, 0x17, /* Sync Word Length Configuration */
+ CC1120_DEVIATION_M, 0x50, /* Frequency Deviation Configuration */
+ CC1120_MODCFG_DEV_E, 0x0d, /* Modulation Format and Frequency Deviation Configuration */
+ CC1120_DCFILT_CFG, 0x1c, /* Digital DC Removal Configuration */
+ CC1120_PREAMBLE_CFG1, 0x18, /* Preamble Length Configuration */
+ CC1120_PREAMBLE_CFG0, 0x2a, /* */
+ CC1120_FREQ_IF_CFG, 0x40, /* RX Mixer Frequency Configuration */
+ CC1120_IQIC, 0x46, /* Digital Image Channel Compensation Configuration */
+ CC1120_CHAN_BW, 0x02, /* Channel Filter Configuration */
+ CC1120_MDMCFG1, 0x46, /* General Modem Parameter Configuration */
+ CC1120_MDMCFG0, 0x05, /* General Modem Parameter Configuration */
+ CC1120_DRATE2, 0x93, /* Data Rate Configuration Exponent and Mantissa [19:16] */
+ CC1120_DRATE1, 0xa4, /* Data Rate Configuration Mantissa [15:8] */
+ CC1120_DRATE0, 0x00, /* Data Rate Configuration Mantissa [7:0] */
+ CC1120_AGC_REF, 0x20, /* AGC Reference Level Configuration */
+ CC1120_AGC_CS_THR, 0x19, /* Carrier Sense Threshold Configuration */
+ CC1120_AGC_GAIN_ADJUST, 0x00, /* RSSI Offset Configuration */
+ CC1120_AGC_CFG3, 0x91, /* AGC Configuration */
+ CC1120_AGC_CFG2, 0x20, /* AGC Configuration */
+ CC1120_AGC_CFG1, 0xa9, /* AGC Configuration */
+ CC1120_AGC_CFG0, 0xcf, /* AGC Configuration */
+ CC1120_FIFO_CFG, 0x00, /* FIFO Configuration */
+ CC1120_DEV_ADDR, 0x00, /* Device Address Configuration */
+ CC1120_SETTLING_CFG, 0x03, /* Frequency Synthesizer Calibration and Settling Configuration */
+ CC1120_FS_CFG, 0x14, /* Frequency Synthesizer Configuration */
+ CC1120_WOR_CFG1, 0x08, /* eWOR Configuration, Reg 1 */
+ CC1120_WOR_CFG0, 0x21, /* eWOR Configuration, Reg 0 */
+ CC1120_WOR_EVENT0_MSB, 0x00, /* Event 0 Configuration */
+ CC1120_WOR_EVENT0_LSB, 0x00, /* Event 0 Configuration */
+ CC1120_PKT_CFG2, 0x04, /* Packet Configuration, Reg 2 */
+ CC1120_PKT_CFG1, 0x45, /* Packet Configuration, Reg 1 */
+ CC1120_PKT_CFG0, 0x20, /* Packet Configuration, Reg 0 */
+ CC1120_RFEND_CFG1, 0x0f, /* RFEND Configuration, Reg 1 */
+ CC1120_RFEND_CFG0, 0x00, /* RFEND Configuration, Reg 0 */
+ CC1120_PA_CFG2, 0x3f, /* Power Amplifier Configuration, Reg 2 */
+ CC1120_PA_CFG1, 0x56, /* Power Amplifier Configuration, Reg 1 */
+ CC1120_PA_CFG0, 0x7b, /* Power Amplifier Configuration, Reg 0 */
+ CC1120_PKT_LEN, 0xff, /* Packet Length Configuration */
+ CC1120_IF_MIX_CFG, 0x00, /* IF Mix Configuration */
+ CC1120_FREQOFF_CFG, 0x22, /* Frequency Offset Correction Configuration */
+ CC1120_TOC_CFG, 0x0b, /* Timing Offset Correction Configuration */
+ CC1120_MARC_SPARE, 0x00, /* MARC Spare */
+ CC1120_ECG_CFG, 0x00, /* External Clock Frequency Configuration */
+ CC1120_SOFT_TX_DATA_CFG, 0x00, /* Soft TX Data Configuration */
+ CC1120_EXT_CTRL, 0x01, /* External Control Configuration */
+ CC1120_RCCAL_FINE, 0x00, /* RC Oscillator Calibration (fine) */
+ CC1120_RCCAL_COARSE, 0x00, /* RC Oscillator Calibration (coarse) */
+ CC1120_RCCAL_OFFSET, 0x00, /* RC Oscillator Calibration Clock Offset */
+ CC1120_FREQOFF1, 0x00, /* Frequency Offset (MSB) */
+ CC1120_FREQOFF0, 0x00, /* Frequency Offset (LSB) */
+ CC1120_FREQ2, 0x6c, /* Frequency Configuration [23:16] */
+ CC1120_FREQ1, 0xa3, /* Frequency Configuration [15:8] */
+ CC1120_FREQ0, 0x33, /* Frequency Configuration [7:0] */
+ CC1120_IF_ADC2, 0x02, /* Analog to Digital Converter Configuration, Reg 2 */
+ CC1120_IF_ADC1, 0xa6, /* Analog to Digital Converter Configuration, Reg 1 */
+ CC1120_IF_ADC0, 0x04, /* Analog to Digital Converter Configuration, Reg 0 */
+ CC1120_FS_DIG1, 0x00, /* */
+ CC1120_FS_DIG0, 0x5f, /* */
+ CC1120_FS_CAL3, 0x00, /* */
+ CC1120_FS_CAL2, 0x20, /* */
+ CC1120_FS_CAL1, 0x40, /* */
+ CC1120_FS_CAL0, 0x0e, /* */
+ CC1120_FS_CHP, 0x28, /* Charge Pump Configuration */
+ CC1120_FS_DIVTWO, 0x03, /* Divide by 2 */
+ CC1120_FS_DSM1, 0x00, /* Digital Synthesizer Module Configuration, Reg 1 */
+ CC1120_FS_DSM0, 0x33, /* Digital Synthesizer Module Configuration, Reg 0 */
+ CC1120_FS_DVC1, 0xff, /* Divider Chain Configuration, Reg 1 */
+ CC1120_FS_DVC0, 0x17, /* Divider Chain Configuration, Reg 0 */
+ CC1120_FS_LBI, 0x00, /* Local Bias Configuration */
+ CC1120_FS_PFD, 0x50, /* Phase Frequency Detector Configuration */
+ CC1120_FS_PRE, 0x6e, /* Prescaler Configuration */
+ CC1120_FS_REG_DIV_CML, 0x14, /* */
+ CC1120_FS_SPARE, 0xac, /* */
+ CC1120_FS_VCO4, 0x14, /* VCO Configuration, Reg 4 */
+ CC1120_FS_VCO3, 0x00, /* VCO Configuration, Reg 3 */
+ CC1120_FS_VCO2, 0x00, /* VCO Configuration, Reg 2 */
+ CC1120_FS_VCO1, 0x00, /* VCO Configuration, Reg 1 */
+ CC1120_FS_VCO0, 0xb4, /* VCO Configuration, Reg 0 */
+ CC1120_GBIAS6, 0x00, /* Global Bias Configuration, Reg 6 */
+ CC1120_GBIAS5, 0x02, /* Global Bias Configuration, Reg 5 */
+ CC1120_GBIAS4, 0x00, /* Global Bias Configuration, Reg 4 */
+ CC1120_GBIAS3, 0x00, /* Global Bias Configuration, Reg 3 */
+ CC1120_GBIAS2, 0x10, /* Global Bias Configuration, Reg 2 */
+ CC1120_GBIAS1, 0x00, /* Global Bias Configuration, Reg 1 */
+ CC1120_GBIAS0, 0x00, /* Global Bias Configuration, Reg 0 */
+ CC1120_IFAMP, 0x01, /* Intermediate Frequency Amplifier Configuration */
+ CC1120_LNA, 0x01, /* Low Noise Amplifier Configuration */
+ CC1120_RXMIX, 0x01, /* RX Mixer Configuration */
+ CC1120_XOSC5, 0x0e, /* Crystal Oscillator Configuration, Reg 5 */
+ CC1120_XOSC4, 0xa0, /* Crystal Oscillator Configuration, Reg 4 */
+ CC1120_XOSC3, 0x03, /* Crystal Oscillator Configuration, Reg 3 */
+ CC1120_XOSC2, 0x04, /* Crystal Oscillator Configuration, Reg 2 */
+ CC1120_XOSC1, 0x01, /* Crystal Oscillator Configuration, Reg 1 */
+ CC1120_XOSC0, 0x00, /* Crystal Oscillator Configuration, Reg 0 */
+ CC1120_ANALOG_SPARE, 0x00, /* */
+ CC1120_PA_CFG3, 0x00, /* Power Amplifier Configuration, Reg 3 */
+ CC1120_WOR_TIME1, 0x00, /* eWOR Timer Status (MSB) */
+ CC1120_WOR_TIME0, 0x00, /* eWOR Timer Status (LSB) */
+ CC1120_WOR_CAPTURE1, 0x00, /* eWOR Timer Capture (MSB) */
+ CC1120_WOR_CAPTURE0, 0x00, /* eWOR Timer Capture (LSB) */
+ CC1120_BIST, 0x00, /* MARC BIST */
+ CC1120_DCFILTOFFSET_I1, 0x00, /* DC Filter Offset I (MSB) */
+ CC1120_DCFILTOFFSET_I0, 0x00, /* DC Filter Offset I (LSB) */
+ CC1120_DCFILTOFFSET_Q1, 0x00, /* DC Filter Offset Q (MSB) */
+ CC1120_DCFILTOFFSET_Q0, 0x00, /* DC Filter Offset Q (LSB) */
+ CC1120_IQIE_I1, 0x00, /* IQ Imbalance Value I (MSB) */
+ CC1120_IQIE_I0, 0x00, /* IQ Imbalance Value I (LSB) */
+ CC1120_IQIE_Q1, 0x00, /* IQ Imbalance Value Q (MSB) */
+ CC1120_IQIE_Q0, 0x00, /* IQ Imbalance Value Q (LSB) */
+ CC1120_RSSI1, 0x80, /* Received Signal Strength Indicator (MSB) */
+ CC1120_RSSI0, 0x00, /* Received Signal Strength Indicator (LSB) */
+ CC1120_MARCSTATE, 0x41, /* MARC State */
+ CC1120_LQI_VAL, 0x00, /* Link Quality Indicator Value */
+ CC1120_PQT_SYNC_ERR, 0xff, /* Preamble and Sync Word Error */
+ CC1120_DEM_STATUS, 0x00, /* Demodulator Status */
+ CC1120_FREQOFF_EST1, 0x00, /* Frequency Offset Estimate (MSB) */
+ CC1120_FREQOFF_EST0, 0x00, /* Frequency Offset Estimate (LSB) */
+ CC1120_AGC_GAIN3, 0x00, /* AGC Gain, Reg 3 */
+ CC1120_AGC_GAIN2, 0xd1, /* AGC Gain, Reg 2 */
+ CC1120_AGC_GAIN1, 0x00, /* AGC Gain, Reg 1 */
+ CC1120_AGC_GAIN0, 0x3f, /* AGC Gain, Reg 0 */
+ CC1120_SOFT_RX_DATA_OUT, 0x00, /* Soft Decision Symbol Data */
+ CC1120_SOFT_TX_DATA_IN, 0x00, /* Soft TX Data Input Register */
+ CC1120_ASK_SOFT_RX_DATA, 0x30, /* AGC ASK Soft Decision Output */
+ CC1120_RNDGEN, 0x7f, /* Random Number Value */
+ CC1120_MAGN2, 0x00, /* Signal Magnitude after CORDIC [16] */
+ CC1120_MAGN1, 0x00, /* Signal Magnitude after CORDIC [15:8] */
+ CC1120_MAGN0, 0x00, /* Signal Magnitude after CORDIC [7:0] */
+ CC1120_ANG1, 0x00, /* Signal Angular after CORDIC [9:8] */
+ CC1120_ANG0, 0x00, /* Signal Angular after CORDIC [7:0] */
+ CC1120_CHFILT_I2, 0x08, /* Channel Filter Data Real Part [18:16] */
+ CC1120_CHFILT_I1, 0x00, /* Channel Filter Data Real Part [15:8] */
+ CC1120_CHFILT_I0, 0x00, /* Channel Filter Data Real Part [7:0] */
+ CC1120_CHFILT_Q2, 0x00, /* Channel Filter Data Imaginary Part [18:16] */
+ CC1120_CHFILT_Q1, 0x00, /* Channel Filter Data Imaginary Part [15:8] */
+ CC1120_CHFILT_Q0, 0x00, /* Channel Filter Data Imaginary Part [7:0] */
+ CC1120_GPIO_STATUS, 0x00, /* GPIO Status */
+ CC1120_FSCAL_CTRL, 0x01, /* */
+ CC1120_PHASE_ADJUST, 0x00, /* */
+ CC1120_PARTNUMBER, 0x00, /* Part Number */
+ CC1120_PARTVERSION, 0x00, /* Part Revision */
+ CC1120_SERIAL_STATUS, 0x00, /* Serial Status */
+ CC1120_RX_STATUS, 0x01, /* RX Status */
+ CC1120_TX_STATUS, 0x00, /* TX Status */
+ CC1120_MARC_STATUS1, 0x00, /* MARC Status, Reg 1 */
+ CC1120_MARC_STATUS0, 0x00, /* MARC Status, Reg 0 */
+ CC1120_PA_IFAMP_TEST, 0x00, /* */
+ CC1120_FSRF_TEST, 0x00, /* */
+ CC1120_PRE_TEST, 0x00, /* */
+ CC1120_PRE_OVR, 0x00, /* */
+ CC1120_ADC_TEST, 0x00, /* ADC Test */
+ CC1120_DVC_TEST, 0x0b, /* DVC Test */
+ CC1120_ATEST, 0x40, /* */
+ CC1120_ATEST_LVDS, 0x00, /* */
+ CC1120_ATEST_MODE, 0x00, /* */
+ CC1120_XOSC_TEST1, 0x3c, /* */
+ CC1120_XOSC_TEST0, 0x00, /* */
+ CC1120_RXFIRST, 0x00, /* RX FIFO Pointer (first entry) */
+ CC1120_TXFIRST, 0x00, /* TX FIFO Pointer (first entry) */
+ CC1120_RXLAST, 0x00, /* RX FIFO Pointer (last entry) */
+ CC1120_TXLAST, 0x00, /* TX FIFO Pointer (last entry) */
+
diff --git a/src/cc1111/ao_packet.c b/src/drivers/ao_packet.c
index 7eeb0710..19fe0558 100644
--- a/src/cc1111/ao_packet.c
+++ b/src/drivers/ao_packet.c
@@ -65,8 +65,10 @@ ao_packet_recv(void)
/* Check to see if we got a valid packet */
if (!dma_done)
return 0;
+#ifdef PKT_APPEND_STATUS_1_CRC_OK
if (!(ao_rx_packet.status & PKT_APPEND_STATUS_1_CRC_OK))
return 0;
+#endif
/* Accept packets with matching call signs, or any packet if
* our callsign hasn't been configured
diff --git a/src/cc1111/ao_packet_master.c b/src/drivers/ao_packet_master.c
index 66f94288..66f94288 100644
--- a/src/cc1111/ao_packet_master.c
+++ b/src/drivers/ao_packet_master.c
diff --git a/src/cc1111/ao_packet_slave.c b/src/drivers/ao_packet_slave.c
index fd5d443e..fd5d443e 100644
--- a/src/cc1111/ao_packet_slave.c
+++ b/src/drivers/ao_packet_slave.c
diff --git a/src/megametrum-v0.1/Makefile b/src/megametrum-v0.1/Makefile
index 3c3d7173..37832d16 100644
--- a/src/megametrum-v0.1/Makefile
+++ b/src/megametrum-v0.1/Makefile
@@ -41,7 +41,10 @@ ALTOS_SRC = \
ao_beep_stm.c \
ao_storage.c \
ao_m25.c \
- ao_usb_stm.c
+ ao_usb_stm.c \
+ ao_exti_stm.c \
+ ao_packet.c \
+ ao_packet_slave.c
PRODUCT=MegaMetrum-v0.1
PRODUCT_DEF=-DMEGAMETRUM
diff --git a/src/megametrum-v0.1/ao_megametrum.c b/src/megametrum-v0.1/ao_megametrum.c
index 9efde598..d93480f2 100644
--- a/src/megametrum-v0.1/ao_megametrum.c
+++ b/src/megametrum-v0.1/ao_megametrum.c
@@ -15,7 +15,8 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-#include "ao.h"
+#include <ao.h>
+#include <ao_exti.h>
void
beep(void)
@@ -51,6 +52,8 @@ main(void)
ao_adc_init();
ao_storage_init();
ao_usb_init();
+ ao_exti_init();
+ ao_radio_init();
ao_cmd_register(&ao_mm_cmds[0]);
ao_start_scheduler();
diff --git a/src/megametrum-v0.1/ao_pins.h b/src/megametrum-v0.1/ao_pins.h
index f761e5c3..2e83de8a 100644
--- a/src/megametrum-v0.1/ao_pins.h
+++ b/src/megametrum-v0.1/ao_pins.h
@@ -193,4 +193,17 @@ struct ao_adc {
#define AO_M25_SPI_CS_MASK (1 << 3)
#define AO_M25_SPI_BUS STM_SPI_INDEX(2)
+/*
+ * Radio (cc1120)
+ */
+
+#define AO_CC1120_SPI_CS_PORT stm_gpioc
+#define AO_CC1120_SPI_CS_PIN 5
+#define AO_CC1120_SPI_BUS STM_SPI_INDEX(2)
+
+#define AO_CC1120_INT_PORT stm_gpioc
+#define AO_CC1120_INT_PIN 14
+
+#define AO_CC1120_INT_GPIO 2
+
#endif /* _AO_PINS_H_ */
diff --git a/src/stm/Makefile.defs b/src/stm/Makefile.defs
index 76962a3e..3edfa41d 100644
--- a/src/stm/Makefile.defs
+++ b/src/stm/Makefile.defs
@@ -16,7 +16,7 @@ ifndef VERSION
include ../Version
endif
-AO_CFLAGS=-I. -I../stm -I../core -I..
+AO_CFLAGS=-I. -I../stm -I../core -I../drivers -I..
STM_CFLAGS=-std=gnu99 -mlittle-endian -mcpu=cortex-m3 -mthumb -ffreestanding -nostdlib $(AO_CFLAGS) $(SAT_CFLAGS)
LDFLAGS=-L../stm -Wl,-Taltos.ld
diff --git a/src/stm/ao_arch_funcs.h b/src/stm/ao_arch_funcs.h
index 309937d5..05bb7784 100644
--- a/src/stm/ao_arch_funcs.h
+++ b/src/stm/ao_arch_funcs.h
@@ -32,9 +32,15 @@ void
ao_spi_send(void *block, uint16_t len, uint8_t spi_index);
void
+ao_spi_send_fixed(uint8_t value, uint16_t len, uint8_t spi_index);
+
+void
ao_spi_recv(void *block, uint16_t len, uint8_t spi_index);
void
+ao_spi_duplex(void *out, void *in, uint16_t len, uint8_t spi_index);
+
+void
ao_spi_init(void);
#define ao_spi_get_mask(reg,mask,bus) do { \
@@ -47,7 +53,7 @@ ao_spi_init(void);
ao_spi_put(bus); \
} while (0)
-#define ao_stm_enable_port(port) do { \
+#define ao_enable_port(port) do { \
if (&(port) == &stm_gpioa) \
stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOAEN); \
else if (&(port) == &stm_gpiob) \
@@ -61,29 +67,29 @@ ao_spi_init(void);
} while (0)
-#define ao_stm_enable_cs(port,bit) do { \
+#define ao_enable_cs(port,bit) do { \
stm_gpio_set(&(port), bit, 1); \
stm_moder_set(&(port), bit, STM_MODER_OUTPUT); \
} while (0)
#define ao_spi_init_cs(port, mask) do { \
- ao_stm_enable_port(port); \
- if (mask & 0x0001) ao_stm_enable_cs(port, 0); \
- if (mask & 0x0002) ao_stm_enable_cs(port, 1); \
- if (mask & 0x0004) ao_stm_enable_cs(port, 2); \
- if (mask & 0x0008) ao_stm_enable_cs(port, 3); \
- if (mask & 0x0010) ao_stm_enable_cs(port, 4); \
- if (mask & 0x0020) ao_stm_enable_cs(port, 5); \
- if (mask & 0x0040) ao_stm_enable_cs(port, 6); \
- if (mask & 0x0080) ao_stm_enable_cs(port, 7); \
- if (mask & 0x0100) ao_stm_enable_cs(port, 8); \
- if (mask & 0x0200) ao_stm_enable_cs(port, 9); \
- if (mask & 0x0400) ao_stm_enable_cs(port, 10); \
- if (mask & 0x0800) ao_stm_enable_cs(port, 11); \
- if (mask & 0x1000) ao_stm_enable_cs(port, 12); \
- if (mask & 0x2000) ao_stm_enable_cs(port, 13); \
- if (mask & 0x4000) ao_stm_enable_cs(port, 14); \
- if (mask & 0x8000) ao_stm_enable_cs(port, 15); \
+ ao_enable_port(port); \
+ if ((mask) & 0x0001) ao_enable_cs(port, 0); \
+ if ((mask) & 0x0002) ao_enable_cs(port, 1); \
+ if ((mask) & 0x0004) ao_enable_cs(port, 2); \
+ if ((mask) & 0x0008) ao_enable_cs(port, 3); \
+ if ((mask) & 0x0010) ao_enable_cs(port, 4); \
+ if ((mask) & 0x0020) ao_enable_cs(port, 5); \
+ if ((mask) & 0x0040) ao_enable_cs(port, 6); \
+ if ((mask) & 0x0080) ao_enable_cs(port, 7); \
+ if ((mask) & 0x0100) ao_enable_cs(port, 8); \
+ if ((mask) & 0x0200) ao_enable_cs(port, 9); \
+ if ((mask) & 0x0400) ao_enable_cs(port, 10);\
+ if ((mask) & 0x0800) ao_enable_cs(port, 11);\
+ if ((mask) & 0x1000) ao_enable_cs(port, 12);\
+ if ((mask) & 0x2000) ao_enable_cs(port, 13);\
+ if ((mask) & 0x4000) ao_enable_cs(port, 14);\
+ if ((mask) & 0x8000) ao_enable_cs(port, 15);\
} while (0)
/* ao_dma_stm.c
diff --git a/src/stm/ao_dma_stm.c b/src/stm/ao_dma_stm.c
index 21390748..e76c8e8c 100644
--- a/src/stm/ao_dma_stm.c
+++ b/src/stm/ao_dma_stm.c
@@ -109,6 +109,7 @@ void
ao_dma_abort(uint8_t index)
{
stm_dma.channel[index].ccr &= ~(1 << STM_DMA_CCR_EN);
+ ao_wakeup(&ao_dma_done[index]);
}
void
diff --git a/src/stm/ao_exti.h b/src/stm/ao_exti.h
new file mode 100644
index 00000000..43eaa52f
--- /dev/null
+++ b/src/stm/ao_exti.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright © 2012 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#ifndef _AO_EXTI_H_
+#define _AO_EXTI_H_
+
+#define AO_EXTI_MODE_RISING 1
+#define AO_EXTI_MODE_FALLING 2
+#define AO_EXTI_MODE_PULL_UP 4
+#define AO_EXTI_MODE_PULL_DOWN 8
+
+void
+ao_exti_setup(struct stm_gpio *gpio, uint8_t pin, uint8_t mode, void (*callback)());
+
+void
+ao_exti_enable(struct stm_gpio *gpio, uint8_t pin);
+
+void
+ao_exti_disable(struct stm_gpio *gpio, uint8_t pin);
+
+void
+ao_exti_init(void);
+
+#endif /* _AO_EXTI_H_ */
diff --git a/src/stm/ao_exti_stm.c b/src/stm/ao_exti_stm.c
new file mode 100644
index 00000000..013d453b
--- /dev/null
+++ b/src/stm/ao_exti_stm.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright © 2012 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include <ao.h>
+#include <ao_exti.h>
+
+static void (*ao_exti_callback[16])(void);
+
+static void
+ao_exti_isr(void) {
+ uint32_t pending = stm_exti.pr;
+ uint8_t pin;
+
+ /* Clear pending interrupts */
+ stm_exti.pr = pending;
+ for (pin = 0; pin < 16 && pending; pin++) {
+ uint32_t mask = (1 << pin);
+
+ if (pending & mask) {
+ pending &= ~mask;
+ if (ao_exti_callback[pin])
+ (*ao_exti_callback[pin])();
+ }
+ }
+}
+
+void stm_exti0_isr(void) { ao_exti_isr(); }
+void stm_exti1_isr(void) { ao_exti_isr(); }
+void stm_exti2_isr(void) { ao_exti_isr(); }
+void stm_exti3_isr(void) { ao_exti_isr(); }
+void stm_exti4_isr(void) { ao_exti_isr(); }
+void stm_exti9_5_isr(void) { ao_exti_isr(); }
+void stm_exti15_10_isr(void) { ao_exti_isr(); }
+
+void
+ao_exti_setup (struct stm_gpio *gpio, uint8_t pin, uint8_t mode, void (*callback)(void)) {
+ uint32_t mask = 1 << pin;
+ uint32_t pupdr;
+ uint8_t irq;
+
+ ao_exti_callback[pin] = callback;
+ /* configure pin as input, setting selected pull-up/down mode */
+ stm_moder_set(gpio, pin, STM_MODER_INPUT);
+ switch (mode & (AO_EXTI_MODE_PULL_UP|AO_EXTI_MODE_PULL_DOWN)) {
+ case 0:
+ default:
+ pupdr = STM_PUPDR_NONE;
+ break;
+ case AO_EXTI_MODE_PULL_UP:
+ pupdr = STM_PUPDR_PULL_UP;
+ break;
+ case AO_EXTI_MODE_PULL_DOWN:
+ pupdr = STM_PUPDR_PULL_DOWN;
+ break;
+ }
+ stm_pupdr_set(gpio, pin, pupdr);
+
+ /* Set interrupt mask and rising/falling mode */
+ stm_exti.imr &= ~mask;
+ stm_exti.rtsr |= mask;
+ if (mode & AO_EXTI_MODE_RISING)
+ stm_exti.rtsr |= mask;
+ if (mode & AO_EXTI_MODE_FALLING)
+ stm_exti.ftsr |= mask;
+
+ if (pin <= 4)
+ irq = STM_ISR_EXTI0_POS + pin;
+ else if (pin <= 9)
+ irq = STM_ISR_EXTI9_5_POS;
+ else
+ irq = STM_ISR_EXTI15_10_POS;
+ stm_nvic_set_priority(irq, 10);
+ stm_nvic_set_enable(irq);
+}
+
+void
+ao_exti_enable(struct stm_gpio *gpio, uint8_t pin) {
+ stm_exti.imr |= (1 << pin);
+}
+
+void
+ao_exti_disable(struct stm_gpio *gpio, uint8_t pin) {
+ stm_exti.imr &= ~(1 << pin);
+}
+
+void
+ao_exti_init(void)
+{
+ stm_nvic_set_priority(STM_ISR_EXTI1_POS, 10);
+ stm_nvic_set_priority(STM_ISR_EXTI2_POS, 10);
+ stm_nvic_set_priority(STM_ISR_EXTI3_POS, 10);
+ stm_nvic_set_priority(STM_ISR_EXTI4_POS, 10);
+ stm_nvic_set_priority(STM_ISR_EXTI9_5_POS, 10);
+ stm_nvic_set_priority(STM_ISR_EXTI15_10_POS, 10);
+}
diff --git a/src/stm/ao_spi_stm.c b/src/stm/ao_spi_stm.c
index be24ebcf..8bb0d8e8 100644
--- a/src/stm/ao_spi_stm.c
+++ b/src/stm/ao_spi_stm.c
@@ -97,6 +97,62 @@ ao_spi_send(void *block, uint16_t len, uint8_t spi_index)
}
void
+ao_spi_send_fixed(uint8_t value, uint16_t len, uint8_t spi_index)
+{
+ struct stm_spi *stm_spi = ao_spi_stm_info[spi_index].stm_spi;
+ uint8_t mosi_dma_index = ao_spi_stm_info[spi_index].mosi_dma_index;
+ uint8_t miso_dma_index = ao_spi_stm_info[spi_index].miso_dma_index;
+
+ /* Set up the transmit DMA to deliver data */
+ ao_dma_set_transfer(mosi_dma_index,
+ &stm_spi->dr,
+ &value,
+ len,
+ (0 << STM_DMA_CCR_MEM2MEM) |
+ (STM_DMA_CCR_PL_MEDIUM << STM_DMA_CCR_PL) |
+ (STM_DMA_CCR_MSIZE_8 << STM_DMA_CCR_MSIZE) |
+ (STM_DMA_CCR_PSIZE_8 << STM_DMA_CCR_PSIZE) |
+ (0 << STM_DMA_CCR_MINC) |
+ (0 << STM_DMA_CCR_PINC) |
+ (0 << STM_DMA_CCR_CIRC) |
+ (STM_DMA_CCR_DIR_MEM_TO_PER << STM_DMA_CCR_DIR));
+
+ /* Clear RXNE */
+ (void) stm_spi->dr;
+
+ /* Set up the receive DMA -- when this is done, we know the SPI unit
+ * is idle. Without this, we'd have to poll waiting for the BSY bit to
+ * be cleared
+ */
+ ao_dma_set_transfer(miso_dma_index,
+ &stm_spi->dr,
+ &spi_dev_null,
+ len,
+ (0 << STM_DMA_CCR_MEM2MEM) |
+ (STM_DMA_CCR_PL_MEDIUM << STM_DMA_CCR_PL) |
+ (STM_DMA_CCR_MSIZE_8 << STM_DMA_CCR_MSIZE) |
+ (STM_DMA_CCR_PSIZE_8 << STM_DMA_CCR_PSIZE) |
+ (0 << STM_DMA_CCR_MINC) |
+ (0 << STM_DMA_CCR_PINC) |
+ (0 << STM_DMA_CCR_CIRC) |
+ (STM_DMA_CCR_DIR_PER_TO_MEM << STM_DMA_CCR_DIR));
+ stm_spi->cr2 = ((0 << STM_SPI_CR2_TXEIE) |
+ (0 << STM_SPI_CR2_RXNEIE) |
+ (0 << STM_SPI_CR2_ERRIE) |
+ (0 << STM_SPI_CR2_SSOE) |
+ (1 << STM_SPI_CR2_TXDMAEN) |
+ (1 << STM_SPI_CR2_RXDMAEN));
+ ao_dma_start(miso_dma_index);
+ ao_dma_start(mosi_dma_index);
+ ao_arch_critical(
+ while (!ao_dma_done[miso_dma_index])
+ ao_sleep(&ao_dma_done[miso_dma_index]);
+ );
+ ao_dma_done_transfer(mosi_dma_index);
+ ao_dma_done_transfer(miso_dma_index);
+}
+
+void
ao_spi_recv(void *block, uint16_t len, uint8_t spi_index)
{
struct stm_spi *stm_spi = ao_spi_stm_info[spi_index].stm_spi;
@@ -154,6 +210,63 @@ ao_spi_recv(void *block, uint16_t len, uint8_t spi_index)
}
void
+ao_spi_duplex(void *out, void *in, uint16_t len, uint8_t spi_index)
+{
+ struct stm_spi *stm_spi = ao_spi_stm_info[spi_index].stm_spi;
+ uint8_t mosi_dma_index = ao_spi_stm_info[spi_index].mosi_dma_index;
+ uint8_t miso_dma_index = ao_spi_stm_info[spi_index].miso_dma_index;
+
+ /* Set up transmit DMA to send data */
+ ao_dma_set_transfer(mosi_dma_index,
+ &stm_spi->dr,
+ out,
+ len,
+ (0 << STM_DMA_CCR_MEM2MEM) |
+ (STM_DMA_CCR_PL_MEDIUM << STM_DMA_CCR_PL) |
+ (STM_DMA_CCR_MSIZE_8 << STM_DMA_CCR_MSIZE) |
+ (STM_DMA_CCR_PSIZE_8 << STM_DMA_CCR_PSIZE) |
+ (1 << STM_DMA_CCR_MINC) |
+ (0 << STM_DMA_CCR_PINC) |
+ (0 << STM_DMA_CCR_CIRC) |
+ (STM_DMA_CCR_DIR_MEM_TO_PER << STM_DMA_CCR_DIR));
+
+ /* Clear RXNE */
+ (void) stm_spi->dr;
+
+ /* Set up the receive DMA to capture data */
+ ao_dma_set_transfer(miso_dma_index,
+ &stm_spi->dr,
+ in,
+ len,
+ (0 << STM_DMA_CCR_MEM2MEM) |
+ (STM_DMA_CCR_PL_MEDIUM << STM_DMA_CCR_PL) |
+ (STM_DMA_CCR_MSIZE_8 << STM_DMA_CCR_MSIZE) |
+ (STM_DMA_CCR_PSIZE_8 << STM_DMA_CCR_PSIZE) |
+ (1 << STM_DMA_CCR_MINC) |
+ (0 << STM_DMA_CCR_PINC) |
+ (0 << STM_DMA_CCR_CIRC) |
+ (STM_DMA_CCR_DIR_PER_TO_MEM << STM_DMA_CCR_DIR));
+
+ stm_spi->cr2 = ((0 << STM_SPI_CR2_TXEIE) |
+ (0 << STM_SPI_CR2_RXNEIE) |
+ (0 << STM_SPI_CR2_ERRIE) |
+ (0 << STM_SPI_CR2_SSOE) |
+ (1 << STM_SPI_CR2_TXDMAEN) |
+ (1 << STM_SPI_CR2_RXDMAEN));
+ ao_dma_start(miso_dma_index);
+ ao_dma_start(mosi_dma_index);
+
+ /* Wait until the SPI unit is done */
+ ao_arch_critical(
+ while (!ao_dma_done[miso_dma_index])
+ ao_sleep(&ao_dma_done[miso_dma_index]);
+ );
+
+ ao_dma_done_transfer(mosi_dma_index);
+ ao_dma_done_transfer(miso_dma_index);
+}
+
+void
ao_spi_get(uint8_t spi_index)
{
struct stm_spi *stm_spi = ao_spi_stm_info[spi_index].stm_spi;
diff --git a/src/stm/ao_usb_stm.c b/src/stm/ao_usb_stm.c
index 223fdeaa..71bf1bc7 100644
--- a/src/stm/ao_usb_stm.c
+++ b/src/stm/ao_usb_stm.c
@@ -1005,6 +1005,7 @@ ao_usb_echo(void)
}
#endif
+#if USB_DEBUG
static void
ao_usb_irq(void)
{
@@ -1016,6 +1017,7 @@ __code struct ao_cmds ao_usb_cmds[] = {
{ ao_usb_irq, "I\0Show USB interrupt counts" },
{ 0, NULL }
};
+#endif
void
ao_usb_init(void)
@@ -1027,7 +1029,9 @@ ao_usb_init(void)
#if USB_ECHO
ao_add_task(&ao_usb_echo_task, ao_usb_echo, "usb echo");
#endif
+#if USB_DEBUG
ao_cmd_register(&ao_usb_cmds[0]);
+#endif
#if !USB_ECHO
ao_add_stdio(ao_usb_pollchar, ao_usb_putchar, ao_usb_flush);
#endif
diff --git a/src/stm/stm32l.h b/src/stm/stm32l.h
index e884ef04..10a53a47 100644
--- a/src/stm/stm32l.h
+++ b/src/stm/stm32l.h
@@ -101,13 +101,13 @@ stm_ospeedr_get(struct stm_gpio *gpio, int pin) {
#define STM_PUPDR_RESERVED 3
static inline void
-stm_pupdr_set(struct stm_gpio *gpio, int pin, vuint32_t value) {
+stm_pupdr_set(struct stm_gpio *gpio, int pin, uint32_t value) {
gpio->pupdr = ((gpio->pupdr &
~(STM_PUPDR_MASK << STM_PUPDR_SHIFT(pin))) |
value << STM_PUPDR_SHIFT(pin));
}
-static inline vuint32_t
+static inline uint32_t
stm_pupdr_get(struct stm_gpio *gpio, int pin) {
return (gpio->pupdr >> STM_PUPDR_SHIFT(pin)) & STM_PUPDR_MASK;
}
@@ -1589,4 +1589,16 @@ union stm_usb_bdt {
extern uint8_t stm_usb_sram[];
+struct stm_exti {
+ vuint32_t imr;
+ vuint32_t emr;
+ vuint32_t rtsr;
+ vuint32_t ftsr;
+
+ vuint32_t swier;
+ vuint32_t pr;
+};
+
+extern struct stm_exti stm_exti;
+
#endif /* _STM32L_H_ */