Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
CTCaer
GitHub Repository: CTCaer/hekate
Path: blob/master/bdk/usb/usbd.c
3694 views
1
/*
2
* Enhanced USB Device (EDCI) driver for Tegra X1
3
*
4
* Copyright (c) 2019-2025 CTCaer
5
*
6
* This program is free software; you can redistribute it and/or modify it
7
* under the terms and conditions of the GNU General Public License,
8
* version 2, as published by the Free Software Foundation.
9
*
10
* This program is distributed in the hope it will be useful, but WITHOUT
11
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13
* more details.
14
*
15
* You should have received a copy of the GNU General Public License
16
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17
*/
18
19
#include <string.h>
20
#include <stdlib.h>
21
22
#include <usb/usbd.h>
23
#include <usb/usb_descriptor_types.h>
24
#include <usb/usb_t210.h>
25
26
#include <gfx_utils.h>
27
#include <soc/bpmp.h>
28
#include <soc/clock.h>
29
#include <soc/fuse.h>
30
#include <soc/gpio.h>
31
#include <soc/pinmux.h>
32
#include <soc/pmc.h>
33
#include <soc/timer.h>
34
#include <soc/t210.h>
35
#include <utils/btn.h>
36
37
#include <memory_map.h>
38
39
typedef enum
40
{
41
USB_HW_EP0 = 0,
42
USB_HW_EP1 = 1
43
} usb_hw_ep_t;
44
45
typedef enum
46
{
47
USB_EP_STATUS_IDLE = 0,
48
USB_EP_STATUS_ACTIVE = 1,
49
USB_EP_STATUS_ERROR = 2,
50
USB_EP_STATUS_NO_CONFIG = 3,
51
USB_EP_STATUS_STALLED = 4,
52
USB_EP_STATUS_DISABLED = 5
53
} usb_ep_status_t;
54
55
typedef enum {
56
USB_LOW_SPEED = 0,
57
USB_FULL_SPEED = 1,
58
USB_HIGH_SPEED = 2,
59
USB_SUPER_SPEED = 3,
60
} usb_speed_t;
61
62
typedef struct _dTD_t
63
{
64
vu32 next_dTD;
65
vu32 info;
66
vu32 pages[5];
67
vu32 reserved;
68
} dTD_t;
69
70
typedef struct _dQH_t
71
{
72
vu32 ep_capabilities;
73
vu32 curr_dTD_ptr;
74
vu32 next_dTD_ptr;
75
vu32 token;
76
vu32 buffers[5]; // hmmm.
77
vu32 reserved;
78
vu32 setup[2];
79
vu32 gap[4];
80
} dQH_t;
81
82
typedef struct _usbd_t
83
{
84
volatile dTD_t dtds[4 * 4]; // 4 dTD per endpoint.
85
volatile dQH_t *qhs;
86
int ep_configured[4];
87
int ep_bytes_requested[4];
88
} usbd_t;
89
90
typedef struct _usbd_controller_t
91
{
92
u32 port_speed;
93
t210_usb2d_t *regs;
94
usb_ctrl_setup_t control_setup;
95
usb_desc_t *desc;
96
usb_gadget_type gadget;
97
u8 config_num;
98
u8 interface_num;
99
u8 max_lun;
100
bool usb_phy_ready;
101
bool configuration_set;
102
bool max_lun_set;
103
bool bulk_reset_req;
104
u32 intr_idle_rate;
105
bool intr_idle_req;
106
bool hid_report_sent;
107
void *hid_rpt_buffer;
108
u32 hid_rpt_size;
109
u32 charger_detect;
110
} usbd_controller_t;
111
112
extern u8 hid_report_descriptor_jc[];
113
extern u8 hid_report_descriptor_touch[];
114
extern u32 hid_report_descriptor_jc_size;
115
extern u32 hid_report_descriptor_touch_size;
116
117
extern usb_desc_t usb_gadget_hid_jc_descriptors;
118
extern usb_desc_t usb_gadget_hid_touch_descriptors;
119
extern usb_desc_t usb_gadget_ums_descriptors;
120
121
usbd_t *usbdaemon;
122
123
usbd_controller_t *usbd_otg;
124
usbd_controller_t usbd_usb_otg_controller_ctxt;
125
126
bool usb_init_done = false;
127
128
u8 *usb_ep0_ctrl_buf = (u8 *)USB_EP_CONTROL_BUF_ADDR;
129
130
static int _usbd_reset_usb_otg_phy_device_mode()
131
{
132
usbd_otg->usb_phy_ready = false;
133
134
// Clear UTMIP reset.
135
USB(USB1_IF_USB_SUSP_CTRL) &= ~SUSP_CTRL_UTMIP_RESET;
136
137
// Wait for PHY clock to get validated.
138
u32 retries = 100000; // 200ms timeout.
139
while (!(USB(USB1_IF_USB_SUSP_CTRL) & SUSP_CTRL_USB_PHY_CLK_VALID))
140
{
141
retries--;
142
if (!retries)
143
return USB_ERROR_INIT;
144
usleep(1);
145
}
146
usbd_otg->usb_phy_ready = true;
147
148
// Clear all device addresses, enabled setup requests and transmit events.
149
usbd_otg->regs->periodiclistbase = 0;
150
usbd_otg->regs->endptsetupstat = usbd_otg->regs->endptsetupstat;
151
usbd_otg->regs->endptcomplete = usbd_otg->regs->endptcomplete;
152
153
// Stop device controller.
154
usbd_otg->regs->usbcmd &= ~USB2D_USBCMD_RUN;
155
156
// Set controller mode to idle.
157
usbd_otg->regs->usbmode &= ~USB2D_USBMODE_CM_MASK;
158
159
// Reset the controller.
160
usbd_otg->regs->usbcmd |= USB2D_USBCMD_RESET;
161
162
// Wait for the reset to complete.
163
retries = 100000; // 200ms timeout.
164
while (usbd_otg->regs->usbcmd & USB2D_USBCMD_RESET)
165
{
166
retries--;
167
if (!retries)
168
return USB_ERROR_INIT;
169
usleep(1);
170
}
171
172
// Wait for PHY clock to get validated after reset.
173
retries = 100000; // 200ms timeout.
174
while (!(USB(USB1_IF_USB_SUSP_CTRL) & SUSP_CTRL_USB_PHY_CLK_VALID))
175
{
176
retries--;
177
if (!retries)
178
return USB_ERROR_INIT;
179
usleep(1);
180
}
181
182
// Set controller to Device mode.
183
usbd_otg->regs->usbmode = (usbd_otg->regs->usbmode & ~USB2D_USBMODE_CM_MASK) | USB2D_USBMODE_CM_DEVICE;
184
185
// Wait for the selected mode to be enabled.
186
retries = 100000; // 200ms timeout.
187
while ((usbd_otg->regs->usbmode & USB2D_USBMODE_CM_MASK) != USB2D_USBMODE_CM_DEVICE)
188
{
189
retries--;
190
if (!retries)
191
return USB_ERROR_INIT;
192
usleep(1);
193
}
194
195
// Disable all interrupts.
196
usbd_otg->regs->usbintr = 0;
197
198
// Set the ID pullup and disable all OTGSC interrupts.
199
usbd_otg->regs->otgsc = USB2D_OTGSC_USB_ID_PULLUP;
200
201
// Clear all relevant interrupt statuses.
202
usbd_otg->regs->usbsts = USB2D_USBSTS_UI | USB2D_USBSTS_UEI | USB2D_USBSTS_PCI |
203
USB2D_USBSTS_FRI | USB2D_USBSTS_SEI | USB2D_USBSTS_AAI |
204
USB2D_USBSTS_URI | USB2D_USBSTS_SRI | USB2D_USBSTS_SLI;
205
206
// Disable and clear all OTGSC interrupts.
207
usbd_otg->regs->otgsc = USB2D_OTGSC_USB_IRQ_STS_MASK;
208
209
// Clear EP0, EP1, EP2 setup requests.
210
usbd_otg->regs->endptsetupstat = 7; //TODO: Shouldn't this be endptsetupstat = endptsetupstat?
211
212
// Set all interrupts to immediate.
213
usbd_otg->regs->usbcmd &= ~USB2D_USBCMD_ITC_MASK;
214
215
return USB_RES_OK;
216
}
217
218
static void _usb_charger_detect()
219
{
220
// Charger detect init.
221
usbd_otg->charger_detect = 0;
222
bool charger_detect_enable = FUSE(FUSE_RESERVED_SW) & 0x10; // Disabled on Switch production.
223
if (charger_detect_enable)
224
{
225
usbd_otg->charger_detect |= 1;
226
// Configure detect pin.
227
PINMUX_AUX(PINMUX_AUX_LCD_GPIO1) &= ~(PINMUX_PARKED | PINMUX_TRISTATE | PINMUX_PULL_MASK);
228
gpio_direction_input(GPIO_PORT_V, GPIO_PIN_3);
229
230
// Configure charger pin.
231
PINMUX_AUX(PINMUX_AUX_USB_VBUS_EN1) &= ~(PINMUX_INPUT_ENABLE | PINMUX_PARKED | PINMUX_TRISTATE | PINMUX_PULL_MASK);
232
gpio_config(GPIO_PORT_CC, GPIO_PIN_5, GPIO_MODE_GPIO);
233
gpio_output_enable(GPIO_PORT_CC, GPIO_PIN_5, GPIO_OUTPUT_ENABLE);
234
235
// Enable charger.
236
if (gpio_read(GPIO_PORT_V, GPIO_PIN_3))
237
{
238
usbd_otg->charger_detect |= 2;
239
gpio_write(GPIO_PORT_CC, GPIO_PIN_5, GPIO_HIGH);
240
usbd_otg->charger_detect |= 0x100;
241
USB(USB1_UTMIP_BAT_CHRG_CFG0) = BAT_CHRG_CFG0_OP_SRC_EN; // Clears UTMIP_PD_CHRG and enables charger detect.
242
usleep(5000);
243
}
244
}
245
}
246
247
static void _usb_init_phy()
248
{
249
// Configure and enable PLLU.
250
clock_enable_pllu();
251
252
// Enable USBD clock.
253
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = BIT(CLK_L_USBD);
254
usleep(2);
255
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = BIT(CLK_L_USBD);
256
usleep(2);
257
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = BIT(CLK_L_USBD);
258
usleep(2);
259
260
// Clear XUSB_PADCTL reset
261
CLOCK(CLK_RST_CONTROLLER_RST_DEV_W_CLR) = BIT(CLK_W_XUSB_PADCTL);
262
263
// Enable USB PHY and reset for programming.
264
u32 usb_susp_ctrl = USB(USB1_IF_USB_SUSP_CTRL);
265
USB(USB1_IF_USB_SUSP_CTRL) = usb_susp_ctrl | SUSP_CTRL_UTMIP_RESET;
266
USB(USB1_IF_USB_SUSP_CTRL) = usb_susp_ctrl | SUSP_CTRL_UTMIP_PHY_ENB | SUSP_CTRL_UTMIP_RESET;
267
268
// Enable IDDQ control by software and disable UTMIPLL IDDQ.
269
CLOCK(CLK_RST_CONTROLLER_UTMIPLL_HW_PWRDN_CFG0) = (CLOCK(CLK_RST_CONTROLLER_UTMIPLL_HW_PWRDN_CFG0) & 0xFFFFFFFC) | 1;
270
usleep(10);
271
272
// Disable crystal clock.
273
USB(USB1_UTMIP_MISC_CFG1) &= 0xBFFFFFFF;
274
CLOCK(CLK_RST_CONTROLLER_UTMIP_PLL_CFG2) &= 0xBFFFFFFF;
275
276
// Set B_SESS_VLD.
277
USB(USB1_IF_USB_PHY_VBUS_SENSORS) |= 0x1000;
278
USB(USB1_IF_USB_PHY_VBUS_SENSORS) |= 0x800;
279
280
// Set UTMIPLL dividers and config based on OSC and enable it to 960 MHz.
281
clock_enable_utmipll();
282
283
// Configure UTMIP Transceiver Cells.
284
u32 fuse_usb_calib = FUSE(FUSE_USB_CALIB);
285
USB(USB1_UTMIP_XCVR_CFG0) = (((USB(USB1_UTMIP_XCVR_CFG0) & 0xFFFFFFF0) | (fuse_usb_calib & 0xF)) & 0xFE3FFFFF) | ((fuse_usb_calib & 0x3F) << 25 >> 29 << 22);
286
USB(USB1_UTMIP_XCVR_CFG1) = (USB(USB1_UTMIP_XCVR_CFG1) & 0xFFC3FFFF) | ((fuse_usb_calib << 21) >> 28 << 18);
287
USB(USB1_UTMIP_XCVR_CFG3) = (USB(USB1_UTMIP_XCVR_CFG3) & 0xFFFFC1FF) | ((FUSE(FUSE_USB_CALIB_EXT) & 0x1F) << 9);
288
USB(USB1_UTMIP_XCVR_CFG0) &= 0xFFDFFFFF;
289
USB(USB1_UTMIP_XCVR_CFG2) = (USB(USB1_UTMIP_XCVR_CFG2) & 0xFFFFF1FF) | 0x400;
290
usleep(1);
291
292
// Configure misc UTMIP.
293
USB(USB1_UTMIP_DEBOUNCE_CFG0) = (USB(USB1_UTMIP_DEBOUNCE_CFG0) & 0xFFFF0000) | 0xBB80;
294
USB(USB1_UTMIP_BIAS_CFG1) = (USB(USB1_UTMIP_BIAS_CFG1) & 0xFFFFC0FF) | 0x100; // when osc is 38.4KHz
295
296
//USB(USB1_UTMIP_SPARE_CFG0) &= 0xFFFFFEE7; unpatched0
297
USB(USB1_UTMIP_BIAS_CFG2) |= 2; //patched0 - UTMIP_HSSQUELCH_LEVEL_NEW: 2.
298
USB(USB1_UTMIP_SPARE_CFG0) &= 0xFFFFFE67; //patched0 - FUSE_HS_IREF_CAP_CFG
299
USB(USB1_UTMIP_TX_CFG0) |= 0x80000;
300
301
//USB(USB1_UTMIP_HSRX_CFG0) = (USB(USB1_UTMIP_HSRX_CFG0) & 0xFFF003FF) | 0x88000 | 0x4000; unpatched1
302
USB(USB1_UTMIP_HSRX_CFG0) = (USB(USB1_UTMIP_HSRX_CFG0) & 0xF0F003FF) | 0x88000 | 0x4000; //patched1 - reset UTMIP_PCOUNT_UPDN_DIV: From 1 to 0.
303
USB(USB1_UTMIP_BIAS_CFG2) &= 0xFFFFFFF8; //patched1 - UTMIP_HSSQUELCH_LEVEL_NEW: 0
304
305
USB(USB1_UTMIP_HSRX_CFG1) = (USB(USB1_UTMIP_HSRX_CFG1) & 0xFFFFFFC1) | 0x12;
306
USB(USB1_UTMIP_MISC_CFG1) |= 0x40000000;
307
308
// Enable crystal clock.
309
CLOCK(CLK_RST_CONTROLLER_UTMIP_PLL_CFG2) |= 0x40000000;
310
311
// Enable USB2 tracking clock.
312
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_Y_SET) = BIT(CLK_Y_USB2_TRK);
313
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_USB2_HSIC_TRK) = (CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_USB2_HSIC_TRK) & 0xFFFFFF00) | 6; // Set trank divisor to 4.
314
315
USB(USB1_UTMIP_BIAS_CFG1) = (USB(USB1_UTMIP_BIAS_CFG1) & 0xFFC03F07) | 0x78000 | 0x50; // Set delays.
316
USB(USB1_UTMIP_BIAS_CFG0) &= 0xFFFFFBFF; // Disable Power down bias circuit.
317
usleep(1);
318
319
// Force PDTRK input into power up.
320
USB(USB1_UTMIP_BIAS_CFG1) = (USB(USB1_UTMIP_BIAS_CFG1) & 0xFFFFFFFE) | 2;
321
usleep(100);
322
323
// TRK cycle done. Force PDTRK input into power down.
324
USB(USB1_UTMIP_BIAS_CFG1) = (USB(USB1_UTMIP_BIAS_CFG1) & 0xFF7FFFFF) | 1;
325
usleep(3);
326
327
// Force PDTRK input into power up.
328
USB(USB1_UTMIP_BIAS_CFG1) = USB(USB1_UTMIP_BIAS_CFG1) & 0xFFFFFFFE;
329
usleep(100);
330
331
// TRK cycle done. Force PDTRK input into power down.
332
USB(USB1_UTMIP_BIAS_CFG1) = (USB(USB1_UTMIP_BIAS_CFG1) & 0xFF7FFFFF) | 1;
333
334
// Disable USB2 tracking clock and configure UTMIP misc.
335
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_Y_CLR) = BIT(CLK_Y_USB2_TRK);
336
CLOCK(CLK_RST_CONTROLLER_UTMIP_PLL_CFG2) = (CLOCK(CLK_RST_CONTROLLER_UTMIP_PLL_CFG2) & 0xFEFFFFEA) | 0x2000000 | 0x28 | 2;
337
usleep(1);
338
339
USB(USB1_UTMIP_BIAS_CFG0) &= 0xFF3FF7FF;
340
usleep(1);
341
342
// Clear power downs on UTMIP ID and VBUS wake up, PD, PD2, PDZI, PDCHRP, PDDR.
343
PMC(APBDEV_PMC_USB_AO) &= 0xFFFFFFF3; // UTMIP ID and VBUS wake up.
344
usleep(1);
345
USB(USB1_UTMIP_XCVR_CFG0) &= 0xFFFFBFFF; // UTMIP_FORCE_PD_POWERDOWN.
346
usleep(1);
347
USB(USB1_UTMIP_XCVR_CFG0) &= 0xFFFEFFFF; // UTMIP_FORCE_PD2_POWERDOWN.
348
usleep(1);
349
USB(USB1_UTMIP_XCVR_CFG0) &= 0xFFFBFFFF; // UTMIP_FORCE_PDZI_POWERDOWN.
350
usleep(1);
351
USB(USB1_UTMIP_XCVR_CFG1) &= 0xFFFFFFFB; // UTMIP_FORCE_PDCHRP_POWERDOWN.
352
usleep(1);
353
USB(USB1_UTMIP_XCVR_CFG1) &= 0xFFFFFFEF; // UTMIP_FORCE_PDDR_POWERDOWN.
354
usleep(1);
355
}
356
357
int usb_device_init()
358
{
359
if (usb_init_done)
360
return USB_RES_OK;
361
362
// Ease the stress to APB.
363
bpmp_clk_rate_relaxed(true);
364
365
// Initialize USB2 controller PHY.
366
_usb_init_phy();
367
368
// Restore OC.
369
bpmp_clk_rate_relaxed(false);
370
371
// AHB USB performance cfg.
372
AHB_GIZMO(AHB_GIZMO_AHB_MEM) |= AHB_MEM_DONT_SPLIT_AHB_WR | AHB_MEM_ENB_FAST_REARBITRATE;
373
AHB_GIZMO(AHB_GIZMO_USB) |= AHB_GIZMO_IMMEDIATE;
374
AHB_GIZMO(AHB_ARBITRATION_PRIORITY_CTRL) = PRIORITY_CTRL_WEIGHT(7) | PRIORITY_SELECT_USB;
375
AHB_GIZMO(AHB_AHB_MEM_PREFETCH_CFG1) = MEM_PREFETCH_ENABLE | MEM_PREFETCH_USB_MST_ID |
376
MEM_PREFETCH_ADDR_BNDRY(12) | 0x1000; // Addr boundary 64KB, Inactivity 4096 cycles.
377
378
// Set software and hardware context storage and clear it.
379
usbdaemon = (usbd_t *)USBD_ADDR; // Depends on USB_TD_BUFFER_PAGE_SIZE aligned address.
380
usbd_otg = &usbd_usb_otg_controller_ctxt;
381
memset(usbd_otg, 0, sizeof(usbd_controller_t));
382
memset(usbdaemon, 0, sizeof(usbd_t));
383
384
usbd_otg->regs = (t210_usb2d_t *)USB_OTG_BASE;
385
usbd_otg->usb_phy_ready = false;
386
387
// Initialize USB PHY on the USB_OTG Controller (#1) in Device mode.
388
int res = _usbd_reset_usb_otg_phy_device_mode();
389
usbd_otg->configuration_set = false;
390
391
_usb_charger_detect();
392
393
if (!res)
394
usb_init_done = true;
395
396
return res;
397
}
398
399
static void _usb_device_power_down()
400
{
401
// Enable PHY low power suspend.
402
usbd_otg->regs->hostpc1_devlc |= USB2D_HOSTPC1_DEVLC_PHCD;
403
// Do not use any controller regs after the above!
404
// A reset or clear of the PHCD suspend bit must happen.
405
406
// Power down OTG and Bias circuits.
407
USB(USB1_UTMIP_BIAS_CFG0) |= BIT(11) | BIT(10); // UTMIP_OTGPD, UTMIP_BIASPD.
408
409
// Power down ID detectors.
410
USB(USB1_UTMIP_BIAS_CFG0) |= BIT(23) | BIT(22); // UTMIP_IDPD_SEL, UTMIP_IDPD_VAL.
411
412
if (usbd_otg->charger_detect)
413
{
414
USB(USB1_UTMIP_BAT_CHRG_CFG0) = 1; //UTMIP_PD_CHRG
415
usbd_otg->charger_detect = 0;
416
}
417
418
// Power down the UTMIP transceivers.
419
// UTMIP_FORCE_PDZI_POWERDOWN, UTMIP_FORCE_PD2_POWERDOWN, UTMIP_FORCE_PD_POWERDOWN.
420
USB(USB1_UTMIP_XCVR_CFG0) |= BIT(18) | BIT(16) |BIT(14);
421
// UTMIP_FORCE_PDDR_POWERDOWN, UTMIP_FORCE_PDCHRP_POWERDOWN, UTMIP_FORCE_PDDISC_POWERDOWN.
422
USB(USB1_UTMIP_XCVR_CFG1) |= BIT(4) | BIT(2) | BIT(0);
423
424
// Keep UTMIP in reset.
425
USB(USB1_IF_USB_SUSP_CTRL) |= SUSP_CTRL_UTMIP_RESET;
426
427
// Power down PD trunk.
428
USB(USB1_UTMIP_BIAS_CFG1) |= BIT(0); //UTMIP_FORCE_PDTRK_POWERDOWN.
429
430
// Force UTMIP_PLL power down.
431
CLOCK(CLK_RST_CONTROLLER_UTMIP_PLL_CFG1) |= BIT(14); // UTMIP_FORCE_PLL_ENABLE_POWERDOWN.
432
CLOCK(CLK_RST_CONTROLLER_UTMIP_PLL_CFG1) |= BIT(12); // UTMIP_FORCE_PLL_ACTIVE_POWERDOWN.
433
CLOCK(CLK_RST_CONTROLLER_UTMIP_PLL_CFG2) |= BIT(4) | BIT(0); // UTMIP_FORCE_PD_SAMP_A/C_POWERDOWN.
434
CLOCK(CLK_RST_CONTROLLER_UTMIP_PLL_CFG1) |= BIT(16); // UTMIP_FORCE_PLLU_POWERDOWN.
435
436
// Disable crystal clock.
437
USB(USB1_UTMIP_MISC_CFG1) &= 0xBFFFFFFF;
438
439
// Force enable UTMIPLL IDDQ.
440
CLOCK(CLK_RST_CONTROLLER_UTMIPLL_HW_PWRDN_CFG0) |= 3;
441
442
// Set XUSB_PADCTL reset
443
CLOCK(CLK_RST_CONTROLLER_RST_DEV_W_SET) = BIT(CLK_W_XUSB_PADCTL);
444
445
// Disable USBD clock.
446
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = BIT(CLK_L_USBD);
447
448
// Disable PLLU.
449
clock_disable_pllu();
450
451
usb_init_done = false;
452
}
453
454
static void _usbd_disable_ep1()
455
{
456
usbd_otg->regs->endptctrl[1] = 0;
457
}
458
459
static void _usbd_stall_reset_ep1(usb_dir_t direction, usb_ep_cfg_t stall)
460
{
461
stall &= 1;
462
if (direction == USB_DIR_IN)
463
{
464
usbd_otg->regs->endptctrl[1] = (usbd_otg->regs->endptctrl[1] & ~USB2D_ENDPTCTRL_TX_EP_STALL) | ((u32)stall << 16);
465
if (!stall)
466
usbd_otg->regs->endptctrl[1] |= USB2D_ENDPTCTRL_TX_EP_RESET;
467
}
468
else
469
{
470
usbd_otg->regs->endptctrl[1] = (usbd_otg->regs->endptctrl[1] & ~USB2D_ENDPTCTRL_RX_EP_STALL) | stall;
471
if (!stall)
472
usbd_otg->regs->endptctrl[1] |= USB2D_ENDPTCTRL_RX_EP_RESET;
473
}
474
}
475
476
void usb_device_stall_ep1_bulk_out()
477
{
478
_usbd_stall_reset_ep1(USB_DIR_OUT, USB_EP_CFG_STALL);
479
}
480
481
void usb_device_stall_ep1_bulk_in()
482
{
483
_usbd_stall_reset_ep1(USB_DIR_IN, USB_EP_CFG_STALL);
484
}
485
486
static int _usbd_get_max_pkt_length(int endpoint)
487
{
488
switch (endpoint)
489
{
490
case USB_EP_CTRL_OUT:
491
case USB_EP_CTRL_IN:
492
return 64;
493
case USB_EP_BULK_OUT:
494
case USB_EP_BULK_IN:
495
if (usbd_otg->port_speed == USB_HIGH_SPEED)
496
return 512;
497
else
498
return 64;
499
default:
500
return 64;
501
}
502
}
503
504
static void _usbd_initialize_ep_ctrl(u32 endpoint)
505
{
506
usb_hw_ep_t actual_ep = (endpoint & 2) >> 1;
507
usb_dir_t direction = endpoint & 1;
508
509
memset((void *)&usbdaemon->qhs[endpoint], 0, sizeof(dQH_t));
510
511
if (!endpoint)
512
usbdaemon->qhs[endpoint].ep_capabilities = USB_QHD_EP_CAP_IOS_ENABLE;
513
514
usbdaemon->qhs[endpoint].next_dTD_ptr = 1; // TERMINATE_SET
515
516
u32 max_packet_len = _usbd_get_max_pkt_length(endpoint) & USB_QHD_EP_CAP_MAX_PKT_LEN_MASK;
517
usbdaemon->qhs[endpoint].ep_capabilities |= max_packet_len << 16;
518
519
if (direction == USB_DIR_IN)
520
{
521
u32 endpoint_type = usbd_otg->regs->endptctrl[actual_ep] & ~USB2D_ENDPTCTRL_TX_EP_TYPE_MASK;
522
if (actual_ep)
523
endpoint_type |= usbd_otg->gadget ? USB2D_ENDPTCTRL_TX_EP_TYPE_INTR : USB2D_ENDPTCTRL_TX_EP_TYPE_BULK;
524
else
525
endpoint_type |= USB2D_ENDPTCTRL_TX_EP_TYPE_CTRL;
526
527
usbd_otg->regs->endptctrl[actual_ep] = endpoint_type;
528
529
usbd_otg->regs->endptctrl[actual_ep] &= ~USB2D_ENDPTCTRL_TX_EP_STALL;
530
531
if (actual_ep == USB_HW_EP1)
532
usbd_otg->regs->endptctrl[1] |= USB2D_ENDPTCTRL_TX_EP_RESET;
533
534
usbd_otg->regs->endptctrl[actual_ep] |= USB2D_ENDPTCTRL_TX_EP_ENABLE;
535
}
536
else // EP Bulk OUT.
537
{
538
u32 endpoint_type = usbd_otg->regs->endptctrl[actual_ep] & ~USB2D_ENDPTCTRL_RX_EP_TYPE_MASK;
539
if (actual_ep)
540
endpoint_type |= usbd_otg->gadget ? USB2D_ENDPTCTRL_RX_EP_TYPE_INTR : USB2D_ENDPTCTRL_RX_EP_TYPE_BULK;
541
else
542
endpoint_type |= USB2D_ENDPTCTRL_RX_EP_TYPE_CTRL;
543
544
usbd_otg->regs->endptctrl[actual_ep] = endpoint_type;
545
usbd_otg->regs->endptctrl[actual_ep] &= ~USB2D_ENDPTCTRL_RX_EP_STALL;
546
547
if (actual_ep == USB_HW_EP1)
548
usbd_otg->regs->endptctrl[1] |= USB2D_ENDPTCTRL_RX_EP_RESET;
549
550
usbd_otg->regs->endptctrl[actual_ep] |= USB2D_ENDPTCTRL_RX_EP_ENABLE;
551
}
552
}
553
554
static int _usbd_initialize_ep0()
555
{
556
memset((void *)usbdaemon->qhs, 0, sizeof(dQH_t) * 4); // Clear all used EP queue heads.
557
memset((void *)usbdaemon->dtds, 0, sizeof(dTD_t) * 4); // Clear all used EP0 token heads.
558
559
usbd_otg->regs->asynclistaddr = (u32)usbdaemon->qhs;
560
561
_usbd_initialize_ep_ctrl(USB_EP_CTRL_OUT);
562
_usbd_initialize_ep_ctrl(USB_EP_CTRL_IN);
563
564
// Disable Auto Low Power.
565
usbd_otg->regs->hostpc1_devlc &= ~USB2D_HOSTPC1_DEVLC_ASUS;
566
567
// Initiate an attach event.
568
usbd_otg->regs->usbcmd |= USB2D_USBCMD_RUN;
569
570
u32 retries = 100000; // 200ms timeout.
571
while (!(usbd_otg->regs->usbcmd & USB2D_USBCMD_RUN))
572
{
573
retries--;
574
if (!retries)
575
return USB_ERROR_TIMEOUT;
576
usleep(1);
577
}
578
579
return USB_RES_OK;
580
}
581
582
// static void _disable_usb_wdt4()
583
// {
584
// if (TIMER_WDT4_STATUS & 1)// active
585
// {
586
// TIMER_TMR0_TMR_PTV &= 0x7FFFFFFF; // Disable timer
587
// TIMER_WDT4_UNLOCK_PATTERN = 0xC45A; // Alow writes to disable counter bit.
588
// TIMER_WDT4_COMMAND |= 2; // Disable counter
589
// TIMER_TMR0_TMR_PCR |= 0x40000000;// INTR_CLR
590
// }
591
// }
592
593
int usbd_flush_endpoint(u32 endpoint)
594
{
595
596
usb_hw_ep_t actual_ep = (endpoint & 2) >> 1;
597
usb_dir_t direction = endpoint & 1;
598
u32 reg_mask = endpoint;
599
600
// Flash all endpoints or 1.
601
if (endpoint != USB_EP_ALL)
602
{
603
if (direction == USB_DIR_IN)
604
reg_mask = USB2D_ENDPT_STATUS_TX_OFFSET << actual_ep;
605
else
606
reg_mask = USB2D_ENDPT_STATUS_RX_OFFSET << actual_ep;
607
}
608
usbd_otg->regs->endptflush = reg_mask;
609
610
u32 retries = 100000; // 200ms timeout.
611
while (usbd_otg->regs->endptflush & reg_mask)
612
{
613
retries--;
614
if (!retries)
615
return USB_ERROR_TIMEOUT;
616
usleep(1);
617
}
618
619
// Wait for the endpoint to finish all transactions (buffer not ready).
620
retries = 100000; // 200ms timeout.
621
while (usbd_otg->regs->endptstatus & reg_mask)
622
{
623
retries--;
624
if (!retries)
625
return USB_ERROR_TIMEOUT;
626
usleep(1);
627
}
628
629
// Wait for the endpoint to clear the primed status.
630
retries = 100000; // 200ms timeout.
631
while (usbd_otg->regs->endptprime & reg_mask)
632
{
633
retries--;
634
if (!retries)
635
return USB_ERROR_TIMEOUT;
636
usleep(1);
637
}
638
639
return USB_RES_OK;
640
}
641
642
static void _usb_reset_disable_ep1()
643
{
644
usbd_flush_endpoint(USB_EP_ALL);
645
_usbd_stall_reset_ep1(USB_DIR_OUT, USB_EP_CFG_RESET); // EP1 Bulk OUT.
646
_usbd_stall_reset_ep1(USB_DIR_IN, USB_EP_CFG_RESET); // EP1 Bulk IN.
647
_usbd_disable_ep1();
648
649
usbd_otg->config_num = 0;
650
usbd_otg->interface_num = 0;
651
usbd_otg->configuration_set = false;
652
usbd_otg->max_lun_set = false;
653
}
654
655
void usbd_end(bool reset_ep, bool only_controller)
656
{
657
if (reset_ep)
658
_usb_reset_disable_ep1();
659
660
// Stop device controller.
661
usbd_otg->regs->usbcmd &= ~USB2D_USBCMD_RUN;
662
663
// Enable PHY auto low power suspend.
664
usbd_otg->regs->hostpc1_devlc |= USB2D_HOSTPC1_DEVLC_ASUS;
665
666
if (!only_controller)
667
_usb_device_power_down();
668
}
669
670
static void _usbd_mark_ep_complete(u32 endpoint)
671
{
672
u32 complete_bit;
673
usb_hw_ep_t actual_ep = (endpoint & 2) >> 1;
674
usb_dir_t direction = endpoint & 1;
675
676
usbd_flush_endpoint(endpoint);
677
678
memset((void *)&usbdaemon->dtds[endpoint * 4], 0, sizeof(dTD_t) * 4);
679
memset((void *)&usbdaemon->qhs[endpoint], 0, sizeof(dQH_t));
680
681
usbdaemon->ep_configured[endpoint] = 0;
682
usbdaemon->ep_bytes_requested[endpoint] = 0;
683
684
if (direction == USB_DIR_IN)
685
complete_bit = USB2D_ENDPT_STATUS_TX_OFFSET << actual_ep;
686
else
687
complete_bit = USB2D_ENDPT_STATUS_RX_OFFSET << actual_ep;
688
689
usbd_otg->regs->endptcomplete |= complete_bit;
690
}
691
692
static usb_ep_status_t _usbd_get_ep_status(usb_ep_t endpoint)
693
{
694
bool status;
695
u32 reg_val;
696
u32 reg_mask;
697
u32 actual_ep = (endpoint & 2) >> 1;
698
usb_dir_t direction = endpoint & 1;
699
700
if (direction == USB_DIR_IN)
701
reg_mask = USB2D_ENDPT_STATUS_TX_OFFSET << actual_ep;
702
else
703
reg_mask = USB2D_ENDPT_STATUS_RX_OFFSET << actual_ep;
704
705
if (actual_ep == USB_HW_EP1)
706
reg_val = usbd_otg->regs->endptctrl[1];
707
else
708
reg_val = usbd_otg->regs->endptctrl[0];
709
710
// Check stalled status.
711
if (direction == USB_DIR_IN)
712
status = reg_val & USB2D_ENDPTCTRL_TX_EP_STALL;
713
else
714
status = reg_val & USB2D_ENDPTCTRL_RX_EP_STALL;
715
716
if (status)
717
return USB_EP_STATUS_STALLED;
718
719
// Check enabled status.
720
if (direction == USB_DIR_IN)
721
status = reg_val & USB2D_ENDPTCTRL_TX_EP_ENABLE;
722
else
723
status = reg_val & USB2D_ENDPTCTRL_RX_EP_ENABLE;
724
725
if (!status)
726
return USB_EP_STATUS_DISABLED;
727
728
// CHeck qHD error status.
729
u32 token_error_mask = USB_QHD_TOKEN_HALTED | USB_QHD_TOKEN_BUFFER_ERROR | USB_QHD_TOKEN_XFER_ERROR;
730
if (usbdaemon->qhs[endpoint].token & token_error_mask)
731
return USB_EP_STATUS_ERROR;
732
733
// Check if endpoint has a request or a ready buffer.
734
if ((usbd_otg->regs->endptprime & reg_mask) || (usbd_otg->regs->endptstatus & reg_mask))
735
return USB_EP_STATUS_ACTIVE; // RX/TX active.
736
737
// Return idle or not configured status.
738
if (!usbdaemon->ep_configured[endpoint])
739
return USB_EP_STATUS_NO_CONFIG;
740
741
return USB_EP_STATUS_IDLE;
742
}
743
744
static int _usbd_ep_operation(usb_ep_t endpoint, u8 *buf, u32 len, u32 sync_timeout)
745
{
746
if (!buf)
747
len = 0;
748
749
u32 prime_bit;
750
usb_hw_ep_t actual_ep = (endpoint & 2) >> 1;
751
usb_dir_t direction = endpoint & 1;
752
u32 length_left = len;
753
u32 dtd_ep_idx = endpoint * 4;
754
755
_usbd_mark_ep_complete(endpoint);
756
757
if (endpoint == USB_EP_CTRL_OUT)
758
usbdaemon->qhs[endpoint].ep_capabilities = USB_QHD_EP_CAP_IOS_ENABLE;
759
760
u32 max_packet_len = _usbd_get_max_pkt_length(endpoint) & USB_QHD_EP_CAP_MAX_PKT_LEN_MASK;
761
usbdaemon->qhs[endpoint].ep_capabilities |= (max_packet_len << 16) | USB_QHD_EP_CAP_ZERO_LEN_TERM_DIS;
762
usbdaemon->qhs[endpoint].next_dTD_ptr = 0; // Clear terminate bit.
763
//usbdaemon->qhs[endpoint].ep_capabilities |= USB_QHD_TOKEN_IRQ_ON_COMPLETE;
764
765
usbdaemon->ep_configured[endpoint] = 1;
766
usbdaemon->ep_bytes_requested[endpoint] = len;
767
768
// Configure dTD.
769
u32 dtd_idx = 0;
770
do
771
{
772
if (dtd_idx)
773
usbdaemon->dtds[dtd_ep_idx + dtd_idx - 1].next_dTD = (u32)&usbdaemon->dtds[dtd_ep_idx + dtd_idx];
774
775
u32 dtd_size = MIN(length_left, USB_TD_BUFFER_MAX_SIZE); // 16KB max per dTD.
776
usbdaemon->dtds[dtd_ep_idx + dtd_idx].info = (dtd_size << 16) | USB_QHD_TOKEN_ACTIVE;
777
// usbdaemon->dtds[dtd_ep_idx + dtd_idx].info |= USB_QHD_TOKEN_IRQ_ON_COMPLETE;
778
779
// Set buffers addresses to all page pointers.
780
u32 dt_buffer_offset = dtd_idx * USB_TD_BUFFER_MAX_SIZE;
781
for (u32 i = 0; i < 4; i++)
782
usbdaemon->dtds[dtd_ep_idx + dtd_idx].pages[i] = !buf ? 0 :
783
(u32)&buf[dt_buffer_offset + (USB_TD_BUFFER_PAGE_SIZE * i)];
784
785
//usbdaemon->dtds[dtd_ep_idx + dtd_idx].pages[5] =
786
// (u32)&buf[dt_buffer_offset + (USB_TD_BUFFER_PAGE_SIZE * 4)]; // Last buffer. Unused.
787
788
length_left -= dtd_size;
789
if (length_left)
790
dtd_idx++;
791
}
792
while (length_left);
793
794
// Last dTD, terminate it.
795
usbdaemon->dtds[dtd_ep_idx + dtd_idx].next_dTD = 1;
796
797
// Set first dTD address to queue head next dTD.
798
usbdaemon->qhs[endpoint].next_dTD_ptr |= (u32)&usbdaemon->dtds[dtd_ep_idx] & 0xFFFFFFE0;
799
800
// Flush AHB prefetcher.
801
AHB_GIZMO(AHB_AHB_MEM_PREFETCH_CFG1) &= ~MEM_PREFETCH_ENABLE;
802
AHB_GIZMO(AHB_AHB_MEM_PREFETCH_CFG1) |= MEM_PREFETCH_ENABLE;
803
804
if (direction == USB_DIR_IN)
805
prime_bit = USB2D_ENDPT_STATUS_TX_OFFSET << actual_ep;
806
else
807
prime_bit = USB2D_ENDPT_STATUS_RX_OFFSET << actual_ep;
808
809
// Flush data before priming EP.
810
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLEAN_WAY, false);
811
812
// Prime endpoint.
813
usbd_otg->regs->endptprime |= prime_bit; // USB2_CONTROLLER_USB2D_ENDPTPRIME.
814
815
int res = USB_RES_OK;
816
usb_ep_status_t ep_status;
817
if (sync_timeout)
818
{
819
ep_status = _usbd_get_ep_status(endpoint);
820
if (ep_status == USB_EP_STATUS_ACTIVE)
821
{
822
u32 retries = sync_timeout;
823
while (retries)
824
{
825
ep_status = _usbd_get_ep_status(endpoint);
826
if (ep_status != USB_EP_STATUS_ACTIVE)
827
{
828
if (ep_status == USB_EP_STATUS_DISABLED)
829
res = USB2_ERROR_XFER_EP_DISABLED;
830
goto out;
831
}
832
retries--;
833
usleep(1);
834
}
835
res = USB_ERROR_TIMEOUT;
836
}
837
else if (ep_status == USB_EP_STATUS_DISABLED)
838
res = USB2_ERROR_XFER_EP_DISABLED;
839
out:
840
if (res)
841
_usbd_mark_ep_complete(endpoint);
842
else if (_usbd_get_ep_status(endpoint) != USB_EP_STATUS_IDLE)
843
res = USB_ERROR_XFER_ERROR;
844
845
// Invalidate data after OP is done.
846
if (direction == USB_DIR_OUT)
847
bpmp_mmu_maintenance(BPMP_MMU_MAINT_INVALID_WAY, false);
848
}
849
850
return res;
851
}
852
853
static int _usbd_ep_ack(usb_ep_t ep)
854
{
855
return _usbd_ep_operation(ep, NULL, 0, USB_XFER_SYNCED_ENUM);
856
}
857
858
static void _usbd_set_ep0_stall()
859
{
860
// EP Control endpoints must be always stalled together.
861
usbd_otg->regs->endptctrl[0] = USB2D_ENDPTCTRL_TX_EP_ENABLE | USB2D_ENDPTCTRL_TX_EP_STALL |
862
USB2D_ENDPTCTRL_RX_EP_ENABLE | USB2D_ENDPTCTRL_RX_EP_STALL;
863
}
864
865
int usbd_set_ep_stall(u32 endpoint, int ep_stall)
866
{
867
usb_hw_ep_t actual_ep = (endpoint & 2) >> 1;
868
usb_dir_t direction = endpoint & 1;
869
870
if (ep_stall)
871
{
872
if (direction == USB_DIR_IN)
873
usbd_otg->regs->endptctrl[actual_ep] |= USB2D_ENDPTCTRL_TX_EP_STALL; // Stall EP Bulk IN.
874
else
875
usbd_otg->regs->endptctrl[actual_ep] |= USB2D_ENDPTCTRL_RX_EP_STALL; // Stall EP Bulk OUT.
876
}
877
else
878
{
879
if (direction == USB_DIR_IN)
880
usbd_otg->regs->endptctrl[actual_ep] &= ~USB2D_ENDPTCTRL_TX_EP_STALL; // Clear stall EP Bulk IN.
881
else
882
usbd_otg->regs->endptctrl[actual_ep] &= ~USB2D_ENDPTCTRL_RX_EP_STALL; // Clear stall EP Bulk OUT.
883
}
884
885
return USB_RES_OK;
886
}
887
888
static void _usbd_handle_get_class_request(bool *transmit_data, u8 *desc, int *size, bool *ep_stall)
889
{
890
u8 _bRequest = usbd_otg->control_setup.bRequest;
891
u16 _wIndex = usbd_otg->control_setup.wIndex;
892
u16 _wValue = usbd_otg->control_setup.wValue;
893
u16 _wLength = usbd_otg->control_setup.wLength;
894
895
bool valid_interface = _wIndex == usbd_otg->interface_num;
896
bool valid_val = (_bRequest >= USB_REQUEST_BULK_GET_MAX_LUN) ? (!_wValue) : true;
897
898
if (!valid_interface || !valid_val)
899
{
900
*ep_stall = true;
901
return;
902
}
903
904
switch (_bRequest)
905
{
906
case USB_REQUEST_INTR_GET_REPORT:
907
if (usbd_otg->hid_rpt_size != _wLength)
908
break;
909
910
// _wValue unused as there's only one report type and id.
911
*transmit_data = true;
912
*size = usbd_otg->hid_rpt_size;
913
memcpy(desc, usbd_otg->hid_rpt_buffer, usbd_otg->hid_rpt_size);
914
return;
915
916
case USB_REQUEST_INTR_SET_IDLE:
917
if (_wLength)
918
break;
919
920
usbd_otg->intr_idle_rate = (_wValue & 0xFF) * 4 * 1000; // Only one interface so upper byte ignored.
921
usbd_otg->intr_idle_req = true;
922
_usbd_ep_ack(USB_EP_CTRL_IN);
923
return; // DELAYED_STATUS;
924
925
case USB_REQUEST_BULK_RESET:
926
if (_wLength)
927
break;
928
929
_usbd_ep_ack(USB_EP_CTRL_IN);
930
usbd_otg->bulk_reset_req = true;
931
return; // DELAYED_STATUS;
932
933
case USB_REQUEST_BULK_GET_MAX_LUN:
934
if (_wLength != 1)
935
break;
936
937
*transmit_data = true;
938
*size = 1;
939
desc[0] = usbd_otg->max_lun; // Set 0 LUN for 1 drive supported.
940
usbd_otg->max_lun_set = true;
941
return;
942
943
default:
944
break;
945
}
946
947
*ep_stall = true;
948
}
949
950
static void _usbd_handle_get_descriptor(bool *transmit_data, void **desc, int *size, bool *ep_stall)
951
{
952
u8 descriptor_type = usbd_otg->control_setup.wValue >> 8;
953
u8 descriptor_subtype = usbd_otg->control_setup.wValue & 0xFF;
954
955
switch (descriptor_type)
956
{
957
case USB_DESCRIPTOR_DEVICE:
958
{
959
/*
960
u32 soc_rev = APB_MISC(APB_MISC_GP_HIDREV);
961
usb_device_descriptor.idProduct = (soc_rev >> 8) & 0xFF; // chip_id.
962
usb_device_descriptor.idProduct |= ((soc_rev << 4) | (FUSE(FUSE_SKU_INFO) & 0xF)) << 8; // HIDFAM.
963
usb_device_descriptor.bcdDevice = (soc_rev >> 16) & 0xF; // MINORREV.
964
usb_device_descriptor.bcdDevice |= ((soc_rev >> 4) & 0xF) << 8; // MAJORREV.
965
*/
966
*desc = usbd_otg->desc->dev;
967
*size = usbd_otg->desc->dev->bLength;
968
*transmit_data = true;
969
return;
970
}
971
case USB_DESCRIPTOR_CONFIGURATION:
972
if (usbd_otg->gadget == USB_GADGET_UMS)
973
{
974
if (usbd_otg->port_speed == USB_HIGH_SPEED) // High speed. 512 bytes.
975
{
976
for (u32 i = 0; i < usbd_otg->desc->cfg->interface.bNumEndpoints; i++)
977
usbd_otg->desc->cfg->endpoint[i].wMaxPacketSize = 0x200; // No burst.
978
}
979
else // Full speed. 64 bytes.
980
{
981
for (u32 i = 0; i < usbd_otg->desc->cfg->interface.bNumEndpoints; i++)
982
usbd_otg->desc->cfg->endpoint[i].wMaxPacketSize = 0x40;
983
}
984
}
985
else
986
{
987
usb_cfg_hid_descr_t *tmp = (usb_cfg_hid_descr_t *)usbd_otg->desc->cfg;
988
if (usbd_otg->port_speed == USB_HIGH_SPEED) // High speed. 512 bytes.
989
{
990
for (u32 i = 0; i < tmp->interface.bNumEndpoints; i++)
991
{
992
tmp->endpoint[i].wMaxPacketSize = 0x200;
993
tmp->endpoint[i].bInterval = usbd_otg->gadget == USB_GADGET_HID_GAMEPAD ? 4 : 3; // 8ms : 4ms.
994
}
995
}
996
else // Full speed. 64 bytes.
997
{
998
for (u32 i = 0; i < tmp->interface.bNumEndpoints; i++)
999
{
1000
tmp->endpoint[i].wMaxPacketSize = 0x40;
1001
tmp->endpoint[i].bInterval = usbd_otg->gadget == USB_GADGET_HID_GAMEPAD ? 8 : 4; // 8ms : 4ms.
1002
}
1003
}
1004
}
1005
*desc = usbd_otg->desc->cfg;
1006
*size = usbd_otg->desc->cfg->config.wTotalLength;
1007
*transmit_data = true;
1008
return;
1009
case USB_DESCRIPTOR_STRING:
1010
switch (descriptor_subtype)
1011
{
1012
case 1:
1013
*desc = usbd_otg->desc->vendor;
1014
*size = usbd_otg->desc->vendor[0];
1015
break;
1016
case 2:
1017
*desc = usbd_otg->desc->product;
1018
*size = usbd_otg->desc->product[0];
1019
break;
1020
case 3:
1021
*desc = usbd_otg->desc->serial;
1022
*size = usbd_otg->desc->serial[0];
1023
break;
1024
case 0xEE:
1025
*desc = usbd_otg->desc->ms_os;
1026
*size = usbd_otg->desc->ms_os->bLength;
1027
break;
1028
default:
1029
*desc = usbd_otg->desc->lang_id;
1030
*size = 4;
1031
break;
1032
}
1033
*transmit_data = true;
1034
return;
1035
case USB_DESCRIPTOR_DEVICE_QUALIFIER:
1036
if (!usbd_otg->desc->dev_qual)
1037
goto exit;
1038
usbd_otg->desc->dev_qual->bNumOtherConfigs = 1;
1039
*desc = usbd_otg->desc->dev_qual;
1040
*size = usbd_otg->desc->dev_qual->bLength;
1041
*transmit_data = true;
1042
return;
1043
case USB_DESCRIPTOR_OTHER_SPEED_CONFIGURATION:
1044
if (!usbd_otg->desc->cfg_other)
1045
goto exit;
1046
if (usbd_otg->port_speed == USB_HIGH_SPEED)
1047
{
1048
for (u32 i = 0; i < usbd_otg->desc->cfg_other->interface.bNumEndpoints; i++)
1049
usbd_otg->desc->cfg_other->endpoint[i].wMaxPacketSize = 0x40;
1050
}
1051
else
1052
{
1053
for (u32 i = 0; i < usbd_otg->desc->cfg_other->interface.bNumEndpoints; i++)
1054
usbd_otg->desc->cfg_other->endpoint[i].wMaxPacketSize = 0x200;
1055
}
1056
if ((usbd_otg->charger_detect & 1) && (usbd_otg->charger_detect & 2))
1057
usbd_otg->desc->cfg_other->config.bMaxPower = 500 / 2;
1058
*desc = usbd_otg->desc->cfg_other;
1059
*size = usbd_otg->desc->cfg_other->config.wTotalLength;
1060
*transmit_data = true;
1061
return;
1062
case USB_DESCRIPTOR_DEVICE_BINARY_OBJECT:
1063
*desc = usbd_otg->desc->dev_bot;
1064
*size = usbd_otg->desc->dev_bot->wTotalLength;
1065
*transmit_data = true;
1066
return;
1067
default:
1068
*transmit_data = false;
1069
*ep_stall = true;
1070
return;
1071
}
1072
exit:
1073
*transmit_data = false;
1074
*ep_stall = true;
1075
return;
1076
}
1077
1078
static int _usbd_handle_set_request(bool *ep_stall)
1079
{
1080
int res = USB_RES_OK;
1081
u8 bRequest = usbd_otg->control_setup.bRequest;
1082
if (bRequest == USB_REQUEST_SET_ADDRESS)
1083
{
1084
res = _usbd_ep_ack(USB_EP_CTRL_IN);
1085
1086
// Set USB address for device mode.
1087
if (!res)
1088
usbd_otg->regs->periodiclistbase = (usbd_otg->regs->periodiclistbase & 0x1FFFFFF) | ((usbd_otg->control_setup.wValue & 0xFF) << 25);
1089
}
1090
else if (bRequest == USB_REQUEST_SET_CONFIGURATION)
1091
{
1092
res = _usbd_ep_ack(USB_EP_CTRL_IN);
1093
if (!res)
1094
{
1095
usbd_otg->config_num = usbd_otg->control_setup.wValue;
1096
1097
// Remove configuration.
1098
if (!usbd_otg->config_num)
1099
{
1100
//! TODO: Signal that to userspace.
1101
_usb_reset_disable_ep1();
1102
return res;
1103
}
1104
1105
// Initialize configuration.
1106
_usbd_initialize_ep_ctrl(USB_EP_BULK_OUT);
1107
_usbd_initialize_ep_ctrl(USB_EP_BULK_IN);
1108
usbd_otg->configuration_set = true;
1109
}
1110
}
1111
else
1112
*ep_stall = true;
1113
1114
return res;
1115
}
1116
1117
static int _usbd_handle_ep0_control_transfer()
1118
{
1119
int res = USB_RES_OK;
1120
bool ep_stall = false;
1121
bool transmit_data = false;
1122
1123
u8 *desc = (u8 *)USB_DESCRIPTOR_ADDR;
1124
int size = 0;
1125
1126
u8 _bmRequestType = usbd_otg->control_setup.bmRequestType;
1127
u8 _bRequest = usbd_otg->control_setup.bRequest;
1128
u16 _wValue = usbd_otg->control_setup.wValue;
1129
u16 _wIndex = usbd_otg->control_setup.wIndex;
1130
u16 _wLength = usbd_otg->control_setup.wLength;
1131
1132
//gfx_printf("%02X %02X %04X %04X %04X\n", _bmRequestType, _bRequest, _wValue, _wIndex, _wLength);
1133
1134
switch (_bmRequestType)
1135
{
1136
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_DEVICE): // 0x00.
1137
res = _usbd_handle_set_request(&ep_stall);
1138
break;
1139
1140
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_INTERFACE): // 0x01.
1141
res = _usbd_ep_ack(USB_EP_CTRL_IN);
1142
if (!res)
1143
usbd_otg->interface_num = _wValue;
1144
break;
1145
1146
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_ENDPOINT): // 0x02.
1147
switch (_bRequest)
1148
{
1149
case USB_REQUEST_CLEAR_FEATURE:
1150
case USB_REQUEST_SET_FEATURE:
1151
if ((_wValue & 0xFF) == USB_FEATURE_ENDPOINT_HALT)
1152
{
1153
int direction;
1154
switch (_wIndex) // endpoint
1155
{
1156
case USB_EP_ADDR_CTRL_OUT:
1157
direction = 2;
1158
break;
1159
case USB_EP_ADDR_CTRL_IN:
1160
direction = 3;
1161
break;
1162
case USB_EP_ADDR_BULK_OUT:
1163
direction = 0;
1164
break;
1165
case USB_EP_ADDR_BULK_IN:
1166
direction = 1;
1167
break;
1168
default:
1169
_usbd_stall_reset_ep1(3, USB_EP_CFG_STALL);
1170
goto out;
1171
}
1172
1173
if (_bRequest == USB_REQUEST_CLEAR_FEATURE)
1174
_usbd_stall_reset_ep1(direction, USB_EP_CFG_RESET);
1175
else
1176
_usbd_stall_reset_ep1(direction, USB_EP_CFG_STALL);
1177
1178
res = _usbd_ep_ack(USB_EP_CTRL_IN);
1179
}
1180
else
1181
_usbd_stall_reset_ep1(3, USB_EP_CFG_STALL);
1182
1183
break;
1184
default:
1185
ep_stall = true;
1186
break;
1187
}
1188
break;
1189
1190
case (USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_CLASS | USB_SETUP_RECIPIENT_INTERFACE): // 0x21.
1191
memset(desc, 0, _wLength);
1192
_usbd_handle_get_class_request(&transmit_data, desc, &size, &ep_stall);
1193
break;
1194
1195
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_DEVICE): // 0x80.
1196
switch (_bRequest)
1197
{
1198
case USB_REQUEST_GET_STATUS:
1199
desc[0] = USB_STATUS_DEV_SELF_POWERED;
1200
desc[1] = 0; // No support for remove wake up.
1201
transmit_data = true;
1202
size = 2;
1203
break;
1204
case USB_REQUEST_GET_DESCRIPTOR:
1205
_usbd_handle_get_descriptor(&transmit_data, (void **)&desc, &size, &ep_stall);
1206
break;
1207
case USB_REQUEST_GET_CONFIGURATION:
1208
desc = (u8 *)&usbd_otg->config_num;
1209
size = _wLength;
1210
transmit_data = true;
1211
break;
1212
default:
1213
ep_stall = true;
1214
break;
1215
}
1216
break;
1217
1218
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_INTERFACE): // 0x81.
1219
if (_bRequest == USB_REQUEST_GET_INTERFACE)
1220
{
1221
memset(desc, 0, _wLength);
1222
desc[0] = usbd_otg->interface_num;
1223
size = _wLength;
1224
}
1225
else if (_bRequest == USB_REQUEST_GET_STATUS)
1226
{
1227
memset(desc, 0, _wLength);
1228
size = _wLength;
1229
}
1230
else if (_bRequest == USB_REQUEST_GET_DESCRIPTOR && (_wValue >> 8) == USB_DESCRIPTOR_HID_REPORT && usbd_otg->gadget >= USB_GADGET_HID_GAMEPAD)
1231
{
1232
if (usbd_otg->gadget == USB_GADGET_HID_GAMEPAD)
1233
{
1234
desc = (u8 *)&hid_report_descriptor_jc;
1235
size = hid_report_descriptor_jc_size;
1236
}
1237
else // USB_GADGET_HID_TOUCHPAD
1238
{
1239
desc = (u8 *)&hid_report_descriptor_touch;
1240
size = hid_report_descriptor_touch_size;
1241
}
1242
1243
usbd_otg->hid_report_sent = true;
1244
}
1245
else
1246
{
1247
ep_stall = true;
1248
break;
1249
}
1250
1251
if (_wLength < size)
1252
size = _wLength;
1253
transmit_data = true;
1254
break;
1255
1256
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_ENDPOINT): // 0x82.
1257
if (_bRequest == USB_REQUEST_GET_STATUS)
1258
{
1259
int ep_req;
1260
switch (_wIndex)
1261
{
1262
case USB_EP_ADDR_CTRL_OUT:
1263
ep_req = USB_EP_CTRL_OUT;
1264
break;
1265
case USB_EP_ADDR_BULK_OUT:
1266
ep_req = USB_EP_BULK_OUT;
1267
break;
1268
case USB_EP_ADDR_CTRL_IN:
1269
ep_req = USB_EP_CTRL_IN;
1270
break;
1271
case USB_EP_ADDR_BULK_IN:
1272
ep_req = USB_EP_BULK_IN;
1273
break;
1274
default:
1275
_usbd_stall_reset_ep1(3, USB_EP_CFG_STALL);
1276
goto out;
1277
}
1278
1279
size = _wLength;
1280
memset(desc, 0, size);
1281
1282
if (_usbd_get_ep_status(ep_req) == USB_EP_STATUS_STALLED)
1283
desc[0] = USB_STATUS_EP_HALTED;
1284
else
1285
desc[0] = USB_STATUS_EP_OK;
1286
1287
transmit_data = true;
1288
}
1289
else
1290
_usbd_stall_reset_ep1(3, USB_EP_CFG_STALL);
1291
break;
1292
1293
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_CLASS | USB_SETUP_RECIPIENT_INTERFACE): // 0xA1.
1294
memset(desc, 0, _wLength);
1295
_usbd_handle_get_class_request(&transmit_data, desc, &size, &ep_stall);
1296
break;
1297
1298
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_VENDOR | USB_SETUP_RECIPIENT_DEVICE): // 0xC0.
1299
case (USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_VENDOR | USB_SETUP_RECIPIENT_INTERFACE): // 0xC1.
1300
if (_bRequest == USB_REQUEST_GET_MS_DESCRIPTOR)
1301
{
1302
switch (_wIndex)
1303
{
1304
case USB_DESCRIPTOR_MS_COMPAT_ID:
1305
desc = (u8 *)usbd_otg->desc->ms_cid;
1306
size = usbd_otg->desc->ms_cid->dLength;
1307
transmit_data = true;
1308
break;
1309
case USB_DESCRIPTOR_MS_EXTENDED_PROPERTIES:
1310
desc = (u8 *)usbd_otg->desc->mx_ext;
1311
size = usbd_otg->desc->mx_ext->dLength;
1312
transmit_data = true;
1313
break;
1314
default:
1315
ep_stall = true;
1316
break;
1317
}
1318
}
1319
else
1320
ep_stall = true;
1321
break;
1322
1323
default:
1324
ep_stall = true;
1325
break;
1326
}
1327
1328
// Transmit data to HOST if any.
1329
if (transmit_data)
1330
{
1331
memcpy(usb_ep0_ctrl_buf, desc, size);
1332
1333
if (_wLength < size)
1334
size = _wLength;
1335
res = _usbd_ep_operation(USB_EP_CTRL_IN, usb_ep0_ctrl_buf, size, USB_XFER_SYNCED_ENUM);
1336
if (!res)
1337
res = _usbd_ep_ack(USB_EP_CTRL_OUT);
1338
}
1339
1340
out:
1341
if (ep_stall)
1342
_usbd_set_ep0_stall();
1343
1344
return res;
1345
}
1346
1347
static int _usbd_ep0_initialize()
1348
{
1349
bool enter = false;
1350
if (usbd_otg->configuration_set)
1351
enter = true;
1352
else
1353
{
1354
usbdaemon->qhs = (volatile dQH_t *)USB2_QH_USB2D_QH_EP_BASE;
1355
1356
if (!_usbd_initialize_ep0())
1357
enter = true;
1358
}
1359
1360
if (enter)
1361
{
1362
usbd_otg->configuration_set = false;
1363
usbd_otg->max_lun_set = false;
1364
1365
// Timeout if cable or communication isn't started in 1.5 minutes.
1366
u32 timer = get_tmr_ms() + 90000;
1367
while (true)
1368
{
1369
u32 usb_status_irqs = usbd_otg->regs->usbsts;
1370
1371
// Clear all interrupt statuses.
1372
usbd_otg->regs->usbsts = usb_status_irqs;
1373
1374
// Check if a reset was received.
1375
if (usb_status_irqs & USB2D_USBSTS_URI)
1376
{
1377
//_disable_usb_wdt4();
1378
1379
// Clear all device addresses, enabled setup requests, transmit events and flush all endpoints.
1380
usbd_otg->regs->periodiclistbase = 0;
1381
usbd_otg->regs->endptsetupstat = usbd_otg->regs->endptsetupstat;
1382
usbd_otg->regs->endptcomplete = usbd_otg->regs->endptcomplete;
1383
usbd_flush_endpoint(USB_EP_ALL);
1384
}
1385
1386
// Check if port change happened.
1387
if (usb_status_irqs & USB2D_USBSTS_PCI)
1388
usbd_otg->port_speed = (usbd_otg->regs->hostpc1_devlc & USB2D_HOSTPC1_DEVLC_PSPD_MASK) >> 25;
1389
1390
// Acknowledge setup request for EP0 and copy its configuration.
1391
u32 ep0_setup_req = usbd_otg->regs->endptsetupstat;
1392
if (ep0_setup_req & 1)
1393
{
1394
usbd_otg->regs->endptsetupstat = ep0_setup_req;
1395
memcpy(&usbd_otg->control_setup, (void *)usbdaemon->qhs->setup, 8);
1396
if (_usbd_handle_ep0_control_transfer())
1397
break;
1398
}
1399
if (usbd_otg->configuration_set)
1400
return USB_RES_OK;
1401
1402
if (timer < get_tmr_ms() || btn_read_vol() == (BTN_VOL_UP | BTN_VOL_DOWN))
1403
return USB_ERROR_USER_ABORT;
1404
}
1405
}
1406
1407
return USB_ERROR_TIMEOUT;
1408
}
1409
1410
int usb_device_enumerate(usb_gadget_type gadget)
1411
{
1412
switch (gadget)
1413
{
1414
case USB_GADGET_UMS:
1415
usbd_otg->desc = &usb_gadget_ums_descriptors;
1416
break;
1417
case USB_GADGET_HID_GAMEPAD:
1418
usbd_otg->desc = &usb_gadget_hid_jc_descriptors;
1419
break;
1420
case USB_GADGET_HID_TOUCHPAD:
1421
usbd_otg->desc = &usb_gadget_hid_touch_descriptors;
1422
break;
1423
}
1424
1425
usbd_otg->gadget = gadget;
1426
1427
return _usbd_ep0_initialize();
1428
}
1429
1430
int usbd_handle_ep0_ctrl_setup(u32 *data)
1431
{
1432
// Acknowledge setup request for EP0 and copy its configuration.
1433
u32 ep0_setup_req = usbd_otg->regs->endptsetupstat;
1434
if (ep0_setup_req & 1)
1435
{
1436
usbd_otg->regs->endptsetupstat = ep0_setup_req;
1437
memcpy(&usbd_otg->control_setup, (void *)usbdaemon->qhs->setup, 8);
1438
_usbd_handle_ep0_control_transfer();
1439
memset(usb_ep0_ctrl_buf, 0, USB_TD_BUFFER_PAGE_SIZE);
1440
}
1441
1442
if (usbd_otg->intr_idle_req)
1443
{
1444
if (data)
1445
*data = usbd_otg->intr_idle_rate;
1446
1447
usbd_otg->intr_idle_req = false;
1448
return USB_RES_OK;
1449
}
1450
1451
// Only return error if bulk reset was requested.
1452
if (usbd_otg->bulk_reset_req)
1453
{
1454
usbd_otg->bulk_reset_req = false;
1455
return USB_RES_BULK_RESET;
1456
}
1457
1458
return USB_RES_OK;
1459
}
1460
1461
static usb_ep_status_t _usbd_get_ep1_status(usb_dir_t dir)
1462
{
1463
usb_ep_t ep;
1464
if (dir == USB_DIR_OUT)
1465
ep = USB_EP_BULK_OUT;
1466
else
1467
ep = USB_EP_BULK_IN;
1468
return _usbd_get_ep_status(ep);
1469
}
1470
1471
int usb_device_ep1_out_read(u8 *buf, u32 len, u32 *bytes_read, u32 sync_timeout)
1472
{
1473
if ((u32)buf % USB_EP_BUFFER_ALIGN)
1474
return USB2_ERROR_XFER_NOT_ALIGNED;
1475
1476
if (len > USB_EP_BUFFER_MAX_SIZE)
1477
len = USB_EP_BUFFER_MAX_SIZE;
1478
1479
int res = _usbd_ep_operation(USB_EP_BULK_OUT, buf, len, sync_timeout);
1480
1481
if (sync_timeout && bytes_read)
1482
*bytes_read = res ? 0 : len;
1483
1484
return res;
1485
}
1486
1487
int usb_device_ep1_out_read_big(u8 *buf, u32 len, u32 *bytes_read)
1488
{
1489
if ((u32)buf % USB_EP_BUFFER_ALIGN)
1490
return USB2_ERROR_XFER_NOT_ALIGNED;
1491
1492
if (len > USB_EP_BULK_OUT_MAX_XFER)
1493
len = USB_EP_BULK_OUT_MAX_XFER;
1494
1495
int res;
1496
u32 bytes = 0;
1497
*bytes_read = 0;
1498
u8 *buf_curr = buf;
1499
1500
while (len)
1501
{
1502
u32 len_ep = MIN(len, USB_EP_BUFFER_MAX_SIZE);
1503
1504
res = usb_device_ep1_out_read(buf_curr, len_ep, &bytes, USB_XFER_SYNCED_DATA);
1505
if (res)
1506
return res;
1507
1508
len -= len_ep;
1509
buf_curr += len_ep;
1510
*bytes_read = *bytes_read + bytes;
1511
}
1512
1513
return USB_RES_OK;
1514
}
1515
1516
static int _usbd_get_ep1_out_bytes_read()
1517
{
1518
if (_usbd_get_ep_status(USB_EP_BULK_OUT) != USB_EP_STATUS_IDLE)
1519
return 0;
1520
else
1521
return (usbdaemon->ep_bytes_requested[USB_EP_BULK_OUT] - (usbdaemon->qhs[USB_EP_BULK_OUT].token >> 16));
1522
}
1523
1524
int usb_device_ep1_out_reading_finish(u32 *pending_bytes, u32 sync_timeout)
1525
{
1526
usb_ep_status_t ep_status;
1527
do
1528
{
1529
ep_status = _usbd_get_ep1_status(USB_DIR_OUT);
1530
if ((ep_status == USB_EP_STATUS_IDLE) || (ep_status == USB_EP_STATUS_DISABLED))
1531
break;
1532
1533
usbd_handle_ep0_ctrl_setup(NULL);
1534
}
1535
while ((ep_status == USB_EP_STATUS_ACTIVE) || (ep_status == USB_EP_STATUS_STALLED));
1536
1537
*pending_bytes = _usbd_get_ep1_out_bytes_read();
1538
1539
bpmp_mmu_maintenance(BPMP_MMU_MAINT_INVALID_WAY, false);
1540
1541
if (ep_status == USB_EP_STATUS_IDLE)
1542
return USB_RES_OK;
1543
else if (ep_status == USB_EP_STATUS_DISABLED)
1544
return USB2_ERROR_XFER_EP_DISABLED;
1545
else
1546
return USB_ERROR_XFER_ERROR;
1547
}
1548
1549
int usb_device_ep1_in_write(u8 *buf, u32 len, u32 *bytes_written, u32 sync_timeout)
1550
{
1551
if ((u32)buf % USB_EP_BUFFER_ALIGN)
1552
return USB2_ERROR_XFER_NOT_ALIGNED;
1553
1554
if (len > USB_EP_BUFFER_MAX_SIZE)
1555
len = USB_EP_BUFFER_MAX_SIZE;
1556
1557
int res = _usbd_ep_operation(USB_EP_BULK_IN, buf, len, sync_timeout);
1558
1559
if (sync_timeout && bytes_written)
1560
*bytes_written = res ? 0 : len;
1561
1562
return res;
1563
}
1564
1565
static int _usbd_get_ep1_in_bytes_written()
1566
{
1567
if (_usbd_get_ep_status(USB_EP_BULK_IN) != USB_EP_STATUS_IDLE)
1568
return 0;
1569
else
1570
return (usbdaemon->ep_bytes_requested[USB_EP_BULK_IN] - (usbdaemon->qhs[USB_EP_BULK_IN].token >> 16));
1571
}
1572
1573
int usb_device_ep1_in_writing_finish(u32 *pending_bytes, u32 sync_timeout)
1574
{
1575
usb_ep_status_t ep_status;
1576
do
1577
{
1578
ep_status = _usbd_get_ep1_status(USB_DIR_IN);
1579
if ((ep_status == USB_EP_STATUS_IDLE) || (ep_status == USB_EP_STATUS_DISABLED))
1580
break;
1581
1582
usbd_handle_ep0_ctrl_setup(NULL);
1583
}
1584
while ((ep_status == USB_EP_STATUS_ACTIVE) || (ep_status == USB_EP_STATUS_STALLED));
1585
1586
*pending_bytes = _usbd_get_ep1_in_bytes_written();
1587
1588
if (ep_status == USB_EP_STATUS_IDLE)
1589
return USB_RES_OK;
1590
else if (ep_status == USB_EP_STATUS_DISABLED)
1591
return USB2_ERROR_XFER_EP_DISABLED;
1592
1593
usb_device_stall_ep1_bulk_out();
1594
return USB_ERROR_XFER_ERROR;
1595
}
1596
1597
bool usb_device_get_suspended()
1598
{
1599
bool suspended = (usbd_otg->regs->portsc1 & USB2D_PORTSC1_SUSP) == USB2D_PORTSC1_SUSP;
1600
return suspended;
1601
}
1602
1603
bool usb_device_get_port_in_sleep()
1604
{
1605
// Windows heuristic: Forces port into suspend, sleep and J-State.
1606
return (usbd_otg->regs->portsc1) == 0x885;
1607
}
1608
1609
int usb_device_class_send_max_lun(u8 max_lun)
1610
{
1611
// Timeout if get MAX_LUN request doesn't happen in 10s.
1612
u32 timer = get_tmr_ms() + 10000;
1613
1614
usbd_otg->max_lun = max_lun;
1615
1616
while (!usbd_otg->max_lun_set)
1617
{
1618
usbd_handle_ep0_ctrl_setup(NULL);
1619
if (timer < get_tmr_ms() || btn_read_vol() == (BTN_VOL_UP | BTN_VOL_DOWN))
1620
return USB_ERROR_USER_ABORT;
1621
}
1622
1623
return USB_RES_OK;
1624
}
1625
1626
int usb_device_class_send_hid_report(void *rpt_buffer, u32 rpt_size)
1627
{
1628
// Set buffers.
1629
usbd_otg->hid_rpt_buffer = rpt_buffer;
1630
usbd_otg->hid_rpt_size = rpt_size;
1631
1632
// Timeout if get GET_HID_REPORT request doesn't happen in 10s.
1633
u32 timer = get_tmr_ms() + 10000;
1634
1635
// Wait for request and transfer start.
1636
while (!usbd_otg->hid_report_sent)
1637
{
1638
usbd_handle_ep0_ctrl_setup(NULL);
1639
if (timer < get_tmr_ms() || btn_read_vol() == (BTN_VOL_UP | BTN_VOL_DOWN))
1640
return USB_ERROR_USER_ABORT;
1641
}
1642
1643
return USB_RES_OK;
1644
}
1645
1646
void usb_device_get_ops(usb_ops_t *ops)
1647
{
1648
ops->usbd_flush_endpoint = usbd_flush_endpoint;
1649
ops->usbd_set_ep_stall = usbd_set_ep_stall;
1650
ops->usbd_handle_ep0_ctrl_setup = usbd_handle_ep0_ctrl_setup;
1651
ops->usbd_end = usbd_end;
1652
ops->usb_device_init = usb_device_init;
1653
ops->usb_device_enumerate = usb_device_enumerate;
1654
ops->usb_device_class_send_max_lun = usb_device_class_send_max_lun;
1655
ops->usb_device_class_send_hid_report = usb_device_class_send_hid_report;
1656
ops->usb_device_get_suspended = usb_device_get_suspended;
1657
ops->usb_device_get_port_in_sleep = usb_device_get_port_in_sleep;
1658
1659
ops->usb_device_ep1_out_read = usb_device_ep1_out_read;
1660
ops->usb_device_ep1_out_read_big = usb_device_ep1_out_read_big;
1661
ops->usb_device_ep1_out_reading_finish = usb_device_ep1_out_reading_finish;
1662
ops->usb_device_ep1_in_write = usb_device_ep1_in_write;
1663
ops->usb_device_ep1_in_writing_finish = usb_device_ep1_in_writing_finish;
1664
}
1665
1666
1667