SAM3S8/SD8 Software Package: libraries/usb/device/core/USBD.c Source File

SAM3S8/SD8 Software Package 1.2

# USBD.c

Go to the documentation of this file.

    00001 /* ----------------------------------------------------------------------------
    00002  *         ATMEL Microcontroller Software Support
    00003  * ----------------------------------------------------------------------------
    00004  * Copyright (c) 2008, Atmel Corporation
    00005  *
    00006  * All rights reserved.
    00007  *
    00008  * Redistribution and use in source and binary forms, with or without
    00009  * modification, are permitted provided that the following conditions are met:
    00010  *
    00011  * - Redistributions of source code must retain the above copyright notice,
    00012  * this list of conditions and the disclaimer below.
    00013  *
    00014  * Atmel's name may not be used to endorse or promote products derived from
    00015  * this software without specific prior written permission.
    00016  *
    00017  * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
    00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
    00019  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
    00020  * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
    00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    00022  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
    00023  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
    00024  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
    00025  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
    00026  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    00027  * ----------------------------------------------------------------------------
    00028  */
    00029
    00030 /** \file
    00031  *
    00032  *  \section Purpose
    00033  *
    00034  *  Implementation of USB device functions on a UDP controller.
    00035  *
    00036  *  See \ref usbd_api "USBD API Methods".
    00037  */
    00038
    00039 /** \addtogroup usbd_interface
    00040  *@{
    00041  */
    00042
    00043 /*---------------------------------------------------------------------------
    00044  *      Headers
    00045  *---------------------------------------------------------------------------*/
    00046 #include "board.h"
    00047 #include "USBD.h"
    00048 #include "USBD_HAL.h"
    00049
    00050 //#include <USBLib_Trace.h>
    00051
    00052 /*---------------------------------------------------------------------------
    00053  *      Definitions
    00054  *---------------------------------------------------------------------------*/
    00055
    00056 /*---------------------------------------------------------------------------
    00057  *      Internal variables
    00058  *---------------------------------------------------------------------------*/
    00059
    00060 /** Device current state. */
    00061 static uint8_t deviceState;
    00062 /** Indicates the previous device state */
    00063 static uint8_t previousDeviceState;
    00064
    00065 /*---------------------------------------------------------------------------
    00066  *      Internal Functions
    00067  *---------------------------------------------------------------------------*/
    00068
    00069 /*---------------------------------------------------------------------------
    00070  *      Exported functions
    00071  *---------------------------------------------------------------------------*/
    00072
    00073 /*---------------------------------------------------------------------------
    00074  *      USBD: Event handlers
    00075  *---------------------------------------------------------------------------*/
    00076
    00077 /**
    00078  *  Handle the USB suspend event, should be invoked whenever
    00079  *  HW reports a suspend signal.
    00080  */
    00081 void USBD_SuspendHandler(void)
    00082 {
    00083     /* Don't do anything if the device is already suspended */
    00084     if (deviceState != USBD_STATE_SUSPENDED) {
    00085
    00086         /* Switch to the Suspended state */
    00087         previousDeviceState = deviceState;
    00088         deviceState = USBD_STATE_SUSPENDED;
    00089
    00090         /* Suspend HW interface */
    00091         USBD_HAL_Suspend();
    00092
    00093         /* Invoke the User Suspended callback (Suspend System?) */
    00094         if (USBDCallbacks_Suspended)
    00095             USBDCallbacks_Suspended();
    00096     }
    00097 }
    00098
    00099 /**
    00100  *  Handle the USB resume event, should be invoked whenever
    00101  *  HW reports a resume signal.
    00102  */
    00103 void USBD_ResumeHandler(void)
    00104 {
    00105     /* Don't do anything if the device was not suspended */
    00106     if (deviceState == USBD_STATE_SUSPENDED) {
    00107         /* Active the device */
    00108         USBD_HAL_Activate();
    00109         deviceState = previousDeviceState;
    00110         if (deviceState >= USBD_STATE_DEFAULT) {
    00111             /* Invoke the Resume callback */
    00112             if (USBDCallbacks_Resumed)
    00113                 USBDCallbacks_Resumed();
    00114         }
    00115     }
    00116 }
    00117
    00118 /**
    00119  *  Handle the USB reset event, should be invoked whenever
    00120  *  HW found USB reset signal on bus, which usually is called
    00121  *  "end of bus reset" status.
    00122  */
    00123 void USBD_ResetHandler()
    00124 {
    00125     /* The device enters the Default state */
    00126     deviceState = USBD_STATE_DEFAULT;
    00127     /* Active the USB HW */
    00128     USBD_HAL_Activate();
    00129     /* Only EP0 enabled */
    00130     USBD_HAL_ResetEPs(0xFFFFFFFF, USBD_STATUS_RESET, 0);
    00131     USBD_ConfigureEndpoint(0);
    00132     /* Invoke the Reset callback */
    00133     if (USBDCallbacks_Reset)
    00134         USBDCallbacks_Reset();
    00135 }
    00136
    00137 /**
    00138  *  Handle the USB setup package received, should be invoked
    00139  *  when an endpoint got a setup package as request.
    00140  *  \param bEndpoint Endpoint number.
    00141  *  \param pRequest  Pointer to content of request.
    00142  */
    00143 void USBD_RequestHandler(uint8_t bEndpoint,
    00144                          const USBGenericRequest* pRequest)
    00145 {
    00146     if (bEndpoint != 0) {
    00147         TRACE_WARNING("EP%d request not supported, default EP only",
    00148                       bEndpoint);
    00149     }
    00150     else if (USBDCallbacks_RequestReceived) {
    00151         USBDCallbacks_RequestReceived(pRequest);
    00152     }
    00153 }
    00154
    00155 /*---------------------------------------------------------------------------
    00156  *      USBD: Library interface
    00157  *---------------------------------------------------------------------------*/
    00158
    00159 /**
    00160  * Configures an endpoint according to its Endpoint Descriptor.
    00161  * \param pDescriptor Pointer to an Endpoint descriptor.
    00162  */
    00163 void USBD_ConfigureEndpoint(const USBEndpointDescriptor *pDescriptor)
    00164 {
    00165     USBD_HAL_ConfigureEP(pDescriptor);
    00166 }
    00167
    00168 /**
    00169  * Sends data through a USB endpoint. Sets up the transfer descriptor,
    00170  * writes one or two data payloads (depending on the number of FIFO bank
    00171  * for the endpoint) and then starts the actual transfer. The operation is
    00172  * complete when all the data has been sent.
    00173  *
    00174  * *If the size of the buffer is greater than the size of the endpoint
    00175  *  (or twice the size if the endpoint has two FIFO banks), then the buffer
    00176  *  must be kept allocated until the transfer is finished*. This means that
    00177  *  it is not possible to declare it on the stack (i.e. as a local variable
    00178  *  of a function which returns after starting a transfer).
    00179  *
    00180  * \param bEndpoint Endpoint number.
    00181  * \param pData Pointer to a buffer with the data to send.
    00182  * \param dLength Size of the data buffer.
    00183  * \param fCallback Optional callback function to invoke when the transfer is
    00184  *        complete.
    00185  * \param pArgument Optional argument to the callback function.
    00186  * \return USBD_STATUS_SUCCESS if the transfer has been started;
    00187  *         otherwise, the corresponding error status code.
    00188  */
    00189 uint8_t USBD_Write( uint8_t          bEndpoint,
    00190                     const void       *pData,
    00191                     uint32_t         dLength,
    00192                     TransferCallback fCallback,
    00193                     void             *pArgument )
    00194 {
    00195     USBD_HAL_SetTransferCallback(bEndpoint, fCallback, pArgument);
    00196     return USBD_HAL_Write(bEndpoint, pData, dLength);
    00197 }
    00198 /**
    00199  * Reads incoming data on an USB endpoint This methods sets the transfer
    00200  * descriptor and activate the endpoint interrupt. The actual transfer is
    00201  * then carried out by the endpoint interrupt handler. The Read operation
    00202  * finishes either when the buffer is full, or a short packet (inferior to
    00203  * endpoint maximum  size) is received.
    00204  *
    00205  * *The buffer must be kept allocated until the transfer is finished*.
    00206  * \param bEndpoint Endpoint number.
    00207  * \param pData Pointer to a data buffer.
    00208  * \param dLength Size of the data buffer in bytes.
    00209  * \param fCallback Optional end-of-transfer callback function.
    00210  * \param pArgument Optional argument to the callback function.
    00211  * \return USBD_STATUS_SUCCESS if the read operation has been started;
    00212  *         otherwise, the corresponding error code.
    00213  */
    00214 uint8_t USBD_Read(uint8_t          bEndpoint,
    00215                   void             *pData,
    00216                   uint32_t         dLength,
    00217                   TransferCallback fCallback,
    00218                   void             *pArgument)
    00219 {
    00220     USBD_HAL_SetTransferCallback(bEndpoint, fCallback, pArgument);
    00221     return USBD_HAL_Read(bEndpoint, pData, dLength);
    00222 }
    00223 /**
    00224  * Sets the HALT feature on the given endpoint (if not already in this state).
    00225  * \param bEndpoint Endpoint number.
    00226  */
    00227 void USBD_Halt(uint8_t bEndpoint)
    00228 {
    00229     USBD_HAL_Halt(bEndpoint, 1);
    00230 }
    00231
    00232 /**
    00233  * Clears the Halt feature on the given endpoint.
    00234  * \param bEndpoint Index of endpoint
    00235  */
    00236 void USBD_Unhalt(uint8_t bEndpoint)
    00237 {
    00238     USBD_HAL_Halt(bEndpoint, 0);
    00239 }
    00240
    00241 /**
    00242  * Returns the current Halt status of an endpoint.
    00243  * \param bEndpoint Index of endpoint
    00244  * \return 1 if the endpoint is currently halted; otherwise 0
    00245  */
    00246 uint8_t USBD_IsHalted(uint8_t bEndpoint)
    00247 {
    00248     return USBD_HAL_Halt(bEndpoint, 0xFF);
    00249 }
    00250
    00251 /**
    00252  * Indicates if the device is running in high or full-speed. Always returns 0
    00253  * since UDP does not support high-speed mode.
    00254  */
    00255 uint8_t USBD_IsHighSpeed(void)
    00256 {
    00257     return USBD_HAL_IsHighSpeed();
    00258 }
    00259
    00260 /**
    00261  * Causes the given endpoint to acknowledge the next packet it receives
    00262  * with a STALL handshake.
    00263  * \param bEndpoint Endpoint number.
    00264  * \return USBD_STATUS_SUCCESS or USBD_STATUS_LOCKED.
    00265  */
    00266 uint8_t USBD_Stall(uint8_t bEndpoint)
    00267
    00268 {
    00269     return USBD_HAL_Stall(bEndpoint);
    00270 }
    00271
    00272 /**
    00273  * Sets the device address to the given value.
    00274  * \param address New device address.
    00275  */
    00276 void USBD_SetAddress(uint8_t address)
    00277 {
    00278     TRACE_INFO_WP("SetAddr(%d) ", address);
    00279
    00280     USBD_HAL_SetAddress(address);
    00281     if (address == 0) deviceState = USBD_STATE_DEFAULT;
    00282     else              deviceState = USBD_STATE_ADDRESS;
    00283 }
    00284
    00285 /**
    00286  * Sets the current device configuration.
    00287  * \param cfgnum - Configuration number to set.
    00288  */
    00289 void USBD_SetConfiguration(uint8_t cfgnum)
    00290 {
    00291     TRACE_INFO_WP("SetCfg(%d) ", cfgnum);
    00292
    00293     USBD_HAL_SetConfiguration(cfgnum);
    00294
    00295     if (cfgnum != 0) {
    00296         deviceState = USBD_STATE_CONFIGURED;
    00297     }
    00298     else {
    00299         deviceState = USBD_STATE_ADDRESS;
    00300         /* Reset all endpoints */
    00301         USBD_HAL_ResetEPs(0xFFFFFFFF, USBD_STATUS_RESET, 0);
    00302     }
    00303 }
    00304
    00305 /*---------------------------------------------------------------------------
    00306  *      USBD: Library API
    00307  *---------------------------------------------------------------------------*/
    00308
    00309 /**
    00310  * Starts a remote wake-up procedure.
    00311  */
    00312 void USBD_RemoteWakeUp(void)
    00313 {
    00314     /* Device is NOT suspended */
    00315     if (deviceState != USBD_STATE_SUSPENDED) {
    00316
    00317         TRACE_INFO("USBD_RemoteWakeUp: Device is not suspended\n\r");
    00318         return;
    00319     }
    00320     USBD_HAL_Activate();
    00321     USBD_HAL_RemoteWakeUp();
    00322 }
    00323
    00324 /**
    00325  * Connects the pull-up on the D+ line of the USB.
    00326  */
    00327 void USBD_Connect(void)
    00328 {
    00329     USBD_HAL_Connect();
    00330 }
    00331
    00332 /**
    00333  * Disconnects the pull-up from the D+ line of the USB.
    00334  */
    00335 void USBD_Disconnect(void)
    00336 {
    00337     USBD_HAL_Disconnect();
    00338
    00339     /* Device returns to the Powered state */
    00340
    00341     if (deviceState > USBD_STATE_POWERED) {
    00342
    00343         deviceState = USBD_STATE_POWERED;
    00344     }
    00345
    00346     if (previousDeviceState > USBD_STATE_POWERED) {
    00347
    00348         previousDeviceState = USBD_STATE_POWERED;
    00349     }
    00350 }
    00351
    00352 /**
    00353  * Initializes the USB driver.
    00354  */
    00355 void USBD_Init(void)
    00356 {
    00357     TRACE_INFO_WP("USBD_Init\n\r");
    00358
    00359     /* HW Layer Initialize */
    00360     USBD_HAL_Init();
    00361
    00362     /* Device is in the Attached state */
    00363     deviceState = USBD_STATE_SUSPENDED;
    00364     previousDeviceState = USBD_STATE_POWERED;
    00365
    00366     /* Upper Layer Initialize */
    00367     if (USBDCallbacks_Initialized)
    00368         USBDCallbacks_Initialized();
    00369 }
    00370
    00371 /**
    00372  * Returns the current state of the USB device.
    00373  * \return Device current state.
    00374  */
    00375 uint8_t USBD_GetState(void)
    00376 {
    00377     return deviceState;
    00378 }
    00379
    00380 /**@}*/

All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines