mbed library sources. Supersedes mbed-src.
Dependents: Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more
targets/TARGET_NUVOTON/TARGET_M451/device/StdDriver/m451_usbd.c@149:156823d33999, 2016-10-28 (annotated)
- Committer:
- <>
- Date:
- Fri Oct 28 11:17:30 2016 +0100
- Revision:
- 149:156823d33999
- Child:
- 154:37f96f9d4de2
This updates the lib to the mbed lib v128
NOTE: This release includes a restructuring of the file and directory locations and thus some
include paths in your code may need updating accordingly.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
<> | 149:156823d33999 | 1 | /**************************************************************************//** |
<> | 149:156823d33999 | 2 | * @file usbd.c |
<> | 149:156823d33999 | 3 | * @version V1.00 |
<> | 149:156823d33999 | 4 | * $Revision: 21 $ |
<> | 149:156823d33999 | 5 | * $Date: 15/08/21 3:34p $ |
<> | 149:156823d33999 | 6 | * @brief M451 series USBD driver source file |
<> | 149:156823d33999 | 7 | * |
<> | 149:156823d33999 | 8 | * @note |
<> | 149:156823d33999 | 9 | * Copyright (C) 2014~2015 Nuvoton Technology Corp. All rights reserved. |
<> | 149:156823d33999 | 10 | *****************************************************************************/ |
<> | 149:156823d33999 | 11 | |
<> | 149:156823d33999 | 12 | #include <string.h> |
<> | 149:156823d33999 | 13 | #include "M451Series.h" |
<> | 149:156823d33999 | 14 | |
<> | 149:156823d33999 | 15 | #if 0 |
<> | 149:156823d33999 | 16 | #define DBG_PRINTF printf |
<> | 149:156823d33999 | 17 | #else |
<> | 149:156823d33999 | 18 | #define DBG_PRINTF(...) |
<> | 149:156823d33999 | 19 | #endif |
<> | 149:156823d33999 | 20 | |
<> | 149:156823d33999 | 21 | #ifdef __cplusplus |
<> | 149:156823d33999 | 22 | extern "C" |
<> | 149:156823d33999 | 23 | { |
<> | 149:156823d33999 | 24 | #endif |
<> | 149:156823d33999 | 25 | |
<> | 149:156823d33999 | 26 | /** @addtogroup Standard_Driver Standard Driver |
<> | 149:156823d33999 | 27 | @{ |
<> | 149:156823d33999 | 28 | */ |
<> | 149:156823d33999 | 29 | |
<> | 149:156823d33999 | 30 | /** @addtogroup USBD_Driver USBD Driver |
<> | 149:156823d33999 | 31 | @{ |
<> | 149:156823d33999 | 32 | */ |
<> | 149:156823d33999 | 33 | |
<> | 149:156823d33999 | 34 | |
<> | 149:156823d33999 | 35 | /** @addtogroup USBD_EXPORTED_FUNCTIONS USBD Exported Functions |
<> | 149:156823d33999 | 36 | @{ |
<> | 149:156823d33999 | 37 | */ |
<> | 149:156823d33999 | 38 | |
<> | 149:156823d33999 | 39 | /* Global variables for Control Pipe */ |
<> | 149:156823d33999 | 40 | uint8_t g_usbd_SetupPacket[8] = {0}; /*!< Setup packet buffer */ |
<> | 149:156823d33999 | 41 | volatile uint8_t g_usbd_RemoteWakeupEn = 0; /*!< Remote wake up function enable flag */ |
<> | 149:156823d33999 | 42 | |
<> | 149:156823d33999 | 43 | /** |
<> | 149:156823d33999 | 44 | * @cond HIDDEN_SYMBOLS |
<> | 149:156823d33999 | 45 | */ |
<> | 149:156823d33999 | 46 | static volatile uint8_t *g_usbd_CtrlInPointer = 0; |
<> | 149:156823d33999 | 47 | static volatile uint32_t g_usbd_CtrlInSize = 0; |
<> | 149:156823d33999 | 48 | static volatile uint8_t *g_usbd_CtrlOutPointer = 0; |
<> | 149:156823d33999 | 49 | static volatile uint32_t g_usbd_CtrlOutSize = 0; |
<> | 149:156823d33999 | 50 | static volatile uint32_t g_usbd_CtrlOutSizeLimit = 0; |
<> | 149:156823d33999 | 51 | static volatile uint32_t g_usbd_UsbAddr = 0; |
<> | 149:156823d33999 | 52 | static volatile uint32_t g_usbd_UsbConfig = 0; |
<> | 149:156823d33999 | 53 | static volatile uint32_t g_usbd_CtrlMaxPktSize = 8; |
<> | 149:156823d33999 | 54 | static volatile uint32_t g_usbd_UsbAltInterface = 0; |
<> | 149:156823d33999 | 55 | /** |
<> | 149:156823d33999 | 56 | * @endcond |
<> | 149:156823d33999 | 57 | */ |
<> | 149:156823d33999 | 58 | |
<> | 149:156823d33999 | 59 | const S_USBD_INFO_T *g_usbd_sInfo; /*!< A pointer for USB information structure */ |
<> | 149:156823d33999 | 60 | |
<> | 149:156823d33999 | 61 | VENDOR_REQ g_usbd_pfnVendorRequest = NULL; /*!< USB Vendor Request Functional Pointer */ |
<> | 149:156823d33999 | 62 | CLASS_REQ g_usbd_pfnClassRequest = NULL; /*!< USB Class Request Functional Pointer */ |
<> | 149:156823d33999 | 63 | SET_INTERFACE_REQ g_usbd_pfnSetInterface = NULL; /*!< USB Set Interface Functional Pointer */ |
<> | 149:156823d33999 | 64 | SET_CONFIG_CB g_usbd_pfnSetConfigCallback = NULL; /*!< USB Set configuration callback function pointer */ |
<> | 149:156823d33999 | 65 | uint32_t g_u32EpStallLock = 0; /*!< Bit map flag to lock specified EP when SET_FEATURE */ |
<> | 149:156823d33999 | 66 | |
<> | 149:156823d33999 | 67 | /** |
<> | 149:156823d33999 | 68 | * @brief This function makes USBD module to be ready to use |
<> | 149:156823d33999 | 69 | * |
<> | 149:156823d33999 | 70 | * @param[in] param The structure of USBD information. |
<> | 149:156823d33999 | 71 | * @param[in] pfnClassReq USB Class request callback function. |
<> | 149:156823d33999 | 72 | * @param[in] pfnSetInterface USB Set Interface request callback function. |
<> | 149:156823d33999 | 73 | * |
<> | 149:156823d33999 | 74 | * @return None |
<> | 149:156823d33999 | 75 | * |
<> | 149:156823d33999 | 76 | * @details This function will enable USB controller, USB PHY transceiver and pull-up resistor of USB_D+ pin. USB PHY will drive SE0 to bus. |
<> | 149:156823d33999 | 77 | */ |
<> | 149:156823d33999 | 78 | void USBD_Open(const S_USBD_INFO_T *param, CLASS_REQ pfnClassReq, SET_INTERFACE_REQ pfnSetInterface) |
<> | 149:156823d33999 | 79 | { |
<> | 149:156823d33999 | 80 | g_usbd_sInfo = param; |
<> | 149:156823d33999 | 81 | g_usbd_pfnClassRequest = pfnClassReq; |
<> | 149:156823d33999 | 82 | g_usbd_pfnSetInterface = pfnSetInterface; |
<> | 149:156823d33999 | 83 | |
<> | 149:156823d33999 | 84 | /* get EP0 maximum packet size */ |
<> | 149:156823d33999 | 85 | g_usbd_CtrlMaxPktSize = g_usbd_sInfo->gu8DevDesc[7]; |
<> | 149:156823d33999 | 86 | |
<> | 149:156823d33999 | 87 | /* Initial USB engine */ |
<> | 149:156823d33999 | 88 | USBD->ATTR = 0x7D0; |
<> | 149:156823d33999 | 89 | /* Force SE0 */ |
<> | 149:156823d33999 | 90 | USBD_SET_SE0(); |
<> | 149:156823d33999 | 91 | } |
<> | 149:156823d33999 | 92 | |
<> | 149:156823d33999 | 93 | /** |
<> | 149:156823d33999 | 94 | * @brief This function makes USB host to recognize the device |
<> | 149:156823d33999 | 95 | * |
<> | 149:156823d33999 | 96 | * @param None |
<> | 149:156823d33999 | 97 | * |
<> | 149:156823d33999 | 98 | * @return None |
<> | 149:156823d33999 | 99 | * |
<> | 149:156823d33999 | 100 | * @details Enable WAKEUP, FLDET, USB and BUS interrupts. Disable software-disconnect function after 100ms delay with SysTick timer. |
<> | 149:156823d33999 | 101 | */ |
<> | 149:156823d33999 | 102 | void USBD_Start(void) |
<> | 149:156823d33999 | 103 | { |
<> | 149:156823d33999 | 104 | CLK_SysTickDelay(100000); |
<> | 149:156823d33999 | 105 | /* Disable software-disconnect function */ |
<> | 149:156823d33999 | 106 | USBD_CLR_SE0(); |
<> | 149:156823d33999 | 107 | |
<> | 149:156823d33999 | 108 | /* Clear USB-related interrupts before enable interrupt */ |
<> | 149:156823d33999 | 109 | USBD_CLR_INT_FLAG(USBD_INT_BUS | USBD_INT_USB | USBD_INT_FLDET | USBD_INT_WAKEUP); |
<> | 149:156823d33999 | 110 | |
<> | 149:156823d33999 | 111 | /* Enable USB-related interrupts. */ |
<> | 149:156823d33999 | 112 | USBD_ENABLE_INT(USBD_INT_BUS | USBD_INT_USB | USBD_INT_FLDET | USBD_INT_WAKEUP); |
<> | 149:156823d33999 | 113 | } |
<> | 149:156823d33999 | 114 | |
<> | 149:156823d33999 | 115 | /** |
<> | 149:156823d33999 | 116 | * @brief Get the received SETUP packet |
<> | 149:156823d33999 | 117 | * |
<> | 149:156823d33999 | 118 | * @param[in] buf A buffer pointer used to store 8-byte SETUP packet. |
<> | 149:156823d33999 | 119 | * |
<> | 149:156823d33999 | 120 | * @return None |
<> | 149:156823d33999 | 121 | * |
<> | 149:156823d33999 | 122 | * @details Store SETUP packet to a user-specified buffer. |
<> | 149:156823d33999 | 123 | * |
<> | 149:156823d33999 | 124 | */ |
<> | 149:156823d33999 | 125 | void USBD_GetSetupPacket(uint8_t *buf) |
<> | 149:156823d33999 | 126 | { |
<> | 149:156823d33999 | 127 | USBD_MemCopy(buf, g_usbd_SetupPacket, 8); |
<> | 149:156823d33999 | 128 | } |
<> | 149:156823d33999 | 129 | |
<> | 149:156823d33999 | 130 | /** |
<> | 149:156823d33999 | 131 | * @brief Process SETUP packet |
<> | 149:156823d33999 | 132 | * |
<> | 149:156823d33999 | 133 | * @param None |
<> | 149:156823d33999 | 134 | * |
<> | 149:156823d33999 | 135 | * @return None |
<> | 149:156823d33999 | 136 | * |
<> | 149:156823d33999 | 137 | * @details Parse SETUP packet and perform the corresponding action. |
<> | 149:156823d33999 | 138 | * |
<> | 149:156823d33999 | 139 | */ |
<> | 149:156823d33999 | 140 | void USBD_ProcessSetupPacket(void) |
<> | 149:156823d33999 | 141 | { |
<> | 149:156823d33999 | 142 | /* Get SETUP packet from USB buffer */ |
<> | 149:156823d33999 | 143 | USBD_MemCopy(g_usbd_SetupPacket, (uint8_t *)USBD_BUF_BASE, 8); |
<> | 149:156823d33999 | 144 | /* Check the request type */ |
<> | 149:156823d33999 | 145 | switch(g_usbd_SetupPacket[0] & 0x60) |
<> | 149:156823d33999 | 146 | { |
<> | 149:156823d33999 | 147 | case REQ_STANDARD: // Standard |
<> | 149:156823d33999 | 148 | { |
<> | 149:156823d33999 | 149 | USBD_StandardRequest(); |
<> | 149:156823d33999 | 150 | break; |
<> | 149:156823d33999 | 151 | } |
<> | 149:156823d33999 | 152 | case REQ_CLASS: // Class |
<> | 149:156823d33999 | 153 | { |
<> | 149:156823d33999 | 154 | if(g_usbd_pfnClassRequest != NULL) |
<> | 149:156823d33999 | 155 | { |
<> | 149:156823d33999 | 156 | g_usbd_pfnClassRequest(); |
<> | 149:156823d33999 | 157 | } |
<> | 149:156823d33999 | 158 | break; |
<> | 149:156823d33999 | 159 | } |
<> | 149:156823d33999 | 160 | case REQ_VENDOR: // Vendor |
<> | 149:156823d33999 | 161 | { |
<> | 149:156823d33999 | 162 | if(g_usbd_pfnVendorRequest != NULL) |
<> | 149:156823d33999 | 163 | { |
<> | 149:156823d33999 | 164 | g_usbd_pfnVendorRequest(); |
<> | 149:156823d33999 | 165 | } |
<> | 149:156823d33999 | 166 | break; |
<> | 149:156823d33999 | 167 | } |
<> | 149:156823d33999 | 168 | default: // reserved |
<> | 149:156823d33999 | 169 | { |
<> | 149:156823d33999 | 170 | /* Setup error, stall the device */ |
<> | 149:156823d33999 | 171 | USBD_SET_EP_STALL(EP0); |
<> | 149:156823d33999 | 172 | USBD_SET_EP_STALL(EP1); |
<> | 149:156823d33999 | 173 | break; |
<> | 149:156823d33999 | 174 | } |
<> | 149:156823d33999 | 175 | } |
<> | 149:156823d33999 | 176 | } |
<> | 149:156823d33999 | 177 | |
<> | 149:156823d33999 | 178 | /** |
<> | 149:156823d33999 | 179 | * @brief Process GetDescriptor request |
<> | 149:156823d33999 | 180 | * |
<> | 149:156823d33999 | 181 | * @param None |
<> | 149:156823d33999 | 182 | * |
<> | 149:156823d33999 | 183 | * @return None |
<> | 149:156823d33999 | 184 | * |
<> | 149:156823d33999 | 185 | * @details Parse GetDescriptor request and perform the corresponding action. |
<> | 149:156823d33999 | 186 | * |
<> | 149:156823d33999 | 187 | */ |
<> | 149:156823d33999 | 188 | void USBD_GetDescriptor(void) |
<> | 149:156823d33999 | 189 | { |
<> | 149:156823d33999 | 190 | uint32_t u32Len; |
<> | 149:156823d33999 | 191 | |
<> | 149:156823d33999 | 192 | u32Len = 0; |
<> | 149:156823d33999 | 193 | u32Len = g_usbd_SetupPacket[7]; |
<> | 149:156823d33999 | 194 | u32Len <<= 8; |
<> | 149:156823d33999 | 195 | u32Len += g_usbd_SetupPacket[6]; |
<> | 149:156823d33999 | 196 | |
<> | 149:156823d33999 | 197 | switch(g_usbd_SetupPacket[3]) |
<> | 149:156823d33999 | 198 | { |
<> | 149:156823d33999 | 199 | // Get Device Descriptor |
<> | 149:156823d33999 | 200 | case DESC_DEVICE: |
<> | 149:156823d33999 | 201 | { |
<> | 149:156823d33999 | 202 | u32Len = Minimum(u32Len, LEN_DEVICE); |
<> | 149:156823d33999 | 203 | DBG_PRINTF("Get device desc, %d\n", u32Len); |
<> | 149:156823d33999 | 204 | |
<> | 149:156823d33999 | 205 | USBD_PrepareCtrlIn((uint8_t *)g_usbd_sInfo->gu8DevDesc, u32Len); |
<> | 149:156823d33999 | 206 | |
<> | 149:156823d33999 | 207 | break; |
<> | 149:156823d33999 | 208 | } |
<> | 149:156823d33999 | 209 | // Get Configuration Descriptor |
<> | 149:156823d33999 | 210 | case DESC_CONFIG: |
<> | 149:156823d33999 | 211 | { |
<> | 149:156823d33999 | 212 | uint32_t u32TotalLen; |
<> | 149:156823d33999 | 213 | |
<> | 149:156823d33999 | 214 | u32TotalLen = g_usbd_sInfo->gu8ConfigDesc[3]; |
<> | 149:156823d33999 | 215 | u32TotalLen = g_usbd_sInfo->gu8ConfigDesc[2] + (u32TotalLen << 8); |
<> | 149:156823d33999 | 216 | |
<> | 149:156823d33999 | 217 | DBG_PRINTF("Get config desc len %d, acture len %d\n", u32Len, u32TotalLen); |
<> | 149:156823d33999 | 218 | u32Len = Minimum(u32Len, u32TotalLen); |
<> | 149:156823d33999 | 219 | DBG_PRINTF("Minimum len %d\n", u32Len); |
<> | 149:156823d33999 | 220 | |
<> | 149:156823d33999 | 221 | USBD_PrepareCtrlIn((uint8_t *)g_usbd_sInfo->gu8ConfigDesc, u32Len); |
<> | 149:156823d33999 | 222 | |
<> | 149:156823d33999 | 223 | break; |
<> | 149:156823d33999 | 224 | } |
<> | 149:156823d33999 | 225 | // Get HID Descriptor |
<> | 149:156823d33999 | 226 | case DESC_HID: |
<> | 149:156823d33999 | 227 | { |
<> | 149:156823d33999 | 228 | /* CV3.0 HID Class Descriptor Test, |
<> | 149:156823d33999 | 229 | Need to indicate index of the HID Descriptor within gu8ConfigDescriptor, specifically HID Composite device. */ |
<> | 149:156823d33999 | 230 | uint32_t u32ConfigDescOffset; // u32ConfigDescOffset is configuration descriptor offset (HID descriptor start index) |
<> | 149:156823d33999 | 231 | u32Len = Minimum(u32Len, LEN_HID); |
<> | 149:156823d33999 | 232 | DBG_PRINTF("Get HID desc, %d\n", u32Len); |
<> | 149:156823d33999 | 233 | |
<> | 149:156823d33999 | 234 | u32ConfigDescOffset = g_usbd_sInfo->gu32ConfigHidDescIdx[g_usbd_SetupPacket[4]]; |
<> | 149:156823d33999 | 235 | USBD_PrepareCtrlIn((uint8_t *)&g_usbd_sInfo->gu8ConfigDesc[u32ConfigDescOffset], u32Len); |
<> | 149:156823d33999 | 236 | |
<> | 149:156823d33999 | 237 | break; |
<> | 149:156823d33999 | 238 | } |
<> | 149:156823d33999 | 239 | // Get Report Descriptor |
<> | 149:156823d33999 | 240 | case DESC_HID_RPT: |
<> | 149:156823d33999 | 241 | { |
<> | 149:156823d33999 | 242 | DBG_PRINTF("Get HID report, %d\n", u32Len); |
<> | 149:156823d33999 | 243 | |
<> | 149:156823d33999 | 244 | u32Len = Minimum(u32Len, g_usbd_sInfo->gu32HidReportSize[g_usbd_SetupPacket[4]]); |
<> | 149:156823d33999 | 245 | USBD_PrepareCtrlIn((uint8_t *)g_usbd_sInfo->gu8HidReportDesc[g_usbd_SetupPacket[4]], u32Len); |
<> | 149:156823d33999 | 246 | break; |
<> | 149:156823d33999 | 247 | } |
<> | 149:156823d33999 | 248 | // Get String Descriptor |
<> | 149:156823d33999 | 249 | case DESC_STRING: |
<> | 149:156823d33999 | 250 | { |
<> | 149:156823d33999 | 251 | // Get String Descriptor |
<> | 149:156823d33999 | 252 | if(g_usbd_SetupPacket[2] < 4) |
<> | 149:156823d33999 | 253 | { |
<> | 149:156823d33999 | 254 | u32Len = Minimum(u32Len, g_usbd_sInfo->gu8StringDesc[g_usbd_SetupPacket[2]][0]); |
<> | 149:156823d33999 | 255 | DBG_PRINTF("Get string desc %d\n", u32Len); |
<> | 149:156823d33999 | 256 | |
<> | 149:156823d33999 | 257 | USBD_PrepareCtrlIn((uint8_t *)g_usbd_sInfo->gu8StringDesc[g_usbd_SetupPacket[2]], u32Len); |
<> | 149:156823d33999 | 258 | |
<> | 149:156823d33999 | 259 | |
<> | 149:156823d33999 | 260 | break; |
<> | 149:156823d33999 | 261 | } |
<> | 149:156823d33999 | 262 | else |
<> | 149:156823d33999 | 263 | { |
<> | 149:156823d33999 | 264 | // Not support. Reply STALL. |
<> | 149:156823d33999 | 265 | USBD_SET_EP_STALL(EP0); |
<> | 149:156823d33999 | 266 | USBD_SET_EP_STALL(EP1); |
<> | 149:156823d33999 | 267 | |
<> | 149:156823d33999 | 268 | DBG_PRINTF("Unsupported string desc (%d). Stall ctrl pipe.\n", g_usbd_SetupPacket[2]); |
<> | 149:156823d33999 | 269 | |
<> | 149:156823d33999 | 270 | break; |
<> | 149:156823d33999 | 271 | } |
<> | 149:156823d33999 | 272 | } |
<> | 149:156823d33999 | 273 | default: |
<> | 149:156823d33999 | 274 | // Not support. Reply STALL. |
<> | 149:156823d33999 | 275 | USBD_SET_EP_STALL(EP0); |
<> | 149:156823d33999 | 276 | USBD_SET_EP_STALL(EP1); |
<> | 149:156823d33999 | 277 | |
<> | 149:156823d33999 | 278 | DBG_PRINTF("Unsupported get desc type. stall ctrl pipe\n"); |
<> | 149:156823d33999 | 279 | |
<> | 149:156823d33999 | 280 | break; |
<> | 149:156823d33999 | 281 | } |
<> | 149:156823d33999 | 282 | } |
<> | 149:156823d33999 | 283 | |
<> | 149:156823d33999 | 284 | /** |
<> | 149:156823d33999 | 285 | * @brief Process standard request |
<> | 149:156823d33999 | 286 | * |
<> | 149:156823d33999 | 287 | * @param None |
<> | 149:156823d33999 | 288 | * |
<> | 149:156823d33999 | 289 | * @return None |
<> | 149:156823d33999 | 290 | * |
<> | 149:156823d33999 | 291 | * @details Parse standard request and perform the corresponding action. |
<> | 149:156823d33999 | 292 | * |
<> | 149:156823d33999 | 293 | */ |
<> | 149:156823d33999 | 294 | void USBD_StandardRequest(void) |
<> | 149:156823d33999 | 295 | { |
<> | 149:156823d33999 | 296 | |
<> | 149:156823d33999 | 297 | /* clear global variables for new request */ |
<> | 149:156823d33999 | 298 | g_usbd_CtrlInPointer = 0; |
<> | 149:156823d33999 | 299 | g_usbd_CtrlInSize = 0; |
<> | 149:156823d33999 | 300 | |
<> | 149:156823d33999 | 301 | if(g_usbd_SetupPacket[0] & 0x80) /* request data transfer direction */ |
<> | 149:156823d33999 | 302 | { |
<> | 149:156823d33999 | 303 | // Device to host |
<> | 149:156823d33999 | 304 | switch(g_usbd_SetupPacket[1]) |
<> | 149:156823d33999 | 305 | { |
<> | 149:156823d33999 | 306 | case GET_CONFIGURATION: |
<> | 149:156823d33999 | 307 | { |
<> | 149:156823d33999 | 308 | // Return current configuration setting |
<> | 149:156823d33999 | 309 | /* Data stage */ |
<> | 149:156823d33999 | 310 | M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)) = g_usbd_UsbConfig; |
<> | 149:156823d33999 | 311 | USBD_SET_DATA1(EP0); |
<> | 149:156823d33999 | 312 | USBD_SET_PAYLOAD_LEN(EP0, 1); |
<> | 149:156823d33999 | 313 | /* Status stage */ |
<> | 149:156823d33999 | 314 | USBD_PrepareCtrlOut(0,0); |
<> | 149:156823d33999 | 315 | |
<> | 149:156823d33999 | 316 | DBG_PRINTF("Get configuration\n"); |
<> | 149:156823d33999 | 317 | |
<> | 149:156823d33999 | 318 | break; |
<> | 149:156823d33999 | 319 | } |
<> | 149:156823d33999 | 320 | case GET_DESCRIPTOR: |
<> | 149:156823d33999 | 321 | { |
<> | 149:156823d33999 | 322 | USBD_GetDescriptor(); |
<> | 149:156823d33999 | 323 | USBD_PrepareCtrlOut(0, 0); /* For status stage */ |
<> | 149:156823d33999 | 324 | break; |
<> | 149:156823d33999 | 325 | } |
<> | 149:156823d33999 | 326 | case GET_INTERFACE: |
<> | 149:156823d33999 | 327 | { |
<> | 149:156823d33999 | 328 | // Return current interface setting |
<> | 149:156823d33999 | 329 | /* Data stage */ |
<> | 149:156823d33999 | 330 | M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)) = g_usbd_UsbAltInterface; |
<> | 149:156823d33999 | 331 | USBD_SET_DATA1(EP0); |
<> | 149:156823d33999 | 332 | USBD_SET_PAYLOAD_LEN(EP0, 1); |
<> | 149:156823d33999 | 333 | /* Status stage */ |
<> | 149:156823d33999 | 334 | USBD_PrepareCtrlOut(0, 0); |
<> | 149:156823d33999 | 335 | |
<> | 149:156823d33999 | 336 | DBG_PRINTF("Get interface\n"); |
<> | 149:156823d33999 | 337 | |
<> | 149:156823d33999 | 338 | break; |
<> | 149:156823d33999 | 339 | } |
<> | 149:156823d33999 | 340 | case GET_STATUS: |
<> | 149:156823d33999 | 341 | { |
<> | 149:156823d33999 | 342 | // Device |
<> | 149:156823d33999 | 343 | if(g_usbd_SetupPacket[0] == 0x80) |
<> | 149:156823d33999 | 344 | { |
<> | 149:156823d33999 | 345 | uint8_t u8Tmp; |
<> | 149:156823d33999 | 346 | |
<> | 149:156823d33999 | 347 | u8Tmp = 0; |
<> | 149:156823d33999 | 348 | if(g_usbd_sInfo->gu8ConfigDesc[7] & 0x40) u8Tmp |= 1; // Self-Powered/Bus-Powered. |
<> | 149:156823d33999 | 349 | if(g_usbd_sInfo->gu8ConfigDesc[7] & 0x20) u8Tmp |= (g_usbd_RemoteWakeupEn << 1); // Remote wake up |
<> | 149:156823d33999 | 350 | |
<> | 149:156823d33999 | 351 | M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)) = u8Tmp; |
<> | 149:156823d33999 | 352 | |
<> | 149:156823d33999 | 353 | } |
<> | 149:156823d33999 | 354 | // Interface |
<> | 149:156823d33999 | 355 | else if(g_usbd_SetupPacket[0] == 0x81) |
<> | 149:156823d33999 | 356 | M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)) = 0; |
<> | 149:156823d33999 | 357 | // Endpoint |
<> | 149:156823d33999 | 358 | else if(g_usbd_SetupPacket[0] == 0x82) |
<> | 149:156823d33999 | 359 | { |
<> | 149:156823d33999 | 360 | uint8_t ep = g_usbd_SetupPacket[4] & 0xF; |
<> | 149:156823d33999 | 361 | M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)) = USBD_GetStall(ep) ? 1 : 0; |
<> | 149:156823d33999 | 362 | } |
<> | 149:156823d33999 | 363 | |
<> | 149:156823d33999 | 364 | M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0) + 1) = 0; |
<> | 149:156823d33999 | 365 | /* Data stage */ |
<> | 149:156823d33999 | 366 | USBD_SET_DATA1(EP0); |
<> | 149:156823d33999 | 367 | USBD_SET_PAYLOAD_LEN(EP0, 2); |
<> | 149:156823d33999 | 368 | /* Status stage */ |
<> | 149:156823d33999 | 369 | USBD_PrepareCtrlOut(0, 0); |
<> | 149:156823d33999 | 370 | |
<> | 149:156823d33999 | 371 | DBG_PRINTF("Get status\n"); |
<> | 149:156823d33999 | 372 | |
<> | 149:156823d33999 | 373 | break; |
<> | 149:156823d33999 | 374 | } |
<> | 149:156823d33999 | 375 | default: |
<> | 149:156823d33999 | 376 | { |
<> | 149:156823d33999 | 377 | /* Setup error, stall the device */ |
<> | 149:156823d33999 | 378 | USBD_SET_EP_STALL(EP0); |
<> | 149:156823d33999 | 379 | USBD_SET_EP_STALL(EP1); |
<> | 149:156823d33999 | 380 | |
<> | 149:156823d33999 | 381 | DBG_PRINTF("Unknown request. stall ctrl pipe.\n"); |
<> | 149:156823d33999 | 382 | |
<> | 149:156823d33999 | 383 | break; |
<> | 149:156823d33999 | 384 | } |
<> | 149:156823d33999 | 385 | } |
<> | 149:156823d33999 | 386 | } |
<> | 149:156823d33999 | 387 | else |
<> | 149:156823d33999 | 388 | { |
<> | 149:156823d33999 | 389 | // Host to device |
<> | 149:156823d33999 | 390 | switch(g_usbd_SetupPacket[1]) |
<> | 149:156823d33999 | 391 | { |
<> | 149:156823d33999 | 392 | case CLEAR_FEATURE: |
<> | 149:156823d33999 | 393 | { |
<> | 149:156823d33999 | 394 | if(g_usbd_SetupPacket[2] == FEATURE_ENDPOINT_HALT) |
<> | 149:156823d33999 | 395 | { |
<> | 149:156823d33999 | 396 | int32_t epNum, i; |
<> | 149:156823d33999 | 397 | |
<> | 149:156823d33999 | 398 | /* EP number stall is not allow to be clear in MSC class "Error Recovery Test". |
<> | 149:156823d33999 | 399 | a flag: g_u32EpStallLock is added to support it */ |
<> | 149:156823d33999 | 400 | epNum = g_usbd_SetupPacket[4] & 0xF; |
<> | 149:156823d33999 | 401 | for(i = 0; i < USBD_MAX_EP; i++) |
<> | 149:156823d33999 | 402 | { |
<> | 149:156823d33999 | 403 | if(((USBD->EP[i].CFG & 0xF) == epNum) && ((g_u32EpStallLock & (1 << i)) == 0)) |
<> | 149:156823d33999 | 404 | { |
<> | 149:156823d33999 | 405 | USBD->EP[i].CFGP &= ~USBD_CFGP_SSTALL_Msk; |
<> | 149:156823d33999 | 406 | DBG_PRINTF("Clr stall ep%d %x\n", i, USBD->EP[i].CFGP); |
<> | 149:156823d33999 | 407 | } |
<> | 149:156823d33999 | 408 | } |
<> | 149:156823d33999 | 409 | } |
<> | 149:156823d33999 | 410 | else if(g_usbd_SetupPacket[2] == FEATURE_DEVICE_REMOTE_WAKEUP) |
<> | 149:156823d33999 | 411 | g_usbd_RemoteWakeupEn = 0; |
<> | 149:156823d33999 | 412 | |
<> | 149:156823d33999 | 413 | /* Status stage */ |
<> | 149:156823d33999 | 414 | USBD_SET_DATA1(EP0); |
<> | 149:156823d33999 | 415 | USBD_SET_PAYLOAD_LEN(EP0, 0); |
<> | 149:156823d33999 | 416 | |
<> | 149:156823d33999 | 417 | DBG_PRINTF("Clear feature op %d\n", g_usbd_SetupPacket[2]); |
<> | 149:156823d33999 | 418 | |
<> | 149:156823d33999 | 419 | break; |
<> | 149:156823d33999 | 420 | } |
<> | 149:156823d33999 | 421 | case SET_ADDRESS: |
<> | 149:156823d33999 | 422 | { |
<> | 149:156823d33999 | 423 | g_usbd_UsbAddr = g_usbd_SetupPacket[2]; |
<> | 149:156823d33999 | 424 | DBG_PRINTF("Set addr to %d\n", g_usbd_UsbAddr); |
<> | 149:156823d33999 | 425 | |
<> | 149:156823d33999 | 426 | // DATA IN for end of setup |
<> | 149:156823d33999 | 427 | /* Status Stage */ |
<> | 149:156823d33999 | 428 | USBD_SET_DATA1(EP0); |
<> | 149:156823d33999 | 429 | USBD_SET_PAYLOAD_LEN(EP0, 0); |
<> | 149:156823d33999 | 430 | |
<> | 149:156823d33999 | 431 | break; |
<> | 149:156823d33999 | 432 | } |
<> | 149:156823d33999 | 433 | case SET_CONFIGURATION: |
<> | 149:156823d33999 | 434 | { |
<> | 149:156823d33999 | 435 | g_usbd_UsbConfig = g_usbd_SetupPacket[2]; |
<> | 149:156823d33999 | 436 | |
<> | 149:156823d33999 | 437 | if(g_usbd_pfnSetConfigCallback) |
<> | 149:156823d33999 | 438 | g_usbd_pfnSetConfigCallback(); |
<> | 149:156823d33999 | 439 | |
<> | 149:156823d33999 | 440 | // DATA IN for end of setup |
<> | 149:156823d33999 | 441 | /* Status stage */ |
<> | 149:156823d33999 | 442 | USBD_SET_DATA1(EP0); |
<> | 149:156823d33999 | 443 | USBD_SET_PAYLOAD_LEN(EP0, 0); |
<> | 149:156823d33999 | 444 | |
<> | 149:156823d33999 | 445 | DBG_PRINTF("Set config to %d\n", g_usbd_UsbConfig); |
<> | 149:156823d33999 | 446 | |
<> | 149:156823d33999 | 447 | break; |
<> | 149:156823d33999 | 448 | } |
<> | 149:156823d33999 | 449 | case SET_FEATURE: |
<> | 149:156823d33999 | 450 | { |
<> | 149:156823d33999 | 451 | if(g_usbd_SetupPacket[2] == FEATURE_ENDPOINT_HALT) |
<> | 149:156823d33999 | 452 | { |
<> | 149:156823d33999 | 453 | USBD_SetStall(g_usbd_SetupPacket[4] & 0xF); |
<> | 149:156823d33999 | 454 | DBG_PRINTF("Set feature. stall ep %d\n", g_usbd_SetupPacket[4] & 0xF); |
<> | 149:156823d33999 | 455 | } |
<> | 149:156823d33999 | 456 | else if(g_usbd_SetupPacket[2] == FEATURE_DEVICE_REMOTE_WAKEUP) |
<> | 149:156823d33999 | 457 | { |
<> | 149:156823d33999 | 458 | g_usbd_RemoteWakeupEn = 1; |
<> | 149:156823d33999 | 459 | DBG_PRINTF("Set feature. enable remote wakeup\n"); |
<> | 149:156823d33999 | 460 | } |
<> | 149:156823d33999 | 461 | |
<> | 149:156823d33999 | 462 | /* Status stage */ |
<> | 149:156823d33999 | 463 | USBD_SET_DATA1(EP0); |
<> | 149:156823d33999 | 464 | USBD_SET_PAYLOAD_LEN(EP0, 0); |
<> | 149:156823d33999 | 465 | |
<> | 149:156823d33999 | 466 | |
<> | 149:156823d33999 | 467 | |
<> | 149:156823d33999 | 468 | break; |
<> | 149:156823d33999 | 469 | } |
<> | 149:156823d33999 | 470 | case SET_INTERFACE: |
<> | 149:156823d33999 | 471 | { |
<> | 149:156823d33999 | 472 | g_usbd_UsbAltInterface = g_usbd_SetupPacket[2]; |
<> | 149:156823d33999 | 473 | if(g_usbd_pfnSetInterface != NULL) |
<> | 149:156823d33999 | 474 | g_usbd_pfnSetInterface(); |
<> | 149:156823d33999 | 475 | /* Status stage */ |
<> | 149:156823d33999 | 476 | USBD_SET_DATA1(EP0); |
<> | 149:156823d33999 | 477 | USBD_SET_PAYLOAD_LEN(EP0, 0); |
<> | 149:156823d33999 | 478 | |
<> | 149:156823d33999 | 479 | DBG_PRINTF("Set interface to %d\n", g_usbd_UsbAltInterface); |
<> | 149:156823d33999 | 480 | |
<> | 149:156823d33999 | 481 | break; |
<> | 149:156823d33999 | 482 | } |
<> | 149:156823d33999 | 483 | default: |
<> | 149:156823d33999 | 484 | { |
<> | 149:156823d33999 | 485 | /* Setup error, stall the device */ |
<> | 149:156823d33999 | 486 | USBD_SET_EP_STALL(EP0); |
<> | 149:156823d33999 | 487 | USBD_SET_EP_STALL(EP1); |
<> | 149:156823d33999 | 488 | |
<> | 149:156823d33999 | 489 | DBG_PRINTF("Unsupported request. stall ctrl pipe.\n"); |
<> | 149:156823d33999 | 490 | |
<> | 149:156823d33999 | 491 | break; |
<> | 149:156823d33999 | 492 | } |
<> | 149:156823d33999 | 493 | } |
<> | 149:156823d33999 | 494 | } |
<> | 149:156823d33999 | 495 | } |
<> | 149:156823d33999 | 496 | |
<> | 149:156823d33999 | 497 | /** |
<> | 149:156823d33999 | 498 | * @brief Prepare the first Control IN pipe |
<> | 149:156823d33999 | 499 | * |
<> | 149:156823d33999 | 500 | * @param[in] pu8Buf The pointer of data sent to USB host. |
<> | 149:156823d33999 | 501 | * @param[in] u32Size The IN transfer size. |
<> | 149:156823d33999 | 502 | * |
<> | 149:156823d33999 | 503 | * @return None |
<> | 149:156823d33999 | 504 | * |
<> | 149:156823d33999 | 505 | * @details Prepare data for Control IN transfer. |
<> | 149:156823d33999 | 506 | * |
<> | 149:156823d33999 | 507 | */ |
<> | 149:156823d33999 | 508 | void USBD_PrepareCtrlIn(uint8_t *pu8Buf, uint32_t u32Size) |
<> | 149:156823d33999 | 509 | { |
<> | 149:156823d33999 | 510 | DBG_PRINTF("Prepare Ctrl In %d\n", u32Size); |
<> | 149:156823d33999 | 511 | if(u32Size > g_usbd_CtrlMaxPktSize) |
<> | 149:156823d33999 | 512 | { |
<> | 149:156823d33999 | 513 | // Data size > MXPLD |
<> | 149:156823d33999 | 514 | g_usbd_CtrlInPointer = pu8Buf + g_usbd_CtrlMaxPktSize; |
<> | 149:156823d33999 | 515 | g_usbd_CtrlInSize = u32Size - g_usbd_CtrlMaxPktSize; |
<> | 149:156823d33999 | 516 | USBD_SET_DATA1(EP0); |
<> | 149:156823d33999 | 517 | USBD_MemCopy((uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0), pu8Buf, g_usbd_CtrlMaxPktSize); |
<> | 149:156823d33999 | 518 | USBD_SET_PAYLOAD_LEN(EP0, g_usbd_CtrlMaxPktSize); |
<> | 149:156823d33999 | 519 | } |
<> | 149:156823d33999 | 520 | else |
<> | 149:156823d33999 | 521 | { |
<> | 149:156823d33999 | 522 | // Data size <= MXPLD |
<> | 149:156823d33999 | 523 | g_usbd_CtrlInPointer = 0; |
<> | 149:156823d33999 | 524 | g_usbd_CtrlInSize = 0; |
<> | 149:156823d33999 | 525 | USBD_SET_DATA1(EP0); |
<> | 149:156823d33999 | 526 | USBD_MemCopy((uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0), pu8Buf, u32Size); |
<> | 149:156823d33999 | 527 | USBD_SET_PAYLOAD_LEN(EP0, u32Size); |
<> | 149:156823d33999 | 528 | } |
<> | 149:156823d33999 | 529 | } |
<> | 149:156823d33999 | 530 | |
<> | 149:156823d33999 | 531 | /** |
<> | 149:156823d33999 | 532 | * @brief Repeat Control IN pipe |
<> | 149:156823d33999 | 533 | * |
<> | 149:156823d33999 | 534 | * @param None |
<> | 149:156823d33999 | 535 | * |
<> | 149:156823d33999 | 536 | * @return None |
<> | 149:156823d33999 | 537 | * |
<> | 149:156823d33999 | 538 | * @details This function processes the remained data of Control IN transfer. |
<> | 149:156823d33999 | 539 | * |
<> | 149:156823d33999 | 540 | */ |
<> | 149:156823d33999 | 541 | void USBD_CtrlIn(void) |
<> | 149:156823d33999 | 542 | { |
<> | 149:156823d33999 | 543 | static uint8_t u8ZeroFlag = 0; |
<> | 149:156823d33999 | 544 | |
<> | 149:156823d33999 | 545 | DBG_PRINTF("Ctrl In Ack. residue %d\n", g_usbd_CtrlInSize); |
<> | 149:156823d33999 | 546 | if(g_usbd_CtrlInSize) |
<> | 149:156823d33999 | 547 | { |
<> | 149:156823d33999 | 548 | // Process remained data |
<> | 149:156823d33999 | 549 | if(g_usbd_CtrlInSize > g_usbd_CtrlMaxPktSize) |
<> | 149:156823d33999 | 550 | { |
<> | 149:156823d33999 | 551 | // Data size > MXPLD |
<> | 149:156823d33999 | 552 | USBD_MemCopy((uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0), (uint8_t *)g_usbd_CtrlInPointer, g_usbd_CtrlMaxPktSize); |
<> | 149:156823d33999 | 553 | USBD_SET_PAYLOAD_LEN(EP0, g_usbd_CtrlMaxPktSize); |
<> | 149:156823d33999 | 554 | g_usbd_CtrlInPointer += g_usbd_CtrlMaxPktSize; |
<> | 149:156823d33999 | 555 | g_usbd_CtrlInSize -= g_usbd_CtrlMaxPktSize; |
<> | 149:156823d33999 | 556 | } |
<> | 149:156823d33999 | 557 | else |
<> | 149:156823d33999 | 558 | { |
<> | 149:156823d33999 | 559 | // Data size <= MXPLD |
<> | 149:156823d33999 | 560 | USBD_MemCopy((uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0), (uint8_t *)g_usbd_CtrlInPointer, g_usbd_CtrlInSize); |
<> | 149:156823d33999 | 561 | USBD_SET_PAYLOAD_LEN(EP0, g_usbd_CtrlInSize); |
<> | 149:156823d33999 | 562 | if(g_usbd_CtrlInSize == g_usbd_CtrlMaxPktSize) |
<> | 149:156823d33999 | 563 | u8ZeroFlag = 1; |
<> | 149:156823d33999 | 564 | g_usbd_CtrlInPointer = 0; |
<> | 149:156823d33999 | 565 | g_usbd_CtrlInSize = 0; |
<> | 149:156823d33999 | 566 | } |
<> | 149:156823d33999 | 567 | } |
<> | 149:156823d33999 | 568 | else // No more data for IN token |
<> | 149:156823d33999 | 569 | { |
<> | 149:156823d33999 | 570 | // In ACK for Set address |
<> | 149:156823d33999 | 571 | if((g_usbd_SetupPacket[0] == REQ_STANDARD) && (g_usbd_SetupPacket[1] == SET_ADDRESS)) |
<> | 149:156823d33999 | 572 | { |
<> | 149:156823d33999 | 573 | if((USBD_GET_ADDR() != g_usbd_UsbAddr) && (USBD_GET_ADDR() == 0)) |
<> | 149:156823d33999 | 574 | { |
<> | 149:156823d33999 | 575 | USBD_SET_ADDR(g_usbd_UsbAddr); |
<> | 149:156823d33999 | 576 | } |
<> | 149:156823d33999 | 577 | } |
<> | 149:156823d33999 | 578 | |
<> | 149:156823d33999 | 579 | /* For the case of data size is integral times maximum packet size */ |
<> | 149:156823d33999 | 580 | if(u8ZeroFlag) |
<> | 149:156823d33999 | 581 | { |
<> | 149:156823d33999 | 582 | USBD_SET_PAYLOAD_LEN(EP0, 0); |
<> | 149:156823d33999 | 583 | u8ZeroFlag = 0; |
<> | 149:156823d33999 | 584 | } |
<> | 149:156823d33999 | 585 | |
<> | 149:156823d33999 | 586 | DBG_PRINTF("Ctrl In done.\n"); |
<> | 149:156823d33999 | 587 | |
<> | 149:156823d33999 | 588 | } |
<> | 149:156823d33999 | 589 | } |
<> | 149:156823d33999 | 590 | |
<> | 149:156823d33999 | 591 | /** |
<> | 149:156823d33999 | 592 | * @brief Prepare the first Control OUT pipe |
<> | 149:156823d33999 | 593 | * |
<> | 149:156823d33999 | 594 | * @param[in] pu8Buf The pointer of data received from USB host. |
<> | 149:156823d33999 | 595 | * @param[in] u32Size The OUT transfer size. |
<> | 149:156823d33999 | 596 | * |
<> | 149:156823d33999 | 597 | * @return None |
<> | 149:156823d33999 | 598 | * |
<> | 149:156823d33999 | 599 | * @details This function is used to prepare the first Control OUT transfer. |
<> | 149:156823d33999 | 600 | * |
<> | 149:156823d33999 | 601 | */ |
<> | 149:156823d33999 | 602 | void USBD_PrepareCtrlOut(uint8_t *pu8Buf, uint32_t u32Size) |
<> | 149:156823d33999 | 603 | { |
<> | 149:156823d33999 | 604 | g_usbd_CtrlOutPointer = pu8Buf; |
<> | 149:156823d33999 | 605 | g_usbd_CtrlOutSize = 0; |
<> | 149:156823d33999 | 606 | g_usbd_CtrlOutSizeLimit = u32Size; |
<> | 149:156823d33999 | 607 | USBD_SET_PAYLOAD_LEN(EP1, g_usbd_CtrlMaxPktSize); |
<> | 149:156823d33999 | 608 | } |
<> | 149:156823d33999 | 609 | |
<> | 149:156823d33999 | 610 | /** |
<> | 149:156823d33999 | 611 | * @brief Repeat Control OUT pipe |
<> | 149:156823d33999 | 612 | * |
<> | 149:156823d33999 | 613 | * @param None |
<> | 149:156823d33999 | 614 | * |
<> | 149:156823d33999 | 615 | * @return None |
<> | 149:156823d33999 | 616 | * |
<> | 149:156823d33999 | 617 | * @details This function processes the successive Control OUT transfer. |
<> | 149:156823d33999 | 618 | * |
<> | 149:156823d33999 | 619 | */ |
<> | 149:156823d33999 | 620 | void USBD_CtrlOut(void) |
<> | 149:156823d33999 | 621 | { |
<> | 149:156823d33999 | 622 | uint32_t u32Size; |
<> | 149:156823d33999 | 623 | |
<> | 149:156823d33999 | 624 | DBG_PRINTF("Ctrl Out Ack %d\n", g_usbd_CtrlOutSize); |
<> | 149:156823d33999 | 625 | |
<> | 149:156823d33999 | 626 | if(g_usbd_CtrlOutSize < g_usbd_CtrlOutSizeLimit) |
<> | 149:156823d33999 | 627 | { |
<> | 149:156823d33999 | 628 | u32Size = USBD_GET_PAYLOAD_LEN(EP1); |
<> | 149:156823d33999 | 629 | USBD_MemCopy((uint8_t *)g_usbd_CtrlOutPointer, (uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP1), u32Size); |
<> | 149:156823d33999 | 630 | g_usbd_CtrlOutPointer += u32Size; |
<> | 149:156823d33999 | 631 | g_usbd_CtrlOutSize += u32Size; |
<> | 149:156823d33999 | 632 | |
<> | 149:156823d33999 | 633 | if(g_usbd_CtrlOutSize < g_usbd_CtrlOutSizeLimit) |
<> | 149:156823d33999 | 634 | USBD_SET_PAYLOAD_LEN(EP1, g_usbd_CtrlMaxPktSize); |
<> | 149:156823d33999 | 635 | |
<> | 149:156823d33999 | 636 | } |
<> | 149:156823d33999 | 637 | } |
<> | 149:156823d33999 | 638 | |
<> | 149:156823d33999 | 639 | /** |
<> | 149:156823d33999 | 640 | * @brief Reset software flags |
<> | 149:156823d33999 | 641 | * |
<> | 149:156823d33999 | 642 | * @param None |
<> | 149:156823d33999 | 643 | * |
<> | 149:156823d33999 | 644 | * @return None |
<> | 149:156823d33999 | 645 | * |
<> | 149:156823d33999 | 646 | * @details This function resets all variables for protocol and resets USB device address to 0. |
<> | 149:156823d33999 | 647 | * |
<> | 149:156823d33999 | 648 | */ |
<> | 149:156823d33999 | 649 | void USBD_SwReset(void) |
<> | 149:156823d33999 | 650 | { |
<> | 149:156823d33999 | 651 | int i; |
<> | 149:156823d33999 | 652 | |
<> | 149:156823d33999 | 653 | // Reset all variables for protocol |
<> | 149:156823d33999 | 654 | g_usbd_CtrlInPointer = 0; |
<> | 149:156823d33999 | 655 | g_usbd_CtrlInSize = 0; |
<> | 149:156823d33999 | 656 | g_usbd_CtrlOutPointer = 0; |
<> | 149:156823d33999 | 657 | g_usbd_CtrlOutSize = 0; |
<> | 149:156823d33999 | 658 | g_usbd_CtrlOutSizeLimit = 0; |
<> | 149:156823d33999 | 659 | g_u32EpStallLock = 0; |
<> | 149:156823d33999 | 660 | memset(g_usbd_SetupPacket, 0, 8); |
<> | 149:156823d33999 | 661 | |
<> | 149:156823d33999 | 662 | /* Reset PID DATA0 */ |
<> | 149:156823d33999 | 663 | for(i=0; i<USBD_MAX_EP; i++) |
<> | 149:156823d33999 | 664 | USBD->EP[i].CFG &= ~USBD_CFG_DSQSYNC_Msk; |
<> | 149:156823d33999 | 665 | |
<> | 149:156823d33999 | 666 | // Reset USB device address |
<> | 149:156823d33999 | 667 | USBD_SET_ADDR(0); |
<> | 149:156823d33999 | 668 | } |
<> | 149:156823d33999 | 669 | |
<> | 149:156823d33999 | 670 | /** |
<> | 149:156823d33999 | 671 | * @brief USBD Set Vendor Request |
<> | 149:156823d33999 | 672 | * |
<> | 149:156823d33999 | 673 | * @param[in] pfnVendorReq Vendor Request Callback Function |
<> | 149:156823d33999 | 674 | * |
<> | 149:156823d33999 | 675 | * @return None |
<> | 149:156823d33999 | 676 | * |
<> | 149:156823d33999 | 677 | * @details This function is used to set USBD vendor request callback function |
<> | 149:156823d33999 | 678 | */ |
<> | 149:156823d33999 | 679 | void USBD_SetVendorRequest(VENDOR_REQ pfnVendorReq) |
<> | 149:156823d33999 | 680 | { |
<> | 149:156823d33999 | 681 | g_usbd_pfnVendorRequest = pfnVendorReq; |
<> | 149:156823d33999 | 682 | } |
<> | 149:156823d33999 | 683 | |
<> | 149:156823d33999 | 684 | /** |
<> | 149:156823d33999 | 685 | * @brief The callback function which called when get SET CONFIGURATION request |
<> | 149:156823d33999 | 686 | * |
<> | 149:156823d33999 | 687 | * @param[in] pfnSetConfigCallback Callback function pointer for SET CONFIGURATION request |
<> | 149:156823d33999 | 688 | * |
<> | 149:156823d33999 | 689 | * @return None |
<> | 149:156823d33999 | 690 | * |
<> | 149:156823d33999 | 691 | * @details This function is used to set the callback function which will be called at SET CONFIGURATION request. |
<> | 149:156823d33999 | 692 | */ |
<> | 149:156823d33999 | 693 | void USBD_SetConfigCallback(SET_CONFIG_CB pfnSetConfigCallback) |
<> | 149:156823d33999 | 694 | { |
<> | 149:156823d33999 | 695 | g_usbd_pfnSetConfigCallback = pfnSetConfigCallback; |
<> | 149:156823d33999 | 696 | } |
<> | 149:156823d33999 | 697 | |
<> | 149:156823d33999 | 698 | |
<> | 149:156823d33999 | 699 | /** |
<> | 149:156823d33999 | 700 | * @brief EP stall lock function to avoid stall clear by USB SET FEATURE request. |
<> | 149:156823d33999 | 701 | * |
<> | 149:156823d33999 | 702 | * @param[in] u32EpBitmap Use bitmap to select which endpoints will be locked |
<> | 149:156823d33999 | 703 | * |
<> | 149:156823d33999 | 704 | * @return None |
<> | 149:156823d33999 | 705 | * |
<> | 149:156823d33999 | 706 | * @details This function is used to lock relative endpoint to avoid stall clear by SET FEATURE requst. |
<> | 149:156823d33999 | 707 | * If ep stall locked, user needs to reset USB device or re-configure device to clear it. |
<> | 149:156823d33999 | 708 | */ |
<> | 149:156823d33999 | 709 | void USBD_LockEpStall(uint32_t u32EpBitmap) |
<> | 149:156823d33999 | 710 | { |
<> | 149:156823d33999 | 711 | g_u32EpStallLock = u32EpBitmap; |
<> | 149:156823d33999 | 712 | } |
<> | 149:156823d33999 | 713 | |
<> | 149:156823d33999 | 714 | |
<> | 149:156823d33999 | 715 | |
<> | 149:156823d33999 | 716 | |
<> | 149:156823d33999 | 717 | |
<> | 149:156823d33999 | 718 | /*@}*/ /* end of group USBD_EXPORTED_FUNCTIONS */ |
<> | 149:156823d33999 | 719 | |
<> | 149:156823d33999 | 720 | /*@}*/ /* end of group USBD_Driver */ |
<> | 149:156823d33999 | 721 | |
<> | 149:156823d33999 | 722 | /*@}*/ /* end of group Standard_Driver */ |
<> | 149:156823d33999 | 723 | |
<> | 149:156823d33999 | 724 | #ifdef __cplusplus |
<> | 149:156823d33999 | 725 | } |
<> | 149:156823d33999 | 726 | #endif |
<> | 149:156823d33999 | 727 | |
<> | 149:156823d33999 | 728 | /*** (C) COPYRIGHT 2014~2015 Nuvoton Technology Corp. ***/ |