Il y avait des problèmes dans la libraire...

Fork of USBDEVICE by ST

Committer:
qroche
Date:
Sun Sep 03 23:19:21 2017 +0000
Branch:
master
Revision:
5:3329e56e51d7
Parent:
1:2a3ae13b45ef
fin;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 1 /* Copyright (c) 2010-2011 mbed.org, MIT License
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 2 *
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 4 * and associated documentation files (the "Software"), to deal in the Software without
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 5 * restriction, including without limitation the rights to use, copy, modify, merge, publish,
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 6 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 7 * Software is furnished to do so, subject to the following conditions:
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 8 *
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 9 * The above copyright notice and this permission notice shall be included in all copies or
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 10 * substantial portions of the Software.
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 11 *
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 17 */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 18
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 19 #include "stdint.h"
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 20
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 21 #include "USBEndpoints.h"
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 22 #include "USBDevice.h"
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 23 #include "USBDescriptor.h"
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 24
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 25 //#define DEBUG
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 26
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 27 /* Device status */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 28 #define DEVICE_STATUS_SELF_POWERED (1U<<0)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 29 #define DEVICE_STATUS_REMOTE_WAKEUP (1U<<1)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 30
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 31 /* Endpoint status */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 32 #define ENDPOINT_STATUS_HALT (1U<<0)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 33
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 34 /* Standard feature selectors */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 35 #define DEVICE_REMOTE_WAKEUP (1)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 36 #define ENDPOINT_HALT (0)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 37
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 38 /* Macro to convert wIndex endpoint number to physical endpoint number */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 39 #define WINDEX_TO_PHYSICAL(endpoint) (((endpoint & 0x0f) << 1) + \
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 40 ((endpoint & 0x80) ? 1 : 0))
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 41
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 42
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 43 bool USBDevice::requestGetDescriptor(void)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 44 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 45 bool success = false;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 46 #ifdef DEBUG
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 47 printf("get descr: type: %d\r\n", DESCRIPTOR_TYPE(transfer.setup.wValue));
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 48 #endif
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 49 switch (DESCRIPTOR_TYPE(transfer.setup.wValue))
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 50 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 51 case DEVICE_DESCRIPTOR:
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 52 if (deviceDesc() != NULL)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 53 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 54 if ((deviceDesc()[0] == DEVICE_DESCRIPTOR_LENGTH) \
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 55 && (deviceDesc()[1] == DEVICE_DESCRIPTOR))
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 56 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 57 #ifdef DEBUG
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 58 printf("device descr\r\n");
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 59 #endif
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 60 transfer.remaining = DEVICE_DESCRIPTOR_LENGTH;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 61 transfer.ptr = deviceDesc();
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 62 transfer.direction = DEVICE_TO_HOST;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 63 success = true;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 64 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 65 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 66 break;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 67 case CONFIGURATION_DESCRIPTOR:
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 68 if (configurationDesc() != NULL)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 69 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 70 if ((configurationDesc()[0] == CONFIGURATION_DESCRIPTOR_LENGTH) \
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 71 && (configurationDesc()[1] == CONFIGURATION_DESCRIPTOR))
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 72 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 73 #ifdef DEBUG
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 74 printf("conf descr request\r\n");
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 75 #endif
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 76 /* Get wTotalLength */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 77 transfer.remaining = configurationDesc()[2] \
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 78 | (configurationDesc()[3] << 8);
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 79
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 80 transfer.ptr = configurationDesc();
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 81 transfer.direction = DEVICE_TO_HOST;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 82 success = true;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 83 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 84 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 85 break;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 86 case STRING_DESCRIPTOR:
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 87 #ifdef DEBUG
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 88 printf("str descriptor\r\n");
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 89 #endif
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 90 switch (DESCRIPTOR_INDEX(transfer.setup.wValue))
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 91 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 92 case STRING_OFFSET_LANGID:
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 93 #ifdef DEBUG
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 94 printf("1\r\n");
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 95 #endif
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 96 transfer.remaining = stringLangidDesc()[0];
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 97 transfer.ptr = stringLangidDesc();
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 98 transfer.direction = DEVICE_TO_HOST;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 99 success = true;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 100 break;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 101 case STRING_OFFSET_IMANUFACTURER:
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 102 #ifdef DEBUG
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 103 printf("2\r\n");
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 104 #endif
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 105 transfer.remaining = stringImanufacturerDesc()[0];
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 106 transfer.ptr = stringImanufacturerDesc();
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 107 transfer.direction = DEVICE_TO_HOST;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 108 success = true;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 109 break;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 110 case STRING_OFFSET_IPRODUCT:
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 111 #ifdef DEBUG
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 112 printf("3\r\n");
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 113 #endif
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 114 transfer.remaining = stringIproductDesc()[0];
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 115 transfer.ptr = stringIproductDesc();
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 116 transfer.direction = DEVICE_TO_HOST;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 117 success = true;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 118 break;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 119 case STRING_OFFSET_ISERIAL:
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 120 #ifdef DEBUG
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 121 printf("4\r\n");
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 122 #endif
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 123 transfer.remaining = stringIserialDesc()[0];
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 124 transfer.ptr = stringIserialDesc();
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 125 transfer.direction = DEVICE_TO_HOST;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 126 success = true;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 127 break;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 128 case STRING_OFFSET_ICONFIGURATION:
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 129 #ifdef DEBUG
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 130 printf("5\r\n");
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 131 #endif
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 132 transfer.remaining = stringIConfigurationDesc()[0];
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 133 transfer.ptr = stringIConfigurationDesc();
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 134 transfer.direction = DEVICE_TO_HOST;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 135 success = true;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 136 break;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 137 case STRING_OFFSET_IINTERFACE:
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 138 #ifdef DEBUG
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 139 printf("6\r\n");
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 140 #endif
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 141 transfer.remaining = stringIinterfaceDesc()[0];
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 142 transfer.ptr = stringIinterfaceDesc();
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 143 transfer.direction = DEVICE_TO_HOST;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 144 success = true;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 145 break;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 146 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 147 break;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 148 case INTERFACE_DESCRIPTOR:
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 149 #ifdef DEBUG
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 150 printf("interface descr\r\n");
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 151 #endif
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 152 case ENDPOINT_DESCRIPTOR:
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 153 #ifdef DEBUG
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 154 printf("endpoint descr\r\n");
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 155 #endif
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 156 /* TODO: Support is optional, not implemented here */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 157 break;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 158 default:
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 159 #ifdef DEBUG
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 160 printf("ERROR\r\n");
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 161 #endif
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 162 break;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 163 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 164
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 165 return success;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 166 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 167
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 168 void USBDevice::decodeSetupPacket(uint8_t *data, SETUP_PACKET *packet)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 169 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 170 /* Fill in the elements of a SETUP_PACKET structure from raw data */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 171 packet->bmRequestType.dataTransferDirection = (data[0] & 0x80) >> 7;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 172 packet->bmRequestType.Type = (data[0] & 0x60) >> 5;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 173 packet->bmRequestType.Recipient = data[0] & 0x1f;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 174 packet->bRequest = data[1];
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 175 packet->wValue = (data[2] | (uint16_t)data[3] << 8);
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 176 packet->wIndex = (data[4] | (uint16_t)data[5] << 8);
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 177 packet->wLength = (data[6] | (uint16_t)data[7] << 8);
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 178 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 179
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 180
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 181 bool USBDevice::controlOut(void)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 182 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 183 /* Control transfer data OUT stage */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 184 uint8_t buffer[MAX_PACKET_SIZE_EP0];
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 185 uint32_t packetSize;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 186
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 187 /* Check we should be transferring data OUT */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 188 if (transfer.direction != HOST_TO_DEVICE)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 189 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 190 #if defined(TARGET_KL25Z) | defined(TARGET_KL43Z) | defined(TARGET_KL46Z) | defined(TARGET_K20D5M) | defined(TARGET_K64F) | defined(TARGET_K22F) | defined(TARGET_TEENSY3_1)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 191 /*
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 192 * We seem to have a pending device-to-host transfer. The host must have
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 193 * sent a new control request without waiting for us to finish processing
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 194 * the previous one. This appears to happen when we're connected to certain
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 195 * USB 3.0 host chip set. Do a zeor-length send to tell the host we're not
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 196 * ready for the new request - that'll make it resend - and then just
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 197 * pretend we were successful here so that the pending transfer can finish.
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 198 */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 199 uint8_t buf[1] = { 0 };
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 200 EP0write(buf, 0);
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 201
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 202 /* execute our pending ttransfer */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 203 controlIn();
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 204
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 205 /* indicate success */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 206 return true;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 207 #else
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 208 /* for other platforms, count on the HAL to handle this case */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 209 return false;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 210 #endif
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 211 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 212
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 213 /* Read from endpoint */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 214 packetSize = EP0getReadResult(buffer);
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 215
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 216 /* Check if transfer size is valid */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 217 if (packetSize > transfer.remaining)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 218 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 219 /* Too big */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 220 return false;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 221 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 222
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 223 /* Update transfer */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 224 transfer.ptr += packetSize;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 225 transfer.remaining -= packetSize;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 226
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 227 /* Check if transfer has completed */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 228 if (transfer.remaining == 0)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 229 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 230 /* Transfer completed */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 231 if (transfer.notify)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 232 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 233 /* Notify class layer. */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 234 USBCallback_requestCompleted(buffer, packetSize);
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 235 transfer.notify = false;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 236 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 237 /* Status stage */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 238 EP0write(NULL, 0);
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 239 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 240 else
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 241 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 242 EP0read();
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 243 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 244
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 245 return true;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 246 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 247
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 248 bool USBDevice::controlIn(void)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 249 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 250 /* Control transfer data IN stage */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 251 uint32_t packetSize;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 252
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 253 /* Check if transfer has completed (status stage transactions */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 254 /* also have transfer.remaining == 0) */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 255 if (transfer.remaining == 0)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 256 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 257 if (transfer.zlp)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 258 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 259 /* Send zero length packet */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 260 EP0write(NULL, 0);
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 261 transfer.zlp = false;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 262 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 263
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 264 /* Transfer completed */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 265 if (transfer.notify)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 266 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 267 /* Notify class layer. */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 268 USBCallback_requestCompleted(NULL, 0);
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 269 transfer.notify = false;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 270 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 271
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 272 EP0read();
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 273 EP0readStage();
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 274
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 275 /* Completed */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 276 return true;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 277 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 278
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 279 /* Check we should be transferring data IN */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 280 if (transfer.direction != DEVICE_TO_HOST)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 281 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 282 return false;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 283 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 284
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 285 packetSize = transfer.remaining;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 286
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 287 if (packetSize > MAX_PACKET_SIZE_EP0)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 288 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 289 packetSize = MAX_PACKET_SIZE_EP0;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 290 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 291
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 292 /* Write to endpoint */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 293 EP0write(transfer.ptr, packetSize);
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 294
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 295 /* Update transfer */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 296 transfer.ptr += packetSize;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 297 transfer.remaining -= packetSize;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 298
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 299 return true;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 300 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 301
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 302 bool USBDevice::requestSetAddress(void)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 303 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 304 /* Set the device address */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 305 setAddress(transfer.setup.wValue);
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 306
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 307 if (transfer.setup.wValue == 0)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 308 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 309 device.state = DEFAULT;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 310 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 311 else
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 312 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 313 device.state = ADDRESS;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 314 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 315
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 316 return true;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 317 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 318
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 319 bool USBDevice::requestSetConfiguration(void)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 320 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 321
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 322 device.configuration = transfer.setup.wValue;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 323 /* Set the device configuration */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 324 if (device.configuration == 0)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 325 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 326 /* Not configured */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 327 unconfigureDevice();
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 328 device.state = ADDRESS;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 329 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 330 else
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 331 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 332 if (USBCallback_setConfiguration(device.configuration))
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 333 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 334 /* Valid configuration */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 335 configureDevice();
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 336 device.state = CONFIGURED;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 337 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 338 else
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 339 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 340 return false;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 341 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 342 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 343
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 344 return true;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 345 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 346
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 347 bool USBDevice::requestGetConfiguration(void)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 348 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 349 /* Send the device configuration */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 350 transfer.ptr = &device.configuration;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 351 transfer.remaining = sizeof(device.configuration);
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 352 transfer.direction = DEVICE_TO_HOST;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 353 return true;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 354 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 355
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 356 bool USBDevice::requestGetInterface(void)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 357 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 358 /* Return the selected alternate setting for an interface */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 359
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 360 if (device.state != CONFIGURED)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 361 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 362 return false;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 363 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 364
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 365 /* Send the alternate setting */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 366 transfer.setup.wIndex = currentInterface;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 367 transfer.ptr = &currentAlternate;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 368 transfer.remaining = sizeof(currentAlternate);
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 369 transfer.direction = DEVICE_TO_HOST;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 370 return true;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 371 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 372
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 373 bool USBDevice::requestSetInterface(void)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 374 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 375 bool success = false;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 376 if(USBCallback_setInterface(transfer.setup.wIndex, transfer.setup.wValue))
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 377 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 378 success = true;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 379 currentInterface = transfer.setup.wIndex;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 380 currentAlternate = transfer.setup.wValue;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 381 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 382 return success;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 383 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 384
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 385 bool USBDevice::requestSetFeature()
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 386 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 387 bool success = false;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 388
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 389 if (device.state != CONFIGURED)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 390 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 391 /* Endpoint or interface must be zero */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 392 if (transfer.setup.wIndex != 0)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 393 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 394 return false;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 395 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 396 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 397
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 398 switch (transfer.setup.bmRequestType.Recipient)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 399 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 400 case DEVICE_RECIPIENT:
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 401 /* TODO: Remote wakeup feature not supported */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 402 break;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 403 case ENDPOINT_RECIPIENT:
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 404 if (transfer.setup.wValue == ENDPOINT_HALT)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 405 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 406 /* TODO: We should check that the endpoint number is valid */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 407 stallEndpoint(
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 408 WINDEX_TO_PHYSICAL(transfer.setup.wIndex));
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 409 success = true;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 410 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 411 break;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 412 default:
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 413 break;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 414 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 415
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 416 return success;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 417 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 418
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 419 bool USBDevice::requestClearFeature()
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 420 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 421 bool success = false;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 422
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 423 if (device.state != CONFIGURED)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 424 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 425 /* Endpoint or interface must be zero */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 426 if (transfer.setup.wIndex != 0)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 427 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 428 return false;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 429 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 430 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 431
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 432 switch (transfer.setup.bmRequestType.Recipient)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 433 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 434 case DEVICE_RECIPIENT:
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 435 /* TODO: Remote wakeup feature not supported */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 436 break;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 437 case ENDPOINT_RECIPIENT:
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 438 /* TODO: We should check that the endpoint number is valid */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 439 if (transfer.setup.wValue == ENDPOINT_HALT)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 440 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 441 unstallEndpoint( WINDEX_TO_PHYSICAL(transfer.setup.wIndex));
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 442 success = true;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 443 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 444 break;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 445 default:
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 446 break;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 447 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 448
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 449 return success;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 450 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 451
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 452 bool USBDevice::requestGetStatus(void)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 453 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 454 static uint16_t status;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 455 bool success = false;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 456
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 457 if (device.state != CONFIGURED)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 458 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 459 /* Endpoint or interface must be zero */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 460 if (transfer.setup.wIndex != 0)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 461 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 462 return false;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 463 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 464 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 465
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 466 switch (transfer.setup.bmRequestType.Recipient)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 467 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 468 case DEVICE_RECIPIENT:
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 469 /* TODO: Currently only supports self powered devices */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 470 status = DEVICE_STATUS_SELF_POWERED;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 471 success = true;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 472 break;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 473 case INTERFACE_RECIPIENT:
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 474 status = 0;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 475 success = true;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 476 break;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 477 case ENDPOINT_RECIPIENT:
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 478 /* TODO: We should check that the endpoint number is valid */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 479 if (getEndpointStallState(
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 480 WINDEX_TO_PHYSICAL(transfer.setup.wIndex)))
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 481 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 482 status = ENDPOINT_STATUS_HALT;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 483 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 484 else
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 485 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 486 status = 0;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 487 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 488 success = true;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 489 break;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 490 default:
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 491 break;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 492 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 493
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 494 if (success)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 495 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 496 /* Send the status */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 497 transfer.ptr = (uint8_t *)&status; /* Assumes little endian */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 498 transfer.remaining = sizeof(status);
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 499 transfer.direction = DEVICE_TO_HOST;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 500 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 501
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 502 return success;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 503 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 504
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 505 bool USBDevice::requestSetup(void)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 506 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 507 bool success = false;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 508
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 509 /* Process standard requests */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 510 if ((transfer.setup.bmRequestType.Type == STANDARD_TYPE))
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 511 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 512 switch (transfer.setup.bRequest)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 513 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 514 case GET_STATUS:
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 515 success = requestGetStatus();
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 516 break;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 517 case CLEAR_FEATURE:
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 518 success = requestClearFeature();
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 519 break;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 520 case SET_FEATURE:
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 521 success = requestSetFeature();
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 522 break;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 523 case SET_ADDRESS:
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 524 success = requestSetAddress();
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 525 break;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 526 case GET_DESCRIPTOR:
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 527 success = requestGetDescriptor();
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 528 break;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 529 case SET_DESCRIPTOR:
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 530 /* TODO: Support is optional, not implemented here */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 531 success = false;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 532 break;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 533 case GET_CONFIGURATION:
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 534 success = requestGetConfiguration();
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 535 break;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 536 case SET_CONFIGURATION:
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 537 success = requestSetConfiguration();
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 538 break;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 539 case GET_INTERFACE:
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 540 success = requestGetInterface();
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 541 break;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 542 case SET_INTERFACE:
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 543 success = requestSetInterface();
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 544 break;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 545 default:
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 546 break;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 547 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 548 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 549
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 550 return success;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 551 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 552
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 553 bool USBDevice::controlSetup(void)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 554 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 555 bool success = false;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 556
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 557 /* Control transfer setup stage */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 558 uint8_t buffer[MAX_PACKET_SIZE_EP0];
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 559
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 560 EP0setup(buffer);
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 561
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 562 /* Initialise control transfer state */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 563 decodeSetupPacket(buffer, &transfer.setup);
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 564 transfer.ptr = NULL;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 565 transfer.remaining = 0;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 566 transfer.direction = 0;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 567 transfer.zlp = false;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 568 transfer.notify = false;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 569
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 570 #ifdef DEBUG
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 571 printf("dataTransferDirection: %d\r\nType: %d\r\nRecipient: %d\r\nbRequest: %d\r\nwValue: %d\r\nwIndex: %d\r\nwLength: %d\r\n",transfer.setup.bmRequestType.dataTransferDirection,
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 572 transfer.setup.bmRequestType.Type,
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 573 transfer.setup.bmRequestType.Recipient,
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 574 transfer.setup.bRequest,
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 575 transfer.setup.wValue,
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 576 transfer.setup.wIndex,
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 577 transfer.setup.wLength);
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 578 #endif
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 579
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 580 /* Class / vendor specific */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 581 success = USBCallback_request();
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 582
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 583 if (!success)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 584 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 585 /* Standard requests */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 586 if (!requestSetup())
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 587 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 588 #ifdef DEBUG
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 589 printf("fail!!!!\r\n");
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 590 #endif
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 591 return false;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 592 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 593 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 594
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 595 /* Check transfer size and direction */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 596 if (transfer.setup.wLength>0)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 597 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 598 if (transfer.setup.bmRequestType.dataTransferDirection \
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 599 == DEVICE_TO_HOST)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 600 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 601 /* IN data stage is required */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 602 if (transfer.direction != DEVICE_TO_HOST)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 603 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 604 return false;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 605 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 606
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 607 /* Transfer must be less than or equal to the size */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 608 /* requested by the host */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 609 if (transfer.remaining > transfer.setup.wLength)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 610 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 611 transfer.remaining = transfer.setup.wLength;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 612 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 613 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 614 else
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 615 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 616
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 617 /* OUT data stage is required */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 618 if (transfer.direction != HOST_TO_DEVICE)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 619 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 620 return false;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 621 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 622
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 623 /* Transfer must be equal to the size requested by the host */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 624 if (transfer.remaining != transfer.setup.wLength)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 625 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 626 return false;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 627 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 628 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 629 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 630 else
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 631 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 632 /* No data stage; transfer size must be zero */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 633 if (transfer.remaining != 0)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 634 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 635 return false;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 636 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 637 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 638
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 639 /* Data or status stage if applicable */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 640 if (transfer.setup.wLength>0)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 641 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 642 if (transfer.setup.bmRequestType.dataTransferDirection \
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 643 == DEVICE_TO_HOST)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 644 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 645 /* Check if we'll need to send a zero length packet at */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 646 /* the end of this transfer */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 647 if (transfer.setup.wLength > transfer.remaining)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 648 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 649 /* Device wishes to transfer less than host requested */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 650 if ((transfer.remaining % MAX_PACKET_SIZE_EP0) == 0)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 651 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 652 /* Transfer is a multiple of EP0 max packet size */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 653 transfer.zlp = true;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 654 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 655 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 656
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 657 /* IN stage */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 658 controlIn();
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 659 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 660 else
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 661 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 662 /* OUT stage */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 663 EP0read();
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 664 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 665 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 666 else
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 667 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 668 /* Status stage */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 669 EP0write(NULL, 0);
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 670 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 671
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 672 return true;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 673 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 674
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 675 void USBDevice::busReset(void)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 676 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 677 device.state = DEFAULT;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 678 device.configuration = 0;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 679 device.suspended = false;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 680
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 681 /* Call class / vendor specific busReset function */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 682 USBCallback_busReset();
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 683 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 684
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 685 void USBDevice::EP0setupCallback(void)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 686 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 687 /* Endpoint 0 setup event */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 688 if (!controlSetup())
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 689 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 690 /* Protocol stall */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 691 EP0stall();
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 692 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 693
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 694 /* Return true if an OUT data stage is expected */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 695 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 696
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 697 void USBDevice::EP0out(void)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 698 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 699 /* Endpoint 0 OUT data event */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 700 if (!controlOut())
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 701 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 702 /* Protocol stall; this will stall both endpoints */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 703 EP0stall();
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 704 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 705 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 706
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 707 void USBDevice::EP0in(void)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 708 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 709 #ifdef DEBUG
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 710 printf("EP0IN\r\n");
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 711 #endif
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 712 /* Endpoint 0 IN data event */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 713 if (!controlIn())
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 714 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 715 /* Protocol stall; this will stall both endpoints */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 716 EP0stall();
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 717 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 718 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 719
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 720 bool USBDevice::configured(void)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 721 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 722 /* Returns true if device is in the CONFIGURED state */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 723 return (device.state == CONFIGURED);
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 724 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 725
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 726 void USBDevice::connect(bool blocking)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 727 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 728 /* Connect device */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 729 USBHAL::connect();
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 730
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 731 if (blocking) {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 732 /* Block if not configured */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 733 while (!configured());
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 734 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 735 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 736
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 737 void USBDevice::disconnect(void)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 738 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 739 /* Disconnect device */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 740 USBHAL::disconnect();
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 741
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 742 /* Set initial device state */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 743 device.state = POWERED;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 744 device.configuration = 0;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 745 device.suspended = false;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 746 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 747
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 748 CONTROL_TRANSFER * USBDevice::getTransferPtr(void)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 749 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 750 return &transfer;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 751 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 752
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 753 bool USBDevice::addEndpoint(uint8_t endpoint, uint32_t maxPacket)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 754 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 755 return realiseEndpoint(endpoint, maxPacket, 0);
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 756 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 757
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 758 bool USBDevice::addRateFeedbackEndpoint(uint8_t endpoint, uint32_t maxPacket)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 759 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 760 /* For interrupt endpoints only */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 761 return realiseEndpoint(endpoint, maxPacket, RATE_FEEDBACK_MODE);
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 762 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 763
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 764 uint8_t * USBDevice::findDescriptor(uint8_t descriptorType)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 765 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 766 /* Find a descriptor within the list of descriptors */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 767 /* following a configuration descriptor. */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 768 uint16_t wTotalLength;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 769 uint8_t *ptr;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 770
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 771 if (configurationDesc() == NULL)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 772 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 773 return NULL;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 774 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 775
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 776 /* Check this is a configuration descriptor */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 777 if ((configurationDesc()[0] != CONFIGURATION_DESCRIPTOR_LENGTH) \
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 778 || (configurationDesc()[1] != CONFIGURATION_DESCRIPTOR))
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 779 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 780 return NULL;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 781 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 782
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 783 wTotalLength = configurationDesc()[2] | (configurationDesc()[3] << 8);
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 784
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 785 /* Check there are some more descriptors to follow */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 786 if (wTotalLength <= (CONFIGURATION_DESCRIPTOR_LENGTH+2))
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 787 /* +2 is for bLength and bDescriptorType of next descriptor */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 788 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 789 return NULL;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 790 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 791
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 792 /* Start at first descriptor after the configuration descriptor */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 793 ptr = &(configurationDesc()[CONFIGURATION_DESCRIPTOR_LENGTH]);
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 794
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 795 do {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 796 if (ptr[1] /* bDescriptorType */ == descriptorType)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 797 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 798 /* Found */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 799 return ptr;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 800 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 801
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 802 /* Skip to next descriptor */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 803 ptr += ptr[0]; /* bLength */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 804 } while (ptr < (configurationDesc() + wTotalLength));
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 805
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 806 /* Reached end of the descriptors - not found */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 807 return NULL;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 808 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 809
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 810
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 811 void USBDevice::connectStateChanged(unsigned int connected)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 812 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 813 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 814
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 815 void USBDevice::suspendStateChanged(unsigned int suspended)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 816 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 817 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 818
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 819
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 820 USBDevice::USBDevice(uint16_t vendor_id, uint16_t product_id, uint16_t product_release){
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 821 VENDOR_ID = vendor_id;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 822 PRODUCT_ID = product_id;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 823 PRODUCT_RELEASE = product_release;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 824
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 825 /* Set initial device state */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 826 device.state = POWERED;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 827 device.configuration = 0;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 828 device.suspended = false;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 829 };
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 830
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 831
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 832 bool USBDevice::readStart(uint8_t endpoint, uint32_t maxSize)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 833 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 834 return endpointRead(endpoint, maxSize) == EP_PENDING;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 835 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 836
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 837
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 838 bool USBDevice::write(uint8_t endpoint, uint8_t * buffer, uint32_t size, uint32_t maxSize)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 839 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 840 EP_STATUS result;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 841
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 842 if (size > maxSize)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 843 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 844 return false;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 845 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 846
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 847
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 848 if(!configured()) {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 849 return false;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 850 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 851
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 852 /* Send report */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 853 result = endpointWrite(endpoint, buffer, size);
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 854
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 855 if (result != EP_PENDING)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 856 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 857 return false;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 858 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 859
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 860 /* Wait for completion */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 861 do {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 862 result = endpointWriteResult(endpoint);
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 863 } while ((result == EP_PENDING) && configured());
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 864
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 865 return (result == EP_COMPLETED);
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 866 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 867
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 868
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 869 bool USBDevice::writeNB(uint8_t endpoint, uint8_t * buffer, uint32_t size, uint32_t maxSize)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 870 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 871 EP_STATUS result;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 872
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 873 if (size > maxSize)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 874 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 875 return false;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 876 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 877
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 878 if(!configured()) {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 879 return false;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 880 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 881
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 882 /* Send report */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 883 result = endpointWrite(endpoint, buffer, size);
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 884
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 885 if (result != EP_PENDING)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 886 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 887 return false;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 888 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 889
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 890 result = endpointWriteResult(endpoint);
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 891
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 892 return (result == EP_COMPLETED);
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 893 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 894
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 895
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 896
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 897 bool USBDevice::readEP(uint8_t endpoint, uint8_t * buffer, uint32_t * size, uint32_t maxSize)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 898 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 899 EP_STATUS result;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 900
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 901 if(!configured()) {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 902 return false;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 903 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 904
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 905 /* Wait for completion */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 906 do {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 907 result = endpointReadResult(endpoint, buffer, size);
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 908 } while ((result == EP_PENDING) && configured());
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 909
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 910 return (result == EP_COMPLETED);
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 911 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 912
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 913
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 914 bool USBDevice::readEP_NB(uint8_t endpoint, uint8_t * buffer, uint32_t * size, uint32_t maxSize)
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 915 {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 916 EP_STATUS result;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 917
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 918 if(!configured()) {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 919 return false;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 920 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 921
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 922 result = endpointReadResult(endpoint, buffer, size);
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 923
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 924 return (result == EP_COMPLETED);
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 925 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 926
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 927
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 928
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 929 uint8_t * USBDevice::deviceDesc() {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 930 static uint8_t deviceDescriptor[] = {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 931 DEVICE_DESCRIPTOR_LENGTH, /* bLength */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 932 DEVICE_DESCRIPTOR, /* bDescriptorType */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 933 LSB(USB_VERSION_2_0), /* bcdUSB (LSB) */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 934 MSB(USB_VERSION_2_0), /* bcdUSB (MSB) */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 935 0x00, /* bDeviceClass */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 936 0x00, /* bDeviceSubClass */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 937 0x00, /* bDeviceprotocol */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 938 MAX_PACKET_SIZE_EP0, /* bMaxPacketSize0 */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 939 (uint8_t)(LSB(VENDOR_ID)), /* idVendor (LSB) */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 940 (uint8_t)(MSB(VENDOR_ID)), /* idVendor (MSB) */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 941 (uint8_t)(LSB(PRODUCT_ID)), /* idProduct (LSB) */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 942 (uint8_t)(MSB(PRODUCT_ID)), /* idProduct (MSB) */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 943 (uint8_t)(LSB(PRODUCT_RELEASE)), /* bcdDevice (LSB) */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 944 (uint8_t)(MSB(PRODUCT_RELEASE)), /* bcdDevice (MSB) */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 945 STRING_OFFSET_IMANUFACTURER, /* iManufacturer */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 946 STRING_OFFSET_IPRODUCT, /* iProduct */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 947 STRING_OFFSET_ISERIAL, /* iSerialNumber */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 948 0x01 /* bNumConfigurations */
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 949 };
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 950 return deviceDescriptor;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 951 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 952
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 953 uint8_t * USBDevice::stringLangidDesc() {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 954 static uint8_t stringLangidDescriptor[] = {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 955 0x04, /*bLength*/
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 956 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 957 0x09,0x04, /*bString Lang ID - 0x0409 - English*/
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 958 };
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 959 return stringLangidDescriptor;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 960 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 961
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 962 uint8_t * USBDevice::stringImanufacturerDesc() {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 963 static uint8_t stringImanufacturerDescriptor[] = {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 964 0x12, /*bLength*/
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 965 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 966 'm',0,'b',0,'e',0,'d',0,'.',0,'o',0,'r',0,'g',0, /*bString iManufacturer - mbed.org*/
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 967 };
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 968 return stringImanufacturerDescriptor;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 969 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 970
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 971 uint8_t * USBDevice::stringIserialDesc() {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 972 static uint8_t stringIserialDescriptor[] = {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 973 0x16, /*bLength*/
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 974 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 975 '0',0,'1',0,'2',0,'3',0,'4',0,'5',0,'6',0,'7',0,'8',0,'9',0, /*bString iSerial - 0123456789*/
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 976 };
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 977 return stringIserialDescriptor;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 978 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 979
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 980 uint8_t * USBDevice::stringIConfigurationDesc() {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 981 static uint8_t stringIconfigurationDescriptor[] = {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 982 0x06, /*bLength*/
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 983 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 984 '0',0,'1',0, /*bString iConfiguration - 01*/
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 985 };
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 986 return stringIconfigurationDescriptor;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 987 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 988
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 989 uint8_t * USBDevice::stringIinterfaceDesc() {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 990 static uint8_t stringIinterfaceDescriptor[] = {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 991 0x08, /*bLength*/
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 992 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 993 'U',0,'S',0,'B',0, /*bString iInterface - USB*/
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 994 };
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 995 return stringIinterfaceDescriptor;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 996 }
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 997
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 998 uint8_t * USBDevice::stringIproductDesc() {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 999 static uint8_t stringIproductDescriptor[] = {
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 1000 0x16, /*bLength*/
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 1001 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 1002 'U',0,'S',0,'B',0,' ',0,'D',0,'E',0,'V',0,'I',0,'C',0,'E',0 /*bString iProduct - USB DEVICE*/
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 1003 };
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 1004 return stringIproductDescriptor;
frq08711@LMECWL0871.LME.ST.COM 1:2a3ae13b45ef 1005 }