blob: 9583f509d5749d5bfe7ca18c234b22701d09f3e4 [file] [log] [blame]
Austin Schuh41baf202022-01-01 14:33:40 -08001/*
2 * The MIT License (MIT)
3 *
4 * Copyright (c) 2019 Ha Thach (tinyusb.org)
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 *
24 * This file is part of the TinyUSB stack.
25 */
26
27#include "tusb_option.h"
28
29#if TUSB_OPT_HOST_ENABLED || TUSB_OPT_DEVICE_ENABLED
30
31#include "tusb.h"
32
33// TODO clean up
34#if TUSB_OPT_DEVICE_ENABLED
35#include "device/usbd_pvt.h"
36#endif
37
38bool tusb_init(void)
39{
40#if TUSB_OPT_DEVICE_ENABLED
41 TU_ASSERT ( tud_init(TUD_OPT_RHPORT) ); // init device stack
42#endif
43
44#if TUSB_OPT_HOST_ENABLED
45 TU_ASSERT( tuh_init(TUH_OPT_RHPORT) ); // init host stack
46#endif
47
48 return true;
49}
50
51bool tusb_inited(void)
52{
53 bool ret = false;
54
55#if TUSB_OPT_DEVICE_ENABLED
56 ret = ret || tud_inited();
57#endif
58
59#if TUSB_OPT_HOST_ENABLED
60 ret = ret || tuh_inited();
61#endif
62
63 return ret;
64}
65
66//--------------------------------------------------------------------+
67// Internal Helper for both Host and Device stack
68//--------------------------------------------------------------------+
69
70bool tu_edpt_validate(tusb_desc_endpoint_t const * desc_ep, tusb_speed_t speed)
71{
72 uint16_t const max_packet_size = tu_edpt_packet_size(desc_ep);
73 TU_LOG2(" Open EP %02X with Size = %u\r\n", desc_ep->bEndpointAddress, max_packet_size);
74
75 switch (desc_ep->bmAttributes.xfer)
76 {
77 case TUSB_XFER_ISOCHRONOUS:
78 {
79 uint16_t const spec_size = (speed == TUSB_SPEED_HIGH ? 1024 : 1023);
80 TU_ASSERT(max_packet_size <= spec_size);
81 }
82 break;
83
84 case TUSB_XFER_BULK:
85 if (speed == TUSB_SPEED_HIGH)
86 {
87 // Bulk highspeed must be EXACTLY 512
88 TU_ASSERT(max_packet_size == 512);
89 }else
90 {
91 // TODO Bulk fullspeed can only be 8, 16, 32, 64
92 TU_ASSERT(max_packet_size <= 64);
93 }
94 break;
95
96 case TUSB_XFER_INTERRUPT:
97 {
98 uint16_t const spec_size = (speed == TUSB_SPEED_HIGH ? 1024 : 64);
99 TU_ASSERT(max_packet_size <= spec_size);
100 }
101 break;
102
103 default: return false;
104 }
105
106 return true;
107}
108
109void tu_edpt_bind_driver(uint8_t ep2drv[][2], tusb_desc_interface_t const* desc_itf, uint16_t desc_len, uint8_t driver_id)
110{
111 uint8_t const* p_desc = (uint8_t const*) desc_itf;
112 uint8_t const* desc_end = p_desc + desc_len;
113
114 while( p_desc < desc_end )
115 {
116 if ( TUSB_DESC_ENDPOINT == tu_desc_type(p_desc) )
117 {
118 uint8_t const ep_addr = ((tusb_desc_endpoint_t const*) p_desc)->bEndpointAddress;
119
120 TU_LOG(2, " Bind EP %02x to driver id %u\r\n", ep_addr, driver_id);
121 ep2drv[tu_edpt_number(ep_addr)][tu_edpt_dir(ep_addr)] = driver_id;
122 }
123
124 p_desc = tu_desc_next(p_desc);
125 }
126}
127
128uint16_t tu_desc_get_interface_total_len(tusb_desc_interface_t const* desc_itf, uint8_t itf_count, uint16_t max_len)
129{
130 uint8_t const* p_desc = (uint8_t const*) desc_itf;
131 uint16_t len = 0;
132
133 while (itf_count--)
134 {
135 // Next on interface desc
136 len += tu_desc_len(desc_itf);
137 p_desc = tu_desc_next(p_desc);
138
139 while (len < max_len)
140 {
141 // return on IAD regardless of itf count
142 if ( tu_desc_type(p_desc) == TUSB_DESC_INTERFACE_ASSOCIATION ) return len;
143
144 if ( (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE) &&
145 ((tusb_desc_interface_t const*) p_desc)->bAlternateSetting == 0 )
146 {
147 break;
148 }
149
150 len += tu_desc_len(p_desc);
151 p_desc = tu_desc_next(p_desc);
152 }
153 }
154
155 return len;
156}
157
158/*------------------------------------------------------------------*/
159/* Debug
160 *------------------------------------------------------------------*/
161#if CFG_TUSB_DEBUG
162#include <ctype.h>
163
164char const* const tusb_strerr[TUSB_ERROR_COUNT] = { ERROR_TABLE(ERROR_STRING) };
165
166static void dump_str_line(uint8_t const* buf, uint16_t count)
167{
168 tu_printf(" |");
169
170 // each line is 16 bytes
171 for(uint16_t i=0; i<count; i++)
172 {
173 const char ch = buf[i];
174 tu_printf("%c", isprint(ch) ? ch : '.');
175 }
176
177 tu_printf("|\r\n");
178}
179
180/* Print out memory contents
181 * - buf : buffer
182 * - count : number of item
183 * - indent: prefix spaces on every line
184 */
185void tu_print_mem(void const *buf, uint32_t count, uint8_t indent)
186{
187 uint8_t const size = 1; // fixed 1 byte for now
188
189 if ( !buf || !count )
190 {
191 tu_printf("NULL\r\n");
192 return;
193 }
194
195 uint8_t const *buf8 = (uint8_t const *) buf;
196
197 char format[] = "%00X";
198 format[2] += 2*size;
199
200 const uint8_t item_per_line = 16 / size;
201
202 for(unsigned int i=0; i<count; i++)
203 {
204 unsigned int value=0;
205
206 if ( i%item_per_line == 0 )
207 {
208 // Print Ascii
209 if ( i != 0 )
210 {
211 dump_str_line(buf8-16, 16);
212 }
213
214 for(uint8_t s=0; s < indent; s++) tu_printf(" ");
215
216 // print offset or absolute address
217 tu_printf("%04X: ", 16*i/item_per_line);
218 }
219
220 memcpy(&value, buf8, size);
221 buf8 += size;
222
223 tu_printf(" ");
224 tu_printf(format, value);
225 }
226
227 // fill up last row to 16 for printing ascii
228 const uint32_t remain = count%16;
229 uint8_t nback = (remain ? remain : 16);
230
231 if ( remain )
232 {
233 for(uint32_t i=0; i< 16-remain; i++)
234 {
235 tu_printf(" ");
236 for(int j=0; j<2*size; j++) tu_printf(" ");
237 }
238 }
239
240 dump_str_line(buf8-nback, nback);
241}
242
243#endif
244
245#endif // host or device enabled