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
1616  $(FreakUSB)/usb/usb_buf.o \
1717  $(FreakUSB)/hw/at90usbxx2/ep.o $(FreakUSB)/hw/at90usbxx2/hw.o \
1818  $(FreakUSB)/hw/at90usbxx2/isr.o
19OBJS = atusb.o spi.o descr.o $(USB_OBJS)
19OBJS = atusb.o spi.o descr.o ep0.o $(USB_OBJS)
2020
2121CFLAGS += -I../fw/include \
2222      -I$(FreakUSB)/usb -I$(FreakUSB)/hw/at90usbxx2 \
atusb/fw2/atusb.c
1313
1414
1515void reset_rf(void);
16void ep0_init(void);
1617
1718
1819void reset_rf(void)
...... 
6869    CLR(LED);
6970
7071    usb_init();
72    ep0_init();
7173    hw_init();
7274
7375    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 */
35static const char *build_date = "today";
36static unsigned build_number = 42;
37
38extern void reset_rf(void);
39
40
41#define debug(...)
42#define error(...)
43
44
45static const uint8_t id[] = { EP0ATUSB_MAJOR, EP0ATUSB_MINOR, HW_TYPE };
46static uint8_t buf[MAX_PSDU+3]; /* command, PHDR, and LQI */
47static uint8_t size;
48
49
50static 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
61static 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
92static 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
221static void class_init(void)
222{
223}
224
225
226static void req_handler(req_t *req)
227{
228    if (!my_setup(req))
229        ep_set_stall(EP_CTRL);
230}
231
232
233static void rx_handler(void)
234{
235}
236
237
238void ep0_init(void)
239{
240        usb_reg_class_drvr(class_init, req_handler, rx_handler);
241}
atusb/fw2/spi.h
33
44#include <stdint.h>
55
6
67void spi_begin(void);
78uint8_t spi_io(uint8_t v);
89void spi_end(void);
atusb/fw2/usb/patches/series
22no-cdc.patch
33no-vbus-detect.patch
44correct-array-size.patch
5support-vendor-requests.patch
atusb/fw2/usb/patches/support-vendor-requests.patch
1Index: 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     }
24Index: 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)

Archive Download the corresponding diff file



interactive