IEEE 802.15.4 subsystem
Sign in or create your account | Project List | Help
IEEE 802.15.4 subsystem Git Source Tree
Root/
Source at commit 983d3302949f9c1fd73a5fbf7a25829bef9ba6db created 13 years 1 month ago. By Werner Almesberger, atusb/fw3: split USB driver into chip-specifc and general part | |
---|---|
1 | /* |
2 | * atspi/ep0.c - EP0 extension protocol |
3 | * |
4 | * Written 2008-2010 by Werner Almesberger |
5 | * Copyright 2008-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 <stdint.h> |
15 | |
16 | #include <avr/io.h> |
17 | |
18 | #ifndef NULL |
19 | #define NULL 0 |
20 | #endif |
21 | |
22 | //#include "regs.h" |
23 | //#include "uart.h" |
24 | //#include "usb.h" |
25 | |
26 | #include "usb.h" |
27 | |
28 | #include "at86rf230.h" |
29 | #include "atusb/ep0.h" |
30 | #include "version.h" |
31 | #include "board.h" |
32 | #include "spi.h" |
33 | |
34 | |
35 | #define HW_TYPE HW_TYPE_110131 |
36 | |
37 | #define debug(...) |
38 | #define error(...) |
39 | |
40 | |
41 | static const uint8_t id[] = { EP0ATUSB_MAJOR, EP0ATUSB_MINOR, HW_TYPE }; |
42 | static uint8_t buf[MAX_PSDU+3]; /* command, PHDR, and LQI */ |
43 | static uint8_t size; |
44 | |
45 | |
46 | static void do_buf_write(void *user) |
47 | { |
48 | uint8_t i; |
49 | |
50 | spi_begin(); |
51 | for (i = 0; i != size; i++) |
52 | spi_send(buf[i]); |
53 | spi_end(); |
54 | } |
55 | |
56 | |
57 | #define BUILD_OFFSET 7 /* '#' plus "65535" plus ' ' */ |
58 | |
59 | |
60 | static int my_setup(const struct setup_request *setup) |
61 | { |
62 | unsigned tmp; |
63 | uint8_t i; |
64 | |
65 | switch (setup->bmRequestType | setup->bRequest << 8) { |
66 | case ATUSB_FROM_DEV(ATUSB_ID): |
67 | debug("ATUSB_ID\n"); |
68 | if (setup->wLength > 3) |
69 | return 0; |
70 | usb_send(&eps[0], id, setup->wLength, NULL, NULL); |
71 | return 1; |
72 | case ATUSB_FROM_DEV(ATUSB_BUILD): |
73 | debug("ATUSB_BUILD\n"); |
74 | tmp = build_number; |
75 | for (i = BUILD_OFFSET-2; tmp; i--) { |
76 | buf[i] = (tmp % 10)+'0'; |
77 | tmp /= 10; |
78 | } |
79 | buf[i] = '#'; |
80 | buf[BUILD_OFFSET-1] = ' '; |
81 | for (size = 0; build_date[size]; size++) |
82 | buf[BUILD_OFFSET+size] = build_date[size]; |
83 | size += BUILD_OFFSET-i; |
84 | if (size > setup->wLength) |
85 | return 0; |
86 | usb_send(&eps[0], buf+i, size, NULL, NULL); |
87 | return 1; |
88 | |
89 | #ifdef NOTYET |
90 | case ATUSB_TO_DEV(ATUSB_RESET): |
91 | debug("ATUSB_RESET\n"); |
92 | RSTSRC = SWRSF; |
93 | while (1); |
94 | #endif |
95 | |
96 | case ATUSB_TO_DEV(ATUSB_RF_RESET): |
97 | debug("ATUSB_RF_RESET\n"); |
98 | reset_rf(); |
99 | //ep_send_zlp(EP_CTRL); |
100 | return 1; |
101 | |
102 | case ATUSB_FROM_DEV(ATUSB_POLL_INT): |
103 | debug("ATUSB_POLL_INT\n"); |
104 | if (setup->wLength < 1) |
105 | return 0; |
106 | *buf = read_irq(); |
107 | usb_send(&eps[0], buf, 1, NULL, NULL); |
108 | return 1; |
109 | |
110 | case ATUSB_TO_DEV(ATUSB_REG_WRITE): |
111 | debug("ATUSB_REG_WRITE\n"); |
112 | spi_begin(); |
113 | spi_send(AT86RF230_REG_WRITE | setup->wIndex); |
114 | spi_send(setup->wValue); |
115 | spi_end(); |
116 | //ep_send_zlp(EP_CTRL); |
117 | return 1; |
118 | case ATUSB_FROM_DEV(ATUSB_REG_READ): |
119 | debug("ATUSB_REG_READ\n"); |
120 | spi_begin(); |
121 | spi_send(AT86RF230_REG_READ | setup->wIndex); |
122 | *buf = spi_recv(); |
123 | spi_end(); |
124 | usb_send(&eps[0], buf, 1, NULL, NULL); |
125 | return 1; |
126 | |
127 | case ATUSB_TO_DEV(ATUSB_BUF_WRITE): |
128 | debug("ATUSB_BUF_WRITE\n"); |
129 | if (setup->wLength < 1) |
130 | return 0; |
131 | if (setup->wLength > MAX_PSDU) |
132 | return 0; |
133 | buf[0] = AT86RF230_BUF_WRITE; |
134 | buf[1] = setup->wLength; |
135 | size = setup->wLength+2; |
136 | usb_recv(&eps[0], buf+2, setup->wLength, do_buf_write, NULL); |
137 | return 1; |
138 | case ATUSB_FROM_DEV(ATUSB_BUF_READ): |
139 | debug("ATUSB_BUF_READ\n"); |
140 | if (setup->wLength < 2) /* PHR+LQI */ |
141 | return 0; |
142 | if (setup->wLength > MAX_PSDU+2) /* PHR+PSDU+LQI */ |
143 | return 0; |
144 | spi_begin(); |
145 | spi_send(AT86RF230_BUF_READ); |
146 | size = spi_recv(); |
147 | if (size >= setup->wLength) |
148 | size = setup->wLength-1; |
149 | for (i = 0; i != size+1; i++) |
150 | buf[i] = spi_recv(); |
151 | spi_end(); |
152 | usb_send(&eps[0], buf, size+1, NULL, NULL); |
153 | return 1; |
154 | |
155 | case ATUSB_TO_DEV(ATUSB_SRAM_WRITE): |
156 | debug("ATUSB_SRAM_WRITE\n"); |
157 | if (setup->wIndex > SRAM_SIZE) |
158 | return 0; |
159 | if (setup->wIndex+setup->wLength > SRAM_SIZE) |
160 | return 0; |
161 | buf[0] = AT86RF230_SRAM_WRITE; |
162 | buf[1] = setup->wIndex; |
163 | size = setup->wLength+2; |
164 | usb_recv(&eps[0], buf+2, setup->wLength, do_buf_write, NULL); |
165 | return 1; |
166 | case ATUSB_TO_DEV(ATUSB_SRAM_READ): |
167 | debug("ATUSB_SRAM_READ\n"); |
168 | if (setup->wIndex > SRAM_SIZE) |
169 | return 0; |
170 | if (setup->wIndex+setup->wLength > SRAM_SIZE) |
171 | return 0; |
172 | spi_begin(); |
173 | spi_send(AT86RF230_SRAM_READ); |
174 | spi_send(setup->wIndex); |
175 | for (i = 0; i != size; i++) |
176 | buf[i] = spi_recv(); |
177 | spi_end(); |
178 | usb_send(&eps[0], buf, size, NULL, NULL); |
179 | return 1; |
180 | |
181 | default: |
182 | error("Unrecognized SETUP: 0x%02x 0x%02x ...\n", |
183 | setup->bmRequestType, setup->bRequest); |
184 | return 0; |
185 | } |
186 | } |
187 | |
188 | |
189 | void ep0_init(void) |
190 | { |
191 | user_setup = my_setup; |
192 | } |
193 |