From d644eaeb5c32af3704cd7494981881c28a2064c1 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 4 Mar 2013 00:46:40 +0700 Subject: [PATCH] add test for hcd/host init - TT control - usb cmd complete hcd/host initialization code --- tests/test/host/ehci/test_ehci.c | 40 ++++++++++++++++++++++++++++++-- tinyusb/common/assertion.h | 8 ++++--- tinyusb/host/ehci/ehci.c | 13 ++++++++++- tinyusb/host/ehci/ehci.h | 17 ++++++++++++-- 4 files changed, 70 insertions(+), 8 deletions(-) diff --git a/tests/test/host/ehci/test_ehci.c b/tests/test/host/ehci/test_ehci.c index 81d2e226..2594874e 100644 --- a/tests/test/host/ehci/test_ehci.c +++ b/tests/test/host/ehci/test_ehci.c @@ -315,7 +315,7 @@ void test_ehci_data(void) } //--------------------------------------------------------------------+ -// Initalization +// Initialization //--------------------------------------------------------------------+ void test_hcd_init_data(void) { @@ -375,7 +375,6 @@ void test_hcd_init_async_list(void) TEST_ASSERT(async_head->qtd_overlay.alternate.terminate); TEST_ASSERT(async_head->qtd_overlay.halted); } - } void test_hcd_init_period_list(void) @@ -406,6 +405,43 @@ void test_hcd_init_period_list(void) } #endif } + +void test_hcd_init_tt_control(void) +{ + hcd_init(); + + for(uint32_t i=0; itt_control); + } +} + +void test_hcd_init_usbcmd(void) +{ + hcd_init(); + + for(uint32_t i=0; iusb_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); + } + +} //--------------------------------------------------------------------+ // Helper //--------------------------------------------------------------------+ diff --git a/tinyusb/common/assertion.h b/tinyusb/common/assertion.h index 180d046a..dba81295 100644 --- a/tinyusb/common/assertion.h +++ b/tinyusb/common/assertion.h @@ -61,12 +61,14 @@ extern "C" //--------------------------------------------------------------------+ // Compile-time Assert //--------------------------------------------------------------------+ -#ifdef __COUNTER__ - #define STATIC_ASSSERT(const_expr) enum { XSTRING_CONCAT(static_assert_, __COUNTER__) = 1/(!!(const_expr)) } +#if defined __COUNTER__ && __COUNTER__ != __COUNTER__ + #define _ASSERT_COUNTER __COUNTER__ #else - #define STATIC_ASSSERT(const_expr) enum { XSTRING_CONCAT(static_assert_, __LINE__) = 1/(!!(const_expr)) } + #define _ASSERT_COUNTER __LINE__ #endif +#define STATIC_ASSSERT(const_expr) enum { XSTRING_CONCAT(static_assert_, _ASSERT_COUNTER) = 1/(!!(const_expr)) } + //#if ( defined CFG_PRINTF_UART || defined CFG_PRINTF_USBCDC || defined CFG_PRINTF_DEBUG ) #if TUSB_CFG_DEBUG == 3 #define _PRINTF(...) printf(__VA_ARGS__) diff --git a/tinyusb/host/ehci/ehci.c b/tinyusb/host/ehci/ehci.c index 9cc6289f..64c56f34 100644 --- a/tinyusb/host/ehci/ehci.c +++ b/tinyusb/host/ehci/ehci.c @@ -123,7 +123,7 @@ tusb_error_t hcd_controller_init(uint8_t hostid) regs->usb_sts = EHCI_INT_MASK_ALL; // 2. clear all status regs->usb_int_enable = /*EHCI_INT_MASK_USB |*/ EHCI_INT_MASK_ERROR | EHCI_INT_MASK_PORT_CHANGE | EHCI_INT_MASK_ASYNC_ADVANCE -#if 1 +#if 1 // TODO enable usbint olny | EHCI_INT_MASK_NXP_ASYNC | EHCI_INT_MASK_NXP_PERIODIC #endif ; @@ -164,8 +164,19 @@ tusb_error_t hcd_controller_init(uint8_t hostid) #else regs->periodic_list_base = 0; #endif + + //------------- TT Control (NXP only) -------------// + regs->tt_control = 0; + //------------- USB CMD Register -------------// + regs->usb_cmd = BIT_(EHCI_USBCMD_POS_ASYNC_ENABLE) +#if EHCI_PERIODIC_LIST + | BIT_(EHCI_USBCMD_POS_PERIOD_ENABLE) +#endif + | ((EHCI_CFG_FRAMELIST_SIZE_BITS & BIN8(011)) << EHCI_USBCMD_POS_FRAMELIST_SZIE) + | ((EHCI_CFG_FRAMELIST_SIZE_BITS >> 2) << EHCI_USBCMD_POS_NXP_FRAMELIST_SIZE_MSB); + //------------- ConfigFlag Register (skip) -------------// return TUSB_ERROR_NONE; diff --git a/tinyusb/host/ehci/ehci.h b/tinyusb/host/ehci/ehci.h index 9b184c59..a0b1e635 100644 --- a/tinyusb/host/ehci/ehci.h +++ b/tinyusb/host/ehci/ehci.h @@ -83,9 +83,14 @@ #define EHCI_MAX_ITD 4 #define EHCI_MAX_SITD 16 -#define EHCI_CFG_FRAMELIST_SIZE_BITS 5 /// (0:1024) - (1:512) - (2:256) - (3:128) - (4:64) - (5:32) - (6:16) - (7:8) +#define EHCI_CFG_FRAMELIST_SIZE_BITS 7 /// Framelist Size (NXP specific) (0:1024) - (1:512) - (2:256) - (3:128) - (4:64) - (5:32) - (6:16) - (7:8) #define EHCI_FRAMELIST_SIZE (1024 >> EHCI_CFG_FRAMELIST_SIZE_BITS) +//------------- Validation -------------// +#if EHCI_CFG_FRAMELIST_SIZE_BITS > 7 + #error EHCI_CFG_FRAMELIST_SIZE_BITS must be from 0-7 +#endif + //--------------------------------------------------------------------+ // EHCI Data Structure //--------------------------------------------------------------------+ @@ -308,6 +313,14 @@ enum ehci_interrupt_mask_{ EHCI_INT_MASK_NXP_ASYNC | EHCI_INT_MASK_NXP_PERIODIC }; +enum ehci_usbcmd_pos_ { + EHCI_USBCMD_POS_FRAMELIST_SZIE = 2, + EHCI_USBCMD_POS_PERIOD_ENABLE = 4, + EHCI_USBCMD_POS_ASYNC_ENABLE = 5, + EHCI_USBCMD_POS_NXP_FRAMELIST_SIZE_MSB = 15, + EHCI_USBCMD_POS_INTERRUPT_THRESHOLD = 16 +}; + typedef volatile struct { union { uint32_t usb_cmd ; ///< The Command Register indicates the command to be executed by the serial bus host controller. Writing to the register causes a command to be executed @@ -317,7 +330,7 @@ typedef volatile struct { uint32_t framelist_size : 2 ; ///< This field is R/W only if Programmable Frame List Flagin the HCCPARAMS registers is set to a one. This field specifies the size of the frame list.00b 1024 elements (4096 bytes) Default value 01b 512 elements (2048 bytes) 10b 256 elements (1024 bytes) uint32_t periodic_enable : 1 ; ///< This bit controls whether the host controller skips processing the Periodic Schedule. Values mean: 0b Do not process the Periodic Schedule 1b Use the PERIODICLISTBASE register to access the Periodic Schedule. uint32_t async_enable : 1 ; ///< This bit controls whether the host controller skips processing the Asynchronous Schedule. Values mean: 0b Do not process the Asynchronous Schedule 1b Use the ASYNCLISTADDR register to access the Asynchronous Schedule. - uint32_t advacne_async : 1 ; ///< This bit is used as a doorbell by software to tell the host controller to issue an interrupt the next time it advances asynchronous schedule. Software must write a 1 to this bit to ringthe doorbell. When the host controller has evicted all appropriate cached schedule state, it sets the Interrupt on Async Advancestatus bit in the USBSTS register. If the Interrupt on Async Advance Enablebit in the USBINTR register is a one then the host controller will assert an interrupt at the next interrupt threshold. See Section 4.8.2 for operational details. The host controller sets this bit to a zero after it has set the Interrupt on Async Advance status bit in the USBSTS register to a one. Software should not write a one to this bit when the asynchronous schedule is disabled. Doing so will yield undefined results. + uint32_t advacne_async : 1 ; ///< This bit is used as a doorbell by software to tell the host controller to issue an interrupt the next time it advances asynchronous schedule. Software must write a 1 to this bit to ringthe doorbell. When the host controller has evicted all appropriate cached schedule state, it sets the Interrupt on Async Advancestatus bit in the USBSTS register. If the Interrupt on Async Advance Enablebit in the USBINTR register is a one then the host controller will assert an interrupt at the next interrupt threshold. See Section 4.8.2 for operational details. The host controller sets this bit to a zero after it has set the Interrupt on Async Advance status bit in the USBSTS register to a one. Software should not write a one to this bit when the asynchronous schedule is disabled. Doing so will yield undefined results. uint32_t light_reset : 1 ; ///< This control bit is not required. If implemented, it allows the driver to reset the EHCI controller without affecting the state of the ports or the relationship to the companion host controllers. For example, the PORSTC registers should not be reset to their default values and the CF bit setting should not go to zero (retaining port ownership relationships). A host software read of this bit as zero indicates the Light Host Controller Reset has completed and it is safe for host software to re-initialize the host controller. A host software read of this bit as a one indicates the Light Host Controller Reset has not yet completed. uint32_t async_park : 2 ; ///< It contains a count of the number of successive transactions the host controller is allowed to execute from a high-speed queue head on the Asynchronous schedule before continuing traversal of the Asynchronous schedule. See Section 4.10.3.2 for full operational details. Valid values are 1h to 3h. Software must not write a zero to this bit when Park Mode Enableis a one as this will result in undefined behavior. uint32_t : 1 ; ///< reserved