X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=blobdiff_plain;f=src%2Fdrivers%2Fao_radio_master.c;h=79e4b22b4b672d4f75abe1f4579a367cd7c0fc6e;hp=bfbcb1f8d757e7336806f1b0fdb60a805a801624;hb=1085ec5d57e0ed5d132f2bbdac1a0b6a32c0ab4a;hpb=fc9841ee5e92318471b6bec09b7075a788ab8872 diff --git a/src/drivers/ao_radio_master.c b/src/drivers/ao_radio_master.c index bfbcb1f8..79e4b22b 100644 --- a/src/drivers/ao_radio_master.c +++ b/src/drivers/ao_radio_master.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 @@ -22,13 +23,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,27 +40,21 @@ __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); + AO_SPI_SPEED_2MHz); } static void @@ -64,32 +62,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"); + ao_arch_block_interrupts(); + 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; + } + ao_arch_release_interrupts(); + 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(); - cli(); + PRINTD("waiting for send done %d\n", ao_radio_done); + ao_arch_block_interrupts(); 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"); + ao_arch_release_interrupts(); + 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 +128,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, @@ -150,7 +157,7 @@ ao_radio_send(const void *d, uint8_t size) uint8_t -ao_radio_recv(__xdata void *d, uint8_t size) +ao_radio_recv(__xdata void *d, uint8_t size, uint8_t timeout) { int8_t ret; uint8_t recv; @@ -160,6 +167,7 @@ ao_radio_recv(__xdata void *d, uint8_t size) ao_radio_get(AO_RADIO_SPI_RECV, 0); ao_radio_spi_request.recv_len = size; + ao_radio_spi_request.timeout = timeout; recv = ao_radio_master_send(); if (!recv) { ao_radio_put(); @@ -167,21 +175,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 +194,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 +228,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 +309,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]); }