@@ -313,7 +313,9 @@ TU_ATTR_ALWAYS_INLINE static inline bool queue_event(dcd_event_t const * event,
313
313
static bool process_control_request (uint8_t rhport , tusb_control_request_t const * p_request );
314
314
static bool process_set_config (uint8_t rhport , uint8_t cfg_num );
315
315
static bool process_get_descriptor (uint8_t rhport , tusb_control_request_t const * p_request );
316
-
316
+ #if CFG_TUD_TEST_MODE
317
+ static bool process_test_mode_cb (uint8_t rhport , uint8_t stage , tusb_control_request_t const * request );
318
+ #endif
317
319
// from usbd_control.c
318
320
void usbd_control_reset (void );
319
321
void usbd_control_set_request (tusb_control_request_t const * request );
@@ -753,14 +755,47 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const
753
755
break ;
754
756
755
757
case TUSB_REQ_SET_FEATURE :
756
- // Only support remote wakeup for device feature
757
- TU_VERIFY (TUSB_REQ_FEATURE_REMOTE_WAKEUP == p_request -> wValue );
758
+ // Handle the feature selector
759
+ switch (p_request -> wValue )
760
+ {
761
+ // Support for remote wakeup
762
+ case TUSB_REQ_FEATURE_REMOTE_WAKEUP :
763
+ TU_LOG_USBD (" Enable Remote Wakeup\r\n" );
764
+
765
+ // Host may enable remote wake up before suspending especially HID device
766
+ _usbd_dev .remote_wakeup_en = true;
767
+ tud_control_status (rhport , p_request );
768
+ break ;
758
769
759
- TU_LOG_USBD (" Enable Remote Wakeup\r\n" );
770
+ #if CFG_TUD_TEST_MODE
771
+ // Support for TEST_MODE
772
+ case TUSB_REQ_FEATURE_TEST_MODE : {
773
+ // Only handle the test mode if supported and valid
774
+ TU_VERIFY (dcd_enter_test_mode && dcd_check_test_mode_support && 0 == tu_u16_low (p_request -> wIndex ));
760
775
761
- // Host may enable remote wake up before suspending especially HID device
762
- _usbd_dev .remote_wakeup_en = true;
763
- tud_control_status (rhport , p_request );
776
+ uint8_t selector = tu_u16_high (p_request -> wIndex );
777
+
778
+ // Stall request if the selected test mode isn't supported
779
+ if (!dcd_check_test_mode_support ((test_mode_t )selector ))
780
+ {
781
+ TU_LOG_USBD (" Unsupported Test Mode (test selector index: %d)\r\n" , selector );
782
+
783
+ return false;
784
+ }
785
+
786
+ // Acknowledge request
787
+ tud_control_status (rhport , p_request );
788
+
789
+ TU_LOG_USBD (" Enter Test Mode (test selector index: %d)\r\n" , selector );
790
+
791
+ usbd_control_set_complete_callback (process_test_mode_cb );
792
+ break ;
793
+ }
794
+ #endif /* CFG_TUD_TEST_MODE */
795
+
796
+ // Stall unsupported feature selector
797
+ default : return false;
798
+ }
764
799
break ;
765
800
766
801
case TUSB_REQ_CLEAR_FEATURE :
@@ -1088,6 +1123,20 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const
1088
1123
}
1089
1124
}
1090
1125
1126
+ #if CFG_TUD_TEST_MODE
1127
+ static bool process_test_mode_cb (uint8_t rhport , uint8_t stage , tusb_control_request_t const * request )
1128
+ {
1129
+ // At this point it should already be ensured that dcd_enter_test_mode() is defined
1130
+
1131
+ // Only enter the test mode after the request for it has completed
1132
+ TU_VERIFY (CONTROL_STAGE_ACK == stage );
1133
+
1134
+ dcd_enter_test_mode (rhport , (test_mode_t )tu_u16_high (request -> wIndex ));
1135
+
1136
+ return true;
1137
+ }
1138
+ #endif /* CFG_TUD_TEST_MODE */
1139
+
1091
1140
//--------------------------------------------------------------------+
1092
1141
// DCD Event Handler
1093
1142
//--------------------------------------------------------------------+
0 commit comments