IEEE 802.15.4 subsystem
Sign in or create your account | Project List | Help
IEEE 802.15.4 subsystem Commit Details
Date: | 2011-02-09 03:53:25 (13 years 1 month ago) |
---|---|
Author: | Werner Almesberger |
Commit: | ec21e4ba4756379934fc24635438040f66d2ab7c |
Message: | atusb/fw2: support device -> host side of the ATUSB EP0 protocol - ep0.c: the ATUSB EP0 protocol engine - Makefile (OBJS): added ep0.o - atusb.c (main): initialize the EP0 protocol - spi.h: whitespace cleanup usb/patches/support-vendor-requests.patch: - usb/ctrl.c (ctrl_handler): also pass vendor-specific requests to the class handler - class/CDC/cdc.c (cdc_req_handler): reject vendor requests |
Files: |
atusb/fw2/Makefile (1 diff) atusb/fw2/atusb.c (2 diffs) atusb/fw2/ep0.c (1 diff) atusb/fw2/spi.h (1 diff) atusb/fw2/usb/patches/series (1 diff) atusb/fw2/usb/patches/support-vendor-requests.patch (1 diff) |
Change Details
atusb/fw2/Makefile | ||
---|---|---|
16 | 16 | $(FreakUSB)/usb/usb_buf.o \ |
17 | 17 | $(FreakUSB)/hw/at90usbxx2/ep.o $(FreakUSB)/hw/at90usbxx2/hw.o \ |
18 | 18 | $(FreakUSB)/hw/at90usbxx2/isr.o |
19 | OBJS = atusb.o spi.o descr.o $(USB_OBJS) | |
19 | OBJS = atusb.o spi.o descr.o ep0.o $(USB_OBJS) | |
20 | 20 | |
21 | 21 | CFLAGS += -I../fw/include \ |
22 | 22 | -I$(FreakUSB)/usb -I$(FreakUSB)/hw/at90usbxx2 \ |
atusb/fw2/atusb.c | ||
---|---|---|
13 | 13 | |
14 | 14 | |
15 | 15 | void reset_rf(void); |
16 | void ep0_init(void); | |
16 | 17 | |
17 | 18 | |
18 | 19 | void reset_rf(void) |
... | ... | |
68 | 69 | CLR(LED); |
69 | 70 | |
70 | 71 | usb_init(); |
72 | ep0_init(); | |
71 | 73 | hw_init(); |
72 | 74 | |
73 | 75 | while (1) |
atusb/fw2/ep0.c | ||
---|---|---|
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 | //#ifndef NULL | |
18 | //#define NULL 0 | |
19 | //#endif | |
20 | ||
21 | //#include "regs.h" | |
22 | //#include "uart.h" | |
23 | //#include "usb.h" | |
24 | ||
25 | #include "freakusb.h" | |
26 | ||
27 | #include "at86rf230.h" | |
28 | #include "atusb/ep0.h" | |
29 | //#include "version.h" | |
30 | #include "io.h" | |
31 | #include "spi.h" | |
32 | ||
33 | ||
34 | #define HW_TYPE 2 /* @@@ needs more work */ | |
35 | static const char *build_date = "today"; | |
36 | static unsigned build_number = 42; | |
37 | ||
38 | extern void reset_rf(void); | |
39 | ||
40 | ||
41 | #define debug(...) | |
42 | #define error(...) | |
43 | ||
44 | ||
45 | static const uint8_t id[] = { EP0ATUSB_MAJOR, EP0ATUSB_MINOR, HW_TYPE }; | |
46 | static uint8_t buf[MAX_PSDU+3]; /* command, PHDR, and LQI */ | |
47 | static uint8_t size; | |
48 | ||
49 | ||
50 | static void do_buf_write(void *user) | |
51 | { | |
52 | uint8_t i; | |
53 | ||
54 | spi_begin(); | |
55 | for (i = 0; i != size; i++) | |
56 | spi_send(buf[i]); | |
57 | spi_end(); | |
58 | } | |
59 | ||
60 | ||
61 | static void do_usb_send(const uint8_t *data, int len) | |
62 | { | |
63 | int i; | |
64 | ||
65 | for (i = 0; i++ != len; data++) { | |
66 | usb_buf_write(EP_CTRL, *data); | |
67 | if (!(i % MAX_BUF_SZ)) | |
68 | ep_write(EP_CTRL); | |
69 | } | |
70 | ep_write(EP_CTRL); | |
71 | } | |
72 | ||
73 | ||
74 | #define usb_send(ep, buf, len, arg1, arg2) do_usb_send(buf, len) | |
75 | #define usb_recv(ep, buf, len, fn, arg) /* later */ | |
76 | ||
77 | ||
78 | #define BUILD_OFFSET 7 /* '#' plus "65535" plus ' ' */ | |
79 | ||
80 | ||
81 | /* keep things a similar to the original as possible for now */ | |
82 | #define setup_request req_t | |
83 | #define setup req | |
84 | #define bmRequestType type | |
85 | #define bRequest req | |
86 | #define wValue val | |
87 | #define wLength len | |
88 | #define wIndex idx | |
89 | #define __reentrant | |
90 | ||
91 | ||
92 | static int my_setup(struct setup_request *setup) __reentrant | |
93 | { | |
94 | unsigned tmp; | |
95 | uint8_t i; | |
96 | ||
97 | switch (setup->bmRequestType | setup->bRequest << 8) { | |
98 | case ATUSB_FROM_DEV(ATUSB_ID): | |
99 | debug("ATUSB_ID\n"); | |
100 | if (setup->wLength > 3) | |
101 | return 0; | |
102 | usb_send(&ep0, id, setup->wLength, NULL, NULL); | |
103 | return 1; | |
104 | case ATUSB_FROM_DEV(ATUSB_BUILD): | |
105 | debug("ATUSB_BUILD\n"); | |
106 | tmp = build_number; | |
107 | for (i = BUILD_OFFSET-2; tmp; i--) { | |
108 | buf[i] = (tmp % 10)+'0'; | |
109 | tmp /= 10; | |
110 | } | |
111 | buf[i] = '#'; | |
112 | buf[BUILD_OFFSET-1] = ' '; | |
113 | for (size = 0; build_date[size]; size++) | |
114 | buf[BUILD_OFFSET+size] = build_date[size]; | |
115 | size += BUILD_OFFSET-i; | |
116 | if (size > setup->wLength) | |
117 | return 0; | |
118 | usb_send(&ep0, buf+i, size, NULL, NULL); | |
119 | return 1; | |
120 | ||
121 | #ifdef NOTYET | |
122 | case ATUSB_TO_DEV(ATUSB_RESET): | |
123 | debug("ATUSB_RESET\n"); | |
124 | RSTSRC = SWRSF; | |
125 | while (1); | |
126 | #endif | |
127 | ||
128 | case ATUSB_TO_DEV(ATUSB_RF_RESET): | |
129 | debug("ATUSB_RF_RESET\n"); | |
130 | reset_rf(); | |
131 | return 1; | |
132 | ||
133 | #ifdef NOTYET | |
134 | case ATUSB_FROM_DEV(ATUSB_POLL_INT): | |
135 | debug("ATUSB_POLL_INT\n"); | |
136 | if (setup->wLength < 1) | |
137 | return 0; | |
138 | *buf = IRQ_RF; | |
139 | usb_send(&ep0, buf, 1, NULL, NULL); | |
140 | return 1; | |
141 | #endif | |
142 | ||
143 | case ATUSB_TO_DEV(ATUSB_REG_WRITE): | |
144 | debug("ATUSB_REG_WRITE\n"); | |
145 | spi_begin(); | |
146 | spi_send(AT86RF230_REG_WRITE | setup->wIndex); | |
147 | spi_send(setup->wValue); | |
148 | spi_end(); | |
149 | return 1; | |
150 | case ATUSB_FROM_DEV(ATUSB_REG_READ): | |
151 | debug("ATUSB_REG_READ\n"); | |
152 | spi_begin(); | |
153 | spi_send(AT86RF230_REG_READ | setup->wIndex); | |
154 | *buf = spi_recv(); | |
155 | spi_end(); | |
156 | usb_send(&ep0, buf, 1, NULL, NULL); | |
157 | return 1; | |
158 | ||
159 | case ATUSB_TO_DEV(ATUSB_BUF_WRITE): | |
160 | debug("ATUSB_BUF_WRITE\n"); | |
161 | if (setup->wLength < 1) | |
162 | return 0; | |
163 | if (setup->wLength > MAX_PSDU) | |
164 | return 0; | |
165 | buf[0] = AT86RF230_BUF_WRITE; | |
166 | buf[1] = setup->wLength; | |
167 | size = setup->wLength+2; | |
168 | usb_recv(&ep0, buf+2, setup->wLength, do_buf_write, NULL); | |
169 | return 1; | |
170 | case ATUSB_FROM_DEV(ATUSB_BUF_READ): | |
171 | debug("ATUSB_BUF_READ\n"); | |
172 | if (setup->wLength < 2) /* PHR+LQI */ | |
173 | return 0; | |
174 | if (setup->wLength > MAX_PSDU+2) /* PHR+PSDU+LQI */ | |
175 | return 0; | |
176 | spi_begin(); | |
177 | spi_send(AT86RF230_BUF_READ); | |
178 | size = spi_recv(); | |
179 | if (size >= setup->wLength) | |
180 | size = setup->wLength-1; | |
181 | for (i = 0; i != size+1; i++) | |
182 | buf[i] = spi_recv(); | |
183 | spi_end(); | |
184 | usb_send(&ep0, buf, size+1, NULL, NULL); | |
185 | return 1; | |
186 | ||
187 | case ATUSB_TO_DEV(ATUSB_SRAM_WRITE): | |
188 | debug("ATUSB_SRAM_WRITE\n"); | |
189 | if (setup->wIndex > SRAM_SIZE) | |
190 | return 0; | |
191 | if (setup->wIndex+setup->wLength > SRAM_SIZE) | |
192 | return 0; | |
193 | buf[0] = AT86RF230_SRAM_WRITE; | |
194 | buf[1] = setup->wIndex; | |
195 | size = setup->wLength+2; | |
196 | usb_recv(&ep0, buf+2, setup->wLength, do_buf_write, NULL); | |
197 | return 1; | |
198 | case ATUSB_TO_DEV(ATUSB_SRAM_READ): | |
199 | debug("ATUSB_SRAM_READ\n"); | |
200 | if (setup->wIndex > SRAM_SIZE) | |
201 | return 0; | |
202 | if (setup->wIndex+setup->wLength > SRAM_SIZE) | |
203 | return 0; | |
204 | spi_begin(); | |
205 | spi_send(AT86RF230_SRAM_READ); | |
206 | spi_send(setup->wIndex); | |
207 | for (i = 0; i != size; i++) | |
208 | buf[i] = spi_recv(); | |
209 | spi_end(); | |
210 | usb_send(&ep0, buf, size, NULL, NULL); | |
211 | return 1; | |
212 | ||
213 | default: | |
214 | error("Unrecognized SETUP: 0x%02x 0x%02x ...\n", | |
215 | setup->bmRequestType, setup->bRequest); | |
216 | return 0; | |
217 | } | |
218 | } | |
219 | ||
220 | ||
221 | static void class_init(void) | |
222 | { | |
223 | } | |
224 | ||
225 | ||
226 | static void req_handler(req_t *req) | |
227 | { | |
228 | if (!my_setup(req)) | |
229 | ep_set_stall(EP_CTRL); | |
230 | } | |
231 | ||
232 | ||
233 | static void rx_handler(void) | |
234 | { | |
235 | } | |
236 | ||
237 | ||
238 | void ep0_init(void) | |
239 | { | |
240 | usb_reg_class_drvr(class_init, req_handler, rx_handler); | |
241 | } |
atusb/fw2/spi.h | ||
---|---|---|
3 | 3 | |
4 | 4 | #include <stdint.h> |
5 | 5 | |
6 | ||
6 | 7 | void spi_begin(void); |
7 | 8 | uint8_t spi_io(uint8_t v); |
8 | 9 | void spi_end(void); |
atusb/fw2/usb/patches/series | ||
---|---|---|
2 | 2 | no-cdc.patch |
3 | 3 | no-vbus-detect.patch |
4 | 4 | correct-array-size.patch |
5 | support-vendor-requests.patch |
atusb/fw2/usb/patches/support-vendor-requests.patch | ||
---|---|---|
1 | Index: fw4/class/CDC/cdc.c | |
2 | =================================================================== | |
3 | --- fw4.orig/class/CDC/cdc.c 2011-02-08 17:11:11.000000000 -0300 | |
4 | @@ -76,7 +76,10 @@ | |
5 | { | |
6 | U8 i; | |
7 | usb_pcb_t *pcb = usb_pcb_get(); | |
8 | - | |
9 | + | |
10 | + if (req->type & TYPE_CLASS) | |
11 | + goto reject; | |
12 | + | |
13 | switch (req->req) | |
14 | { | |
15 | case GET_LINE_CODING: | |
16 | @@ -127,6 +130,7 @@ | |
17 | break; | |
18 | ||
19 | default: | |
20 | + reject: | |
21 | ep_set_stall(EP_CTRL); | |
22 | break; | |
23 | } | |
24 | Index: fw4/usb/ctrl.c | |
25 | =================================================================== | |
26 | --- fw4.orig/usb/ctrl.c 2011-02-08 17:09:02.000000000 -0300 | |
27 | @@ -277,7 +277,7 @@ | |
28 | reqp = (req_t *)req; | |
29 | ||
30 | // decode the standard request | |
31 | - if (!(reqp->type & TYPE_CLASS)) | |
32 | + if (!(reqp->type & (TYPE_CLASS | TYPE_VENDOR))) | |
33 | { | |
34 | // this is a standard request | |
35 | switch (reqp->req) |