/***************************************************************************//** * Copyright (c) 2015 by Silicon Laboratories Inc. All rights reserved. * * http://developer.silabs.com/legal/version/v11/Silicon_Labs_Software_License_Agreement.txt ******************************************************************************/ #ifndef __SILICON_LABS_EFM8_USB_H__ #define __SILICON_LABS_EFM8_USB_H__ #include "si_toolchain.h" #include "usbconfig.h" #include #include #include #include /***************************************************************************//** * @addtogroup Efm8_usb * @brief USB Device Protocol Stack for EFM8 devices * @{ * * @section usb_device_contents Contents * * @li @ref usb_device_library_revision * @li @ref usb_device_intro * @li @ref usb_device_api * @li @ref usb_device_conf * @li @ref usb_device_powersave * @li @ref usb_device_transfers * @li @ref usb_device_pitfalls * * @n @section usb_device_library_revision EFM8 USB Library Revision * Library Revision: 1.0.3 * * @n @section usb_device_intro Introduction * * The USB device protocol stack provides an API which makes it possible to * create USB devices with a minimum of effort. The device stack supports Control, * Bulk, Interrupt, and Isochronous transfers. * * The stack is highly configurable to suit various needs and includes * demonstration projects to get you started fast. * * We recommend that you read through this documentation, then proceed to build * and test a few example projects before you start designing your own device. * * @n @section usb_library_architecture_diagram Library Architecture Diagram * * @image html USB_Library_Architecture.png * * @n @section usb_device_api The EFM8 USB Library API * * This section contains brief descriptions of the functions in the API. You will * find detailed information on input and output parameters and return values by * clicking on the hyper-linked function names. It is also a good idea to study * the code in the USB demonstration projects. * * Your application code must include one header file: @em efm8_usb.h. * * All functions defined in the API can be called from within interrupt handlers. * * @subsection usb_device_api_functions API Functions * * @ref USBD_Init() @n * This function is called to register your device and all its properties with * the device stack. The application must fill in a @ref USBD_Init_TypeDef * structure prior to calling. When this function has been called your device * is ready to be enumerated by the USB host. * * @ref USBD_Read(), @ref USBD_Write() @n * These functions initiate data transfers. * @n @htmlonly USBD_Read() @endhtmlonly initiate a transfer of data @em * from host @em to device (an @em OUT transfer in USB terminology). * @n @htmlonly USBD_Write() @endhtmlonly initiate a transfer of data @em from * device @em to host (an @em IN transfer). * * When the USB host actually performs the transfer, your application will be * notified by means of a call to the @ref USBD_XferCompleteCb() callback * function (optionally). Refer to @ref TransferCallback for details of the * callback functionality. * * @ref USBD_AbortTransfer(), @ref USBD_AbortAllTransfers() @n * These functions terminate transfers that are initiated with @htmlonly * USBD_Read() or USBD_Write() @endhtmlonly but that have not completed yet. * These functions will deactivate the transfer setup to make the USB device * endpoint hardware ready for new (and potentially) different transfers. * * @ref USBD_Connect(), @ref USBD_Disconnect() @n * These functions turn the data-line (D+ or D-) pull-up on or off. They can * be used to force re-enumeration. It's good practice to delay at least one * second between @htmlonly USBD_Disconnect() and USBD_Connect() @endhtmlonly * to allow the USB host to unload the currently active device driver. * * @ref USBD_EpIsBusy() @n * Checks if an endpoint is busy. * * @ref USBD_StallEp(), @ref USBD_UnStallEp() @n * These functions stall or un-stall an endpoint. This functionality may not * be needed by your application. They may be useful when implementing some * USB classes, e.g. a mass storage devices use them extensively. * * @ref USBD_Stop() @n * Removes the data-line (D+ or D-) pull-up and disables the USB block. The * application should call @htmlonly USBD_Init() after calling * USBD_Stop() @endhtmlonly to restart USB operation. * * @ref USBD_Suspend() @n * Puts the device in its low-power suspend mode. This function will not exit * until a wakeup event (resume signaling, VBUS attachment/removal, or remote * wakeup source interrupt) occurs. The USB Library can be configured to * automatically call this function by configuring @ref SLAB_USB_PWRSAVE_MODE. * * @ref USBD_RemoteWakeup() @n * Used in SUSPENDED state (see @ref USB_Status_TypeDef) to signal resume to * host. The function will be called automatically by the library if the * @ref USBD_RemoteWakeupCb() function returns true. The function will * also check that the host has sent a SET_FEATURE request to enable Remote * Wakeup before issuing the resume. * * @ref USBD_GetUsbState() @n * Returns the device USB state (see @ref USBD_State_TypeDef). Refer to * Figure 9-1. "Device State Diagram" in the USB revision 2.0 specification. * * @ref USBD_Run() @n * When @ref SLAB_USB_POLLED_MODE is set to 1, the USB interrupt is disabled * and the application must periodically call @htmlonly USBD_Run() * @endhtmlonly to handle USB events. * * @n @subsection usb_device_api_callback Callback Functions * * @subsubsection usb_device_api_mandatory_callbacks Mandatory Callback Functions * * @n @anchor TransferCallback * @ref USBD_XferCompleteCb() is called each time a packet is sent or * received. It is called with three parameters, the status of the transfer, * the number of bytes transferred and the number of bytes remaining. The * transfer complete callback can be enabled or disabled by setting the * callback parameters of @ref USBD_Write() and @ref USBD_Read() to * true or false. * @note This callback is called from within the USB interrupt handler if * @ref SLAB_USB_POLLED_MODE is set to 1. Otherwise, it is called from * @ref USBD_Run(). * * @n * @subsubsection usb_device_api_optional_callbacks Optional Callback Functions * * @n These callbacks are all optional, and it is up to the application * programmer to decide if the application needs the functionality they * provide. Each callback is enabled or disabled by setting a constant in * usbconfig.h. * @note These callbacks are called from within the USB interrupt handler if * @ref SLAB_USB_POLLED_MODE is set to 1. Otherwise, they are called * from @ref USBD_Run(). * * @n USBD_ResetCb() is called each time reset signaling is sensed on the USB * wire. * * @n USBD_SofCb() is called with the frame number as a parameter on each SOF * interrupt. * * @n USBD_DeviceStateChangeCb() is called whenever the device state changes. * Some uses of this include detecting that a USB suspend has been issued * in order to reduce current consumption or calling USBD_Read() after * entering the Configured state. The USB HID keyboard example * project has a good example on how to use this callback. * * @n USBD_IsSelfPoweredCb() is called by the device stack when host * queries the device with a GET_STATUS command to check if the device is * currently self-powered or bus-powered. This feature is only applicable on * self-powered devices which can also operate when only bus power is * available. * * @n USBD_SetupCmdCb() is called each time a setup command is received from * the host. Use this callback to override or extend the default handling of * standard setup commands, and to implement class- or vendor-specific setup * commands. The USB HID keyboard example project has a good example of how * to use this callback. * * @n @section usb_device_conf Configuring the Library * * Your application must provide a header file named @em usbconfig.h. This file * must contain the following \#define's. See @ref usb_config for * documentation of these constants.@n @n * @code * // ----------------------------------------------------------------------------- * // Specify bus- or self-powered * // ----------------------------------------------------------------------------- * #define SLAB_USB_BUS_POWERED 0 * * // ----------------------------------------------------------------------------- * // Specify USB speed * // ----------------------------------------------------------------------------- * #define SLAB_USB_FULL_SPEED 1 * * // ----------------------------------------------------------------------------- * // Enable or disable the clock recovery * // ----------------------------------------------------------------------------- * #define SLAB_USB_CLOCK_RECOVERY_ENABLED 1 * * // ----------------------------------------------------------------------------- * // Enable or disable remote wakeup * // ----------------------------------------------------------------------------- * #define SLAB_USB_REMOTE_WAKEUP_ENABLED 0 * * // ----------------------------------------------------------------------------- * // Specify number of interfaces and whether any interfaces support alternate * // settings * // ----------------------------------------------------------------------------- * #define SLAB_USB_NUM_INTERFACES 1 * #define SLAB_USB_SUPPORT_ALT_INTERFACES 0 * * // ----------------------------------------------------------------------------- * // Enable or disable each endpoint * // ----------------------------------------------------------------------------- * #define SLAB_USB_EP1IN_USED 1 * #define SLAB_USB_EP1OUT_USED 0 * #define SLAB_USB_EP2IN_USED 0 * #define SLAB_USB_EP2OUT_USED 0 * #define SLAB_USB_EP3IN_USED 0 * #define SLAB_USB_EP3OUT_USED 0 * * // ----------------------------------------------------------------------------- * // Specify the maximum packet size for each endpoint * // ----------------------------------------------------------------------------- * #define SLAB_USB_EP1IN_MAX_PACKET_SIZE 64 * #define SLAB_USB_EP1OUT_MAX_PACKET_SIZE 0 * #define SLAB_USB_EP2IN_MAX_PACKET_SIZE 0 * #define SLAB_USB_EP2OUT_MAX_PACKET_SIZE 0 * #define SLAB_USB_EP3IN_MAX_PACKET_SIZE 0 * #define SLAB_USB_EP3OUT_MAX_PACKET_SIZE 0 * * // ----------------------------------------------------------------------------- * // Specify transfer type of each endpoint * // ----------------------------------------------------------------------------- * #define SLAB_USB_EP1IN_TRANSFER_TYPE USB_EPTYPE_INTR * #define SLAB_USB_EP1OUT_TRANSFER_TYPE USB_EPTYPE_BULK * #define SLAB_USB_EP2IN_TRANSFER_TYPE USB_EPTYPE_INTR * #define SLAB_USB_EP2OUT_TRANSFER_TYPE USB_EPTYPE_BULK * #define SLAB_USB_EP3IN_TRANSFER_TYPE USB_EPTYPE_ISOC * #define SLAB_USB_EP3OUT_TRANSFER_TYPE USB_EPTYPE_ISOC * * // ----------------------------------------------------------------------------- * // Enable or disable callback functions * // ----------------------------------------------------------------------------- * #define SLAB_USB_RESET_CB 1 * #define SLAB_USB_SOF_CB 1 * #define SLAB_USB_STATE_CHANGE_CB 1 * #define SLAB_USB_IS_SELF_POWERED_CB 1 * #define SLAB_USB_SETUP_CMD_CB 1 * #define SLAB_USB_HANDLER_CB 0 * * // ----------------------------------------------------------------------------- * // Specify number of languages supported by string descriptors * // ----------------------------------------------------------------------------- * #define SLAB_USB_NUM_LANGUAGES 1 * * // ----------------------------------------------------------------------------- * // If only one descriptor language is supported, specify that language here. * // If multiple descriptor languages are supported, this value is ignored and * // the supported languages must listed in the * // myUsbStringTableLanguageIDsDescriptor structure. * // ----------------------------------------------------------------------------- * #define SLAB_USB_LANGUAGE USB_LANGID_ENUS * * // ----------------------------------------------------------------------------- * // Enable use of UTF-8 strings for string descriptors. * // If this option is enabled then packed string descriptors that are created * // with UTF8_PACKED_STATIC_CONST_STRING_DESC() can be UTF-8 encoded and they * // will be decoded into UCS-2 16-bit wide character format used for USB string * // descriptors. If this feature is not needed then it can be disabled to save * // some code memory space. * // ----------------------------------------------------------------------------- * #define SLAB_USB_UTF8_STRINGS 1 * * // ----------------------------------------------------------------------------- * // Set the power saving mode * // * // SLAB_USB_PWRSAVE_MODE configures when the device will automatically enter * // the USB power-save mode. It is a bitmask constant with bit values: * // * // USB_PWRSAVE_MODE_OFF - No energy saving mode selected * // USB_PWRSAVE_MODE_ONSUSPEND - Enter USB power-save mode on USB suspend * // USB_PWRSAVE_MODE_ONVBUSOFF - Enter USB power-save mode when not attached * // to the USB host. * // USB_PWRSAVE_MODE_FASTWAKE - Exit USB power-save mode more quickly, but * // consume more power while in USB power-save * // mode. * // While the device is in USB power-save mode * // (typically during USB suspend), the * // internal voltage regulator stays in normal * // power mode instead of entering suspend * // power mode. * // This is an advanced feature that may be * // useful in certain applications that support * // remote wakeup. * // ----------------------------------------------------------------------------- * #define SLAB_USB_PWRSAVE_MODE (USB_PWRSAVE_MODE_ONVBUSOFF \ * | USB_PWRSAVE_MODE_ONSUSPEND) * * // ----------------------------------------------------------------------------- * // Enable or disable polled mode * // * // When enabled, the application must call USBD_Run() periodically to process * // USB events. * // When disabled, USB events will be handled automatically by an interrupt * // handler. * // ----------------------------------------------------------------------------- * #define SLAB_USB_POLLED_MODE 0 * @endcode * * @n @section usb_device_powersave Energy-saving options * * The device stack provides built-in energy saving options.These options * are configured by setting flags in @ref SLAB_USB_PWRSAVE_MODE in @em * usbconfig.h. These flags are bitmasks and can be or'd together.@n@n * * Energy-Saving Option Flags: * * @ref USB_PWRSAVE_MODE_OFF@n The device will not automatically enter its * low-power suspned mode after detecting a USB suspend. The application * firmware may still call @ref USBD_Suspend() to manually enter suspend mode. * * @ref USB_PWRSAVE_MODE_ONSUSPEND@n Enter a low-power suspend mode * when a USB suspend is detected. When resume signaling is detected, * the stack will exit the low-power mode. * * @ref USB_PWRSAVE_MODE_ONVBUSOFF@n Enter the low-power suspend * mode any time the device detects that VBUS is not present. When VBUS is * attached, the stack will exit the low-power mode. The USB Specification * does not define the state of the device when VBUS is not present, but it * may be desirable for some applications to enter suspend mode when in this * undefined state. * * @ref USB_PWRSAVE_MODE_FASTWAKE@n Keep the internal regulator at * its normal operating state while in the low-power suspend state. This * allows the device to wake from suspend more quickly than it would from its * suspend state. This option can be useful in applications that support * remote wakeup and need to exit suspend in time to recognize some external * signal (i.e. a byte received on the UART). The device will still consume * low enough power to meet the USB Suspend Current Specification, but it will * be slightly higher than it would otherwise be. * * The USB HID Keyboard device example project demonstrates some of these * energy-saving options. * * Example: * Leave all energy saving to the stack, the device enters low-power mode on * suspend and when detached from host. @n * In usbconfig.h: * @code * #define SLAB_USB_PWRSAVE_MODE (USB_PWRSAVE_MODE_ONSUSPEND | USB_PWRSAVE_MODE_ONVBUSOFF) * @endcode * * @n @section usb_device_transfers Transfer Operation * * @subsection usb_device_transfers_overview Overview * * A USB transfer consists of one or more packets. For an IN transfer, the * packets are sent from the device to the host. For an OUT transfer, the * packets are sent from the host to the device. @ref USBD_Write() initiates * an IN transfer, while @ref USBD_Read() initiates an OUT transfer. * * @subsection usb_device_transfers_types Transfer Types * * There are four USB transfer types: @ref usb_device_transfer_types_control, * @ref usb_device_transfer_types_bulk, @ref usb_device_transfer_types_interrupt, * and @ref usb_device_transfer_types_isochronous. * * @subsubsection usb_device_transfer_types_control Control * * Control transfers are used to send configuration and status * information, and also to send vendor-defined data. The USB Library only * supports control transfers on Endpoint 0. @n @n * The application firmware can handle control requests by looking at the * contents of the setup packet in @ref USBD_SetupCmdCb(). If the application * supports a particular request, it can call @ref USBD_Read() or @ref * USBD_Write() with epAddr set to EP0 and return @ref * USB_STATUS_OK. If it does not need to handle the request, it should return * @ref USB_STATUS_REQ_UNHANDLED. This will notify the library that it should * try to handle the setup command. The library will automatically service * Standard (i.e. Chapter 9) requests, so @ref USBD_SetupCmdCb() should return * @ref USB_STATUS_REQ_UNHANDLED unless it is a class- or vendor-specific * request. If neither the library nor the application supports a setup * request, the library will issue a stall. * * @subsubsection usb_device_transfer_types_bulk Bulk * * Bulk transfers are used to send large, non-periodic data. Examples include * sending a file to a Mass Storage Device or a print-job to a printer. A bulk * transfer may consist of one or more packets. * * Endpoints are configured for bulk mode in usbconfig.h. As an * example: @code * #define SLAB_USB_EP1OUT_TRANSFER_TYPE USB_EPTYPE_BULK@endcode * configures Endpout 1 OUT transfers for bulk mode. * * The @ref byteCount parameter of @ref USBD_Write() and @ref USBD_Read() * configures the maximum length for a given bulk transfer. The transfer will * complete when the device sends or receives either: * 1. A packet less than its maximum packet size * 2. Exactly the number of bytes specified in @ref byteCount * Note that @ref USBD_XferCompleteCb() will be called for each packet sent or * received for the duration of a transfer. * * @subsubsection usb_device_transfer_types_interrupt Interrupt * * Interrupt transfers are used to send low-bandwidth, hight-latency data at * a non-periodic rate. Examples include input devices, such as mice, * keyboards, and joysticks. An interrupt transfer may consist of one or more * packets. * * Endpoints are configured for interrupt mode in usbconfig.h. As an * example: @code * #define SLAB_USB_EP1OUT_TRANSFER_TYPE USB_EPTYPE_INTR@endcode * configures Endpout 1 OUT transfers for interrupt mode. * * Interrupt transfers work identically to bulk transfer in the USB Library. * Refer to @ref usb_device_transfer_types_bulk for more information. * * @subsubsection usb_device_transfer_types_isochronous Isochronous * * Isochronous transfers are used to send periodic, continuous data. Automatic * error-checking is not included with isochronous transfers as it is with all * other transfer types. Examples include streaming audio and video. As * isochronous data is sent at a continuous rate, it typically consists of * one IN and/or OUT packet per frame. * * Endpoint 3 is the only endpoint in the USB Library that supports * isochronous transfers. Endpoints are configured for isochronous mode in * usbconfig.h. As an example: @code * #define SLAB_USB_EP3OUT_TRANSFER_TYPE USB_EPTYPE_ISOC@endcode * configures Endpout 3 OUT transfers for isochronous mode. * * The library works differently for isochronous transfers. The application * must define a circular buffer to hold isochronous data. When calling * USBD_Read() or USBD_Write(), dat is the first address of this * buffer and byteCount is its length. The library will read from or * write to this buffer as soon as the host issues a request, so it is the * responsibility of the application firmware to ensure that this buffer is * fed or consumed at the correct rate to prevent an underrun/overrun * condition. * * The parameters of @ref USBD_XferCompleteCb() take on a different meaning in * isochronous mode. For OUT transfers, xferred is the number of * bute received in the last packet and remaining is the current * index into the circular buffer. For IN transfers, xferred is * ignored, remaining is the current index into the circular buffer, * and the return value is the number of bytes to transmit in the next * packet. * * @n @section usb_device_pitfalls Pitfalls * * @subsection usb_device_pitfalls_nonreentrancy Non-Reentrancy * * Due to the non-reentrant architecture of the 8051, it is recommended * that all calls to a particular API function be made from functions of the * same interrupt priority (main loop, low priority, or high priority). * * The interrupt priority of the USB callback functions is determined by the * constant @ref SLAB_USB_POLLED_MODE. When 0, the callbacks are called from * the USB Interrupt Handler. When 1, the callbacks are called from * USBD_Run(), which is typically called from the main loop. * If an API function must be called from functions of differing interrupt * priorities, there are a number of ways to ensure that the calls are made * safely: * * 1. Disable the interrupt source of the higher-priority function before * making the call. Restore the interrupt enable setting after the call * returns: * * (Assuming @htmlonly USBD_Write() is called from main() and * USBD_XferCompleteCb() @endhtmlonly, the call from main() should * disable and restore the USB interrupt): * @code * bool usbIntsEnabled = USB_GetIntsEnabled(); * * USB_DisableInts(); * * USBD_Write(EP1IN, myBuf, 1, true); * * if (usbIntsEnabled) * { * USB_EnableInts(); * } * @endcode * * 2. Add the compiler-specific reentrant keyword to the function * definition(s) in efm8_usbd.c: * @code * int8_t USBD_AbortTransfer(uint8_t epAddr) reentrant * @endcode * and to the function prototype definition(s) in efm8_usb.h: * @code * int8_t USBD_AbortTransfer(uint8_t epAddr) reentrant; * @endcode * Using the reentrant keyword may require the application to provide * a heap for local variable allocation. Additionally, it will reduce * the performance and increase the code size of the modified function. * 3. Make a copy of the function(s) and rename it. Call the original * function in once context, and the renamed version in another. * * @subsection usb_device_pitfalls_buffer_allocation Buffer Allocation * * Dynamically allocated buffers passed to @ref USBD_Write() and @ref * USBD_Read() must not be freed until the transfer completes. * ******************************************************************************/ /***************************************************************************//** * @addtogroup efm8_usb_constants Constants * @{ ******************************************************************************/ // ----------------------------------------------------------------------------- // Global Constants // SETUP request, direction of data stage #define USB_SETUP_DIR_OUT 0 ///< Setup request data stage OUT direction value. #define USB_SETUP_DIR_IN 1 ///< Setup request data stage IN direction value. #define USB_SETUP_DIR_MASK 0x80 ///< Setup request data stage direction mask. #define USB_SETUP_DIR_D2H 0x80 ///< Setup request data stage IN direction mask. #define USB_SETUP_DIR_H2D 0x00 ///< Setup request data stage OUT direction mask. // SETUP request type #define USB_SETUP_TYPE_STANDARD 0 ///< Standard setup request value. #define USB_SETUP_TYPE_CLASS 1 ///< Class setup request value. #define USB_SETUP_TYPE_VENDOR 2 ///< Vendor setup request value. #define USB_SETUP_TYPE_STANDARD_MASK 0x00 ///< Standard setup request mask. #define USB_SETUP_TYPE_CLASS_MASK 0x20 ///< Class setup request mask. #define USB_SETUP_TYPE_VENDOR_MASK 0x40 ///< Vendor setup request mask. // SETUP request recipient #define USB_SETUP_RECIPIENT_DEVICE 0 ///< Setup request device recipient value. #define USB_SETUP_RECIPIENT_INTERFACE 1 ///< Setup request interface recipient value. #define USB_SETUP_RECIPIENT_ENDPOINT 2 ///< Setup request endpoint recipient value. #define USB_SETUP_RECIPIENT_OTHER 3 ///< Setup request other recipient value. // bmRequestType bitmasks #define USB_BMREQUESTTYPE_RECIPIENT 0x1F ///< Recipient is bmRequestType[4:0] #define USB_BMREQUESTTYPE_TYPE 0x60 ///< Type is bmRequestType[6:5] #define USB_BMREQUESTTYPE_DIRECTION 0x80 ///< Recipient is bmRequestType[7] // SETUP standard request codes for Full Speed devices #define GET_STATUS 0 ///< Standard setup request GET_STATUS. #define CLEAR_FEATURE 1 ///< Standard setup request CLEAR_FEATURE. #define SET_FEATURE 3 ///< Standard setup request SET_FEATURE. #define SET_ADDRESS 5 ///< Standard setup request SET_ADDRESS. #define GET_DESCRIPTOR 6 ///< Standard setup request GET_DESCRIPTOR. #define SET_DESCRIPTOR 7 ///< Standard setup request SET_DESCRIPTOR. #define GET_CONFIGURATION 8 ///< Standard setup request GET_CONFIGURATION. #define SET_CONFIGURATION 9 ///< Standard setup request SET_CONFIGURATION. #define GET_INTERFACE 10 ///< Standard setup request GET_INTERFACE. #define SET_INTERFACE 11 ///< Standard setup request SET_INTERFACE. #define SYNCH_FRAME 12 ///< Standard setup request SYNCH_FRAME. // SETUP class request codes #define USB_HID_GET_REPORT 0x01 ///< HID class setup request GET_REPORT. #define USB_HID_GET_IDLE 0x02 ///< HID class setup request GET_IDLE. #define USB_HID_SET_REPORT 0x09 ///< HID class setup request SET_REPORT. #define USB_HID_SET_IDLE 0x0A ///< HID class setup request SET_IDLE. #define USB_HID_SET_PROTOCOL 0x0B ///< HID class setup request SET_PROTOCOL. #define USB_CDC_SETLINECODING 0x20 ///< CDC class setup request SET_LINE_CODING. #define USB_CDC_GETLINECODING 0x21 ///< CDC class setup request GET_LINE_CODING. #define USB_CDC_SETCTRLLINESTATE 0x22 ///< CDC class setup request SET_CONTROL_LINE_STATE. #define USB_MSD_BOTRESET 0xFF ///< MSD class setup request Bulk only transfer reset. #define USB_MSD_GETMAXLUN 0xFE ///< MSD class setup request Get Max LUN. // SETUP command GET/SET_DESCRIPTOR descriptor types #define USB_DEVICE_DESCRIPTOR 1 ///< DEVICE descriptor value. #define USB_CONFIG_DESCRIPTOR 2 ///< CONFIGURATION descriptor value. #define USB_STRING_DESCRIPTOR 3 ///< STRING descriptor value. #define USB_INTERFACE_DESCRIPTOR 4 ///< INTERFACE descriptor value. #define USB_ENDPOINT_DESCRIPTOR 5 ///< ENDPOINT descriptor value. #define USB_DEVICE_QUALIFIER_DESCRIPTOR 6 ///< DEVICE_QUALIFIER descriptor value. #define USB_OTHER_SPEED_CONFIG_DESCRIPTOR 7 ///< OTHER_SPEED_CONFIGURATION descriptor value. #define USB_INTERFACE_POWER_DESCRIPTOR 8 ///< INTERFACE_POWER descriptor value. #define USB_HUB_DESCRIPTOR 0x29 ///< HUB descriptor value. #define USB_HID_DESCRIPTOR 0x21 ///< HID descriptor value. #define USB_HID_REPORT_DESCRIPTOR 0x22 ///< HID REPORT descriptor value. #define USB_CS_INTERFACE_DESCRIPTOR 0x24 ///< Audio Class-specific Descriptor Type. #define USB_DEVICE_DESCSIZE 18 ///< Device descriptor size. #define USB_CONFIG_DESCSIZE 9 ///< Configuration descriptor size. #define USB_INTERFACE_DESCSIZE 9 ///< Interface descriptor size. #define USB_ENDPOINT_DESCSIZE 7 ///< Endpoint descriptor size. #define USB_DEVICE_QUALIFIER_DESCSIZE 10 ///< Device qualifier descriptor size. #define USB_OTHER_SPEED_CONFIG_DESCSIZE 9 ///< Device other speed configuration descriptor size. #define USB_HID_DESCSIZE 9 ///< HID descriptor size. #define USB_CDC_HEADER_FND_DESCSIZE 5 ///< CDC Header functional descriptor size. #define USB_CDC_CALLMNG_FND_DESCSIZE 5 ///< CDC Call Management functional descriptor size. #define USB_CDC_ACM_FND_DESCSIZE 4 ///< CDC Abstract Control Management functional descriptor size. // String descriptor locations #define USB_STRING_DESCRIPTOR_ENCODING 0 ///< Denotes whether string descriptor is UTF-8 or binary #define USB_STRING_DESCRIPTOR_LENGTH 1 ///< Length of string descriptor #define USB_STRING_DESCRIPTOR_TYPE 2 ///< Type of string descriptor (USB_STRING_DESCRIPTOR) #define USB_STRING_DESCRIPTOR_NAME 3 ///< The string encoded as per USB_STRING_DESCRIPTOR_PACKED // String descriptor encoding types #define USB_STRING_DESCRIPTOR_UTF16LE 0 ///< The string is in UTF-16LE encoding #define USB_STRING_DESCRIPTOR_UTF16LE_PACKED 1 ///< The string is in packed UTF-16LE encoding (the 0x00 /// characters between ASCII characters are omitted) #define USB_STRING_DESCRIPTOR_UTF8 2 ///< The string is in UTF-8 encoding // Misc. USB definitions #define USB_FULL_EP0_SIZE 64 ///< The size of endpoint 0 at full speed. #define USB_FULL_INT_BULK_MAX_EP_SIZE 64 ///< The max size of any full speed bulk/interrupt endpoint. #define USB_FULL_ISOC_MAX_EP_SIZE 1023 ///< The max size of any full speed isochronous endpoint. #define USB_LOW_EP0_SIZE 8 ///< The size of endpoint 0 at low speed. #define USB_LOW_INT_BULK_MAX_EP_SIZE 8 ///< The max size of any low speed bulk/interrupt endpoint. #define USB_LOW_ISOC_MAX_EP_SIZE 0 ///< The max size of any low speed isochronous endpoint. #define USB_EPTYPE_CTRL 0 ///< Endpoint type control. #define USB_EPTYPE_ISOC 1 ///< Endpoint type isochronous. #define USB_EPTYPE_BULK 2 ///< Endpoint type bulk. #define USB_EPTYPE_INTR 3 ///< Endpoint type interrupt. #define USB_EP_DIR_IN 0x80 ///< Endpoint IN direction mask. #define USB_EP_DIR_OUT 0x00 ///< Endponit OUT direction mask. #define USB_SETUP_PKT_SIZE 8 ///< Setup request packet size. #define USB_EPNUM_MASK 0x0F ///< Endpoint number mask. #define USB_LANGID_ENUS 0x0409 ///< English-United States language id. #define USB_LANGID_NOBO 0x0414 ///< Norwegian-Bokmal language id. #define USB_MAX_DEVICE_ADDRESS 127 ///< Maximum allowable device address. #define MAX_USB_EP_NUM 15 ///< Limit imposed by the USB standard #define USB_VENDOR_ID_SILICON_LABS 0x10C4 ///< Silicon Labs VID #define CONFIG_DESC_BM_REMOTEWAKEUP 0x20 ///< Configuration descriptor attribute macro. #define CONFIG_DESC_BM_SELFPOWERED 0x40 ///< Configuration descriptor attribute macro. #define CONFIG_DESC_BM_RESERVED_D7 0x80 ///< Configuration descriptor attribute macro. #define CONFIG_DESC_BM_TRANSFERTYPE 0x03 ///< Configuration descriptor transfer type bitmask. #define CONFIG_DESC_MAXPOWER_mA(x) (((x)+1)/2) ///< Configuration descriptor power macro. #define DEVICE_IS_SELFPOWERED 0x0001 ///< Standard request GET_STATUS bitmask. #define REMOTE_WAKEUP_ENABLED 0x0002 ///< Standard request GET_STATUS bitmask. #define USB_FEATURE_ENDPOINT_HALT 0 ///< Standard request CLEAR/SET_FEATURE bitmask. #define USB_FEATURE_DEVICE_REMOTE_WAKEUP 1 ///< Standard request CLEAR/SET_FEATURE bitmask. #define HUB_FEATURE_PORT_RESET 4 ///< HUB class request CLEAR/SET_PORT_FEATURE feature selector. #define HUB_FEATURE_PORT_POWER 8 ///< HUB class request CLEAR/SET_PORT_FEATURE feature selector. #define HUB_FEATURE_C_PORT_CONNECTION 16 ///< HUB class request CLEAR/SET_PORT_FEATURE feature selector. #define HUB_FEATURE_C_PORT_RESET 20 ///< HUB class request CLEAR/SET_PORT_FEATURE feature selector. #define HUB_FEATURE_PORT_INDICATOR 22 ///< HUB class request CLEAR/SET_PORT_FEATURE feature selector. #define USB_CLASS_CDC 2 ///< CDC device/interface class code. #define USB_CLASS_CDC_DATA 0x0A ///< CDC Data interface class code. #define USB_CLASS_CDC_ACM 2 ///< CDC Abstract Control Model interface subclass code. #define USB_CLASS_CDC_HFN 0 ///< CDC class Header Functional Descriptor subtype. #define USB_CLASS_CDC_CMNGFN 1 ///< CDC class Call Management Functional Descriptor subtype. #define USB_CLASS_CDC_ACMFN 2 ///< CDC class Abstract Control Management Functional Descriptor subtype. #define USB_CLASS_CDC_UNIONFN 6 ///< CDC class Union Functional Descriptor subtype. #define USB_CLASS_HID 3 ///< HID device/interface class code. #define USB_CLASS_HID_KEYBOARD 1 ///< HID keyboard interface protocol code. #define USB_CLASS_HID_MOUSE 2 ///< HID mouse interface protocol code. #define USB_CLASS_HUB 9 ///< HUB device/interface class code. #define USB_CLASS_MSD 8 ///< MSD device/interface class code. #define USB_CLASS_MSD_BOT_TRANSPORT 0x50 ///< MSD Bulk Only Transport protocol. #define USB_CLASS_MSD_SCSI_CMDSET 6 ///< MSD Subclass SCSI transparent command set. #define USB_CLASS_MSD_CSW_CMDPASSED 0 ///< MSD BOT Command status wrapper command passed code. #define USB_CLASS_MSD_CSW_CMDFAILED 1 ///< MSD BOT Command status wrapper command failed code. #define USB_CLASS_MSD_CSW_PHASEERROR 2 ///< MSD BOT Command status wrapper cmd phase error code. #define USB_CLASS_VENDOR_SPECIFIC 0xFF ///< Vendor Specific class #define USB_SUBCLASS_VENDOR_SPECIFIC 0xFF ///< Vendor Specific sub-class /// @brief USB power save modes #define USB_PWRSAVE_MODE_OFF 0 ///< No energy saving option selected. #define USB_PWRSAVE_MODE_ONSUSPEND 1 ///< Enter USB power-save mode on suspend. #define USB_PWRSAVE_MODE_ONVBUSOFF 2 ///< Enter USB power-save mode when not attached to the USB host. #define USB_PWRSAVE_MODE_FASTWAKE 4 ///< Exit USB power-save mode more quickly. This is useful for ///< some applications that support remote wakeup. /// @brief Endpoint 0 packet size #if SLAB_USB_FULL_SPEED #define USB_EP0_SIZE USB_FULL_EP0_SIZE #else #define USB_EP0_SIZE USB_LOW_EP0_SIZE #endif // SLABS_USB_FULL_SPEED /// @brief Total number of USB endpoints used by the device #define SLAB_USB_NUM_EPS_USED (SLAB_USB_EP1IN_USED \ + SLAB_USB_EP1OUT_USED \ + SLAB_USB_EP2IN_USED \ + SLAB_USB_EP2OUT_USED \ + SLAB_USB_EP3IN_USED \ + SLAB_USB_EP3OUT_USED \ + 1) /** @} (end addtogroup efm8_usb_constants Constants) */ /***************************************************************************//** * @addtogroup efm8_usb_macros Macros * @{ ******************************************************************************/ // ----------------------------------------------------------------------------- // Global Macros /// Macro for getting minimum value. #ifndef EFM8_MIN #define EFM8_MIN(a, b) ((a) < (b) ? (a) : (b)) #endif /// Macro for getting maximum value. #ifndef EFM8_MAX #define EFM8_MAX(a, b) ((a) > (b) ? (a) : (b)) #endif #ifndef UNREFERENCED_ARGUMENT #if defined __C51__ /// Macro for removing unreferenced arguments from compiler warnings #define UNREFERENCED_ARGUMENT(arg) (0, arg) #elif defined __ICC8051__ /// Macro for removing unreferenced arguments from compiler warnings #define UNREFERENCED_ARGUMENT(arg) ((void)arg) #endif #endif /***************************************************************************//** * @brief Macro for creating USB-compliant UTF-16LE UNICODE string * descriptor from a C string. * @details This macro should be used for ASCII strings in which all * characters are represented by a single ASCII byte (i.e. * U.S. English strings). * The USB Library will expand variables created with this macro * by inserting a 0x00 between each character. This allows the * string to be stored in a "packed", or compressed, format. * @n@n This example sends "Silicon Labs" as the Manufacturer String: * * #define MFR_STRING "Silicon Labs" * * UTF16LE_PACKED_STATIC_CONST_STRING_DESC(manufacturer[], \ * MFR_STRING); * @param __name * The name of the variable that holds the string descriptor * @param __val * The value of the string descriptor ******************************************************************************/ #define UTF16LE_PACKED_STATIC_CONST_STRING_DESC(__name, __val, __size) \ SI_SEGMENT_VARIABLE(__name, static const USB_StringDescriptor_TypeDef, SI_SEG_CODE) = \ { USB_STRING_DESCRIPTOR_UTF16LE_PACKED, __size * 2, USB_STRING_DESCRIPTOR, __val } /***************************************************************************//** * @brief Macro for creating USB-compliant UTF-16LE UNICODE string * descriptor from a UTF-8 string. * @details This macro should be used for UTF-8 strings in which all * characters are represented by a valid UTF-8 byte sequence * of 1-3 bytes per character. The USB library will expand * variables created with this macro by decoding the UTF-8 * sequence into 16-bit wide UCS-2 characters required for USB * string descriptors. * @n@n This example set an array named _manufacturer[]_ to a * series of symbols: an anchor, a lightning bolt, and a * fußball as the Manufacturer String: * * #define MFR_STRING "⚓⚡⚽" * * // This string has 3 Unicode characters so the __len * // parameter is 3, even though it will take 3 bytes to * // represent each character * UTF8_PACKED_STATIC_CONST_STRING_DESC(manufacturer[], 3, \ * MFR_STRING); * @param __name * The name of the variable that holds the string descriptor * @param __len * Number of Unicode characters (or codepoints) in the string * @param __val * The value of the string descriptor ******************************************************************************/ #define UTF8_PACKED_STATIC_CONST_STRING_DESC(__name, __len, __val) \ SI_SEGMENT_VARIABLE(__name, static const USB_StringDescriptor_TypeDef, SI_SEG_CODE) = \ { USB_STRING_DESCRIPTOR_UTF8, (__len) * 2, USB_STRING_DESCRIPTOR, __val } /***************************************************************************//** * @brief Macro for creating USB-compliant UTF-16LE UNICODE string * descriptor from a UTF-8 string. * @details This macro should be used for UTF-8 strings in which all * characters are represented by a valid UTF-8 byte sequence * of 1-3 bytes per character. The USB library will expand * variables created with this macro by decoding the UTF-8 * sequence into 16-bit wide UCS-2 characters required for USB * string descriptors. * @n@n This example set an array named _manufacturer[]_ to a * series of symbols: an anchor, a lightning bolt, and a * fußball as the Manufacturer String: * * #define MFR_STRING "⚓⚡⚽" * * // This string has 3 Unicode characters so the __len * // parameter is 3, even though it will take 3 bytes to * // represent each character * UTF8_PACKED_STATIC_CONST_STRING_DESC(manufacturer[], 3, \ * MFR_STRING); * @param __name * The name of the variable that holds the string descriptor * @param __len * Number of Unicode characters (or codepoints) in the string * @param __val * The value of the string descriptor ******************************************************************************/ #define UTF8_PACKED_STATIC_CONST_STRING_DESC(__name, __len, __val) \ SI_SEGMENT_VARIABLE(__name, static const USB_StringDescriptor_TypeDef, SI_SEG_CODE) = \ { USB_STRING_DESCRIPTOR_UTF8, (__len) * 2, USB_STRING_DESCRIPTOR, __val } /***************************************************************************//** * @brief Macro for creating USB-compliant UTF-16LE UNICODE string * descriptor from a C array initializer. * @details This macro should be used for converting an array initializer * into a string descriptor. Unlike @ref * UTF16LE_PACKED_STATIC_CONST_STRING_DESC(), the library will not * attempt to unpack variables created with this macro, so the * array will be sent exactly as it is defined. * @n@n This example sends "Mouse" as the Product String: * * #define PROD_STRING 'M',0,'o',0,'u',0,'s',0,'e',0 * * ARRAY_STATIC_CONST_STRING_DESC(product[], \ * 10, \ * PROD_STRING); * @param __name * The name of the variable that holds the string descriptor * @param __len * Number of characters (including nulls) in the string to send * @param __val * The array initializer. ******************************************************************************/ #define ARRAY_STATIC_CONST_STRING_DESC(__name, __len, __val) \ SI_SEGMENT_VARIABLE(__name, static const USB_StringDescriptor_TypeDef, SI_SEG_CODE) = \ { USB_STRING_DESCRIPTOR_UTF16LE, __len + 2, USB_STRING_DESCRIPTOR, __val } /***************************************************************************//** * @brief Macro for creating USB-compliant UTF-16LE UNICODE string * descriptor from a UTF-16 C string. * @details This macro should be used for strings which are already * represented in UTF-16. This is an advanced option that should * only be used for some foreign languages. * @param __name * The name of the variable that holds the string descriptor * @param __val * The value of the string descriptor ******************************************************************************/ #define UTF16LE_STATIC_CONST_STRING_DESC(__name, __val) \ SI_SEGMENT_VARIABLE(__name, static const USB_StringDescriptor_TypeDef, SI_SEG_CODE) = \ { USB_STRING_DESCRIPTOR_UTF16LE, sizeof(__val) + 2, USB_STRING_DESCRIPTOR, __val } /***************************************************************************//** * @brief Macro for creating Language ID's String Descriptor (String * Descriptor 0) * @details This macro should be used to create the Language ID String * Descriptor. * @n@n This example USB device only support U.S. English: * * #define LANG_STRING htole16(SLAB_USB_LANGUAGE) * * LANGID_STATIC_CONST_STRING_DESC(langDesc[], LANG_STRING); * * This example USB device support Norwegian U.S. English: * * #define LANG_STRING htole16(USB_LANGID_NOBO), \ * htole16(USB_LANGID_ENUS) * * LANGID_STATIC_CONST_STRING_DESC(langDesc[], LANG_STRING); * * @param __name * The name of the variable that holds the string descriptor * @param __val * The value of the string descriptor ******************************************************************************/ #define LANGID_STATIC_CONST_STRING_DESC(__name, __val) \ SI_SEGMENT_VARIABLE(__name, static const USB_LangId_StringDescriptor_Typedef, SI_SEG_CODE) = \ { htole16(((SLAB_USB_NUM_LANGUAGES * 2) + 2) + (USB_STRING_DESCRIPTOR << 8)), __val } /** @} (end addtogroup efm8_usb_macros Macros) */ /***************************************************************************//** * @addtogroup efm8_usb_typedefs Typedefs * @{ ******************************************************************************/ // ----------------------------------------------------------------------------- // Typedefs /// @brief USB transfer status enumerator. typedef enum { USB_STATUS_OK = 0, ///< No errors detected. USB_STATUS_REQ_ERR = -1, ///< Setup request error. USB_STATUS_EP_BUSY = -2, ///< Endpoint is busy. USB_STATUS_REQ_UNHANDLED = -3, ///< Setup request not handled. USB_STATUS_ILLEGAL = -4, ///< Illegal operation attempted. USB_STATUS_EP_STALLED = -5, ///< Endpoint is stalled. USB_STATUS_EP_ABORTED = -6, ///< Endpoint transfer was aborted. USB_STATUS_EP_ERROR = -7, ///< Endpoint transfer error. USB_STATUS_EP_NAK = -8, ///< Endpoint NAK'ed transfer request. USB_STATUS_DEVICE_UNCONFIGURED = -9, ///< Device is unconfigured. USB_STATUS_DEVICE_SUSPENDED = -10, ///< Device is suspended. USB_STATUS_DEVICE_RESET = -11, ///< Device is/was reset. USB_STATUS_TIMEOUT = -12, ///< Transfer timeout. USB_STATUS_DEVICE_REMOVED = -13, ///< Device was removed. USB_STATUS_EP_RX_BUFFER_OVERRUN = -14, ///< Not enough data in the Rx buffer to hold the USB_STATUS_DATA_ERROR = -15, ///< OUT packet had CRC or bit-stuffing error ///< last received packet } USB_Status_TypeDef; /// @brief USB device state enumerator. typedef enum { USBD_STATE_NONE = 0, ///< Device state is undefined/unknown. USBD_STATE_ATTACHED = 1, ///< Device state is ATTACHED. USBD_STATE_POWERED = 2, ///< Device state is POWERED. USBD_STATE_DEFAULT = 3, ///< Device state is DEFAULT. USBD_STATE_ADDRESSED = 4, ///< Device state is ADDRESSED. USBD_STATE_SUSPENDED = 5, ///< Device state is SUSPENDED. USBD_STATE_CONFIGURED = 6, ///< Device state is CONFIGURED. USBD_STATE_LASTMARKER = 7, ///< Device state enum end marker. } USBD_State_TypeDef; /// @cond DO_NOT_INCLUDE_WITH_DOXYGEN /// @brief Endpoint states typedef enum { D_EP_DISABLED = 0, ///< Endpoint is disabled D_EP_IDLE = 1, ///< Endpoint is idle D_EP_TRANSMITTING = 2, ///< Endpoint is transmitting data D_EP_RECEIVING = 3, ///< Endpoint is receiving data D_EP_STATUS = 4, ///< Endpoint is in status stage D_EP_STALL = 5, ///< Endpoint is stalling D_EP_HALT = 6, ///< Endpoint is halted D_EP_LASTMARKER = 7 ///< End of EpState enum } USBD_EpState_TypeDef; /// @endcond DO_NOT_INCLUDE_WITH_DOXYGEN /// @brief Endpoint access address typedef enum { EP0, #if (SLAB_USB_EP1IN_USED) EP1IN, #endif #if (SLAB_USB_EP2IN_USED) EP2IN, #endif #if (SLAB_USB_EP3IN_USED) EP3IN, #endif #if (SLAB_USB_EP1OUT_USED) EP1OUT, #endif #if (SLAB_USB_EP2OUT_USED) EP2OUT, #endif #if (SLAB_USB_EP3OUT_USED) EP3OUT, #endif } USB_EP_Index_TypeDef; /// @brief USB Setup type. typedef struct { struct { uint8_t Recipient : 5; ///< Request recipient (device, interface, endpoint, other) uint8_t Type : 2; ///< Request type (standard, class or vendor). uint8_t Direction : 1; ///< Transfer direction of SETUP data phase. } bmRequestType; uint8_t bRequest; uint16_t wValue; uint16_t wIndex; uint16_t wLength; } USB_Setup_TypeDef; /// @brief USB Setup Union type. typedef union { USB_Setup_TypeDef setup; uint8_t c[8]; uint16_t i[4]; } USB_Setup_UnionDef; /// @brief USB Device Descriptor. typedef struct { uint8_t bLength; ///< Size of this descriptor in bytes uint8_t bDescriptorType; ///< Constant DEVICE Descriptor Type uint16_t bcdUSB; ///< USB Specification Release Number in BCD uint8_t bDeviceClass; ///< Class code (assigned by the USB-IF) uint8_t bDeviceSubClass; ///< Subclass code (assigned by the USB-IF) uint8_t bDeviceProtocol; ///< Protocol code (assigned by the USB-IF) uint8_t bMaxPacketSize0; ///< Maximum packet size for endpoint zero uint16_t idVendor; ///< Vendor ID (assigned by the USB-IF) uint16_t idProduct; ///< Product ID (assigned by the manufacturer) uint16_t bcdDevice; ///< Device release number in binary-coded decimal uint8_t iManufacturer; ///< Index of string descriptor describing manufacturer uint8_t iProduct; ///< Index of string descriptor describing product uint8_t iSerialNumber; ///< Index of string descriptor describing the serial number uint8_t bNumConfigurations; ///< Number of possible configurations } USB_DeviceDescriptor_TypeDef; /// @brief USB Configuration Descriptor. typedef struct { uint8_t bLength; ///< Size of this descriptor in bytes uint8_t bDescriptorType; ///< Constant CONFIGURATION Descriptor Type uint16_t wTotalLength; ///< Total length of data returned for this ///< configuration. Includes the combined length of all ///< descriptors (configuration, interface, endpoint, ///< and class- or vendor-specific) returned for this ///< configuration. uint8_t bNumInterfaces; ///< Number of interfaces supported by this ///< configuration uint8_t bConfigurationValue; ///< Value to use as an argument to the ///< SetConfiguration request to select this ///< configuration. uint8_t iConfiguration; ///< Index of string descriptor describing this ///< configuration. uint8_t bmAttributes; ///< Configuration characteristics. ///< @n D7: Reserved (set to one) ///< @n D6: Self-powered ///< @n D5: Remote Wakeup ///< @n D4...0: Reserved (reset to zero) uint8_t bMaxPower; ///< Maximum power consumption of the USB device, unit ///< is 2mA per LSB } USB_ConfigurationDescriptor_TypeDef; /// @brief USB Interface Descriptor. typedef struct { uint8_t bLength; ///< Size of this descriptor in bytes. uint8_t bDescriptorType; ///< Constant INTERFACE Descriptor Type. uint8_t bInterfaceNumber; ///< Number of this interface. Zero-based value ///< identifying the index in the array of concurrent ///< interfaces supported by this configuration. uint8_t bAlternateSetting; ///< Value used to select this alternate setting for ///< the interface identified in the prior field. uint8_t bNumEndpoints; ///< Number of endpoints used by this interface ///< (excluding endpoint zero). If this value is zero, ///< this interface only uses the Default Control Pipe. uint8_t bInterfaceClass; ///< Class code (assigned by the USB-IF). A value ///< of zero is reserved for future standardization. If ///< this field is set to FFH, the interface class is ///< vendor-specific. All other values are reserved for ///< assignment by the USB-IF. uint8_t bInterfaceSubClass; ///< Subclass code (assigned by the USB-IF). These codes ///< are qualified by the value of the bInterfaceClass ///< field. If the bInterfaceClass field is reset to ///< zero, this field must also be reset to zero. If ///< the bInterfaceClass field is not set to FFH, all ///< values are reserved for assignment by the USB-IF. uint8_t bInterfaceProtocol; ///< Protocol code (assigned by the USB). These codes ///< are qualified by the value of the bInterfaceClass ///< and the bInterfaceSubClass fields. If an interface ///< supports class-specific requests, this code ///< identifies the protocols that the device uses as ///< defined by the specification of the device class. ///< If this field is reset to zero, the device does ///< not use a class-specific protocol on this ///< interface. If this field is set to FFH, the device ///< uses a vendor-specific protocol for this interface uint8_t iInterface; ///< Index of string descriptor describing this ///< interface. } USB_InterfaceDescriptor_TypeDef; /// @brief USB Endpoint Descriptor. typedef struct { uint8_t bLength; ///< Size of this descriptor in bytes uint8_t bDescriptorType; ///< Constant ENDPOINT Descriptor Type uint8_t bEndpointAddress; ///< The address of the endpoint uint8_t bmAttributes; ///< This field describes the endpoint attributes uint16_t wMaxPacketSize; ///< Maximum packet size for the endpoint uint8_t bInterval; ///< Interval for polling EP for data transfers } USB_EndpointDescriptor_TypeDef; /// @brief USB String Descriptor. typedef uint8_t USB_StringDescriptor_TypeDef; ///< The string descriptor /// @brief USB Language ID String Descriptor. typedef uint16_t USB_LangId_StringDescriptor_Typedef; ///< The language ID string descriptor #if (SLAB_USB_NUM_LANGUAGES == 1) /// @brief USB String Table Structure. typedef SI_VARIABLE_SEGMENT_POINTER(, USB_StringDescriptor_TypeDef, SI_SEG_GENERIC) USB_StringTable_TypeDef; #elif (SLAB_USB_NUM_LANGUAGES > 1) typedef struct { uint16_t *languageIDs; USB_StringDescriptor_TypeDef * * *languageArray; } USB_StringTable_TypeDef; #endif // ( SLAB_USB_NUM_LANGUAGES == 1 ) /// @brief USB Device stack initialization structure. /// @details This structure is passed to @ref USBD_Init() when starting up /// the device. typedef struct { SI_VARIABLE_SEGMENT_POINTER(deviceDescriptor, USB_DeviceDescriptor_TypeDef, SI_SEG_GENERIC); ///< Pointer to the device descriptor SI_VARIABLE_SEGMENT_POINTER(configDescriptor, USB_ConfigurationDescriptor_TypeDef, SI_SEG_GENERIC); ///< Pointer to the configuration descriptor SI_VARIABLE_SEGMENT_POINTER(stringDescriptors, USB_StringTable_TypeDef, SI_SEG_GENERIC); ///< Pointer to an array of string descriptor pointers uint8_t numberOfStrings; ///< Number of strings in string descriptor array } USBD_Init_TypeDef; /// @cond DO_NOT_INCLUDE_WITH_DOXYGEN // Endpoint structure typedef struct { SI_VARIABLE_SEGMENT_POINTER(buf, uint8_t, SI_SEG_GENERIC); uint16_t remaining; USBD_EpState_TypeDef state; union { struct { uint8_t callback : 1; uint8_t outPacketPending : 1; uint8_t inPacketPending : 1; uint8_t waitForRead : 1; } bits; uint8_t c; } misc; } USBD_Ep_TypeDef; // USB Device structure typedef struct { uint8_t configurationValue; #if SLAB_USB_REMOTE_WAKEUP_ENABLED uint8_t remoteWakeupEnabled; #endif uint8_t numberOfStrings; USBD_State_TypeDef state; USBD_State_TypeDef savedState; USB_Setup_TypeDef setup; union { struct { uint8_t type : 7; uint8_t init : 1; } encoding; uint8_t c; } ep0String; USBD_Ep_TypeDef ep0; #if SLAB_USB_EP1IN_USED USBD_Ep_TypeDef ep1in; #endif #if SLAB_USB_EP2IN_USED USBD_Ep_TypeDef ep2in; #endif #if SLAB_USB_EP3IN_USED USBD_Ep_TypeDef ep3in; #endif #if SLAB_USB_EP1OUT_USED USBD_Ep_TypeDef ep1out; #endif #if SLAB_USB_EP2OUT_USED USBD_Ep_TypeDef ep2out; #endif #if SLAB_USB_EP3OUT_USED USBD_Ep_TypeDef ep3out; #endif #if ((SLAB_USB_EP3IN_USED) && (SLAB_USB_EP3IN_TRANSFER_TYPE == USB_EPTYPE_ISOC)) uint16_t ep3inIsoIdx; #endif #if ((SLAB_USB_EP3OUT_USED) && (SLAB_USB_EP3OUT_TRANSFER_TYPE == USB_EPTYPE_ISOC)) uint16_t ep3outIsoIdx; #endif #if SLAB_USB_SUPPORT_ALT_INTERFACES uint8_t interfaceAltSetting[SLAB_USB_NUM_INTERFACES]; #endif SI_VARIABLE_SEGMENT_POINTER(deviceDescriptor, USB_DeviceDescriptor_TypeDef, SI_SEG_GENERIC); SI_VARIABLE_SEGMENT_POINTER(configDescriptor, USB_ConfigurationDescriptor_TypeDef, SI_SEG_GENERIC); SI_VARIABLE_SEGMENT_POINTER(stringDescriptors, USB_StringTable_TypeDef, SI_SEG_GENERIC); } USBD_Device_TypeDef; /// @endcond DO_NOT_INCLUDE_WITH_DOXYGEN /** @} (end addtogroup efm8_usb_typedefs Typedefs) */ /***************************************************************************//** * @addtogroup efm8_usb_constants Constants * @{ ******************************************************************************/ // ----------------------------------------------------------------------------- // Compiler-specific memory segment definitions #ifndef MEM_MODEL_SEG // ----------------------------------------------------------------------------- // Memory Model-Specific Location // // MEM_MODEL_SEG is the default memory segment used for a given // memory model. Some variables use this symbol in order to reduce the amount // of code space and number of cycles it takes to access them. // The user can override this value by defining it in his usbconfig.h file. // For example: // // #define MEM_MODEL_LOC SI_SEG_XDATA // // will place these variables in XRAM regardless of the memory model used to // build the project. // ----------------------------------------------------------------------------- #if (defined SDCC) || (defined __SDCC) #if (__SDCC_MODEL_SMALL) #define MEM_MODEL_SEG SI_SEG_IDATA #elif defined __SDCC_MODEL_MEDIUM #define MEM_MODEL_SEG SI_SEG_PDATA #elif (defined __SDCC_MODEL_LARGE) || (defined __SDCC_MODEL_HUGE) #define MEM_MODEL_SEG SI_SEG_XDATA #else #error "Illegal memory model setting." #endif #elif defined __RC51__ #if (__MEMORY_MODEL__ == 0) // TINY #define MEM_MODEL_SEG SI_SEG_IDATA #elif (__MEMORY_MODEL__ == 1) // SMALL #define MEM_MODEL_SEG SI_SEG_IDATA #elif (__MEMORY_MODEL__ == 2) // COMPACT #define MEM_MODEL_SEG SI_SEG_PDATA #elif (__MEMORY_MODEL__ == 3) // LARGE #define MEM_MODEL_SEG SI_SEG_XDATA #elif (__MEMORY_MODEL__ == 4) // HUGE #define MEM_MODEL_SEG SI_SEG_PDATA #else #error "Illegal memory model setting." #endif #elif defined __C51__ #if (__MODEL__ == 0) // SMALL #define MEM_MODEL_SEG SI_SEG_IDATA #elif (__MODEL__ == 1) // COMPACT #define MEM_MODEL_SEG SI_SEG_PDATA #elif (__MODEL__ == 2) // LARGE #define MEM_MODEL_SEG SI_SEG_XDATA #else #error "Illegal memory model setting." #endif #elif defined _CC51 #if (_MODEL == 's') // SMALL #define MEM_MODEL_SEG SI_SEG_IDATA #elif (_MODEL == 'a') // AUXPAGE #define MEM_MODEL_SEG SI_SEG_PDATA #elif (_MODEL == 'l') // LARGE #define MEM_MODEL_SEG SI_SEG_XDATA #elif (_MODEL == 'r') // REENTRANT #define MEM_MODEL_SEG SI_SEG_XDATA #else #error "Illegal memory model setting." #endif #elif defined __ICC8051__ #if (__DATA_MODEL__ == 0) // TINY #define MEM_MODEL_SEG SI_SEG_IDATA #elif (__DATA_MODEL__ == 1) // SMALL #define MEM_MODEL_SEG SI_SEG_IDATA #elif (__DATA_MODEL__ == 2) // LARGE #define MEM_MODEL_SEG SI_SEG_XDATA #elif (__DATA_MODEL__ == 3) // GENERIC #define MEM_MODEL_SEG SI_SEG_XDATA #elif (__DATA_MODEL__ == 4) // FAR #define MEM_MODEL_SEG SI_SEG_XDATA #else #error "Illegal memory model setting." #endif #endif #endif // #ifndef MEM_MODEL_SEG /** @} (end addtogroup efm8_usb_constants Constants) */ /// @cond DO_NOT_INCLUDE_WITH_DOXYGEN void USBD_SetUsbState(USBD_State_TypeDef newState); USB_Status_TypeDef USBDCH9_SetupCmd(void); /// @endcond DO_NOT_INCLUDE_WITH_DOXYGEN // ----------------------------------------------------------------------------- // Library Configuration Definitions /**************************************************************************//** * @addtogroup efm8_usb_config Library Configuration * @{ * * @details Library configuration constants read from usbconfig.h. * * This library will look for configuration constants in **usbconfig.h**. * This file is provided/written by the user and should be * located in a directory that is part of the include path. * *****************************************************************************/ /**************************************************************************//** * @def SLAB_USB_BUS_POWERED * @brief Configures the USB device for bus-powered or self-powered mode. * @details * When '1' the USB device is bus-powered. * When '0' the USB device is self-powered. * * Default setting is '1' and may be overridden by defining in 'usbconfig.h'. * * @note The EFM8UB1, EFM8UB3, and EFM8UB4 devices can be configured to ignore * the voltage on the VBUS pin and to instead use that pin as GPIO. If * this feature is used, SLAB_USB_BUS_POWERED should be set to '1' even if * the device is not drawing its power from the VBUS line. *****************************************************************************/ /**************************************************************************//** * @def SLAB_USB_FULL_SPEED * @brief Configures the USB device for full-speed or low-speed operation. * @details * When '1' the USB device is full-speed * When '0' the USB device is low-speed * * Default setting is '1' and may be overridden by defining in 'usbconfig.h'. * *****************************************************************************/ /**************************************************************************//** * @def SLAB_USB_CLOCK_RECOVERY_ENABLED * @brief Enables/disables the USB Clock Recovery * @details USB Clock Recovery uses the incoming USB dat stream to adjust the * internal oscillator. This allows the internal oscillator to meet the * requirements for USB clock tolerance. * * When '1' the USB clock recovery is enabled * When '0' the USB clock recovery is disabled * * Default setting is '1' and may be overridden by defining in 'usbconfig.h'. * *****************************************************************************/ /**************************************************************************//** * @def SLAB_USB_REMOTE_WAKEUP_ENABLED * @brief Enables/disables remote wakeup capability * @details Remote wakeup allow the USB device to wake the host from suspend. * When enabled, the library will call @ref USBD_RemoteWakeupCb() to determine * if the remote wakeup source caused the device to wake up. If it did, the * library will exit suspend mode and call @ref USBD_RemoteWakeup() to wake * up the host. * * When '1' remote wakeup is enabled * When '0' remote wakeup is disabled * * Default setting is '0' and may be overridden by defining in 'usbconfig.h'. * *****************************************************************************/ /**************************************************************************//** * @def SLAB_USB_NUM_INTERFACES * @brief The number of interfaces available in the configuration * @details * Default setting is '1' and may be overridden by defining in 'usbconfig.h'. * *****************************************************************************/ /**************************************************************************//** * @def SLAB_USB_SUPPORT_ALT_INTERFACES * @brief Enables/disables alternate interface settings * @details If any of the interfaces support alternate settings, this should be * set to '1'. Upon receiveing a SET_INTERFACE request, the library will call * @ref USBD_SetInterfaceCb(), which should return @ref USB_STATUS_OK if the * alternate setting is valid or @ref USB_STATUS_REQ_ERR if it is not. * * When '1' alternate inteface settings are supported * When '0' alternate interface settings are not supported, and the library will * respond to any SET_INTERFACE request with a procedural stall * * Default setting is '0' and may be overridden by defining in 'usbconfig.h'. * *****************************************************************************/ /**************************************************************************//** * @def SLAB_USB_EP1IN_USED * @brief Enables/disables Endpoint 1 IN * @details * When '1' Endpoint 1 IN is enabled * When '0' Endpoint 1 IN is disabled * * Default setting is '0' and may be overridden by defining in 'usbconfig.h'. * *****************************************************************************/ /**************************************************************************//** * @def SLAB_USB_EP1OUT_USED * @brief Enables/disables Endpoint 1 OUT * @details * When '1' Endpoint 1 OUT is enabled * When '0' Endpoint 1 OUT is disabled * * Default setting is '0' and may be overridden by defining in 'usbconfig.h'. * *****************************************************************************/ /**************************************************************************//** * @def SLAB_USB_EP2IN_USED * @brief Enables/disables Endpoint 2 IN * @details * When '1' Endpoint 2 IN is enabled * When '0' Endpoint 2 IN is disabled * * Default setting is '0' and may be overridden by defining in 'usbconfig.h'. * *****************************************************************************/ /**************************************************************************//** * @def SLAB_USB_EP2OUT_USED * @brief Enables/disables Endpoint 2 OUT * @details * When '1' Endpoint 2 OUT is enabled * When '0' Endpoint 2 OUT is disabled * * Default setting is '0' and may be overridden by defining in 'usbconfig.h'. * *****************************************************************************/ /**************************************************************************//** * @def SLAB_USB_EP3IN_USED * @brief Enables/disables Endpoint 3 IN * @details * When '1' Endpoint 3 IN is enabled * When '0' Endpoint 3 IN is disabled * * Default setting is '0' and may be overridden by defining in 'usbconfig.h'. * *****************************************************************************/ /**************************************************************************//** * @def SLAB_USB_EP3OUT_USED * @brief Enables/disables Endpoint 3 OUT * @details * When '1' Endpoint 3 OUT is enabled * When '0' Endpoint 3 OUT is disabled * * Default setting is '0' and may be overridden by defining in 'usbconfig.h'. * *****************************************************************************/ /**************************************************************************//** * @def SLAB_USB_EP1IN_MAX_PACKET_SIZE * @brief The maximum packet size that can be received on Endpoint 1 IN * @details * Default setting is '64' and may be overridden by defining in 'usbconfig.h'. * *****************************************************************************/ /**************************************************************************//** * @def SLAB_USB_EP1OUT_MAX_PACKET_SIZE * @brief The maximum packet size that can be transmitted on Endpoint 1 OUT * @details * Default setting is '64' and may be overridden by defining in 'usbconfig.h'. * *****************************************************************************/ /**************************************************************************//** * @def SLAB_USB_EP2IN_MAX_PACKET_SIZE * @brief The maximum packet size that can be received on Endpoint 2 IN * @details * Default setting is '64' and may be overridden by defining in 'usbconfig.h'. * *****************************************************************************/ /**************************************************************************//** * @def SLAB_USB_EP2OUT_MAX_PACKET_SIZE * @brief The maximum packet size that can be transmitted on Endpoint 2 OUT * @details * Default setting is '64' and may be overridden by defining in 'usbconfig.h'. * *****************************************************************************/ /**************************************************************************//** * @def SLAB_USB_EP3IN_MAX_PACKET_SIZE * @brief The maximum packet size that can be received on Endpoint 3 IN * @details * Default setting is '64' and may be overridden by defining in 'usbconfig.h'. * *****************************************************************************/ /**************************************************************************//** * @def SLAB_USB_EP3OUT_MAX_PACKET_SIZE * @brief The maximum packet size that can be transmitted on Endpoint 3 OUT * @details * Default setting is '64' and may be overridden by defining in 'usbconfig.h'. * *****************************************************************************/ /**************************************************************************//** * @def SLAB_USB_EP1IN_TRANSFER_TYPE * @brief Transfer type on Endpoint 1 IN * @details * May take one of the following values: * USB_EPTYPE_INTR - Interrupt * USB_EPTYPE_BULK - Bulk * * Default setting is @ref USB_EPTYPE_INTR and may be overridden by defining in * 'usbconfig.h'. * *****************************************************************************/ /**************************************************************************//** * @def SLAB_USB_EP1OUT_TRANSFER_TYPE * @brief Transfer type on Endpoint 1 OUT * @details * May take one of the following values: * USB_EPTYPE_INTR - Interrupt * USB_EPTYPE_BULK - Bulk * * Default setting is @ref USB_EPTYPE_INTR and may be overridden by defining in * 'usbconfig.h'. * *****************************************************************************/ /**************************************************************************//** * @def SLAB_USB_EP2IN_TRANSFER_TYPE * @brief Transfer type on Endpoint 2 IN * @details * May take one of the following values: * USB_EPTYPE_INTR - Interrupt * USB_EPTYPE_BULK - Bulk * * Default setting is @ref USB_EPTYPE_INTR and may be overridden by defining in * 'usbconfig.h'. * *****************************************************************************/ /**************************************************************************//** * @def SLAB_USB_EP2OUT_TRANSFER_TYPE * @brief Transfer type on Endpoint 2 OUT * @details * May take one of the following values: * USB_EPTYPE_INTR - Interrupt * USB_EPTYPE_BULK - Bulk * * Default setting is @ref USB_EPTYPE_INTR and may be overridden by defining in * 'usbconfig.h'. * *****************************************************************************/ /**************************************************************************//** * @def SLAB_USB_EP3IN_TRANSFER_TYPE * @brief Transfer type on Endpoint 3 IN * @details * May take one of the following values: * USB_EPTYPE_INTR - Interrupt * USB_EPTYPE_BULK - Bulk * USB_EPTYPE_ISOC - Isochronous * * Default setting is @ref USB_EPTYPE_INTR and may be overridden by defining in * 'usbconfig.h'. * *****************************************************************************/ /**************************************************************************//** * @def SLAB_USB_EP3OUT_TRANSFER_TYPE * @brief Transfer type on Endpoint 3 OUT * @details * May take one of the following values: * USB_EPTYPE_INTR - Interrupt * USB_EPTYPE_BULK - Bulk * USB_EPTYPE_ISOC - Isochronous * * Default setting is @ref USB_EPTYPE_INTR and may be overridden by defining in * 'usbconfig.h'. * *****************************************************************************/ /**************************************************************************//** * @def SLAB_USB_RESET_CB * @brief Enables/disables the USB Reset callback function * @details * When '1' @ref USBD_ResetCb() is called upon reception of a USB Reset * When '0' @ref USBD_ResetCb() is not called upon reception of a USB Reset * * Default setting is '0' and may be overridden by defining in 'usbconfig.h'. * *****************************************************************************/ /**************************************************************************//** * @def SLAB_USB_SOF_CB * @brief Enables/disables the USB Start-Of-Frame callback function * @details * When '1' @ref USBD_SofCb() is called upon reception of a Start-of-Frame * packet * When '0' @ref USBD_SofCb() is not called upon reception of a Start-of-Frame * packet * * Default setting is '0' and may be overridden by defining in 'usbconfig.h'. * *****************************************************************************/ /**************************************************************************//** * @def SLAB_USB_STATE_CHANGE_CB * @brief Enables/disables the USB State Change callback function * @details * When '1' @ref USBD_DeviceStateChangeCb() is called when the USB device state * changes * When '0' @ref USBD_DeviceStateChangeCb() is not called when the USB device * state changes * * Default setting is '0' and may be overridden by defining in 'usbconfig.h'. * *****************************************************************************/ /**************************************************************************//** * @def SLAB_USB_IS_SELF_POWERED_CB * @brief Enables/disables the USB Self-Powered callback function * @details * When '1' @ref USBD_IsSelfPoweredCb() is called upon reception of a * GET_STATUS (Self-Powered) request * When '0' @ref USBD_IsSelfPoweredCb() is not called upon reception of a * GET_STATUS (Self-Powered) request * * Default setting is '0' and may be overridden by defining in 'usbconfig.h'. * *****************************************************************************/ /**************************************************************************//** * @def SLAB_USB_SETUP_CMD_CB * @brief Enables/disables the USB Setup Command callback function * @details * When '1' @ref USBD_SetupCmdCb() is called upon reception of a Setup Request * When '0' @ref USBD_SetupCmdCb() is not called upon reception of a Setup * Request * * Default setting is '0' and may be overridden by defining in 'usbconfig.h'. * *****************************************************************************/ /**************************************************************************//** * @def SLAB_USB_HANDLER_CB * @brief Enables/disables the USB Handler Entry and Exit callback functions * @details * When '1' @ref USBD_EnterHandler() will be called before the USB handler * executes and @ref USBD_ExitHandler() will be called after the USB handler * completes * When '0' @ref USBD_EnterHandler() and @ref USBD_ExitHandler() will not be * called * * Default setting is '0' and may be overridden by defining in 'usbconfig.h'. * *****************************************************************************/ /**************************************************************************//** * @def SLAB_USB_NUM_LANGUAGES * @brief Number of languages supported by the USB string descriptors * @details * Default setting is '1' and may be overridden by defining in 'usbconfig.h'. * *****************************************************************************/ /**************************************************************************//** * @def SLAB_USB_LANGUAGE * @brief * Defines the language of the USB string descriptors when * @ref SLAB_USB_NUM_LANGUAGES is '1'. * * @details * When @ref SLAB_USB_NUM_LANGUAGES is greater than '1', the supported languages * must be defined in a separate table, and a structure of type * @ref USB_StringDescriptor_TypeDef must be defined for each supported * language * * Default setting is @ref USB_LANGID_ENUS and may be overridden by defining in * 'usbconfig.h'. * *****************************************************************************/ /**************************************************************************//** * @def SLAB_USB_UTF8_STRINGS * @brief * Enables UTF-8 string decoding for USB string descriptors that are created * using @ref UTF8_PACKED_STATIC_CONST_STRING_DESC. * * @details * If this option is enabled, USB descriptor strings that are created using * @ref UTF8_PACKED_STATIC_CONST_STRING_DESC can be encoded as UTF-8 which * allows for Unicode characters (up to 16-bits wide) to be used for USB * string descriptors. The UTF-8 strings will be decoded into UCS-2 16-bit * wide character format required by USB. If this feature is not needed then * this option can be disabled to save code memory space. If this option is * disabled, then @ref UTF8_PACKED_STATIC_CONST_STRING_DESC should not be used. * * Default setting is '0' and may be overridden by defining in 'usbconfig.h'. * *****************************************************************************/ /**************************************************************************//** * @def SLAB_USB_PWRSAVE_MODE * @brief Configures the power-saving options supported by the device * * @details * Default setting is @ref USB_PWRSAVE_MODE_ONSUSPEND and may be overridden by * defining in 'usbconfig.h'. * * SLAB_USB_PWRSAVE_MODE configures when the device will automatically enter * the USB power-save mode. It is a bitmask constant with bit values: * * @ref USB_PWRSAVE_MODE_OFF - No energy saving option selected * @ref USB_PWRSAVE_MODE_ONSUSPEND - Enter USB power-save mode on USB suspend * @ref USB_PWRSAVE_MODE_ONVBUSOFF - Enter USB power-save mode when not * attached to the USB host. * @ref USB_PWRSAVE_MODE_FASTWAKE - Exit USB power-save mode more quickly. * This is useful for some applications that * support remote wakeup. *****************************************************************************/ /**************************************************************************//** * @def SLAB_USB_POLLED_MODE * @brief Enables/disables USB library polled mode * @details * When '1' the library will run in polled mode * When '0' the library will run in interrupt mode * * Default setting is '0' and may be overridden by defining in 'usbconfig.h'. * *****************************************************************************/ /** @} (end addtogroup efm8_usb_config Library Configuration) */ // Set default USB library configurations if the value is not configured in // usbconfig.h #ifndef SLAB_USB_BUS_POWERED #define SLAB_USB_BUS_POWERED 1 #endif #ifndef SLAB_USB_FULL_SPEED #define SLAB_USB_FULL_SPEED 1 #endif #ifndef SLAB_USB_CLOCK_RECOVERY_ENABLED #define SLAB_USB_CLOCK_RECOVERY_ENABLED 1 #endif #ifndef SLAB_USB_REMOTE_WAKEUP_ENABLED #define SLAB_USB_REMOTE_WAKEUP_ENABLED 0 #endif #ifndef SLAB_USB_NUM_INTERFACES #define SLAB_USB_NUM_INTERFACES 1 #endif #ifndef SLAB_USB_SUPPORT_ALT_INTERFACES #define SLAB_USB_SUPPORT_ALT_INTERFACES 0 #endif #ifndef SLAB_USB_EP1IN_USED #define SLAB_USB_EP1IN_USED 0 #endif #ifndef SLAB_USB_EP1OUT_USED #define SLAB_USB_EP1OUT_USED 0 #endif #ifndef SLAB_USB_EP2IN_USED #define SLAB_USB_EP2IN_USED 0 #endif #ifndef SLAB_USB_EP2OUT_USED #define SLAB_USB_EP2OUT_USED 0 #endif #ifndef SLAB_USB_EP3IN_USED #define SLAB_USB_EP3IN_USED 0 #endif #ifndef SLAB_USB_EP3OUT_USED #define SLAB_USB_EP3OUT_USED 0 #endif #ifndef SLAB_USB_EP1IN_MAX_PACKET_SIZE #define SLAB_USB_EP1IN_MAX_PACKET_SIZE 64 #endif #ifndef SLAB_USB_EP1OUT_MAX_PACKET_SIZE #define SLAB_USB_EP1OUT_MAX_PACKET_SIZE 64 #endif #ifndef SLAB_USB_EP2IN_MAX_PACKET_SIZE #define SLAB_USB_EP2IN_MAX_PACKET_SIZE 64 #endif #ifndef SLAB_USB_EP2OUT_MAX_PACKET_SIZE #define SLAB_USB_EP2OUT_MAX_PACKET_SIZE 64 #endif #ifndef SLAB_USB_EP3IN_MAX_PACKET_SIZE #define SLAB_USB_EP3IN_MAX_PACKET_SIZE 64 #endif #ifndef SLAB_USB_EP3OUT_MAX_PACKET_SIZE #define SLAB_USB_EP3OUT_MAX_PACKET_SIZE 64 #endif #ifndef SLAB_USB_EP1IN_TRANSFER_TYPE #define SLAB_USB_EP1IN_TRANSFER_TYPE USB_EPTYPE_INTR #endif #ifndef SLAB_USB_EP1OUT_TRANSFER_TYPE #define SLAB_USB_EP1OUT_TRANSFER_TYPE USB_EPTYPE_INTR #endif #ifndef SLAB_USB_EP2IN_TRANSFER_TYPE #define SLAB_USB_EP2IN_TRANSFER_TYPE USB_EPTYPE_INTR #endif #ifndef SLAB_USB_EP2OUT_TRANSFER_TYPE #define SLAB_USB_EP2OUT_TRANSFER_TYPE USB_EPTYPE_INTR #endif #ifndef SLAB_USB_EP3IN_TRANSFER_TYPE #define SLAB_USB_EP3IN_TRANSFER_TYPE USB_EPTYPE_INTR #endif #ifndef SLAB_USB_EP3OUT_TRANSFER_TYPE #define SLAB_USB_EP3OUT_TRANSFER_TYPE USB_EPTYPE_INTR #endif #ifndef SLAB_USB_RESET_CB #define SLAB_USB_RESET_CB 0 #endif #ifndef SLAB_USB_SOF_CB #define SLAB_USB_SOF_CB 0 #endif #ifndef SLAB_USB_STATE_CHANGE_CB #define SLAB_USB_STATE_CHANGE_CB 0 #endif #ifndef SLAB_USB_IS_SELF_POWERED_CB #define SLAB_USB_IS_SELF_POWERED_CB 0 #endif #ifndef SLAB_USB_SETUP_CMD_CB #define SLAB_USB_SETUP_CMD_CB 0 #endif #ifndef SLAB_USB_HANDLER_CB #define SLAB_USB_HANDLER_CB 0 #endif #ifndef SLAB_USB_NUM_LANGUAGES #define SLAB_USB_NUM_LANGUAGES 1 #endif #ifndef SLAB_USB_LANGUAGE #define SLAB_USB_LANGUAGE USB_LANGID_ENUS #endif #ifndef SLAB_USB_UTF8_STRINGS #define SLAB_USB_UTF8_STRINGS 0 #endif #ifndef SLAB_USB_PWRSAVE_MODE #define SLAB_USB_PWRSAVE_MODE USB_PWRSAVE_MODE_ONSUSPEND #endif #ifndef SLAB_USB_POLLED_MODE #define SLAB_USB_POLLED_MODE 0 #endif #if SLAB_USB_POLLED_MODE void usbIrqHandler(void); #endif /***************************************************************************//** * @addtogroup efm8_api API Functions * @{ ******************************************************************************/ /***************************************************************************//** * @brief * Abort all pending transfers. * * @details * Aborts transfers for all endpoints currently in use. Pending * transfers on the default endpoint (EP0) are not aborted. ******************************************************************************/ void USBD_AbortAllTransfers(void); /***************************************************************************//** * @brief * Abort a pending transfer on a specific endpoint. * * @param epAddr * The address of the endpoint to abort. * @return * @ref USB_STATUS_OK is the transfer aborted, @ref USB_STATUS_ILLEGAL * otherwise ******************************************************************************/ int8_t USBD_AbortTransfer(uint8_t epAddr); /***************************************************************************//** * @brief * Start USB device operation. * * @details * Device operation is started by connecting a pull-up resistor on the * appropriate USB data line. ******************************************************************************/ void USBD_Connect(void); /***************************************************************************//** * @brief * Stop USB device operation. * * @details * Device operation is stopped by disconnecting the pull-up resistor from the * appropriate USB data line. Often referred to as a "soft" disconnect. ******************************************************************************/ void USBD_Disconnect(void); /***************************************************************************//** * @brief * Check if an endpoint is busy doing a transfer. * * @param epAddr * The address of the endpoint to check. * * @return * True if endpoint is busy, false otherwise. ******************************************************************************/ bool USBD_EpIsBusy(uint8_t epAddr); /***************************************************************************//** * @brief * Get current USB device state. * * @return * Device USB state. See @ref USBD_State_TypeDef. ******************************************************************************/ USBD_State_TypeDef USBD_GetUsbState(void); /***************************************************************************//** * @brief * Initializes USB device hardware and internal protocol stack data structures, * then connects the data-line (D+ or D-) pullup resistor to signal host that * enumeration can begin. * * @note * You may later use @ref USBD_Disconnect() and @ref USBD_Connect() to force * reenumeration. * * @param p * Pointer to device initialization struct. See @ref USBD_Init_TypeDef. * * @return * @ref USB_STATUS_OK on success, else an appropriate error code. ******************************************************************************/ int8_t USBD_Init(SI_VARIABLE_SEGMENT_POINTER(p, const USBD_Init_TypeDef, SI_SEG_GENERIC)); /***************************************************************************//** * @brief * Start a read (OUT) transfer on an endpoint. * * @note * If it is possible that the host will send more data than your device * expects, round buffer size up to the next multiple of maxpacket size. * * @param epAddr * Endpoint address. * * @param dat * Pointer to transfer data buffer. * * @param byteCount * Transfer length. * * @param callback * Boolean to determine if USB_XferCompleteCb should be called for this * transfer. * * @return * @ref USB_STATUS_OK on success, else an appropriate error code. ******************************************************************************/ int8_t USBD_Read(uint8_t epAddr, SI_VARIABLE_SEGMENT_POINTER(dat, uint8_t, SI_SEG_GENERIC), uint16_t byteCount, bool callback); /***************************************************************************//** * @brief * Perform a remote wakeup signaling sequence. * * @note * This function is typically called by the library if @ref * USBD_RemoteWakeupCb() returns true, so it does not need to be called by * application code. * * @return * @ref USB_STATUS_OK on success, else an appropriate error code. ******************************************************************************/ int8_t USBD_RemoteWakeup(void); /***************************************************************************//** * @brief * Processes USB events when the library is configured for polled mode * * @details * The USB library can be configured for interrupt (SLAB_USB_POLLED_MODE == 0) * or polled (SLAB_USB_POLLED_MODE == 1) mode. * * When in interrupt mode, the USB interrupt handler will trigger * when a USB event occurs. Callback functions will be called as needed. * * When in polled mode, the application must call USBD_Run() periodically to * check for and process USB events. This may be useful in complex systems or * when using an RTOS to perform all USB processing in the main loop instead * of in the interrupt context. * ******************************************************************************/ void USBD_Run(void); /***************************************************************************//** * @brief * Set an endpoint in the stalled (halted) state. * * @param epAddr * The address of the endpoint to stall. * * @return * @ref USB_STATUS_OK on success, else an appropriate error code. ******************************************************************************/ int8_t USBD_StallEp(uint8_t epAddr); /***************************************************************************//** * @brief * Stop USB device stack operation. * * @details * The data-line pullup resistor is turned off, USB interrupts are disabled, * and finally the USB pins are disabled. ******************************************************************************/ void USBD_Stop(void); /***************************************************************************//** * @brief * Enters USB suspend mode * * @details * Disables USB transceiver, VDD Monitor, and prefetch engine. Suspends the * internal regulator and internal oscillator. * This function will not exit until the device recognizes resume signaling, * VBUS attachment/removal, or a remote wakeup source interrupt. * Before exiting, restores the states of the USB transceiver, * VDD Monitor, prefetch engine, and internal regulator. ******************************************************************************/ void USBD_Suspend(void); /***************************************************************************//** * @brief * Reset stall state on a stalled (halted) endpoint. * * @param epAddr * The address of the endpoint to un-stall. * * @return * @ref USB_STATUS_OK on success, else an appropriate error code. ******************************************************************************/ int8_t USBD_UnStallEp(uint8_t epAddr); /***************************************************************************//** * @brief * Start a write (IN) transfer on an endpoint. * * @param epAddr * Endpoint address. * * @param dat * Pointer to transfer data buffer. This buffer must be WORD (4 byte) aligned. * * @param byteCount * Transfer length. * * @param callback * Boolean to determine if USB_XferCompleteCb should be called for this * transfer. * * @return * @ref USB_STATUS_OK on success, else an appropriate error code. ******************************************************************************/ int8_t USBD_Write(uint8_t epAddr, SI_VARIABLE_SEGMENT_POINTER(dat, uint8_t, SI_SEG_GENERIC), uint16_t byteCount, bool callback); /** @} (end addtogroup efm8_api API Functions) */ /***************************************************************************//** * @addtogroup efm8_callbacks Callback Functions * @{ ******************************************************************************/ /***************************************************************************//** * @brief * USB Handler Entry callback function. * @details * Some systems may wish to be in a low-power state when between USB events. * This low-power state may configure the system clock to a very low * frequency. In order to reduce the execution time of the USB handler, this * function is called before the handler executes to allow the system to switch * to a higher clock source. When all USB processing is complete, * @ref USBD_ExitHandler() will be called to allow the system to return * to the low-power state. * This callback function is optionally enabled by setting * @ref SLAB_USB_HANDLER_CB to 1. ******************************************************************************/ void USBD_EnterHandler(void); /***************************************************************************//** * @brief * USB Handler Exit callback function. * @details * Some systems may wish to be in a low-power state when between USB events. * This low-power state may configure the system clock to a very low * frequency. This function is called after all USB processing is finished * to allow a system that was previously configured by * @ref USBD_EnterHandler() for high power to return to a low power state. * This callback function is optionally enabled by setting * @ref SLAB_USB_HANDLER_CB to 1. ******************************************************************************/ void USBD_ExitHandler(void); /***************************************************************************//** * @brief * USB Reset callback function. * @details * Called whenever USB reset signaling is detected on the USB port. ******************************************************************************/ void USBD_ResetCb(void); /***************************************************************************//** * @brief * USB Start Of Frame (SOF) interrupt callback function. * * @details * Called at each SOF interrupt (if enabled), * * @param sofNr * Current frame number. The value rolls over to 0 after 16383 (0x3FFF). ******************************************************************************/ void USBD_SofCb(uint16_t sofNr); /***************************************************************************//** * @brief * USB State change callback function. * * @details * Called whenever the USB state of the device changes * * @param oldState * The device USB state just left. See @ref USBD_State_TypeDef. * * @param newState * New (the current) USB device state. See @ref USBD_State_TypeDef. ******************************************************************************/ void USBD_DeviceStateChangeCb(USBD_State_TypeDef oldState, USBD_State_TypeDef newState); /***************************************************************************//** * @brief * USB power mode callback function. * * @details * Called whenever the device stack needs to know if the device is currently * self- or bus-powered. Typically when host has issued a @ref GET_STATUS * setup command. * * @return * True if self-powered, false otherwise. ******************************************************************************/ bool USBD_IsSelfPoweredCb(void); /***************************************************************************//** * @brief * USB setup request callback function. * * @details * Called on each setup request received from host. This gives the system a * possibility to extend or override standard requests, and to implement class * or vendor specific requests. Return @ref USB_STATUS_OK if the request is * handled, return @ref USB_STATUS_REQ_ERR if it is an illegal request or * return @ref USB_STATUS_REQ_UNHANDLED to pass the request on to the default * request handler. * * @param setup * Pointer to a USB setup packet. See @ref USB_Setup_TypeDef. * * @return * An appropriate status/error code. See @ref USB_Status_TypeDef. ******************************************************************************/ USB_Status_TypeDef USBD_SetupCmdCb(SI_VARIABLE_SEGMENT_POINTER(setup, USB_Setup_TypeDef, MEM_MODEL_SEG)); /***************************************************************************//** * @brief * USB set interface callback function. * * @details * Called each time the SET_INTERFACE request is made. * * @param interface * Number of the interface to set. * * @param altSetting * Alternate setting for the interface * * @return * @ref USB_STATUS_OK if the alternate interface is valid and can be set, * @ref USB_STATUS_REQ_ERR otherwise ******************************************************************************/ USB_Status_TypeDef USBD_SetInterfaceCb(uint8_t interface, uint8_t altSetting); /***************************************************************************//** * @brief * Queries the application to see if a remote wakeup occurred. * @details * If remote wakeup is enabled via @ref SLAB_USB_REMOTE_WAKEUP_ENABLED, the * USB library will query the application after waking from suspend to see if * the remote wakeup source was the reason for the wakeup. If this function * returns True, the library will call @ref USBD_RemoteWakeup() to wake up the * host and exit suspend mode. * @return * True if the remote wakeup source was the reason the device woke from * suspend, false otherwise. * ******************************************************************************/ bool USBD_RemoteWakeupCb(void); /***************************************************************************//** * @brief * Delays 10 - 15 ms while resume signaling is active during a remote * wakeup event * ******************************************************************************/ void USBD_RemoteWakeupDelay(void); /***************************************************************************//** * @brief * Processes USB events when the library is configured for polled mode * * @ details * The USB library can be configured for interrupt * (@ref SLAB_USB_POLLED_MODE == 0) or polled (@ref SLAB_USB_POLLED_MODE == 1) * mode. * * When in interrupt mode, the USB interrupt handler will trigger * when a USB event occurs. Callback functions will be called as needed. * * When in polled mode, the application must call USBD_Run() periodically to * check for and process USB events. This may be useful in complex systems or * when using an RTOS to perform all USB processing in the main loop instead * of in the interrupt context. * ******************************************************************************/ void USBD_Run(void); /***************************************************************************//** * @brief * USB transfer complete callback function. * * @details * Called each time a packet is sent on an IN endpoint or received on an * OUT endpoint. * * @param epAddr * Endpoint on which the transfer occurred * * @param status * Status of the endpoint * * @param xferred * For bulk, interrupt, and control transfers: * Number of bytes transferred since the last USBD_Write() or USBD_Read() * call. * For isochronous IN transfers: * This parameter is not used * For isochronous OUT transfers: * the number of bytes received in the last packet * * @param remaining * For bulk, interrupt, and control transfers: * Number of bytes left to send or receive on the endpoint * For isochronous transfers: * The current index into the circular buffer holding isochronous data * * @return * For bulk, interrupt, and control transfers: * '0' * For isochronous IN transfers: * the number of bytes to transmit in the next packet * For isochronous OUT ransfers: * '0' ******************************************************************************/ uint16_t USBD_XferCompleteCb(uint8_t epAddr, \ USB_Status_TypeDef status, \ uint16_t xferred, \ uint16_t remaining); /** @} (end addtogroup efm8_callbacks Callback Functions) */ /// @cond DO_NOT_INCLUDE_WITH_DOXYGEN // -------------------- FIFO Access Functions --------------------------------- void USB_ReadFIFO(uint8_t fifoNum, uint8_t numBytes, SI_VARIABLE_SEGMENT_POINTER(dat, uint8_t, SI_SEG_GENERIC)); void USB_WriteFIFO(uint8_t fifoNum, uint8_t numBytes, SI_VARIABLE_SEGMENT_POINTER(dat, uint8_t, SI_SEG_GENERIC), bool txPacket); /// @endcond DO_NOT_INCLUDE_WITH_DOXYGEN // -------------------- Include Files ------------------------------------------ // Error if peripheral driver not in use #include "usb_0.h" /** @} (end addtogroup Efm8_usb) */ #endif // __SILICON_LABS_EFM8_USB_H__