Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers USBDevice.cpp Source File

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 }