mirror of https://github.com/ARMmbed/mbed-os.git
				
				
				
			Add USBDevice test code
Add a USB test and the class USBTester.cpp to go along with it.pull/9768/head
							parent
							
								
									caace4ac61
								
							
						
					
					
						commit
						f9f12766d8
					
				| 
						 | 
				
			
			@ -0,0 +1,349 @@
 | 
			
		|||
"""
 | 
			
		||||
mbed SDK
 | 
			
		||||
Copyright (c) 2018-2018 ARM Limited
 | 
			
		||||
 | 
			
		||||
Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
you may not use this file except in compliance with the License.
 | 
			
		||||
You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
See the License for the specific language governing permissions and
 | 
			
		||||
limitations under the License.
 | 
			
		||||
"""
 | 
			
		||||
from __future__ import print_function
 | 
			
		||||
 | 
			
		||||
from mbed_host_tests import BaseHostTest
 | 
			
		||||
from argparse import ArgumentParser
 | 
			
		||||
import time
 | 
			
		||||
import sys
 | 
			
		||||
from threading import Thread
 | 
			
		||||
 | 
			
		||||
import usb.core
 | 
			
		||||
from usb.util import build_request_type
 | 
			
		||||
from usb.util import CTRL_OUT, CTRL_IN
 | 
			
		||||
from usb.util import CTRL_TYPE_STANDARD, CTRL_TYPE_CLASS, CTRL_TYPE_VENDOR
 | 
			
		||||
from usb.util import (CTRL_RECIPIENT_DEVICE, CTRL_RECIPIENT_INTERFACE,
 | 
			
		||||
                      CTRL_RECIPIENT_ENDPOINT, CTRL_RECIPIENT_OTHER)
 | 
			
		||||
 | 
			
		||||
def get_interface(dev, interface, alternate=0):
 | 
			
		||||
    intf = None
 | 
			
		||||
    for active_if in dev.get_active_configuration():
 | 
			
		||||
        if active_if.bInterfaceNumber == interface and active_if.bAlternateSetting == alternate:
 | 
			
		||||
            assert intf is None, "duplicate interface"
 | 
			
		||||
            intf = active_if
 | 
			
		||||
    return intf
 | 
			
		||||
 | 
			
		||||
VENDOR_TEST_CTRL_IN = 1
 | 
			
		||||
VENDOR_TEST_CTRL_OUT = 2
 | 
			
		||||
VENDOR_TEST_CTRL_NONE = 3
 | 
			
		||||
VENDOR_TEST_CTRL_IN_DELAY = 4
 | 
			
		||||
VENDOR_TEST_CTRL_OUT_DELAY = 5
 | 
			
		||||
VENDOR_TEST_CTRL_NONE_DELAY = 6
 | 
			
		||||
VENDOR_TEST_CTRL_IN_STATUS_DELAY = 7
 | 
			
		||||
VENDOR_TEST_CTRL_OUT_STATUS_DELAY = 8
 | 
			
		||||
VENDOR_TEST_UNSUPPORTED_REQUEST = 32
 | 
			
		||||
 | 
			
		||||
