summaryrefslogtreecommitdiff
path: root/usblib/device/usbdbulk.c
diff options
context:
space:
mode:
authorYuval Adam <yuv.adm@gmail.com>2014-03-16 14:41:11 +0200
committerYuval Adam <yuv.adm@gmail.com>2014-03-16 14:41:11 +0200
commit990090a4cc9070837d31e66b58d40f0c3d038741 (patch)
treecf1b905082c364e9b223e0c5058566103138dae5 /usblib/device/usbdbulk.c
parent7f4da522479c0f00126219f0c23b804c3a93d7a6 (diff)
Add usblib and utils
Diffstat (limited to 'usblib/device/usbdbulk.c')
-rw-r--r--usblib/device/usbdbulk.c1562
1 files changed, 1562 insertions, 0 deletions
diff --git a/usblib/device/usbdbulk.c b/usblib/device/usbdbulk.c
new file mode 100644
index 0000000..1e4cf0b
--- /dev/null
+++ b/usblib/device/usbdbulk.c
@@ -0,0 +1,1562 @@
+//*****************************************************************************
+//
+// usbdbulk.c - USB bulk device class driver.
+//
+// Copyright (c) 2008-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva USB Library.
+//
+//*****************************************************************************
+
+#include <stdbool.h>
+#include <stdint.h>
+#include "inc/hw_memmap.h"
+#include "inc/hw_types.h"
+#include "driverlib/debug.h"
+#include "driverlib/rom.h"
+#include "driverlib/rom_map.h"
+#include "driverlib/usb.h"
+#include "usblib/usblib.h"
+#include "usblib/usblibpriv.h"
+#include "usblib/device/usbdevice.h"
+#include "usblib/device/usbdbulk.h"
+#include "usblib/device/usbdcomp.h"
+#include "usblib/usblibpriv.h"
+
+//*****************************************************************************
+//
+//! \addtogroup bulk_device_class_api
+//! @{
+//
+//*****************************************************************************
+
+//*****************************************************************************
+//
+// The subset of endpoint status flags that we consider to be reception
+// errors. These are passed to the client via USB_EVENT_ERROR if seen.
+//
+//*****************************************************************************
+#define USB_RX_ERROR_FLAGS (USBERR_DEV_RX_DATA_ERROR | \
+ USBERR_DEV_RX_OVERRUN | \
+ USBERR_DEV_RX_FIFO_FULL)
+
+//*****************************************************************************
+//
+// Flags that may appear in ui16DeferredOpFlags to indicate some operation that
+// has been requested but could not be processed at the time it was received.
+// Each deferred operation is defined as the bit number that should be set in
+// tBulkInstance->ui16DeferredOpFlags to indicate that the operation is
+// pending.
+//
+//*****************************************************************************
+#define BULK_DO_PACKET_RX 5
+
+//*****************************************************************************
+//
+// Endpoints to use for each of the required endpoints in the driver.'
+//
+//*****************************************************************************
+#define DATA_IN_ENDPOINT USB_EP_1
+#define DATA_OUT_ENDPOINT USB_EP_1
+
+//*****************************************************************************
+//
+// Maximum packet size for the bulk endpoints used for bulk data
+// transmission and reception and the associated FIFO sizes to set aside
+// for each endpoint.
+//
+//*****************************************************************************
+#define DATA_IN_EP_FIFO_SIZE USB_FIFO_SZ_64
+#define DATA_OUT_EP_FIFO_SIZE USB_FIFO_SZ_64
+
+#define DATA_IN_EP_MAX_SIZE USBFIFOSizeToBytes(DATA_IN_EP_FIFO_SIZE)
+#define DATA_OUT_EP_MAX_SIZE USBFIFOSizeToBytes(DATA_OUT_EP_FIFO_SIZE)
+
+//*****************************************************************************
+//
+// Device Descriptor. This is stored in RAM to allow several fields to be
+// changed at runtime based on the client's requirements.
+//
+//*****************************************************************************
+uint8_t g_pui8BulkDeviceDescriptor[] =
+{
+ 18, // Size of this structure.
+ USB_DTYPE_DEVICE, // Type of this structure.
+ USBShort(0x110), // USB version 1.1 (if we say 2.0, hosts assume
+ // high-speed - see USB 2.0 spec 9.2.6.6)
+ USB_CLASS_VEND_SPECIFIC, // USB Device Class
+ 0, // USB Device Sub-class
+ 0, // USB Device protocol
+ 64, // Maximum packet size for default pipe.
+ USBShort(0), // Vendor ID (VID).
+ USBShort(0), // Product ID (PID).
+ USBShort(0x100), // Device Version BCD.
+ 1, // Manufacturer string identifier.
+ 2, // Product string identifier.
+ 3, // Product serial number.
+ 1 // Number of configurations.
+};
+
+//*****************************************************************************
+//
+// Bulk device configuration descriptor.
+//
+// It is vital that the configuration descriptor bConfigurationValue field
+// (byte 6) is 1 for the first configuration and increments by 1 for each
+// additional configuration defined here. This relationship is assumed in the
+// device stack for simplicity even though the USB 2.0 specification imposes
+// no such restriction on the bConfigurationValue values.
+//
+// Note that this structure is deliberately located in RAM since we need to
+// be able to patch some values in it based on client requirements.
+//
+//*****************************************************************************
+uint8_t g_pui8BulkDescriptor[] =
+{
+ //
+ // Configuration descriptor header.
+ //
+ 9, // Size of the configuration descriptor.
+ USB_DTYPE_CONFIGURATION, // Type of this descriptor.
+ USBShort(32), // The total size of this full structure.
+ 1, // The number of interfaces in this
+ // configuration.
+ 1, // The unique value for this configuration.
+ 5, // The string identifier that describes this
+ // configuration.
+ USB_CONF_ATTR_SELF_PWR, // Bus Powered, Self Powered, remote wake up.
+ 250, // The maximum power in 2mA increments.
+};
+
+//*****************************************************************************
+//
+// The remainder of the configuration descriptor is stored in flash since we
+// don't need to modify anything in it at runtime.
+//
+//*****************************************************************************
+const uint8_t g_pui8BulkInterface[BULKINTERFACE_SIZE] =
+{
+ //
+ // Vendor-specific Interface Descriptor.
+ //
+ 9, // Size of the interface descriptor.
+ USB_DTYPE_INTERFACE, // Type of this descriptor.
+ 0, // The index for this interface.
+ 0, // The alternate setting for this
+ // interface.
+ 2, // The number of endpoints used by this
+ // interface.
+ USB_CLASS_VEND_SPECIFIC, // The interface class
+ 0, // The interface sub-class.
+ 0, // The interface protocol for the sub-class
+ // specified above.
+ 4, // The string index for this interface.
+
+ //
+ // Endpoint Descriptor
+ //
+ 7, // The size of the endpoint descriptor.
+ USB_DTYPE_ENDPOINT, // Descriptor type is an endpoint.
+ USB_EP_DESC_IN | USBEPToIndex(DATA_IN_ENDPOINT),
+ USB_EP_ATTR_BULK, // Endpoint is a bulk endpoint.
+ USBShort(DATA_IN_EP_MAX_SIZE), // The maximum packet size.
+ 0, // The polling interval for this endpoint.
+
+ //
+ // Endpoint Descriptor
+ //
+ 7, // The size of the endpoint descriptor.
+ USB_DTYPE_ENDPOINT, // Descriptor type is an endpoint.
+ USB_EP_DESC_OUT | USBEPToIndex(DATA_OUT_ENDPOINT),
+ USB_EP_ATTR_BULK, // Endpoint is a bulk endpoint.
+ USBShort(DATA_OUT_EP_MAX_SIZE), // The maximum packet size.
+ 0, // The polling interval for this endpoint.
+};
+
+//*****************************************************************************
+//
+// The bulk configuration descriptor is defined as two sections, one
+// containing just the 9 byte USB configuration descriptor and the other
+// containing everything else that is sent to the host along with it.
+//
+//*****************************************************************************
+const tConfigSection g_sBulkConfigSection =
+{
+ sizeof(g_pui8BulkDescriptor),
+ g_pui8BulkDescriptor
+};
+
+const tConfigSection g_sBulkInterfaceSection =
+{
+ sizeof(g_pui8BulkInterface),
+ g_pui8BulkInterface
+};
+
+//*****************************************************************************
+//
+// This array lists all the sections that must be concatenated to make a
+// single, complete bulk device configuration descriptor.
+//
+//*****************************************************************************
+const tConfigSection *g_psBulkSections[] =
+{
+ &g_sBulkConfigSection,
+ &g_sBulkInterfaceSection
+};
+
+#define NUM_BULK_SECTIONS (sizeof(g_psBulkSections) / \
+ sizeof(g_psBulkSections[0]))
+
+//*****************************************************************************
+//
+// The header for the single configuration we support. This is the root of
+// the data structure that defines all the bits and pieces that are pulled
+// together to generate the configuration descriptor.
+//
+//*****************************************************************************
+const tConfigHeader g_sBulkConfigHeader =
+{
+ NUM_BULK_SECTIONS,
+ g_psBulkSections
+};
+
+//*****************************************************************************
+//
+// Configuration Descriptor.
+//
+//*****************************************************************************
+const tConfigHeader * const g_ppBulkConfigDescriptors[] =
+{
+ &g_sBulkConfigHeader
+};
+
+//*****************************************************************************
+//
+// Forward references for device handler callbacks
+//
+//*****************************************************************************
+static void HandleConfigChange(void *pvBulkDevice, uint32_t ui32Info);
+static void HandleDisconnect(void *pvBulkDevice);
+static void HandleEndpoints(void *pvBulkDevice, uint32_t ui32Status);
+static void HandleSuspend(void *pvBulkDevice);
+static void HandleResume(void *pvBulkDevice);
+static void HandleDevice(void *pvBulkDevice, uint32_t ui32Request,
+ void *pvRequestData);
+
+//*****************************************************************************
+//
+// Device event handler callbacks.
+//
+//*****************************************************************************
+const tCustomHandlers g_sBulkHandlers =
+{
+ //
+ // GetDescriptor
+ //
+ 0,
+
+ //
+ // RequestHandler
+ //
+ 0,
+
+ //
+ // InterfaceChange
+ //
+ 0,
+
+ //
+ // ConfigChange
+ //
+ HandleConfigChange,
+
+ //
+ // DataReceived
+ //
+ 0,
+
+ //
+ // DataSentCallback
+ //
+ 0,
+
+ //
+ // ResetHandler
+ //
+ 0,
+
+ //
+ // SuspendHandler
+ //
+ HandleSuspend,
+
+ //
+ // ResumeHandler
+ //
+ HandleResume,
+
+ //
+ // DisconnectHandler
+ //
+ HandleDisconnect,
+
+ //
+ // EndpointHandler
+ //
+ HandleEndpoints,
+
+ //
+ // Device handler
+ //
+ HandleDevice
+};
+
+//*****************************************************************************
+//
+// Set or clear deferred operation flags in an "atomic" manner.
+//
+// \param pui16DeferredOp points to the flags variable which is to be modified.
+// \param ui16Bit indicates which bit number is to be set or cleared.
+// \param bSet indicates the state that the flag must be set to. If \b true,
+// the flag is set, if \b false, the flag is cleared.
+//
+// This function safely sets or clears a bit in a flag variable. The operation
+// makes use of bitbanding to ensure that the operation is atomic (no read-
+// modify-write is required).
+//
+// \return None.
+//
+//*****************************************************************************
+static void
+SetDeferredOpFlag(volatile uint16_t *pui16DeferredOp, uint16_t ui16Bit,
+ bool bSet)
+{
+ //
+ // Set the flag bit to 1 or 0 using a bitband access.
+ //
+ HWREGBITH(pui16DeferredOp, ui16Bit) = bSet ? 1 : 0;
+}
+
+//*****************************************************************************
+//
+// Receives notifications related to data received from the host.
+//
+// \param psBulkDevice is the device instance whose endpoint is to be
+// processed.
+// \param ui32Status is the USB interrupt status that caused this function to
+// be called.
+//
+// This function is called from HandleEndpoints for all interrupts signaling
+// the arrival of data on the bulk OUT endpoint (in other words, whenever the
+// host has sent us a packet of data). We inform the client that a packet
+// is available and, on return, check to see if the packet has been read. If
+// not, we schedule another notification to the client for a later time.
+//
+// \return Returns \b true on success or \b false on failure.
+//
+//*****************************************************************************
+static bool
+ProcessDataFromHost(tUSBDBulkDevice *psBulkDevice, uint32_t ui32Status)
+{
+ uint32_t ui32EPStatus;
+ uint32_t ui32Size;
+ tBulkInstance *psInst;
+
+ //
+ // Get a pointer to the bulk device instance data pointer
+ //
+ psInst = &psBulkDevice->sPrivateData;
+
+ //
+ // Get the endpoint status to see why we were called.
+ //
+ ui32EPStatus = MAP_USBEndpointStatus(USB0_BASE, psInst->ui8OUTEndpoint);
+
+ //
+ // Clear the status bits.
+ //
+ MAP_USBDevEndpointStatusClear(USB0_BASE, psInst->ui8OUTEndpoint,
+ ui32EPStatus);
+
+ //
+ // Has a packet been received?
+ //
+ if(ui32EPStatus & USB_DEV_RX_PKT_RDY)
+ {
+ //
+ // Set the flag we use to indicate that a packet read is pending. This
+ // will be cleared if the packet is read. If the client does not read
+ // the packet in the context of the USB_EVENT_RX_AVAILABLE callback,
+ // the event will be signaled later during tick processing.
+ //
+ SetDeferredOpFlag(&psInst->ui16DeferredOpFlags, BULK_DO_PACKET_RX,
+ true);
+
+ //
+ // How big is the packet we have just received?
+ //
+ ui32Size = MAP_USBEndpointDataAvail(psInst->ui32USBBase,
+ psInst->ui8OUTEndpoint);
+
+ //
+ // The receive channel is not blocked so let the caller know
+ // that a packet is waiting. The parameters are set to indicate
+ // that the packet has not been read from the hardware FIFO yet.
+ //
+ psBulkDevice->pfnRxCallback(psBulkDevice->pvRxCBData,
+ USB_EVENT_RX_AVAILABLE,
+ ui32Size, (void *)0);
+ }
+ else
+ {
+ //
+ // No packet was received. Some error must have been reported. Check
+ // and pass this on to the client if necessary.
+ //
+ if(ui32EPStatus & USB_RX_ERROR_FLAGS)
+ {
+ //
+ // This is an error we report to the client so allow the callback
+ // to handle it.
+ //
+ psBulkDevice->pfnRxCallback(psBulkDevice->pvRxCBData,
+ USB_EVENT_ERROR,
+ (ui32EPStatus & USB_RX_ERROR_FLAGS),
+ (void *)0);
+ }
+ return(false);
+ }
+
+ return(true);
+}
+
+//*****************************************************************************
+//
+// Receives notifications related to data sent to the host.
+//
+// \param psBulkDevice is the device instance whose endpoint is to be
+// processed.
+// \param ui32Status is the USB interrupt status that caused this function to
+// be called.
+//
+// This function is called from HandleEndpoints for all interrupts originating
+// from the bulk IN endpoint (in other words, whenever data has been
+// transmitted to the USB host). We examine the cause of the interrupt and,
+// if due to completion of a transmission, notify the client.
+//
+// \return Returns \b true on success or \b false on failure.
+//
+//*****************************************************************************
+static bool
+ProcessDataToHost(tUSBDBulkDevice *psBulkDevice, uint32_t ui32Status)
+{
+ tBulkInstance *psInst;
+ uint32_t ui32EPStatus, ui32Size;
+
+ //
+ // Get a pointer to the bulk device instance data pointer
+ //
+ psInst = &psBulkDevice->sPrivateData;
+
+ //
+ // Get the endpoint status to see why we were called.
+ //
+ ui32EPStatus = MAP_USBEndpointStatus(psInst->ui32USBBase,
+ psInst->ui8INEndpoint);
+
+ //
+ // Clear the status bits.
+ //
+ MAP_USBDevEndpointStatusClear(psInst->ui32USBBase, psInst->ui8INEndpoint,
+ ui32EPStatus);
+
+ //
+ // Our last transmission completed. Clear our state back to idle and
+ // see if we need to send any more data.
+ //
+ psInst->iBulkTxState = eBulkStateIdle;
+
+ //
+ // Notify the client that the last transmission completed.
+ //
+ ui32Size = psInst->ui16LastTxSize;
+ psInst->ui16LastTxSize = 0;
+ psBulkDevice->pfnTxCallback(psBulkDevice->pvTxCBData,
+ USB_EVENT_TX_COMPLETE, ui32Size, (void *)0);
+
+ return(true);
+}
+
+//*****************************************************************************
+//
+// Called by the USB stack for any activity involving one of our endpoints
+// other than EP0. This function is a fan out that merely directs the call to
+// the correct handler depending upon the endpoint and transaction direction
+// signaled in ui32Status.
+//
+//*****************************************************************************
+static void
+HandleEndpoints(void *pvBulkDevice, uint32_t ui32Status)
+{
+ tUSBDBulkDevice *psBulkDevice;
+ tBulkInstance *psInst;
+
+ ASSERT(pvBulkDevice != 0);
+
+ //
+ // The bulk device structure pointer.
+ //
+ psBulkDevice = (tUSBDBulkDevice *)pvBulkDevice;
+
+ //
+ // Get a pointer to the bulk device instance data pointer
+ //
+ psInst = &psBulkDevice->sPrivateData;
+
+ //
+ // Handler for the bulk OUT data endpoint.
+ //
+ if(ui32Status & (0x10000 << USBEPToIndex(psInst->ui8OUTEndpoint)))
+ {
+ //
+ // Data is being sent to us from the host.
+ //
+ ProcessDataFromHost(psBulkDevice, ui32Status);
+ }
+
+ //
+ // Handler for the bulk IN data endpoint.
+ //
+ if(ui32Status & (1 << USBEPToIndex(psInst->ui8INEndpoint)))
+ {
+ ProcessDataToHost(psBulkDevice, ui32Status);
+ }
+}
+
+//*****************************************************************************
+//
+// Called by the USB stack whenever a configuration change occurs.
+//
+//*****************************************************************************
+static void
+HandleConfigChange(void *pvBulkDevice, uint32_t ui32Info)
+{
+ tBulkInstance *psInst;
+ tUSBDBulkDevice *psBulkDevice;
+
+ ASSERT(pvBulkDevice != 0);
+
+ //
+ // The bulk device structure pointer.
+ //
+ psBulkDevice = (tUSBDBulkDevice *)pvBulkDevice;
+
+ //
+ // Get a pointer to the bulk device instance data pointer
+ //
+ psInst = &psBulkDevice->sPrivateData;
+
+ //
+ // Set all our endpoints to idle state.
+ //
+ psInst->iBulkRxState = eBulkStateIdle;
+ psInst->iBulkTxState = eBulkStateIdle;
+
+ //
+ // If we have a control callback, let the client know we are open for
+ // business.
+ //
+ if(psBulkDevice->pfnRxCallback)
+ {
+ //
+ // Pass the connected event to the client.
+ //
+ psBulkDevice->pfnRxCallback(psBulkDevice->pvRxCBData,
+ USB_EVENT_CONNECTED, 0, (void *)0);
+ }
+
+ //
+ // Remember that we are connected.
+ //
+ psInst->bConnected = true;
+}
+
+//*****************************************************************************
+//
+// Device instance specific handler.
+//
+//*****************************************************************************
+static void
+HandleDevice(void *pvBulkDevice, uint32_t ui32Request, void *pvRequestData)
+{
+ tBulkInstance *psInst;
+ uint8_t *pui8Data;
+ tUSBDBulkDevice *psBulkDevice;
+
+ //
+ // The bulk device structure pointer.
+ //
+ psBulkDevice = (tUSBDBulkDevice *)pvBulkDevice;
+
+ //
+ // Get a pointer to the bulk device instance data pointer
+ //
+ psInst = &psBulkDevice->sPrivateData;
+
+ //
+ // Create the 8-bit array used by the events supported by the USB Bulk
+ // class.
+ //
+ pui8Data = (uint8_t *)pvRequestData;
+
+ switch(ui32Request)
+ {
+ //
+ // This was an interface change event.
+ //
+ case USB_EVENT_COMP_IFACE_CHANGE:
+ {
+ psInst->ui8Interface = pui8Data[1];
+ break;
+ }
+
+ //
+ // This was an endpoint change event.
+ //
+ case USB_EVENT_COMP_EP_CHANGE:
+ {
+ //
+ // Determine if this is an IN or OUT endpoint that has changed.
+ //
+ if(pui8Data[0] & USB_EP_DESC_IN)
+ {
+ psInst->ui8INEndpoint = IndexToUSBEP((pui8Data[1] & 0x7f));
+ }
+ else
+ {
+ //
+ // Extract the new endpoint number.
+ //
+ psInst->ui8OUTEndpoint = IndexToUSBEP(pui8Data[1] & 0x7f);
+ }
+ break;
+ }
+ case USB_EVENT_LPM_RESUME:
+ {
+ if(psBulkDevice->pfnRxCallback)
+ {
+ //
+ // Pass the LPM resume event to the client.
+ //
+ psBulkDevice->pfnRxCallback(psBulkDevice->pvRxCBData,
+ USB_EVENT_LPM_RESUME, 0,
+ (void *)0);
+ }
+ break;
+ }
+ case USB_EVENT_LPM_SLEEP:
+ {
+ if(psBulkDevice->pfnRxCallback)
+ {
+ //
+ // Pass the LPM sleep event to the client.
+ //
+ psBulkDevice->pfnRxCallback(psBulkDevice->pvRxCBData,
+ USB_EVENT_LPM_SLEEP, 0, (void *)0);
+ }
+ break;
+ }
+ case USB_EVENT_LPM_ERROR:
+ {
+ if(psBulkDevice->pfnRxCallback)
+ {
+ //
+ // Pass the LPM error event to the client.
+ //
+ psBulkDevice->pfnRxCallback(psBulkDevice->pvRxCBData,
+ USB_EVENT_LPM_ERROR, 0, (void *)0);
+ }
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+}
+
+//*****************************************************************************
+//
+// This function is called by the USB device stack whenever the device is
+// disconnected from the host.
+//
+//*****************************************************************************
+static void
+HandleDisconnect(void *pvBulkDevice)
+{
+ tUSBDBulkDevice *psBulkDevice;
+ tBulkInstance *psInst;
+
+ ASSERT(pvBulkDevice != 0);
+
+ //
+ // The bulk device structure pointer.
+ //
+ psBulkDevice = (tUSBDBulkDevice *)pvBulkDevice;
+
+ //
+ // Get a pointer to the bulk device instance data pointer
+ //
+ psInst = &psBulkDevice->sPrivateData;
+
+ //
+ // If we are not currently connected so let the client know we are open
+ // for business.
+ //
+ if(psInst->bConnected)
+ {
+ //
+ // Pass the disconnected event to the client.
+ //
+ psBulkDevice->pfnRxCallback(psBulkDevice->pvRxCBData,
+ USB_EVENT_DISCONNECTED, 0, (void *)0);
+ }
+
+ //
+ // Remember that we are no longer connected.
+ //
+ psInst->bConnected = false;
+}
+
+//*****************************************************************************
+//
+// This function is called by the USB device stack whenever the bus is put into
+// suspend state.
+//
+//*****************************************************************************
+static void
+HandleSuspend(void *pvBulkDevice)
+{
+ const tUSBDBulkDevice *psBulkDevice;
+
+ ASSERT(pvBulkDevice != 0);
+
+ //
+ // The bulk device structure pointer.
+ //
+ psBulkDevice = (const tUSBDBulkDevice *)pvBulkDevice;
+
+ //
+ // Pass the event on to the client.
+ //
+ psBulkDevice->pfnRxCallback(psBulkDevice->pvRxCBData, USB_EVENT_SUSPEND, 0,
+ (void *)0);
+}
+
+//*****************************************************************************
+//
+// This function is called by the USB device stack whenever the bus is taken
+// out of suspend state.
+//
+//*****************************************************************************
+static void
+HandleResume(void *pvBulkDevice)
+{
+ const tUSBDBulkDevice *psBulkDevice;
+
+ ASSERT(pvBulkDevice != 0);
+
+ //
+ // The bulk device structure pointer.
+ //
+ psBulkDevice = (const tUSBDBulkDevice *)pvBulkDevice;
+
+ //
+ // Pass the event on to the client.
+ //
+ psBulkDevice->pfnRxCallback(psBulkDevice->pvRxCBData, USB_EVENT_RESUME, 0,
+ (void *)0);
+}
+
+//*****************************************************************************
+//
+// This function is called periodically and provides us with a time reference
+// and method of implementing delayed or time-dependent operations.
+//
+// \param ui32Index is the index of the USB controller for which this tick
+// is being generated.
+// \param ui32TimemS is the elapsed time in milliseconds since the last call
+// to this function.
+//
+// \return None.
+//
+//*****************************************************************************
+static void
+BulkTickHandler(void *pvBulkDevice, uint32_t ui32TimemS)
+{
+ tBulkInstance *psInst;
+ uint32_t ui32Size;
+ tUSBDBulkDevice *psBulkDevice;
+
+ ASSERT(pvBulkDevice != 0);
+
+ //
+ // The bulk device structure pointer.
+ //
+ psBulkDevice = (tUSBDBulkDevice *)pvBulkDevice;
+
+ //
+ // Get a pointer to the bulk device instance data pointer
+ //
+ psInst = &psBulkDevice->sPrivateData;
+
+ //
+ // Do we have a deferred receive waiting
+ //
+ if(psInst->ui16DeferredOpFlags & (1 << BULK_DO_PACKET_RX))
+ {
+ //
+ // Yes - how big is the waiting packet?
+ //
+ ui32Size = MAP_USBEndpointDataAvail(psInst->ui32USBBase,
+ psInst->ui8OUTEndpoint);
+
+ //
+ // Tell the client that there is a packet waiting for it.
+ //
+ psBulkDevice->pfnRxCallback(psBulkDevice->pvRxCBData,
+ USB_EVENT_RX_AVAILABLE, ui32Size,
+ (void *)0);
+ }
+
+ return;
+}
+
+//*****************************************************************************
+//
+//! Initializes bulk device operation for a given USB controller.
+//!
+//! \param ui32Index is the index of the USB controller which is to be
+//! initialized for bulk device operation.
+//! \param psBulkDevice points to a structure containing parameters customizing
+//! the operation of the bulk device.
+//!
+//! An application wishing to make use of a USB bulk communication channel
+//! must call this function to initialize the USB controller and attach the
+//! device to the USB bus. This function performs all required USB
+//! initialization.
+//!
+//! On successful completion, this function will return the \e psBulkDevice
+//! pointer passed to it. This must be passed on all future calls to the
+//! device driver related to this device.
+//!
+//! The USBDBulk interface offers packet-based transmit and receive operation.
+//! If the application would rather use block based communication with
+//! transmit and receive buffers, USB buffers may be used above the bulk
+//! transmit and receive channels to offer this functionality.
+//!
+//! Transmit Operation:
+//!
+//! Calls to USBDBulkPacketWrite() must send no more than 64 bytes of data at a
+//! time and may only be made when no other transmission is currently
+//! outstanding.
+//!
+//! Once a packet of data has been acknowledged by the USB host, a
+//! \b USB_EVENT_TX_COMPLETE event is sent to the application callback to
+//! inform it that another packet may be transmitted.
+//!
+//! Receive Operation:
+//!
+//! An incoming USB data packet will result in a call to the application
+//! callback with event \b USBD_EVENT_RX_AVAILABLE. The application must then
+//! call USBDBulkPacketRead(), passing a buffer capable of holding 64 bytes, to
+//! retrieve the data and acknowledge reception to the USB host.
+//!
+//! \note The application must not make any calls to the low level USB Device
+//! API if interacting with USB via the USB bulk device class API. Doing so
+//! will cause unpredictable (though almost certainly unpleasant) behavior.
+//!
+//! \return Returns NULL on failure or void pointer that should be used with
+//! the remaining USB bulk class APSs.
+//
+//*****************************************************************************
+void *
+USBDBulkInit(uint32_t ui32Index, tUSBDBulkDevice *psBulkDevice)
+{
+ void *pvBulkDevice;
+ tDeviceDescriptor *psDevDesc;
+ tConfigDescriptor *psConfigDesc;
+
+ //
+ // Check parameter validity.
+ //
+ ASSERT(ui32Index == 0);
+ ASSERT(psBulkDevice);
+
+ pvBulkDevice = USBDBulkCompositeInit(ui32Index, psBulkDevice, 0);
+
+ if(pvBulkDevice)
+ {
+ //
+ // Fix up the device descriptor with the client-supplied values.
+ //
+ psDevDesc = (tDeviceDescriptor *)g_pui8BulkDeviceDescriptor;
+ psDevDesc->idVendor = psBulkDevice->ui16VID;
+ psDevDesc->idProduct = psBulkDevice->ui16PID;
+
+ //
+ // Fix up the configuration descriptor with client-supplied values.
+ //
+ psConfigDesc = (tConfigDescriptor *)g_pui8BulkDescriptor;
+ psConfigDesc->bmAttributes = psBulkDevice->ui8PwrAttributes;
+ psConfigDesc->bMaxPower = (uint8_t)(psBulkDevice->ui16MaxPowermA / 2);
+
+ //
+ // All is well so now pass the descriptors to the lower layer and put
+ // the bulk device on the bus.
+ //
+ USBDCDInit(ui32Index, &psBulkDevice->sPrivateData.sDevInfo,
+ (void *)psBulkDevice);
+ }
+
+ //
+ // Return the pointer to the instance indicating that everything went well.
+ //
+ return(pvBulkDevice);
+}
+
+//*****************************************************************************
+//
+//! Initializes bulk device operation for a given USB controller.
+//!
+//! \param ui32Index is the index of the USB controller which is to be
+//! initialized for bulk device operation.
+//! \param psBulkDevice points to a structure containing parameters customizing
+//! the operation of the bulk device.
+//! \param psCompEntry is the composite device entry to initialize when
+//! creating a composite device.
+//!
+//! This call is very similar to USBDBulkInit() except that it is used for
+//! initializing an instance of the bulk device for use in a composite device.
+//! When this bulk device is part of a composite device, then the
+//! \e psCompEntry should point to the composite device entry to initialize.
+//! This is part of the array that is passed to the USBDCompositeInit()
+//! function.
+//!
+//! \return Returns zero on failure or a non-zero value that should be
+//! used with the remaining USB Bulk APIs.
+//
+//*****************************************************************************
+void *
+USBDBulkCompositeInit(uint32_t ui32Index, tUSBDBulkDevice *psBulkDevice,
+ tCompositeEntry *psCompEntry)
+{
+ tBulkInstance *psInst;
+
+ //
+ // Check parameter validity.
+ //
+ ASSERT(ui32Index == 0);
+ ASSERT(psBulkDevice);
+ ASSERT(psBulkDevice->ppui8StringDescriptors);
+ ASSERT(psBulkDevice->pfnRxCallback);
+ ASSERT(psBulkDevice->pfnTxCallback);
+
+ //
+ // Initialize the workspace in the passed instance structure.
+ //
+ psInst = &psBulkDevice->sPrivateData;
+
+ //
+ // Initialize the composite entry that is used by the composite device
+ // class.
+ //
+ if(psCompEntry != 0)
+ {
+ psCompEntry->psDevInfo = &psInst->sDevInfo;
+ psCompEntry->pvInstance = (void *)psBulkDevice;
+ }
+
+ //
+ // Initialize the device information structure.
+ //
+ psInst->sDevInfo.psCallbacks = &g_sBulkHandlers;
+ psInst->sDevInfo.pui8DeviceDescriptor = g_pui8BulkDeviceDescriptor;
+ psInst->sDevInfo.ppsConfigDescriptors = g_ppBulkConfigDescriptors;
+ psInst->sDevInfo.ppui8StringDescriptors = 0;
+ psInst->sDevInfo.ui32NumStringDescriptors = 0;
+
+ //
+ // Set the basic state information for the class.
+ //
+ psInst->ui32USBBase = USB0_BASE;
+ psInst->iBulkRxState = eBulkStateUnconfigured;
+ psInst->iBulkTxState = eBulkStateUnconfigured;
+ psInst->ui16DeferredOpFlags = 0;
+ psInst->bConnected = false;
+
+ //
+ // Initialize the device info structure for the Bulk device.
+ //
+ USBDCDDeviceInfoInit(0, &psInst->sDevInfo);
+
+ //
+ // Set the default endpoint and interface assignments.
+ //
+ psInst->ui8INEndpoint = DATA_IN_ENDPOINT;
+ psInst->ui8OUTEndpoint = DATA_OUT_ENDPOINT;
+ psInst->ui8Interface = 0;
+
+ //
+ // Plug in the client's string stable to the device information
+ // structure.
+ //
+ psInst->sDevInfo.ppui8StringDescriptors =
+ psBulkDevice->ppui8StringDescriptors;
+ psInst->sDevInfo.ui32NumStringDescriptors =
+ psBulkDevice->ui32NumStringDescriptors;
+
+ //
+ // Initialize the USB tick module, this will prevent it from being
+ // initialized later in the call to USBDCDInit();
+ //
+ InternalUSBTickInit();
+
+ //
+ // Register our tick handler (this must be done after USBDCDInit).
+ //
+ InternalUSBRegisterTickHandler(BulkTickHandler, (void *)psBulkDevice);
+
+ //
+ // Return the pointer to the instance indicating that everything went well.
+ //
+ return((void *)psBulkDevice);
+}
+
+//*****************************************************************************
+//
+//! Shut down the bulk device.
+//!
+//! \param pvBulkDevice is the pointer to the device instance structure as
+//! returned by USBDBulkInit().
+//!
+//! This function terminates device operation for the instance supplied and
+//! removes the device from the USB bus. This function should not be called
+//! if the bulk device is part of a composite device and instead the
+//! USBDCompositeTerm() function should be called for the full composite
+//! device.
+//!
+//! Following this call, the \e pvBulkDevice instance should not me used in any
+//! other calls.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+USBDBulkTerm(void *pvBulkDevice)
+{
+ tBulkInstance *psInst;
+
+ ASSERT(pvBulkDevice);
+
+ //
+ // Get a pointer to the bulk device instance data pointer
+ //
+ psInst = &((tUSBDBulkDevice *)pvBulkDevice)->sPrivateData;
+
+ //
+ // Terminate the requested instance.
+ //
+ USBDCDTerm(USBBaseToIndex(psInst->ui32USBBase));
+
+ psInst->ui32USBBase = 0;
+
+ return;
+}
+
+//*****************************************************************************
+//
+//! Sets the client-specific pointer parameter for the receive channel
+//! callback.
+//!
+//! \param pvBulkDevice is the pointer to the device instance structure as
+//! returned by USBDBulkInit().
+//! \param pvCBData is the pointer that client wishes to be provided on each
+//! event sent to the receive channel callback function.
+//!
+//! The client uses this function to change the callback pointer passed in
+//! the first parameter on all callbacks to the \e pfnRxCallback function
+//! passed on USBDBulkInit().
+//!
+//! If a client wants to make runtime changes in the callback pointer, it must
+//! ensure that the \e pvBulkDevice structure passed to USBDBulkInit() resides
+//! in RAM. If this structure is in flash, callback pointer changes are not
+//! possible.
+//!
+//! \return Returns the previous callback pointer that was being used for
+//! this instance's receive callback.
+//
+//*****************************************************************************
+void *
+USBDBulkSetRxCBData(void *pvBulkDevice, void *pvCBData)
+{
+ void *pvOldValue;
+
+ ASSERT(pvBulkDevice);
+
+ //
+ // Set the callback data for the receive channel after remembering the
+ // previous value.
+ //
+ pvOldValue = ((tUSBDBulkDevice *)pvBulkDevice)->pvRxCBData;
+ ((tUSBDBulkDevice *)pvBulkDevice)->pvRxCBData = pvCBData;
+
+ //
+ // Return the previous callback pointer.
+ //
+ return(pvOldValue);
+}
+
+//*****************************************************************************
+//
+//! Sets the client-specific pointer parameter for the transmit callback.
+//!
+//! \param pvBulkDevice is the pointer to the device instance structure as
+//! returned by USBDBulkInit().
+//! \param pvCBData is the pointer that client wishes to be provided on each
+//! event sent to the transmit channel callback function.
+//!
+//! The client uses this function to change the callback pointer passed in
+//! the first parameter on all callbacks to the \e pfnTxCallback function
+//! passed on USBDBulkInit().
+//!
+//! If a client wants to make runtime changes in the callback pointer, it must
+//! ensure that the \e pvBulkDevice structure passed to USBDBulkInit() resides
+//! in RAM. If this structure is in flash, callback pointer changes are not
+//! possible.
+//!
+//! \return Returns the previous callback pointer that was being used for
+//! this instance's transmit callback.
+//
+//*****************************************************************************
+void *
+USBDBulkSetTxCBData(void *pvBulkDevice, void *pvCBData)
+{
+ void *pvOldValue;
+
+ ASSERT(pvBulkDevice);
+
+ //
+ // Set the callback pointer for the transmit channel after remembering the
+ // previous value.
+ //
+ pvOldValue = ((tUSBDBulkDevice *)pvBulkDevice)->pvTxCBData;
+ ((tUSBDBulkDevice *)pvBulkDevice)->pvTxCBData = pvCBData;
+
+ //
+ // Return the previous callback pointer value.
+ //
+ return(pvOldValue);
+}
+
+//*****************************************************************************
+//
+//! Transmits a packet of data to the USB host via the bulk data interface.
+//!
+//! \param pvBulkDevice is the pointer to the device instance structure as
+//! returned by USBDBulkInit().
+//! \param pi8Data points to the first byte of data which is to be transmitted.
+//! \param ui32Length is the number of bytes of data to transmit.
+//! \param bLast indicates whether more data is to be written before a packet
+//! should be scheduled for transmission. If \b true, the client will make
+//! a further call to this function. If \b false, no further call will be
+//! made and the driver should schedule transmission of a short packet.
+//!
+//! This function schedules the supplied data for transmission to the USB
+//! host in a single USB packet. If no transmission is currently ongoing,
+//! the data is immediately copied to the relevant USB endpoint FIFO for
+//! transmission. Whenever a USB packet is acknowledged by the host, a
+//! \b USB_EVENT_TX_COMPLETE event will be sent to the transmit channel
+//! callback indicating that more data can now be transmitted.
+//!
+//! The maximum value for \e ui32Length is 64 bytes (the maximum USB packet
+//! size for the bulk endpoints in use by the device). Attempts to send more
+//! data than this will result in a return code of 0 indicating that the data
+//! cannot be sent.
+//!
+//! The \e bLast parameter allows a client to make multiple calls to this
+//! function before scheduling transmission of the packet to the host. This
+//! can be helpful if, for example, constructing a packet on the fly or
+//! writing a packet which spans the wrap point in a ring buffer.
+//!
+//! \return Returns the number of bytes actually sent. At this level, this
+//! will either be the number of bytes passed (if less than or equal to the
+//! maximum packet size for the USB endpoint in use and no outstanding
+//! transmission ongoing) or 0 to indicate a failure.
+//
+//*****************************************************************************
+uint32_t
+USBDBulkPacketWrite(void *pvBulkDevice, uint8_t *pi8Data, uint32_t ui32Length,
+ bool bLast)
+{
+ tBulkInstance *psInst;
+ int32_t i32Retcode;
+
+ ASSERT(pvBulkDevice);
+
+ //
+ // Get a pointer to the bulk device instance data pointer
+ //
+ psInst = &((tUSBDBulkDevice *)pvBulkDevice)->sPrivateData;
+
+ //
+ // Can we send the data provided?
+ //
+ if((ui32Length > DATA_IN_EP_MAX_SIZE) ||
+ (psInst->iBulkTxState != eBulkStateIdle))
+ {
+ //
+ // Either the packet was too big or we are in the middle of sending
+ // another packet. Return 0 to indicate that we can't send this data.
+ //
+ return(0);
+ }
+
+ //
+ // Copy the data into the USB endpoint FIFO.
+ //
+ i32Retcode = MAP_USBEndpointDataPut(psInst->ui32USBBase,
+ psInst->ui8INEndpoint,
+ pi8Data, ui32Length);
+
+ //
+ // Did we copy the data successfully?
+ //
+ if(i32Retcode != -1)
+ {
+ //
+ // Remember how many bytes we sent.
+ //
+ psInst->ui16LastTxSize += (uint16_t)ui32Length;
+
+ //
+ // If this is the last call for this packet, schedule transmission.
+ //
+ if(bLast)
+ {
+ //
+ // Send the packet to the host if we have received all the data we
+ // can expect for this packet.
+ //
+ psInst->iBulkTxState = eBulkStateWaitData;
+ i32Retcode = MAP_USBEndpointDataSend(psInst->ui32USBBase,
+ psInst->ui8INEndpoint,
+ USB_TRANS_IN);
+ }
+ }
+
+ //
+ // Did an error occur while trying to send the data?
+ //
+ if(i32Retcode != -1)
+ {
+ //
+ // No - tell the caller we sent all the bytes provided.
+ //
+ return(ui32Length);
+ }
+ else
+ {
+ //
+ // Yes - tell the caller we could not send the data.
+ //
+ return(0);
+ }
+}
+
+//*****************************************************************************
+//
+//! Reads a packet of data received from the USB host via the bulk data
+//! interface.
+//!
+//! \param pvBulkDevice is the pointer to the device instance structure as
+//! returned by USBDBulkInit().
+//! \param pi8Data points to a buffer into which the received data will be
+//! written.
+//! \param ui32Length is the size of the buffer pointed to by pi8Data.
+//! \param bLast indicates whether the client will make a further call to
+//! read additional data from the packet.
+//!
+//! This function reads up to \e ui32Length bytes of data received from the USB
+//! host into the supplied application buffer. If the driver detects that the
+//! entire packet has been read, it is acknowledged to the host.
+//!
+//! The \e bLast parameter is ignored in this implementation since the end of
+//! a packet can be determined without relying upon the client to provide
+//! this information.
+//!
+//! \return Returns the number of bytes of data read.
+//
+//*****************************************************************************
+uint32_t
+USBDBulkPacketRead(void *pvBulkDevice, uint8_t *pi8Data, uint32_t ui32Length,
+ bool bLast)
+{
+ uint32_t ui32EPStatus, ui32Count, ui32Pkt;
+ tBulkInstance *psInst;
+ int32_t i32Retcode;
+
+ ASSERT(pvBulkDevice);
+
+ //
+ // Get our instance data pointer
+ //
+ psInst = &((tUSBDBulkDevice *)pvBulkDevice)->sPrivateData;
+
+ //
+ // Does the relevant endpoint FIFO have a packet waiting for us?
+ //
+ ui32EPStatus = MAP_USBEndpointStatus(psInst->ui32USBBase,
+ psInst->ui8OUTEndpoint);
+
+ if(ui32EPStatus & USB_DEV_RX_PKT_RDY)
+ {
+ //
+ // How many bytes are available for us to receive?
+ //
+ ui32Pkt = MAP_USBEndpointDataAvail(psInst->ui32USBBase,
+ psInst->ui8OUTEndpoint);
+
+ //
+ // Get as much data as we can.
+ //
+ ui32Count = ui32Length;
+ i32Retcode = MAP_USBEndpointDataGet(psInst->ui32USBBase,
+ psInst->ui8OUTEndpoint,
+ pi8Data, &ui32Count);
+
+ //
+ // Did we read the last of the packet data?
+ //
+ if(ui32Count == ui32Pkt)
+ {
+ //
+ // Clear the endpoint status so that we know no packet is
+ // waiting.
+ //
+ MAP_USBDevEndpointStatusClear(psInst->ui32USBBase,
+ psInst->ui8OUTEndpoint,
+ ui32EPStatus);
+
+ //
+ // Acknowledge the data, thus freeing the host to send the
+ // next packet.
+ //
+ MAP_USBDevEndpointDataAck(psInst->ui32USBBase,
+ psInst->ui8OUTEndpoint, true);
+
+ //
+ // Clear the flag we set to indicate that a packet read is
+ // pending.
+ //
+ SetDeferredOpFlag(&psInst->ui16DeferredOpFlags, BULK_DO_PACKET_RX,
+ false);
+ }
+
+ //
+ // If all went well, tell the caller how many bytes they got.
+ //
+ if(i32Retcode != -1)
+ {
+ return(ui32Count);
+ }
+ }
+
+ //
+ // No packet was available or an error occurred while reading so tell
+ // the caller no bytes were returned.
+ //
+ return(0);
+}
+
+//*****************************************************************************
+//
+//! Returns the number of free bytes in the transmit buffer.
+//!
+//! \param pvBulkDevice is the pointer to the device instance structure as
+//! returned by USBDBulkInit().
+//!
+//! This function returns the maximum number of bytes that can be passed on a
+//! call to USBDBulkPacketWrite() and accepted for transmission. The value
+//! returned will be the maximum USB packet size (64) if no transmission is
+//! currently outstanding or 0 if a transmission is in progress.
+//!
+//! \return Returns the number of bytes available in the transmit buffer.
+//
+//*****************************************************************************
+uint32_t
+USBDBulkTxPacketAvailable(void *pvBulkDevice)
+{
+ tBulkInstance *psInst;
+
+ ASSERT(pvBulkDevice);
+
+ //
+ // Get our instance data pointer.
+ //
+ psInst = &((tUSBDBulkDevice *)pvBulkDevice)->sPrivateData;
+
+ //
+ // Do we have a packet transmission currently ongoing?
+ //
+ if(psInst->iBulkTxState != eBulkStateIdle)
+ {
+ //
+ // We are not ready to receive a new packet so return 0.
+ //
+ return(0);
+ }
+ else
+ {
+ //
+ // We can receive a packet so return the max packet size for the
+ // relevant endpoint.
+ //
+ return(DATA_IN_EP_MAX_SIZE);
+ }
+}
+
+//*****************************************************************************
+//
+//! Determines whether a packet is available and, if so, the size of the
+//! buffer required to read it.
+//!
+//! \param pvBulkDevice is the pointer to the device instance structure as
+//! returned by USBDBulkInit().
+//!
+//! This function may be used to determine if a received packet remains to be
+//! read and allows the application to determine the buffer size needed to
+//! read the data.
+//!
+//! \return Returns 0 if no received packet remains unprocessed or the
+//! size of the packet if a packet is waiting to be read.
+//
+//*****************************************************************************
+uint32_t
+USBDBulkRxPacketAvailable(void *pvBulkDevice)
+{
+ uint32_t ui32EPStatus, ui32Size;
+ tBulkInstance *psInst;
+
+ ASSERT(pvBulkDevice);
+
+ //
+ // Get a pointer to the bulk device instance data pointer
+ //
+ psInst = &((tUSBDBulkDevice *)pvBulkDevice)->sPrivateData;
+
+ //
+ // Does the relevant endpoint FIFO have a packet waiting for us?
+ //
+ ui32EPStatus = MAP_USBEndpointStatus(psInst->ui32USBBase,
+ psInst->ui8OUTEndpoint);
+
+ if(ui32EPStatus & USB_DEV_RX_PKT_RDY)
+ {
+ //
+ // Yes - a packet is waiting. How big is it?
+ //
+ ui32Size = MAP_USBEndpointDataAvail(psInst->ui32USBBase,
+ psInst->ui8OUTEndpoint);
+
+ return(ui32Size);
+ }
+ else
+ {
+ //
+ // There is no packet waiting to be received.
+ //
+ return(0);
+ }
+}
+#ifndef DEPRECATED
+
+//*****************************************************************************
+//
+//! Reports the device power status (bus- or self-powered) to the USB library.
+//!
+//! \param pvBulkDevice is the pointer to the bulk device instance structure.
+//! \param ui8Power indicates the current power status, either
+//! \b USB_STATUS_SELF_PWR or \b USB_STATUS_BUS_PWR.
+//!
+//! Applications which support switching between bus- or self-powered
+//! operation should call this function whenever the power source changes
+//! to indicate the current power status to the USB library. This information
+//! is required by the USB library to allow correct responses to be provided
+//! when the host requests status from the device.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+USBDBulkPowerStatusSet(void *pvBulkDevice, uint8_t ui8Power)
+{
+ ASSERT(pvBulkDevice);
+
+ //
+ // Pass the request through to the lower layer.
+ //
+ USBDCDPowerStatusSet(0, ui8Power);
+}
+#endif
+
+//*****************************************************************************
+//
+//! Requests a remote wake up to resume communication when in suspended state.
+//!
+//! \param pvBulkDevice is the pointer to the bulk device instance structure.
+//!
+//! When the bus is suspended, an application which supports remote wake up
+//! (advertised to the host via the configuration descriptor) may call this
+//! function to initiate remote wake up signaling to the host. If the remote
+//! wake up feature has not been disabled by the host, this will cause the bus
+//! to resume operation within 20mS. If the host has disabled remote wake up,
+//! \b false will be returned to indicate that the wake up request was not
+//! successful.
+//!
+//! \return Returns \b true if the remote wake up is not disabled and the
+//! signaling was started or \b false if remote wake up is disabled or if
+//! signaling is currently ongoing following a previous call to this function.
+//
+//*****************************************************************************
+bool
+USBDBulkRemoteWakeupRequest(void *pvBulkDevice)
+{
+ ASSERT(pvBulkDevice);
+
+ //
+ // Pass the request through to the lower layer.
+ //
+ return(USBDCDRemoteWakeupRequest(0));
+}
+
+//*****************************************************************************
+//
+// Close the Doxygen group.
+//! @}
+//
+//*****************************************************************************