X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=blobdiff_plain;f=src%2Fdrivers%2Fao_radio_slave.c;h=2f1dab29fc0e51c14a8f1a4d30f00dbc73402e60;hp=9dff511b313288cfdd48b799027e1fa1028a9fc2;hb=1085ec5d57e0ed5d132f2bbdac1a0b6a32c0ab4a;hpb=5ed88fb72c3e3ecf3333c700d838667db71cfbdc diff --git a/src/drivers/ao_radio_slave.c b/src/drivers/ao_radio_slave.c index 9dff511b..2f1dab29 100644 --- a/src/drivers/ao_radio_slave.c +++ b/src/drivers/ao_radio_slave.c @@ -3,7 +3,8 @@ * * 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. + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of @@ -23,105 +24,110 @@ 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 __xdata uint8_t slave_state; static void -ao_radio_slave_signal(void) +ao_radio_slave_low(void) { + uint16_t i; + + if (slave_state != 1) + ao_panic(1); 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); + for (i = 0; i < 1000; i++) + ao_arch_nop(); + slave_state = 0; +} + +static void +ao_radio_slave_high(void) +{ + if (slave_state != 0) + ao_panic(2); + ao_gpio_set(AO_RADIO_SLAVE_INT_PORT, AO_RADIO_SLAVE_INT_BIT, AO_RADIO_SLAVE_INT_PIN, 1); + slave_state = 1; } static void ao_radio_slave_spi(void) { + ao_spi_get_slave(AO_RADIO_SLAVE_BUS); 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)); + ao_spi_recv(&ao_radio_spi_request, + (2 << 13) | sizeof (ao_radio_spi_request), + AO_RADIO_SLAVE_BUS); + ao_radio_slave_high(); + ao_spi_recv_wait(); switch (ao_radio_spi_request.request) { case AO_RADIO_SPI_RECV: + + /* XXX monitor CS to interrupt the receive */ + + ao_config.radio_setting = ao_radio_spi_request.setting; + ao_led_on(AO_LED_RX); + ao_radio_spi_reply.status = ao_radio_recv(&ao_radio_spi_reply.payload, + ao_radio_spi_request.recv_len, + ao_radio_spi_request.timeout); + ao_led_off(AO_LED_RX); + ao_radio_spi_reply.rssi = 0; + ao_spi_send(&ao_radio_spi_reply, + AO_RADIO_SPI_REPLY_HEADER_LEN + ao_radio_spi_request.recv_len, + AO_RADIO_SLAVE_BUS); + ao_radio_slave_low(); + ao_spi_send_wait(); + continue; 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_led_on(AO_LED_RX); + ao_radio_spi_reply.status = ao_radio_cmac_recv(&ao_radio_spi_reply.payload, + ao_radio_spi_request.recv_len, + ao_radio_spi_request.timeout); + ao_led_off(AO_LED_RX); + ao_radio_spi_reply.rssi = ao_radio_cmac_rssi; ao_spi_send(&ao_radio_spi_reply, - ao_radio_spi_request.recv_len + AO_RADIO_SPI_REPLY_HEADER_LEN, + AO_RADIO_SPI_REPLY_HEADER_LEN + ao_radio_spi_request.recv_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; + ao_radio_slave_low(); + ao_spi_send_wait(); + continue; 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_led_on(AO_LED_TX); + ao_radio_send(&ao_radio_spi_request.payload, + ao_radio_spi_request.len - AO_RADIO_SPI_REQUEST_HEADER_LEN); + ao_led_off(AO_LED_TX); 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_led_on(AO_LED_TX); + ao_radio_cmac_send(&ao_radio_spi_request.payload, + ao_radio_spi_request.len - AO_RADIO_SPI_REQUEST_HEADER_LEN); + ao_led_off(AO_LED_TX); 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_config.radio_setting = ao_radio_spi_request.setting; 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(); + ao_radio_slave_low(); } } 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); + ao_enable_output(AO_RADIO_SLAVE_INT_PORT, AO_RADIO_SLAVE_INT_BIT, AO_RADIO_SLAVE_INT_PIN, 0); }