summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--digital/dev2/src/usb_gpio/Makefile14
-rw-r--r--digital/dev2/src/usb_gpio/avrconfig.h79
-rw-r--r--digital/dev2/src/usb_gpio/descriptors.c166
-rw-r--r--digital/dev2/src/usb_gpio/descriptors.h34
-rw-r--r--digital/dev2/src/usb_gpio/main.c171
-rwxr-xr-xdigital/dev2/tools/dev2ctl.py (renamed from digital/dev2/src/usb_serial_isp/dev2ctl.py)19
6 files changed, 482 insertions, 1 deletions
diff --git a/digital/dev2/src/usb_gpio/Makefile b/digital/dev2/src/usb_gpio/Makefile
new file mode 100644
index 00000000..3de3f7f8
--- /dev/null
+++ b/digital/dev2/src/usb_gpio/Makefile
@@ -0,0 +1,14 @@
+BASE = ../../../avr
+AVR_PROGS = dev2_gpio
+dev2_gpio_SOURCES = main.c descriptors.c select.c
+MODULES = usb
+CONFIGFILE = avrconfig.h
+AVR_MCU = at90usb162
+# -O2 : speed
+# -Os : size
+OPTIMIZE = -Os
+
+INCLUDES = -I.. -I.
+vpath %.c ../common
+
+include $(BASE)/make/Makefile.gen
diff --git a/digital/dev2/src/usb_gpio/avrconfig.h b/digital/dev2/src/usb_gpio/avrconfig.h
new file mode 100644
index 00000000..085aed8b
--- /dev/null
+++ b/digital/dev2/src/usb_gpio/avrconfig.h
@@ -0,0 +1,79 @@
+#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
+
+/* uart - UART module. */
+/** Select hardware uart for primary uart: 0, 1 or -1 to disable. */
+#define AC_UART0_PORT 1
+/** Baudrate: 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, 76800,
+ * 115200, 230400, 250000, 500000, 1000000. */
+#define AC_UART0_BAUDRATE 38400
+/** Send mode:
+ * - POLLING: no interrupts.
+ * - RING: interrupts, ring buffer. */
+#define AC_UART0_SEND_MODE RING
+/** Recv mode, same as send mode. */
+#define AC_UART0_RECV_MODE RING
+/** Character size: 5, 6, 7, 8, 9 (only 8 implemented). */
+#define AC_UART0_CHAR_SIZE 8
+/** Parity : ODD, EVEN, NONE. */
+#define AC_UART0_PARITY EVEN
+/** Stop bits : 1, 2. */
+#define AC_UART0_STOP_BITS 1
+/** Send buffer size, should be power of 2 for RING mode. */
+#define AC_UART0_SEND_BUFFER_SIZE 16
+/** Recv buffer size, should be power of 2 for RING mode. */
+#define AC_UART0_RECV_BUFFER_SIZE 32
+/** If the send buffer is full when putc:
+ * - DROP: drop the new byte.
+ * - WAIT: wait until there is room in the send buffer. */
+#define AC_UART0_SEND_BUFFER_FULL WAIT
+/** In HOST compilation:
+ * - STDIO: use stdin/out.
+ * - PTS: use pseudo terminal. */
+#define AC_UART0_HOST_DRIVER STDIO
+/** Same thing for secondary port. */
+#define AC_UART1_PORT -1
+#define AC_UART1_BAUDRATE 115200
+#define AC_UART1_SEND_MODE RING
+#define AC_UART1_RECV_MODE RING
+#define AC_UART1_CHAR_SIZE 8
+#define AC_UART1_PARITY EVEN
+#define AC_UART1_STOP_BITS 1
+#define AC_UART1_SEND_BUFFER_SIZE 32
+#define AC_UART1_RECV_BUFFER_SIZE 32
+#define AC_UART1_SEND_BUFFER_FULL WAIT
+#define AC_UART1_HOST_DRIVER PTS
+
+/* usb */
+#include "modules/usb/lufaconfig.h"
+
+#endif /* avrconfig_h */
diff --git a/digital/dev2/src/usb_gpio/descriptors.c b/digital/dev2/src/usb_gpio/descriptors.c
new file mode 100644
index 00000000..d2046b3d
--- /dev/null
+++ b/digital/dev2/src/usb_gpio/descriptors.c
@@ -0,0 +1,166 @@
+/* descriptors.c */
+/* dev2 - Multi-purpose development board using USB and Ethernet. {{{
+ *
+ * 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 "common.h"
+
+#include "modules/usb/usb.h"
+
+#include <avr/pgmspace.h>
+
+#include "descriptors.h"
+
+/* 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_Configuration_t;
+
+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: 1,
+ 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 | GPIO_RX_EPNUM),
+ Attributes: EP_TYPE_BULK,
+ EndpointSize: GPIO_RX_EPSIZE,
+ PollingIntervalMS: 0x00
+ },
+
+ TS1_DataInEndpoint:
+ {
+ Header: { Size: sizeof (USB_Descriptor_Endpoint_t),
+ Type: DTYPE_Endpoint },
+ EndpointAddress: (ENDPOINT_DESCRIPTOR_DIR_IN | GPIO_TX_EPNUM),
+ Attributes: EP_TYPE_BULK,
+ EndpointSize: GPIO_TX_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 (9), Type: DTYPE_String },
+ UnicodeString: L"dev2 gpio"
+};
+
+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/dev2/src/usb_gpio/descriptors.h b/digital/dev2/src/usb_gpio/descriptors.h
new file mode 100644
index 00000000..610a90c0
--- /dev/null
+++ b/digital/dev2/src/usb_gpio/descriptors.h
@@ -0,0 +1,34 @@
+#ifndef descriptors_h
+#define descriptors_h
+/* descriptors.h */
+/* dev2 - Multi-purpose development board using USB and Ethernet. {{{
+ *
+ * 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.
+ *
+ * }}} */
+
+/* Endpoints. */
+#define GPIO_TX_EPNUM 1
+#define GPIO_TX_EPSIZE 16
+#define GPIO_RX_EPNUM 2
+#define GPIO_RX_EPSIZE 16
+
+#endif /* descriptors_h */
diff --git a/digital/dev2/src/usb_gpio/main.c b/digital/dev2/src/usb_gpio/main.c
new file mode 100644
index 00000000..734e5198
--- /dev/null
+++ b/digital/dev2/src/usb_gpio/main.c
@@ -0,0 +1,171 @@
+/* main.c */
+/* dev2 - Multi-purpose development board using USB and Ethernet. {{{
+ *
+ * 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 "common.h"
+
+#include "modules/usb/usb.h"
+#include "io.h"
+
+#include <avr/wdt.h>
+
+#include "descriptors.h"
+#include "common/select.h"
+
+HANDLES_EVENT (USB_Connect);
+HANDLES_EVENT (USB_Disconnect);
+HANDLES_EVENT (USB_ConfigurationChanged);
+HANDLES_EVENT (USB_UnhandledControlPacket);
+
+volatile uint8_t usb_connected, usb_configured;
+
+void
+gpio_task (void)
+{
+ Endpoint_SelectEndpoint (GPIO_RX_EPNUM);
+ /* If data is available from USB: */
+ if (Endpoint_ReadWriteAllowed ())
+ {
+ /* Read as much as possible, and clear endpoint. */
+ do {
+ Endpoint_Discard_Byte ();
+ } while (Endpoint_ReadWriteAllowed ());
+ Endpoint_ClearCurrentBank ();
+ /* Now, print current GPIO state if possible. */
+ Endpoint_SelectEndpoint (GPIO_TX_EPNUM);
+ if (Endpoint_ReadWriteAllowed ())
+ {
+ uint8_t i, pin;
+ pin = PIND;
+ for (i = 0; i < 8; i++)
+ {
+ Endpoint_Write_Byte (pin & 0x80 ? '1' : '0');
+ pin <<= 1;
+ }
+ Endpoint_Write_Byte ('\r');
+ Endpoint_ClearCurrentBank ();
+ }
+ }
+}
+
+int
+main (void)
+{
+ /* Disable watchdog if enabled by bootloader/fuses. */
+ MCUSR &= ~(1 << WDRF);
+ wdt_disable ();
+ /* Disable Clock Division. */
+ SetSystemClockPrescaler (0);
+ /* Initialise hardware. */
+ select_init ();
+ /* Initialize USB Subsystem. */
+ USB_Init ();
+ /* Main loop. */
+ while (1)
+ {
+ if (usb_connected)
+ USB_USBTask ();
+ if (usb_configured)
+ {
+ gpio_task ();
+ }
+ }
+}
+
+EVENT_HANDLER (USB_Connect)
+{
+ usb_connected = 1;
+}
+
+EVENT_HANDLER (USB_Disconnect)
+{
+ usb_connected = 0;
+ usb_configured = 0;
+}
+
+EVENT_HANDLER (USB_ConfigurationChanged)
+{
+ /* Setup Rx and Tx Endpoints for the first port. */
+ Endpoint_ConfigureEndpoint (GPIO_TX_EPNUM, EP_TYPE_BULK,
+ ENDPOINT_DIR_IN, GPIO_TX_EPSIZE,
+ ENDPOINT_BANK_SINGLE);
+ Endpoint_ConfigureEndpoint (GPIO_RX_EPNUM, EP_TYPE_BULK,
+ ENDPOINT_DIR_OUT, GPIO_RX_EPSIZE,
+ ENDPOINT_BANK_SINGLE);
+ /* Start tasks. */
+ usb_configured = 1;
+}
+
+EVENT_HANDLER (USB_UnhandledControlPacket)
+{
+ /* Process TS specific control requests. */
+ switch (bRequest)
+ {
+ /* Switch back to DFU mode. */
+ 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;
+ /* Select output. */
+ case 1:
+ if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_VENDOR |
+ REQREC_DEVICE))
+ {
+ /* Selector parameter. */
+ uint8_t output = Endpoint_Read_Byte ();
+ Endpoint_ClearSetupReceived ();
+ /* Select output. */
+ select_out (output);
+ /* Send acknowledgement. */
+ Endpoint_ClearSetupIN ();
+ }
+ break;
+ /* Set GPIO. */
+ case 0x80:
+ if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_VENDOR |
+ REQREC_DEVICE))
+ {
+ /* GPIO parameter. */
+ uint8_t ddr = Endpoint_Read_Byte ();
+ uint8_t port = Endpoint_Read_Byte ();
+ Endpoint_ClearSetupReceived ();
+ /* Set GPIO. */
+ DDRD = ddr;
+ PORTD = port;
+ /* Send acknowledgement. */
+ Endpoint_ClearSetupIN ();
+ }
+ break;
+ }
+}
+
diff --git a/digital/dev2/src/usb_serial_isp/dev2ctl.py b/digital/dev2/tools/dev2ctl.py
index 00097521..3cbe4d20 100755
--- a/digital/dev2/src/usb_serial_isp/dev2ctl.py
+++ b/digital/dev2/tools/dev2ctl.py
@@ -33,18 +33,25 @@ opt.add_option ('-s', '--select', type = 'int',
help = 'select specified OUTPUT (1 to 4)', metavar = 'OUTPUT')
opt.add_option ('-u', '--unselect', action = 'store_true', default = False,
help = 'unselect outputs')
+opt.add_option ('-g', '--gpio', type = 'int', nargs = 2,
+ help = 'set DDR and PORT', metavar = 'DDR PORT')
opt.add_option ('-d', '--dfu', action = 'store_true', default = False,
help = 'go to DFU boot loader')
(options, args) = opt.parse_args ()
if args:
opt.error ('too many arguments')
-if (options.select is not None) + options.unselect + options.dfu != 1:
+if ((options.select is not None) + options.unselect
+ + (options.gpio is not None)
+ + options.dfu != 1):
opt.error ('choose one of available options')
if options.select is not None and (options.select < 1 or options.select > 4):
opt.error ('output out of bound')
if options.unselect:
options.select = 0
+if options.gpio is not None and (options.gpio[0] < 0 or options.gpio[0] > 0xff
+ or options.gpio[1] < 0 or options.gpio[1] > 0xff):
+ opt.error ('invalid range')
# Open device.
d = None
@@ -55,6 +62,10 @@ for bus in usb.busses ():
if d is None:
print >> sys.stderr, 'device not found'
sys.exit (1)
+prod = d.getString (2, 32)
+if 'dev2' not in prod:
+ print >> sys.stderr, 'not a dev2 device'
+ sys.exit (1)
# Send control message.
if options.dfu:
@@ -62,5 +73,11 @@ if options.dfu:
elif options.select is not None:
d.controlMsg (usb.TYPE_VENDOR | usb.RECIP_DEVICE, 1, 0,
value = options.select)
+elif options.gpio is not None:
+ if 'gpio' not in prod:
+ print >> sys.stderr, 'not a gpio device'
+ sys.exit (1)
+ d.controlMsg (usb.TYPE_VENDOR | usb.RECIP_DEVICE, 0x80, 0,
+ value = options.gpio[0] | (options.gpio[1] << 8))
else:
assert 0