rename test folder

This commit is contained in:
hathach
2013-06-29 16:16:05 +07:00
parent 7e6e5cc356
commit d7fc73ff76
31 changed files with 0 additions and 0 deletions
@@ -0,0 +1,184 @@
/**************************************************************************/
/*!
@file test_ehci_init.c
@author hathach (tinyusb.org)
@section LICENSE
Software License Agreement (BSD License)
Copyright (c) 2013, hathach (tinyusb.org)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holders nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
INCLUDING NEGLIGENCE OR OTHERWISE ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This file is part of the tinyusb stack.
*/
/**************************************************************************/
#include <stdlib.h>
#include "unity.h"
#include "type_helper.h"
#include "tusb_option.h"
#include "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_info_t usbh_devices[TUSB_CFG_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, 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, 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)
{
#if EHCI_PERIODIC_LIST
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);
#endif
}
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);
#if EHCI_PERIODIC_LIST
TEST_ASSERT(regs->usb_cmd_bit.periodic_enable);
#else
TEST_ASSERT_FALSE(regs->usb_cmd_bit.periodic_enable);
#endif
//------------- Framelist size (NXP specific) -------------//
TEST_ASSERT_BITS(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,103 @@
/**************************************************************************/
/*!
@file test_ehci_isr.c
@author hathach (tinyusb.org)
@section LICENSE
Software License Agreement (BSD License)
Copyright (c) 2013, hathach (tinyusb.org)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holders nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
INCLUDING NEGLIGENCE OR OTHERWISE ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This file is part of the tinyusb stack.
*/
/**************************************************************************/
#include <stdlib.h>
#include "unity.h"
#include "tusb_option.h"
#include "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_info_t usbh_devices[TUSB_CFG_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)
{
usbh_device_plugged_isr_Expect(hostid);
//------------- Code Under Test -------------//
ehci_controller_device_plug(hostid, TUSB_SPEED_HIGH);
}
void test_isr_device_connect_fullspeed(void)
{
usbh_device_plugged_isr_Expect(hostid);
//------------- Code Under Test -------------//
ehci_controller_device_plug(hostid, TUSB_SPEED_FULL);
}
void test_isr_device_connect_slowspeed(void)
{
usbh_device_plugged_isr_Expect(hostid);
//------------- Code Under Test -------------//
ehci_controller_device_plug(hostid, TUSB_SPEED_LOW);
}
void test_isr_device_disconnect(void)
{
usbh_device_unplugged_isr_Expect(hostid);
//------------- Code Under Test -------------//
ehci_controller_device_unplug(hostid);
TEST_ASSERT(regs->usb_cmd_bit.advacne_async);
}
@@ -0,0 +1,304 @@
/**************************************************************************/
/*!
@file test_ehci_structure.c
@author hathach (tinyusb.org)
@section LICENSE
Software License Agreement (BSD License)
Copyright (c) 2013, hathach (tinyusb.org)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holders nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
INCLUDING NEGLIGENCE OR OTHERWISE ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This file is part of the tinyusb stack.
*/
/**************************************************************************/
#include <stdlib.h>
#include "unity.h"
#include "tusb_option.h"
#include "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_info_t usbh_devices[TUSB_CFG_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 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, advacne_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,197 @@
/**************************************************************************/
/*!
@file test_usbh_hcd_integration.c
@author hathach (tinyusb.org)
@section LICENSE
Software License Agreement (BSD License)
Copyright (c) 2013, hathach (tinyusb.org)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holders nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
INCLUDING NEGLIGENCE OR OTHERWISE ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This file is part of the tinyusb stack.
*/
/**************************************************************************/
#include <stdlib.h>
#include "unity.h"
#include "tusb_option.h"
#include "errors.h"
#include "binary.h"
#include "type_helper.h"
#include "hal.h"
#include "mock_osal.h"
#include "mock_hid_host.h"
#include "hcd.h"
#include "usbh_hcd.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;
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_STATUS( hcd_pipe_control_xfer(dev_addr,
&(tusb_std_request_t) {
.bmRequestType = { .direction = TUSB_DIR_HOST_TO_DEV, .type = TUSB_REQUEST_TYPE_STANDARD, .recipient = TUSB_REQUEST_RECIPIENT_DEVICE },
.bRequest = TUSB_REQUEST_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 );
}
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_STATUS( hcd_pipe_control_xfer(dev_addr,
&(tusb_std_request_t) {
.bmRequestType = { .direction = TUSB_DIR_HOST_TO_DEV, .type = TUSB_REQUEST_TYPE_STANDARD, .recipient = TUSB_REQUEST_RECIPIENT_DEVICE },
.bRequest = TUSB_REQUEST_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;
ehci_controller_device_unplug(hostid);
//------------- Code Under Test -------------//
hcd_isr(hostid); // port change detect
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);
}
void test_bulk_pipe_close(void)
{
tusb_descriptor_endpoint_t const desc_ept_bulk_in =
{
.bLength = sizeof(tusb_descriptor_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_pipe_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);
}
void test_device_unplugged_status(void)
{
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);
}
@@ -0,0 +1,178 @@
/**************************************************************************/
/*!
@file test_pipe_bulk_open.c
@author hathach (tinyusb.org)
@section LICENSE
Software License Agreement (BSD License)
Copyright (c) 2013, hathach (tinyusb.org)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holders nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
INCLUDING NEGLIGENCE OR OTHERWISE ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This file is part of the tinyusb stack.
*/
/**************************************************************************/
#include <stdlib.h>
#include "unity.h"
#include "tusb_option.h"
#include "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_info_t usbh_devices[TUSB_CFG_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;
memclr_(usbh_devices, sizeof(usbh_device_info_t)*(TUSB_CFG_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_descriptor_endpoint_t const desc_ept_bulk_in =
{
.bLength = sizeof(tusb_descriptor_endpoint_t),
.bDescriptorType = TUSB_DESC_TYPE_ENDPOINT,
.bEndpointAddress = 0x81,
.bmAttributes = { .xfer = TUSB_XFER_BULK },
.wMaxPacketSize = 512,
.bInterval = 0
};
void verify_bulk_open_qhd(ehci_qhd_t *p_qhd, tusb_descriptor_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, 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_descriptor_endpoint_t const * desc_endpoint = &desc_ept_bulk_in;
//------------- Code Under TEST -------------//
pipe_hdl = hcd_pipe_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, align32(async_head->next.address));
TEST_ASSERT_FALSE(async_head->next.terminate);
TEST_ASSERT_EQUAL(EHCI_QUEUE_ELEMENT_QHD, async_head->next.type);
}
//--------------------------------------------------------------------+
// PIPE CLOSE
//--------------------------------------------------------------------+
void test_bulk_close(void)
{
tusb_descriptor_endpoint_t const * desc_endpoint = &desc_ept_bulk_in;
pipe_handle_t pipe_hdl = hcd_pipe_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( align32(async_head->next.address) != (uint32_t) p_qhd );
TEST_ASSERT_EQUAL_HEX( (uint32_t) async_head, align32(p_qhd->next.address) );
TEST_ASSERT_EQUAL(EHCI_QUEUE_ELEMENT_QHD, p_qhd->next.type);
}
@@ -0,0 +1,221 @@
/**************************************************************************/
/*!
@file test_ehci_pipe_bulk_xfer.c
@author hathach (tinyusb.org)
@section LICENSE
Software License Agreement (BSD License)
Copyright (c) 2013, hathach (tinyusb.org)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holders nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
INCLUDING NEGLIGENCE OR OTHERWISE ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This file is part of the tinyusb stack.
*/
/**************************************************************************/
#include <stdlib.h>
#include "unity.h"
#include "tusb_option.h"
#include "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_info_t usbh_devices[TUSB_CFG_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_descriptor_endpoint_t const desc_ept_bulk_in =
{
.bLength = sizeof(tusb_descriptor_endpoint_t),
.bDescriptorType = TUSB_DESC_TYPE_ENDPOINT,
.bEndpointAddress = 0x81,
.bmAttributes = { .xfer = TUSB_XFER_BULK },
.wMaxPacketSize = 512,
.bInterval = 0
};
tusb_descriptor_endpoint_t const desc_ept_bulk_out =
{
.bLength = sizeof(tusb_descriptor_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();
memclr_(xfer_data, sizeof(xfer_data));
memclr_(usbh_devices, sizeof(usbh_device_info_t)*(TUSB_CFG_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_pipe_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_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( align4k((uint32_t) (p_data+4096*i)), 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_pipe_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;
TEST_ASSERT(p_qtd->pingstate_err);
}
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( 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;
usbh_isr_Expect(pipe_hdl_bulk, TUSB_CLASS_MSC, TUSB_EVENT_XFER_COMPLETE);
//------------- Code Under Test -------------//
ehci_controller_run(hostid);
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,196 @@
/**************************************************************************/
/*!
@file test_ehci_pipe.c
@author hathach (tinyusb.org)
@section LICENSE
Software License Agreement (BSD License)
Copyright (c) 2013, hathach (tinyusb.org)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holders nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
INCLUDING NEGLIGENCE OR OTHERWISE ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This file is part of the tinyusb stack.
*/
/**************************************************************************/
#include <stdlib.h>
#include "unity.h"
#include "tusb_option.h"
#include "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_info_t usbh_devices[TUSB_CFG_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)
{
memclr_(usbh_devices, sizeof(usbh_device_info_t)*(TUSB_CFG_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, 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( align32(get_async_head(hostid)->next.address) != (uint32_t) p_control_qhd );
TEST_ASSERT_EQUAL( get_async_head(hostid), align32(p_control_qhd->next.address));
}
@@ -0,0 +1,252 @@
/**************************************************************************/
/*!
@file test_ehci_pipe_xfer.c
@author hathach (tinyusb.org)
@section LICENSE
Software License Agreement (BSD License)
Copyright (c) 2013, hathach (tinyusb.org)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holders nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
INCLUDING NEGLIGENCE OR OTHERWISE ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This file is part of the tinyusb stack.
*/
/**************************************************************************/
#include <stdlib.h>
#include "unity.h"
#include "tusb_option.h"
#include "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_info_t usbh_devices[TUSB_CFG_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();
memclr_(usbh_devices, sizeof(usbh_device_info_t)*(TUSB_CFG_HOST_DEVICE_MAX+1));
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_std_request_t request_get_dev_desc =
{
.bmRequestType = { .direction = TUSB_DIR_DEV_TO_HOST, .type = TUSB_REQUEST_TYPE_STANDARD, .recipient = TUSB_REQUEST_RECIPIENT_DEVICE },
.bRequest = TUSB_REQUEST_GET_DESCRIPTOR,
.wValue = (TUSB_DESC_TYPE_DEVICE << 8),
.wLength = 18
};
tusb_std_request_t request_set_dev_addr =
{
.bmRequestType = { .direction = TUSB_DIR_HOST_TO_DEV, .type = TUSB_REQUEST_TYPE_STANDARD, .recipient = TUSB_REQUEST_RECIPIENT_DEVICE },
.bRequest = TUSB_REQUEST_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_STATUS( 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_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_STATUS( 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_STATUS( 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_STATUS( hcd_pipe_control_xfer(dev_addr, &request_get_dev_desc, xfer_data) );
usbh_isr_Expect(((pipe_handle_t){.dev_addr = dev_addr}), 0, TUSB_EVENT_XFER_COMPLETE);
//------------- Code Under TEST -------------//
ehci_controller_run(hostid);
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_STATUS( hcd_pipe_control_xfer(dev_addr, &request_get_dev_desc, xfer_data) );
usbh_isr_Expect(((pipe_handle_t){.dev_addr = dev_addr}), 0, TUSB_EVENT_XFER_ERROR);
//------------- Code Under TEST -------------//
ehci_controller_run_error(hostid);
}
@@ -0,0 +1,342 @@
/**************************************************************************/
/*!
@file test_ehci_pipe.c
@author hathach (tinyusb.org)
@section LICENSE
Software License Agreement (BSD License)
Copyright (c) 2013, hathach (tinyusb.org)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holders nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
INCLUDING NEGLIGENCE OR OTHERWISE ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This file is part of the tinyusb stack.
*/
/**************************************************************************/
#include "unity.h"
#include "tusb_option.h"
#include "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_info_t usbh_devices[TUSB_CFG_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)
{
memclr_(usbh_devices, sizeof(usbh_device_info_t)*(TUSB_CFG_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;
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_descriptor_endpoint_t const desc_ept_interrupt_out =
{
.bLength = sizeof(tusb_descriptor_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_descriptor_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, 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_pipe_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_descriptor_endpoint_t int_edp_interval = desc_ept_interrupt_out;
int_edp_interval.bInterval = 1;
//------------- Code Under TEST -------------//
pipe_hdl = hcd_pipe_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(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_descriptor_endpoint_t int_edp_interval = desc_ept_interrupt_out;
int_edp_interval.bInterval = 2;
//------------- Code Under TEST -------------//
pipe_hdl = hcd_pipe_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 , cardinality_of(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_descriptor_endpoint_t int_edp_interval = desc_ept_interrupt_out;
int_edp_interval.bInterval = 3;
//------------- Code Under TEST -------------//
pipe_hdl = hcd_pipe_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, cardinality_of(p_int_qhd->interrupt_smask) );
check_int_endpoint_link(period_head_arr, p_int_qhd);
}
void test_open_interrupt_hs_interval_4(void)
{
tusb_descriptor_endpoint_t int_edp_interval = desc_ept_interrupt_out;
int_edp_interval.bInterval = 4;
//------------- Code Under TEST -------------//
pipe_hdl = hcd_pipe_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, cardinality_of(p_int_qhd->interrupt_smask) );
check_int_endpoint_link(period_head_arr, p_int_qhd);
}
void test_open_interrupt_hs_interval_5(void)
{
tusb_descriptor_endpoint_t int_edp_interval = desc_ept_interrupt_out;
int_edp_interval.bInterval = 5;
//------------- Code Under TEST -------------//
pipe_hdl = hcd_pipe_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, cardinality_of(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_descriptor_endpoint_t int_edp_interval = desc_ept_interrupt_out;
int_edp_interval.bInterval = 6;
//------------- Code Under TEST -------------//
pipe_hdl = hcd_pipe_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, cardinality_of(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_descriptor_endpoint_t int_edp_interval = desc_ept_interrupt_out;
int_edp_interval.bInterval = 7;
//------------- Code Under TEST -------------//
pipe_hdl = hcd_pipe_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, cardinality_of(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_descriptor_endpoint_t int_edp_interval = desc_ept_interrupt_out;
int_edp_interval.bInterval = 16;
//------------- Code Under TEST -------------//
pipe_hdl = hcd_pipe_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, cardinality_of(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_pipe_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_descriptor_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_pipe_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_pipe_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( align32(period_head_arr->next.address) != (uint32_t) p_int_qhd );
TEST_ASSERT_EQUAL_HEX( (uint32_t) period_head_arr, 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_descriptor_endpoint_t int_edp_interval = desc_ept_interrupt_out;
int_edp_interval.bInterval = 9;
pipe_hdl = hcd_pipe_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( align32(get_period_head(hostid, 8)->address) != (uint32_t) p_int_qhd );
TEST_ASSERT_EQUAL_HEX( (uint32_t) get_period_head(hostid, 8), align32(p_int_qhd->next.address ) );
TEST_ASSERT_EQUAL(EHCI_QUEUE_ELEMENT_QHD, p_int_qhd->next.type);
}
@@ -0,0 +1,236 @@
/**************************************************************************/
/*!
@file test_ehci_pipe_bulk_xfer.c
@author hathach (tinyusb.org)
@section LICENSE
Software License Agreement (BSD License)
Copyright (c) 2013, hathach (tinyusb.org)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holders nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
INCLUDING NEGLIGENCE OR OTHERWISE ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This file is part of the tinyusb stack.
*/
/**************************************************************************/
#include <stdlib.h>
#include "unity.h"
#include "tusb_option.h"
#include "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_info_t usbh_devices[TUSB_CFG_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_descriptor_endpoint_t const desc_ept_interrupt_in =
{
.bLength = sizeof(tusb_descriptor_endpoint_t),
.bDescriptorType = TUSB_DESC_TYPE_ENDPOINT,
.bEndpointAddress = 0x81,
.bmAttributes = { .xfer = TUSB_XFER_INTERRUPT },
.wMaxPacketSize = 8,
.bInterval = 2
};
static tusb_descriptor_endpoint_t const desc_ept_interupt_out =
{
.bLength = sizeof(tusb_descriptor_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();
memclr_(usbh_devices, sizeof(usbh_device_info_t)*(TUSB_CFG_HOST_DEVICE_MAX+1));
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_pipe_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_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( align4k((uint32_t) (p_data+4096*i)), 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( 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) );
usbh_isr_Expect(pipe_hdl_interrupt, TUSB_CLASS_HID, TUSB_EVENT_XFER_COMPLETE);
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);
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_descriptor_endpoint_t desc_endpoint_2ms = desc_ept_interrupt_in;
desc_endpoint_2ms.bInterval = 5;
pipe_handle_t pipe_hdl_2ms = hcd_pipe_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);
check_qhd_after_complete(p_qhd_2ms);
TEST_ASSERT_FALSE(p_head->used);
TEST_ASSERT_FALSE(p_tail->used);
}
@@ -0,0 +1,99 @@
/**************************************************************************/
/*!
@file test_ehci_pipe.c
@author hathach (tinyusb.org)
@section LICENSE
Software License Agreement (BSD License)
Copyright (c) 2013, hathach (tinyusb.org)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holders nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
INCLUDING NEGLIGENCE OR OTHERWISE ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This file is part of the tinyusb stack.
*/
/**************************************************************************/
#include "unity.h"
#include "tusb_option.h"
#include "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_info_t usbh_devices[TUSB_CFG_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)
{
memclr_(usbh_devices, sizeof(usbh_device_info_t)*(TUSB_CFG_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_descriptor_endpoint_t const desc_ept_iso_in =
{
.bLength = sizeof(tusb_descriptor_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_pipe_open(dev_addr, &desc_ept_iso_in, TUSB_CLASS_AUDIO);
TEST_ASSERT_EQUAL(0, pipe_hdl.dev_addr);
}