diff options
author | Keith Packard <keithp@keithp.com> | 2012-08-27 13:49:07 -0700 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2012-08-27 13:49:07 -0700 |
commit | c31d07fb35a5b4d283facf649bed3f0f9802d1fc (patch) | |
tree | e2900a97417674359273491ca9f283bc94167f9e /src/drivers/ao_radio_slave.c | |
parent | 0f3483f93137f41a61f3fcbe06afcaffb1b9e17b (diff) |
altos: Add SPI linked radio API
Forward the necessary radio functions over the SPI link
Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'src/drivers/ao_radio_slave.c')
-rw-r--r-- | src/drivers/ao_radio_slave.c | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/src/drivers/ao_radio_slave.c b/src/drivers/ao_radio_slave.c new file mode 100644 index 00000000..9dff511b --- /dev/null +++ b/src/drivers/ao_radio_slave.c @@ -0,0 +1,127 @@ +/* + * 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_radio_spi.h> +#include <ao_radio_cmac.h> + +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_spi_recv_request; +static __xdata uint8_t ao_radio_spi_recv_len; +static __xdata uint16_t ao_radio_spi_recv_timeout; + +static void +ao_radio_slave_signal(void) +{ + ao_gpio_set(AO_RADIO_SLAVE_INT_PORT, AO_RADIO_SLAVE_INT_BIT, AO_RADIO_SLAVE_INT_PIN, 0); + 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); +} + +static void +ao_radio_slave_spi(void) +{ + for (;;) { + 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)); + switch (ao_radio_spi_request.request) { + case AO_RADIO_SPI_RECV: + case AO_RADIO_SPI_CMAC_RECV: + ao_config.radio_setting = ao_radio_spi_request.setting; + ao_radio_spi_recv_request = ao_radio_spi_request.request; + 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); + break; + case AO_RADIO_SPI_RECV_FETCH: + ao_spi_get_slave(AO_RADIO_SLAVE_BUS); + ao_spi_send(&ao_radio_spi_reply, + ao_radio_spi_request.recv_len + AO_RADIO_SPI_REPLY_HEADER_LEN, + AO_RADIO_SLAVE_BUS); + ao_spi_put_slave(AO_RADIO_SLAVE_BUS); + break; + 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(); + 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(); + 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: + ao_radio_test(1); + ao_radio_slave_signal(); + break; + + case AO_RADIO_SPI_TEST_OFF: + ao_radio_test(0); + ao_radio_slave_signal(); + break; + } + } +} + +static void +ao_radio_slave_recv(void) +{ + uint8_t len; + for (;;) { + while (!ao_radio_spi_recv_len) + ao_sleep(&ao_radio_spi_recv_len); + len = ao_radio_spi_recv_len; + ao_radio_spi_recv_len = 0; + if (ao_radio_spi_recv_request == AO_RADIO_SPI_RECV) { + ao_radio_spi_reply.status = ao_radio_recv(&ao_radio_spi_reply.payload, len); + ao_radio_spi_reply.rssi = 0; + } else { + ao_radio_spi_reply.status = ao_radio_cmac_recv(&ao_radio_spi_reply.payload, len, + ao_radio_spi_recv_timeout); + ao_radio_spi_reply.rssi = ao_radio_cmac_rssi; + } + ao_radio_slave_signal(); + } +} + +static __xdata struct ao_task ao_radio_slave_spi_task; +static __xdata struct ao_task ao_radio_slave_recv_task; + +void +ao_radio_slave_init(void) +{ + ao_add_task(&ao_radio_slave_spi_task, ao_radio_slave_spi, "radio_spi"); + ao_add_task(&ao_radio_slave_recv_task, ao_radio_slave_recv, "radio_recv"); + ao_enable_output(AO_RADIO_SLAVE_INT_PORT, AO_RADIO_SLAVE_INT_BIT, AO_RADIO_SLAVE_INT_PIN, 1); +} |