summaryrefslogtreecommitdiff
path: root/digital/avr
diff options
context:
space:
mode:
authorNicolas Schodet2009-04-10 01:16:16 +0200
committerNicolas Schodet2009-04-10 01:16:16 +0200
commit23cee4f9ac0e293f6e32c0215879aedb4c151718 (patch)
tree1f92a4fa696fc60b1a62f4da4963297418744374 /digital/avr
parent74298f8ca11dc8d3b0359d1d4e124d6494c3eeac (diff)
* digital/avr/modules/usb:
- added usb module.
Diffstat (limited to 'digital/avr')
-rw-r--r--digital/avr/modules/usb/Makefile.module7
-rw-r--r--digital/avr/modules/usb/README24
-rw-r--r--digital/avr/modules/usb/avrconfig.h31
-rw-r--r--digital/avr/modules/usb/lufaconfig.h35
-rw-r--r--digital/avr/modules/usb/test/Makefile11
-rw-r--r--digital/avr/modules/usb/test/avrconfig.h36
-rw-r--r--digital/avr/modules/usb/test/descriptors.c184
-rw-r--r--digital/avr/modules/usb/test/descriptors.h55
-rw-r--r--digital/avr/modules/usb/test/test_usb.c180
-rw-r--r--digital/avr/modules/usb/test/test_usb.h41
-rw-r--r--digital/avr/modules/usb/test/todfu.py8
11 files changed, 612 insertions, 0 deletions
diff --git a/digital/avr/modules/usb/Makefile.module b/digital/avr/modules/usb/Makefile.module
new file mode 100644
index 00000000..53fc6a1b
--- /dev/null
+++ b/digital/avr/modules/usb/Makefile.module
@@ -0,0 +1,7 @@
+usb_SOURCES = DevChapter9.c Endpoint.c LowLevel.c \
+ Events.c StdDescriptors.c USBInterrupt.c USBTask.c
+vpath %.c $(BASE)/modules/usb/lufa/LUFA/Drivers/USB/LowLevel
+vpath %.c $(BASE)/modules/usb/lufa/LUFA/Drivers/USB/HighLevel
+CFLAGS += -std=gnu99 -fpack-struct -fshort-enums -ffunction-sections
+CPPFLAGS += -I$(BASE)/modules/usb/lufa
+LDFLAGS += -Wl,--relax -Wl,--gc-sections
diff --git a/digital/avr/modules/usb/README b/digital/avr/modules/usb/README
new file mode 100644
index 00000000..ed8de1d0
--- /dev/null
+++ b/digital/avr/modules/usb/README
@@ -0,0 +1,24 @@
+usb - USB device module using LUFA.
+
+Use LUFA library for USB device.
+
+
+Copyright (C) 2009 Nicolas Schodet
+
+APBTeam:
+ Web: http://apbteam.org/
+ Email: team AT apbteam DOT org
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
diff --git a/digital/avr/modules/usb/avrconfig.h b/digital/avr/modules/usb/avrconfig.h
new file mode 100644
index 00000000..47f72949
--- /dev/null
+++ b/digital/avr/modules/usb/avrconfig.h
@@ -0,0 +1,31 @@
+#ifndef avrconfig_h
+#define avrconfig_h
+/* avrconfig.h */
+/* usb - USB device module using LUFA. {{{
+ *
+ * Copyright (C) 2009 Nicolas Schodet
+ *
+ * APBTeam:
+ * Web: http://apbteam.org/
+ * Email: team AT apbteam DOT org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * }}} */
+
+/* usb */
+#include "lufaconfig.h"
+
+#endif /* avrconfig_h */
diff --git a/digital/avr/modules/usb/lufaconfig.h b/digital/avr/modules/usb/lufaconfig.h
new file mode 100644
index 00000000..3a436225
--- /dev/null
+++ b/digital/avr/modules/usb/lufaconfig.h
@@ -0,0 +1,35 @@
+#ifndef lufaconfig_h
+#define lufaconfig_h
+/* lufaconfig.h */
+/* usb - USB device module using LUFA. {{{
+ *
+ * Copyright (C) 2009 Nicolas Schodet
+ *
+ * APBTeam:
+ * Web: http://apbteam.org/
+ * Email: team AT apbteam DOT org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * }}} */
+
+#define F_CPU AC_FREQ
+#define USE_NONSTANDARD_DESCRIPTOR_NAMES
+#define NO_STREAM_CALLBACKS
+#define USB_DEVICE_ONLY
+#define USE_STATIC_OPTIONS (USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED \
+ | USB_OPT_AUTO_PLL)
+
+#endif /* lufaconfig_h */
diff --git a/digital/avr/modules/usb/test/Makefile b/digital/avr/modules/usb/test/Makefile
new file mode 100644
index 00000000..46d339b6
--- /dev/null
+++ b/digital/avr/modules/usb/test/Makefile
@@ -0,0 +1,11 @@
+BASE = ../../..
+AVR_PROGS = test_usb
+test_usb_SOURCES = test_usb.c descriptors.c
+MODULES = usb
+CONFIGFILE = avrconfig.h
+AVR_MCU = at90usb162
+# -O2 : speed
+# -Os : size
+OPTIMIZE = -Os
+
+include $(BASE)/make/Makefile.gen
diff --git a/digital/avr/modules/usb/test/avrconfig.h b/digital/avr/modules/usb/test/avrconfig.h
new file mode 100644
index 00000000..0a90876d
--- /dev/null
+++ b/digital/avr/modules/usb/test/avrconfig.h
@@ -0,0 +1,36 @@
+#ifndef avrconfig_h
+#define avrconfig_h
+/* avrconfig.h */
+/* usb - USB device module using LUFA. {{{
+ *
+ * Copyright (C) 2009 Nicolas Schodet
+ *
+ * APBTeam:
+ * Web: http://apbteam.org/
+ * Email: team AT apbteam DOT org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * }}} */
+
+/* utils */
+/** AVR Frequency : 1000000, 1843200, 2000000, 3686400, 4000000, 7372800,
+ * 8000000, 11059200, 14745600, 16000000, 18432000, 20000000. */
+#define AC_FREQ 8000000
+
+/* usb */
+#include "modules/usb/lufaconfig.h"
+
+#endif /* avrconfig_h */
diff --git a/digital/avr/modules/usb/test/descriptors.c b/digital/avr/modules/usb/test/descriptors.c
new file mode 100644
index 00000000..4ccc7b49
--- /dev/null
+++ b/digital/avr/modules/usb/test/descriptors.c
@@ -0,0 +1,184 @@
+/* descriptors.c */
+/* usb - USB device module using LUFA. {{{
+ *
+ * Copyright (C) 2009 Nicolas Schodet
+ *
+ * APBTeam:
+ * Web: http://apbteam.org/
+ * Email: team AT apbteam DOT org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * }}} */
+#include "descriptors.h"
+
+USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
+{
+ Header: { Size: sizeof (USB_Descriptor_Device_t), Type: DTYPE_Device },
+ USBSpecification: VERSION_BCD (01.10),
+ Class: 0xFF,
+ SubClass: 0x00,
+ Protocol: 0x00,
+ Endpoint0Size: 8,
+ /* Taken from LUFA IDs. */
+ VendorID: 0x03EB,
+ ProductID: 0x204E,
+ ReleaseNumber: 0x0000,
+ ManufacturerStrIndex: 0x01,
+ ProductStrIndex: 0x02,
+ SerialNumStrIndex: NO_DESCRIPTOR,
+ NumberOfConfigurations: 1
+};
+
+USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
+{
+ Config:
+ {
+ Header: { Size: sizeof (USB_Descriptor_Configuration_Header_t),
+ Type: DTYPE_Configuration },
+ TotalConfigurationSize: sizeof (USB_Descriptor_Configuration_t),
+ TotalInterfaces: 2,
+ ConfigurationNumber: 1,
+ ConfigurationStrIndex: NO_DESCRIPTOR,
+ ConfigAttributes: (USB_CONFIG_ATTR_BUSPOWERED |
+ USB_CONFIG_ATTR_SELFPOWERED),
+ MaxPowerConsumption: USB_CONFIG_POWER_MA (100)
+ },
+
+ TS1_Interface:
+ {
+ Header: { Size: sizeof (USB_Descriptor_Interface_t),
+ Type: DTYPE_Interface },
+ InterfaceNumber: 0,
+ AlternateSetting: 0,
+ TotalEndpoints: 2,
+ Class: 0xFF,
+ SubClass: 0x00,
+ Protocol: 0x00,
+ InterfaceStrIndex: NO_DESCRIPTOR
+ },
+
+ TS1_DataOutEndpoint:
+ {
+ Header: { Size: sizeof (USB_Descriptor_Endpoint_t),
+ Type: DTYPE_Endpoint },
+ EndpointAddress: (ENDPOINT_DESCRIPTOR_DIR_OUT | TS1_RX_EPNUM),
+ Attributes: EP_TYPE_BULK,
+ EndpointSize: TS_TXRX_EPSIZE,
+ PollingIntervalMS: 0x00
+ },
+
+ TS1_DataInEndpoint:
+ {
+ Header: { Size: sizeof (USB_Descriptor_Endpoint_t),
+ Type: DTYPE_Endpoint },
+ EndpointAddress: (ENDPOINT_DESCRIPTOR_DIR_IN | TS1_TX_EPNUM),
+ Attributes: EP_TYPE_BULK,
+ EndpointSize: TS_TXRX_EPSIZE,
+ PollingIntervalMS: 0x00
+ },
+
+ TS2_Interface:
+ {
+ Header: { Size: sizeof (USB_Descriptor_Interface_t),
+ Type: DTYPE_Interface },
+ InterfaceNumber: 1,
+ AlternateSetting: 0,
+ TotalEndpoints: 2,
+ Class: 0xFF,
+ SubClass: 0x00,
+ Protocol: 0x00,
+ InterfaceStrIndex: NO_DESCRIPTOR
+ },
+
+ TS2_DataOutEndpoint:
+ {
+ Header: { Size: sizeof (USB_Descriptor_Endpoint_t),
+ Type: DTYPE_Endpoint },
+ EndpointAddress: (ENDPOINT_DESCRIPTOR_DIR_OUT | TS2_RX_EPNUM),
+ Attributes: EP_TYPE_BULK,
+ EndpointSize: TS_TXRX_EPSIZE,
+ PollingIntervalMS: 0x00
+ },
+
+ TS2_DataInEndpoint:
+ {
+ Header: { Size: sizeof (USB_Descriptor_Endpoint_t),
+ Type: DTYPE_Endpoint },
+ EndpointAddress: (ENDPOINT_DESCRIPTOR_DIR_IN | TS2_TX_EPNUM),
+ Attributes: EP_TYPE_BULK,
+ EndpointSize: TS_TXRX_EPSIZE,
+ PollingIntervalMS: 0x00
+ }
+};
+
+USB_Descriptor_String_t PROGMEM LanguageString =
+{
+ Header: { Size: USB_STRING_LEN (1), Type: DTYPE_String },
+ UnicodeString: {LANGUAGE_ID_ENG}
+};
+
+USB_Descriptor_String_t PROGMEM ManufacturerString =
+{
+ Header: { Size: USB_STRING_LEN (7), Type: DTYPE_String },
+ UnicodeString: L"APBTeam"
+};
+
+USB_Descriptor_String_t PROGMEM ProductString =
+{
+ Header: { Size: USB_STRING_LEN (16), Type: DTYPE_String },
+ UnicodeString: L"Dual Serial Echo"
+};
+
+uint16_t
+USB_GetDescriptor (const uint16_t wValue, const uint8_t wIndex,
+ void** const DescriptorAddress)
+{
+ const uint8_t DescriptorType = wValue >> 8;
+ const uint8_t DescriptorNumber = wValue & 0xFF;
+ void * Address = NULL;
+ uint16_t Size = NO_DESCRIPTOR;
+ switch (DescriptorType)
+ {
+ case DTYPE_Device:
+ Address = DESCRIPTOR_ADDRESS (DeviceDescriptor);
+ Size = sizeof (USB_Descriptor_Device_t);
+ break;
+ case DTYPE_Configuration:
+ Address = DESCRIPTOR_ADDRESS (ConfigurationDescriptor);
+ Size = sizeof (USB_Descriptor_Configuration_t);
+ break;
+ case DTYPE_String:
+ switch (DescriptorNumber)
+ {
+ case 0x00:
+ Address = DESCRIPTOR_ADDRESS (LanguageString);
+ Size = pgm_read_byte (&LanguageString.Header.Size);
+ break;
+ case 0x01:
+ Address = DESCRIPTOR_ADDRESS (ManufacturerString);
+ Size = pgm_read_byte (&ManufacturerString.Header.Size);
+ break;
+ case 0x02:
+ Address = DESCRIPTOR_ADDRESS (ProductString);
+ Size = pgm_read_byte (&ProductString.Header.Size);
+ break;
+ }
+ break;
+ }
+ *DescriptorAddress = Address;
+ return Size;
+}
+
diff --git a/digital/avr/modules/usb/test/descriptors.h b/digital/avr/modules/usb/test/descriptors.h
new file mode 100644
index 00000000..f7052672
--- /dev/null
+++ b/digital/avr/modules/usb/test/descriptors.h
@@ -0,0 +1,55 @@
+#ifndef descriptors_h
+#define descriptors_h
+/* descriptors.h */
+/* usb - USB device module using LUFA. {{{
+ *
+ * Copyright (C) 2009 Nicolas Schodet
+ *
+ * APBTeam:
+ * Web: http://apbteam.org/
+ * Email: team AT apbteam DOT org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * }}} */
+#include <LUFA/Drivers/USB/USB.h>
+#include <avr/pgmspace.h>
+
+/* Endpoints. */
+#define TS1_TX_EPNUM 1
+#define TS1_RX_EPNUM 2
+#define TS2_TX_EPNUM 3
+#define TS2_RX_EPNUM 4
+#define TS_TXRX_EPSIZE 16
+
+/* Configuration structure. */
+typedef struct
+{
+ USB_Descriptor_Configuration_Header_t Config;
+ USB_Descriptor_Interface_t TS1_Interface;
+ USB_Descriptor_Endpoint_t TS1_DataOutEndpoint;
+ USB_Descriptor_Endpoint_t TS1_DataInEndpoint;
+ USB_Descriptor_Interface_t TS2_Interface;
+ USB_Descriptor_Endpoint_t TS2_DataOutEndpoint;
+ USB_Descriptor_Endpoint_t TS2_DataInEndpoint;
+} USB_Descriptor_Configuration_t;
+
+/* Used by LUFA to get descriptors. */
+uint16_t
+USB_GetDescriptor (const uint16_t wValue, const uint8_t wIndex,
+ void** const DescriptorAddress)
+ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG (3);
+
+#endif /* descriptors_h */
diff --git a/digital/avr/modules/usb/test/test_usb.c b/digital/avr/modules/usb/test/test_usb.c
new file mode 100644
index 00000000..5442c0fd
--- /dev/null
+++ b/digital/avr/modules/usb/test/test_usb.c
@@ -0,0 +1,180 @@
+/* test_usb.c */
+/* usb - USB device module using LUFA. {{{
+ *
+ * Copyright (C) 2009 Nicolas Schodet
+ *
+ * APBTeam:
+ * Web: http://apbteam.org/
+ * Email: team AT apbteam DOT org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * }}} */
+#include "test_usb.h"
+
+/** Based on DualCDC example from LUFA. Refers to LUFA Demos for more
+ * comments. There is only 4 endpoints on the at90usb162, therefore a dual
+ * CDC-ACM cannot be implemented. To access this dual "serial port", use a
+ * generic usb_serial driver. */
+
+volatile uint8_t USB_USBTask_run;
+volatile uint8_t TS1Task_run;
+volatile uint8_t TS2Task_run;
+
+void
+TS1Task (void);
+
+void
+TS2Task (void);
+
+int
+main (void)
+{
+ /* Disable watchdog if enabled by bootloader/fuses. */
+ MCUSR &= ~(1 << WDRF);
+ wdt_disable ();
+ /* Disable Clock Division. */
+ SetSystemClockPrescaler (0);
+ /* Initialize USB Subsystem. */
+ USB_Init ();
+ /* Main loop. */
+ while (1)
+ {
+ if (USB_USBTask_run)
+ USB_USBTask ();
+ if (TS1Task_run)
+ TS1Task ();
+ if (TS2Task_run)
+ TS2Task ();
+ }
+}
+
+EVENT_HANDLER (USB_Connect)
+{
+ /* Start USB management task. */
+ USB_USBTask_run = 1;
+}
+
+EVENT_HANDLER (USB_Disconnect)
+{
+ USB_USBTask_run = 0;
+ TS1Task_run = 0;
+ TS2Task_run = 0;
+}
+
+EVENT_HANDLER (USB_ConfigurationChanged)
+{
+ /* Setup Rx and Tx Endpoints for the first port. */
+ Endpoint_ConfigureEndpoint (TS1_TX_EPNUM, EP_TYPE_BULK,
+ ENDPOINT_DIR_IN, TS_TXRX_EPSIZE,
+ ENDPOINT_BANK_SINGLE);
+ Endpoint_ConfigureEndpoint (TS1_RX_EPNUM, EP_TYPE_BULK,
+ ENDPOINT_DIR_OUT, TS_TXRX_EPSIZE,
+ ENDPOINT_BANK_SINGLE);
+ /* Setup Rx and Tx Endpoints for the second port. */
+ Endpoint_ConfigureEndpoint (TS2_TX_EPNUM, EP_TYPE_BULK,
+ ENDPOINT_DIR_IN, TS_TXRX_EPSIZE,
+ ENDPOINT_BANK_SINGLE);
+ Endpoint_ConfigureEndpoint (TS2_RX_EPNUM, EP_TYPE_BULK,
+ ENDPOINT_DIR_OUT, TS_TXRX_EPSIZE,
+ ENDPOINT_BANK_SINGLE);
+ /* Start tasks. */
+ TS1Task_run = 1;
+ TS2Task_run = 1;
+}
+
+EVENT_HANDLER (USB_UnhandledControlPacket)
+{
+ /* Discard the unused wValue parameter. */
+ Endpoint_Ignore_Word ();
+ /* wIndex indicates the interface being controlled. */
+ Endpoint_Ignore_Word ();
+ /* Process TS specific control requests. */
+ switch (bRequest)
+ {
+ case 0:
+ if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_VENDOR |
+ REQREC_DEVICE))
+ {
+ Endpoint_ClearSetupReceived ();
+ /* Send acknowledgement and wait for it to be sent. */
+ Endpoint_ClearSetupIN ();
+ while (!Endpoint_IsSetupINReady ())
+ ;
+ USB_ShutDown ();
+ /* Jump to bootloader. */
+ ((void (*) (void)) 0x3000) ();
+ }
+ break;
+ }
+}
+
+void
+TS1Task (void)
+{
+ /* Select the Serial Rx Endpoint. */
+ Endpoint_SelectEndpoint (TS1_RX_EPNUM);
+ /* Check to see if any data has been received. */
+ if (Endpoint_ReadWriteAllowed ())
+ {
+ /* Create a temp buffer big enough to hold the incoming endpoint
+ * packet. */
+ uint8_t Buffer[Endpoint_BytesInEndpoint ()];
+ /* Remember how large the incoming packet is. */
+ uint16_t DataLength = Endpoint_BytesInEndpoint ();
+ /* Read in the incoming packet into the buffer. */
+ Endpoint_Read_Stream_LE (&Buffer, DataLength);
+ /* Finalize the stream transfer to send the last packet. */
+ Endpoint_ClearCurrentBank ();
+ /* Select the Serial Tx Endpoint. */
+ Endpoint_SelectEndpoint (TS1_TX_EPNUM);
+ /* Write the received data to the endpoint. */
+ Endpoint_Write_Stream_LE (&Buffer, DataLength);
+ /* Finalize the stream transfer to send the last packet. */
+ Endpoint_ClearCurrentBank ();
+ }
+}
+
+void
+TS2Task (void)
+{
+ /* Select the Serial Rx Endpoint. */
+ Endpoint_SelectEndpoint (TS2_RX_EPNUM);
+ /* Check to see if any data has been received. */
+ if (Endpoint_ReadWriteAllowed ())
+ {
+ uint16_t i;
+ /* Create a temp buffer big enough to hold the incoming endpoint
+ * packet. */
+ uint8_t Buffer[Endpoint_BytesInEndpoint ()];
+ /* Remember how large the incoming packet is. */
+ uint16_t DataLength = Endpoint_BytesInEndpoint ();
+ /* Read in the incoming packet into the buffer. */
+ Endpoint_Read_Stream_LE (&Buffer, DataLength);
+ /* Finalize the stream transfer to send the last packet. */
+ Endpoint_ClearCurrentBank ();
+ /* Convert to upper case. */
+ for (i = 0; i < DataLength; i++)
+ if (Buffer[i] >= 'a' && Buffer[i] <= 'z')
+ Buffer[i] -= 'a' - 'A';
+ /* Select the Serial Tx Endpoint. */
+ Endpoint_SelectEndpoint (TS2_TX_EPNUM);
+ /* Write the received data to the endpoint. */
+ Endpoint_Write_Stream_LE (&Buffer, DataLength);
+ /* Finalize the stream transfer to send the last packet. */
+ Endpoint_ClearCurrentBank ();
+ }
+}
+
diff --git a/digital/avr/modules/usb/test/test_usb.h b/digital/avr/modules/usb/test/test_usb.h
new file mode 100644
index 00000000..36b2e27e
--- /dev/null
+++ b/digital/avr/modules/usb/test/test_usb.h
@@ -0,0 +1,41 @@
+#ifndef test_usb_h
+#define test_usb_h
+/* test_usb.h */
+/* usb - USB device module using LUFA. {{{
+ *
+ * Copyright (C) 2009 Nicolas Schodet
+ *
+ * APBTeam:
+ * Web: http://apbteam.org/
+ * Email: team AT apbteam DOT org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * }}} */
+#include <avr/io.h>
+#include <avr/wdt.h>
+#include <string.h>
+
+#include "descriptors.h"
+
+#include <LUFA/Version.h>
+#include <LUFA/Drivers/USB/USB.h>
+
+HANDLES_EVENT (USB_Connect);
+HANDLES_EVENT (USB_Disconnect);
+HANDLES_EVENT (USB_ConfigurationChanged);
+HANDLES_EVENT (USB_UnhandledControlPacket);
+
+#endif /* test_usb_h */
diff --git a/digital/avr/modules/usb/test/todfu.py b/digital/avr/modules/usb/test/todfu.py
new file mode 100644
index 00000000..60e47eac
--- /dev/null
+++ b/digital/avr/modules/usb/test/todfu.py
@@ -0,0 +1,8 @@
+# Switch back to DFU mode.
+import usb
+
+for bus in usb.busses ():
+ for dev in bus.devices:
+ if dev.idVendor == 0x03eb and dev.idProduct == 0x204e:
+ d = dev.open ()
+ d.controlMsg (usb.TYPE_VENDOR | usb.RECIP_DEVICE, 0, 0)