summaryrefslogtreecommitdiff
path: root/src/drivers/ao_radio_master.c
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2012-08-29 11:23:13 -0700
committerKeith Packard <keithp@keithp.com>2012-08-29 11:23:13 -0700
commit3e7e8e21f2bb823cb6e74c73d0feddbc3a891107 (patch)
tree8e634ffc0990f6383b397dea443a57a67042d095 /src/drivers/ao_radio_master.c
parent1b6ed262460ee75fb5bb684d13d19c26c7ea750b (diff)
altos: SPI radio - use 1->0 for 'done' and 0->1 for 'ready'
This changes how the SPI radio protocol uses the interrupt line. Instead of a pulse indicating operation done, this now uses a 0 value for done and a 1 value for ready. The key distinction is that the master can tell when the slave is waiting for the next command instead of hoping that it got done 'soon enough'. Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'src/drivers/ao_radio_master.c')
-rw-r--r--src/drivers/ao_radio_master.c112
1 files changed, 60 insertions, 52 deletions
diff --git a/src/drivers/ao_radio_master.c b/src/drivers/ao_radio_master.c
index bfbcb1f8..73ac3c03 100644
--- a/src/drivers/ao_radio_master.c
+++ b/src/drivers/ao_radio_master.c
@@ -22,13 +22,16 @@
static __xdata struct ao_radio_spi_reply ao_radio_spi_reply;
static __xdata struct ao_radio_spi_request ao_radio_spi_request;
-static volatile __xdata uint8_t ao_radio_done = 1;
+static volatile __xdata uint8_t ao_radio_wait_mode;
+static volatile __xdata uint8_t ao_radio_done = 0;
+static volatile __xdata uint8_t ao_radio_ready = 1;
static __xdata uint8_t ao_radio_mutex;
+static __xdata uint8_t ao_radio_aes_seq;
__xdata int8_t ao_radio_cmac_rssi;
#if 0
-#define PRINTD(...) do { printf ("\r%s: ", __func__); printf(__VA_ARGS__); flush(); } while(0)
+#define PRINTD(...) do { printf ("\r%5u %s: ", ao_tick_count, __func__); printf(__VA_ARGS__); flush(); } while(0)
#else
#define PRINTD(...)
#endif
@@ -36,24 +39,18 @@ __xdata int8_t ao_radio_cmac_rssi;
static void
ao_radio_isr(void)
{
- ao_exti_disable(AO_RADIO_INT_PORT, AO_RADIO_INT_PIN);
- ao_radio_done = 1;
- ao_wakeup((void *) &ao_radio_done);
-}
-
-static void
-ao_radio_master_delay(void)
-{
-// uint16_t i;
-// for (i = 0; i < 1000; i++)
-// ao_arch_nop();
- ao_delay(1);
+ if (ao_gpio_get(AO_RADIO_INT_PORT, AO_RADIO_INT_PIN, AO_RADIO_INT)) {
+ ao_radio_ready = 1;
+ ao_wakeup((void *) &ao_radio_ready);
+ } else {
+ ao_radio_done = 1;
+ ao_wakeup((void *) &ao_radio_done);
+ }
}
static void
ao_radio_master_start(void)
{
- ao_radio_master_delay();
ao_spi_get_bit(AO_RADIO_CS_PORT, AO_RADIO_CS_PIN, AO_RADIO_CS,
AO_RADIO_SPI_BUS,
AO_SPI_SPEED_200kHz);
@@ -64,32 +61,50 @@ ao_radio_master_stop(void)
{
ao_spi_put_bit(AO_RADIO_CS_PORT, AO_RADIO_CS_PIN, AO_RADIO_CS,
AO_RADIO_SPI_BUS);
-// ao_delay(1);
}
static uint8_t
ao_radio_master_send(void)
{
- if (!ao_radio_done)
- printf ("radio not done in ao_radio_master_send\n");
+ uint8_t ret;
+
PRINTD("send %d\n", ao_radio_spi_request.len);
ao_radio_done = 0;
- ao_exti_enable(AO_RADIO_INT_PORT, AO_RADIO_INT_PIN);
+
+ /* Wait for radio chip to be ready for a command
+ */
+
+ PRINTD("Waiting radio ready\n");
+ cli();
+ ao_radio_ready = ao_gpio_get(AO_RADIO_INT_PORT,
+ AO_RADIO_INT_PIN, AO_RADIO_INT);
+ ret = 0;
+ while (!ao_radio_ready) {
+ ret = ao_sleep((void *) &ao_radio_ready);
+ if (ret)
+ break;
+ }
+ sei();
+ if (ret)
+ return 0;
+
+ PRINTD("radio_ready %d radio_done %d\n", ao_radio_ready, ao_radio_done);
+
+ /* Send the command
+ */
+ ao_radio_wait_mode = 0;
ao_radio_master_start();
ao_spi_send(&ao_radio_spi_request,
ao_radio_spi_request.len,
AO_RADIO_SPI_BUS);
ao_radio_master_stop();
+ PRINTD("waiting for send done %d\n", ao_radio_done);
cli();
while (!ao_radio_done)
- if (ao_sleep((void *) &ao_radio_done)) {
- printf ("ao_radio_master awoken\n");
+ if (ao_sleep((void *) &ao_radio_done))
break;
- }
sei();
- PRINTD ("sent, radio done %d\n", ao_radio_done);
- if (!ao_radio_done)
- printf ("radio didn't finish after ao_radio_master_send\n");
+ PRINTD ("sent, radio done %d isr_0 %d isr_1 %d\n", ao_radio_done, isr_0_count, isr_1_count);
return ao_radio_done;
}
@@ -112,15 +127,6 @@ ao_radio_put(void)
static void
ao_radio_get_data(__xdata void *d, uint8_t size)
{
- uint8_t ret;
-
- PRINTD ("send fetch req\n");
- ao_radio_spi_request.len = AO_RADIO_SPI_REQUEST_HEADER_LEN;
- ao_radio_spi_request.request = AO_RADIO_SPI_RECV_FETCH;
- ao_radio_spi_request.recv_len = size;
- ret = ao_radio_master_send();
- PRINTD ("fetch req sent %d\n", ret);
-
PRINTD ("fetch\n");
ao_radio_master_start();
ao_spi_recv(&ao_radio_spi_reply,
@@ -167,21 +173,17 @@ ao_radio_recv(__xdata void *d, uint8_t size)
return 0;
}
ao_radio_get_data(d, size);
-
recv = ao_radio_spi_reply.status;
-
ao_radio_put();
return recv;
}
-int8_t
-ao_radio_cmac_send(__xdata void *packet, uint8_t len) __reentrant
+static void
+ao_radio_cmac_set_key(void)
{
- if (len > AO_CMAC_MAX_LEN)
- return AO_RADIO_CMAC_LEN_ERROR;
-
- PRINTD ("cmac_send: send %d\n", len);
+ if (ao_radio_aes_seq == ao_config_aes_seq)
+ return;
/* Set the key.
*/
PRINTD ("set key\n");
@@ -190,6 +192,18 @@ ao_radio_cmac_send(__xdata void *packet, uint8_t len) __reentrant
ao_radio_master_send();
ao_radio_put();
PRINTD ("key set\n");
+ ao_radio_aes_seq = ao_config_aes_seq;
+}
+
+int8_t
+ao_radio_cmac_send(__xdata void *packet, uint8_t len) __reentrant
+{
+ if (len > AO_CMAC_MAX_LEN)
+ return AO_RADIO_CMAC_LEN_ERROR;
+
+ ao_radio_cmac_set_key();
+
+ PRINTD ("cmac_send: send %d\n", len);
/* Send the data
*/
@@ -212,21 +226,14 @@ ao_radio_cmac_recv(__xdata void *packet, uint8_t len, uint16_t timeout) __reentr
if (len > AO_CMAC_MAX_LEN)
return AO_RADIO_CMAC_LEN_ERROR;
- /* Set the key.
- */
- PRINTD ("setting key\n");
- ao_radio_get(AO_RADIO_SPI_CMAC_KEY, AO_AES_LEN);
- ao_radio_spi_request.timeout = timeout;
- ao_xmemcpy(&ao_radio_spi_request.payload, &ao_config.aes_key, AO_AES_LEN);
- recv = ao_radio_master_send();
- ao_radio_put();
- PRINTD ("key set: %d\n", recv);
+ ao_radio_cmac_set_key();
/* Recv the data
*/
PRINTD ("queuing recv\n");
ao_radio_get(AO_RADIO_SPI_CMAC_RECV, 0);
ao_radio_spi_request.recv_len = len;
+ ao_radio_spi_request.timeout = timeout;
recv = ao_radio_master_send();
PRINTD ("recv queued: %d\n", recv);
if (!recv) {
@@ -300,7 +307,8 @@ ao_radio_init(void)
ao_enable_port(AO_RADIO_INT_PORT);
ao_exti_setup(AO_RADIO_INT_PORT,
AO_RADIO_INT_PIN,
- AO_EXTI_MODE_FALLING,
+ AO_EXTI_MODE_RISING|AO_EXTI_MODE_FALLING,
ao_radio_isr);
+ ao_exti_enable(AO_RADIO_INT_PORT, AO_RADIO_INT_PIN);
ao_cmd_register(&ao_radio_cmds[0]);
}