atrf/tools/atspi-id/atspi-id.c |
1 | | /* |
2 | | * atspi-id/atspi-id.c - Identify a ben-wpan AF86RF230 board |
3 | | * |
4 | | * Written 2010 by Werner Almesberger |
5 | | * Copyright 2010 Werner Almesberger |
6 | | * |
7 | | * This program is free software; you can redistribute it and/or modify |
8 | | * it under the terms of the GNU General Public License as published by |
9 | | * the Free Software Foundation; either version 2 of the License, or |
10 | | * (at your option) any later version. |
11 | | */ |
12 | | |
13 | | |
14 | | #include <stdlib.h> |
15 | | #include <stdio.h> |
16 | | #include <usb.h> |
17 | | |
18 | | #include "at86rf230.h" |
19 | | #include "atspi/ep0.h" |
20 | | #include "atspi.h" |
21 | | |
22 | | |
23 | | #define FROM_DEV ATSPI_FROM_DEV(0) |
24 | | |
25 | | #define BUF_SIZE 256 |
26 | | |
27 | | |
28 | | |
29 | | static int get_id(usb_dev_handle *dev, void *data, int size) |
30 | | { |
31 | | int res; |
32 | | |
33 | | res = usb_control_msg(dev, FROM_DEV, ATSPI_ID, 0, 0, data, size, 1000); |
34 | | if (res < 0) |
35 | | fprintf(stderr, "ATSPI_ID: %s\n", usb_strerror()); |
36 | | return res; |
37 | | } |
38 | | |
39 | | |
40 | | static int atspi_get_protocol(usb_dev_handle *dev, |
41 | | uint8_t *major, uint8_t *minor, uint8_t *target) |
42 | | { |
43 | | uint8_t ids[3]; |
44 | | |
45 | | if (get_id(dev, ids, 3) < 0) |
46 | | return -1; |
47 | | if (major) |
48 | | *major = ids[0]; |
49 | | if (minor) |
50 | | *minor = ids[1]; |
51 | | if (target) |
52 | | *target = ids[2]; |
53 | | |
54 | | return 0; |
55 | | } |
56 | | |
57 | | |
58 | | static int atspi_get_build(usb_dev_handle *dev, char *buf, size_t size) |
59 | | { |
60 | | int res; |
61 | | |
62 | | res = usb_control_msg(dev, FROM_DEV, ATSPI_BUILD, 0, 0, buf, size, |
63 | | 1000); |
64 | | if (res < 0) |
65 | | fprintf(stderr, "ATSPI_BUILD: %s\n", usb_strerror()); |
66 | | return res; |
67 | | } |
68 | | |
69 | | |
70 | | static void show_info(usb_dev_handle *dev) |
71 | | { |
72 | | const struct usb_device *device = usb_device(dev); |
73 | | uint8_t major, minor, target; |
74 | | char buf[BUF_SIZE+1]; /* +1 for terminating \0 */ |
75 | | int len; |
76 | | uint8_t part, version, man_id_0, man_id_1; |
77 | | |
78 | | printf("%04x:%04x ", |
79 | | device->descriptor.idVendor, device->descriptor.idProduct); |
80 | | |
81 | | if (atspi_get_protocol(dev, &major, &minor, &target) < 0) |
82 | | exit(1); |
83 | | printf("protocol %u.%u hw %u\n", major, minor, target); |
84 | | |
85 | | len = atspi_get_build(dev, buf, sizeof(buf)-1); |
86 | | if (len < 0) |
87 | | exit(1); |
88 | | buf[len] = 0; |
89 | | printf("%10s%s\n", "", buf); |
90 | | |
91 | | part = atspi_reg_read(dev, REG_PART_NUM); |
92 | | version = atspi_reg_read(dev, REG_VERSION_NUM); |
93 | | man_id_0 = atspi_reg_read(dev, REG_MAN_ID_0); |
94 | | man_id_1 = atspi_reg_read(dev, REG_MAN_ID_1); |
95 | | printf("%10spart 0x%02x version %u manufacturer xxxx%02x%02x\n", "", |
96 | | part, version, man_id_1, man_id_0); |
97 | | } |
98 | | |
99 | | |
100 | | static void usage(const char *name) |
101 | | { |
102 | | fprintf(stderr, "%s\n", name); |
103 | | exit(1); |
104 | | } |
105 | | |
106 | | |
107 | | int main(int argc, const char **argv) |
108 | | { |
109 | | usb_dev_handle *dev; |
110 | | |
111 | | if (argc != 1) |
112 | | usage(*argv); |
113 | | dev = atspi_open(); |
114 | | if (!dev) |
115 | | return 1; |
116 | | |
117 | | show_info(dev); |
118 | | |
119 | | return 0; |
120 | | } |
atrf/tools/atspi-rssi/atspi-rssi.c |
1 | | /* |
2 | | * atspi-rssi/atspi-rssi.c - ben-wpan AF86RF230 spectrum scan |
3 | | * |
4 | | * Written 2010 by Werner Almesberger |
5 | | * Copyright 2010 Werner Almesberger |
6 | | * |
7 | | * This program is free software; you can redistribute it and/or modify |
8 | | * it under the terms of the GNU General Public License as published by |
9 | | * the Free Software Foundation; either version 2 of the License, or |
10 | | * (at your option) any later version. |
11 | | */ |
12 | | |
13 | | |
14 | | #include <stdlib.h> |
15 | | #include <stdio.h> |
16 | | #include <usb.h> |
17 | | #include <sys/time.h> |
18 | | |
19 | | #include "at86rf230.h" |
20 | | #include "atspi/ep0.h" |
21 | | #include "atspi.h" |
22 | | |
23 | | |
24 | | static struct timeval t0; |
25 | | |
26 | | |
27 | | static void sweep(usb_dev_handle *dev) |
28 | | { |
29 | | int chan, rssi; |
30 | | struct timeval t; |
31 | | |
32 | | for (chan = 11; chan <= 26; chan++) { |
33 | | atspi_reg_write(dev, REG_PHY_CC_CCA, chan); |
34 | | /* |
35 | | * No need to explicitly wait for the PPL lock - going USB-SPI |
36 | | * is pretty slow, leaving the transceiver plenty of time. |
37 | | */ |
38 | | gettimeofday(&t, NULL); |
39 | | rssi = atspi_reg_read(dev, REG_PHY_RSSI) & RSSI_MASK; |
40 | | t.tv_sec -= t0.tv_sec; |
41 | | t.tv_usec -= t0.tv_usec; |
42 | | printf("%d %f %d\n", |
43 | | 2405+(chan-11)*5, |
44 | | (double) t.tv_sec+t.tv_usec/1000000.0, |
45 | | -91+3*(rssi-1)); |
46 | | } |
47 | | printf("\n"); |
48 | | } |
49 | | |
50 | | |
51 | | static void usage(const char *name) |
52 | | { |
53 | | fprintf(stderr, "%s sweeps \n", name); |
54 | | exit(1); |
55 | | } |
56 | | |
57 | | |
58 | | int main(int argc, const char **argv) |
59 | | { |
60 | | usb_dev_handle *dev; |
61 | | unsigned long sweeps, i; |
62 | | char *end; |
63 | | |
64 | | if (argc != 2) |
65 | | usage(*argv); |
66 | | sweeps = strtoul(argv[1], &end, 0); |
67 | | if (*end) |
68 | | usage(*argv); |
69 | | |
70 | | dev = atspi_open(); |
71 | | if (!dev) |
72 | | return 1; |
73 | | |
74 | | atspi_reg_write(dev, REG_TRX_STATE, TRX_CMD_TRX_OFF); |
75 | | /* |
76 | | * No need to explicitly wait for things to stabilize - going USB-SPI |
77 | | * is pretty slow, leaving the transceiver more than enough time. |
78 | | */ |
79 | | atspi_reg_write(dev, REG_TRX_STATE, TRX_CMD_RX_ON); |
80 | | |
81 | | gettimeofday(&t0, NULL); |
82 | | for (i = 0; i != sweeps; i++) |
83 | | sweep(dev); |
84 | | |
85 | | atspi_reg_write(dev, REG_TRX_STATE, TRX_CMD_TRX_OFF); |
86 | | |
87 | | return 0; |
88 | | } |
atrf/tools/atspi-trim/atspi-trim.c |
1 | | /* |
2 | | * atspi-trim/atspi-trim.c - AF86RF230 oscillator trim utility |
3 | | * |
4 | | * Written 2010 by Werner Almesberger |
5 | | * Copyright 2010 Werner Almesberger |
6 | | * |
7 | | * This program is free software; you can redistribute it and/or modify |
8 | | * it under the terms of the GNU General Public License as published by |
9 | | * the Free Software Foundation; either version 2 of the License, or |
10 | | * (at your option) any later version. |
11 | | */ |
12 | | |
13 | | |
14 | | #include <stdlib.h> |
15 | | #include <stdio.h> |
16 | | #include <usb.h> |
17 | | #include <sys/time.h> |
18 | | |
19 | | #include "at86rf230.h" |
20 | | #include "atspi/ep0.h" |
21 | | #include "atspi.h" |
22 | | |
23 | | |
24 | | static void usage(const char *name) |
25 | | { |
26 | | fprintf(stderr, "%s [trim_value]\n", name); |
27 | | exit(1); |
28 | | } |
29 | | |
30 | | |
31 | | int main(int argc, const char **argv) |
32 | | { |
33 | | usb_dev_handle *dev; |
34 | | int trim = -1; |
35 | | char *end; |
36 | | |
37 | | switch (argc) { |
38 | | case 1: |
39 | | break; |
40 | | case 2: |
41 | | trim = strtoul(argv[1], &end, 0); |
42 | | if (*end || trim > 15) |
43 | | usage(*argv); |
44 | | break; |
45 | | default: |
46 | | usage(*argv); |
47 | | } |
48 | | |
49 | | dev = atspi_open(); |
50 | | if (!dev) |
51 | | return 1; |
52 | | |
53 | | if (trim == -1) { |
54 | | trim = atspi_reg_read(dev, REG_XOSC_CTRL) & XTAL_TRIM_MASK; |
55 | | printf("%d (%d.%d pF)\n", trim, trim*3/10, trim*3 % 10); |
56 | | } else { |
57 | | atspi_reg_write(dev, REG_XOSC_CTRL, |
58 | | (XTAL_MODE_INT << XTAL_MODE_SHIFT) | trim); |
59 | | } |
60 | | |
61 | | return 0; |
62 | | } |
atrf/tools/atspi-txrx/atspi-txrx.c |
1 | | /* |
2 | | * atspi-txrx/atspi-txrx.c - ben-wpan AF86RF230 TX/RX |
3 | | * |
4 | | * Written 2010 by Werner Almesberger |
5 | | * Copyright 2010 Werner Almesberger |
6 | | * |
7 | | * This program is free software; you can redistribute it and/or modify |
8 | | * it under the terms of the GNU General Public License as published by |
9 | | * the Free Software Foundation; either version 2 of the License, or |
10 | | * (at your option) any later version. |
11 | | */ |
12 | | |
13 | | |
14 | | #include <stdlib.h> |
15 | | #include <stdio.h> |
16 | | #include <string.h> |
17 | | #include <usb.h> |
18 | | |
19 | | #include "at86rf230.h" |
20 | | #include "atspi/ep0.h" |
21 | | #include "atspi.h" |
22 | | |
23 | | |
24 | | /* |
25 | | * According to IEEE 802.15.4-2003 section E.2.6, channel 15 is the only |
26 | | * channel that falls into the 802.11 guard bands in North America an Europe. |
27 | | */ |
28 | | |
29 | | #define DEFAULT_CHANNEL 15 /* channel 15, 2425 MHz */ |
30 | | |
31 | | /* |
32 | | * Transmit power, dBm. IEEE 802.15.4-2003 section E.3.1.3 specifies a transmit |
33 | | * power of 0 dBm for IEEE 802.15.4. We assume an antenna gain of 3 dB or |
34 | | * better. |
35 | | */ |
36 | | |
37 | | #define DEFAULT_POWER -3.2 /* transmit power, dBm */ |
38 | | |
39 | | |
40 | | static double tx_pwr[] = { |
41 | | 3.0, 2.6, 2.1, 1.6, |
42 | | 1.1, 0.5, -0.2, -1.2, |
43 | | -2.2, -3.2, -4.2, -5.2, |
44 | | -7.2, -9.2, -12.2, -17.2 |
45 | | }; |
46 | | |
47 | | |
48 | | static usb_dev_handle *init_txrx(int trim) |
49 | | { |
50 | | usb_dev_handle *dev; |
51 | | |
52 | | dev = atspi_open(); |
53 | | if (!dev) |
54 | | exit(1); |
55 | | |
56 | | atspi_reset_rf(dev); |
57 | | atspi_reg_write(dev, REG_TRX_STATE, TRX_CMD_TRX_OFF); |
58 | | atspi_reg_write(dev, REG_XOSC_CTRL, |
59 | | (XTAL_MODE_INT << XTAL_MODE_SHIFT) | trim); |
60 | | atspi_reg_write(dev, REG_TRX_CTRL_0, 0); /* disable CLKM */ |
61 | | |
62 | | return dev; |
63 | | } |
64 | | |
65 | | |
66 | | static void set_channel(usb_dev_handle *dev, int channel) |
67 | | { |
68 | | atspi_reg_write(dev, REG_PHY_CC_CCA, (1 << CCA_MODE_SHIFT) | channel); |
69 | | } |
70 | | |
71 | | |
72 | | static void set_power(usb_dev_handle *dev, double power) |
73 | | { |
74 | | int n; |
75 | | |
76 | | for (n = 0; n != sizeof(tx_pwr)/sizeof(*tx_pwr)-1; n++) |
77 | | if (tx_pwr[n] <= power) |
78 | | break; |
79 | | atspi_reg_write(dev, REG_PHY_TX_PWR, TX_AUTO_CRC_ON | n); |
80 | | } |
81 | | |
82 | | |
83 | | static void receive(usb_dev_handle *dev) |
84 | | { |
85 | | uint8_t irq; |
86 | | uint8_t buf[MAX_PSDU+1]; /* PSDU+LQI */ |
87 | | int n, ok, i; |
88 | | uint8_t lq; |
89 | | |
90 | | atspi_reg_write(dev, REG_TRX_STATE, TRX_CMD_RX_ON); |
91 | | |
92 | | (void) atspi_reg_read(dev, REG_IRQ_STATUS); |
93 | | |
94 | | fprintf(stderr, "Ready.\n"); |
95 | | while (1) { |
96 | | irq = atspi_reg_read(dev, REG_IRQ_STATUS); |
97 | | if (atspi_error()) |
98 | | exit(1); |
99 | | if (!irq) |
100 | | continue; |
101 | | if (irq == IRQ_TRX_END) |
102 | | break; |
103 | | fprintf(stderr, "IRQ (0x%02x):", irq); |
104 | | if (irq & IRQ_PLL_LOCK) |
105 | | fprintf(stderr, " PLL_LOCK"); |
106 | | if (irq & IRQ_PLL_UNLOCK) |
107 | | fprintf(stderr, " PLL_UNLOCK"); |
108 | | if (irq & IRQ_RX_START) |
109 | | fprintf(stderr, " RX_START"); |
110 | | if (irq & IRQ_TRX_UR) |
111 | | fprintf(stderr, " TRX_UR"); |
112 | | if (irq & IRQ_BAT_LOW) |
113 | | fprintf(stderr, " BAT_LOW"); |
114 | | fprintf(stderr, "\n"); |
115 | | if (irq & IRQ_TRX_END) |
116 | | break; |
117 | | } |
118 | | |
119 | | n = atspi_buf_read(dev, buf, sizeof(buf)); |
120 | | if (n < 0) |
121 | | exit(1); |
122 | | if (n < 3) { |
123 | | fprintf(stderr, "%d bytes received\n", n); |
124 | | exit(1); |
125 | | } |
126 | | ok = !!(atspi_reg_read(dev, REG_PHY_RSSI) & RX_CRC_VALID); |
127 | | lq = buf[n-1]; |
128 | | fprintf(stderr, "%d bytes payload, CRC %s, LQI %u\n", |
129 | | n-3, ok ? "OK" : "BAD", lq); |
130 | | for (i = 0; i != n-3; i++) |
131 | | putchar(buf[i] < ' ' || buf[i] > '~' ? '?' : buf[i]); |
132 | | putchar('\n'); |
133 | | } |
134 | | |
135 | | |
136 | | static void transmit(usb_dev_handle *dev, const char *msg) |
137 | | { |
138 | | uint8_t buf[MAX_PSDU]; |
139 | | |
140 | | atspi_reg_write(dev, REG_TRX_STATE, TRX_CMD_PLL_ON); |
141 | | |
142 | | /* |
143 | | * We need to copy the message to append the CRC placeholders. |
144 | | */ |
145 | | strcpy((void *) buf, msg); |
146 | | atspi_buf_write(dev, buf, strlen(msg)+2); |
147 | | |
148 | | /* @@@ should wait for clear channel */ |
149 | | atspi_reg_write(dev, REG_TRX_STATE, TRX_CMD_TX_START); |
150 | | /* @@@ should wait for TX done */ |
151 | | } |
152 | | |
153 | | |
154 | | static void usage(const char *name) |
155 | | { |
156 | | fprintf(stderr, |
157 | | "usage: %s [-c channel] [-p power] [-t trim] [message]\n" |
158 | | " -c channel channel number, 11 to 26 (default %d)\n" |
159 | | " -p power transmit power, -17.2 to 3.0 dBm (default %.1f)\n" |
160 | | " -t trim trim capacitor, 0 to 15 (default 0)\n" |
161 | | , name , DEFAULT_CHANNEL, DEFAULT_POWER); |
162 | | exit(1); |
163 | | } |
164 | | |
165 | | |
166 | | int main(int argc, char *const *argv) |
167 | | { |
168 | | int channel = DEFAULT_CHANNEL; |
169 | | double power = DEFAULT_POWER; |
170 | | int trim = 0; |
171 | | char *end; |
172 | | int c; |
173 | | usb_dev_handle *dev; |
174 | | |
175 | | while ((c = getopt(argc, argv, "c:p:t:")) != EOF) |
176 | | switch (c) { |
177 | | case 'c': |
178 | | channel = strtoul(optarg, &end, 0); |
179 | | if (*end) |
180 | | usage(*argv); |
181 | | if (channel < 11 || channel > 26) |
182 | | usage(*argv); |
183 | | break; |
184 | | case 'p': |
185 | | power = strtod(optarg, &end); |
186 | | if (*end) |
187 | | usage(*argv); |
188 | | break; |
189 | | case 't': |
190 | | trim = strtoul(optarg, &end, 0); |
191 | | if (*end) |
192 | | usage(*argv); |
193 | | if (trim > 15) |
194 | | usage(*argv); |
195 | | break; |
196 | | default: |
197 | | usage(*argv); |
198 | | } |
199 | | |
200 | | switch (argc-optind) { |
201 | | case 0: |
202 | | dev = init_txrx(trim); |
203 | | set_channel(dev, channel); |
204 | | receive(dev); |
205 | | break; |
206 | | case 1: |
207 | | dev = init_txrx(trim); |
208 | | set_channel(dev, channel); |
209 | | set_power(dev, power); |
210 | | transmit(dev, argv[optind]); |
211 | | break; |
212 | | default: |
213 | | usage(*argv); |
214 | | } |
215 | | |
216 | | return 0; |
217 | | } |
atrf/tools/include/atspi.h |
1 | | /* |
2 | | * include/atspi.h - ATSPI access functions library |
3 | | * |
4 | | * Written 2010 by Werner Almesberger |
5 | | * Copyright 2010 Werner Almesberger |
6 | | * |
7 | | * This program is free software; you can redistribute it and/or modify |
8 | | * it under the terms of the GNU General Public License as published by |
9 | | * the Free Software Foundation; either version 2 of the License, or |
10 | | * (at your option) any later version. |
11 | | */ |
12 | | |
13 | | #ifndef ATSPI_H |
14 | | #define ATSPI_H |
15 | | |
16 | | #include <stdint.h> |
17 | | #include <usb.h> |
18 | | |
19 | | |
20 | | int atspi_error(void); |
21 | | int atspi_clear_error(void); |
22 | | |
23 | | usb_dev_handle *atspi_open(void); |
24 | | void atspi_close(usb_dev_handle *dev); |
25 | | |
26 | | void atspi_reset(usb_dev_handle *dev); |
27 | | void atspi_reset_rf(usb_dev_handle *dev); |
28 | | |
29 | | void atspi_reg_write(usb_dev_handle *dev, uint8_t reg, uint8_t value); |
30 | | uint8_t atspi_reg_read(usb_dev_handle *dev, uint8_t reg); |
31 | | |
32 | | void atspi_buf_write(usb_dev_handle *dev, const void *buf, int size); |
33 | | int atspi_buf_read(usb_dev_handle *dev, void *buf, int size); |
34 | | |
35 | | #endif /* !ATSPI_H */ |
atrf/tools/lib/atspi.c |
1 | | /* |
2 | | * lib/atspi.c - ATSPI access functions library |
3 | | * |
4 | | * Written 2010 by Werner Almesberger |
5 | | * Copyright 2010 Werner Almesberger |
6 | | * |
7 | | * This program is free software; you can redistribute it and/or modify |
8 | | * it under the terms of the GNU General Public License as published by |
9 | | * the Free Software Foundation; either version 2 of the License, or |
10 | | * (at your option) any later version. |
11 | | */ |
12 | | |
13 | | |
14 | | #include <stdio.h> |
15 | | #include <usb.h> |
16 | | |
17 | | #include "f32xbase/usb.h" |
18 | | #include "atspi/ep0.h" |
19 | | #include "atspi/usb-ids.h" |
20 | | |
21 | | #include "atspi.h" |
22 | | |
23 | | |
24 | | #define FROM_DEV ATSPI_FROM_DEV(0) |
25 | | #define TO_DEV ATSPI_TO_DEV(0) |
26 | | |
27 | | |
28 | | /* ----- error handling ---------------------------------------------------- */ |
29 | | |
30 | | |
31 | | static int error; |
32 | | |
33 | | |
34 | | int atspi_error(void) |
35 | | { |
36 | | return error; |
37 | | } |
38 | | |
39 | | |
40 | | int atspi_clear_error(void) |
41 | | { |
42 | | int ret; |
43 | | |
44 | | ret = error; |
45 | | error = 0; |
46 | | return ret; |
47 | | } |
48 | | |
49 | | |
50 | | /* ----- open/close -------------------------------------------------------- */ |
51 | | |
52 | | |
53 | | usb_dev_handle *atspi_open(void) |
54 | | { |
55 | | usb_dev_handle *dev; |
56 | | |
57 | | dev = open_usb(USB_VENDOR, USB_PRODUCT); |
58 | | if (dev) { |
59 | | error = 0; |
60 | | } else { |
61 | | fprintf(stderr, ":-(\n"); |
62 | | error = 1; |
63 | | } |
64 | | return dev; |
65 | | } |
66 | | |
67 | | |
68 | | void atspi_close(usb_dev_handle *dev) |
69 | | { |
70 | | /* to do */ |
71 | | } |
72 | | |
73 | | |
74 | | /* ----- device mode ------------------------------------------------------- */ |
75 | | |
76 | | |
77 | | void atspi_reset(usb_dev_handle *dev) |
78 | | { |
79 | | int res; |
80 | | |
81 | | if (error) |
82 | | return; |
83 | | |
84 | | res = |
85 | | usb_control_msg(dev, TO_DEV, ATSPI_RESET, 0, 0, NULL, 0, 1000); |
86 | | if (res < 0) { |
87 | | fprintf(stderr, "ATSPI_RESET: %d\n", res); |
88 | | error = 1; |
89 | | } |
90 | | } |
91 | | |
92 | | |
93 | | void atspi_reset_rf(usb_dev_handle *dev) |
94 | | { |
95 | | int res; |
96 | | |
97 | | if (error) |
98 | | return; |
99 | | |
100 | | res = |
101 | | usb_control_msg(dev, TO_DEV, ATSPI_RF_RESET, 0, 0, NULL, 0, 1000); |
102 | | if (res < 0) { |
103 | | fprintf(stderr, "ATSPI_RF_RESET: %d\n", res); |
104 | | error = 1; |
105 | | } |
106 | | } |
107 | | |
108 | | |
109 | | /* ----- register access --------------------------------------------------- */ |
110 | | |
111 | | |
112 | | void atspi_reg_write(usb_dev_handle *dev, uint8_t reg, uint8_t value) |
113 | | { |
114 | | int res; |
115 | | |
116 | | if (error) |
117 | | return; |
118 | | |
119 | | res = usb_control_msg(dev, TO_DEV, ATSPI_REG_WRITE, value, reg, |
120 | | NULL, 0, 1000); |
121 | | if (res < 0) { |
122 | | fprintf(stderr, "ATSPI_REG_WRITE: %d\n", res); |
123 | | error = 1; |
124 | | } |
125 | | } |
126 | | |
127 | | |
128 | | uint8_t atspi_reg_read(usb_dev_handle *dev, uint8_t reg) |
129 | | { |
130 | | uint8_t value = 0; |
131 | | int res; |
132 | | |
133 | | if (error) |
134 | | return 0; |
135 | | |
136 | | res = usb_control_msg(dev, FROM_DEV, ATSPI_REG_READ, 0, reg, |
137 | | (void *) &value, 1, 1000); |
138 | | if (res < 0) { |
139 | | fprintf(stderr, "ATSPI_REG_READ: %d\n", res); |
140 | | error = 1; |
141 | | } |
142 | | return value; |
143 | | } |
144 | | |
145 | | |
146 | | /* ----- frame buffer access ----------------------------------------------- */ |
147 | | |
148 | | |
149 | | void atspi_buf_write(usb_dev_handle *dev, const void *buf, int size) |
150 | | { |
151 | | int res; |
152 | | |
153 | | if (error) |
154 | | return; |
155 | | |
156 | | res = usb_control_msg(dev, TO_DEV, ATSPI_BUF_WRITE, 0, 0, |
157 | | (void *) buf, size, 1000); |
158 | | if (res < 0) { |
159 | | fprintf(stderr, "ATSPI_BUF_WRITE: %d\n", res); |
160 | | error = 1; |
161 | | } |
162 | | |
163 | | } |
164 | | |
165 | | |
166 | | int atspi_buf_read(usb_dev_handle *dev, void *buf, int size) |
167 | | { |
168 | | int res; |
169 | | |
170 | | if (error) |
171 | | return -1; |
172 | | |
173 | | res = usb_control_msg(dev, FROM_DEV, ATSPI_BUF_READ, 0, 0, |
174 | | buf, size, 1000); |
175 | | if (res < 0) { |
176 | | fprintf(stderr, "ATSPI_BUF_READ: %d\n", res); |
177 | | error = 1; |
178 | | } |
179 | | |
180 | | return res; |
181 | | } |
tools/atspi-id/atspi-id.c |
| 1 | /* |
| 2 | * atspi-id/atspi-id.c - Identify a ben-wpan AF86RF230 board |
| 3 | * |
| 4 | * Written 2010 by Werner Almesberger |
| 5 | * Copyright 2010 Werner Almesberger |
| 6 | * |
| 7 | * This program is free software; you can redistribute it and/or modify |
| 8 | * it under the terms of the GNU General Public License as published by |
| 9 | * the Free Software Foundation; either version 2 of the License, or |
| 10 | * (at your option) any later version. |
| 11 | */ |
| 12 | |
| 13 | |
| 14 | #include <stdlib.h> |
| 15 | #include <stdio.h> |
| 16 | #include <usb.h> |
| 17 | |
| 18 | #include "at86rf230.h" |
| 19 | #include "atspi/ep0.h" |
| 20 | #include "atspi.h" |
| 21 | |
| 22 | |
| 23 | #define FROM_DEV ATSPI_FROM_DEV(0) |
| 24 | |
| 25 | #define BUF_SIZE 256 |
| 26 | |
| 27 | |
| 28 | |
| 29 | static int get_id(usb_dev_handle *dev, void *data, int size) |
| 30 | { |
| 31 | int res; |
| 32 | |
| 33 | res = usb_control_msg(dev, FROM_DEV, ATSPI_ID, 0, 0, data, size, 1000); |
| 34 | if (res < 0) |
| 35 | fprintf(stderr, "ATSPI_ID: %s\n", usb_strerror()); |
| 36 | return res; |
| 37 | } |
| 38 | |
| 39 | |
| 40 | static int atspi_get_protocol(usb_dev_handle *dev, |
| 41 | uint8_t *major, uint8_t *minor, uint8_t *target) |
| 42 | { |
| 43 | uint8_t ids[3]; |
| 44 | |
| 45 | if (get_id(dev, ids, 3) < 0) |
| 46 | return -1; |
| 47 | if (major) |
| 48 | *major = ids[0]; |
| 49 | if (minor) |
| 50 | *minor = ids[1]; |
| 51 | if (target) |
| 52 | *target = ids[2]; |
| 53 | |
| 54 | return 0; |
| 55 | } |
| 56 | |
| 57 | |
| 58 | static int atspi_get_build(usb_dev_handle *dev, char *buf, size_t size) |
| 59 | { |
| 60 | int res; |
| 61 | |
| 62 | res = usb_control_msg(dev, FROM_DEV, ATSPI_BUILD, 0, 0, buf, size, |
| 63 | 1000); |
| 64 | if (res < 0) |
| 65 | fprintf(stderr, "ATSPI_BUILD: %s\n", usb_strerror()); |
| 66 | return res; |
| 67 | } |
| 68 | |
| 69 | |
| 70 | static void show_info(usb_dev_handle *dev) |
| 71 | { |
| 72 | const struct usb_device *device = usb_device(dev); |
| 73 | uint8_t major, minor, target; |
| 74 | char buf[BUF_SIZE+1]; /* +1 for terminating \0 */ |
| 75 | int len; |
| 76 | uint8_t part, version, man_id_0, man_id_1; |
| 77 | |
| 78 | printf("%04x:%04x ", |
| 79 | device->descriptor.idVendor, device->descriptor.idProduct); |
| 80 | |
| 81 | if (atspi_get_protocol(dev, &major, &minor, &target) < 0) |
| 82 | exit(1); |
| 83 | printf("protocol %u.%u hw %u\n", major, minor, target); |
| 84 | |
| 85 | len = atspi_get_build(dev, buf, sizeof(buf)-1); |
| 86 | if (len < 0) |
| 87 | exit(1); |
| 88 | buf[len] = 0; |
| 89 | printf("%10s%s\n", "", buf); |
| 90 | |
| 91 | part = atspi_reg_read(dev, REG_PART_NUM); |
| 92 | version = atspi_reg_read(dev, REG_VERSION_NUM); |
| 93 | man_id_0 = atspi_reg_read(dev, REG_MAN_ID_0); |
| 94 | man_id_1 = atspi_reg_read(dev, REG_MAN_ID_1); |
| 95 | printf("%10spart 0x%02x version %u manufacturer xxxx%02x%02x\n", "", |
| 96 | part, version, man_id_1, man_id_0); |
| 97 | } |
| 98 | |
| 99 | |
| 100 | static void usage(const char *name) |
| 101 | { |
| 102 | fprintf(stderr, "%s\n", name); |
| 103 | exit(1); |
| 104 | } |
| 105 | |
| 106 | |
| 107 | int main(int argc, const char **argv) |
| 108 | { |
| 109 | usb_dev_handle *dev; |
| 110 | |
| 111 | if (argc != 1) |
| 112 | usage(*argv); |
| 113 | dev = atspi_open(); |
| 114 | if (!dev) |
| 115 | return 1; |
| 116 | |
| 117 | show_info(dev); |
| 118 | |
| 119 | return 0; |
| 120 | } |
tools/atspi-rssi/atspi-rssi.c |
| 1 | /* |
| 2 | * atspi-rssi/atspi-rssi.c - ben-wpan AF86RF230 spectrum scan |
| 3 | * |
| 4 | * Written 2010 by Werner Almesberger |
| 5 | * Copyright 2010 Werner Almesberger |
| 6 | * |
| 7 | * This program is free software; you can redistribute it and/or modify |
| 8 | * it under the terms of the GNU General Public License as published by |
| 9 | * the Free Software Foundation; either version 2 of the License, or |
| 10 | * (at your option) any later version. |
| 11 | */ |
| 12 | |
| 13 | |
| 14 | #include <stdlib.h> |
| 15 | #include <stdio.h> |
| 16 | #include <usb.h> |
| 17 | #include <sys/time.h> |
| 18 | |
| 19 | #include "at86rf230.h" |
| 20 | #include "atspi/ep0.h" |
| 21 | #include "atspi.h" |
| 22 | |
| 23 | |
| 24 | static struct timeval t0; |
| 25 | |
| 26 | |
| 27 | static void sweep(usb_dev_handle *dev) |
| 28 | { |
| 29 | int chan, rssi; |
| 30 | struct timeval t; |
| 31 | |
| 32 | for (chan = 11; chan <= 26; chan++) { |
| 33 | atspi_reg_write(dev, REG_PHY_CC_CCA, chan); |
| 34 | /* |
| 35 | * No need to explicitly wait for the PPL lock - going USB-SPI |
| 36 | * is pretty slow, leaving the transceiver plenty of time. |
| 37 | */ |
| 38 | gettimeofday(&t, NULL); |
| 39 | rssi = atspi_reg_read(dev, REG_PHY_RSSI) & RSSI_MASK; |
| 40 | t.tv_sec -= t0.tv_sec; |
| 41 | t.tv_usec -= t0.tv_usec; |
| 42 | printf("%d %f %d\n", |
| 43 | 2405+(chan-11)*5, |
| 44 | (double) t.tv_sec+t.tv_usec/1000000.0, |
| 45 | -91+3*(rssi-1)); |
| 46 | } |
| 47 | printf("\n"); |
| 48 | } |
| 49 | |
| 50 | |
| 51 | static void usage(const char *name) |
| 52 | { |
| 53 | fprintf(stderr, "%s sweeps \n", name); |
| 54 | exit(1); |
| 55 | } |
| 56 | |
| 57 | |
| 58 | int main(int argc, const char **argv) |
| 59 | { |
| 60 | usb_dev_handle *dev; |
| 61 | unsigned long sweeps, i; |
| 62 | char *end; |
| 63 | |
| 64 | if (argc != 2) |
| 65 | usage(*argv); |
| 66 | sweeps = strtoul(argv[1], &end, 0); |
| 67 | if (*end) |
| 68 | usage(*argv); |
| 69 | |
| 70 | dev = atspi_open(); |
| 71 | if (!dev) |
| 72 | return 1; |
| 73 | |
| 74 | atspi_reg_write(dev, REG_TRX_STATE, TRX_CMD_TRX_OFF); |
| 75 | /* |
| 76 | * No need to explicitly wait for things to stabilize - going USB-SPI |
| 77 | * is pretty slow, leaving the transceiver more than enough time. |
| 78 | */ |
| 79 | atspi_reg_write(dev, REG_TRX_STATE, TRX_CMD_RX_ON); |
| 80 | |
| 81 | gettimeofday(&t0, NULL); |
| 82 | for (i = 0; i != sweeps; i++) |
| 83 | sweep(dev); |
| 84 | |
| 85 | atspi_reg_write(dev, REG_TRX_STATE, TRX_CMD_TRX_OFF); |
| 86 | |
| 87 | return 0; |
| 88 | } |
tools/atspi-trim/atspi-trim.c |
| 1 | /* |
| 2 | * atspi-trim/atspi-trim.c - AF86RF230 oscillator trim utility |
| 3 | * |
| 4 | * Written 2010 by Werner Almesberger |
| 5 | * Copyright 2010 Werner Almesberger |
| 6 | * |
| 7 | * This program is free software; you can redistribute it and/or modify |
| 8 | * it under the terms of the GNU General Public License as published by |
| 9 | * the Free Software Foundation; either version 2 of the License, or |
| 10 | * (at your option) any later version. |
| 11 | */ |
| 12 | |
| 13 | |
| 14 | #include <stdlib.h> |
| 15 | #include <stdio.h> |
| 16 | #include <usb.h> |
| 17 | #include <sys/time.h> |
| 18 | |
| 19 | #include "at86rf230.h" |
| 20 | #include "atspi/ep0.h" |
| 21 | #include "atspi.h" |
| 22 | |
| 23 | |
| 24 | static void usage(const char *name) |
| 25 | { |
| 26 | fprintf(stderr, "%s [trim_value]\n", name); |
| 27 | exit(1); |
| 28 | } |
| 29 | |
| 30 | |
| 31 | int main(int argc, const char **argv) |
| 32 | { |
| 33 | usb_dev_handle *dev; |
| 34 | int trim = -1; |
| 35 | char *end; |
| 36 | |
| 37 | switch (argc) { |
| 38 | case 1: |
| 39 | break; |
| 40 | case 2: |
| 41 | trim = strtoul(argv[1], &end, 0); |
| 42 | if (*end || trim > 15) |
| 43 | usage(*argv); |
| 44 | break; |
| 45 | default: |
| 46 | usage(*argv); |
| 47 | } |
| 48 | |
| 49 | dev = atspi_open(); |
| 50 | if (!dev) |
| 51 | return 1; |
| 52 | |
| 53 | if (trim == -1) { |
| 54 | trim = atspi_reg_read(dev, REG_XOSC_CTRL) & XTAL_TRIM_MASK; |
| 55 | printf("%d (%d.%d pF)\n", trim, trim*3/10, trim*3 % 10); |
| 56 | } else { |
| 57 | atspi_reg_write(dev, REG_XOSC_CTRL, |
| 58 | (XTAL_MODE_INT << XTAL_MODE_SHIFT) | trim); |
| 59 | } |
| 60 | |
| 61 | return 0; |
| 62 | } |
tools/atspi-txrx/atspi-txrx.c |
| 1 | /* |
| 2 | * atspi-txrx/atspi-txrx.c - ben-wpan AF86RF230 TX/RX |
| 3 | * |
| 4 | * Written 2010 by Werner Almesberger |
| 5 | * Copyright 2010 Werner Almesberger |
| 6 | * |
| 7 | * This program is free software; you can redistribute it and/or modify |
| 8 | * it under the terms of the GNU General Public License as published by |
| 9 | * the Free Software Foundation; either version 2 of the License, or |
| 10 | * (at your option) any later version. |
| 11 | */ |
| 12 | |
| 13 | |
| 14 | #include <stdlib.h> |
| 15 | #include <stdio.h> |
| 16 | #include <string.h> |
| 17 | #include <usb.h> |
| 18 | |
| 19 | #include "at86rf230.h" |
| 20 | #include "atspi/ep0.h" |
| 21 | #include "atspi.h" |
| 22 | |
| 23 | |
| 24 | /* |
| 25 | * According to IEEE 802.15.4-2003 section E.2.6, channel 15 is the only |
| 26 | * channel that falls into the 802.11 guard bands in North America an Europe. |
| 27 | */ |
| 28 | |
| 29 | #define DEFAULT_CHANNEL 15 /* channel 15, 2425 MHz */ |
| 30 | |
| 31 | /* |
| 32 | * Transmit power, dBm. IEEE 802.15.4-2003 section E.3.1.3 specifies a transmit |
| 33 | * power of 0 dBm for IEEE 802.15.4. We assume an antenna gain of 3 dB or |
| 34 | * better. |
| 35 | */ |
| 36 | |
| 37 | #define DEFAULT_POWER -3.2 /* transmit power, dBm */ |
| 38 | |
| 39 | |
| 40 | static double tx_pwr[] = { |
| 41 | 3.0, 2.6, 2.1, 1.6, |
| 42 | 1.1, 0.5, -0.2, -1.2, |
| 43 | -2.2, -3.2, -4.2, -5.2, |
| 44 | -7.2, -9.2, -12.2, -17.2 |
| 45 | }; |
| 46 | |
| 47 | |
| 48 | static usb_dev_handle *init_txrx(int trim) |
| 49 | { |
| 50 | usb_dev_handle *dev; |
| 51 | |
| 52 | dev = atspi_open(); |
| 53 | if (!dev) |
| 54 | exit(1); |
| 55 | |
| 56 | atspi_reset_rf(dev); |
| 57 | atspi_reg_write(dev, REG_TRX_STATE, TRX_CMD_TRX_OFF); |
| 58 | atspi_reg_write(dev, REG_XOSC_CTRL, |
| 59 | (XTAL_MODE_INT << XTAL_MODE_SHIFT) | trim); |
| 60 | atspi_reg_write(dev, REG_TRX_CTRL_0, 0); /* disable CLKM */ |
| 61 | |
| 62 | return dev; |
| 63 | } |
| 64 | |
| 65 | |
| 66 | static void set_channel(usb_dev_handle *dev, int channel) |
| 67 | { |
| 68 | atspi_reg_write(dev, REG_PHY_CC_CCA, (1 << CCA_MODE_SHIFT) | channel); |
| 69 | } |
| 70 | |
| 71 | |
| 72 | static void set_power(usb_dev_handle *dev, double power) |
| 73 | { |
| 74 | int n; |
| 75 | |
| 76 | for (n = 0; n != sizeof(tx_pwr)/sizeof(*tx_pwr)-1; n++) |
| 77 | if (tx_pwr[n] <= power) |
| 78 | break; |
| 79 | atspi_reg_write(dev, REG_PHY_TX_PWR, TX_AUTO_CRC_ON | n); |
| 80 | } |
| 81 | |
| 82 | |
| 83 | static void receive(usb_dev_handle *dev) |
| 84 | { |
| 85 | uint8_t irq; |
| 86 | uint8_t buf[MAX_PSDU+1]; /* PSDU+LQI */ |
| 87 | int n, ok, i; |
| 88 | uint8_t lq; |
| 89 | |
| 90 | atspi_reg_write(dev, REG_TRX_STATE, TRX_CMD_RX_ON); |
| 91 | |
| 92 | (void) atspi_reg_read(dev, REG_IRQ_STATUS); |
| 93 | |
| 94 | fprintf(stderr, "Ready.\n"); |
| 95 | while (1) { |
| 96 | irq = atspi_reg_read(dev, REG_IRQ_STATUS); |
| 97 | if (atspi_error()) |
| 98 | exit(1); |
| 99 | if (!irq) |
| 100 | continue; |
| 101 | if (irq == IRQ_TRX_END) |
| 102 | break; |
| 103 | fprintf(stderr, "IRQ (0x%02x):", irq); |
| 104 | if (irq & IRQ_PLL_LOCK) |
| 105 | fprintf(stderr, " PLL_LOCK"); |
| 106 | if (irq & IRQ_PLL_UNLOCK) |
| 107 | fprintf(stderr, " PLL_UNLOCK"); |
| 108 | if (irq & IRQ_RX_START) |
| 109 | fprintf(stderr, " RX_START"); |
| 110 | if (irq & IRQ_TRX_UR) |
| 111 | fprintf(stderr, " TRX_UR"); |
| 112 | if (irq & IRQ_BAT_LOW) |
| 113 | fprintf(stderr, " BAT_LOW"); |
| 114 | fprintf(stderr, "\n"); |
| 115 | if (irq & IRQ_TRX_END) |
| 116 | break; |
| 117 | } |
| 118 | |
| 119 | n = atspi_buf_read(dev, buf, sizeof(buf)); |
| 120 | if (n < 0) |
| 121 | exit(1); |
| 122 | if (n < 3) { |
| 123 | fprintf(stderr, "%d bytes received\n", n); |
| 124 | exit(1); |
| 125 | } |
| 126 | ok = !!(atspi_reg_read(dev, REG_PHY_RSSI) & RX_CRC_VALID); |
| 127 | lq = buf[n-1]; |
| 128 | fprintf(stderr, "%d bytes payload, CRC %s, LQI %u\n", |
| 129 | n-3, ok ? "OK" : "BAD", lq); |
| 130 | for (i = 0; i != n-3; i++) |
| 131 | putchar(buf[i] < ' ' || buf[i] > '~' ? '?' : buf[i]); |
| 132 | putchar('\n'); |
| 133 | } |
| 134 | |
| 135 | |
| 136 | static void transmit(usb_dev_handle *dev, const char *msg) |
| 137 | { |
| 138 | uint8_t buf[MAX_PSDU]; |
| 139 | |
| 140 | atspi_reg_write(dev, REG_TRX_STATE, TRX_CMD_PLL_ON); |
| 141 | |
| 142 | /* |
| 143 | * We need to copy the message to append the CRC placeholders. |
| 144 | */ |
| 145 | strcpy((void *) buf, msg); |
| 146 | atspi_buf_write(dev, buf, strlen(msg)+2); |
| 147 | |
| 148 | /* @@@ should wait for clear channel */ |
| 149 | atspi_reg_write(dev, REG_TRX_STATE, TRX_CMD_TX_START); |
| 150 | /* @@@ should wait for TX done */ |
| 151 | } |
| 152 | |
| 153 | |
| 154 | static void usage(const char *name) |
| 155 | { |
| 156 | fprintf(stderr, |
| 157 | "usage: %s [-c channel] [-p power] [-t trim] [message]\n" |
| 158 | " -c channel channel number, 11 to 26 (default %d)\n" |
| 159 | " -p power transmit power, -17.2 to 3.0 dBm (default %.1f)\n" |
| 160 | " -t trim trim capacitor, 0 to 15 (default 0)\n" |
| 161 | , name , DEFAULT_CHANNEL, DEFAULT_POWER); |
| 162 | exit(1); |
| 163 | } |
| 164 | |
| 165 | |
| 166 | int main(int argc, char *const *argv) |
| 167 | { |
| 168 | int channel = DEFAULT_CHANNEL; |
| 169 | double power = DEFAULT_POWER; |
| 170 | int trim = 0; |
| 171 | char *end; |
| 172 | int c; |
| 173 | usb_dev_handle *dev; |
| 174 | |
| 175 | while ((c = getopt(argc, argv, "c:p:t:")) != EOF) |
| 176 | switch (c) { |
| 177 | case 'c': |
| 178 | channel = strtoul(optarg, &end, 0); |
| 179 | if (*end) |
| 180 | usage(*argv); |
| 181 | if (channel < 11 || channel > 26) |
| 182 | usage(*argv); |
| 183 | break; |
| 184 | case 'p': |
| 185 | power = strtod(optarg, &end); |
| 186 | if (*end) |
| 187 | usage(*argv); |
| 188 | break; |
| 189 | case 't': |
| 190 | trim = strtoul(optarg, &end, 0); |
| 191 | if (*end) |
| 192 | usage(*argv); |
| 193 | if (trim > 15) |
| 194 | usage(*argv); |
| 195 | break; |
| 196 | default: |
| 197 | usage(*argv); |
| 198 | } |
| 199 | |
| 200 | switch (argc-optind) { |
| 201 | case 0: |
| 202 | dev = init_txrx(trim); |
| 203 | set_channel(dev, channel); |
| 204 | receive(dev); |
| 205 | break; |
| 206 | case 1: |
| 207 | dev = init_txrx(trim); |
| 208 | set_channel(dev, channel); |
| 209 | set_power(dev, power); |
| 210 | transmit(dev, argv[optind]); |
| 211 | break; |
| 212 | default: |
| 213 | usage(*argv); |
| 214 | } |
| 215 | |
| 216 | return 0; |
| 217 | } |
tools/include/atspi.h |
| 1 | /* |
| 2 | * include/atspi.h - ATSPI access functions library |
| 3 | * |
| 4 | * Written 2010 by Werner Almesberger |
| 5 | * Copyright 2010 Werner Almesberger |
| 6 | * |
| 7 | * This program is free software; you can redistribute it and/or modify |
| 8 | * it under the terms of the GNU General Public License as published by |
| 9 | * the Free Software Foundation; either version 2 of the License, or |
| 10 | * (at your option) any later version. |
| 11 | */ |
| 12 | |
| 13 | #ifndef ATSPI_H |
| 14 | #define ATSPI_H |
| 15 | |
| 16 | #include <stdint.h> |
| 17 | #include <usb.h> |
| 18 | |
| 19 | |
| 20 | int atspi_error(void); |
| 21 | int atspi_clear_error(void); |
| 22 | |
| 23 | usb_dev_handle *atspi_open(void); |
| 24 | void atspi_close(usb_dev_handle *dev); |
| 25 | |
| 26 | void atspi_reset(usb_dev_handle *dev); |
| 27 | void atspi_reset_rf(usb_dev_handle *dev); |
| 28 | |
| 29 | void atspi_reg_write(usb_dev_handle *dev, uint8_t reg, uint8_t value); |
| 30 | uint8_t atspi_reg_read(usb_dev_handle *dev, uint8_t reg); |
| 31 | |
| 32 | void atspi_buf_write(usb_dev_handle *dev, const void *buf, int size); |
| 33 | int atspi_buf_read(usb_dev_handle *dev, void *buf, int size); |
| 34 | |
| 35 | #endif /* !ATSPI_H */ |
tools/lib/atspi.c |
| 1 | /* |
| 2 | * lib/atspi.c - ATSPI access functions library |
| 3 | * |
| 4 | * Written 2010 by Werner Almesberger |
| 5 | * Copyright 2010 Werner Almesberger |
| 6 | * |
| 7 | * This program is free software; you can redistribute it and/or modify |
| 8 | * it under the terms of the GNU General Public License as published by |
| 9 | * the Free Software Foundation; either version 2 of the License, or |
| 10 | * (at your option) any later version. |
| 11 | */ |
| 12 | |
| 13 | |
| 14 | #include <stdio.h> |
| 15 | #include <usb.h> |
| 16 | |
| 17 | #include "f32xbase/usb.h" |
| 18 | #include "atspi/ep0.h" |
| 19 | #include "atspi/usb-ids.h" |
| 20 | |
| 21 | #include "atspi.h" |
| 22 | |
| 23 | |
| 24 | #define FROM_DEV ATSPI_FROM_DEV(0) |
| 25 | #define TO_DEV ATSPI_TO_DEV(0) |
| 26 | |
| 27 | |
| 28 | /* ----- error handling ---------------------------------------------------- */ |
| 29 | |
| 30 | |
| 31 | static int error; |
| 32 | |
| 33 | |
| 34 | int atspi_error(void) |
| 35 | { |
| 36 | return error; |
| 37 | } |
| 38 | |
| 39 | |
| 40 | int atspi_clear_error(void) |
| 41 | { |
| 42 | int ret; |
| 43 | |
| 44 | ret = error; |
| 45 | error = 0; |
| 46 | return ret; |
| 47 | } |
| 48 | |
| 49 | |
| 50 | /* ----- open/close -------------------------------------------------------- */ |
| 51 | |
| 52 | |
| 53 | usb_dev_handle *atspi_open(void) |
| 54 | { |
| 55 | usb_dev_handle *dev; |
| 56 | |
| 57 | dev = open_usb(USB_VENDOR, USB_PRODUCT); |
| 58 | if (dev) { |
| 59 | error = 0; |
| 60 | } else { |
| 61 | fprintf(stderr, ":-(\n"); |
| 62 | error = 1; |
| 63 | } |
| 64 | return dev; |
| 65 | } |
| 66 | |
| 67 | |
| 68 | void atspi_close(usb_dev_handle *dev) |
| 69 | { |
| 70 | /* to do */ |
| 71 | } |
| 72 | |
| 73 | |
| 74 | /* ----- device mode ------------------------------------------------------- */ |
| 75 | |
| 76 | |
| 77 | void atspi_reset(usb_dev_handle *dev) |
| 78 | { |
| 79 | int res; |
| 80 | |
| 81 | if (error) |
| 82 | return; |
| 83 | |
| 84 | res = |
| 85 | usb_control_msg(dev, TO_DEV, ATSPI_RESET, 0, 0, NULL, 0, 1000); |
| 86 | if (res < 0) { |
| 87 | fprintf(stderr, "ATSPI_RESET: %d\n", res); |
| 88 | error = 1; |
| 89 | } |
| 90 | } |
| 91 | |
| 92 | |
| 93 | void atspi_reset_rf(usb_dev_handle *dev) |
| 94 | { |
| 95 | int res; |
| 96 | |
| 97 | if (error) |
| 98 | return; |
| 99 | |
| 100 | res = |
| 101 | usb_control_msg(dev, TO_DEV, ATSPI_RF_RESET, 0, 0, NULL, 0, 1000); |
| 102 | if (res < 0) { |
| 103 | fprintf(stderr, "ATSPI_RF_RESET: %d\n", res); |
| 104 | error = 1; |
| 105 | } |
| 106 | } |
| 107 | |
| 108 | |
| 109 | /* ----- register access --------------------------------------------------- */ |
| 110 | |
| 111 | |
| 112 | void atspi_reg_write(usb_dev_handle *dev, uint8_t reg, uint8_t value) |
| 113 | { |
| 114 | int res; |
| 115 | |
| 116 | if (error) |
| 117 | return; |
| 118 | |
| 119 | res = usb_control_msg(dev, TO_DEV, ATSPI_REG_WRITE, value, reg, |
| 120 | NULL, 0, 1000); |
| 121 | if (res < 0) { |
| 122 | fprintf(stderr, "ATSPI_REG_WRITE: %d\n", res); |
| 123 | error = 1; |
| 124 | } |
| 125 | } |
| 126 | |
| 127 | |
| 128 | uint8_t atspi_reg_read(usb_dev_handle *dev, uint8_t reg) |
| 129 | { |
| 130 | uint8_t value = 0; |
| 131 | int res; |
| 132 | |
| 133 | if (error) |
| 134 | return 0; |
| 135 | |
| 136 | res = usb_control_msg(dev, FROM_DEV, ATSPI_REG_READ, 0, reg, |
| 137 | (void *) &value, 1, 1000); |
| 138 | if (res < 0) { |
| 139 | fprintf(stderr, "ATSPI_REG_READ: %d\n", res); |
| 140 | error = 1; |
| 141 | } |
| 142 | return value; |
| 143 | } |
| 144 | |
| 145 | |
| 146 | /* ----- frame buffer access ----------------------------------------------- */ |
| 147 | |
| 148 | |
| 149 | void atspi_buf_write(usb_dev_handle *dev, const void *buf, int size) |
| 150 | { |
| 151 | int res; |
| 152 | |
| 153 | if (error) |
| 154 | return; |
| 155 | |
| 156 | res = usb_control_msg(dev, TO_DEV, ATSPI_BUF_WRITE, 0, 0, |
| 157 | (void *) buf, size, 1000); |
| 158 | if (res < 0) { |
| 159 | fprintf(stderr, "ATSPI_BUF_WRITE: %d\n", res); |
| 160 | error = 1; |
| 161 | } |
| 162 | |
| 163 | } |
| 164 | |
| 165 | |
| 166 | int atspi_buf_read(usb_dev_handle *dev, void *buf, int size) |
| 167 | { |
| 168 | int res; |
| 169 | |
| 170 | if (error) |
| 171 | return -1; |
| 172 | |
| 173 | res = usb_control_msg(dev, FROM_DEV, ATSPI_BUF_READ, 0, 0, |
| 174 | buf, size, 1000); |
| 175 | if (res < 0) { |
| 176 | fprintf(stderr, "ATSPI_BUF_READ: %d\n", res); |
| 177 | error = 1; |
| 178 | } |
| 179 | |
| 180 | return res; |
| 181 | } |