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