⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usb_framework.h

📁 reference about wireless design which is helpful to everyone
💻 H
📖 第 1 页 / 共 2 页
字号:
#ifndef USBFRAMEWORK_H
#define USBFRAMEWORK_H
/** \addtogroup module_usb_framework USB Framework (usbfw)
 * \brief This module contains USB status information, functions for initialization, USB device reset
 * handling, and most importantly, the framework for transfers on endpoint 0, FIFO access, and endpoint
 * control.
 *
 * \section section_init Framework Initialization
 * The framework and the USB peripheral unit can be initialized once the 48 MHz crystal oscillator is
 * running. This is done by \ref usbfwInit(), which:
 * \li Initializes framework variables
 * \li Enables the USB peripheral unit by setting the \c SLEEP.USB_EN bit
 * \li Enables the pull-up resistor via a GPIO pin
 *
 * When completing the last step, the host will be recognize the USB device, and start the enumeration
 * process. To reply to the shortly incoming standard requests, the call to \ref usbfwInit() must be
 * followed immediately by USB Interrupt \ref section_usbirq_initialization.
 *
 * \section section_endpoint_0_transfers Endpoint 0 Transfers
 * The USB interface uses endpoint 0 to perform setup requests of the standard, vendor and class types.
 * Such transfers consist of three phases:
 * - A setup phase, where an 8-byte \ref USB_SETUP_HEADER is transferred to the device.
 * - An IN/OUT data phase, if the length field of the \ref USB_SETUP_HEADER structure is non-zero.
 * - A handshake phase, where the application can stall the endpoint to indicate error conditions.
 *
 * The setup handler, \ref usbfwSetupHandler(), takes care of the low-level parts of these transfers,
 * including the IN/OUT buffering during the data phase (when there is one). The transfers fall into two
 * categories:
 * - Most standard requests can be processed internally, with little or no intervention form the user
 *   application. This is done internally by the \ref module_usb_standard_requests module.
 * - Vendor and class requests are application specific and must always be processed by the application.
 *   Whenever such a request is received, the following hooks will be called between the phases:
 *     - <tt>void usbcrHookProcessOut(void)</tt>: Class requests with OUT data phase
 *     - <tt>void usbcrHookProcessIn(void)</tt>: Class requests with IN data phase
 *     - <tt>void usbvrHookProcessOut(void)</tt>: Vendor requests with OUT data phase
 *     - <tt>void usbvrHookProcessIn(void)</tt>: Vendor requests with IN data phase
 *
 * \section section_setup_handler_usage Setup Handler Usage
 * This section describes what is required to make the vendor and class request hooks work. This
 * information also applies to the standard requests that needs application processing
 * (\ref usbsrHookSetDescriptor(), \ref usbsrHookSynchFrame(), and some cases of
 * \ref usbsrHookSetFeature() and \ref usbsrHookClearFeature()).
 *
 * The transactions are made using a clean and efficient interface, consisting of two data structures and
 * the endpoint 0 status byte:
 * - The endpoint status is initially \ref EP_IDLE, which basically means that the setup handler is ready
 *   for a new setup phase (a new request). Upon an incoming request, the processing hook is called, and
 *   the \ref usbSetupHeader structure contains the 8 bytes received during the setup phase. At this
 *   point there are four different outcomes:
 *     - If the request is unknown or contains errors, the endpoint should be stalled. This is done by
 *       setting the endpoint status to \ref EP_STALL.
 *     - If there is no data phase (the length field is zero), the endpoint status should just remain in
 *       it's current state, \ref EP_IDLE.
 *     - If the request has an IN data phase, the \ref usbSetupData structure must be prepared. This
 *       includes setting a pointer to where IN data should be taken from, and the number of bytes to be
 *       transferred (usually the same number as indicated by the length field, but it can also be a
 *       lower number). The endpoint state is then changed to \ref EP_TX.
 *     - If the request has an OUT data phase, the \ref usbSetupData structure must be prepared. This
 *       includes setting a pointer to where OUT data should be stored, and the number of bytes to be
 *       transferred (always the same number as indicated by the length field). The endpoint state is
 *       then changed to \ref EP_RX.
 * - When the data phase is complete, the processing hook will be called a second time to notify the
 *   application. Under normal conditions the endpoint status will be either \ref EP_TX or \ref EP_RX,
 *   and does not need to be changed any further (as this is done automatically upon return). If the
 *   endpoint status is \ref EP_CANCEL, it means that the USB host cancelled the setup transfer.
 *
 * The following code examples illustrate practical usage (more code is available in the application
 * example projects):
 *
 * \par Example 1: Endpoint 0 Requests With OUT Data phase
 *
 * \code
 * BYTE pLcdBuffer[358];
 *
 * void usbvrHookProcessOut(void) {
 *
 *    // When this vendor request is received, we should either update a part of pLcdBuffer[] or leave
 *    // it as it is, and then refresh the LCD display. The index field of the setup header contains the
 *    // index of the first character to be updated, and the length field how many characters to update.
 *    if (usbSetupHeader.request == VR_LCD_UPDATE) {
 *
 *       // First the endpoint status is EP_IDLE...
 *       if (usbfwData.ep0Status == EP_IDLE) {
 *
 *          // There is no new data -> Just refresh the display
 *          if (usbSetupHeader.length == 0) {
 *             lcdRefresh();
 *             // There is no change to the endpoint status in this case
 *
 *          // The PC wants to send data that will be stored outside pLcdBuffer -> stall the endpoint!
 *          } else if ((usbSetupHeader.length > sizeof(pTextBuffer) ||
 *                     (usbSetupHeader.index >= sizeof(pTextBuffer) ||
 *                     ((usbSetupHeader.index + usbSetupHeader.length) > sizeof(pTextBuffer)) {
 *             usbfwData.ep0Status = EP_STALL;
 *
 *          // Setup the buffer
 *          } else {
 *             usbSetupData.pBuffer = &pLcdBuffer[usbSetupHeader.index];
 *             usbSetupData.bytesLeft = usbSetupHeader.length;
 *             usbfwData.ep0Status = EP_RX;
 *          }
 *
 *       // Then the endpoint status is EP_RX (remember: we did that here when setting up the buffer)
 *       } else if (usbfwData.ep0Status == EP_RX) {
 *          // usbfwSetupHandler() has now updated pLcdBuffer, so all we need to do is refresh the LCD
 *          lcdRefresh();
 *          // usbfwData.ep0Status is automatically reset to EP_IDLE when returning to usbfwSetupHandler()
 *       }
 *
 *    // Unknown request?
 *    } else {
 *       usbfwData.ep0Status = EP_STALL;
 *    }
 * }
 * \endcode
 *
 * \par Example 2: Endpoint 0 Requests With IN Data phase
 *
 * \code
 * UINT8 keyBufferPos;
 * BOOL blockKeyboard;
 * char pKeyBuffer[150];
 *
 * void usbvrProcessIn(void) {
 *
 *    // When this vendor request is received, we should send all registered key-strokes, and reset the
 *    // position counter. New keystrokes are blocked during the transfer to avoid overwriting the buffer
 *    // before it has been sent to the host.
 *    if (usbSetupHeader.request == VR_GET_KEYS) {
 *
 *       // First the endpoint status is EP_IDLE...
 *       if (usbfwData.ep0Status == EP_IDLE) {
 *
 *          // Make sure that we do not send more than the PC asked for
 *          if (usbSetupHeader.length < keyBufferPos) {
 *             usbfwData.ep0Status = EP_STALL;
 *
 *          // Otherwise... , and reset the position counter
 *          } else {
 *             // Block for new keystrokes
 *             blockKeyboard = TRUE;
 *
 *             // Setup the buffer
 *             usbSetupData.pBuffer = pKeyBuffer;
 *             usbSetupData.bytesLeft = keyBufferPos;
 *             usbfwData.ep0Status = EP_TX;
 *
 *             // Reset the position counter
 *             keyBufferPos = 0;
 *          }
 *
 *       // Then the endpoint status is EP_TX (remember: we did that here when setting up the buffer)
 *       } else if (usbfwData.ep0Status == EP_TX) {
 *
 *          // pKeyBuffer has now been sent to the host, so new keystrokes can safely be registered
 *          blockKeyboard = FALSE;
 *
 *          // usbfwData.ep0Status is automatically reset to EP_IDLE when returning to usbfwSetupHandler()
 *       }
 *
 *    // Unknown request?
 *    } else {
 *       usbfwData.ep0Status = EP_STALL;
 *    }
 * }
 * \endcode
 *
 * If automated data transfer is not desired, the application should set \c USBFW_DATA.ep0Status to
 * either \ref EP_MANUAL_RX or \ref EP_MANUAL_TX instead of \ref EP_RX or \ref EP_TX, respectively. Until
 * the transfer is completed, the processing function (e.g. \ref usbvrHookProcessIn()) will be called at
 * every endpoint 0 interrupt.
 * @{
 */
#include "cc2511_usb_library_headers.h"


#ifdef EXTERN
   #undef EXTERN
#endif
#ifdef USBFRAMEWORK_C
   #define EXTERN
#else
   #define EXTERN extern
#endif


//-------------------------------------------------------------------------------------------------------
/// \name Bus Pull-Up Control
//@{
///Enable pull-up on D+
#define USB_ENABLE_PULLUP()       do { P1_0 = 1; P1DIR |= 0x01; } while (0)

///Disable pull-up on D+
#define USB_DISABLE_PULLUP()       do { P1DIR &= ~0x01; } while (0)
//@}
//-------------------------------------------------------------------------------------------------------


//-------------------------------------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -