This includes long delays to avoid overrunning the cc1111 input,
otherwise it works pretty well. The delays mean that we can't capture
the reply to a cmac command though, so more work is needed.
Signed-off-by: Keith Packard <keithp@keithp.com>
#define ao_spi_send(block, len, bus) ao_spi_send_bus(block, len)
#define ao_spi_recv(block, len, bus) ao_spi_recv_bus(block, len)
#define ao_spi_send(block, len, bus) ao_spi_send_bus(block, len)
#define ao_spi_recv(block, len, bus) ao_spi_recv_bus(block, len)
+#if AO_SPI_SLAVE
+void
+ao_spi_send_wait(void);
+
+void
+ao_spi_recv_wait(void);
+#endif
+
#endif
ao_dma_start(ao_spi_dma_out_id);
ao_dma_trigger(ao_spi_dma_out_id);
#endif
ao_dma_start(ao_spi_dma_out_id);
ao_dma_trigger(ao_spi_dma_out_id);
-#if AO_SPI_SLAVE
- __critical while (!ao_spi_dma_out_done)
- ao_sleep(&ao_spi_dma_out_done);
-#else
__critical while (!ao_spi_dma_in_done)
ao_sleep(&ao_spi_dma_in_done);
#endif
}
__critical while (!ao_spi_dma_in_done)
ao_sleep(&ao_spi_dma_in_done);
#endif
}
+#if AO_SPI_SLAVE
+void
+ao_spi_send_wait(void)
+{
+ __critical while (!ao_spi_dma_out_done)
+ ao_sleep(&ao_spi_dma_out_done);
+}
+#endif
/* Receive bytes over SPI.
*
/* Receive bytes over SPI.
*
#if !AO_SPI_SLAVE
ao_dma_start(ao_spi_dma_out_id);
ao_dma_trigger(ao_spi_dma_out_id);
#if !AO_SPI_SLAVE
ao_dma_start(ao_spi_dma_out_id);
ao_dma_trigger(ao_spi_dma_out_id);
__critical while (!ao_spi_dma_in_done)
ao_sleep(&ao_spi_dma_in_done);
__critical while (!ao_spi_dma_in_done)
ao_sleep(&ao_spi_dma_in_done);
+#if AO_SPI_SLAVE
+void
+ao_spi_recv_wait(void)
+{
+ __critical while (!ao_spi_dma_in_done)
+ ao_sleep(&ao_spi_dma_in_done);
+}
+#endif
static __xdata struct ao_radio_spi_reply ao_radio_spi_reply;
static __xdata struct ao_radio_spi_request ao_radio_spi_request;
static __xdata struct ao_radio_spi_reply ao_radio_spi_reply;
static __xdata struct ao_radio_spi_request ao_radio_spi_request;
-static __xdata uint8_t ao_radio_done;
+static volatile __xdata uint8_t ao_radio_done = 1;
static __xdata uint8_t ao_radio_mutex;
__xdata int8_t ao_radio_cmac_rssi;
static __xdata uint8_t ao_radio_mutex;
__xdata int8_t ao_radio_cmac_rssi;
+#if 0
+#define PRINTD(...) do { printf ("\r%s: ", __func__); printf(__VA_ARGS__); flush(); } while(0)
+#else
+#define PRINTD(...)
+#endif
+
static void
ao_radio_isr(void)
{
ao_exti_disable(AO_RADIO_INT_PORT, AO_RADIO_INT_PIN);
ao_radio_done = 1;
static void
ao_radio_isr(void)
{
ao_exti_disable(AO_RADIO_INT_PORT, AO_RADIO_INT_PIN);
ao_radio_done = 1;
- ao_wakeup(&ao_radio_done);
+ 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);
}
static void
ao_radio_master_start(void)
{
}
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_get_bit(AO_RADIO_CS_PORT, AO_RADIO_CS_PIN, AO_RADIO_CS,
AO_RADIO_SPI_BUS,
{
ao_spi_put_bit(AO_RADIO_CS_PORT, AO_RADIO_CS_PIN, AO_RADIO_CS,
AO_RADIO_SPI_BUS);
{
ao_spi_put_bit(AO_RADIO_CS_PORT, AO_RADIO_CS_PIN, AO_RADIO_CS,
AO_RADIO_SPI_BUS);
static uint8_t
ao_radio_master_send(void)
{
static uint8_t
ao_radio_master_send(void)
{
+ if (!ao_radio_done)
+ printf ("radio not done in ao_radio_master_send\n");
+ PRINTD("send %d\n", ao_radio_spi_request.len);
ao_radio_done = 0;
ao_exti_enable(AO_RADIO_INT_PORT, AO_RADIO_INT_PIN);
ao_radio_master_start();
ao_radio_done = 0;
ao_exti_enable(AO_RADIO_INT_PORT, AO_RADIO_INT_PIN);
ao_radio_master_start();
ao_radio_master_stop();
cli();
while (!ao_radio_done)
ao_radio_master_stop();
cli();
while (!ao_radio_done)
- if (ao_sleep(&ao_radio_done))
+ if (ao_sleep((void *) &ao_radio_done)) {
+ printf ("ao_radio_master awoken\n");
+ PRINTD ("sent, radio done %d\n", ao_radio_done);
+ if (!ao_radio_done)
+ printf ("radio didn't finish after ao_radio_master_send\n");
-static void
-ao_radio_master_recv(uint16_t len)
-{
- ao_radio_master_start();
- ao_spi_recv(&ao_radio_spi_reply,
- len,
- AO_RADIO_SPI_BUS);
- ao_radio_master_stop();
-}
-
static void
ao_radio_get(uint8_t req, uint8_t len)
{
static void
ao_radio_get(uint8_t req, uint8_t len)
{
static void
ao_radio_get_data(__xdata void *d, uint8_t size)
{
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,
AO_RADIO_SPI_REPLY_HEADER_LEN + size,
AO_RADIO_SPI_BUS);
ao_radio_master_stop();
ao_xmemcpy(d, ao_radio_spi_reply.payload, size);
ao_radio_master_start();
ao_spi_recv(&ao_radio_spi_reply,
AO_RADIO_SPI_REPLY_HEADER_LEN + size,
AO_RADIO_SPI_BUS);
ao_radio_master_stop();
ao_xmemcpy(d, ao_radio_spi_reply.payload, size);
+ PRINTD ("fetched %d\n", size);
return 0;
}
ao_radio_get_data(d, size);
return 0;
}
ao_radio_get_data(d, size);
recv = ao_radio_spi_reply.status;
recv = ao_radio_spi_reply.status;
if (len > AO_CMAC_MAX_LEN)
return AO_RADIO_CMAC_LEN_ERROR;
if (len > AO_CMAC_MAX_LEN)
return AO_RADIO_CMAC_LEN_ERROR;
+ PRINTD ("cmac_send: send %d\n", len);
ao_radio_get(AO_RADIO_SPI_CMAC_KEY, AO_AES_LEN);
ao_xmemcpy(&ao_radio_spi_request.payload, &ao_config.aes_key, AO_AES_LEN);
ao_radio_master_send();
ao_radio_put();
ao_radio_get(AO_RADIO_SPI_CMAC_KEY, AO_AES_LEN);
ao_xmemcpy(&ao_radio_spi_request.payload, &ao_config.aes_key, AO_AES_LEN);
ao_radio_master_send();
ao_radio_put();
+ PRINTD ("sending packet\n");
ao_radio_get(AO_RADIO_SPI_CMAC_SEND, len);
ao_xmemcpy(&ao_radio_spi_request.payload, packet, len);
ao_radio_master_send();
ao_radio_put();
ao_radio_get(AO_RADIO_SPI_CMAC_SEND, len);
ao_xmemcpy(&ao_radio_spi_request.payload, packet, len);
ao_radio_master_send();
ao_radio_put();
+ PRINTD ("packet sent\n");
return AO_RADIO_CMAC_OK;
}
return AO_RADIO_CMAC_OK;
}
ao_radio_cmac_recv(__xdata void *packet, uint8_t len, uint16_t timeout) __reentrant
{
int8_t ret;
ao_radio_cmac_recv(__xdata void *packet, uint8_t len, uint16_t timeout) __reentrant
{
int8_t ret;
if (len > AO_CMAC_MAX_LEN)
return AO_RADIO_CMAC_LEN_ERROR;
/* Set the key.
*/
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);
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);
- ao_radio_master_send();
+ recv = ao_radio_master_send();
+ PRINTD ("key set: %d\n", recv);
+ PRINTD ("queuing recv\n");
ao_radio_get(AO_RADIO_SPI_CMAC_RECV, 0);
ao_radio_spi_request.recv_len = len;
recv = ao_radio_master_send();
ao_radio_get(AO_RADIO_SPI_CMAC_RECV, 0);
ao_radio_spi_request.recv_len = len;
recv = ao_radio_master_send();
+ PRINTD ("recv queued: %d\n", recv);
if (!recv) {
ao_radio_put();
ao_radio_recv_abort();
return AO_RADIO_CMAC_TIMEOUT;
}
if (!recv) {
ao_radio_put();
ao_radio_recv_abort();
return AO_RADIO_CMAC_TIMEOUT;
}
+
+ PRINTD ("fetching data\n");
ao_radio_get_data(packet, len);
recv = ao_radio_spi_reply.status;
ao_radio_get_data(packet, len);
recv = ao_radio_spi_reply.status;
+ ao_radio_cmac_rssi = ao_radio_spi_reply.rssi;
+ PRINTD ("data fetched: %d %d\n", recv, ao_radio_cmac_rssi);
ao_arch_nop();
ao_arch_nop();
ao_arch_nop();
ao_arch_nop();
ao_arch_nop();
ao_arch_nop();
- ao_gpio_set(AO_RADIO_SLAVE_INT_PORT, AO_RADIO_SLAVE_INT_BIT, AO_RADIO_SLAVE_INT_PIN, 0);
+ ao_gpio_set(AO_RADIO_SLAVE_INT_PORT, AO_RADIO_SLAVE_INT_BIT, AO_RADIO_SLAVE_INT_PIN, 1);
}
static void
ao_radio_slave_spi(void)
{
}
static void
ao_radio_slave_spi(void)
{
+ uint8_t need_signal = 0;
+
+ ao_spi_get_slave(AO_RADIO_SLAVE_BUS);
- ao_spi_get_slave(AO_RADIO_SLAVE_BUS);
- ao_spi_recv(&ao_radio_spi_request, (2 << 13) | sizeof (ao_radio_spi_request), AO_RADIO_SLAVE_BUS);
- ao_spi_put_slave(AO_RADIO_SLAVE_BUS);
- ao_led_for(AO_LED_RED, AO_MS_TO_TICKS(1000));
+ ao_spi_recv(&ao_radio_spi_request,
+ (2 << 13) | sizeof (ao_radio_spi_request),
+ AO_RADIO_SLAVE_BUS);
+ if (need_signal) {
+ ao_radio_slave_signal();
+ need_signal = 0;
+ }
+ ao_spi_recv_wait();
switch (ao_radio_spi_request.request) {
case AO_RADIO_SPI_RECV:
case AO_RADIO_SPI_CMAC_RECV:
switch (ao_radio_spi_request.request) {
case AO_RADIO_SPI_RECV:
case AO_RADIO_SPI_CMAC_RECV:
ao_radio_spi_recv_len = ao_radio_spi_request.recv_len;
ao_radio_spi_recv_timeout = ao_radio_spi_request.timeout;
ao_wakeup(&ao_radio_spi_recv_len);
ao_radio_spi_recv_len = ao_radio_spi_request.recv_len;
ao_radio_spi_recv_timeout = ao_radio_spi_request.timeout;
ao_wakeup(&ao_radio_spi_recv_len);
case AO_RADIO_SPI_RECV_FETCH:
case AO_RADIO_SPI_RECV_FETCH:
- ao_spi_get_slave(AO_RADIO_SLAVE_BUS);
ao_spi_send(&ao_radio_spi_reply,
ao_spi_send(&ao_radio_spi_reply,
- ao_radio_spi_request.recv_len + AO_RADIO_SPI_REPLY_HEADER_LEN,
+ ao_radio_spi_request.recv_len,
- ao_spi_put_slave(AO_RADIO_SLAVE_BUS);
- break;
+ ao_radio_slave_signal();
+ ao_spi_send_wait();
+ continue;
case AO_RADIO_SPI_RECV_ABORT:
ao_radio_recv_abort();
break;
case AO_RADIO_SPI_SEND:
ao_config.radio_setting = ao_radio_spi_request.setting;
case AO_RADIO_SPI_RECV_ABORT:
ao_radio_recv_abort();
break;
case AO_RADIO_SPI_SEND:
ao_config.radio_setting = ao_radio_spi_request.setting;
- ao_radio_send(&ao_radio_spi_request.payload, ao_radio_spi_request.len - AO_RADIO_SPI_REQUEST_HEADER_LEN);
- ao_radio_slave_signal();
+ ao_radio_send(&ao_radio_spi_request.payload,
+ ao_radio_spi_request.len - AO_RADIO_SPI_REQUEST_HEADER_LEN);
break;
case AO_RADIO_SPI_CMAC_SEND:
ao_config.radio_setting = ao_radio_spi_request.setting;
break;
case AO_RADIO_SPI_CMAC_SEND:
ao_config.radio_setting = ao_radio_spi_request.setting;
- ao_radio_cmac_send(&ao_radio_spi_request.payload, ao_radio_spi_request.len - AO_RADIO_SPI_REQUEST_HEADER_LEN);
- ao_radio_slave_signal();
+ ao_radio_cmac_send(&ao_radio_spi_request.payload,
+ ao_radio_spi_request.len - AO_RADIO_SPI_REQUEST_HEADER_LEN);
break;
case AO_RADIO_SPI_CMAC_KEY:
ao_xmemcpy(&ao_config.aes_key, ao_radio_spi_request.payload, AO_AES_LEN);
break;
case AO_RADIO_SPI_CMAC_KEY:
ao_xmemcpy(&ao_config.aes_key, ao_radio_spi_request.payload, AO_AES_LEN);
- ao_radio_slave_signal();
break;
case AO_RADIO_SPI_TEST_ON:
break;
case AO_RADIO_SPI_TEST_ON:
+ ao_config.radio_setting = ao_radio_spi_request.setting;
- ao_radio_slave_signal();
break;
case AO_RADIO_SPI_TEST_OFF:
ao_radio_test(0);
break;
case AO_RADIO_SPI_TEST_OFF:
ao_radio_test(0);
- ao_radio_slave_signal();