class PyusbBasicTest(BaseHostTest):
 | 
			
		||||
    """
 | 
			
		||||
    """
 | 
			
		||||
    def _callback_usb_enumeration_done(self, key, value, timestamp):
 | 
			
		||||
        print("Received key %s = %s" % (key, value))
 | 
			
		||||
        self.log("Received key %s = %s" % (key, value))
 | 
			
		||||
        test_device(value, self.log)
 | 
			
		||||
        passed = True
 | 
			
		||||
        results = "pass" if passed else "fail"
 | 
			
		||||
        self.send_kv(results, "0")
 | 
			
		||||
 | 
			
		||||
    def setup(self):
 | 
			
		||||
        self.__result = False
 | 
			
		||||
        self.register_callback('usb_enumeration_done', self._callback_usb_enumeration_done)
 | 
			
		||||
 | 
			
		||||
    def result(self):
 | 
			
		||||
        return self.__result
 | 
			
		||||
 | 
			
		||||
    def teardown(self):
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TestMatch(object):
 | 
			
		||||
 | 
			
		||||
    def __init__(self, serial):
 | 
			
		||||
        self.serial = serial
 | 
			
		||||
 | 
			
		||||
    def __call__(self, dev):
 | 
			
		||||
        try:
 | 
			
		||||
            return dev.serial_number == self.serial
 | 
			
		||||
        except ValueError:
 | 
			
		||||
            return False
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_device(serial_number, log=print):
 | 
			
		||||
        dev = usb.core.find(custom_match=TestMatch(serial_number))
 | 
			
		||||
        if dev is None:
 | 
			
		||||
            log("Device not found")
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
        ## --Control Tests-- ##
 | 
			
		||||
        #control_basic_test(dev, log)
 | 
			
		||||
            # Test control IN/OUT/NODATA
 | 
			
		||||
        control_stall_test(dev, log)
 | 
			
		||||
            # Invalid control in/out/nodata requests are stalled
 | 
			
		||||
            # Stall during different points in the control transfer
 | 
			
		||||
        #control_sizes_test(dev, log)
 | 
			
		||||
            # Test control requests of various data stage sizes (1,8,16,32,64,255,256,...)
 | 
			
		||||
        control_stress_test(dev, log)
 | 
			
		||||
            # normal and delay mode
 | 
			
		||||
 | 
			
		||||
        ## --Endpoint test-- ##
 | 
			
		||||
        #for each endpoint
 | 
			
		||||
            #-test all allowed wMaxPacketSize sizes and transfer types
 | 
			
		||||
            #-stall tests
 | 
			
		||||
                #-set/clear stall control request
 | 
			
		||||
                #-stall at random points of sending/receiveing data
 | 
			
		||||
            #-test aborting an in progress transfer
 | 
			
		||||
        #test as many endpoints at once as possible
 | 
			
		||||
        #test biggest configuration possible
 | 
			
		||||
 | 
			
		||||
        ## --physical test-- ##
 | 
			
		||||
        #-reset notification/handling
 | 
			
		||||
        #-connect/disconnect tests - have device disconnect and then reconnect
 | 
			
		||||
            #-disconnect during various phases of control transfers and endpoint transfers
 | 
			
		||||
        #-suspend/resume tests (may not be possible to test with current framework)
 | 
			
		||||
            #-suspend/resume notifications
 | 
			
		||||
 | 
			
		||||
        ## -- Stress tests-- ##
 | 
			
		||||
        #-concurrent tests (all endpoints at once including control)
 | 
			
		||||
        #-concurrent tests + reset + delay
 | 
			
		||||
 | 
			
		||||
        ## -- other tests-- ##
 | 
			
		||||
        #-report throughput for in/out of control, bulk, interrupt and iso transfers
 | 
			
		||||
        #-verify that construction/destruction repeatedly works gracefully
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        intf = get_interface(dev, 0, 0)
 | 
			
		||||
 | 
			
		||||
        # Find endpoints
 | 
			
		||||
        bulk_in = None
 | 
			
		||||
        bulk_out = None 
 | 
			
		||||
        int_in = None
 | 
			
		||||
        int_out = None
 | 
			
		||||
        
 | 
			
		||||
        for endpoint in intf:
 | 
			
		||||
            log("Processing endpoint %s" % endpoint)
 | 
			
		||||
            ep_type = endpoint.bmAttributes & 0x3
 | 
			
		||||
            if  ep_type == 2:
 | 
			
		||||
                if endpoint.bEndpointAddress & 0x80:
 | 
			
		||||
                    assert bulk_in is None
 | 
			
		||||
                    bulk_in = endpoint
 | 
			
		||||
                else:
 | 
			
		||||
                    assert bulk_out is None
 | 
			
		||||
                    bulk_out = endpoint
 | 
			
		||||
            elif ep_type == 3:
 | 
			
		||||
                if endpoint.bEndpointAddress & 0x80:
 | 
			
		||||
                    assert int_in is None
 | 
			
		||||
                    int_in = endpoint
 | 
			
		||||
                else:
 | 
			
		||||
                    assert int_out is None
 | 
			
		||||
                    int_out = endpoint
 | 
			
		||||
        assert bulk_in is not None
 | 
			
		||||
        assert bulk_out is not None
 | 
			
		||||
        assert int_in is not None
 | 
			
		||||
        assert int_out is not None
 | 
			
		||||
        bulk_out.write("hello" + "x" *256);
 | 
			
		||||
        int_out.write("world" + "x" *256);
 | 
			
		||||
 | 
			
		||||
        dev.set_interface_altsetting(0, 1)
 | 
			
		||||
 | 
			
		||||
        intf = get_interface(dev, 0, 0)
 | 
			
		||||
 | 
			
		||||
        # Find endpoints
 | 
			
		||||
        bulk_in = None
 | 
			
		||||
        bulk_out = None
 | 
			
		||||
        int_in = None
 | 
			
		||||
        int_out = None
 | 
			
		||||
 | 
			
		||||
        for endpoint in intf:
 | 
			
		||||
            log("Processing endpoint %s" % endpoint)
 | 
			
		||||
            ep_type = endpoint.bmAttributes & 0x3
 | 
			
		||||
            if  ep_type == 2:
 | 
			
		||||
                if endpoint.bEndpointAddress & 0x80:
 | 
			
		||||
                    assert bulk_in is None
 | 
			
		||||
                    bulk_in = endpoint
 | 
			
		||||
                else:
 | 
			
		||||
                    assert bulk_out is None
 | 
			
		||||
                    bulk_out = endpoint
 | 
			
		||||
            elif ep_type == 3:
 | 
			
		||||
                if endpoint.bEndpointAddress & 0x80:
 | 
			
		||||
                    assert int_in is None
 | 
			
		||||
                    int_in = endpoint
 | 
			
		||||
                else:
 | 
			
		||||
                    assert int_out is None
 | 
			
		||||
                    int_out = endpoint
 | 
			
		||||
        assert bulk_in is not None
 | 
			
		||||
        assert bulk_out is not None
 | 
			
		||||
        assert int_in is not None
 | 
			
		||||
        assert int_out is not None
 | 
			
		||||
        bulk_out.write("hello2" + "x" *256);
 | 
			
		||||
        int_out.write("world2" + "x" *256);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        t = Thread(target=write_data, args=(bulk_out,))
 | 
			
		||||
        t.start()
 | 
			
		||||
 | 
			
		||||
        for _ in range(10):
 | 
			
		||||
            request_type = build_request_type(CTRL_OUT, CTRL_TYPE_VENDOR,
 | 
			
		||||
                                              CTRL_RECIPIENT_DEVICE)
 | 
			
		||||
            request = VENDOR_TEST_CTRL_NONE_DELAY
 | 
			
		||||
            value = 0               # Always 0 for this request
 | 
			
		||||
            index = 0               # Communication interface
 | 
			
		||||
            length = 0              # No data
 | 
			
		||||
            dev.ctrl_transfer(request_type, request, value, index, length, 5000)
 | 
			
		||||
 | 
			
		||||
        t.join()
 | 
			
		||||
 | 
			
		||||
        return True
 | 
			
		||||
 | 
			
		||||
