Mouse code for the MacroRat
mbed-dev/targets/TARGET_NUVOTON/TARGET_M451/device/StdDriver/m451_usbd.c@46:b156ef445742, 2017-06-03 (annotated)
- Committer:
- sahilmgandhi
- Date:
- Sat Jun 03 00:22:44 2017 +0000
- Revision:
- 46:b156ef445742
- Parent:
- 18:6a4db94011d3
Final code for internal battlebot competition.
Who changed what in which revision?
User | Revision | Line number | New 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. ***/ |