summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Pointner <equinox@spreadspace.org>2013-07-09 02:30:35 +0200
committerChristian Pointner <equinox@spreadspace.org>2013-07-09 02:30:35 +0200
commitb733b78fe7a74dd2f9413531f41ab22919ed2f36 (patch)
tree3301df2eecea1c61ace5d4b61ea2c61c32c3b2cf
parentadded patch against contiki-2.6 and enabled UIP_ROUTER (diff)
added avr-utils, added nodectl
-rw-r--r--.gitignore6
-rw-r--r--software/defines.mk211
-rw-r--r--software/include.mk160
-rw-r--r--software/lib/anyio.c109
-rw-r--r--software/lib/anyio.h33
-rw-r--r--software/lib/crc8.c63
-rw-r--r--software/lib/crc8.h40
-rw-r--r--software/lib/led.c146
-rw-r--r--software/lib/led.h36
-rw-r--r--software/lib/lufa-descriptor-keyboardmouse.c308
-rw-r--r--software/lib/lufa-descriptor-keyboardmouse.h81
-rw-r--r--software/lib/lufa-descriptor-rndis.c265
-rw-r--r--software/lib/lufa-descriptor-rndis.h89
-rw-r--r--software/lib/lufa-descriptor-usbdualserial.c392
-rw-r--r--software/lib/lufa-descriptor-usbdualserial.h112
-rw-r--r--software/lib/lufa-descriptor-usbserial.c278
-rw-r--r--software/lib/lufa-descriptor-usbserial.h89
-rw-r--r--software/lib/onewire.c274
-rw-r--r--software/lib/onewire.h92
-rw-r--r--software/lib/usbio.c109
-rw-r--r--software/lib/usbio.h33
-rw-r--r--software/lib/util.c114
-rw-r--r--software/lib/util.h29
-rw-r--r--software/lufa.mk41
-rw-r--r--software/nodectl/Makefile41
-rw-r--r--software/nodectl/nodectl.c256
26 files changed, 3407 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index 70ddceb..d1bf9e6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,3 +6,9 @@ contrib/contiki-2.6/
software/dustmap-node/contiki-avr-zigbit.*
software/dustmap-node/dustmap-node.avr-zigbit*
software/dustmap-node/obj_avr-zigbit/
+sortware/nodectl/*.a
+sortware/nodectl/*.o
+sortware/nodectl/*.d
+sortware/nodectl/*.d.*
+sortware/nodectl/*.hex
+sortware/nodectl/*.elf
diff --git a/software/defines.mk b/software/defines.mk
new file mode 100644
index 0000000..2d506bc
--- /dev/null
+++ b/software/defines.mk
@@ -0,0 +1,211 @@
+##
+## spreadspace avr utils
+##
+##
+## Copyright (C) 2013 Christian Pointner <equinox@spreadspace.org>
+##
+## This file is part of spreadspace avr utils.
+##
+## spreadspace avr utils 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 3 of the License, or
+## any later version.
+##
+## spreadspace avr utils 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 spreadspace avr utils. If not, see <http://www.gnu.org/licenses/>.
+##
+
+ifeq ($(BOARD_TYPE),teensy1)
+ MCU := at90usb162
+ ARCH = AVR8
+ F_CPU := 16000000
+ F_USB = $(F_CPU)
+ PROG := teensy
+ LUFA_BOARD = TEENSY
+endif
+ifeq ($(BOARD_TYPE),teensy2)
+ MCU := atmega32u4
+ ARCH = AVR8
+ F_CPU := 16000000
+ F_USB = $(F_CPU)
+ PROG := teensy
+ LUFA_BOARD = TEENSY2
+endif
+ifeq ($(BOARD_TYPE),teensy1pp)
+ MCU := at90usb646
+ ARCH = AVR8
+ F_CPU := 16000000
+ F_USB = $(F_CPU)
+ PROG := teensy
+ LUFA_BOARD = TEENSY
+endif
+ifeq ($(BOARD_TYPE),teensy2pp)
+ MCU := at90usb1286
+ ARCH = AVR8
+ F_CPU := 16000000
+ F_USB = $(F_CPU)
+ PROG := teensy
+ LUFA_BOARD = TEENSY2
+endif
+ifeq ($(BOARD_TYPE),minimus)
+ MCU := at90usb162
+ ARCH = AVR8
+ F_CPU := 16000000
+ F_USB = $(F_CPU)
+ PROG := DFU
+ LUFA_BOARD = MINIMUS
+ RESET_FUNC := ../tools/reset_minimus
+ RESET_PARAM = "03eb:2ffa"
+endif
+ifeq ($(BOARD_TYPE),minimus32)
+ MCU := atmega32u2
+ ARCH = AVR8
+ F_CPU := 16000000
+ F_USB = $(F_CPU)
+ PROG := DFU
+ LUFA_BOARD = MINIMUS
+ RESET_FUNC := ../tools/reset_minimus
+ RESET_PARAM = "03eb:2ff0"
+endif
+ifeq ($(BOARD_TYPE),hhd70dongle)
+ MCU := atmega32u4
+ ARCH = AVR8
+ F_CPU := 16000000
+ F_USB = $(F_CPU)
+ PROG := DFU
+ LUFA_BOARD = NONE
+endif
+ifeq ($(BOARD_TYPE),rda1846dongle)
+ MCU := atmega32u4
+ ARCH = AVR8
+ F_CPU := 16000000
+ F_USB = $(F_CPU)
+ PROG := DFU
+ LUFA_BOARD = NONE
+endif
+ifeq ($(BOARD_TYPE),culV3)
+ MCU := atmega32u4
+ ARCH = AVR8
+ F_CPU := 8000000
+ F_USB = $(F_CPU)
+ PROG := DFU
+ LUFA_BOARD = CULV3
+endif
+ifeq ($(BOARD_TYPE),slowpandongle1)
+ MCU := at90usb162
+ ARCH = AVR8
+ F_CPU := 16000000
+ F_USB = $(F_CPU)
+ PROG := DFU
+ LUFA_BOARD = NONE
+endif
+ifeq ($(BOARD_TYPE),slowpandongle2)
+ MCU := atmega32u4
+ ARCH = AVR8
+ F_CPU := 16000000
+ F_USB = $(F_CPU)
+ PROG := DFU
+ LUFA_BOARD = NONE
+endif
+ifeq ($(BOARD_TYPE),arduinoUno)
+ MCU := atmega328p
+ ARCH = AVR8
+ F_CPU := 16000000
+ PROG := avrdude
+ UPLOAD_RATE := 57600
+ PROG_TYPE := stk500v1
+ AVRDUDE_PORT := /dev/ttyUSB0
+ RESET_FUNC := ../tools/reset_arduino
+ RESET_PARAM = $(AVRDUDE_PORT)
+endif
+ifeq ($(BOARD_TYPE),arduino2009v2)
+ MCU := atmega328p
+ ARCH = AVR8
+ F_CPU := 16000000
+ PROG := avrdude
+ UPLOAD_RATE := 57600
+ PROG_TYPE := stk500v1
+ AVRDUDE_PORT := /dev/ttyUSB0
+ RESET_FUNC := ../tools/reset_arduino
+ RESET_PARAM = $(AVRDUDE_PORT)
+endif
+ifeq ($(BOARD_TYPE),arduino2009)
+ MCU := atmega168
+ ARCH = AVR8
+ F_CPU := 16000000
+ PROG := avrdude
+ UPLOAD_RATE := 19200
+ PROG_TYPE := stk500v1
+ AVRDUDE_PORT := /dev/ttyUSB0
+ RESET_FUNC := ../tools/reset_arduino
+ RESET_PARAM = $(AVRDUDE_PORT)
+endif
+ifeq ($(BOARD_TYPE),arduino10000)
+ MCU := atmega168
+ ARCH = AVR8
+ F_CPU := 16000000
+ PROG := avrdude
+ UPLOAD_RATE := 19200
+ PROG_TYPE := stk500v1
+ AVRDUDE_PORT := /dev/ttyUSB0
+ RESET_FUNC := ../tools/reset_arduino
+ RESET_PARAM = $(AVRDUDE_PORT)
+endif
+ifeq ($(BOARD_TYPE),arduinoNG)
+ MCU := atmega8
+ ARCH = AVR8
+ F_CPU := 16000000
+ PROG := avrdude
+ UPLOAD_RATE := 19200
+ PROG_TYPE := stk500v1
+ AVRDUDE_PORT := /dev/ttyUSB0
+ RESET_FUNC := ../tools/reset_dummy
+endif
+ifeq ($(BOARD_TYPE),AvrNetIo)
+ MCU := atmega32
+ ARCH = AVR8
+ F_CPU := 16000000
+ PROG := avrdude
+ UPLOAD_RATE := 19200
+ PROG_TYPE := stk500v2
+ AVRDUDE_PORT := /dev/ttyS0
+endif
+
+CC = avr-gcc
+OBJCOPY = avr-objcopy
+AR = avr-ar rcs
+
+LIB_DIR = ../lib
+
+DFU = dfu-programmer
+teensy = teensy_loader_cli
+avrdude = avrdude
+
+## Options common to compile, link and assembly rules
+COMMON = -mmcu=$(MCU)
+
+## Compile options common for all C compilation units.
+CFLAGS = $(COMMON)
+CFLAGS += -O2
+CFLAGS += -funsigned-char
+CFLAGS += -funsigned-bitfields
+CFLAGS += -ffunction-sections
+CFLAGS += -fpack-struct
+CFLAGS += -fshort-enums
+CFLAGS += -Wall
+CFLAGS += -Wstrict-prototypes
+CFLAGS += -I$(LIB_DIR)
+CFLAGS += -DF_CPU=$(F_CPU)UL
+CFLAGS += -D__BOARD_$(BOARD_TYPE)__
+CFLAGS += -DARCH=ARCH_$(ARCH)
+CFLAGS += -std=c99
+
+
+## Linker flags
+LDFLAGS = $(COMMON)
+LDFLAGS +=
diff --git a/software/include.mk b/software/include.mk
new file mode 100644
index 0000000..3d2bb22
--- /dev/null
+++ b/software/include.mk
@@ -0,0 +1,160 @@
+##
+## spreadspace avr utils
+##
+##
+## Copyright (C) 2013 Christian Pointner <equinox@spreadspace.org>
+##
+## This file is part of spreadspace avr utils.
+##
+## spreadspace avr utils 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 3 of the License, or
+## any later version.
+##
+## spreadspace avr utils 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 spreadspace avr utils. If not, see <http://www.gnu.org/licenses/>.
+##
+
+include ../defines.mk
+
+## project-specific objects
+SRC := $(OBJ:%.o=%.c)
+DEP := $(SRC:%.c=%.d)
+OBJ_LIB := $(LIBS:%=lib-%.o)
+SRC_LIB := $(LIBS:%=$(LIB_DIR)/%.c)
+DEP_LIB := $(LIBS:%=lib-%.d)
+
+.PHONY: prepare clean clean-external distclean clean-lufa program erase flash reset run
+
+ELFFILE := $(NAME).elf
+HEXFILE := $(NAME).hex
+
+all: prepare $(HEXFILE)
+
+
+## external Libs
+LDFLAGS += -L./
+
+ifdef LUFA_PATH
+CFLAGS += -I$(LUFA_PATH)
+CFLAGS += -DF_USB=$(F_USB)UL
+CFLAGS += -DBOARD=BOARD_$(LUFA_BOARD)
+CFLAGS += $(LUFA_OPTS)
+endif
+
+prepare: $(EXTERNAL_LIBS:%=build-%)
+clean-external: $(EXTERNAL_LIBS:%=clean-%)
+
+export
+build-lufa: liblufa.a
+
+liblufa.a:
+ @echo "building external LUFA lib ($(LUFA_PATH))"
+ make -f ../lufa.mk liblufa.a
+ make -f ../lufa.mk clean
+
+clean-lufa:
+ @echo "cleaning external LUFA lib ($(LUFA_PATH))"
+ make -f ../lufa.mk clean
+ rm -f liblufa.a
+
+
+## project-specific objects
+lib-%.d: $(LIB_DIR)/%.c
+ @set -e; rm -f $@; \
+ $(CC) -MM $(CFLAGS) $< > $@.$$$$; \
+ sed 's,\($*\)\.o[ :]*,lib-\1.o $@ : ,g' < $@.$$$$ > $@; \
+ rm -f $@.$$$$; echo '(re)building $@'
+
+%.d: %.c
+ @set -e; rm -f $@; \
+ $(CC) -MM $(CFLAGS) $< > $@.$$$$; \
+ sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
+ rm -f $@.$$$$; echo '(re)building $@'
+
+ifneq ($(MAKECMDGOALS),distclean)
+-include $(DEP)
+-include $(DEP_LIB)
+endif
+
+lib-%.o: $(LIB_DIR)/%.c
+ $(CC) $(CFLAGS) -c $< -o $@
+
+%.o: %.c
+ $(CC) $(CFLAGS) -c $< -o $@
+
+$(ELFFILE): $(OBJ) $(OBJ_LIB) $(EXTERNAL_LIBS:%=lib%.a)
+ $(CC) $(LDFLAGS) $(OBJ) $(OBJ_LIB) $(EXTERNAL_LIBS:%=-l%) -o $@
+
+$(HEXFILE): $(ELFFILE)
+ $(OBJCOPY) -O ihex -R .eeprom -R .fuse -R .lock -R .signature $< $@
+
+clean: $(CLEAN_TARGETS)
+ rm -f *.o
+ rm -f *.d
+ rm -f *.d.*
+ rm -f $(ELFFILE)
+ rm -f $(HEXFILE)
+
+distclean: clean-external clean
+
+### DFU-Programmer
+define DFU/erase
+ $(DFU) $(MCU) erase || true
+endef
+
+define DFU/flash
+ $(DFU) $(MCU) flash $1
+endef
+
+define DFU/run
+ $(DFU) $(MCU) start
+endef
+
+### teensy-loader
+define teensy/erase
+endef
+
+define teensy/flash
+ $(teensy) -mmcu=$(MCU) -w -v $1
+endef
+
+define teensy/run
+endef
+
+### avrdude
+define avrdude/erase
+endef
+
+define avrdude/flash
+ $(avrdude) -V -F -p $(MCU) -P $(AVRDUDE_PORT) -c $(PROG_TYPE) -b $(UPLOAD_RATE) -U flash:w:$1
+endef
+
+define avrdude/run
+endef
+
+### Program Targets
+program: reset erase flash run
+
+erase:
+ $(call $(PROG)/$@,)
+
+flash: $(HEXFILE)
+ $(call $(PROG)/$@,$(HEXFILE))
+
+run:
+ $(call $(PROG)/$@,)
+
+reset:
+ @if [ -n "$(RESET_FUNC)" ]; then \
+ if [ -x "$(RESET_FUNC)" ]; then \
+ eval $(RESET_FUNC) $(RESET_PARAM); \
+ else \
+ echo "WARNING: ignoring non-existing or non-executable reset script"; \
+ fi \
+ fi
diff --git a/software/lib/anyio.c b/software/lib/anyio.c
new file mode 100644
index 0000000..1ad4e96
--- /dev/null
+++ b/software/lib/anyio.c
@@ -0,0 +1,109 @@
+/*
+ * spreadspace avr utils
+ *
+ *
+ * Copyright (C) 2013 Christian Pointner <equinox@spreadspace.org>
+ * Othmar Gsenger <otti@wirdorange.org>
+ *
+ * This file is part of spreadspace avr utils.
+ *
+ * spreadspace avr utils 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 3 of the License, or
+ * any later version.
+ *
+ * spreadspace avr utils 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 spreadspace avr utils. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+
+#include "anyio.h"
+
+#include <LUFA/Drivers/USB/USB.h>
+#include "lufa-descriptor-usbserial.h"
+#include "LUFA/Drivers/Peripheral/Serial.h"
+
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2012.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+USB_ClassInfo_CDC_Device_t VirtualSerial_CDC_Interface =
+ {
+ .Config =
+ {
+ .ControlInterfaceNumber = 0,
+
+ .DataINEndpointNumber = CDC_TX_EPNUM,
+ .DataINEndpointSize = CDC_TXRX_EPSIZE,
+ .DataINEndpointDoubleBank = false,
+
+ .DataOUTEndpointNumber = CDC_RX_EPNUM,
+ .DataOUTEndpointSize = CDC_TXRX_EPSIZE,
+ .DataOUTEndpointDoubleBank = false,
+
+ .NotificationEndpointNumber = CDC_NOTIFICATION_EPNUM,
+ .NotificationEndpointSize = CDC_NOTIFICATION_EPSIZE,
+ .NotificationEndpointDoubleBank = false,
+ },
+ };
+
+void EVENT_USB_Device_ConfigurationChanged(void)
+{
+ CDC_Device_ConfigureEndpoints(&VirtualSerial_CDC_Interface);
+}
+
+void EVENT_USB_Device_ControlRequest(void)
+{
+ CDC_Device_ProcessControlRequest(&VirtualSerial_CDC_Interface);
+}
+/* end LUFA CDC-ACM specific definitions*/
+
+static FILE usb_stream;
+static FILE serial_stream;
+
+void anyio_init(const uint32_t baudrate, const uint8_t doublespeed)
+{
+ Serial_Init(baudrate, doublespeed);
+ Serial_CreateStream(&serial_stream);
+ stdin = stdout = stderr = &serial_stream;
+
+ USB_Init();
+ CDC_Device_CreateStream(&VirtualSerial_CDC_Interface,&usb_stream);
+}
+
+void anyio_task(void)
+{
+ CDC_Device_USBTask(&VirtualSerial_CDC_Interface);
+ USB_USBTask();
+}
+
+int16_t anyio_bytes_received(void)
+{
+ if(stdin == &usb_stream)
+ return CDC_Device_BytesReceived(&VirtualSerial_CDC_Interface);
+ else
+ return (int16_t)Serial_IsCharReceived();
+}
+
+void EVENT_CDC_Device_ControLineStateChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
+{
+ if(CDCInterfaceInfo->State.ControlLineStates.HostToDevice & CDC_CONTROL_LINE_OUT_DTR)
+ stdin = stdout = stderr = &usb_stream;
+ else
+ stdin = stdout = stderr = &serial_stream;
+}
+
+void EVENT_USB_Device_Disconnect(void)
+{
+ stdin = stdout = stderr = &serial_stream;
+}
diff --git a/software/lib/anyio.h b/software/lib/anyio.h
new file mode 100644
index 0000000..d774a82
--- /dev/null
+++ b/software/lib/anyio.h
@@ -0,0 +1,33 @@
+/*
+ * spreadspace avr utils
+ *
+ *
+ * Copyright (C) 2013 Christian Pointner <equinox@spreadspace.org>
+ * Othmar Gsenger <otti@wirdorange.org>
+ *
+ * This file is part of spreadspace avr utils.
+ *
+ * spreadspace avr utils 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 3 of the License, or
+ * any later version.
+ *
+ * spreadspace avr utils 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 spreadspace avr utils. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SPREADAVR_anyio_h_INCLUDED
+#define SPREADAVR_anyio_h_INCLUDED
+
+#include <stdint.h>
+
+void anyio_init(const uint32_t baudrate, const uint8_t doublespeed);
+void anyio_task(void);
+int16_t anyio_bytes_received(void);
+
+#endif
diff --git a/software/lib/crc8.c b/software/lib/crc8.c
new file mode 100644
index 0000000..ef30f71
--- /dev/null
+++ b/software/lib/crc8.c
@@ -0,0 +1,63 @@
+/* please read copyright-notice at EOF */
+
+#include <stdint.h>
+
+#define CRC8INIT 0x00
+#define CRC8POLY 0x18 //0X18 = X^8+X^5+X^4+X^0
+
+uint8_t crc8( uint8_t *data, uint16_t number_of_bytes_in_data )
+{
+ uint8_t crc;
+ uint16_t loop_count;
+ uint8_t bit_counter;
+ uint8_t b;
+ uint8_t feedback_bit;
+
+ crc = CRC8INIT;
+
+ for (loop_count = 0; loop_count != number_of_bytes_in_data; loop_count++)
+ {
+ b = data[loop_count];
+
+ bit_counter = 8;
+ do {
+ feedback_bit = (crc ^ b) & 0x01;
+
+ if ( feedback_bit == 0x01 ) {
+ crc = crc ^ CRC8POLY;
+ }
+ crc = (crc >> 1) & 0x7F;
+ if ( feedback_bit == 0x01 ) {
+ crc = crc | 0x80;
+ }
+
+ b = b >> 1;
+ bit_counter--;
+
+ } while (bit_counter > 0);
+ }
+
+ return crc;
+}
+
+/*
+This code is from Colin O'Flynn - Copyright (c) 2002
+only minor changes by M.Thomas 9/2004
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
diff --git a/software/lib/crc8.h b/software/lib/crc8.h
new file mode 100644
index 0000000..c84f8f3
--- /dev/null
+++ b/software/lib/crc8.h
@@ -0,0 +1,40 @@
+#ifndef CRC8_H_
+#define CRC8_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+uint8_t crc8( uint8_t* data, uint16_t number_of_bytes_in_data );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/*
+This is based on code from :
+
+Copyright (c) 2002 Colin O'Flynn
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
diff --git a/software/lib/led.c b/software/lib/led.c
new file mode 100644
index 0000000..bc62431
--- /dev/null
+++ b/software/lib/led.c
@@ -0,0 +1,146 @@
+/*
+ * spreadspace avr utils
+ *
+ *
+ * Copyright (C) 2013 Christian Pointner <equinox@spreadspace.org>
+ *
+ * This file is part of spreadspace avr utils.
+ *
+ * spreadspace avr utils 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 3 of the License, or
+ * any later version.
+ *
+ * spreadspace avr utils 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 spreadspace avr utils. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <avr/io.h>
+
+#include "led.h"
+
+#if defined(__BOARD_minimus__) || defined(__BOARD_minimus32__)
+#define NUM_LEDS 2
+#elif defined(__BOARD_teensy1__) || defined(__BOARD_teensy1pp__) || defined(__BOARD_teensy2__) || defined(__BOARD_teensy2pp__) \
+ || defined(__BOARD_arduinoNG__) || defined(__BOARD_arduino2009v2__) || defined(__BOARD_arduino2009__) || defined(__BOARD_arduino10000__) \
+ || defined(__BOARD_hhd70dongle__) || defined(__BOARD_rda1846dongle__) || defined(__BOARD_culV3__) \
+ || defined(__BOARD_slowpandongle1__) || defined(__BOARD_slowpandongle2__)
+#define NUM_LEDS 1
+#else
+#define NUM_LEDS 0
+#endif
+
+#if defined(__BOARD_teensy1__) || defined(__BOARD_teensy1pp__) || defined(__BOARD_minimus__) || defined(__BOARD_minimus32__)
+#define LED_DIR 0
+#else
+#define LED_DIR 1
+#endif
+
+#if defined(__BOARD_teensy1__) || defined(__BOARD_teensy1pp__) || defined(__BOARD_teensy2__) || defined(__BOARD_teensy2pp__)
+#define LED_PORT PORTD
+#define LED_DDR DDRD
+#define LED_PINNUM 6
+#endif
+
+#if defined(__BOARD_minimus__) || defined(__BOARD_minimus32__)
+#define LED_PORT PORTD
+#define LED_DDR DDRD
+#define LED_PINNUM 5
+
+#define LED2_PORT PORTD
+#define LED2_DDR DDRD
+#define LED2_PINNUM 6
+#endif
+
+#if defined(__BOARD_slowpandongle2__) || defined(__BOARD_hhd70dongle__) || defined(__BOARD_rda1846dongle__) || defined(__BOARD_culV3__)
+#define LED_PORT PORTE
+#define LED_DDR DDRE
+#define LED_PINNUM 6
+#endif
+
+#if defined(__BOARD_slowpandongle1__)
+#define LED_PORT PORTC
+#define LED_DDR DDRC
+#define LED_PINNUM 2
+#endif
+
+#if defined(__BOARD_arduino2009v2__) || defined(__BOARD_arduino2009__) || defined(__BOARD_arduino10000__) || defined(__BOARD_arduinoNG__)
+#define LED_PORT PORTB
+#define LED_DDR DDRB
+#define LED_PINNUM 5
+#endif
+
+void led_init(void)
+{
+#if NUM_LEDS >= 1
+ led_off();
+ LED_DDR = 1<<LED_PINNUM;
+#if NUM_LEDS >= 2
+ LED2_DDR |= 1<<LED2_PINNUM;
+#endif
+#endif
+}
+
+void led_on(void)
+{
+#if NUM_LEDS >= 1
+#if LED_DIR == 1
+ LED_PORT |= 1<<LED_PINNUM;
+#else
+ LED_PORT &= ~(1<<LED_PINNUM);
+#endif
+#endif
+}
+
+void led_off(void)
+{
+#if NUM_LEDS >= 1
+#if LED_DIR == 1
+ LED_PORT &= ~(1<<LED_PINNUM);
+#else
+ LED_PORT |= 1<<LED_PINNUM;
+#endif
+#endif
+}
+
+void led_toggle(void)
+{
+#if NUM_LEDS >= 1
+ LED_PORT ^= 1<<LED_PINNUM;
+#endif
+}
+
+
+void led2_on(void)
+{
+#if NUM_LEDS >= 2
+#if LED_DIR == 1
+ LED2_PORT |= 1<<LED2_PINNUM;
+#else
+ LED2_PORT &= ~(1<<LED2_PINNUM);
+#endif
+#endif
+}
+
+void led2_off(void)
+{
+#if NUM_LEDS >= 2
+#if LED_DIR == 1
+ LED2_PORT &= ~(1<<LED2_PINNUM);
+#else
+ LED2_PORT |= 1<<LED2_PINNUM;
+#endif
+#endif
+}
+
+void led2_toggle(void)
+{
+#if NUM_LEDS >= 2
+ LED2_PORT ^= 1<<LED2_PINNUM;
+#endif
+}
diff --git a/software/lib/led.h b/software/lib/led.h
new file mode 100644
index 0000000..b69015a
--- /dev/null
+++ b/software/lib/led.h
@@ -0,0 +1,36 @@
+/*
+ * spreadspace avr utils
+ *
+ *
+ * Copyright (C) 2013 Christian Pointner <equinox@spreadspace.org>
+ *
+ * This file is part of spreadspace avr utils.
+ *
+ * spreadspace avr utils 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 3 of the License, or
+ * any later version.
+ *
+ * spreadspace avr utils 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 spreadspace avr utils. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SPREADAVR_led_h_INCLUDED
+#define SPREADAVR_led_h_INCLUDED
+
+void led_init(void);
+
+void led_on(void);
+void led_off(void);
+void led_toggle(void);
+
+void led2_on(void);
+void led2_off(void);
+void led2_toggle(void);
+
+#endif
diff --git a/software/lib/lufa-descriptor-keyboardmouse.c b/software/lib/lufa-descriptor-keyboardmouse.c
new file mode 100644
index 0000000..ca19381
--- /dev/null
+++ b/software/lib/lufa-descriptor-keyboardmouse.c
@@ -0,0 +1,308 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2012.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+/** \file
+ *
+ * USB Device Descriptors, for library use when in USB device mode. Descriptors are special
+ * computer-readable structures which the host requests upon device enumeration, to determine
+ * the device's capabilities and functions.
+ */
+
+#include "lufa-descriptor-keyboardmouse.h"
+
+/** HID class report descriptor. This is a special descriptor constructed with values from the
+ * USBIF HID class specification to describe the reports and capabilities of the HID device. This
+ * descriptor is parsed by the host and its contents used to determine what data (and in what encoding)
+ * the device will send, and what it may be sent back from the host. Refer to the HID specification for
+ * more details on HID report descriptors.
+ *
+ * This descriptor describes the mouse HID interface's report structure.
+ */
+const USB_Descriptor_HIDReport_Datatype_t PROGMEM MouseReport[] =
+{
+ /* Use the HID class driver's standard Mouse report.
+ * Min X/Y Axis values: -1
+ * Max X/Y Axis values: 1
+ * Min physical X/Y Axis values (used to determine resolution): -1
+ * Max physical X/Y Axis values (used to determine resolution): 1
+ * Buttons: 3
+ * Absolute screen coordinates: false
+ */
+ HID_DESCRIPTOR_MOUSE(-1, 1, -1, 1, 3, false)
+};
+
+/** Same as the MouseReport structure, but defines the keyboard HID interface's report structure. */
+const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] =
+{
+ /* Use the HID class driver's standard Keyboard report.
+ * Max simultaneous keys: 6
+ */
+ HID_DESCRIPTOR_KEYBOARD(6)
+};
+
+/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
+ * device characteristics, including the supported USB version, control endpoint size and the
+ * number of device configurations. The descriptor is read out by the USB host when the enumeration
+ * process begins.
+ */
+const USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
+{
+ .Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
+
+ .USBSpecification = VERSION_BCD(01.10),
+ .Class = USB_CSCP_NoDeviceClass,
+ .SubClass = USB_CSCP_NoDeviceSubclass,
+ .Protocol = USB_CSCP_NoDeviceProtocol,
+
+ .Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
+
+ .VendorID = 0x03EB,
+ .ProductID = 0x204D,
+ .ReleaseNumber = VERSION_BCD(00.01),
+
+ .ManufacturerStrIndex = 0x01,
+ .ProductStrIndex = 0x02,
+ .SerialNumStrIndex = NO_DESCRIPTOR,
+
+ .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
+};
+
+/** Configuration descriptor structure. This descriptor, located in FLASH memory, describes the usage
+ * of the device in one of its supported configurations, including information about any device interfaces
+ * and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting
+ * a configuration so that the host may correctly communicate with the USB device.
+ */
+const 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_RESERVED | USB_CONFIG_ATTR_SELFPOWERED),
+
+ .MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
+ },
+
+ .HID1_KeyboardInterface =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
+
+ .InterfaceNumber = 0x00,
+ .AlternateSetting = 0x00,
+
+ .TotalEndpoints = 1,
+
+ .Class = HID_CSCP_HIDClass,
+ .SubClass = HID_CSCP_BootSubclass,
+ .Protocol = HID_CSCP_KeyboardBootProtocol,
+
+ .InterfaceStrIndex = NO_DESCRIPTOR
+ },
+
+ .HID1_KeyboardHID =
+ {
+ .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
+
+ .HIDSpec = VERSION_BCD(01.11),
+ .CountryCode = 0x00,
+ .TotalReportDescriptors = 1,
+ .HIDReportType = HID_DTYPE_Report,
+ .HIDReportLength = sizeof(KeyboardReport)
+ },
+
+ .HID1_ReportINEndpoint =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+ .EndpointAddress = (ENDPOINT_DIR_IN | KEYBOARD_IN_EPNUM),
+ .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+ .EndpointSize = HID_EPSIZE,
+ .PollingIntervalMS = 0x01
+ },
+
+ .HID2_MouseInterface =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
+
+ .InterfaceNumber = 0x01,
+ .AlternateSetting = 0x00,
+
+ .TotalEndpoints = 1,
+
+ .Class = HID_CSCP_HIDClass,
+ .SubClass = HID_CSCP_BootSubclass,
+ .Protocol = HID_CSCP_MouseBootProtocol,
+
+ .InterfaceStrIndex = NO_DESCRIPTOR
+ },
+
+ .HID2_MouseHID =
+ {
+ .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
+
+ .HIDSpec = VERSION_BCD(01.11),
+ .CountryCode = 0x00,
+ .TotalReportDescriptors = 1,
+ .HIDReportType = HID_DTYPE_Report,
+ .HIDReportLength = sizeof(MouseReport)
+ },
+
+ .HID2_ReportINEndpoint =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+ .EndpointAddress = (ENDPOINT_DIR_IN | MOUSE_IN_EPNUM),
+ .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+ .EndpointSize = HID_EPSIZE,
+ .PollingIntervalMS = 0x01
+ }
+};
+
+/** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests
+ * the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate
+ * via the language ID table available at USB.org what languages the device supports for its string descriptors.
+ */
+const USB_Descriptor_String_t PROGMEM LanguageString =
+{
+ .Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
+
+ .UnicodeString = {LANGUAGE_ID_ENG}
+};
+
+/** Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable
+ * form, and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
+ * Descriptor.
+ */
+const USB_Descriptor_String_t PROGMEM ManufacturerString =
+{
+ .Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String},
+#ifndef USB_MANUFACTURER
+ .UnicodeString = L"Dean Camera"
+#else
+ .UnicodeString = USB_MANUFACTURER
+#endif
+};
+
+/** Product descriptor string. This is a Unicode string containing the product's details in human readable form,
+ * and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
+ * Descriptor.
+ */
+const USB_Descriptor_String_t PROGMEM ProductString =
+{
+ .Header = {.Size = USB_STRING_LEN(28), .Type = DTYPE_String},
+#ifndef USB_PRODUCT
+ .UnicodeString = L"LUFA Mouse and Keyboard Demo"
+#else
+ .UnicodeString = USB_PRODUCT
+#endif
+};
+
+/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"
+ * documentation) by the application code so that the address and size of a requested descriptor can be given
+ * to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
+ * is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
+ * USB host.
+ */
+uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
+ const uint8_t wIndex,
+ const void** const DescriptorAddress)
+{
+ const uint8_t DescriptorType = (wValue >> 8);
+ const uint8_t DescriptorNumber = (wValue & 0xFF);
+
+ const void* Address = NULL;
+ uint16_t Size = NO_DESCRIPTOR;
+
+ switch (DescriptorType)
+ {
+ case DTYPE_Device:
+ Address = &DeviceDescriptor;
+ Size = sizeof(USB_Descriptor_Device_t);
+ break;
+ case DTYPE_Configuration:
+ Address = &ConfigurationDescriptor;
+ Size = sizeof(USB_Descriptor_Configuration_t);
+ break;
+ case DTYPE_String:
+ switch (DescriptorNumber)
+ {
+ case 0x00:
+ Address = &LanguageString;
+ Size = pgm_read_byte(&LanguageString.Header.Size);
+ break;
+ case 0x01:
+ Address = &ManufacturerString;
+ Size = pgm_read_byte(&ManufacturerString.Header.Size);
+ break;
+ case 0x02:
+ Address = &ProductString;
+ Size = pgm_read_byte(&ProductString.Header.Size);
+ break;
+ }
+
+ break;
+ case HID_DTYPE_HID:
+ if (!(wIndex))
+ {
+ Address = &ConfigurationDescriptor.HID1_KeyboardHID;
+ Size = sizeof(USB_HID_Descriptor_HID_t);
+ }
+ else
+ {
+ Address = &ConfigurationDescriptor.HID2_MouseHID;
+ Size = sizeof(USB_HID_Descriptor_HID_t);
+ }
+
+ break;
+ case HID_DTYPE_Report:
+ if (!(wIndex))
+ {
+ Address = &KeyboardReport;
+ Size = sizeof(KeyboardReport);
+ }
+ else
+ {
+ Address = &MouseReport;
+ Size = sizeof(MouseReport);
+ }
+
+ break;
+ }
+
+ *DescriptorAddress = Address;
+ return Size;
+}
+
diff --git a/software/lib/lufa-descriptor-keyboardmouse.h b/software/lib/lufa-descriptor-keyboardmouse.h
new file mode 100644
index 0000000..9381602
--- /dev/null
+++ b/software/lib/lufa-descriptor-keyboardmouse.h
@@ -0,0 +1,81 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2012.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+/** \file
+ *
+ * Header file for Descriptors.c.
+ */
+
+#ifndef _DESCRIPTORS_H_
+#define _DESCRIPTORS_H_
+
+ /* Includes: */
+ #include <avr/pgmspace.h>
+
+ #include <LUFA/Drivers/USB/USB.h>
+
+ /* Type Defines: */
+ /** Type define for the device configuration descriptor structure. This must be defined in the
+ * application code, as the configuration descriptor contains several sub-descriptors which
+ * vary between devices, and which describe the device's usage to the host.
+ */
+ typedef struct
+ {
+ USB_Descriptor_Configuration_Header_t Config;
+
+ // Keyboard HID Interface
+ USB_Descriptor_Interface_t HID1_KeyboardInterface;
+ USB_HID_Descriptor_HID_t HID1_KeyboardHID;
+ USB_Descriptor_Endpoint_t HID1_ReportINEndpoint;
+
+ // Mouse HID Interface
+ USB_Descriptor_Interface_t HID2_MouseInterface;
+ USB_HID_Descriptor_HID_t HID2_MouseHID;
+ USB_Descriptor_Endpoint_t HID2_ReportINEndpoint;
+ } USB_Descriptor_Configuration_t;
+
+ /* Macros: */
+ /** Endpoint number of the Keyboard HID reporting IN endpoint. */
+ #define KEYBOARD_IN_EPNUM 1
+
+ /** Endpoint number of the Mouse HID reporting IN endpoint. */
+ #define MOUSE_IN_EPNUM 3
+
+ /** Size in bytes of each of the HID reporting IN endpoints. */
+ #define HID_EPSIZE 8
+
+ /* Function Prototypes: */
+ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
+ const uint8_t wIndex,
+ const void** const DescriptorAddress)
+ ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
+
+#endif
+
diff --git a/software/lib/lufa-descriptor-rndis.c b/software/lib/lufa-descriptor-rndis.c
new file mode 100644
index 0000000..28ea637
--- /dev/null
+++ b/software/lib/lufa-descriptor-rndis.c
@@ -0,0 +1,265 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2012.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+/** \file
+ *
+ * USB Device Descriptors, for library use when in USB device mode. Descriptors are special
+ * computer-readable structures which the host requests upon device enumeration, to determine
+ * the device's capabilities and functions.
+ */
+
+#include "lufa-descriptor-rndis.h"
+
+/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
+ * device characteristics, including the supported USB version, control endpoint size and the
+ * number of device configurations. The descriptor is read out by the USB host when the enumeration
+ * process begins.
+ */
+const USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
+{
+ .Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
+
+ .USBSpecification = VERSION_BCD(01.10),
+ .Class = CDC_CSCP_CDCClass,
+ .SubClass = CDC_CSCP_NoSpecificSubclass,
+ .Protocol = CDC_CSCP_NoSpecificProtocol,
+
+ .Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
+
+ .VendorID = 0x03EB,
+ .ProductID = 0x204C,
+ .ReleaseNumber = VERSION_BCD(00.01),
+
+ .ManufacturerStrIndex = 0x01,
+ .ProductStrIndex = 0x02,
+ .SerialNumStrIndex = NO_DESCRIPTOR,
+
+ .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
+};
+
+/** Configuration descriptor structure. This descriptor, located in FLASH memory, describes the usage
+ * of the device in one of its supported configurations, including information about any device interfaces
+ * and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting
+ * a configuration so that the host may correctly communicate with the USB device.
+ */
+const 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_RESERVED | USB_CONFIG_ATTR_SELFPOWERED),
+
+ .MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
+ },
+
+ .CDC_CCI_Interface =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
+
+ .InterfaceNumber = 0,
+ .AlternateSetting = 0,
+
+ .TotalEndpoints = 1,
+
+ .Class = CDC_CSCP_CDCClass,
+ .SubClass = CDC_CSCP_ACMSubclass,
+ .Protocol = CDC_CSCP_VendorSpecificProtocol,
+
+ .InterfaceStrIndex = NO_DESCRIPTOR
+ },
+
+ .CDC_Functional_Header =
+ {
+ .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalHeader_t), .Type = DTYPE_CSInterface},
+ .Subtype = CDC_DSUBTYPE_CSInterface_Header,
+
+ .CDCSpecification = VERSION_BCD(01.10),
+ },
+
+ .CDC_Functional_ACM =
+ {
+ .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalACM_t), .Type = DTYPE_CSInterface},
+ .Subtype = CDC_DSUBTYPE_CSInterface_ACM,
+
+ .Capabilities = 0x00,
+ },
+
+ .CDC_Functional_Union =
+ {
+ .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalUnion_t), .Type = DTYPE_CSInterface},
+ .Subtype = CDC_DSUBTYPE_CSInterface_Union,
+
+ .MasterInterfaceNumber = 0,
+ .SlaveInterfaceNumber = 1,
+ },
+
+ .CDC_NotificationEndpoint =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+ .EndpointAddress = (ENDPOINT_DIR_IN | CDC_NOTIFICATION_EPNUM),
+ .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+ .EndpointSize = CDC_NOTIFICATION_EPSIZE,
+ .PollingIntervalMS = 0xFF
+ },
+
+ .CDC_DCI_Interface =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
+
+ .InterfaceNumber = 1,
+ .AlternateSetting = 0,
+
+ .TotalEndpoints = 2,
+
+ .Class = CDC_CSCP_CDCDataClass,
+ .SubClass = CDC_CSCP_NoDataSubclass,
+ .Protocol = CDC_CSCP_NoDataProtocol,
+
+ .InterfaceStrIndex = NO_DESCRIPTOR
+ },
+
+ .RNDIS_DataOutEndpoint =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+ .EndpointAddress = (ENDPOINT_DIR_OUT | CDC_RX_EPNUM),
+ .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+ .EndpointSize = CDC_TXRX_EPSIZE,
+ .PollingIntervalMS = 0x01
+ },
+
+ .RNDIS_DataInEndpoint =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+ .EndpointAddress = (ENDPOINT_DIR_IN | CDC_TX_EPNUM),
+ .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+ .EndpointSize = CDC_TXRX_EPSIZE,
+ .PollingIntervalMS = 0x01
+ }
+};
+
+/** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests
+ * the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate
+ * via the language ID table available at USB.org what languages the device supports for its string descriptors.
+ */
+const USB_Descriptor_String_t PROGMEM LanguageString =
+{
+ .Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
+
+ .UnicodeString = {LANGUAGE_ID_ENG}
+};
+
+/** Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable
+ * form, and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
+ * Descriptor.
+ */
+const USB_Descriptor_String_t PROGMEM ManufacturerString =
+{
+ .Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String},
+#ifndef USB_MANUFACTURER
+ .UnicodeString = L"Dean Camera"
+#else
+ .UnicodeString = USB_MANUFACTURER
+#endif
+};
+
+/** Product descriptor string. This is a Unicode string containing the product's details in human readable form,
+ * and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
+ * Descriptor.
+ */
+const USB_Descriptor_String_t PROGMEM ProductString =
+{
+ .Header = {.Size = USB_STRING_LEN(23), .Type = DTYPE_String},
+#ifndef USB_PRODUCT
+ .UnicodeString = L"LUFA USB-RS232 Adapter"
+#else
+ .UnicodeString = USB_PRODUCT
+#endif
+};
+
+/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"
+ * documentation) by the application code so that the address and size of a requested descriptor can be given
+ * to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
+ * is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
+ * USB host.
+ */
+uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
+ const uint8_t wIndex,
+ const void** const DescriptorAddress)
+{
+ const uint8_t DescriptorType = (wValue >> 8);
+ const uint8_t DescriptorNumber = (wValue & 0xFF);
+
+ const void* Address = NULL;
+ uint16_t Size = NO_DESCRIPTOR;
+
+ switch (DescriptorType)
+ {
+ case DTYPE_Device:
+ Address = &DeviceDescriptor;
+ Size = sizeof(USB_Descriptor_Device_t);
+ break;
+ case DTYPE_Configuration:
+ Address = &ConfigurationDescriptor;
+ Size = sizeof(USB_Descriptor_Configuration_t);
+ break;
+ case DTYPE_String:
+ switch (DescriptorNumber)
+ {
+ case 0x00:
+ Address = &LanguageString;
+ Size = pgm_read_byte(&LanguageString.Header.Size);
+ break;
+ case 0x01:
+ Address = &ManufacturerString;
+ Size = pgm_read_byte(&ManufacturerString.Header.Size);
+ break;
+ case 0x02:
+ Address = &ProductString;
+ Size = pgm_read_byte(&ProductString.Header.Size);
+ break;
+ }
+
+ break;
+ }
+
+ *DescriptorAddress = Address;
+ return Size;
+}
+
diff --git a/software/lib/lufa-descriptor-rndis.h b/software/lib/lufa-descriptor-rndis.h
new file mode 100644
index 0000000..508ac2f
--- /dev/null
+++ b/software/lib/lufa-descriptor-rndis.h
@@ -0,0 +1,89 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2012.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+/** \file
+ *
+ * Header file for Descriptors.c.
+ */
+
+#ifndef _DESCRIPTORS_H_
+#define _DESCRIPTORS_H_
+
+ /* Includes: */
+ #include <LUFA/Drivers/USB/USB.h>
+
+ #include <avr/pgmspace.h>
+
+ /* Macros: */
+ /** Endpoint number of the CDC device-to-host notification IN endpoint. */
+ #define CDC_NOTIFICATION_EPNUM 3
+
+ /** Endpoint number of the CDC device-to-host data IN endpoint. */
+ #define CDC_TX_EPNUM 1
+
+ /** Endpoint number of the CDC host-to-device data OUT endpoint. */
+ #define CDC_RX_EPNUM 2
+
+ /** Size in bytes of the CDC device-to-host notification IN endpoint. */
+ #define CDC_NOTIFICATION_EPSIZE 8
+
+ /** Size in bytes of the CDC data IN and OUT endpoints. */
+ #define CDC_TXRX_EPSIZE 64
+
+ /* Type Defines: */
+ /** Type define for the device configuration descriptor structure. This must be defined in the
+ * application code, as the configuration descriptor contains several sub-descriptors which
+ * vary between devices, and which describe the device's usage to the host.
+ */
+ typedef struct
+ {
+ USB_Descriptor_Configuration_Header_t Config;
+
+ // RNDIS CDC Control Interface
+ USB_Descriptor_Interface_t CDC_CCI_Interface;
+ USB_CDC_Descriptor_FunctionalHeader_t CDC_Functional_Header;
+ USB_CDC_Descriptor_FunctionalACM_t CDC_Functional_ACM;
+ USB_CDC_Descriptor_FunctionalUnion_t CDC_Functional_Union;
+ USB_Descriptor_Endpoint_t CDC_NotificationEndpoint;
+
+ // RNDIS CDC Data Interface
+ USB_Descriptor_Interface_t CDC_DCI_Interface;
+ USB_Descriptor_Endpoint_t RNDIS_DataOutEndpoint;
+ USB_Descriptor_Endpoint_t RNDIS_DataInEndpoint;
+ } USB_Descriptor_Configuration_t;
+
+ /* Function Prototypes: */
+ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
+ const uint8_t wIndex,
+ const void** const DescriptorAddress)
+ ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
+
+#endif
+
diff --git a/software/lib/lufa-descriptor-usbdualserial.c b/software/lib/lufa-descriptor-usbdualserial.c
new file mode 100644
index 0000000..0d506c7
--- /dev/null
+++ b/software/lib/lufa-descriptor-usbdualserial.c
@@ -0,0 +1,392 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2012.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+/** \file
+ *
+ * USB Device Descriptors, for library use when in USB device mode. Descriptors are special
+ * computer-readable structures which the host requests upon device enumeration, to determine
+ * the device's capabilities and functions.
+ */
+
+#include "lufa-descriptor-usbdualserial.h"
+
+/* On some devices, there is a factory set internal serial number which can be automatically sent to the host as
+ * the device's serial number when the Device Descriptor's .SerialNumStrIndex entry is set to USE_INTERNAL_SERIAL.
+ * This allows the host to track a device across insertions on different ports, allowing them to retain allocated
+ * resources like COM port numbers and drivers. On demos using this feature, give a warning on unsupported devices
+ * so that the user can supply their own serial number descriptor instead or remove the USE_INTERNAL_SERIAL value
+ * from the Device Descriptor (forcing the host to generate a serial number for each device from the VID, PID and
+ * port location).
+ */
+#if (USE_INTERNAL_SERIAL == NO_DESCRIPTOR)
+ #warning USE_INTERNAL_SERIAL is not available on this AVR - please manually construct a device serial descriptor.
+#endif
+
+/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
+ * device characteristics, including the supported USB version, control endpoint size and the
+ * number of device configurations. The descriptor is read out by the USB host when the enumeration
+ * process begins.
+ */
+const USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
+{
+ .Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
+
+ .USBSpecification = VERSION_BCD(01.10),
+ .Class = USB_CSCP_IADDeviceClass,
+ .SubClass = USB_CSCP_IADDeviceSubclass,
+ .Protocol = USB_CSCP_IADDeviceProtocol,
+
+ .Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
+
+ .VendorID = 0x03EB,
+ .ProductID = 0x204E,
+ .ReleaseNumber = VERSION_BCD(00.01),
+
+ .ManufacturerStrIndex = 0x01,
+ .ProductStrIndex = 0x02,
+ .SerialNumStrIndex = USE_INTERNAL_SERIAL,
+
+ .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
+};
+
+/** Configuration descriptor structure. This descriptor, located in FLASH memory, describes the usage
+ * of the device in one of its supported configurations, including information about any device interfaces
+ * and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting
+ * a configuration so that the host may correctly communicate with the USB device.
+ */
+const 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 = 4,
+
+ .ConfigurationNumber = 1,
+ .ConfigurationStrIndex = NO_DESCRIPTOR,
+
+ .ConfigAttributes = (USB_CONFIG_ATTR_RESERVED | USB_CONFIG_ATTR_SELFPOWERED),
+
+ .MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
+ },
+
+ .CDC1_IAD =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Interface_Association_t), .Type = DTYPE_InterfaceAssociation},
+
+ .FirstInterfaceIndex = 0,
+ .TotalInterfaces = 2,
+
+ .Class = CDC_CSCP_CDCClass,
+ .SubClass = CDC_CSCP_ACMSubclass,
+ .Protocol = CDC_CSCP_ATCommandProtocol,
+
+ .IADStrIndex = NO_DESCRIPTOR
+ },
+
+ .CDC1_CCI_Interface =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
+
+ .InterfaceNumber = 0,
+ .AlternateSetting = 0,
+
+ .TotalEndpoints = 1,
+
+ .Class = CDC_CSCP_CDCClass,
+ .SubClass = CDC_CSCP_ACMSubclass,
+ .Protocol = CDC_CSCP_ATCommandProtocol,
+
+ .InterfaceStrIndex = NO_DESCRIPTOR
+ },
+
+ .CDC1_Functional_Header =
+ {
+ .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalHeader_t), .Type = DTYPE_CSInterface},
+ .Subtype = CDC_DSUBTYPE_CSInterface_Header,
+
+ .CDCSpecification = VERSION_BCD(01.10),
+ },
+
+ .CDC1_Functional_ACM =
+ {
+ .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalACM_t), .Type = DTYPE_CSInterface},
+ .Subtype = CDC_DSUBTYPE_CSInterface_ACM,
+
+ .Capabilities = 0x06,
+ },
+
+ .CDC1_Functional_Union =
+ {
+ .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalUnion_t), .Type = DTYPE_CSInterface},
+ .Subtype = CDC_DSUBTYPE_CSInterface_Union,
+
+ .MasterInterfaceNumber = 0,
+ .SlaveInterfaceNumber = 1,
+ },
+
+ .CDC1_ManagementEndpoint =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+ .EndpointAddress = (ENDPOINT_DIR_IN | CDC1_NOTIFICATION_EPNUM),
+ .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+ .EndpointSize = CDC_NOTIFICATION_EPSIZE,
+ .PollingIntervalMS = 0xFF
+ },
+
+ .CDC1_DCI_Interface =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
+
+ .InterfaceNumber = 1,
+ .AlternateSetting = 0,
+
+ .TotalEndpoints = 2,
+
+ .Class = CDC_CSCP_CDCDataClass,
+ .SubClass = CDC_CSCP_NoDataSubclass,
+ .Protocol = CDC_CSCP_NoDataProtocol,
+
+ .InterfaceStrIndex = NO_DESCRIPTOR
+ },
+
+ .CDC1_DataOutEndpoint =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+ .EndpointAddress = (ENDPOINT_DIR_OUT | CDC1_RX_EPNUM),
+ .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+ .EndpointSize = CDC_TXRX_EPSIZE,
+ .PollingIntervalMS = 0x01
+ },
+
+ .CDC1_DataInEndpoint =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+ .EndpointAddress = (ENDPOINT_DIR_IN | CDC1_TX_EPNUM),
+ .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+ .EndpointSize = CDC_TXRX_EPSIZE,
+ .PollingIntervalMS = 0x01
+ },
+
+ .CDC2_IAD =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Interface_Association_t), .Type = DTYPE_InterfaceAssociation},
+
+ .FirstInterfaceIndex = 2,
+ .TotalInterfaces = 2,
+
+ .Class = CDC_CSCP_CDCClass,
+ .SubClass = CDC_CSCP_ACMSubclass,
+ .Protocol = CDC_CSCP_ATCommandProtocol,
+
+ .IADStrIndex = NO_DESCRIPTOR
+ },
+
+ .CDC2_CCI_Interface =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
+
+ .InterfaceNumber = 2,
+ .AlternateSetting = 0,
+
+ .TotalEndpoints = 1,
+
+ .Class = CDC_CSCP_CDCClass,
+ .SubClass = CDC_CSCP_ACMSubclass,
+ .Protocol = CDC_CSCP_ATCommandProtocol,
+
+ .InterfaceStrIndex = NO_DESCRIPTOR
+ },
+
+ .CDC2_Functional_Header =
+ {
+ .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalHeader_t), .Type = DTYPE_CSInterface},
+ .Subtype = CDC_DSUBTYPE_CSInterface_Header,
+
+ .CDCSpecification = VERSION_BCD(01.10),
+ },
+
+ .CDC2_Functional_ACM =
+ {
+ .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalACM_t), .Type = DTYPE_CSInterface},
+ .Subtype = CDC_DSUBTYPE_CSInterface_ACM,
+
+ .Capabilities = 0x06,
+ },
+
+ .CDC2_Functional_Union =
+ {
+ .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalUnion_t), .Type = DTYPE_CSInterface},
+ .Subtype = CDC_DSUBTYPE_CSInterface_Union,
+
+ .MasterInterfaceNumber = 2,
+ .SlaveInterfaceNumber = 3,
+ },
+
+ .CDC2_ManagementEndpoint =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+ .EndpointAddress = (ENDPOINT_DIR_IN | CDC2_NOTIFICATION_EPNUM),
+ .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+ .EndpointSize = CDC_NOTIFICATION_EPSIZE,
+ .PollingIntervalMS = 0xFF
+ },
+
+ .CDC2_DCI_Interface =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
+
+ .InterfaceNumber = 3,
+ .AlternateSetting = 0,
+
+ .TotalEndpoints = 2,
+
+ .Class = CDC_CSCP_CDCDataClass,
+ .SubClass = CDC_CSCP_NoDataSubclass,
+ .Protocol = CDC_CSCP_NoDataProtocol,
+
+ .InterfaceStrIndex = NO_DESCRIPTOR
+ },
+
+ .CDC2_DataOutEndpoint =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+ .EndpointAddress = (ENDPOINT_DIR_OUT | CDC2_RX_EPNUM),
+ .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+ .EndpointSize = CDC_TXRX_EPSIZE,
+ .PollingIntervalMS = 0x01
+ },
+
+ .CDC2_DataInEndpoint =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+ .EndpointAddress = (ENDPOINT_DIR_IN | CDC2_TX_EPNUM),
+ .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+ .EndpointSize = CDC_TXRX_EPSIZE,
+ .PollingIntervalMS = 0x01
+ }
+};
+
+/** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests
+ * the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate
+ * via the language ID table available at USB.org what languages the device supports for its string descriptors.
+ */
+const USB_Descriptor_String_t PROGMEM LanguageString =
+{
+ .Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
+
+ .UnicodeString = {LANGUAGE_ID_ENG}
+};
+
+/** Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable
+ * form, and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
+ * Descriptor.
+ */
+const USB_Descriptor_String_t PROGMEM ManufacturerString =
+{
+ .Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String},
+#ifndef USB_MANUFACTURER
+ .UnicodeString = L"Dean Camera"
+#else
+ .UnicodeString = USB_MANUFACTURER
+#endif
+};
+
+/** Product descriptor string. This is a Unicode string containing the product's details in human readable form,
+ * and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
+ * Descriptor.
+ */
+const USB_Descriptor_String_t PROGMEM ProductString =
+{
+ .Header = {.Size = USB_STRING_LEN(13), .Type = DTYPE_String},
+#ifndef USB_PRODUCT
+ .UnicodeString = L"LUFA Dual CDC Demo"
+#else
+ .UnicodeString = USB_PRODUCT
+#endif
+};
+
+/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"
+ * documentation) by the application code so that the address and size of a requested descriptor can be given
+ * to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
+ * is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
+ * USB host.
+ */
+uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
+ const uint8_t wIndex,
+ const void** const DescriptorAddress)
+{
+ const uint8_t DescriptorType = (wValue >> 8);
+ const uint8_t DescriptorNumber = (wValue & 0xFF);
+
+ const void* Address = NULL;
+ uint16_t Size = NO_DESCRIPTOR;
+
+ switch (DescriptorType)
+ {
+ case DTYPE_Device:
+ Address = &DeviceDescriptor;
+ Size = sizeof(USB_Descriptor_Device_t);
+ break;
+ case DTYPE_Configuration:
+ Address = &ConfigurationDescriptor;
+ Size = sizeof(USB_Descriptor_Configuration_t);
+ break;
+ case DTYPE_String:
+ switch (DescriptorNumber)
+ {
+ case 0x00:
+ Address = &LanguageString;
+ Size = pgm_read_byte(&LanguageString.Header.Size);
+ break;
+ case 0x01:
+ Address = &ManufacturerString;
+ Size = pgm_read_byte(&ManufacturerString.Header.Size);
+ break;
+ case 0x02:
+ Address = &ProductString;
+ Size = pgm_read_byte(&ProductString.Header.Size);
+ break;
+ }
+
+ break;
+ }
+
+ *DescriptorAddress = Address;
+ return Size;
+}
+
diff --git a/software/lib/lufa-descriptor-usbdualserial.h b/software/lib/lufa-descriptor-usbdualserial.h
new file mode 100644
index 0000000..d1e6ca6
--- /dev/null
+++ b/software/lib/lufa-descriptor-usbdualserial.h
@@ -0,0 +1,112 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2012.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+/** \file
+ *
+ * Header file for Descriptors.c.
+ */
+
+#ifndef _DESCRIPTORS_H_
+#define _DESCRIPTORS_H_
+
+ /* Includes: */
+ #include <avr/pgmspace.h>
+
+ #include <LUFA/Drivers/USB/USB.h>
+
+ /* Macros: */
+ /** Endpoint number of the first CDC interface's device-to-host data IN endpoint. */
+ #define CDC1_TX_EPNUM 1
+
+ /** Endpoint number of the first CDC interface's host-to-device data OUT endpoint. */
+ #define CDC1_RX_EPNUM 2
+
+ /** Endpoint number of the first CDC interface's device-to-host notification IN endpoint. */
+ #define CDC1_NOTIFICATION_EPNUM 3
+
+ /** Endpoint number of the second CDC interface's device-to-host data IN endpoint. */
+ #define CDC2_TX_EPNUM 4
+
+ /** Endpoint number of the second CDC interface's host-to-device data OUT endpoint. */
+ #define CDC2_RX_EPNUM 5
+
+ /** Endpoint number of the second CDC interface's device-to-host notification IN endpoint. */
+ #define CDC2_NOTIFICATION_EPNUM 6
+
+ /** Size in bytes of the CDC device-to-host notification IN endpoints. */
+ #define CDC_NOTIFICATION_EPSIZE 8
+
+ /** Size in bytes of the CDC data IN and OUT endpoints. */
+ #define CDC_TXRX_EPSIZE 16
+
+ /* Type Defines: */
+ /** Type define for the device configuration descriptor structure. This must be defined in the
+ * application code, as the configuration descriptor contains several sub-descriptors which
+ * vary between devices, and which describe the device's usage to the host.
+ */
+ typedef struct
+ {
+ USB_Descriptor_Configuration_Header_t Config;
+
+ // First CDC Control Interface
+ USB_Descriptor_Interface_Association_t CDC1_IAD;
+ USB_Descriptor_Interface_t CDC1_CCI_Interface;
+ USB_CDC_Descriptor_FunctionalHeader_t CDC1_Functional_Header;
+ USB_CDC_Descriptor_FunctionalACM_t CDC1_Functional_ACM;
+ USB_CDC_Descriptor_FunctionalUnion_t CDC1_Functional_Union;
+ USB_Descriptor_Endpoint_t CDC1_ManagementEndpoint;
+
+ // First CDC Data Interface
+ USB_Descriptor_Interface_t CDC1_DCI_Interface;
+ USB_Descriptor_Endpoint_t CDC1_DataOutEndpoint;
+ USB_Descriptor_Endpoint_t CDC1_DataInEndpoint;
+
+ // Second CDC Control Interface
+ USB_Descriptor_Interface_Association_t CDC2_IAD;
+ USB_Descriptor_Interface_t CDC2_CCI_Interface;
+ USB_CDC_Descriptor_FunctionalHeader_t CDC2_Functional_Header;
+ USB_CDC_Descriptor_FunctionalACM_t CDC2_Functional_ACM;
+ USB_CDC_Descriptor_FunctionalUnion_t CDC2_Functional_Union;
+ USB_Descriptor_Endpoint_t CDC2_ManagementEndpoint;
+
+ // Second CDC Data Interface
+ USB_Descriptor_Interface_t CDC2_DCI_Interface;
+ USB_Descriptor_Endpoint_t CDC2_DataOutEndpoint;
+ USB_Descriptor_Endpoint_t CDC2_DataInEndpoint;
+ } USB_Descriptor_Configuration_t;
+
+ /* Function Prototypes: */
+ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
+ const uint8_t wIndex,
+ const void** const DescriptorAddress)
+ ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
+
+#endif
+
diff --git a/software/lib/lufa-descriptor-usbserial.c b/software/lib/lufa-descriptor-usbserial.c
new file mode 100644
index 0000000..1c049be
--- /dev/null
+++ b/software/lib/lufa-descriptor-usbserial.c
@@ -0,0 +1,278 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2012.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+/** \file
+ *
+ * USB Device Descriptors, for library use when in USB device mode. Descriptors are special
+ * computer-readable structures which the host requests upon device enumeration, to determine
+ * the device's capabilities and functions.
+ */
+
+#include "lufa-descriptor-usbserial.h"
+
+/* On some devices, there is a factory set internal serial number which can be automatically sent to the host as
+ * the device's serial number when the Device Descriptor's .SerialNumStrIndex entry is set to USE_INTERNAL_SERIAL.
+ * This allows the host to track a device across insertions on different ports, allowing them to retain allocated
+ * resources like COM port numbers and drivers. On demos using this feature, give a warning on unsupported devices
+ * so that the user can supply their own serial number descriptor instead or remove the USE_INTERNAL_SERIAL value
+ * from the Device Descriptor (forcing the host to generate a serial number for each device from the VID, PID and
+ * port location).
+ */
+#if (USE_INTERNAL_SERIAL == NO_DESCRIPTOR)
+ #warning USE_INTERNAL_SERIAL is not available on this AVR - please manually construct a device serial descriptor.
+#endif
+
+/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
+ * device characteristics, including the supported USB version, control endpoint size and the
+ * number of device configurations. The descriptor is read out by the USB host when the enumeration
+ * process begins.
+ */
+const USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
+{
+ .Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
+
+ .USBSpecification = VERSION_BCD(01.10),
+ .Class = CDC_CSCP_CDCClass,
+ .SubClass = CDC_CSCP_NoSpecificSubclass,
+ .Protocol = CDC_CSCP_NoSpecificProtocol,
+
+ .Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
+
+ .VendorID = 0x03EB,
+ .ProductID = 0x204B,
+ .ReleaseNumber = VERSION_BCD(00.01),
+
+ .ManufacturerStrIndex = 0x01,
+ .ProductStrIndex = 0x02,
+ .SerialNumStrIndex = USE_INTERNAL_SERIAL,
+
+ .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
+};
+
+/** Configuration descriptor structure. This descriptor, located in FLASH memory, describes the usage
+ * of the device in one of its supported configurations, including information about any device interfaces
+ * and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting
+ * a configuration so that the host may correctly communicate with the USB device.
+ */
+const 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_RESERVED | USB_CONFIG_ATTR_SELFPOWERED),
+
+ .MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
+ },
+
+ .CDC_CCI_Interface =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
+
+ .InterfaceNumber = 0,
+ .AlternateSetting = 0,
+
+ .TotalEndpoints = 1,
+
+ .Class = CDC_CSCP_CDCClass,
+ .SubClass = CDC_CSCP_ACMSubclass,
+ .Protocol = CDC_CSCP_ATCommandProtocol,
+
+ .InterfaceStrIndex = NO_DESCRIPTOR
+ },
+
+ .CDC_Functional_Header =
+ {
+ .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalHeader_t), .Type = DTYPE_CSInterface},
+ .Subtype = CDC_DSUBTYPE_CSInterface_Header,
+
+ .CDCSpecification = VERSION_BCD(01.10),
+ },
+
+ .CDC_Functional_ACM =
+ {
+ .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalACM_t), .Type = DTYPE_CSInterface},
+ .Subtype = CDC_DSUBTYPE_CSInterface_ACM,
+
+ .Capabilities = 0x06,
+ },
+
+ .CDC_Functional_Union =
+ {
+ .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalUnion_t), .Type = DTYPE_CSInterface},
+ .Subtype = CDC_DSUBTYPE_CSInterface_Union,
+
+ .MasterInterfaceNumber = 0,
+ .SlaveInterfaceNumber = 1,
+ },
+
+ .CDC_NotificationEndpoint =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+ .EndpointAddress = (ENDPOINT_DIR_IN | CDC_NOTIFICATION_EPNUM),
+ .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+ .EndpointSize = CDC_NOTIFICATION_EPSIZE,
+ .PollingIntervalMS = 0xFF
+ },
+
+ .CDC_DCI_Interface =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
+
+ .InterfaceNumber = 1,
+ .AlternateSetting = 0,
+
+ .TotalEndpoints = 2,
+
+ .Class = CDC_CSCP_CDCDataClass,
+ .SubClass = CDC_CSCP_NoDataSubclass,
+ .Protocol = CDC_CSCP_NoDataProtocol,
+
+ .InterfaceStrIndex = NO_DESCRIPTOR
+ },
+
+ .CDC_DataOutEndpoint =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+ .EndpointAddress = (ENDPOINT_DIR_OUT | CDC_RX_EPNUM),
+ .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+ .EndpointSize = CDC_TXRX_EPSIZE,
+ .PollingIntervalMS = 0x01
+ },
+
+ .CDC_DataInEndpoint =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+ .EndpointAddress = (ENDPOINT_DIR_IN | CDC_TX_EPNUM),
+ .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+ .EndpointSize = CDC_TXRX_EPSIZE,
+ .PollingIntervalMS = 0x01
+ }
+};
+
+/** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests
+ * the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate
+ * via the language ID table available at USB.org what languages the device supports for its string descriptors.
+ */
+const USB_Descriptor_String_t PROGMEM LanguageString =
+{
+ .Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
+
+ .UnicodeString = {LANGUAGE_ID_ENG}
+};
+
+
+/** Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable
+ * form, and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
+ * Descriptor.
+ */
+const USB_Descriptor_String_t PROGMEM ManufacturerString =
+{
+ .Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String},
+#ifndef USB_MANUFACTURER
+ .UnicodeString = L"Dean Camera"
+#else
+ .UnicodeString = USB_MANUFACTURER
+#endif
+};
+
+/** Product descriptor string. This is a Unicode string containing the product's details in human readable form,
+ * and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
+ * Descriptor.
+ */
+const USB_Descriptor_String_t PROGMEM ProductString =
+{
+ .Header = {.Size = USB_STRING_LEN(23), .Type = DTYPE_String},
+#ifndef USB_PRODUCT
+ .UnicodeString = L"LUFA USB-RS232 Adapter"
+#else
+ .UnicodeString = USB_PRODUCT
+#endif
+};
+
+/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"
+ * documentation) by the application code so that the address and size of a requested descriptor can be given
+ * to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
+ * is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
+ * USB host.
+ */
+uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
+ const uint8_t wIndex,
+ const void** const DescriptorAddress)
+{
+ const uint8_t DescriptorType = (wValue >> 8);
+ const uint8_t DescriptorNumber = (wValue & 0xFF);
+
+ const void* Address = NULL;
+ uint16_t Size = NO_DESCRIPTOR;
+
+ switch (DescriptorType)
+ {
+ case DTYPE_Device:
+ Address = &DeviceDescriptor;
+ Size = sizeof(USB_Descriptor_Device_t);
+ break;
+ case DTYPE_Configuration:
+ Address = &ConfigurationDescriptor;
+ Size = sizeof(USB_Descriptor_Configuration_t);
+ break;
+ case DTYPE_String:
+ switch (DescriptorNumber)
+ {
+ case 0x00:
+ Address = &LanguageString;
+ Size = pgm_read_byte(&LanguageString.Header.Size);
+ break;
+ case 0x01:
+ Address = &ManufacturerString;
+ Size = pgm_read_byte(&ManufacturerString.Header.Size);
+ break;
+ case 0x02:
+ Address = &ProductString;
+ Size = pgm_read_byte(&ProductString.Header.Size);
+ break;
+ }
+
+ break;
+ }
+
+ *DescriptorAddress = Address;
+ return Size;
+}
+
diff --git a/software/lib/lufa-descriptor-usbserial.h b/software/lib/lufa-descriptor-usbserial.h
new file mode 100644
index 0000000..97afd41
--- /dev/null
+++ b/software/lib/lufa-descriptor-usbserial.h
@@ -0,0 +1,89 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2012.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+/** \file
+ *
+ * Header file for Descriptors.c.
+ */
+
+#ifndef _DESCRIPTORS_H_
+#define _DESCRIPTORS_H_
+
+ /* Includes: */
+ #include <avr/pgmspace.h>
+
+ #include <LUFA/Drivers/USB/USB.h>
+
+ /* Macros: */
+ /** Endpoint number of the CDC device-to-host notification IN endpoint. */
+ #define CDC_NOTIFICATION_EPNUM 2
+
+ /** Endpoint number of the CDC device-to-host data IN endpoint. */
+ #define CDC_TX_EPNUM 3
+
+ /** Endpoint number of the CDC host-to-device data OUT endpoint. */
+ #define CDC_RX_EPNUM 4
+
+ /** Size in bytes of the CDC device-to-host notification IN endpoint. */
+ #define CDC_NOTIFICATION_EPSIZE 8
+
+ /** Size in bytes of the CDC data IN and OUT endpoints. */
+ #define CDC_TXRX_EPSIZE 16
+
+ /* Type Defines: */
+ /** Type define for the device configuration descriptor structure. This must be defined in the
+ * application code, as the configuration descriptor contains several sub-descriptors which
+ * vary between devices, and which describe the device's usage to the host.
+ */
+ typedef struct
+ {
+ USB_Descriptor_Configuration_Header_t Config;
+
+ // CDC Command Interface
+ USB_Descriptor_Interface_t CDC_CCI_Interface;
+ USB_CDC_Descriptor_FunctionalHeader_t CDC_Functional_Header;
+ USB_CDC_Descriptor_FunctionalACM_t CDC_Functional_ACM;
+ USB_CDC_Descriptor_FunctionalUnion_t CDC_Functional_Union;
+ USB_Descriptor_Endpoint_t CDC_NotificationEndpoint;
+
+ // CDC Data Interface
+ USB_Descriptor_Interface_t CDC_DCI_Interface;
+ USB_Descriptor_Endpoint_t CDC_DataOutEndpoint;
+ USB_Descriptor_Endpoint_t CDC_DataInEndpoint;
+ } USB_Descriptor_Configuration_t;
+
+ /* Function Prototypes: */
+ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
+ const uint8_t wIndex,
+ const void** const DescriptorAddress)
+ ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
+
+#endif
+
diff --git a/software/lib/onewire.c b/software/lib/onewire.c
new file mode 100644
index 0000000..ba1a681
--- /dev/null
+++ b/software/lib/onewire.c
@@ -0,0 +1,274 @@
+/*
+ * spreadspace avr utils
+ *
+ *
+ * Copyright (C) 2013 Christian Pointner <equinox@spreadspace.org>
+ *
+ * This file is part of spreadspace avr utils.
+ *
+ * spreadspace avr utils 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 3 of the License, or
+ * any later version.
+ *
+ * spreadspace avr utils 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 spreadspace avr utils. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ This is inspired by
+
+ DS18x20 Demo-Program
+
+ V 0.9.2, 2/2011
+
+ by Martin Thomas <eversmith@heizung-thomas.de>
+ http://www.siwawi.arubi.uni-kl.de/avr-projects
+*/
+
+#include <avr/io.h>
+#include <util/delay.h>
+#include <util/atomic.h>
+
+#include "onewire.h"
+
+#define ONEWIRE_GET_IN(bus) ( *(bus->in) & (1 << bus->pin) )
+#define ONEWIRE_OUT_LOW(bus) ( *(bus->out) &= (uint8_t) ~(1 << bus->pin) )
+#define ONEWIRE_OUT_HIGH(bus) ( *(bus->out) |= (uint8_t) (1 << bus->pin) )
+#define ONEWIRE_DIR_IN(bus) ( *(bus->ddr) &= (uint8_t) ~(1 << bus->pin) )
+#define ONEWIRE_DIR_OUT(bus) ( *(bus->ddr) |= (uint8_t) (1 << bus->pin) )
+
+void onewire_init(onewire_bus_t* bus)
+{
+ onewire_reset(bus);
+}
+
+uint8_t onewire_input_pin_state(onewire_bus_t* bus)
+{
+ return ONEWIRE_GET_IN(bus);
+}
+
+void onewire_parasite_enable(onewire_bus_t* bus)
+{
+ ONEWIRE_OUT_HIGH(bus);
+ ONEWIRE_DIR_OUT(bus);
+}
+
+void onewire_parasite_disable(onewire_bus_t* bus)
+{
+ ONEWIRE_DIR_IN(bus);
+#if (!ONEWIRE_USE_INTERNAL_PULLUP)
+ ONEWIRE_OUT_LOW(bus);
+#endif
+}
+
+uint8_t onewire_reset(onewire_bus_t* bus)
+{
+ uint8_t err;
+
+ ONEWIRE_OUT_LOW(bus);
+ ONEWIRE_DIR_OUT(bus); // pull OW-Pin low for 480us
+ _delay_us(480);
+
+ ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
+ // set Pin as input - wait for clients to pull low
+ ONEWIRE_DIR_IN(bus); // input
+#if ONEWIRE_USE_INTERNAL_PULLUP
+ ONEWIRE_OUT_HIGH(bus);
+#endif
+
+ _delay_us(64); // was 66
+ err = ONEWIRE_GET_IN(bus); // no presence detect
+ // if err!=0: nobody pulled to low, still high
+ }
+
+ // after a delay the clients should release the line
+ // and input-pin gets back to high by pull-up-resistor
+ _delay_us(480 - 64); // was 480-66
+ if(ONEWIRE_GET_IN(bus) == 0) {
+ err = 1; // short circuit, expected low but got high
+ }
+
+ return err;
+}
+
+
+/* Timing issue when using runtime-bus-selection (!ONEWIRE_ONE_BUS):
+ The master should sample at the end of the 15-slot after initiating
+ the read-time-slot. The variable bus-settings need more
+ cycles than the constant ones so the delays had to be shortened
+ to achive a 15uS overall delay
+ Setting/clearing a bit in I/O Register needs 1 cyle in ONEWIRE_ONE_BUS
+ but around 14 cyles in configureable bus (us-Delay is 4 cyles per uS) */
+static uint8_t onewire_bit_io_intern(onewire_bus_t* bus, uint8_t b, uint8_t with_parasite_enable)
+{
+ ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
+#if ONEWIRE_USE_INTERNAL_PULLUP
+ ONEWIRE_OUT_LOW(bus);
+#endif
+ ONEWIRE_DIR_OUT(bus); // drive bus low
+ _delay_us(2); // T_INT > 1usec accoding to timing-diagramm
+ if(b) {
+ ONEWIRE_DIR_IN(bus); // to write "1" release bus, resistor pulls high
+#if ONEWIRE_USE_INTERNAL_PULLUP
+ ONEWIRE_OUT_HIGH(bus);
+#endif
+ }
+
+ // "Output data from the DS18B20 is valid for 15usec after the falling
+ // edge that initiated the read time slot. Therefore, the master must
+ // release the bus and then sample the bus state within 15ussec from
+ // the start of the slot."
+ _delay_us(15-2-ONEWIRE_CONF_DELAYOFFSET);
+
+ if(ONEWIRE_GET_IN(bus) == 0)
+ b = 0; // sample at end of read-timeslot
+
+ _delay_us(60-15-2+ONEWIRE_CONF_DELAYOFFSET);
+#if ONEWIRE_USE_INTERNAL_PULLUP
+ ONEWIRE_OUT_HIGH(bus);
+#endif
+ ONEWIRE_DIR_IN(bus);
+
+ if(with_parasite_enable) {
+ onewire_parasite_enable(bus);
+ }
+
+ } /* ATOMIC_BLOCK */
+
+ _delay_us(ONEWIRE_RECOVERY_TIME); // may be increased for longer wires
+
+ return b;
+}
+
+uint8_t onewire_bit_io(onewire_bus_t* bus, uint8_t b)
+{
+ return onewire_bit_io_intern(bus, b & 1, 0);
+}
+
+uint8_t onewire_byte_wr(onewire_bus_t* bus, uint8_t b)
+{
+ uint8_t i = 8, j;
+
+ do {
+ j = onewire_bit_io(bus, b & 1);
+ b >>= 1;
+ if( j ) {
+ b |= 0x80;
+ }
+ } while( --i );
+
+ return b;
+}
+
+uint8_t onewire_byte_wr_with_parasite_enable(onewire_bus_t* bus, uint8_t b)
+{
+ uint8_t i = 8, j;
+
+ do {
+ if (i != 1) {
+ j = onewire_bit_io_intern(bus, b & 1, 0);
+ } else {
+ j = onewire_bit_io_intern(bus, b & 1, 1);
+ }
+ b >>= 1;
+ if(j) {
+ b |= 0x80;
+ }
+ } while(--i);
+
+ return b;
+}
+
+uint8_t onewire_byte_rd(onewire_bus_t* bus)
+{
+ // read by sending only "1"s, so bus gets released
+ // after the init low-pulse in every slot
+ return onewire_byte_wr(bus, 0xFF);
+}
+
+
+uint8_t onewire_rom_search(onewire_bus_t* bus, uint8_t diff, uint8_t *id )
+{
+ uint8_t i, j, next_diff;
+ uint8_t b;
+
+ if(onewire_reset(bus)) {
+ return ONEWIRE_PRESENCE_ERR; // error, no device found <--- early exit!
+ }
+
+ onewire_byte_wr(ONEWIRE_SEARCH_ROM); // ROM search command
+ next_diff = ONEWIRE_LAST_DEVICE; // unchanged on last device
+
+ i = ONEWIRE_ROMCODE_SIZE * 8; // 8 bytes
+
+ do {
+ j = 8; // 8 bits
+ do {
+ b = onewire_bit_io(bus, 1); // read bit
+ if(onewire_bit_io(bus, 1)) { // read complement bit
+ if(b) { // 0b11
+ return ONEWIRE_DATA_ERR; // data error <--- early exit!
+ }
+ }
+ else {
+ if(!b) { // 0b00 = 2 devices
+ if(diff > i || ((*id & 1) && diff != i)) {
+ b = 1; // now 1
+ next_diff = i; // next pass 0
+ }
+ }
+ }
+ onewire_bit_io(bus, b); // write bit
+ *id >>= 1;
+ if(b) *id |= 0x80; // store bit
+ i--;
+
+ } while(--j);
+ id++; // next byte
+ } while(i);
+
+ return next_diff; // to continue search
+}
+
+
+static void onewire_command_intern(onewire_bus_t* bus, uint8_t command, uint8_t *id, uint8_t with_parasite_enable)
+{
+ uint8_t i;
+
+ onewire_reset(bus);
+
+ if( id ) {
+ onewire_byte_wr(bus, ONEWIRE_MATCH_ROM); // to a single device
+ i = ONEWIRE_ROMCODE_SIZE;
+ do {
+ onewire_byte_wr(bus, *id);
+ id++;
+ } while(--i);
+ }
+ else {
+ onewire_byte_wr(bus, ONEWIRE_SKIP_ROM); // to all devices
+ }
+
+ if(with_parasite_enable) {
+ onewire_byte_wr_with_parasite_enable(bus, command);
+ } else {
+ onewire_byte_wr(bus, command);
+ }
+}
+
+void onewire_command(onewire_bus_t* bus, uint8_t command, uint8_t *id )
+{
+ onewire_command_intern(bus, command, id, 0);
+}
+
+void onewire_command_with_parasite_enable(onewire_bus_t* bus, uint8_t command, uint8_t *id)
+{
+ onewire_command_intern(bus, command, id, 1);
+}
+
diff --git a/software/lib/onewire.h b/software/lib/onewire.h
new file mode 100644
index 0000000..ecd8207
--- /dev/null
+++ b/software/lib/onewire.h
@@ -0,0 +1,92 @@
+/*
+ * spreadspace avr utils
+ *
+ *
+ * Copyright (C) 2013 Christian Pointner <equinox@spreadspace.org>
+ *
+ * This file is part of spreadspace avr utils.
+ *
+ * spreadspace avr utils 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 3 of the License, or
+ * any later version.
+ *
+ * spreadspace avr utils 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 spreadspace avr utils. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ This is inspired by
+
+ DS18x20 Demo-Program
+
+ V 0.9.2, 2/2011
+
+ by Martin Thomas <eversmith@heizung-thomas.de>
+ http://www.siwawi.arubi.uni-kl.de/avr-projects
+*/
+
+
+#ifndef SPREADAVR_onewire_h_INCLUDED
+#define SPREADAVR_onewire_h_INCLUDED
+
+typedef struct {
+ uint8_t* in;
+ uint8_t* out;
+ uint8_t* ddr;
+ uint8_t pin;
+} onewire_bus_t;
+
+#define OW_CONF_CYCLESPERACCESS 13
+#define OW_CONF_DELAYOFFSET ( (uint16_t)( ((OW_CONF_CYCLESPERACCESS) * 1000000L) / F_CPU ) )
+
+// Recovery time (T_Rec) minimum 1usec - increase for long lines
+// 5 usecs is a value give in some Maxim AppNotes
+// 30u secs seem to be reliable for longer lines
+//#define OW_RECOVERY_TIME 5 /* usec */
+//#define OW_RECOVERY_TIME 300 /* usec */
+#define OW_RECOVERY_TIME 10 /* usec */
+
+// Use AVR's internal pull-up resistor instead of external 4,7k resistor.
+// Based on information from Sascha Schade. Experimental but worked in tests
+// with one DS18B20 and one DS18S20 on a rather short bus (60cm), where both
+// sensores have been parasite-powered.
+#define OW_USE_INTERNAL_PULLUP 1 /* 0=external, 1=internal */
+
+/*******************************************/
+
+
+#define OW_MATCH_ROM 0x55
+#define OW_SKIP_ROM 0xCC
+#define OW_SEARCH_ROM 0xF0
+
+#define OW_SEARCH_FIRST 0xFF // start new search
+#define OW_PRESENCE_ERR 0xFF
+#define OW_DATA_ERR 0xFE
+#define OW_LAST_DEVICE 0x00 // last device found
+
+// rom-code size including CRC
+#define OW_ROMCODE_SIZE 8
+
+void onewire_init(onewire_bus_t* bus);
+uint8_t onewire_reset(onewire_bus_t* bus);
+
+extern uint8_t onewire_bit_io(onewire_bus_t* bus, uint8_t b);
+extern uint8_t onewire_byte_wr(onewire_bus_t* bus, uint8_t b);
+extern uint8_t onewire_byte_rd(onewire_bus_t* bus);
+
+extern uint8_t onewire_rom_search(onewire_bus_t* bus, uint8_t diff, uint8_t *id);
+
+extern void onewire_command(onewire_bus_t* bus, uint8_t command, uint8_t *id);
+extern void onewire_command_with_parasite_enable(onewire_bus_t* bus, uint8_t command, uint8_t *id);
+
+extern void onewire_parasite_enable(onewire_bus_t* bus);
+extern void onewire_parasite_disable(onewire_bus_t* bus);
+extern uint8_t onewire_input_pin_state(onewire_bus_t* bus);
+
+#endif
diff --git a/software/lib/usbio.c b/software/lib/usbio.c
new file mode 100644
index 0000000..371f9e7
--- /dev/null
+++ b/software/lib/usbio.c
@@ -0,0 +1,109 @@
+/*
+ * spreadspace avr utils
+ *
+ *
+ * Copyright (C) 2013 Christian Pointner <equinox@spreadspace.org>
+ * Othmar Gsenger <otti@wirdorange.org>
+ *
+ * This file is part of spreadspace avr utils.
+ *
+ * spreadspace avr utils 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 3 of the License, or
+ * any later version.
+ *
+ * spreadspace avr utils 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 spreadspace avr utils. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+
+#include "usbio.h"
+
+#include <LUFA/Drivers/USB/USB.h>
+#include "lufa-descriptor-usbserial.h"
+#include "LUFA/Drivers/Peripheral/Serial.h"
+
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2012.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+USB_ClassInfo_CDC_Device_t VirtualSerial_CDC_Interface =
+ {
+ .Config =
+ {
+ .ControlInterfaceNumber = 0,
+
+ .DataINEndpointNumber = CDC_TX_EPNUM,
+ .DataINEndpointSize = CDC_TXRX_EPSIZE,
+ .DataINEndpointDoubleBank = false,
+
+ .DataOUTEndpointNumber = CDC_RX_EPNUM,
+ .DataOUTEndpointSize = CDC_TXRX_EPSIZE,
+ .DataOUTEndpointDoubleBank = false,
+
+ .NotificationEndpointNumber = CDC_NOTIFICATION_EPNUM,
+ .NotificationEndpointSize = CDC_NOTIFICATION_EPSIZE,
+ .NotificationEndpointDoubleBank = false,
+ },
+ };
+
+void EVENT_USB_Device_ConfigurationChanged(void)
+{
+ CDC_Device_ConfigureEndpoints(&VirtualSerial_CDC_Interface);
+}
+
+void EVENT_USB_Device_ControlRequest(void)
+{
+ CDC_Device_ProcessControlRequest(&VirtualSerial_CDC_Interface);
+}
+/* end LUFA CDC-ACM specific definitions*/
+
+static int dummy_putchar(char DataByte, FILE *Stream) { return 0; }
+static int dummy_getchar(FILE *Stream) { return 0; }
+static FILE dummy_stream = FDEV_SETUP_STREAM(dummy_putchar, dummy_getchar, _FDEV_SETUP_RW);
+static FILE usb_stream;
+
+void usbio_init(void)
+{
+ stdin = stdout = stderr = &dummy_stream;
+
+ USB_Init();
+ CDC_Device_CreateStream(&VirtualSerial_CDC_Interface,&usb_stream);
+}
+
+void usbio_task(void)
+{
+ CDC_Device_USBTask(&VirtualSerial_CDC_Interface);
+ USB_USBTask();
+}
+
+int16_t usbio_bytes_received(void)
+{
+ if(stdin == &usb_stream)
+ return CDC_Device_BytesReceived(&VirtualSerial_CDC_Interface);
+ else
+ return 0;
+}
+
+void EVENT_CDC_Device_ControLineStateChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
+{
+ if(CDCInterfaceInfo->State.ControlLineStates.HostToDevice & CDC_CONTROL_LINE_OUT_DTR)
+ stdin = stdout = stderr = &usb_stream;
+ else
+ stdin = stdout = stderr = &dummy_stream;
+}
+
+void EVENT_USB_Device_Disconnect(void)
+{
+ stdin = stdout = stderr = &dummy_stream;
+}
diff --git a/software/lib/usbio.h b/software/lib/usbio.h
new file mode 100644
index 0000000..cdc5bec
--- /dev/null
+++ b/software/lib/usbio.h
@@ -0,0 +1,33 @@
+/*
+ * spreadspace avr utils
+ *
+ *
+ * Copyright (C) 2013 Christian Pointner <equinox@spreadspace.org>
+ * Othmar Gsenger <otti@wirdorange.org>
+ *
+ * This file is part of spreadspace avr utils.
+ *
+ * spreadspace avr utils 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 3 of the License, or
+ * any later version.
+ *
+ * spreadspace avr utils 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 spreadspace avr utils. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SPREADAVR_usbio_h_INCLUDED
+#define SPREADAVR_usbio_h_INCLUDED
+
+#include <stdint.h>
+
+void usbio_init(void);
+void usbio_task(void);
+int16_t usbio_bytes_received(void);
+
+#endif
diff --git a/software/lib/util.c b/software/lib/util.c
new file mode 100644
index 0000000..0e99a93
--- /dev/null
+++ b/software/lib/util.c
@@ -0,0 +1,114 @@
+/*
+ * spreadspace avr utils
+ *
+ *
+ * Copyright (C) 2013 Christian Pointner <equinox@spreadspace.org>
+ *
+ * This file is part of spreadspace avr utils.
+ *
+ * spreadspace avr utils 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 3 of the License, or
+ * any later version.
+ *
+ * spreadspace avr utils 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 spreadspace avr utils. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <avr/interrupt.h>
+#include <avr/io.h>
+#include <util/delay.h>
+
+#include "util.h"
+
+#if defined(CLKPR)
+#define CPU_PRESCALE(n) do { CLKPR = 0x80; CLKPR = (n); } while(0)
+#else
+#define CPU_PRESCALE(n)
+#endif
+
+void cpu_init(void)
+{
+ CPU_PRESCALE(0);
+}
+
+#if defined(__BOARD_teensy1__)
+ #define BOOTLOADER_VEC 0x3E00
+#elif defined(__BOARD_teensy2__)
+ #define BOOTLOADER_VEC 0x7E00
+#elif defined(__BOARD_teensy1pp__)
+ #define BOOTLOADER_VEC 0xFC00
+#elif defined(__BOARD_teensy2pp__)
+ #define BOOTLOADER_VEC 0x1FC00
+#elif defined(__BOARD_minimus__)
+ #define BOOTLOADER_VEC 0x3000
+#elif defined(__BOARD_minimus32__)
+ #define BOOTLOADER_VEC 0x3800
+#elif defined(__BOARD_hhd70dongle__) || defined(__BOARD_rda1846dongle__) || defined(__BOARD_culV3__)
+ #define BOOTLOADER_VEC 0x3800
+#elif defined(__BOARD_slowpandongle1__) || defined(__BOARD_slowpandongle2__)
+ #define BOOTLOADER_VEC 0x3800
+#else
+ #define BOOTLOADER_VEC 0x0000
+#endif
+
+typedef void (*f_ptr_type)(void);
+f_ptr_type start_bootloader = (f_ptr_type)BOOTLOADER_VEC;
+
+void reset2bootloader(void)
+{
+#if defined(__BOARD_teensy1__) || defined(__BOARD_teensy1pp__) || defined(__BOARD_teensy2__) || defined(__BOARD_teensy2pp__) || \
+ defined(__BOARD_hhd70dongle__) || defined(__BOARD_rda1846dongle__) || defined(__BOARD_culV3__) || \
+ defined(__BOARD_slowpandongle1__) || defined(__BOARD_slowpandongle2__) || \
+ defined(__BOARD_minimus__) || defined(__BOARD_minimus32__)
+ cli();
+ // disable watchdog, if enabled
+ // disable all peripherals
+ UDCON = 1;
+ USBCON = (1<<FRZCLK); // disable USB
+ UCSR1B = 0;
+ _delay_ms(5);
+ #if defined(__BOARD_teensy1__)
+ EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0;
+ TIMSK0 = 0; TIMSK1 = 0; UCSR1B = 0;
+ DDRB = 0; DDRC = 0; DDRD = 0;
+ PORTB = 0; PORTC = 0; PORTD = 0;
+ #elif defined(__BOARD_teensy2__)
+ EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0; ADCSRA = 0;
+ TIMSK0 = 0; TIMSK1 = 0; TIMSK3 = 0; TIMSK4 = 0; UCSR1B = 0; TWCR = 0;
+ DDRB = 0; DDRC = 0; DDRD = 0; DDRE = 0; DDRF = 0; TWCR = 0;
+ PORTB = 0; PORTC = 0; PORTD = 0; PORTE = 0; PORTF = 0;
+ #elif defined(__BOARD_teensy1pp__)
+ EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0; ADCSRA = 0;
+ TIMSK0 = 0; TIMSK1 = 0; TIMSK2 = 0; TIMSK3 = 0; UCSR1B = 0; TWCR = 0;
+ DDRA = 0; DDRB = 0; DDRC = 0; DDRD = 0; DDRE = 0; DDRF = 0;
+ PORTA = 0; PORTB = 0; PORTC = 0; PORTD = 0; PORTE = 0; PORTF = 0;
+ #elif defined(__BOARD_teensy2pp__)
+ EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0; ADCSRA = 0;
+ TIMSK0 = 0; TIMSK1 = 0; TIMSK2 = 0; TIMSK3 = 0; UCSR1B = 0; TWCR = 0;
+ DDRA = 0; DDRB = 0; DDRC = 0; DDRD = 0; DDRE = 0; DDRF = 0;
+ PORTA = 0; PORTB = 0; PORTC = 0; PORTD = 0; PORTE = 0; PORTF = 0;
+ #elif defined(__BOARD_minimus__) || defined(__BOARD_slowpandongle1__)
+ EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0;
+ TIMSK0 = 0; TIMSK1 = 0; UCSR1B = 0;
+ DDRB = 0; DDRC = 0; DDRD = 0;
+ PORTB = 0; PORTC = 0; PORTD = 0;
+ #elif defined(__BOARD_minimus32__)
+ EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0;
+ TIMSK0 = 0; TIMSK1 = 0; UCSR1B = 0;
+ DDRB = 0; DDRC = 0; DDRD = 0;
+ PORTB = 0; PORTC = 0; PORTD = 0;
+ #elif defined(__BOARD_hhd70dongle2__) || defined(__BOARD_hhd70dongle__) || defined(__BOARD_rda1846dongle__) || defined(__BOARD_culV3__)
+ EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0; ADCSRA = 0;
+ TIMSK0 = 0; TIMSK1 = 0; TIMSK3 = 0; TIMSK4 = 0; UCSR1B = 0; TWCR = 0;
+ DDRB = 0; DDRC = 0; DDRD = 0; DDRE = 0; DDRF = 0; TWCR = 0;
+ PORTB = 0; PORTC = 0; PORTD = 0; PORTE = 0; PORTF = 0;
+ #endif
+ start_bootloader();
+#endif
+}
diff --git a/software/lib/util.h b/software/lib/util.h
new file mode 100644
index 0000000..b8403b3
--- /dev/null
+++ b/software/lib/util.h
@@ -0,0 +1,29 @@
+/*
+ * spreadspace avr utils
+ *
+ *
+ * Copyright (C) 2013 Christian Pointner <equinox@spreadspace.org>
+ *
+ * This file is part of spreadspace avr utils.
+ *
+ * spreadspace avr utils 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 3 of the License, or
+ * any later version.
+ *
+ * spreadspace avr utils 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 spreadspace avr utils. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SPREADAVR_util_h_INCLUDED
+#define SPREADAVR_util_h_INCLUDED
+
+void cpu_init(void);
+void reset2bootloader(void);
+
+#endif
diff --git a/software/lufa.mk b/software/lufa.mk
new file mode 100644
index 0000000..ec4dd7a
--- /dev/null
+++ b/software/lufa.mk
@@ -0,0 +1,41 @@
+##
+## spreadspace avr utils
+##
+##
+## Copyright (C) 2013 Christian Pointner <equinox@spreadspace.org>
+##
+## This file is part of spreadspace avr utils.
+##
+## spreadspace avr utils 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 3 of the License, or
+## any later version.
+##
+## spreadspace avr utils 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 spreadspace avr utils. If not, see <http://www.gnu.org/licenses/>.
+##
+
+include ../defines.mk
+
+include $(LUFA_PATH)/LUFA/makefile
+SRC:=$(foreach COMP,$(LUFA_COMPONENTS),$(LUFA_SRC_$(COMP)))
+
+CFLAGS += -DF_USB=$(F_USB)UL
+CFLAGS += -DBOARD=BOARD_$(LUFA_BOARD)
+CFLAGS += $(LUFA_OPTS)
+
+OBJ = $(SRC:%.c=%.o)
+
+liblufa.a: $(OBJ)
+ $(AR) $@ $(OBJ)
+
+%.o: %.c
+ $(CC) -c $(CFLAGS) $< -o $@
+
+clean:
+ rm -f $(SRC:%.c=%.o)
diff --git a/software/nodectl/Makefile b/software/nodectl/Makefile
new file mode 100644
index 0000000..99b073b
--- /dev/null
+++ b/software/nodectl/Makefile
@@ -0,0 +1,41 @@
+##
+## spreadspace avr utils
+##
+##
+## Copyright (C) 2013 Christian Pointner <equinox@spreadspace.org>
+##
+## This file is part of spreadspace avr utils.
+##
+## spreadspace avr utils 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 3 of the License, or
+## any later version.
+##
+## spreadspace avr utils 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 spreadspace avr utils. If not, see <http://www.gnu.org/licenses/>.
+##
+
+NAME := nodectl
+BOARD_TYPE := slowpandongle2
+OBJ := $(NAME).o
+LIBS := util led lufa-descriptor-usbdualserial
+EXTERNAL_LIBS := lufa
+
+LUFA_PATH := ../../contrib/LUFA-120219
+LUFA_OPTS = -D USB_DEVICE_ONLY
+LUFA_OPTS += -D FIXED_CONTROL_ENDPOINT_SIZE=8
+LUFA_OPTS += -D FIXED_NUM_CONFIGURATIONS=1
+LUFA_OPTS += -D USE_FLASH_DESCRIPTORS
+LUFA_OPTS += -D USE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"
+
+LUFA_OPTS += -D USB_MANUFACTURER="L\"equinox\""
+LUFA_OPTS += -D USB_PRODUCT="L\"$(NAME)\""
+
+LUFA_COMPONENTS := USB USBCLASS SERIAL
+
+include ../include.mk
diff --git a/software/nodectl/nodectl.c b/software/nodectl/nodectl.c
new file mode 100644
index 0000000..ce51442
--- /dev/null
+++ b/software/nodectl/nodectl.c
@@ -0,0 +1,256 @@
+/*
+ * spreadspace avr utils
+ *
+ *
+ * Copyright (C) 2013 Christian Pointner <equinox@spreadspace.org>
+ *
+ * This file is part of spreadspace avr utils.
+ *
+ * spreadspace avr utils 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 3 of the License, or
+ * any later version.
+ *
+ * spreadspace avr utils 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 spreadspace avr utils. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include <avr/io.h>
+#include <avr/wdt.h>
+#include <avr/interrupt.h>
+#include <avr/power.h>
+#include <util/delay.h>
+
+#include "util.h"
+#include "led.h"
+
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2012.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+#include <LUFA/Drivers/USB/USB.h>
+#include <LUFA/Drivers/Peripheral/Serial.h>
+#include <LUFA/Drivers/Misc/RingBuffer.h>
+#include "lufa-descriptor-usbdualserial.h"
+
+static RingBuffer_t USBtoUSART_Buffer;
+static uint8_t USBtoUSART_Buffer_Data[128];
+static RingBuffer_t USARTtoUSB_Buffer;
+static uint8_t USARTtoUSB_Buffer_Data[128];
+
+USB_ClassInfo_CDC_Device_t VirtualSerial1_CDC_Interface =
+ {
+ .Config =
+ {
+ .ControlInterfaceNumber = 0,
+
+ .DataINEndpointNumber = CDC1_TX_EPNUM,
+ .DataINEndpointSize = CDC_TXRX_EPSIZE,
+ .DataINEndpointDoubleBank = false,
+
+ .DataOUTEndpointNumber = CDC1_RX_EPNUM,
+ .DataOUTEndpointSize = CDC_TXRX_EPSIZE,
+ .DataOUTEndpointDoubleBank = false,
+
+ .NotificationEndpointNumber = CDC1_NOTIFICATION_EPNUM,
+ .NotificationEndpointSize = CDC_NOTIFICATION_EPSIZE,
+ .NotificationEndpointDoubleBank = false,
+ },
+ };
+
+USB_ClassInfo_CDC_Device_t VirtualSerial2_CDC_Interface =
+ {
+ .Config =
+ {
+ .ControlInterfaceNumber = 2,
+
+ .DataINEndpointNumber = CDC2_TX_EPNUM,
+ .DataINEndpointSize = CDC_TXRX_EPSIZE,
+ .DataINEndpointDoubleBank = false,
+
+ .DataOUTEndpointNumber = CDC2_RX_EPNUM,
+ .DataOUTEndpointSize = CDC_TXRX_EPSIZE,
+ .DataOUTEndpointDoubleBank = false,
+
+ .NotificationEndpointNumber = CDC2_NOTIFICATION_EPNUM,
+ .NotificationEndpointSize = CDC_NOTIFICATION_EPSIZE,
+ .NotificationEndpointDoubleBank = false,
+ },
+ };
+
+void EVENT_USB_Device_ConfigurationChanged(void)
+{
+ CDC_Device_ConfigureEndpoints(&VirtualSerial1_CDC_Interface);
+ CDC_Device_ConfigureEndpoints(&VirtualSerial2_CDC_Interface);
+}
+
+void EVENT_USB_Device_ControlRequest(void)
+{
+ CDC_Device_ProcessControlRequest(&VirtualSerial1_CDC_Interface);
+ CDC_Device_ProcessControlRequest(&VirtualSerial2_CDC_Interface);
+}
+
+void EVENT_CDC_Device_LineEncodingChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
+{
+ if(CDCInterfaceInfo != &VirtualSerial1_CDC_Interface)
+ return;
+
+ uint8_t ConfigMask = 0;
+
+ switch (CDCInterfaceInfo->State.LineEncoding.ParityType)
+ {
+ case CDC_PARITY_Odd:
+ ConfigMask = ((1 << UPM11) | (1 << UPM10));
+ break;
+ case CDC_PARITY_Even:
+ ConfigMask = (1 << UPM11);
+ break;
+ }
+
+ if (CDCInterfaceInfo->State.LineEncoding.CharFormat == CDC_LINEENCODING_TwoStopBits)
+ ConfigMask |= (1 << USBS1);
+
+ switch (CDCInterfaceInfo->State.LineEncoding.DataBits)
+ {
+ case 6:
+ ConfigMask |= (1 << UCSZ10);
+ break;
+ case 7:
+ ConfigMask |= (1 << UCSZ11);
+ break;
+ case 8:
+ ConfigMask |= ((1 << UCSZ11) | (1 << UCSZ10));
+ break;
+ }
+
+ /* Must turn off USART before reconfiguring it, otherwise incorrect operation may occur */
+ UCSR1B = 0;
+ UCSR1A = 0;
+ UCSR1C = 0;
+
+ /* Set the new baud rate before configuring the USART */
+ UBRR1 = SERIAL_2X_UBBRVAL(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS);
+
+ /* Reconfigure the USART in double speed mode for a wider baud rate range at the expense of accuracy */
+ UCSR1C = ConfigMask;
+ UCSR1A = (1 << U2X1);
+ UCSR1B = ((1 << RXCIE1) | (1 << TXEN1) | (1 << RXEN1));
+}
+
+ISR(USART1_RX_vect, ISR_BLOCK)
+{
+ uint8_t ReceivedByte = UDR1;
+
+ if (USB_DeviceState == DEVICE_STATE_Configured)
+ RingBuffer_Insert(&USARTtoUSB_Buffer, ReceivedByte);
+}
+
+void usbserial_init(void)
+{
+ RingBuffer_InitBuffer(&USBtoUSART_Buffer, USBtoUSART_Buffer_Data, sizeof(USBtoUSART_Buffer_Data));
+ RingBuffer_InitBuffer(&USARTtoUSB_Buffer, USARTtoUSB_Buffer_Data, sizeof(USARTtoUSB_Buffer_Data));
+ TCCR0B = (1 << CS02);
+}
+
+void usbserial_task(void)
+{
+ if (!(RingBuffer_IsFull(&USBtoUSART_Buffer))) {
+ int16_t ReceivedByte = CDC_Device_ReceiveByte(&VirtualSerial1_CDC_Interface);
+ if (!(ReceivedByte < 0))
+ RingBuffer_Insert(&USBtoUSART_Buffer, ReceivedByte);
+ }
+
+ uint16_t BufferCount = RingBuffer_GetCount(&USARTtoUSB_Buffer);
+ if ((TIFR0 & (1 << TOV0)) || (BufferCount > (uint8_t)(sizeof(USARTtoUSB_Buffer_Data) * .75))) {
+ TIFR0 |= (1 << TOV0);
+ while (BufferCount--) {
+ if (CDC_Device_SendByte(&VirtualSerial1_CDC_Interface, RingBuffer_Peek(&USARTtoUSB_Buffer)) != ENDPOINT_READYWAIT_NoError)
+ break;
+
+ RingBuffer_Remove(&USARTtoUSB_Buffer);
+ }
+ }
+
+ if (!(RingBuffer_IsEmpty(&USBtoUSART_Buffer)))
+ Serial_SendByte(RingBuffer_Remove(&USBtoUSART_Buffer));
+}
+/* end LUFA CDC-ACM specific definitions*/
+
+
+
+FILE usb_stream;
+
+void stdio_init(void)
+{
+ CDC_Device_CreateStream(&VirtualSerial2_CDC_Interface, &usb_stream);
+ stdin = &usb_stream;
+ stdout = &usb_stream;
+ stderr = &usb_stream;
+}
+
+void nodectl_init(void)
+{
+ DDRD &= ~(1<<4);
+ PORTD |= (1<<4);
+}
+
+void reset6lowpan(void)
+{
+ DDRD |= (1<<4);
+ PORTD &= ~(1<<4);
+ _delay_ms(10);
+ PORTD |= (1<<4);
+ DDRD &= ~(1<<4);
+}
+
+void handle_cmd(uint8_t cmd)
+{
+ switch(cmd) {
+ case '0': led_off(); break;
+ case '1': led_on(); break;
+ case 't': led_toggle(); break;
+ case 'r': reset6lowpan(); break;
+ case 'b': reset2bootloader(); break;
+ default: printf("unknown command\r\n"); return;
+ }
+ printf("ok\r\n");
+}
+
+int main(void)
+{
+ MCUSR &= ~(1 << WDRF);
+ wdt_disable();
+
+ cpu_init();
+ led_init();
+ USB_Init();
+ stdio_init();
+ usbserial_init();
+ nodectl_init();
+ sei();
+
+ for(;;) {
+ int16_t BytesReceived = CDC_Device_BytesReceived(&VirtualSerial2_CDC_Interface);
+ while(BytesReceived > 0) {
+ int ReceivedByte = fgetc(stdin);
+ if(ReceivedByte != EOF) {
+ handle_cmd(ReceivedByte);
+ }
+ BytesReceived--;
+ }
+
+ usbserial_task();
+ CDC_Device_USBTask(&VirtualSerial1_CDC_Interface);
+ CDC_Device_USBTask(&VirtualSerial2_CDC_Interface);
+ USB_USBTask();
+ }
+}