USBDevice with MAX32620HSP platform support

Fork of USBDevice by mbed official

Committer:
mbed_official
Date:
Thu Aug 13 15:46:06 2015 +0100
Revision:
59:2af474687369
Synchronized with git revision 376d6a73e345b728a788041adb166b08cd8d2b95

Full URL: https://github.com/mbedmicro/mbed/commit/376d6a73e345b728a788041adb166b08cd8d2b95/

Silicon Labs - Add support for USBDevice

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 59:2af474687369 1 /**************************************************************************//**
mbed_official 59:2af474687369 2 * @file em_usbd.c
mbed_official 59:2af474687369 3 * @brief USB protocol stack library, device API.
mbed_official 59:2af474687369 4 * @version 3.20.14
mbed_official 59:2af474687369 5 ******************************************************************************
mbed_official 59:2af474687369 6 * @section License
mbed_official 59:2af474687369 7 * <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
mbed_official 59:2af474687369 8 *******************************************************************************
mbed_official 59:2af474687369 9 *
mbed_official 59:2af474687369 10 * Licensed under the Apache License, Version 2.0 (the "License");
mbed_official 59:2af474687369 11 * you may not use this file except in compliance with the License.
mbed_official 59:2af474687369 12 * You may obtain a copy of the License at
mbed_official 59:2af474687369 13 *
mbed_official 59:2af474687369 14 * http://www.apache.org/licenses/LICENSE-2.0
mbed_official 59:2af474687369 15 *
mbed_official 59:2af474687369 16 * Unless required by applicable law or agreed to in writing, software
mbed_official 59:2af474687369 17 * distributed under the License is distributed on an "AS IS" BASIS,
mbed_official 59:2af474687369 18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mbed_official 59:2af474687369 19 * See the License for the specific language governing permissions and
mbed_official 59:2af474687369 20 * limitations under the License.
mbed_official 59:2af474687369 21 *
mbed_official 59:2af474687369 22 ******************************************************************************/
mbed_official 59:2af474687369 23
mbed_official 59:2af474687369 24 #include "em_device.h"
mbed_official 59:2af474687369 25 #if defined( USB_PRESENT ) && ( USB_COUNT == 1 )
mbed_official 59:2af474687369 26 #include "em_usb.h"
mbed_official 59:2af474687369 27 #if defined( USB_DEVICE )
mbed_official 59:2af474687369 28
mbed_official 59:2af474687369 29 #include "em_cmu.h"
mbed_official 59:2af474687369 30 #include "em_usbtypes.h"
mbed_official 59:2af474687369 31 #include "em_usbhal.h"
mbed_official 59:2af474687369 32 #include "em_usbd.h"
mbed_official 59:2af474687369 33
mbed_official 59:2af474687369 34 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
mbed_official 59:2af474687369 35
mbed_official 59:2af474687369 36 static USBD_Device_TypeDef device;
mbed_official 59:2af474687369 37 USBD_Device_TypeDef *dev = &device;
mbed_official 59:2af474687369 38
mbed_official 59:2af474687369 39 static uint32_t totalRxFifoSize = 0, totalTxFifoSize = 0;
mbed_official 59:2af474687369 40 static int numEps = 0;
mbed_official 59:2af474687369 41 static int txFifoNum = 1;
mbed_official 59:2af474687369 42
mbed_official 59:2af474687369 43 static void USBD_ResetEndpoints(void);
mbed_official 59:2af474687369 44 extern USB_Status_TypeDef USBDHAL_ReconfigureFifos( uint32_t totalRxFifoSize,
mbed_official 59:2af474687369 45 uint32_t totalTxFifoSize );
mbed_official 59:2af474687369 46 #ifndef __MBED__
mbed_official 59:2af474687369 47 static const char *stateNames[] =
mbed_official 59:2af474687369 48 {
mbed_official 59:2af474687369 49 [ USBD_STATE_NONE ] = "NONE ",
mbed_official 59:2af474687369 50 [ USBD_STATE_ATTACHED ] = "ATTACHED ",
mbed_official 59:2af474687369 51 [ USBD_STATE_POWERED ] = "POWERED ",
mbed_official 59:2af474687369 52 [ USBD_STATE_DEFAULT ] = "DEFAULT ",
mbed_official 59:2af474687369 53 [ USBD_STATE_ADDRESSED ] = "ADDRESSED ",
mbed_official 59:2af474687369 54 [ USBD_STATE_CONFIGURED ] = "CONFIGURED",
mbed_official 59:2af474687369 55 [ USBD_STATE_SUSPENDED ] = "SUSPENDED ",
mbed_official 59:2af474687369 56 [ USBD_STATE_LASTMARKER ] = "UNDEFINED "
mbed_official 59:2af474687369 57 };
mbed_official 59:2af474687369 58 #endif
mbed_official 59:2af474687369 59
mbed_official 59:2af474687369 60 /** @endcond */
mbed_official 59:2af474687369 61
mbed_official 59:2af474687369 62 /***************************************************************************//**
mbed_official 59:2af474687369 63 * @brief
mbed_official 59:2af474687369 64 * Abort all pending transfers.
mbed_official 59:2af474687369 65 *
mbed_official 59:2af474687369 66 * @details
mbed_official 59:2af474687369 67 * Aborts transfers for all endpoints currently in use. Pending
mbed_official 59:2af474687369 68 * transfers on the default endpoint (EP0) are not aborted.
mbed_official 59:2af474687369 69 ******************************************************************************/
mbed_official 59:2af474687369 70 void USBD_AbortAllTransfers( void )
mbed_official 59:2af474687369 71 {
mbed_official 59:2af474687369 72 INT_Disable();
mbed_official 59:2af474687369 73 USBDHAL_AbortAllTransfers( USB_STATUS_EP_ABORTED );
mbed_official 59:2af474687369 74 INT_Enable();
mbed_official 59:2af474687369 75 }
mbed_official 59:2af474687369 76
mbed_official 59:2af474687369 77 /***************************************************************************//**
mbed_official 59:2af474687369 78 * @brief
mbed_official 59:2af474687369 79 * Abort a pending transfer on a specific endpoint.
mbed_official 59:2af474687369 80 *
mbed_official 59:2af474687369 81 * @param[in] epAddr
mbed_official 59:2af474687369 82 * The address of the endpoint to abort.
mbed_official 59:2af474687369 83 ******************************************************************************/
mbed_official 59:2af474687369 84 int USBD_AbortTransfer( int epAddr )
mbed_official 59:2af474687369 85 {
mbed_official 59:2af474687369 86 USB_XferCompleteCb_TypeDef callback;
mbed_official 59:2af474687369 87 USBD_Ep_TypeDef *ep = USBD_GetEpFromAddr( epAddr );
mbed_official 59:2af474687369 88
mbed_official 59:2af474687369 89 if ( ep == NULL )
mbed_official 59:2af474687369 90 {
mbed_official 59:2af474687369 91 DEBUG_USB_API_PUTS( "\nUSBD_AbortTransfer(), Illegal endpoint" );
mbed_official 59:2af474687369 92 EFM_ASSERT( false );
mbed_official 59:2af474687369 93 return USB_STATUS_ILLEGAL;
mbed_official 59:2af474687369 94 }
mbed_official 59:2af474687369 95
mbed_official 59:2af474687369 96 if ( ep->num == 0 )
mbed_official 59:2af474687369 97 {
mbed_official 59:2af474687369 98 DEBUG_USB_API_PUTS( "\nUSBD_AbortTransfer(), Illegal endpoint" );
mbed_official 59:2af474687369 99 EFM_ASSERT( false );
mbed_official 59:2af474687369 100 return USB_STATUS_ILLEGAL;
mbed_official 59:2af474687369 101 }
mbed_official 59:2af474687369 102
mbed_official 59:2af474687369 103 INT_Disable();
mbed_official 59:2af474687369 104 if ( ep->state == D_EP_IDLE )
mbed_official 59:2af474687369 105 {
mbed_official 59:2af474687369 106 INT_Enable();
mbed_official 59:2af474687369 107 return USB_STATUS_OK;
mbed_official 59:2af474687369 108 }
mbed_official 59:2af474687369 109
mbed_official 59:2af474687369 110 USBD_AbortEp( ep );
mbed_official 59:2af474687369 111
mbed_official 59:2af474687369 112 ep->state = D_EP_IDLE;
mbed_official 59:2af474687369 113 if ( ep->xferCompleteCb )
mbed_official 59:2af474687369 114 {
mbed_official 59:2af474687369 115 callback = ep->xferCompleteCb;
mbed_official 59:2af474687369 116 ep->xferCompleteCb = NULL;
mbed_official 59:2af474687369 117
mbed_official 59:2af474687369 118 if ( ( dev->lastState == USBD_STATE_CONFIGURED ) &&
mbed_official 59:2af474687369 119 ( dev->state == USBD_STATE_ADDRESSED ) )
mbed_official 59:2af474687369 120 {
mbed_official 59:2af474687369 121 USBDHAL_DeactivateEp( ep );
mbed_official 59:2af474687369 122 }
mbed_official 59:2af474687369 123
mbed_official 59:2af474687369 124 DEBUG_TRACE_ABORT( USB_STATUS_EP_ABORTED );
mbed_official 59:2af474687369 125 callback( USB_STATUS_EP_ABORTED, ep->xferred, ep->remaining );
mbed_official 59:2af474687369 126 }
mbed_official 59:2af474687369 127
mbed_official 59:2af474687369 128 INT_Enable();
mbed_official 59:2af474687369 129 return USB_STATUS_OK;
mbed_official 59:2af474687369 130 }
mbed_official 59:2af474687369 131
mbed_official 59:2af474687369 132 /***************************************************************************//**
mbed_official 59:2af474687369 133 * @brief
mbed_official 59:2af474687369 134 * Start USB device operation.
mbed_official 59:2af474687369 135 *
mbed_official 59:2af474687369 136 * @details
mbed_official 59:2af474687369 137 * Device operation is started by connecting a pullup resistor on the
mbed_official 59:2af474687369 138 * appropriate USB data line.
mbed_official 59:2af474687369 139 ******************************************************************************/
mbed_official 59:2af474687369 140 void USBD_Connect( void )
mbed_official 59:2af474687369 141 {
mbed_official 59:2af474687369 142 INT_Disable();
mbed_official 59:2af474687369 143 USBDHAL_Connect();
mbed_official 59:2af474687369 144 INT_Enable();
mbed_official 59:2af474687369 145 }
mbed_official 59:2af474687369 146
mbed_official 59:2af474687369 147 /***************************************************************************//**
mbed_official 59:2af474687369 148 * @brief
mbed_official 59:2af474687369 149 * Stop USB device operation.
mbed_official 59:2af474687369 150 *
mbed_official 59:2af474687369 151 * @details
mbed_official 59:2af474687369 152 * Device operation is stopped by disconnecting the pullup resistor from the
mbed_official 59:2af474687369 153 * appropriate USB data line. Often referred to as a "soft" disconnect.
mbed_official 59:2af474687369 154 ******************************************************************************/
mbed_official 59:2af474687369 155 void USBD_Disconnect( void )
mbed_official 59:2af474687369 156 {
mbed_official 59:2af474687369 157 INT_Disable();
mbed_official 59:2af474687369 158 USBDHAL_Disconnect();
mbed_official 59:2af474687369 159 INT_Enable();
mbed_official 59:2af474687369 160 }
mbed_official 59:2af474687369 161
mbed_official 59:2af474687369 162 /***************************************************************************//**
mbed_official 59:2af474687369 163 * @brief
mbed_official 59:2af474687369 164 * Check if an endpoint is busy doing a transfer.
mbed_official 59:2af474687369 165 *
mbed_official 59:2af474687369 166 * @param[in] epAddr
mbed_official 59:2af474687369 167 * The address of the endpoint to check.
mbed_official 59:2af474687369 168 *
mbed_official 59:2af474687369 169 * @return
mbed_official 59:2af474687369 170 * True if endpoint is busy, false otherwise.
mbed_official 59:2af474687369 171 ******************************************************************************/
mbed_official 59:2af474687369 172 bool USBD_EpIsBusy( int epAddr )
mbed_official 59:2af474687369 173 {
mbed_official 59:2af474687369 174 USBD_Ep_TypeDef *ep = USBD_GetEpFromAddr( epAddr );
mbed_official 59:2af474687369 175
mbed_official 59:2af474687369 176 if ( ep == NULL )
mbed_official 59:2af474687369 177 {
mbed_official 59:2af474687369 178 DEBUG_USB_API_PUTS( "\nUSBD_EpIsBusy(), Illegal endpoint" );
mbed_official 59:2af474687369 179 EFM_ASSERT( false );
mbed_official 59:2af474687369 180 return USB_STATUS_ILLEGAL;
mbed_official 59:2af474687369 181 }
mbed_official 59:2af474687369 182
mbed_official 59:2af474687369 183 if ( ep->state == D_EP_IDLE )
mbed_official 59:2af474687369 184 return false;
mbed_official 59:2af474687369 185
mbed_official 59:2af474687369 186 return true;
mbed_official 59:2af474687369 187 }
mbed_official 59:2af474687369 188
mbed_official 59:2af474687369 189 /***************************************************************************//**
mbed_official 59:2af474687369 190 * @brief
mbed_official 59:2af474687369 191 * Get current USB device state.
mbed_official 59:2af474687369 192 *
mbed_official 59:2af474687369 193 * @return
mbed_official 59:2af474687369 194 * Device USB state. See @ref USBD_State_TypeDef.
mbed_official 59:2af474687369 195 ******************************************************************************/
mbed_official 59:2af474687369 196 USBD_State_TypeDef USBD_GetUsbState( void )
mbed_official 59:2af474687369 197 {
mbed_official 59:2af474687369 198 return dev->state;
mbed_official 59:2af474687369 199 }
mbed_official 59:2af474687369 200
mbed_official 59:2af474687369 201 /***************************************************************************//**
mbed_official 59:2af474687369 202 * @brief
mbed_official 59:2af474687369 203 * Get a string naming a device USB state.
mbed_official 59:2af474687369 204 *
mbed_official 59:2af474687369 205 * @param[in] state
mbed_official 59:2af474687369 206 * Device USB state. See @ref USBD_State_TypeDef.
mbed_official 59:2af474687369 207 *
mbed_official 59:2af474687369 208 * @return
mbed_official 59:2af474687369 209 * State name string pointer.
mbed_official 59:2af474687369 210 ******************************************************************************/
mbed_official 59:2af474687369 211 const char *USBD_GetUsbStateName( USBD_State_TypeDef state )
mbed_official 59:2af474687369 212 {
mbed_official 59:2af474687369 213 if ( state > USBD_STATE_LASTMARKER )
mbed_official 59:2af474687369 214 state = USBD_STATE_LASTMARKER;
mbed_official 59:2af474687369 215
mbed_official 59:2af474687369 216 #ifndef __MBED__
mbed_official 59:2af474687369 217 return stateNames[ state ];
mbed_official 59:2af474687369 218 #else
mbed_official 59:2af474687369 219 return NULL;
mbed_official 59:2af474687369 220 #endif
mbed_official 59:2af474687369 221 }
mbed_official 59:2af474687369 222
mbed_official 59:2af474687369 223 /***************************************************************************//**
mbed_official 59:2af474687369 224 * @brief
mbed_official 59:2af474687369 225 * Initializes USB device hardware and internal protocol stack data structures,
mbed_official 59:2af474687369 226 * then connects the data-line (D+ or D-) pullup resistor to signal host that
mbed_official 59:2af474687369 227 * enumeration can begin.
mbed_official 59:2af474687369 228 *
mbed_official 59:2af474687369 229 * @note
mbed_official 59:2af474687369 230 * You may later use @ref USBD_Disconnect() and @ref USBD_Connect() to force
mbed_official 59:2af474687369 231 * reenumeration.
mbed_official 59:2af474687369 232 *
mbed_official 59:2af474687369 233 * @param[in] p
mbed_official 59:2af474687369 234 * Pointer to device initialization struct. See @ref USBD_Init_TypeDef.
mbed_official 59:2af474687369 235 *
mbed_official 59:2af474687369 236 * @return
mbed_official 59:2af474687369 237 * @ref USB_STATUS_OK on success, else an appropriate error code.
mbed_official 59:2af474687369 238 ******************************************************************************/
mbed_official 59:2af474687369 239 int USBD_Init( const USBD_Init_TypeDef *p )
mbed_official 59:2af474687369 240 {
mbed_official 59:2af474687369 241 USBD_Ep_TypeDef *ep;
mbed_official 59:2af474687369 242
mbed_official 59:2af474687369 243 #if !defined( USB_CORECLK_HFRCO ) || !defined( CMU_OSCENCMD_USHFRCOEN )
mbed_official 59:2af474687369 244 /* Devices supporting crystal-less USB can use HFRCO or HFXO as core clock. */
mbed_official 59:2af474687369 245 /* All other devices must use HFXO as core clock. */
mbed_official 59:2af474687369 246 if ( CMU_ClockSelectGet( cmuClock_HF ) != cmuSelect_HFXO )
mbed_official 59:2af474687369 247 {
mbed_official 59:2af474687369 248 CMU_ClockSelectSet( cmuClock_HF, cmuSelect_HFXO );
mbed_official 59:2af474687369 249 }
mbed_official 59:2af474687369 250 #endif
mbed_official 59:2af474687369 251
mbed_official 59:2af474687369 252 #if !defined( CMU_OSCENCMD_USHFRCOEN )
mbed_official 59:2af474687369 253 #if ( USB_USBC_32kHz_CLK == USB_USBC_32kHz_CLK_LFXO )
mbed_official 59:2af474687369 254 CMU_OscillatorEnable(cmuOsc_LFXO, true, false);
mbed_official 59:2af474687369 255 #else
mbed_official 59:2af474687369 256 CMU_OscillatorEnable(cmuOsc_LFRCO, true, false);
mbed_official 59:2af474687369 257 #endif
mbed_official 59:2af474687369 258
mbed_official 59:2af474687369 259 #else
mbed_official 59:2af474687369 260 CMU_ClockEnable(cmuClock_CORELE, true);
mbed_official 59:2af474687369 261 /* LFC clock is needed to detect USB suspend when LEMIDLE is activated. */
mbed_official 59:2af474687369 262 #if ( USB_USBC_32kHz_CLK == USB_USBC_32kHz_CLK_LFXO )
mbed_official 59:2af474687369 263 CMU_ClockSelectSet(cmuClock_LFC, cmuSelect_LFXO);
mbed_official 59:2af474687369 264 #else
mbed_official 59:2af474687369 265 CMU_ClockSelectSet(cmuClock_LFC, cmuSelect_LFRCO);
mbed_official 59:2af474687369 266 #endif
mbed_official 59:2af474687369 267 CMU_ClockEnable(cmuClock_USBLE, true);
mbed_official 59:2af474687369 268 #endif
mbed_official 59:2af474687369 269
mbed_official 59:2af474687369 270 USBTIMER_Init();
mbed_official 59:2af474687369 271
mbed_official 59:2af474687369 272 memset( dev, 0, sizeof( USBD_Device_TypeDef ) );
mbed_official 59:2af474687369 273
mbed_official 59:2af474687369 274 dev->setup = dev->setupPkt;
mbed_official 59:2af474687369 275 dev->state = USBD_STATE_LASTMARKER;
mbed_official 59:2af474687369 276 dev->savedState = USBD_STATE_NONE;
mbed_official 59:2af474687369 277 dev->lastState = USBD_STATE_NONE;
mbed_official 59:2af474687369 278 dev->callbacks = p->callbacks;
mbed_official 59:2af474687369 279 dev->remoteWakeupEnabled = false;
mbed_official 59:2af474687369 280
mbed_official 59:2af474687369 281 /* Initialize EP0 */
mbed_official 59:2af474687369 282
mbed_official 59:2af474687369 283 ep = &dev->ep[ 0 ];
mbed_official 59:2af474687369 284 ep->in = false;
mbed_official 59:2af474687369 285 ep->buf = NULL;
mbed_official 59:2af474687369 286 ep->num = 0;
mbed_official 59:2af474687369 287 ep->mask = 1;
mbed_official 59:2af474687369 288 ep->addr = 0;
mbed_official 59:2af474687369 289 ep->type = USB_EPTYPE_CTRL;
mbed_official 59:2af474687369 290 ep->txFifoNum = 0;
mbed_official 59:2af474687369 291
mbed_official 59:2af474687369 292 /* FIXME! */
mbed_official 59:2af474687369 293 ep->packetSize = 64;
mbed_official 59:2af474687369 294 dev->ep0MpsCode = _USB_DOEP0CTL_MPS_64B;
mbed_official 59:2af474687369 295
mbed_official 59:2af474687369 296 ep->remaining = 0;
mbed_official 59:2af474687369 297 ep->xferred = 0;
mbed_official 59:2af474687369 298 ep->state = D_EP_IDLE;
mbed_official 59:2af474687369 299 ep->xferCompleteCb = NULL;
mbed_official 59:2af474687369 300 ep->fifoSize = ep->packetSize / 4;
mbed_official 59:2af474687369 301
mbed_official 59:2af474687369 302 totalTxFifoSize = ep->fifoSize * p->bufferingMultiplier[ 0 ];
mbed_official 59:2af474687369 303 totalRxFifoSize = (ep->fifoSize + 1) * p->bufferingMultiplier[ 0 ];
mbed_official 59:2af474687369 304
mbed_official 59:2af474687369 305 /* Rx-FIFO size: SETUP packets : 4*n + 6 n=#CTRL EP's
mbed_official 59:2af474687369 306 * GOTNAK : 1
mbed_official 59:2af474687369 307 * Status info : 2*n n=#OUT EP's (EP0 included) in HW
mbed_official 59:2af474687369 308 */
mbed_official 59:2af474687369 309 totalRxFifoSize += 10 + 1 + ( 2 * (MAX_NUM_OUT_EPS + 1) );
mbed_official 59:2af474687369 310
mbed_official 59:2af474687369 311 INT_Disable();
mbed_official 59:2af474687369 312
mbed_official 59:2af474687369 313 /* Enable USB clock */
mbed_official 59:2af474687369 314 CMU->HFCORECLKEN0 |= CMU_HFCORECLKEN0_USB | CMU_HFCORECLKEN0_USBC;
mbed_official 59:2af474687369 315
mbed_official 59:2af474687369 316 #if defined( CMU_OSCENCMD_USHFRCOEN )
mbed_official 59:2af474687369 317 CMU->USHFRCOCONF = CMU_USHFRCOCONF_BAND_48MHZ;
mbed_official 59:2af474687369 318 CMU_ClockSelectSet( cmuClock_USBC, cmuSelect_USHFRCO );
mbed_official 59:2af474687369 319
mbed_official 59:2af474687369 320 /* Enable USHFRCO Clock Recovery mode. */
mbed_official 59:2af474687369 321 CMU->USBCRCTRL |= CMU_USBCRCTRL_EN;
mbed_official 59:2af474687369 322
mbed_official 59:2af474687369 323 /* Turn on Low Energy Mode (LEM) features. */
mbed_official 59:2af474687369 324 USB->CTRL = USB_CTRL_LEMOSCCTRL_GATE
mbed_official 59:2af474687369 325 | USB_CTRL_LEMIDLEEN
mbed_official 59:2af474687369 326 | USB_CTRL_LEMPHYCTRL;
mbed_official 59:2af474687369 327 #else
mbed_official 59:2af474687369 328 CMU_ClockSelectSet( cmuClock_USBC, cmuSelect_HFCLK );
mbed_official 59:2af474687369 329 #endif
mbed_official 59:2af474687369 330
mbed_official 59:2af474687369 331 USBHAL_DisableGlobalInt();
mbed_official 59:2af474687369 332
mbed_official 59:2af474687369 333 if ( USBDHAL_CoreInit( totalRxFifoSize, totalTxFifoSize ) == USB_STATUS_OK )
mbed_official 59:2af474687369 334 {
mbed_official 59:2af474687369 335 USBDHAL_EnableUsbResetAndSuspendInt();
mbed_official 59:2af474687369 336 USBHAL_EnableGlobalInt();
mbed_official 59:2af474687369 337 NVIC_ClearPendingIRQ( USB_IRQn );
mbed_official 59:2af474687369 338 NVIC_EnableIRQ( USB_IRQn );
mbed_official 59:2af474687369 339 }
mbed_official 59:2af474687369 340 else
mbed_official 59:2af474687369 341 {
mbed_official 59:2af474687369 342 INT_Enable();
mbed_official 59:2af474687369 343 DEBUG_USB_API_PUTS( "\nUSBD_Init(), FIFO setup error" );
mbed_official 59:2af474687369 344 EFM_ASSERT( false );
mbed_official 59:2af474687369 345 return USB_STATUS_ILLEGAL;
mbed_official 59:2af474687369 346 }
mbed_official 59:2af474687369 347
mbed_official 59:2af474687369 348 #if ( USB_PWRSAVE_MODE & USB_PWRSAVE_MODE_ONVBUSOFF )
mbed_official 59:2af474687369 349 if ( USBHAL_VbusIsOn() )
mbed_official 59:2af474687369 350 {
mbed_official 59:2af474687369 351 USBD_SetUsbState( USBD_STATE_POWERED );
mbed_official 59:2af474687369 352 }
mbed_official 59:2af474687369 353 else
mbed_official 59:2af474687369 354 #endif
mbed_official 59:2af474687369 355 {
mbed_official 59:2af474687369 356 USBD_SetUsbState( USBD_STATE_NONE );
mbed_official 59:2af474687369 357 }
mbed_official 59:2af474687369 358
mbed_official 59:2af474687369 359 INT_Enable();
mbed_official 59:2af474687369 360 return USB_STATUS_OK;
mbed_official 59:2af474687369 361 }
mbed_official 59:2af474687369 362
mbed_official 59:2af474687369 363 /***************************************************************************//**
mbed_official 59:2af474687369 364 * @brief
mbed_official 59:2af474687369 365 * Start a read (OUT) transfer on an endpoint.
mbed_official 59:2af474687369 366 *
mbed_official 59:2af474687369 367 * @note
mbed_official 59:2af474687369 368 * The transfer buffer length must be a multiple of 4 bytes in length and
mbed_official 59:2af474687369 369 * WORD (4 byte) aligned. When allocating the buffer, round buffer length up.
mbed_official 59:2af474687369 370 * If it is possible that the host will send more data than your device
mbed_official 59:2af474687369 371 * expects, round buffer size up to the next multiple of maxpacket size.
mbed_official 59:2af474687369 372 *
mbed_official 59:2af474687369 373 * @param[in] epAddr
mbed_official 59:2af474687369 374 * Endpoint address.
mbed_official 59:2af474687369 375 *
mbed_official 59:2af474687369 376 * @param[in] data
mbed_official 59:2af474687369 377 * Pointer to transfer data buffer.
mbed_official 59:2af474687369 378 *
mbed_official 59:2af474687369 379 * @param[in] byteCount
mbed_official 59:2af474687369 380 * Transfer length.
mbed_official 59:2af474687369 381 *
mbed_official 59:2af474687369 382 * @param[in] callback
mbed_official 59:2af474687369 383 * Function to be called on transfer completion. Supply NULL if no callback
mbed_official 59:2af474687369 384 * is needed. See @ref USB_XferCompleteCb_TypeDef.
mbed_official 59:2af474687369 385 *
mbed_official 59:2af474687369 386 * @return
mbed_official 59:2af474687369 387 * @ref USB_STATUS_OK on success, else an appropriate error code.
mbed_official 59:2af474687369 388 ******************************************************************************/
mbed_official 59:2af474687369 389 int USBD_Read( int epAddr, void *data, int byteCount,
mbed_official 59:2af474687369 390 USB_XferCompleteCb_TypeDef callback )
mbed_official 59:2af474687369 391 {
mbed_official 59:2af474687369 392 USBD_Ep_TypeDef *ep = USBD_GetEpFromAddr( epAddr );
mbed_official 59:2af474687369 393
mbed_official 59:2af474687369 394 USB_PRINTF("USBD: Read addr %x, data %p, size %d, cb 0x%lx\n",
mbed_official 59:2af474687369 395 epAddr, data, byteCount, (uint32_t)callback);
mbed_official 59:2af474687369 396
mbed_official 59:2af474687369 397 if ( ep == NULL )
mbed_official 59:2af474687369 398 {
mbed_official 59:2af474687369 399 DEBUG_USB_API_PUTS( "\nUSBD_Read(), Illegal endpoint" );
mbed_official 59:2af474687369 400 EFM_ASSERT( false );
mbed_official 59:2af474687369 401 return USB_STATUS_ILLEGAL;
mbed_official 59:2af474687369 402 }
mbed_official 59:2af474687369 403
mbed_official 59:2af474687369 404 if ( ( byteCount > MAX_XFER_LEN ) ||
mbed_official 59:2af474687369 405 ( ( byteCount / ep->packetSize ) > MAX_PACKETS_PR_XFER ) )
mbed_official 59:2af474687369 406 {
mbed_official 59:2af474687369 407 DEBUG_USB_API_PUTS( "\nUSBD_Read(), Illegal transfer size" );
mbed_official 59:2af474687369 408 EFM_ASSERT( false );
mbed_official 59:2af474687369 409 return USB_STATUS_ILLEGAL;
mbed_official 59:2af474687369 410 }
mbed_official 59:2af474687369 411
mbed_official 59:2af474687369 412 if ( (uint32_t)data & 3 )
mbed_official 59:2af474687369 413 {
mbed_official 59:2af474687369 414 DEBUG_USB_API_PUTS( "\nUSBD_Read(), Misaligned data buffer" );
mbed_official 59:2af474687369 415 EFM_ASSERT( false );
mbed_official 59:2af474687369 416 return USB_STATUS_ILLEGAL;
mbed_official 59:2af474687369 417 }
mbed_official 59:2af474687369 418
mbed_official 59:2af474687369 419 INT_Disable();
mbed_official 59:2af474687369 420 if ( USBDHAL_EpIsStalled( ep ) )
mbed_official 59:2af474687369 421 {
mbed_official 59:2af474687369 422 INT_Enable();
mbed_official 59:2af474687369 423 DEBUG_USB_API_PUTS( "\nUSBD_Read(), Endpoint is halted" );
mbed_official 59:2af474687369 424 return USB_STATUS_EP_STALLED;
mbed_official 59:2af474687369 425 }
mbed_official 59:2af474687369 426
mbed_official 59:2af474687369 427 if ( ep->state != D_EP_IDLE )
mbed_official 59:2af474687369 428 {
mbed_official 59:2af474687369 429 INT_Enable();
mbed_official 59:2af474687369 430 DEBUG_USB_API_PUTS( "\nUSBD_Read(), Endpoint is busy" );
mbed_official 59:2af474687369 431 return USB_STATUS_EP_BUSY;
mbed_official 59:2af474687369 432 }
mbed_official 59:2af474687369 433
mbed_official 59:2af474687369 434 if ( ( ep->num > 0 ) && ( USBD_GetUsbState() != USBD_STATE_CONFIGURED ) )
mbed_official 59:2af474687369 435 {
mbed_official 59:2af474687369 436 INT_Enable();
mbed_official 59:2af474687369 437 DEBUG_USB_API_PUTS( "\nUSBD_Read(), Device not configured" );
mbed_official 59:2af474687369 438 return USB_STATUS_DEVICE_UNCONFIGURED;
mbed_official 59:2af474687369 439 }
mbed_official 59:2af474687369 440
mbed_official 59:2af474687369 441 ep->buf = (uint8_t*)data;
mbed_official 59:2af474687369 442 ep->remaining = byteCount;
mbed_official 59:2af474687369 443 ep->xferred = 0;
mbed_official 59:2af474687369 444
mbed_official 59:2af474687369 445 if ( ep->num == 0 )
mbed_official 59:2af474687369 446 {
mbed_official 59:2af474687369 447 ep->in = false;
mbed_official 59:2af474687369 448 }
mbed_official 59:2af474687369 449 else if ( ep->in != false )
mbed_official 59:2af474687369 450 {
mbed_official 59:2af474687369 451 INT_Enable();
mbed_official 59:2af474687369 452 DEBUG_USB_API_PUTS( "\nUSBD_Read(), Illegal EP direction" );
mbed_official 59:2af474687369 453 EFM_ASSERT( false );
mbed_official 59:2af474687369 454 return USB_STATUS_ILLEGAL;
mbed_official 59:2af474687369 455 }
mbed_official 59:2af474687369 456
mbed_official 59:2af474687369 457 ep->state = D_EP_RECEIVING;
mbed_official 59:2af474687369 458 ep->xferCompleteCb = callback;
mbed_official 59:2af474687369 459
mbed_official 59:2af474687369 460 USBD_ArmEp( ep );
mbed_official 59:2af474687369 461 INT_Enable();
mbed_official 59:2af474687369 462 return USB_STATUS_OK;
mbed_official 59:2af474687369 463 }
mbed_official 59:2af474687369 464
mbed_official 59:2af474687369 465 /***************************************************************************//**
mbed_official 59:2af474687369 466 * @brief
mbed_official 59:2af474687369 467 * Perform a remote wakeup signalling sequence.
mbed_official 59:2af474687369 468 *
mbed_official 59:2af474687369 469 * @note
mbed_official 59:2af474687369 470 * It is the responsibility of the application to ensure that remote wakeup
mbed_official 59:2af474687369 471 * is not attempted before the device has been suspended for at least 5
mbed_official 59:2af474687369 472 * miliseconds. This function should not be called from within an interrupt
mbed_official 59:2af474687369 473 * handler.
mbed_official 59:2af474687369 474 *
mbed_official 59:2af474687369 475 * @return
mbed_official 59:2af474687369 476 * @ref USB_STATUS_OK on success, else an appropriate error code.
mbed_official 59:2af474687369 477 ******************************************************************************/
mbed_official 59:2af474687369 478 int USBD_RemoteWakeup( void )
mbed_official 59:2af474687369 479 {
mbed_official 59:2af474687369 480 INT_Disable();
mbed_official 59:2af474687369 481
mbed_official 59:2af474687369 482 if ( ( dev->state != USBD_STATE_SUSPENDED ) ||
mbed_official 59:2af474687369 483 ( dev->remoteWakeupEnabled == false ) )
mbed_official 59:2af474687369 484 {
mbed_official 59:2af474687369 485 INT_Enable();
mbed_official 59:2af474687369 486 DEBUG_USB_API_PUTS( "\nUSBD_RemoteWakeup(), Illegal remote wakeup" );
mbed_official 59:2af474687369 487 return USB_STATUS_ILLEGAL;
mbed_official 59:2af474687369 488 }
mbed_official 59:2af474687369 489
mbed_official 59:2af474687369 490 USBDHAL_SetRemoteWakeup();
mbed_official 59:2af474687369 491 INT_Enable();
mbed_official 59:2af474687369 492 USBTIMER_DelayMs( 10 );
mbed_official 59:2af474687369 493 INT_Disable();
mbed_official 59:2af474687369 494 USBDHAL_ClearRemoteWakeup();
mbed_official 59:2af474687369 495 INT_Enable();
mbed_official 59:2af474687369 496 return USB_STATUS_OK;
mbed_official 59:2af474687369 497 }
mbed_official 59:2af474687369 498
mbed_official 59:2af474687369 499 /***************************************************************************//**
mbed_official 59:2af474687369 500 * @brief
mbed_official 59:2af474687369 501 * Check if it is ok to enter energy mode EM2.
mbed_official 59:2af474687369 502 *
mbed_official 59:2af474687369 503 * @note
mbed_official 59:2af474687369 504 * Before entering EM2 both the USB hardware and the USB stack must be in a
mbed_official 59:2af474687369 505 * certain state, this function checks if all conditions for entering EM2
mbed_official 59:2af474687369 506 * is met.
mbed_official 59:2af474687369 507 * Refer to the @ref usb_device_powersave section for more information.
mbed_official 59:2af474687369 508 *
mbed_official 59:2af474687369 509 * @return
mbed_official 59:2af474687369 510 * True if ok to enter EM2, false otherwise.
mbed_official 59:2af474687369 511 ******************************************************************************/
mbed_official 59:2af474687369 512 bool USBD_SafeToEnterEM2( void )
mbed_official 59:2af474687369 513 {
mbed_official 59:2af474687369 514 #if ( USB_PWRSAVE_MODE )
mbed_official 59:2af474687369 515 return USBD_poweredDown ? true : false;
mbed_official 59:2af474687369 516 #else
mbed_official 59:2af474687369 517 return false;
mbed_official 59:2af474687369 518 #endif
mbed_official 59:2af474687369 519 }
mbed_official 59:2af474687369 520
mbed_official 59:2af474687369 521 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
mbed_official 59:2af474687369 522
mbed_official 59:2af474687369 523 void USBD_SetUsbState( USBD_State_TypeDef newState )
mbed_official 59:2af474687369 524 {
mbed_official 59:2af474687369 525 USBD_State_TypeDef currentState;
mbed_official 59:2af474687369 526
mbed_official 59:2af474687369 527 currentState = dev->state;
mbed_official 59:2af474687369 528 if ( newState == USBD_STATE_SUSPENDED )
mbed_official 59:2af474687369 529 {
mbed_official 59:2af474687369 530 dev->savedState = currentState;
mbed_official 59:2af474687369 531 }
mbed_official 59:2af474687369 532
mbed_official 59:2af474687369 533 dev->lastState = dev->state;
mbed_official 59:2af474687369 534 dev->state = newState;
mbed_official 59:2af474687369 535
mbed_official 59:2af474687369 536 if ( ( dev->callbacks->usbStateChange ) &&
mbed_official 59:2af474687369 537 ( currentState != newState ) )
mbed_official 59:2af474687369 538 {
mbed_official 59:2af474687369 539 /* When we transition to a state "lower" than CONFIGURED
mbed_official 59:2af474687369 540 * we must reset the endpoint data
mbed_official 59:2af474687369 541 */
mbed_official 59:2af474687369 542 if ( (dev->lastState == USBD_STATE_CONFIGURED ||
mbed_official 59:2af474687369 543 dev->lastState == USBD_STATE_SUSPENDED ) &&
mbed_official 59:2af474687369 544 dev->state < USBD_STATE_CONFIGURED )
mbed_official 59:2af474687369 545 {
mbed_official 59:2af474687369 546 USBD_ResetEndpoints();
mbed_official 59:2af474687369 547 }
mbed_official 59:2af474687369 548
mbed_official 59:2af474687369 549 dev->callbacks->usbStateChange( currentState, newState );
mbed_official 59:2af474687369 550 }
mbed_official 59:2af474687369 551 }
mbed_official 59:2af474687369 552
mbed_official 59:2af474687369 553 /** @endcond */
mbed_official 59:2af474687369 554
mbed_official 59:2af474687369 555 /***************************************************************************//**
mbed_official 59:2af474687369 556 * @brief
mbed_official 59:2af474687369 557 * Set an endpoint in the stalled (halted) state.
mbed_official 59:2af474687369 558 *
mbed_official 59:2af474687369 559 * @param[in] epAddr
mbed_official 59:2af474687369 560 * The address of the endpoint to stall.
mbed_official 59:2af474687369 561 *
mbed_official 59:2af474687369 562 * @return
mbed_official 59:2af474687369 563 * @ref USB_STATUS_OK on success, else an appropriate error code.
mbed_official 59:2af474687369 564 ******************************************************************************/
mbed_official 59:2af474687369 565 int USBD_StallEp( int epAddr )
mbed_official 59:2af474687369 566 {
mbed_official 59:2af474687369 567 USB_Status_TypeDef retVal;
mbed_official 59:2af474687369 568 USBD_Ep_TypeDef *ep = USBD_GetEpFromAddr( epAddr );
mbed_official 59:2af474687369 569
mbed_official 59:2af474687369 570 if ( ep == NULL )
mbed_official 59:2af474687369 571 {
mbed_official 59:2af474687369 572 DEBUG_USB_API_PUTS( "\nUSBD_StallEp(), Illegal request" );
mbed_official 59:2af474687369 573 EFM_ASSERT( false );
mbed_official 59:2af474687369 574 return USB_STATUS_ILLEGAL;
mbed_official 59:2af474687369 575 }
mbed_official 59:2af474687369 576
mbed_official 59:2af474687369 577 if ( ep->num == 0 )
mbed_official 59:2af474687369 578 {
mbed_official 59:2af474687369 579 DEBUG_USB_API_PUTS( "\nUSBD_StallEp(), Illegal endpoint" );
mbed_official 59:2af474687369 580 EFM_ASSERT( false );
mbed_official 59:2af474687369 581 return USB_STATUS_ILLEGAL;
mbed_official 59:2af474687369 582 }
mbed_official 59:2af474687369 583
mbed_official 59:2af474687369 584 INT_Disable();
mbed_official 59:2af474687369 585 retVal = USBDHAL_StallEp( ep );
mbed_official 59:2af474687369 586 INT_Enable();
mbed_official 59:2af474687369 587
mbed_official 59:2af474687369 588 if ( retVal != USB_STATUS_OK )
mbed_official 59:2af474687369 589 {
mbed_official 59:2af474687369 590 retVal = USB_STATUS_ILLEGAL;
mbed_official 59:2af474687369 591 }
mbed_official 59:2af474687369 592
mbed_official 59:2af474687369 593 return retVal;
mbed_official 59:2af474687369 594 }
mbed_official 59:2af474687369 595
mbed_official 59:2af474687369 596 /***************************************************************************//**
mbed_official 59:2af474687369 597 * @brief
mbed_official 59:2af474687369 598 * Stop USB device stack operation.
mbed_official 59:2af474687369 599 *
mbed_official 59:2af474687369 600 * @details
mbed_official 59:2af474687369 601 * The data-line pullup resistor is turned off, USB interrupts are disabled,
mbed_official 59:2af474687369 602 * and finally the USB pins are disabled.
mbed_official 59:2af474687369 603 ******************************************************************************/
mbed_official 59:2af474687369 604 void USBD_Stop( void )
mbed_official 59:2af474687369 605 {
mbed_official 59:2af474687369 606 USBD_Disconnect();
mbed_official 59:2af474687369 607 NVIC_DisableIRQ( USB_IRQn );
mbed_official 59:2af474687369 608 USBHAL_DisableGlobalInt();
mbed_official 59:2af474687369 609 USBHAL_DisableUsbInt();
mbed_official 59:2af474687369 610 USBHAL_DisablePhyPins();
mbed_official 59:2af474687369 611 USBD_SetUsbState( USBD_STATE_NONE );
mbed_official 59:2af474687369 612 /* Turn off USB clocks. */
mbed_official 59:2af474687369 613 CMU->HFCORECLKEN0 &= ~(CMU_HFCORECLKEN0_USB | CMU_HFCORECLKEN0_USBC);
mbed_official 59:2af474687369 614 }
mbed_official 59:2af474687369 615
mbed_official 59:2af474687369 616 /***************************************************************************//**
mbed_official 59:2af474687369 617 * @brief
mbed_official 59:2af474687369 618 * Reset stall state on a stalled (halted) endpoint.
mbed_official 59:2af474687369 619 *
mbed_official 59:2af474687369 620 * @param[in] epAddr
mbed_official 59:2af474687369 621 * The address of the endpoint to un-stall.
mbed_official 59:2af474687369 622 *
mbed_official 59:2af474687369 623 * @return
mbed_official 59:2af474687369 624 * @ref USB_STATUS_OK on success, else an appropriate error code.
mbed_official 59:2af474687369 625 ******************************************************************************/
mbed_official 59:2af474687369 626 int USBD_UnStallEp( int epAddr )
mbed_official 59:2af474687369 627 {
mbed_official 59:2af474687369 628 USB_Status_TypeDef retVal;
mbed_official 59:2af474687369 629 USBD_Ep_TypeDef *ep = USBD_GetEpFromAddr( epAddr );
mbed_official 59:2af474687369 630
mbed_official 59:2af474687369 631 if ( ep == NULL )
mbed_official 59:2af474687369 632 {
mbed_official 59:2af474687369 633 DEBUG_USB_API_PUTS( "\nUSBD_UnStallEp(), Illegal request" );
mbed_official 59:2af474687369 634 EFM_ASSERT( false );
mbed_official 59:2af474687369 635 return USB_STATUS_ILLEGAL;
mbed_official 59:2af474687369 636 }
mbed_official 59:2af474687369 637
mbed_official 59:2af474687369 638 if ( ep->num == 0 )
mbed_official 59:2af474687369 639 {
mbed_official 59:2af474687369 640 DEBUG_USB_API_PUTS( "\nUSBD_UnStallEp(), Illegal endpoint" );
mbed_official 59:2af474687369 641 EFM_ASSERT( false );
mbed_official 59:2af474687369 642 return USB_STATUS_ILLEGAL;
mbed_official 59:2af474687369 643 }
mbed_official 59:2af474687369 644
mbed_official 59:2af474687369 645 INT_Disable();
mbed_official 59:2af474687369 646 retVal = USBDHAL_UnStallEp( ep );
mbed_official 59:2af474687369 647 INT_Enable();
mbed_official 59:2af474687369 648
mbed_official 59:2af474687369 649 if ( retVal != USB_STATUS_OK )
mbed_official 59:2af474687369 650 {
mbed_official 59:2af474687369 651 retVal = USB_STATUS_ILLEGAL;
mbed_official 59:2af474687369 652 }
mbed_official 59:2af474687369 653
mbed_official 59:2af474687369 654 return retVal;
mbed_official 59:2af474687369 655 }
mbed_official 59:2af474687369 656
mbed_official 59:2af474687369 657 /***************************************************************************//**
mbed_official 59:2af474687369 658 * @brief
mbed_official 59:2af474687369 659 * Start a write (IN) transfer on an endpoint.
mbed_official 59:2af474687369 660 *
mbed_official 59:2af474687369 661 * @param[in] epAddr
mbed_official 59:2af474687369 662 * Endpoint address.
mbed_official 59:2af474687369 663 *
mbed_official 59:2af474687369 664 * @param[in] data
mbed_official 59:2af474687369 665 * Pointer to transfer data buffer. This buffer must be WORD (4 byte) aligned.
mbed_official 59:2af474687369 666 *
mbed_official 59:2af474687369 667 * @param[in] byteCount
mbed_official 59:2af474687369 668 * Transfer length.
mbed_official 59:2af474687369 669 *
mbed_official 59:2af474687369 670 * @param[in] callback
mbed_official 59:2af474687369 671 * Function to be called on transfer completion. Supply NULL if no callback
mbed_official 59:2af474687369 672 * is needed. See @ref USB_XferCompleteCb_TypeDef.
mbed_official 59:2af474687369 673 *
mbed_official 59:2af474687369 674 * @return
mbed_official 59:2af474687369 675 * @ref USB_STATUS_OK on success, else an appropriate error code.
mbed_official 59:2af474687369 676 ******************************************************************************/
mbed_official 59:2af474687369 677 int USBD_Write( int epAddr, void *data, int byteCount,
mbed_official 59:2af474687369 678 USB_XferCompleteCb_TypeDef callback )
mbed_official 59:2af474687369 679 {
mbed_official 59:2af474687369 680 USBD_Ep_TypeDef *ep = USBD_GetEpFromAddr( epAddr );
mbed_official 59:2af474687369 681
mbed_official 59:2af474687369 682 USB_PRINTF("USBD: Write addr %x, data %p, size %d, cb 0x%lx\n",
mbed_official 59:2af474687369 683 epAddr, data, byteCount, (uint32_t)callback);
mbed_official 59:2af474687369 684
mbed_official 59:2af474687369 685 if ( ep == NULL )
mbed_official 59:2af474687369 686 {
mbed_official 59:2af474687369 687 DEBUG_USB_API_PUTS( "\nUSBD_Write(), Illegal endpoint" );
mbed_official 59:2af474687369 688 EFM_ASSERT( false );
mbed_official 59:2af474687369 689 return USB_STATUS_ILLEGAL;
mbed_official 59:2af474687369 690 }
mbed_official 59:2af474687369 691
mbed_official 59:2af474687369 692 if ( ( byteCount > MAX_XFER_LEN ) ||
mbed_official 59:2af474687369 693 ( ( byteCount / ep->packetSize ) > MAX_PACKETS_PR_XFER ) )
mbed_official 59:2af474687369 694 {
mbed_official 59:2af474687369 695 DEBUG_USB_API_PUTS( "\nUSBD_Write(), Illegal transfer size" );
mbed_official 59:2af474687369 696 EFM_ASSERT( false );
mbed_official 59:2af474687369 697 return USB_STATUS_ILLEGAL;
mbed_official 59:2af474687369 698 }
mbed_official 59:2af474687369 699
mbed_official 59:2af474687369 700 if ( (uint32_t)data & 3 )
mbed_official 59:2af474687369 701 {
mbed_official 59:2af474687369 702 DEBUG_USB_API_PUTS( "\nUSBD_Write(), Misaligned data buffer" );
mbed_official 59:2af474687369 703 EFM_ASSERT( false );
mbed_official 59:2af474687369 704 return USB_STATUS_ILLEGAL;
mbed_official 59:2af474687369 705 }
mbed_official 59:2af474687369 706
mbed_official 59:2af474687369 707 INT_Disable();
mbed_official 59:2af474687369 708 if ( USBDHAL_EpIsStalled( ep ) )
mbed_official 59:2af474687369 709 {
mbed_official 59:2af474687369 710 INT_Enable();
mbed_official 59:2af474687369 711 DEBUG_USB_API_PUTS( "\nUSBD_Write(), Endpoint is halted" );
mbed_official 59:2af474687369 712 return USB_STATUS_EP_STALLED;
mbed_official 59:2af474687369 713 }
mbed_official 59:2af474687369 714
mbed_official 59:2af474687369 715 if ( ep->state != D_EP_IDLE )
mbed_official 59:2af474687369 716 {
mbed_official 59:2af474687369 717 INT_Enable();
mbed_official 59:2af474687369 718 DEBUG_USB_API_PUTS( "\nUSBD_Write(), Endpoint is busy" );
mbed_official 59:2af474687369 719 return USB_STATUS_EP_BUSY;
mbed_official 59:2af474687369 720 }
mbed_official 59:2af474687369 721
mbed_official 59:2af474687369 722 if ( ( ep->num > 0 ) && ( USBD_GetUsbState() != USBD_STATE_CONFIGURED ) )
mbed_official 59:2af474687369 723 {
mbed_official 59:2af474687369 724 INT_Enable();
mbed_official 59:2af474687369 725 DEBUG_USB_API_PUTS( "\nUSBD_Write(), Device not configured" );
mbed_official 59:2af474687369 726 return USB_STATUS_DEVICE_UNCONFIGURED;
mbed_official 59:2af474687369 727 }
mbed_official 59:2af474687369 728
mbed_official 59:2af474687369 729 ep->buf = (uint8_t*)data;
mbed_official 59:2af474687369 730 ep->remaining = byteCount;
mbed_official 59:2af474687369 731 ep->xferred = 0;
mbed_official 59:2af474687369 732
mbed_official 59:2af474687369 733 if ( ep->num == 0 )
mbed_official 59:2af474687369 734 {
mbed_official 59:2af474687369 735 ep->in = true;
mbed_official 59:2af474687369 736 }
mbed_official 59:2af474687369 737 else if ( ep->in != true )
mbed_official 59:2af474687369 738 {
mbed_official 59:2af474687369 739 INT_Enable();
mbed_official 59:2af474687369 740 DEBUG_USB_API_PUTS( "\nUSBD_Write(), Illegal EP direction" );
mbed_official 59:2af474687369 741 EFM_ASSERT( false );
mbed_official 59:2af474687369 742 return USB_STATUS_ILLEGAL;
mbed_official 59:2af474687369 743 }
mbed_official 59:2af474687369 744
mbed_official 59:2af474687369 745 ep->state = D_EP_TRANSMITTING;
mbed_official 59:2af474687369 746 ep->xferCompleteCb = callback;
mbed_official 59:2af474687369 747
mbed_official 59:2af474687369 748 USBD_ArmEp( ep );
mbed_official 59:2af474687369 749 INT_Enable();
mbed_official 59:2af474687369 750 return USB_STATUS_OK;
mbed_official 59:2af474687369 751 }
mbed_official 59:2af474687369 752
mbed_official 59:2af474687369 753 int USBD_SetAddress(uint8_t addr)
mbed_official 59:2af474687369 754 {
mbed_official 59:2af474687369 755 int retVal = USB_STATUS_REQ_ERR;
mbed_official 59:2af474687369 756
mbed_official 59:2af474687369 757 if ( dev->state == USBD_STATE_DEFAULT )
mbed_official 59:2af474687369 758 {
mbed_official 59:2af474687369 759 if ( addr != 0 )
mbed_official 59:2af474687369 760 {
mbed_official 59:2af474687369 761 USBD_SetUsbState( USBD_STATE_ADDRESSED );
mbed_official 59:2af474687369 762 }
mbed_official 59:2af474687369 763 USBDHAL_SetAddr( addr );
mbed_official 59:2af474687369 764 retVal = USB_STATUS_OK;
mbed_official 59:2af474687369 765 }
mbed_official 59:2af474687369 766 else if ( dev->state == USBD_STATE_ADDRESSED )
mbed_official 59:2af474687369 767 {
mbed_official 59:2af474687369 768 if ( addr == 0 )
mbed_official 59:2af474687369 769 {
mbed_official 59:2af474687369 770 USBD_SetUsbState( USBD_STATE_DEFAULT );
mbed_official 59:2af474687369 771 }
mbed_official 59:2af474687369 772 USBDHAL_SetAddr( addr );
mbed_official 59:2af474687369 773 retVal = USB_STATUS_OK;
mbed_official 59:2af474687369 774 }
mbed_official 59:2af474687369 775
mbed_official 59:2af474687369 776 return retVal;
mbed_official 59:2af474687369 777 }
mbed_official 59:2af474687369 778
mbed_official 59:2af474687369 779 /***************************************************************************//**
mbed_official 59:2af474687369 780 * @brief
mbed_official 59:2af474687369 781 * Query the stall state of an endpoint
mbed_official 59:2af474687369 782 *
mbed_official 59:2af474687369 783 * @param[in] epAddr
mbed_official 59:2af474687369 784 * The address of the endpoint to query.
mbed_official 59:2af474687369 785 *
mbed_official 59:2af474687369 786 * @return
mbed_official 59:2af474687369 787 * True if endpoint is stalled, false otherwise
mbed_official 59:2af474687369 788 ******************************************************************************/
mbed_official 59:2af474687369 789 int USBD_EpIsStalled(int epAddr)
mbed_official 59:2af474687369 790 {
mbed_official 59:2af474687369 791 USBD_Ep_TypeDef *ep = USBD_GetEpFromAddr( epAddr );
mbed_official 59:2af474687369 792
mbed_official 59:2af474687369 793 if( !ep )
mbed_official 59:2af474687369 794 {
mbed_official 59:2af474687369 795 return false;
mbed_official 59:2af474687369 796 }
mbed_official 59:2af474687369 797
mbed_official 59:2af474687369 798 return USBDHAL_EpIsStalled(ep);
mbed_official 59:2af474687369 799 }
mbed_official 59:2af474687369 800
mbed_official 59:2af474687369 801 /***************************************************************************//**
mbed_official 59:2af474687369 802 * @brief
mbed_official 59:2af474687369 803 * Reset (remove) all client endpoints
mbed_official 59:2af474687369 804 *
mbed_official 59:2af474687369 805 * @details
mbed_official 59:2af474687369 806 * Removes client endpoints, and resets the RX/TX fifos. No endpoints
mbed_official 59:2af474687369 807 * other than EP0 can be used until added with @ref USBD_AddEndpoint.
mbed_official 59:2af474687369 808 ******************************************************************************/
mbed_official 59:2af474687369 809 static void USBD_ResetEndpoints(void)
mbed_official 59:2af474687369 810 {
mbed_official 59:2af474687369 811 USBD_Ep_TypeDef *ep = &dev->ep[0];
mbed_official 59:2af474687369 812
mbed_official 59:2af474687369 813 numEps = 0;
mbed_official 59:2af474687369 814 txFifoNum = 1;
mbed_official 59:2af474687369 815
mbed_official 59:2af474687369 816 totalTxFifoSize = ep->fifoSize * 1;
mbed_official 59:2af474687369 817 totalRxFifoSize = (ep->fifoSize + 1) * 1;
mbed_official 59:2af474687369 818 totalRxFifoSize += 10 + 1 + ( 2 * (MAX_NUM_OUT_EPS + 1) );
mbed_official 59:2af474687369 819 }
mbed_official 59:2af474687369 820
mbed_official 59:2af474687369 821 /***************************************************************************//**
mbed_official 59:2af474687369 822 * @brief
mbed_official 59:2af474687369 823 * Add a new endpoint
mbed_official 59:2af474687369 824 *
mbed_official 59:2af474687369 825 * @param[in] epAddr
mbed_official 59:2af474687369 826 * Endpoint address
mbed_official 59:2af474687369 827 *
mbed_official 59:2af474687369 828 * @param[in] transferType
mbed_official 59:2af474687369 829 * Endpoint type, one of @ref USB_EPTYPE_BULK, @ref USB_EPTYPE_INTR or
mbed_official 59:2af474687369 830 * @ref USB_EPTYPE_ISOC.
mbed_official 59:2af474687369 831 *
mbed_official 59:2af474687369 832 * @param[in] maxPacketSize
mbed_official 59:2af474687369 833 * Maximum packet size of the new endpoint, in bytes
mbed_official 59:2af474687369 834 *
mbed_official 59:2af474687369 835 * @param[in] bufferMult
mbed_official 59:2af474687369 836 * FIFO buffer size multiplier
mbed_official 59:2af474687369 837 *
mbed_official 59:2af474687369 838 * @return
mbed_official 59:2af474687369 839 * @ref USB_STATUS_OK on success, else an appropriate error code.
mbed_official 59:2af474687369 840 ******************************************************************************/
mbed_official 59:2af474687369 841 int USBD_AddEndpoint(int epAddr, int transferType,
mbed_official 59:2af474687369 842 int maxPacketSize, int bufferMult)
mbed_official 59:2af474687369 843 {
mbed_official 59:2af474687369 844 USBD_Ep_TypeDef *ep;
mbed_official 59:2af474687369 845
mbed_official 59:2af474687369 846 numEps++;
mbed_official 59:2af474687369 847
mbed_official 59:2af474687369 848 ep = &dev->ep[ numEps ];
mbed_official 59:2af474687369 849 ep->in = ( epAddr & USB_SETUP_DIR_MASK ) != 0;
mbed_official 59:2af474687369 850 ep->buf = NULL;
mbed_official 59:2af474687369 851 ep->addr = epAddr;
mbed_official 59:2af474687369 852 ep->num = ep->addr & USB_EPNUM_MASK;
mbed_official 59:2af474687369 853 ep->mask = 1 << ep->num;
mbed_official 59:2af474687369 854 ep->type = transferType;
mbed_official 59:2af474687369 855 ep->packetSize = maxPacketSize;
mbed_official 59:2af474687369 856 ep->remaining = 0;
mbed_official 59:2af474687369 857 ep->xferred = 0;
mbed_official 59:2af474687369 858 ep->state = D_EP_IDLE;
mbed_official 59:2af474687369 859 ep->xferCompleteCb = NULL;
mbed_official 59:2af474687369 860
mbed_official 59:2af474687369 861 if ( ep->in )
mbed_official 59:2af474687369 862 {
mbed_official 59:2af474687369 863 ep->txFifoNum = txFifoNum++;
mbed_official 59:2af474687369 864 ep->fifoSize = ( ( ep->packetSize + 3 ) / 4 ) * bufferMult;
mbed_official 59:2af474687369 865 dev->inEpAddr2EpIndex[ ep->num ] = numEps;
mbed_official 59:2af474687369 866 totalTxFifoSize += ep->fifoSize;
mbed_official 59:2af474687369 867
mbed_official 59:2af474687369 868 if ( ep->num > MAX_NUM_IN_EPS )
mbed_official 59:2af474687369 869 {
mbed_official 59:2af474687369 870 DEBUG_USB_API_PUTS( "\nUSBD_AddEndpoint(), Illegal IN EP address" );
mbed_official 59:2af474687369 871 EFM_ASSERT( false );
mbed_official 59:2af474687369 872 return USB_STATUS_ILLEGAL;
mbed_official 59:2af474687369 873 }
mbed_official 59:2af474687369 874 }
mbed_official 59:2af474687369 875 else
mbed_official 59:2af474687369 876 {
mbed_official 59:2af474687369 877 ep->fifoSize = ( ( ( ep->packetSize + 3 ) / 4 ) + 1 ) * bufferMult;
mbed_official 59:2af474687369 878 dev->outEpAddr2EpIndex[ ep->num ] = numEps;
mbed_official 59:2af474687369 879 totalRxFifoSize += ep->fifoSize;
mbed_official 59:2af474687369 880
mbed_official 59:2af474687369 881 if ( ep->num > MAX_NUM_OUT_EPS )
mbed_official 59:2af474687369 882 {
mbed_official 59:2af474687369 883 DEBUG_USB_API_PUTS( "\nUSBD_AddEndpoint(), Illegal OUT EP address" );
mbed_official 59:2af474687369 884 EFM_ASSERT( false );
mbed_official 59:2af474687369 885 return USB_STATUS_ILLEGAL;
mbed_official 59:2af474687369 886 }
mbed_official 59:2af474687369 887 }
mbed_official 59:2af474687369 888
mbed_official 59:2af474687369 889 USB_PRINTF("USBD: Added endpoint %d to slot %d, in %d, addr 0x%x, type %d, ps %d, fifo %ld (total tx %ld, rx %ld)\n",
mbed_official 59:2af474687369 890 ep->num, numEps, ep->in, ep->addr, ep->type, ep->packetSize, ep->fifoSize,
mbed_official 59:2af474687369 891 totalTxFifoSize, totalRxFifoSize);
mbed_official 59:2af474687369 892
mbed_official 59:2af474687369 893 INT_Disable();
mbed_official 59:2af474687369 894 #if defined( CMU_OSCENCMD_USHFRCOEN )
mbed_official 59:2af474687369 895 /* Happy Gecko workaround: disable LEM GATE mode if using ISOC endpoints. */
mbed_official 59:2af474687369 896 if ( transferType == USB_EPTYPE_ISOC )
mbed_official 59:2af474687369 897 {
mbed_official 59:2af474687369 898 USB->CTRL = (USB->CTRL & ~_USB_CTRL_LEMOSCCTRL_MASK) | USB_CTRL_LEMOSCCTRL_NONE;
mbed_official 59:2af474687369 899 }
mbed_official 59:2af474687369 900 #endif
mbed_official 59:2af474687369 901
mbed_official 59:2af474687369 902 int ret = USBDHAL_ReconfigureFifos(totalRxFifoSize, totalTxFifoSize);
mbed_official 59:2af474687369 903 INT_Enable();
mbed_official 59:2af474687369 904
mbed_official 59:2af474687369 905 if( ret != USB_STATUS_OK ) {
mbed_official 59:2af474687369 906 return ret;
mbed_official 59:2af474687369 907 }
mbed_official 59:2af474687369 908
mbed_official 59:2af474687369 909 USBDHAL_ActivateEp(ep, false);
mbed_official 59:2af474687369 910
mbed_official 59:2af474687369 911 return USB_STATUS_OK;
mbed_official 59:2af474687369 912 }
mbed_official 59:2af474687369 913
mbed_official 59:2af474687369 914
mbed_official 59:2af474687369 915 /***************************************************************************//**
mbed_official 59:2af474687369 916 * @brief
mbed_official 59:2af474687369 917 * Set an endpoint0 in the stalled (halted) state.
mbed_official 59:2af474687369 918 *
mbed_official 59:2af474687369 919 * @details
mbed_official 59:2af474687369 920 * Temporarily stalls endpoint 0. Used to signal a failure to respond to
mbed_official 59:2af474687369 921 * the host's setup packet.
mbed_official 59:2af474687369 922 ******************************************************************************/
mbed_official 59:2af474687369 923 void USBD_StallEp0()
mbed_official 59:2af474687369 924 {
mbed_official 59:2af474687369 925 int const epAddr = 0;
mbed_official 59:2af474687369 926 USBD_Ep_TypeDef *ep = USBD_GetEpFromAddr( epAddr );
mbed_official 59:2af474687369 927 ep->in = true;
mbed_official 59:2af474687369 928 USBDHAL_StallEp( ep ); /* Stall Ep0 IN */
mbed_official 59:2af474687369 929 ep->in = false; /* OUT for next SETUP */
mbed_official 59:2af474687369 930 USBDHAL_StallEp( ep ); /* Stall Ep0 OUT */
mbed_official 59:2af474687369 931 #if !defined( USB_DOEP0INT_STUPPKTRCVD )
mbed_official 59:2af474687369 932 USBDHAL_ReenableEp0Setup( dev ); /* Prepare for next SETUP pkt. */
mbed_official 59:2af474687369 933 #else
mbed_official 59:2af474687369 934 USBDHAL_StartEp0Setup( dev );
mbed_official 59:2af474687369 935 #endif
mbed_official 59:2af474687369 936 ep->state = D_EP_IDLE;
mbed_official 59:2af474687369 937 }
mbed_official 59:2af474687369 938
mbed_official 59:2af474687369 939 /******** THE REST OF THE FILE IS DOCUMENTATION ONLY !**********************//**
mbed_official 59:2af474687369 940 * @{
mbed_official 59:2af474687369 941
mbed_official 59:2af474687369 942 @page usb_device USB device stack library
mbed_official 59:2af474687369 943
mbed_official 59:2af474687369 944 The source files for the USB device stack resides in the usb directory
mbed_official 59:2af474687369 945 and follows the naming convention: em_usbd<em>nnn</em>.c/h.
mbed_official 59:2af474687369 946
mbed_official 59:2af474687369 947 @li @ref usb_device_intro
mbed_official 59:2af474687369 948 @li @ref usb_device_api
mbed_official 59:2af474687369 949 @li @ref usb_device_conf
mbed_official 59:2af474687369 950 @li @ref usb_device_powersave
mbed_official 59:2af474687369 951 @li @ref usb_device_example1
mbed_official 59:2af474687369 952
mbed_official 59:2af474687369 953
mbed_official 59:2af474687369 954 @n @section usb_device_intro Introduction
mbed_official 59:2af474687369 955
mbed_official 59:2af474687369 956 The USB device protocol stack provides an API which makes it possible to
mbed_official 59:2af474687369 957 create USB devices with a minimum of effort. The device stack supports control,
mbed_official 59:2af474687369 958 bulk and interrupt transfers.
mbed_official 59:2af474687369 959
mbed_official 59:2af474687369 960 The stack is highly configurable to suit various needs, it does also contain
mbed_official 59:2af474687369 961 useful debugging features together with several demonstration projects to
mbed_official 59:2af474687369 962 get you started fast.
mbed_official 59:2af474687369 963
mbed_official 59:2af474687369 964 We recommend that you read through this documentation, then proceed to build
mbed_official 59:2af474687369 965 and test a few example projects before you start designing your own device.
mbed_official 59:2af474687369 966
mbed_official 59:2af474687369 967 @n @section usb_device_api The device stack API
mbed_official 59:2af474687369 968
mbed_official 59:2af474687369 969 This section contains brief descriptions of the functions in the API. You will
mbed_official 59:2af474687369 970 find detailed information on input and output parameters and return values by
mbed_official 59:2af474687369 971 clicking on the hyperlinked function names. It is also a good idea to study
mbed_official 59:2af474687369 972 the code in the USB demonstration projects.
mbed_official 59:2af474687369 973
mbed_official 59:2af474687369 974 Your application code must include one header file: @em em_usb.h.
mbed_official 59:2af474687369 975
mbed_official 59:2af474687369 976 All functions defined in the API can be called from within interrupt handlers.
mbed_official 59:2af474687369 977
mbed_official 59:2af474687369 978 The USB stack use a hardware timer to keep track of time. TIMER0 is the
mbed_official 59:2af474687369 979 default choice, refer to @ref usb_device_conf for other possibilities.
mbed_official 59:2af474687369 980 Your application must not use the selected timer.
mbed_official 59:2af474687369 981
mbed_official 59:2af474687369 982 <b>Pitfalls:</b>@n
mbed_official 59:2af474687369 983 The USB peripheral will fill your receive buffers in quantities of WORD's
mbed_official 59:2af474687369 984 (4 bytes). Transmit and receive buffers must be WORD aligned, in
mbed_official 59:2af474687369 985 addition when allocating storage for receive buffers, round size up to
mbed_official 59:2af474687369 986 next WORD boundary. If it is possible that the host will send more data
mbed_official 59:2af474687369 987 than your device expects, round buffer size up to the next multiple of
mbed_official 59:2af474687369 988 maxpacket size for the relevant endpoint to avoid data corruption.
mbed_official 59:2af474687369 989
mbed_official 59:2af474687369 990 Transmit buffers passed to @htmlonly USBD_Write() @endhtmlonly must be
mbed_official 59:2af474687369 991 statically allocated because @htmlonly USBD_Write() @endhtmlonly only
mbed_official 59:2af474687369 992 initiates the transfer. When the host decide to actually perform the
mbed_official 59:2af474687369 993 transfer, your data must be available.
mbed_official 59:2af474687369 994
mbed_official 59:2af474687369 995 @n @ref USBD_Init() @n
mbed_official 59:2af474687369 996 This function is called to register your device and all its properties with
mbed_official 59:2af474687369 997 the device stack. The application must fill in a @ref USBD_Init_TypeDef
mbed_official 59:2af474687369 998 structure prior to calling. Refer to @ref DeviceInitCallbacks for the
mbed_official 59:2af474687369 999 optional callback functions defined within this structure. When this
mbed_official 59:2af474687369 1000 function has been called your device is ready to be enumerated by the USB
mbed_official 59:2af474687369 1001 host.
mbed_official 59:2af474687369 1002
mbed_official 59:2af474687369 1003 @ref USBD_Read(), @ref USBD_Write() @n
mbed_official 59:2af474687369 1004 These functions initiate data transfers.
mbed_official 59:2af474687369 1005 @n @htmlonly USBD_Read() @endhtmlonly initiate a transfer of data @em
mbed_official 59:2af474687369 1006 from host @em to device (an @em OUT transfer in USB terminology).
mbed_official 59:2af474687369 1007 @n @htmlonly USBD_Write() @endhtmlonly initiate a transfer of data @em from
mbed_official 59:2af474687369 1008 device @em to host (an @em IN transfer).
mbed_official 59:2af474687369 1009
mbed_official 59:2af474687369 1010 When the USB host actually performs the transfer, your application will be
mbed_official 59:2af474687369 1011 notified by means of a callback function which you provide (optionally).
mbed_official 59:2af474687369 1012 Refer to @ref TransferCallback for details of the callback functionality.
mbed_official 59:2af474687369 1013
mbed_official 59:2af474687369 1014 @ref USBD_AbortTransfer(), @ref USBD_AbortAllTransfers() @n
mbed_official 59:2af474687369 1015 These functions terminate transfers that are initiated, but has not yet
mbed_official 59:2af474687369 1016 taken place. If a transfer is initiated with @htmlonly USBD_Read()
mbed_official 59:2af474687369 1017 or USBD_Write(), @endhtmlonly but the USB host never actually peform
mbed_official 59:2af474687369 1018 the transfers, these functions will deactivate the transfer setup to make
mbed_official 59:2af474687369 1019 the USB device endpoint hardware ready for new (and potentially) different
mbed_official 59:2af474687369 1020 transfers.
mbed_official 59:2af474687369 1021
mbed_official 59:2af474687369 1022 @ref USBD_Connect(), @ref USBD_Disconnect() @n
mbed_official 59:2af474687369 1023 These functions turns the data-line (D+ or D-) pullup on or off. They can be
mbed_official 59:2af474687369 1024 used to force reenumeration. It's good practice to delay at least one second
mbed_official 59:2af474687369 1025 between @htmlonly USBD_Disconnect() and USBD_Connect() @endhtmlonly
mbed_official 59:2af474687369 1026 to allow the USB host to unload the currently active device driver.
mbed_official 59:2af474687369 1027
mbed_official 59:2af474687369 1028 @ref USBD_EpIsBusy() @n
mbed_official 59:2af474687369 1029 Check if an endpoint is busy.
mbed_official 59:2af474687369 1030
mbed_official 59:2af474687369 1031 @ref USBD_StallEp(), @ref USBD_UnStallEp() @n
mbed_official 59:2af474687369 1032 These functions stalls or un-stalls an endpoint. This functionality may not
mbed_official 59:2af474687369 1033 be needed by your application, but the USB device stack use them in response
mbed_official 59:2af474687369 1034 to standard setup commands SET_FEATURE and CLEAR_FEATURE. They may be useful
mbed_official 59:2af474687369 1035 when implementing some USB classes, e.g. a mass storage device use them
mbed_official 59:2af474687369 1036 extensively.
mbed_official 59:2af474687369 1037
mbed_official 59:2af474687369 1038 @ref USBD_RemoteWakeup() @n
mbed_official 59:2af474687369 1039 Used in SUSPENDED state (see @ref USB_Status_TypeDef) to signal resume to
mbed_official 59:2af474687369 1040 host. It's the applications responsibility to adhere to the USB standard
mbed_official 59:2af474687369 1041 which states that a device can not signal resume before it has been
mbed_official 59:2af474687369 1042 SUSPENDED for at least 5 ms. The function will also check the configuration
mbed_official 59:2af474687369 1043 descriptor defined by the application to see if it is legal for the device
mbed_official 59:2af474687369 1044 to signal resume.
mbed_official 59:2af474687369 1045
mbed_official 59:2af474687369 1046 @ref USBD_GetUsbState() @n
mbed_official 59:2af474687369 1047 Returns the device USB state (see @ref USBD_State_TypeDef). Refer to
mbed_official 59:2af474687369 1048 Figure 9-1. "Device State Diagram" in the USB revision 2.0 specification.
mbed_official 59:2af474687369 1049
mbed_official 59:2af474687369 1050 @ref USBD_GetUsbStateName() @n
mbed_official 59:2af474687369 1051 Returns a text string naming a given USB device state.
mbed_official 59:2af474687369 1052
mbed_official 59:2af474687369 1053 @ref USBD_SafeToEnterEM2() @n
mbed_official 59:2af474687369 1054 Check if it is ok to enter energy mode EM2. Refer to the
mbed_official 59:2af474687369 1055 @ref usb_device_powersave section for more information.
mbed_official 59:2af474687369 1056
mbed_official 59:2af474687369 1057 @n @anchor TransferCallback <b>The transfer complete callback function:</b> @n
mbed_official 59:2af474687369 1058 @n USB_XferCompleteCb_TypeDef() is called when a transfer completes. It is
mbed_official 59:2af474687369 1059 called with three parameters, the status of the transfer, the number of
mbed_official 59:2af474687369 1060 bytes transferred and the number of bytes remaining. It may not always be
mbed_official 59:2af474687369 1061 needed to have a callback on transfer completion, but you should keep in
mbed_official 59:2af474687369 1062 mind that a transfer may be aborted when you least expect it. A transfer
mbed_official 59:2af474687369 1063 will be aborted if host stalls the endpoint, if host resets your device, if
mbed_official 59:2af474687369 1064 host unconfigures your device or if you unplug your device cable and the
mbed_official 59:2af474687369 1065 device is selfpowered.
mbed_official 59:2af474687369 1066 @htmlonly USB_XferCompleteCb_TypeDef() @endhtmlonly is also called if your
mbed_official 59:2af474687369 1067 application use @htmlonly USBD_AbortTransfer() or USBD_AbortAllTransfers()
mbed_official 59:2af474687369 1068 @endhtmlonly calls.
mbed_official 59:2af474687369 1069 @note This callback is called from within an interrupt handler with
mbed_official 59:2af474687369 1070 interrupts disabled.
mbed_official 59:2af474687369 1071
mbed_official 59:2af474687369 1072 @n @anchor DeviceInitCallbacks <b>Optional callbacks passed to the stack via
mbed_official 59:2af474687369 1073 the @ref USBD_Init() function:</b> @n
mbed_official 59:2af474687369 1074 @n These callbacks are all optional, and it is up to the application
mbed_official 59:2af474687369 1075 programmer to decide if the application needs the functionality they
mbed_official 59:2af474687369 1076 provide.
mbed_official 59:2af474687369 1077 @note These callbacks are all called from within an interrupt handler
mbed_official 59:2af474687369 1078 with interrupts disabled.
mbed_official 59:2af474687369 1079
mbed_official 59:2af474687369 1080 USBD_UsbResetCb_TypeDef() is called each time reset signalling is sensed on
mbed_official 59:2af474687369 1081 the USB wire.
mbed_official 59:2af474687369 1082
mbed_official 59:2af474687369 1083 @n USBD_SofIntCb_TypeDef() is called with framenumber as a parameter on
mbed_official 59:2af474687369 1084 each SOF interrupt.
mbed_official 59:2af474687369 1085
mbed_official 59:2af474687369 1086 @n USBD_DeviceStateChangeCb_TypeDef() is called whenever the device state
mbed_official 59:2af474687369 1087 change. Useful for detecting e.g. SUSPENDED state change in order to reduce
mbed_official 59:2af474687369 1088 current consumption of buspowered devices. The USB HID keyboard example
mbed_official 59:2af474687369 1089 project has a good example on how to use this callback.
mbed_official 59:2af474687369 1090
mbed_official 59:2af474687369 1091 @n USBD_IsSelfPoweredCb_TypeDef() is called by the device stack when host
mbed_official 59:2af474687369 1092 queries the device with a standard setup GET_STATUS command to check if the
mbed_official 59:2af474687369 1093 device is currently selfpowered or buspowered. This feature is only
mbed_official 59:2af474687369 1094 applicable on selfpowered devices which also works when only buspower is
mbed_official 59:2af474687369 1095 available.
mbed_official 59:2af474687369 1096
mbed_official 59:2af474687369 1097 @n USBD_SetupCmdCb_TypeDef() is called each time a setup command is
mbed_official 59:2af474687369 1098 received from host. Use this callback to override or extend the default
mbed_official 59:2af474687369 1099 handling of standard setup commands, and to implement class or vendor
mbed_official 59:2af474687369 1100 specific setup commands. The USB HID keyboard example project has a good
mbed_official 59:2af474687369 1101 example on how to use this callback.
mbed_official 59:2af474687369 1102
mbed_official 59:2af474687369 1103 @n <b>Utility functions:</b> @n
mbed_official 59:2af474687369 1104 @n USB_PUTCHAR() Transmit a single char on the debug serial port.
mbed_official 59:2af474687369 1105 @n @n USB_PUTS() Transmit a zero terminated string on the debug serial port.
mbed_official 59:2af474687369 1106 @n @n USB_PRINTF() Transmit "printf" formated data on the debug serial port.
mbed_official 59:2af474687369 1107 @n @n USB_GetErrorMsgString() Return an error message string for a given
mbed_official 59:2af474687369 1108 error code.
mbed_official 59:2af474687369 1109 @n @n USB_PrintErrorMsgString() Format and print a text string given an
mbed_official 59:2af474687369 1110 error code, prepends an optional user supplied leader string.
mbed_official 59:2af474687369 1111 @n @n USBTIMER_DelayMs() Active wait millisecond delay function. Can also be
mbed_official 59:2af474687369 1112 used inside interrupt handlers.
mbed_official 59:2af474687369 1113 @n @n USBTIMER_DelayUs() Active wait microsecond delay function. Can also be
mbed_official 59:2af474687369 1114 used inside interrupt handlers.
mbed_official 59:2af474687369 1115 @n @n USBTIMER_Init() Initialize the timer system. Called by @htmlonly
mbed_official 59:2af474687369 1116 USBD_Init(), @endhtmlonly but your application must call it again to
mbed_official 59:2af474687369 1117 reinitialize whenever you change the HFPERCLK frequency.
mbed_official 59:2af474687369 1118 @n @n USBTIMER_Start() Start a timer. You can configure the USB device stack
mbed_official 59:2af474687369 1119 to provide any number of timers. The timers have 1 ms resolution, your
mbed_official 59:2af474687369 1120 application is notified of timeout by means of a callback.
mbed_official 59:2af474687369 1121 @n @n USBTIMER_Stop() Stop a timer.
mbed_official 59:2af474687369 1122
mbed_official 59:2af474687369 1123 @n @section usb_device_conf Configuring the device stack
mbed_official 59:2af474687369 1124
mbed_official 59:2af474687369 1125 Your application must provide a header file named @em usbconfig.h. This file
mbed_official 59:2af474687369 1126 must contain the following \#define's:@n @n
mbed_official 59:2af474687369 1127 @verbatim
mbed_official 59:2af474687369 1128 #define USB_DEVICE // Compile the stack for device mode.
mbed_official 59:2af474687369 1129 #define NUM_EP_USED n // Your application use 'n' endpoints in
mbed_official 59:2af474687369 1130 // addition to endpoint 0. @endverbatim
mbed_official 59:2af474687369 1131
mbed_official 59:2af474687369 1132 @n @em usbconfig.h may define the following items: @n @n
mbed_official 59:2af474687369 1133 @verbatim
mbed_official 59:2af474687369 1134 #define NUM_APP_TIMERS n // Your application needs 'n' timers
mbed_official 59:2af474687369 1135
mbed_official 59:2af474687369 1136 #define DEBUG_USB_API // Turn on API debug diagnostics.
mbed_official 59:2af474687369 1137
mbed_official 59:2af474687369 1138 // Some utility functions in the API needs printf. These
mbed_official 59:2af474687369 1139 // functions have "print" in their name. This macro enables
mbed_official 59:2af474687369 1140 // these functions.
mbed_official 59:2af474687369 1141 #define USB_USE_PRINTF // Enable utility print functions.
mbed_official 59:2af474687369 1142
mbed_official 59:2af474687369 1143 // Define a function for transmitting a single char on the serial port.
mbed_official 59:2af474687369 1144 extern int RETARGET_WriteChar(char c);
mbed_official 59:2af474687369 1145 #define USER_PUTCHAR RETARGET_WriteChar
mbed_official 59:2af474687369 1146
mbed_official 59:2af474687369 1147 #define USB_TIMER USB_TIMERn // Select which hardware timer the USB stack
mbed_official 59:2af474687369 1148 // is allowed to use. Valid values are n=0,1,2...
mbed_official 59:2af474687369 1149 // corresponding to TIMER0, TIMER1, ...
mbed_official 59:2af474687369 1150 // If not specified, TIMER0 is used
mbed_official 59:2af474687369 1151
mbed_official 59:2af474687369 1152 #define USB_VBUS_SWITCH_NOT_PRESENT // Hardware does not have a VBUS switch
mbed_official 59:2af474687369 1153
mbed_official 59:2af474687369 1154 #define USB_CORECLK_HFRCO // Devices supporting crystal-less USB can use
mbed_official 59:2af474687369 1155 // HFRCO as core clock, default is HFXO
mbed_official 59:2af474687369 1156 @endverbatim
mbed_official 59:2af474687369 1157
mbed_official 59:2af474687369 1158 @n You are strongly encouraged to start application development with DEBUG_USB_API
mbed_official 59:2af474687369 1159 turned on. When DEBUG_USB_API is turned on and USER_PUTCHAR is defined, useful
mbed_official 59:2af474687369 1160 debugging information will be output on the development kit serial port.
mbed_official 59:2af474687369 1161 Compiling with the DEBUG_EFM_USER flag will also enable all asserts
mbed_official 59:2af474687369 1162 in both @em emlib and in the USB stack. If asserts are enabled and
mbed_official 59:2af474687369 1163 USER_PUTCHAR defined, assert texts will be output on the serial port.
mbed_official 59:2af474687369 1164
mbed_official 59:2af474687369 1165 You application must include @em retargetserial.c if DEBUG_USB_API is defined
mbed_official 59:2af474687369 1166 and @em retargetio.c if USB_USE_PRINTF is defined.
mbed_official 59:2af474687369 1167 These files reside in the @em drivers
mbed_official 59:2af474687369 1168 directory in the software package for your development board. Refer to
mbed_official 59:2af474687369 1169 @ref usb_device_powersave for energy-saving mode configurations.
mbed_official 59:2af474687369 1170
mbed_official 59:2af474687369 1171 @n @section usb_device_powersave Energy-saving modes
mbed_official 59:2af474687369 1172
mbed_official 59:2af474687369 1173 The device stack provides two energy saving levels. The first level is to
mbed_official 59:2af474687369 1174 set the USB peripheral in energy saving mode, the next level is to enter
mbed_official 59:2af474687369 1175 Energy Mode 2 (EM2). These energy saving modes can be applied when the device
mbed_official 59:2af474687369 1176 is suspended by the USB host, or when when the device is not connected to a
mbed_official 59:2af474687369 1177 USB host.
mbed_official 59:2af474687369 1178 In addition to this an application can use energy modes EM1 and EM2. There
mbed_official 59:2af474687369 1179 are no restrictions on when EM1 can be entered, EM2 can only be entered
mbed_official 59:2af474687369 1180 when the USB device is suspended or detached from host.
mbed_official 59:2af474687369 1181
mbed_official 59:2af474687369 1182 Energy-saving modes are selected with a \#define in @em usbconfig.h, default
mbed_official 59:2af474687369 1183 selection is to not use any energy saving modes.@n @n
mbed_official 59:2af474687369 1184 @verbatim
mbed_official 59:2af474687369 1185 #define USB_PWRSAVE_MODE (USB_PWRSAVE_MODE_ONSUSPEND | USB_PWRSAVE_MODE_ENTEREM2)@endverbatim
mbed_official 59:2af474687369 1186
mbed_official 59:2af474687369 1187 There are three flags available, the flags can be or'ed together as shown above.
mbed_official 59:2af474687369 1188
mbed_official 59:2af474687369 1189 <b>\#define USB_PWRSAVE_MODE_ONSUSPEND</b>@n Set USB peripheral in low power
mbed_official 59:2af474687369 1190 mode on suspend.
mbed_official 59:2af474687369 1191
mbed_official 59:2af474687369 1192 <b>\#define USB_PWRSAVE_MODE_ONVBUSOFF</b>@n Set USB peripheral in low power
mbed_official 59:2af474687369 1193 mode when not attached to a host. This mode assumes that the internal voltage
mbed_official 59:2af474687369 1194 regulator is used and that the VREGI pin of the chip is connected to VBUS.
mbed_official 59:2af474687369 1195 This option can not be used with bus-powered devices.
mbed_official 59:2af474687369 1196
mbed_official 59:2af474687369 1197 <b>\#define USB_PWRSAVE_MODE_ENTEREM2</b>@n Enter EM2 when USB peripheral is
mbed_official 59:2af474687369 1198 in low power mode.
mbed_official 59:2af474687369 1199
mbed_official 59:2af474687369 1200 When the USB peripheral is set in low power mode, it must be clocked by a 32kHz
mbed_official 59:2af474687369 1201 clock. Both LFXO and LFRCO can be used, but only LFXO guarantee USB specification
mbed_official 59:2af474687369 1202 compliance. Selection is done with a \#define in @em usbconfig.h.@n @n
mbed_official 59:2af474687369 1203 @verbatim
mbed_official 59:2af474687369 1204 #define USB_USBC_32kHz_CLK USB_USBC_32kHz_CLK_LFXO @endverbatim
mbed_official 59:2af474687369 1205 Two flags are available, <b>USB_USBC_32kHz_CLK_LFXO</b> and
mbed_official 59:2af474687369 1206 <b>USB_USBC_32kHz_CLK_LFRCO</b>. <b>USB_USBC_32kHz_CLK_LFXO</b> is selected
mbed_official 59:2af474687369 1207 by default.
mbed_official 59:2af474687369 1208
mbed_official 59:2af474687369 1209 The USB HID keyboard and Mass Storage device example projects demonstrate
mbed_official 59:2af474687369 1210 different energy-saving modes.
mbed_official 59:2af474687369 1211
mbed_official 59:2af474687369 1212 <b>Example 1:</b>
mbed_official 59:2af474687369 1213 Leave all energy saving to the stack, the device enters EM2 on suspend and
mbed_official 59:2af474687369 1214 when detached from host. @n
mbed_official 59:2af474687369 1215 @verbatim
mbed_official 59:2af474687369 1216 In usbconfig.h:
mbed_official 59:2af474687369 1217
mbed_official 59:2af474687369 1218 #define USB_PWRSAVE_MODE (USB_PWRSAVE_MODE_ONSUSPEND | USB_PWRSAVE_MODE_ONVBUSOFF | USB_PWRSAVE_MODE_ENTEREM2)
mbed_official 59:2af474687369 1219 @endverbatim
mbed_official 59:2af474687369 1220
mbed_official 59:2af474687369 1221 @n <b>Example 2:</b>
mbed_official 59:2af474687369 1222 Let the stack control energy saving in the USB periheral but let your
mbed_official 59:2af474687369 1223 application control energy modes EM1 and EM2. @n
mbed_official 59:2af474687369 1224 @verbatim
mbed_official 59:2af474687369 1225 In usbconfig.h:
mbed_official 59:2af474687369 1226
mbed_official 59:2af474687369 1227 #define USB_PWRSAVE_MODE (USB_PWRSAVE_MODE_ONSUSPEND | USB_PWRSAVE_MODE_ONVBUSOFF)
mbed_official 59:2af474687369 1228
mbed_official 59:2af474687369 1229 In application code:
mbed_official 59:2af474687369 1230
mbed_official 59:2af474687369 1231 if ( USBD_SafeToEnterEM2() )
mbed_official 59:2af474687369 1232 EMU_EnterEM2(true);
mbed_official 59:2af474687369 1233 else
mbed_official 59:2af474687369 1234 EMU_EnterEM1(); @endverbatim
mbed_official 59:2af474687369 1235
mbed_official 59:2af474687369 1236 @n @section usb_device_example1 Vendor unique device example application
mbed_official 59:2af474687369 1237
mbed_official 59:2af474687369 1238 This example represents the most simple USB device imaginable. It's purpose
mbed_official 59:2af474687369 1239 is to turn user LED's on or off under control of vendor unique setup commands.
mbed_official 59:2af474687369 1240 The device will rely on @em libusb device driver on the host, a host
mbed_official 59:2af474687369 1241 application @em EFM32-LedApp.exe is bundled with the example.
mbed_official 59:2af474687369 1242
mbed_official 59:2af474687369 1243 The main() is really simple ! @n @n
mbed_official 59:2af474687369 1244 @verbatim
mbed_official 59:2af474687369 1245 #include "em_usb.h"
mbed_official 59:2af474687369 1246
mbed_official 59:2af474687369 1247 #include "descriptors.h"
mbed_official 59:2af474687369 1248
mbed_official 59:2af474687369 1249 int main( void )
mbed_official 59:2af474687369 1250 {
mbed_official 59:2af474687369 1251 BSP_Init(BSP_INIT_DEFAULT); // Initialize DK board register access
mbed_official 59:2af474687369 1252 CMU_ClockSelectSet( cmuClock_HF, cmuSelect_HFXO );
mbed_official 59:2af474687369 1253 BSP_LedsSet(0); // Turn off all LED's
mbed_official 59:2af474687369 1254
mbed_official 59:2af474687369 1255 ConsoleDebugInit(); // Initialize UART for debug diagnostics
mbed_official 59:2af474687369 1256
mbed_official 59:2af474687369 1257 USB_PUTS( "\nEFM32 USB LED Vendor Unique Device example\n" );
mbed_official 59:2af474687369 1258
mbed_official 59:2af474687369 1259 USBD_Init( &initstruct ); // GO !
mbed_official 59:2af474687369 1260
mbed_official 59:2af474687369 1261 //When using a debugger it is pratical to uncomment the following three
mbed_official 59:2af474687369 1262 //lines to force host to re-enumerate the device.
mbed_official 59:2af474687369 1263
mbed_official 59:2af474687369 1264 //USBD_Disconnect();
mbed_official 59:2af474687369 1265 //USBTIMER_DelayMs( 1000 );
mbed_official 59:2af474687369 1266 //USBD_Connect();
mbed_official 59:2af474687369 1267
mbed_official 59:2af474687369 1268 for (;;) {}
mbed_official 59:2af474687369 1269 } @endverbatim
mbed_official 59:2af474687369 1270
mbed_official 59:2af474687369 1271 @n Configure the device stack in <em>usbconfig.h</em>: @n @n
mbed_official 59:2af474687369 1272 @verbatim
mbed_official 59:2af474687369 1273 #define USB_DEVICE // Compile stack for device mode.
mbed_official 59:2af474687369 1274
mbed_official 59:2af474687369 1275 // **************************************************************************
mbed_official 59:2af474687369 1276 ** **
mbed_official 59:2af474687369 1277 ** Specify number of endpoints used (in addition to EP0). **
mbed_official 59:2af474687369 1278 ** **
mbed_official 59:2af474687369 1279 *****************************************************************************
mbed_official 59:2af474687369 1280 #define NUM_EP_USED 0 // EP0 is the only endpoint used.
mbed_official 59:2af474687369 1281
mbed_official 59:2af474687369 1282 // **************************************************************************
mbed_official 59:2af474687369 1283 ** **
mbed_official 59:2af474687369 1284 ** Configure serial port debug output. **
mbed_official 59:2af474687369 1285 ** **
mbed_official 59:2af474687369 1286 *****************************************************************************
mbed_official 59:2af474687369 1287 // Prototype a function for transmitting a single char on the serial port.
mbed_official 59:2af474687369 1288 extern int RETARGET_WriteChar(char c);
mbed_official 59:2af474687369 1289 #define USER_PUTCHAR RETARGET_WriteChar
mbed_official 59:2af474687369 1290
mbed_official 59:2af474687369 1291 // Enable debug diagnostics from API functions (illegal input params etc.)
mbed_official 59:2af474687369 1292 #define DEBUG_USB_API @endverbatim
mbed_official 59:2af474687369 1293
mbed_official 59:2af474687369 1294 @n Define device properties and fill in USB initstruct in
mbed_official 59:2af474687369 1295 <em>descriptors.h</em>: @n @n
mbed_official 59:2af474687369 1296 @verbatim
mbed_official 59:2af474687369 1297 EFM32_ALIGN(4)
mbed_official 59:2af474687369 1298 static const USB_DeviceDescriptor_TypeDef deviceDesc __attribute__ ((aligned(4))) =
mbed_official 59:2af474687369 1299 {
mbed_official 59:2af474687369 1300 .bLength = USB_DEVICE_DESCSIZE,
mbed_official 59:2af474687369 1301 .bDescriptorType = USB_DEVICE_DESCRIPTOR,
mbed_official 59:2af474687369 1302 .bcdUSB = 0x0200,
mbed_official 59:2af474687369 1303 .bDeviceClass = 0xFF,
mbed_official 59:2af474687369 1304 .bDeviceSubClass = 0,
mbed_official 59:2af474687369 1305 .bDeviceProtocol = 0,
mbed_official 59:2af474687369 1306 .bMaxPacketSize0 = USB_FS_CTRL_EP_MAXSIZE,
mbed_official 59:2af474687369 1307 .idVendor = 0x10C4,
mbed_official 59:2af474687369 1308 .idProduct = 0x0001,
mbed_official 59:2af474687369 1309 .bcdDevice = 0x0000,
mbed_official 59:2af474687369 1310 .iManufacturer = 1,
mbed_official 59:2af474687369 1311 .iProduct = 2,
mbed_official 59:2af474687369 1312 .iSerialNumber = 3,
mbed_official 59:2af474687369 1313 .bNumConfigurations = 1
mbed_official 59:2af474687369 1314 };
mbed_official 59:2af474687369 1315
mbed_official 59:2af474687369 1316 EFM32_ALIGN(4)
mbed_official 59:2af474687369 1317 static const uint8_t configDesc[] __attribute__ ((aligned(4)))=
mbed_official 59:2af474687369 1318 {
mbed_official 59:2af474687369 1319 // *** Configuration descriptor ***
mbed_official 59:2af474687369 1320 USB_CONFIG_DESCSIZE, // bLength
mbed_official 59:2af474687369 1321 USB_CONFIG_DESCRIPTOR, // bDescriptorType
mbed_official 59:2af474687369 1322 USB_CONFIG_DESCSIZE + // wTotalLength (LSB)
mbed_official 59:2af474687369 1323 USB_INTERFACE_DESCSIZE,
mbed_official 59:2af474687369 1324 (USB_CONFIG_DESCSIZE + // wTotalLength (MSB)
mbed_official 59:2af474687369 1325 USB_INTERFACE_DESCSIZE)>>8,
mbed_official 59:2af474687369 1326 1, // bNumInterfaces
mbed_official 59:2af474687369 1327 1, // bConfigurationValue
mbed_official 59:2af474687369 1328 0, // iConfiguration
mbed_official 59:2af474687369 1329 CONFIG_DESC_BM_RESERVED_D7 | // bmAttrib: Self powered
mbed_official 59:2af474687369 1330 CONFIG_DESC_BM_SELFPOWERED,
mbed_official 59:2af474687369 1331 CONFIG_DESC_MAXPOWER_mA( 100 ), // bMaxPower: 100 mA
mbed_official 59:2af474687369 1332
mbed_official 59:2af474687369 1333 // *** Interface descriptor ***
mbed_official 59:2af474687369 1334 USB_INTERFACE_DESCSIZE, // bLength
mbed_official 59:2af474687369 1335 USB_INTERFACE_DESCRIPTOR, // bDescriptorType
mbed_official 59:2af474687369 1336 0, // bInterfaceNumber
mbed_official 59:2af474687369 1337 0, // bAlternateSetting
mbed_official 59:2af474687369 1338 NUM_EP_USED, // bNumEndpoints
mbed_official 59:2af474687369 1339 0xFF, // bInterfaceClass
mbed_official 59:2af474687369 1340 0, // bInterfaceSubClass
mbed_official 59:2af474687369 1341 0, // bInterfaceProtocol
mbed_official 59:2af474687369 1342 0, // iInterface
mbed_official 59:2af474687369 1343 };
mbed_official 59:2af474687369 1344
mbed_official 59:2af474687369 1345 STATIC_CONST_STRING_DESC_LANGID( langID, 0x04, 0x09 );
mbed_official 59:2af474687369 1346 STATIC_CONST_STRING_DESC( iManufacturer, 'E','n','e','r','g','y',' ', \
mbed_official 59:2af474687369 1347 'M','i','c','r','o',' ','A','S' );
mbed_official 59:2af474687369 1348 STATIC_CONST_STRING_DESC( iProduct , 'V','e','n','d','o','r',' ', \
mbed_official 59:2af474687369 1349 'U','n','i','q','u','e',' ', \
mbed_official 59:2af474687369 1350 'L','E','D',' ', \
mbed_official 59:2af474687369 1351 'D','e','v','i','c','e' );
mbed_official 59:2af474687369 1352 STATIC_CONST_STRING_DESC( iSerialNumber, '0','0','0','0','0','0', \
mbed_official 59:2af474687369 1353 '0','0','1','2','3','4' );
mbed_official 59:2af474687369 1354
mbed_official 59:2af474687369 1355 static const void * const strings[] =
mbed_official 59:2af474687369 1356 {
mbed_official 59:2af474687369 1357 &langID,
mbed_official 59:2af474687369 1358 &iManufacturer,
mbed_official 59:2af474687369 1359 &iProduct,
mbed_official 59:2af474687369 1360 &iSerialNumber
mbed_official 59:2af474687369 1361 };
mbed_official 59:2af474687369 1362
mbed_official 59:2af474687369 1363 // Endpoint buffer sizes
mbed_official 59:2af474687369 1364 // 1 = single buffer, 2 = double buffering, 3 = tripple buffering ...
mbed_official 59:2af474687369 1365 static const uint8_t bufferingMultiplier[ NUM_EP_USED + 1 ] = { 1 };
mbed_official 59:2af474687369 1366
mbed_official 59:2af474687369 1367 static const USBD_Callbacks_TypeDef callbacks =
mbed_official 59:2af474687369 1368 {
mbed_official 59:2af474687369 1369 .usbReset = NULL,
mbed_official 59:2af474687369 1370 .usbStateChange = NULL,
mbed_official 59:2af474687369 1371 .setupCmd = SetupCmd,
mbed_official 59:2af474687369 1372 .isSelfPowered = NULL,
mbed_official 59:2af474687369 1373 .sofInt = NULL
mbed_official 59:2af474687369 1374 };
mbed_official 59:2af474687369 1375
mbed_official 59:2af474687369 1376 static const USBD_Init_TypeDef initstruct =
mbed_official 59:2af474687369 1377 {
mbed_official 59:2af474687369 1378 .deviceDescriptor = &deviceDesc,
mbed_official 59:2af474687369 1379 .configDescriptor = configDesc,
mbed_official 59:2af474687369 1380 .stringDescriptors = strings,
mbed_official 59:2af474687369 1381 .numberOfStrings = sizeof(strings)/sizeof(void*),
mbed_official 59:2af474687369 1382 .callbacks = &callbacks,
mbed_official 59:2af474687369 1383 .bufferingMultiplier = bufferingMultiplier
mbed_official 59:2af474687369 1384 }; @endverbatim
mbed_official 59:2af474687369 1385
mbed_official 59:2af474687369 1386 @n Now we have to implement vendor unique USB setup commands to control the
mbed_official 59:2af474687369 1387 LED's (see callbacks variable above). Notice that the buffer variable below is
mbed_official 59:2af474687369 1388 statically allocated because @htmlonly USBD_Write() @endhtmlonly only
mbed_official 59:2af474687369 1389 initiates the transfer. When the host actually performs the transfer, the
mbed_official 59:2af474687369 1390 SetupCmd() function will have returned ! @n @n
mbed_official 59:2af474687369 1391
mbed_official 59:2af474687369 1392 @verbatim
mbed_official 59:2af474687369 1393 #define VND_GET_LEDS 0x10
mbed_official 59:2af474687369 1394 #define VND_SET_LED 0x11
mbed_official 59:2af474687369 1395
mbed_official 59:2af474687369 1396 static int SetupCmd( const USB_Setup_TypeDef *setup )
mbed_official 59:2af474687369 1397 {
mbed_official 59:2af474687369 1398 int retVal;
mbed_official 59:2af474687369 1399 uint16_t leds;
mbed_official 59:2af474687369 1400 static uint32_t buffer;
mbed_official 59:2af474687369 1401 uint8_t *pBuffer = (uint8_t*)&buffer;
mbed_official 59:2af474687369 1402
mbed_official 59:2af474687369 1403 retVal = USB_STATUS_REQ_UNHANDLED;
mbed_official 59:2af474687369 1404
mbed_official 59:2af474687369 1405 if ( setup->Type == USB_SETUP_TYPE_VENDOR )
mbed_official 59:2af474687369 1406 {
mbed_official 59:2af474687369 1407 switch ( setup->bRequest )
mbed_official 59:2af474687369 1408 {
mbed_official 59:2af474687369 1409 case VND_GET_LEDS:
mbed_official 59:2af474687369 1410 // ********************
mbed_official 59:2af474687369 1411 *pBuffer = BSP_LedsGet() & 0x1F;
mbed_official 59:2af474687369 1412 retVal = USBD_Write( 0, pBuffer, setup->wLength, NULL );
mbed_official 59:2af474687369 1413 break;
mbed_official 59:2af474687369 1414
mbed_official 59:2af474687369 1415 case VND_SET_LED:
mbed_official 59:2af474687369 1416 // ********************
mbed_official 59:2af474687369 1417 leds = DVK_getLEDs() & 0x1F;
mbed_official 59:2af474687369 1418 if ( setup->wValue )
mbed_official 59:2af474687369 1419 {
mbed_official 59:2af474687369 1420 leds |= LED0 << setup->wIndex;
mbed_official 59:2af474687369 1421 }
mbed_official 59:2af474687369 1422 else
mbed_official 59:2af474687369 1423 {
mbed_official 59:2af474687369 1424 leds &= ~( LED0 << setup->wIndex );
mbed_official 59:2af474687369 1425 }
mbed_official 59:2af474687369 1426 BSP_LedsSet( leds );
mbed_official 59:2af474687369 1427 retVal = USB_STATUS_OK;
mbed_official 59:2af474687369 1428 break;
mbed_official 59:2af474687369 1429 }
mbed_official 59:2af474687369 1430 }
mbed_official 59:2af474687369 1431
mbed_official 59:2af474687369 1432 return retVal;
mbed_official 59:2af474687369 1433 }@endverbatim
mbed_official 59:2af474687369 1434
mbed_official 59:2af474687369 1435 * @}**************************************************************************/
mbed_official 59:2af474687369 1436
mbed_official 59:2af474687369 1437 #endif /* defined( USB_DEVICE ) */
mbed_official 59:2af474687369 1438 #endif /* defined( USB_PRESENT ) && ( USB_COUNT == 1 ) */