From c662309489fe0831db0b2e0bff954325f6a77b9e Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 11 Sep 2012 11:36:30 -0700 Subject: [PATCH] Hot steaming pile of in-progress USB test code. Eventually, this will morph into a proper stack. But first, to "make it work". --- firmware/usb_performance/usb_performance.c | 326 ++++++++++++++++++++- 1 file changed, 324 insertions(+), 2 deletions(-) diff --git a/firmware/usb_performance/usb_performance.c b/firmware/usb_performance/usb_performance.c index d68b6dd0..b46edeb5 100644 --- a/firmware/usb_performance/usb_performance.c +++ b/firmware/usb_performance/usb_performance.c @@ -1,9 +1,320 @@ +#include + #include +#include #include +#include +#include +#include +#include + +#include + +#include + +#define ATTR_ALIGNED(x) __attribute__ ((aligned(x))) +#define __DATA(x) __attribute__ ((section("x"))) +/* +#define REGISTER_START(register_name) \ + #define REGISTER_FIELD_NAME(x) register_name##_x \ + typedef enum { +#define REGISTER_BIT(name, ordinal) \ + REGISTER_FIELD_NAME(name##_bit) = ordinal, \ + REGISTER_FIELD_NAME(name) = (1 << ordinal), +#define REGISTER_END(x) \ + } register_name_bit_t; \ + #undef REGISTER_NAME +*/ + +typedef enum { + RESET_CTRL0_USB0_RST_bit = 17, +} RESET_CTRL0_bit_t; + +//REGISTER_START(RESET_CTRL0) +// REGISTER_BIT(USB0_RST, 17) +//REGISTER_END(RESET_CTRL0) + +typedef enum { + CREG_CREG0_USB0PHY_bit = 5, +} CREG_CREG0_bit_t; + +typedef enum { + USB0_USBCMD_D_RS_bit = 0, + USB0_USBCMD_D_RS = 1 << USB0_USBCMD_D_RS_bit, + + USB0_USBCMD_D_RST_bit = 1, + USB0_USBCMD_D_RST = 1 << USB0_USBCMD_D_RST_bit, + + USB0_USBCMD_D_ITC_base = 16, + USB0_USBCMD_D_ITC_width = 8, + USB0_USBCMD_D_ITC_mask = ((1 << USB0_USBCMD_D_ITC_width) - 1) << + USB0_USBCMD_D_ITC_base, +} USB0_USBCMD_D_bit_t; + +typedef enum { + USB0_USBSTS_UI_bit = 0, + USB0_USBSTS_UI = 1 << USB0_USBSTS_UI_bit, + + USB0_USBSTS_UEI_bit = 1, + USB0_USBSTS_UEI = 1 << USB0_USBSTS_UEI_bit, + + USB0_USBSTS_PCI_bit = 2, + USB0_USBSTS_PCI = 1 << USB0_USBSTS_PCI_bit, + + USB0_USBSTS_AAI_bit = 5, + USB0_USBSTS_AAI = 1 << USB0_USBSTS_AAI_bit, + + USB0_USBSTS_URI_bit = 6, + USB0_USBSTS_URI = 1 << USB0_USBSTS_URI_bit, + + USB0_USBSTS_SRI_bit = 7, + USB0_USBSTS_SRI = 1 << USB0_USBSTS_SRI_bit, + + USB0_USBSTS_SLI_bit = 8, + USB0_USBSTS_SLI = 1 << USB0_USBSTS_SLI_bit, + + USB0_USBSTS_NAKI_bit = 16, + USB0_USBSTS_NAKI = 1 << USB0_USBSTS_NAKI_bit, +} USB0_USBSTS_bit_t; + +typedef enum { + USB0_USBINTR_D_UE_bit = 0, + USB0_USBINTR_D_UE = 1 << USB0_USBINTR_D_UE_bit, + + USB0_USBINTR_D_UEE_bit = 1, + USB0_USBINTR_D_UEE = 1 << USB0_USBINTR_D_UEE_bit, + + USB0_USBINTR_D_PCE_bit = 2, + USB0_USBINTR_D_PCE = 1 << USB0_USBINTR_D_PCE_bit, + + USB0_USBINTR_D_URE_bit = 6, + USB0_USBINTR_D_URE = 1 << USB0_USBINTR_D_URE_bit, + + USB0_USBINTR_D_SRE_bit = 7, + USB0_USBINTR_D_SRE = 1 << USB0_USBINTR_D_SRE_bit, + + USB0_USBINTR_D_SLE_bit = 8, + USB0_USBINTR_D_SLE = 1 << USB0_USBINTR_D_SLE_bit, + + USB0_USBINTR_D_NAKE_bit = 16, + USB0_USBINTR_D_NAKE = 1 << USB0_USBINTR_D_NAKE_bit, +} USB0_USBINTR_D_bit_t; + +typedef enum { + USB0_USBMODE_D_CM_base = 0, + USB0_USBMODE_D_SLOM_bit = 3, + USB0_USBMODE_D_SLOM = 1 << USB0_USBMODE_D_SLOM_bit, +} USB0_USBMODE_D_bit_t; + +typedef enum { + USB0_ENDPTCTRL0_RXS_bit = 0, + USB0_ENDPTCTRL0_RXS = 1 << USB0_ENDPTCTRL0_RXS_bit, + + USB0_ENDPTCTRL0_RXT_base = 2, + + USB0_ENDPTCTRL0_RXE_bit = 7, + USB0_ENDPTCTRL0_RXE = 1 << USB0_ENDPTCTRL0_RXE_bit, + + USB0_ENDPTCTRL0_TXS_bit = 16, + USB0_ENDPTCTRL0_TXS = 1 << USB0_ENDPTCTRL0_TXS_bit, + + USB0_ENDPTCTRL0_TXT_base = 18, + USB0_ENDPTCTRL0_TXT_width = 2, + USB0_ENDPTCTRL0_TXT_mask = ((1 << USB0_ENDPTCTRL0_TXT_width) - 1) << + USB0_ENDPTCTRL0_TXT_base, + + USB0_ENDPTCTRL0_TXE_bit = 23, + USB0_ENDPTCTRL0_TXE = 1 << USB0_ENDPTCTRL0_TXE_bit, +} USB0_ENDPTCTRL0_bit_t; + +typedef enum { + + USB0_ENDPTCTRL_RXS_bit = 0, + USB0_ENDPTCTRL_RXS = 1 << USB0_ENDPTCTRL_RXS_bit, + + USB0_ENDPTCTRL_RXT_base = 2, + USB0_ENDPTCTRL_RXT_width = 2, + USB0_ENDPTCTRL_RXT_mask = ((1 << USB0_ENDPTCTRL_RXT_width) - 1) << + USB0_ENDPTCTRL_RXT_base, + + USB0_ENDPTCTRL_RXI_bit = 5, + USB0_ENDPTCTRL_RXI = 1 << USB0_ENDPTCTRL_RXI_bit, + + USB0_ENDPTCTRL_RXR_bit = 6, + USB0_ENDPTCTRL_RXR = 1 << USB0_ENDPTCTRL_RXR_bit, + + USB0_ENDPTCTRL_RXE_bit = 7, + USB0_ENDPTCTRL_RXE = 1 << USB0_ENDPTCTRL_RXE_bit, + + USB0_ENDPTCTRL_TXS_bit = 16, + USB0_ENDPTCTRL_TXS = 1 << USB0_ENDPTCTRL_TXS_bit, + + USB0_ENDPTCTRL_TXT_base = 18, + USB0_ENDPTCTRL_TXT_width = 2, + USB0_ENDPTCTRL_TXT_mask = ((1 << USB0_ENDPTCTRL_TXT_width) - 1) << + USB0_ENDPTCTRL_TXT_base, + + USB0_ENDPTCTRL_TXE_bit = 23, + USB0_ENDPTCTRL_TXE = 1 << USB0_ENDPTCTRL_TXE_bit, +} USB0_ENDPTCTRL_bit_t; + +void usb_reset_peripheral() { + RESET_CTRL0 = (1 << RESET_CTRL0_USB0_RST_bit); + RESET_CTRL0 = 0; + + while( (RESET_ACTIVE_STATUS0 & (1 << RESET_CTRL0_USB0_RST_bit)) == 0 ); +} + +void usb_enable_phy() { + peripheral_bitband_clear(&CREG_CREG0, CREG_CREG0_USB0PHY_bit); +} + +void usb_wait_for_endpoint_priming_to_finish() { + while( USB0_ENDPTPRIME ); +} + +void usb_wait_for_endpoint_flushing_to_finish() { + while( USB0_ENDPTFLUSH ); +} + +void usb_flush_all_primed_endpoints() { + usb_wait_for_endpoint_priming_to_finish(); + USB0_ENDPTFLUSH = ~0; + usb_wait_for_endpoint_flushing_to_finish(); +} + +void usb_stop_controller() { + peripheral_bitband_clear(&USB0_USBCMD_D, USB0_USBCMD_D_RS_bit); +} + +void usb_run_controller() { + peripheral_bitband_set(&USB0_USBCMD_D, USB0_USBCMD_D_RS_bit); +} + +uint_fast8_t usb_controller_is_resetting() { + return (USB0_USBCMD_D & USB0_USBCMD_D_RST) != 0; +} + +void usb_reset_controller() { + USB0_USBCMD_D = USB0_USBCMD_D_RST; + while( usb_controller_is_resetting() ); +} +/* +void usb_reset() { + usb_flush_all_primed_endpoints(); + usb_stop_controller(); + usb_reset_controller(); + //while( usb_controller_is_resetting() ); +} +*/ +/* +void usb_disable_endpoint(uint_fast8_t logical_endpoint_number) { + USB0_ENDPTCTRL(logical_endpoint_number) &= ~((1 << ) | (1 << )); +} + +void usb_disable_all_endpoints() { + // Endpoint 0 is always enabled. + for(uint_fast8_t i=1; i<6; i++) { + usb_disable_endpoint(i); + } +} + +void usb_clear_all_pending_interrupts() { + +} + +void usb_reset() { + usb_disable_all_endpoints(); + usb_clear_all_pending_interrupts(); +} +*/ +/* +void usb_clear_all_interrupts() { + USB0_USBSTS = + USB0_USBSTS_UI | + USB0_USBSTS_UEI | + USB0_USBSTS_PCI | + USB0_USBSTS_URI | + USB0_USBSTS_SRI | + USB0_USBSTS_SLI; +} +*/ +typedef struct { + uint32_t next_dtd_pointer; + uint32_t total_bytes; + uint32_t buffer_pointer_page[5]; +} usb0_endpoint_transfer_descriptor_t; + +typedef enum { + queue_head_capabilities_IOS_bit = 15, + queue_head_capabilities_IOS = 1 << queue_head_capabilities_IOS_bit, + + queue_head_capabilities_MPL_base = 16, + queue_head_capabilities_MPL_length = 11, + + queue_head_capabilities_ZLT_bit = 29, + queue_head_capabilities_ZLT = 1 << queue_head_capabilities_ZLT_bit, + + queue_head_capabilities_MULT_base = 30, + queue_head_capabilities_MULT_length = 2, +} queue_head_capabilities_t; + +typedef volatile struct { + volatile uint32_t capabilities; + volatile uint32_t current_dtd_pointer; + //volatile usb0_endpoint_transfer_descriptor_t; + volatile uint32_t next_dtd_pointer; + volatile uint32_t total_bytes; + volatile uint32_t buffer_pointer_page[5]; + volatile uint32_t _reserved_0; + volatile uint8_t setup[8]; + volatile uint32_t _reserved_1[4]; +} usb0_queue_head_t; + +volatile usb0_queue_head_t queue_head[12] ATTR_ALIGNED(2048) __DATA(USBRAM_SECTION); +volatile usb0_endpoint_transfer_descriptor_t transfer_descriptor[12] ATTR_ALIGNED(64) __DATA(USBRAM_SECTION); + +void usb_init() { + usb_enable_phy(); + usb_reset_controller(); + USB0_USBMODE_D = + (1 << USB0_USBMODE_D_SLOM_bit) | + (2 << USB0_USBMODE_D_CM_base); + + nvic_enable_irq(NVIC_M4_USB0_IRQ); + + // Set interrupt threshold interval to 0 + USB0_USBCMD_D &= ~(USB0_USBCMD_D_ITC_mask); + + USB0_ENDPOINTLISTADDR = (uint32_t)&queue_head; + for(uint_fast8_t i=0; i<2; i++) { + queue_head[i].next_dtd_pointer = (uint32_t)&transfer_descriptor[i]; + } + + // Enable interrupts + USB0_USBINTR_D = + USB0_USBINTR_D_UE | + USB0_USBINTR_D_UEE | + USB0_USBINTR_D_PCE | + USB0_USBINTR_D_URE | + USB0_USBINTR_D_SRE | + USB0_USBINTR_D_SLE | + USB0_USBINTR_D_NAKE; + + queue_head[0].capabilities = + queue_head_capabilities_ZLT | + (64 << queue_head_capabilities_MPL_base) | + queue_head_capabilities_IOS; +} + +void usb0_irqhandler(void) { + gpio_clear(PORT_LED1_3, PIN_LED1); + gpio_clear(PORT_LED1_3, PIN_LED2); + gpio_clear(PORT_LED1_3, PIN_LED3); +} int main(void) { - pin_setup(); enable_1v8_power(); cpu_clock_init(); @@ -13,9 +324,20 @@ int main(void) { CGU_BASE_APB1_CLK = (CGU_BASE_CLK_AUTOBLOCK | (CGU_SRC_PLL1 << CGU_BASE_CLK_SEL_SHIFT)); + + usb_reset_peripheral(); + + gpio_set(PORT_LED1_3, PIN_LED1); + gpio_set(PORT_LED1_3, PIN_LED2); + gpio_set(PORT_LED1_3, PIN_LED3); + + usb_init(); while (1) { - + delay(10000000); + gpio_clear(PORT_LED1_3, PIN_LED1); + delay(10000000); + gpio_set(PORT_LED1_3, PIN_LED1); } return 0;