def write_data(pipe):
 | 
			
		||||
    print("Write data running")
 | 
			
		||||
    count = 0
 | 
			
		||||
    for _ in range(40):
 | 
			
		||||
        pipe.write("Value is %s" % count)
 | 
			
		||||
        count += 1
 | 
			
		||||
        print("Count %s" % count)
 | 
			
		||||
        time.sleep(0.5)
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
def control_stall_test(dev, log):
 | 
			
		||||
 | 
			
		||||
    # Control OUT stall
 | 
			
		||||
    try:
 | 
			
		||||
        request_type = build_request_type(CTRL_OUT, CTRL_TYPE_VENDOR,
 | 
			
		||||
                                          CTRL_RECIPIENT_DEVICE)
 | 
			
		||||
        request = VENDOR_TEST_UNSUPPORTED_REQUEST
 | 
			
		||||
        value = 0                           # Always 0 for this request
 | 
			
		||||
        index = 0                           # Communication interface
 | 
			
		||||
        data = bytearray(64)                # Dummy data
 | 
			
		||||
        dev.ctrl_transfer(request_type, request, value, index, data, 5000)
 | 
			
		||||
        raise Exception("Invalid request not stalled")
 | 
			
		||||
    except usb.core.USBError:
 | 
			
		||||
        log("Invalid request stalled")
 | 
			
		||||
 | 
			
		||||
    # Control request with no data stage (Device-to-host)
 | 
			
		||||
    try:
 | 
			
		||||
        request_type = build_request_type(CTRL_IN, CTRL_TYPE_VENDOR,
 | 
			
		||||
                                          CTRL_RECIPIENT_DEVICE)
 | 
			
		||||
        request = VENDOR_TEST_UNSUPPORTED_REQUEST
 | 
			
		||||
        value = 0                           # Always 0 for this request
 | 
			
		||||
        index = 0                           # Communication interface
 | 
			
		||||
        length = 0
 | 
			
		||||
        dev.ctrl_transfer(request_type, request, value, index, length, 5000)
 | 
			
		||||
        raise Exception("Invalid request not stalled")
 | 
			
		||||
    except usb.core.USBError:
 | 
			
		||||
        log("Invalid request stalled")
 | 
			
		||||
 | 
			
		||||
    # Control request with no data stage (Host-to-device)
 | 
			
		||||
    try:
 | 
			
		||||
        request_type = build_request_type(CTRL_OUT, CTRL_TYPE_VENDOR,
 | 
			
		||||
                                          CTRL_RECIPIENT_DEVICE)
 | 
			
		||||
        request = VENDOR_TEST_UNSUPPORTED_REQUEST
 | 
			
		||||
        value = 0                           # Always 0 for this request
 | 
			
		||||
        index = 0                           # Communication interface
 | 
			
		||||
        length = 0
 | 
			
		||||
        dev.ctrl_transfer(request_type, request, value, index, length, 5000)
 | 
			
		||||
        raise Exception("Invalid request not stalled")
 | 
			
		||||
    except usb.core.USBError:
 | 
			
		||||
        log("Invalid request stalled")
 | 
			
		||||
 | 
			
		||||
    # Control IN stall
 | 
			
		||||
    try:
 | 
			
		||||
        request_type = build_request_type(CTRL_IN, CTRL_TYPE_VENDOR,
 | 
			
		||||
                                          CTRL_RECIPIENT_DEVICE)
 | 
			
		||||
        request = VENDOR_TEST_UNSUPPORTED_REQUEST
 | 
			
		||||
        value = 0                           # Always 0 for this request
 | 
			
		||||
        index = 0                           # Communication interface
 | 
			
		||||
        length = 255
 | 
			
		||||
        dev.ctrl_transfer(request_type, request, value, index, length, 5000)
 | 
			
		||||
        raise Exception("Invalid request not stalled")
 | 
			
		||||
    except usb.core.USBError:
 | 
			
		||||
        log("Invalid request stalled")
 | 
			
		||||
 | 
			
		||||
    for i in (6, 7, 5):
 | 
			
		||||
        try:
 | 
			
		||||
            request_type = build_request_type(CTRL_IN, CTRL_TYPE_STANDARD,
 | 
			
		||||
                                              CTRL_RECIPIENT_DEVICE)
 | 
			
		||||
            request = 0x6                   # GET_DESCRIPTOR
 | 
			
		||||
            value = (0x03 << 8) | (i << 0)  # String descriptor index
 | 
			
		||||
            index = 0                       # Communication interface
 | 
			
		||||
            length = 255
 | 
			
		||||
            resp = dev.ctrl_transfer(request_type, request, value, index, length, 5000)
 | 
			
		||||
            log("Requesting string %s passed" % i)
 | 
			
		||||
        except usb.core.USBError:
 | 
			
		||||
            log("Requesting string %s failed" % i)
 | 
			
		||||
                
 | 
			
		||||
                
 | 
			
		||||
