Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
USBDevice.cpp
00001 /* 00002 * Copyright (c) 2018-2019, Arm Limited and affiliates. 00003 * SPDX-License-Identifier: Apache-2.0 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); 00006 * you may not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 00018 #include <stdint.h> 00019 #include <string.h> 00020 00021 #include "USBDevice.h" 00022 #include "USBDescriptor.h" 00023 #include "usb_phy_api.h" 00024 #include "mbed_assert.h" 00025 #include "platform/mbed_error.h" 00026 00027 //#define DEBUG 00028 00029 /* Device status */ 00030 #define DEVICE_STATUS_SELF_POWERED (1U<<0) 00031 #define DEVICE_STATUS_REMOTE_WAKEUP (1U<<1) 00032 00033 /* Endpoint status */ 00034 #define ENDPOINT_STATUS_HALT (1U<<0) 00035 00036 /* Standard feature selectors */ 00037 #define DEVICE_REMOTE_WAKEUP (1) 00038 #define ENDPOINT_HALT (0) 00039 00040 /* Endpoint macros */ 00041 #define EP_INDEXABLE(endpoint) (EP_VALID(endpoint) && !EP_CONTROL(endpoint)) 00042 #define EP_TO_INDEX(endpoint) ((((endpoint & 0xf) << 1) | (endpoint & 0x80 ? 1 : 0)) - 2) 00043 #define INDEX_TO_EP(index) ((usb_ep_t)((((index) >> 1) | (index & 1 ? 0x80 : 0)) + 1)) 00044 #define EP_VALID(endpoint) (((endpoint) & ~0x8F) == 0) 00045 #define EP_CONTROL(endpoint) (((endpoint) & 0xF) == 0) 00046 #define EP_RX(endpoint) ((endpoint) & 0x80) 00047 00048 /* Other defines */ 00049 #define ENDPOINT_ENABLED (1 << 0) 00050 #define ENDPOINT_STALLED (1 << 1) 00051 00052 /* The maximum wMaxPacketSize for endpoint 0 */ 00053 #if defined(MAX_PACKET_SIZE_EP0) 00054 #undef MAX_PACKET_SIZE_EP0 00055 #endif 00056 #define MAX_PACKET_SIZE_EP0 64 00057 00058 #define USB_MIN(a, b) ((a) > (b) ? (b) : (a)) 00059 00060 00061 bool USBDevice::_request_get_descriptor() 00062 { 00063 assert_locked(); 00064 00065 bool success = false; 00066 #ifdef DEBUG 00067 printf("get descr: type: %d\r\n", DESCRIPTOR_TYPE(_transfer.setup.wValue)); 00068 #endif 00069 switch (DESCRIPTOR_TYPE(_transfer.setup.wValue)) { 00070 case DEVICE_DESCRIPTOR: { 00071 if (device_desc() != NULL) { 00072 if ((device_desc()[0] == DEVICE_DESCRIPTOR_LENGTH) \ 00073 && (device_desc()[1] == DEVICE_DESCRIPTOR)) { 00074 #ifdef DEBUG 00075 printf("device descr\r\n"); 00076 #endif 00077 _transfer.remaining = DEVICE_DESCRIPTOR_LENGTH; 00078 _transfer.ptr = (uint8_t *)device_desc(); 00079 _transfer.direction = Send; 00080 success = true; 00081 } 00082 } 00083 break; 00084 } 00085 case CONFIGURATION_DESCRIPTOR: { 00086 const uint8_t idx = DESCRIPTOR_INDEX(_transfer.setup.wValue); 00087 if (configuration_desc(idx) != NULL) { 00088 if ((configuration_desc(idx)[0] == CONFIGURATION_DESCRIPTOR_LENGTH) \ 00089 && (configuration_desc(idx)[1] == CONFIGURATION_DESCRIPTOR)) { 00090 #ifdef DEBUG 00091 printf("conf descr request\r\n"); 00092 #endif 00093 /* Get wTotalLength */ 00094 _transfer.remaining = configuration_desc(idx)[2] \ 00095 | (configuration_desc(idx)[3] << 8); 00096 00097 _transfer.ptr = (uint8_t *)configuration_desc(idx); 00098 _transfer.direction = Send; 00099 success = true; 00100 } 00101 } 00102 break; 00103 } 00104 case STRING_DESCRIPTOR: { 00105 #ifdef DEBUG 00106 printf("str descriptor\r\n"); 00107 #endif 00108 switch (DESCRIPTOR_INDEX(_transfer.setup.wValue)) { 00109 case STRING_OFFSET_LANGID: 00110 #ifdef DEBUG 00111 printf("1\r\n"); 00112 #endif 00113 _transfer.remaining = string_langid_desc()[0]; 00114 _transfer.ptr = (uint8_t *)string_langid_desc(); 00115 _transfer.direction = Send; 00116 success = true; 00117 break; 00118 case STRING_OFFSET_IMANUFACTURER: 00119 #ifdef DEBUG 00120 printf("2\r\n"); 00121 #endif 00122 _transfer.remaining = string_imanufacturer_desc()[0]; 00123 _transfer.ptr = (uint8_t *)string_imanufacturer_desc(); 00124 _transfer.direction = Send; 00125 success = true; 00126 break; 00127 case STRING_OFFSET_IPRODUCT: 00128 #ifdef DEBUG 00129 printf("3\r\n"); 00130 #endif 00131 _transfer.remaining = string_iproduct_desc()[0]; 00132 _transfer.ptr = (uint8_t *)string_iproduct_desc(); 00133 _transfer.direction = Send; 00134 success = true; 00135 break; 00136 case STRING_OFFSET_ISERIAL: 00137 #ifdef DEBUG 00138 printf("4\r\n"); 00139 #endif 00140 _transfer.remaining = string_iserial_desc()[0]; 00141 _transfer.ptr = (uint8_t *)string_iserial_desc(); 00142 _transfer.direction = Send; 00143 success = true; 00144 break; 00145 case STRING_OFFSET_ICONFIGURATION: 00146 #ifdef DEBUG 00147 printf("5\r\n"); 00148 #endif 00149 _transfer.remaining = string_iconfiguration_desc()[0]; 00150 _transfer.ptr = (uint8_t *)string_iconfiguration_desc(); 00151 _transfer.direction = Send; 00152 success = true; 00153 break; 00154 case STRING_OFFSET_IINTERFACE: 00155 #ifdef DEBUG 00156 printf("6\r\n"); 00157 #endif 00158 _transfer.remaining = string_iinterface_desc()[0]; 00159 _transfer.ptr = (uint8_t *)string_iinterface_desc(); 00160 _transfer.direction = Send; 00161 success = true; 00162 break; 00163 } 00164 break; 00165 } 00166 case INTERFACE_DESCRIPTOR: { 00167 #ifdef DEBUG 00168 printf("interface descr\r\n"); 00169 #endif 00170 break; 00171 } 00172 case ENDPOINT_DESCRIPTOR: { 00173 #ifdef DEBUG 00174 printf("endpoint descr\r\n"); 00175 #endif 00176 /* TODO: Support is optional, not implemented here */ 00177 break; 00178 } 00179 default: { 00180 #ifdef DEBUG 00181 printf("ERROR\r\n"); 00182 #endif 00183 break; 00184 } 00185 } 00186 00187 return success; 00188 } 00189 00190 void USBDevice::_decode_setup_packet(uint8_t *data, setup_packet_t *packet) 00191 { 00192 // No lock needed - stateless function 00193 00194 /* Fill in the elements of a setup_packet_t structure from raw data */ 00195 packet->bmRequestType.dataTransferDirection = (data[0] & 0x80) >> 7; 00196 packet->bmRequestType.Type = (data[0] & 0x60) >> 5; 00197 packet->bmRequestType.Recipient = data[0] & 0x1f; 00198 packet->bRequest = data[1]; 00199 packet->wValue = (data[2] | (uint16_t)data[3] << 8); 00200 packet->wIndex = (data[4] | (uint16_t)data[5] << 8); 00201 packet->wLength = (data[6] | (uint16_t)data[7] << 8); 00202 } 00203 00204 00205 bool USBDevice::_control_out() 00206 { 00207 assert_locked(); 00208 00209 /* Control transfer data OUT stage */ 00210 uint32_t packetSize; 00211 00212 /* Check we should be transferring data OUT */ 00213 if (_transfer.direction != Receive) { 00214 /* for other platforms, count on the HAL to handle this case */ 00215 return false; 00216 } 00217 00218 /* Read from endpoint */ 00219 packetSize = _phy->ep0_read_result(); 00220 00221 /* Check if transfer size is valid */ 00222 if (packetSize > _transfer.remaining) { 00223 /* Too big */ 00224 return false; 00225 } 00226 00227 /* Update transfer */ 00228 _transfer.ptr += packetSize; 00229 _transfer.remaining -= packetSize; 00230 00231 /* Check if transfer has completed */ 00232 if (_transfer.remaining == 0) { 00233 /* Transfer completed */ 00234 _transfer.user_callback = RequestXferDone; 00235 if (_transfer.notify) { 00236 /* Notify class layer. */ 00237 _transfer.notify = false; 00238 callback_request_xfer_done(&_transfer.setup, false); 00239 } else { 00240 complete_request_xfer_done(true); 00241 } 00242 } else { 00243 _phy->ep0_read(_transfer.ptr, USB_MIN(_transfer.remaining, _max_packet_size_ep0)); 00244 } 00245 00246 return true; 00247 } 00248 00249 bool USBDevice::_control_in() 00250 { 00251 assert_locked(); 00252 00253 /* Control transfer data IN stage */ 00254 uint32_t packetSize; 00255 00256 00257 /* Check we should be transferring data IN */ 00258 if (_transfer.direction != Send) { 00259 return false; 00260 } 00261 00262 if (_transfer.remaining == 0) { 00263 if (!_transfer.zlp) { 00264 /* Status as already been sent so ignore this IN. */ 00265 return true; 00266 } 00267 /* ZLP will be sent below */ 00268 _transfer.zlp = false; 00269 } 00270 00271 packetSize = _transfer.remaining; 00272 00273 if (packetSize > _max_packet_size_ep0) { 00274 packetSize = _max_packet_size_ep0; 00275 } 00276 00277 /* Write to endpoint */ 00278 _phy->ep0_write(_transfer.ptr, packetSize); 00279 00280 /* Update transfer */ 00281 _transfer.ptr += packetSize; 00282 _transfer.remaining -= packetSize; 00283 00284 /* Send status if all the data has been sent 00285 * NOTE - Start the status stage immediately 00286 * after writing the last packet. Do not wait 00287 * for the next IN event, as this can be dropped 00288 * if the ACK by the host is corrupted. 00289 * 00290 * For more info on this see section 00291 * 8.5.3.2 of the USB2.0 specification. 00292 */ 00293 if ((_transfer.remaining == 0) && !_transfer.zlp) { 00294 /* Transfer completed */ 00295 _transfer.user_callback = RequestXferDone; 00296 if (_transfer.notify) { 00297 /* Notify class layer. */ 00298 _transfer.notify = false; 00299 callback_request_xfer_done(&_transfer.setup, false); 00300 } else { 00301 complete_request_xfer_done(true); 00302 } 00303 00304 00305 /* Completed */ 00306 return true; 00307 } 00308 00309 00310 return true; 00311 } 00312 00313 void USBDevice::complete_request_xfer_done(bool success) 00314 { 00315 lock(); 00316 00317 MBED_ASSERT(_transfer.user_callback == RequestXferDone); 00318 _transfer.args.status = success; 00319 _run_later(&USBDevice::_complete_request_xfer_done); 00320 00321 unlock(); 00322 } 00323 00324 void USBDevice::_complete_request_xfer_done() 00325 { 00326 assert_locked(); 00327 00328 bool success = _transfer.args.status; 00329 00330 _transfer.user_callback = None; 00331 if (_abort_control) { 00332 _control_abort(); 00333 return; 00334 } 00335 00336 if (!success) { 00337 _phy->ep0_stall(); 00338 return; 00339 } 00340 00341 /* Status stage */ 00342 if (_transfer.stage == DataOut) { 00343 _transfer.stage = Status; 00344 _phy->ep0_write(NULL, 0); 00345 } else if (_transfer.stage == DataIn) { 00346 _transfer.stage = Status; 00347 _phy->ep0_read(NULL, 0); 00348 } 00349 } 00350 00351 bool USBDevice::_request_set_address() 00352 { 00353 assert_locked(); 00354 00355 /* Set the device address */ 00356 _phy->set_address(_transfer.setup.wValue); 00357 00358 if (_transfer.setup.wValue == 0) { 00359 _change_state(Default); 00360 } else { 00361 _change_state(Address); 00362 } 00363 00364 return true; 00365 } 00366 00367 bool USBDevice::_request_set_configuration() 00368 { 00369 assert_locked(); 00370 00371 _device.configuration = _transfer.setup.wValue; 00372 /* Set the device configuration */ 00373 if (_device.configuration == 0) { 00374 /* Not configured */ 00375 _phy->unconfigure(); 00376 _change_state(Address); 00377 } else { 00378 _endpoint_add_remove_allowed = true; 00379 _transfer.user_callback = SetConfiguration; 00380 callback_set_configuration(_device.configuration); 00381 } 00382 00383 return true; 00384 } 00385 00386 void USBDevice::complete_set_configuration(bool success) 00387 { 00388 lock(); 00389 00390 MBED_ASSERT(_transfer.user_callback == SetConfiguration); 00391 _transfer.args.status = success; 00392 _run_later(&USBDevice::_complete_set_configuration); 00393 00394 unlock(); 00395 } 00396 00397 void USBDevice::_complete_set_configuration() 00398 { 00399 assert_locked(); 00400 00401 bool success = _transfer.args.status; 00402 if ((_abort_control || !success) && !configured()) { 00403 // The set configuration request was aborted or failed so 00404 // reset any endpoints which may have been added. 00405 memset(_endpoint_info, 0, sizeof(_endpoint_info)); 00406 _device.configuration = 0; 00407 _endpoint_add_remove_allowed = false; 00408 } 00409 00410 00411 _transfer.user_callback = None; 00412 if (_abort_control) { 00413 _control_abort(); 00414 return; 00415 } 00416 00417 if (success) { 00418 /* Valid configuration */ 00419 _phy->configure(); 00420 _change_state(Configured); 00421 _control_setup_continue(); 00422 } else { 00423 _phy->ep0_stall(); 00424 return; 00425 } 00426 } 00427 00428 bool USBDevice::_request_get_configuration() 00429 { 00430 assert_locked(); 00431 00432 /* Send the device configuration */ 00433 _transfer.ptr = &_device.configuration; 00434 _transfer.remaining = sizeof(_device.configuration); 00435 _transfer.direction = Send; 00436 return true; 00437 } 00438 00439 bool USBDevice::_request_get_interface() 00440 { 00441 assert_locked(); 00442 00443 /* Return the selected alternate setting for an interface */ 00444 00445 if (_device.state != Configured) { 00446 return false; 00447 } 00448 00449 /* Send the alternate setting */ 00450 _transfer.setup.wIndex = _current_interface; 00451 _transfer.ptr = &_current_alternate; 00452 _transfer.remaining = sizeof(_current_alternate); 00453 _transfer.direction = Send; 00454 return true; 00455 } 00456 00457 bool USBDevice::_request_set_interface() 00458 { 00459 assert_locked(); 00460 00461 _transfer.user_callback = SetInterface; 00462 callback_set_interface(_transfer.setup.wIndex, _transfer.setup.wValue); 00463 return true; 00464 } 00465 00466 void USBDevice::complete_set_interface(bool success) 00467 { 00468 lock(); 00469 00470 MBED_ASSERT(_transfer.user_callback == SetInterface); 00471 _transfer.args.status = success; 00472 _run_later(&USBDevice::_complete_set_interface); 00473 00474 unlock(); 00475 } 00476 00477 void USBDevice::_complete_set_interface() 00478 { 00479 assert_locked(); 00480 00481 bool success = _transfer.args.status; 00482 00483 _transfer.user_callback = None; 00484 if (_abort_control) { 00485 _control_abort(); 00486 return; 00487 } 00488 00489 if (success) { 00490 _current_interface = _transfer.setup.wIndex; 00491 _current_alternate = _transfer.setup.wValue; 00492 _control_setup_continue(); 00493 } else { 00494 _phy->ep0_stall(); 00495 return; 00496 } 00497 } 00498 00499 bool USBDevice::_request_set_feature() 00500 { 00501 assert_locked(); 00502 bool success = false; 00503 00504 if (_device.state != Configured) { 00505 /* Endpoint or interface must be zero */ 00506 if (_transfer.setup.wIndex != 0) { 00507 return false; 00508 } 00509 } 00510 00511 switch (_transfer.setup.bmRequestType.Recipient) { 00512 case DEVICE_RECIPIENT: 00513 /* TODO: Remote wakeup feature not supported */ 00514 break; 00515 case ENDPOINT_RECIPIENT: 00516 if (!EP_INDEXABLE(_transfer.setup.wIndex)) { 00517 break; 00518 } else if (_transfer.setup.wValue == ENDPOINT_HALT) { 00519 endpoint_stall(_transfer.setup.wIndex); 00520 success = true; 00521 } 00522 break; 00523 default: 00524 break; 00525 } 00526 00527 return success; 00528 } 00529 00530 bool USBDevice::_request_clear_feature() 00531 { 00532 assert_locked(); 00533 00534 bool success = false; 00535 00536 if (_device.state != Configured) { 00537 /* Endpoint or interface must be zero */ 00538 if (_transfer.setup.wIndex != 0) { 00539 return false; 00540 } 00541 } 00542 00543 switch (_transfer.setup.bmRequestType.Recipient) { 00544 case DEVICE_RECIPIENT: 00545 /* TODO: Remote wakeup feature not supported */ 00546 break; 00547 case ENDPOINT_RECIPIENT: 00548 if (!EP_INDEXABLE(_transfer.setup.wIndex)) { 00549 break; 00550 } else if (_transfer.setup.wValue == ENDPOINT_HALT) { 00551 endpoint_unstall(_transfer.setup.wIndex); 00552 success = true; 00553 } 00554 break; 00555 default: 00556 break; 00557 } 00558 00559 return success; 00560 } 00561 00562 bool USBDevice::_request_get_status() 00563 { 00564 assert_locked(); 00565 00566 static uint16_t status; 00567 bool success = false; 00568 00569 if (_device.state != Configured) { 00570 /* Endpoint or interface must be zero */ 00571 if (_transfer.setup.wIndex != 0) { 00572 return false; 00573 } 00574 } 00575 00576 switch (_transfer.setup.bmRequestType.Recipient) { 00577 case DEVICE_RECIPIENT: 00578 /* TODO: Currently only supports self powered devices */ 00579 status = DEVICE_STATUS_SELF_POWERED; 00580 success = true; 00581 break; 00582 case INTERFACE_RECIPIENT: 00583 status = 0; 00584 success = true; 00585 break; 00586 case ENDPOINT_RECIPIENT: 00587 if (!EP_VALID(_transfer.setup.wIndex)) { 00588 break; 00589 } else if (EP_CONTROL(_transfer.setup.wIndex)) { 00590 /* Control endpoint can't be halted */ 00591 status = 0; 00592 } else if (_endpoint_info[EP_TO_INDEX(_transfer.setup.wIndex & 0xFF)].flags & ENDPOINT_STALLED) { 00593 status = ENDPOINT_STATUS_HALT; 00594 } else { 00595 status = 0; 00596 } 00597 success = true; 00598 break; 00599 default: 00600 break; 00601 } 00602 00603 if (success) { 00604 /* Send the status */ 00605 _transfer.ptr = (uint8_t *)&status; /* Assumes little endian */ 00606 _transfer.remaining = sizeof(status); 00607 _transfer.direction = Send; 00608 } 00609 00610 return success; 00611 } 00612 00613 bool USBDevice::_request_setup() 00614 { 00615 assert_locked(); 00616 00617 bool success = false; 00618 00619 /* Process standard requests */ 00620 if (_transfer.setup.bmRequestType.Type == STANDARD_TYPE) { 00621 switch (_transfer.setup.bRequest) { 00622 case GET_STATUS: 00623 success = _request_get_status(); 00624 break; 00625 case CLEAR_FEATURE: 00626 success = _request_clear_feature(); 00627 break; 00628 case SET_FEATURE: 00629 success = _request_set_feature(); 00630 break; 00631 case SET_ADDRESS: 00632 success = _request_set_address(); 00633 break; 00634 case GET_DESCRIPTOR: 00635 success = _request_get_descriptor(); 00636 break; 00637 case SET_DESCRIPTOR: 00638 /* TODO: Support is optional, not implemented here */ 00639 success = false; 00640 break; 00641 case GET_CONFIGURATION: 00642 success = _request_get_configuration(); 00643 break; 00644 case SET_CONFIGURATION: 00645 success = _request_set_configuration(); 00646 break; 00647 case GET_INTERFACE: 00648 success = _request_get_interface(); 00649 break; 00650 case SET_INTERFACE: 00651 success = _request_set_interface(); 00652 break; 00653 default: 00654 break; 00655 } 00656 } 00657 00658 return success; 00659 } 00660 00661 void USBDevice::_control_setup() 00662 { 00663 assert_locked(); 00664 00665 /* Control transfer setup stage */ 00666 uint8_t buffer[MAX_PACKET_SIZE_EP0]; 00667 00668 _phy->ep0_setup_read_result(buffer, _max_packet_size_ep0); 00669 00670 /* Initialise control transfer state */ 00671 _decode_setup_packet(buffer, &_transfer.setup); 00672 _transfer.ptr = NULL; 00673 _transfer.remaining = 0; 00674 _transfer.direction = 0; 00675 _transfer.zlp = false; 00676 _transfer.notify = false; 00677 _transfer.stage = Setup; 00678 _transfer.user_callback = Request; 00679 00680 #ifdef DEBUG 00681 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, 00682 _transfer.setup.bmRequestType.Type, 00683 _transfer.setup.bmRequestType.Recipient, 00684 _transfer.setup.bRequest, 00685 _transfer.setup.wValue, 00686 _transfer.setup.wIndex, 00687 _transfer.setup.wLength); 00688 #endif 00689 00690 /* Class / vendor specific */ 00691 callback_request(&_transfer.setup); 00692 } 00693 00694 void USBDevice::complete_request(RequestResult direction, uint8_t *data, uint32_t size) 00695 { 00696 lock(); 00697 00698 MBED_ASSERT(_transfer.user_callback == Request); 00699 _transfer.args.request.result = direction; 00700 _transfer.args.request.data = data; 00701 _transfer.args.request.size = size; 00702 _run_later(&USBDevice::_complete_request); 00703 00704 unlock(); 00705 } 00706 00707 void USBDevice::_complete_request() 00708 { 00709 assert_locked(); 00710 00711 RequestResult direction = _transfer.args.request.result; 00712 uint8_t *data = _transfer.args.request.data; 00713 uint32_t size = _transfer.args.request.size; 00714 00715 _transfer.user_callback = None; 00716 if (_abort_control) { 00717 if ((direction == Receive) || (direction == Send)) { 00718 _transfer.user_callback = RequestXferDone; 00719 callback_request_xfer_done(&_transfer.setup, true); 00720 } else { 00721 _control_abort(); 00722 } 00723 return; 00724 } 00725 00726 if (direction == PassThrough) { 00727 /* Standard requests */ 00728 if (!_request_setup()) { 00729 _phy->ep0_stall(); 00730 return; 00731 } 00732 00733 /* user_callback may be set by _request_setup() */ 00734 if (_transfer.user_callback == None) { 00735 _control_setup_continue(); 00736 } 00737 } else if (direction == Failure) { 00738 _phy->ep0_stall(); 00739 return; 00740 } else { 00741 _transfer.notify = true; 00742 _transfer.remaining = size; 00743 _transfer.ptr = data; 00744 _transfer.direction = direction; 00745 _control_setup_continue(); 00746 } 00747 } 00748 00749 void USBDevice::_control_abort_start() 00750 { 00751 assert_locked(); 00752 00753 _setup_ready = false; 00754 if (_transfer.user_callback == None) { 00755 _control_abort(); 00756 } else { 00757 _abort_control = true; 00758 } 00759 } 00760 00761 void USBDevice::_control_setup_continue() 00762 { 00763 assert_locked(); 00764 00765 /* Check transfer size and direction */ 00766 if (_transfer.setup.wLength > 0) { 00767 if (_transfer.setup.bmRequestType.dataTransferDirection \ 00768 == Send) { 00769 /* IN data stage is required */ 00770 if (_transfer.direction != Send) { 00771 _phy->ep0_stall(); 00772 return; 00773 } 00774 00775 /* Transfer must be less than or equal to the size */ 00776 /* requested by the host */ 00777 if (_transfer.remaining > _transfer.setup.wLength) { 00778 _transfer.remaining = _transfer.setup.wLength; 00779 } 00780 } else { 00781 00782 /* OUT data stage is required */ 00783 if (_transfer.direction != Receive) { 00784 _phy->ep0_stall(); 00785 return; 00786 } 00787 00788 /* Transfer must be equal to the size requested by the host */ 00789 if (_transfer.remaining != _transfer.setup.wLength) { 00790 _phy->ep0_stall(); 00791 return; 00792 } 00793 } 00794 } else { 00795 /* No data stage; transfer size must be zero */ 00796 if (_transfer.remaining != 0) { 00797 _phy->ep0_stall(); 00798 return; 00799 } 00800 } 00801 00802 /* Data or status stage if applicable */ 00803 if (_transfer.setup.wLength > 0) { 00804 if (_transfer.setup.bmRequestType.dataTransferDirection \ 00805 == Send) { 00806 /* Check if we'll need to send a zero length packet at */ 00807 /* the end of this transfer */ 00808 if (_transfer.setup.wLength > _transfer.remaining) { 00809 /* Device wishes to transfer less than host requested */ 00810 if ((_transfer.remaining % _max_packet_size_ep0) == 0) { 00811 /* Transfer is a multiple of EP0 max packet size */ 00812 _transfer.zlp = true; 00813 } 00814 } 00815 00816 /* IN stage */ 00817 _transfer.stage = DataIn; 00818 _control_in(); 00819 } else { 00820 /* OUT stage */ 00821 _transfer.stage = DataOut; 00822 _phy->ep0_read(_transfer.ptr, USB_MIN(_transfer.remaining, _max_packet_size_ep0)); 00823 } 00824 } else { 00825 /* Status stage */ 00826 _transfer.stage = Status; 00827 _phy->ep0_write(NULL, 0); 00828 } 00829 } 00830 00831 void USBDevice::_control_abort() 00832 { 00833 assert_locked(); 00834 00835 _abort_control = false; 00836 _transfer.stage = Status; 00837 } 00838 00839 void USBDevice::reset() 00840 { 00841 assert_locked(); 00842 00843 _change_state(Default); 00844 _device.suspended = false; 00845 _control_abort_start(); 00846 00847 /* Call class / vendor specific busReset function */ 00848 callback_reset(); 00849 } 00850 00851 void USBDevice::ep0_setup() 00852 { 00853 assert_locked(); 00854 00855 if (_device.state < Default) { 00856 #if MBED_TRAP_ERRORS_ENABLED 00857 MBED_ERROR( 00858 MBED_MAKE_ERROR( 00859 MBED_MODULE_DRIVER_USB, 00860 MBED_ERROR_CODE_NOT_READY 00861 ), 00862 "Device state is \"Powered\" or \"Detached\"" 00863 ); 00864 #else 00865 return; 00866 #endif // MBED_TRAP_ERRORS_ENABLED 00867 } 00868 00869 _setup_ready = true; 00870 00871 /* Endpoint 0 setup event */ 00872 if (_transfer.user_callback == None) { 00873 _control_setup(); 00874 } else { 00875 /* A new setup packet has arrived so abort the 00876 current control transfer */ 00877 _abort_control = true; 00878 } 00879 00880 } 00881 00882 void USBDevice::ep0_out() 00883 { 00884 assert_locked(); 00885 00886 if (_device.state < Default) { 00887 #if MBED_TRAP_ERRORS_ENABLED 00888 MBED_ERROR( 00889 MBED_MAKE_ERROR( 00890 MBED_MODULE_DRIVER_USB, 00891 MBED_ERROR_CODE_NOT_READY 00892 ), 00893 "Device state is \"Powered\" or \"Detached\"" 00894 ); 00895 #else 00896 return; 00897 #endif // MBED_TRAP_ERRORS_ENABLED 00898 } 00899 00900 if (_transfer.user_callback != None) { 00901 /* EP0 OUT should not receive data if the stack is waiting 00902 on a user callback for the buffer to fill or status */ 00903 #if MBED_TRAP_ERRORS_ENABLED 00904 MBED_ERROR( 00905 MBED_MAKE_ERROR( 00906 MBED_MODULE_DRIVER_USB, 00907 MBED_ERROR_CODE_NOT_READY 00908 ), 00909 "The stack is waiting on a user callback for the buffer to fill or status." 00910 ); 00911 #else 00912 return; 00913 #endif // MBED_TRAP_ERRORS_ENABLED 00914 } 00915 00916 if (_transfer.stage == Status) { 00917 // No action needed on status stage 00918 return; 00919 } 00920 00921 /* Endpoint 0 OUT data event */ 00922 if (!_control_out()) { 00923 /* Protocol stall; this will stall both endpoints */ 00924 _phy->ep0_stall(); 00925 return; 00926 } 00927 } 00928 00929 void USBDevice::ep0_in() 00930 { 00931 assert_locked(); 00932 00933 if (_device.state < Default) { 00934 #if MBED_TRAP_ERRORS_ENABLED 00935 MBED_ERROR( 00936 MBED_MAKE_ERROR( 00937 MBED_MODULE_DRIVER_USB, 00938 MBED_ERROR_CODE_NOT_READY 00939 ), 00940 "Device state is \"Powered\" or \"Detached\"" 00941 ); 00942 #else 00943 return; 00944 #endif // MBED_TRAP_ERRORS_ENABLED 00945 } 00946 00947 #ifdef DEBUG 00948 printf("ep0_in\r\n"); 00949 #endif 00950 if (_transfer.stage == Status) { 00951 // No action needed on status stage 00952 return; 00953 } 00954 00955 /* Endpoint 0 IN data event */ 00956 if (!_control_in()) { 00957 /* Protocol stall; this will stall both endpoints */ 00958 _phy->ep0_stall(); 00959 return; 00960 } 00961 } 00962 00963 void USBDevice::out(usb_ep_t endpoint) 00964 { 00965 assert_locked(); 00966 00967 if (!EP_INDEXABLE(endpoint)) { 00968 #if MBED_TRAP_ERRORS_ENABLED 00969 MBED_ERROR( 00970 MBED_MAKE_ERROR( 00971 MBED_MODULE_DRIVER_USB, 00972 MBED_ERROR_CODE_INVALID_INDEX 00973 ), 00974 "The endpoint is not indexable." 00975 ); 00976 #else 00977 return; 00978 #endif // MBED_TRAP_ERRORS_ENABLED 00979 } 00980 00981 endpoint_info_t *info = &_endpoint_info[EP_TO_INDEX(endpoint)]; 00982 00983 MBED_ASSERT(info->pending >= 1); 00984 info->pending -= 1; 00985 if (info->callback) { 00986 info->callback(); 00987 } 00988 } 00989 00990 void USBDevice::in(usb_ep_t endpoint) 00991 { 00992 assert_locked(); 00993 00994 if (!EP_INDEXABLE(endpoint)) { 00995 #if MBED_TRAP_ERRORS_ENABLED 00996 MBED_ERROR( 00997 MBED_MAKE_ERROR( 00998 MBED_MODULE_DRIVER_USB, 00999 MBED_ERROR_CODE_INVALID_INDEX 01000 ), 01001 "The endpoint is not indexable." 01002 ); 01003 #else 01004 return; 01005 #endif // MBED_TRAP_ERRORS_ENABLED 01006 } 01007 01008 endpoint_info_t *info = &_endpoint_info[EP_TO_INDEX(endpoint)]; 01009 01010 MBED_ASSERT(info->pending >= 1); 01011 info->pending -= 1; 01012 if (info->callback) { 01013 info->callback(); 01014 } 01015 } 01016 01017 void USBDevice::init() 01018 { 01019 lock(); 01020 01021 if (!_initialized) { 01022 this->_phy->init(this); 01023 _max_packet_size_ep0 = this->_phy->ep0_set_max_packet(MAX_PACKET_SIZE_EP0); 01024 _initialized = true; 01025 } 01026 01027 unlock(); 01028 } 01029 01030 void USBDevice::deinit() 01031 { 01032 lock(); 01033 01034 if (_initialized) { 01035 disconnect(); 01036 this->_phy->deinit(); 01037 _initialized = false; 01038 } 01039 01040 unlock(); 01041 } 01042 01043 bool USBDevice::configured() 01044 { 01045 lock(); 01046 01047 /* Returns true if device is in the Configured state */ 01048 bool ret = (_device.state == Configured); 01049 01050 unlock(); 01051 return ret; 01052 } 01053 01054 void USBDevice::connect() 01055 { 01056 lock(); 01057 01058 /* Ensure device has been initialized */ 01059 init(); 01060 01061 /* Connect device */ 01062 if (!_connected) { 01063 _phy->connect(); 01064 _connected = true; 01065 } 01066 01067 unlock(); 01068 } 01069 01070 void USBDevice::disconnect() 01071 { 01072 lock(); 01073 01074 /* Disconnect device */ 01075 if (_connected) { 01076 _phy->disconnect(); 01077 _connected = false; 01078 } 01079 01080 /* Set initial device state */ 01081 if (_device.state > Powered) { 01082 _change_state(Powered); 01083 } 01084 //TODO - remove these? 01085 _device.configuration = 0; 01086 _device.suspended = false; 01087 01088 unlock(); 01089 } 01090 01091 void USBDevice::sof_enable() 01092 { 01093 lock(); 01094 01095 _phy->sof_enable(); 01096 01097 unlock(); 01098 } 01099 01100 void USBDevice::sof_disable() 01101 { 01102 lock(); 01103 01104 _phy->sof_disable(); 01105 01106 unlock(); 01107 } 01108 01109 bool USBDevice::endpoint_add(usb_ep_t endpoint, uint32_t max_packet_size, usb_ep_type_t type, mbed::Callback<void()> callback) 01110 { 01111 lock(); 01112 01113 if (!EP_INDEXABLE(endpoint)) { 01114 #if MBED_TRAP_ERRORS_ENABLED 01115 MBED_ERROR( 01116 MBED_MAKE_ERROR( 01117 MBED_MODULE_DRIVER_USB, 01118 MBED_ERROR_CODE_INVALID_INDEX 01119 ), 01120 "The endpoint is not indexable." 01121 ); 01122 #else 01123 unlock(); 01124 return false; 01125 #endif // MBED_TRAP_ERRORS_ENABLED 01126 } 01127 01128 if (!_endpoint_add_remove_allowed) { 01129 unlock(); 01130 return false; 01131 } 01132 01133 endpoint_info_t *info = &_endpoint_info[EP_TO_INDEX(endpoint)]; 01134 MBED_ASSERT(!(info->flags & ENDPOINT_ENABLED)); 01135 MBED_ASSERT(max_packet_size <= 1024); 01136 01137 bool ret = _phy->endpoint_add(endpoint, max_packet_size, type); 01138 if (ret) { 01139 info->callback = callback; 01140 info->flags |= ENDPOINT_ENABLED; 01141 info->pending = 0; 01142 info->max_packet_size = max_packet_size; 01143 } 01144 01145 unlock(); 01146 return ret; 01147 } 01148 01149 void USBDevice::endpoint_remove(usb_ep_t endpoint) 01150 { 01151 lock(); 01152 01153 if (!EP_INDEXABLE(endpoint)) { 01154 #if MBED_TRAP_ERRORS_ENABLED 01155 MBED_ERROR( 01156 MBED_MAKE_ERROR( 01157 MBED_MODULE_DRIVER_USB, 01158 MBED_ERROR_CODE_INVALID_INDEX 01159 ), 01160 "The endpoint is not indexable." 01161 ); 01162 #else 01163 unlock(); 01164 return; 01165 #endif // MBED_TRAP_ERRORS_ENABLED 01166 } 01167 01168 if (!_endpoint_add_remove_allowed) { 01169 unlock(); 01170 return; 01171 } 01172 01173 endpoint_info_t *info = &_endpoint_info[EP_TO_INDEX(endpoint)]; 01174 MBED_ASSERT(info->flags & ENDPOINT_ENABLED); 01175 01176 if (info->pending) { 01177 _phy->endpoint_abort(endpoint); 01178 } 01179 01180 info->callback = NULL; 01181 info->flags = 0; 01182 info->pending = 0; 01183 info->max_packet_size = 0; 01184 01185 _phy->endpoint_remove(endpoint); 01186 01187 unlock(); 01188 } 01189 01190 void USBDevice::endpoint_remove_all() 01191 { 01192 lock(); 01193 01194 for (uint32_t i = 0; i < sizeof(_endpoint_info) / sizeof(_endpoint_info[0]); i++) { 01195 endpoint_info_t *info = _endpoint_info + i; 01196 if (info->flags & ENDPOINT_ENABLED) { 01197 endpoint_remove(INDEX_TO_EP(i)); 01198 } 01199 } 01200 01201 unlock(); 01202 } 01203 01204 void USBDevice::endpoint_stall(usb_ep_t endpoint) 01205 { 01206 lock(); 01207 01208 if (!EP_INDEXABLE(endpoint)) { 01209 #if MBED_TRAP_ERRORS_ENABLED 01210 MBED_ERROR( 01211 MBED_MAKE_ERROR( 01212 MBED_MODULE_DRIVER_USB, 01213 MBED_ERROR_CODE_INVALID_INDEX 01214 ), 01215 "The endpoint is not indexable." 01216 ); 01217 #else 01218 unlock(); 01219 return; 01220 #endif // MBED_TRAP_ERRORS_ENABLED 01221 } 01222 01223 endpoint_info_t *info = &_endpoint_info[EP_TO_INDEX(endpoint)]; 01224 if (!(info->flags & ENDPOINT_ENABLED)) { 01225 // Invalid endpoint is being used 01226 MBED_ASSERT(!configured()); 01227 unlock(); 01228 return; 01229 } 01230 01231 info->flags |= ENDPOINT_STALLED; 01232 _phy->endpoint_stall(endpoint); 01233 01234 if (info->pending) { 01235 endpoint_abort(endpoint); 01236 } 01237 01238 unlock(); 01239 } 01240 01241 void USBDevice::endpoint_unstall(usb_ep_t endpoint) 01242 { 01243 lock(); 01244 01245 if (!EP_INDEXABLE(endpoint)) { 01246 #if MBED_TRAP_ERRORS_ENABLED 01247 MBED_ERROR( 01248 MBED_MAKE_ERROR( 01249 MBED_MODULE_DRIVER_USB, 01250 MBED_ERROR_CODE_INVALID_INDEX 01251 ), 01252 "The endpoint is not indexable." 01253 ); 01254 #else 01255 unlock(); 01256 return; 01257 #endif // MBED_TRAP_ERRORS_ENABLED 01258 } 01259 01260 endpoint_info_t *info = &_endpoint_info[EP_TO_INDEX(endpoint)]; 01261 if (!(info->flags & ENDPOINT_ENABLED)) { 01262 // Invalid endpoint is being used 01263 MBED_ASSERT(!configured()); 01264 unlock(); 01265 return; 01266 } 01267 01268 if (info->pending) { 01269 endpoint_abort(endpoint); 01270 } 01271 01272 info->flags &= ~ENDPOINT_STALLED; 01273 _phy->endpoint_unstall(endpoint); 01274 01275 unlock(); 01276 } 01277 01278 uint8_t *USBDevice::find_descriptor(uint8_t descriptorType, uint8_t index) 01279 { 01280 /* Find a descriptor within the list of descriptors */ 01281 /* following a configuration descriptor. */ 01282 uint16_t wTotalLength; 01283 uint8_t *ptr; 01284 01285 if (configuration_desc(index) == NULL) { 01286 return NULL; 01287 } 01288 01289 /* Check this is a configuration descriptor */ 01290 if ((configuration_desc(index)[0] != CONFIGURATION_DESCRIPTOR_LENGTH) \ 01291 || (configuration_desc(index)[1] != CONFIGURATION_DESCRIPTOR)) { 01292 return NULL; 01293 } 01294 01295 wTotalLength = configuration_desc(index)[2] | (configuration_desc(index)[3] << 8); 01296 01297 /* Check there are some more descriptors to follow */ 01298 if (wTotalLength <= (CONFIGURATION_DESCRIPTOR_LENGTH + 2)) 01299 /* +2 is for bLength and bDescriptorType of next descriptor */ 01300 { 01301 return NULL; 01302 } 01303 01304 /* Start at first descriptor after the configuration descriptor */ 01305 ptr = &(((uint8_t *)configuration_desc(index))[CONFIGURATION_DESCRIPTOR_LENGTH]); 01306 01307 do { 01308 if (ptr[1] /* bDescriptorType */ == descriptorType) { 01309 /* Found */ 01310 return ptr; 01311 } 01312 01313 /* Skip to next descriptor */ 01314 ptr += ptr[0]; /* bLength */ 01315 } while (ptr < (configuration_desc(index) + wTotalLength)); 01316 01317 /* Reached end of the descriptors - not found */ 01318 return NULL; 01319 } 01320 01321 const usb_ep_table_t *USBDevice::endpoint_table() 01322 { 01323 return _phy->endpoint_table(); 01324 } 01325 01326 void USBDevice::power(bool powered) 01327 { 01328 assert_locked(); 01329 01330 if (!powered && _device.state > Attached) { 01331 _change_state(Attached); 01332 } 01333 } 01334 01335 void USBDevice::suspend(bool suspended) 01336 { 01337 } 01338 01339 void USBDevice::sof(int frame_number) 01340 { 01341 callback_sof(frame_number); 01342 } 01343 01344 01345 USBDevice::USBDevice(USBPhy *phy, uint16_t vendor_id, uint16_t product_id, uint16_t product_release) 01346 { 01347 this->vendor_id = vendor_id; 01348 this->product_id = product_id; 01349 this->product_release = product_release; 01350 01351 memset(_endpoint_info, 0, sizeof(_endpoint_info)); 01352 memset(&_transfer, 0, sizeof(_transfer)); 01353 _transfer.user_callback = None; 01354 01355 _setup_ready = false; 01356 _abort_control = false; 01357 01358 _phy = phy; 01359 _initialized = false; 01360 _connected = false; 01361 _endpoint_add_remove_allowed = false; 01362 _current_interface = 0; 01363 _current_alternate = 0; 01364 _locked = 0; 01365 _post_process = NULL; 01366 _max_packet_size_ep0 = 0; 01367 01368 /* Set initial device state */ 01369 _device.state = Powered; 01370 _device.configuration = 0; 01371 _device.suspended = false; 01372 } 01373 01374 USBDevice::~USBDevice() 01375 { 01376 MBED_ASSERT(!_initialized); 01377 deinit(); 01378 } 01379 01380 uint32_t USBDevice::endpoint_max_packet_size(usb_ep_t endpoint) 01381 { 01382 lock(); 01383 01384 uint32_t size = 0; 01385 if (EP_CONTROL(endpoint)) { 01386 size = _max_packet_size_ep0; 01387 } else { 01388 endpoint_info_t *info = &_endpoint_info[EP_TO_INDEX(endpoint)]; 01389 size = info->max_packet_size; 01390 } 01391 01392 unlock(); 01393 return size; 01394 } 01395 01396 void USBDevice::endpoint_abort(usb_ep_t endpoint) 01397 { 01398 lock(); 01399 01400 if (!EP_INDEXABLE(endpoint)) { 01401 #if MBED_TRAP_ERRORS_ENABLED 01402 MBED_ERROR( 01403 MBED_MAKE_ERROR( 01404 MBED_MODULE_DRIVER_USB, 01405 MBED_ERROR_CODE_INVALID_INDEX 01406 ), 01407 "The endpoint is not indexable." 01408 ); 01409 #else 01410 unlock(); 01411 return; 01412 #endif // MBED_TRAP_ERRORS_ENABLED 01413 } 01414 01415 endpoint_info_t *info = &_endpoint_info[EP_TO_INDEX(endpoint)]; 01416 if (!(info->flags & ENDPOINT_ENABLED)) { 01417 // Assert that only valid endpoints are used when in the configured state 01418 MBED_ASSERT(!configured()); 01419 unlock(); 01420 return; 01421 } 01422 01423 if (info->pending) { 01424 _phy->endpoint_abort(endpoint); 01425 info->pending = 0; 01426 } 01427 01428 unlock(); 01429 } 01430 01431 bool USBDevice::read_start(usb_ep_t endpoint, uint8_t *buffer, uint32_t max_size) 01432 { 01433 lock(); 01434 01435 if (!EP_INDEXABLE(endpoint)) { 01436 #if MBED_TRAP_ERRORS_ENABLED 01437 MBED_ERROR( 01438 MBED_MAKE_ERROR( 01439 MBED_MODULE_DRIVER_USB, 01440 MBED_ERROR_CODE_INVALID_INDEX 01441 ), 01442 "The endpoint is not indexable." 01443 ); 01444 #else 01445 unlock(); 01446 return false; 01447 #endif // MBED_TRAP_ERRORS_ENABLED 01448 } 01449 01450 endpoint_info_t *info = &_endpoint_info[EP_TO_INDEX(endpoint)]; 01451 if (!(info->flags & ENDPOINT_ENABLED)) { 01452 // Assert that only valid endpoints are used when in the configured state 01453 MBED_ASSERT(!configured()); 01454 unlock(); 01455 return false; 01456 } 01457 01458 if (max_size < info->max_packet_size) { 01459 #if MBED_TRAP_ERRORS_ENABLED 01460 MBED_ERROR( 01461 MBED_MAKE_ERROR( 01462 MBED_MODULE_DRIVER_USB, 01463 MBED_ERROR_CODE_INVALID_SIZE 01464 ), 01465 "The size of the data to read is less than the max packet size for this endpoint." 01466 ); 01467 #else 01468 unlock(); 01469 return false; 01470 #endif // MBED_TRAP_ERRORS_ENABLED 01471 } 01472 01473 if (info->pending) { 01474 // Only allow 1 packet 01475 unlock(); 01476 return false; 01477 } 01478 01479 bool ret = _phy->endpoint_read(endpoint, buffer, info->max_packet_size); 01480 if (ret) { 01481 info->pending += 1; 01482 } 01483 01484 unlock(); 01485 01486 return ret; 01487 } 01488 01489 uint32_t USBDevice::read_finish(usb_ep_t endpoint) 01490 { 01491 lock(); 01492 01493 if (!EP_INDEXABLE(endpoint)) { 01494 #if MBED_TRAP_ERRORS_ENABLED 01495 MBED_ERROR( 01496 MBED_MAKE_ERROR( 01497 MBED_MODULE_DRIVER_USB, 01498 MBED_ERROR_CODE_INVALID_INDEX 01499 ), 01500 "The endpoint is not indexable." 01501 ); 01502 #else 01503 unlock(); 01504 return 0; 01505 #endif // MBED_TRAP_ERRORS_ENABLED 01506 } 01507 01508 endpoint_info_t *info = &_endpoint_info[EP_TO_INDEX(endpoint)]; 01509 if (!(info->flags & ENDPOINT_ENABLED)) { 01510 // Assert that only valid endpoints are used when in the configured state 01511 MBED_ASSERT(!configured()); 01512 unlock(); 01513 return 0; 01514 } 01515 01516 uint32_t size = 0; 01517 size = _phy->endpoint_read_result(endpoint); 01518 unlock(); 01519 return size; 01520 } 01521 01522 bool USBDevice::write_start(usb_ep_t endpoint, uint8_t *buffer, uint32_t size) 01523 { 01524 lock(); 01525 01526 if (!EP_INDEXABLE(endpoint)) { 01527 #if MBED_TRAP_ERRORS_ENABLED 01528 MBED_ERROR( 01529 MBED_MAKE_ERROR( 01530 MBED_MODULE_DRIVER_USB, 01531 MBED_ERROR_CODE_INVALID_INDEX 01532 ), 01533 "The endpoint is not indexable" 01534 ); 01535 #else 01536 unlock(); 01537 return false; 01538 #endif // MBED_TRAP_ERRORS_ENABLED 01539 } 01540 01541 endpoint_info_t *info = &_endpoint_info[EP_TO_INDEX(endpoint)]; 01542 if (!(info->flags & ENDPOINT_ENABLED)) { 01543 // Assert that only valid endpoints are used when in the configured state 01544 MBED_ASSERT(!configured()); 01545 unlock(); 01546 return false; 01547 } 01548 01549 if (size > info->max_packet_size) { 01550 #if MBED_TRAP_ERRORS_ENABLED 01551 MBED_ERROR( 01552 MBED_MAKE_ERROR( 01553 MBED_MODULE_DRIVER_USB, 01554 MBED_ERROR_CODE_INVALID_SIZE 01555 ), 01556 "Size being written is too large." 01557 ); 01558 #else 01559 unlock(); 01560 return false; 01561 #endif // MBED_TRAP_ERRORS_ENABLED 01562 } 01563 01564 if (info->pending) { 01565 // Only allow 1 packet 01566 unlock(); 01567 return false; 01568 } 01569 01570 /* Send report */ 01571 bool ret = _phy->endpoint_write(endpoint, buffer, size); 01572 if (ret) { 01573 info->transfer_size = size; 01574 info->pending += 1; 01575 } else { 01576 info->transfer_size = 0; 01577 } 01578 01579 unlock(); 01580 return ret; 01581 } 01582 01583 uint32_t USBDevice::write_finish(usb_ep_t endpoint) 01584 { 01585 uint32_t ret = 0; 01586 01587 lock(); 01588 01589 if (!EP_INDEXABLE(endpoint)) { 01590 #if MBED_TRAP_ERRORS_ENABLED 01591 MBED_ERROR( 01592 MBED_MAKE_ERROR( 01593 MBED_MODULE_DRIVER_USB, 01594 MBED_ERROR_CODE_INVALID_INDEX 01595 ), 01596 "The endpoint is not indexable." 01597 ); 01598 #else 01599 unlock(); 01600 return 0; 01601 #endif // MBED_TRAP_ERRORS_ENABLED 01602 } 01603 01604 endpoint_info_t *info = &_endpoint_info[EP_TO_INDEX(endpoint)]; 01605 if (!(info->flags & ENDPOINT_ENABLED)) { 01606 // Assert that only valid endpoints are used when in the configured state 01607 MBED_ASSERT(!configured()); 01608 unlock(); 01609 return 0; 01610 } 01611 01612 ret = info->transfer_size; 01613 01614 unlock(); 01615 return ret; 01616 } 01617 01618 const uint8_t *USBDevice::device_desc() 01619 { 01620 uint8_t device_descriptor_temp[] = { 01621 DEVICE_DESCRIPTOR_LENGTH, /* bLength */ 01622 DEVICE_DESCRIPTOR, /* bDescriptorType */ 01623 LSB(USB_VERSION_2_0), /* bcdUSB (LSB) */ 01624 MSB(USB_VERSION_2_0), /* bcdUSB (MSB) */ 01625 0x00, /* bDeviceClass */ 01626 0x00, /* bDeviceSubClass */ 01627 0x00, /* bDeviceprotocol */ 01628 (uint8_t)_max_packet_size_ep0, /* bMaxPacketSize0 */ 01629 (uint8_t)(LSB(vendor_id)), /* idVendor (LSB) */ 01630 (uint8_t)(MSB(vendor_id)), /* idVendor (MSB) */ 01631 (uint8_t)(LSB(product_id)), /* idProduct (LSB) */ 01632 (uint8_t)(MSB(product_id)), /* idProduct (MSB) */ 01633 (uint8_t)(LSB(product_release)), /* bcdDevice (LSB) */ 01634 (uint8_t)(MSB(product_release)), /* bcdDevice (MSB) */ 01635 STRING_OFFSET_IMANUFACTURER, /* iManufacturer */ 01636 STRING_OFFSET_IPRODUCT, /* iProduct */ 01637 STRING_OFFSET_ISERIAL, /* iSerialNumber */ 01638 0x01 /* bNumConfigurations */ 01639 }; 01640 MBED_ASSERT(sizeof(device_descriptor_temp) == sizeof(device_descriptor)); 01641 memcpy(device_descriptor, device_descriptor_temp, sizeof(device_descriptor)); 01642 return device_descriptor; 01643 } 01644 01645 const uint8_t *USBDevice::string_langid_desc() 01646 { 01647 static const uint8_t string_langid_descriptor[] = { 01648 0x04, /*bLength*/ 01649 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/ 01650 0x09, 0x04, /*bString Lang ID - 0x0409 - English*/ 01651 }; 01652 return string_langid_descriptor; 01653 } 01654 01655 const uint8_t *USBDevice::string_imanufacturer_desc() 01656 { 01657 static const uint8_t string_imanufacturer_descriptor[] = { 01658 0x12, /*bLength*/ 01659 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/ 01660 'm', 0, 'b', 0, 'e', 0, 'd', 0, '.', 0, 'o', 0, 'r', 0, 'g', 0, /*bString iManufacturer - mbed.org*/ 01661 }; 01662 return string_imanufacturer_descriptor; 01663 } 01664 01665 const uint8_t *USBDevice::string_iserial_desc() 01666 { 01667 static const uint8_t string_iserial_descriptor[] = { 01668 0x16, /*bLength*/ 01669 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/ 01670 '0', 0, '1', 0, '2', 0, '3', 0, '4', 0, '5', 0, '6', 0, '7', 0, '8', 0, '9', 0, /*bString iSerial - 0123456789*/ 01671 }; 01672 return string_iserial_descriptor; 01673 } 01674 01675 const uint8_t *USBDevice::string_iconfiguration_desc() 01676 { 01677 static const uint8_t string_iconfiguration_descriptor[] = { 01678 0x06, /*bLength*/ 01679 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/ 01680 '0', 0, '1', 0, /*bString iConfiguration - 01*/ 01681 }; 01682 return string_iconfiguration_descriptor; 01683 } 01684 01685 const uint8_t *USBDevice::string_iinterface_desc() 01686 { 01687 static const uint8_t string_iinterface_descriptor[] = { 01688 0x08, /*bLength*/ 01689 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/ 01690 'U', 0, 'S', 0, 'B', 0, /*bString iInterface - USB*/ 01691 }; 01692 return string_iinterface_descriptor; 01693 } 01694 01695 const uint8_t *USBDevice::string_iproduct_desc() 01696 { 01697 static const uint8_t string_iproduct_descriptor[] = { 01698 0x16, /*bLength*/ 01699 STRING_DESCRIPTOR, /*bDescriptorType 0x03*/ 01700 'U', 0, 'S', 0, 'B', 0, ' ', 0, 'D', 0, 'E', 0, 'V', 0, 'I', 0, 'C', 0, 'E', 0 /*bString iProduct - USB DEVICE*/ 01701 }; 01702 return string_iproduct_descriptor; 01703 } 01704 01705 void USBDevice::start_process() 01706 { 01707 lock(); 01708 01709 _phy->process(); 01710 01711 unlock(); 01712 } 01713 01714 void USBDevice::lock() 01715 { 01716 core_util_critical_section_enter(); 01717 _locked++; 01718 MBED_ASSERT(_locked > 0); 01719 } 01720 01721 void USBDevice::unlock() 01722 { 01723 if (_locked == 1) { 01724 // Perform post processing before fully unlocking 01725 while (_post_process != NULL) { 01726 void (USBDevice::*call)() = _post_process; 01727 _post_process = NULL; 01728 (this->*call)(); 01729 } 01730 } 01731 01732 MBED_ASSERT(_locked > 0); 01733 _locked--; 01734 core_util_critical_section_exit(); 01735 } 01736 01737 void USBDevice::assert_locked() 01738 { 01739 MBED_ASSERT(_locked > 0); 01740 } 01741 01742 void USBDevice::_change_state(DeviceState new_state) 01743 { 01744 assert_locked(); 01745 01746 DeviceState old_state = _device.state; 01747 _device.state = new_state; 01748 01749 if (old_state == new_state) { 01750 return; 01751 } 01752 01753 bool leaving_configured_state = (old_state >= Configured) && (new_state < Configured); 01754 bool leaving_default_state = (old_state >= Default) && (new_state < Default); 01755 01756 if (leaving_configured_state) { 01757 memset(_endpoint_info, 0, sizeof(_endpoint_info)); 01758 _device.configuration = 0; 01759 _endpoint_add_remove_allowed = false; 01760 } 01761 01762 if (leaving_default_state) { 01763 /* Abort any pending control transfers */ 01764 _control_abort_start(); 01765 } 01766 01767 callback_state_change(new_state); 01768 } 01769 01770 void USBDevice::_run_later(void (USBDevice::*function)()) 01771 { 01772 _post_process = function; 01773 }
Generated on Tue Jul 12 2022 13:55:02 by
