Skip to content

Commit 51a0889

Browse files
authored
Merge pull request hathach#2211 from hathach/host-usb-reset
Host usb reset
2 parents 1b92108 + 4938971 commit 51a0889

File tree

9 files changed

+164
-161
lines changed

9 files changed

+164
-161
lines changed

hw/bsp/lpc18/boards/mcb1800/ozone/lpc1857.jdebug

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*/
1111
void OnProjectLoad (void) {
1212
Project.AddSvdFile ("Cortex-M3.svd");
13-
Project.AddSvdFile ("./LPC18xx.svd");
13+
Project.AddSvdFile ("../../../../../../../cmsis-svd/data/NXP/LPC18xx.svd");
1414

1515
Project.SetDevice ("LPC1857");
1616
Project.SetHostIF ("USB", "");
@@ -20,7 +20,8 @@ void OnProjectLoad (void) {
2020
Project.SetTraceSource ("Trace Pins");
2121
Project.SetTracePortWidth (4);
2222

23-
File.Open ("../../../../../../examples/device/cdc_msc/cmake-build-mcb1800/cdc_msc.elf");
23+
//File.Open ("../../../../../../examples/cmake-build-mcb1800/device/cdc_msc/cdc_msc.elf");
24+
File.Open ("../../../../../../examples/cmake-build-mcb1800/host/cdc_msc_hid/cdc_msc_hid.elf");
2425
}
2526
/*********************************************************************
2627
*

src/class/msc/msc_host.c

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -421,19 +421,16 @@ bool msch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *de
421421
return true;
422422
}
423423

424-
bool msch_set_config(uint8_t dev_addr, uint8_t itf_num)
425-
{
424+
bool msch_set_config(uint8_t dev_addr, uint8_t itf_num) {
426425
msch_interface_t* p_msc = get_itf(dev_addr);
427426
TU_ASSERT(p_msc->itf_num == itf_num);
428427

429428
p_msc->configured = true;
430429

431430
//------------- Get Max Lun -------------//
432431
TU_LOG_DRV("MSC Get Max Lun\r\n");
433-
tusb_control_request_t const request =
434-
{
435-
.bmRequestType_bit =
436-
{
432+
tusb_control_request_t const request = {
433+
.bmRequestType_bit = {
437434
.recipient = TUSB_REQ_RCPT_INTERFACE,
438435
.type = TUSB_REQ_TYPE_CLASS,
439436
.direction = TUSB_DIR_IN
@@ -444,12 +441,11 @@ bool msch_set_config(uint8_t dev_addr, uint8_t itf_num)
444441
.wLength = 1
445442
};
446443

447-
tuh_xfer_t xfer =
448-
{
444+
tuh_xfer_t xfer = {
449445
.daddr = dev_addr,
450446
.ep_addr = 0,
451447
.setup = &request,
452-
.buffer = &p_msc->max_lun,
448+
.buffer = _msch_buffer,
453449
.complete_cb = config_get_maxlun_complete,
454450
.user_data = 0
455451
};
@@ -467,6 +463,8 @@ static void config_get_maxlun_complete (tuh_xfer_t* xfer)
467463
p_msc->max_lun = (XFER_RESULT_SUCCESS == xfer->result) ? _msch_buffer[0] : 0;
468464
p_msc->max_lun++; // MAX LUN is minus 1 by specs
469465

466+
TU_LOG_DRV(" Max LUN = %u\r\n", p_msc->max_lun);
467+
470468
// TODO multiple LUN support
471469
TU_LOG_DRV("SCSI Test Unit Ready\r\n");
472470
uint8_t const lun = 0;

src/host/hcd.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,10 +149,11 @@ uint32_t hcd_frame_number(uint8_t rhport);
149149
// Get the current connect status of roothub port
150150
bool hcd_port_connect_status(uint8_t rhport);
151151

152-
// Reset USB bus on the port
152+
// Reset USB bus on the port. Return immediately, bus reset sequence may not be complete.
153+
// Some port would require hcd_port_reset_end() to be invoked after 10ms to complete the reset sequence.
153154
void hcd_port_reset(uint8_t rhport);
154155

155-
// TODO implement later
156+
// Complete bus reset sequence, may be required by some controllers
156157
void hcd_port_reset_end(uint8_t rhport);
157158

158159
// Get port link speed

src/host/hub.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ static void connection_port_reset_complete (tuh_xfer_t* xfer);
330330
bool hub_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) {
331331
(void) xferred_bytes; // TODO can be more than 1 for hub with lots of ports
332332
(void) ep_addr;
333-
TU_ASSERT(result == XFER_RESULT_SUCCESS);
333+
TU_VERIFY(result == XFER_RESULT_SUCCESS);
334334

335335
hub_interface_t* p_hub = get_itf(dev_addr);
336336

src/host/usbh.c

Lines changed: 62 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -181,9 +181,6 @@ static usbh_class_driver_t const usbh_class_drivers[] =
181181
};
182182

183183
enum { USBH_CLASS_DRIVER_COUNT = TU_ARRAY_SIZE(usbh_class_drivers) };
184-
185-
enum { RESET_DELAY = 500 }; // 200 USB specs say only 50ms but many devices require much longer
186-
187184
enum { CONFIG_NUM = 1 }; // default to use configuration 1
188185

189186

@@ -251,40 +248,27 @@ static bool usbh_control_xfer_cb (uint8_t daddr, uint8_t ep_addr, xfer_result_t
251248

252249
#if CFG_TUSB_OS == OPT_OS_NONE
253250
// TODO rework time-related function later
254-
TU_ATTR_WEAK void osal_task_delay(uint32_t msec)
255-
{
251+
// weak and overridable
252+
TU_ATTR_WEAK void osal_task_delay(uint32_t msec) {
256253
const uint32_t start = hcd_frame_number(_usbh_controller);
257254
while ( ( hcd_frame_number(_usbh_controller) - start ) < msec ) {}
258255
}
259256
#endif
260257

261258
//--------------------------------------------------------------------+
262-
// PUBLIC API (Parameter Verification is required)
259+
// Device API
263260
//--------------------------------------------------------------------+
264261

265-
bool tuh_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param)
266-
{
267-
if (hcd_configure)
268-
{
269-
return hcd_configure(rhport, cfg_id, cfg_param);
270-
}else
271-
{
272-
return false;
273-
}
274-
}
275-
276-
bool tuh_mounted(uint8_t dev_addr)
277-
{
278-
usbh_device_t* dev = get_device(dev_addr);
262+
bool tuh_mounted(uint8_t dev_addr) {
263+
usbh_device_t *dev = get_device(dev_addr);
279264
TU_VERIFY(dev);
280265
return dev->configured;
281266
}
282267

283-
bool tuh_vid_pid_get(uint8_t dev_addr, uint16_t* vid, uint16_t* pid)
284-
{
268+
bool tuh_vid_pid_get(uint8_t dev_addr, uint16_t *vid, uint16_t *pid) {
285269
*vid = *pid = 0;
286270

287-
usbh_device_t const* dev = get_device(dev_addr);
271+
usbh_device_t const *dev = get_device(dev_addr);
288272
TU_VERIFY(dev && dev->addressed && dev->vid != 0);
289273

290274
*vid = dev->vid;
@@ -293,26 +277,48 @@ bool tuh_vid_pid_get(uint8_t dev_addr, uint16_t* vid, uint16_t* pid)
293277
return true;
294278
}
295279

296-
tusb_speed_t tuh_speed_get (uint8_t dev_addr)
297-
{
298-
usbh_device_t* dev = get_device(dev_addr);
280+
tusb_speed_t tuh_speed_get(uint8_t dev_addr) {
281+
usbh_device_t *dev = get_device(dev_addr);
299282
return (tusb_speed_t) (dev ? get_device(dev_addr)->speed : _dev0.speed);
300283
}
301284

302-
static void clear_device(usbh_device_t* dev)
303-
{
285+
bool tuh_rhport_is_active(uint8_t rhport) {
286+
return _usbh_controller == rhport;
287+
}
288+
289+
bool tuh_rhport_reset_bus(uint8_t rhport, bool active) {
290+
TU_VERIFY(tuh_rhport_is_active(rhport));
291+
if ( active ) {
292+
hcd_port_reset(rhport);
293+
} else {
294+
hcd_port_reset_end(rhport);
295+
}
296+
return true;
297+
}
298+
299+
//--------------------------------------------------------------------+
300+
// PUBLIC API (Parameter Verification is required)
301+
//--------------------------------------------------------------------+
302+
303+
bool tuh_configure(uint8_t rhport, uint32_t cfg_id, const void *cfg_param) {
304+
if ( hcd_configure ) {
305+
return hcd_configure(rhport, cfg_id, cfg_param);
306+
} else {
307+
return false;
308+
}
309+
}
310+
311+
static void clear_device(usbh_device_t* dev) {
304312
tu_memclr(dev, sizeof(usbh_device_t));
305313
memset(dev->itf2drv, TUSB_INDEX_INVALID_8, sizeof(dev->itf2drv)); // invalid mapping
306314
memset(dev->ep2drv , TUSB_INDEX_INVALID_8, sizeof(dev->ep2drv )); // invalid mapping
307315
}
308316

309-
bool tuh_inited(void)
310-
{
317+
bool tuh_inited(void) {
311318
return _usbh_controller != TUSB_INDEX_INVALID_8;
312319
}
313320

314-
bool tuh_init(uint8_t controller_id)
315-
{
321+
bool tuh_init(uint8_t controller_id) {
316322
// skip if already initialized
317323
if ( tuh_inited() ) return true;
318324

@@ -359,8 +365,7 @@ bool tuh_init(uint8_t controller_id)
359365
return true;
360366
}
361367

362-
bool tuh_task_event_ready(void)
363-
{
368+
bool tuh_task_event_ready(void) {
364369
// Skip if stack is not initialized
365370
if ( !tuh_inited() ) return false;
366371

@@ -385,8 +390,7 @@ bool tuh_task_event_ready(void)
385390
}
386391
@endcode
387392
*/
388-
void tuh_task_ext(uint32_t timeout_ms, bool in_isr)
389-
{
393+
void tuh_task_ext(uint32_t timeout_ms, bool in_isr) {
390394
(void) in_isr; // not implemented yet
391395

392396
// Skip if stack is not initialized
@@ -403,8 +407,7 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr)
403407
case HCD_EVENT_DEVICE_ATTACH:
404408
// due to the shared _usbh_ctrl_buf, we must complete enumerating
405409
// one device before enumerating another one.
406-
if ( _dev0.enumerating )
407-
{
410+
if ( _dev0.enumerating ) {
408411
TU_LOG_USBH("[%u:] USBH Defer Attach until current enumeration complete\r\n", event.rhport);
409412

410413
bool is_empty = osal_queue_empty(_usbh_q);
@@ -414,8 +417,7 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr)
414417
// Exit if this is the only event in the queue, otherwise we may loop forever
415418
return;
416419
}
417-
}else
418-
{
420+
}else {
419421
TU_LOG_USBH("[%u:] USBH DEVICE ATTACH\r\n", event.rhport);
420422
_dev0.enumerating = 1;
421423
enum_new_device(&event);
@@ -428,8 +430,7 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr)
428430

429431
#if CFG_TUH_HUB
430432
// TODO remove
431-
if ( event.connection.hub_addr != 0)
432-
{
433+
if ( event.connection.hub_addr != 0) {
433434
// done with hub, waiting for next data on status pipe
434435
(void) hub_edpt_status_xfer( event.connection.hub_addr );
435436
}
@@ -1230,6 +1231,12 @@ static void process_removing_device(uint8_t rhport, uint8_t hub_addr, uint8_t hu
12301231
// one device before enumerating another one.
12311232
//--------------------------------------------------------------------+
12321233

1234+
enum {
1235+
ENUM_RESET_DELAY = 50, // USB specs: 10 to 50ms
1236+
ENUM_CONTACT_DEBOUNCING_DELAY = 450, // when plug/unplug a device, physical connection can be bouncing and may
1237+
// generate a series of attach/detach event. This delay wait for stable connection
1238+
};
1239+
12331240
enum {
12341241
ENUM_IDLE,
12351242
ENUM_RESET_1, // 1st reset when attached
@@ -1311,7 +1318,7 @@ static void process_enumeration(tuh_xfer_t* xfer)
13111318
break;
13121319

13131320
case ENUM_HUB_GET_STATUS_2:
1314-
osal_task_delay(RESET_DELAY);
1321+
osal_task_delay(ENUM_RESET_DELAY);
13151322
TU_ASSERT( hub_port_get_status(_dev0.hub_addr, _dev0.hub_port, _usbh_ctrl_buf, process_enumeration, ENUM_HUB_CLEAR_RESET_2), );
13161323
break;
13171324

@@ -1468,12 +1475,14 @@ static bool enum_new_device(hcd_event_t* event)
14681475
if (_dev0.hub_addr == 0)
14691476
{
14701477
// connected/disconnected directly with roothub
1471-
// wait until device is stable TODO non blocking
14721478
hcd_port_reset(_dev0.rhport);
1473-
osal_task_delay(RESET_DELAY); // TODO may not work for no-OS on MCU that require reset_end() since
1474-
// sof of controller may not running while resetting
1479+
osal_task_delay(ENUM_RESET_DELAY); // TODO may not work for no-OS on MCU that require reset_end() since
1480+
// sof of controller may not running while resetting
14751481
hcd_port_reset_end( _dev0.rhport);
14761482

1483+
// wait until device connection is stable TODO non blocking
1484+
osal_task_delay(ENUM_CONTACT_DEBOUNCING_DELAY);
1485+
14771486
// device unplugged while delaying
14781487
if ( !hcd_port_connect_status(_dev0.rhport) ) {
14791488
enum_full_complete();
@@ -1489,15 +1498,16 @@ static bool enum_new_device(hcd_event_t* event)
14891498
xfer.result = XFER_RESULT_SUCCESS;
14901499
xfer.user_data = ENUM_ADDR0_DEVICE_DESC;
14911500

1501+
14921502
process_enumeration(&xfer);
14931503

14941504
}
14951505
#if CFG_TUH_HUB
14961506
else
14971507
{
14981508
// connected/disconnected via external hub
1499-
// wait until device is stable
1500-
osal_task_delay(RESET_DELAY);
1509+
// wait until device connection is stable TODO non blocking
1510+
osal_task_delay(ENUM_CONTACT_DEBOUNCING_DELAY);
15011511

15021512
// ENUM_HUB_GET_STATUS
15031513
//TU_ASSERT( hub_port_get_status(_dev0.hub_addr, _dev0.hub_port, _usbh_ctrl_buf, enum_hub_get_status0_complete, 0) );
@@ -1508,23 +1518,19 @@ static bool enum_new_device(hcd_event_t* event)
15081518
return true;
15091519
}
15101520

1511-
static uint8_t get_new_address(bool is_hub)
1512-
{
1521+
static uint8_t get_new_address(bool is_hub) {
15131522
uint8_t start;
15141523
uint8_t end;
15151524

1516-
if ( is_hub )
1517-
{
1525+
if ( is_hub ) {
15181526
start = CFG_TUH_DEVICE_MAX;
15191527
end = start + CFG_TUH_HUB;
1520-
}else
1521-
{
1528+
}else {
15221529
start = 0;
15231530
end = start + CFG_TUH_DEVICE_MAX;
15241531
}
15251532

1526-
for (uint8_t idx = start; idx < end; idx++)
1527-
{
1533+
for (uint8_t idx = start; idx < end; idx++) {
15281534
if (!_usbh_devices[idx].connected) return (idx+1);
15291535
}
15301536

0 commit comments

Comments
 (0)