Tests: USB: Add data toggle test

pull/9768/head
Filip Jagodzinski 2018-06-07 17:19:20 +02:00 committed by Russ Butler
parent ff8a9b6ae8
commit c12e2d15f5
2 changed files with 155 additions and 1 deletions

View File

@ -290,6 +290,19 @@ class PyusbBasicTest(BaseHostTest):
except (RuntimeError) as exc:
self.report_error(exc)
def _callback_ep_test_data_toggle(self, key, value, timestamp):
self.log("Received serial %s" % (value))
dev = self.find_device(value)
if(dev == None):
return
try:
ep_test_data_toggle(dev, log=print)
self.report_success()
except (RuntimeError) as exc:
self.report_error(exc)
def _callback_reset_support(self, key, value, timestamp):
status = "false" if sys.platform == "darwin" else "true"
self.log("Reset supported: %s" % status)
@ -345,6 +358,7 @@ class PyusbBasicTest(BaseHostTest):
self.register_callback('ep_test_parallel_transfers', self._callback_ep_test_parallel_transfers)
self.register_callback('ep_test_parallel_transfers_ctrl', self._callback_ep_test_parallel_transfers_ctrl)
self.register_callback('ep_test_abort', self._callback_ep_test_abort)
self.register_callback('ep_test_data_toggle', self._callback_ep_test_data_toggle)
self.register_callback('reset_support', self._callback_reset_support)
@ -1354,6 +1368,106 @@ def ep_test_abort(dev, log, verbose=False):
NUM_PACKETS_UNTIL_ABORT * ep_out.wMaxPacketSize, payload_size))
def ep_test_data_toggle(dev, log, verbose=False):
"""Test data toggle reset for bulk OUT/IN endpoint pairs.
Given a USB device
When an interface is set
Then the data toggle bits for all endpoints are reset to DATA0
When clear feature is called for an endpoint that *IS NOT* stalled
Then the data toggle is reset to DATA0 for that endpoint
When clear halt is called for an endpoint that *IS* stalled
Then the data toggle is reset to DATA0 for that endpoint
"""
cfg = dev.get_active_configuration()
for intf in cfg:
log('interface {}, alt {} -- '.format(intf.bInterfaceNumber, intf.bAlternateSetting), end='')
if intf.bAlternateSetting == 0:
log('skipping the default AlternateSetting')
continue
log('running tests')
if verbose:
log('Testing data toggle reset for bulk endpoint pair.')
# 1.1 reset OUT and IN data toggle to DATA0
intf.set_altsetting()
bulk_out, bulk_in = find_ep_pair(intf, usb.ENDPOINT_TYPE_BULK)
# 1.2 send and receive a single data packet,
# so both OUT and IN endpoints switch to DATA1
loopback_ep_test(bulk_out, bulk_in, bulk_out.wMaxPacketSize)
# 1.3 reset OUT and IN data toggle to DATA0
# USB spec, section 9.1.1.5
# "
# Configuring a device or changing an alternate setting causes all of the status and
# configuration values associated with endpoints in the affected interfaces to be set to their default values.
# This includes setting the data toggle of any endpoint using data toggles to the value DATA0.
# "
intf.set_altsetting()
bulk_out, bulk_in = find_ep_pair(intf, usb.ENDPOINT_TYPE_BULK)
# 1.4 verify that host and USB device are still in sync with respect to data toggle
try:
loopback_ep_test(bulk_out, bulk_in, bulk_out.wMaxPacketSize)
except usb.USBError as err:
if verbose:
log(USB_ERROR_FMT.format(err, bulk_out, bulk_in, bulk_out.wMaxPacketSize))
raise_unconditionally(lineno(), 'Data toggle not reset when setting interface.')
# 2.1 reset OUT and IN data toggle to DATA0
intf.set_altsetting()
bulk_out, bulk_in = find_ep_pair(intf, usb.ENDPOINT_TYPE_BULK)
# 2.2 send and receive a single data packet,
# so both OUT and IN endpoints switch to DATA1
loopback_ep_test(bulk_out, bulk_in, bulk_out.wMaxPacketSize)
# 2.3 reset OUT data toggle to DATA0
# USB spec, section 9.4.5
# "
# For endpoints using data toggle, regardless of whether an endpoint has the Halt feature set, a
# ClearFeature(ENDPOINT_HALT) request always results in the data toggle being reinitialized to DATA0.
# "
bulk_out.clear_halt()
# request_endpoint_read_start(dev, bulk_out)
# 2.4 verify that host and USB device are still in sync with respect to data toggle
try:
loopback_ep_test(bulk_out, bulk_in, bulk_out.wMaxPacketSize)
except usb.USBError as err:
if verbose:
log(USB_ERROR_FMT.format(err, bulk_out, bulk_in, bulk_out.wMaxPacketSize))
raise_unconditionally(lineno(), 'Data toggle not reset when calling ClearFeature(ENDPOINT_HALT) '
'on an endpoint that has not been halted.')
# 3.1 reset OUT and IN data toggle to DATA0
intf.set_altsetting()
bulk_out, bulk_in = find_ep_pair(intf, usb.ENDPOINT_TYPE_BULK)
# 3.2 send and receive a single data packet,
# so both OUT and IN endpoints switch to DATA1
loopback_ep_test(bulk_out, bulk_in, bulk_out.wMaxPacketSize)
# 3.3 reset IN data toggle to DATA0
# USB spec, section 9.4.5
# "
# For endpoints using data toggle, regardless of whether an endpoint has the Halt feature set, a
# ClearFeature(ENDPOINT_HALT) request always results in the data toggle being reinitialized to DATA0.
# "
usb.control.set_feature(dev, FEATURE_ENDPOINT_HALT, bulk_in)
bulk_in.clear_halt()
# 3.4 verify that host and USB device are still in sync with respect to data toggle
try:
loopback_ep_test(bulk_out, bulk_in, bulk_out.wMaxPacketSize)
except usb.USBError as err:
if verbose:
log(USB_ERROR_FMT.format(err, bulk_out, bulk_in, bulk_out.wMaxPacketSize))
raise_unconditionally(lineno(), 'Data toggle not reset when clearing endpoint halt.')
def device_reset_test(log):
"""
Test USB implementation against repeated reset

View File

@ -385,6 +385,45 @@ void ep_test_abort()
}
}
/** Test data toggle reset for bulk OUT/IN endpoint pairs
*
* Given a USB device
* When an interface is set
* Then the data toggle bits for all endpoints are reset to DATA0
* When clear feature is called for an endpoint that *IS NOT* stalled
* Then the data toggle is reset to DATA0 for that endpoint
* When clear halt is called for an endpoint that *IS* stalled
* Then the data toggle is reset to DATA0 for that endpoint
*/
void ep_test_data_toggle()
{
uint16_t vendor_id = 0x0d28;
// Use a product ID different than that used in other tests,
// to help Windows hosts use the correct configuration descriptor.
uint16_t product_id = 0x0206;
uint16_t product_release = 0x0001;
char _key[11] = { };
char _value[128] = { };
{
USBEndpointTester serial(get_phy(), vendor_id, product_id, product_release, false);
greentea_send_kv("ep_test_data_toggle", serial.get_serial_desc_string());
greentea_parse_kv(_key, _value, sizeof(_key), sizeof(_value));
#if EP_DBG
wait_ms(100);
printf("cnt_cb_set_conf = %lu\r\n", serial.get_cnt_cb_set_conf());
printf("cnt_cb_set_intf = %lu\r\n", serial.get_cnt_cb_set_intf());
printf("cnt_cb_bulk_out = %lu\r\n", serial.get_cnt_cb_bulk_out());
printf("cnt_cb_bulk_in = %lu\r\n", serial.get_cnt_cb_bulk_in());
printf("cnt_cb_int_out = %lu\r\n", serial.get_cnt_cb_int_out());
printf("cnt_cb_int_in = %lu\r\n", serial.get_cnt_cb_int_in());
printf("cnt_cb_iso_out = %lu\r\n", serial.get_cnt_cb_iso_out());
printf("cnt_cb_iso_in = %lu\r\n", serial.get_cnt_cb_iso_in());
#endif
TEST_ASSERT_EQUAL_STRING("pass", _key);
}
}
/** Test USB implementation against repeated reset
Given an initialized USB (HOST <---> DUT connection established)
@ -602,7 +641,8 @@ Case cases[] = {
Case("endpoint test halt", ep_test_halt),
Case("endpoint test parallel transfers", ep_test_parallel_transfers),
Case("endpoint test parallel transfers ctrl", ep_test_parallel_transfers_ctrl),
Case("endpoint test abort", ep_test_abort)
Case("endpoint test abort", ep_test_abort),
Case("endpoint test data toggle reset", ep_test_data_toggle)
};
utest::v1::status_t greentea_test_setup(const size_t number_of_cases)