summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2012-01-05 22:18:45 +0100
committerHarald Welte <laforge@gnumonks.org>2012-01-05 22:19:41 +0100
commit250c85da27eb54137378c7f215b443b29ca5ecde (patch)
tree5b667372c0f29cede3f12ae2a5e0ca1bfbbfe88c
parent620d68be79940904d93647055a6f47fa3439da96 (diff)
initial commit of at91sam3u-ek/osmo-sdr DFU experiments
-rw-r--r--usb-dfu-experiment/Makefile238
-rw-r--r--usb-dfu-experiment/dfu_desc.c115
-rw-r--r--usb-dfu-experiment/dfu_desc.h2
-rw-r--r--usb-dfu-experiment/main.c365
-rw-r--r--usb-dfu-experiment/scripts/usbstring.c202
-rw-r--r--usb-dfu-experiment/usb_strings.txt7
6 files changed, 929 insertions, 0 deletions
diff --git a/usb-dfu-experiment/Makefile b/usb-dfu-experiment/Makefile
new file mode 100644
index 0000000..e7ef099
--- /dev/null
+++ b/usb-dfu-experiment/Makefile
@@ -0,0 +1,238 @@
+# ----------------------------------------------------------------------------
+# ATMEL Microcontroller Software Support
+# ----------------------------------------------------------------------------
+# Copyright (c) 2008, Atmel Corporation
+#
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# - Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the disclaimer below.
+#
+# Atmel's name may not be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+# DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+# ----------------------------------------------------------------------------
+
+# Makefile for compiling the usb-device-core-project project
+
+#-------------------------------------------------------------------------------
+# User-modifiable options
+#-------------------------------------------------------------------------------
+
+# Chip & board used for compilation
+# (can be overriden by adding CHIP=chip and BOARD=board to the command-line)
+CHIP = at91sam3u4
+BOARD = at91sam3u-ek
+
+# Trace level used for compilation
+# (can be overriden by adding TRACE_LEVEL=#number to the command-line)
+# TRACE_LEVEL_DEBUG 5
+# TRACE_LEVEL_INFO 4
+# TRACE_LEVEL_WARNING 3
+# TRACE_LEVEL_ERROR 2
+# TRACE_LEVEL_FATAL 1
+# TRACE_LEVEL_NO_TRACE 0
+TRACE_LEVEL = 5
+
+# Optimization level, put in comment for debugging
+OPTIMIZATION = -Os
+
+# AT91 library directory
+AT91LIB = ../../at91lib
+
+# External library
+EXT_LIBS= ../external_libs
+
+# Output file basename
+OUTPUT = usb-dfu-experiment-$(BOARD)-$(CHIP)
+
+# Compile with chip specific features
+include $(AT91LIB)/boards/$(BOARD)/$(CHIP)/chip.mak
+
+# Compile for all memories available on the board (this sets $(MEMORIES))
+include $(AT91LIB)/boards/$(BOARD)/board.mak
+
+# Output directories
+BIN = bin
+OBJ = obj
+
+#-------------------------------------------------------------------------------
+# Tools
+#-------------------------------------------------------------------------------
+
+# Tool suffix when cross-compiling
+CROSS_COMPILE = arm-cm3-eabi-
+
+# Compilation tools
+CC = $(CROSS_COMPILE)gcc
+SIZE = $(CROSS_COMPILE)size
+STRIP = $(CROSS_COMPILE)strip
+OBJCOPY = $(CROSS_COMPILE)objcopy
+
+# Flags
+INCLUDES += -I$(AT91LIB)/boards/$(BOARD)
+INCLUDES += -I$(AT91LIB)/peripherals
+INCLUDES += -I$(AT91LIB)/components
+INCLUDES += -I$(AT91LIB)/drivers
+INCLUDES += -I$(AT91LIB)
+INCLUDES += -I$(EXT_LIBS)
+INCLUDES += -I$(EXT_LIBS)/cmsis
+INCLUDES += -I.
+
+ifeq ($(CHIP_CORE), cortexm3)
+TARGET_OPTS = -mcpu=cortex-m3 -mthumb
+else
+TARGET_OPTS =
+endif
+
+CFLAGS += $(TARGET_OPTS)
+CFLAGS += -Wall -mlong-calls -ffunction-sections
+CFLAGS += -g $(OPTIMIZATION) $(INCLUDES) -D$(CHIP) -DTRACE_LEVEL=$(TRACE_LEVEL)
+ASFLAGS = $(TARGET_OPTS) -Wall -g $(OPTIMIZATION) $(INCLUDES) -D$(CHIP) -D__ASSEMBLY__
+LDFLAGS = -g $(OPTIMIZATION) -nostartfiles $(TARGET_OPTS) -Wl,--gc-sections
+
+#-------------------------------------------------------------------------------
+# Files
+#-------------------------------------------------------------------------------
+
+# Directories where source files can be found
+PERIPH = $(AT91LIB)/peripherals
+BOARDS = $(AT91LIB)/boards
+UTILITY = $(AT91LIB)/utility
+COMP = $(AT91LIB)/components
+DRIVER = $(AT91LIB)/drivers
+USB = $(AT91LIB)/usb
+
+VPATH += $(UTILITY)
+VPATH += $(PERIPH)/dbgu
+VPATH += $(PERIPH)/pio
+VPATH += $(PERIPH)/irq
+VPATH += $(PERIPH)/ssc
+VPATH += $(PERIPH)/twi
+VPATH += $(PERIPH)/pmc
+VPATH += $(PERIPH)/cp15
+VPATH += $(BOARDS)/$(BOARD)
+VPATH += $(BOARDS)/$(BOARD)/$(CHIP)
+VPATH += $(DRIVER)/twi
+VPATH += $(PERIPH)/mci
+VPATH += $(PERIPH)/dma
+VPATH += $(DRIVER)/dmad
+VPATH += $(EXT_LIBS)/cmsis
+
+VPATH += $(USB)/device/core
+VPATH += $(USB)/device/dfu
+VPATH += $(USB)/common/core
+VPATH += $(USB)/common/audio
+
+# Objects built from C source files
+C_OBJECTS += main.o
+C_OBJECTS += dfu_desc.o
+C_OBJECTS += USBD_UDPHS.o
+C_OBJECTS += USBDDriver.o
+C_OBJECTS += USBDCallbacks_Initialized.o
+C_OBJECTS += USBDCallbacks_Reset.o
+#C_OBJECTS += USBDCallbacks_Resumed.o
+#C_OBJECTS += USBDCallbacks_Suspended.o
+C_OBJECTS += USBDDriverCb_CfgChanged.o
+#C_OBJECTS += USBDDriverCb_IfSettingChanged.o
+C_OBJECTS += USBInterfaceRequest.o
+C_OBJECTS += USBFeatureRequest.o
+C_OBJECTS += USBGenericRequest.o
+C_OBJECTS += USBGetDescriptorRequest.o
+C_OBJECTS += USBSetAddressRequest.o
+C_OBJECTS += USBSetConfigurationRequest.o
+C_OBJECTS += USBGenericDescriptor.o
+C_OBJECTS += USBConfigurationDescriptor.o
+C_OBJECTS += USBEndpointDescriptor.o
+C_OBJECTS += dfu_driver.o
+C_OBJECTS += dbgu.o
+C_OBJECTS += pio.o
+C_OBJECTS += pio_it.o
+C_OBJECTS += ssc.o
+C_OBJECTS += twi.o
+C_OBJECTS += pmc.o
+C_OBJECTS += led.o
+C_OBJECTS += twid.o
+C_OBJECTS += string.o
+C_OBJECTS += stdio.o
+C_OBJECTS += math.o
+C_OBJECTS += trace.o
+C_OBJECTS += board_memories.o
+C_OBJECTS += board_lowlevel.o
+
+
+# Objects for different chips
+ifeq ($(CHIP_CORE), cortexm3)
+C_OBJECTS += nvic.o
+C_OBJECTS += exceptions.o
+C_OBJECTS += board_cstartup_gnu.o
+C_OBJECTS += core_cm3.o
+else
+C_OBJECTS += aic.o
+C_OBJECTS += cp15.o
+endif
+
+ifeq ($(CHIP_IP_MCI), MCI_DMA)
+C_OBJECTS += dmad.o
+C_OBJECTS += dma.o
+C_OBJECTS += mci_hs.o
+else
+C_OBJECTS += mci.o
+endif
+
+# Objects built from Assembly source files
+ifneq ($(CHIP_CORE), cortexm3)
+ASM_OBJECTS += board_cstartup.o
+ASM_OBJECTS += cp15_asm.o
+endif
+
+# Append OBJ and BIN directories to output filename
+OUTPUT := $(BIN)/$(OUTPUT)
+
+#-------------------------------------------------------------------------------
+# Rules
+#-------------------------------------------------------------------------------
+
+all: $(BIN) $(OBJ) $(MEMORIES)
+
+$(BIN) $(OBJ):
+ mkdir $@
+
+define RULES
+C_OBJECTS_$(1) = $(addprefix $(OBJ)/$(1)_, $(C_OBJECTS))
+ASM_OBJECTS_$(1) = $(addprefix $(OBJ)/$(1)_, $(ASM_OBJECTS))
+
+$(1): $$(ASM_OBJECTS_$(1)) $$(C_OBJECTS_$(1))
+ $(CC) $(LDFLAGS) -T"$(AT91LIB)/boards/$(BOARD)/$(CHIP)/$$@.lds" -o $(OUTPUT)-$$@.elf $$^
+ $(OBJCOPY) -O binary $(OUTPUT)-$$@.elf $(OUTPUT)-$$@.bin
+ $(SIZE) $$^ $(OUTPUT)-$$@.elf
+
+$$(C_OBJECTS_$(1)): $(OBJ)/$(1)_%.o: %.c Makefile $(OBJ) $(BIN)
+ $(CC) $(CFLAGS) -D$(1) -c -o $$@ $$<
+
+$$(ASM_OBJECTS_$(1)): $(OBJ)/$(1)_%.o: %.S Makefile $(OBJ) $(BIN)
+ $(CC) $(ASFLAGS) -D$(1) -c -o $$@ $$<
+
+debug_$(1): $(1)
+ perl ../resources/gdb/debug.pl $(OUTPUT)-$(1).elf
+
+endef
+
+$(foreach MEMORY, $(MEMORIES), $(eval $(call RULES,$(MEMORY))))
+
+clean:
+ -rm -f $(OBJ)/*.o $(BIN)/*.bin $(BIN)/*.elf
+
diff --git a/usb-dfu-experiment/dfu_desc.c b/usb-dfu-experiment/dfu_desc.c
new file mode 100644
index 0000000..36f8104
--- /dev/null
+++ b/usb-dfu-experiment/dfu_desc.c
@@ -0,0 +1,115 @@
+
+#include <usb/common/core/USBGenericDescriptor.h>
+#include <usb/common/core/USBDeviceDescriptor.h>
+#include <usb/common/core/USBConfigurationDescriptor.h>
+#include <usb/common/core/USBInterfaceDescriptor.h>
+#include <usb/common/core/USBEndpointDescriptor.h>
+#include <usb/common/core/USBStringDescriptor.h>
+
+#include <usb/device/core/USBDDriverDescriptors.h>
+
+#include <usb/common/dfu/usb_dfu.h>
+#include <usb/device/dfu/dfu.h>
+
+/* for board-specific config */
+#include <board.h>
+
+struct dfu_desc {
+ USBConfigurationDescriptor ucfg;
+ USBInterfaceDescriptor uif[BOARD_DFU_NUM_IF];
+ struct usb_dfu_func_descriptor func_dfu;
+} __attribute__ ((packed));
+
+enum {
+ STR_MANUF = 1,
+ STR_PROD,
+ STR_CONFIG,
+ _STR_FIRST_ALT,
+ STR_SERIAL = (_STR_FIRST_ALT+BOARD_DFU_NUM_IF),
+};
+
+static const USBDeviceDescriptor fsDevice = {
+ .bLength = sizeof(USBDeviceDescriptor),
+ .bDescriptorType = USBGenericDescriptor_DEVICE,
+ .bcdUSB = USBDeviceDescriptor_USB2_00,
+ .bDeviceClass = 0,
+ .bDeviceSubClass = 0,
+ .bDeviceProtocol = 0,
+ .bMaxPacketSize0 = CHIP_USB_ENDPOINTS_MAXPACKETSIZE(0),
+ .idVendor = BOARD_USB_VENDOR,
+ .idProduct = BOARD_USB_PRODUCT,
+ .bcdDevice = BOARD_USB_RELEASE,
+ .iManufacturer = STR_MANUF,
+ .iProduct = STR_PROD,
+ .iSerialNumber = STR_SERIAL,
+ .bNumConfigurations = 1,
+};
+
+
+#define DFU_IF(ALT) \
+ { \
+ .bLength = sizeof(USBInterfaceDescriptor), \
+ .bDescriptorType = USBGenericDescriptor_INTERFACE, \
+ .bInterfaceNumber = 0, \
+ .bAlternateSetting = ALT, \
+ .bNumEndpoints = 0, \
+ .bInterfaceClass = 0xfe, \
+ .bInterfaceSubClass = 1, \
+ .iInterface = (_STR_FIRST_ALT+ALT), \
+ .bInterfaceProtocol = 2, \
+ }
+
+const struct dfu_desc dfu_cfg_descriptor = {
+ .ucfg = {
+ .bLength = sizeof(USBConfigurationDescriptor),
+ .bDescriptorType = USBGenericDescriptor_CONFIGURATION,
+ .wTotalLength = sizeof(USBConfigurationDescriptor) +
+ BOARD_DFU_NUM_IF * sizeof(USBInterfaceDescriptor) +
+ sizeof(struct usb_dfu_func_descriptor),
+ .bNumInterfaces = 1,
+ .bConfigurationValue = 1,
+ .iConfiguration = STR_CONFIG,
+ .bmAttributes = BOARD_USB_BMATTRIBUTES,
+ .bMaxPower = 100,
+ },
+ .uif[0] = DFU_IF(0),
+#if BOARD_DFU_NUM_IF > 1
+ .uif[1] = DFU_IF(1),
+#endif
+#if BOARD_DFU_NUM_IF > 2
+ .uif[2] = DFU_IF(2),
+#endif
+#if BOARD_DFU_NUM_IF > 3
+ .uif[3] = DFU_IF(3),
+#endif
+#if BOARD_DFU_NUM_IF > 4
+ .uif[4] = DFU_IF(4),
+#endif
+ .func_dfu = DFU_FUNC_DESC
+};
+
+#include "usb_strings.h"
+
+
+static const unsigned char *usb_strings[] = {
+ USB_STRINGS_GENERATED
+ (const unsigned char *) &string1
+};
+
+const USBDDriverDescriptors dfu_descriptors = {
+ .pFsDevice = &fsDevice,
+ .pFsConfiguration = &dfu_cfg_descriptor.ucfg,
+//#if defined (CHIP_USB_UDPHS) || defined(CHIP_USB_OTGHS)
+#if 0 // DFU only supports FS for now
+ .pFsQualifier = ,
+ .pFsOtherSpeed = ,
+ .pHsDevice = ,
+ .pHsConfiguration = ,
+ .pHsQualifier = ,
+ .pHsOtherSpeed = ,
+#else
+ 0, 0, 0, 0, 0, 0,
+#endif
+ .pStrings = usb_strings,
+ .numStrings = ARRAY_SIZE(usb_strings),
+};
diff --git a/usb-dfu-experiment/dfu_desc.h b/usb-dfu-experiment/dfu_desc.h
new file mode 100644
index 0000000..2f8de47
--- /dev/null
+++ b/usb-dfu-experiment/dfu_desc.h
@@ -0,0 +1,2 @@
+
+const USBDDriverDescriptors dfu_descriptors;
diff --git a/usb-dfu-experiment/main.c b/usb-dfu-experiment/main.c
new file mode 100644
index 0000000..4cc267e
--- /dev/null
+++ b/usb-dfu-experiment/main.c
@@ -0,0 +1,365 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2009, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ----------------------------------------------------------------------------
+ */
+/**
+ * \file
+ *
+ * This file contains all the specific code for the
+ * usb_fast_source example.
+ */
+
+/*----------------------------------------------------------------------------
+ * Headers
+ *----------------------------------------------------------------------------*/
+
+#include <board.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdbool.h>
+
+#include <irq/irq.h>
+#include <pio/pio.h>
+#include <pio/pio_it.h>
+#include <utility/trace.h>
+#include <utility/led.h>
+
+#include <usb/device/core/USBD.h>
+#include <usb/device/core/USBDDriver.h>
+#include <usb/common/core/USBStringDescriptor.h>
+#include <usb/device/dfu/dfu.h>
+
+#include "dfu_desc.h"
+
+/*----------------------------------------------------------------------------
+ * Definitions
+ *----------------------------------------------------------------------------*/
+
+#if 0
+/** Number of available audio buffers. */
+#define BUFFER_NUMBER 8
+/** Size of one buffer in bytes. */
+#define BUFFER_SIZE (AUDDLoopRecDriver_BYTESPERFRAME*2)
+#endif
+
+/// Use for power management
+#define STATE_IDLE 0
+/// The USB device is in suspend state
+#define STATE_SUSPEND 4
+/// The USB device is in resume state
+#define STATE_RESUME 5
+
+//------------------------------------------------------------------------------
+// Internal variables
+//------------------------------------------------------------------------------
+/// State of USB, for suspend and resume
+unsigned char USBState = STATE_IDLE;
+
+#if 0
+/** Data buffers for receiving audio frames from the USB host. */
+static uint8_t buffers[BUFFER_NUMBER][BUFFER_SIZE];
+/** Number of samples stored in each data buffer. */
+static uint32_t bufferSizes[BUFFER_NUMBER];
+/** Next buffer in which USB data can be stored. */
+static uint32_t inBufferIndex = 0;
+/** Number of buffers that can be sent to the DAC. */
+static volatile uint32_t numBuffersToSend = 0;
+#endif
+
+/** Current state of the playback stream interface. */
+static volatile uint8_t isPlyActive = 0;
+/** Current state of the record stream interface. */
+static volatile uint8_t isRecActive = 0;
+
+/*----------------------------------------------------------------------------
+ * VBus monitoring (optional)
+ *----------------------------------------------------------------------------*/
+
+/** VBus pin instance. */
+static const Pin pinVbus = PIN_USB_VBUS;
+
+/**
+ * Handles interrupts coming from PIO controllers.
+ */
+static void ISR_Vbus(const Pin *pPin)
+{
+ /* Check current level on VBus */
+ if (PIO_Get(&pinVbus))
+ {
+ TRACE_INFO("VBUS conn\n\r");
+ USBD_Connect();
+ }
+ else
+ {
+ TRACE_INFO("VBUS discon\n\r");
+ USBD_Disconnect();
+ }
+}
+
+/**
+ * Configures the VBus pin to trigger an interrupt when the level on that pin
+ * changes.
+ */
+static void VBus_Configure( void )
+{
+ /* Configure PIO */
+ PIO_Configure(&pinVbus, 1);
+ PIO_ConfigureIt(&pinVbus, ISR_Vbus);
+ PIO_EnableIt(&pinVbus);
+
+ /* Check current level on VBus */
+ if (PIO_Get(&pinVbus))
+ {
+ /* if VBUS present, force the connect */
+ USBD_Connect();
+ }
+ else
+ {
+ TRACE_INFO("discon\n\r");
+ USBD_Disconnect();
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * USB Power Control
+ *----------------------------------------------------------------------------*/
+
+#ifdef PIN_USB_POWER_ENA
+/** Power Enable A (MicroAB Socket) pin instance. */
+static const Pin pinPOnA = PIN_USB_POWER_ENA;
+#endif
+#ifdef PIN_USB_POWER_ENB
+/** Power Enable B (A Socket) pin instance. */
+static const Pin pinPOnB = PIN_USB_POWER_ENB;
+#endif
+#ifdef PIN_USB_POWER_ENC
+/** Power Enable C (A Socket) pin instance. */
+static const Pin pinPOnC = PIN_USB_POWER_ENC;
+#endif
+/**
+ * Configures the Power Enable pin to disable self power.
+ */
+static void USBPower_Configure( void )
+{
+ #ifdef PIN_USB_POWER_ENA
+ PIO_Configure(&pinPOnA, 1);
+ #endif
+ #ifdef PIN_USB_POWER_ENB
+ PIO_Configure(&pinPOnB, 1);
+ #endif
+ #ifdef PIN_USB_POWER_ENC
+ PIO_Configure(&pinPOnC, 1);
+ #endif
+}
+
+/*----------------------------------------------------------------------------
+ * Internal functions
+ *----------------------------------------------------------------------------*/
+
+#if 0
+/**
+ * Invoked when a frame has been received.
+ */
+static void FrameReceived(uint32_t unused,
+ uint8_t status,
+ uint32_t transferred,
+ uint32_t remaining)
+{
+ if (status == USBD_STATUS_SUCCESS)
+ {
+ /* Loopback! add this buffer to write list */
+ if (!isRecActive) {}
+ else
+ {
+ AUDDLoopRecDriver_Write(buffers[inBufferIndex],
+ AUDDLoopRecDriver_BYTESPERFRAME,
+ NULL, 0);
+ }
+
+ /* Update input status data */
+ bufferSizes[inBufferIndex] = transferred
+ / AUDDLoopRecDriver_BYTESPERSAMPLE;
+ inBufferIndex = (inBufferIndex + 1) % BUFFER_NUMBER;
+ numBuffersToSend++;
+
+ }
+ else if (status == USBD_STATUS_ABORTED)
+ {
+ /* Error , ABORT, add NULL buffer */
+ bufferSizes[inBufferIndex] = 0;
+ inBufferIndex = (inBufferIndex + 1) % BUFFER_NUMBER;
+ numBuffersToSend++;
+ }
+ else
+ {
+ /* Packet is discarded */
+ }
+
+ /* Receive next packet */
+ AUDDLoopRecDriver_Read(buffers[inBufferIndex],
+ AUDDLoopRecDriver_BYTESPERFRAME,
+ (TransferCallback) FrameReceived,
+ 0); // No optional argument
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * Callbacks re-implementation
+ *----------------------------------------------------------------------------*/
+
+//------------------------------------------------------------------------------
+/// Invoked when the USB device leaves the Suspended state. By default,
+/// configures the LEDs.
+//------------------------------------------------------------------------------
+void USBDCallbacks_Resumed(void)
+{
+ // Initialize LEDs
+ LED_Configure(USBD_LEDPOWER);
+ LED_Set(USBD_LEDPOWER);
+ LED_Configure(USBD_LEDUSB);
+ LED_Clear(USBD_LEDUSB);
+ USBState = STATE_RESUME;
+}
+
+//------------------------------------------------------------------------------
+/// Invoked when the USB device gets suspended. By default, turns off all LEDs.
+//------------------------------------------------------------------------------
+void USBDCallbacks_Suspended(void)
+{
+ // Turn off LEDs
+ LED_Clear(USBD_LEDPOWER);
+ LED_Clear(USBD_LEDUSB);
+ USBState = STATE_SUSPEND;
+}
+
+
+static int to_usb_string(char *out, int out_len, const char *in)
+{
+ int in_len = strlen(in);
+ int num_out = USBStringDescriptor_LENGTH(in_len);
+ int i;
+ char *cur = out;
+
+ if (num_out > out_len || num_out >= 255 || num_out < 0)
+ return -EINVAL;
+
+ *cur++ = num_out;
+ *cur++ = USBGenericDescriptor_STRING;
+
+ for (i = 0; i < in_len; i++) {
+ *cur++ = in[i];
+ *cur++ = 0;
+ }
+
+ return cur - out;
+}
+
+/* USBD callback */
+void USBDCallbacks_RequestReceived(const USBGenericRequest *request)
+{
+ USBDFU_DFU_RequestHandler(request);
+}
+
+/* USBD callback */
+void USBDDriverCallbacks_InterfaceSettingChanged(unsigned char interface,
+ unsigned char setting)
+{
+ TRACE_DEBUG("DFU: IfSettingChgd()\n");
+}
+
+/* DFU callback */
+int USBDFU_handle_upload(uint16_t val, uint16_t len, int first)
+{
+ TRACE_DEBUG("DFU: handle_upload()\n");
+ return 0;
+}
+
+/* DFU callback */
+int USBDFU_handle_dnload(uint16_t val, uint16_t len, int first)
+{
+ TRACE_DEBUG("DFU: handle_dnload()\n");
+ return 0;
+}
+
+/* DFU callback */
+void dfu_drv_updstatus(void)
+{
+ TRACE_DEBUG("DFU: updstatus()\n");
+}
+
+
+/*----------------------------------------------------------------------------
+ * Exported functions
+ *----------------------------------------------------------------------------*/
+
+extern void USBD_IrqHandler(void);
+
+static unsigned char altsettings[4];
+
+int main(void)
+{
+ volatile uint8_t usbConn = 0;
+
+ TRACE_CONFIGURE(DBGU_STANDARD, 115200, BOARD_MCK);
+
+ printf("-- USB DFU Test %s --\n\r", SOFTPACK_VERSION);
+ printf("-- %s\n\r", BOARD_NAME);
+ printf("-- Compiled: %s %s --\n\r", __DATE__, __TIME__);
+
+ /* If they are present, configure Vbus & Wake-up pins */
+ PIO_InitializeInterrupts(0);
+
+ /* Initialize all USB power (off) */
+ USBPower_Configure();
+
+ /* Audio STREAM LED */
+ LED_Configure(USBD_LEDOTHER);
+
+ USBDFU_Initialize(&dfu_descriptors, altsettings);
+
+ /* connect if needed */
+ VBus_Configure();
+
+ static int state = 0;
+
+ /* Infinite loop */
+ while (1)
+ {
+ if (USBD_GetState() < USBD_STATE_CONFIGURED)
+ {
+ usbConn = 0;
+ continue;
+ } else
+ usbConn = 1;
+ TRACE_DEBUG(".");
+ }
+}
+/** \endcond */
diff --git a/usb-dfu-experiment/scripts/usbstring.c b/usb-dfu-experiment/scripts/usbstring.c
new file mode 100644
index 0000000..2d5b040
--- /dev/null
+++ b/usb-dfu-experiment/scripts/usbstring.c
@@ -0,0 +1,202 @@
+/* AT91SAM7 USB string descriptor builder
+ * (C) 2006 by Harald Welte <laforge@gnumonks.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* Based on existing utf8_to_utf16le() function,
+ * Copyright (C) 2003 David Brownell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+static int utf8_to_utf16le(const char *s, u_int16_t *cp, unsigned len)
+{
+ int count = 0;
+ u_int8_t c;
+ u_int16_t uchar;
+
+ /* this insists on correct encodings, though not minimal ones.
+ * BUT it currently rejects legit 4-byte UTF-8 code points,
+ * which need surrogate pairs. (Unicode 3.1 can use them.)
+ */
+ while (len != 0 && (c = (u_int8_t) *s++) != 0) {
+ if (c & 0x80) {
+ // 2-byte sequence:
+ // 00000yyyyyxxxxxx = 110yyyyy 10xxxxxx
+ if ((c & 0xe0) == 0xc0) {
+ uchar = (c & 0x1f) << 6;
+
+ c = (u_int8_t) *s++;
+ if ((c & 0xc0) != 0xc0)
+ goto fail;
+ c &= 0x3f;
+ uchar |= c;
+
+ // 3-byte sequence (most CJKV characters):
+ // zzzzyyyyyyxxxxxx = 1110zzzz 10yyyyyy 10xxxxxx
+ } else if ((c & 0xf0) == 0xe0) {
+ uchar = (c & 0x0f) << 12;
+
+ c = (u_int8_t) *s++;
+ if ((c & 0xc0) != 0xc0)
+ goto fail;
+ c &= 0x3f;
+ uchar |= c << 6;
+
+ c = (u_int8_t) *s++;
+ if ((c & 0xc0) != 0xc0)
+ goto fail;
+ c &= 0x3f;
+ uchar |= c;
+
+ /* no bogus surrogates */
+ if (0xd800 <= uchar && uchar <= 0xdfff)
+ goto fail;
+
+ // 4-byte sequence (surrogate pairs, currently rare):
+ // 11101110wwwwzzzzyy + 110111yyyyxxxxxx
+ // = 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx
+ // (uuuuu = wwww + 1)
+ // FIXME accept the surrogate code points (only)
+
+ } else
+ goto fail;
+ } else
+ uchar = c;
+
+ *cp++ = uchar;
+ count++;
+ len--;
+ }
+ return count;
+fail:
+ return -1;
+}
+
+#define COLUMNS 6
+static int print_array16(u_int16_t *buf, int len)
+{
+ int i;
+ for (i = 0; i < len; i++) {
+ int mod = i % COLUMNS;
+ char *suffix;
+ char *prefix;
+
+ switch (mod) {
+ case 0:
+ if (i == 0)
+ prefix = "\t";
+ else
+ prefix= "\t\t\t";
+ suffix = ", ";
+ break;
+ case COLUMNS-1:
+ prefix = "";
+ suffix = ",\n";
+ break;
+ default:
+ prefix = "";
+ suffix = ", ";
+ break;
+ }
+
+ printf("%s0x%04x%s", prefix, buf[i], suffix);
+ }
+}
+
+static void print_structhdr(int i, int size)
+{
+ printf( "static const struct {\n"
+ "\tstruct usb_descriptor_header hdr;\n"
+ "\tuint16_t wData[];\n"
+ "} __attribute__((packed)) string%d = {\n"
+ "\t.hdr = {\n"
+ "\t\t.bLength = USBStringDescriptor_LENGTH(%u),\n"
+ "\t\t.bDescriptorType = USBGenericDescriptor_STRING,\n"
+ "\t},\n"
+ "\t.wData = {", i, size);
+}
+static void print_structftr(void)
+{
+ printf("},\n};\n\n");
+}
+
+int main(int argc, char **argv)
+{
+ char asciibuf[512+1];
+ u_int16_t utf16buf[1024+1];
+ int len;
+ int j, i = 1;
+
+ printf("#ifndef _USB_STRINGS_H\n#define _USB_STRINGS_H\n\n");
+ printf("/* THIS FILE IS AUTOGENERATED, DO NOT MODIFY MANUALLY */\n\n");
+
+ printf("#include <stdint.h>\n");
+ printf("#include <usb/common/core/USBGenericDescriptor.h>\n");
+
+ printf("#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))\n\n");
+
+ printf("/* All standard descriptors have these 2 fields at the beginning */\n\n");
+ printf("struct usb_descriptor_header {\n"
+ "\tuint8_t bLength;\n"
+ "\tuint8_t bDescriptorType;\n"
+ "} __attribute__ ((packed));\n\n");
+
+ print_structhdr(0, 1);
+ printf("0x0409 /* English */ ");
+ print_structftr();
+
+ while (scanf("%512[^\n]\n", asciibuf) != EOF) {
+ len = strlen(asciibuf);
+ printf("/* String %u \"%s\" */\n", i, asciibuf);
+
+ /* FIXME: check return value */
+ utf8_to_utf16le(asciibuf, utf16buf, len);
+
+ print_structhdr(i, len);
+
+ print_array16(utf16buf, len);
+
+ print_structftr();
+
+ i++;
+ }
+
+#if 0
+ printf("static const unsigned char *usb_strings[] = {\n");
+ for (j = 0; j < i; j++)
+ printf("\t(const unsigned char *) &string%d,\n", j);
+ printf("};\n\n");
+#else
+ printf("#define USB_STRINGS_GENERATED\t\t\t\t\\\n");
+ for (j = 0; j < i; j++)
+ printf("\t(const unsigned char *) &string%d,\t\t\\\n", j);
+ printf("\n");
+#endif
+
+ printf("#endif /* _USB_STRINGS_H */\n");
+
+ exit(0);
+}
diff --git a/usb-dfu-experiment/usb_strings.txt b/usb-dfu-experiment/usb_strings.txt
new file mode 100644
index 0000000..08dc2ec
--- /dev/null
+++ b/usb-dfu-experiment/usb_strings.txt
@@ -0,0 +1,7 @@
+sysmocom - systems for mobile communications GmbH
+OsmoSDR Software Defined Radio
+OsmoSDR Device Firmware Upgrade
+OsmoSDR DFU Interface - Application Partition
+OsmoSDR DFU Interface - Bootloader Partition
+OsmoSDR DFU Interface - RAM
+OsmoSDR DFU Interface - FPGA
personal git repositories of Harald Welte. Your mileage may vary