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
EndpointResolver.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 "EndpointResolver.h" 00019 00020 static uint32_t logical_to_index(uint32_t logical, bool in_not_out) 00021 { 00022 return (logical << 1) | (in_not_out ? 1 : 0); 00023 } 00024 00025 static uint32_t index_to_logical(uint32_t index) 00026 { 00027 return index >> 1; 00028 } 00029 00030 00031 EndpointResolver::EndpointResolver(const usb_ep_table_t *table) : _table(table), _cost(0), _used(0), _valid(true) 00032 { 00033 // Do nothing 00034 } 00035 00036 EndpointResolver::~EndpointResolver() 00037 { 00038 // Do nothing 00039 } 00040 00041 void EndpointResolver::endpoint_ctrl(uint32_t size) 00042 { 00043 endpoint_in(USB_EP_TYPE_CTRL, size); 00044 endpoint_out(USB_EP_TYPE_CTRL, size); 00045 } 00046 00047 usb_ep_t EndpointResolver::next_free_endpoint(bool in_not_out, usb_ep_type_t type, uint32_t size) 00048 { 00049 int index = next_index(type, in_not_out); 00050 if (index < 0) { 00051 _valid = false; 00052 return 0; 00053 } 00054 00055 const usb_ep_entry_t &entry = _table->table[index_to_logical(index)]; 00056 _cost += entry.base_cost + entry.byte_cost * size; 00057 _used |= 1 << index; 00058 00059 return index_to_endpoint(index); 00060 00061 } 00062 usb_ep_t EndpointResolver::endpoint_in(usb_ep_type_t type, uint32_t size) 00063 { 00064 return next_free_endpoint(true, type, size); 00065 } 00066 00067 usb_ep_t EndpointResolver::endpoint_out(usb_ep_type_t type, uint32_t size) 00068 { 00069 return next_free_endpoint(false, type, size); 00070 } 00071 00072 bool EndpointResolver::valid() 00073 { 00074 return _valid && (_cost <= _table->resources); 00075 } 00076 00077 void EndpointResolver::reset() 00078 { 00079 _cost = 0; 00080 _used = 0; 00081 _valid = true; 00082 } 00083 00084 usb_ep_t EndpointResolver::index_to_endpoint(int index) 00085 { 00086 return index_to_logical(index) | ((index & 1) ? 0x80 : 0); 00087 } 00088 00089 int EndpointResolver::next_index(usb_ep_type_t type, bool in_not_out) 00090 { 00091 for (int logical = 0; logical < (int)(sizeof(_table->table) / sizeof(_table->table[0])); logical++) { 00092 uint32_t index = logical_to_index(logical, in_not_out); 00093 uint32_t other = logical_to_index(logical, !in_not_out); 00094 const usb_ep_entry_t &entry = _table->table[logical]; 00095 00096 usb_ep_attr_t dir = entry.attributes & USB_EP_ATTR_DIR_MASK; 00097 bool in_allowed = dir != USB_EP_ATTR_DIR_OUT; 00098 bool out_allowed = dir != USB_EP_ATTR_DIR_IN; 00099 bool shared = dir == USB_EP_ATTR_DIR_IN_OR_OUT; 00100 00101 if (!(entry.attributes & (1 << type))) { 00102 // This type is not supported 00103 continue; 00104 } 00105 00106 if (in_not_out && !in_allowed) { 00107 // In endpoint not supported 00108 continue; 00109 } 00110 00111 if (!in_not_out && !out_allowed) { 00112 // Out endpoint not supported 00113 continue; 00114 } 00115 00116 if (_used & (1 << index)) { 00117 // This endpoint is in use 00118 continue; 00119 } 00120 00121 if (shared && (_used & (1 << other))) { 00122 // This endpoint can only be one direction at a time and is in 00123 // use by the other direction 00124 continue; 00125 } 00126 00127 return index; 00128 } 00129 00130 // Not found 00131 return -1; 00132 }
Generated on Tue Jul 12 2022 13:54:18 by
