2 * Copyright © 2012 Keith Packard <keithp@keithp.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
19 #include <ao_radio_spi.h>
21 #include <ao_radio_cmac.h>
23 static __xdata struct ao_radio_spi_reply ao_radio_spi_reply;
24 static __xdata struct ao_radio_spi_request ao_radio_spi_request;
25 static __xdata uint8_t ao_radio_done;
26 static __xdata uint8_t ao_radio_mutex;
28 __xdata int8_t ao_radio_cmac_rssi;
33 ao_exti_disable(AO_RADIO_INT_PORT, AO_RADIO_INT_PIN);
35 ao_wakeup(&ao_radio_done);
39 ao_radio_master_start(void)
41 ao_spi_get_bit(AO_RADIO_CS_PORT, AO_RADIO_CS_PIN, AO_RADIO_CS,
47 ao_radio_master_stop(void)
49 ao_spi_put_bit(AO_RADIO_CS_PORT, AO_RADIO_CS_PIN, AO_RADIO_CS,
55 ao_radio_master_send(void)
58 ao_exti_enable(AO_RADIO_INT_PORT, AO_RADIO_INT_PIN);
59 ao_radio_master_start();
60 ao_spi_send(&ao_radio_spi_request,
61 ao_radio_spi_request.len,
63 ao_radio_master_stop();
65 while (!ao_radio_done)
66 if (ao_sleep(&ao_radio_done))
73 ao_radio_master_recv(uint16_t len)
75 ao_radio_master_start();
76 ao_spi_recv(&ao_radio_spi_reply,
79 ao_radio_master_stop();
83 ao_radio_get(uint8_t req, uint8_t len)
86 ao_mutex_get(&ao_radio_mutex);
87 ao_radio_spi_request.len = AO_RADIO_SPI_REQUEST_HEADER_LEN + len;
88 ao_radio_spi_request.request = req;
89 ao_radio_spi_request.setting = ao_config.radio_setting;
95 ao_mutex_put(&ao_radio_mutex);
99 ao_radio_get_data(__xdata void *d, uint8_t size)
101 ao_radio_master_start();
102 ao_spi_recv(&ao_radio_spi_reply,
103 AO_RADIO_SPI_REPLY_HEADER_LEN + size,
105 ao_radio_master_stop();
106 ao_xmemcpy(d, ao_radio_spi_reply.payload, size);
110 ao_radio_recv_abort(void)
112 ao_radio_get(AO_RADIO_SPI_RECV_ABORT, 0);
113 ao_radio_master_send();
118 ao_radio_send(const void *d, uint8_t size)
120 ao_radio_get(AO_RADIO_SPI_SEND, size);
121 ao_xmemcpy(&ao_radio_spi_request.payload, d, size);
122 ao_radio_master_send();
128 ao_radio_recv(__xdata void *d, uint8_t size)
136 ao_radio_get(AO_RADIO_SPI_RECV, 0);
137 ao_radio_spi_request.recv_len = size;
138 recv = ao_radio_master_send();
141 ao_radio_recv_abort();
144 ao_radio_get_data(d, size);
145 recv = ao_radio_spi_reply.status;
151 ao_radio_cmac_send(__xdata void *packet, uint8_t len) __reentrant
153 if (len > AO_CMAC_MAX_LEN)
154 return AO_RADIO_CMAC_LEN_ERROR;
158 ao_radio_get(AO_RADIO_SPI_CMAC_KEY, AO_AES_LEN);
159 ao_xmemcpy(&ao_radio_spi_request.payload, &ao_config.aes_key, AO_AES_LEN);
160 ao_radio_master_send();
166 ao_radio_get(AO_RADIO_SPI_CMAC_SEND, len);
167 ao_xmemcpy(&ao_radio_spi_request.payload, packet, len);
168 ao_radio_master_send();
170 return AO_RADIO_CMAC_OK;
174 ao_radio_cmac_recv(__xdata void *packet, uint8_t len, uint16_t timeout) __reentrant
179 if (len > AO_CMAC_MAX_LEN)
180 return AO_RADIO_CMAC_LEN_ERROR;
184 ao_radio_get(AO_RADIO_SPI_CMAC_KEY, AO_AES_LEN);
185 ao_radio_spi_request.timeout = timeout;
186 ao_xmemcpy(&ao_radio_spi_request.payload, &ao_config.aes_key, AO_AES_LEN);
187 ao_radio_master_send();
193 ao_radio_get(AO_RADIO_SPI_CMAC_RECV, 0);
194 ao_radio_spi_request.recv_len = len;
195 recv = ao_radio_master_send();
198 ao_radio_recv_abort();
199 return AO_RADIO_CMAC_TIMEOUT;
201 ao_radio_get_data(packet, len);
202 recv = ao_radio_spi_reply.status;
207 static uint8_t ao_radio_test_on;
210 ao_radio_test(uint8_t on)
213 if (!ao_radio_test_on) {
214 ao_radio_get(AO_RADIO_SPI_TEST_ON, 0);
215 ao_radio_test_on = 1;
216 ao_radio_master_send();
219 if (ao_radio_test_on) {
220 ao_radio_spi_request.len = AO_RADIO_SPI_REQUEST_HEADER_LEN;
221 ao_radio_spi_request.request = AO_RADIO_SPI_TEST_OFF;
222 ao_radio_master_send();
223 ao_radio_test_on = 0;
230 ao_radio_test_cmd(void)
234 if (ao_cmd_lex_c != '\n') {
236 mode = (uint8_t) ao_cmd_lex_u32;
242 printf ("Hit a character to stop..."); flush();
250 __code struct ao_cmds ao_radio_cmds[] = {
251 { ao_radio_test_cmd, "C <1 start, 0 stop, none both>\0Radio carrier test" },
258 ao_spi_init_cs(AO_RADIO_CS_PORT, (1 << AO_RADIO_CS_PIN));
260 ao_enable_port(AO_RADIO_INT_PORT);
261 ao_exti_setup(AO_RADIO_INT_PORT,
263 AO_EXTI_MODE_FALLING,
265 ao_cmd_register(&ao_radio_cmds[0]);