Repostiory containing DAPLink source code with Reset Pin workaround for HANI_IOT board.

Upstream: https://github.com/ARMmbed/DAPLink

Committer:
Pawel Zarembski
Date:
Tue Apr 07 12:55:42 2020 +0200
Revision:
0:01f31e923fe2
hani: DAPLink with reset workaround

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Pawel Zarembski 0:01f31e923fe2 1 /**
Pawel Zarembski 0:01f31e923fe2 2 * @file usbd_core.c
Pawel Zarembski 0:01f31e923fe2 3 * @brief USB Device core
Pawel Zarembski 0:01f31e923fe2 4 *
Pawel Zarembski 0:01f31e923fe2 5 * DAPLink Interface Firmware
Pawel Zarembski 0:01f31e923fe2 6 * Copyright (c) 2009-2016, ARM Limited, All Rights Reserved
Pawel Zarembski 0:01f31e923fe2 7 * SPDX-License-Identifier: Apache-2.0
Pawel Zarembski 0:01f31e923fe2 8 *
Pawel Zarembski 0:01f31e923fe2 9 * Licensed under the Apache License, Version 2.0 (the "License"); you may
Pawel Zarembski 0:01f31e923fe2 10 * not use this file except in compliance with the License.
Pawel Zarembski 0:01f31e923fe2 11 * You may obtain a copy of the License at
Pawel Zarembski 0:01f31e923fe2 12 *
Pawel Zarembski 0:01f31e923fe2 13 * http://www.apache.org/licenses/LICENSE-2.0
Pawel Zarembski 0:01f31e923fe2 14 *
Pawel Zarembski 0:01f31e923fe2 15 * Unless required by applicable law or agreed to in writing, software
Pawel Zarembski 0:01f31e923fe2 16 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
Pawel Zarembski 0:01f31e923fe2 17 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Pawel Zarembski 0:01f31e923fe2 18 * See the License for the specific language governing permissions and
Pawel Zarembski 0:01f31e923fe2 19 * limitations under the License.
Pawel Zarembski 0:01f31e923fe2 20 */
Pawel Zarembski 0:01f31e923fe2 21
Pawel Zarembski 0:01f31e923fe2 22 #include <string.h>
Pawel Zarembski 0:01f31e923fe2 23 #include "rl_usb.h"
Pawel Zarembski 0:01f31e923fe2 24 #include "usb_for_lib.h"
Pawel Zarembski 0:01f31e923fe2 25 #include "info.h"
Pawel Zarembski 0:01f31e923fe2 26
Pawel Zarembski 0:01f31e923fe2 27 U16 USBD_DeviceStatus;
Pawel Zarembski 0:01f31e923fe2 28 U8 USBD_DeviceAddress;
Pawel Zarembski 0:01f31e923fe2 29 U8 USBD_Configuration;
Pawel Zarembski 0:01f31e923fe2 30 U32 USBD_EndPointMask;
Pawel Zarembski 0:01f31e923fe2 31 U32 USBD_EndPointHalt;
Pawel Zarembski 0:01f31e923fe2 32 U32 USBD_EndPointStall; /* EP must stay stalled */
Pawel Zarembski 0:01f31e923fe2 33 U8 USBD_NumInterfaces;
Pawel Zarembski 0:01f31e923fe2 34 U8 USBD_HighSpeed;
Pawel Zarembski 0:01f31e923fe2 35 U8 USBD_ZLP;
Pawel Zarembski 0:01f31e923fe2 36
Pawel Zarembski 0:01f31e923fe2 37 USBD_EP_DATA USBD_EP0Data;
Pawel Zarembski 0:01f31e923fe2 38 USB_SETUP_PACKET USBD_SetupPacket;
Pawel Zarembski 0:01f31e923fe2 39
Pawel Zarembski 0:01f31e923fe2 40 #ifdef __RTX
Pawel Zarembski 0:01f31e923fe2 41 OS_TID USBD_RTX_DevTask; /* USB Device Task ID */
Pawel Zarembski 0:01f31e923fe2 42 OS_TID USBD_RTX_EPTask[16]; /* USB Endpoint Task ID's */
Pawel Zarembski 0:01f31e923fe2 43 OS_TID USBD_RTX_CoreTask; /* USB Core Task ID */
Pawel Zarembski 0:01f31e923fe2 44 #endif
Pawel Zarembski 0:01f31e923fe2 45
Pawel Zarembski 0:01f31e923fe2 46
Pawel Zarembski 0:01f31e923fe2 47 __asm void $$USBD$$version(void)
Pawel Zarembski 0:01f31e923fe2 48 {
Pawel Zarembski 0:01f31e923fe2 49 /* Export a version number symbol for a version control. */
Pawel Zarembski 0:01f31e923fe2 50 EXPORT __RL_USBD_VER
Pawel Zarembski 0:01f31e923fe2 51 __RL_USBD_VER EQU 0x470
Pawel Zarembski 0:01f31e923fe2 52 }
Pawel Zarembski 0:01f31e923fe2 53
Pawel Zarembski 0:01f31e923fe2 54
Pawel Zarembski 0:01f31e923fe2 55 /*
Pawel Zarembski 0:01f31e923fe2 56 * Init USB Device Core and Hardware
Pawel Zarembski 0:01f31e923fe2 57 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 58 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 59 */
Pawel Zarembski 0:01f31e923fe2 60
Pawel Zarembski 0:01f31e923fe2 61 void usbd_init(void)
Pawel Zarembski 0:01f31e923fe2 62 {
Pawel Zarembski 0:01f31e923fe2 63 USBD_HighSpeed = __FALSE;
Pawel Zarembski 0:01f31e923fe2 64 usbd_class_init();
Pawel Zarembski 0:01f31e923fe2 65 USBD_RTX_TaskInit();
Pawel Zarembski 0:01f31e923fe2 66 USBD_Init();
Pawel Zarembski 0:01f31e923fe2 67 }
Pawel Zarembski 0:01f31e923fe2 68
Pawel Zarembski 0:01f31e923fe2 69
Pawel Zarembski 0:01f31e923fe2 70 /*
Pawel Zarembski 0:01f31e923fe2 71 * USB Device Connect/Disconnect Function
Pawel Zarembski 0:01f31e923fe2 72 * Called by the User to Connect/Disconnect USB Device
Pawel Zarembski 0:01f31e923fe2 73 * Parameters: con: Connect/Disconnect
Pawel Zarembski 0:01f31e923fe2 74 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 75 */
Pawel Zarembski 0:01f31e923fe2 76
Pawel Zarembski 0:01f31e923fe2 77 void usbd_connect(BOOL con)
Pawel Zarembski 0:01f31e923fe2 78 {
Pawel Zarembski 0:01f31e923fe2 79 USBD_Connect(con);
Pawel Zarembski 0:01f31e923fe2 80 }
Pawel Zarembski 0:01f31e923fe2 81
Pawel Zarembski 0:01f31e923fe2 82
Pawel Zarembski 0:01f31e923fe2 83 /*
Pawel Zarembski 0:01f31e923fe2 84 * Reset USB Device Core
Pawel Zarembski 0:01f31e923fe2 85 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 86 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 87 */
Pawel Zarembski 0:01f31e923fe2 88
Pawel Zarembski 0:01f31e923fe2 89 void usbd_reset_core(void)
Pawel Zarembski 0:01f31e923fe2 90 {
Pawel Zarembski 0:01f31e923fe2 91 USBD_DeviceStatus = usbd_power;
Pawel Zarembski 0:01f31e923fe2 92 USBD_DeviceAddress = 0;
Pawel Zarembski 0:01f31e923fe2 93 USBD_Configuration = 0;
Pawel Zarembski 0:01f31e923fe2 94 USBD_EndPointMask = 0x00010001;
Pawel Zarembski 0:01f31e923fe2 95 USBD_EndPointHalt = 0x00000000;
Pawel Zarembski 0:01f31e923fe2 96 USBD_EndPointStall = 0x00000000;
Pawel Zarembski 0:01f31e923fe2 97 }
Pawel Zarembski 0:01f31e923fe2 98
Pawel Zarembski 0:01f31e923fe2 99
Pawel Zarembski 0:01f31e923fe2 100 /*
Pawel Zarembski 0:01f31e923fe2 101 * USB Device Configured Function
Pawel Zarembski 0:01f31e923fe2 102 * Called by the User to check id USB Device is configured
Pawel Zarembski 0:01f31e923fe2 103 * Parameters:
Pawel Zarembski 0:01f31e923fe2 104 * Return Value: Configurated state (FALSE = unconfigured, TRUE = configured)
Pawel Zarembski 0:01f31e923fe2 105 */
Pawel Zarembski 0:01f31e923fe2 106
Pawel Zarembski 0:01f31e923fe2 107 BOOL usbd_configured(void)
Pawel Zarembski 0:01f31e923fe2 108 {
Pawel Zarembski 0:01f31e923fe2 109 if (USBD_Configuration) {
Pawel Zarembski 0:01f31e923fe2 110 return (__TRUE);
Pawel Zarembski 0:01f31e923fe2 111 }
Pawel Zarembski 0:01f31e923fe2 112
Pawel Zarembski 0:01f31e923fe2 113 return (__FALSE);
Pawel Zarembski 0:01f31e923fe2 114 }
Pawel Zarembski 0:01f31e923fe2 115
Pawel Zarembski 0:01f31e923fe2 116
Pawel Zarembski 0:01f31e923fe2 117 /*
Pawel Zarembski 0:01f31e923fe2 118 * USB Device Request - Setup Stage
Pawel Zarembski 0:01f31e923fe2 119 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 120 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 121 */
Pawel Zarembski 0:01f31e923fe2 122
Pawel Zarembski 0:01f31e923fe2 123 void USBD_SetupStage(void)
Pawel Zarembski 0:01f31e923fe2 124 {
Pawel Zarembski 0:01f31e923fe2 125 USBD_ReadEP(0x00, (U8 *)&USBD_SetupPacket, sizeof(USBD_SetupPacket));
Pawel Zarembski 0:01f31e923fe2 126 }
Pawel Zarembski 0:01f31e923fe2 127
Pawel Zarembski 0:01f31e923fe2 128
Pawel Zarembski 0:01f31e923fe2 129 /*
Pawel Zarembski 0:01f31e923fe2 130 * USB Device Request - Data In Stage
Pawel Zarembski 0:01f31e923fe2 131 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 132 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 133 */
Pawel Zarembski 0:01f31e923fe2 134
Pawel Zarembski 0:01f31e923fe2 135 void USBD_DataInStage(void)
Pawel Zarembski 0:01f31e923fe2 136 {
Pawel Zarembski 0:01f31e923fe2 137 U32 cnt;
Pawel Zarembski 0:01f31e923fe2 138
Pawel Zarembski 0:01f31e923fe2 139 if (USBD_EP0Data.Count > usbd_max_packet0) {
Pawel Zarembski 0:01f31e923fe2 140 cnt = usbd_max_packet0;
Pawel Zarembski 0:01f31e923fe2 141 } else {
Pawel Zarembski 0:01f31e923fe2 142 cnt = USBD_EP0Data.Count;
Pawel Zarembski 0:01f31e923fe2 143 }
Pawel Zarembski 0:01f31e923fe2 144
Pawel Zarembski 0:01f31e923fe2 145 if (!cnt) {
Pawel Zarembski 0:01f31e923fe2 146 USBD_ZLP = 0;
Pawel Zarembski 0:01f31e923fe2 147 }
Pawel Zarembski 0:01f31e923fe2 148
Pawel Zarembski 0:01f31e923fe2 149 cnt = USBD_WriteEP(0x80, USBD_EP0Data.pData, cnt);
Pawel Zarembski 0:01f31e923fe2 150 USBD_EP0Data.pData += cnt;
Pawel Zarembski 0:01f31e923fe2 151 USBD_EP0Data.Count -= cnt;
Pawel Zarembski 0:01f31e923fe2 152 }
Pawel Zarembski 0:01f31e923fe2 153
Pawel Zarembski 0:01f31e923fe2 154
Pawel Zarembski 0:01f31e923fe2 155 /*
Pawel Zarembski 0:01f31e923fe2 156 * USB Device Request - Data Out Stage
Pawel Zarembski 0:01f31e923fe2 157 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 158 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 159 */
Pawel Zarembski 0:01f31e923fe2 160
Pawel Zarembski 0:01f31e923fe2 161 void USBD_DataOutStage(void)
Pawel Zarembski 0:01f31e923fe2 162 {
Pawel Zarembski 0:01f31e923fe2 163 U32 cnt;
Pawel Zarembski 0:01f31e923fe2 164 cnt = USBD_ReadEP(0x00, USBD_EP0Data.pData, USBD_EP0Data.Count);
Pawel Zarembski 0:01f31e923fe2 165 USBD_EP0Data.pData += cnt;
Pawel Zarembski 0:01f31e923fe2 166 USBD_EP0Data.Count -= cnt;
Pawel Zarembski 0:01f31e923fe2 167 }
Pawel Zarembski 0:01f31e923fe2 168
Pawel Zarembski 0:01f31e923fe2 169
Pawel Zarembski 0:01f31e923fe2 170 /*
Pawel Zarembski 0:01f31e923fe2 171 * USB Device Request - Status In Stage
Pawel Zarembski 0:01f31e923fe2 172 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 173 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 174 */
Pawel Zarembski 0:01f31e923fe2 175
Pawel Zarembski 0:01f31e923fe2 176 void USBD_StatusInStage(void)
Pawel Zarembski 0:01f31e923fe2 177 {
Pawel Zarembski 0:01f31e923fe2 178 USBD_WriteEP(0x80, NULL, 0);
Pawel Zarembski 0:01f31e923fe2 179 }
Pawel Zarembski 0:01f31e923fe2 180
Pawel Zarembski 0:01f31e923fe2 181
Pawel Zarembski 0:01f31e923fe2 182 /*
Pawel Zarembski 0:01f31e923fe2 183 * USB Device Request - Status Out Stage
Pawel Zarembski 0:01f31e923fe2 184 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 185 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 186 */
Pawel Zarembski 0:01f31e923fe2 187
Pawel Zarembski 0:01f31e923fe2 188 void USBD_StatusOutStage(void)
Pawel Zarembski 0:01f31e923fe2 189 {
Pawel Zarembski 0:01f31e923fe2 190 USBD_ReadEP(0x00, USBD_EP0Buf, usbd_max_packet0);
Pawel Zarembski 0:01f31e923fe2 191 }
Pawel Zarembski 0:01f31e923fe2 192
Pawel Zarembski 0:01f31e923fe2 193
Pawel Zarembski 0:01f31e923fe2 194 /*
Pawel Zarembski 0:01f31e923fe2 195 * Get Status USB Device Request
Pawel Zarembski 0:01f31e923fe2 196 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 197 * Return Value: TRUE - Success, FALSE - Error
Pawel Zarembski 0:01f31e923fe2 198 */
Pawel Zarembski 0:01f31e923fe2 199
Pawel Zarembski 0:01f31e923fe2 200 static inline BOOL USBD_ReqGetStatus(void)
Pawel Zarembski 0:01f31e923fe2 201 {
Pawel Zarembski 0:01f31e923fe2 202 U32 n, m;
Pawel Zarembski 0:01f31e923fe2 203
Pawel Zarembski 0:01f31e923fe2 204 switch (USBD_SetupPacket.bmRequestType.Recipient) {
Pawel Zarembski 0:01f31e923fe2 205 case REQUEST_TO_DEVICE:
Pawel Zarembski 0:01f31e923fe2 206 USBD_EP0Data.pData = (U8 *)&USBD_DeviceStatus;
Pawel Zarembski 0:01f31e923fe2 207 break;
Pawel Zarembski 0:01f31e923fe2 208
Pawel Zarembski 0:01f31e923fe2 209 case REQUEST_TO_INTERFACE:
Pawel Zarembski 0:01f31e923fe2 210 if ((USBD_Configuration != 0) && (USBD_SetupPacket.wIndexL < USBD_NumInterfaces)) {
Pawel Zarembski 0:01f31e923fe2 211 *((__packed U16 *)USBD_EP0Buf) = 0;
Pawel Zarembski 0:01f31e923fe2 212 USBD_EP0Data.pData = USBD_EP0Buf;
Pawel Zarembski 0:01f31e923fe2 213 } else {
Pawel Zarembski 0:01f31e923fe2 214 return (__FALSE);
Pawel Zarembski 0:01f31e923fe2 215 }
Pawel Zarembski 0:01f31e923fe2 216
Pawel Zarembski 0:01f31e923fe2 217 break;
Pawel Zarembski 0:01f31e923fe2 218
Pawel Zarembski 0:01f31e923fe2 219 case REQUEST_TO_ENDPOINT:
Pawel Zarembski 0:01f31e923fe2 220 n = USBD_SetupPacket.wIndexL & 0x8F;
Pawel Zarembski 0:01f31e923fe2 221 m = (n & 0x80) ? ((1 << 16) << (n & 0x0F)) : (1 << n);
Pawel Zarembski 0:01f31e923fe2 222
Pawel Zarembski 0:01f31e923fe2 223 if (((USBD_Configuration != 0) || ((n & 0x0F) == 0)) && (USBD_EndPointMask & m)) {
Pawel Zarembski 0:01f31e923fe2 224 *((__packed U16 *)USBD_EP0Buf) = (USBD_EndPointHalt & m) ? 1 : 0;
Pawel Zarembski 0:01f31e923fe2 225 USBD_EP0Data.pData = USBD_EP0Buf;
Pawel Zarembski 0:01f31e923fe2 226 } else {
Pawel Zarembski 0:01f31e923fe2 227 return (__FALSE);
Pawel Zarembski 0:01f31e923fe2 228 }
Pawel Zarembski 0:01f31e923fe2 229
Pawel Zarembski 0:01f31e923fe2 230 break;
Pawel Zarembski 0:01f31e923fe2 231
Pawel Zarembski 0:01f31e923fe2 232 default:
Pawel Zarembski 0:01f31e923fe2 233 return (__FALSE);
Pawel Zarembski 0:01f31e923fe2 234 }
Pawel Zarembski 0:01f31e923fe2 235
Pawel Zarembski 0:01f31e923fe2 236 return (__TRUE);
Pawel Zarembski 0:01f31e923fe2 237 }
Pawel Zarembski 0:01f31e923fe2 238
Pawel Zarembski 0:01f31e923fe2 239
Pawel Zarembski 0:01f31e923fe2 240 /*
Pawel Zarembski 0:01f31e923fe2 241 * Set/Clear Feature USB Device Request
Pawel Zarembski 0:01f31e923fe2 242 * Parameters: sc: 0 - Clear, 1 - Set
Pawel Zarembski 0:01f31e923fe2 243 * Return Value: TRUE - Success, FALSE - Error
Pawel Zarembski 0:01f31e923fe2 244 */
Pawel Zarembski 0:01f31e923fe2 245
Pawel Zarembski 0:01f31e923fe2 246 static inline BOOL USBD_ReqSetClrFeature(U32 sc)
Pawel Zarembski 0:01f31e923fe2 247 {
Pawel Zarembski 0:01f31e923fe2 248 U32 n, m;
Pawel Zarembski 0:01f31e923fe2 249
Pawel Zarembski 0:01f31e923fe2 250 switch (USBD_SetupPacket.bmRequestType.Recipient) {
Pawel Zarembski 0:01f31e923fe2 251 case REQUEST_TO_DEVICE:
Pawel Zarembski 0:01f31e923fe2 252 if (USBD_SetupPacket.wValue == USB_FEATURE_REMOTE_WAKEUP) {
Pawel Zarembski 0:01f31e923fe2 253 if (sc) {
Pawel Zarembski 0:01f31e923fe2 254 USBD_WakeUpCfg(__TRUE);
Pawel Zarembski 0:01f31e923fe2 255 USBD_DeviceStatus |= USB_GETSTATUS_REMOTE_WAKEUP;
Pawel Zarembski 0:01f31e923fe2 256 } else {
Pawel Zarembski 0:01f31e923fe2 257 USBD_WakeUpCfg(__FALSE);
Pawel Zarembski 0:01f31e923fe2 258 USBD_DeviceStatus &= ~USB_GETSTATUS_REMOTE_WAKEUP;
Pawel Zarembski 0:01f31e923fe2 259 }
Pawel Zarembski 0:01f31e923fe2 260 } else {
Pawel Zarembski 0:01f31e923fe2 261 return (__FALSE);
Pawel Zarembski 0:01f31e923fe2 262 }
Pawel Zarembski 0:01f31e923fe2 263
Pawel Zarembski 0:01f31e923fe2 264 break;
Pawel Zarembski 0:01f31e923fe2 265
Pawel Zarembski 0:01f31e923fe2 266 case REQUEST_TO_INTERFACE:
Pawel Zarembski 0:01f31e923fe2 267 return (__FALSE);
Pawel Zarembski 0:01f31e923fe2 268
Pawel Zarembski 0:01f31e923fe2 269 case REQUEST_TO_ENDPOINT:
Pawel Zarembski 0:01f31e923fe2 270 n = USBD_SetupPacket.wIndexL & 0x8F;
Pawel Zarembski 0:01f31e923fe2 271 m = (n & 0x80) ? ((1 << 16) << (n & 0x0F)) : (1 << n);
Pawel Zarembski 0:01f31e923fe2 272
Pawel Zarembski 0:01f31e923fe2 273 if ((USBD_Configuration != 0) && ((n & 0x0F) != 0) && (USBD_EndPointMask & m)) {
Pawel Zarembski 0:01f31e923fe2 274 if (USBD_SetupPacket.wValue == USB_FEATURE_ENDPOINT_STALL) {
Pawel Zarembski 0:01f31e923fe2 275 if (sc) {
Pawel Zarembski 0:01f31e923fe2 276 USBD_SetStallEP(n);
Pawel Zarembski 0:01f31e923fe2 277 USBD_EndPointHalt |= m;
Pawel Zarembski 0:01f31e923fe2 278 } else {
Pawel Zarembski 0:01f31e923fe2 279 if ((USBD_EndPointStall & m) != 0) {
Pawel Zarembski 0:01f31e923fe2 280 return (__TRUE);
Pawel Zarembski 0:01f31e923fe2 281 }
Pawel Zarembski 0:01f31e923fe2 282
Pawel Zarembski 0:01f31e923fe2 283 USBD_ClrStallEP(n);
Pawel Zarembski 0:01f31e923fe2 284 USBD_ReqClrFeature_MSC(n);
Pawel Zarembski 0:01f31e923fe2 285 USBD_EndPointHalt &= ~m;
Pawel Zarembski 0:01f31e923fe2 286 }
Pawel Zarembski 0:01f31e923fe2 287 } else {
Pawel Zarembski 0:01f31e923fe2 288 return (__FALSE);
Pawel Zarembski 0:01f31e923fe2 289 }
Pawel Zarembski 0:01f31e923fe2 290 } else {
Pawel Zarembski 0:01f31e923fe2 291 return (__FALSE);
Pawel Zarembski 0:01f31e923fe2 292 }
Pawel Zarembski 0:01f31e923fe2 293
Pawel Zarembski 0:01f31e923fe2 294 break;
Pawel Zarembski 0:01f31e923fe2 295
Pawel Zarembski 0:01f31e923fe2 296 default:
Pawel Zarembski 0:01f31e923fe2 297 return (__FALSE);
Pawel Zarembski 0:01f31e923fe2 298 }
Pawel Zarembski 0:01f31e923fe2 299
Pawel Zarembski 0:01f31e923fe2 300 return (__TRUE);
Pawel Zarembski 0:01f31e923fe2 301 }
Pawel Zarembski 0:01f31e923fe2 302
Pawel Zarembski 0:01f31e923fe2 303
Pawel Zarembski 0:01f31e923fe2 304 /*
Pawel Zarembski 0:01f31e923fe2 305 * Set Address USB Device Request
Pawel Zarembski 0:01f31e923fe2 306 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 307 * Return Value: TRUE - Success, FALSE - Error
Pawel Zarembski 0:01f31e923fe2 308 */
Pawel Zarembski 0:01f31e923fe2 309
Pawel Zarembski 0:01f31e923fe2 310 static inline BOOL USBD_ReqSetAddress(void)
Pawel Zarembski 0:01f31e923fe2 311 {
Pawel Zarembski 0:01f31e923fe2 312 switch (USBD_SetupPacket.bmRequestType.Recipient) {
Pawel Zarembski 0:01f31e923fe2 313 case REQUEST_TO_DEVICE:
Pawel Zarembski 0:01f31e923fe2 314 USBD_DeviceAddress = 0x80 | USBD_SetupPacket.wValueL;
Pawel Zarembski 0:01f31e923fe2 315 break;
Pawel Zarembski 0:01f31e923fe2 316
Pawel Zarembski 0:01f31e923fe2 317 default:
Pawel Zarembski 0:01f31e923fe2 318 return (__FALSE);
Pawel Zarembski 0:01f31e923fe2 319 }
Pawel Zarembski 0:01f31e923fe2 320
Pawel Zarembski 0:01f31e923fe2 321 return (__TRUE);
Pawel Zarembski 0:01f31e923fe2 322 }
Pawel Zarembski 0:01f31e923fe2 323
Pawel Zarembski 0:01f31e923fe2 324
Pawel Zarembski 0:01f31e923fe2 325 /*
Pawel Zarembski 0:01f31e923fe2 326 * Get Descriptor USB Device Request
Pawel Zarembski 0:01f31e923fe2 327 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 328 * Return Value: TRUE - Success, FALSE - Error
Pawel Zarembski 0:01f31e923fe2 329 */
Pawel Zarembski 0:01f31e923fe2 330
Pawel Zarembski 0:01f31e923fe2 331 static inline BOOL USBD_ReqGetDescriptor(void)
Pawel Zarembski 0:01f31e923fe2 332 {
Pawel Zarembski 0:01f31e923fe2 333 U8 *pD;
Pawel Zarembski 0:01f31e923fe2 334 U32 len, n;
Pawel Zarembski 0:01f31e923fe2 335
Pawel Zarembski 0:01f31e923fe2 336 switch (USBD_SetupPacket.bmRequestType.Recipient) {
Pawel Zarembski 0:01f31e923fe2 337 case REQUEST_TO_DEVICE:
Pawel Zarembski 0:01f31e923fe2 338 switch (USBD_SetupPacket.wValueH) {
Pawel Zarembski 0:01f31e923fe2 339 case USB_DEVICE_DESCRIPTOR_TYPE:
Pawel Zarembski 0:01f31e923fe2 340 USBD_EP0Data.pData = (U8 *)USBD_DeviceDescriptor;
Pawel Zarembski 0:01f31e923fe2 341 len = USB_DEVICE_DESC_SIZE;
Pawel Zarembski 0:01f31e923fe2 342 break;
Pawel Zarembski 0:01f31e923fe2 343
Pawel Zarembski 0:01f31e923fe2 344 case USB_DEVICE_QUALIFIER_DESCRIPTOR_TYPE:
Pawel Zarembski 0:01f31e923fe2 345 if (!usbd_hs_enable) {
Pawel Zarembski 0:01f31e923fe2 346 return (__FALSE); /* High speed not enabled */
Pawel Zarembski 0:01f31e923fe2 347 }
Pawel Zarembski 0:01f31e923fe2 348
Pawel Zarembski 0:01f31e923fe2 349 if (USBD_HighSpeed == __FALSE) {
Pawel Zarembski 0:01f31e923fe2 350 USBD_EP0Data.pData = (U8 *)USBD_DeviceQualifier;
Pawel Zarembski 0:01f31e923fe2 351 } else {
Pawel Zarembski 0:01f31e923fe2 352 USBD_EP0Data.pData = (U8 *)USBD_DeviceQualifier_HS;
Pawel Zarembski 0:01f31e923fe2 353 }
Pawel Zarembski 0:01f31e923fe2 354
Pawel Zarembski 0:01f31e923fe2 355 len = USB_DEVICE_QUALI_SIZE;
Pawel Zarembski 0:01f31e923fe2 356 break;
Pawel Zarembski 0:01f31e923fe2 357
Pawel Zarembski 0:01f31e923fe2 358 case USB_CONFIGURATION_DESCRIPTOR_TYPE:
Pawel Zarembski 0:01f31e923fe2 359 if ((!usbd_hs_enable) && (USBD_HighSpeed == __TRUE)) {
Pawel Zarembski 0:01f31e923fe2 360 return (__FALSE); /* High speed request but high-speed not enabled */
Pawel Zarembski 0:01f31e923fe2 361 }
Pawel Zarembski 0:01f31e923fe2 362
Pawel Zarembski 0:01f31e923fe2 363 if (USBD_HighSpeed == __FALSE) {
Pawel Zarembski 0:01f31e923fe2 364 pD = (U8 *)USBD_ConfigDescriptor;
Pawel Zarembski 0:01f31e923fe2 365 ((USB_CONFIGURATION_DESCRIPTOR *)pD)->bDescriptorType = USB_CONFIGURATION_DESCRIPTOR_TYPE; //same descriptor is used in other configuration
Pawel Zarembski 0:01f31e923fe2 366 } else {
Pawel Zarembski 0:01f31e923fe2 367 pD = (U8 *)USBD_ConfigDescriptor_HS;
Pawel Zarembski 0:01f31e923fe2 368 ((USB_CONFIGURATION_DESCRIPTOR *)pD)->bDescriptorType = USB_CONFIGURATION_DESCRIPTOR_TYPE; //same descriptor is used in other configuration
Pawel Zarembski 0:01f31e923fe2 369 }
Pawel Zarembski 0:01f31e923fe2 370
Pawel Zarembski 0:01f31e923fe2 371 for (n = 0; n != USBD_SetupPacket.wValueL; n++) {
Pawel Zarembski 0:01f31e923fe2 372 if (((USB_CONFIGURATION_DESCRIPTOR *)pD)->bLength != 0) {
Pawel Zarembski 0:01f31e923fe2 373 pD += ((USB_CONFIGURATION_DESCRIPTOR *)pD)->wTotalLength;
Pawel Zarembski 0:01f31e923fe2 374 }
Pawel Zarembski 0:01f31e923fe2 375 }
Pawel Zarembski 0:01f31e923fe2 376
Pawel Zarembski 0:01f31e923fe2 377 if (((USB_CONFIGURATION_DESCRIPTOR *)pD)->bLength == 0) {
Pawel Zarembski 0:01f31e923fe2 378 return (__FALSE);
Pawel Zarembski 0:01f31e923fe2 379 }
Pawel Zarembski 0:01f31e923fe2 380
Pawel Zarembski 0:01f31e923fe2 381 USBD_EP0Data.pData = pD;
Pawel Zarembski 0:01f31e923fe2 382 len = ((USB_CONFIGURATION_DESCRIPTOR *)pD)->wTotalLength;
Pawel Zarembski 0:01f31e923fe2 383 break;
Pawel Zarembski 0:01f31e923fe2 384
Pawel Zarembski 0:01f31e923fe2 385 case USB_OTHER_SPEED_CONFIG_DESCRIPTOR_TYPE:
Pawel Zarembski 0:01f31e923fe2 386 if (!usbd_hs_enable) {
Pawel Zarembski 0:01f31e923fe2 387 return (__FALSE); /* High speed not enabled */
Pawel Zarembski 0:01f31e923fe2 388 }
Pawel Zarembski 0:01f31e923fe2 389
Pawel Zarembski 0:01f31e923fe2 390 if (USBD_HighSpeed == __FALSE) {
Pawel Zarembski 0:01f31e923fe2 391 pD = (U8 *)USBD_ConfigDescriptor_HS;
Pawel Zarembski 0:01f31e923fe2 392 ((USB_CONFIGURATION_DESCRIPTOR *)pD)->bDescriptorType = USB_OTHER_SPEED_CONFIG_DESCRIPTOR_TYPE; //same descriptor is used in main configuration
Pawel Zarembski 0:01f31e923fe2 393 } else {
Pawel Zarembski 0:01f31e923fe2 394 pD = (U8 *)USBD_ConfigDescriptor;
Pawel Zarembski 0:01f31e923fe2 395 ((USB_CONFIGURATION_DESCRIPTOR *)pD)->bDescriptorType = USB_OTHER_SPEED_CONFIG_DESCRIPTOR_TYPE; //same descriptor is used in main configuration
Pawel Zarembski 0:01f31e923fe2 396 }
Pawel Zarembski 0:01f31e923fe2 397
Pawel Zarembski 0:01f31e923fe2 398 for (n = 0; n != USBD_SetupPacket.wValueL; n++) {
Pawel Zarembski 0:01f31e923fe2 399 if (((USB_CONFIGURATION_DESCRIPTOR *)pD)->bLength != 0) {
Pawel Zarembski 0:01f31e923fe2 400 pD += ((USB_CONFIGURATION_DESCRIPTOR *)pD)->wTotalLength;
Pawel Zarembski 0:01f31e923fe2 401 }
Pawel Zarembski 0:01f31e923fe2 402 }
Pawel Zarembski 0:01f31e923fe2 403
Pawel Zarembski 0:01f31e923fe2 404 if (((USB_CONFIGURATION_DESCRIPTOR *)pD)->bLength == 0) {
Pawel Zarembski 0:01f31e923fe2 405 return (__FALSE);
Pawel Zarembski 0:01f31e923fe2 406 }
Pawel Zarembski 0:01f31e923fe2 407
Pawel Zarembski 0:01f31e923fe2 408 USBD_EP0Data.pData = pD;
Pawel Zarembski 0:01f31e923fe2 409 len = ((USB_CONFIGURATION_DESCRIPTOR *)pD)->wTotalLength;
Pawel Zarembski 0:01f31e923fe2 410 break;
Pawel Zarembski 0:01f31e923fe2 411
Pawel Zarembski 0:01f31e923fe2 412 case USB_STRING_DESCRIPTOR_TYPE:
Pawel Zarembski 0:01f31e923fe2 413 pD = (U8 *)USBD_StringDescriptor;
Pawel Zarembski 0:01f31e923fe2 414
Pawel Zarembski 0:01f31e923fe2 415 // added by sam to send unique id string descriptor
Pawel Zarembski 0:01f31e923fe2 416 if (USBD_SetupPacket.wValueL == 3) {
Pawel Zarembski 0:01f31e923fe2 417 USBD_EP0Data.pData = (uint8_t *)info_get_unique_id_string_descriptor();
Pawel Zarembski 0:01f31e923fe2 418 len = ((USB_STRING_DESCRIPTOR *)USBD_EP0Data.pData)->bLength;
Pawel Zarembski 0:01f31e923fe2 419 break;
Pawel Zarembski 0:01f31e923fe2 420 }
Pawel Zarembski 0:01f31e923fe2 421
Pawel Zarembski 0:01f31e923fe2 422 for (n = 0; n != USBD_SetupPacket.wValueL; n++) {
Pawel Zarembski 0:01f31e923fe2 423 if (((USB_STRING_DESCRIPTOR *)pD)->bLength != 0) {
Pawel Zarembski 0:01f31e923fe2 424 pD += ((USB_STRING_DESCRIPTOR *)pD)->bLength;
Pawel Zarembski 0:01f31e923fe2 425 }
Pawel Zarembski 0:01f31e923fe2 426 }
Pawel Zarembski 0:01f31e923fe2 427
Pawel Zarembski 0:01f31e923fe2 428 if (((USB_STRING_DESCRIPTOR *)pD)->bLength == 0) {
Pawel Zarembski 0:01f31e923fe2 429 return (__FALSE);
Pawel Zarembski 0:01f31e923fe2 430 }
Pawel Zarembski 0:01f31e923fe2 431
Pawel Zarembski 0:01f31e923fe2 432 USBD_EP0Data.pData = pD;
Pawel Zarembski 0:01f31e923fe2 433 len = ((USB_STRING_DESCRIPTOR *)pD)->bLength;
Pawel Zarembski 0:01f31e923fe2 434 break;
Pawel Zarembski 0:01f31e923fe2 435
Pawel Zarembski 0:01f31e923fe2 436 case USB_BINARY_OBJECT_STORE_DESCRIPTOR_TYPE:
Pawel Zarembski 0:01f31e923fe2 437 if (!usbd_bos_enable) {
Pawel Zarembski 0:01f31e923fe2 438 return (__FALSE); /* High speed not enabled */
Pawel Zarembski 0:01f31e923fe2 439 }
Pawel Zarembski 0:01f31e923fe2 440
Pawel Zarembski 0:01f31e923fe2 441 pD = (U8 *)USBD_BinaryObjectStoreDescriptor;
Pawel Zarembski 0:01f31e923fe2 442 USBD_EP0Data.pData = pD;
Pawel Zarembski 0:01f31e923fe2 443
Pawel Zarembski 0:01f31e923fe2 444 if (((USB_BINARY_OBJECT_STORE_DESCRIPTOR *)pD)->bLength == 0) {
Pawel Zarembski 0:01f31e923fe2 445 return (__FALSE);
Pawel Zarembski 0:01f31e923fe2 446 }
Pawel Zarembski 0:01f31e923fe2 447
Pawel Zarembski 0:01f31e923fe2 448 len = ((USB_BINARY_OBJECT_STORE_DESCRIPTOR *)pD)->wTotalLength;
Pawel Zarembski 0:01f31e923fe2 449 break;
Pawel Zarembski 0:01f31e923fe2 450
Pawel Zarembski 0:01f31e923fe2 451 default:
Pawel Zarembski 0:01f31e923fe2 452 return (__FALSE);
Pawel Zarembski 0:01f31e923fe2 453 }
Pawel Zarembski 0:01f31e923fe2 454
Pawel Zarembski 0:01f31e923fe2 455 break;
Pawel Zarembski 0:01f31e923fe2 456
Pawel Zarembski 0:01f31e923fe2 457 case REQUEST_TO_INTERFACE:
Pawel Zarembski 0:01f31e923fe2 458 if (!USBD_ReqGetDescriptor_HID(&pD, &len)) {
Pawel Zarembski 0:01f31e923fe2 459 return (__FALSE);
Pawel Zarembski 0:01f31e923fe2 460 }
Pawel Zarembski 0:01f31e923fe2 461
Pawel Zarembski 0:01f31e923fe2 462 break;
Pawel Zarembski 0:01f31e923fe2 463
Pawel Zarembski 0:01f31e923fe2 464 default:
Pawel Zarembski 0:01f31e923fe2 465 return (__FALSE);
Pawel Zarembski 0:01f31e923fe2 466 }
Pawel Zarembski 0:01f31e923fe2 467
Pawel Zarembski 0:01f31e923fe2 468 if (USBD_EP0Data.Count > len) {
Pawel Zarembski 0:01f31e923fe2 469 USBD_EP0Data.Count = len;
Pawel Zarembski 0:01f31e923fe2 470
Pawel Zarembski 0:01f31e923fe2 471 if (!(USBD_EP0Data.Count & (usbd_max_packet0 - 1))) {
Pawel Zarembski 0:01f31e923fe2 472 USBD_ZLP = 1;
Pawel Zarembski 0:01f31e923fe2 473 }
Pawel Zarembski 0:01f31e923fe2 474 }
Pawel Zarembski 0:01f31e923fe2 475
Pawel Zarembski 0:01f31e923fe2 476 return (__TRUE);
Pawel Zarembski 0:01f31e923fe2 477 }
Pawel Zarembski 0:01f31e923fe2 478
Pawel Zarembski 0:01f31e923fe2 479
Pawel Zarembski 0:01f31e923fe2 480 /*
Pawel Zarembski 0:01f31e923fe2 481 * Get Configuration USB Device Request
Pawel Zarembski 0:01f31e923fe2 482 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 483 * Return Value: TRUE - Success, FALSE - Error
Pawel Zarembski 0:01f31e923fe2 484 */
Pawel Zarembski 0:01f31e923fe2 485
Pawel Zarembski 0:01f31e923fe2 486 static inline BOOL USBD_ReqGetConfiguration(void)
Pawel Zarembski 0:01f31e923fe2 487 {
Pawel Zarembski 0:01f31e923fe2 488 switch (USBD_SetupPacket.bmRequestType.Recipient) {
Pawel Zarembski 0:01f31e923fe2 489 case REQUEST_TO_DEVICE:
Pawel Zarembski 0:01f31e923fe2 490 USBD_EP0Data.pData = &USBD_Configuration;
Pawel Zarembski 0:01f31e923fe2 491 break;
Pawel Zarembski 0:01f31e923fe2 492
Pawel Zarembski 0:01f31e923fe2 493 default:
Pawel Zarembski 0:01f31e923fe2 494 return (__FALSE);
Pawel Zarembski 0:01f31e923fe2 495 }
Pawel Zarembski 0:01f31e923fe2 496
Pawel Zarembski 0:01f31e923fe2 497 return (__TRUE);
Pawel Zarembski 0:01f31e923fe2 498 }
Pawel Zarembski 0:01f31e923fe2 499
Pawel Zarembski 0:01f31e923fe2 500
Pawel Zarembski 0:01f31e923fe2 501 /*
Pawel Zarembski 0:01f31e923fe2 502 * Set Configuration USB Device Request
Pawel Zarembski 0:01f31e923fe2 503 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 504 * Return Value: TRUE - Success, FALSE - Error
Pawel Zarembski 0:01f31e923fe2 505 */
Pawel Zarembski 0:01f31e923fe2 506
Pawel Zarembski 0:01f31e923fe2 507 static inline BOOL USBD_ReqSetConfiguration(void)
Pawel Zarembski 0:01f31e923fe2 508 {
Pawel Zarembski 0:01f31e923fe2 509 USB_CONFIGURATION_DESCRIPTOR *pD;
Pawel Zarembski 0:01f31e923fe2 510 U32 alt = 0;
Pawel Zarembski 0:01f31e923fe2 511 U32 n, m;
Pawel Zarembski 0:01f31e923fe2 512
Pawel Zarembski 0:01f31e923fe2 513 switch (USBD_SetupPacket.bmRequestType.Recipient) {
Pawel Zarembski 0:01f31e923fe2 514 case REQUEST_TO_DEVICE:
Pawel Zarembski 0:01f31e923fe2 515 if (USBD_SetupPacket.wValueL) {
Pawel Zarembski 0:01f31e923fe2 516 if ((!usbd_hs_enable) && (USBD_HighSpeed == __TRUE)) {
Pawel Zarembski 0:01f31e923fe2 517 return (__FALSE); /* High speed request but high-speed not enabled */
Pawel Zarembski 0:01f31e923fe2 518 }
Pawel Zarembski 0:01f31e923fe2 519
Pawel Zarembski 0:01f31e923fe2 520 if (USBD_HighSpeed == __FALSE) {
Pawel Zarembski 0:01f31e923fe2 521 pD = (USB_CONFIGURATION_DESCRIPTOR *)USBD_ConfigDescriptor;
Pawel Zarembski 0:01f31e923fe2 522 } else {
Pawel Zarembski 0:01f31e923fe2 523 pD = (USB_CONFIGURATION_DESCRIPTOR *)USBD_ConfigDescriptor_HS;
Pawel Zarembski 0:01f31e923fe2 524 }
Pawel Zarembski 0:01f31e923fe2 525
Pawel Zarembski 0:01f31e923fe2 526 while (pD->bLength) {
Pawel Zarembski 0:01f31e923fe2 527 switch (pD->bDescriptorType) {
Pawel Zarembski 0:01f31e923fe2 528 case USB_CONFIGURATION_DESCRIPTOR_TYPE:
Pawel Zarembski 0:01f31e923fe2 529 case USB_OTHER_SPEED_CONFIG_DESCRIPTOR_TYPE:
Pawel Zarembski 0:01f31e923fe2 530 if (((USB_CONFIGURATION_DESCRIPTOR *)pD)->bConfigurationValue == USBD_SetupPacket.wValueL) {
Pawel Zarembski 0:01f31e923fe2 531 USBD_Configuration = USBD_SetupPacket.wValueL;
Pawel Zarembski 0:01f31e923fe2 532 USBD_NumInterfaces = ((USB_CONFIGURATION_DESCRIPTOR *)pD)->bNumInterfaces;
Pawel Zarembski 0:01f31e923fe2 533
Pawel Zarembski 0:01f31e923fe2 534 for (n = 0; n < usbd_if_num; n++) {
Pawel Zarembski 0:01f31e923fe2 535 USBD_AltSetting[n] = 0;
Pawel Zarembski 0:01f31e923fe2 536 }
Pawel Zarembski 0:01f31e923fe2 537
Pawel Zarembski 0:01f31e923fe2 538 for (n = 1; n < 16; n++) {
Pawel Zarembski 0:01f31e923fe2 539 if (USBD_EndPointMask & (1 << n)) {
Pawel Zarembski 0:01f31e923fe2 540 USBD_DisableEP(n);
Pawel Zarembski 0:01f31e923fe2 541 }
Pawel Zarembski 0:01f31e923fe2 542
Pawel Zarembski 0:01f31e923fe2 543 if (USBD_EndPointMask & ((1 << 16) << n)) {
Pawel Zarembski 0:01f31e923fe2 544 USBD_DisableEP(n | 0x80);
Pawel Zarembski 0:01f31e923fe2 545 }
Pawel Zarembski 0:01f31e923fe2 546 }
Pawel Zarembski 0:01f31e923fe2 547
Pawel Zarembski 0:01f31e923fe2 548 USBD_EndPointMask = 0x00010001;
Pawel Zarembski 0:01f31e923fe2 549 USBD_EndPointHalt = 0x00000000;
Pawel Zarembski 0:01f31e923fe2 550 USBD_EndPointStall = 0x00000000;
Pawel Zarembski 0:01f31e923fe2 551 USBD_Configure(__TRUE);
Pawel Zarembski 0:01f31e923fe2 552
Pawel Zarembski 0:01f31e923fe2 553 if (((USB_CONFIGURATION_DESCRIPTOR *)pD)->bmAttributes & USB_CONFIG_POWERED_MASK) {
Pawel Zarembski 0:01f31e923fe2 554 USBD_DeviceStatus |= USB_GETSTATUS_SELF_POWERED;
Pawel Zarembski 0:01f31e923fe2 555 } else {
Pawel Zarembski 0:01f31e923fe2 556 USBD_DeviceStatus &= ~USB_GETSTATUS_SELF_POWERED;
Pawel Zarembski 0:01f31e923fe2 557 }
Pawel Zarembski 0:01f31e923fe2 558 } else {
Pawel Zarembski 0:01f31e923fe2 559 pD = (USB_CONFIGURATION_DESCRIPTOR *)((U8 *)pD + ((USB_CONFIGURATION_DESCRIPTOR *)pD)->wTotalLength);
Pawel Zarembski 0:01f31e923fe2 560 continue;
Pawel Zarembski 0:01f31e923fe2 561 }
Pawel Zarembski 0:01f31e923fe2 562
Pawel Zarembski 0:01f31e923fe2 563 break;
Pawel Zarembski 0:01f31e923fe2 564
Pawel Zarembski 0:01f31e923fe2 565 case USB_INTERFACE_DESCRIPTOR_TYPE:
Pawel Zarembski 0:01f31e923fe2 566 alt = ((USB_INTERFACE_DESCRIPTOR *)pD)->bAlternateSetting;
Pawel Zarembski 0:01f31e923fe2 567 break;
Pawel Zarembski 0:01f31e923fe2 568
Pawel Zarembski 0:01f31e923fe2 569 case USB_ENDPOINT_DESCRIPTOR_TYPE:
Pawel Zarembski 0:01f31e923fe2 570 if (alt == 0) {
Pawel Zarembski 0:01f31e923fe2 571 n = ((USB_ENDPOINT_DESCRIPTOR *)pD)->bEndpointAddress & 0x8F;
Pawel Zarembski 0:01f31e923fe2 572 m = (n & 0x80) ? ((1 << 16) << (n & 0x0F)) : (1 << n);
Pawel Zarembski 0:01f31e923fe2 573 USBD_EndPointMask |= m;
Pawel Zarembski 0:01f31e923fe2 574 USBD_ConfigEP((void *)pD);
Pawel Zarembski 0:01f31e923fe2 575 USBD_EnableEP(n);
Pawel Zarembski 0:01f31e923fe2 576 USBD_ResetEP(n);
Pawel Zarembski 0:01f31e923fe2 577 }
Pawel Zarembski 0:01f31e923fe2 578
Pawel Zarembski 0:01f31e923fe2 579 break;
Pawel Zarembski 0:01f31e923fe2 580 }
Pawel Zarembski 0:01f31e923fe2 581
Pawel Zarembski 0:01f31e923fe2 582 pD = (USB_CONFIGURATION_DESCRIPTOR *)((U8 *)pD + pD->bLength);
Pawel Zarembski 0:01f31e923fe2 583 }
Pawel Zarembski 0:01f31e923fe2 584 } else {
Pawel Zarembski 0:01f31e923fe2 585 USBD_Configuration = 0;
Pawel Zarembski 0:01f31e923fe2 586
Pawel Zarembski 0:01f31e923fe2 587 for (n = 1; n < 16; n++) {
Pawel Zarembski 0:01f31e923fe2 588 if (USBD_EndPointMask & (1 << n)) {
Pawel Zarembski 0:01f31e923fe2 589 USBD_DisableEP(n);
Pawel Zarembski 0:01f31e923fe2 590 }
Pawel Zarembski 0:01f31e923fe2 591
Pawel Zarembski 0:01f31e923fe2 592 if (USBD_EndPointMask & ((1 << 16) << n)) {
Pawel Zarembski 0:01f31e923fe2 593 USBD_DisableEP(n | 0x80);
Pawel Zarembski 0:01f31e923fe2 594 }
Pawel Zarembski 0:01f31e923fe2 595 }
Pawel Zarembski 0:01f31e923fe2 596
Pawel Zarembski 0:01f31e923fe2 597 USBD_EndPointMask = 0x00010001;
Pawel Zarembski 0:01f31e923fe2 598 USBD_EndPointHalt = 0x00000000;
Pawel Zarembski 0:01f31e923fe2 599 USBD_EndPointStall = 0x00000000;
Pawel Zarembski 0:01f31e923fe2 600 USBD_Configure(__FALSE);
Pawel Zarembski 0:01f31e923fe2 601 }
Pawel Zarembski 0:01f31e923fe2 602
Pawel Zarembski 0:01f31e923fe2 603 if (USBD_Configuration != USBD_SetupPacket.wValueL) {
Pawel Zarembski 0:01f31e923fe2 604 return (__FALSE);
Pawel Zarembski 0:01f31e923fe2 605 }
Pawel Zarembski 0:01f31e923fe2 606
Pawel Zarembski 0:01f31e923fe2 607 break;
Pawel Zarembski 0:01f31e923fe2 608
Pawel Zarembski 0:01f31e923fe2 609 default:
Pawel Zarembski 0:01f31e923fe2 610 return (__FALSE);
Pawel Zarembski 0:01f31e923fe2 611 }
Pawel Zarembski 0:01f31e923fe2 612
Pawel Zarembski 0:01f31e923fe2 613 return (__TRUE);
Pawel Zarembski 0:01f31e923fe2 614 }
Pawel Zarembski 0:01f31e923fe2 615
Pawel Zarembski 0:01f31e923fe2 616
Pawel Zarembski 0:01f31e923fe2 617 /*
Pawel Zarembski 0:01f31e923fe2 618 * Get Interface USB Device Request
Pawel Zarembski 0:01f31e923fe2 619 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 620 * Return Value: TRUE - Success, FALSE - Error
Pawel Zarembski 0:01f31e923fe2 621 */
Pawel Zarembski 0:01f31e923fe2 622
Pawel Zarembski 0:01f31e923fe2 623 static inline BOOL USBD_ReqGetInterface(void)
Pawel Zarembski 0:01f31e923fe2 624 {
Pawel Zarembski 0:01f31e923fe2 625 switch (USBD_SetupPacket.bmRequestType.Recipient) {
Pawel Zarembski 0:01f31e923fe2 626 case REQUEST_TO_INTERFACE:
Pawel Zarembski 0:01f31e923fe2 627 if ((USBD_Configuration != 0) && (USBD_SetupPacket.wIndexL < USBD_NumInterfaces)) {
Pawel Zarembski 0:01f31e923fe2 628 USBD_EP0Data.pData = USBD_AltSetting + USBD_SetupPacket.wIndexL;
Pawel Zarembski 0:01f31e923fe2 629 } else {
Pawel Zarembski 0:01f31e923fe2 630 return (__FALSE);
Pawel Zarembski 0:01f31e923fe2 631 }
Pawel Zarembski 0:01f31e923fe2 632
Pawel Zarembski 0:01f31e923fe2 633 break;
Pawel Zarembski 0:01f31e923fe2 634
Pawel Zarembski 0:01f31e923fe2 635 default:
Pawel Zarembski 0:01f31e923fe2 636 return (__FALSE);
Pawel Zarembski 0:01f31e923fe2 637 }
Pawel Zarembski 0:01f31e923fe2 638
Pawel Zarembski 0:01f31e923fe2 639 return (__TRUE);
Pawel Zarembski 0:01f31e923fe2 640 }
Pawel Zarembski 0:01f31e923fe2 641
Pawel Zarembski 0:01f31e923fe2 642
Pawel Zarembski 0:01f31e923fe2 643 /*
Pawel Zarembski 0:01f31e923fe2 644 * Set Interface USB Device Request
Pawel Zarembski 0:01f31e923fe2 645 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 646 * Return Value: TRUE - Success, FALSE - Error
Pawel Zarembski 0:01f31e923fe2 647 */
Pawel Zarembski 0:01f31e923fe2 648
Pawel Zarembski 0:01f31e923fe2 649 static inline BOOL USBD_ReqSetInterface(void)
Pawel Zarembski 0:01f31e923fe2 650 {
Pawel Zarembski 0:01f31e923fe2 651 USB_COMMON_DESCRIPTOR *pD;
Pawel Zarembski 0:01f31e923fe2 652 U32 ifn = 0, alt = 0, old = 0, msk = 0;
Pawel Zarembski 0:01f31e923fe2 653 U32 n, m;
Pawel Zarembski 0:01f31e923fe2 654 BOOL set;
Pawel Zarembski 0:01f31e923fe2 655
Pawel Zarembski 0:01f31e923fe2 656 switch (USBD_SetupPacket.bmRequestType.Recipient) {
Pawel Zarembski 0:01f31e923fe2 657 case REQUEST_TO_INTERFACE:
Pawel Zarembski 0:01f31e923fe2 658 if (USBD_Configuration == 0) {
Pawel Zarembski 0:01f31e923fe2 659 return (__FALSE);
Pawel Zarembski 0:01f31e923fe2 660 }
Pawel Zarembski 0:01f31e923fe2 661
Pawel Zarembski 0:01f31e923fe2 662 set = __FALSE;
Pawel Zarembski 0:01f31e923fe2 663
Pawel Zarembski 0:01f31e923fe2 664 if ((!usbd_hs_enable) && (USBD_HighSpeed == __TRUE)) {
Pawel Zarembski 0:01f31e923fe2 665 return (__FALSE); /* High speed request but high-speed not enabled */
Pawel Zarembski 0:01f31e923fe2 666 }
Pawel Zarembski 0:01f31e923fe2 667
Pawel Zarembski 0:01f31e923fe2 668 if (USBD_HighSpeed == __FALSE) {
Pawel Zarembski 0:01f31e923fe2 669 pD = (USB_COMMON_DESCRIPTOR *)USBD_ConfigDescriptor;
Pawel Zarembski 0:01f31e923fe2 670 } else {
Pawel Zarembski 0:01f31e923fe2 671 pD = (USB_COMMON_DESCRIPTOR *)USBD_ConfigDescriptor_HS;
Pawel Zarembski 0:01f31e923fe2 672 }
Pawel Zarembski 0:01f31e923fe2 673
Pawel Zarembski 0:01f31e923fe2 674 while (pD->bLength) {
Pawel Zarembski 0:01f31e923fe2 675 switch (pD->bDescriptorType) {
Pawel Zarembski 0:01f31e923fe2 676 case USB_CONFIGURATION_DESCRIPTOR_TYPE:
Pawel Zarembski 0:01f31e923fe2 677 case USB_OTHER_SPEED_CONFIG_DESCRIPTOR_TYPE:
Pawel Zarembski 0:01f31e923fe2 678 if (((USB_CONFIGURATION_DESCRIPTOR *)pD)->bConfigurationValue != USBD_Configuration) {
Pawel Zarembski 0:01f31e923fe2 679 pD = (USB_COMMON_DESCRIPTOR *)((U8 *)pD + ((USB_CONFIGURATION_DESCRIPTOR *)pD)->wTotalLength);
Pawel Zarembski 0:01f31e923fe2 680 continue;
Pawel Zarembski 0:01f31e923fe2 681 }
Pawel Zarembski 0:01f31e923fe2 682
Pawel Zarembski 0:01f31e923fe2 683 break;
Pawel Zarembski 0:01f31e923fe2 684
Pawel Zarembski 0:01f31e923fe2 685 case USB_INTERFACE_DESCRIPTOR_TYPE:
Pawel Zarembski 0:01f31e923fe2 686 ifn = ((USB_INTERFACE_DESCRIPTOR *)pD)->bInterfaceNumber;
Pawel Zarembski 0:01f31e923fe2 687 alt = ((USB_INTERFACE_DESCRIPTOR *)pD)->bAlternateSetting;
Pawel Zarembski 0:01f31e923fe2 688 msk = 0;
Pawel Zarembski 0:01f31e923fe2 689
Pawel Zarembski 0:01f31e923fe2 690 if ((ifn == USBD_SetupPacket.wIndexL) && (alt == USBD_SetupPacket.wValueL)) {
Pawel Zarembski 0:01f31e923fe2 691 set = __TRUE;
Pawel Zarembski 0:01f31e923fe2 692 old = USBD_AltSetting[ifn];
Pawel Zarembski 0:01f31e923fe2 693 USBD_AltSetting[ifn] = (U8)alt;
Pawel Zarembski 0:01f31e923fe2 694 }
Pawel Zarembski 0:01f31e923fe2 695
Pawel Zarembski 0:01f31e923fe2 696 break;
Pawel Zarembski 0:01f31e923fe2 697
Pawel Zarembski 0:01f31e923fe2 698 case USB_ENDPOINT_DESCRIPTOR_TYPE:
Pawel Zarembski 0:01f31e923fe2 699 if (ifn == USBD_SetupPacket.wIndexL) {
Pawel Zarembski 0:01f31e923fe2 700 n = ((USB_ENDPOINT_DESCRIPTOR *)pD)->bEndpointAddress & 0x8F;
Pawel Zarembski 0:01f31e923fe2 701 m = (n & 0x80) ? ((1 << 16) << (n & 0x0F)) : (1 << n);
Pawel Zarembski 0:01f31e923fe2 702
Pawel Zarembski 0:01f31e923fe2 703 if (alt == USBD_SetupPacket.wValueL) {
Pawel Zarembski 0:01f31e923fe2 704 USBD_EndPointMask |= m;
Pawel Zarembski 0:01f31e923fe2 705 USBD_EndPointHalt &= ~m;
Pawel Zarembski 0:01f31e923fe2 706 USBD_ConfigEP((USB_ENDPOINT_DESCRIPTOR *)pD);
Pawel Zarembski 0:01f31e923fe2 707 USBD_EnableEP(n);
Pawel Zarembski 0:01f31e923fe2 708 USBD_ResetEP(n);
Pawel Zarembski 0:01f31e923fe2 709 msk |= m;
Pawel Zarembski 0:01f31e923fe2 710 } else if ((alt == old) && ((msk & m) == 0)) {
Pawel Zarembski 0:01f31e923fe2 711 USBD_EndPointMask &= ~m;
Pawel Zarembski 0:01f31e923fe2 712 USBD_EndPointHalt &= ~m;
Pawel Zarembski 0:01f31e923fe2 713 USBD_DisableEP(n);
Pawel Zarembski 0:01f31e923fe2 714 }
Pawel Zarembski 0:01f31e923fe2 715 }
Pawel Zarembski 0:01f31e923fe2 716
Pawel Zarembski 0:01f31e923fe2 717 break;
Pawel Zarembski 0:01f31e923fe2 718 }
Pawel Zarembski 0:01f31e923fe2 719
Pawel Zarembski 0:01f31e923fe2 720 pD = (USB_COMMON_DESCRIPTOR *)((U8 *)pD + pD->bLength);
Pawel Zarembski 0:01f31e923fe2 721 }
Pawel Zarembski 0:01f31e923fe2 722
Pawel Zarembski 0:01f31e923fe2 723 break;
Pawel Zarembski 0:01f31e923fe2 724
Pawel Zarembski 0:01f31e923fe2 725 default:
Pawel Zarembski 0:01f31e923fe2 726 return (__FALSE);
Pawel Zarembski 0:01f31e923fe2 727 }
Pawel Zarembski 0:01f31e923fe2 728
Pawel Zarembski 0:01f31e923fe2 729 return (set);
Pawel Zarembski 0:01f31e923fe2 730 }
Pawel Zarembski 0:01f31e923fe2 731
Pawel Zarembski 0:01f31e923fe2 732
Pawel Zarembski 0:01f31e923fe2 733 /*
Pawel Zarembski 0:01f31e923fe2 734 * USB Device Endpoint 0 Event Callback
Pawel Zarembski 0:01f31e923fe2 735 * Parameters: event
Pawel Zarembski 0:01f31e923fe2 736 * Return Value: none
Pawel Zarembski 0:01f31e923fe2 737 */
Pawel Zarembski 0:01f31e923fe2 738
Pawel Zarembski 0:01f31e923fe2 739 void USBD_EndPoint0(U32 event)
Pawel Zarembski 0:01f31e923fe2 740 {
Pawel Zarembski 0:01f31e923fe2 741 if (event & USBD_EVT_SETUP) {
Pawel Zarembski 0:01f31e923fe2 742 USBD_SetupStage();
Pawel Zarembski 0:01f31e923fe2 743 USBD_DirCtrlEP(USBD_SetupPacket.bmRequestType.Dir);
Pawel Zarembski 0:01f31e923fe2 744 USBD_EP0Data.Count = USBD_SetupPacket.wLength; /* Number of bytes to transfer */
Pawel Zarembski 0:01f31e923fe2 745
Pawel Zarembski 0:01f31e923fe2 746 switch (USBD_SetupPacket.bmRequestType.Type) {
Pawel Zarembski 0:01f31e923fe2 747 case REQUEST_STANDARD:
Pawel Zarembski 0:01f31e923fe2 748 switch (USBD_SetupPacket.bRequest) {
Pawel Zarembski 0:01f31e923fe2 749 case USB_REQUEST_GET_STATUS:
Pawel Zarembski 0:01f31e923fe2 750 if (!USBD_ReqGetStatus()) {
Pawel Zarembski 0:01f31e923fe2 751 goto stall;
Pawel Zarembski 0:01f31e923fe2 752 }
Pawel Zarembski 0:01f31e923fe2 753
Pawel Zarembski 0:01f31e923fe2 754 USBD_DataInStage();
Pawel Zarembski 0:01f31e923fe2 755 break;
Pawel Zarembski 0:01f31e923fe2 756
Pawel Zarembski 0:01f31e923fe2 757 case USB_REQUEST_CLEAR_FEATURE:
Pawel Zarembski 0:01f31e923fe2 758 if (!USBD_ReqSetClrFeature(0)) {
Pawel Zarembski 0:01f31e923fe2 759 goto stall;
Pawel Zarembski 0:01f31e923fe2 760 }
Pawel Zarembski 0:01f31e923fe2 761
Pawel Zarembski 0:01f31e923fe2 762 USBD_StatusInStage();
Pawel Zarembski 0:01f31e923fe2 763 #ifdef __RTX
Pawel Zarembski 0:01f31e923fe2 764
Pawel Zarembski 0:01f31e923fe2 765 if (__rtx) {
Pawel Zarembski 0:01f31e923fe2 766 if (USBD_RTX_CoreTask) {
Pawel Zarembski 0:01f31e923fe2 767 usbd_os_evt_set(USBD_EVT_CLR_FEATURE, USBD_RTX_CoreTask);
Pawel Zarembski 0:01f31e923fe2 768 }
Pawel Zarembski 0:01f31e923fe2 769 } else {
Pawel Zarembski 0:01f31e923fe2 770 #endif
Pawel Zarembski 0:01f31e923fe2 771
Pawel Zarembski 0:01f31e923fe2 772 if (USBD_P_Feature_Event) {
Pawel Zarembski 0:01f31e923fe2 773 USBD_P_Feature_Event();
Pawel Zarembski 0:01f31e923fe2 774 }
Pawel Zarembski 0:01f31e923fe2 775
Pawel Zarembski 0:01f31e923fe2 776 #ifdef __RTX
Pawel Zarembski 0:01f31e923fe2 777 }
Pawel Zarembski 0:01f31e923fe2 778
Pawel Zarembski 0:01f31e923fe2 779 #endif
Pawel Zarembski 0:01f31e923fe2 780 break;
Pawel Zarembski 0:01f31e923fe2 781
Pawel Zarembski 0:01f31e923fe2 782 case USB_REQUEST_SET_FEATURE:
Pawel Zarembski 0:01f31e923fe2 783 if (!USBD_ReqSetClrFeature(1)) {
Pawel Zarembski 0:01f31e923fe2 784 goto stall;
Pawel Zarembski 0:01f31e923fe2 785 }
Pawel Zarembski 0:01f31e923fe2 786
Pawel Zarembski 0:01f31e923fe2 787 USBD_StatusInStage();
Pawel Zarembski 0:01f31e923fe2 788 #ifdef __RTX
Pawel Zarembski 0:01f31e923fe2 789
Pawel Zarembski 0:01f31e923fe2 790 if (__rtx) {
Pawel Zarembski 0:01f31e923fe2 791 if (USBD_RTX_CoreTask) {
Pawel Zarembski 0:01f31e923fe2 792 usbd_os_evt_set(USBD_EVT_SET_FEATURE, USBD_RTX_CoreTask);
Pawel Zarembski 0:01f31e923fe2 793 }
Pawel Zarembski 0:01f31e923fe2 794 } else {
Pawel Zarembski 0:01f31e923fe2 795 #endif
Pawel Zarembski 0:01f31e923fe2 796
Pawel Zarembski 0:01f31e923fe2 797 if (USBD_P_Feature_Event) {
Pawel Zarembski 0:01f31e923fe2 798 USBD_P_Feature_Event();
Pawel Zarembski 0:01f31e923fe2 799 }
Pawel Zarembski 0:01f31e923fe2 800
Pawel Zarembski 0:01f31e923fe2 801 #ifdef __RTX
Pawel Zarembski 0:01f31e923fe2 802 }
Pawel Zarembski 0:01f31e923fe2 803
Pawel Zarembski 0:01f31e923fe2 804 #endif
Pawel Zarembski 0:01f31e923fe2 805 break;
Pawel Zarembski 0:01f31e923fe2 806
Pawel Zarembski 0:01f31e923fe2 807 case USB_REQUEST_SET_ADDRESS:
Pawel Zarembski 0:01f31e923fe2 808 if (!USBD_ReqSetAddress()) {
Pawel Zarembski 0:01f31e923fe2 809 goto stall;
Pawel Zarembski 0:01f31e923fe2 810 }
Pawel Zarembski 0:01f31e923fe2 811
Pawel Zarembski 0:01f31e923fe2 812 USBD_SetAddress(USBD_DeviceAddress & 0x7F, 1);
Pawel Zarembski 0:01f31e923fe2 813 USBD_StatusInStage();
Pawel Zarembski 0:01f31e923fe2 814 break;
Pawel Zarembski 0:01f31e923fe2 815
Pawel Zarembski 0:01f31e923fe2 816 case USB_REQUEST_GET_DESCRIPTOR:
Pawel Zarembski 0:01f31e923fe2 817 if (!USBD_ReqGetDescriptor()) {
Pawel Zarembski 0:01f31e923fe2 818 goto stall;
Pawel Zarembski 0:01f31e923fe2 819 }
Pawel Zarembski 0:01f31e923fe2 820
Pawel Zarembski 0:01f31e923fe2 821 USBD_DataInStage();
Pawel Zarembski 0:01f31e923fe2 822 break;
Pawel Zarembski 0:01f31e923fe2 823
Pawel Zarembski 0:01f31e923fe2 824 case USB_REQUEST_SET_DESCRIPTOR:
Pawel Zarembski 0:01f31e923fe2 825 goto stall;
Pawel Zarembski 0:01f31e923fe2 826
Pawel Zarembski 0:01f31e923fe2 827 case USB_REQUEST_GET_CONFIGURATION:
Pawel Zarembski 0:01f31e923fe2 828 if (!USBD_ReqGetConfiguration()) {
Pawel Zarembski 0:01f31e923fe2 829 goto stall;
Pawel Zarembski 0:01f31e923fe2 830 }
Pawel Zarembski 0:01f31e923fe2 831
Pawel Zarembski 0:01f31e923fe2 832 USBD_DataInStage();
Pawel Zarembski 0:01f31e923fe2 833 break;
Pawel Zarembski 0:01f31e923fe2 834
Pawel Zarembski 0:01f31e923fe2 835 case USB_REQUEST_SET_CONFIGURATION:
Pawel Zarembski 0:01f31e923fe2 836 if (!USBD_ReqSetConfiguration()) {
Pawel Zarembski 0:01f31e923fe2 837 goto stall;
Pawel Zarembski 0:01f31e923fe2 838 }
Pawel Zarembski 0:01f31e923fe2 839
Pawel Zarembski 0:01f31e923fe2 840 USBD_StatusInStage();
Pawel Zarembski 0:01f31e923fe2 841 #ifdef __RTX
Pawel Zarembski 0:01f31e923fe2 842
Pawel Zarembski 0:01f31e923fe2 843 if (__rtx) {
Pawel Zarembski 0:01f31e923fe2 844 if (USBD_RTX_CoreTask) {
Pawel Zarembski 0:01f31e923fe2 845 usbd_os_evt_set(USBD_EVT_SET_CFG, USBD_RTX_CoreTask);
Pawel Zarembski 0:01f31e923fe2 846 }
Pawel Zarembski 0:01f31e923fe2 847 } else {
Pawel Zarembski 0:01f31e923fe2 848 #endif
Pawel Zarembski 0:01f31e923fe2 849
Pawel Zarembski 0:01f31e923fe2 850 if (USBD_P_Configure_Event) {
Pawel Zarembski 0:01f31e923fe2 851 USBD_P_Configure_Event();
Pawel Zarembski 0:01f31e923fe2 852 }
Pawel Zarembski 0:01f31e923fe2 853
Pawel Zarembski 0:01f31e923fe2 854 #ifdef __RTX
Pawel Zarembski 0:01f31e923fe2 855 }
Pawel Zarembski 0:01f31e923fe2 856
Pawel Zarembski 0:01f31e923fe2 857 #endif
Pawel Zarembski 0:01f31e923fe2 858 break;
Pawel Zarembski 0:01f31e923fe2 859
Pawel Zarembski 0:01f31e923fe2 860 case USB_REQUEST_GET_INTERFACE:
Pawel Zarembski 0:01f31e923fe2 861 if (!USBD_ReqGetInterface()) {
Pawel Zarembski 0:01f31e923fe2 862 goto stall;
Pawel Zarembski 0:01f31e923fe2 863 }
Pawel Zarembski 0:01f31e923fe2 864
Pawel Zarembski 0:01f31e923fe2 865 USBD_DataInStage();
Pawel Zarembski 0:01f31e923fe2 866 break;
Pawel Zarembski 0:01f31e923fe2 867
Pawel Zarembski 0:01f31e923fe2 868 case USB_REQUEST_SET_INTERFACE:
Pawel Zarembski 0:01f31e923fe2 869 if (!USBD_ReqSetInterface()) {
Pawel Zarembski 0:01f31e923fe2 870 goto stall;
Pawel Zarembski 0:01f31e923fe2 871 }
Pawel Zarembski 0:01f31e923fe2 872
Pawel Zarembski 0:01f31e923fe2 873 USBD_StatusInStage();
Pawel Zarembski 0:01f31e923fe2 874 #ifdef __RTX
Pawel Zarembski 0:01f31e923fe2 875
Pawel Zarembski 0:01f31e923fe2 876 if (__rtx) {
Pawel Zarembski 0:01f31e923fe2 877 if (USBD_RTX_CoreTask) {
Pawel Zarembski 0:01f31e923fe2 878 usbd_os_evt_set(USBD_EVT_SET_IF, USBD_RTX_CoreTask);
Pawel Zarembski 0:01f31e923fe2 879 }
Pawel Zarembski 0:01f31e923fe2 880 } else {
Pawel Zarembski 0:01f31e923fe2 881 #endif
Pawel Zarembski 0:01f31e923fe2 882
Pawel Zarembski 0:01f31e923fe2 883 if (USBD_P_Interface_Event) {
Pawel Zarembski 0:01f31e923fe2 884 USBD_P_Interface_Event();
Pawel Zarembski 0:01f31e923fe2 885 }
Pawel Zarembski 0:01f31e923fe2 886
Pawel Zarembski 0:01f31e923fe2 887 #ifdef __RTX
Pawel Zarembski 0:01f31e923fe2 888 }
Pawel Zarembski 0:01f31e923fe2 889
Pawel Zarembski 0:01f31e923fe2 890 #endif
Pawel Zarembski 0:01f31e923fe2 891 break;
Pawel Zarembski 0:01f31e923fe2 892
Pawel Zarembski 0:01f31e923fe2 893 default:
Pawel Zarembski 0:01f31e923fe2 894 goto stall;
Pawel Zarembski 0:01f31e923fe2 895 }
Pawel Zarembski 0:01f31e923fe2 896
Pawel Zarembski 0:01f31e923fe2 897 break; /* end case REQUEST_STANDARD */
Pawel Zarembski 0:01f31e923fe2 898
Pawel Zarembski 0:01f31e923fe2 899 case REQUEST_CLASS:
Pawel Zarembski 0:01f31e923fe2 900 switch (USBD_SetupPacket.bmRequestType.Recipient) {
Pawel Zarembski 0:01f31e923fe2 901 case REQUEST_TO_DEVICE:
Pawel Zarembski 0:01f31e923fe2 902 goto stall; /* not supported */
Pawel Zarembski 0:01f31e923fe2 903
Pawel Zarembski 0:01f31e923fe2 904 case REQUEST_TO_INTERFACE:
Pawel Zarembski 0:01f31e923fe2 905 if (USBD_EndPoint0_Setup_HID_ReqToIF()) {
Pawel Zarembski 0:01f31e923fe2 906 goto setup_class_ok;
Pawel Zarembski 0:01f31e923fe2 907 }
Pawel Zarembski 0:01f31e923fe2 908
Pawel Zarembski 0:01f31e923fe2 909 if (USBD_EndPoint0_Setup_MSC_ReqToIF()) {
Pawel Zarembski 0:01f31e923fe2 910 goto setup_class_ok;
Pawel Zarembski 0:01f31e923fe2 911 }
Pawel Zarembski 0:01f31e923fe2 912
Pawel Zarembski 0:01f31e923fe2 913 if (USBD_EndPoint0_Setup_CDC_ReqToIF()) {
Pawel Zarembski 0:01f31e923fe2 914 goto setup_class_ok;
Pawel Zarembski 0:01f31e923fe2 915 }
Pawel Zarembski 0:01f31e923fe2 916
Pawel Zarembski 0:01f31e923fe2 917 goto stall; /* not supported */
Pawel Zarembski 0:01f31e923fe2 918
Pawel Zarembski 0:01f31e923fe2 919 /* end case REQUEST_TO_INTERFACE */
Pawel Zarembski 0:01f31e923fe2 920
Pawel Zarembski 0:01f31e923fe2 921 case REQUEST_TO_ENDPOINT:
Pawel Zarembski 0:01f31e923fe2 922 goto stall;
Pawel Zarembski 0:01f31e923fe2 923
Pawel Zarembski 0:01f31e923fe2 924 /* end case REQUEST_TO_ENDPOINT */
Pawel Zarembski 0:01f31e923fe2 925
Pawel Zarembski 0:01f31e923fe2 926 default:
Pawel Zarembski 0:01f31e923fe2 927 goto stall;
Pawel Zarembski 0:01f31e923fe2 928 }
Pawel Zarembski 0:01f31e923fe2 929
Pawel Zarembski 0:01f31e923fe2 930 setup_class_ok: /* request finished successfully */
Pawel Zarembski 0:01f31e923fe2 931 break; /* end case REQUEST_CLASS */
Pawel Zarembski 0:01f31e923fe2 932
Pawel Zarembski 0:01f31e923fe2 933 case REQUEST_VENDOR:
Pawel Zarembski 0:01f31e923fe2 934 switch (USBD_SetupPacket.bmRequestType.Recipient) {
Pawel Zarembski 0:01f31e923fe2 935 case REQUEST_TO_DEVICE:
Pawel Zarembski 0:01f31e923fe2 936 if (USBD_EndPoint0_Setup_WebUSB_ReqToDevice()) {
Pawel Zarembski 0:01f31e923fe2 937 goto setup_vendor_ok;
Pawel Zarembski 0:01f31e923fe2 938 }
Pawel Zarembski 0:01f31e923fe2 939
Pawel Zarembski 0:01f31e923fe2 940 if (USBD_EndPoint0_Setup_WinUSB_ReqToDevice()) {
Pawel Zarembski 0:01f31e923fe2 941 goto setup_vendor_ok;
Pawel Zarembski 0:01f31e923fe2 942 }
Pawel Zarembski 0:01f31e923fe2 943
Pawel Zarembski 0:01f31e923fe2 944 goto stall;
Pawel Zarembski 0:01f31e923fe2 945
Pawel Zarembski 0:01f31e923fe2 946 default:
Pawel Zarembski 0:01f31e923fe2 947 goto stall;
Pawel Zarembski 0:01f31e923fe2 948 }
Pawel Zarembski 0:01f31e923fe2 949 setup_vendor_ok:
Pawel Zarembski 0:01f31e923fe2 950 break; /* end case REQUEST_VENDOR */
Pawel Zarembski 0:01f31e923fe2 951
Pawel Zarembski 0:01f31e923fe2 952 default:
Pawel Zarembski 0:01f31e923fe2 953 stall:
Pawel Zarembski 0:01f31e923fe2 954 if ((USBD_SetupPacket.bmRequestType.Dir == REQUEST_HOST_TO_DEVICE) &&
Pawel Zarembski 0:01f31e923fe2 955 (USBD_SetupPacket.wLength != 0)) {
Pawel Zarembski 0:01f31e923fe2 956 USBD_SetStallEP(0x00);
Pawel Zarembski 0:01f31e923fe2 957 } else {
Pawel Zarembski 0:01f31e923fe2 958 USBD_SetStallEP(0x80);
Pawel Zarembski 0:01f31e923fe2 959 }
Pawel Zarembski 0:01f31e923fe2 960
Pawel Zarembski 0:01f31e923fe2 961 USBD_EP0Data.Count = 0;
Pawel Zarembski 0:01f31e923fe2 962 break;
Pawel Zarembski 0:01f31e923fe2 963 }
Pawel Zarembski 0:01f31e923fe2 964 }
Pawel Zarembski 0:01f31e923fe2 965
Pawel Zarembski 0:01f31e923fe2 966 if (event & USBD_EVT_OUT) {
Pawel Zarembski 0:01f31e923fe2 967 if (USBD_SetupPacket.bmRequestType.Dir == REQUEST_HOST_TO_DEVICE) {
Pawel Zarembski 0:01f31e923fe2 968 if (USBD_EP0Data.Count) { /* still data to receive ? */
Pawel Zarembski 0:01f31e923fe2 969 USBD_DataOutStage(); /* receive data */
Pawel Zarembski 0:01f31e923fe2 970
Pawel Zarembski 0:01f31e923fe2 971 if (USBD_EP0Data.Count == 0) { /* data complete ? */
Pawel Zarembski 0:01f31e923fe2 972 switch (USBD_SetupPacket.bmRequestType.Type) {
Pawel Zarembski 0:01f31e923fe2 973 case REQUEST_STANDARD:
Pawel Zarembski 0:01f31e923fe2 974 goto stall_i; /* not supported */
Pawel Zarembski 0:01f31e923fe2 975
Pawel Zarembski 0:01f31e923fe2 976 case REQUEST_CLASS:
Pawel Zarembski 0:01f31e923fe2 977 switch (USBD_SetupPacket.bmRequestType.Recipient) {
Pawel Zarembski 0:01f31e923fe2 978 case REQUEST_TO_DEVICE:
Pawel Zarembski 0:01f31e923fe2 979 goto stall_i; /* not supported */
Pawel Zarembski 0:01f31e923fe2 980
Pawel Zarembski 0:01f31e923fe2 981 case REQUEST_TO_INTERFACE:
Pawel Zarembski 0:01f31e923fe2 982 if (USBD_EndPoint0_Out_HID_ReqToIF()) {
Pawel Zarembski 0:01f31e923fe2 983 goto out_class_ok;
Pawel Zarembski 0:01f31e923fe2 984 }
Pawel Zarembski 0:01f31e923fe2 985
Pawel Zarembski 0:01f31e923fe2 986 if (USBD_EndPoint0_Out_CDC_ReqToIF()) {
Pawel Zarembski 0:01f31e923fe2 987 goto out_class_ok;
Pawel Zarembski 0:01f31e923fe2 988 }
Pawel Zarembski 0:01f31e923fe2 989
Pawel Zarembski 0:01f31e923fe2 990 goto stall_i;
Pawel Zarembski 0:01f31e923fe2 991
Pawel Zarembski 0:01f31e923fe2 992 /* end case REQUEST_TO_INTERFACE */
Pawel Zarembski 0:01f31e923fe2 993
Pawel Zarembski 0:01f31e923fe2 994 case REQUEST_TO_ENDPOINT:
Pawel Zarembski 0:01f31e923fe2 995 goto stall_i;
Pawel Zarembski 0:01f31e923fe2 996
Pawel Zarembski 0:01f31e923fe2 997 /* end case REQUEST_TO_ENDPOINT */
Pawel Zarembski 0:01f31e923fe2 998
Pawel Zarembski 0:01f31e923fe2 999 default:
Pawel Zarembski 0:01f31e923fe2 1000 goto stall_i;
Pawel Zarembski 0:01f31e923fe2 1001 }
Pawel Zarembski 0:01f31e923fe2 1002
Pawel Zarembski 0:01f31e923fe2 1003 out_class_ok: /* request finished successfully */
Pawel Zarembski 0:01f31e923fe2 1004 break; /* end case REQUEST_CLASS */
Pawel Zarembski 0:01f31e923fe2 1005
Pawel Zarembski 0:01f31e923fe2 1006 default:
Pawel Zarembski 0:01f31e923fe2 1007 stall_i:
Pawel Zarembski 0:01f31e923fe2 1008 USBD_SetStallEP(0x80);
Pawel Zarembski 0:01f31e923fe2 1009 USBD_EP0Data.Count = 0;
Pawel Zarembski 0:01f31e923fe2 1010 break;
Pawel Zarembski 0:01f31e923fe2 1011 }
Pawel Zarembski 0:01f31e923fe2 1012 }
Pawel Zarembski 0:01f31e923fe2 1013 }
Pawel Zarembski 0:01f31e923fe2 1014 } else {
Pawel Zarembski 0:01f31e923fe2 1015 USBD_StatusOutStage(); /* receive Acknowledge */
Pawel Zarembski 0:01f31e923fe2 1016 }
Pawel Zarembski 0:01f31e923fe2 1017 } /* end USBD_EVT_OUT */
Pawel Zarembski 0:01f31e923fe2 1018
Pawel Zarembski 0:01f31e923fe2 1019 if (event & USBD_EVT_IN) {
Pawel Zarembski 0:01f31e923fe2 1020 if (USBD_SetupPacket.bmRequestType.Dir == REQUEST_DEVICE_TO_HOST) {
Pawel Zarembski 0:01f31e923fe2 1021 if (USBD_EP0Data.Count || USBD_ZLP) {
Pawel Zarembski 0:01f31e923fe2 1022 USBD_DataInStage(); /* send data */
Pawel Zarembski 0:01f31e923fe2 1023 }
Pawel Zarembski 0:01f31e923fe2 1024 } else {
Pawel Zarembski 0:01f31e923fe2 1025 if (USBD_DeviceAddress & 0x80) {
Pawel Zarembski 0:01f31e923fe2 1026 USBD_DeviceAddress &= 0x7F;
Pawel Zarembski 0:01f31e923fe2 1027 USBD_SetAddress(USBD_DeviceAddress, 0);
Pawel Zarembski 0:01f31e923fe2 1028 }
Pawel Zarembski 0:01f31e923fe2 1029 }
Pawel Zarembski 0:01f31e923fe2 1030 } /* end USBD_EVT_IN */
Pawel Zarembski 0:01f31e923fe2 1031
Pawel Zarembski 0:01f31e923fe2 1032 if (event & USBD_EVT_OUT_STALL) {
Pawel Zarembski 0:01f31e923fe2 1033 USBD_ClrStallEP(0x00);
Pawel Zarembski 0:01f31e923fe2 1034 }
Pawel Zarembski 0:01f31e923fe2 1035
Pawel Zarembski 0:01f31e923fe2 1036 if (event & USBD_EVT_IN_STALL) {
Pawel Zarembski 0:01f31e923fe2 1037 USBD_ClrStallEP(0x80);
Pawel Zarembski 0:01f31e923fe2 1038 }
Pawel Zarembski 0:01f31e923fe2 1039 }
Pawel Zarembski 0:01f31e923fe2 1040
Pawel Zarembski 0:01f31e923fe2 1041
Pawel Zarembski 0:01f31e923fe2 1042 /*
Pawel Zarembski 0:01f31e923fe2 1043 * USB Device Endpoint 0 RTX Task
Pawel Zarembski 0:01f31e923fe2 1044 * Parameters: none
Pawel Zarembski 0:01f31e923fe2 1045 * Return Value: none
Pawel Zarembski 0:01f31e923fe2 1046 */
Pawel Zarembski 0:01f31e923fe2 1047
Pawel Zarembski 0:01f31e923fe2 1048 #ifdef __RTX
Pawel Zarembski 0:01f31e923fe2 1049 void USBD_RTX_EndPoint0(void)
Pawel Zarembski 0:01f31e923fe2 1050 {
Pawel Zarembski 0:01f31e923fe2 1051 for (;;) {
Pawel Zarembski 0:01f31e923fe2 1052 usbd_os_evt_wait_or(0xFFFF, 0xFFFF);
Pawel Zarembski 0:01f31e923fe2 1053 USBD_EndPoint0(usbd_os_evt_get());
Pawel Zarembski 0:01f31e923fe2 1054 }
Pawel Zarembski 0:01f31e923fe2 1055 }
Pawel Zarembski 0:01f31e923fe2 1056 #endif