USB device stack

Dependents:   mbed-mX-USB-TEST1 USBMSD_SD_HID_HelloWorld HidTest MIDI_usb_bridge ... more

Legacy Warning

This is an mbed 2 library. To learn more about mbed OS 5, visit the docs.

Pull requests against this repository are no longer supported. Please raise against mbed OS 5 as documented above.

Committer:
Kojto
Date:
Thu Jul 27 12:14:04 2017 +0100
Revision:
71:53949e6131f6
Update libraries

Fixes the previous commmit, as some devices were not copied. USBDevice contains
now targets directory with all targets implementations

Who changed what in which revision?

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