def control_stress_test(dev, log):
 | 
			
		||||
 | 
			
		||||
    # Test various patterns of control transfers
 | 
			
		||||
    #
 | 
			
		||||
    # Some devices have had problems with back-to-back
 | 
			
		||||
    # control transfers. Intentionally send these sequences
 | 
			
		||||
    # to make sure they are properly handled.
 | 
			
		||||
    count = 0
 | 
			
		||||
    for _ in range(100):
 | 
			
		||||
        # Control transfer with a data in stage
 | 
			
		||||
        request_type = build_request_type(CTRL_IN, CTRL_TYPE_VENDOR,
 | 
			
		||||
                                          CTRL_RECIPIENT_DEVICE)
 | 
			
		||||
        request = VENDOR_TEST_CTRL_IN
 | 
			
		||||
        value = 8                           # Size of data the device should actually send
 | 
			
		||||
        index = count                       # Unused - set for debugging only
 | 
			
		||||
        length = 255
 | 
			
		||||
        dev.ctrl_transfer(request_type, request, value, index, length, 5000)
 | 
			
		||||
        count += 1
 | 
			
		||||
 | 
			
		||||
    for _ in range(100):
 | 
			
		||||
        # Control transfer with a data out stage followed
 | 
			
		||||
        # by a control transfer with a data in stage
 | 
			
		||||
        request_type = build_request_type(CTRL_OUT, CTRL_TYPE_VENDOR,
 | 
			
		||||
                                          CTRL_RECIPIENT_DEVICE)
 | 
			
		||||
        request = VENDOR_TEST_CTRL_OUT
 | 
			
		||||
        value = 8                           # Size of data the device should actually read
 | 
			
		||||
        index = count                       # Unused - set for debugging only
 | 
			
		||||
        data = bytearray(8)                 # Dummy data
 | 
			
		||||
        dev.ctrl_transfer(request_type, request, value, index, data, 5000)
 | 
			
		||||
        count += 1
 | 
			
		||||
 | 
			
		||||
        request_type = build_request_type(CTRL_IN, CTRL_TYPE_VENDOR,
 | 
			
		||||
                                          CTRL_RECIPIENT_DEVICE)
 | 
			
		||||
        request = VENDOR_TEST_CTRL_IN
 | 
			
		||||
        value = 8                           # Size of data the device should actually send
 | 
			
		||||
        index = count                       # Unused - set for debugging only
 | 
			
		||||
        length = 255
 | 
			
		||||
        dev.ctrl_transfer(request_type, request, value, index, length, 5000)
 | 
			
		||||
        count += 1
 | 
			
		||||
 | 
			
		||||
    for _ in range(100):
 | 
			
		||||
        # Control transfer with a data out stage
 | 
			
		||||
        request_type = build_request_type(CTRL_OUT, CTRL_TYPE_VENDOR,
 | 
			
		||||
                                          CTRL_RECIPIENT_DEVICE)
 | 
			
		||||
        request = VENDOR_TEST_CTRL_OUT
 | 
			
		||||
        value = 8                           # Size of data the device should actually read
 | 
			
		||||
        index = count                       # Unused - set for debugging only
 | 
			
		||||
        data = bytearray(8)                 # Dummy data
 | 
			
		||||
        dev.ctrl_transfer(request_type, request, value, index, data, 5000)
 | 
			
		||||
        count += 1
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def main():
 | 
			
		||||
    parser = ArgumentParser(description="USB basic test")
 | 
			
		||||
    parser.add_argument('serial', help='USB serial number of DUT')
 | 
			
		||||
    args = parser.parse_args()
 | 
			
		||||
    ret = test_device(args.serial)
 | 
			
		||||
    print("Test %s" % "passed" if ret else "failed")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if __name__ == "__main__":
 | 
			
		||||
    main()
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,384 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) 2018-2018, ARM Limited, All Rights Reserved
 | 
			
		||||
 * SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License"); you may
 | 
			
		||||
 * not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 | 
			
		||||
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "stdint.h"
 | 
			
		||||
#include "USBTester.h"
 | 
			
		||||
#include "mbed_shared_queues.h"
 | 
			
		||||
#include "EndpointResolver.h"
 | 
			
		||||
 | 
			
		||||
#define DEFAULT_CONFIGURATION (1)
 | 
			
		||||
 | 
			
		||||
#define VENDOR_TEST_CTRL_IN                 1
 | 
			
		||||
#define VENDOR_TEST_CTRL_OUT                2
 | 
			
		||||
#define VENDOR_TEST_CTRL_NONE               3
 | 
			
		||||
#define VENDOR_TEST_CTRL_IN_DELAY           4
 | 
			
		||||
#define VENDOR_TEST_CTRL_OUT_DELAY          5
 | 
			
		||||
#define VENDOR_TEST_CTRL_NONE_DELAY         6
 | 
			
		||||
#define VENDOR_TEST_CTRL_IN_STATUS_DELAY    7
 | 
			
		||||
#define VENDOR_TEST_CTRL_OUT_STATUS_DELAY   8
 | 
			
		||||
 | 
			
		||||
#define MAX_EP_SIZE 64
 | 
			
		||||
#define MIN_EP_SIZE 8
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
USBTester::USBTester(uint16_t vendor_id, uint16_t product_id, uint16_t product_release, bool connect_blocking): USBDevice(vendor_id, product_id, product_release)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    EndpointResolver resolver(endpoint_table());
 | 
			
		||||
 | 
			
		||||
    resolver.endpoint_ctrl(64);
 | 
			
		||||
    bulk_in = resolver.endpoint_in(USB_EP_TYPE_BULK, 64);
 | 
			
		||||
    bulk_out = resolver.endpoint_out(USB_EP_TYPE_BULK, 64);
 | 
			
		||||
    int_in = resolver.endpoint_in(USB_EP_TYPE_INT, 64);
 | 
			
		||||
    int_out = resolver.endpoint_out(USB_EP_TYPE_INT, 64);
 | 
			
		||||
    MBED_ASSERT(resolver.valid());
 | 
			
		||||
    queue = mbed_highprio_event_queue();
 | 
			
		||||
 | 
			
		||||
    configuration_desc();
 | 
			
		||||
 | 
			
		||||
    init();
 | 
			
		||||
    USBDevice::connect(connect_blocking);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
