rename tests to obsolete
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* This file is part of the TinyUSB stack.
|
||||
*/
|
||||
|
||||
/** \ingroup TBD
|
||||
* \defgroup TBD
|
||||
* \brief TBD
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _TUSB_CDC_CALLBACK_H_
|
||||
#define _TUSB_CDC_CALLBACK_H_
|
||||
|
||||
#include "common/common.h"
|
||||
#include "cdc_host.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void tusbh_cdc_mounted_cb(uint8_t dev_addr);
|
||||
void tusbh_cdc_unmounted_cb(uint8_t dev_addr);
|
||||
void tusbh_cdc_xfer_isr(uint8_t dev_addr, xfer_result_t event, cdc_pipeid_t pipe_id, uint32_t xferred_bytes);
|
||||
|
||||
void tusbh_cdc_rndis_mounted_cb(uint8_t dev_addr);
|
||||
void tusbh_cdc_rndis_unmounted_isr(uint8_t dev_addr);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _TUSB_CDC_CALLBACK_H_ */
|
||||
|
||||
/** @} */
|
||||
@@ -0,0 +1,276 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* This file is part of the TinyUSB stack.
|
||||
*/
|
||||
|
||||
#include "tusb_option.h"
|
||||
#include "descriptor_cdc.h"
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// CDC Serials
|
||||
//--------------------------------------------------------------------+
|
||||
CFG_TUSB_MEM_SECTION
|
||||
const cdc_configuration_desc_t cdc_config_descriptor =
|
||||
{
|
||||
.configuration =
|
||||
{
|
||||
.bLength = sizeof(tusb_desc_configuration_t),
|
||||
.bDescriptorType = TUSB_DESC_TYPE_CONFIGURATION,
|
||||
|
||||
.wTotalLength = sizeof(cdc_configuration_desc_t),
|
||||
.bNumInterfaces = 2,
|
||||
|
||||
.bConfigurationValue = 1,
|
||||
.iConfiguration = 0x00,
|
||||
.bmAttributes = TUSB_DESC_CONFIG_ATT_BUS_POWER,
|
||||
.bMaxPower = TUSB_DESC_CONFIG_POWER_MA(100)
|
||||
},
|
||||
|
||||
// IAD points to CDC Interfaces
|
||||
.cdc_iad =
|
||||
{
|
||||
.bLength = sizeof(tusb_desc_interface_assoc_t),
|
||||
.bDescriptorType = TUSB_DESC_TYPE_INTERFACE_ASSOCIATION,
|
||||
|
||||
.bFirstInterface = 1,
|
||||
.bInterfaceCount = 2,
|
||||
|
||||
.bFunctionClass = TUSB_CLASS_CDC,
|
||||
.bFunctionSubClass = CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL,
|
||||
.bFunctionProtocol = CDC_COMM_PROTOCOL_ATCOMMAND,
|
||||
|
||||
.iFunction = 0
|
||||
},
|
||||
|
||||
|
||||
// USB CDC Serial Interface
|
||||
//------------- CDC Communication Interface -------------//
|
||||
.cdc_comm_interface =
|
||||
{
|
||||
.bLength = sizeof(tusb_desc_interface_t),
|
||||
.bDescriptorType = TUSB_DESC_TYPE_INTERFACE,
|
||||
.bInterfaceNumber = 1,
|
||||
.bAlternateSetting = 0,
|
||||
.bNumEndpoints = 1,
|
||||
.bInterfaceClass = TUSB_CLASS_CDC,
|
||||
.bInterfaceSubClass = CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL,
|
||||
.bInterfaceProtocol = CDC_COMM_PROTOCOL_ATCOMMAND,
|
||||
.iInterface = 0x00
|
||||
},
|
||||
|
||||
.cdc_header =
|
||||
{
|
||||
.bLength = sizeof(cdc_desc_func_header_t),
|
||||
.bDescriptorType = TUSB_DESC_TYPE_INTERFACE_CLASS_SPECIFIC,
|
||||
.bDescriptorSubType = CDC_FUNC_DESC_HEADER,
|
||||
.bcdCDC = 0x0120
|
||||
},
|
||||
|
||||
.cdc_acm =
|
||||
{
|
||||
.bLength = sizeof(cdc_desc_func_acm_t),
|
||||
.bDescriptorType = TUSB_DESC_TYPE_INTERFACE_CLASS_SPECIFIC,
|
||||
.bDescriptorSubType = CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT,
|
||||
.bmCapabilities = { // 0x06
|
||||
.support_line_request = 1,
|
||||
.support_send_break = 1
|
||||
}
|
||||
},
|
||||
|
||||
.cdc_union =
|
||||
{
|
||||
.bLength = sizeof(cdc_desc_func_union_t), // plus number of
|
||||
.bDescriptorType = TUSB_DESC_TYPE_INTERFACE_CLASS_SPECIFIC,
|
||||
.bDescriptorSubType = CDC_FUNC_DESC_UNION,
|
||||
.bControlInterface = 1,
|
||||
.bSubordinateInterface = 2,
|
||||
},
|
||||
|
||||
.cdc_endpoint_notification =
|
||||
{
|
||||
.bLength = sizeof(tusb_desc_endpoint_t),
|
||||
.bDescriptorType = TUSB_DESC_TYPE_ENDPOINT,
|
||||
.bEndpointAddress = 0x81,
|
||||
.bmAttributes = { .xfer = TUSB_XFER_INTERRUPT },
|
||||
.wMaxPacketSize = 8,
|
||||
.bInterval = 0x0a // lowest polling rate
|
||||
},
|
||||
|
||||
//------------- CDC Data Interface -------------//
|
||||
.cdc_data_interface =
|
||||
{
|
||||
.bLength = sizeof(tusb_desc_interface_t),
|
||||
.bDescriptorType = TUSB_DESC_TYPE_INTERFACE,
|
||||
.bInterfaceNumber = 2,
|
||||
.bAlternateSetting = 0x00,
|
||||
.bNumEndpoints = 2,
|
||||
.bInterfaceClass = TUSB_CLASS_CDC_DATA,
|
||||
.bInterfaceSubClass = 0,
|
||||
.bInterfaceProtocol = 0,
|
||||
.iInterface = 0x00
|
||||
},
|
||||
|
||||
.cdc_endpoint_out =
|
||||
{
|
||||
.bLength = sizeof(tusb_desc_endpoint_t),
|
||||
.bDescriptorType = TUSB_DESC_TYPE_ENDPOINT,
|
||||
.bEndpointAddress = 2,
|
||||
.bmAttributes = { .xfer = TUSB_XFER_BULK },
|
||||
.wMaxPacketSize = 64,
|
||||
.bInterval = 0
|
||||
},
|
||||
|
||||
.cdc_endpoint_in =
|
||||
{
|
||||
.bLength = sizeof(tusb_desc_endpoint_t),
|
||||
.bDescriptorType = TUSB_DESC_TYPE_ENDPOINT,
|
||||
.bEndpointAddress = 0x82,
|
||||
.bmAttributes = { .xfer = TUSB_XFER_BULK },
|
||||
.wMaxPacketSize = 64,
|
||||
.bInterval = 0
|
||||
},
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// CDC RNSID
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
CFG_TUSB_MEM_SECTION
|
||||
const cdc_configuration_desc_t rndis_config_descriptor =
|
||||
{
|
||||
.configuration =
|
||||
{
|
||||
.bLength = sizeof(tusb_desc_configuration_t),
|
||||
.bDescriptorType = TUSB_DESC_TYPE_CONFIGURATION,
|
||||
|
||||
.wTotalLength = sizeof(cdc_configuration_desc_t),
|
||||
.bNumInterfaces = 2,
|
||||
|
||||
.bConfigurationValue = 1,
|
||||
.iConfiguration = 0x00,
|
||||
.bmAttributes = TUSB_DESC_CONFIG_ATT_BUS_POWER,
|
||||
.bMaxPower = TUSB_DESC_CONFIG_POWER_MA(100)
|
||||
},
|
||||
|
||||
// IAD points to CDC Interfaces
|
||||
.cdc_iad =
|
||||
{
|
||||
.bLength = sizeof(tusb_desc_interface_assoc_t),
|
||||
.bDescriptorType = TUSB_DESC_TYPE_INTERFACE_ASSOCIATION,
|
||||
|
||||
.bFirstInterface = 1,
|
||||
.bInterfaceCount = 2,
|
||||
|
||||
.bFunctionClass = TUSB_CLASS_CDC,
|
||||
.bFunctionSubClass = CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL,
|
||||
.bFunctionProtocol = 0,
|
||||
|
||||
.iFunction = 0
|
||||
},
|
||||
|
||||
|
||||
// USB CDC Serial Interface
|
||||
//------------- CDC Communication Interface -------------//
|
||||
.cdc_comm_interface =
|
||||
{
|
||||
.bLength = sizeof(tusb_desc_interface_t),
|
||||
.bDescriptorType = TUSB_DESC_TYPE_INTERFACE,
|
||||
.bInterfaceNumber = 1,
|
||||
.bAlternateSetting = 0,
|
||||
.bNumEndpoints = 1,
|
||||
.bInterfaceClass = TUSB_CLASS_CDC,
|
||||
.bInterfaceSubClass = CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL,
|
||||
.bInterfaceProtocol = 0xff, // RNDIS is vendor specific protocol
|
||||
.iInterface = 0x00
|
||||
},
|
||||
|
||||
.cdc_header =
|
||||
{
|
||||
.bLength = sizeof(cdc_desc_func_header_t),
|
||||
.bDescriptorType = TUSB_DESC_TYPE_INTERFACE_CLASS_SPECIFIC,
|
||||
.bDescriptorSubType = CDC_FUNC_DESC_HEADER,
|
||||
.bcdCDC = 0x0120
|
||||
},
|
||||
|
||||
.cdc_acm =
|
||||
{
|
||||
.bLength = sizeof(cdc_desc_func_acm_t),
|
||||
.bDescriptorType = TUSB_DESC_TYPE_INTERFACE_CLASS_SPECIFIC,
|
||||
.bDescriptorSubType = CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT,
|
||||
.bmCapabilities = { 0 }
|
||||
},
|
||||
|
||||
.cdc_union =
|
||||
{
|
||||
.bLength = sizeof(cdc_desc_func_union_t), // plus number of
|
||||
.bDescriptorType = TUSB_DESC_TYPE_INTERFACE_CLASS_SPECIFIC,
|
||||
.bDescriptorSubType = CDC_FUNC_DESC_UNION,
|
||||
.bControlInterface = 1,
|
||||
.bSubordinateInterface = 2,
|
||||
},
|
||||
|
||||
.cdc_endpoint_notification =
|
||||
{
|
||||
.bLength = sizeof(tusb_desc_endpoint_t),
|
||||
.bDescriptorType = TUSB_DESC_TYPE_ENDPOINT,
|
||||
.bEndpointAddress = 0x81,
|
||||
.bmAttributes = { .xfer = TUSB_XFER_INTERRUPT },
|
||||
.wMaxPacketSize = 8,
|
||||
.bInterval = 0x0a // lowest polling rate
|
||||
},
|
||||
|
||||
//------------- CDC Data Interface -------------//
|
||||
.cdc_data_interface =
|
||||
{
|
||||
.bLength = sizeof(tusb_desc_interface_t),
|
||||
.bDescriptorType = TUSB_DESC_TYPE_INTERFACE,
|
||||
.bInterfaceNumber = 2,
|
||||
.bAlternateSetting = 0x00,
|
||||
.bNumEndpoints = 2,
|
||||
.bInterfaceClass = TUSB_CLASS_CDC_DATA,
|
||||
.bInterfaceSubClass = 0,
|
||||
.bInterfaceProtocol = 0,
|
||||
.iInterface = 0x00
|
||||
},
|
||||
|
||||
.cdc_endpoint_out =
|
||||
{
|
||||
.bLength = sizeof(tusb_desc_endpoint_t),
|
||||
.bDescriptorType = TUSB_DESC_TYPE_ENDPOINT,
|
||||
.bEndpointAddress = 2,
|
||||
.bmAttributes = { .xfer = TUSB_XFER_BULK },
|
||||
.wMaxPacketSize = 512,
|
||||
.bInterval = 0
|
||||
},
|
||||
|
||||
.cdc_endpoint_in =
|
||||
{
|
||||
.bLength = sizeof(tusb_desc_endpoint_t),
|
||||
.bDescriptorType = TUSB_DESC_TYPE_ENDPOINT,
|
||||
.bEndpointAddress = 0x82,
|
||||
.bmAttributes = { .xfer = TUSB_XFER_BULK },
|
||||
.wMaxPacketSize = 512,
|
||||
.bInterval = 0
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* This file is part of the TinyUSB stack.
|
||||
*/
|
||||
|
||||
/** \ingroup TBD
|
||||
* \defgroup TBD
|
||||
* \brief TBD
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _TUSB_DESCRIPTOR_CDC_H_
|
||||
#define _TUSB_DESCRIPTOR_CDC_H_
|
||||
|
||||
#include "common/common.h"
|
||||
#include "class/cdc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
tusb_desc_configuration_t configuration;
|
||||
|
||||
tusb_desc_interface_assoc_t cdc_iad;
|
||||
|
||||
//CDC Control Interface
|
||||
tusb_desc_interface_t cdc_comm_interface;
|
||||
cdc_desc_func_header_t cdc_header;
|
||||
cdc_desc_func_acm_t cdc_acm;
|
||||
cdc_desc_func_union_t cdc_union;
|
||||
tusb_desc_endpoint_t cdc_endpoint_notification;
|
||||
|
||||
//CDC Data Interface
|
||||
tusb_desc_interface_t cdc_data_interface;
|
||||
tusb_desc_endpoint_t cdc_endpoint_out;
|
||||
tusb_desc_endpoint_t cdc_endpoint_in;
|
||||
|
||||
} cdc_configuration_desc_t;
|
||||
|
||||
extern const cdc_configuration_desc_t cdc_config_descriptor;
|
||||
extern const cdc_configuration_desc_t rndis_config_descriptor;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _TUSB_DESCRIPTOR_CDC_H_ */
|
||||
|
||||
/** @} */
|
||||
@@ -0,0 +1,278 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* This file is part of the TinyUSB stack.
|
||||
*/
|
||||
|
||||
#include "stdlib.h"
|
||||
#include "unity.h"
|
||||
#include "tusb_option.h"
|
||||
#include "tusb_errors.h"
|
||||
#include "binary.h"
|
||||
#include "type_helper.h"
|
||||
|
||||
#include "mock_osal.h"
|
||||
#include "mock_hcd.h"
|
||||
#include "mock_usbh.h"
|
||||
#include "mock_cdc_callback.h"
|
||||
|
||||
#include "descriptor_cdc.h"
|
||||
#include "cdc_host.h"
|
||||
|
||||
#if CFG_TUH_CDC_RNDIS // TODO enable
|
||||
#include "cdc_rndis_host.h"
|
||||
#endif
|
||||
|
||||
static uint8_t dev_addr;
|
||||
static uint16_t length;
|
||||
|
||||
static tusb_desc_interface_t const * p_comm_interface = &cdc_config_descriptor.cdc_comm_interface;
|
||||
static tusb_desc_endpoint_t const * p_endpoint_notification = &cdc_config_descriptor.cdc_endpoint_notification;
|
||||
static tusb_desc_endpoint_t const * p_endpoint_out = &cdc_config_descriptor.cdc_endpoint_out;
|
||||
static tusb_desc_endpoint_t const * p_endpoint_in = &cdc_config_descriptor.cdc_endpoint_in;
|
||||
|
||||
extern cdch_data_t cdch_data[CFG_TUSB_HOST_DEVICE_MAX];
|
||||
static cdch_data_t * p_cdc = &cdch_data[0];
|
||||
|
||||
void setUp(void)
|
||||
{
|
||||
length = 0;
|
||||
dev_addr = 1;
|
||||
|
||||
tu_memclr(cdch_data, sizeof(cdch_data_t)*CFG_TUSB_HOST_DEVICE_MAX);
|
||||
}
|
||||
|
||||
void tearDown(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// OPEN
|
||||
//--------------------------------------------------------------------+
|
||||
void test_cdch_open_failed_to_open_notification_endpoint(void)
|
||||
{
|
||||
pipe_handle_t null_hdl = {0};
|
||||
|
||||
hcd_edpt_open_ExpectAndReturn(dev_addr, p_endpoint_notification, TUSB_CLASS_CDC, null_hdl);
|
||||
|
||||
//------------- CUT -------------//
|
||||
TEST_ASSERT_EQUAL(TUSB_ERROR_HCD_OPEN_PIPE_FAILED, cdch_open(dev_addr, p_comm_interface, &length));
|
||||
|
||||
}
|
||||
|
||||
void test_cdch_open_failed_to_open_data_endpoint_out(void)
|
||||
{
|
||||
pipe_handle_t dummy_hld = { .dev_addr = 1 };
|
||||
pipe_handle_t null_hdl = {0};
|
||||
|
||||
hcd_edpt_open_ExpectAndReturn(dev_addr, p_endpoint_notification, TUSB_CLASS_CDC, dummy_hld);
|
||||
hcd_edpt_open_ExpectAndReturn(dev_addr, p_endpoint_out, TUSB_CLASS_CDC, null_hdl);
|
||||
|
||||
//------------- CUT -------------//
|
||||
TEST_ASSERT_EQUAL(TUSB_ERROR_HCD_OPEN_PIPE_FAILED, cdch_open(dev_addr, p_comm_interface, &length));
|
||||
|
||||
}
|
||||
|
||||
void test_cdch_open_failed_to_open_data_endpoint_in(void)
|
||||
{
|
||||
pipe_handle_t dummy_hld = { .dev_addr = 1 };
|
||||
pipe_handle_t null_hdl = {0};
|
||||
|
||||
hcd_edpt_open_ExpectAndReturn(dev_addr, p_endpoint_notification, TUSB_CLASS_CDC, dummy_hld);
|
||||
hcd_edpt_open_ExpectAndReturn(dev_addr, p_endpoint_out, TUSB_CLASS_CDC, dummy_hld);
|
||||
hcd_edpt_open_ExpectAndReturn(dev_addr, p_endpoint_in, TUSB_CLASS_CDC, null_hdl);
|
||||
|
||||
//------------- CUT -------------//
|
||||
TEST_ASSERT_EQUAL(TUSB_ERROR_HCD_OPEN_PIPE_FAILED, cdch_open(dev_addr, p_comm_interface, &length));
|
||||
|
||||
}
|
||||
|
||||
void test_cdch_open_length_check(void)
|
||||
{
|
||||
const uint16_t expected_length =
|
||||
//------------- Comm Interface -------------//
|
||||
sizeof(tusb_desc_interface_t) + sizeof(cdc_desc_func_header_t) +
|
||||
sizeof(cdc_desc_func_acm_t) + sizeof(cdc_desc_func_union_t) +
|
||||
sizeof(tusb_desc_endpoint_t) +
|
||||
//------------- Data Interface -------------//
|
||||
sizeof(tusb_desc_interface_t) + 2*sizeof(tusb_desc_endpoint_t);
|
||||
|
||||
pipe_handle_t dummy_hld = { .dev_addr = 1 };
|
||||
hcd_edpt_open_IgnoreAndReturn(dummy_hld);
|
||||
tusbh_cdc_mounted_cb_Expect(dev_addr);
|
||||
|
||||
//------------- CUT -------------//
|
||||
TEST_ASSERT_EQUAL( TUSB_ERROR_NONE, cdch_open(dev_addr, p_comm_interface, &length) );
|
||||
|
||||
TEST_ASSERT_EQUAL(expected_length, length);
|
||||
}
|
||||
|
||||
void test_cdch_open_interface_number_check(void)
|
||||
{
|
||||
pipe_handle_t dummy_hld = { .dev_addr = 1 };
|
||||
hcd_edpt_open_IgnoreAndReturn(dummy_hld);
|
||||
tusbh_cdc_mounted_cb_Expect(dev_addr);
|
||||
|
||||
//------------- CUT -------------//
|
||||
TEST_ASSERT_EQUAL( TUSB_ERROR_NONE, cdch_open(dev_addr, p_comm_interface, &length) );
|
||||
|
||||
TEST_ASSERT_EQUAL(1, p_cdc->interface_number);
|
||||
|
||||
}
|
||||
|
||||
void test_cdch_open_protocol_check(void)
|
||||
{
|
||||
pipe_handle_t dummy_hld = { .dev_addr = 1 };
|
||||
hcd_edpt_open_IgnoreAndReturn(dummy_hld);
|
||||
tusbh_cdc_mounted_cb_Expect(dev_addr);
|
||||
|
||||
//------------- CUT -------------//
|
||||
TEST_ASSERT_EQUAL( TUSB_ERROR_NONE, cdch_open(dev_addr, p_comm_interface, &length) );
|
||||
|
||||
TEST_ASSERT_EQUAL(p_comm_interface->bInterfaceProtocol, p_cdc->interface_protocol);
|
||||
|
||||
}
|
||||
|
||||
void test_cdch_open_acm_capacity_check(void)
|
||||
{
|
||||
pipe_handle_t dummy_hld = { .dev_addr = 1 };
|
||||
hcd_edpt_open_IgnoreAndReturn(dummy_hld);
|
||||
tusbh_cdc_mounted_cb_Expect(dev_addr);
|
||||
|
||||
//------------- CUT -------------//
|
||||
TEST_ASSERT_EQUAL( TUSB_ERROR_NONE, cdch_open(dev_addr, p_comm_interface, &length) );
|
||||
|
||||
TEST_ASSERT_EQUAL_MEMORY(&cdc_config_descriptor.cdc_acm.bmCapabilities, &p_cdc->acm_capability, 1);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// CLOSE
|
||||
//--------------------------------------------------------------------+
|
||||
void test_cdch_close_device(void)
|
||||
{
|
||||
pipe_handle_t pipe_notification = { .dev_addr = 1, .xfer_type = TUSB_XFER_INTERRUPT };
|
||||
pipe_handle_t pipe_out = { .dev_addr = 1, .xfer_type = TUSB_XFER_BULK, .index = 0 };
|
||||
pipe_handle_t pipe_int = { .dev_addr = 1, .xfer_type = TUSB_XFER_BULK, .index = 1 };
|
||||
|
||||
hcd_edpt_open_ExpectAndReturn(dev_addr, p_endpoint_notification, TUSB_CLASS_CDC, pipe_notification);
|
||||
hcd_edpt_open_ExpectAndReturn(dev_addr, p_endpoint_out, TUSB_CLASS_CDC, pipe_out);
|
||||
hcd_edpt_open_ExpectAndReturn(dev_addr, p_endpoint_in, TUSB_CLASS_CDC, pipe_int);
|
||||
tusbh_cdc_mounted_cb_Expect(dev_addr);
|
||||
|
||||
TEST_ASSERT_EQUAL( TUSB_ERROR_NONE, cdch_open(dev_addr, p_comm_interface, &length) );
|
||||
|
||||
hcd_pipe_close_ExpectAndReturn(pipe_notification , TUSB_ERROR_NONE);
|
||||
hcd_pipe_close_ExpectAndReturn(pipe_int , TUSB_ERROR_NONE);
|
||||
hcd_pipe_close_ExpectAndReturn(pipe_out , TUSB_ERROR_NONE);
|
||||
|
||||
tusbh_cdc_unmounted_cb_Expect(dev_addr);
|
||||
|
||||
//------------- CUT -------------//
|
||||
cdch_close(dev_addr);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// CHECKING API
|
||||
//--------------------------------------------------------------------+
|
||||
void test_cdc_serial_is_mounted_not_configured(void)
|
||||
{
|
||||
tusbh_device_get_mounted_class_flag_ExpectAndReturn(dev_addr, 0);
|
||||
|
||||
TEST_ASSERT_FALSE( tusbh_cdc_serial_is_mounted(dev_addr) );
|
||||
}
|
||||
|
||||
void test_cdc_serial_is_mounted_protocol_zero(void)
|
||||
{
|
||||
tusbh_device_get_mounted_class_flag_ExpectAndReturn(dev_addr, TU_BIT(TUSB_CLASS_CDC) );
|
||||
cdch_data[0].interface_protocol = 0;
|
||||
|
||||
TEST_ASSERT_FALSE( tusbh_cdc_serial_is_mounted(dev_addr) );
|
||||
}
|
||||
|
||||
void test_cdc_serial_is_mounted_protocol_is_vendor(void)
|
||||
{
|
||||
tusbh_device_get_mounted_class_flag_ExpectAndReturn(dev_addr, TU_BIT(TUSB_CLASS_CDC) );
|
||||
cdch_data[0].interface_protocol = 0xff;
|
||||
|
||||
TEST_ASSERT_FALSE( tusbh_cdc_serial_is_mounted(dev_addr) );
|
||||
}
|
||||
|
||||
void test_cdc_serial_is_mounted_protocol_is_at_command(void)
|
||||
{
|
||||
tusbh_device_get_mounted_class_flag_ExpectAndReturn(dev_addr, TU_BIT(TUSB_CLASS_CDC) );
|
||||
cdch_data[0].interface_protocol = CDC_COMM_PROTOCOL_ATCOMMAND;
|
||||
|
||||
TEST_ASSERT( tusbh_cdc_serial_is_mounted(dev_addr) );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// TRANSFER API
|
||||
//--------------------------------------------------------------------+
|
||||
void test_cdc_xfer_notification_pipe(void)
|
||||
{
|
||||
pipe_handle_t pipe_notification = { .dev_addr = 1, .xfer_type = TUSB_XFER_INTERRUPT };
|
||||
pipe_handle_t pipe_out = { .dev_addr = 1, .xfer_type = TUSB_XFER_BULK, .index = 0 };
|
||||
pipe_handle_t pipe_in = { .dev_addr = 1, .xfer_type = TUSB_XFER_BULK, .index = 1 };
|
||||
|
||||
cdch_data[dev_addr-1].pipe_notification = pipe_notification;
|
||||
cdch_data[dev_addr-1].pipe_out = pipe_out;
|
||||
cdch_data[dev_addr-1].pipe_in = pipe_in;
|
||||
|
||||
tusbh_cdc_xfer_isr_Expect(dev_addr, XFER_RESULT_SUCCESS, CDC_PIPE_NOTIFICATION, 10);
|
||||
|
||||
//------------- CUT -------------//
|
||||
cdch_isr(pipe_notification, XFER_RESULT_SUCCESS, 10);
|
||||
}
|
||||
|
||||
void test_cdc_xfer_pipe_out(void)
|
||||
{
|
||||
pipe_handle_t pipe_notification = { .dev_addr = 1, .xfer_type = TUSB_XFER_INTERRUPT };
|
||||
pipe_handle_t pipe_out = { .dev_addr = 1, .xfer_type = TUSB_XFER_BULK, .index = 0 };
|
||||
pipe_handle_t pipe_in = { .dev_addr = 1, .xfer_type = TUSB_XFER_BULK, .index = 1 };
|
||||
|
||||
cdch_data[dev_addr-1].pipe_notification = pipe_notification;
|
||||
cdch_data[dev_addr-1].pipe_out = pipe_out;
|
||||
cdch_data[dev_addr-1].pipe_in = pipe_in;
|
||||
|
||||
tusbh_cdc_xfer_isr_Expect(dev_addr, XFER_RESULT_FAILED, CDC_PIPE_DATA_OUT, 20);
|
||||
|
||||
//------------- CUT -------------//
|
||||
cdch_isr(pipe_out, XFER_RESULT_FAILED, 20);
|
||||
}
|
||||
|
||||
void test_cdc_xfer_pipe_in(void)
|
||||
{
|
||||
pipe_handle_t pipe_notification = { .dev_addr = 1, .xfer_type = TUSB_XFER_INTERRUPT };
|
||||
pipe_handle_t pipe_out = { .dev_addr = 1, .xfer_type = TUSB_XFER_BULK, .index = 0 };
|
||||
pipe_handle_t pipe_in = { .dev_addr = 1, .xfer_type = TUSB_XFER_BULK, .index = 1 };
|
||||
|
||||
cdch_data[dev_addr-1].pipe_notification = pipe_notification;
|
||||
cdch_data[dev_addr-1].pipe_out = pipe_out;
|
||||
cdch_data[dev_addr-1].pipe_in = pipe_in;
|
||||
|
||||
tusbh_cdc_xfer_isr_Expect(dev_addr, XFER_RESULT_STALLED, CDC_PIPE_DATA_IN, 0);
|
||||
|
||||
//------------- CUT -------------//
|
||||
cdch_isr(pipe_in, XFER_RESULT_STALLED, 0);
|
||||
}
|
||||
@@ -0,0 +1,304 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* This file is part of the TinyUSB stack.
|
||||
*/
|
||||
|
||||
void setUp(void)
|
||||
{
|
||||
}
|
||||
void tearDown(void)
|
||||
{
|
||||
}
|
||||
|
||||
#if 0 // TODO enable
|
||||
#include "stdlib.h"
|
||||
#include "unity.h"
|
||||
#include "tusb_option.h"
|
||||
#include "tusb_errors.h"
|
||||
#include "binary.h"
|
||||
#include "type_helper.h"
|
||||
|
||||
#include "mock_osal.h"
|
||||
#include "mock_hcd.h"
|
||||
#include "mock_usbh.h"
|
||||
#include "mock_cdc_callback.h"
|
||||
|
||||
#include "descriptor_cdc.h"
|
||||
#include "cdc_host.h"
|
||||
#include "cdc_rndis_host.h"
|
||||
|
||||
static uint8_t dev_addr;
|
||||
static uint16_t length;
|
||||
|
||||
static tusb_desc_interface_t const * p_comm_interface = &rndis_config_descriptor.cdc_comm_interface;
|
||||
static tusb_desc_endpoint_t const * p_endpoint_notification = &rndis_config_descriptor.cdc_endpoint_notification;
|
||||
static tusb_desc_endpoint_t const * p_endpoint_out = &rndis_config_descriptor.cdc_endpoint_out;
|
||||
static tusb_desc_endpoint_t const * p_endpoint_in = &rndis_config_descriptor.cdc_endpoint_in;
|
||||
|
||||
static pipe_handle_t pipe_notification = { .dev_addr = 1, .xfer_type = TUSB_XFER_INTERRUPT };
|
||||
static pipe_handle_t pipe_out = { .dev_addr = 1, .xfer_type = TUSB_XFER_BULK, .index = 0 };
|
||||
static pipe_handle_t pipe_in = { .dev_addr = 1, .xfer_type = TUSB_XFER_BULK, .index = 1 };
|
||||
|
||||
extern cdch_data_t cdch_data[CFG_TUSB_HOST_DEVICE_MAX];
|
||||
extern rndish_data_t rndish_data[CFG_TUSB_HOST_DEVICE_MAX];
|
||||
|
||||
static cdch_data_t * p_cdc = &cdch_data[0];
|
||||
static rndish_data_t * p_rndis = &rndish_data[0];
|
||||
|
||||
enum {
|
||||
bmrequest_send = 0x21,
|
||||
bmrequest_get = 0xA1
|
||||
};
|
||||
|
||||
void stub_mutex_wait(osal_mutex_handle_t mutex_hdl, uint32_t msec, tusb_error_t *p_error, int num_call)
|
||||
{
|
||||
*p_error = TUSB_ERROR_NONE;
|
||||
}
|
||||
|
||||
void setUp(void)
|
||||
{
|
||||
length = 0;
|
||||
dev_addr = 1;
|
||||
|
||||
for (uint8_t i=0; i<CFG_TUSB_HOST_DEVICE_MAX; i++)
|
||||
{
|
||||
osal_semaphore_create_ExpectAndReturn( &rndish_data[i].semaphore_notification, &rndish_data[i].semaphore_notification);
|
||||
}
|
||||
|
||||
cdch_init();
|
||||
|
||||
osal_mutex_wait_StubWithCallback(stub_mutex_wait);
|
||||
osal_mutex_release_IgnoreAndReturn(TUSB_ERROR_NONE);
|
||||
|
||||
hcd_edpt_open_ExpectAndReturn(dev_addr, p_endpoint_notification, TUSB_CLASS_CDC, pipe_notification);
|
||||
hcd_edpt_open_ExpectAndReturn(dev_addr, p_endpoint_out, TUSB_CLASS_CDC, pipe_out);
|
||||
hcd_edpt_open_ExpectAndReturn(dev_addr, p_endpoint_in, TUSB_CLASS_CDC, pipe_in);
|
||||
}
|
||||
|
||||
void tearDown(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
static rndis_msg_initialize_t msg_init =
|
||||
{
|
||||
.type = RNDIS_MSG_INITIALIZE,
|
||||
.length = sizeof(rndis_msg_initialize_t),
|
||||
.request_id = 1, // TODO should use some magic number
|
||||
.major_version = 1,
|
||||
.minor_version = 0,
|
||||
.max_xfer_size = 0x4000 // TODO mimic windows
|
||||
};
|
||||
|
||||
static rndis_msg_initialize_cmplt_t msg_init_cmplt =
|
||||
{
|
||||
.type = RNDIS_MSG_INITIALIZE_CMPLT,
|
||||
.length = sizeof(rndis_msg_initialize_cmplt_t),
|
||||
.request_id = 1,
|
||||
.status = RNDIS_STATUS_SUCCESS,
|
||||
.major_version = 1,
|
||||
.minor_version = 0,
|
||||
.device_flags = 0x10,
|
||||
.medium = 0, // TODO cannot find info on this
|
||||
.max_packet_per_xfer = 1,
|
||||
.max_xfer_size = 0x100, // TODO change later
|
||||
.packet_alignment_factor = 5 // aligment of each RNDIS message (payload) = 2^factor
|
||||
};
|
||||
|
||||
static rndis_msg_query_t msg_query_permanent_addr =
|
||||
{
|
||||
.type = RNDIS_MSG_QUERY,
|
||||
.length = sizeof(rndis_msg_query_t)+6,
|
||||
.request_id = 1,
|
||||
.oid = RNDIS_OID_802_3_PERMANENT_ADDRESS,
|
||||
.buffer_length = 6,
|
||||
.buffer_offset = 20,
|
||||
.oid_buffer = {0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
static rndis_msg_query_cmplt_t msg_query_permanent_addr_cmplt =
|
||||
{
|
||||
.type = RNDIS_MSG_QUERY_CMPLT,
|
||||
.length = sizeof(rndis_msg_query_cmplt_t)+6,
|
||||
.request_id = 1,
|
||||
.status = RNDIS_STATUS_SUCCESS,
|
||||
.buffer_length = 6,
|
||||
.buffer_offset = 16,
|
||||
.oid_buffer = "CAFEBB"
|
||||
};
|
||||
|
||||
static rndis_msg_set_t msg_set_packet_filter =
|
||||
{
|
||||
.type = RNDIS_MSG_SET,
|
||||
.length = sizeof(rndis_msg_set_t)+4,
|
||||
.request_id = 1,
|
||||
.oid = RNDIS_OID_GEN_CURRENT_PACKET_FILTER,
|
||||
.buffer_length = 4,
|
||||
.buffer_offset = 20,
|
||||
.oid_buffer = {RNDIS_PACKET_TYPE_DIRECTED | RNDIS_PACKET_TYPE_MULTICAST | RNDIS_PACKET_TYPE_BROADCAST, 0, 0, 0}
|
||||
};
|
||||
|
||||
static rndis_msg_set_cmplt_t msg_set_packet_filter_cmplt =
|
||||
{
|
||||
.type = RNDIS_MSG_SET_CMPLT,
|
||||
.length = sizeof(rndis_msg_set_cmplt_t),
|
||||
.request_id = 1,
|
||||
.status = RNDIS_STATUS_SUCCESS
|
||||
};
|
||||
|
||||
static tusb_error_t stub_pipe_notification_xfer(pipe_handle_t pipe_hdl, uint8_t buffer[], uint16_t total_bytes, bool int_on_complete, int num_call)
|
||||
{
|
||||
TEST_ASSERT( pipehandle_is_equal(pipe_notification, pipe_hdl) );
|
||||
TEST_ASSERT_EQUAL( 8, total_bytes );
|
||||
TEST_ASSERT( int_on_complete );
|
||||
|
||||
buffer[0] = 1; // response available
|
||||
|
||||
cdch_isr(pipe_hdl, XFER_RESULT_SUCCESS, 8);
|
||||
|
||||
return TUSB_ERROR_NONE;
|
||||
}
|
||||
|
||||
void stub_sem_wait_success(osal_semaphore_handle_t const sem_hdl, uint32_t msec, tusb_error_t *p_error, int num_call)
|
||||
{
|
||||
TEST_ASSERT_EQUAL_HEX(p_rndis->sem_notification_hdl, sem_hdl);
|
||||
(*p_error) = TUSB_ERROR_NONE;
|
||||
}
|
||||
|
||||
void stub_sem_wait_timeout(osal_semaphore_handle_t const sem_hdl, uint32_t msec, tusb_error_t *p_error, int num_call)
|
||||
{
|
||||
(*p_error) = TUSB_ERROR_OSAL_TIMEOUT;
|
||||
}
|
||||
|
||||
//------------- Test Code -------------//
|
||||
void test_rndis_send_initalize_failed(void)
|
||||
{
|
||||
usbh_control_xfer_subtask_ExpectWithArrayAndReturn(
|
||||
dev_addr, bmrequest_send, SEND_ENCAPSULATED_COMMAND, 0, p_comm_interface->bInterfaceNumber,
|
||||
sizeof(rndis_msg_initialize_t), (uint8_t*)&msg_init, sizeof(rndis_msg_initialize_t), TUSB_ERROR_OSAL_TIMEOUT);
|
||||
|
||||
tusbh_cdc_mounted_cb_Expect(dev_addr);
|
||||
|
||||
//------------- Code Under Test -------------//
|
||||
TEST_ASSERT_EQUAL( TUSB_ERROR_NONE, cdch_open_subtask(dev_addr, p_comm_interface, &length) );
|
||||
}
|
||||
|
||||
void test_rndis_initialization_notification_timeout(void)
|
||||
{
|
||||
usbh_control_xfer_subtask_ExpectWithArrayAndReturn(
|
||||
dev_addr, bmrequest_send, SEND_ENCAPSULATED_COMMAND, 0, p_comm_interface->bInterfaceNumber,
|
||||
sizeof(rndis_msg_initialize_t), (uint8_t*)&msg_init, sizeof(rndis_msg_initialize_t), TUSB_ERROR_NONE);
|
||||
|
||||
hcd_pipe_xfer_IgnoreAndReturn(TUSB_ERROR_NONE);
|
||||
osal_semaphore_wait_StubWithCallback(stub_sem_wait_timeout);
|
||||
|
||||
tusbh_cdc_mounted_cb_Expect(dev_addr);
|
||||
|
||||
//------------- Code Under Test -------------//
|
||||
TEST_ASSERT_STATUS( cdch_open_subtask(dev_addr, p_comm_interface, &length) );
|
||||
TEST_ASSERT_FALSE(p_cdc->is_rndis);
|
||||
}
|
||||
|
||||
tusb_error_t stub_control_xfer(uint8_t addr, uint8_t bmRequestType, uint8_t bRequest,
|
||||
uint16_t wValue, uint16_t wIndex, uint16_t wLength, uint8_t* data, int num_call )
|
||||
{
|
||||
TEST_ASSERT_EQUAL(p_comm_interface->bInterfaceNumber, wIndex);
|
||||
TEST_ASSERT_EQUAL(0, wValue);
|
||||
TEST_ASSERT_EQUAL(dev_addr, addr);
|
||||
|
||||
switch(num_call)
|
||||
{
|
||||
//------------- Initialize -------------//
|
||||
case 0*2+0: // initialize
|
||||
TEST_ASSERT_EQUAL(bmrequest_send, bmRequestType);
|
||||
TEST_ASSERT_EQUAL(SEND_ENCAPSULATED_COMMAND, bRequest);
|
||||
TEST_ASSERT_EQUAL(sizeof(rndis_msg_initialize_t), wLength);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(&msg_init, data, wLength);
|
||||
break;
|
||||
|
||||
case 0*2+1: // initialize complete
|
||||
TEST_ASSERT_EQUAL(bmrequest_get, bmRequestType);
|
||||
TEST_ASSERT_EQUAL(GET_ENCAPSULATED_RESPONSE, bRequest);
|
||||
TEST_ASSERT( wLength >= 0x0400 ); // Microsoft Specs
|
||||
memcpy(data, &msg_init_cmplt, sizeof(rndis_msg_initialize_cmplt_t));
|
||||
break;
|
||||
|
||||
// query for RNDIS_OID_802_3_PERMANENT_ADDRESS
|
||||
case 1*2+0:
|
||||
TEST_ASSERT_EQUAL(bmrequest_send, bmRequestType);
|
||||
TEST_ASSERT_EQUAL(SEND_ENCAPSULATED_COMMAND, bRequest);
|
||||
TEST_ASSERT_EQUAL(sizeof(rndis_msg_query_t) + 6, wLength); // 6 bytes for MAC address
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(&msg_query_permanent_addr, data, wLength);
|
||||
break;
|
||||
|
||||
case 1*2+1: // query complete for RNDIS_OID_802_3_PERMANENT_ADDRESS
|
||||
TEST_ASSERT_EQUAL(bmrequest_get, bmRequestType);
|
||||
TEST_ASSERT_EQUAL(GET_ENCAPSULATED_RESPONSE, bRequest);
|
||||
TEST_ASSERT( wLength >= 0x0400 ); // Microsoft Specs
|
||||
memcpy(data, &msg_query_permanent_addr_cmplt, sizeof(rndis_msg_query_cmplt_t) + 6);
|
||||
break;
|
||||
|
||||
// set RNDIS_OID_GEN_CURRENT_PACKET_FILTER to DIRECTED | MULTICAST | BROADCAST
|
||||
case 2*2+0:
|
||||
TEST_ASSERT_EQUAL(bmrequest_send, bmRequestType);
|
||||
TEST_ASSERT_EQUAL(SEND_ENCAPSULATED_COMMAND, bRequest);
|
||||
TEST_ASSERT_EQUAL(sizeof(rndis_msg_set_t)+4, wLength);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(&msg_set_packet_filter, data, wLength);
|
||||
break;
|
||||
|
||||
case 2*2+1: // query complete for RNDIS_OID_802_3_PERMANENT_ADDRESS
|
||||
TEST_ASSERT_EQUAL(bmrequest_get, bmRequestType);
|
||||
TEST_ASSERT_EQUAL(GET_ENCAPSULATED_RESPONSE, bRequest);
|
||||
TEST_ASSERT( wLength >= 0x0400 ); // Microsoft Specs
|
||||
memcpy(data, &msg_set_packet_filter_cmplt, sizeof(rndis_msg_set_cmplt_t) );
|
||||
break;
|
||||
|
||||
default:
|
||||
return TUSB_ERROR_OSAL_TIMEOUT;
|
||||
}
|
||||
|
||||
return TUSB_ERROR_NONE;
|
||||
}
|
||||
|
||||
void test_rndis_initialization_sequence_ok(void)
|
||||
{
|
||||
usbh_control_xfer_subtask_StubWithCallback(stub_control_xfer);
|
||||
hcd_pipe_xfer_StubWithCallback(stub_pipe_notification_xfer);
|
||||
osal_semaphore_wait_StubWithCallback(stub_sem_wait_success);
|
||||
|
||||
osal_semaphore_post_ExpectAndReturn(p_rndis->sem_notification_hdl, TUSB_ERROR_NONE);
|
||||
osal_semaphore_post_ExpectAndReturn(p_rndis->sem_notification_hdl, TUSB_ERROR_NONE);
|
||||
osal_semaphore_post_ExpectAndReturn(p_rndis->sem_notification_hdl, TUSB_ERROR_NONE);
|
||||
|
||||
tusbh_cdc_rndis_mounted_cb_Expect(dev_addr);
|
||||
|
||||
//------------- Code Under Test -------------//
|
||||
TEST_ASSERT_STATUS( cdch_open_subtask(dev_addr, p_comm_interface, &length) );
|
||||
|
||||
TEST_ASSERT(p_cdc->is_rndis);
|
||||
TEST_ASSERT_EQUAL(msg_init_cmplt.max_xfer_size, p_rndis->max_xfer_size);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY("CAFEBB", p_rndis->mac_address, 6);
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* This file is part of the TinyUSB stack.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "unity.h"
|
||||
#include "type_helper.h"
|
||||
#include "tusb_option.h"
|
||||
#include "tusb_errors.h"
|
||||
#include "binary.h"
|
||||
|
||||
#include "hal.h"
|
||||
#include "hcd.h"
|
||||
#include "ehci.h"
|
||||
|
||||
#include "ehci_controller_fake.h"
|
||||
#include "mock_osal.h"
|
||||
#include "mock_usbh_hcd.h"
|
||||
|
||||
usbh_device_t _usbh_devices[CFG_TUSB_HOST_DEVICE_MAX+1];
|
||||
|
||||
static uint8_t hostid;
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Setup/Teardown + helper declare
|
||||
//--------------------------------------------------------------------+
|
||||
void setUp(void)
|
||||
{
|
||||
ehci_controller_init();
|
||||
TEST_ASSERT_STATUS( hcd_init() );
|
||||
|
||||
hostid = RANDOM(CONTROLLER_HOST_NUMBER) + TEST_CONTROLLER_HOST_START_INDEX;
|
||||
}
|
||||
|
||||
void tearDown(void)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------+
|
||||
void test_hcd_init_data(void)
|
||||
{
|
||||
//------------- check memory data -------------//
|
||||
TEST_ASSERT_MEM_ZERO(&ehci_data.device, sizeof(ehci_data.device));
|
||||
TEST_ASSERT_MEM_ZERO(ehci_data.addr0_qtd, sizeof(ehci_qtd_t)*3);
|
||||
}
|
||||
|
||||
void test_hcd_init_usbint(void)
|
||||
{
|
||||
ehci_registers_t* const regs = get_operational_register(hostid);
|
||||
|
||||
//------------- USB INT Enable-------------//
|
||||
TEST_ASSERT(regs->usb_int_enable_bit.usb_error);
|
||||
TEST_ASSERT(regs->usb_int_enable_bit.port_change_detect);
|
||||
TEST_ASSERT(regs->usb_int_enable_bit.async_advance);
|
||||
|
||||
TEST_ASSERT_FALSE(regs->usb_int_enable_bit.framelist_rollover);
|
||||
TEST_ASSERT_FALSE(regs->usb_int_enable_bit.pci_host_system_error);
|
||||
|
||||
TEST_ASSERT_FALSE(regs->usb_int_enable_bit.nxp_int_sof);
|
||||
TEST_ASSERT_FALSE(regs->usb_int_enable_bit.usb);
|
||||
TEST_ASSERT_TRUE(regs->usb_int_enable_bit.nxp_int_async);
|
||||
TEST_ASSERT_TRUE(regs->usb_int_enable_bit.nxp_int_period);
|
||||
|
||||
// TODO to be portable use usbint instead of nxp int async/period
|
||||
}
|
||||
|
||||
void test_hcd_init_async_list(void)
|
||||
{
|
||||
ehci_registers_t * const regs = get_operational_register(hostid);
|
||||
ehci_qhd_t * const async_head = get_async_head(hostid);
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX(async_head, regs->async_list_base);
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX(async_head, tu_align32( (uint32_t) async_head) );
|
||||
TEST_ASSERT_EQUAL(EHCI_QUEUE_ELEMENT_QHD, async_head->next.type);
|
||||
TEST_ASSERT_FALSE(async_head->next.terminate);
|
||||
|
||||
TEST_ASSERT(async_head->head_list_flag);
|
||||
TEST_ASSERT(async_head->qtd_overlay.halted);
|
||||
}
|
||||
|
||||
void check_qhd_endpoint_link(ehci_link_t *p_prev, ehci_qhd_t *p_qhd)
|
||||
{
|
||||
//------------- period list check -------------//
|
||||
TEST_ASSERT_EQUAL_HEX((uint32_t) p_qhd, tu_align32(p_prev->address));
|
||||
TEST_ASSERT_FALSE(p_prev->terminate);
|
||||
TEST_ASSERT_EQUAL(EHCI_QUEUE_ELEMENT_QHD, p_prev->type);
|
||||
}
|
||||
|
||||
void test_hcd_init_period_list(void)
|
||||
{
|
||||
ehci_registers_t* const regs = get_operational_register(hostid);
|
||||
ehci_qhd_t * const period_head_arr = get_period_head(hostid, 1);
|
||||
ehci_link_t * const framelist = get_period_frame_list(hostid);
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX( (uint32_t) framelist, regs->periodic_list_base);
|
||||
|
||||
check_qhd_endpoint_link( framelist+0, period_head_arr+1);
|
||||
check_qhd_endpoint_link( framelist+2, period_head_arr+1);
|
||||
check_qhd_endpoint_link( framelist+4, period_head_arr+1);
|
||||
check_qhd_endpoint_link( framelist+6, period_head_arr+1);
|
||||
|
||||
check_qhd_endpoint_link( framelist+1, period_head_arr+2);
|
||||
check_qhd_endpoint_link( framelist+5, period_head_arr+2);
|
||||
|
||||
check_qhd_endpoint_link( framelist+3, period_head_arr+3);
|
||||
check_qhd_endpoint_link( framelist+7, period_head_arr);
|
||||
check_qhd_endpoint_link( (ehci_link_t*) (period_head_arr+1), period_head_arr);
|
||||
check_qhd_endpoint_link( (ehci_link_t*) (period_head_arr+2), period_head_arr);
|
||||
check_qhd_endpoint_link( (ehci_link_t*) (period_head_arr+3), period_head_arr);
|
||||
|
||||
for(uint32_t i=0; i<4; i++)
|
||||
{
|
||||
TEST_ASSERT(period_head_arr[i].interrupt_smask);
|
||||
TEST_ASSERT(period_head_arr[i].qtd_overlay.halted);
|
||||
}
|
||||
|
||||
TEST_ASSERT_TRUE(period_head_arr[0].next.terminate);
|
||||
}
|
||||
|
||||
void test_hcd_init_tt_control(void)
|
||||
{
|
||||
ehci_registers_t* const regs = get_operational_register(hostid);
|
||||
}
|
||||
|
||||
void test_hcd_init_usbcmd(void)
|
||||
{
|
||||
ehci_registers_t* const regs = get_operational_register(hostid);
|
||||
|
||||
TEST_ASSERT(regs->usb_cmd_bit.async_enable);
|
||||
TEST_ASSERT(regs->usb_cmd_bit.periodic_enable);
|
||||
|
||||
//------------- Framelist size (NXP specific) -------------//
|
||||
TEST_ASSERT_BITS(TU_BIN8(11), EHCI_CFG_FRAMELIST_SIZE_BITS, regs->usb_cmd_bit.framelist_size);
|
||||
TEST_ASSERT_EQUAL(EHCI_CFG_FRAMELIST_SIZE_BITS >> 2, regs->usb_cmd_bit.nxp_framelist_size_msb);
|
||||
}
|
||||
|
||||
void test_hcd_init_portsc(void)
|
||||
{
|
||||
TEST_IGNORE_MESSAGE("more advance stuff need manipulate this register");
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* This file is part of the TinyUSB stack.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "unity.h"
|
||||
#include "tusb_option.h"
|
||||
#include "tusb_errors.h"
|
||||
#include "binary.h"
|
||||
#include "type_helper.h"
|
||||
|
||||
#include "hal.h"
|
||||
#include "ehci.h"
|
||||
|
||||
#include "ehci_controller_fake.h"
|
||||
#include "mock_osal.h"
|
||||
#include "mock_usbh_hcd.h"
|
||||
|
||||
usbh_device_t _usbh_devices[CFG_TUSB_HOST_DEVICE_MAX+1];
|
||||
|
||||
static uint8_t hostid;
|
||||
static ehci_registers_t * regs;
|
||||
|
||||
void setUp(void)
|
||||
{
|
||||
ehci_controller_init();
|
||||
TEST_ASSERT_STATUS( hcd_init());
|
||||
|
||||
hostid = RANDOM(CONTROLLER_HOST_NUMBER) + TEST_CONTROLLER_HOST_START_INDEX;
|
||||
regs = get_operational_register(hostid);
|
||||
}
|
||||
|
||||
void tearDown(void)
|
||||
{
|
||||
}
|
||||
|
||||
void test_isr_device_connect_highspeed(void)
|
||||
{
|
||||
hcd_event_device_attach_Expect(hostid);
|
||||
|
||||
//------------- Code Under Test -------------//
|
||||
ehci_controller_device_plug(hostid, TUSB_SPEED_HIGH);
|
||||
}
|
||||
|
||||
void test_isr_device_connect_fullspeed(void)
|
||||
{
|
||||
hcd_event_device_attach_Expect(hostid);
|
||||
|
||||
//------------- Code Under Test -------------//
|
||||
ehci_controller_device_plug(hostid, TUSB_SPEED_FULL);
|
||||
}
|
||||
|
||||
void test_isr_device_connect_slowspeed(void)
|
||||
{
|
||||
hcd_event_device_attach_Expect(hostid);
|
||||
|
||||
//------------- Code Under Test -------------//
|
||||
ehci_controller_device_plug(hostid, TUSB_SPEED_LOW);
|
||||
}
|
||||
|
||||
void test_isr_device_disconnect(void)
|
||||
{
|
||||
hcd_event_device_remove_Expect(hostid);
|
||||
|
||||
//------------- Code Under Test -------------//
|
||||
ehci_controller_device_unplug(hostid);
|
||||
|
||||
|
||||
// TEST_ASSERT(regs->usb_cmd_bit.advacne_async);
|
||||
}
|
||||
@@ -0,0 +1,292 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* This file is part of the TinyUSB stack.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "unity.h"
|
||||
#include "tusb_option.h"
|
||||
#include "tusb_errors.h"
|
||||
#include "binary.h"
|
||||
#include "type_helper.h"
|
||||
|
||||
#include "hal.h"
|
||||
#include "hcd.h"
|
||||
#include "ehci.h"
|
||||
|
||||
#include "ehci_controller_fake.h"
|
||||
#include "mock_osal.h"
|
||||
#include "mock_usbh_hcd.h"
|
||||
|
||||
usbh_device_t _usbh_devices[CFG_TUSB_HOST_DEVICE_MAX+1];
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Setup/Teardown + helper declare
|
||||
//--------------------------------------------------------------------+
|
||||
void setUp(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void tearDown(void)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
//
|
||||
//--------------------------------------------------------------------+
|
||||
void test_struct_alignment(void)
|
||||
{
|
||||
TEST_ASSERT_EQUAL( 32, __alignof__(ehci_qhd_t) );
|
||||
// TEST_ASSERT_EQUAL( 32, __alignof__(ehci_qtd_t) ); ehci_qtd_t is used to declare overlay variable in qhd --> cannot declare with TU_ATTR_ALIGNED(32)
|
||||
|
||||
TEST_ASSERT_EQUAL( 32, __alignof__(ehci_itd_t) );
|
||||
TEST_ASSERT_EQUAL( 32, __alignof__(ehci_sitd_t) );
|
||||
|
||||
}
|
||||
|
||||
void test_struct_size(void)
|
||||
{
|
||||
if (4 < sizeof(void*)) // running tests in x64 environment
|
||||
{
|
||||
TEST_ASSERT_EQUAL( 64 - 8, offsetof(ehci_qhd_t, p_qtd_list_head) ); // 64 - 2x 32-bit pointer qtds
|
||||
}else
|
||||
{
|
||||
TEST_ASSERT_EQUAL( 64, sizeof(ehci_qhd_t) );
|
||||
}
|
||||
TEST_ASSERT_EQUAL( 32, sizeof(ehci_qtd_t) );
|
||||
|
||||
TEST_ASSERT_EQUAL( 64, sizeof(ehci_itd_t) );
|
||||
TEST_ASSERT_EQUAL( 32, sizeof(ehci_sitd_t) );
|
||||
|
||||
TEST_ASSERT_EQUAL( 4, sizeof(ehci_link_t) );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// EHCI Data Structure
|
||||
//--------------------------------------------------------------------+
|
||||
void test_qtd_structure(void)
|
||||
{
|
||||
TEST_ASSERT_EQUAL( 0, offsetof(ehci_qtd_t, next));
|
||||
TEST_ASSERT_EQUAL( 4, offsetof(ehci_qtd_t, alternate));
|
||||
TEST_ASSERT_EQUAL( 5, BITFIELD_OFFSET_OF_UINT32(ehci_qtd_t, 1, used));
|
||||
|
||||
//------------- Word 2 -------------//
|
||||
TEST_ASSERT_EQUAL( 0, BITFIELD_OFFSET_OF_UINT32(ehci_qtd_t, 2, pingstate_err) );
|
||||
TEST_ASSERT_EQUAL( 1, BITFIELD_OFFSET_OF_UINT32(ehci_qtd_t, 2, non_hs_split_state) );
|
||||
TEST_ASSERT_EQUAL( 2, BITFIELD_OFFSET_OF_UINT32(ehci_qtd_t, 2, non_hs_period_missed_uframe));
|
||||
TEST_ASSERT_EQUAL( 3, BITFIELD_OFFSET_OF_UINT32(ehci_qtd_t, 2, xact_err) );
|
||||
TEST_ASSERT_EQUAL( 4, BITFIELD_OFFSET_OF_UINT32(ehci_qtd_t, 2, babble_err) );
|
||||
TEST_ASSERT_EQUAL( 5, BITFIELD_OFFSET_OF_UINT32(ehci_qtd_t, 2, buffer_err) );
|
||||
TEST_ASSERT_EQUAL( 6, BITFIELD_OFFSET_OF_UINT32(ehci_qtd_t, 2, halted) );
|
||||
TEST_ASSERT_EQUAL( 7, BITFIELD_OFFSET_OF_UINT32(ehci_qtd_t, 2, active) );
|
||||
TEST_ASSERT_EQUAL( 8, BITFIELD_OFFSET_OF_UINT32(ehci_qtd_t, 2, pid) );
|
||||
TEST_ASSERT_EQUAL( 10, BITFIELD_OFFSET_OF_UINT32(ehci_qtd_t, 2, cerr) );
|
||||
TEST_ASSERT_EQUAL( 12, BITFIELD_OFFSET_OF_UINT32(ehci_qtd_t, 2, current_page) );
|
||||
TEST_ASSERT_EQUAL( 15, BITFIELD_OFFSET_OF_UINT32(ehci_qtd_t, 2, int_on_complete) );
|
||||
TEST_ASSERT_EQUAL( 16, BITFIELD_OFFSET_OF_UINT32(ehci_qtd_t, 2, total_bytes) );
|
||||
TEST_ASSERT_EQUAL( 31, BITFIELD_OFFSET_OF_UINT32(ehci_qtd_t, 2, data_toggle) );
|
||||
|
||||
TEST_ASSERT_EQUAL( 12, offsetof(ehci_qtd_t, buffer));
|
||||
}
|
||||
|
||||
void test_qhd_structure(void)
|
||||
{
|
||||
TEST_ASSERT_EQUAL( 0, offsetof(ehci_qhd_t, next));
|
||||
|
||||
//------------- Word 1 -------------//
|
||||
TEST_ASSERT_EQUAL( 0, BITFIELD_OFFSET_OF_UINT32(ehci_qhd_t, 1, device_address) );
|
||||
TEST_ASSERT_EQUAL( 7, BITFIELD_OFFSET_OF_UINT32(ehci_qhd_t, 1, non_hs_period_inactive_next_xact) );
|
||||
TEST_ASSERT_EQUAL( 8, BITFIELD_OFFSET_OF_UINT32(ehci_qhd_t, 1, endpoint_number) );
|
||||
TEST_ASSERT_EQUAL( 12, BITFIELD_OFFSET_OF_UINT32(ehci_qhd_t, 1, endpoint_speed) );
|
||||
TEST_ASSERT_EQUAL( 14, BITFIELD_OFFSET_OF_UINT32(ehci_qhd_t, 1, data_toggle_control) );
|
||||
TEST_ASSERT_EQUAL( 15, BITFIELD_OFFSET_OF_UINT32(ehci_qhd_t, 1, head_list_flag) );
|
||||
TEST_ASSERT_EQUAL( 16, BITFIELD_OFFSET_OF_UINT32(ehci_qhd_t, 1, max_package_size) );
|
||||
TEST_ASSERT_EQUAL( 27, BITFIELD_OFFSET_OF_UINT32(ehci_qhd_t, 1, non_hs_control_endpoint) );
|
||||
TEST_ASSERT_EQUAL( 28, BITFIELD_OFFSET_OF_UINT32(ehci_qhd_t, 1, nak_count_reload) );
|
||||
|
||||
//------------- Word 2 -------------//
|
||||
TEST_ASSERT_EQUAL( 0, BITFIELD_OFFSET_OF_UINT32(ehci_qhd_t, 2, interrupt_smask) );
|
||||
TEST_ASSERT_EQUAL( 8, BITFIELD_OFFSET_OF_UINT32(ehci_qhd_t, 2, non_hs_interrupt_cmask) );
|
||||
TEST_ASSERT_EQUAL( 16, BITFIELD_OFFSET_OF_UINT32(ehci_qhd_t, 2, hub_address) );
|
||||
TEST_ASSERT_EQUAL( 23, BITFIELD_OFFSET_OF_UINT32(ehci_qhd_t, 2, hub_port) );
|
||||
TEST_ASSERT_EQUAL( 30, BITFIELD_OFFSET_OF_UINT32(ehci_qhd_t, 2, mult) );
|
||||
|
||||
TEST_ASSERT_EQUAL( 3*4, offsetof(ehci_qhd_t, qtd_addr));
|
||||
TEST_ASSERT_EQUAL( 4*4, offsetof(ehci_qhd_t, qtd_overlay));
|
||||
}
|
||||
|
||||
void test_itd_structure(void)
|
||||
{
|
||||
TEST_ASSERT_EQUAL( 0, offsetof(ehci_itd_t, next));
|
||||
|
||||
// Each Transaction Word
|
||||
TEST_ASSERT_EQUAL( 0 , BITFIELD_OFFSET_OF_MEMBER(ehci_itd_t, xact[0], offset) );
|
||||
TEST_ASSERT_EQUAL( 12 , BITFIELD_OFFSET_OF_MEMBER(ehci_itd_t, xact[0], page_select) );
|
||||
TEST_ASSERT_EQUAL( 15 , BITFIELD_OFFSET_OF_MEMBER(ehci_itd_t, xact[0], int_on_complete) );
|
||||
TEST_ASSERT_EQUAL( 16 , BITFIELD_OFFSET_OF_MEMBER(ehci_itd_t, xact[0], length) );
|
||||
TEST_ASSERT_EQUAL( 28 , BITFIELD_OFFSET_OF_MEMBER(ehci_itd_t, xact[0], error) );
|
||||
TEST_ASSERT_EQUAL( 29 , BITFIELD_OFFSET_OF_MEMBER(ehci_itd_t, xact[0], babble_err) );
|
||||
TEST_ASSERT_EQUAL( 30 , BITFIELD_OFFSET_OF_MEMBER(ehci_itd_t, xact[0], buffer_err) );
|
||||
TEST_ASSERT_EQUAL( 31 , BITFIELD_OFFSET_OF_MEMBER(ehci_itd_t, xact[0], active) );
|
||||
|
||||
TEST_ASSERT_EQUAL( 9*4, offsetof(ehci_itd_t, BufferPointer));
|
||||
}
|
||||
|
||||
void test_sitd_structure(void)
|
||||
{
|
||||
TEST_ASSERT_EQUAL( 0, offsetof(ehci_sitd_t, next));
|
||||
|
||||
//------------- Word 1 -------------//
|
||||
TEST_ASSERT_EQUAL( 0, BITFIELD_OFFSET_OF_UINT32(ehci_sitd_t, 1, device_address) );
|
||||
TEST_ASSERT_EQUAL( 8, BITFIELD_OFFSET_OF_UINT32(ehci_sitd_t, 1, endpoint_number) );
|
||||
TEST_ASSERT_EQUAL( 16, BITFIELD_OFFSET_OF_UINT32(ehci_sitd_t, 1, hub_address) );
|
||||
TEST_ASSERT_EQUAL( 24, BITFIELD_OFFSET_OF_UINT32(ehci_sitd_t, 1, port_number) );
|
||||
TEST_ASSERT_EQUAL( 31, BITFIELD_OFFSET_OF_UINT32(ehci_sitd_t, 1, direction) );
|
||||
|
||||
//------------- Word 2 -------------//
|
||||
TEST_ASSERT_EQUAL( 4*2, offsetof(ehci_sitd_t, interrupt_smask));
|
||||
TEST_ASSERT_EQUAL( 4*2+1, offsetof(ehci_sitd_t, non_hs_interrupt_cmask));
|
||||
|
||||
//------------- Word 3 -------------//
|
||||
TEST_ASSERT_EQUAL( 1, BITFIELD_OFFSET_OF_UINT32(ehci_sitd_t, 3, split_state) );
|
||||
TEST_ASSERT_EQUAL( 2, BITFIELD_OFFSET_OF_UINT32(ehci_sitd_t, 3, missed_uframe));
|
||||
TEST_ASSERT_EQUAL( 3, BITFIELD_OFFSET_OF_UINT32(ehci_sitd_t, 3, xact_err) );
|
||||
TEST_ASSERT_EQUAL( 4, BITFIELD_OFFSET_OF_UINT32(ehci_sitd_t, 3, babble_err) );
|
||||
TEST_ASSERT_EQUAL( 5, BITFIELD_OFFSET_OF_UINT32(ehci_sitd_t, 3, buffer_err) );
|
||||
TEST_ASSERT_EQUAL( 6, BITFIELD_OFFSET_OF_UINT32(ehci_sitd_t, 3, error) );
|
||||
TEST_ASSERT_EQUAL( 7, BITFIELD_OFFSET_OF_UINT32(ehci_sitd_t, 3, active) );
|
||||
|
||||
TEST_ASSERT_EQUAL( 8, BITFIELD_OFFSET_OF_UINT32(ehci_sitd_t, 3, cmask_progress) );
|
||||
TEST_ASSERT_EQUAL( 16, BITFIELD_OFFSET_OF_UINT32(ehci_sitd_t, 3, total_bytes) );
|
||||
TEST_ASSERT_EQUAL( 30, BITFIELD_OFFSET_OF_UINT32(ehci_sitd_t, 3, page_select) );
|
||||
TEST_ASSERT_EQUAL( 31, BITFIELD_OFFSET_OF_UINT32(ehci_sitd_t, 3, int_on_complete) );
|
||||
|
||||
//------------- Word 4 -------------//
|
||||
TEST_ASSERT_EQUAL( 4*4, offsetof(ehci_sitd_t, buffer));
|
||||
|
||||
TEST_ASSERT_EQUAL( 4*6, offsetof(ehci_sitd_t, back));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// EHCI Register Interface
|
||||
//--------------------------------------------------------------------+
|
||||
void test_register_offset(void)
|
||||
{
|
||||
TEST_ASSERT_EQUAL( 0x00, offsetof(ehci_registers_t, usb_cmd));
|
||||
TEST_ASSERT_EQUAL( 0x04, offsetof(ehci_registers_t, usb_sts));
|
||||
TEST_ASSERT_EQUAL( 0x08, offsetof(ehci_registers_t, usb_int_enable));
|
||||
TEST_ASSERT_EQUAL( 0x0C, offsetof(ehci_registers_t, frame_index));
|
||||
TEST_ASSERT_EQUAL( 0x10, offsetof(ehci_registers_t, ctrl_ds_seg));
|
||||
TEST_ASSERT_EQUAL( 0x14, offsetof(ehci_registers_t, periodic_list_base));
|
||||
TEST_ASSERT_EQUAL( 0x18, offsetof(ehci_registers_t, async_list_base));
|
||||
TEST_ASSERT_EQUAL( 0x1C, offsetof(ehci_registers_t, tt_control)); // NXP specific
|
||||
TEST_ASSERT_EQUAL( 0x40, offsetof(ehci_registers_t, config_flag)); // NXP not used
|
||||
TEST_ASSERT_EQUAL( 0x44, offsetof(ehci_registers_t, portsc));
|
||||
}
|
||||
|
||||
void test_register_usbcmd(void)
|
||||
{
|
||||
TEST_ASSERT_EQUAL( 0 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_cmd_bit, run_stop) );
|
||||
TEST_ASSERT_EQUAL( 1 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_cmd_bit, reset) );
|
||||
TEST_ASSERT_EQUAL( 2 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_cmd_bit, framelist_size) );
|
||||
TEST_ASSERT_EQUAL( 4 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_cmd_bit, periodic_enable) );
|
||||
TEST_ASSERT_EQUAL( 5 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_cmd_bit, async_enable) );
|
||||
TEST_ASSERT_EQUAL( 6 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_cmd_bit, advance_async) );
|
||||
TEST_ASSERT_EQUAL( 7 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_cmd_bit, light_reset) );
|
||||
TEST_ASSERT_EQUAL( 8 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_cmd_bit, async_park) );
|
||||
TEST_ASSERT_EQUAL( 11 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_cmd_bit, async_park_enable) );
|
||||
TEST_ASSERT_EQUAL( 15 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_cmd_bit, nxp_framelist_size_msb) );
|
||||
TEST_ASSERT_EQUAL( 16 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_cmd_bit, int_threshold) );
|
||||
}
|
||||
|
||||
void test_register_usbsts(void)
|
||||
{
|
||||
TEST_ASSERT_EQUAL( 0 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_sts_bit, usb));
|
||||
TEST_ASSERT_EQUAL( 1 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_sts_bit, usb_error));
|
||||
TEST_ASSERT_EQUAL( 2 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_sts_bit, port_change_detect));
|
||||
TEST_ASSERT_EQUAL( 3 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_sts_bit, framelist_rollover));
|
||||
TEST_ASSERT_EQUAL( 4 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_sts_bit, pci_host_system_error));
|
||||
TEST_ASSERT_EQUAL( 5 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_sts_bit, async_advance));
|
||||
TEST_ASSERT_EQUAL( 7 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_sts_bit, nxp_int_sof));
|
||||
TEST_ASSERT_EQUAL( 12 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_sts_bit, hc_halted));
|
||||
TEST_ASSERT_EQUAL( 13 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_sts_bit, reclamation));
|
||||
TEST_ASSERT_EQUAL( 14 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_sts_bit, period_schedule_status));
|
||||
TEST_ASSERT_EQUAL( 15 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_sts_bit, async_schedule_status));
|
||||
TEST_ASSERT_EQUAL( 18 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_sts_bit, nxp_int_async));
|
||||
TEST_ASSERT_EQUAL( 19 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_sts_bit, nxp_int_period));
|
||||
}
|
||||
|
||||
void test_register_usbint(void)
|
||||
{
|
||||
TEST_ASSERT_EQUAL( 0 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_int_enable_bit, usb));
|
||||
TEST_ASSERT_EQUAL( 1 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_int_enable_bit, usb_error));
|
||||
TEST_ASSERT_EQUAL( 2 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_int_enable_bit, port_change_detect));
|
||||
TEST_ASSERT_EQUAL( 3 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_int_enable_bit, framelist_rollover));
|
||||
TEST_ASSERT_EQUAL( 4 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_int_enable_bit, pci_host_system_error));
|
||||
TEST_ASSERT_EQUAL( 5 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_int_enable_bit, async_advance));
|
||||
TEST_ASSERT_EQUAL( 7 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_int_enable_bit, nxp_int_sof));
|
||||
TEST_ASSERT_EQUAL( 18 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_int_enable_bit, nxp_int_async));
|
||||
TEST_ASSERT_EQUAL( 19 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_int_enable_bit, nxp_int_period));
|
||||
|
||||
}
|
||||
|
||||
void test_register_portsc(void)
|
||||
{
|
||||
TEST_ASSERT_EQUAL( 0 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, portsc_bit, current_connect_status));
|
||||
TEST_ASSERT_EQUAL( 1 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, portsc_bit, connect_status_change));
|
||||
TEST_ASSERT_EQUAL( 2 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, portsc_bit, port_enable));
|
||||
TEST_ASSERT_EQUAL( 3 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, portsc_bit, port_enable_change));
|
||||
TEST_ASSERT_EQUAL( 4 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, portsc_bit, over_current_active));
|
||||
TEST_ASSERT_EQUAL( 5 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, portsc_bit, over_current_change));
|
||||
TEST_ASSERT_EQUAL( 6 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, portsc_bit, force_port_resume));
|
||||
TEST_ASSERT_EQUAL( 7 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, portsc_bit, suspend));
|
||||
TEST_ASSERT_EQUAL( 8 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, portsc_bit, port_reset));
|
||||
TEST_ASSERT_EQUAL( 9 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, portsc_bit, nxp_highspeed_status));
|
||||
TEST_ASSERT_EQUAL( 10 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, portsc_bit, line_status));
|
||||
TEST_ASSERT_EQUAL( 12 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, portsc_bit, port_power));
|
||||
TEST_ASSERT_EQUAL( 13 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, portsc_bit, port_owner));
|
||||
TEST_ASSERT_EQUAL( 14 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, portsc_bit, port_indicator_control));
|
||||
TEST_ASSERT_EQUAL( 16 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, portsc_bit, port_test_control));
|
||||
TEST_ASSERT_EQUAL( 20 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, portsc_bit, wake_on_connect_enable));
|
||||
TEST_ASSERT_EQUAL( 21 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, portsc_bit, wake_on_disconnect_enable));
|
||||
TEST_ASSERT_EQUAL( 22 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, portsc_bit, wake_on_over_current_enable));
|
||||
TEST_ASSERT_EQUAL( 23 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, portsc_bit, nxp_phy_clock_disable));
|
||||
TEST_ASSERT_EQUAL( 24 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, portsc_bit, nxp_port_force_fullspeed));
|
||||
TEST_ASSERT_EQUAL( 26 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, portsc_bit, nxp_port_speed));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// EHCI Data Organization
|
||||
//--------------------------------------------------------------------+
|
||||
void test_ehci_data(void)
|
||||
{
|
||||
for(uint32_t i=0; i<CONTROLLER_HOST_NUMBER; i++)
|
||||
{
|
||||
uint8_t hostid = i+TEST_CONTROLLER_HOST_START_INDEX;
|
||||
TEST_ASSERT_BITS_LOW(4096-1, (uint32_t)get_period_frame_list(hostid) );
|
||||
}
|
||||
|
||||
// TODO more tests on ehci_data
|
||||
}
|
||||
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* This file is part of the TinyUSB stack.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "unity.h"
|
||||
#include "tusb_option.h"
|
||||
#include "tusb_errors.h"
|
||||
#include "binary.h"
|
||||
#include "type_helper.h"
|
||||
|
||||
#include "hal.h"
|
||||
#include "mock_osal.h"
|
||||
#include "mock_hid_host.h"
|
||||
#include "mock_msc_host.h"
|
||||
#include "mock_cdc_host.h"
|
||||
|
||||
#include "hcd.h"
|
||||
#include "usbh_hcd.h"
|
||||
#include "hub.h"
|
||||
#include "usbh.h"
|
||||
#include "ehci.h"
|
||||
#include "ehci_controller_fake.h"
|
||||
#include "host_helper.h"
|
||||
|
||||
static uint8_t const control_max_packet_size = 64;
|
||||
static uint8_t hub_addr;
|
||||
static uint8_t hub_port;
|
||||
static uint8_t dev_addr;
|
||||
static uint8_t hostid;
|
||||
|
||||
static ehci_registers_t * regs;
|
||||
static ehci_qhd_t *async_head;
|
||||
static ehci_qhd_t *period_head_arr;
|
||||
|
||||
extern osal_queue_handle_t enum_queue_hdl;
|
||||
|
||||
void setUp(void)
|
||||
{
|
||||
hub_addr = hub_port = 0;
|
||||
dev_addr = 1;
|
||||
hostid = RANDOM(CONTROLLER_HOST_NUMBER) + TEST_CONTROLLER_HOST_START_INDEX;
|
||||
|
||||
ehci_controller_init();
|
||||
|
||||
helper_usbh_init_expect();
|
||||
helper_class_init_expect();
|
||||
usbh_init();
|
||||
|
||||
helper_usbh_device_emulate(dev_addr, hub_addr, hub_port, hostid, TUSB_SPEED_HIGH);
|
||||
|
||||
regs = get_operational_register(hostid);
|
||||
async_head = get_async_head( hostid );
|
||||
period_head_arr = (ehci_qhd_t*) get_period_head( hostid, 1 );
|
||||
regs->usb_sts = 0; // hcd_init clear usb_sts by writing 1s
|
||||
}
|
||||
|
||||
void tearDown(void)
|
||||
{
|
||||
}
|
||||
|
||||
void test_addr0_control_close(void)
|
||||
{
|
||||
dev_addr = 0;
|
||||
helper_usbh_device_emulate(0, hub_addr, hub_port, hostid, TUSB_SPEED_HIGH);
|
||||
|
||||
TEST_ASSERT_STATUS( hcd_pipe_control_open(dev_addr, control_max_packet_size) );
|
||||
|
||||
TEST_ASSERT( hcd_pipe_control_xfer(dev_addr,
|
||||
&(tusb_control_request_t) {
|
||||
.bmRequestType_bit = { .direction = TUSB_DIR_HOST_TO_DEV, .type = TUSB_REQ_TYPE_STANDARD, .recipient = TUSB_REQ_RECIPIENT_DEVICE },
|
||||
.bRequest = TUSB_REQ_SET_ADDRESS,
|
||||
.wValue = 3 },
|
||||
NULL) ) ;
|
||||
|
||||
ehci_qhd_t *p_qhd = async_head;
|
||||
TEST_ASSERT_STATUS( hcd_pipe_control_close(dev_addr) );
|
||||
|
||||
//------------- Code Under Test -------------//
|
||||
regs->usb_sts_bit.port_change_detect = 0; // clear port change detect
|
||||
regs->usb_sts_bit.async_advance = 1;
|
||||
hcd_isr(hostid); // async advance
|
||||
|
||||
TEST_ASSERT( p_qhd->qtd_overlay.halted );
|
||||
TEST_ASSERT_FALSE( p_qhd->is_removing );
|
||||
TEST_ASSERT_NULL( p_qhd->p_qtd_list_head );
|
||||
TEST_ASSERT_NULL( p_qhd->p_qtd_list_tail );
|
||||
}
|
||||
|
||||
#if 0 // TODO TEST enable this
|
||||
void test_isr_disconnect_then_async_advance_control_pipe(void)
|
||||
{
|
||||
TEST_ASSERT_STATUS( hcd_pipe_control_open(dev_addr, control_max_packet_size) );
|
||||
|
||||
TEST_ASSERT( hcd_pipe_control_xfer(dev_addr,
|
||||
&(tusb_control_request_t) {
|
||||
.bmRequestType_bit = { .direction = TUSB_DIR_HOST_TO_DEV, .type = TUSB_REQ_TYPE_STANDARD, .recipient = TUSB_REQ_RECIPIENT_DEVICE },
|
||||
.bRequest = TUSB_REQ_SET_ADDRESS,
|
||||
.wValue = 3 },
|
||||
NULL) );
|
||||
|
||||
ehci_qhd_t *p_qhd = get_control_qhd(dev_addr);
|
||||
ehci_qtd_t *p_qtd_head = p_qhd->p_qtd_list_head;
|
||||
ehci_qtd_t *p_qtd_tail = p_qhd->p_qtd_list_tail;
|
||||
|
||||
usbh_enumerate_t root_enum_entry = { .core_id = hostid, .hub_addr = 0, .hub_port = 0 };
|
||||
osal_queue_send_ExpectWithArrayAndReturn(enum_queue_hdl, (uint8_t*)&root_enum_entry, sizeof(usbh_enumerate_t), TUSB_ERROR_NONE);
|
||||
|
||||
ehci_controller_device_unplug(hostid);
|
||||
|
||||
//------------- Code Under Test -------------//
|
||||
usbh_enumeration_task(NULL); // carry out unplug task
|
||||
regs->usb_sts_bit.port_change_detect = 0; // clear port change detect
|
||||
regs->usb_sts_bit.async_advance = 1;
|
||||
hcd_isr(hostid); // async advance
|
||||
|
||||
TEST_ASSERT_FALSE(p_qhd->used);
|
||||
TEST_ASSERT_FALSE(p_qhd->is_removing);
|
||||
// TEST_ASSERT_NULL(p_qhd->p_qtd_list_head);
|
||||
// TEST_ASSERT_NULL(p_qhd->p_qtd_list_tail);
|
||||
}
|
||||
#endif
|
||||
|
||||
void test_bulk_pipe_close(void)
|
||||
{
|
||||
tusb_desc_endpoint_t const desc_ept_bulk_in =
|
||||
{
|
||||
.bLength = sizeof(tusb_desc_endpoint_t),
|
||||
.bDescriptorType = TUSB_DESC_TYPE_ENDPOINT,
|
||||
.bEndpointAddress = 0x81,
|
||||
.bmAttributes = { .xfer = TUSB_XFER_BULK },
|
||||
.wMaxPacketSize = 512,
|
||||
.bInterval = 0
|
||||
};
|
||||
|
||||
uint8_t xfer_data[100];
|
||||
pipe_handle_t pipe_hdl = hcd_edpt_open(dev_addr, &desc_ept_bulk_in, TUSB_CLASS_MSC);
|
||||
|
||||
TEST_ASSERT_STATUS( hcd_pipe_xfer(pipe_hdl, xfer_data, sizeof(xfer_data), 100) );
|
||||
TEST_ASSERT_STATUS( hcd_pipe_xfer(pipe_hdl, xfer_data, sizeof(xfer_data), 50) );
|
||||
|
||||
ehci_qhd_t *p_qhd = &ehci_data.device[dev_addr-1].qhd[pipe_hdl.index];
|
||||
ehci_qtd_t *p_qtd_head = p_qhd->p_qtd_list_head;
|
||||
ehci_qtd_t *p_qtd_tail = p_qhd->p_qtd_list_tail;
|
||||
|
||||
TEST_ASSERT_STATUS( hcd_pipe_close(pipe_hdl) );
|
||||
|
||||
//------------- Code Under Test -------------//
|
||||
regs->usb_sts_bit.async_advance = 1;
|
||||
get_control_qhd(dev_addr)->is_removing = 1; // mimic unmount
|
||||
hcd_isr(hostid); // async advance
|
||||
|
||||
TEST_ASSERT_FALSE(p_qhd->used);
|
||||
TEST_ASSERT_FALSE(p_qhd->is_removing);
|
||||
// TEST_ASSERT_NULL(p_qhd->p_qtd_list_head);
|
||||
// TEST_ASSERT_NULL(p_qhd->p_qtd_list_tail);
|
||||
TEST_ASSERT_FALSE(p_qtd_head->used);
|
||||
TEST_ASSERT_FALSE(p_qtd_tail->used);
|
||||
}
|
||||
|
||||
#if 0 // TODO TEST enable this
|
||||
void test_device_unplugged_status(void)
|
||||
{
|
||||
usbh_enumerate_t root_enum_entry = { .core_id = hostid, .hub_addr = 0, .hub_port = 0 };
|
||||
osal_queue_send_ExpectWithArrayAndReturn(enum_queue_hdl, (uint8_t*)&root_enum_entry, sizeof(usbh_enumerate_t), TUSB_ERROR_NONE);
|
||||
|
||||
ehci_controller_device_unplug(hostid);
|
||||
// hcd_isr(hostid);
|
||||
TEST_ASSERT_EQUAL(TUSB_DEVICE_STATE_REMOVING, usbh_devices[dev_addr].state);
|
||||
|
||||
regs->usb_sts_bit.async_advance = 1;
|
||||
hcd_isr(hostid); // async advance
|
||||
|
||||
TEST_ASSERT_EQUAL(TUSB_DEVICE_STATE_UNPLUG, usbh_devices[dev_addr].state);
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* This file is part of the TinyUSB stack.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "unity.h"
|
||||
#include "tusb_option.h"
|
||||
#include "tusb_errors.h"
|
||||
#include "binary.h"
|
||||
#include "type_helper.h"
|
||||
|
||||
#include "hal.h"
|
||||
#include "mock_osal.h"
|
||||
#include "hcd.h"
|
||||
#include "mock_usbh_hcd.h"
|
||||
#include "ehci.h"
|
||||
#include "ehci_controller_fake.h"
|
||||
#include "host_helper.h"
|
||||
|
||||
usbh_device_t _usbh_devices[CFG_TUSB_HOST_DEVICE_MAX+1];
|
||||
|
||||
static uint8_t const hub_addr = 2;
|
||||
static uint8_t const hub_port = 2;
|
||||
static uint8_t dev_addr;
|
||||
static uint8_t hostid;
|
||||
|
||||
static ehci_qhd_t *async_head;
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Setup/Teardown + helper declare
|
||||
//--------------------------------------------------------------------+
|
||||
void setUp(void)
|
||||
{
|
||||
TEST_ASSERT_STATUS( hcd_init() );
|
||||
|
||||
dev_addr = 1;
|
||||
hostid = RANDOM(CONTROLLER_HOST_NUMBER) + TEST_CONTROLLER_HOST_START_INDEX;
|
||||
|
||||
tu_memclr(_usbh_devices, sizeof(usbh_device_t)*(CFG_TUSB_HOST_DEVICE_MAX+1));
|
||||
helper_usbh_device_emulate(dev_addr, hub_addr, hub_port, hostid, TUSB_SPEED_HIGH);
|
||||
|
||||
async_head = get_async_head( hostid );
|
||||
}
|
||||
|
||||
void tearDown(void)
|
||||
{
|
||||
}
|
||||
|
||||
void verify_open_qhd(ehci_qhd_t *p_qhd, uint8_t endpoint_addr, uint16_t max_packet_size)
|
||||
{
|
||||
TEST_ASSERT_EQUAL(dev_addr, p_qhd->device_address);
|
||||
TEST_ASSERT_FALSE(p_qhd->non_hs_period_inactive_next_xact);
|
||||
TEST_ASSERT_EQUAL(endpoint_addr & 0x0F, p_qhd->endpoint_number);
|
||||
TEST_ASSERT_EQUAL(_usbh_devices[dev_addr].speed, p_qhd->endpoint_speed);
|
||||
TEST_ASSERT_EQUAL(max_packet_size, p_qhd->max_package_size);
|
||||
TEST_ASSERT_EQUAL(0, p_qhd->nak_count_reload); // TDD NAK Reload disable
|
||||
|
||||
TEST_ASSERT_EQUAL(hub_addr, p_qhd->hub_address);
|
||||
TEST_ASSERT_EQUAL(hub_port, p_qhd->hub_port);
|
||||
TEST_ASSERT_EQUAL(1, p_qhd->mult); // TDD operation model for mult
|
||||
|
||||
TEST_ASSERT_FALSE(p_qhd->qtd_overlay.halted);
|
||||
TEST_ASSERT(p_qhd->qtd_overlay.next.terminate);
|
||||
TEST_ASSERT(p_qhd->qtd_overlay.alternate.terminate);
|
||||
|
||||
//------------- HCD -------------//
|
||||
TEST_ASSERT(p_qhd->used);
|
||||
TEST_ASSERT_FALSE(p_qhd->is_removing);
|
||||
TEST_ASSERT_NULL(p_qhd->p_qtd_list_head);
|
||||
TEST_ASSERT_NULL(p_qhd->p_qtd_list_tail);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// PIPE OPEN
|
||||
//--------------------------------------------------------------------+
|
||||
tusb_desc_endpoint_t const desc_ept_bulk_in =
|
||||
{
|
||||
.bLength = sizeof(tusb_desc_endpoint_t),
|
||||
.bDescriptorType = TUSB_DESC_TYPE_ENDPOINT,
|
||||
.bEndpointAddress = 0x81,
|
||||
.bmAttributes = { .xfer = TUSB_XFER_BULK },
|
||||
.wMaxPacketSize = 512,
|
||||
.bInterval = 0
|
||||
};
|
||||
|
||||
tusb_desc_endpoint_t const desc_ept_bulk_out =
|
||||
{
|
||||
.bLength = sizeof(tusb_desc_endpoint_t),
|
||||
.bDescriptorType = TUSB_DESC_TYPE_ENDPOINT,
|
||||
.bEndpointAddress = 0x01,
|
||||
.bmAttributes = { .xfer = TUSB_XFER_BULK },
|
||||
.wMaxPacketSize = 512,
|
||||
.bInterval = 0
|
||||
};
|
||||
|
||||
void verify_bulk_open_qhd(ehci_qhd_t *p_qhd, tusb_desc_endpoint_t const * desc_endpoint, uint8_t class_code)
|
||||
{
|
||||
verify_open_qhd(p_qhd, desc_endpoint->bEndpointAddress, desc_endpoint->wMaxPacketSize.size);
|
||||
|
||||
TEST_ASSERT_FALSE(p_qhd->head_list_flag);
|
||||
TEST_ASSERT_EQUAL(0, p_qhd->data_toggle_control);
|
||||
TEST_ASSERT_EQUAL(0, p_qhd->interrupt_smask);
|
||||
TEST_ASSERT_EQUAL(0, p_qhd->non_hs_interrupt_cmask);
|
||||
TEST_ASSERT_FALSE(p_qhd->non_hs_control_endpoint);
|
||||
|
||||
// TEST_ASSERT_EQUAL(desc_endpoint->bInterval); TDD highspeed bulk/control OUT
|
||||
|
||||
TEST_ASSERT_EQUAL(desc_endpoint->bEndpointAddress & 0x80 ? EHCI_PID_IN : EHCI_PID_OUT, p_qhd->pid_non_control);
|
||||
|
||||
TEST_ASSERT_EQUAL(class_code, p_qhd->class_code);
|
||||
//------------- async list check -------------//
|
||||
TEST_ASSERT_EQUAL_HEX((uint32_t) p_qhd, tu_align32(async_head->next.address));
|
||||
TEST_ASSERT_FALSE(async_head->next.terminate);
|
||||
TEST_ASSERT_EQUAL(EHCI_QUEUE_ELEMENT_QHD, async_head->next.type);
|
||||
}
|
||||
|
||||
void test_open_bulk_qhd_data(void)
|
||||
{
|
||||
ehci_qhd_t *p_qhd;
|
||||
pipe_handle_t pipe_hdl;
|
||||
tusb_desc_endpoint_t const * desc_endpoint = &desc_ept_bulk_in;
|
||||
|
||||
//------------- Code Under TEST -------------//
|
||||
pipe_hdl = hcd_edpt_open(dev_addr, desc_endpoint, TUSB_CLASS_MSC);
|
||||
|
||||
TEST_ASSERT_EQUAL(dev_addr, pipe_hdl.dev_addr);
|
||||
TEST_ASSERT_EQUAL(TUSB_XFER_BULK, pipe_hdl.xfer_type);
|
||||
|
||||
p_qhd = &ehci_data.device[ pipe_hdl.dev_addr-1 ].qhd[ pipe_hdl.index ];
|
||||
verify_bulk_open_qhd(p_qhd, desc_endpoint, TUSB_CLASS_MSC);
|
||||
|
||||
//------------- async list check -------------//
|
||||
TEST_ASSERT_EQUAL_HEX((uint32_t) p_qhd, tu_align32(async_head->next.address));
|
||||
TEST_ASSERT_FALSE(async_head->next.terminate);
|
||||
TEST_ASSERT_EQUAL(EHCI_QUEUE_ELEMENT_QHD, async_head->next.type);
|
||||
}
|
||||
|
||||
void test_open_bulk_hs_out_pingstate(void)
|
||||
{
|
||||
ehci_qhd_t *p_qhd;
|
||||
pipe_handle_t pipe_hdl;
|
||||
|
||||
//------------- Code Under TEST -------------//
|
||||
pipe_hdl = hcd_edpt_open(dev_addr, &desc_ept_bulk_out, TUSB_CLASS_MSC);
|
||||
|
||||
p_qhd = &ehci_data.device[ pipe_hdl.dev_addr-1 ].qhd[ pipe_hdl.index ];
|
||||
TEST_ASSERT(p_qhd->qtd_overlay.pingstate_err);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// PIPE CLOSE
|
||||
//--------------------------------------------------------------------+
|
||||
void test_bulk_close(void)
|
||||
{
|
||||
tusb_desc_endpoint_t const * desc_endpoint = &desc_ept_bulk_in;
|
||||
pipe_handle_t pipe_hdl = hcd_edpt_open(dev_addr, desc_endpoint, TUSB_CLASS_MSC);
|
||||
ehci_qhd_t *p_qhd = &ehci_data.device[ pipe_hdl.dev_addr-1].qhd[ pipe_hdl.index ];
|
||||
|
||||
//------------- Code Under TEST -------------//
|
||||
hcd_pipe_close(pipe_hdl);
|
||||
|
||||
TEST_ASSERT(p_qhd->is_removing);
|
||||
TEST_ASSERT( tu_align32(async_head->next.address) != (uint32_t) p_qhd );
|
||||
TEST_ASSERT_EQUAL_HEX( (uint32_t) async_head, tu_align32(p_qhd->next.address) );
|
||||
TEST_ASSERT_EQUAL(EHCI_QUEUE_ELEMENT_QHD, p_qhd->next.type);
|
||||
}
|
||||
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* This file is part of the TinyUSB stack.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "unity.h"
|
||||
#include "tusb_option.h"
|
||||
#include "tusb_errors.h"
|
||||
#include "binary.h"
|
||||
#include "type_helper.h"
|
||||
|
||||
#include "hal.h"
|
||||
#include "mock_osal.h"
|
||||
#include "hcd.h"
|
||||
#include "mock_usbh_hcd.h"
|
||||
#include "ehci.h"
|
||||
#include "ehci_controller_fake.h"
|
||||
#include "host_helper.h"
|
||||
|
||||
usbh_device_t _usbh_devices[CFG_TUSB_HOST_DEVICE_MAX+1];
|
||||
|
||||
static uint8_t hub_addr = 2;
|
||||
static uint8_t hub_port = 2;
|
||||
static uint8_t dev_addr;
|
||||
static uint8_t hostid;
|
||||
static uint8_t xfer_data [18000]; // 18K to test buffer pointer list
|
||||
static uint8_t data2[100];
|
||||
|
||||
static ehci_qhd_t *async_head;
|
||||
static ehci_qhd_t *p_qhd_bulk;
|
||||
static pipe_handle_t pipe_hdl_bulk;
|
||||
|
||||
tusb_desc_endpoint_t const desc_ept_bulk_in =
|
||||
{
|
||||
.bLength = sizeof(tusb_desc_endpoint_t),
|
||||
.bDescriptorType = TUSB_DESC_TYPE_ENDPOINT,
|
||||
.bEndpointAddress = 0x81,
|
||||
.bmAttributes = { .xfer = TUSB_XFER_BULK },
|
||||
.wMaxPacketSize = 512,
|
||||
.bInterval = 0
|
||||
};
|
||||
|
||||
tusb_desc_endpoint_t const desc_ept_bulk_out =
|
||||
{
|
||||
.bLength = sizeof(tusb_desc_endpoint_t),
|
||||
.bDescriptorType = TUSB_DESC_TYPE_ENDPOINT,
|
||||
.bEndpointAddress = 0x01,
|
||||
.bmAttributes = { .xfer = TUSB_XFER_BULK },
|
||||
.wMaxPacketSize = 512,
|
||||
.bInterval = 0
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Setup/Teardown + helper declare
|
||||
//--------------------------------------------------------------------+
|
||||
void setUp(void)
|
||||
{
|
||||
ehci_controller_init();
|
||||
tu_memclr(xfer_data, sizeof(xfer_data));
|
||||
tu_memclr(_usbh_devices, sizeof(usbh_device_t)*(CFG_TUSB_HOST_DEVICE_MAX+1));
|
||||
|
||||
TEST_ASSERT_STATUS( hcd_init() );
|
||||
|
||||
dev_addr = 1;
|
||||
hostid = RANDOM(CONTROLLER_HOST_NUMBER) + TEST_CONTROLLER_HOST_START_INDEX;
|
||||
helper_usbh_device_emulate(dev_addr, hub_addr, hub_port, hostid, TUSB_SPEED_HIGH);
|
||||
|
||||
async_head = get_async_head( hostid );
|
||||
|
||||
//------------- pipe open -------------//
|
||||
pipe_hdl_bulk = hcd_edpt_open(dev_addr, &desc_ept_bulk_in, TUSB_CLASS_MSC);
|
||||
|
||||
TEST_ASSERT_EQUAL(dev_addr, pipe_hdl_bulk.dev_addr);
|
||||
TEST_ASSERT_EQUAL(TUSB_XFER_BULK, pipe_hdl_bulk.xfer_type);
|
||||
|
||||
p_qhd_bulk = &ehci_data.device[ dev_addr -1].qhd[ pipe_hdl_bulk.index ];
|
||||
}
|
||||
|
||||
void tearDown(void)
|
||||
{
|
||||
}
|
||||
//--------------------------------------------------------------------+
|
||||
// BULK TRANSFER
|
||||
//--------------------------------------------------------------------+
|
||||
void verify_qtd(ehci_qtd_t *p_qtd, uint8_t p_data[], uint16_t length)
|
||||
{
|
||||
TEST_ASSERT_TRUE(p_qtd->alternate.terminate); // not used, always invalid
|
||||
|
||||
//------------- status -------------//
|
||||
TEST_ASSERT_FALSE(p_qtd->pingstate_err);
|
||||
TEST_ASSERT_FALSE(p_qtd->non_hs_split_state);
|
||||
TEST_ASSERT_FALSE(p_qtd->non_hs_period_missed_uframe);
|
||||
TEST_ASSERT_FALSE(p_qtd->xact_err);
|
||||
TEST_ASSERT_FALSE(p_qtd->babble_err);
|
||||
TEST_ASSERT_FALSE(p_qtd->buffer_err);
|
||||
TEST_ASSERT_FALSE(p_qtd->halted);
|
||||
TEST_ASSERT_TRUE(p_qtd->active);
|
||||
|
||||
TEST_ASSERT_FALSE(p_qtd->data_toggle);
|
||||
TEST_ASSERT_EQUAL(3, p_qtd->cerr);
|
||||
TEST_ASSERT_EQUAL(0, p_qtd->current_page);
|
||||
TEST_ASSERT_EQUAL(length, p_qtd->total_bytes);
|
||||
TEST_ASSERT_EQUAL(length, p_qtd->expected_bytes);
|
||||
TEST_ASSERT_TRUE(p_qtd->used);
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX( p_data, p_qtd->buffer[0] );
|
||||
for(uint8_t i=1; i<5; i++)
|
||||
{
|
||||
TEST_ASSERT_EQUAL_HEX( tu_align4k((uint32_t) (p_data+4096*i)), tu_align4k(p_qtd->buffer[i]) );
|
||||
}
|
||||
}
|
||||
|
||||
void test_bulk_xfer_hs_ping_out(void)
|
||||
{
|
||||
_usbh_devices[dev_addr].speed = TUSB_SPEED_HIGH;
|
||||
|
||||
pipe_handle_t pipe_hdl = hcd_edpt_open(dev_addr, &desc_ept_bulk_out, TUSB_CLASS_MSC);
|
||||
ehci_qhd_t *p_qhd = qhd_get_from_pipe_handle(pipe_hdl);
|
||||
|
||||
//------------- Code Under Test -------------//
|
||||
TEST_ASSERT_STATUS( hcd_pipe_xfer(pipe_hdl, xfer_data, sizeof(xfer_data), true) );
|
||||
|
||||
ehci_qtd_t* p_qtd = p_qhd->p_qtd_list_head;
|
||||
}
|
||||
|
||||
void test_bulk_xfer(void)
|
||||
{
|
||||
//------------- Code Under Test -------------//
|
||||
TEST_ASSERT_STATUS( hcd_pipe_xfer(pipe_hdl_bulk, xfer_data, sizeof(xfer_data), true) );
|
||||
|
||||
ehci_qtd_t* p_qtd = p_qhd_bulk->p_qtd_list_head;
|
||||
TEST_ASSERT_NOT_NULL(p_qtd);
|
||||
|
||||
verify_qtd( p_qtd, xfer_data, sizeof(xfer_data));
|
||||
TEST_ASSERT_EQUAL_HEX(p_qhd_bulk->qtd_overlay.next.address, p_qtd);
|
||||
TEST_ASSERT_TRUE(p_qtd->next.terminate);
|
||||
TEST_ASSERT_EQUAL(EHCI_PID_IN, p_qtd->pid);
|
||||
TEST_ASSERT_TRUE(p_qtd->int_on_complete);
|
||||
}
|
||||
|
||||
void test_bulk_xfer_double(void)
|
||||
{
|
||||
//------------- Code Under Test -------------//
|
||||
TEST_ASSERT_STATUS( hcd_pipe_xfer(pipe_hdl_bulk, xfer_data, sizeof(xfer_data), false) );
|
||||
|
||||
TEST_ASSERT_STATUS( hcd_pipe_xfer(pipe_hdl_bulk, data2, sizeof(data2), true) );
|
||||
|
||||
ehci_qtd_t* p_head = p_qhd_bulk->p_qtd_list_head;
|
||||
ehci_qtd_t* p_tail = p_qhd_bulk->p_qtd_list_tail;
|
||||
|
||||
//------------- list head -------------//
|
||||
TEST_ASSERT_NOT_NULL(p_head);
|
||||
verify_qtd(p_head, xfer_data, sizeof(xfer_data));
|
||||
TEST_ASSERT_EQUAL_HEX(p_qhd_bulk->qtd_overlay.next.address, p_head);
|
||||
TEST_ASSERT_EQUAL(EHCI_PID_IN, p_head->pid);
|
||||
TEST_ASSERT_FALSE(p_head->next.terminate);
|
||||
TEST_ASSERT_FALSE(p_head->int_on_complete);
|
||||
|
||||
//------------- list tail -------------//
|
||||
TEST_ASSERT_NOT_NULL(p_tail);
|
||||
verify_qtd(p_tail, data2, sizeof(data2));
|
||||
TEST_ASSERT_EQUAL_HEX( tu_align32(p_head->next.address), p_tail);
|
||||
TEST_ASSERT_EQUAL(EHCI_PID_IN, p_tail->pid);
|
||||
TEST_ASSERT_TRUE(p_tail->next.terminate);
|
||||
TEST_ASSERT_TRUE(p_tail->int_on_complete);
|
||||
}
|
||||
|
||||
void test_bulk_xfer_complete_isr(void)
|
||||
{
|
||||
TEST_ASSERT_STATUS( hcd_pipe_xfer(pipe_hdl_bulk, xfer_data, sizeof(xfer_data), false) );
|
||||
|
||||
TEST_ASSERT_STATUS( hcd_pipe_xfer(pipe_hdl_bulk, data2, sizeof(data2), true) );
|
||||
|
||||
ehci_qtd_t* p_head = p_qhd_bulk->p_qtd_list_head;
|
||||
ehci_qtd_t* p_tail = p_qhd_bulk->p_qtd_list_tail;
|
||||
|
||||
hcd_event_xfer_complete_Expect(pipe_hdl_bulk, TUSB_CLASS_MSC, XFER_RESULT_SUCCESS, sizeof(data2)+sizeof(xfer_data));
|
||||
|
||||
//------------- Code Under Test -------------//
|
||||
ehci_controller_run(hostid);
|
||||
|
||||
TEST_ASSERT_EQUAL(0, p_qhd_bulk->total_xferred_bytes);
|
||||
TEST_ASSERT_TRUE(p_qhd_bulk->qtd_overlay.next.terminate);
|
||||
TEST_ASSERT_FALSE(p_head->used);
|
||||
TEST_ASSERT_FALSE(p_tail->used);
|
||||
TEST_ASSERT_NULL(p_qhd_bulk->p_qtd_list_head);
|
||||
TEST_ASSERT_NULL(p_qhd_bulk->p_qtd_list_tail);
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* This file is part of the TinyUSB stack.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "unity.h"
|
||||
#include "tusb_option.h"
|
||||
#include "tusb_errors.h"
|
||||
#include "binary.h"
|
||||
#include "type_helper.h"
|
||||
|
||||
#include "hal.h"
|
||||
#include "mock_osal.h"
|
||||
#include "hcd.h"
|
||||
#include "mock_usbh_hcd.h"
|
||||
#include "ehci.h"
|
||||
#include "ehci_controller_fake.h"
|
||||
#include "host_helper.h"
|
||||
|
||||
usbh_device_t _usbh_devices[CFG_TUSB_HOST_DEVICE_MAX+1];
|
||||
|
||||
static uint8_t const control_max_packet_size = 64;
|
||||
static uint8_t const hub_addr = 2;
|
||||
static uint8_t const hub_port = 2;
|
||||
static uint8_t dev_addr;
|
||||
static uint8_t hostid;
|
||||
|
||||
static ehci_qhd_t *async_head;
|
||||
static ehci_qhd_t *p_control_qhd;
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Setup/Teardown + helper declare
|
||||
//--------------------------------------------------------------------+
|
||||
void setUp(void)
|
||||
{
|
||||
tu_memclr(_usbh_devices, sizeof(usbh_device_t)*(CFG_TUSB_HOST_DEVICE_MAX+1));
|
||||
|
||||
TEST_ASSERT_STATUS( hcd_init() );
|
||||
|
||||
dev_addr = 1;
|
||||
hostid = RANDOM(CONTROLLER_HOST_NUMBER) + TEST_CONTROLLER_HOST_START_INDEX;
|
||||
|
||||
helper_usbh_device_emulate(0, hub_addr, hub_port, hostid, TUSB_SPEED_HIGH);
|
||||
helper_usbh_device_emulate(dev_addr, hub_addr, hub_port, hostid, TUSB_SPEED_HIGH);
|
||||
|
||||
async_head = get_async_head( hostid );
|
||||
p_control_qhd = &ehci_data.device[dev_addr-1].control.qhd;
|
||||
}
|
||||
|
||||
void tearDown(void)
|
||||
{
|
||||
}
|
||||
|
||||
void verify_open_qhd(ehci_qhd_t *p_qhd, uint8_t endpoint_addr, uint16_t max_packet_size)
|
||||
{
|
||||
TEST_ASSERT_EQUAL(dev_addr, p_qhd->device_address);
|
||||
TEST_ASSERT_FALSE(p_qhd->non_hs_period_inactive_next_xact);
|
||||
TEST_ASSERT_EQUAL(endpoint_addr & 0x0F, p_qhd->endpoint_number);
|
||||
TEST_ASSERT_EQUAL(_usbh_devices[dev_addr].speed, p_qhd->endpoint_speed);
|
||||
TEST_ASSERT_EQUAL(max_packet_size, p_qhd->max_package_size);
|
||||
TEST_ASSERT_EQUAL(0, p_qhd->nak_count_reload); // TDD NAK Reload disable
|
||||
|
||||
TEST_ASSERT_EQUAL(hub_addr, p_qhd->hub_address);
|
||||
TEST_ASSERT_EQUAL(hub_port, p_qhd->hub_port);
|
||||
TEST_ASSERT_EQUAL(1, p_qhd->mult); // TDD operation model for mult
|
||||
|
||||
TEST_ASSERT_FALSE(p_qhd->qtd_overlay.halted);
|
||||
TEST_ASSERT(p_qhd->qtd_overlay.next.terminate);
|
||||
TEST_ASSERT(p_qhd->qtd_overlay.alternate.terminate);
|
||||
|
||||
//------------- HCD -------------//
|
||||
TEST_ASSERT(p_qhd->used);
|
||||
TEST_ASSERT_FALSE(p_qhd->is_removing);
|
||||
TEST_ASSERT_NULL(p_qhd->p_qtd_list_head);
|
||||
TEST_ASSERT_NULL(p_qhd->p_qtd_list_tail);
|
||||
}
|
||||
|
||||
void verify_control_open_qhd(ehci_qhd_t *p_qhd)
|
||||
{
|
||||
verify_open_qhd(p_qhd, 0, control_max_packet_size);
|
||||
|
||||
TEST_ASSERT_EQUAL(0, p_qhd->class_code);
|
||||
TEST_ASSERT_EQUAL(1, p_qhd->data_toggle_control);
|
||||
TEST_ASSERT_EQUAL(0, p_qhd->interrupt_smask);
|
||||
TEST_ASSERT_EQUAL(0, p_qhd->non_hs_interrupt_cmask);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// PIPE OPEN
|
||||
//--------------------------------------------------------------------+
|
||||
void test_control_open_addr0_qhd_data(void)
|
||||
{
|
||||
dev_addr = 0;
|
||||
|
||||
//------------- Code Under Test -------------//
|
||||
TEST_ASSERT_STATUS( hcd_pipe_control_open(dev_addr, control_max_packet_size) );
|
||||
|
||||
verify_control_open_qhd(async_head);
|
||||
TEST_ASSERT(async_head->head_list_flag);
|
||||
}
|
||||
|
||||
void test_control_open_qhd_data(void)
|
||||
{
|
||||
//------------- Code Under TEST -------------//
|
||||
TEST_ASSERT_STATUS( hcd_pipe_control_open(dev_addr, control_max_packet_size));
|
||||
|
||||
verify_control_open_qhd(p_control_qhd);
|
||||
TEST_ASSERT_FALSE(p_control_qhd->head_list_flag);
|
||||
|
||||
//------------- async list check -------------//
|
||||
TEST_ASSERT_EQUAL_HEX((uint32_t) p_control_qhd, tu_align32(async_head->next.address));
|
||||
TEST_ASSERT_FALSE(async_head->next.terminate);
|
||||
TEST_ASSERT_EQUAL(EHCI_QUEUE_ELEMENT_QHD, async_head->next.type);
|
||||
}
|
||||
|
||||
void test_control_open_highspeed(void)
|
||||
{
|
||||
_usbh_devices[dev_addr].speed = TUSB_SPEED_HIGH;
|
||||
|
||||
//------------- Code Under TEST -------------//
|
||||
TEST_ASSERT_STATUS( hcd_pipe_control_open(dev_addr, control_max_packet_size) );
|
||||
TEST_ASSERT_FALSE(p_control_qhd->non_hs_control_endpoint);
|
||||
}
|
||||
|
||||
void test_control_open_non_highspeed(void)
|
||||
{
|
||||
_usbh_devices[dev_addr].speed = TUSB_SPEED_FULL;
|
||||
|
||||
//------------- Code Under TEST -------------//
|
||||
TEST_ASSERT_STATUS( hcd_pipe_control_open(dev_addr, control_max_packet_size) );
|
||||
|
||||
TEST_ASSERT_TRUE(p_control_qhd->non_hs_control_endpoint);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// PIPE CLOSE
|
||||
//--------------------------------------------------------------------+
|
||||
void test_control_addr0_close(void)
|
||||
{
|
||||
dev_addr = 0;
|
||||
TEST_ASSERT_STATUS( hcd_pipe_control_open(dev_addr, control_max_packet_size) );
|
||||
|
||||
//------------- Code Under Test -------------//
|
||||
TEST_ASSERT_STATUS( hcd_pipe_control_close(dev_addr) );
|
||||
|
||||
TEST_ASSERT(async_head->head_list_flag);
|
||||
TEST_ASSERT(async_head->is_removing);
|
||||
}
|
||||
|
||||
void test_control_close(void)
|
||||
{
|
||||
TEST_ASSERT_STATUS( hcd_pipe_control_open(dev_addr, control_max_packet_size) );
|
||||
|
||||
//------------- Code Under TEST -------------//
|
||||
TEST_ASSERT_STATUS( hcd_pipe_control_close(dev_addr) );
|
||||
|
||||
TEST_ASSERT(p_control_qhd->is_removing);
|
||||
TEST_ASSERT(p_control_qhd->used);
|
||||
|
||||
TEST_ASSERT( tu_align32(get_async_head(hostid)->next.address) != (uint32_t) p_control_qhd );
|
||||
TEST_ASSERT_EQUAL( get_async_head(hostid), tu_align32(p_control_qhd->next.address));
|
||||
}
|
||||
@@ -0,0 +1,275 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* This file is part of the TinyUSB stack.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "unity.h"
|
||||
#include "tusb_option.h"
|
||||
#include "tusb_errors.h"
|
||||
#include "binary.h"
|
||||
#include "type_helper.h"
|
||||
|
||||
#include "hal.h"
|
||||
#include "mock_osal.h"
|
||||
#include "hcd.h"
|
||||
#include "mock_usbh_hcd.h"
|
||||
#include "ehci.h"
|
||||
#include "ehci_controller_fake.h"
|
||||
#include "host_helper.h"
|
||||
|
||||
usbh_device_t _usbh_devices[CFG_TUSB_HOST_DEVICE_MAX+1];
|
||||
|
||||
static uint8_t const control_max_packet_size = 64;
|
||||
static uint8_t const hub_addr = 2;
|
||||
static uint8_t const hub_port = 2;
|
||||
static uint8_t dev_addr;
|
||||
static uint8_t hostid;
|
||||
static uint8_t xfer_data [100];
|
||||
|
||||
static ehci_qhd_t *async_head;
|
||||
static ehci_qhd_t *p_control_qhd;
|
||||
|
||||
static ehci_qtd_t *p_setup;
|
||||
static ehci_qtd_t *p_data;
|
||||
static ehci_qtd_t *p_status;
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Setup/Teardown + helper declare
|
||||
//--------------------------------------------------------------------+
|
||||
void setUp(void)
|
||||
{
|
||||
ehci_controller_init();
|
||||
|
||||
tu_memclr(_usbh_devices, sizeof(usbh_device_t)*(CFG_TUSB_HOST_DEVICE_MAX+1));
|
||||
tu_memclr(xfer_data, sizeof(xfer_data));
|
||||
|
||||
TEST_ASSERT_STATUS( hcd_init() );
|
||||
|
||||
dev_addr = 1;
|
||||
hostid = RANDOM(CONTROLLER_HOST_NUMBER) + TEST_CONTROLLER_HOST_START_INDEX;
|
||||
|
||||
helper_usbh_device_emulate(0 , hub_addr, hub_port, hostid, TUSB_SPEED_HIGH);
|
||||
helper_usbh_device_emulate(dev_addr , hub_addr, hub_port, hostid, TUSB_SPEED_HIGH);
|
||||
|
||||
async_head = get_async_head( hostid );
|
||||
|
||||
//------------- pipe open -------------//
|
||||
TEST_ASSERT_STATUS( hcd_pipe_control_open(dev_addr, control_max_packet_size) );
|
||||
|
||||
p_control_qhd = &ehci_data.device[dev_addr-1].control.qhd;
|
||||
|
||||
p_setup = &ehci_data.device[dev_addr-1].control.qtd[0];
|
||||
p_data = &ehci_data.device[dev_addr-1].control.qtd[1];
|
||||
p_status = &ehci_data.device[dev_addr-1].control.qtd[2];
|
||||
}
|
||||
|
||||
void tearDown(void)
|
||||
{
|
||||
}
|
||||
//--------------------------------------------------------------------+
|
||||
// CONTROL TRANSFER
|
||||
//--------------------------------------------------------------------+
|
||||
tusb_control_request_t request_get_dev_desc =
|
||||
{
|
||||
.bmRequestType_bit = { .direction = TUSB_DIR_DEV_TO_HOST, .type = TUSB_REQ_TYPE_STANDARD, .recipient = TUSB_REQ_RECIPIENT_DEVICE },
|
||||
.bRequest = TUSB_REQ_GET_DESCRIPTOR,
|
||||
.wValue = (TUSB_DESC_TYPE_DEVICE << 8),
|
||||
.wLength = 18
|
||||
};
|
||||
|
||||
tusb_control_request_t request_set_dev_addr =
|
||||
{
|
||||
.bmRequestType_bit = { .direction = TUSB_DIR_HOST_TO_DEV, .type = TUSB_REQ_TYPE_STANDARD, .recipient = TUSB_REQ_RECIPIENT_DEVICE },
|
||||
.bRequest = TUSB_REQ_SET_ADDRESS,
|
||||
.wValue = 3
|
||||
};
|
||||
|
||||
void verify_qtd(ehci_qtd_t *p_qtd, uint8_t p_data[], uint16_t length)
|
||||
{
|
||||
TEST_ASSERT_TRUE(p_qtd->alternate.terminate); // not used, always invalid
|
||||
|
||||
TEST_ASSERT_FALSE(p_qtd->pingstate_err);
|
||||
TEST_ASSERT_FALSE(p_qtd->non_hs_split_state);
|
||||
TEST_ASSERT_FALSE(p_qtd->non_hs_period_missed_uframe);
|
||||
TEST_ASSERT_FALSE(p_qtd->xact_err);
|
||||
TEST_ASSERT_FALSE(p_qtd->babble_err);
|
||||
TEST_ASSERT_FALSE(p_qtd->buffer_err);
|
||||
TEST_ASSERT_FALSE(p_qtd->halted);
|
||||
TEST_ASSERT_TRUE(p_qtd->active);
|
||||
|
||||
TEST_ASSERT_EQUAL(3, p_qtd->cerr);
|
||||
TEST_ASSERT_EQUAL(0, p_qtd->current_page);
|
||||
TEST_ASSERT_EQUAL(length, p_qtd->total_bytes);
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX(p_data, p_qtd->buffer[0]);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Address 0
|
||||
//--------------------------------------------------------------------+
|
||||
void test_control_addr0_xfer_get_check_qhd_qtd_mapping(void)
|
||||
{
|
||||
dev_addr = 0;
|
||||
ehci_qhd_t * const p_qhd = async_head;
|
||||
|
||||
TEST_ASSERT_STATUS( hcd_pipe_control_open(dev_addr, control_max_packet_size) );
|
||||
|
||||
//------------- Code Under TEST -------------//
|
||||
TEST_ASSERT( hcd_pipe_control_xfer(dev_addr, &request_get_dev_desc, xfer_data) );
|
||||
|
||||
p_setup = &ehci_data.addr0_qtd[0];
|
||||
p_data = &ehci_data.addr0_qtd[1];
|
||||
p_status = &ehci_data.addr0_qtd[2];
|
||||
|
||||
TEST_ASSERT_EQUAL(0 , p_qhd->total_xferred_bytes);
|
||||
TEST_ASSERT_EQUAL_HEX( p_setup, p_qhd->qtd_overlay.next.address );
|
||||
TEST_ASSERT_EQUAL_HEX( p_setup , p_qhd->p_qtd_list_head);
|
||||
TEST_ASSERT_EQUAL_HEX( p_data , p_setup->next.address);
|
||||
TEST_ASSERT_EQUAL_HEX( p_status , p_data->next.address );
|
||||
TEST_ASSERT_TRUE( p_status->next.terminate );
|
||||
|
||||
verify_qtd(p_setup, (uint8_t*) &request_get_dev_desc, 8);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Normal Control
|
||||
//--------------------------------------------------------------------+
|
||||
void test_control_xfer_get(void)
|
||||
{
|
||||
//------------- Code Under TEST -------------//
|
||||
TEST_ASSERT( hcd_pipe_control_xfer(dev_addr, &request_get_dev_desc, xfer_data) );
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX( p_setup, p_control_qhd->qtd_overlay.next.address );
|
||||
TEST_ASSERT_EQUAL_HEX( p_setup , p_control_qhd->p_qtd_list_head);
|
||||
TEST_ASSERT_EQUAL_HEX( p_data , p_setup->next.address);
|
||||
TEST_ASSERT_EQUAL_HEX( p_status , p_data->next.address );
|
||||
TEST_ASSERT_TRUE( p_status->next.terminate );
|
||||
|
||||
//------------- SETUP -------------//
|
||||
verify_qtd(p_setup, (uint8_t*) &request_get_dev_desc, 8);
|
||||
|
||||
TEST_ASSERT_FALSE(p_setup->int_on_complete);
|
||||
TEST_ASSERT_FALSE(p_setup->data_toggle);
|
||||
TEST_ASSERT_EQUAL(EHCI_PID_SETUP, p_setup->pid);
|
||||
|
||||
//------------- DATA -------------//
|
||||
verify_qtd(p_data, xfer_data, request_get_dev_desc.wLength);
|
||||
TEST_ASSERT_FALSE(p_data->int_on_complete);
|
||||
TEST_ASSERT_TRUE(p_data->data_toggle);
|
||||
TEST_ASSERT_EQUAL(EHCI_PID_IN, p_data->pid);
|
||||
|
||||
//------------- STATUS -------------//
|
||||
verify_qtd(p_status, NULL, 0);
|
||||
TEST_ASSERT_TRUE(p_status->int_on_complete);
|
||||
TEST_ASSERT_TRUE(p_status->data_toggle);
|
||||
TEST_ASSERT_EQUAL(EHCI_PID_OUT, p_status->pid);
|
||||
TEST_ASSERT_TRUE(p_status->next.terminate);
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX(p_setup, p_control_qhd->p_qtd_list_head);
|
||||
TEST_ASSERT_EQUAL_HEX(p_status, p_control_qhd->p_qtd_list_tail);
|
||||
}
|
||||
|
||||
void test_control_xfer_set(void)
|
||||
{
|
||||
//------------- Code Under TEST -------------//
|
||||
TEST_ASSERT( hcd_pipe_control_xfer(dev_addr, &request_set_dev_addr, xfer_data) );
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX( p_setup, p_control_qhd->qtd_overlay.next.address );
|
||||
TEST_ASSERT_EQUAL_HEX( p_setup , p_control_qhd->p_qtd_list_head);
|
||||
TEST_ASSERT_EQUAL_HEX( p_status , p_setup->next.address );
|
||||
TEST_ASSERT_TRUE( p_status->next.terminate );
|
||||
|
||||
//------------- STATUS -------------//
|
||||
verify_qtd(p_status, NULL, 0);
|
||||
TEST_ASSERT_TRUE(p_status->int_on_complete);
|
||||
TEST_ASSERT_TRUE(p_status->data_toggle);
|
||||
TEST_ASSERT_EQUAL(EHCI_PID_IN, p_status->pid);
|
||||
TEST_ASSERT_TRUE(p_status->next.terminate);
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX(p_setup, p_control_qhd->p_qtd_list_head);
|
||||
TEST_ASSERT_EQUAL_HEX(p_status, p_control_qhd->p_qtd_list_tail);
|
||||
}
|
||||
|
||||
void test_control_xfer_complete_isr(void)
|
||||
{
|
||||
TEST_ASSERT( hcd_pipe_control_xfer(dev_addr, &request_get_dev_desc, xfer_data) );
|
||||
|
||||
hcd_event_xfer_complete_Expect(((pipe_handle_t){.dev_addr = dev_addr}), 0, XFER_RESULT_SUCCESS, 18);
|
||||
|
||||
//------------- Code Under TEST -------------//
|
||||
ehci_controller_run(hostid);
|
||||
|
||||
TEST_ASSERT_EQUAL(0, p_control_qhd->total_xferred_bytes);
|
||||
TEST_ASSERT_NULL(p_control_qhd->p_qtd_list_head);
|
||||
TEST_ASSERT_NULL(p_control_qhd->p_qtd_list_tail);
|
||||
|
||||
TEST_ASSERT_FALSE(p_setup->used);
|
||||
TEST_ASSERT_FALSE(p_data->used);
|
||||
TEST_ASSERT_FALSE(p_status->used);
|
||||
|
||||
}
|
||||
|
||||
void test_control_xfer_error_isr(void)
|
||||
{
|
||||
TEST_ASSERT( hcd_pipe_control_xfer(dev_addr, &request_get_dev_desc, xfer_data) );
|
||||
|
||||
hcd_event_xfer_complete_Expect(((pipe_handle_t){.dev_addr = dev_addr}), 0, XFER_RESULT_FAILED, 0);
|
||||
|
||||
//------------- Code Under TEST -------------//
|
||||
ehci_controller_run_error(hostid);
|
||||
|
||||
TEST_ASSERT_EQUAL(0, p_control_qhd->total_xferred_bytes);
|
||||
|
||||
TEST_ASSERT_NULL( p_control_qhd->p_qtd_list_head );
|
||||
TEST_ASSERT_NULL( p_control_qhd->p_qtd_list_tail );
|
||||
|
||||
TEST_ASSERT_TRUE( p_control_qhd->qtd_overlay.next.terminate);
|
||||
TEST_ASSERT_TRUE( p_control_qhd->qtd_overlay.alternate.terminate);
|
||||
TEST_ASSERT_FALSE( p_control_qhd->qtd_overlay.halted);
|
||||
}
|
||||
|
||||
void test_control_xfer_error_stall(void)
|
||||
{
|
||||
TEST_ASSERT( hcd_pipe_control_xfer(dev_addr, &request_get_dev_desc, xfer_data) );
|
||||
|
||||
hcd_event_xfer_complete_Expect(((pipe_handle_t){.dev_addr = dev_addr}), 0, XFER_RESULT_STALLED, 0);
|
||||
|
||||
//------------- Code Under TEST -------------//
|
||||
ehci_controller_run_stall(hostid);
|
||||
|
||||
TEST_ASSERT_EQUAL(0, p_control_qhd->total_xferred_bytes);
|
||||
|
||||
TEST_ASSERT_NULL( p_control_qhd->p_qtd_list_head );
|
||||
TEST_ASSERT_NULL( p_control_qhd->p_qtd_list_tail );
|
||||
|
||||
TEST_ASSERT_TRUE( p_control_qhd->qtd_overlay.next.terminate);
|
||||
TEST_ASSERT_TRUE( p_control_qhd->qtd_overlay.alternate.terminate);
|
||||
TEST_ASSERT_FALSE( p_control_qhd->qtd_overlay.halted);
|
||||
|
||||
TEST_ASSERT_FALSE( p_setup->used );
|
||||
TEST_ASSERT_FALSE( p_data->used );
|
||||
TEST_ASSERT_FALSE( p_status->used );
|
||||
}
|
||||
|
||||
@@ -0,0 +1,330 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* This file is part of the TinyUSB stack.
|
||||
*/
|
||||
|
||||
#include "unity.h"
|
||||
#include "tusb_option.h"
|
||||
#include "tusb_errors.h"
|
||||
#include "binary.h"
|
||||
#include "type_helper.h"
|
||||
|
||||
#include "hal.h"
|
||||
#include "mock_osal.h"
|
||||
#include "hcd.h"
|
||||
#include "mock_usbh_hcd.h"
|
||||
#include "ehci.h"
|
||||
#include "ehci_controller_fake.h"
|
||||
#include "host_helper.h"
|
||||
|
||||
usbh_device_t _usbh_devices[CFG_TUSB_HOST_DEVICE_MAX+1];
|
||||
|
||||
static uint8_t const hub_addr = 2;
|
||||
static uint8_t const hub_port = 2;
|
||||
static uint8_t dev_addr;
|
||||
static uint8_t hostid;
|
||||
|
||||
static ehci_qhd_t *period_head_arr;
|
||||
|
||||
static ehci_qhd_t *p_int_qhd;
|
||||
static pipe_handle_t pipe_hdl;
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Setup/Teardown + helper declare
|
||||
//--------------------------------------------------------------------+
|
||||
void setUp(void)
|
||||
{
|
||||
tu_memclr(_usbh_devices, sizeof(usbh_device_t)*(CFG_TUSB_HOST_DEVICE_MAX+1));
|
||||
|
||||
hcd_init();
|
||||
|
||||
dev_addr = 1;
|
||||
hostid = RANDOM(CONTROLLER_HOST_NUMBER) + TEST_CONTROLLER_HOST_START_INDEX;
|
||||
|
||||
helper_usbh_device_emulate(dev_addr , hub_addr, hub_port, hostid, TUSB_SPEED_HIGH);
|
||||
|
||||
period_head_arr = get_period_head( hostid, 1 );
|
||||
p_int_qhd = NULL;
|
||||
tu_memclr(&pipe_hdl, sizeof(pipe_handle_t));
|
||||
}
|
||||
|
||||
void tearDown(void)
|
||||
{
|
||||
}
|
||||
|
||||
void verify_open_qhd(ehci_qhd_t *p_qhd, uint8_t endpoint_addr, uint16_t max_packet_size)
|
||||
{
|
||||
TEST_ASSERT_EQUAL(dev_addr, p_qhd->device_address);
|
||||
TEST_ASSERT_FALSE(p_qhd->non_hs_period_inactive_next_xact);
|
||||
TEST_ASSERT_EQUAL(endpoint_addr & 0x0F, p_qhd->endpoint_number);
|
||||
TEST_ASSERT_EQUAL(_usbh_devices[dev_addr].speed, p_qhd->endpoint_speed);
|
||||
TEST_ASSERT_EQUAL(max_packet_size, p_qhd->max_package_size);
|
||||
TEST_ASSERT_EQUAL(0, p_qhd->nak_count_reload); // TDD NAK Reload disable
|
||||
|
||||
TEST_ASSERT_EQUAL(hub_addr, p_qhd->hub_address);
|
||||
TEST_ASSERT_EQUAL(hub_port, p_qhd->hub_port);
|
||||
TEST_ASSERT_EQUAL(1, p_qhd->mult); // TDD operation model for mult
|
||||
|
||||
TEST_ASSERT_FALSE(p_qhd->qtd_overlay.halted);
|
||||
TEST_ASSERT(p_qhd->qtd_overlay.next.terminate);
|
||||
TEST_ASSERT(p_qhd->qtd_overlay.alternate.terminate);
|
||||
|
||||
//------------- HCD -------------//
|
||||
TEST_ASSERT(p_qhd->used);
|
||||
TEST_ASSERT_FALSE(p_qhd->is_removing);
|
||||
TEST_ASSERT_NULL(p_qhd->p_qtd_list_head);
|
||||
TEST_ASSERT_NULL(p_qhd->p_qtd_list_tail);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// PIPE OPEN
|
||||
//--------------------------------------------------------------------+
|
||||
tusb_desc_endpoint_t const desc_ept_interrupt_out =
|
||||
{
|
||||
.bLength = sizeof(tusb_desc_endpoint_t),
|
||||
.bDescriptorType = TUSB_DESC_TYPE_ENDPOINT,
|
||||
.bEndpointAddress = 0x02,
|
||||
.bmAttributes = { .xfer = TUSB_XFER_INTERRUPT },
|
||||
.wMaxPacketSize = 16,
|
||||
.bInterval = 4
|
||||
};
|
||||
void verify_int_qhd(ehci_qhd_t *p_qhd, tusb_desc_endpoint_t const * desc_endpoint, uint8_t class_code)
|
||||
{
|
||||
verify_open_qhd(p_qhd, desc_endpoint->bEndpointAddress, desc_endpoint->wMaxPacketSize.size);
|
||||
|
||||
TEST_ASSERT_FALSE(p_qhd->head_list_flag);
|
||||
TEST_ASSERT_FALSE(p_qhd->data_toggle_control);
|
||||
TEST_ASSERT_FALSE(p_qhd->non_hs_control_endpoint);
|
||||
|
||||
TEST_ASSERT_EQUAL(desc_endpoint->bEndpointAddress & 0x80 ? EHCI_PID_IN : EHCI_PID_OUT, p_qhd->pid_non_control);
|
||||
}
|
||||
|
||||
void check_int_endpoint_link(ehci_qhd_t *p_prev, ehci_qhd_t *p_qhd)
|
||||
{
|
||||
//------------- period list check -------------//
|
||||
TEST_ASSERT_EQUAL_HEX((uint32_t) p_qhd, tu_align32(p_prev->next.address));
|
||||
TEST_ASSERT_FALSE(p_prev->next.terminate);
|
||||
TEST_ASSERT_EQUAL(EHCI_QUEUE_ELEMENT_QHD, p_prev->next.type);
|
||||
}
|
||||
|
||||
void test_open_interrupt_qhd_hs(void)
|
||||
{
|
||||
//------------- Code Under TEST -------------//
|
||||
pipe_hdl = hcd_edpt_open(dev_addr, &desc_ept_interrupt_out, TUSB_CLASS_HID);
|
||||
|
||||
TEST_ASSERT_EQUAL(dev_addr, pipe_hdl.dev_addr);
|
||||
TEST_ASSERT_EQUAL(TUSB_XFER_INTERRUPT, pipe_hdl.xfer_type);
|
||||
|
||||
p_int_qhd = &ehci_data.device[ pipe_hdl.dev_addr-1].qhd[ pipe_hdl.index ];
|
||||
|
||||
verify_int_qhd(p_int_qhd, &desc_ept_interrupt_out, TUSB_CLASS_HID);
|
||||
|
||||
TEST_ASSERT_EQUAL(0, p_int_qhd->non_hs_interrupt_cmask);
|
||||
}
|
||||
|
||||
void test_open_interrupt_hs_interval_1(void)
|
||||
{
|
||||
tusb_desc_endpoint_t int_edp_interval = desc_ept_interrupt_out;
|
||||
int_edp_interval.bInterval = 1;
|
||||
|
||||
//------------- Code Under TEST -------------//
|
||||
pipe_hdl = hcd_edpt_open(dev_addr, &int_edp_interval, TUSB_CLASS_HID);
|
||||
p_int_qhd = &ehci_data.device[ pipe_hdl.dev_addr-1].qhd[ pipe_hdl.index ];
|
||||
|
||||
TEST_ASSERT_EQUAL(0 , p_int_qhd->interval_ms);
|
||||
TEST_ASSERT_EQUAL(TU_BIN8(11111111) , p_int_qhd->interrupt_smask);
|
||||
|
||||
check_int_endpoint_link(period_head_arr, p_int_qhd);
|
||||
}
|
||||
|
||||
void test_open_interrupt_hs_interval_2(void)
|
||||
{
|
||||
tusb_desc_endpoint_t int_edp_interval = desc_ept_interrupt_out;
|
||||
int_edp_interval.bInterval = 2;
|
||||
|
||||
//------------- Code Under TEST -------------//
|
||||
pipe_hdl = hcd_edpt_open(dev_addr, &int_edp_interval, TUSB_CLASS_HID);
|
||||
p_int_qhd = &ehci_data.device[ pipe_hdl.dev_addr-1].qhd[ pipe_hdl.index ];
|
||||
|
||||
TEST_ASSERT_EQUAL(0 , p_int_qhd->interval_ms);
|
||||
TEST_ASSERT_EQUAL(4 , tu_cardof(p_int_qhd->interrupt_smask)); // either 10101010 or 01010101
|
||||
check_int_endpoint_link(period_head_arr, p_int_qhd);
|
||||
}
|
||||
|
||||
void test_open_interrupt_hs_interval_3(void)
|
||||
{
|
||||
tusb_desc_endpoint_t int_edp_interval = desc_ept_interrupt_out;
|
||||
int_edp_interval.bInterval = 3;
|
||||
|
||||
//------------- Code Under TEST -------------//
|
||||
pipe_hdl = hcd_edpt_open(dev_addr, &int_edp_interval, TUSB_CLASS_HID);
|
||||
p_int_qhd = &ehci_data.device[ pipe_hdl.dev_addr-1].qhd[ pipe_hdl.index ];
|
||||
|
||||
TEST_ASSERT_EQUAL(0, p_int_qhd->interval_ms);
|
||||
TEST_ASSERT_EQUAL(2, tu_cardof(p_int_qhd->interrupt_smask) );
|
||||
check_int_endpoint_link(period_head_arr, p_int_qhd);
|
||||
}
|
||||
|
||||
void test_open_interrupt_hs_interval_4(void)
|
||||
{
|
||||
tusb_desc_endpoint_t int_edp_interval = desc_ept_interrupt_out;
|
||||
int_edp_interval.bInterval = 4;
|
||||
|
||||
//------------- Code Under TEST -------------//
|
||||
pipe_hdl = hcd_edpt_open(dev_addr, &int_edp_interval, TUSB_CLASS_HID);
|
||||
p_int_qhd = &ehci_data.device[ pipe_hdl.dev_addr-1].qhd[ pipe_hdl.index ];
|
||||
|
||||
TEST_ASSERT_EQUAL(1, p_int_qhd->interval_ms);
|
||||
TEST_ASSERT_EQUAL(1, tu_cardof(p_int_qhd->interrupt_smask) );
|
||||
check_int_endpoint_link(period_head_arr, p_int_qhd);
|
||||
}
|
||||
|
||||
void test_open_interrupt_hs_interval_5(void)
|
||||
{
|
||||
tusb_desc_endpoint_t int_edp_interval = desc_ept_interrupt_out;
|
||||
int_edp_interval.bInterval = 5;
|
||||
|
||||
//------------- Code Under TEST -------------//
|
||||
pipe_hdl = hcd_edpt_open(dev_addr, &int_edp_interval, TUSB_CLASS_HID);
|
||||
p_int_qhd = &ehci_data.device[ pipe_hdl.dev_addr-1].qhd[ pipe_hdl.index ];
|
||||
|
||||
TEST_ASSERT_EQUAL(2, p_int_qhd->interval_ms);
|
||||
TEST_ASSERT_EQUAL(1, tu_cardof(p_int_qhd->interrupt_smask) );
|
||||
check_int_endpoint_link( get_period_head(hostid, 2), p_int_qhd );
|
||||
}
|
||||
|
||||
void test_open_interrupt_hs_interval_6(void)
|
||||
{
|
||||
tusb_desc_endpoint_t int_edp_interval = desc_ept_interrupt_out;
|
||||
int_edp_interval.bInterval = 6;
|
||||
|
||||
//------------- Code Under TEST -------------//
|
||||
pipe_hdl = hcd_edpt_open(dev_addr, &int_edp_interval, TUSB_CLASS_HID);
|
||||
p_int_qhd = &ehci_data.device[ pipe_hdl.dev_addr-1].qhd[ pipe_hdl.index ];
|
||||
|
||||
TEST_ASSERT_EQUAL(4, p_int_qhd->interval_ms);
|
||||
TEST_ASSERT_EQUAL(1, tu_cardof(p_int_qhd->interrupt_smask) );
|
||||
check_int_endpoint_link( get_period_head(hostid, 4), p_int_qhd);
|
||||
}
|
||||
|
||||
void test_open_interrupt_hs_interval_7(void)
|
||||
{
|
||||
tusb_desc_endpoint_t int_edp_interval = desc_ept_interrupt_out;
|
||||
int_edp_interval.bInterval = 7;
|
||||
|
||||
//------------- Code Under TEST -------------//
|
||||
pipe_hdl = hcd_edpt_open(dev_addr, &int_edp_interval, TUSB_CLASS_HID);
|
||||
p_int_qhd = &ehci_data.device[ pipe_hdl.dev_addr-1].qhd[ pipe_hdl.index ];
|
||||
|
||||
TEST_ASSERT_EQUAL(8, p_int_qhd->interval_ms);
|
||||
TEST_ASSERT_EQUAL(1, tu_cardof(p_int_qhd->interrupt_smask) );
|
||||
check_int_endpoint_link( get_period_head(hostid, 8), p_int_qhd);
|
||||
}
|
||||
|
||||
void test_open_interrupt_hs_interval_8(void)
|
||||
{
|
||||
tusb_desc_endpoint_t int_edp_interval = desc_ept_interrupt_out;
|
||||
int_edp_interval.bInterval = 16;
|
||||
|
||||
//------------- Code Under TEST -------------//
|
||||
pipe_hdl = hcd_edpt_open(dev_addr, &int_edp_interval, TUSB_CLASS_HID);
|
||||
p_int_qhd = &ehci_data.device[ pipe_hdl.dev_addr-1].qhd[ pipe_hdl.index ];
|
||||
|
||||
TEST_ASSERT_EQUAL(255, p_int_qhd->interval_ms);
|
||||
TEST_ASSERT_EQUAL(1, tu_cardof(p_int_qhd->interrupt_smask) );
|
||||
check_int_endpoint_link( get_period_head(hostid, 255), p_int_qhd);
|
||||
check_int_endpoint_link( get_period_head(hostid, 8) , p_int_qhd);
|
||||
}
|
||||
|
||||
void test_open_interrupt_qhd_non_hs(void)
|
||||
{
|
||||
_usbh_devices[dev_addr].speed = TUSB_SPEED_FULL;
|
||||
|
||||
//------------- Code Under TEST -------------//
|
||||
pipe_hdl = hcd_edpt_open(dev_addr, &desc_ept_interrupt_out, TUSB_CLASS_HID);
|
||||
|
||||
TEST_ASSERT_EQUAL(dev_addr, pipe_hdl.dev_addr);
|
||||
TEST_ASSERT_EQUAL(TUSB_XFER_INTERRUPT, pipe_hdl.xfer_type);
|
||||
|
||||
p_int_qhd = &ehci_data.device[ pipe_hdl.dev_addr-1].qhd[ pipe_hdl.index ];
|
||||
|
||||
verify_int_qhd(p_int_qhd, &desc_ept_interrupt_out, TUSB_CLASS_HID);
|
||||
|
||||
TEST_ASSERT_EQUAL(desc_ept_interrupt_out.bInterval, p_int_qhd->interval_ms);
|
||||
TEST_ASSERT_EQUAL(1, p_int_qhd->interrupt_smask);
|
||||
TEST_ASSERT_EQUAL(0x1c, p_int_qhd->non_hs_interrupt_cmask);
|
||||
}
|
||||
|
||||
void test_open_interrupt_qhd_non_hs_9(void)
|
||||
{
|
||||
tusb_desc_endpoint_t int_edp_interval = desc_ept_interrupt_out;
|
||||
int_edp_interval.bInterval = 32;
|
||||
|
||||
_usbh_devices[dev_addr].speed = TUSB_SPEED_FULL;
|
||||
|
||||
//------------- Code Under TEST -------------//
|
||||
pipe_hdl = hcd_edpt_open(dev_addr, &int_edp_interval, TUSB_CLASS_HID);
|
||||
p_int_qhd = &ehci_data.device[ pipe_hdl.dev_addr-1].qhd[ pipe_hdl.index ];
|
||||
|
||||
TEST_ASSERT_EQUAL(int_edp_interval.bInterval, p_int_qhd->interval_ms);
|
||||
check_int_endpoint_link( get_period_head(hostid, 32), p_int_qhd);
|
||||
check_int_endpoint_link( get_period_head(hostid, 8) , p_int_qhd);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// PIPE CLOSE
|
||||
//--------------------------------------------------------------------+
|
||||
void test_interrupt_close(void)
|
||||
{
|
||||
pipe_hdl = hcd_edpt_open(dev_addr, &desc_ept_interrupt_out, TUSB_CLASS_HID);
|
||||
p_int_qhd = qhd_get_from_pipe_handle(pipe_hdl);
|
||||
|
||||
//------------- Code Under TEST -------------//
|
||||
TEST_ASSERT_EQUAL(TUSB_ERROR_NONE,
|
||||
hcd_pipe_close(pipe_hdl) );
|
||||
|
||||
TEST_ASSERT(p_int_qhd->is_removing);
|
||||
TEST_ASSERT( tu_align32(period_head_arr->next.address) != (uint32_t) p_int_qhd );
|
||||
TEST_ASSERT_EQUAL_HEX( (uint32_t) period_head_arr, tu_align32(p_int_qhd->next.address ) );
|
||||
TEST_ASSERT_EQUAL(EHCI_QUEUE_ELEMENT_QHD, p_int_qhd->next.type);
|
||||
}
|
||||
|
||||
void test_interrupt_256ms_close(void)
|
||||
{
|
||||
tusb_desc_endpoint_t int_edp_interval = desc_ept_interrupt_out;
|
||||
int_edp_interval.bInterval = 9;
|
||||
|
||||
pipe_hdl = hcd_edpt_open(dev_addr, &int_edp_interval, TUSB_CLASS_HID);
|
||||
p_int_qhd = qhd_get_from_pipe_handle(pipe_hdl);
|
||||
|
||||
//------------- Code Under TEST -------------//
|
||||
TEST_ASSERT_EQUAL(TUSB_ERROR_NONE,
|
||||
hcd_pipe_close(pipe_hdl) );
|
||||
|
||||
TEST_ASSERT(p_int_qhd->is_removing);
|
||||
TEST_ASSERT( tu_align32(get_period_head(hostid, 8)->address) != (uint32_t) p_int_qhd );
|
||||
TEST_ASSERT_EQUAL_HEX( (uint32_t) get_period_head(hostid, 8), tu_align32(p_int_qhd->next.address ) );
|
||||
TEST_ASSERT_EQUAL(EHCI_QUEUE_ELEMENT_QHD, p_int_qhd->next.type);
|
||||
}
|
||||
@@ -0,0 +1,252 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* This file is part of the TinyUSB stack.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "unity.h"
|
||||
#include "tusb_option.h"
|
||||
#include "tusb_errors.h"
|
||||
#include "binary.h"
|
||||
#include "type_helper.h"
|
||||
|
||||
#include "hal.h"
|
||||
#include "mock_osal.h"
|
||||
#include "hcd.h"
|
||||
#include "mock_usbh_hcd.h"
|
||||
#include "ehci.h"
|
||||
#include "ehci_controller_fake.h"
|
||||
#include "host_helper.h"
|
||||
|
||||
usbh_device_t _usbh_devices[CFG_TUSB_HOST_DEVICE_MAX+1];
|
||||
|
||||
static uint8_t const hub_addr = 2;
|
||||
static uint8_t const hub_port = 2;
|
||||
static uint8_t dev_addr;
|
||||
static uint8_t hostid;
|
||||
static uint8_t xfer_data [100];
|
||||
static uint8_t data2[100];
|
||||
|
||||
static ehci_qhd_t *period_head_arr;
|
||||
static ehci_qhd_t *p_qhd_interrupt;
|
||||
static pipe_handle_t pipe_hdl_interrupt;
|
||||
|
||||
static tusb_desc_endpoint_t const desc_ept_interrupt_in =
|
||||
{
|
||||
.bLength = sizeof(tusb_desc_endpoint_t),
|
||||
.bDescriptorType = TUSB_DESC_TYPE_ENDPOINT,
|
||||
.bEndpointAddress = 0x81,
|
||||
.bmAttributes = { .xfer = TUSB_XFER_INTERRUPT },
|
||||
.wMaxPacketSize = 8,
|
||||
.bInterval = 2
|
||||
};
|
||||
|
||||
static tusb_desc_endpoint_t const desc_ept_interupt_out =
|
||||
{
|
||||
.bLength = sizeof(tusb_desc_endpoint_t),
|
||||
.bDescriptorType = TUSB_DESC_TYPE_ENDPOINT,
|
||||
.bEndpointAddress = 0x01,
|
||||
.bmAttributes = { .xfer = TUSB_XFER_INTERRUPT },
|
||||
.wMaxPacketSize = 64,
|
||||
.bInterval = 3
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Setup/Teardown + helper declare
|
||||
//--------------------------------------------------------------------+
|
||||
void setUp(void)
|
||||
{
|
||||
ehci_controller_init();
|
||||
|
||||
tu_memclr(_usbh_devices, sizeof(usbh_device_t)*(CFG_TUSB_HOST_DEVICE_MAX+1));
|
||||
tu_memclr(xfer_data, sizeof(xfer_data));
|
||||
|
||||
TEST_ASSERT_STATUS( hcd_init() );
|
||||
|
||||
dev_addr = 1;
|
||||
hostid = RANDOM(CONTROLLER_HOST_NUMBER) + TEST_CONTROLLER_HOST_START_INDEX;
|
||||
|
||||
helper_usbh_device_emulate(dev_addr , hub_addr, hub_port, hostid, TUSB_SPEED_HIGH);
|
||||
|
||||
period_head_arr = (ehci_qhd_t*) get_period_head( hostid, 1 );
|
||||
|
||||
//------------- pipe open -------------//
|
||||
pipe_hdl_interrupt = hcd_edpt_open(dev_addr, &desc_ept_interrupt_in, TUSB_CLASS_HID);
|
||||
|
||||
TEST_ASSERT_EQUAL(dev_addr, pipe_hdl_interrupt.dev_addr);
|
||||
TEST_ASSERT_EQUAL(TUSB_XFER_INTERRUPT, pipe_hdl_interrupt.xfer_type);
|
||||
|
||||
p_qhd_interrupt = &ehci_data.device[ dev_addr -1].qhd[ pipe_hdl_interrupt.index ];
|
||||
}
|
||||
|
||||
void tearDown(void)
|
||||
{
|
||||
}
|
||||
//--------------------------------------------------------------------+
|
||||
// BULK TRANSFER
|
||||
//--------------------------------------------------------------------+
|
||||
void verify_qtd(ehci_qtd_t *p_qtd, uint8_t p_data[], uint16_t length)
|
||||
{
|
||||
TEST_ASSERT_TRUE(p_qtd->alternate.terminate); // not used, always invalid
|
||||
|
||||
//------------- status -------------//
|
||||
TEST_ASSERT_FALSE(p_qtd->pingstate_err);
|
||||
TEST_ASSERT_FALSE(p_qtd->non_hs_split_state);
|
||||
TEST_ASSERT_FALSE(p_qtd->non_hs_period_missed_uframe);
|
||||
TEST_ASSERT_FALSE(p_qtd->xact_err);
|
||||
TEST_ASSERT_FALSE(p_qtd->babble_err);
|
||||
TEST_ASSERT_FALSE(p_qtd->buffer_err);
|
||||
TEST_ASSERT_FALSE(p_qtd->halted);
|
||||
TEST_ASSERT_TRUE(p_qtd->active);
|
||||
|
||||
TEST_ASSERT_FALSE(p_qtd->data_toggle);
|
||||
TEST_ASSERT_EQUAL(3, p_qtd->cerr);
|
||||
TEST_ASSERT_EQUAL(0, p_qtd->current_page);
|
||||
TEST_ASSERT_EQUAL(length, p_qtd->total_bytes);
|
||||
TEST_ASSERT_EQUAL(length, p_qtd->expected_bytes);
|
||||
TEST_ASSERT_TRUE(p_qtd->used);
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX( p_data, p_qtd->buffer[0] );
|
||||
for(uint8_t i=1; i<5; i++)
|
||||
{
|
||||
TEST_ASSERT_EQUAL_HEX( tu_align4k((uint32_t) (p_data+4096*i)), tu_align4k(p_qtd->buffer[i]) );
|
||||
}
|
||||
}
|
||||
|
||||
void test_interrupt_xfer(void)
|
||||
{
|
||||
//------------- Code Under Test -------------//
|
||||
TEST_ASSERT_STATUS( hcd_pipe_xfer(pipe_hdl_interrupt, xfer_data, sizeof(xfer_data), true) );
|
||||
|
||||
ehci_qtd_t* p_qtd = p_qhd_interrupt->p_qtd_list_head;
|
||||
TEST_ASSERT_NOT_NULL(p_qtd);
|
||||
|
||||
verify_qtd( p_qtd, xfer_data, sizeof(xfer_data));
|
||||
TEST_ASSERT_EQUAL_HEX(p_qhd_interrupt->qtd_overlay.next.address, p_qtd);
|
||||
TEST_ASSERT_TRUE(p_qtd->next.terminate);
|
||||
TEST_ASSERT_EQUAL(EHCI_PID_IN, p_qtd->pid);
|
||||
TEST_ASSERT_TRUE(p_qtd->int_on_complete);
|
||||
}
|
||||
|
||||
void test_interrupt_xfer_double(void)
|
||||
{
|
||||
//------------- Code Under Test -------------//
|
||||
TEST_ASSERT_STATUS( hcd_pipe_xfer(pipe_hdl_interrupt, xfer_data, sizeof(xfer_data), false) );
|
||||
|
||||
TEST_ASSERT_STATUS( hcd_pipe_xfer(pipe_hdl_interrupt, data2, sizeof(data2), true) );
|
||||
|
||||
ehci_qtd_t* p_head = p_qhd_interrupt->p_qtd_list_head;
|
||||
ehci_qtd_t* p_tail = p_qhd_interrupt->p_qtd_list_tail;
|
||||
|
||||
//------------- list head -------------//
|
||||
TEST_ASSERT_NOT_NULL(p_head);
|
||||
verify_qtd(p_head, xfer_data, sizeof(xfer_data));
|
||||
TEST_ASSERT_EQUAL_HEX(p_qhd_interrupt->qtd_overlay.next.address, p_head);
|
||||
TEST_ASSERT_EQUAL(EHCI_PID_IN, p_head->pid);
|
||||
TEST_ASSERT_FALSE(p_head->next.terminate);
|
||||
TEST_ASSERT_FALSE(p_head->int_on_complete);
|
||||
|
||||
//------------- list tail -------------//
|
||||
TEST_ASSERT_NOT_NULL(p_tail);
|
||||
verify_qtd(p_tail, data2, sizeof(data2));
|
||||
TEST_ASSERT_EQUAL_HEX( tu_align32(p_head->next.address), p_tail);
|
||||
TEST_ASSERT_EQUAL(EHCI_PID_IN, p_tail->pid);
|
||||
TEST_ASSERT_TRUE(p_tail->next.terminate);
|
||||
TEST_ASSERT_TRUE(p_tail->int_on_complete);
|
||||
}
|
||||
|
||||
void check_qhd_after_complete(ehci_qhd_t *p_qhd)
|
||||
{
|
||||
TEST_ASSERT_TRUE(p_qhd->qtd_overlay.next.terminate);
|
||||
TEST_ASSERT_NULL(p_qhd->p_qtd_list_head);
|
||||
TEST_ASSERT_NULL(p_qhd->p_qtd_list_tail);
|
||||
}
|
||||
|
||||
void test_interrupt_xfer_complete_isr_interval_less_than_1ms(void)
|
||||
{
|
||||
TEST_ASSERT_STATUS( hcd_pipe_xfer(pipe_hdl_interrupt, xfer_data, sizeof(xfer_data), false) );
|
||||
|
||||
TEST_ASSERT_STATUS( hcd_pipe_xfer(pipe_hdl_interrupt, data2, sizeof(data2), true) );
|
||||
|
||||
hcd_event_xfer_complete_Expect(pipe_hdl_interrupt, TUSB_CLASS_HID, XFER_RESULT_SUCCESS, sizeof(xfer_data)+sizeof(data2));
|
||||
|
||||
ehci_qtd_t* p_head = p_qhd_interrupt->p_qtd_list_head;
|
||||
ehci_qtd_t* p_tail = p_qhd_interrupt->p_qtd_list_tail;
|
||||
|
||||
//------------- Code Under Test -------------//
|
||||
ehci_controller_run(hostid);
|
||||
|
||||
TEST_ASSERT_EQUAL(0, p_qhd_interrupt->total_xferred_bytes);
|
||||
check_qhd_after_complete(p_qhd_interrupt);
|
||||
TEST_ASSERT_FALSE(p_head->used);
|
||||
TEST_ASSERT_FALSE(p_tail->used);
|
||||
}
|
||||
|
||||
void test_interrupt_xfer_complete_isr_interval_2ms(void)
|
||||
{
|
||||
tusb_desc_endpoint_t desc_endpoint_2ms = desc_ept_interrupt_in;
|
||||
desc_endpoint_2ms.bInterval = 5;
|
||||
|
||||
pipe_handle_t pipe_hdl_2ms = hcd_edpt_open(dev_addr, &desc_endpoint_2ms, TUSB_CLASS_HID);
|
||||
ehci_qhd_t * p_qhd_2ms = &ehci_data.device[ dev_addr -1].qhd[ pipe_hdl_2ms.index ];
|
||||
|
||||
TEST_ASSERT_STATUS( hcd_pipe_xfer(pipe_hdl_2ms, xfer_data, sizeof(xfer_data), false) );
|
||||
|
||||
ehci_qtd_t* p_head = p_qhd_2ms->p_qtd_list_head;
|
||||
ehci_qtd_t* p_tail = p_qhd_2ms->p_qtd_list_tail;
|
||||
|
||||
//------------- Code Under Test -------------//
|
||||
ehci_controller_run(hostid);
|
||||
|
||||
TEST_ASSERT_EQUAL(0, p_qhd_interrupt->total_xferred_bytes);
|
||||
check_qhd_after_complete(p_qhd_2ms);
|
||||
TEST_ASSERT_FALSE(p_head->used);
|
||||
TEST_ASSERT_FALSE(p_tail->used);
|
||||
|
||||
}
|
||||
|
||||
void test_interrupt_xfer_error_isr(void)
|
||||
{
|
||||
TEST_ASSERT_STATUS( hcd_pipe_xfer(pipe_hdl_interrupt, xfer_data, sizeof(xfer_data), true) );
|
||||
|
||||
hcd_event_xfer_complete_Expect(pipe_hdl_interrupt, TUSB_CLASS_HID, XFER_RESULT_FAILED, 0);
|
||||
|
||||
//------------- Code Under TEST -------------//
|
||||
ehci_controller_run_error(hostid);
|
||||
|
||||
TEST_ASSERT_EQUAL(0, p_qhd_interrupt->total_xferred_bytes);
|
||||
}
|
||||
|
||||
void test_interrupt_xfer_error_stall(void)
|
||||
{
|
||||
TEST_ASSERT_STATUS( hcd_pipe_xfer(pipe_hdl_interrupt, xfer_data, sizeof(xfer_data), true) );
|
||||
|
||||
hcd_event_xfer_complete_Expect(pipe_hdl_interrupt, TUSB_CLASS_HID, XFER_RESULT_STALLED, 0);
|
||||
|
||||
//------------- Code Under TEST -------------//
|
||||
ehci_controller_run_stall(hostid);
|
||||
|
||||
TEST_ASSERT_EQUAL(0, p_qhd_interrupt->total_xferred_bytes);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* This file is part of the TinyUSB stack.
|
||||
*/
|
||||
|
||||
#include "unity.h"
|
||||
#include "tusb_option.h"
|
||||
#include "tusb_errors.h"
|
||||
#include "binary.h"
|
||||
#include "type_helper.h"
|
||||
|
||||
#include "hal.h"
|
||||
#include "mock_osal.h"
|
||||
#include "hcd.h"
|
||||
#include "mock_usbh_hcd.h"
|
||||
#include "ehci.h"
|
||||
#include "ehci_controller_fake.h"
|
||||
#include "host_helper.h"
|
||||
|
||||
usbh_device_t _usbh_devices[CFG_TUSB_HOST_DEVICE_MAX+1];
|
||||
|
||||
static uint8_t const hub_addr = 2;
|
||||
static uint8_t const hub_port = 2;
|
||||
static uint8_t dev_addr;
|
||||
static uint8_t hostid;
|
||||
|
||||
static ehci_qhd_t *period_head_arr;
|
||||
//--------------------------------------------------------------------+
|
||||
// Setup/Teardown + helper declare
|
||||
//--------------------------------------------------------------------+
|
||||
void setUp(void)
|
||||
{
|
||||
tu_memclr(_usbh_devices, sizeof(usbh_device_t)*(CFG_TUSB_HOST_DEVICE_MAX+1));
|
||||
|
||||
hcd_init();
|
||||
|
||||
dev_addr = 1;
|
||||
hostid = RANDOM(CONTROLLER_HOST_NUMBER) + TEST_CONTROLLER_HOST_START_INDEX;
|
||||
|
||||
helper_usbh_device_emulate(dev_addr , hub_addr, hub_port, hostid, TUSB_SPEED_HIGH);
|
||||
|
||||
period_head_arr = get_period_head( hostid, 1 );
|
||||
}
|
||||
|
||||
void tearDown(void)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// TODO ISOCRHONOUS PIPE
|
||||
//--------------------------------------------------------------------+
|
||||
tusb_desc_endpoint_t const desc_ept_iso_in =
|
||||
{
|
||||
.bLength = sizeof(tusb_desc_endpoint_t),
|
||||
.bDescriptorType = TUSB_DESC_TYPE_ENDPOINT,
|
||||
.bEndpointAddress = 0x83,
|
||||
.bmAttributes = { .xfer = TUSB_XFER_ISOCHRONOUS },
|
||||
.wMaxPacketSize = 1024,
|
||||
.bInterval = 1
|
||||
};
|
||||
|
||||
void test_open_isochronous(void)
|
||||
{
|
||||
pipe_handle_t pipe_hdl = hcd_edpt_open(dev_addr, &desc_ept_iso_in, TUSB_CLASS_AUDIO);
|
||||
TEST_ASSERT_EQUAL(0, pipe_hdl.dev_addr);
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* This file is part of the TinyUSB stack.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief TBD
|
||||
*
|
||||
* \note TBD
|
||||
*/
|
||||
|
||||
/** \ingroup TBD
|
||||
* \defgroup TBD
|
||||
* \brief TBD
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _TUSB_HIDH_CALLBACK_H_
|
||||
#define _TUSB_HIDH_CALLBACK_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "common/common.h"
|
||||
|
||||
//------------- hidh -------------//
|
||||
void tusbh_hid_keyboard_isr(uint8_t dev_addr, xfer_result_t event);
|
||||
void tusbh_hid_keyboard_mounted_cb(uint8_t dev_addr);
|
||||
void tusbh_hid_keyboard_unmounted_cb(uint8_t dev_addr);
|
||||
|
||||
void tusbh_hid_mouse_isr(uint8_t dev_addr, xfer_result_t event);
|
||||
void tusbh_hid_mouse_mounted_cb(uint8_t dev_addr);
|
||||
void tusbh_hid_mouse_unmounted_cb(uint8_t dev_addr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _TUSB_HIDH_CALLBACK_H_ */
|
||||
|
||||
/** @} */
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* This file is part of the TinyUSB stack.
|
||||
*/
|
||||
|
||||
#include "stdlib.h"
|
||||
#include "unity.h"
|
||||
#include "tusb_option.h"
|
||||
#include "tusb_errors.h"
|
||||
#include "binary.h"
|
||||
#include "type_helper.h"
|
||||
#include "common/common.h"
|
||||
|
||||
#include "descriptor_test.h"
|
||||
#include "mock_osal.h"
|
||||
#include "mock_hcd.h"
|
||||
#include "mock_usbh.h"
|
||||
#include "hid_host.h"
|
||||
#include "mock_hidh_callback.h"
|
||||
|
||||
uint8_t dev_addr;
|
||||
pipe_handle_t pipe_hdl;
|
||||
|
||||
extern hidh_interface_info_t keyboardh_data[CFG_TUSB_HOST_DEVICE_MAX];
|
||||
|
||||
tusb_desc_interface_t const *p_kbd_interface_desc = &desc_configuration.keyboard_interface;
|
||||
tusb_hid_descriptor_hid_t const *p_kbh_hid_desc = &desc_configuration.keyboard_hid;
|
||||
tusb_desc_endpoint_t const *p_kdb_endpoint_desc = &desc_configuration.keyboard_endpoint;
|
||||
|
||||
void setUp(void)
|
||||
{
|
||||
dev_addr = RANDOM(CFG_TUSB_HOST_DEVICE_MAX)+1;
|
||||
pipe_hdl = (pipe_handle_t) {.dev_addr = dev_addr, .xfer_type = TUSB_XFER_INTERRUPT, .index = 2};
|
||||
}
|
||||
|
||||
void tearDown(void)
|
||||
{
|
||||
}
|
||||
|
||||
//void test_hidh_open_ok(void)
|
||||
//{
|
||||
// uint16_t length=0;
|
||||
//
|
||||
// // TODO expect get HID report descriptor
|
||||
// hcd_edpt_open_IgnoreAndReturn( pipe_hdl );
|
||||
//
|
||||
// //------------- Code Under TEST -------------//
|
||||
// TEST_ASSERT_EQUAL(TUSB_ERROR_NONE, hidh_open_subtask(dev_addr, p_kbd_interface_desc, &length) );
|
||||
//
|
||||
// TEST_ASSERT_EQUAL(sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + sizeof(tusb_desc_endpoint_t),
|
||||
// length);
|
||||
//}
|
||||
|
||||
void test_hidh_close(void)
|
||||
{
|
||||
keyboardh_data[dev_addr-1].pipe_hdl = pipe_hdl;
|
||||
keyboardh_data[dev_addr-1].report_size = 8;
|
||||
|
||||
hcd_pipe_close_ExpectAndReturn(pipe_hdl, TUSB_ERROR_NONE);
|
||||
tusbh_hid_keyboard_unmounted_cb_Expect(dev_addr);
|
||||
|
||||
//------------- Code Under TEST -------------//
|
||||
hidh_close(dev_addr);
|
||||
|
||||
TEST_ASSERT_MEM_ZERO(&keyboardh_data[dev_addr-1], sizeof(hidh_interface_info_t));
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* This file is part of the TinyUSB stack.
|
||||
*/
|
||||
|
||||
#include "stdlib.h"
|
||||
#include "unity.h"
|
||||
#include "type_helper.h"
|
||||
#include "tusb_errors.h"
|
||||
#include "common/common.h"
|
||||
|
||||
#include "hid_host.h"
|
||||
#include "mock_osal.h"
|
||||
#include "mock_cdc_host.h"
|
||||
#include "mock_msc_host.h"
|
||||
#include "mock_hub.h"
|
||||
|
||||
#include "mock_hcd.h"
|
||||
#include "usbh.h"
|
||||
#include "mock_hidh_callback.h"
|
||||
#include "descriptor_test.h"
|
||||
#include "host_helper.h"
|
||||
|
||||
|
||||
extern hidh_interface_info_t mouseh_data[CFG_TUSB_HOST_DEVICE_MAX];
|
||||
hidh_interface_info_t *p_hidh_mouse;
|
||||
hid_mouse_report_t report;
|
||||
|
||||
tusb_desc_interface_t const *p_mouse_interface_desc = &desc_configuration.mouse_interface;
|
||||
tusb_desc_endpoint_t const *p_mouse_endpoint_desc = &desc_configuration.mouse_endpoint;
|
||||
|
||||
uint8_t dev_addr;
|
||||
|
||||
void setUp(void)
|
||||
{
|
||||
helper_usbh_init_expect();
|
||||
usbh_init();
|
||||
|
||||
dev_addr = RANDOM(CFG_TUSB_HOST_DEVICE_MAX)+1;
|
||||
|
||||
// uint16_t length;
|
||||
// TEST_ASSERT_STATUS( hidh_open_subtask(dev_addr, p_mouse_interface_desc, &length) );
|
||||
//
|
||||
// p_hidh_mouse = &mouse_data[dev_addr-1];
|
||||
//
|
||||
// p_hidh_mouse->report_size = sizeof(hid_mouse_report_t);
|
||||
// p_hidh_mouse->pipe_hdl = (pipe_handle_t) {
|
||||
// .dev_addr = dev_addr,
|
||||
// .xfer_type = TUSB_XFER_INTERRUPT,
|
||||
// .index = 1
|
||||
// };
|
||||
}
|
||||
|
||||
void tearDown(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//void test_generic_init(void)
|
||||
//{
|
||||
// hidh_init();
|
||||
//
|
||||
// TEST_ASSERT_MEM_ZERO(mouse_data, sizeof(hidh_interface_info_t)*CFG_TUSB_HOST_DEVICE_MAX);
|
||||
//}
|
||||
@@ -0,0 +1,216 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* This file is part of the TinyUSB stack.
|
||||
*/
|
||||
|
||||
#include "stdlib.h"
|
||||
#include "unity.h"
|
||||
#include "type_helper.h"
|
||||
#include "tusb_errors.h"
|
||||
#include "common/common.h"
|
||||
#include "hid_host.h"
|
||||
#include "mock_osal.h"
|
||||
#include "mock_usbh.h"
|
||||
#include "mock_hcd.h"
|
||||
#include "mock_hidh_callback.h"
|
||||
#include "descriptor_test.h"
|
||||
|
||||
extern hidh_interface_info_t keyboardh_data[CFG_TUSB_HOST_DEVICE_MAX];
|
||||
|
||||
hid_keyboard_report_t sample_key[2] =
|
||||
{
|
||||
{
|
||||
.modifier = KEYBOARD_MODIFIER_LEFTCTRL,
|
||||
.keycode = {4}//{KEYBOARD_KEYCODE_a} TODO ascii to key code table
|
||||
},
|
||||
{
|
||||
.modifier = KEYBOARD_MODIFIER_RIGHTALT,
|
||||
.keycode = {5}//{KEYBOARD_KEYCODE_z}
|
||||
}
|
||||
};
|
||||
|
||||
uint8_t dev_addr;
|
||||
hidh_interface_info_t *p_hidh_kbd;
|
||||
|
||||
hid_keyboard_report_t report;
|
||||
|
||||
tusb_desc_interface_t const *p_kbd_interface_desc = &desc_configuration.keyboard_interface;
|
||||
tusb_desc_endpoint_t const *p_kdb_endpoint_desc = &desc_configuration.keyboard_endpoint;
|
||||
|
||||
void setUp(void)
|
||||
{
|
||||
hidh_init();
|
||||
tu_memclr(&report, sizeof(hid_keyboard_report_t));
|
||||
dev_addr = RANDOM(CFG_TUSB_HOST_DEVICE_MAX)+1;
|
||||
|
||||
p_hidh_kbd = &keyboardh_data[dev_addr-1];
|
||||
|
||||
p_hidh_kbd->report_size = sizeof(hid_keyboard_report_t);
|
||||
p_hidh_kbd->pipe_hdl = (pipe_handle_t) {
|
||||
.dev_addr = dev_addr,
|
||||
.xfer_type = TUSB_XFER_INTERRUPT,
|
||||
.index = 1
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
void tearDown(void)
|
||||
{
|
||||
}
|
||||
|
||||
void test_keyboard_init(void)
|
||||
{
|
||||
hidh_init();
|
||||
|
||||
TEST_ASSERT_MEM_ZERO(keyboardh_data, sizeof(hidh_interface_info_t)*CFG_TUSB_HOST_DEVICE_MAX);
|
||||
}
|
||||
|
||||
//------------- is supported -------------//
|
||||
void test_keyboard_is_supported_fail_unplug(void)
|
||||
{
|
||||
tusbh_device_get_state_IgnoreAndReturn(TUSB_DEVICE_STATE_UNPLUG);
|
||||
TEST_ASSERT_FALSE( tusbh_hid_keyboard_is_mounted(dev_addr) );
|
||||
}
|
||||
|
||||
void test_keyboard_is_supported_fail_not_opened(void)
|
||||
{
|
||||
hidh_init();
|
||||
tusbh_device_get_state_IgnoreAndReturn(TUSB_DEVICE_STATE_CONFIGURED);
|
||||
TEST_ASSERT_FALSE( tusbh_hid_keyboard_is_mounted(dev_addr) );
|
||||
}
|
||||
|
||||
void test_keyboard_is_supported_ok(void)
|
||||
{
|
||||
tusbh_device_get_state_IgnoreAndReturn(TUSB_DEVICE_STATE_CONFIGURED);
|
||||
TEST_ASSERT_TRUE( tusbh_hid_keyboard_is_mounted(dev_addr) );
|
||||
}
|
||||
|
||||
tusb_error_t stub_set_idle_request(uint8_t address, tusb_control_request_t const* p_request, uint8_t* data, int num_call)
|
||||
{
|
||||
TEST_ASSERT_EQUAL( dev_addr, address);
|
||||
|
||||
//------------- expecting Set Idle with value = 0 -------------//
|
||||
TEST_ASSERT_NOT_NULL( p_request );
|
||||
TEST_ASSERT_EQUAL(TUSB_DIR_HOST_TO_DEV , p_request->bmRequestType_bit.direction);
|
||||
TEST_ASSERT_EQUAL(TUSB_REQ_TYPE_CLASS , p_request->bmRequestType_bit.type);
|
||||
TEST_ASSERT_EQUAL(TUSB_REQ_RECIPIENT_INTERFACE , p_request->bmRequestType_bit.recipient);
|
||||
TEST_ASSERT_EQUAL(HID_REQ_CONTROL_SET_IDLE , p_request->bRequest);
|
||||
TEST_ASSERT_EQUAL(0 , p_request->wValue);
|
||||
TEST_ASSERT_EQUAL(p_kbd_interface_desc->bInterfaceNumber , p_request->wIndex);
|
||||
|
||||
TEST_ASSERT_NULL(data);
|
||||
|
||||
return TUSB_ERROR_NONE;
|
||||
}
|
||||
|
||||
void test_keyboard_open_ok(void)
|
||||
{
|
||||
uint16_t length=0;
|
||||
pipe_handle_t pipe_hdl = {.dev_addr = dev_addr, .xfer_type = TUSB_XFER_INTERRUPT, .index = 2};
|
||||
|
||||
hidh_init();
|
||||
|
||||
usbh_control_xfer_subtask_ExpectAndReturn(dev_addr, bm_request_type(TUSB_DIR_HOST_TO_DEV, TUSB_REQ_TYPE_CLASS, TUSB_REQ_RECIPIENT_INTERFACE),
|
||||
HID_REQ_CONTROL_SET_IDLE, 0, p_kbd_interface_desc->bInterfaceNumber, 0, NULL,
|
||||
TUSB_ERROR_NONE);
|
||||
hcd_edpt_open_ExpectAndReturn(dev_addr, p_kdb_endpoint_desc, TUSB_CLASS_HID, pipe_hdl);
|
||||
tusbh_hid_keyboard_mounted_cb_Expect(dev_addr);
|
||||
|
||||
//------------- Code Under TEST -------------//
|
||||
TEST_ASSERT_EQUAL(TUSB_ERROR_NONE, hidh_open_subtask(dev_addr, p_kbd_interface_desc, &length));
|
||||
|
||||
TEST_ASSERT_PIPE_HANDLE(pipe_hdl, p_hidh_kbd->pipe_hdl);
|
||||
TEST_ASSERT_EQUAL(8, p_hidh_kbd->report_size);
|
||||
TEST_ASSERT_EQUAL(sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + sizeof(tusb_desc_endpoint_t),
|
||||
length);
|
||||
TEST_ASSERT_EQUAL(p_kbd_interface_desc->bInterfaceNumber, p_hidh_kbd->interface_number);
|
||||
|
||||
tusbh_device_get_state_IgnoreAndReturn(TUSB_DEVICE_STATE_CONFIGURED);
|
||||
TEST_ASSERT_TRUE( tusbh_hid_keyboard_is_mounted(dev_addr) );
|
||||
// TEST_ASSERT_FALSE( tusbh_hid_keyboard_is_busy(dev_addr) );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// keyboard_get
|
||||
//--------------------------------------------------------------------+
|
||||
void test_keyboard_get_invalid_address(void)
|
||||
{
|
||||
tusbh_device_get_state_IgnoreAndReturn(TUSB_DEVICE_STATE_CONFIGURED);
|
||||
TEST_ASSERT_EQUAL(TUSB_ERROR_INVALID_PARA, tusbh_hid_keyboard_get_report(0, NULL)); // invalid address
|
||||
}
|
||||
|
||||
void test_keyboard_get_invalid_buffer(void)
|
||||
{
|
||||
tusbh_device_get_state_IgnoreAndReturn(TUSB_DEVICE_STATE_CONFIGURED);
|
||||
TEST_ASSERT_EQUAL(TUSB_ERROR_INVALID_PARA, tusbh_hid_keyboard_get_report(dev_addr, NULL)); // invalid buffer
|
||||
}
|
||||
|
||||
void test_keyboard_get_device_not_ready(void)
|
||||
{
|
||||
tusbh_device_get_state_IgnoreAndReturn(TUSB_DEVICE_STATE_UNPLUG);
|
||||
TEST_ASSERT_EQUAL(TUSB_ERROR_DEVICE_NOT_READY, tusbh_hid_keyboard_get_report(dev_addr, &report)); // device not mounted
|
||||
}
|
||||
|
||||
void test_keyboard_get_report_xfer_failed()
|
||||
{
|
||||
tusbh_device_get_state_IgnoreAndReturn(TUSB_DEVICE_STATE_CONFIGURED);
|
||||
hcd_edpt_busy_ExpectAndReturn(p_hidh_kbd->pipe_hdl, false);
|
||||
hcd_pipe_xfer_ExpectAndReturn(p_hidh_kbd->pipe_hdl, (uint8_t*) &report, p_hidh_kbd->report_size, true, TUSB_ERROR_INVALID_PARA);
|
||||
|
||||
//------------- Code Under TEST -------------//
|
||||
TEST_ASSERT_EQUAL(TUSB_ERROR_INVALID_PARA, tusbh_hid_keyboard_get_report(dev_addr, &report));
|
||||
}
|
||||
|
||||
void test_keyboard_get_report_xfer_failed_busy()
|
||||
{
|
||||
tusbh_device_get_state_IgnoreAndReturn(TUSB_DEVICE_STATE_CONFIGURED);
|
||||
hcd_edpt_busy_ExpectAndReturn(p_hidh_kbd->pipe_hdl, true);
|
||||
|
||||
TEST_ASSERT_EQUAL(TUSB_ERROR_INTERFACE_IS_BUSY, tusbh_hid_keyboard_get_report(dev_addr, &report));
|
||||
}
|
||||
|
||||
void test_keyboard_get_ok()
|
||||
{
|
||||
tusbh_device_get_state_IgnoreAndReturn(TUSB_DEVICE_STATE_CONFIGURED);
|
||||
// TEST_ASSERT_EQUAL(TUSB_INTERFACE_STATUS_READY, tusbh_hid_keyboard_status(dev_addr));
|
||||
hcd_edpt_busy_ExpectAndReturn(p_hidh_kbd->pipe_hdl, false);
|
||||
hcd_pipe_xfer_ExpectAndReturn(p_hidh_kbd->pipe_hdl, (uint8_t*) &report, p_hidh_kbd->report_size, true, TUSB_ERROR_NONE);
|
||||
|
||||
//------------- Code Under TEST -------------//
|
||||
TEST_ASSERT_EQUAL(TUSB_ERROR_NONE, tusbh_hid_keyboard_get_report(dev_addr, &report));
|
||||
// TEST_ASSERT_EQUAL(TUSB_INTERFACE_STATUS_BUSY, tusbh_hid_keyboard_status(dev_addr));
|
||||
}
|
||||
|
||||
void test_keyboard_isr_event_complete(void)
|
||||
{
|
||||
tusbh_hid_keyboard_isr_Expect(dev_addr, XFER_RESULT_SUCCESS);
|
||||
|
||||
//------------- Code Under TEST -------------//
|
||||
hidh_isr(p_hidh_kbd->pipe_hdl, XFER_RESULT_SUCCESS, 8);
|
||||
|
||||
// tusbh_device_get_state_IgnoreAndReturn(TUSB_DEVICE_STATE_CONFIGURED);
|
||||
// TEST_ASSERT_EQUAL(TUSB_INTERFACE_STATUS_COMPLETE, tusbh_hid_keyboard_status(dev_addr));
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* This file is part of the TinyUSB stack.
|
||||
*/
|
||||
|
||||
#include "stdlib.h"
|
||||
#include "unity.h"
|
||||
#include "type_helper.h"
|
||||
#include "tusb_errors.h"
|
||||
#include "common/common.h"
|
||||
|
||||
#include "hid_host.h"
|
||||
#include "mock_osal.h"
|
||||
#include "mock_usbh.h"
|
||||
#include "mock_hcd.h"
|
||||
#include "mock_hidh_callback.h"
|
||||
#include "descriptor_test.h"
|
||||
|
||||
extern hidh_interface_info_t mouseh_data[CFG_TUSB_HOST_DEVICE_MAX];
|
||||
hidh_interface_info_t *p_hidh_mouse;
|
||||
hid_mouse_report_t report;
|
||||
|
||||
tusb_desc_interface_t const *p_mouse_interface_desc = &desc_configuration.mouse_interface;
|
||||
tusb_desc_endpoint_t const *p_mouse_endpoint_desc = &desc_configuration.mouse_endpoint;
|
||||
|
||||
uint8_t dev_addr;
|
||||
|
||||
void setUp(void)
|
||||
{
|
||||
hidh_init();
|
||||
|
||||
tu_memclr(&report, sizeof(hid_mouse_report_t));
|
||||
dev_addr = RANDOM(CFG_TUSB_HOST_DEVICE_MAX)+1;
|
||||
|
||||
p_hidh_mouse = &mouseh_data[dev_addr-1];
|
||||
|
||||
p_hidh_mouse->report_size = sizeof(hid_mouse_report_t);
|
||||
p_hidh_mouse->pipe_hdl = (pipe_handle_t) {
|
||||
.dev_addr = dev_addr,
|
||||
.xfer_type = TUSB_XFER_INTERRUPT,
|
||||
.index = 1
|
||||
};
|
||||
}
|
||||
|
||||
void tearDown(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void test_mouse_init(void)
|
||||
{
|
||||
hidh_init();
|
||||
|
||||
TEST_ASSERT_MEM_ZERO(mouseh_data, sizeof(hidh_interface_info_t)*CFG_TUSB_HOST_DEVICE_MAX);
|
||||
}
|
||||
|
||||
//------------- is supported -------------//
|
||||
void test_mouse_is_supported_fail_unplug(void)
|
||||
{
|
||||
tusbh_device_get_state_IgnoreAndReturn(TUSB_DEVICE_STATE_UNPLUG);
|
||||
TEST_ASSERT_FALSE( tusbh_hid_mouse_is_mounted(dev_addr) );
|
||||
}
|
||||
|
||||
void test_mouse_is_supported_fail_not_opened(void)
|
||||
{
|
||||
hidh_init();
|
||||
tusbh_device_get_state_IgnoreAndReturn(TUSB_DEVICE_STATE_CONFIGURED);
|
||||
TEST_ASSERT_FALSE( tusbh_hid_mouse_is_mounted(dev_addr) );
|
||||
}
|
||||
|
||||
void test_mouse_is_supported_ok(void)
|
||||
{
|
||||
tusbh_device_get_state_IgnoreAndReturn(TUSB_DEVICE_STATE_CONFIGURED);
|
||||
TEST_ASSERT_TRUE( tusbh_hid_mouse_is_mounted(dev_addr) );
|
||||
}
|
||||
|
||||
void test_mouse_open_ok(void)
|
||||
{
|
||||
uint16_t length=0;
|
||||
pipe_handle_t pipe_hdl = {.dev_addr = dev_addr, .xfer_type = TUSB_XFER_INTERRUPT, .index = 2};
|
||||
|
||||
hidh_init();
|
||||
|
||||
usbh_control_xfer_subtask_ExpectAndReturn(dev_addr, bm_request_type(TUSB_DIR_HOST_TO_DEV, TUSB_REQ_TYPE_CLASS, TUSB_REQ_RECIPIENT_INTERFACE),
|
||||
HID_REQ_CONTROL_SET_IDLE, 0, p_mouse_interface_desc->bInterfaceNumber, 0, NULL,
|
||||
TUSB_ERROR_NONE);
|
||||
hcd_edpt_open_ExpectAndReturn(dev_addr, p_mouse_endpoint_desc, TUSB_CLASS_HID, pipe_hdl);
|
||||
tusbh_hid_mouse_mounted_cb_Expect(dev_addr);
|
||||
|
||||
//------------- Code Under TEST -------------//
|
||||
TEST_ASSERT_STATUS( hidh_open_subtask(dev_addr, p_mouse_interface_desc, &length));
|
||||
|
||||
TEST_ASSERT_PIPE_HANDLE(pipe_hdl, p_hidh_mouse->pipe_hdl);
|
||||
TEST_ASSERT_EQUAL(8, p_hidh_mouse->report_size);
|
||||
TEST_ASSERT_EQUAL(sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + sizeof(tusb_desc_endpoint_t),
|
||||
length);
|
||||
TEST_ASSERT_EQUAL(p_mouse_interface_desc->bInterfaceNumber, p_hidh_mouse->interface_number);
|
||||
|
||||
tusbh_device_get_state_IgnoreAndReturn(TUSB_DEVICE_STATE_CONFIGURED);
|
||||
TEST_ASSERT_TRUE( tusbh_hid_mouse_is_mounted(dev_addr) );
|
||||
// TEST_ASSERT_FALSE( tusbh_hid_mouse_is_busy(dev_addr) );
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// mouse_get
|
||||
//--------------------------------------------------------------------+
|
||||
void test_mouse_get_invalid_address(void)
|
||||
{
|
||||
tusbh_device_get_state_IgnoreAndReturn(TUSB_DEVICE_STATE_CONFIGURED);
|
||||
TEST_ASSERT_EQUAL(TUSB_ERROR_INVALID_PARA, tusbh_hid_mouse_get_report(0, NULL)); // invalid address
|
||||
}
|
||||
|
||||
void test_mouse_get_invalid_buffer(void)
|
||||
{
|
||||
tusbh_device_get_state_IgnoreAndReturn(TUSB_DEVICE_STATE_CONFIGURED);
|
||||
TEST_ASSERT_EQUAL(TUSB_ERROR_INVALID_PARA, tusbh_hid_mouse_get_report(dev_addr, NULL)); // invalid buffer
|
||||
}
|
||||
|
||||
void test_mouse_get_device_not_ready(void)
|
||||
{
|
||||
tusbh_device_get_state_IgnoreAndReturn(TUSB_DEVICE_STATE_UNPLUG);
|
||||
TEST_ASSERT_EQUAL(TUSB_ERROR_DEVICE_NOT_READY, tusbh_hid_mouse_get_report(dev_addr, &report)); // device not mounted
|
||||
}
|
||||
|
||||
void test_mouse_get_report_xfer_failed()
|
||||
{
|
||||
tusbh_device_get_state_IgnoreAndReturn(TUSB_DEVICE_STATE_CONFIGURED);
|
||||
hcd_edpt_busy_ExpectAndReturn(p_hidh_mouse->pipe_hdl, false);
|
||||
hcd_pipe_xfer_ExpectAndReturn(p_hidh_mouse->pipe_hdl, (uint8_t*) &report, p_hidh_mouse->report_size, true, TUSB_ERROR_INVALID_PARA);
|
||||
|
||||
//------------- Code Under TEST -------------//
|
||||
TEST_ASSERT_EQUAL(TUSB_ERROR_INVALID_PARA, tusbh_hid_mouse_get_report(dev_addr, &report));
|
||||
}
|
||||
|
||||
void test_mouse_get_report_xfer_failed_busy()
|
||||
{
|
||||
tusbh_device_get_state_IgnoreAndReturn(TUSB_DEVICE_STATE_CONFIGURED);
|
||||
hcd_edpt_busy_ExpectAndReturn(p_hidh_mouse->pipe_hdl, true);
|
||||
|
||||
TEST_ASSERT_EQUAL(TUSB_ERROR_INTERFACE_IS_BUSY, tusbh_hid_mouse_get_report(dev_addr, &report));
|
||||
}
|
||||
|
||||
void test_mouse_get_ok()
|
||||
{
|
||||
tusbh_device_get_state_IgnoreAndReturn(TUSB_DEVICE_STATE_CONFIGURED);
|
||||
// TEST_ASSERT_EQUAL(TUSB_INTERFACE_STATUS_READY, tusbh_hid_mouse_status(dev_addr));
|
||||
hcd_edpt_busy_ExpectAndReturn(p_hidh_mouse->pipe_hdl, false);
|
||||
hcd_pipe_xfer_ExpectAndReturn(p_hidh_mouse->pipe_hdl, (uint8_t*) &report, p_hidh_mouse->report_size, true, TUSB_ERROR_NONE);
|
||||
|
||||
//------------- Code Under TEST -------------//
|
||||
TEST_ASSERT_STATUS( tusbh_hid_mouse_get_report(dev_addr, &report));
|
||||
|
||||
// TEST_ASSERT_EQUAL(TUSB_INTERFACE_STATUS_BUSY, tusbh_hid_mouse_status(dev_addr));
|
||||
}
|
||||
|
||||
void test_mouse_isr_event_xfer_complete(void)
|
||||
{
|
||||
tusbh_hid_mouse_isr_Expect(dev_addr, XFER_RESULT_SUCCESS);
|
||||
|
||||
//------------- Code Under TEST -------------//
|
||||
hidh_isr(p_hidh_mouse->pipe_hdl, XFER_RESULT_SUCCESS, 8);
|
||||
|
||||
tusbh_device_get_state_IgnoreAndReturn(TUSB_DEVICE_STATE_CONFIGURED);
|
||||
// TEST_ASSERT_EQUAL(TUSB_INTERFACE_STATUS_COMPLETE, tusbh_hid_mouse_status(dev_addr));
|
||||
}
|
||||
|
||||
void test_mouse_isr_event_xfer_error(void)
|
||||
{
|
||||
tusbh_hid_mouse_isr_Expect(dev_addr, XFER_RESULT_FAILED);
|
||||
|
||||
//------------- Code Under TEST -------------//
|
||||
hidh_isr(p_hidh_mouse->pipe_hdl, XFER_RESULT_FAILED, 0);
|
||||
|
||||
tusbh_device_get_state_IgnoreAndReturn(TUSB_DEVICE_STATE_CONFIGURED);
|
||||
// TEST_ASSERT_EQUAL(TUSB_INTERFACE_STATUS_ERROR, tusbh_hid_mouse_status(dev_addr));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* This file is part of the TinyUSB stack.
|
||||
*/
|
||||
|
||||
#include "common/common.h"
|
||||
#include "host/usbh.h"
|
||||
#include "host/usbh_hcd.h"
|
||||
|
||||
static inline void helper_class_init_expect(void)
|
||||
{ // class code number order
|
||||
#if CFG_TUH_CDC
|
||||
cdch_init_Expect();
|
||||
#endif
|
||||
|
||||
#if HOST_CLASS_HID
|
||||
hidh_init_Expect();
|
||||
#endif
|
||||
|
||||
#if CFG_TUH_MSC
|
||||
msch_init_Expect();
|
||||
#endif
|
||||
|
||||
//TODO update more classes
|
||||
}
|
||||
|
||||
|
||||
static inline void helper_usbh_init_expect(void)
|
||||
{
|
||||
osal_queue_create_IgnoreAndReturn( (osal_queue_handle_t) 0x4566 );
|
||||
osal_task_create_IgnoreAndReturn(TUSB_ERROR_NONE);
|
||||
|
||||
osal_semaphore_create_IgnoreAndReturn( (osal_semaphore_handle_t) 0x1234);
|
||||
osal_mutex_create_IgnoreAndReturn((osal_mutex_handle_t) 0x789a);
|
||||
}
|
||||
|
||||
static inline void helper_usbh_device_emulate(uint8_t dev_addr, uint8_t hub_addr, uint8_t hub_port, uint8_t hostid, tusb_speed_t speed)
|
||||
{
|
||||
_usbh_devices[dev_addr].rhport = hostid;
|
||||
_usbh_devices[dev_addr].hub_addr = hub_addr;
|
||||
_usbh_devices[dev_addr].hub_port = hub_port;
|
||||
_usbh_devices[dev_addr].speed = speed;
|
||||
_usbh_devices[dev_addr].state = dev_addr ? TUSB_DEVICE_STATE_CONFIGURED : TUSB_DEVICE_STATE_UNPLUG;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* This file is part of the TinyUSB stack.
|
||||
*/
|
||||
|
||||
#include "unity.h"
|
||||
|
||||
void setUp(void)
|
||||
{
|
||||
}
|
||||
|
||||
void tearDown(void)
|
||||
{
|
||||
}
|
||||
|
||||
void test_()
|
||||
{
|
||||
// TEST_IGNORE();
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* This file is part of the TinyUSB stack.
|
||||
*/
|
||||
|
||||
//#include "stdlib.h"
|
||||
//#include "unity.h"
|
||||
//#include "type_helper.h"
|
||||
//#include "tusb_option.h"
|
||||
//#include "tusb_errors.h"
|
||||
//
|
||||
//#include "mock_osal.h"
|
||||
//#include "hcd.h"
|
||||
//#include "usbh.h"
|
||||
//#include "tusb.h"
|
||||
//#include "hid_host.h"
|
||||
////#include "ehci_controller_fake.h"
|
||||
//
|
||||
//#include "descriptor_test.h"
|
||||
//
|
||||
//uint8_t dev_addr;
|
||||
//uint8_t hostid;
|
||||
//
|
||||
void setUp(void)
|
||||
{
|
||||
// dev_addr = RANDOM(CFG_TUSB_HOST_DEVICE_MAX)+1;
|
||||
// hostid = RANDOM(CONTROLLER_HOST_NUMBER) + TEST_CONTROLLER_HOST_START_INDEX;
|
||||
//
|
||||
//// ehci_controller_init();
|
||||
// tusb_init();
|
||||
//
|
||||
}
|
||||
//
|
||||
void tearDown(void)
|
||||
{
|
||||
}
|
||||
//
|
||||
//osal_semaphore_handle_t sem_create_stub(osal_semaphore_t * const sem, int num_call)
|
||||
//{
|
||||
// (*p_sem) = 0;
|
||||
// return (osal_semaphore_handle_t) p_sem;
|
||||
//}
|
||||
//void sem_wait_stub(osal_semaphore_handle_t const sem_hdl, uint32_t msec, tusb_error_t *p_error, int num_call)
|
||||
//{
|
||||
//
|
||||
//}
|
||||
//tusb_error_t sem_post_stub(osal_semaphore_handle_t const sem_hdl, int num_call)
|
||||
//{
|
||||
// (*sem_hdl)++;
|
||||
//
|
||||
// return TUSB_ERROR_NONE;
|
||||
//}
|
||||
//void sem_reset_stub(osal_semaphore_handle_t const sem_hdl, int num_call)
|
||||
//{
|
||||
// (*sem_hdl) = 0;
|
||||
//}
|
||||
//
|
||||
//osal_queue_handle_t queue_create_stub (osal_queue_t *p_queue, int num_call)
|
||||
//{
|
||||
// p_queue->count = p_queue->wr_idx = p_queue->rd_idx = 0;
|
||||
// return (osal_queue_handle_t) p_queue;
|
||||
//}
|
||||
//void queue_receive_stub (osal_queue_handle_t const queue_hdl, uint32_t *p_data, uint32_t msec, tusb_error_t *p_error, int num_call)
|
||||
//{
|
||||
//
|
||||
//}
|
||||
//tusb_error_t queue_send_stub (osal_queue_handle_t const queue_hdl, uint32_t data, int num_call)
|
||||
//{
|
||||
// //TODO mutex lock hal_interrupt_disable
|
||||
//
|
||||
// queue_hdl->buffer[queue_hdl->wr_idx] = data;
|
||||
// queue_hdl->wr_idx = (queue_hdl->wr_idx + 1) % queue_hdl->depth;
|
||||
//
|
||||
// if (queue_hdl->depth == queue_hdl->count) // queue is full, 1st rd is overwritten
|
||||
// {
|
||||
// queue_hdl->rd_idx = queue_hdl->wr_idx; // keep full state
|
||||
// }else
|
||||
// {
|
||||
// queue_hdl->count++;
|
||||
// }
|
||||
//
|
||||
// //TODO mutex unlock hal_interrupt_enable
|
||||
//
|
||||
// return TUSB_ERROR_NONE;
|
||||
//}
|
||||
//void queue_flush_stub(osal_queue_handle_t const queue_hdl, int num_call)
|
||||
//{
|
||||
// queue_hdl->count = queue_hdl->rd_idx = queue_hdl->wr_idx = 0;
|
||||
//}
|
||||
//
|
||||
//void test_(void)
|
||||
//{
|
||||
// ehci_controller_device_plug(hostid, TUSB_SPEED_HIGH);
|
||||
//
|
||||
// tusb_task_runner(); // get 8-byte descriptor
|
||||
// ehci_controller_control_xfer_proceed(0, &desc_device);
|
||||
//
|
||||
// tusb_task_runner(); // get 8-byte descriptor
|
||||
//}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* This file is part of the TinyUSB stack.
|
||||
*/
|
||||
|
||||
/** \ingroup TBD
|
||||
* \defgroup TBD
|
||||
* \brief TBD
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _TUSB_MSCH_CALLBACK_H_
|
||||
#define _TUSB_MSCH_CALLBACK_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "common/common.h"
|
||||
|
||||
void tusbh_msc_mounted_cb(uint8_t dev_addr);
|
||||
void tusbh_msc_unmounted_cb(uint8_t dev_addr);
|
||||
void tusbh_msc_isr(uint8_t dev_addr, xfer_result_t event, uint32_t xferred_bytes);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _TUSB_MSCH_CALLBACK_H_ */
|
||||
|
||||
/** @} */
|
||||
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* This file is part of the TinyUSB stack.
|
||||
*/
|
||||
|
||||
#include "stdlib.h"
|
||||
#include "unity.h"
|
||||
#include "tusb_option.h"
|
||||
#include "tusb_errors.h"
|
||||
#include "binary.h"
|
||||
#include "type_helper.h"
|
||||
|
||||
#include "descriptor_test.h"
|
||||
#include "mock_osal.h"
|
||||
#include "mock_hcd.h"
|
||||
#include "mock_usbh.h"
|
||||
|
||||
#include "mock_msch_callback.h"
|
||||
#include "msc_host.h"
|
||||
|
||||
extern msch_interface_t msch_data[CFG_TUSB_HOST_DEVICE_MAX];
|
||||
|
||||
static tusb_desc_interface_t const *p_msc_interface_desc = &desc_configuration.msc_interface;
|
||||
static tusb_desc_endpoint_t const *p_edp_in = &desc_configuration.msc_endpoint_in;
|
||||
static tusb_desc_endpoint_t const *p_edp_out = &desc_configuration.msc_endpoint_out;
|
||||
|
||||
static msch_interface_t* p_msc;
|
||||
|
||||
static uint8_t dev_addr;
|
||||
static pipe_handle_t pipe_in, pipe_out;
|
||||
static pipe_handle_t const pipe_null = { 0 };
|
||||
static uint16_t length;
|
||||
|
||||
void setUp(void)
|
||||
{
|
||||
dev_addr = RANDOM(CFG_TUSB_HOST_DEVICE_MAX)+1;
|
||||
|
||||
osal_semaphore_create_IgnoreAndReturn( (osal_semaphore_handle_t) 0x1234);
|
||||
msch_init();
|
||||
TEST_ASSERT_MEM_ZERO(msch_data, sizeof(msch_interface_t)*CFG_TUSB_HOST_DEVICE_MAX);
|
||||
|
||||
p_msc = &msch_data[dev_addr-1];
|
||||
pipe_in = (pipe_handle_t) {.dev_addr = dev_addr, .xfer_type = TUSB_XFER_BULK, .index = 1};
|
||||
pipe_out = (pipe_handle_t) {.dev_addr = dev_addr, .xfer_type = TUSB_XFER_BULK, .index = 2};
|
||||
}
|
||||
|
||||
void tearDown(void)
|
||||
{
|
||||
length = 0;
|
||||
}
|
||||
|
||||
void test_open_pipe_in_failed(void)
|
||||
{
|
||||
hcd_edpt_open_ExpectAndReturn(dev_addr, p_edp_in, TUSB_CLASS_MSC, pipe_null);
|
||||
|
||||
TEST_ASSERT(TUSB_ERROR_NONE != msch_open(dev_addr, p_msc_interface_desc, &length));
|
||||
}
|
||||
|
||||
void test_open_pipe_out_failed(void)
|
||||
{
|
||||
hcd_edpt_open_ExpectAndReturn(dev_addr, p_edp_in, TUSB_CLASS_MSC, (pipe_handle_t) {1} );
|
||||
hcd_edpt_open_ExpectAndReturn(dev_addr, p_edp_out, TUSB_CLASS_MSC, pipe_null);
|
||||
|
||||
TEST_ASSERT(TUSB_ERROR_NONE != msch_open(dev_addr, p_msc_interface_desc, &length));
|
||||
}
|
||||
|
||||
tusb_error_t stub_control_xfer(uint8_t dev_addr, uint8_t bmRequestType, uint8_t bRequest,
|
||||
uint16_t wValue, uint16_t wIndex, uint16_t wLength, uint8_t* data, int num_call)
|
||||
{
|
||||
switch ( num_call )
|
||||
{
|
||||
case 0: // get max lun
|
||||
TEST_ASSERT_EQUAL(bm_request_type(TUSB_DIR_DEV_TO_HOST, TUSB_REQ_TYPE_CLASS, TUSB_REQ_RECIPIENT_INTERFACE),
|
||||
bmRequestType);
|
||||
TEST_ASSERT_EQUAL(MSC_REQ_GET_MAX_LUN, bRequest);
|
||||
TEST_ASSERT_EQUAL(p_msc_interface_desc->bInterfaceNumber, wIndex);
|
||||
TEST_ASSERT_EQUAL(1, wLength);
|
||||
*data = 1; // TODO multiple LUN support
|
||||
break;
|
||||
|
||||
default:
|
||||
TEST_FAIL();
|
||||
return TUSB_ERROR_FAILED;
|
||||
}
|
||||
|
||||
return TUSB_ERROR_NONE;
|
||||
}
|
||||
#if 0 // TODO TEST enable this
|
||||
void test_open_desc_length(void)
|
||||
{
|
||||
hcd_edpt_open_ExpectAndReturn(dev_addr, p_edp_in, TUSB_CLASS_MSC, pipe_in);
|
||||
hcd_edpt_open_ExpectAndReturn(dev_addr, p_edp_out, TUSB_CLASS_MSC, pipe_out);
|
||||
|
||||
usbh_control_xfer_subtask_IgnoreAndReturn(TUSB_ERROR_NONE);
|
||||
hcd_pipe_xfer_IgnoreAndReturn(TUSB_ERROR_NONE);
|
||||
hcd_pipe_queue_xfer_IgnoreAndReturn(TUSB_ERROR_NONE);
|
||||
|
||||
//------------- Code Under Test -------------//
|
||||
TEST_ASSERT_STATUS( msch_open(dev_addr, p_msc_interface_desc, &length) );
|
||||
|
||||
TEST_ASSERT_EQUAL(sizeof(tusb_desc_interface_t) + 2*sizeof(tusb_desc_endpoint_t),
|
||||
length);
|
||||
}
|
||||
|
||||
void test_open_ok(void)
|
||||
{
|
||||
hcd_edpt_open_ExpectAndReturn(dev_addr, p_edp_in, TUSB_CLASS_MSC, pipe_in);
|
||||
hcd_edpt_open_ExpectAndReturn(dev_addr, p_edp_out, TUSB_CLASS_MSC, pipe_out);
|
||||
|
||||
//------------- get max lun -------------//
|
||||
usbh_control_xfer_subtask_StubWithCallback(stub_control_xfer);
|
||||
|
||||
//------------- Code Under Test -------------//
|
||||
TEST_ASSERT_STATUS( msch_open(dev_addr, p_msc_interface_desc, &length) );
|
||||
|
||||
TEST_ASSERT_EQUAL(p_msc_interface_desc->bInterfaceNumber, p_msc->interface_number);
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,327 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* This file is part of the TinyUSB stack.
|
||||
*/
|
||||
|
||||
#include "unity.h"
|
||||
#include "tusb_errors.h"
|
||||
#include "descriptor_test.h"
|
||||
|
||||
#include "mock_osal.h"
|
||||
#include "usbh.h"
|
||||
#include "mock_hcd.h"
|
||||
#include "mock_hub.h"
|
||||
#include "usbh_hcd.h"
|
||||
|
||||
#include "mock_tusb_callback.h"
|
||||
#include "mock_hid_host.h"
|
||||
#include "mock_cdc_host.h"
|
||||
#include "mock_msc_host.h"
|
||||
|
||||
extern usbh_device_t _usbh_devices[CFG_TUSB_HOST_DEVICE_MAX+1];
|
||||
extern uint8_t enum_data_buffer[CFG_TUSB_HOST_ENUM_BUFFER_SIZE];
|
||||
|
||||
usbh_enumerate_t const enum_connect = {
|
||||
.rhport = 0,
|
||||
.hub_addr = 0,
|
||||
.hub_port = 0,
|
||||
};
|
||||
|
||||
tusb_speed_t device_speed = TUSB_SPEED_FULL;
|
||||
|
||||
void queue_recv_stub (osal_queue_handle_t const queue_hdl, uint32_t *p_data, uint32_t msec, tusb_error_t *p_error, int num_call);
|
||||
void semaphore_wait_success_stub(osal_semaphore_handle_t const sem_hdl, uint32_t msec, tusb_error_t *p_error, int num_call);
|
||||
tusb_error_t control_xfer_stub(uint8_t dev_addr, const tusb_control_request_t * const p_request, uint8_t data[], int num_call);
|
||||
|
||||
enum {
|
||||
POWER_STABLE_DELAY = 500,
|
||||
RESET_DELAY = 200 // USB specs say only 50ms though many devices requires a longer time
|
||||
};
|
||||
|
||||
void setUp(void)
|
||||
{
|
||||
tu_memclr(_usbh_devices, sizeof(usbh_device_t)*(CFG_TUSB_HOST_DEVICE_MAX+1));
|
||||
|
||||
osal_queue_receive_StubWithCallback(queue_recv_stub);
|
||||
osal_semaphore_wait_StubWithCallback(semaphore_wait_success_stub);
|
||||
osal_semaphore_post_IgnoreAndReturn(TUSB_ERROR_NONE);
|
||||
osal_mutex_wait_StubWithCallback(semaphore_wait_success_stub);
|
||||
osal_mutex_release_IgnoreAndReturn(TUSB_ERROR_NONE);
|
||||
hcd_pipe_control_xfer_StubWithCallback(control_xfer_stub);
|
||||
|
||||
hcd_port_connect_status_ExpectAndReturn(enum_connect.rhport, true);
|
||||
osal_task_delay_Expect(POWER_STABLE_DELAY);
|
||||
hcd_port_connect_status_ExpectAndReturn(enum_connect.rhport, true);
|
||||
hcd_port_reset_Expect(enum_connect.rhport);
|
||||
osal_task_delay_Expect(RESET_DELAY);
|
||||
hcd_port_speed_get_ExpectAndReturn(enum_connect.rhport, device_speed);
|
||||
|
||||
osal_semaphore_reset_Expect( _usbh_devices[0].control.sem_hdl );
|
||||
osal_mutex_reset_Expect( _usbh_devices[0].control.mutex_hdl );
|
||||
hcd_pipe_control_open_ExpectAndReturn(0, 8, TUSB_ERROR_NONE);
|
||||
}
|
||||
|
||||
void tearDown(void)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// STUB & HELPER
|
||||
//--------------------------------------------------------------------+
|
||||
void queue_recv_stub (osal_queue_handle_t const queue_hdl, uint32_t *p_data, uint32_t msec, tusb_error_t *p_error, int num_call)
|
||||
{
|
||||
(*p_data) = ( *((uint32_t*) &enum_connect) );
|
||||
(*p_error) = TUSB_ERROR_NONE;
|
||||
}
|
||||
|
||||
void semaphore_wait_success_stub(osal_semaphore_handle_t const sem_hdl, uint32_t msec, tusb_error_t *p_error, int num_call)
|
||||
{
|
||||
(*p_error) = TUSB_ERROR_NONE;
|
||||
}
|
||||
|
||||
#define semaphore_wait_timeout_stub(n) semaphore_wait_timeout_##n
|
||||
#define semaphore_wait_timeout(n) \
|
||||
void semaphore_wait_timeout_##n(osal_semaphore_handle_t const sem_hdl, uint32_t msec, tusb_error_t *p_error, int num_call) {\
|
||||
if (num_call >= n)\
|
||||
(*p_error) = TUSB_ERROR_OSAL_TIMEOUT;\
|
||||
else \
|
||||
(*p_error) = TUSB_ERROR_NONE;\
|
||||
}
|
||||
|
||||
semaphore_wait_timeout(0)
|
||||
semaphore_wait_timeout(1)
|
||||
semaphore_wait_timeout(2)
|
||||
semaphore_wait_timeout(3)
|
||||
semaphore_wait_timeout(4)
|
||||
semaphore_wait_timeout(5)
|
||||
semaphore_wait_timeout(6)
|
||||
semaphore_wait_timeout(7)
|
||||
semaphore_wait_timeout(8)
|
||||
|
||||
tusb_error_t control_xfer_stub(uint8_t dev_addr, const tusb_control_request_t * const p_request, uint8_t data[], int num_call)
|
||||
{
|
||||
switch (num_call)
|
||||
{
|
||||
case 0: // get 8 bytes of device descriptor
|
||||
TEST_ASSERT_EQUAL(TUSB_REQ_GET_DESCRIPTOR, p_request->bRequest);
|
||||
TEST_ASSERT_EQUAL(TUSB_DESC_TYPE_DEVICE, p_request->wValue >> 8);
|
||||
TEST_ASSERT_EQUAL(8, p_request->wLength);
|
||||
memcpy(data, &desc_device, p_request->wLength);
|
||||
break;
|
||||
|
||||
case 1: // set device address
|
||||
TEST_ASSERT_EQUAL(TUSB_REQ_SET_ADDRESS, p_request->bRequest);
|
||||
TEST_ASSERT_EQUAL(p_request->wValue, 1);
|
||||
break;
|
||||
|
||||
case 2: // get full device decriptor for new address
|
||||
TEST_ASSERT_EQUAL(TUSB_REQ_GET_DESCRIPTOR, p_request->bRequest);
|
||||
TEST_ASSERT_EQUAL(TUSB_DESC_TYPE_DEVICE, p_request->wValue >> 8);
|
||||
TEST_ASSERT_EQUAL(18, p_request->wLength);
|
||||
memcpy(data, &desc_device, p_request->wLength);
|
||||
break;
|
||||
|
||||
case 3: // get 9 bytes of configuration descriptor
|
||||
TEST_ASSERT_EQUAL(TUSB_REQ_GET_DESCRIPTOR, p_request->bRequest);
|
||||
TEST_ASSERT_EQUAL(TUSB_DESC_TYPE_CONFIGURATION, p_request->wValue >> 8);
|
||||
TEST_ASSERT_EQUAL(9, p_request->wLength);
|
||||
memcpy(data, &desc_configuration, p_request->wLength);
|
||||
break;
|
||||
|
||||
case 4: // get full-length configuration descriptor
|
||||
TEST_ASSERT_EQUAL(TUSB_REQ_GET_DESCRIPTOR, p_request->bRequest);
|
||||
TEST_ASSERT_EQUAL(TUSB_DESC_TYPE_CONFIGURATION, p_request->wValue >> 8);
|
||||
TEST_ASSERT_EQUAL(CFG_TUSB_HOST_ENUM_BUFFER_SIZE, p_request->wLength);
|
||||
memcpy(data, &desc_configuration, p_request->wLength);
|
||||
break;
|
||||
|
||||
case 5: // set configure
|
||||
TEST_ASSERT_EQUAL(TUSB_REQ_SET_CONFIGURATION, p_request->bRequest);
|
||||
TEST_ASSERT_EQUAL(1, p_request->wValue);
|
||||
TEST_ASSERT_EQUAL(0, p_request->wIndex);
|
||||
TEST_ASSERT_EQUAL(0, p_request->wLength);
|
||||
break;
|
||||
|
||||
default:
|
||||
return TUSB_ERROR_OSAL_TIMEOUT;
|
||||
}
|
||||
|
||||
hcd_event_xfer_complete(
|
||||
(pipe_handle_t) { .dev_addr = (num_call > 1 ? 1 : 0), .xfer_type = TUSB_XFER_CONTROL },
|
||||
0, XFER_RESULT_SUCCESS, 0);
|
||||
|
||||
return TUSB_ERROR_NONE;
|
||||
}
|
||||
|
||||
tusb_error_t stub_hidh_open(uint8_t dev_addr, tusb_desc_interface_t const *descriptor, uint16_t *p_length, int num_call)
|
||||
{
|
||||
*p_length = sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + sizeof(tusb_desc_endpoint_t);
|
||||
return TUSB_ERROR_NONE;
|
||||
}
|
||||
|
||||
tusb_error_t stub_msch_open(uint8_t dev_addr, tusb_desc_interface_t const *descriptor, uint16_t *p_length, int num_call)
|
||||
{
|
||||
*p_length = sizeof(tusb_desc_interface_t) + 2*sizeof(tusb_desc_endpoint_t);
|
||||
return TUSB_ERROR_NONE;
|
||||
}
|
||||
|
||||
tusb_error_t stub_cdch_open(uint8_t dev_addr, tusb_desc_interface_t const *descriptor, uint16_t *p_length, int num_call)
|
||||
{
|
||||
*p_length =
|
||||
//------------- Comm Interface -------------//
|
||||
sizeof(tusb_desc_interface_t) + sizeof(cdc_desc_func_header_t) +
|
||||
sizeof(cdc_desc_func_acm_t) + sizeof(cdc_desc_func_union_t) +
|
||||
sizeof(tusb_desc_endpoint_t) +
|
||||
//------------- Data Interface -------------//
|
||||
sizeof(tusb_desc_interface_t) + 2*sizeof(tusb_desc_endpoint_t);
|
||||
|
||||
return TUSB_ERROR_NONE;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// enumeration
|
||||
//--------------------------------------------------------------------+
|
||||
void test_addr0_failed_dev_desc(void)
|
||||
{
|
||||
osal_semaphore_wait_StubWithCallback(semaphore_wait_timeout_stub(0));
|
||||
|
||||
// tusbh_device_mount_failed_cb_Expect(TUSB_ERROR_USBH_MOUNT_DEVICE_NOT_RESPOND, NULL);
|
||||
|
||||
usbh_enumeration_task(NULL);
|
||||
|
||||
TEST_ASSERT_EQUAL(TUSB_DEVICE_STATE_ADDRESSED, _usbh_devices[0].state);
|
||||
|
||||
}
|
||||
|
||||
void test_addr0_failed_set_address(void)
|
||||
{
|
||||
osal_semaphore_wait_StubWithCallback(semaphore_wait_timeout_stub(1));
|
||||
hcd_port_reset_Expect( _usbh_devices[0].rhport );
|
||||
osal_task_delay_Expect(RESET_DELAY);
|
||||
// tusbh_device_mount_failed_cb_Expect(TUSB_ERROR_USBH_MOUNT_DEVICE_NOT_RESPOND, NULL);
|
||||
|
||||
usbh_enumeration_task(NULL);
|
||||
|
||||
TEST_ASSERT_EQUAL(TUSB_DEVICE_STATE_ADDRESSED, _usbh_devices[0].state);
|
||||
TEST_ASSERT_EQUAL_MEMORY(&desc_device, enum_data_buffer, 8);
|
||||
}
|
||||
|
||||
void test_enum_failed_get_full_dev_desc(void)
|
||||
{
|
||||
osal_semaphore_wait_StubWithCallback(semaphore_wait_timeout_stub(2));
|
||||
hcd_port_reset_Expect( _usbh_devices[0].rhport );
|
||||
osal_task_delay_Expect(RESET_DELAY);
|
||||
hcd_pipe_control_close_ExpectAndReturn(0, TUSB_ERROR_NONE);
|
||||
|
||||
osal_semaphore_reset_Expect( _usbh_devices[0].control.sem_hdl );
|
||||
osal_mutex_reset_Expect( _usbh_devices[0].control.mutex_hdl );
|
||||
hcd_pipe_control_open_ExpectAndReturn(1, desc_device.bMaxPacketSize0, TUSB_ERROR_NONE);
|
||||
// tusbh_device_mount_failed_cb_Expect(TUSB_ERROR_USBH_MOUNT_DEVICE_NOT_RESPOND, NULL);
|
||||
|
||||
usbh_enumeration_task(NULL);
|
||||
|
||||
TEST_ASSERT_EQUAL(TUSB_DEVICE_STATE_UNPLUG, _usbh_devices[0].state);
|
||||
TEST_ASSERT_EQUAL(TUSB_DEVICE_STATE_ADDRESSED, _usbh_devices[1].state);
|
||||
TEST_ASSERT_EQUAL(TUSB_SPEED_FULL, _usbh_devices[1].speed);
|
||||
TEST_ASSERT_EQUAL(enum_connect.rhport, _usbh_devices[1].rhport);
|
||||
TEST_ASSERT_EQUAL(enum_connect.hub_addr, _usbh_devices[1].hub_addr);
|
||||
TEST_ASSERT_EQUAL(enum_connect.hub_port, _usbh_devices[1].hub_port);
|
||||
}
|
||||
|
||||
void test_enum_failed_get_9byte_config_desc(void)
|
||||
{
|
||||
osal_semaphore_wait_StubWithCallback(semaphore_wait_timeout_stub(3));
|
||||
hcd_port_reset_Expect( _usbh_devices[0].rhport );
|
||||
osal_task_delay_Expect(RESET_DELAY);
|
||||
hcd_pipe_control_close_ExpectAndReturn(0, TUSB_ERROR_NONE);
|
||||
osal_semaphore_reset_Expect( _usbh_devices[0].control.sem_hdl );
|
||||
osal_mutex_reset_Expect( _usbh_devices[0].control.mutex_hdl );
|
||||
|
||||
hcd_pipe_control_open_ExpectAndReturn(1, desc_device.bMaxPacketSize0, TUSB_ERROR_NONE);
|
||||
tusbh_device_attached_cb_ExpectAndReturn((tusb_desc_device_t*) enum_data_buffer, 1);
|
||||
// tusbh_device_mount_failed_cb_Expect(TUSB_ERROR_USBH_MOUNT_DEVICE_NOT_RESPOND, NULL);
|
||||
|
||||
usbh_enumeration_task(NULL);
|
||||
|
||||
TEST_ASSERT_EQUAL(desc_device.idVendor, _usbh_devices[1].vendor_id);
|
||||
TEST_ASSERT_EQUAL(desc_device.idProduct, _usbh_devices[1].product_id);
|
||||
TEST_ASSERT_EQUAL(desc_device.bNumConfigurations, _usbh_devices[1].configure_count);
|
||||
}
|
||||
|
||||
void test_enum_failed_get_full_config_desc(void)
|
||||
{
|
||||
osal_semaphore_wait_StubWithCallback(semaphore_wait_timeout_stub(4));
|
||||
hcd_port_reset_Expect( _usbh_devices[0].rhport );
|
||||
osal_task_delay_Expect(RESET_DELAY);
|
||||
hcd_pipe_control_close_ExpectAndReturn(0, TUSB_ERROR_NONE);
|
||||
osal_semaphore_reset_Expect( _usbh_devices[0].control.sem_hdl );
|
||||
osal_mutex_reset_Expect( _usbh_devices[0].control.mutex_hdl );
|
||||
hcd_pipe_control_open_ExpectAndReturn(1, desc_device.bMaxPacketSize0, TUSB_ERROR_NONE);
|
||||
tusbh_device_attached_cb_ExpectAndReturn((tusb_desc_device_t*) enum_data_buffer, 1);
|
||||
// tusbh_device_mount_failed_cb_Expect(TUSB_ERROR_USBH_MOUNT_DEVICE_NOT_RESPOND, NULL);
|
||||
|
||||
usbh_enumeration_task(NULL);
|
||||
}
|
||||
|
||||
void test_enum_parse_config_desc(void)
|
||||
{
|
||||
osal_semaphore_wait_StubWithCallback(semaphore_wait_timeout_stub(5));
|
||||
hcd_port_reset_Expect( _usbh_devices[0].rhport );
|
||||
osal_task_delay_Expect(RESET_DELAY);
|
||||
hcd_pipe_control_close_ExpectAndReturn(0, TUSB_ERROR_NONE);
|
||||
osal_semaphore_reset_Expect( _usbh_devices[0].control.sem_hdl );
|
||||
osal_mutex_reset_Expect( _usbh_devices[0].control.mutex_hdl );
|
||||
hcd_pipe_control_open_ExpectAndReturn(1, desc_device.bMaxPacketSize0, TUSB_ERROR_NONE);
|
||||
tusbh_device_attached_cb_ExpectAndReturn((tusb_desc_device_t*) enum_data_buffer, 1);
|
||||
|
||||
// tusbh_device_mount_failed_cb_Expect(TUSB_ERROR_USBH_MOUNT_DEVICE_NOT_RESPOND, NULL); // fail to set configure
|
||||
|
||||
usbh_enumeration_task(NULL);
|
||||
|
||||
TEST_ASSERT_EQUAL(desc_configuration.configuration.bNumInterfaces, _usbh_devices[1].interface_count);
|
||||
}
|
||||
|
||||
void test_enum_set_configure(void)
|
||||
{
|
||||
osal_semaphore_wait_StubWithCallback(semaphore_wait_timeout_stub(6));
|
||||
hcd_port_reset_Expect( _usbh_devices[0].rhport );
|
||||
osal_task_delay_Expect(RESET_DELAY);
|
||||
hcd_pipe_control_close_ExpectAndReturn(0, TUSB_ERROR_NONE);
|
||||
osal_semaphore_reset_Expect( _usbh_devices[0].control.sem_hdl );
|
||||
osal_mutex_reset_Expect( _usbh_devices[0].control.mutex_hdl );
|
||||
hcd_pipe_control_open_ExpectAndReturn(1, desc_device.bMaxPacketSize0, TUSB_ERROR_NONE);
|
||||
tusbh_device_attached_cb_ExpectAndReturn((tusb_desc_device_t*) enum_data_buffer, 1);
|
||||
|
||||
// class open TODO more class expect
|
||||
hidh_open_subtask_StubWithCallback(stub_hidh_open);
|
||||
msch_open_subtask_StubWithCallback(stub_msch_open);
|
||||
cdch_open_subtask_StubWithCallback(stub_cdch_open);
|
||||
|
||||
tusbh_device_mount_succeed_cb_Expect(1);
|
||||
|
||||
usbh_enumeration_task(NULL);
|
||||
|
||||
TEST_ASSERT_EQUAL( TU_BIT(TUSB_CLASS_HID) | TU_BIT(TUSB_CLASS_MSC) | TU_BIT(TUSB_CLASS_CDC),
|
||||
_usbh_devices[1].flag_supported_class); // TODO change later
|
||||
}
|
||||
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* This file is part of the TinyUSB stack.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "unity.h"
|
||||
#include "tusb_errors.h"
|
||||
#include "type_helper.h"
|
||||
|
||||
#include "mock_osal.h"
|
||||
#include "usbh.h"
|
||||
#include "mock_hub.h"
|
||||
#include "usbh_hcd.h"
|
||||
#include "mock_hcd.h"
|
||||
|
||||
#include "mock_tusb_callback.h"
|
||||
#include "mock_hid_host.h"
|
||||
#include "mock_cdc_host.h"
|
||||
#include "mock_msc_host.h"
|
||||
#include "host_helper.h"
|
||||
|
||||
uint8_t dev_addr;
|
||||
void setUp(void)
|
||||
{
|
||||
dev_addr = RANDOM(CFG_TUSB_HOST_DEVICE_MAX)+1;
|
||||
}
|
||||
|
||||
void tearDown(void)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// get_status
|
||||
//--------------------------------------------------------------------+
|
||||
void test_usbh_status_get_fail(void)
|
||||
{
|
||||
_usbh_devices[dev_addr].state = 0;
|
||||
|
||||
TEST_ASSERT_EQUAL( TUSB_DEVICE_STATE_INVALID_PARAMETER, tusbh_device_get_state(CFG_TUSB_HOST_DEVICE_MAX+1) );
|
||||
TEST_ASSERT_EQUAL( TUSB_DEVICE_STATE_UNPLUG, tusbh_device_get_state(dev_addr) );
|
||||
}
|
||||
|
||||
void test_usbh_status_get_succeed(void)
|
||||
{
|
||||
_usbh_devices[dev_addr].state = TUSB_DEVICE_STATE_CONFIGURED;
|
||||
TEST_ASSERT_EQUAL( TUSB_DEVICE_STATE_CONFIGURED, tusbh_device_get_state(dev_addr) );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Init
|
||||
//--------------------------------------------------------------------+
|
||||
void test_usbh_init_hcd_failed(void)
|
||||
{
|
||||
hcd_init_IgnoreAndReturn(TUSB_ERROR_HCD_FAILED);
|
||||
TEST_ASSERT_EQUAL(TUSB_ERROR_HCD_FAILED, usbh_init());
|
||||
}
|
||||
|
||||
void test_usbh_init_enum_queue_create_failed(void)
|
||||
{
|
||||
hcd_init_ExpectAndReturn(TUSB_ERROR_NONE);
|
||||
osal_queue_create_IgnoreAndReturn(NULL);
|
||||
TEST_ASSERT_EQUAL(TUSB_ERROR_OSAL_QUEUE_FAILED, usbh_init());
|
||||
}
|
||||
|
||||
void test_usbh_init_enum_task_create_failed(void)
|
||||
{
|
||||
hcd_init_ExpectAndReturn(TUSB_ERROR_NONE);
|
||||
osal_queue_create_IgnoreAndReturn((osal_queue_handle_t) 0x1234);
|
||||
osal_task_create_IgnoreAndReturn(TUSB_ERROR_OSAL_TASK_FAILED);
|
||||
TEST_ASSERT_EQUAL(TUSB_ERROR_OSAL_TASK_FAILED, usbh_init());
|
||||
}
|
||||
|
||||
|
||||
void test_usbh_init_semaphore_create_failed(void)
|
||||
{
|
||||
hcd_init_ExpectAndReturn(TUSB_ERROR_NONE);
|
||||
osal_queue_create_IgnoreAndReturn((osal_queue_handle_t) 0x1234);
|
||||
osal_task_create_IgnoreAndReturn(TUSB_ERROR_NONE);
|
||||
osal_semaphore_create_IgnoreAndReturn(NULL);
|
||||
TEST_ASSERT_EQUAL(TUSB_ERROR_OSAL_SEMAPHORE_FAILED, usbh_init());
|
||||
}
|
||||
|
||||
void test_usbh_init_mutex_create_failed(void)
|
||||
{
|
||||
hcd_init_ExpectAndReturn(TUSB_ERROR_NONE);
|
||||
osal_queue_create_IgnoreAndReturn((osal_queue_handle_t) 0x1234);
|
||||
osal_task_create_IgnoreAndReturn(TUSB_ERROR_NONE);
|
||||
osal_semaphore_create_IgnoreAndReturn((osal_semaphore_handle_t) 0x1234);
|
||||
osal_mutex_create_IgnoreAndReturn(NULL);
|
||||
TEST_ASSERT_EQUAL(TUSB_ERROR_OSAL_MUTEX_FAILED, usbh_init());
|
||||
}
|
||||
|
||||
void test_usbh_init_ok(void)
|
||||
{
|
||||
hcd_init_ExpectAndReturn(TUSB_ERROR_NONE);
|
||||
|
||||
helper_usbh_init_expect();
|
||||
helper_class_init_expect();
|
||||
|
||||
//------------- code under test -------------//
|
||||
TEST_ASSERT_EQUAL(TUSB_ERROR_NONE, usbh_init());
|
||||
|
||||
for (uint8_t i=0; i<CFG_TUSB_HOST_DEVICE_MAX+1; i++)
|
||||
{
|
||||
TEST_ASSERT_NOT_NULL(_usbh_devices[i].control.sem_hdl);
|
||||
}
|
||||
}
|
||||
|
||||
#if 0 // TODO TEST enable this
|
||||
// device is not mounted before, even the control pipe is not open, do nothing
|
||||
void test_hcd_event_device_remove_device_not_previously_mounted(void)
|
||||
{
|
||||
uint8_t dev_addr = 1;
|
||||
|
||||
_usbh_devices[dev_addr].state = TUSB_DEVICE_STATE_UNPLUG;
|
||||
_usbh_devices[dev_addr].core_id = 0;
|
||||
_usbh_devices[dev_addr].hub_addr = 0;
|
||||
_usbh_devices[dev_addr].hub_port = 0;
|
||||
|
||||
hcd_event_device_remove(0);
|
||||
}
|
||||
|
||||
void test_hcd_event_device_remove(void)
|
||||
{
|
||||
uint8_t dev_addr = 1;
|
||||
|
||||
_usbh_devices[dev_addr].state = TUSB_DEVICE_STATE_CONFIGURED;
|
||||
_usbh_devices[dev_addr].core_id = 0;
|
||||
_usbh_devices[dev_addr].hub_addr = 0;
|
||||
_usbh_devices[dev_addr].hub_port = 0;
|
||||
_usbh_devices[dev_addr].flag_supported_class = TU_BIT(TUSB_CLASS_HID);
|
||||
|
||||
hidh_close_Expect(dev_addr);
|
||||
hcd_pipe_control_close_ExpectAndReturn(dev_addr, TUSB_ERROR_NONE);
|
||||
|
||||
//------------- Code Under Test -------------//
|
||||
hcd_event_device_remove(0);
|
||||
|
||||
TEST_ASSERT_EQUAL(TUSB_DEVICE_STATE_REMOVING, _usbh_devices[dev_addr].state);
|
||||
}
|
||||
|
||||
void test_usbh_device_unplugged_multple_class(void)
|
||||
{
|
||||
uint8_t dev_addr = 1;
|
||||
|
||||
_usbh_devices[dev_addr].state = TUSB_DEVICE_STATE_CONFIGURED;
|
||||
_usbh_devices[dev_addr].core_id = 0;
|
||||
_usbh_devices[dev_addr].hub_addr = 0;
|
||||
_usbh_devices[dev_addr].hub_port = 0;
|
||||
_usbh_devices[dev_addr].flag_supported_class = TU_BIT(TUSB_CLASS_HID) | TU_BIT(TUSB_CLASS_MSC) | TU_BIT(TUSB_CLASS_CDC);
|
||||
|
||||
cdch_close_Expect(dev_addr);
|
||||
hidh_close_Expect(dev_addr);
|
||||
msch_close_Expect(dev_addr);
|
||||
|
||||
hcd_pipe_control_close_ExpectAndReturn(dev_addr, TUSB_ERROR_NONE);
|
||||
|
||||
//------------- Code Under Test -------------//
|
||||
hcd_event_device_remove(0);
|
||||
|
||||
TEST_ASSERT_EQUAL(TUSB_DEVICE_STATE_REMOVING, _usbh_devices[dev_addr].state);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
void semaphore_wait_success_stub(osal_mutex_handle_t const sem_hdl, uint32_t msec, tusb_error_t *p_error, int num_call)
|
||||
{
|
||||
(*p_error) = TUSB_ERROR_NONE;
|
||||
}
|
||||
|
||||
static void mutex_wait_failed_stub(osal_mutex_handle_t const sem_hdl, uint32_t msec, tusb_error_t *p_error, int num_call)
|
||||
{
|
||||
(*p_error) = TUSB_ERROR_OSAL_TIMEOUT;
|
||||
}
|
||||
|
||||
void test_usbh_control_xfer_mutex_failed(void)
|
||||
{
|
||||
tusb_control_request_t a_request =
|
||||
{
|
||||
.bmRequestType = 1,
|
||||
.bRequest = 2,
|
||||
.wValue = 3,
|
||||
.wIndex = 4,
|
||||
.wLength = 0
|
||||
};
|
||||
|
||||
osal_mutex_wait_StubWithCallback(mutex_wait_failed_stub);
|
||||
osal_mutex_release_ExpectAndReturn(_usbh_devices[dev_addr].control.mutex_hdl, TUSB_ERROR_NONE);
|
||||
|
||||
//------------- Code Under Test -------------//
|
||||
usbh_control_xfer(dev_addr, 1, 2, 3, 4, 0, NULL);
|
||||
}
|
||||
|
||||
void test_usbh_control_xfer_ok(void)
|
||||
{
|
||||
tusb_control_request_t a_request =
|
||||
{
|
||||
.bmRequestType = 1,
|
||||
.bRequest = 2,
|
||||
.wValue = 3,
|
||||
.wIndex = 4,
|
||||
.wLength = 0
|
||||
};
|
||||
|
||||
osal_mutex_wait_StubWithCallback(semaphore_wait_success_stub);
|
||||
|
||||
hcd_pipe_control_xfer_ExpectAndReturn(dev_addr, &a_request, NULL, TUSB_ERROR_NONE);
|
||||
osal_semaphore_wait_StubWithCallback(semaphore_wait_success_stub);
|
||||
|
||||
osal_mutex_release_ExpectAndReturn(_usbh_devices[dev_addr].control.mutex_hdl, TUSB_ERROR_NONE);
|
||||
|
||||
//------------- Code Under Test -------------//
|
||||
usbh_control_xfer(dev_addr, 1, 2, 3, 4, 0, NULL);
|
||||
}
|
||||
|
||||
//void test_hcd_event_xfer_complete_non_control_stalled(void) // do nothing for stall on control
|
||||
//{
|
||||
//
|
||||
//}
|
||||
Reference in New Issue
Block a user