summaryrefslogtreecommitdiff
path: root/usb-dfu-experiment/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'usb-dfu-experiment/main.c')
-rw-r--r--usb-dfu-experiment/main.c365
1 files changed, 365 insertions, 0 deletions
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 */
personal git repositories of Harald Welte. Your mileage may vary