USBTester::~USBTester()
 | 
			
		||||
{
 | 
			
		||||
    deinit();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void USBTester::callback_state_change(DeviceState new_state)
 | 
			
		||||
{
 | 
			
		||||
    // Nothing to do
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void USBTester::callback_request(const setup_packet_t *setup)
 | 
			
		||||
{
 | 
			
		||||
    /* Called in ISR context */
 | 
			
		||||
    RequestResult result = PassThrough;
 | 
			
		||||
    uint8_t *data = NULL;
 | 
			
		||||
    uint32_t size = 0;
 | 
			
		||||
    uint32_t delay = 0;
 | 
			
		||||
 | 
			
		||||
    /* Process vendor-specific requests */
 | 
			
		||||
    if (setup->bmRequestType.Type == VENDOR_TYPE) {
 | 
			
		||||
        switch (setup->bRequest) {
 | 
			
		||||
            case VENDOR_TEST_CTRL_IN:
 | 
			
		||||
                result = Send;
 | 
			
		||||
                data = ctrl_buf;
 | 
			
		||||
                size = setup->wValue < sizeof(ctrl_buf) ? setup->wValue : sizeof(ctrl_buf);
 | 
			
		||||
                break;
 | 
			
		||||
            case VENDOR_TEST_CTRL_OUT:
 | 
			
		||||
                result = Receive;
 | 
			
		||||
                data = ctrl_buf;
 | 
			
		||||
                size = setup->wValue < 8 ? setup->wValue  : 8;
 | 
			
		||||
                break;
 | 
			
		||||
            case VENDOR_TEST_CTRL_NONE:
 | 
			
		||||
                result = Success;
 | 
			
		||||
                break;
 | 
			
		||||
            case VENDOR_TEST_CTRL_NONE_DELAY:
 | 
			
		||||
                result = Success;
 | 
			
		||||
                delay = 2000;
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                result = PassThrough;
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (delay) {
 | 
			
		||||
        queue->call_in(delay, static_cast<USBDevice *>(this), &USBTester::complete_request, Success, data, size);
 | 
			
		||||
    } else {
 | 
			
		||||
        complete_request(result, data, size);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void USBTester::callback_request_xfer_done(const setup_packet_t *setup, bool aborted)
 | 
			
		||||
{
 | 
			
		||||
    if (aborted) {
 | 
			
		||||
        complete_request_xfer_done(false);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool result = false;
 | 
			
		||||
    if (setup->bmRequestType.Type == VENDOR_TYPE) {
 | 
			
		||||
        switch (setup->bRequest) {
 | 
			
		||||
            case VENDOR_TEST_CTRL_IN:
 | 
			
		||||
                result = true;
 | 
			
		||||
                break;
 | 
			
		||||
            case VENDOR_TEST_CTRL_OUT:
 | 
			
		||||
                result = true;
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                result = false;
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    complete_request_xfer_done(true);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Called in ISR context
 | 
			
		||||
// Set configuration. Return false if the
 | 
			
		||||
// configuration is not supported.
 | 
			
		||||
void USBTester::callback_set_configuration(uint8_t configuration)
 | 
			
		||||
{
 | 
			
		||||
    if (configuration != DEFAULT_CONFIGURATION) {
 | 
			
		||||
        complete_set_configuration(false);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Configure endpoints > 0
 | 
			
		||||
    endpoint_add(int_in, MAX_EP_SIZE, USB_EP_TYPE_INT);
 | 
			
		||||
    endpoint_add(int_out, MAX_EP_SIZE, USB_EP_TYPE_INT, &USBTester::epint_out_callback);
 | 
			
		||||
    endpoint_add(bulk_in, MAX_EP_SIZE, USB_EP_TYPE_BULK);
 | 
			
		||||
    endpoint_add(bulk_out, MAX_EP_SIZE, USB_EP_TYPE_BULK, &USBTester::epbulk_out_callback);
 | 
			
		||||
 | 
			
		||||
    read_start(int_out);
 | 
			
		||||
    read_start(bulk_out);
 | 
			
		||||
 | 
			
		||||
    complete_set_configuration(true);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void USBTester::callback_set_interface(uint16_t interface, uint8_t alternate)
 | 
			
		||||
{
 | 
			
		||||
    if (interface == 0 && alternate == 0) {
 | 
			
		||||
        endpoint_remove(int_in);
 | 
			
		||||
        endpoint_remove(int_out);
 | 
			
		||||
        endpoint_remove(bulk_in);
 | 
			
		||||
        endpoint_remove(bulk_out);
 | 
			
		||||
 | 
			
		||||
        endpoint_add(int_in, MAX_EP_SIZE, USB_EP_TYPE_INT);
 | 
			
		||||
        endpoint_add(int_out, MAX_EP_SIZE, USB_EP_TYPE_INT, &USBTester::epint_out_callback);
 | 
			
		||||
        endpoint_add(bulk_in, MAX_EP_SIZE, USB_EP_TYPE_BULK);
 | 
			
		||||
        endpoint_add(bulk_out, MAX_EP_SIZE, USB_EP_TYPE_BULK, &USBTester::epbulk_out_callback);
 | 
			
		||||
 | 
			
		||||
        read_start(int_out);
 | 
			
		||||
        read_start(bulk_out);
 | 
			
		||||
 | 
			
		||||
        complete_set_interface(true);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    if (interface == 0 && alternate == 1) {
 | 
			
		||||
        endpoint_remove(int_in);
 | 
			
		||||
        endpoint_remove(int_out);
 | 
			
		||||
        endpoint_remove(bulk_in);
 | 
			
		||||
        endpoint_remove(bulk_out);
 | 
			
		||||
 | 
			
		||||
        endpoint_add(int_in, MIN_EP_SIZE, USB_EP_TYPE_INT);
 | 
			
		||||
        endpoint_add(int_out, MIN_EP_SIZE, USB_EP_TYPE_INT, &USBTester::epint_out_callback);
 | 
			
		||||
        endpoint_add(bulk_in, MIN_EP_SIZE, USB_EP_TYPE_BULK);
 | 
			
		||||
        endpoint_add(bulk_out, MIN_EP_SIZE, USB_EP_TYPE_BULK, &USBTester::epbulk_out_callback);
 | 
			
		||||
 | 
			
		||||
        read_start(int_out);
 | 
			
		||||
        read_start(bulk_out);
 | 
			
		||||
 | 
			
		||||
        complete_set_interface(true);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    complete_set_interface(false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const uint8_t *USBTester::device_desc()
 | 
			
		||||
{
 | 
			
		||||
    uint8_t ep0_size = endpoint_max_packet_size(0x00);
 | 
			
		||||
    uint8_t device_descriptor_temp[] = {
 | 
			
		||||
        18,                   // bLength
 | 
			
		||||
        1,                    // bDescriptorType
 | 
			
		||||
        0x10, 0x01,           // bcdUSB
 | 
			
		||||
        0,                    // bDeviceClass
 | 
			
		||||
        0,                    // bDeviceSubClass
 | 
			
		||||
        0,                    // bDeviceProtocol
 | 
			
		||||
        ep0_size,             // bMaxPacketSize0
 | 
			
		||||
        (uint8_t)(LSB(vendor_id)), (uint8_t)(MSB(vendor_id)),  // idVendor
 | 
			
		||||
        (uint8_t)(LSB(product_id)), (uint8_t)(MSB(product_id)),// idProduct
 | 
			
		||||
        0x00, 0x01,           // bcdDevice
 | 
			
		||||
        1,                    // iManufacturer
 | 
			
		||||
        2,                    // iProduct
 | 
			
		||||
        3,                    // iSerialNumber
 | 
			
		||||
        1                     // bNumConfigurations
 | 
			
		||||
    };
 | 
			
		||||
    MBED_ASSERT(sizeof(device_descriptor_temp) == sizeof(device_descriptor));
 | 
			
		||||
    memcpy(device_descriptor, device_descriptor_temp, sizeof(device_descriptor));
 | 
			
		||||
    return device_descriptor;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const uint8_t *USBTester::string_iinterface_desc()
 | 
			
		||||
{
 | 
			
		||||
    static const uint8_t string_iinterface_descriptor[] = {
 | 
			
		||||
        0x08,
 | 
			
		||||
        STRING_DESCRIPTOR,
 | 
			
		||||
        'C', 0, 'D', 0, 'C', 0,
 | 
			
		||||
    };
 | 
			
		||||
    return string_iinterface_descriptor;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const uint8_t *USBTester::string_iproduct_desc()
 | 
			
		||||
{
 | 
			
		||||
    static const uint8_t string_iproduct_descriptor[] = {
 | 
			
		||||
        0x16,
 | 
			
		||||
        STRING_DESCRIPTOR,
 | 
			
		||||
        'C', 0, 'D', 0, 'C', 0, ' ', 0, 'D', 0, 'E', 0, 'V', 0, 'I', 0, 'C', 0, 'E', 0
 | 
			
		||||
    };
 | 
			
		||||
    return string_iproduct_descriptor;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define CONFIG1_DESC_SIZE (9+9+7+7+7+7 + 9+7+7+7+7)
 | 
			
		||||
 | 
			
		||||
const uint8_t *USBTester::configuration_desc()
 | 
			
		||||
{
 | 
			
		||||
    static const uint8_t config_descriptor[] = {
 | 
			
		||||
        // configuration descriptor
 | 
			
		||||
        9,                      // bLength
 | 
			
		||||
        2,                      // bDescriptorType
 | 
			
		||||
        LSB(CONFIG1_DESC_SIZE), // wTotalLength
 | 
			
		||||
        MSB(CONFIG1_DESC_SIZE),
 | 
			
		||||
        1,                      // bNumInterfaces
 | 
			
		||||
        1,                      // bConfigurationValue
 | 
			
		||||
        0,                      // iConfiguration
 | 
			
		||||
        0x80,                   // bmAttributes
 | 
			
		||||
        50,                     // bMaxPower
 | 
			
		||||
 | 
			
		||||
        // Interface 0 setting 0
 | 
			
		||||
 | 
			
		||||
        // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
 | 
			
		||||
        9,                          // bLength
 | 
			
		||||
        4,                          // bDescriptorType
 | 
			
		||||
        0,                          // bInterfaceNumber
 | 
			
		||||
        0,                          // bAlternateSetting
 | 
			
		||||
        4,                          // bNumEndpoints
 | 
			
		||||
        0xFF,                       // bInterfaceClass
 | 
			
		||||
        0xFF,                       // bInterfaceSubClass
 | 
			
		||||
        0xFF,                       // bInterfaceProtocol
 | 
			
		||||
        0,                          // iInterface
 | 
			
		||||
 | 
			
		||||
        // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
 | 
			
		||||
        ENDPOINT_DESCRIPTOR_LENGTH, // bLength
 | 
			
		||||
        ENDPOINT_DESCRIPTOR,        // bDescriptorType
 | 
			
		||||
        bulk_in,                    // bEndpointAddress
 | 
			
		||||
        E_BULK,                     // bmAttributes (0x02=bulk)
 | 
			
		||||
        LSB(MAX_EP_SIZE),// wMaxPacketSize (LSB)
 | 
			
		||||
        MSB(MAX_EP_SIZE),// wMaxPacketSize (MSB)
 | 
			
		||||
        0,                          // bInterval
 | 
			
		||||
 | 
			
		||||
        // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
 | 
			
		||||
        ENDPOINT_DESCRIPTOR_LENGTH, // bLength
 | 
			
		||||
        ENDPOINT_DESCRIPTOR,        // bDescriptorType
 | 
			
		||||
        bulk_out,                   // bEndpointAddress
 | 
			
		||||
        E_BULK,                     // bmAttributes (0x02=bulk)
 | 
			
		||||
        LSB(MAX_EP_SIZE),// wMaxPacketSize (LSB)
 | 
			
		||||
        MSB(MAX_EP_SIZE),// wMaxPacketSize (MSB)
 | 
			
		||||
        0,                          // bInterval
 | 
			
		||||
 | 
			
		||||
        // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
 | 
			
		||||
        ENDPOINT_DESCRIPTOR_LENGTH, // bLength
 | 
			
		||||
        ENDPOINT_DESCRIPTOR,        // bDescriptorType
 | 
			
		||||
        int_in,                     // bEndpointAddress
 | 
			
		||||
        E_INTERRUPT,                // bmAttributes (0x03=interrupt)
 | 
			
		||||
        LSB(MAX_EP_SIZE), // wMaxPacketSize (LSB)
 | 
			
		||||
        MSB(MAX_EP_SIZE), // wMaxPacketSize (MSB)
 | 
			
		||||
        1,                          // bInterval
 | 
			
		||||
 | 
			
		||||
        // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
 | 
			
		||||
        ENDPOINT_DESCRIPTOR_LENGTH, // bLength
 | 
			
		||||
        ENDPOINT_DESCRIPTOR,        // bDescriptorType
 | 
			
		||||
        int_out,                    // bEndpointAddress
 | 
			
		||||
        E_INTERRUPT,                // bmAttributes (0x03=interrupt)
 | 
			
		||||
        LSB(MAX_EP_SIZE), // wMaxPacketSize (LSB)
 | 
			
		||||
        MSB(MAX_EP_SIZE), // wMaxPacketSize (MSB)
 | 
			
		||||
        1,                          // bInterval
 | 
			
		||||
 | 
			
		||||
        // Interface 0 setting 1
 | 
			
		||||
 | 
			
		||||
        // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
 | 
			
		||||
        9,                          // bLength
 | 
			
		||||
        4,                          // bDescriptorType
 | 
			
		||||
        0,                          // bInterfaceNumber
 | 
			
		||||
        1,                          // bAlternateSetting
 | 
			
		||||
        4,                          // bNumEndpoints
 | 
			
		||||
        0xFF,                       // bInterfaceClass
 | 
			
		||||
        0xFF,                       // bInterfaceSubClass
 | 
			
		||||
        0xFF,                       // bInterfaceProtocol
 | 
			
		||||
        0,                          // iInterface
 | 
			
		||||
 | 
			
		||||
        // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
 | 
			
		||||
        ENDPOINT_DESCRIPTOR_LENGTH, // bLength
 | 
			
		||||
        ENDPOINT_DESCRIPTOR,        // bDescriptorType
 | 
			
		||||
        bulk_in,                    // bEndpointAddress
 | 
			
		||||
        E_BULK,                     // bmAttributes (0x02=bulk)
 | 
			
		||||
        LSB(MIN_EP_SIZE),           // wMaxPacketSize (LSB)
 | 
			
		||||
        MSB(MIN_EP_SIZE),           // wMaxPacketSize (MSB)
 | 
			
		||||
        0,                          // bInterval
 | 
			
		||||
 | 
			
		||||
        // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
 | 
			
		||||
        ENDPOINT_DESCRIPTOR_LENGTH, // bLength
 | 
			
		||||
        ENDPOINT_DESCRIPTOR,        // bDescriptorType
 | 
			
		||||
        bulk_out,                   // bEndpointAddress
 | 
			
		||||
        E_BULK,                     // bmAttributes (0x02=bulk)
 | 
			
		||||
        LSB(MIN_EP_SIZE),           // wMaxPacketSize (LSB)
 | 
			
		||||
        MSB(MIN_EP_SIZE),           // wMaxPacketSize (MSB)
 | 
			
		||||
        0,                          // bInterval
 | 
			
		||||
 | 
			
		||||
        // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
 | 
			
		||||
        ENDPOINT_DESCRIPTOR_LENGTH, // bLength
 | 
			
		||||
        ENDPOINT_DESCRIPTOR,        // bDescriptorType
 | 
			
		||||
        int_in,                     // bEndpointAddress
 | 
			
		||||
        E_INTERRUPT,                // bmAttributes (0x03=interrupt)
 | 
			
		||||
        LSB(MIN_EP_SIZE),           // wMaxPacketSize (LSB)
 | 
			
		||||
        MSB(MIN_EP_SIZE),           // wMaxPacketSize (MSB)
 | 
			
		||||
        1,                          // bInterval
 | 
			
		||||
 | 
			
		||||
        // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
 | 
			
		||||
        ENDPOINT_DESCRIPTOR_LENGTH, // bLength
 | 
			
		||||
        ENDPOINT_DESCRIPTOR,        // bDescriptorType
 | 
			
		||||
        int_out,                    // bEndpointAddress
 | 
			
		||||
        E_INTERRUPT,                // bmAttributes (0x03=interrupt)
 | 
			
		||||
        LSB(MIN_EP_SIZE),           // wMaxPacketSize (LSB)
 | 
			
		||||
        MSB(MIN_EP_SIZE),           // wMaxPacketSize (MSB)
 | 
			
		||||
        1                           // bInterval
 | 
			
		||||
 | 
			
		||||
    };
 | 
			
		||||
    return config_descriptor;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void USBTester::epint_out_callback(usb_ep_t endpoint)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t buffer[65];
 | 
			
		||||
    uint32_t size = 0;
 | 
			
		||||
 | 
			
		||||
    if (!read_finish(endpoint, buffer, sizeof(buffer), &size)) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    if (!read_start(endpoint)) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
void USBTester::epbulk_out_callback(usb_ep_t endpoint)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t buffer[65];
 | 
			
		||||
    uint32_t size = 0;
 | 
			
		||||
 | 
			
		||||
    if (!read_finish(endpoint, buffer, sizeof(buffer), &size)) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    if (!read_start(endpoint)) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,91 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) 2018-2018, ARM Limited, All Rights Reserved
 | 
			
		||||
 * SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License"); you may
 | 
			
		||||
 * not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 | 
			
		||||
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef USB_TESTER_H
 | 
			
		||||
#define USB_TESTER_H
 | 
			
		||||
 | 
			
		||||
/* These headers are included for child class. */
 | 
			
		||||
#include "USBDescriptor.h"
 | 
			
		||||
#include "USBDevice_Types.h"
 | 
			
		||||
#include "EventQueue.h"
 | 
			
		||||
 | 
			
		||||
#include "USBDevice.h"
 | 
			
		||||
 | 
			
		||||
class USBTester: public USBDevice {
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
    * Constructor
 | 
			
		||||
    *
 | 
			
		||||
    * @param vendor_id Your vendor_id
 | 
			
		||||
    * @param product_id Your product_id
 | 
			
		||||
    * @param product_release Your preoduct_release
 | 
			
		||||
    * @param connect_blocking define if the connection must be blocked if USB not plugged in
 | 
			
		||||
    */
 | 
			
		||||
    USBTester(uint16_t vendor_id, uint16_t product_id, uint16_t product_release, bool connect_blocking);
 | 
			
		||||
 | 
			
		||||
    ~USBTester();
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
    * Get device descriptor. Warning: this method has to store the length of the report descriptor in reportLength.
 | 
			
		||||
    *
 | 
			
		||||
    * @returns pointer to the device descriptor
 | 
			
		||||
    */
 | 
			
		||||
    virtual const uint8_t *device_desc();
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
    * Get string product descriptor
 | 
			
		||||
    *
 | 
			
		||||
    * @returns pointer to the string product descriptor
 | 
			
		||||
    */
 | 
			
		||||
    virtual const uint8_t *string_iproduct_desc();
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
    * Get string interface descriptor
 | 
			
		||||
    *
 | 
			
		||||
    * @returns pointer to the string interface descriptor
 | 
			
		||||
    */
 | 
			
		||||
    virtual const uint8_t *string_iinterface_desc();
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
    * Get configuration descriptor
 | 
			
		||||
    *
 | 
			
		||||
    * @returns pointer to the configuration descriptor
 | 
			
		||||
    */
 | 
			
		||||
    virtual const uint8_t *configuration_desc();
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
    uint8_t bulk_in;
 | 
			
		||||
    uint8_t bulk_out;
 | 
			
		||||
    uint8_t int_in;
 | 
			
		||||
    uint8_t int_out;
 | 
			
		||||
    EventQueue *queue;
 | 
			
		||||
 | 
			
		||||
    virtual void callback_state_change(DeviceState new_state);
 | 
			
		||||
    virtual void callback_request(const setup_packet_t *setup);
 | 
			
		||||
    virtual void callback_request_xfer_done(const setup_packet_t *setup, bool aborted);
 | 
			
		||||
    virtual void callback_set_configuration(uint8_t configuration);
 | 
			
		||||
    virtual void callback_set_interface(uint16_t interface, uint8_t alternate);
 | 
			
		||||
    virtual void epbulk_out_callback(usb_ep_t endpoint);
 | 
			
		||||
    virtual void epint_out_callback(usb_ep_t endpoint);
 | 
			
		||||
    uint8_t ctrl_buf[2048];
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,62 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) 2018-2018, ARM Limited, All Rights Reserved
 | 
			
		||||
 * SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License"); you may
 | 
			
		||||
 * not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 | 
			
		||||
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include "mbed.h"
 | 
			
		||||
#include "greentea-client/test_env.h"
 | 
			
		||||
#include "unity/unity.h"
 | 
			
		||||
#include "utest/utest.h"
 | 
			
		||||
 | 
			
		||||
#include "USBTester.h"
 | 
			
		||||
 | 
			
		||||
#if !defined(DEVICE_USBDEVICE) || !DEVICE_USBDEVICE
 | 
			
		||||
#error [NOT_SUPPORTED] USB Device not supported for this target
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
using namespace utest::v1;
 | 
			
		||||
 | 
			
		||||
// Echo server (echo payload to host)
 | 
			
		||||
void test_case_basic()
 | 
			
		||||
{
 | 
			
		||||
    char _key[11] = {};
 | 
			
		||||
    char _value[128] = {};
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        USBTester serial(0x0d28, 0x0205, 0x0001, true);
 | 
			
		||||
 | 
			
		||||
        greentea_send_kv("usb_enumeration_done", "0123456789");
 | 
			
		||||
        // Wait for host before terminating
 | 
			
		||||
        greentea_parse_kv(_key, _value, sizeof(_key), sizeof(_value));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Case cases[] = {
 | 
			
		||||
    Case("pyusb basic test", test_case_basic),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
utest::v1::status_t greentea_test_setup(const size_t number_of_cases)
 | 
			
		||||
{
 | 
			
		||||
    GREENTEA_SETUP(120, "pyusb_basic");
 | 
			
		||||
    return greentea_test_setup_handler(number_of_cases);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler);
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    Harness::run(specification);
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
		Reference in New Issue