Mouse code for the MacroRat

Dependencies:   ITG3200 QEI

Committer:
sahilmgandhi
Date:
Sun May 14 23:18:57 2017 +0000
Revision:
18:6a4db94011d3
Publishing again

Who changed what in which revision?

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