@@ -44,6 +44,7 @@ typedef struct
44
44
uint8_t status_change ; // data from status change interrupt endpoint
45
45
46
46
hub_port_status_response_t port_status ;
47
+ hub_status_response_t hub_status ;
47
48
} hub_interface_t ;
48
49
49
50
CFG_TUSB_MEM_SECTION static hub_interface_t hub_data [CFG_TUH_HUB ];
@@ -85,7 +86,7 @@ bool hub_port_clear_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature,
85
86
{
86
87
.bmRequestType_bit =
87
88
{
88
- .recipient = TUSB_REQ_RCPT_OTHER ,
89
+ .recipient = ( hub_port == 0 ) ? TUSB_REQ_RCPT_DEVICE : TUSB_REQ_RCPT_OTHER ,
89
90
.type = TUSB_REQ_TYPE_CLASS ,
90
91
.direction = TUSB_DIR_OUT
91
92
},
@@ -117,7 +118,7 @@ bool hub_port_set_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature,
117
118
{
118
119
.bmRequestType_bit =
119
120
{
120
- .recipient = TUSB_REQ_RCPT_OTHER ,
121
+ .recipient = ( hub_port == 0 ) ? TUSB_REQ_RCPT_DEVICE : TUSB_REQ_RCPT_OTHER ,
121
122
.type = TUSB_REQ_TYPE_CLASS ,
122
123
.direction = TUSB_DIR_OUT
123
124
},
@@ -149,7 +150,7 @@ bool hub_port_get_status(uint8_t hub_addr, uint8_t hub_port, void* resp,
149
150
{
150
151
.bmRequestType_bit =
151
152
{
152
- .recipient = TUSB_REQ_RCPT_OTHER ,
153
+ .recipient = ( hub_port == 0 ) ? TUSB_REQ_RCPT_DEVICE : TUSB_REQ_RCPT_OTHER ,
153
154
.type = TUSB_REQ_TYPE_CLASS ,
154
155
.direction = TUSB_DIR_IN
155
156
},
@@ -313,7 +314,8 @@ static void config_port_power_complete (tuh_xfer_t* xfer)
313
314
// Connection Changes
314
315
//--------------------------------------------------------------------+
315
316
316
- static void connection_get_status_complete (tuh_xfer_t * xfer );
317
+ static void hub_port_get_status_complete (tuh_xfer_t * xfer );
318
+ static void hub_get_status_complete (tuh_xfer_t * xfer );
317
319
static void connection_clear_conn_change_complete (tuh_xfer_t * xfer );
318
320
static void connection_port_reset_complete (tuh_xfer_t * xfer );
319
321
@@ -326,19 +328,31 @@ bool hub_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32
326
328
327
329
hub_interface_t * p_hub = get_itf (dev_addr );
328
330
329
- TU_LOG2 (" Port Status Change = 0x%02X\r\n" , p_hub -> status_change );
331
+ TU_LOG2 (" Hub Status Change = 0x%02X\r\n" , p_hub -> status_change );
330
332
331
- // Hub ignore bit0 in status change
332
- for ( uint8_t port = 1 ; port <= p_hub -> port_count ; port ++ )
333
+ // Hub bit 0 is for the hub device events
334
+ if ( tu_bit_test ( p_hub -> status_change , 0 ) )
333
335
{
334
- if ( tu_bit_test ( p_hub -> status_change , port ) )
336
+ if (hub_port_get_status ( dev_addr , 0 , & p_hub -> hub_status , hub_get_status_complete , 0 ) == false )
335
337
{
336
- if (hub_port_get_status (dev_addr , port , & p_hub -> port_status , connection_get_status_complete , 0 ) == false)
338
+ //Hub status control transfer failed, retry
339
+ hub_edpt_status_xfer (dev_addr );
340
+ }
341
+ }
342
+ else
343
+ {
344
+ // Hub bits 1 to n are hub port events
345
+ for (uint8_t port = 1 ; port <= p_hub -> port_count ; port ++ )
346
+ {
347
+ if ( tu_bit_test (p_hub -> status_change , port ) )
337
348
{
338
- //Hub status control transfer failed, retry
339
- hub_edpt_status_xfer (dev_addr );
349
+ if (hub_port_get_status (dev_addr , port , & p_hub -> port_status , hub_port_get_status_complete , 0 ) == false)
350
+ {
351
+ //Hub status control transfer failed, retry
352
+ hub_edpt_status_xfer (dev_addr );
353
+ }
354
+ break ;
340
355
}
341
- break ;
342
356
}
343
357
}
344
358
@@ -347,7 +361,36 @@ bool hub_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32
347
361
return true;
348
362
}
349
363
350
- static void connection_get_status_complete (tuh_xfer_t * xfer )
364
+ static void hub_clear_feature_complete_stub (tuh_xfer_t * xfer )
365
+ {
366
+ TU_ASSERT (xfer -> result == XFER_RESULT_SUCCESS , );
367
+ hub_edpt_status_xfer (xfer -> daddr );
368
+ }
369
+
370
+ static void hub_get_status_complete (tuh_xfer_t * xfer )
371
+ {
372
+ TU_ASSERT (xfer -> result == XFER_RESULT_SUCCESS , );
373
+
374
+ uint8_t const daddr = xfer -> daddr ;
375
+ hub_interface_t * p_hub = get_itf (daddr );
376
+ uint8_t const port_num = (uint8_t ) tu_le16toh (xfer -> setup -> wIndex );
377
+ TU_ASSERT (port_num == 0 , );
378
+
379
+ TU_LOG2 ("HUB Got hub status, addr = %u, status = %04x\r\n" , daddr , p_hub -> hub_status .change .value );
380
+
381
+ if (p_hub -> hub_status .change .local_power_source )
382
+ {
383
+ TU_LOG2 ("HUB Local Power Change, addr = %u\r\n" , daddr );
384
+ hub_port_clear_feature (daddr , port_num , HUB_FEATURE_HUB_LOCAL_POWER_CHANGE , hub_clear_feature_complete_stub , 0 );
385
+ }
386
+ else if (p_hub -> hub_status .change .over_current )
387
+ {
388
+ TU_LOG1 ("HUB Over Current, addr = %u\r\n" , daddr );
389
+ hub_port_clear_feature (daddr , port_num , HUB_FEATURE_HUB_OVER_CURRENT_CHANGE , hub_clear_feature_complete_stub , 0 );
390
+ }
391
+ }
392
+
393
+ static void hub_port_get_status_complete (tuh_xfer_t * xfer )
351
394
{
352
395
TU_ASSERT (xfer -> result == XFER_RESULT_SUCCESS , );
353
396
@@ -365,7 +408,24 @@ static void connection_get_status_complete (tuh_xfer_t* xfer)
365
408
hub_port_clear_feature (daddr , port_num , HUB_FEATURE_PORT_CONNECTION_CHANGE , connection_clear_conn_change_complete , 0 );
366
409
}else
367
410
{
368
- // Other changes are: Enable, Suspend, Over Current, Reset, L1 state
411
+ // Clear other port status change interrupts. TODO Not currently handled - just cleared.
412
+ if (p_hub -> port_status .change .port_enable )
413
+ {
414
+ hub_port_clear_feature (daddr , port_num , HUB_FEATURE_PORT_ENABLE_CHANGE , hub_clear_feature_complete_stub , 0 );
415
+ }
416
+ else if (p_hub -> port_status .change .suspend )
417
+ {
418
+ hub_port_clear_feature (daddr , port_num , HUB_FEATURE_PORT_SUSPEND_CHANGE , hub_clear_feature_complete_stub , 0 );
419
+ }
420
+ else if (p_hub -> port_status .change .over_current )
421
+ {
422
+ hub_port_clear_feature (daddr , port_num , HUB_FEATURE_PORT_OVER_CURRENT_CHANGE , hub_clear_feature_complete_stub , 0 );
423
+ }
424
+ else if (p_hub -> port_status .change .reset )
425
+ {
426
+ hub_port_clear_feature (daddr , port_num , HUB_FEATURE_PORT_RESET_CHANGE , hub_clear_feature_complete_stub , 0 );
427
+ }
428
+ // Other changes are: L1 state
369
429
// TODO clear change
370
430
371
431
// prepare for next hub status
0 commit comments