From 72ee83eda93f6e6594ae56cdde3f2f65be8a1384 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 31 Jul 2012 21:38:57 -0700 Subject: [PATCH 01/41] Moving gpio_setup() / pin_setup() functions in separate projects to hackrf_core.h/c. Moved enable_1v8_power() and release_cpld_jtag_pins() to hackrf_core.h/c. --- firmware/blinky/blinky.c | 33 +----------- firmware/blinky_rom_to_ram/blinky.c | 33 +----------- firmware/common/hackrf_core.c | 52 +++++++++++++++++++ firmware/common/hackrf_core.h | 6 +++ firmware/mixertx/mixertx.c | 26 ---------- firmware/sgpio-rx/sgpio-rx.c | 46 ---------------- firmware/sgpio/sgpio.c | 46 ---------------- .../sgpio_passthrough.c | 46 ---------------- firmware/simpletx/simpletx.c | 26 ---------- firmware/startup/startup.c | 28 +--------- firmware/startup_systick/startup_systick.c | 28 +--------- .../startup_systick_perfo/startup_systick.c | 28 +--------- .../startup_systick.c | 28 +--------- 13 files changed, 64 insertions(+), 362 deletions(-) diff --git a/firmware/blinky/blinky.c b/firmware/blinky/blinky.c index 8842ff9d..2c0c0011 100644 --- a/firmware/blinky/blinky.c +++ b/firmware/blinky/blinky.c @@ -24,43 +24,12 @@ #include "hackrf_core.h" -void gpio_setup(void) -{ - /* Configure SCU Pin Mux as GPIO */ - scu_pinmux(SCU_PINMUX_LED1, SCU_GPIO_FAST); - scu_pinmux(SCU_PINMUX_LED2, SCU_GPIO_FAST); - scu_pinmux(SCU_PINMUX_LED3, SCU_GPIO_FAST); - - scu_pinmux(SCU_PINMUX_EN1V8, SCU_GPIO_FAST); - - scu_pinmux(SCU_PINMUX_BOOT0, SCU_GPIO_FAST); - scu_pinmux(SCU_PINMUX_BOOT1, SCU_GPIO_FAST); - scu_pinmux(SCU_PINMUX_BOOT2, SCU_GPIO_FAST); - scu_pinmux(SCU_PINMUX_BOOT3, SCU_GPIO_FAST); - - /* Configure all GPIO as Input (safe state) */ - GPIO0_DIR = 0; - GPIO1_DIR = 0; - GPIO2_DIR = 0; - GPIO3_DIR = 0; - GPIO4_DIR = 0; - GPIO5_DIR = 0; - GPIO6_DIR = 0; - GPIO7_DIR = 0; - - /* Configure GPIO2[1/2/8] (P4_1/2 P6_12) as output. */ - GPIO2_DIR |= (PIN_LED1|PIN_LED2|PIN_LED3); - - /* GPIO3[6] on P6_10 as output. */ - GPIO3_DIR |= PIN_EN1V8; -} - u32 boot0, boot1, boot2, boot3; int main(void) { int i; - gpio_setup(); + pin_setup(); /* Set 1V8 */ gpio_set(PORT_EN1V8, PIN_EN1V8); diff --git a/firmware/blinky_rom_to_ram/blinky.c b/firmware/blinky_rom_to_ram/blinky.c index 8842ff9d..2c0c0011 100644 --- a/firmware/blinky_rom_to_ram/blinky.c +++ b/firmware/blinky_rom_to_ram/blinky.c @@ -24,43 +24,12 @@ #include "hackrf_core.h" -void gpio_setup(void) -{ - /* Configure SCU Pin Mux as GPIO */ - scu_pinmux(SCU_PINMUX_LED1, SCU_GPIO_FAST); - scu_pinmux(SCU_PINMUX_LED2, SCU_GPIO_FAST); - scu_pinmux(SCU_PINMUX_LED3, SCU_GPIO_FAST); - - scu_pinmux(SCU_PINMUX_EN1V8, SCU_GPIO_FAST); - - scu_pinmux(SCU_PINMUX_BOOT0, SCU_GPIO_FAST); - scu_pinmux(SCU_PINMUX_BOOT1, SCU_GPIO_FAST); - scu_pinmux(SCU_PINMUX_BOOT2, SCU_GPIO_FAST); - scu_pinmux(SCU_PINMUX_BOOT3, SCU_GPIO_FAST); - - /* Configure all GPIO as Input (safe state) */ - GPIO0_DIR = 0; - GPIO1_DIR = 0; - GPIO2_DIR = 0; - GPIO3_DIR = 0; - GPIO4_DIR = 0; - GPIO5_DIR = 0; - GPIO6_DIR = 0; - GPIO7_DIR = 0; - - /* Configure GPIO2[1/2/8] (P4_1/2 P6_12) as output. */ - GPIO2_DIR |= (PIN_LED1|PIN_LED2|PIN_LED3); - - /* GPIO3[6] on P6_10 as output. */ - GPIO3_DIR |= PIN_EN1V8; -} - u32 boot0, boot1, boot2, boot3; int main(void) { int i; - gpio_setup(); + pin_setup(); /* Set 1V8 */ gpio_set(PORT_EN1V8, PIN_EN1V8); diff --git a/firmware/common/hackrf_core.c b/firmware/common/hackrf_core.c index 67b673a0..aa45816f 100644 --- a/firmware/common/hackrf_core.c +++ b/firmware/common/hackrf_core.c @@ -204,4 +204,56 @@ void ssp1_set_mode_max5864(void) SSP_SLAVE_OUT_ENABLE); } +void pin_setup(void) { + /* Configure SCU Pin Mux as GPIO */ + scu_pinmux(SCU_PINMUX_LED1, SCU_GPIO_FAST); + scu_pinmux(SCU_PINMUX_LED2, SCU_GPIO_FAST); + scu_pinmux(SCU_PINMUX_LED3, SCU_GPIO_FAST); + + scu_pinmux(SCU_PINMUX_EN1V8, SCU_GPIO_FAST); + + scu_pinmux(SCU_PINMUX_BOOT0, SCU_GPIO_FAST); + scu_pinmux(SCU_PINMUX_BOOT1, SCU_GPIO_FAST); + scu_pinmux(SCU_PINMUX_BOOT2, SCU_GPIO_FAST); + scu_pinmux(SCU_PINMUX_BOOT3, SCU_GPIO_FAST); + + /* Configure all GPIO as Input (safe state) */ + GPIO0_DIR = 0; + GPIO1_DIR = 0; + GPIO2_DIR = 0; + GPIO3_DIR = 0; + GPIO4_DIR = 0; + GPIO5_DIR = 0; + GPIO6_DIR = 0; + GPIO7_DIR = 0; + + /* Configure GPIO2[1/2/8] (P4_1/2 P6_12) as output. */ + GPIO2_DIR |= (PIN_LED1 | PIN_LED2 | PIN_LED3); + + /* GPIO3[6] on P6_10 as output. */ + GPIO3_DIR |= PIN_EN1V8; + + /* Configure SSP1 Peripheral (to be moved later in SSP driver) */ + scu_pinmux(SCU_SSP1_MISO, (SCU_SSP_IO | SCU_CONF_FUNCTION5)); + scu_pinmux(SCU_SSP1_MOSI, (SCU_SSP_IO | SCU_CONF_FUNCTION5)); + scu_pinmux(SCU_SSP1_SCK, (SCU_SSP_IO | SCU_CONF_FUNCTION1)); + scu_pinmux(SCU_SSP1_SSEL, (SCU_SSP_IO | SCU_CONF_FUNCTION1)); +} + +void enable_1v8_power(void) { + gpio_set(PORT_EN1V8, PIN_EN1V8); +} + +void release_cpld_jtag_pins(void) { + scu_pinmux(SCU_PINMUX_CPLD_TDO, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION4); + scu_pinmux(SCU_PINMUX_CPLD_TCK, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION0); + scu_pinmux(SCU_PINMUX_CPLD_TMS, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION0); + scu_pinmux(SCU_PINMUX_CPLD_TDI, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION0); + + GPIO_DIR(PORT_CPLD_TDO) &= ~PIN_CPLD_TDO; + GPIO_DIR(PORT_CPLD_TCK) &= ~PIN_CPLD_TCK; + GPIO_DIR(PORT_CPLD_TMS) &= ~PIN_CPLD_TMS; + GPIO_DIR(PORT_CPLD_TDI) &= ~PIN_CPLD_TDI; +} + #endif diff --git a/firmware/common/hackrf_core.h b/firmware/common/hackrf_core.h index 8121ff71..85aa2c11 100644 --- a/firmware/common/hackrf_core.h +++ b/firmware/common/hackrf_core.h @@ -159,6 +159,12 @@ void ssp1_init(void); void ssp1_set_mode_max2837(void); void ssp1_set_mode_max5864(void); +void pin_setup(void); + +void release_cpld_jtag_pins(void); + +void enable_1v8_power(void); + #ifdef __cplusplus } #endif diff --git a/firmware/mixertx/mixertx.c b/firmware/mixertx/mixertx.c index ea41bb21..6d5152bb 100644 --- a/firmware/mixertx/mixertx.c +++ b/firmware/mixertx/mixertx.c @@ -28,32 +28,6 @@ #include "max2837.h" #include "rffc5071.h" -void pin_setup(void) -{ - /* Configure SCU Pin Mux as GPIO */ - scu_pinmux(SCU_PINMUX_LED1, SCU_GPIO_FAST); - scu_pinmux(SCU_PINMUX_LED2, SCU_GPIO_FAST); - scu_pinmux(SCU_PINMUX_LED3, SCU_GPIO_FAST); - - scu_pinmux(SCU_PINMUX_EN1V8, SCU_GPIO_FAST); - - /* Configure all GPIO as Input (safe state) */ - GPIO0_DIR = 0; - GPIO1_DIR = 0; - GPIO2_DIR = 0; - GPIO3_DIR = 0; - GPIO4_DIR = 0; - GPIO5_DIR = 0; - GPIO6_DIR = 0; - GPIO7_DIR = 0; - - /* Configure GPIO2[1/2/8] (P4_1/2 P6_12) as output. */ - GPIO2_DIR |= (PIN_LED1|PIN_LED2|PIN_LED3); - - /* GPIO3[6] on P6_10 as output. */ - GPIO3_DIR |= PIN_EN1V8; -} - int main(void) { const uint32_t freq = 2441000000U; diff --git a/firmware/sgpio-rx/sgpio-rx.c b/firmware/sgpio-rx/sgpio-rx.c index c2e00ee3..c3dff963 100644 --- a/firmware/sgpio-rx/sgpio-rx.c +++ b/firmware/sgpio-rx/sgpio-rx.c @@ -30,52 +30,6 @@ #include #include -void pin_setup(void) { - /* Configure SCU Pin Mux as GPIO */ - scu_pinmux(SCU_PINMUX_LED1, SCU_GPIO_FAST); - scu_pinmux(SCU_PINMUX_LED2, SCU_GPIO_FAST); - scu_pinmux(SCU_PINMUX_LED3, SCU_GPIO_FAST); - - scu_pinmux(SCU_PINMUX_EN1V8, SCU_GPIO_FAST); - - /* Configure all GPIO as Input (safe state) */GPIO0_DIR = 0; - GPIO1_DIR = 0; - GPIO2_DIR = 0; - GPIO3_DIR = 0; - GPIO4_DIR = 0; - GPIO5_DIR = 0; - GPIO6_DIR = 0; - GPIO7_DIR = 0; - - /* Configure GPIO2[1/2/8] (P4_1/2 P6_12) as output. */ - GPIO2_DIR |= (PIN_LED1 | PIN_LED2 | PIN_LED3); - - /* GPIO3[6] on P6_10 as output. */ - GPIO3_DIR |= PIN_EN1V8; - - /* Configure SSP1 Peripheral (to be moved later in SSP driver) */ - scu_pinmux(SCU_SSP1_MISO, (SCU_SSP_IO | SCU_CONF_FUNCTION5)); - scu_pinmux(SCU_SSP1_MOSI, (SCU_SSP_IO | SCU_CONF_FUNCTION5)); - scu_pinmux(SCU_SSP1_SCK, (SCU_SSP_IO | SCU_CONF_FUNCTION1)); - scu_pinmux(SCU_SSP1_SSEL, (SCU_SSP_IO | SCU_CONF_FUNCTION1)); -} - -void enable_1v8_power() { - gpio_set(PORT_EN1V8, PIN_EN1V8); -} - -void release_cpld_jtag_pins() { - scu_pinmux(SCU_PINMUX_CPLD_TDO, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION4); - scu_pinmux(SCU_PINMUX_CPLD_TCK, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION0); - scu_pinmux(SCU_PINMUX_CPLD_TMS, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION0); - scu_pinmux(SCU_PINMUX_CPLD_TDI, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION0); - - GPIO_DIR(PORT_CPLD_TDO) &= ~PIN_CPLD_TDO; - GPIO_DIR(PORT_CPLD_TCK) &= ~PIN_CPLD_TCK; - GPIO_DIR(PORT_CPLD_TMS) &= ~PIN_CPLD_TMS; - GPIO_DIR(PORT_CPLD_TDI) &= ~PIN_CPLD_TDI; -} - void configure_sgpio_pin_functions() { scu_pinmux(SCU_PINMUX_SGPIO0, SCU_GPIO_FAST | SCU_CONF_FUNCTION3); scu_pinmux(SCU_PINMUX_SGPIO1, SCU_GPIO_FAST | SCU_CONF_FUNCTION3); diff --git a/firmware/sgpio/sgpio.c b/firmware/sgpio/sgpio.c index cc200142..2df82c05 100644 --- a/firmware/sgpio/sgpio.c +++ b/firmware/sgpio/sgpio.c @@ -29,52 +29,6 @@ #include #include -void pin_setup(void) { - /* Configure SCU Pin Mux as GPIO */ - scu_pinmux(SCU_PINMUX_LED1, SCU_GPIO_FAST); - scu_pinmux(SCU_PINMUX_LED2, SCU_GPIO_FAST); - scu_pinmux(SCU_PINMUX_LED3, SCU_GPIO_FAST); - - scu_pinmux(SCU_PINMUX_EN1V8, SCU_GPIO_FAST); - - /* Configure all GPIO as Input (safe state) */GPIO0_DIR = 0; - GPIO1_DIR = 0; - GPIO2_DIR = 0; - GPIO3_DIR = 0; - GPIO4_DIR = 0; - GPIO5_DIR = 0; - GPIO6_DIR = 0; - GPIO7_DIR = 0; - - /* Configure GPIO2[1/2/8] (P4_1/2 P6_12) as output. */ - GPIO2_DIR |= (PIN_LED1 | PIN_LED2 | PIN_LED3); - - /* GPIO3[6] on P6_10 as output. */ - GPIO3_DIR |= PIN_EN1V8; - - /* Configure SSP1 Peripheral (to be moved later in SSP driver) */ - scu_pinmux(SCU_SSP1_MISO, (SCU_SSP_IO | SCU_CONF_FUNCTION5)); - scu_pinmux(SCU_SSP1_MOSI, (SCU_SSP_IO | SCU_CONF_FUNCTION5)); - scu_pinmux(SCU_SSP1_SCK, (SCU_SSP_IO | SCU_CONF_FUNCTION1)); - scu_pinmux(SCU_SSP1_SSEL, (SCU_SSP_IO | SCU_CONF_FUNCTION1)); -} - -void enable_1v8_power() { - gpio_set(PORT_EN1V8, PIN_EN1V8); -} - -void release_cpld_jtag_pins() { - scu_pinmux(SCU_PINMUX_CPLD_TDO, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION4); - scu_pinmux(SCU_PINMUX_CPLD_TCK, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION0); - scu_pinmux(SCU_PINMUX_CPLD_TMS, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION0); - scu_pinmux(SCU_PINMUX_CPLD_TDI, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION0); - - GPIO_DIR(PORT_CPLD_TDO) &= ~PIN_CPLD_TDO; - GPIO_DIR(PORT_CPLD_TCK) &= ~PIN_CPLD_TCK; - GPIO_DIR(PORT_CPLD_TMS) &= ~PIN_CPLD_TMS; - GPIO_DIR(PORT_CPLD_TDI) &= ~PIN_CPLD_TDI; -} - void configure_sgpio_pin_functions() { scu_pinmux(SCU_PINMUX_SGPIO0, SCU_GPIO_FAST | SCU_CONF_FUNCTION3); scu_pinmux(SCU_PINMUX_SGPIO1, SCU_GPIO_FAST | SCU_CONF_FUNCTION3); diff --git a/firmware/sgpio_passthrough_rom_to_ram/sgpio_passthrough.c b/firmware/sgpio_passthrough_rom_to_ram/sgpio_passthrough.c index c5525c57..afdf8a25 100644 --- a/firmware/sgpio_passthrough_rom_to_ram/sgpio_passthrough.c +++ b/firmware/sgpio_passthrough_rom_to_ram/sgpio_passthrough.c @@ -29,52 +29,6 @@ #include -void pin_setup(void) { - /* Configure SCU Pin Mux as GPIO */ - scu_pinmux(SCU_PINMUX_LED1, SCU_GPIO_FAST); - scu_pinmux(SCU_PINMUX_LED2, SCU_GPIO_FAST); - scu_pinmux(SCU_PINMUX_LED3, SCU_GPIO_FAST); - - scu_pinmux(SCU_PINMUX_EN1V8, SCU_GPIO_FAST); - - /* Configure all GPIO as Input (safe state) */GPIO0_DIR = 0; - GPIO1_DIR = 0; - GPIO2_DIR = 0; - GPIO3_DIR = 0; - GPIO4_DIR = 0; - GPIO5_DIR = 0; - GPIO6_DIR = 0; - GPIO7_DIR = 0; - - /* Configure GPIO2[1/2/8] (P4_1/2 P6_12) as output. */ - GPIO2_DIR |= (PIN_LED1 | PIN_LED2 | PIN_LED3); - - /* GPIO3[6] on P6_10 as output. */ - GPIO3_DIR |= PIN_EN1V8; - - /* Configure SSP1 Peripheral (to be moved later in SSP driver) */ - scu_pinmux(SCU_SSP1_MISO, (SCU_SSP_IO | SCU_CONF_FUNCTION5)); - scu_pinmux(SCU_SSP1_MOSI, (SCU_SSP_IO | SCU_CONF_FUNCTION5)); - scu_pinmux(SCU_SSP1_SCK, (SCU_SSP_IO | SCU_CONF_FUNCTION1)); - scu_pinmux(SCU_SSP1_SSEL, (SCU_SSP_IO | SCU_CONF_FUNCTION1)); -} - -void enable_1v8_power() { - gpio_set(PORT_EN1V8, PIN_EN1V8); -} - -void release_cpld_jtag_pins() { - scu_pinmux(SCU_PINMUX_CPLD_TDO, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION4); - scu_pinmux(SCU_PINMUX_CPLD_TCK, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION0); - scu_pinmux(SCU_PINMUX_CPLD_TMS, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION0); - scu_pinmux(SCU_PINMUX_CPLD_TDI, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION0); - - GPIO_DIR(PORT_CPLD_TDO) &= ~PIN_CPLD_TDO; - GPIO_DIR(PORT_CPLD_TCK) &= ~PIN_CPLD_TCK; - GPIO_DIR(PORT_CPLD_TMS) &= ~PIN_CPLD_TMS; - GPIO_DIR(PORT_CPLD_TDI) &= ~PIN_CPLD_TDI; -} - void configure_sgpio_pin_functions() { scu_pinmux(SCU_PINMUX_SGPIO0, SCU_GPIO_FAST | SCU_CONF_FUNCTION3); scu_pinmux(SCU_PINMUX_SGPIO1, SCU_GPIO_FAST | SCU_CONF_FUNCTION3); diff --git a/firmware/simpletx/simpletx.c b/firmware/simpletx/simpletx.c index 7d61cb6a..e50fbf54 100644 --- a/firmware/simpletx/simpletx.c +++ b/firmware/simpletx/simpletx.c @@ -27,32 +27,6 @@ #include "hackrf_core.h" #include "max2837.h" -void pin_setup(void) -{ - /* Configure SCU Pin Mux as GPIO */ - scu_pinmux(SCU_PINMUX_LED1, SCU_GPIO_FAST); - scu_pinmux(SCU_PINMUX_LED2, SCU_GPIO_FAST); - scu_pinmux(SCU_PINMUX_LED3, SCU_GPIO_FAST); - - scu_pinmux(SCU_PINMUX_EN1V8, SCU_GPIO_FAST); - - /* Configure all GPIO as Input (safe state) */ - GPIO0_DIR = 0; - GPIO1_DIR = 0; - GPIO2_DIR = 0; - GPIO3_DIR = 0; - GPIO4_DIR = 0; - GPIO5_DIR = 0; - GPIO6_DIR = 0; - GPIO7_DIR = 0; - - /* Configure GPIO2[1/2/8] (P4_1/2 P6_12) as output. */ - GPIO2_DIR |= (PIN_LED1|PIN_LED2|PIN_LED3); - - /* GPIO3[6] on P6_10 as output. */ - GPIO3_DIR |= PIN_EN1V8; -} - int main(void) { const uint32_t freq = 2441000000U; diff --git a/firmware/startup/startup.c b/firmware/startup/startup.c index 912ef38a..b805d1f2 100644 --- a/firmware/startup/startup.c +++ b/firmware/startup/startup.c @@ -25,37 +25,11 @@ #include "hackrf_core.h" -void gpio_setup(void) -{ - /* Configure SCU Pin Mux as GPIO */ - scu_pinmux(SCU_PINMUX_LED1, SCU_GPIO_FAST); - scu_pinmux(SCU_PINMUX_LED2, SCU_GPIO_FAST); - scu_pinmux(SCU_PINMUX_LED3, SCU_GPIO_FAST); - - scu_pinmux(SCU_PINMUX_EN1V8, SCU_GPIO_FAST); - - /* Configure all GPIO as Input (safe state) */ - GPIO0_DIR = 0; - GPIO1_DIR = 0; - GPIO2_DIR = 0; - GPIO3_DIR = 0; - GPIO4_DIR = 0; - GPIO5_DIR = 0; - GPIO6_DIR = 0; - GPIO7_DIR = 0; - - /* Configure GPIO2[1/2/8] (P4_1/2 P6_12) as output. */ - GPIO2_DIR |= (PIN_LED1|PIN_LED2|PIN_LED3); - - /* GPIO3[6] on P6_10 as output. */ - GPIO3_DIR |= PIN_EN1V8; -} - int main(void) { u32 i; - gpio_setup(); + pin_setup(); gpio_set(PORT_EN1V8, PIN_EN1V8); /* 1V8 on */ diff --git a/firmware/startup_systick/startup_systick.c b/firmware/startup_systick/startup_systick.c index c7c3e01e..98b4d5b3 100644 --- a/firmware/startup_systick/startup_systick.c +++ b/firmware/startup_systick/startup_systick.c @@ -32,32 +32,6 @@ volatile u32 g_ulSysTickCount; u32 g_NbCyclePerSecond; -void gpio_setup(void) -{ - /* Configure SCU Pin Mux as GPIO */ - scu_pinmux(SCU_PINMUX_LED1, SCU_GPIO_FAST); - scu_pinmux(SCU_PINMUX_LED2, SCU_GPIO_FAST); - scu_pinmux(SCU_PINMUX_LED3, SCU_GPIO_FAST); - - scu_pinmux(SCU_PINMUX_EN1V8, SCU_GPIO_FAST); - - /* Configure all GPIO as Input (safe state) */ - GPIO0_DIR = 0; - GPIO1_DIR = 0; - GPIO2_DIR = 0; - GPIO3_DIR = 0; - GPIO4_DIR = 0; - GPIO5_DIR = 0; - GPIO6_DIR = 0; - GPIO7_DIR = 0; - - /* Configure GPIO2[1/2/8] (P4_1/2 P6_12) as output. */ - GPIO2_DIR |= (PIN_LED1|PIN_LED2|PIN_LED3); - - /* GPIO3[6] on P6_10 as output. */ - GPIO3_DIR |= PIN_EN1V8; -} - void systick_setup(void) { u32 systick_reload_val; @@ -155,7 +129,7 @@ void sys_tick_handler(void) int main(void) { - gpio_setup(); + pin_setup(); gpio_set(PORT_EN1V8, PIN_EN1V8); /* 1V8 on */ diff --git a/firmware/startup_systick_perfo/startup_systick.c b/firmware/startup_systick_perfo/startup_systick.c index a8be4b05..a5bae126 100644 --- a/firmware/startup_systick_perfo/startup_systick.c +++ b/firmware/startup_systick_perfo/startup_systick.c @@ -32,32 +32,6 @@ volatile u32 g_ulSysTickCount; u32 g_NbCyclePerSecond; -void gpio_setup(void) -{ - /* Configure SCU Pin Mux as GPIO */ - scu_pinmux(SCU_PINMUX_LED1, SCU_GPIO_FAST); - scu_pinmux(SCU_PINMUX_LED2, SCU_GPIO_FAST); - scu_pinmux(SCU_PINMUX_LED3, SCU_GPIO_FAST); - - scu_pinmux(SCU_PINMUX_EN1V8, SCU_GPIO_FAST); - - /* Configure all GPIO as Input (safe state) */ - GPIO0_DIR = 0; - GPIO1_DIR = 0; - GPIO2_DIR = 0; - GPIO3_DIR = 0; - GPIO4_DIR = 0; - GPIO5_DIR = 0; - GPIO6_DIR = 0; - GPIO7_DIR = 0; - - /* Configure GPIO2[1/2/8] (P4_1/2 P6_12) as output. */ - GPIO2_DIR |= (PIN_LED1|PIN_LED2|PIN_LED3); - - /* GPIO3[6] on P6_10 as output. */ - GPIO3_DIR |= PIN_EN1V8; -} - void systick_setup(void) { u32 systick_reload_val; @@ -168,7 +142,7 @@ extern u32 test_nb_instruction_per_sec_1000_nop_asm(); int main(void) { - gpio_setup(); + pin_setup(); gpio_set(PORT_EN1V8, PIN_EN1V8); /* 1V8 on */ diff --git a/firmware/startup_systick_perfo_rom_to_ram/startup_systick.c b/firmware/startup_systick_perfo_rom_to_ram/startup_systick.c index a8be4b05..a5bae126 100644 --- a/firmware/startup_systick_perfo_rom_to_ram/startup_systick.c +++ b/firmware/startup_systick_perfo_rom_to_ram/startup_systick.c @@ -32,32 +32,6 @@ volatile u32 g_ulSysTickCount; u32 g_NbCyclePerSecond; -void gpio_setup(void) -{ - /* Configure SCU Pin Mux as GPIO */ - scu_pinmux(SCU_PINMUX_LED1, SCU_GPIO_FAST); - scu_pinmux(SCU_PINMUX_LED2, SCU_GPIO_FAST); - scu_pinmux(SCU_PINMUX_LED3, SCU_GPIO_FAST); - - scu_pinmux(SCU_PINMUX_EN1V8, SCU_GPIO_FAST); - - /* Configure all GPIO as Input (safe state) */ - GPIO0_DIR = 0; - GPIO1_DIR = 0; - GPIO2_DIR = 0; - GPIO3_DIR = 0; - GPIO4_DIR = 0; - GPIO5_DIR = 0; - GPIO6_DIR = 0; - GPIO7_DIR = 0; - - /* Configure GPIO2[1/2/8] (P4_1/2 P6_12) as output. */ - GPIO2_DIR |= (PIN_LED1|PIN_LED2|PIN_LED3); - - /* GPIO3[6] on P6_10 as output. */ - GPIO3_DIR |= PIN_EN1V8; -} - void systick_setup(void) { u32 systick_reload_val; @@ -168,7 +142,7 @@ extern u32 test_nb_instruction_per_sec_1000_nop_asm(); int main(void) { - gpio_setup(); + pin_setup(); gpio_set(PORT_EN1V8, PIN_EN1V8); /* 1V8 on */ From 79d352f17fba6c077dea26e4a0cb111c263b0a6b Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 31 Jul 2012 21:39:43 -0700 Subject: [PATCH 02/41] Fixed Makefile breakage in blinky and blinky_rom_to_ram. --- firmware/blinky/Makefile | 4 +++- firmware/blinky_rom_to_ram/Makefile | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/firmware/blinky/Makefile b/firmware/blinky/Makefile index 96e5a9ba..4d1aac31 100644 --- a/firmware/blinky/Makefile +++ b/firmware/blinky/Makefile @@ -2,6 +2,8 @@ BINARY = blinky -SRC = $(BINARY).c +SRC = $(BINARY).c \ + ../common/hackrf_core.c \ + ../common/si5351c.c include ../common/Makefile_inc.mk diff --git a/firmware/blinky_rom_to_ram/Makefile b/firmware/blinky_rom_to_ram/Makefile index 936e0348..d4f487b8 100644 --- a/firmware/blinky_rom_to_ram/Makefile +++ b/firmware/blinky_rom_to_ram/Makefile @@ -2,7 +2,9 @@ BINARY = blinky -SRC = $(BINARY).c +SRC = $(BINARY).c \ + ../common/hackrf_core.c \ + ../common/si5351c.c LDSCRIPT = ../common/LPC4330_M4_rom_to_ram.ld include ../common/Makefile_inc.mk From f0e4cffb8739aca3bd849c7214bbc11b967a483d Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 31 Jul 2012 22:03:01 -0700 Subject: [PATCH 03/41] Removed release_cpld_jtag_pins() and incorporated code into pin_setup(). --- firmware/common/hackrf_core.c | 23 +++++++++++------------ firmware/common/hackrf_core.h | 2 -- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/firmware/common/hackrf_core.c b/firmware/common/hackrf_core.c index aa45816f..5ec3921c 100644 --- a/firmware/common/hackrf_core.c +++ b/firmware/common/hackrf_core.c @@ -205,6 +205,17 @@ void ssp1_set_mode_max5864(void) } void pin_setup(void) { + /* Release CPLD JTAG pins */ + scu_pinmux(SCU_PINMUX_CPLD_TDO, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION4); + scu_pinmux(SCU_PINMUX_CPLD_TCK, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION0); + scu_pinmux(SCU_PINMUX_CPLD_TMS, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION0); + scu_pinmux(SCU_PINMUX_CPLD_TDI, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION0); + + GPIO_DIR(PORT_CPLD_TDO) &= ~PIN_CPLD_TDO; + GPIO_DIR(PORT_CPLD_TCK) &= ~PIN_CPLD_TCK; + GPIO_DIR(PORT_CPLD_TMS) &= ~PIN_CPLD_TMS; + GPIO_DIR(PORT_CPLD_TDI) &= ~PIN_CPLD_TDI; + /* Configure SCU Pin Mux as GPIO */ scu_pinmux(SCU_PINMUX_LED1, SCU_GPIO_FAST); scu_pinmux(SCU_PINMUX_LED2, SCU_GPIO_FAST); @@ -244,16 +255,4 @@ void enable_1v8_power(void) { gpio_set(PORT_EN1V8, PIN_EN1V8); } -void release_cpld_jtag_pins(void) { - scu_pinmux(SCU_PINMUX_CPLD_TDO, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION4); - scu_pinmux(SCU_PINMUX_CPLD_TCK, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION0); - scu_pinmux(SCU_PINMUX_CPLD_TMS, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION0); - scu_pinmux(SCU_PINMUX_CPLD_TDI, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION0); - - GPIO_DIR(PORT_CPLD_TDO) &= ~PIN_CPLD_TDO; - GPIO_DIR(PORT_CPLD_TCK) &= ~PIN_CPLD_TCK; - GPIO_DIR(PORT_CPLD_TMS) &= ~PIN_CPLD_TMS; - GPIO_DIR(PORT_CPLD_TDI) &= ~PIN_CPLD_TDI; -} - #endif diff --git a/firmware/common/hackrf_core.h b/firmware/common/hackrf_core.h index 85aa2c11..18575759 100644 --- a/firmware/common/hackrf_core.h +++ b/firmware/common/hackrf_core.h @@ -161,8 +161,6 @@ void ssp1_set_mode_max5864(void); void pin_setup(void); -void release_cpld_jtag_pins(void); - void enable_1v8_power(void); #ifdef __cplusplus From 33617e67011eebc3cfbf8f8470c19cde1ad65005 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 31 Jul 2012 22:03:58 -0700 Subject: [PATCH 04/41] Makefile for all firmware projects. TODO: There's still something broken about the *_rom_to_ram projects, but I'm not sure what it is yet... --- firmware/Makefile | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 firmware/Makefile diff --git a/firmware/Makefile b/firmware/Makefile new file mode 100644 index 00000000..9111dbd7 --- /dev/null +++ b/firmware/Makefile @@ -0,0 +1,38 @@ +# Hey Emacs, this is a -*- makefile -*- + +TARGETS = blinky \ + mixertx \ + sgpio \ + sgpio-rx \ + simpletx \ + startup \ + startup_systick \ + startup_systick_perfo \ + usb_performance + +# blinky_rom_to_ram +# sgpio_passthrough_rom_to_ram +# startup_systick_perfo_rom_to_ram + +all: build + +build: examples + +examples: + $(Q)for i in $(TARGETS); do \ + if [ -d $$i ]; then \ + printf " BUILD $$i\n"; \ + $(MAKE) -C $$i || exit $?; \ + fi; \ + done + +clean: + $(Q)for i in $(addprefix lib/,$(TARGETS)) \ + $(TARGETS); do \ + if [ -d $$i ]; then \ + printf " CLEAN $$i\n"; \ + $(MAKE) -C $$i clean || exit $?; \ + fi; \ + done + +.PHONY: build examples From 2a6e3a89d3d299c9f4a8501e55bc92c6801981a3 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 31 Jul 2012 22:05:28 -0700 Subject: [PATCH 05/41] USB performance test firmware project. It does absolutely nothing to start with, but at least the Makefile I just checked in won't blow up! :-) --- firmware/usb_performance/Makefile | 10 ++++++++++ firmware/usb_performance/usb_performance.c | 22 ++++++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 firmware/usb_performance/Makefile create mode 100644 firmware/usb_performance/usb_performance.c diff --git a/firmware/usb_performance/Makefile b/firmware/usb_performance/Makefile new file mode 100644 index 00000000..88f0f621 --- /dev/null +++ b/firmware/usb_performance/Makefile @@ -0,0 +1,10 @@ +# Hey Emacs, this is a -*- makefile -*- + +BINARY = usb_performance + +SRC = $(BINARY).c \ + ../common/hackrf_core.c \ + ../common/si5351c.c \ + ../common/bitband.c + +include ../common/Makefile_inc.mk diff --git a/firmware/usb_performance/usb_performance.c b/firmware/usb_performance/usb_performance.c new file mode 100644 index 00000000..d68b6dd0 --- /dev/null +++ b/firmware/usb_performance/usb_performance.c @@ -0,0 +1,22 @@ +#include + +#include + +int main(void) { + + pin_setup(); + enable_1v8_power(); + cpu_clock_init(); + + CGU_BASE_PERIPH_CLK = (CGU_BASE_CLK_AUTOBLOCK + | (CGU_SRC_PLL1 << CGU_BASE_CLK_SEL_SHIFT)); + + CGU_BASE_APB1_CLK = (CGU_BASE_CLK_AUTOBLOCK + | (CGU_SRC_PLL1 << CGU_BASE_CLK_SEL_SHIFT)); + + while (1) { + + } + + return 0; +} From 9f4f1d0b6ba917519e4a559298c62061cb422943 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 31 Jul 2012 22:07:08 -0700 Subject: [PATCH 06/41] Bitband library, factored out of other code. --- firmware/common/bitband.c | 45 +++++++++++++++++++++++++++++++++++++++ firmware/common/bitband.h | 32 ++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 firmware/common/bitband.c create mode 100644 firmware/common/bitband.h diff --git a/firmware/common/bitband.c b/firmware/common/bitband.c new file mode 100644 index 00000000..82ba5383 --- /dev/null +++ b/firmware/common/bitband.c @@ -0,0 +1,45 @@ +/* + * Copyright 2012 Jared Boone + * + * This file is part of HackRF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include "bitband.h" + +volatile uint_fast8_t* peripheral_bitband_address(volatile void* const address, const uint_fast8_t bit_number) { + const uint32_t bit_band_base = 0x42000000; + const uint32_t byte_offset = (uint32_t)address - 0x40000000; + const uint32_t bit_word_offset = (byte_offset * 32) + (bit_number * 4); + const uint32_t bit_word_address = bit_band_base + bit_word_offset; + return (volatile uint_fast8_t*)bit_word_address; +} + +void peripheral_bitband_set(volatile void* const peripheral_address, const uint_fast8_t bit_number) { + volatile uint_fast8_t* const bitband_address = peripheral_bitband_address(peripheral_address, bit_number); + *bitband_address = 1; +} + +void peripheral_bitband_clear(volatile void* const peripheral_address, const uint_fast8_t bit_number) { + volatile uint_fast8_t* const bitband_address = peripheral_bitband_address(peripheral_address, bit_number); + *bitband_address = 0; +} + +uint_fast8_t peripheral_bitband_get(volatile void* const peripheral_address, const uint_fast8_t bit_number) { + volatile uint_fast8_t* const bitband_address = peripheral_bitband_address(peripheral_address, bit_number); + return *bitband_address; +} diff --git a/firmware/common/bitband.h b/firmware/common/bitband.h new file mode 100644 index 00000000..20407b5d --- /dev/null +++ b/firmware/common/bitband.h @@ -0,0 +1,32 @@ +/* + * Copyright 2012 Jared Boone + * + * This file is part of HackRF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __BITBAND_H__ +#define __BITBAND_H__ + +#include + +volatile uint_fast8_t* peripheral_bitband_address(volatile void* const address, const uint_fast8_t bit_number); +void peripheral_bitband_set(volatile void* const peripheral_address, const uint_fast8_t bit_number); +void peripheral_bitband_clear(volatile void* const peripheral_address, const uint_fast8_t bit_number); +uint_fast8_t peripheral_bitband_get(volatile void* const peripheral_address, const uint_fast8_t bit_number); + +#endif//__BITBAND_H__ From f5d21b947bda3478530cdaa662407f95802a3925 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 11 Sep 2012 11:31:49 -0700 Subject: [PATCH 07/41] Changes to bit band API to make it more type-sane. --- firmware/common/bitband.c | 12 ++++++------ firmware/common/bitband.h | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/firmware/common/bitband.c b/firmware/common/bitband.c index 82ba5383..f55e806c 100644 --- a/firmware/common/bitband.c +++ b/firmware/common/bitband.c @@ -21,25 +21,25 @@ #include "bitband.h" -volatile uint_fast8_t* peripheral_bitband_address(volatile void* const address, const uint_fast8_t bit_number) { +volatile uint32_t* peripheral_bitband_address(volatile void* const address, const uint_fast8_t bit_number) { const uint32_t bit_band_base = 0x42000000; const uint32_t byte_offset = (uint32_t)address - 0x40000000; const uint32_t bit_word_offset = (byte_offset * 32) + (bit_number * 4); const uint32_t bit_word_address = bit_band_base + bit_word_offset; - return (volatile uint_fast8_t*)bit_word_address; + return (volatile uint32_t*)bit_word_address; } void peripheral_bitband_set(volatile void* const peripheral_address, const uint_fast8_t bit_number) { - volatile uint_fast8_t* const bitband_address = peripheral_bitband_address(peripheral_address, bit_number); + volatile uint32_t* const bitband_address = peripheral_bitband_address(peripheral_address, bit_number); *bitband_address = 1; } void peripheral_bitband_clear(volatile void* const peripheral_address, const uint_fast8_t bit_number) { - volatile uint_fast8_t* const bitband_address = peripheral_bitband_address(peripheral_address, bit_number); + volatile uint32_t* const bitband_address = peripheral_bitband_address(peripheral_address, bit_number); *bitband_address = 0; } -uint_fast8_t peripheral_bitband_get(volatile void* const peripheral_address, const uint_fast8_t bit_number) { - volatile uint_fast8_t* const bitband_address = peripheral_bitband_address(peripheral_address, bit_number); +uint32_t peripheral_bitband_get(volatile void* const peripheral_address, const uint_fast8_t bit_number) { + volatile uint32_t* const bitband_address = peripheral_bitband_address(peripheral_address, bit_number); return *bitband_address; } diff --git a/firmware/common/bitband.h b/firmware/common/bitband.h index 20407b5d..d62b4759 100644 --- a/firmware/common/bitband.h +++ b/firmware/common/bitband.h @@ -24,9 +24,9 @@ #include -volatile uint_fast8_t* peripheral_bitband_address(volatile void* const address, const uint_fast8_t bit_number); +volatile uint32_t* peripheral_bitband_address(volatile void* const address, const uint_fast8_t bit_number); void peripheral_bitband_set(volatile void* const peripheral_address, const uint_fast8_t bit_number); void peripheral_bitband_clear(volatile void* const peripheral_address, const uint_fast8_t bit_number); -uint_fast8_t peripheral_bitband_get(volatile void* const peripheral_address, const uint_fast8_t bit_number); +uint32_t peripheral_bitband_get(volatile void* const peripheral_address, const uint_fast8_t bit_number); #endif//__BITBAND_H__ From 7d942c86ac01f47f51c907aab850ec42d213128d Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 11 Sep 2012 11:32:20 -0700 Subject: [PATCH 08/41] Exposing the delay() core function. --- firmware/common/hackrf_core.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/firmware/common/hackrf_core.h b/firmware/common/hackrf_core.h index 18575759..c2e029d7 100644 --- a/firmware/common/hackrf_core.h +++ b/firmware/common/hackrf_core.h @@ -29,6 +29,8 @@ extern "C" { #endif +#include + /* hardware identification number */ #define BOARD_ID_JELLYBEAN 0 @@ -154,6 +156,8 @@ extern "C" /* TODO add other Pins */ #endif +void delay(uint32_t duration); + void cpu_clock_init(void); void ssp1_init(void); void ssp1_set_mode_max2837(void); From af1281fdbef1754c708664048096a13bb2e9ccc5 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 11 Sep 2012 11:33:07 -0700 Subject: [PATCH 09/41] LDScript for RAM-only operation. (That's how I like to roll -- load RAM over SWD and execute.) --- firmware/common/LPC4330_M4_ram_only.ld | 34 ++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 firmware/common/LPC4330_M4_ram_only.ld diff --git a/firmware/common/LPC4330_M4_ram_only.ld b/firmware/common/LPC4330_M4_ram_only.ld new file mode 100644 index 00000000..6fb4a2f8 --- /dev/null +++ b/firmware/common/LPC4330_M4_ram_only.ld @@ -0,0 +1,34 @@ +/* + * Copyright 2012 Michael Ossmann + * + * This file is part of HackRF + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +/* Linker script for HackRF Jellybean (LPC4330, 1M SPI flash, 264K SRAM). */ + +MEMORY +{ + /* rom is really the shadow region that points to SPI flash or elsewhere */ + rom (rx) : ORIGIN = 0x00000000, LENGTH = 128K + ram_local1 (rwx) : ORIGIN = 0x10000000, LENGTH = 128K + ram_local2 (rwx) : ORIGIN = 0x10080000, LENGTH = 72K + ram_ahb (rwx) : ORIGIN = 0x20000000, LENGTH = 64K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_lpc43xx_ram_only.ld From ddd379680386a9b18e7aaf52864ef6faece18c70 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 11 Sep 2012 11:33:26 -0700 Subject: [PATCH 10/41] Makefile change to use RAM-only LDScript. --- firmware/usb_performance/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/firmware/usb_performance/Makefile b/firmware/usb_performance/Makefile index 88f0f621..403ea76a 100644 --- a/firmware/usb_performance/Makefile +++ b/firmware/usb_performance/Makefile @@ -7,4 +7,5 @@ SRC = $(BINARY).c \ ../common/si5351c.c \ ../common/bitband.c +LDSCRIPT = ../common/LPC4330_M4_ram_only.ld include ../common/Makefile_inc.mk From c662309489fe0831db0b2e0bff954325f6a77b9e Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Tue, 11 Sep 2012 11:36:30 -0700 Subject: [PATCH 11/41] 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; From 416cdc6b20f2f1629167ded11390e04aebe9537f Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 27 Sep 2012 16:26:47 -0700 Subject: [PATCH 12/41] Added missing hackrf_core pin_setup() and enable_1v8_power(), which have somehow gone missing. --- firmware/common/hackrf_core.c | 51 +++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/firmware/common/hackrf_core.c b/firmware/common/hackrf_core.c index 88accc11..2f99d7fd 100644 --- a/firmware/common/hackrf_core.c +++ b/firmware/common/hackrf_core.c @@ -254,3 +254,54 @@ void ssp1_set_mode_max5864(void) SSP_MASTER, SSP_SLAVE_OUT_ENABLE); } + +void pin_setup(void) { + /* Release CPLD JTAG pins */ + scu_pinmux(SCU_PINMUX_CPLD_TDO, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION4); + scu_pinmux(SCU_PINMUX_CPLD_TCK, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION0); + scu_pinmux(SCU_PINMUX_CPLD_TMS, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION0); + scu_pinmux(SCU_PINMUX_CPLD_TDI, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION0); + + GPIO_DIR(PORT_CPLD_TDO) &= ~PIN_CPLD_TDO; + GPIO_DIR(PORT_CPLD_TCK) &= ~PIN_CPLD_TCK; + GPIO_DIR(PORT_CPLD_TMS) &= ~PIN_CPLD_TMS; + GPIO_DIR(PORT_CPLD_TDI) &= ~PIN_CPLD_TDI; + + /* Configure SCU Pin Mux as GPIO */ + scu_pinmux(SCU_PINMUX_LED1, SCU_GPIO_FAST); + scu_pinmux(SCU_PINMUX_LED2, SCU_GPIO_FAST); + scu_pinmux(SCU_PINMUX_LED3, SCU_GPIO_FAST); + + scu_pinmux(SCU_PINMUX_EN1V8, SCU_GPIO_FAST); + + scu_pinmux(SCU_PINMUX_BOOT0, SCU_GPIO_FAST); + scu_pinmux(SCU_PINMUX_BOOT1, SCU_GPIO_FAST); + scu_pinmux(SCU_PINMUX_BOOT2, SCU_GPIO_FAST); + scu_pinmux(SCU_PINMUX_BOOT3, SCU_GPIO_FAST); + + /* Configure all GPIO as Input (safe state) */ + GPIO0_DIR = 0; + GPIO1_DIR = 0; + GPIO2_DIR = 0; + GPIO3_DIR = 0; + GPIO4_DIR = 0; + GPIO5_DIR = 0; + GPIO6_DIR = 0; + GPIO7_DIR = 0; + + /* Configure GPIO2[1/2/8] (P4_1/2 P6_12) as output. */ + GPIO2_DIR |= (PIN_LED1 | PIN_LED2 | PIN_LED3); + + /* GPIO3[6] on P6_10 as output. */ + GPIO3_DIR |= PIN_EN1V8; + + /* Configure SSP1 Peripheral (to be moved later in SSP driver) */ + scu_pinmux(SCU_SSP1_MISO, (SCU_SSP_IO | SCU_CONF_FUNCTION5)); + scu_pinmux(SCU_SSP1_MOSI, (SCU_SSP_IO | SCU_CONF_FUNCTION5)); + scu_pinmux(SCU_SSP1_SCK, (SCU_SSP_IO | SCU_CONF_FUNCTION1)); + scu_pinmux(SCU_SSP1_SSEL, (SCU_SSP_IO | SCU_CONF_FUNCTION1)); +} + +void enable_1v8_power(void) { + gpio_set(PORT_EN1V8, PIN_EN1V8); +} From cbd42cf9701688f201db5459c33c788bebef0cca Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 27 Sep 2012 17:04:14 -0700 Subject: [PATCH 13/41] Adjustments for new auto-generated #defines. --- firmware/usb_performance/usb_performance.c | 167 ++------------------- 1 file changed, 12 insertions(+), 155 deletions(-) diff --git a/firmware/usb_performance/usb_performance.c b/firmware/usb_performance/usb_performance.c index b46edeb5..cb4f172d 100644 --- a/firmware/usb_performance/usb_performance.c +++ b/firmware/usb_performance/usb_performance.c @@ -15,159 +15,16 @@ #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 = RESET_CTRL0_USB0_RST; RESET_CTRL0 = 0; - while( (RESET_ACTIVE_STATUS0 & (1 << RESET_CTRL0_USB0_RST_bit)) == 0 ); + while( (RESET_ACTIVE_STATUS0 & RESET_CTRL0_USB0_RST) == 0 ); } void usb_enable_phy() { - peripheral_bitband_clear(&CREG_CREG0, CREG_CREG0_USB0PHY_bit); + peripheral_bitband_clear(&CREG_CREG0, CREG_CREG0_USB0PHY_SHIFT); } void usb_wait_for_endpoint_priming_to_finish() { @@ -185,11 +42,11 @@ void usb_flush_all_primed_endpoints() { } void usb_stop_controller() { - peripheral_bitband_clear(&USB0_USBCMD_D, USB0_USBCMD_D_RS_bit); + peripheral_bitband_clear(&USB0_USBCMD_D, USB0_USBCMD_D_RS_SHIFT); } void usb_run_controller() { - peripheral_bitband_set(&USB0_USBCMD_D, USB0_USBCMD_D_RS_bit); + peripheral_bitband_set(&USB0_USBCMD_D, USB0_USBCMD_D_RS_SHIFT); } uint_fast8_t usb_controller_is_resetting() { @@ -279,13 +136,13 @@ void usb_init() { usb_enable_phy(); usb_reset_controller(); USB0_USBMODE_D = - (1 << USB0_USBMODE_D_SLOM_bit) | - (2 << USB0_USBMODE_D_CM_base); + USB0_USBMODE_D_SLOM | + USB0_USBMODE_D_CM1_0(2); nvic_enable_irq(NVIC_M4_USB0_IRQ); // Set interrupt threshold interval to 0 - USB0_USBCMD_D &= ~(USB0_USBCMD_D_ITC_mask); + USB0_USBCMD_D &= ~(USB0_USBCMD_D_ITC_MASK); USB0_ENDPOINTLISTADDR = (uint32_t)&queue_head; for(uint_fast8_t i=0; i<2; i++) { @@ -319,11 +176,11 @@ int main(void) { enable_1v8_power(); cpu_clock_init(); - CGU_BASE_PERIPH_CLK = (CGU_BASE_CLK_AUTOBLOCK - | (CGU_SRC_PLL1 << CGU_BASE_CLK_SEL_SHIFT)); + CGU_BASE_PERIPH_CLK = CGU_BASE_PERIPH_CLK_AUTOBLOCK + | CGU_BASE_PERIPH_CLK_CLK_SEL(CGU_SRC_PLL1); - CGU_BASE_APB1_CLK = (CGU_BASE_CLK_AUTOBLOCK - | (CGU_SRC_PLL1 << CGU_BASE_CLK_SEL_SHIFT)); + CGU_BASE_APB1_CLK = CGU_BASE_APB1_CLK_AUTOBLOCK + | CGU_BASE_APB1_CLK_CLK_SEL(CGU_SRC_PLL1); usb_reset_peripheral(); From f574f70a8765c547a9a289e907938af5e6689c74 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 27 Sep 2012 17:52:36 -0700 Subject: [PATCH 14/41] More small tweaks due to CGU register #define changes. --- firmware/sgpio-rx/sgpio-rx.c | 8 ++++---- firmware/sgpio/sgpio.c | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/firmware/sgpio-rx/sgpio-rx.c b/firmware/sgpio-rx/sgpio-rx.c index 9b3f258f..284c1d69 100644 --- a/firmware/sgpio-rx/sgpio-rx.c +++ b/firmware/sgpio-rx/sgpio-rx.c @@ -271,11 +271,11 @@ int main(void) { enable_1v8_power(); cpu_clock_init(); - CGU_BASE_PERIPH_CLK = (CGU_BASE_CLK_AUTOBLOCK - | (CGU_SRC_PLL1 << CGU_BASE_CLK_SEL_SHIFT)); + CGU_BASE_PERIPH_CLK = CGU_BASE_PERIPH_CLK_AUTOBLOCK + | CGU_BASE_PERIPH_CLK_CLK_SEL(CGU_SRC_PLL1); - CGU_BASE_APB1_CLK = (CGU_BASE_CLK_AUTOBLOCK - | (CGU_SRC_PLL1 << CGU_BASE_CLK_SEL_SHIFT)); + CGU_BASE_APB1_CLK = CGU_BASE_APB1_CLK_AUTOBLOCK + | CGU_BASE_APB1_CLK_CLK_SEL(CGU_SRC_PLL1); ssp1_init(); ssp1_set_mode_max2837(); diff --git a/firmware/sgpio/sgpio.c b/firmware/sgpio/sgpio.c index 2df82c05..5d17238d 100644 --- a/firmware/sgpio/sgpio.c +++ b/firmware/sgpio/sgpio.c @@ -243,11 +243,11 @@ int main(void) { cpu_clock_init(); ssp1_init(); - CGU_BASE_PERIPH_CLK = (CGU_BASE_CLK_AUTOBLOCK - | (CGU_SRC_PLL1 << CGU_BASE_CLK_SEL_SHIFT)); + CGU_BASE_PERIPH_CLK = CGU_BASE_PERIPH_CLK_AUTOBLOCK + | CGU_BASE_PERIPH_CLK_CLK_SEL(CGU_SRC_PLL1); - CGU_BASE_APB1_CLK = (CGU_BASE_CLK_AUTOBLOCK - | (CGU_SRC_PLL1 << CGU_BASE_CLK_SEL_SHIFT)); + CGU_BASE_APB1_CLK = CGU_BASE_APB1_CLK_AUTOBLOCK + | CGU_BASE_APB1_CLK_CLK_SEL(CGU_SRC_PLL1); gpio_set(PORT_LED1_3, PIN_LED1); From 776c50262889dc2c1356decbeda376167ee4b217 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 27 Sep 2012 17:55:54 -0700 Subject: [PATCH 15/41] More tweaks related to CGU #define changes. --- firmware/common/hackrf_core.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/firmware/common/hackrf_core.c b/firmware/common/hackrf_core.c index 2f99d7fd..90d58aae 100644 --- a/firmware/common/hackrf_core.c +++ b/firmware/common/hackrf_core.c @@ -142,11 +142,11 @@ void cpu_clock_init(void) CGU_XTAL_OSC_CTRL &= ~CGU_XTAL_OSC_CTRL_ENABLE; /* use XTAL_OSC as clock source for BASE_M4_CLK (CPU) */ - CGU_BASE_M4_CLK = ((CGU_SRC_XTAL << CGU_BASE_CLK_SEL_SHIFT)); + CGU_BASE_M4_CLK = CGU_BASE_M4_CLK_CLK_SEL(CGU_SRC_XTAL); /* use XTAL_OSC as clock source for APB1 */ - CGU_BASE_APB1_CLK = (CGU_BASE_CLK_AUTOBLOCK - | (CGU_SRC_XTAL << CGU_BASE_CLK_SEL_SHIFT)); + CGU_BASE_APB1_CLK = CGU_BASE_APB1_CLK_AUTOBLOCK + | CGU_BASE_APB1_CLK_CLK_SEL(CGU_SRC_XTAL); /* use XTAL_OSC as clock source for PLL1 */ CGU_PLL1_CTRL = (CGU_PLL1_CTRL_AUTOBLOCK @@ -172,21 +172,21 @@ void cpu_clock_init(void) while (!(CGU_PLL1_STAT & CGU_PLL1_STAT_LOCK)); /* use PLL1 as clock source for BASE_M4_CLK (CPU) */ - CGU_BASE_M4_CLK = ((CGU_SRC_PLL1 << CGU_BASE_CLK_SEL_SHIFT)); + CGU_BASE_M4_CLK = CGU_BASE_M4_CLK_CLK_SEL(CGU_SRC_PLL1); /* use XTAL_OSC as clock source for PLL0USB */ - CGU_PLL0USB_CTRL = (CGU_PLL0USB_CTRL_PD + CGU_PLL0USB_CTRL = CGU_PLL0USB_CTRL_PD | CGU_PLL0USB_CTRL_AUTOBLOCK - | (CGU_SRC_XTAL << CGU_PLL0USB_CTRL_CLK_SEL_SHIFT)); + | CGU_PLL0USB_CTRL_CLK_SEL(CGU_SRC_XTAL); while (CGU_PLL0USB_STAT & CGU_PLL0USB_STAT_LOCK); /* configure PLL0USB to produce 480 MHz clock from 12 MHz XTAL_OSC */ - CGU_PLL0USB_MDIV = ((0x07FFA << CGU_PLL0USB_MDIV_MDEC_SHIFT) - | (0x0B << CGU_PLL0USB_SELP_MDEC_SHIFT) - | (0x10 << CGU_PLL0USB_SELI_MDEC_SHIFT) - | (0x0 << CGU_PLL0USB_SELR_MDEC_SHIFT)); - CGU_PLL0USB_NP_DIV = (98 << CGU_PLL0USB_NP_DIV_PDEC_SHIFT) - | (514 << CGU_PLL0USB_NP_DIV_NDEC_SHIFT); + CGU_PLL0USB_MDIV = CGU_PLL0USB_MDIV_MDEC(0x07FFA) + | CGU_PLL0USB_MDIV_SELP(0x0B) + | CGU_PLL0USB_MDIV_SELI(0x10) + | CGU_PLL0USB_MDIV_SELR(0x0); + CGU_PLL0USB_NP_DIV = CGU_PLL0USB_NP_DIV_PDEC(98) + | CGU_PLL0USB_NP_DIV_NDEC(514); CGU_PLL0USB_CTRL |= (CGU_PLL0USB_CTRL_PD | CGU_PLL0USB_CTRL_DIRECTI | CGU_PLL0USB_CTRL_DIRECTO @@ -197,8 +197,8 @@ void cpu_clock_init(void) while (!(CGU_PLL0USB_STAT & CGU_PLL0USB_STAT_LOCK)); /* use PLL0USB as clock source for USB0 */ - CGU_BASE_USB0_CLK = (CGU_BASE_CLK_AUTOBLOCK - | (CGU_SRC_PLL0USB << CGU_BASE_CLK_SEL_SHIFT)); + CGU_BASE_USB0_CLK = CGU_BASE_USB0_CLK_AUTOBLOCK + | CGU_BASE_USB0_CLK_CLK_SEL(CGU_SRC_PLL0USB); } void ssp1_init(void) From aaaf14819a477d7649ce8a7593adbd7b8f2970d2 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 27 Sep 2012 18:58:00 -0700 Subject: [PATCH 16/41] Move PLL1/M4 CLK up to full speed (204MHz) in two steps, according to UM chapter 11.2.1. --- firmware/common/hackrf_core.c | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/firmware/common/hackrf_core.c b/firmware/common/hackrf_core.c index 90d58aae..46fb76bd 100644 --- a/firmware/common/hackrf_core.c +++ b/firmware/common/hackrf_core.c @@ -149,23 +149,12 @@ void cpu_clock_init(void) | CGU_BASE_APB1_CLK_CLK_SEL(CGU_SRC_XTAL); /* use XTAL_OSC as clock source for PLL1 */ - CGU_PLL1_CTRL = (CGU_PLL1_CTRL_AUTOBLOCK - | (CGU_SRC_XTAL << CGU_PLL1_CTRL_CLK_SEL_SHIFT)); - - /* configure PLL1 to produce 204 MHz clock from 12 MHz XTAL_OSC */ - /* not sure why, but it doesn't work without the following line */ - CGU_PLL1_CTRL &= ~(CGU_PLL1_CTRL_BYPASS - | CGU_PLL1_CTRL_FBSEL - | CGU_PLL1_CTRL_DIRECT - | CGU_PLL1_CTRL_DIRECT - | (0x3 << CGU_PLL1_CTRL_PSEL_SHIFT) - | (0x3 << CGU_PLL1_CTRL_NSEL_SHIFT) - | (0xFF << CGU_PLL1_CTRL_MSEL_SHIFT)); - CGU_PLL1_CTRL |= (CGU_PLL1_CTRL_FBSEL - | CGU_PLL1_CTRL_DIRECT - | (0 << CGU_PLL1_CTRL_PSEL_SHIFT) - | (0 << CGU_PLL1_CTRL_NSEL_SHIFT) - | (16 << CGU_PLL1_CTRL_MSEL_SHIFT)); + /* Start PLL1 at 12MHz * 17 / 2 = 102MHz. */ + CGU_PLL1_CTRL = CGU_PLL1_CTRL_CLK_SEL(CGU_SRC_XTAL) + | CGU_PLL1_CTRL_PSEL(1) + | CGU_PLL1_CTRL_NSEL(0) + | CGU_PLL1_CTRL_MSEL(16) + | CGU_PLL1_CTRL_PD; /* power on PLL1 and wait until stable */ CGU_PLL1_CTRL &= ~CGU_PLL1_CTRL_PD; @@ -174,6 +163,15 @@ void cpu_clock_init(void) /* use PLL1 as clock source for BASE_M4_CLK (CPU) */ CGU_BASE_M4_CLK = CGU_BASE_M4_CLK_CLK_SEL(CGU_SRC_PLL1); + /* Move PLL1 up to 12MHz * 17 = 204MHz. */ + CGU_PLL1_CTRL = CGU_PLL1_CTRL_CLK_SEL(CGU_SRC_XTAL) + | CGU_PLL1_CTRL_PSEL(0) + | CGU_PLL1_CTRL_NSEL(0) + | CGU_PLL1_CTRL_MSEL(16); + + /* wait until stable */ + while (!(CGU_PLL1_STAT & CGU_PLL1_STAT_LOCK)); + /* use XTAL_OSC as clock source for PLL0USB */ CGU_PLL0USB_CTRL = CGU_PLL0USB_CTRL_PD | CGU_PLL0USB_CTRL_AUTOBLOCK From a975fbc5770e00af20173b77fb14f730d9a884d4 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Thu, 27 Sep 2012 19:29:43 -0700 Subject: [PATCH 17/41] Replaced apparently incorrect PLL0USB MDIV and NP_DIV values with values straight out of the User Manual's table 94. --- firmware/common/hackrf_core.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/firmware/common/hackrf_core.c b/firmware/common/hackrf_core.c index 46fb76bd..8686aedc 100644 --- a/firmware/common/hackrf_core.c +++ b/firmware/common/hackrf_core.c @@ -179,12 +179,9 @@ void cpu_clock_init(void) while (CGU_PLL0USB_STAT & CGU_PLL0USB_STAT_LOCK); /* configure PLL0USB to produce 480 MHz clock from 12 MHz XTAL_OSC */ - CGU_PLL0USB_MDIV = CGU_PLL0USB_MDIV_MDEC(0x07FFA) - | CGU_PLL0USB_MDIV_SELP(0x0B) - | CGU_PLL0USB_MDIV_SELI(0x10) - | CGU_PLL0USB_MDIV_SELR(0x0); - CGU_PLL0USB_NP_DIV = CGU_PLL0USB_NP_DIV_PDEC(98) - | CGU_PLL0USB_NP_DIV_NDEC(514); + /* Values from User Manual v1.4 Table 94, for 12MHz oscillator. */ + CGU_PLL0USB_MDIV = 0x06167FFA; + CGU_PLL0USB_NP_DIV = 0x00302062; CGU_PLL0USB_CTRL |= (CGU_PLL0USB_CTRL_PD | CGU_PLL0USB_CTRL_DIRECTI | CGU_PLL0USB_CTRL_DIRECTO From 46f24d6f47d2eb39d459c21888d19c0529af3eaf Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sat, 6 Oct 2012 17:29:56 -0700 Subject: [PATCH 18/41] Remove ROM memory region from "ram_only" linker script. --- firmware/common/LPC4330_M4_ram_only.ld | 2 -- 1 file changed, 2 deletions(-) diff --git a/firmware/common/LPC4330_M4_ram_only.ld b/firmware/common/LPC4330_M4_ram_only.ld index 6fb4a2f8..eb9ace11 100644 --- a/firmware/common/LPC4330_M4_ram_only.ld +++ b/firmware/common/LPC4330_M4_ram_only.ld @@ -23,8 +23,6 @@ MEMORY { - /* rom is really the shadow region that points to SPI flash or elsewhere */ - rom (rx) : ORIGIN = 0x00000000, LENGTH = 128K ram_local1 (rwx) : ORIGIN = 0x10000000, LENGTH = 128K ram_local2 (rwx) : ORIGIN = 0x10080000, LENGTH = 72K ram_ahb (rwx) : ORIGIN = 0x20000000, LENGTH = 64K From 182157a19cbfbf6c402a381c367ea80e4064878e Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sat, 6 Oct 2012 17:30:26 -0700 Subject: [PATCH 19/41] Add ram_ahb memory region to linker scripts. --- firmware/common/LPC4330_M4.ld | 1 + firmware/common/LPC4330_M4_ROM_to_RAM.ld | 1 + 2 files changed, 2 insertions(+) diff --git a/firmware/common/LPC4330_M4.ld b/firmware/common/LPC4330_M4.ld index d73b4d47..8a9b2ad4 100644 --- a/firmware/common/LPC4330_M4.ld +++ b/firmware/common/LPC4330_M4.ld @@ -27,6 +27,7 @@ MEMORY rom (rx) : ORIGIN = 0x00000000, LENGTH = 1M ram (rwx) : ORIGIN = 0x10000000, LENGTH = 128K /* there are some additional RAM regions */ + ram_ahb (rwx) : ORIGIN = 0x20000000, LENGTH = 64K } /* Include the common ld script. */ diff --git a/firmware/common/LPC4330_M4_ROM_to_RAM.ld b/firmware/common/LPC4330_M4_ROM_to_RAM.ld index e3852933..995c54f5 100644 --- a/firmware/common/LPC4330_M4_ROM_to_RAM.ld +++ b/firmware/common/LPC4330_M4_ROM_to_RAM.ld @@ -31,6 +31,7 @@ MEMORY ram (rwx) : ORIGIN = 0x10000000, LENGTH = 128K /* there are some additional RAM regions for data */ ram_data (rw) : ORIGIN = 0x10080000, LENGTH = 72K + ram_ahb (rwx) : ORIGIN = 0x20000000, LENGTH = 64K } /* Include the common ld script. */ From f68fdaba7a3886e93c88b129d886a2db52ec3435 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sat, 6 Oct 2012 17:33:17 -0700 Subject: [PATCH 20/41] Add .usbram section handling to linker scripts and makefile. --- firmware/common/LPC4330_M4.ld | 3 ++ firmware/common/LPC4330_M4_ROM_to_RAM.ld | 3 ++ firmware/common/LPC4330_M4_ram_only.ld | 3 ++ firmware/common/Makefile_inc.mk | 4 ++- firmware/common/usbram.ld | 35 ++++++++++++++++++++++++ 5 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 firmware/common/usbram.ld diff --git a/firmware/common/LPC4330_M4.ld b/firmware/common/LPC4330_M4.ld index 8a9b2ad4..5edc3428 100644 --- a/firmware/common/LPC4330_M4.ld +++ b/firmware/common/LPC4330_M4.ld @@ -1,5 +1,6 @@ /* * Copyright 2012 Michael Ossmann + * Copyright 2012 Jared Boone * * This file is part of HackRF * @@ -32,3 +33,5 @@ MEMORY /* Include the common ld script. */ INCLUDE libopencm3_lpc43xx.ld + +INCLUDE usbram.ld diff --git a/firmware/common/LPC4330_M4_ROM_to_RAM.ld b/firmware/common/LPC4330_M4_ROM_to_RAM.ld index 995c54f5..f7e5886d 100644 --- a/firmware/common/LPC4330_M4_ROM_to_RAM.ld +++ b/firmware/common/LPC4330_M4_ROM_to_RAM.ld @@ -1,6 +1,7 @@ /* * Copyright 2012 Michael Ossmann * Copyright (C) 2012 Benjamin Vernoux + * Copyright 2012 Jared Boone * * This file is part of HackRF * @@ -36,3 +37,5 @@ MEMORY /* Include the common ld script. */ INCLUDE libopencm3_lpc43xx_rom_to_ram.ld + +INCLUDE usbram.ld diff --git a/firmware/common/LPC4330_M4_ram_only.ld b/firmware/common/LPC4330_M4_ram_only.ld index eb9ace11..11bb1d88 100644 --- a/firmware/common/LPC4330_M4_ram_only.ld +++ b/firmware/common/LPC4330_M4_ram_only.ld @@ -1,5 +1,6 @@ /* * Copyright 2012 Michael Ossmann + * Copyright 2012 Jared Boone * * This file is part of HackRF * @@ -30,3 +31,5 @@ MEMORY /* Include the common ld script. */ INCLUDE libopencm3_lpc43xx_ram_only.ld + +INCLUDE usbram.ld diff --git a/firmware/common/Makefile_inc.mk b/firmware/common/Makefile_inc.mk index 384fd9f1..1c635525 100644 --- a/firmware/common/Makefile_inc.mk +++ b/firmware/common/Makefile_inc.mk @@ -4,6 +4,7 @@ # Copyright 2010 Piotr Esden-Tempski # Copyright 2012 Michael Ossmann # Copyright 2012 Benjamin Vernoux +# Copyright 2012 Jared Boone # # This file is part of HackRF. # @@ -51,6 +52,7 @@ CFLAGS += -std=c99 -O2 -g3 -Wall -Wextra -I$(LIBOPENCM3)/include -I../common \ $(HACKRF_OPTS) #LDSCRIPT ?= $(BINARY).ld LDFLAGS += -L$(TOOLCHAIN_DIR)/lib/armv7e-m/fpu \ + -L../common \ -L$(LIBOPENCM3)/lib -L$(LIBOPENCM3)/lib/lpc43xx \ -T$(LDSCRIPT) -nostartfiles \ -Wl,--gc-sections -Xlinker -Map=$(BINARY).map @@ -78,7 +80,7 @@ flash: $(BINARY).flash %.bin: %.elf @#printf " OBJCOPY $(*).bin\n" - $(Q)$(OBJCOPY) -Obinary $(*).elf $(*).bin + $(Q)$(OBJCOPY) -Obinary -R .usbram $(*).elf $(*).bin %.hex: %.elf @#printf " OBJCOPY $(*).hex\n" diff --git a/firmware/common/usbram.ld b/firmware/common/usbram.ld new file mode 100644 index 00000000..279aaad3 --- /dev/null +++ b/firmware/common/usbram.ld @@ -0,0 +1,35 @@ +/* + * Copyright 2012 Jared Boone + * + * This file is part of HackRF + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +SECTIONS +{ + . = ORIGIN(ram_ahb); + + .usbram : { + . = ALIGN(4096); + *(.usb_data) + . = ALIGN(2048); + *(.usb_qh) + . = ALIGN(64); + *(.usb_td) + } >ram_ahb + +} From 900463ee5c360f1def5f4d1bcd6755bae4a5c1ce Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sat, 6 Oct 2012 17:35:11 -0700 Subject: [PATCH 21/41] Added fault handler code which can be optionally compiled/linked for debugging. --- firmware/common/fault_handler.c | 55 +++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 firmware/common/fault_handler.c diff --git a/firmware/common/fault_handler.c b/firmware/common/fault_handler.c new file mode 100644 index 00000000..f82742f7 --- /dev/null +++ b/firmware/common/fault_handler.c @@ -0,0 +1,55 @@ +/* + * Copyright 2012 Jared Boone + * + * This file is part of HackRF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include + +__attribute__((naked)) +void hard_fault_handler(void) { + __asm__("TST LR, #4"); + __asm__("ITE EQ"); + __asm__("MRSEQ R0, MSP"); + __asm__("MRSNE R0, PSP"); + __asm__("B hard_fault_handler_c"); +} + +void hard_fault_handler_c(uint32_t* args) { + // args[0-7]: r0, r1, r2, r3, r12, lr, pc, psr + // Other interesting registers to examine: + // CFSR: Configurable Fault Status Register + // HFSR: Hard Fault Status Register + // DFSR: Debug Fault Status Register + // AFSR: Auxiliary Fault Status Register + // MMAR: MemManage Fault Address Register + // BFAR: Bus Fault Address Register + while(1); +} + +void mem_manage_handler() { + while(1); +} + +void bus_fault_handler() { + while(1); +} + +void usage_fault_handler() { + while(1); +} From 3451a3c3d8e1969530ac695621e2016067361d06 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sat, 6 Oct 2012 18:58:18 -0700 Subject: [PATCH 22/41] Tons of new USB code. It should eventually migrate into common, or even libopencm3, once it's not a steaming pile of crap... --- firmware/usb_performance/usb.c | 603 ++++++++++++++++++ firmware/usb_performance/usb.h | 77 +++ firmware/usb_performance/usb_descriptor.c | 169 +++++ firmware/usb_performance/usb_descriptor.h | 12 + firmware/usb_performance/usb_request.c | 63 ++ firmware/usb_performance/usb_request.h | 45 ++ .../usb_performance/usb_standard_request.c | 257 ++++++++ .../usb_performance/usb_standard_request.h | 24 + firmware/usb_performance/usb_type.h | 101 +++ 9 files changed, 1351 insertions(+) create mode 100644 firmware/usb_performance/usb.c create mode 100644 firmware/usb_performance/usb.h create mode 100644 firmware/usb_performance/usb_descriptor.c create mode 100644 firmware/usb_performance/usb_descriptor.h create mode 100644 firmware/usb_performance/usb_request.c create mode 100644 firmware/usb_performance/usb_request.h create mode 100644 firmware/usb_performance/usb_standard_request.c create mode 100644 firmware/usb_performance/usb_standard_request.h create mode 100644 firmware/usb_performance/usb_type.h diff --git a/firmware/usb_performance/usb.c b/firmware/usb_performance/usb.c new file mode 100644 index 00000000..a47c47c2 --- /dev/null +++ b/firmware/usb_performance/usb.c @@ -0,0 +1,603 @@ +#include +#include + +#include "usb.h" +#include "usb_type.h" +#include "usb_standard_request.h" + +#include +#include +#include +#include + +usb_device_t* usb_device_usb0 = 0; + +usb_queue_head_t usb_qh[12] ATTR_SECTION(".usb_qh"); +usb_transfer_descriptor_t usb_td[12] ATTR_SECTION(".usb_td"); + +#define USB_QH_INDEX(endpoint_address) (((endpoint_address & 0xF) * 2) + ((endpoint_address >> 7) & 1)) +#define USB_TD_INDEX(endpoint_address) (((endpoint_address & 0xF) * 2) + ((endpoint_address >> 7) & 1)) + +usb_queue_head_t* usb_queue_head( + const uint_fast8_t endpoint_address +) { + return &usb_qh[USB_QH_INDEX(endpoint_address)]; +} + +usb_transfer_descriptor_t* usb_transfer_descriptor( + const uint_fast8_t endpoint_address +) { + return &usb_td[USB_TD_INDEX(endpoint_address)]; +} + +static usb_endpoint_t* usb_endpoint_from_address( + const uint_fast8_t endpoint_address +) { + return (usb_endpoint_t*)usb_queue_head(endpoint_address)->_reserved_0; +} + +static uint_fast8_t usb_endpoint_address( + const usb_transfer_direction_t direction, + const uint_fast8_t number +) { + return ((direction == USB_TRANSFER_DIRECTION_IN) ? 0x80 : 0x00) + number; +} + +static bool usb_endpoint_is_in(const uint_fast8_t endpoint_address) { + return (endpoint_address & 0x80) ? true : false; +} + +static uint_fast8_t usb_endpoint_number(const uint_fast8_t endpoint_address) { + return (endpoint_address & 0xF); +} + +void usb_peripheral_reset() { + RESET_CTRL0 = RESET_CTRL0_USB0_RST; + RESET_CTRL0 = 0; + + while( (RESET_ACTIVE_STATUS0 & RESET_CTRL0_USB0_RST) == 0 ); +} + +static void usb_phy_enable() { + CREG_CREG0 &= ~CREG_CREG0_USB0PHY; +} + +static void usb_wait_for_endpoint_priming_to_finish(const uint32_t mask) { + // Wait until controller has parsed new transfer descriptors and prepared + // receive buffers. + while( USB0_ENDPTPRIME & mask ); +} + +static void usb_flush_endpoints(const uint32_t mask) { + // Clear any primed buffers. If a packet is in progress, that transfer + // will continue until completion. + USB0_ENDPTFLUSH = mask; +} + +static void usb_wait_for_endpoint_flushing_to_finish(const uint32_t mask) { + // Wait until controller has flushed all endpoints / cleared any primed + // buffers. + while( USB0_ENDPTFLUSH & mask ); +} + +static void usb_flush_primed_endpoints(const uint32_t mask) { + usb_wait_for_endpoint_priming_to_finish(mask); + usb_flush_endpoints(mask); + usb_wait_for_endpoint_flushing_to_finish(mask); +} + +static void usb_flush_all_primed_endpoints() { + usb_flush_primed_endpoints(0xFFFFFFFF); +} + +static void usb_endpoint_set_type( + const usb_endpoint_t* const endpoint, + const usb_transfer_type_t transfer_type +) { + // NOTE: UM10503 section 23.6.24 "Endpoint 1 to 5 control registers" says + // that the disabled side of an endpoint must be set to a non-control type + // (e.g. bulk, interrupt, or iso). + const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address); + USB0_ENDPTCTRL(endpoint_number) + = ( USB0_ENDPTCTRL(endpoint_number) + & ~(USB0_ENDPTCTRL_TXT1_0_MASK | USB0_ENDPTCTRL_RXT_MASK) + ) + | ( USB0_ENDPTCTRL_TXT1_0(transfer_type) + | USB0_ENDPTCTRL_RXT(transfer_type) + ); +} + +static void usb_endpoint_enable( + const usb_endpoint_t* const endpoint +) { + const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address); + if( usb_endpoint_is_in(endpoint->address) ) { + USB0_ENDPTCTRL(endpoint_number) |= (USB0_ENDPTCTRL_TXE | USB0_ENDPTCTRL_TXR); + } else { + USB0_ENDPTCTRL(endpoint_number) |= (USB0_ENDPTCTRL_RXE | USB0_ENDPTCTRL_RXR); + } +} + +void usb_endpoint_disable( + const usb_endpoint_t* const endpoint +) { + const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address); + if( usb_endpoint_is_in(endpoint->address) ) { + USB0_ENDPTCTRL(endpoint_number) &= ~(USB0_ENDPTCTRL_TXE); + } else { + USB0_ENDPTCTRL(endpoint_number) &= ~(USB0_ENDPTCTRL_RXE); + } +} + +void usb_endpoint_prime( + const usb_endpoint_t* const endpoint, + usb_transfer_descriptor_t* const first_td +) { + usb_queue_head_t* const qh = usb_queue_head(endpoint->address); + + qh->next_dtd_pointer = first_td; + qh->total_bytes + &= ~( USB_TD_DTD_TOKEN_STATUS_ACTIVE + | USB_TD_DTD_TOKEN_STATUS_HALTED + ) + ; + + const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address); + if( usb_endpoint_is_in(endpoint->address) ) { + USB0_ENDPTPRIME = USB0_ENDPTPRIME_PETB(1 << endpoint_number); + } else { + USB0_ENDPTPRIME = USB0_ENDPTPRIME_PERB(1 << endpoint_number); + } +} + +static bool usb_endpoint_is_priming( + const usb_endpoint_t* const endpoint +) { + const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address); + if( usb_endpoint_is_in(endpoint->address) ) { + return USB0_ENDPTPRIME & USB0_ENDPTPRIME_PETB(1 << endpoint_number); + } else { + return USB0_ENDPTPRIME & USB0_ENDPTPRIME_PERB(1 << endpoint_number); + } +} + +void usb_endpoint_flush( + const usb_endpoint_t* const endpoint +) { + const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address); + if( usb_endpoint_is_in(endpoint->address) ) { + usb_flush_primed_endpoints(USB0_ENDPTFLUSH_FETB(1 << endpoint_number)); + } else { + usb_flush_primed_endpoints(USB0_ENDPTFLUSH_FERB(1 << endpoint_number)); + } +} + +static bool usb_endpoint_is_flushing( + const usb_endpoint_t* const endpoint +) { + const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address); + if( usb_endpoint_is_in(endpoint->address) ) { + return USB0_ENDPTFLUSH & USB0_ENDPTFLUSH_FETB(1 << endpoint_number); + } else { + return USB0_ENDPTFLUSH & USB0_ENDPTFLUSH_FERB(1 << endpoint_number); + } +} + +bool usb_endpoint_is_ready( + const usb_endpoint_t* const endpoint +) { + const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address); + if( usb_endpoint_is_in(endpoint->address) ) { + return USB0_ENDPTSTAT & USB0_ENDPTSTAT_ETBR(1 << endpoint_number); + } else { + return USB0_ENDPTSTAT & USB0_ENDPTSTAT_ERBR(1 << endpoint_number); + } +} + +void usb_endpoint_stall( + const usb_endpoint_t* const endpoint +) { + // Endpoint is to be stalled as a pair -- both OUT and IN. + // See UM10503 section 23.10.5.2 "Stalling" + const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address); + USB0_ENDPTCTRL(endpoint_number) |= (USB0_ENDPTCTRL_RXS | USB0_ENDPTCTRL_TXS); + + // TODO: Also need to reset data toggle in both directions? +} + +static void usb_controller_run() { + USB0_USBCMD_D |= USB0_USBCMD_D_RS; +} + +static void usb_controller_stop() { + USB0_USBCMD_D &= ~USB0_USBCMD_D_RS; +} + +static uint_fast8_t usb_controller_is_resetting() { + return (USB0_USBCMD_D & USB0_USBCMD_D_RST) != 0; +} + +static void usb_controller_set_device_mode() { + // Set USB0 peripheral mode + USB0_USBMODE_D = USB0_USBMODE_D_CM1_0(2); + + // Set device-related OTG flags + // OTG termination: controls pull-down on USB_DM + // VBUS_Discharge: VBUS discharges through resistor + USB0_OTGSC = USB0_OTGSC_OT | USB0_OTGSC_VD; +} + +usb_speed_t usb_speed( + const usb_device_t* const device +) { + if( device == usb_device_usb0 ) { + switch( USB0_PORTSC1_D & USB0_PORTSC1_D_PSPD_MASK ) { + case USB0_PORTSC1_D_PSPD(0): + return USB_SPEED_FULL; + + case USB0_PORTSC1_D_PSPD(2): + return USB_SPEED_HIGH; + + default: + // TODO: What to do/return here? Is this even possible? + return USB_SPEED_FULL; + } + } else { + // TODO: This should not be possible with a more class-like + // implementation. + return USB_SPEED_FULL; + } +} + +static void usb_clear_status(const uint32_t status) { + USB0_USBSTS_D = status; +} + +static uint32_t usb_get_status() { + // Mask status flags with enabled flag interrupts. + const uint32_t status = USB0_USBSTS_D & USB0_USBINTR_D; + + // Clear flags that were just read, leaving alone any flags that + // were just set (after the read). It's important to read and + // reset flags atomically! :-) + usb_clear_status(status); + + return status; +} + +static void usb_clear_endpoint_setup_status(const uint32_t endpoint_setup_status) { + USB0_ENDPTSETUPSTAT = endpoint_setup_status; +} + +static uint32_t usb_get_endpoint_setup_status() { + return USB0_ENDPTSETUPSTAT; +} + +static void usb_clear_endpoint_complete(const uint32_t endpoint_complete) { + USB0_ENDPTCOMPLETE = endpoint_complete; +} + +static uint32_t usb_get_endpoint_complete() { + return USB0_ENDPTCOMPLETE; +} + +static void usb_disable_all_endpoints() { + // Endpoint 0 is always enabled. TODO: So why set ENDPTCTRL0? + USB0_ENDPTCTRL0 &= ~(USB0_ENDPTCTRL0_RXE | USB0_ENDPTCTRL0_TXE); + USB0_ENDPTCTRL1 &= ~(USB0_ENDPTCTRL1_RXE | USB0_ENDPTCTRL1_TXE); + USB0_ENDPTCTRL2 &= ~(USB0_ENDPTCTRL2_RXE | USB0_ENDPTCTRL2_TXE); + USB0_ENDPTCTRL3 &= ~(USB0_ENDPTCTRL3_RXE | USB0_ENDPTCTRL3_TXE); + USB0_ENDPTCTRL4 &= ~(USB0_ENDPTCTRL4_RXE | USB0_ENDPTCTRL4_TXE); + USB0_ENDPTCTRL5 &= ~(USB0_ENDPTCTRL5_RXE | USB0_ENDPTCTRL5_TXE); +} + +static void usb_clear_all_pending_interrupts() { + USB0_ENDPTNAK = ~0; + USB0_ENDPTNAKEN = 0; + USB0_USBSTS_D = ~0; + USB0_ENDPTSETUPSTAT = USB0_ENDPTSETUPSTAT; + USB0_ENDPTCOMPLETE = USB0_ENDPTCOMPLETE; +} + +void usb_set_address_immediate( + const usb_device_t* const device, + const uint_fast8_t address +) { + if( device == usb_device_usb0 ) { + USB0_DEVICEADDR = USB0_DEVICEADDR_USBADR(address); + } +} + +void usb_set_address_deferred( + const usb_device_t* const device, + const uint_fast8_t address +) { + if( device == usb_device_usb0 ) { + USB0_DEVICEADDR + = USB0_DEVICEADDR_USBADR(address) + | USB0_DEVICEADDR_USBADRA + ; + } +} + +static void usb_reset_all_endpoints() { + usb_disable_all_endpoints(); + usb_clear_all_pending_interrupts(); + usb_flush_all_primed_endpoints(); +} + +static void usb_controller_reset() { + // TODO: Good to disable some USB interrupts to avoid priming new + // new endpoints before the controller is reset? + usb_reset_all_endpoints(); + usb_controller_stop(); + + // Reset controller. Resets internal pipelines, timers, counters, state + // machines to initial values. Not recommended when device is in attached + // state -- effect on attached host is undefined. Detach first by flushing + // all primed endpoints and stopping controller. + USB0_USBCMD_D = USB0_USBCMD_D_RST; + + while( usb_controller_is_resetting() ); +} + +static void usb_bus_reset(usb_device_t* const device) { + // According to UM10503 v1.4 section 23.10.3 "Bus reset": + usb_reset_all_endpoints(); + usb_set_address_immediate(device, 0); + usb_set_configuration(device, 0); + + // TODO: Enable endpoint 0, which might not actually be necessary, + // as the datasheet claims it can't be disabled. + + //wait_ms(3); + // + //if( USB0_PORTSC1 & USB0_PORTSC1_PR ) { + // // Port still is in the reset state. + //} else { + // usb_hardware_reset(); + //} +} + +static void usb_interrupt_enable( + usb_device_t* const device +) { + if( device == usb_device_usb0 ) { + nvic_enable_irq(NVIC_M4_USB0_IRQ); + } +} + +void usb_device_init( + const uint_fast8_t device_ordinal, + usb_device_t* const device +) { + if( device_ordinal == 0 ) { + usb_device_usb0 = device; + + usb_phy_enable(); + usb_controller_reset(); + usb_controller_set_device_mode(); + + // Set interrupt threshold interval to 0 + USB0_USBCMD_D &= ~USB0_USBCMD_D_ITC_MASK; + + // Configure endpoint list address + USB0_ENDPOINTLISTADDR = (uint32_t)usb_qh; + + // 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 + ; + } +} + +void usb_run( + usb_device_t* const device +) { + usb_interrupt_enable(device); + usb_controller_run(device); +} + +static void copy_setup(usb_setup_t* const dst, const volatile uint8_t* const src) { + dst->request_type = src[0]; + dst->request = src[1]; + dst->value_l = src[2]; + dst->value_h = src[3]; + dst->index_l = src[4]; + dst->index_h = src[5]; + dst->length_l = src[6]; + dst->length_h = src[7]; +} + +void usb_endpoint_init( + const usb_endpoint_t* const endpoint +) { + usb_endpoint_flush(endpoint); + + uint_fast16_t max_packet_size = endpoint->device->descriptor[7]; + usb_transfer_type_t transfer_type = USB_TRANSFER_TYPE_CONTROL; + const uint8_t* const endpoint_descriptor = usb_endpoint_descriptor(endpoint); + if( endpoint_descriptor ) { + max_packet_size = usb_endpoint_descriptor_max_packet_size(endpoint_descriptor); + transfer_type = usb_endpoint_descriptor_transfer_type(endpoint_descriptor); + } + + // TODO: There are more capabilities to adjust based on the endpoint + // descriptor. + usb_queue_head_t* const qh = usb_queue_head(endpoint->address); + qh->capabilities + = USB_QH_CAPABILITIES_MULT(0) + | USB_QH_CAPABILITIES_ZLT + | USB_QH_CAPABILITIES_MPL(max_packet_size) + | ((transfer_type == USB_TRANSFER_TYPE_CONTROL) ? USB_QH_CAPABILITIES_IOS : 0) + ; + qh->current_dtd_pointer = 0; + qh->next_dtd_pointer = USB_TD_NEXT_DTD_POINTER_TERMINATE; + qh->total_bytes + = USB_TD_DTD_TOKEN_TOTAL_BYTES(0) + | USB_TD_DTD_TOKEN_MULTO(0) + ; + qh->buffer_pointer_page[0] = 0; + qh->buffer_pointer_page[1] = 0; + qh->buffer_pointer_page[2] = 0; + qh->buffer_pointer_page[3] = 0; + qh->buffer_pointer_page[4] = 0; + + // This is how we look up an endpoint structure from an endpoint address: + qh->_reserved_0 = (uint32_t)endpoint; + + // TODO: Should NAK be enabled? I'm kinda squishy on this... + //USB0_ENDPTNAKEN |= + // USB0_ENDPTNAKEN_EPRNE(1 << endpoint_out->number); + + usb_endpoint_set_type(endpoint, transfer_type); + + usb_endpoint_enable(endpoint); +} + +void usb_endpoint_schedule( + const usb_endpoint_t* const endpoint, + void* const data, + const uint32_t maximum_length +) { + usb_transfer_descriptor_t* const td = usb_transfer_descriptor(endpoint->address); + + // Ensure that OUT endpoint is ready to be primed. + // It may have been flushed due to an aborted transaction. + // TODO: This should be preceded by a flush? + while( usb_endpoint_is_ready(endpoint) ); + + // Configure a transfer. + td->next_dtd_pointer = USB_TD_NEXT_DTD_POINTER_TERMINATE; + td->total_bytes = + USB_TD_DTD_TOKEN_TOTAL_BYTES(maximum_length) + | USB_TD_DTD_TOKEN_IOC + | USB_TD_DTD_TOKEN_MULTO(0) + | USB_TD_DTD_TOKEN_STATUS_ACTIVE + ; + td->buffer_pointer_page[0] = (uint32_t)data; + td->buffer_pointer_page[1] = ((uint32_t)data + 0x1000) & 0xfffff000; + td->buffer_pointer_page[2] = ((uint32_t)data + 0x2000) & 0xfffff000; + td->buffer_pointer_page[3] = ((uint32_t)data + 0x3000) & 0xfffff000; + td->buffer_pointer_page[4] = ((uint32_t)data + 0x4000) & 0xfffff000; + + usb_endpoint_prime(endpoint, td); +} + +void usb_endpoint_schedule_ack( + const usb_endpoint_t* const endpoint +) { + usb_endpoint_schedule(endpoint, 0, 0); +} + +static void usb_check_for_setup_events() { + const uint32_t endptsetupstat = usb_get_endpoint_setup_status(); + if( endptsetupstat ) { + for( uint_fast8_t i=0; i<6; i++ ) { + const uint32_t endptsetupstat_bit = USB0_ENDPTSETUPSTAT_ENDPTSETUPSTAT(1 << i); + if( endptsetupstat & endptsetupstat_bit ) { + usb_endpoint_t* const endpoint = + usb_endpoint_from_address( + usb_endpoint_address(USB_TRANSFER_DIRECTION_OUT, i) + ); + if( endpoint && endpoint->setup_complete ) { + copy_setup(&endpoint->setup, usb_queue_head(endpoint->address)->setup); + usb_clear_endpoint_setup_status(endptsetupstat_bit); + endpoint->setup_complete(endpoint); + } else { + usb_clear_endpoint_setup_status(endptsetupstat_bit); + } + } + } + } +} + +static void usb_check_for_transfer_events() { + const uint32_t endptcomplete = usb_get_endpoint_complete(); + if( endptcomplete ) { + for( uint_fast8_t i=0; i<6; i++ ) { + + const uint32_t endptcomplete_out_bit = USB0_ENDPTCOMPLETE_ERCE(1 << i); + if( endptcomplete & endptcomplete_out_bit ) { + usb_clear_endpoint_complete(endptcomplete_out_bit); + usb_endpoint_t* const endpoint = + usb_endpoint_from_address( + usb_endpoint_address(USB_TRANSFER_DIRECTION_OUT, i) + ); + if( endpoint && endpoint->transfer_complete ) { + endpoint->transfer_complete(endpoint); + } + } + + const uint32_t endptcomplete_in_bit = USB0_ENDPTCOMPLETE_ETCE(1 << i); + if( endptcomplete & endptcomplete_in_bit ) { + usb_clear_endpoint_complete(endptcomplete_in_bit); + usb_endpoint_t* const endpoint = + usb_endpoint_from_address( + usb_endpoint_address(USB_TRANSFER_DIRECTION_IN, i) + ); + if( endpoint && endpoint->transfer_complete ) { + endpoint->transfer_complete(endpoint); + } + } + } + } +} + +void usb0_irqhandler() { + const uint32_t status = usb_get_status(); + + if( status == 0 ) { + // Nothing to do. + return; + } + + if( status & USB0_USBSTS_D_UI ) { + // USB: + // - Completed transaction transfer descriptor has IOC set. + // - Short packet detected. + // - SETUP packet received. + + usb_check_for_setup_events(); + usb_check_for_transfer_events(); + + // TODO: Reset ignored ENDPTSETUPSTAT and ENDPTCOMPLETE flags? + } + + if( status & USB0_USBSTS_D_SRI ) { + // Start Of Frame received. + } + + if( status & USB0_USBSTS_D_PCI ) { + // Port change detect: + // Port controller entered full- or high-speed operational state. + } + + if( status & USB0_USBSTS_D_SLI ) { + // Device controller suspend. + } + + if( status & USB0_USBSTS_D_URI ) { + // USB reset received. + usb_bus_reset(usb_device_usb0); + } + + if( status & USB0_USBSTS_D_UEI ) { + // USB error: + // Completion of a USB transaction resulted in an error condition. + // Set along with USBINT if the TD on which the error interrupt + // occurred also had its interrupt on complete (IOC) bit set. + // The device controller detects resume signalling only. + } + + if( status & USB0_USBSTS_D_NAKI ) { + // Both the TX/RX endpoint NAK bit and corresponding TX/RX endpoint + // NAK enable bit are set. + } +} diff --git a/firmware/usb_performance/usb.h b/firmware/usb_performance/usb.h new file mode 100644 index 00000000..86c1683d --- /dev/null +++ b/firmware/usb_performance/usb.h @@ -0,0 +1,77 @@ +#ifndef __USB_H__ +#define __USB_H__ + +// TODO: Refactor to support high performance operations without having to +// expose usb_transfer_descriptor_t. Or usb_endpoint_prime(). Or, or, or... +#include + +#include "usb_type.h" + +#define ATTR_ALIGNED(x) __attribute__ ((aligned(x))) +#define ATTR_SECTION(x) __attribute__ ((section(x))) + +void usb_peripheral_reset(); + +void usb_device_init( + const uint_fast8_t device_ordinal, + usb_device_t* const device +); + +void usb_run( + usb_device_t* const device +); + +void usb_run_tasks( + const usb_device_t* const device +); + +usb_speed_t usb_speed( + const usb_device_t* const device +); + +void usb_set_address_immediate( + const usb_device_t* const device, + const uint_fast8_t address +); + +void usb_set_address_deferred( + const usb_device_t* const device, + const uint_fast8_t address +); + +void usb_endpoint_init( + const usb_endpoint_t* const endpoint +); + +void usb_endpoint_schedule( + const usb_endpoint_t* const endpoint, + void* const data, + const uint32_t maximum_length +); + +void usb_endpoint_schedule_ack( + const usb_endpoint_t* const endpoint +); + +void usb_endpoint_stall( + const usb_endpoint_t* const endpoint +); + +void usb_endpoint_disable( + const usb_endpoint_t* const endpoint +); + +void usb_endpoint_flush( + const usb_endpoint_t* const endpoint +); + +bool usb_endpoint_is_ready( + const usb_endpoint_t* const endpoint +); + +void usb_endpoint_prime( + const usb_endpoint_t* const endpoint, + usb_transfer_descriptor_t* const first_td +); + +#endif//__USB_H__ diff --git a/firmware/usb_performance/usb_descriptor.c b/firmware/usb_performance/usb_descriptor.c new file mode 100644 index 00000000..704978a3 --- /dev/null +++ b/firmware/usb_performance/usb_descriptor.c @@ -0,0 +1,169 @@ +#include + +#include "usb_type.h" + +#define USB_VENDOR_ID (0x1D50) +#define USB_PRODUCT_ID (0x604B) + +#define USB_WORD(x) (x & 0xFF), ((x >> 8) & 0xFF) + +#define USB_MAX_PACKET0 (64) +#define USB_MAX_PACKET_BULK_FS (64) +#define USB_MAX_PACKET_BULK_HS (512) + +#define USB_BULK_IN_EP_ADDR (0x81) +#define USB_BULK_OUT_EP_ADDR (0x02) + +#define USB_STRING_LANGID (0x0409) + +uint8_t usb_descriptor_device[] = { + 18, // bLength + USB_DESCRIPTOR_TYPE_DEVICE, // bDescriptorType + USB_WORD(0x0200), // bcdUSB + 0x00, // bDeviceClass + 0x00, // bDeviceSubClass + 0x00, // bDeviceProtocol + USB_MAX_PACKET0, // bMaxPacketSize0 + USB_WORD(USB_VENDOR_ID), // idVendor + USB_WORD(USB_PRODUCT_ID), // idProduct + USB_WORD(0x0100), // bcdDevice + 0x01, // iManufacturer + 0x02, // iProduct + 0x00, // iSerialNumber + 0x01 // bNumConfigurations +}; + +uint8_t usb_descriptor_device_qualifier[] = { + 10, // bLength + USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER, // bDescriptorType + USB_WORD(0x0200), // bcdUSB + 0x00, // bDeviceClass + 0x00, // bDeviceSubClass + 0x00, // bDeviceProtocol + 64, // bMaxPacketSize0 + 0x01, // bNumOtherSpeedConfigurations + 0x00 // bReserved +}; + +uint8_t usb_descriptor_configuration_full_speed[] = { + 9, // bLength + USB_DESCRIPTOR_TYPE_CONFIGURATION, // bDescriptorType + USB_WORD(32), // wTotalLength + 0x01, // bNumInterfaces + 0x01, // bConfigurationValue + 0x00, // iConfiguration + 0x80, // bmAttributes: USB-powered + 250, // bMaxPower: 500mA + + 9, // bLength + USB_DESCRIPTOR_TYPE_INTERFACE, // bDescriptorType + 0x00, // bInterfaceNumber + 0x00, // bAlternateSetting + 0x02, // bNumEndpoints + 0xFF, // bInterfaceClass: vendor-specific + 0xFF, // bInterfaceSubClass + 0xFF, // bInterfaceProtocol: vendor-specific + 0x00, // iInterface + + 7, // bLength + USB_DESCRIPTOR_TYPE_ENDPOINT, // bDescriptorType + USB_BULK_IN_EP_ADDR, // bEndpointAddress + 0x02, // bmAttributes: BULK + USB_WORD(USB_MAX_PACKET_BULK_FS), // wMaxPacketSize + 0x00, // bInterval: no NAK + + 7, // bLength + USB_DESCRIPTOR_TYPE_ENDPOINT, // bDescriptorType + USB_BULK_OUT_EP_ADDR, // bEndpointAddress + 0x02, // bmAttributes: BULK + USB_WORD(USB_MAX_PACKET_BULK_FS), // wMaxPacketSize + 0x00, // bInterval: no NAK + + 0, // TERMINATOR +}; + +uint8_t usb_descriptor_configuration_high_speed[] = { + 9, // bLength + USB_DESCRIPTOR_TYPE_CONFIGURATION, // bDescriptorType + USB_WORD(32), // wTotalLength + 0x01, // bNumInterfaces + 0x01, // bConfigurationValue + 0x00, // iConfiguration + 0x80, // bmAttributes: USB-powered + 250, // bMaxPower: 500mA + + 9, // bLength + USB_DESCRIPTOR_TYPE_INTERFACE, // bDescriptorType + 0x00, // bInterfaceNumber + 0x00, // bAlternateSetting + 0x02, // bNumEndpoints + 0xFF, // bInterfaceClass: vendor-specific + 0xFF, // bInterfaceSubClass + 0xFF, // bInterfaceProtocol: vendor-specific + 0x00, // iInterface + + 7, // bLength + USB_DESCRIPTOR_TYPE_ENDPOINT, // bDescriptorType + USB_BULK_IN_EP_ADDR, // bEndpointAddress + 0x02, // bmAttributes: BULK + USB_WORD(USB_MAX_PACKET_BULK_HS), // wMaxPacketSize + 0x00, // bInterval: no NAK + + 7, // bLength + USB_DESCRIPTOR_TYPE_ENDPOINT, // bDescriptorType + USB_BULK_OUT_EP_ADDR, // bEndpointAddress + 0x02, // bmAttributes: BULK + USB_WORD(USB_MAX_PACKET_BULK_HS), // wMaxPacketSize + 0x00, // bInterval: no NAK + + 0, // TERMINATOR +}; + +uint8_t usb_descriptor_string_languages[] = { + 0x04, // bLength + USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType + USB_WORD(USB_STRING_LANGID), // wLANGID +}; + +uint8_t usb_descriptor_string_manufacturer[] = { + 40, // bLength + USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType + 'G', 0x00, + 'r', 0x00, + 'e', 0x00, + 'a', 0x00, + 't', 0x00, + ' ', 0x00, + 'S', 0x00, + 'c', 0x00, + 'o', 0x00, + 't', 0x00, + 't', 0x00, + ' ', 0x00, + 'G', 0x00, + 'a', 0x00, + 'd', 0x00, + 'g', 0x00, + 'e', 0x00, + 't', 0x00, + 's', 0x00, +}; + +uint8_t usb_descriptor_string_product[] = { + 14, // bLength + USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType + 'H', 0x00, + 'a', 0x00, + 'c', 0x00, + 'k', 0x00, + 'R', 0x00, + 'F', 0x00, +}; + +uint8_t* const usb_descriptor_strings[] = { + usb_descriptor_string_languages, + usb_descriptor_string_manufacturer, + usb_descriptor_string_product, + + 0, // TERMINATOR +}; diff --git a/firmware/usb_performance/usb_descriptor.h b/firmware/usb_performance/usb_descriptor.h new file mode 100644 index 00000000..91026296 --- /dev/null +++ b/firmware/usb_performance/usb_descriptor.h @@ -0,0 +1,12 @@ +#include + +extern uint8_t usb_descriptor_device[]; +extern uint8_t usb_descriptor_device_qualifier[]; +extern uint8_t usb_descriptor_configuration_full_speed[]; +extern uint8_t usb_descriptor_configuration_high_speed[]; +extern uint8_t usb_descriptor_string_languages[]; +extern uint8_t usb_descriptor_string_manufacturer[]; +extern uint8_t usb_descriptor_string_product[]; +extern uint8_t usb_descriptor_string_serial_number[]; + +extern uint8_t* usb_descriptor_strings[]; diff --git a/firmware/usb_performance/usb_request.c b/firmware/usb_performance/usb_request.c new file mode 100644 index 00000000..08aacbc6 --- /dev/null +++ b/firmware/usb_performance/usb_request.c @@ -0,0 +1,63 @@ +#include "usb_request.h" + +#include + +static void usb_request( + usb_endpoint_t* const endpoint, + const usb_transfer_stage_t stage +) { + usb_request_handler_fn handler = 0; + + switch( endpoint->setup.request_type & USB_SETUP_REQUEST_TYPE_mask ) { + case USB_SETUP_REQUEST_TYPE_STANDARD: + handler = usb_request_handlers.standard; + break; + + case USB_SETUP_REQUEST_TYPE_CLASS: + handler = usb_request_handlers.class; + break; + + case USB_SETUP_REQUEST_TYPE_VENDOR: + handler = usb_request_handlers.vendor; + break; + + case USB_SETUP_REQUEST_TYPE_RESERVED: + handler = usb_request_handlers.reserved; + break; + } + + if( handler ) { + handler(endpoint, stage); + } +} + +void usb_setup_complete( + usb_endpoint_t* const endpoint +) { + usb_request(endpoint, USB_TRANSFER_STAGE_SETUP); +} + +void usb_control_out_complete( + usb_endpoint_t* const endpoint +) { + const bool device_to_host = + endpoint->setup.request_type >> USB_SETUP_REQUEST_TYPE_DATA_TRANSFER_DIRECTION_shift; + if( device_to_host ) { + usb_request(endpoint, USB_TRANSFER_STAGE_STATUS); + } else { + usb_request(endpoint, USB_TRANSFER_STAGE_DATA); + } +} + +void usb_control_in_complete( + usb_endpoint_t* const endpoint +) { + const bool device_to_host = + endpoint->setup.request_type >> USB_SETUP_REQUEST_TYPE_DATA_TRANSFER_DIRECTION_shift; + if( device_to_host ) { + usb_request(endpoint, USB_TRANSFER_STAGE_DATA); + } else { + usb_request(endpoint, USB_TRANSFER_STAGE_STATUS); + } +} + diff --git a/firmware/usb_performance/usb_request.h b/firmware/usb_performance/usb_request.h new file mode 100644 index 00000000..51833b02 --- /dev/null +++ b/firmware/usb_performance/usb_request.h @@ -0,0 +1,45 @@ +#ifndef __USB_REQUEST_H__ +#define __USB_REQUEST_H__ + +#include "usb_type.h" + +typedef enum { + USB_RESPONSE_NONE, + USB_RESPONSE_IN, + USB_RESPONSE_OUT, + USB_RESPONSE_STALL, +} usb_endpoint_type_t; + +typedef enum { + USB_TRANSFER_STAGE_SETUP, + USB_TRANSFER_STAGE_DATA, + USB_TRANSFER_STAGE_STATUS, +} usb_transfer_stage_t; + +typedef void (*usb_request_handler_fn)( + usb_endpoint_t* const response, + const usb_transfer_stage_t stage +); + +typedef struct { + usb_request_handler_fn standard; + usb_request_handler_fn class; + usb_request_handler_fn vendor; + usb_request_handler_fn reserved; +} usb_request_handlers_t; + +extern const usb_request_handlers_t usb_request_handlers; + +void usb_setup_complete( + usb_endpoint_t* const endpoint +); + +void usb_control_in_complete( + usb_endpoint_t* const endpoint +); + +void usb_control_out_complete( + usb_endpoint_t* const endpoint +); + +#endif//__USB_REQUEST_H__ diff --git a/firmware/usb_performance/usb_standard_request.c b/firmware/usb_performance/usb_standard_request.c new file mode 100644 index 00000000..18330b13 --- /dev/null +++ b/firmware/usb_performance/usb_standard_request.c @@ -0,0 +1,257 @@ +#include + +#include "usb_standard_request.h" + +#include "usb.h" +#include "usb_type.h" +#include "usb_descriptor.h" + +const uint8_t* usb_endpoint_descriptor( + const usb_endpoint_t* const endpoint +) { + const usb_configuration_t* const configuration = endpoint->device->configuration; + if( configuration ) { + const uint8_t* descriptor = configuration->descriptor; + while( descriptor[0] != 0 ) { + if( descriptor[1] == USB_DESCRIPTOR_TYPE_ENDPOINT ) { + if( descriptor[2] == endpoint->address ) { + return descriptor; + } + } + descriptor += descriptor[0]; + } + } + + return 0; +} + +uint_fast16_t usb_endpoint_descriptor_max_packet_size( + const uint8_t* const endpoint_descriptor +) { + return (endpoint_descriptor[5] << 8) | endpoint_descriptor[4]; +} + +usb_transfer_type_t usb_endpoint_descriptor_transfer_type( + const uint8_t* const endpoint_descriptor +) { + return (endpoint_descriptor[3] & 0x3); +} + +extern bool usb_set_configuration( + usb_device_t* const device, + const uint_fast8_t configuration_number +); + +static void usb_send_descriptor( + usb_endpoint_t* const endpoint, + uint8_t* const descriptor_data +) { + const uint32_t setup_length = (endpoint->setup.length_h << 8) | endpoint->setup.length_l; + uint32_t descriptor_length = descriptor_data[0]; + if( descriptor_data[1] == USB_DESCRIPTOR_TYPE_CONFIGURATION ) { + descriptor_length = (descriptor_data[3] << 8) | descriptor_data[2]; + } + usb_endpoint_schedule( + endpoint->in, + descriptor_data, + (setup_length > descriptor_length) ? descriptor_length : setup_length + ); +} + +static void usb_send_descriptor_string( + usb_endpoint_t* const endpoint +) { + uint_fast8_t index = endpoint->setup.value_l; + for( uint_fast8_t i=0; usb_descriptor_strings[i] != 0; i++ ) { + if( i == index ) { + usb_send_descriptor(endpoint, usb_descriptor_strings[i]); + return; + } + } + + usb_endpoint_stall(endpoint); +} + +static void usb_standard_request_get_descriptor_setup( + usb_endpoint_t* const endpoint +) { + switch( endpoint->setup.value_h ) { + case USB_DESCRIPTOR_TYPE_DEVICE: + usb_send_descriptor(endpoint, usb_descriptor_device); + break; + + case USB_DESCRIPTOR_TYPE_CONFIGURATION: + // TODO: Duplicated code. Refactor. + if( usb_speed(endpoint->device) == USB_SPEED_HIGH ) { + usb_send_descriptor(endpoint, usb_descriptor_configuration_high_speed); + } else { + usb_send_descriptor(endpoint, usb_descriptor_configuration_full_speed); + } + break; + + case USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER: + usb_send_descriptor(endpoint, usb_descriptor_device_qualifier); + break; + + case USB_DESCRIPTOR_TYPE_OTHER_SPEED_CONFIGURATION: + // TODO: Duplicated code. Refactor. + if( usb_speed(endpoint->device) == USB_SPEED_HIGH ) { + usb_send_descriptor(endpoint, usb_descriptor_configuration_full_speed); + } else { + usb_send_descriptor(endpoint, usb_descriptor_configuration_high_speed); + } + break; + + case USB_DESCRIPTOR_TYPE_STRING: + usb_send_descriptor_string(endpoint); + break; + + case USB_DESCRIPTOR_TYPE_INTERFACE: + case USB_DESCRIPTOR_TYPE_ENDPOINT: + default: + usb_endpoint_stall(endpoint); + break; + } +} + +static void usb_standard_request_get_descriptor( + usb_endpoint_t* const endpoint, + const usb_transfer_stage_t stage +) { + switch( stage ) { + case USB_TRANSFER_STAGE_SETUP: + usb_standard_request_get_descriptor_setup(endpoint); + usb_endpoint_schedule_ack(endpoint->out); + break; + + case USB_TRANSFER_STAGE_DATA: + break; + + case USB_TRANSFER_STAGE_STATUS: + break; + + } +} + +/*********************************************************************/ + +static void usb_standard_request_set_address( + usb_endpoint_t* const endpoint, + const usb_transfer_stage_t stage +) { + switch( stage ) { + case USB_TRANSFER_STAGE_SETUP: + usb_set_address_deferred(endpoint->device, endpoint->setup.value_l); + usb_endpoint_schedule_ack(endpoint->in); + break; + + case USB_TRANSFER_STAGE_DATA: + break; + + case USB_TRANSFER_STAGE_STATUS: + /* NOTE: Not necessary to set address here, as DEVICEADR.USBADRA bit + * will cause controller to automatically perform set address + * operation on IN ACK. + */ + break; + + default: + break; + } +} + +/*********************************************************************/ + +static void usb_standard_request_set_configuration_setup( + usb_endpoint_t* const endpoint +) { + const uint8_t usb_configuration = endpoint->setup.value_l; + if( usb_set_configuration(endpoint->device, usb_configuration) ) { + if( usb_configuration == 0 ) { + // TODO: Should this be done immediately? + usb_set_address_immediate(endpoint->device, 0); + } + usb_endpoint_schedule_ack(endpoint->in); + } else { + usb_endpoint_stall(endpoint); + } +} + +static void usb_standard_request_set_configuration( + usb_endpoint_t* const endpoint, + const usb_transfer_stage_t stage +) { + switch( stage ) { + case USB_TRANSFER_STAGE_SETUP: + usb_standard_request_set_configuration_setup(endpoint); + break; + + case USB_TRANSFER_STAGE_DATA: + break; + + case USB_TRANSFER_STAGE_STATUS: + break; + + } +} + +/*********************************************************************/ + +static void usb_standard_request_get_configuration_setup( + usb_endpoint_t* const endpoint +) { + if( (endpoint->setup.length_h == 0) && (endpoint->setup.length_l == 1) ) { + endpoint->buffer[0] = 0; + if( endpoint->device->configuration ) { + endpoint->buffer[0] = endpoint->device->configuration->number; + } + usb_endpoint_schedule(endpoint->in, &endpoint->buffer, 1); + } else { + usb_endpoint_stall(endpoint); + } +} + +static void usb_standard_request_get_configuration( + usb_endpoint_t* const endpoint, + const usb_transfer_stage_t stage +) { + switch( stage ) { + case USB_TRANSFER_STAGE_SETUP: + usb_standard_request_get_configuration_setup(endpoint); + usb_endpoint_schedule_ack(endpoint->out); + break; + + case USB_TRANSFER_STAGE_DATA: + break; + + case USB_TRANSFER_STAGE_STATUS: + break; + + } +} + +/*********************************************************************/ + +void usb_standard_request( + usb_endpoint_t* const endpoint, + const usb_transfer_stage_t stage +) { + switch( endpoint->setup.request ) { + case USB_STANDARD_REQUEST_GET_DESCRIPTOR: + usb_standard_request_get_descriptor(endpoint, stage); + break; + + case USB_STANDARD_REQUEST_SET_ADDRESS: + usb_standard_request_set_address(endpoint, stage); + break; + + case USB_STANDARD_REQUEST_SET_CONFIGURATION: + usb_standard_request_set_configuration(endpoint, stage); + break; + + case USB_STANDARD_REQUEST_GET_CONFIGURATION: + usb_standard_request_get_configuration(endpoint, stage); + break; + + } +} diff --git a/firmware/usb_performance/usb_standard_request.h b/firmware/usb_performance/usb_standard_request.h new file mode 100644 index 00000000..87479942 --- /dev/null +++ b/firmware/usb_performance/usb_standard_request.h @@ -0,0 +1,24 @@ +#ifndef __USB_STANDARD_REQUEST_H__ +#define __USB_STANDARD_REQUEST_H__ + +#include "usb_type.h" +#include "usb_request.h" + +void usb_standard_request( + usb_endpoint_t* const endpoint, + const usb_transfer_stage_t stage +); + +const uint8_t* usb_endpoint_descriptor( + const usb_endpoint_t* const endpoint +); + +uint_fast16_t usb_endpoint_descriptor_max_packet_size( + const uint8_t* const endpoint_descriptor +); + +usb_transfer_type_t usb_endpoint_descriptor_transfer_type( + const uint8_t* const endpoint_descriptor +); + +#endif//__USB_STANDARD_REQUEST_H__ diff --git a/firmware/usb_performance/usb_type.h b/firmware/usb_performance/usb_type.h new file mode 100644 index 00000000..0393c1d0 --- /dev/null +++ b/firmware/usb_performance/usb_type.h @@ -0,0 +1,101 @@ +#ifndef __USB_TYPE_H__ +#define __USB_TYPE_H__ + +#include +#include + +typedef struct { + uint8_t request_type; + uint8_t request; + uint8_t value_l; + uint8_t value_h; + uint8_t index_l; + uint8_t index_h; + uint8_t length_l; + uint8_t length_h; +} usb_setup_t; + +typedef enum { + USB_STANDARD_REQUEST_GET_STATUS = 0, + USB_STANDARD_REQUEST_CLEAR_FEATURE = 1, + USB_STANDARD_REQUEST_SET_FEATURE = 3, + USB_STANDARD_REQUEST_SET_ADDRESS = 5, + USB_STANDARD_REQUEST_GET_DESCRIPTOR = 6, + USB_STANDARD_REQUEST_SET_DESCRIPTOR = 7, + USB_STANDARD_REQUEST_GET_CONFIGURATION = 8, + USB_STANDARD_REQUEST_SET_CONFIGURATION = 9, + USB_STANDARD_REQUEST_GET_INTERFACE = 10, + USB_STANDARD_REQUEST_SET_INTERFACE = 11, + USB_STANDARD_REQUEST_SYNCH_FRAME = 12, +} usb_standard_request_t; + +typedef enum { + USB_SETUP_REQUEST_TYPE_shift = 5, + USB_SETUP_REQUEST_TYPE_mask = 3 << USB_SETUP_REQUEST_TYPE_shift, + + USB_SETUP_REQUEST_TYPE_STANDARD = 0 << USB_SETUP_REQUEST_TYPE_shift, + USB_SETUP_REQUEST_TYPE_CLASS = 1 << USB_SETUP_REQUEST_TYPE_shift, + USB_SETUP_REQUEST_TYPE_VENDOR = 2 << USB_SETUP_REQUEST_TYPE_shift, + USB_SETUP_REQUEST_TYPE_RESERVED = 3 << USB_SETUP_REQUEST_TYPE_shift, + + USB_SETUP_REQUEST_TYPE_DATA_TRANSFER_DIRECTION_shift = 7, + USB_SETUP_REQUEST_TYPE_DATA_TRANSFER_DIRECTION_mask = 1 << USB_SETUP_REQUEST_TYPE_DATA_TRANSFER_DIRECTION_shift, + USB_SETUP_REQUEST_TYPE_DATA_TRANSFER_DIRECTION_HOST_TO_DEVICE = 0 << USB_SETUP_REQUEST_TYPE_DATA_TRANSFER_DIRECTION_shift, + USB_SETUP_REQUEST_TYPE_DATA_TRANSFER_DIRECTION_DEVICE_TO_HOST = 1 << USB_SETUP_REQUEST_TYPE_DATA_TRANSFER_DIRECTION_shift, +} usb_setup_request_type_t; + +typedef enum { + USB_TRANSFER_DIRECTION_OUT = 0, + USB_TRANSFER_DIRECTION_IN = 1, +} usb_transfer_direction_t; + +typedef enum { + USB_DESCRIPTOR_TYPE_DEVICE = 1, + USB_DESCRIPTOR_TYPE_CONFIGURATION = 2, + USB_DESCRIPTOR_TYPE_STRING = 3, + USB_DESCRIPTOR_TYPE_INTERFACE = 4, + USB_DESCRIPTOR_TYPE_ENDPOINT = 5, + USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER = 6, + USB_DESCRIPTOR_TYPE_OTHER_SPEED_CONFIGURATION = 7, + USB_DESCRIPTOR_TYPE_INTERFACE_POWER = 8, +} usb_descriptor_type_t; + +typedef enum { + USB_TRANSFER_TYPE_CONTROL = 0, + USB_TRANSFER_TYPE_ISOCHRONOUS = 1, + USB_TRANSFER_TYPE_BULK = 2, + USB_TRANSFER_TYPE_INTERRUPT = 3, +} usb_transfer_type_t; + +typedef enum { + USB_SPEED_LOW = 0, + USB_SPEED_FULL = 1, + USB_SPEED_HIGH = 2, + USB_SPEED_SUPER = 3, +} usb_speed_t; + +typedef struct { + const uint8_t* const descriptor; + const uint32_t number; + const usb_speed_t speed; +} usb_configuration_t; + +typedef struct { + const uint8_t* const descriptor; + usb_configuration_t* (*configurations)[]; + const usb_configuration_t* configuration; +} usb_device_t; + +typedef struct usb_endpoint_t usb_endpoint_t; +struct usb_endpoint_t { + usb_setup_t setup; + uint8_t buffer[8]; // Buffer for use during IN stage. + const uint_fast8_t address; + usb_device_t* const device; + usb_endpoint_t* const in; + usb_endpoint_t* const out; + void (*setup_complete)(usb_endpoint_t* const endpoint); + void (*transfer_complete)(usb_endpoint_t* const endpoint); +}; + +#endif//__USB_TYPE_H__ From 749671029a243c7580f32b51f0ae4f6ccf827e4e Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sat, 6 Oct 2012 18:58:59 -0700 Subject: [PATCH 23/41] New version of the usb_performance test firmware, with the new (and functional) USB "stack". --- firmware/usb_performance/Makefile | 5 + firmware/usb_performance/usb_performance.c | 296 ++++++++++----------- 2 files changed, 143 insertions(+), 158 deletions(-) diff --git a/firmware/usb_performance/Makefile b/firmware/usb_performance/Makefile index 403ea76a..3b874fb7 100644 --- a/firmware/usb_performance/Makefile +++ b/firmware/usb_performance/Makefile @@ -3,6 +3,11 @@ BINARY = usb_performance SRC = $(BINARY).c \ + usb.c \ + usb_request.c \ + usb_standard_request.c \ + usb_descriptor.c \ + ../common/fault_handler.c \ ../common/hackrf_core.c \ ../common/si5351c.c \ ../common/bitband.c diff --git a/firmware/usb_performance/usb_performance.c b/firmware/usb_performance/usb_performance.c index cb4f172d..7734d1e4 100644 --- a/firmware/usb_performance/usb_performance.c +++ b/firmware/usb_performance/usb_performance.c @@ -1,175 +1,158 @@ #include #include -#include #include -#include #include -#include -#include -#include +#include "usb.h" +#include "usb_type.h" +#include "usb_request.h" +#include "usb_descriptor.h" +#include "usb_standard_request.h" -#include +volatile uint_fast8_t usb_bulk_buffer_index = 0; +uint8_t usb_bulk_buffer[2][16384] ATTR_SECTION(".usb_data"); +const uint_fast8_t usb_bulk_buffer_count = + sizeof(usb_bulk_buffer) / sizeof(usb_bulk_buffer[0]); -#define ATTR_ALIGNED(x) __attribute__ ((aligned(x))) -#define __DATA(x) __attribute__ ((section("x"))) - -void usb_reset_peripheral() { - RESET_CTRL0 = RESET_CTRL0_USB0_RST; - RESET_CTRL0 = 0; - - while( (RESET_ACTIVE_STATUS0 & RESET_CTRL0_USB0_RST) == 0 ); +static void usb_endpoint_bulk_transfer(usb_endpoint_t* const endpoint) { + usb_endpoint_schedule(endpoint, usb_bulk_buffer[usb_bulk_buffer_index], sizeof(usb_bulk_buffer[usb_bulk_buffer_index])); + usb_bulk_buffer_index = (usb_bulk_buffer_index + 1) % usb_bulk_buffer_count; } -void usb_enable_phy() { - peripheral_bitband_clear(&CREG_CREG0, CREG_CREG0_USB0PHY_SHIFT); -} +usb_configuration_t usb_configuration_high_speed = { + .number = 1, + .speed = USB_SPEED_HIGH, + .descriptor = usb_descriptor_configuration_high_speed, +}; -void usb_wait_for_endpoint_priming_to_finish() { - while( USB0_ENDPTPRIME ); -} +usb_configuration_t usb_configuration_full_speed = { + .number = 1, + .speed = USB_SPEED_FULL, + .descriptor = usb_descriptor_configuration_full_speed, +}; -void usb_wait_for_endpoint_flushing_to_finish() { - while( USB0_ENDPTFLUSH ); -} +usb_configuration_t* usb_configurations[] = { + &usb_configuration_high_speed, + &usb_configuration_full_speed, + 0, +}; -void usb_flush_all_primed_endpoints() { - usb_wait_for_endpoint_priming_to_finish(); - USB0_ENDPTFLUSH = ~0; - usb_wait_for_endpoint_flushing_to_finish(); -} +usb_device_t usb_device = { + .descriptor = usb_descriptor_device, + .configurations = &usb_configurations, + .configuration = 0, +}; -void usb_stop_controller() { - peripheral_bitband_clear(&USB0_USBCMD_D, USB0_USBCMD_D_RS_SHIFT); -} +usb_endpoint_t usb_endpoint_control_out; +usb_endpoint_t usb_endpoint_control_in; -void usb_run_controller() { - peripheral_bitband_set(&USB0_USBCMD_D, USB0_USBCMD_D_RS_SHIFT); -} +usb_endpoint_t usb_endpoint_control_out = { + .address = 0x00, + .device = &usb_device, + .in = &usb_endpoint_control_in, + .out = &usb_endpoint_control_out, + .setup_complete = usb_setup_complete, + .transfer_complete = usb_control_out_complete, +}; -uint_fast8_t usb_controller_is_resetting() { - return (USB0_USBCMD_D & USB0_USBCMD_D_RST) != 0; -} +usb_endpoint_t usb_endpoint_control_in = { + .address = 0x80, + .device = &usb_device, + .in = &usb_endpoint_control_in, + .out = &usb_endpoint_control_out, + .setup_complete = 0, + .transfer_complete = usb_control_in_complete, +}; -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 << )); -} +// NOTE: Endpoint number for IN and OUT are different. I wish I had some +// evidence that having BULK IN and OUT on separate endpoint numbers was +// actually a good idea. Seems like everybody does it that way, but why? -void usb_disable_all_endpoints() { - // Endpoint 0 is always enabled. - for(uint_fast8_t i=1; i<6; i++) { - usb_disable_endpoint(i); - } -} +usb_endpoint_t usb_endpoint_bulk_in = { + .address = 0x81, + .device = &usb_device, + .in = &usb_endpoint_bulk_in, + .out = 0, + .setup_complete = 0, + .transfer_complete = usb_endpoint_bulk_transfer, +}; -void usb_clear_all_pending_interrupts() { - -} +usb_endpoint_t usb_endpoint_bulk_out = { + .address = 0x02, + .device = &usb_device, + .in = 0, + .out = &usb_endpoint_bulk_out, + .setup_complete = 0, + .transfer_complete = usb_endpoint_bulk_transfer, +}; -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; +const usb_request_handlers_t usb_request_handlers = { + .standard = usb_standard_request, + .class = 0, + .vendor = 0, + .reserved = 0, +}; -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; +// TODO: Seems like this should live in usb_standard_request.c. +bool usb_set_configuration( + usb_device_t* const device, + const uint_fast8_t configuration_number +) { + const usb_configuration_t* new_configuration = 0; + if( configuration_number != 0 ) { + + // Locate requested configuration. + if( device->configurations ) { + usb_configuration_t** configurations = *(device->configurations); + uint32_t i = 0; + const usb_speed_t usb_speed_current = usb_speed(device); + while( configurations[i] ) { + if( (configurations[i]->speed == usb_speed_current) && + (configurations[i]->number == configuration_number) ) { + new_configuration = configurations[i]; + break; + } + i++; + } + } -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 = - USB0_USBMODE_D_SLOM | - USB0_USBMODE_D_CM1_0(2); - - 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]; + // Requested configuration not found: request error. + if( new_configuration == 0 ) { + return false; + } } - // 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; -} + if( new_configuration != device->configuration ) { + // Configuration changed. + device->configuration = new_configuration; -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); -} + // TODO: This is lame. There should be a way to link stuff together so + // that changing the configuration will initialize the related + // endpoints. No hard-coding crap like this! Then, when there's no more + // hard-coding, this whole function can move into a shared/reusable + // library. + if( device->configuration && (device->configuration->number == 1) ) { + usb_endpoint_init(&usb_endpoint_bulk_in); + usb_endpoint_init(&usb_endpoint_bulk_out); + + usb_endpoint_bulk_transfer(&usb_endpoint_bulk_out); + //usb_endpoint_bulk_transfer(&usb_endpoint_bulk_in); + } else { + usb_endpoint_disable(&usb_endpoint_bulk_in); + usb_endpoint_disable(&usb_endpoint_bulk_out); + } + + if( device->configuration ) { + gpio_set(PORT_LED1_3, PIN_LED1); + } else { + gpio_clear(PORT_LED1_3, PIN_LED1); + } + } + + return true; +}; int main(void) { pin_setup(); @@ -181,20 +164,17 @@ int main(void) { CGU_BASE_APB1_CLK = CGU_BASE_APB1_CLK_AUTOBLOCK | CGU_BASE_APB1_CLK_CLK_SEL(CGU_SRC_PLL1); - - 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(); + + usb_peripheral_reset(); + + usb_device_init(0, &usb_device); + + usb_endpoint_init(&usb_endpoint_control_out); + usb_endpoint_init(&usb_endpoint_control_in); + + usb_run(&usb_device); while (1) { - delay(10000000); - gpio_clear(PORT_LED1_3, PIN_LED1); - delay(10000000); - gpio_set(PORT_LED1_3, PIN_LED1); } return 0; From aff5cc0c69f80734fa14a34004290df314136116 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sat, 6 Oct 2012 19:11:19 -0700 Subject: [PATCH 24/41] Oops, forgot license header on new files... --- firmware/usb_performance/Makefile | 20 ++++++++++++++++++ firmware/usb_performance/usb.c | 21 +++++++++++++++++++ firmware/usb_performance/usb.h | 21 +++++++++++++++++++ firmware/usb_performance/usb_descriptor.c | 21 +++++++++++++++++++ firmware/usb_performance/usb_descriptor.h | 21 +++++++++++++++++++ firmware/usb_performance/usb_performance.c | 21 +++++++++++++++++++ firmware/usb_performance/usb_request.c | 21 +++++++++++++++++++ firmware/usb_performance/usb_request.h | 21 +++++++++++++++++++ .../usb_performance/usb_standard_request.c | 21 +++++++++++++++++++ .../usb_performance/usb_standard_request.h | 21 +++++++++++++++++++ firmware/usb_performance/usb_type.h | 21 +++++++++++++++++++ 11 files changed, 230 insertions(+) diff --git a/firmware/usb_performance/Makefile b/firmware/usb_performance/Makefile index 3b874fb7..ea65f127 100644 --- a/firmware/usb_performance/Makefile +++ b/firmware/usb_performance/Makefile @@ -1,4 +1,24 @@ # Hey Emacs, this is a -*- makefile -*- +# +# Copyright 2012 Jared Boone +# +# This file is part of HackRF. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# BINARY = usb_performance diff --git a/firmware/usb_performance/usb.c b/firmware/usb_performance/usb.c index a47c47c2..73ed3592 100644 --- a/firmware/usb_performance/usb.c +++ b/firmware/usb_performance/usb.c @@ -1,3 +1,24 @@ +/* + * Copyright 2012 Jared Boone + * + * This file is part of HackRF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + #include #include diff --git a/firmware/usb_performance/usb.h b/firmware/usb_performance/usb.h index 86c1683d..2f2104c5 100644 --- a/firmware/usb_performance/usb.h +++ b/firmware/usb_performance/usb.h @@ -1,3 +1,24 @@ +/* + * Copyright 2012 Jared Boone + * + * This file is part of HackRF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + #ifndef __USB_H__ #define __USB_H__ diff --git a/firmware/usb_performance/usb_descriptor.c b/firmware/usb_performance/usb_descriptor.c index 704978a3..e27218bb 100644 --- a/firmware/usb_performance/usb_descriptor.c +++ b/firmware/usb_performance/usb_descriptor.c @@ -1,3 +1,24 @@ +/* + * Copyright 2012 Jared Boone + * + * This file is part of HackRF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + #include #include "usb_type.h" diff --git a/firmware/usb_performance/usb_descriptor.h b/firmware/usb_performance/usb_descriptor.h index 91026296..a1676f04 100644 --- a/firmware/usb_performance/usb_descriptor.h +++ b/firmware/usb_performance/usb_descriptor.h @@ -1,3 +1,24 @@ +/* + * Copyright 2012 Jared Boone + * + * This file is part of HackRF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + #include extern uint8_t usb_descriptor_device[]; diff --git a/firmware/usb_performance/usb_performance.c b/firmware/usb_performance/usb_performance.c index 7734d1e4..ef38a4b4 100644 --- a/firmware/usb_performance/usb_performance.c +++ b/firmware/usb_performance/usb_performance.c @@ -1,3 +1,24 @@ +/* + * Copyright 2012 Jared Boone + * + * This file is part of HackRF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + #include #include diff --git a/firmware/usb_performance/usb_request.c b/firmware/usb_performance/usb_request.c index 08aacbc6..df6ae427 100644 --- a/firmware/usb_performance/usb_request.c +++ b/firmware/usb_performance/usb_request.c @@ -1,3 +1,24 @@ +/* + * Copyright 2012 Jared Boone + * + * This file is part of HackRF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + #include "usb_request.h" #include diff --git a/firmware/usb_performance/usb_request.h b/firmware/usb_performance/usb_request.h index 51833b02..a637924f 100644 --- a/firmware/usb_performance/usb_request.h +++ b/firmware/usb_performance/usb_request.h @@ -1,3 +1,24 @@ +/* + * Copyright 2012 Jared Boone + * + * This file is part of HackRF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + #ifndef __USB_REQUEST_H__ #define __USB_REQUEST_H__ diff --git a/firmware/usb_performance/usb_standard_request.c b/firmware/usb_performance/usb_standard_request.c index 18330b13..1b42bd5e 100644 --- a/firmware/usb_performance/usb_standard_request.c +++ b/firmware/usb_performance/usb_standard_request.c @@ -1,3 +1,24 @@ +/* + * Copyright 2012 Jared Boone + * + * This file is part of HackRF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + #include #include "usb_standard_request.h" diff --git a/firmware/usb_performance/usb_standard_request.h b/firmware/usb_performance/usb_standard_request.h index 87479942..e96dba21 100644 --- a/firmware/usb_performance/usb_standard_request.h +++ b/firmware/usb_performance/usb_standard_request.h @@ -1,3 +1,24 @@ +/* + * Copyright 2012 Jared Boone + * + * This file is part of HackRF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + #ifndef __USB_STANDARD_REQUEST_H__ #define __USB_STANDARD_REQUEST_H__ diff --git a/firmware/usb_performance/usb_type.h b/firmware/usb_performance/usb_type.h index 0393c1d0..54287fd5 100644 --- a/firmware/usb_performance/usb_type.h +++ b/firmware/usb_performance/usb_type.h @@ -1,3 +1,24 @@ +/* + * Copyright 2012 Jared Boone + * + * This file is part of HackRF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + #ifndef __USB_TYPE_H__ #define __USB_TYPE_H__ From 4f9a5a1ba41cad483aeae2de1771f2f5c176e421 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Sat, 6 Oct 2012 19:14:55 -0700 Subject: [PATCH 25/41] Fix-ups to copyrights -- missing e-mail address and inconsistent formatting. --- firmware/common/bitband.c | 2 +- firmware/common/bitband.h | 2 +- firmware/common/fault_handler.c | 2 +- firmware/common/hackrf_core.c | 4 ++-- firmware/common/hackrf_core.h | 2 +- firmware/common/max5864.c | 2 +- firmware/common/max5864.h | 2 +- firmware/common/si5351c.c | 4 ++-- firmware/common/si5351c.h | 4 ++-- 9 files changed, 12 insertions(+), 12 deletions(-) diff --git a/firmware/common/bitband.c b/firmware/common/bitband.c index f55e806c..8f4e618b 100644 --- a/firmware/common/bitband.c +++ b/firmware/common/bitband.c @@ -1,5 +1,5 @@ /* - * Copyright 2012 Jared Boone + * Copyright 2012 Jared Boone * * This file is part of HackRF. * diff --git a/firmware/common/bitband.h b/firmware/common/bitband.h index d62b4759..03aef8d2 100644 --- a/firmware/common/bitband.h +++ b/firmware/common/bitband.h @@ -1,5 +1,5 @@ /* - * Copyright 2012 Jared Boone + * Copyright 2012 Jared Boone * * This file is part of HackRF. * diff --git a/firmware/common/fault_handler.c b/firmware/common/fault_handler.c index f82742f7..ccbfd185 100644 --- a/firmware/common/fault_handler.c +++ b/firmware/common/fault_handler.c @@ -1,5 +1,5 @@ /* - * Copyright 2012 Jared Boone + * Copyright 2012 Jared Boone * * This file is part of HackRF. * diff --git a/firmware/common/hackrf_core.c b/firmware/common/hackrf_core.c index 8686aedc..8bb58d3c 100644 --- a/firmware/common/hackrf_core.c +++ b/firmware/common/hackrf_core.c @@ -1,6 +1,6 @@ /* - * Copyright 2012 Michael Ossmann - * Copyright 2012 Jared Boone + * Copyright 2012 Michael Ossmann + * Copyright 2012 Jared Boone * * This file is part of HackRF. * diff --git a/firmware/common/hackrf_core.h b/firmware/common/hackrf_core.h index 69dedba9..37722b1c 100644 --- a/firmware/common/hackrf_core.h +++ b/firmware/common/hackrf_core.h @@ -1,7 +1,7 @@ /* * Copyright 2012 Michael Ossmann * Copyright 2012 Benjamin Vernoux - * Copyright (C) 2012 Jared Boone + * Copyright 2012 Jared Boone * * This file is part of HackRF. * diff --git a/firmware/common/max5864.c b/firmware/common/max5864.c index 711bdbbd..a0f5dcff 100644 --- a/firmware/common/max5864.c +++ b/firmware/common/max5864.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Jared Boone + * Copyright 2012 Jared Boone * * This file is part of HackRF. * diff --git a/firmware/common/max5864.h b/firmware/common/max5864.h index 0af59415..72519645 100644 --- a/firmware/common/max5864.h +++ b/firmware/common/max5864.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Jared Boone + * Copyright 2012 Jared Boone * * This file is part of HackRF. * diff --git a/firmware/common/si5351c.c b/firmware/common/si5351c.c index fa506150..eff4b498 100644 --- a/firmware/common/si5351c.c +++ b/firmware/common/si5351c.c @@ -1,6 +1,6 @@ /* - * Copyright 2012 Michael Ossmann - * Copyright 2012 Jared Boone + * Copyright 2012 Michael Ossmann + * Copyright 2012 Jared Boone * * This file is part of HackRF. * diff --git a/firmware/common/si5351c.h b/firmware/common/si5351c.h index 729619af..740da2f4 100644 --- a/firmware/common/si5351c.h +++ b/firmware/common/si5351c.h @@ -1,6 +1,6 @@ /* - * Copyright 2012 Michael Ossmann - * Copyright 2012 Jared Boone + * Copyright 2012 Michael Ossmann + * Copyright 2012 Jared Boone * * This file is part of HackRF. * From 685f5cdd6e291f300dec9f1b60f1ae79fc9bc0c6 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 10 Oct 2012 11:51:06 -0700 Subject: [PATCH 26/41] More detail in comments about Jellybean/Lemondrop clock destinations. --- firmware/common/hackrf_core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/firmware/common/hackrf_core.c b/firmware/common/hackrf_core.c index 8bb58d3c..3bca88df 100644 --- a/firmware/common/hackrf_core.c +++ b/firmware/common/hackrf_core.c @@ -53,9 +53,9 @@ void cpu_clock_init(void) /* * Jellybean/Lemondrop clocks: * CLK0 -> MAX2837 - * CLK1 -> MAX5864/CPLD - * CLK2 -> CPLD - * CLK3 -> CPLD + * CLK1 -> MAX5864/CPLD.GCLK0 + * CLK2 -> CPLD.GCLK1 + * CLK3 -> CPLD.GCLK2 * CLK4 -> LPC4330 * CLK5 -> RFFC5072 * CLK6 -> extra From f34e30510dfb537763e42144a7d14e9cafa6f04a Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 10 Oct 2012 13:36:10 -0700 Subject: [PATCH 27/41] Added fault handler header file, where I've defined the Cortex-M3/M4 SCB using a struct instead of a slew of #defines. This deviates from the libopencm3 method, but is superior in other ways. So, there you go. It's not in libopencm3, it's here. Added example (er, "reminder") code comment about registers to look at when debugging a Hard Fault. --- firmware/common/fault_handler.c | 15 ++++++- firmware/common/fault_handler.h | 73 +++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 firmware/common/fault_handler.h diff --git a/firmware/common/fault_handler.c b/firmware/common/fault_handler.c index ccbfd185..6127d538 100644 --- a/firmware/common/fault_handler.c +++ b/firmware/common/fault_handler.c @@ -21,6 +21,8 @@ #include +#include "fault_handler.h" + __attribute__((naked)) void hard_fault_handler(void) { __asm__("TST LR, #4"); @@ -30,15 +32,26 @@ void hard_fault_handler(void) { __asm__("B hard_fault_handler_c"); } + void hard_fault_handler_c(uint32_t* args) { // args[0-7]: r0, r1, r2, r3, r12, lr, pc, psr // Other interesting registers to examine: // CFSR: Configurable Fault Status Register // HFSR: Hard Fault Status Register // DFSR: Debug Fault Status Register - // AFSR: Auxiliary Fault Status Register + // AFSR: Auxiliary Fault Status Register // MMAR: MemManage Fault Address Register // BFAR: Bus Fault Address Register + + /* + if( SCB->HFSR & SCB_HFSR_FORCED ) { + if( SCB->CFSR & SCB_CFSR_BFSR_BFARVALID ) { + SCB->BFAR; + if( SCB->CFSR & CSCB_CFSR_BFSR_PRECISERR ) { + } + } + } + */ while(1); } diff --git a/firmware/common/fault_handler.h b/firmware/common/fault_handler.h new file mode 100644 index 00000000..f52e760e --- /dev/null +++ b/firmware/common/fault_handler.h @@ -0,0 +1,73 @@ +/* + * Copyright 2012 Jared Boone + * + * This file is part of HackRF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __FAULT_HANDLER__ +#define __FAULT_HANDLER__ + +#include + +#include + +// TODO: Move all this to a Cortex-M(?) include file, since these +// structures are supposedly the same between processors (to an +// undetermined extent). +typedef struct armv7m_scb_t armv7m_scb_t; +struct armv7m_scb_t { + volatile const uint32_t CPUID; + volatile uint32_t ICSR; + volatile uint32_t VTOR; + volatile uint32_t AIRCR; + volatile uint32_t SCR; + volatile uint32_t CCR; + volatile uint32_t SHPR1; + volatile uint32_t SHPR2; + volatile uint32_t SHPR3; + volatile uint32_t SHCSR; + volatile uint32_t CFSR; + volatile uint32_t HFSR; + volatile uint32_t DFSR; + volatile uint32_t MMFAR; + volatile uint32_t BFAR; + volatile uint32_t AFSR; + volatile const uint32_t ID_PFR0; + volatile const uint32_t ID_PFR1; + volatile const uint32_t ID_DFR0; + volatile const uint32_t ID_AFR0; + volatile const uint32_t ID_MMFR0; + volatile const uint32_t ID_MMFR1; + volatile const uint32_t ID_MMFR2; + volatile const uint32_t ID_MMFR3; + volatile const uint32_t ID_ISAR0; + volatile const uint32_t ID_ISAR1; + volatile const uint32_t ID_ISAR2; + volatile const uint32_t ID_ISAR3; + volatile const uint32_t ID_ISAR4; + volatile const uint32_t __reserved_0x74_0x87[5]; + volatile uint32_t CPACR; +} __attribute__((packed)); + +static armv7m_scb_t* const SCB = (armv7m_scb_t*)SCB_BASE; + +#define SCB_HFSR_DEBUGEVT (1 << 31) +#define SCB_HFSR_FORCED (1 << 30) +#define SCB_HFSR_VECTTBL (1 << 1) + +#endif//__FAULT_HANDLER__ From 39eb2682f9a8a4e7680bac5b7e83509e717f13ea Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 10 Oct 2012 14:27:21 -0700 Subject: [PATCH 28/41] Split ram_ahb memory region into two, with a 32K hole where the USB buffers live. Split ram region into two, representing the two local RAM buses. Remove reference to usbram.ld, since it's no longer necessary. --- firmware/common/LPC4330_M4.ld | 12 +++++--- firmware/common/LPC4330_M4_ROM_to_RAM.ld | 14 ++++++---- firmware/common/LPC4330_M4_ram_only.ld | 9 ++++-- firmware/common/usbram.ld | 35 ------------------------ 4 files changed, 22 insertions(+), 48 deletions(-) delete mode 100644 firmware/common/usbram.ld diff --git a/firmware/common/LPC4330_M4.ld b/firmware/common/LPC4330_M4.ld index 5edc3428..694fd265 100644 --- a/firmware/common/LPC4330_M4.ld +++ b/firmware/common/LPC4330_M4.ld @@ -26,12 +26,16 @@ MEMORY { /* rom is really the shadow region that points to SPI flash or elsewhere */ rom (rx) : ORIGIN = 0x00000000, LENGTH = 1M - ram (rwx) : ORIGIN = 0x10000000, LENGTH = 128K + ram_local1 (rwx) : ORIGIN = 0x10000000, LENGTH = 128K + ram_local2 (rwx) : ORIGIN = 0x10080000, LENGTH = 72K /* there are some additional RAM regions */ - ram_ahb (rwx) : ORIGIN = 0x20000000, LENGTH = 64K + ram_ahb1 (rwx) : ORIGIN = 0x20000000, LENGTH = 16K + /* Removed 32K of AHB SRAM for USB buffer. Straddles two blocks of RAM + * to get performance benefit of having two USB buffers addressable + * simultaneously (on two different buses of the AHB multilayer matrix) + */ + ram_ahb2 (rwx) : ORIGIN = 0x2000C000, LENGTH = 16K } /* Include the common ld script. */ INCLUDE libopencm3_lpc43xx.ld - -INCLUDE usbram.ld diff --git a/firmware/common/LPC4330_M4_ROM_to_RAM.ld b/firmware/common/LPC4330_M4_ROM_to_RAM.ld index f7e5886d..f6b1d008 100644 --- a/firmware/common/LPC4330_M4_ROM_to_RAM.ld +++ b/firmware/common/LPC4330_M4_ROM_to_RAM.ld @@ -29,13 +29,15 @@ MEMORY rom_flash (rx) : ORIGIN = 0x80000000, LENGTH = 1M /* rom is really the shadow region that points to SPI flash or elsewhere */ rom (rx) : ORIGIN = 0x00000000, LENGTH = 1M - ram (rwx) : ORIGIN = 0x10000000, LENGTH = 128K - /* there are some additional RAM regions for data */ - ram_data (rw) : ORIGIN = 0x10080000, LENGTH = 72K - ram_ahb (rwx) : ORIGIN = 0x20000000, LENGTH = 64K + ram_local1 (rwx) : ORIGIN = 0x10000000, LENGTH = 128K + ram_local2 (rwx) : ORIGIN = 0x10080000, LENGTH = 72K + ram_ahb1 (rwx) : ORIGIN = 0x20000000, LENGTH = 16K + /* Removed 32K of AHB SRAM for USB buffer. Straddles two blocks of RAM + * to get performance benefit of having two USB buffers addressable + * simultaneously (on two different buses of the AHB multilayer matrix) + */ + ram_ahb2 (rwx) : ORIGIN = 0x2000C000, LENGTH = 16K } /* Include the common ld script. */ INCLUDE libopencm3_lpc43xx_rom_to_ram.ld - -INCLUDE usbram.ld diff --git a/firmware/common/LPC4330_M4_ram_only.ld b/firmware/common/LPC4330_M4_ram_only.ld index 11bb1d88..4149fbd7 100644 --- a/firmware/common/LPC4330_M4_ram_only.ld +++ b/firmware/common/LPC4330_M4_ram_only.ld @@ -26,10 +26,13 @@ MEMORY { ram_local1 (rwx) : ORIGIN = 0x10000000, LENGTH = 128K ram_local2 (rwx) : ORIGIN = 0x10080000, LENGTH = 72K - ram_ahb (rwx) : ORIGIN = 0x20000000, LENGTH = 64K + ram_ahb1 (rwx) : ORIGIN = 0x20000000, LENGTH = 16K + /* Removed 32K of AHB SRAM for USB buffer. Straddles two blocks of RAM + * to get performance benefit of having two USB buffers addressable + * simultaneously (on two different buses of the AHB multilayer matrix) + */ + ram_ahb2 (rwx) : ORIGIN = 0x2000C000, LENGTH = 16K } /* Include the common ld script. */ INCLUDE libopencm3_lpc43xx_ram_only.ld - -INCLUDE usbram.ld diff --git a/firmware/common/usbram.ld b/firmware/common/usbram.ld deleted file mode 100644 index 279aaad3..00000000 --- a/firmware/common/usbram.ld +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2012 Jared Boone - * - * This file is part of HackRF - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -SECTIONS -{ - . = ORIGIN(ram_ahb); - - .usbram : { - . = ALIGN(4096); - *(.usb_data) - . = ALIGN(2048); - *(.usb_qh) - . = ALIGN(64); - *(.usb_td) - } >ram_ahb - -} From 5989465eb98b4f653de984b0339db0d7e3b29cdc Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 10 Oct 2012 14:30:28 -0700 Subject: [PATCH 29/41] Add SGPIO configuration API and code, extracted from existing SGPIO projects. --- firmware/common/sgpio.c | 301 +++++++++++++++++++++++++++++++++++ firmware/common/sgpio.h | 34 ++++ firmware/sgpio-rx/Makefile | 1 + firmware/sgpio-rx/sgpio-rx.c | 192 ++-------------------- firmware/sgpio/Makefile | 1 + firmware/sgpio/sgpio.c | 187 +--------------------- 6 files changed, 354 insertions(+), 362 deletions(-) create mode 100644 firmware/common/sgpio.c create mode 100644 firmware/common/sgpio.h diff --git a/firmware/common/sgpio.c b/firmware/common/sgpio.c new file mode 100644 index 00000000..2db69608 --- /dev/null +++ b/firmware/common/sgpio.c @@ -0,0 +1,301 @@ +/* + * Copyright 2012 Jared Boone + * + * This file is part of HackRF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include +#include + +#include + +void sgpio_configure_pin_functions() { + scu_pinmux(SCU_PINMUX_SGPIO0, SCU_GPIO_FAST | SCU_CONF_FUNCTION3); + scu_pinmux(SCU_PINMUX_SGPIO1, SCU_GPIO_FAST | SCU_CONF_FUNCTION3); + scu_pinmux(SCU_PINMUX_SGPIO2, SCU_GPIO_FAST | SCU_CONF_FUNCTION2); + scu_pinmux(SCU_PINMUX_SGPIO3, SCU_GPIO_FAST | SCU_CONF_FUNCTION2); + scu_pinmux(SCU_PINMUX_SGPIO4, SCU_GPIO_FAST | SCU_CONF_FUNCTION2); + scu_pinmux(SCU_PINMUX_SGPIO5, SCU_GPIO_FAST | SCU_CONF_FUNCTION2); + scu_pinmux(SCU_PINMUX_SGPIO6, SCU_GPIO_FAST | SCU_CONF_FUNCTION0); + scu_pinmux(SCU_PINMUX_SGPIO7, SCU_GPIO_FAST | SCU_CONF_FUNCTION6); + scu_pinmux(SCU_PINMUX_SGPIO8, SCU_GPIO_FAST | SCU_CONF_FUNCTION6); + scu_pinmux(SCU_PINMUX_SGPIO9, SCU_GPIO_FAST | SCU_CONF_FUNCTION7); + scu_pinmux(SCU_PINMUX_SGPIO10, SCU_GPIO_FAST | SCU_CONF_FUNCTION6); + scu_pinmux(SCU_PINMUX_SGPIO11, SCU_GPIO_FAST | SCU_CONF_FUNCTION6); + scu_pinmux(SCU_PINMUX_SGPIO12, SCU_GPIO_FAST | SCU_CONF_FUNCTION6); + scu_pinmux(SCU_PINMUX_SGPIO13, SCU_GPIO_FAST | SCU_CONF_FUNCTION7); + scu_pinmux(SCU_PINMUX_SGPIO14, SCU_GPIO_FAST | SCU_CONF_FUNCTION7); + scu_pinmux(SCU_PINMUX_SGPIO15, SCU_GPIO_FAST | SCU_CONF_FUNCTION7); +} + + +void sgpio_test_interface() { + const uint_fast8_t host_clock_sgpio_pin = 8; // Input + const uint_fast8_t host_capture_sgpio_pin = 9; // Input + const uint_fast8_t host_disable_sgpio_pin = 10; // Output + const uint_fast8_t host_direction_sgpio_pin = 11; // Output + + SGPIO_GPIO_OENREG = 0; // All inputs for the moment. + + // Disable all counters during configuration + SGPIO_CTRL_ENABLE = 0; + + sgpio_configure_pin_functions(); + + // Make all SGPIO controlled by SGPIO's "GPIO" registers + for (uint_fast8_t i = 0; i < 16; i++) { + SGPIO_OUT_MUX_CFG(i) = (0L << 4) | (4L << 0); + } + + // Set SGPIO output values. + SGPIO_GPIO_OUTREG = (1L << host_direction_sgpio_pin) + | (1L << host_disable_sgpio_pin); + + // Enable SGPIO pin outputs. + SGPIO_GPIO_OENREG = (1L << host_direction_sgpio_pin) + | (1L << host_disable_sgpio_pin) | (0L << host_capture_sgpio_pin) + | (0L << host_clock_sgpio_pin) | (0xFF << 0); + + // Configure SGPIO slices. + + // Enable codec data stream. + SGPIO_GPIO_OUTREG &= ~(1L << host_disable_sgpio_pin); + + while (1) { + for (uint_fast8_t i = 0; i < 8; i++) { + SGPIO_GPIO_OUTREG ^= (1L << i); + } + } +} + +void sgpio_configure_for_tx() { + // Disable all counters during configuration + SGPIO_CTRL_ENABLE = 0; + + sgpio_configure_pin_functions(); + + // Set SGPIO output values. + SGPIO_GPIO_OUTREG = + (1L << 11) | // direction + (1L << 10); // disable + + // Enable SGPIO pin outputs. + SGPIO_GPIO_OENREG = + (1L << 11) | // direction: TX: data to CPLD + (1L << 10) | // disable + (0L << 9) | // capture + (0L << 8) | // clock + 0xFF; // data: output + + SGPIO_OUT_MUX_CFG( 8) = 0; // SGPIO: Input: clock + SGPIO_OUT_MUX_CFG( 9) = 0; // SGPIO: Input: qualifier + SGPIO_OUT_MUX_CFG(10) = (0L << 4) | (4L << 0); // GPIO: Output: disable + SGPIO_OUT_MUX_CFG(11) = (0L << 4) | (4L << 0); // GPIO: Output: direction + + for(uint_fast8_t i=0; i<8; i++) { + // SGPIO pin 0 outputs slice A bit "i". + SGPIO_OUT_MUX_CFG(i) = + (0L << 4) | // P_OE_CFG = 0 + (9L << 0); // P_OUT_CFG = 9, dout_doutm8a (8-bit mode 8a) + } + + // Slice A + SGPIO_MUX_CFG(SGPIO_SLICE_A) = + (0L << 12) | // CONCAT_ORDER = 0 (self-loop) + (1L << 11) | // CONCAT_ENABLE = 1 (concatenate data) + (0L << 9) | // QUALIFIER_SLICE_MODE = X + (1L << 7) | // QUALIFIER_PIN_MODE = 1 (SGPIO9) + (3L << 5) | // QUALIFIER_MODE = 3 (external SGPIO pin) + (0L << 3) | // CLK_SOURCE_SLICE_MODE = X + (0L << 1) | // CLK_SOURCE_PIN_MODE = 0 (SGPIO8) + (1L << 0); // EXT_CLK_ENABLE = 1, external clock signal (slice) + + SGPIO_SLICE_MUX_CFG(SGPIO_SLICE_A) = + (0L << 8) | // INV_QUALIFIER = 0 (use normal qualifier) + (3L << 6) | // PARALLEL_MODE = 3 (shift 8 bits per clock) + (0L << 4) | // DATA_CAPTURE_MODE = 0 (detect rising edge) + (0L << 3) | // INV_OUT_CLK = 0 (normal clock) + (1L << 2) | // CLKGEN_MODE = 1 (use external pin clock) + (0L << 1) | // CLK_CAPTURE_MODE = 0 (use rising clock edge) + (0L << 0); // MATCH_MODE = 0 (do not match data) + + SGPIO_PRESET(SGPIO_SLICE_A) = 0; + SGPIO_COUNT(SGPIO_SLICE_A) = 0; + SGPIO_POS(SGPIO_SLICE_A) = (0x3L << 8) | (0x3L << 0); + SGPIO_REG(SGPIO_SLICE_A) = 0x80808080; // Primary output data register + SGPIO_REG_SS(SGPIO_SLICE_A) = 0x80808080; // Shadow output data register + + // Start SGPIO operation by enabling slice clocks. + SGPIO_CTRL_ENABLE = + (1L << SGPIO_SLICE_A) + ; +} + +void sgpio_configure_for_rx() { + // Disable all counters during configuration + SGPIO_CTRL_ENABLE = 0; + + sgpio_configure_pin_functions(); + + // Set SGPIO output values. + SGPIO_GPIO_OUTREG = + (0L << 11) | // direction + (1L << 10); // disable + + // Enable SGPIO pin outputs. + SGPIO_GPIO_OENREG = + (1L << 11) | // direction: RX: data from CPLD + (1L << 10) | // disable + (0L << 9) | // capture + (0L << 8) | // clock + 0x00; // data: input + + SGPIO_OUT_MUX_CFG( 8) = 0; // SGPIO: Input: clock + SGPIO_OUT_MUX_CFG( 9) = 0; // SGPIO: Input: qualifier + SGPIO_OUT_MUX_CFG(10) = (0L << 4) | (4L << 0); // GPIO: Output: disable + SGPIO_OUT_MUX_CFG(11) = (0L << 4) | (4L << 0); // GPIO: Output: direction + + for(uint_fast8_t i=0; i<8; i++) { + SGPIO_OUT_MUX_CFG(i) = + (0L << 4) | // P_OE_CFG = 0 + (9L << 0); // P_OUT_CFG = 9, dout_doutm8a (8-bit mode 8a) + } + + // Slice A + SGPIO_MUX_CFG(SGPIO_SLICE_A) = + (0L << 12) | // CONCAT_ORDER = X + (0L << 11) | // CONCAT_ENABLE = 0 (concatenate data) + (0L << 9) | // QUALIFIER_SLICE_MODE = X + (1L << 7) | // QUALIFIER_PIN_MODE = 1 (SGPIO9) + (3L << 5) | // QUALIFIER_MODE = 3 (external SGPIO pin) + (0L << 3) | // CLK_SOURCE_SLICE_MODE = X + (0L << 1) | // CLK_SOURCE_PIN_MODE = 0 (SGPIO8) + (1L << 0); // EXT_CLK_ENABLE = 1, external clock signal (slice) + + SGPIO_SLICE_MUX_CFG(SGPIO_SLICE_A) = + (0L << 8) | // INV_QUALIFIER = 0 (use normal qualifier) + (3L << 6) | // PARALLEL_MODE = 3 (shift 8 bits per clock) + (0L << 4) | // DATA_CAPTURE_MODE = 0 (detect rising edge) + (0L << 3) | // INV_OUT_CLK = X + (1L << 2) | // CLKGEN_MODE = 1 (use external pin clock) + (1L << 1) | // CLK_CAPTURE_MODE = 1 (use falling clock edge) + (0L << 0); // MATCH_MODE = 0 (do not match data) + + SGPIO_PRESET(SGPIO_SLICE_A) = 0; + SGPIO_COUNT(SGPIO_SLICE_A) = 0; + SGPIO_POS(SGPIO_SLICE_A) = (0 << 8) | (0 << 0); + SGPIO_REG(SGPIO_SLICE_A) = 0xCAFEBABE; // Primary output data register + SGPIO_REG_SS(SGPIO_SLICE_A) = 0xDEADBEEF; // Shadow output data register + + // Start SGPIO operation by enabling slice clocks. + SGPIO_CTRL_ENABLE = + (1L << SGPIO_SLICE_A) + ; +} + +void sgpio_configure_for_rx_deep() { + // Disable all counters during configuration + SGPIO_CTRL_ENABLE = 0; + + sgpio_configure_pin_functions(); + + // Set SGPIO output values. + SGPIO_GPIO_OUTREG = + (0L << 11) | // direction + (1L << 10); // disable + + // Enable SGPIO pin outputs. + SGPIO_GPIO_OENREG = + (1L << 11) | // direction: RX: data from CPLD + (1L << 10) | // disable + (0L << 9) | // capture + (0L << 8) | // clock + 0x00; // data: input + + SGPIO_OUT_MUX_CFG( 8) = 0; // SGPIO: Input: clock + SGPIO_OUT_MUX_CFG( 9) = 0; // SGPIO: Input: qualifier + SGPIO_OUT_MUX_CFG(10) = (0L << 4) | (4L << 0); // GPIO: Output: disable + SGPIO_OUT_MUX_CFG(11) = (0L << 4) | (4L << 0); // GPIO: Output: direction + + for(uint_fast8_t i=0; i<8; i++) { + SGPIO_OUT_MUX_CFG(i) = + (0L << 4) | // P_OE_CFG = 0 + (9L << 0); // P_OUT_CFG = 9, dout_doutm8a (8-bit mode 8a) + } + + const uint_fast8_t slice_indices[] = { + SGPIO_SLICE_A, + SGPIO_SLICE_I, + SGPIO_SLICE_E, + SGPIO_SLICE_J, + SGPIO_SLICE_C, + SGPIO_SLICE_K, + SGPIO_SLICE_F, + SGPIO_SLICE_L, + }; + + uint32_t slice_enable_mask = 0; + for(uint_fast8_t i=0; i<8; i++) { + uint_fast8_t slice_index = slice_indices[i]; + const uint_fast8_t concat_order = (slice_index == SGPIO_SLICE_A) ? 0 : 3; + const uint_fast8_t concat_enable = (slice_index == SGPIO_SLICE_A) ? 0 : 1; + SGPIO_MUX_CFG(slice_index) = + (concat_order << 12) | // CONCAT_ORDER = 3 (eight slices) + (concat_enable << 11) | // CONCAT_ENABLE = 1 (concatenate data) + (0L << 9) | // QUALIFIER_SLICE_MODE = X + (1L << 7) | // QUALIFIER_PIN_MODE = 1 (SGPIO9) + (3L << 5) | // QUALIFIER_MODE = 3 (external SGPIO pin) + (0L << 3) | // CLK_SOURCE_SLICE_MODE = X + (0L << 1) | // CLK_SOURCE_PIN_MODE = 0 (SGPIO8) + (1L << 0); // EXT_CLK_ENABLE = 1, external clock signal (slice) + + SGPIO_SLICE_MUX_CFG(slice_index) = + (0L << 8) | // INV_QUALIFIER = 0 (use normal qualifier) + (3L << 6) | // PARALLEL_MODE = 3 (shift 8 bits per clock) + (0L << 4) | // DATA_CAPTURE_MODE = 0 (detect rising edge) + (0L << 3) | // INV_OUT_CLK = X + (1L << 2) | // CLKGEN_MODE = 1 (use external pin clock) + (1L << 1) | // CLK_CAPTURE_MODE = 1 (use falling clock edge) + (0L << 0); // MATCH_MODE = 0 (do not match data) + + SGPIO_PRESET(slice_index) = 0; // External clock, don't care + SGPIO_COUNT(slice_index) = 0; // External clock, don't care + SGPIO_POS(slice_index) = (0x1f << 8) | (0x1f << 0); + SGPIO_REG(slice_index) = 0xFFFFFFFF; // Primary output data register + SGPIO_REG_SS(slice_index) = 0xFFFFFFFF; // Shadow output data register + + slice_enable_mask |= (1 << slice_index); + } + + // Start SGPIO operation by enabling slice clocks. + SGPIO_CTRL_ENABLE = slice_enable_mask; +} + +void sgpio_cpld_stream_enable() { + // Enable codec data stream. + SGPIO_GPIO_OUTREG &= ~(1L << 10); +} + +void sgpio_cpld_stream_disable() { + // Disable codec data stream. + SGPIO_GPIO_OUTREG |= (1L << 10); +} + +bool sgpio_cpld_stream_is_enabled() { + return (SGPIO_GPIO_OUTREG & (1L << 10)) == 0; +} \ No newline at end of file diff --git a/firmware/common/sgpio.h b/firmware/common/sgpio.h new file mode 100644 index 00000000..8b8f471c --- /dev/null +++ b/firmware/common/sgpio.h @@ -0,0 +1,34 @@ +/* + * Copyright 2012 Jared Boone + * + * This file is part of HackRF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __SGPIO_H__ +#define __SGPIO_H__ + +void sgpio_configure_pin_functions(); +void sgpio_test_interface(); +void sgpio_configure_for_tx(); +void sgpio_configure_for_rx(); +void sgpio_configure_for_rx_deep(); +void sgpio_cpld_stream_enable(); +void sgpio_cpld_stream_disable(); +bool sgpio_cpld_stream_is_enabled(); + +#endif//__SGPIO_H__ diff --git a/firmware/sgpio-rx/Makefile b/firmware/sgpio-rx/Makefile index 9f750ea3..894853b0 100644 --- a/firmware/sgpio-rx/Makefile +++ b/firmware/sgpio-rx/Makefile @@ -4,6 +4,7 @@ BINARY = sgpio-rx SRC = $(BINARY).c \ ../common/hackrf_core.c \ + ../common/sgpio.c \ ../common/si5351c.c \ ../common/max2837.c \ ../common/max5864.c \ diff --git a/firmware/sgpio-rx/sgpio-rx.c b/firmware/sgpio-rx/sgpio-rx.c index 284c1d69..ff87195b 100644 --- a/firmware/sgpio-rx/sgpio-rx.c +++ b/firmware/sgpio-rx/sgpio-rx.c @@ -30,127 +30,11 @@ #include #include #include +#include -void configure_sgpio_pin_functions() { - scu_pinmux(SCU_PINMUX_SGPIO0, SCU_GPIO_FAST | SCU_CONF_FUNCTION3); - scu_pinmux(SCU_PINMUX_SGPIO1, SCU_GPIO_FAST | SCU_CONF_FUNCTION3); - scu_pinmux(SCU_PINMUX_SGPIO2, SCU_GPIO_FAST | SCU_CONF_FUNCTION2); - scu_pinmux(SCU_PINMUX_SGPIO3, SCU_GPIO_FAST | SCU_CONF_FUNCTION2); - scu_pinmux(SCU_PINMUX_SGPIO4, SCU_GPIO_FAST | SCU_CONF_FUNCTION2); - scu_pinmux(SCU_PINMUX_SGPIO5, SCU_GPIO_FAST | SCU_CONF_FUNCTION2); - scu_pinmux(SCU_PINMUX_SGPIO6, SCU_GPIO_FAST | SCU_CONF_FUNCTION0); - scu_pinmux(SCU_PINMUX_SGPIO7, SCU_GPIO_FAST | SCU_CONF_FUNCTION6); - scu_pinmux(SCU_PINMUX_SGPIO8, SCU_GPIO_FAST | SCU_CONF_FUNCTION6); - scu_pinmux(SCU_PINMUX_SGPIO9, SCU_GPIO_FAST | SCU_CONF_FUNCTION7); - scu_pinmux(SCU_PINMUX_SGPIO10, SCU_GPIO_FAST | SCU_CONF_FUNCTION6); - scu_pinmux(SCU_PINMUX_SGPIO11, SCU_GPIO_FAST | SCU_CONF_FUNCTION6); - scu_pinmux(SCU_PINMUX_SGPIO12, SCU_GPIO_FAST | SCU_CONF_FUNCTION6); - scu_pinmux(SCU_PINMUX_SGPIO13, SCU_GPIO_FAST | SCU_CONF_FUNCTION7); - scu_pinmux(SCU_PINMUX_SGPIO14, SCU_GPIO_FAST | SCU_CONF_FUNCTION7); - scu_pinmux(SCU_PINMUX_SGPIO15, SCU_GPIO_FAST | SCU_CONF_FUNCTION7); -} - -void test_sgpio_interface() { - const uint_fast8_t host_clock_sgpio_pin = 8; // Input - const uint_fast8_t host_capture_sgpio_pin = 9; // Input - const uint_fast8_t host_disable_sgpio_pin = 10; // Output - const uint_fast8_t host_direction_sgpio_pin = 11; // Output - - SGPIO_GPIO_OENREG = 0; // All inputs for the moment. - - // Disable all counters during configuration - SGPIO_CTRL_ENABLE = 0; - - configure_sgpio_pin_functions(); - - // Make all SGPIO controlled by SGPIO's "GPIO" registers - for (uint_fast8_t i = 0; i < 16; i++) { - SGPIO_OUT_MUX_CFG(i) = (0L << 4) | (4L << 0); - } - - // Set SGPIO output values. - SGPIO_GPIO_OUTREG = (1L << host_direction_sgpio_pin) - | (1L << host_disable_sgpio_pin); - - // Enable SGPIO pin outputs. - SGPIO_GPIO_OENREG = (1L << host_direction_sgpio_pin) - | (1L << host_disable_sgpio_pin) | (0L << host_capture_sgpio_pin) - | (0L << host_clock_sgpio_pin) | (0xFF << 0); - - // Configure SGPIO slices. - - // Enable codec data stream. - SGPIO_GPIO_OUTREG &= ~(1L << host_disable_sgpio_pin); - - while (1) { - for (uint_fast8_t i = 0; i < 8; i++) { - SGPIO_GPIO_OUTREG ^= (1L << i); - } - } -} - -void configure_sgpio_test_tx() { - // Disable all counters during configuration - SGPIO_CTRL_ENABLE = 0; - - configure_sgpio_pin_functions(); - - // Set SGPIO output values. - SGPIO_GPIO_OUTREG = - (1L << 11) | // direction - (1L << 10); // disable - - // Enable SGPIO pin outputs. - SGPIO_GPIO_OENREG = - (1L << 11) | // direction: TX: data to CPLD - (1L << 10) | // disable - (0L << 9) | // capture - (0L << 8) | // clock - 0xFF; // data: output - - SGPIO_OUT_MUX_CFG( 8) = 0; // SGPIO: Input: clock - SGPIO_OUT_MUX_CFG( 9) = 0; // SGPIO: Input: qualifier - SGPIO_OUT_MUX_CFG(10) = (0L << 4) | (4L << 0); // GPIO: Output: disable - SGPIO_OUT_MUX_CFG(11) = (0L << 4) | (4L << 0); // GPIO: Output: direction - - for(uint_fast8_t i=0; i<8; i++) { - // SGPIO pin 0 outputs slice A bit "i". - SGPIO_OUT_MUX_CFG(i) = - (0L << 4) | // P_OE_CFG = 0 - (9L << 0); // P_OUT_CFG = 9, dout_doutm8a (8-bit mode 8a) - } - - // Slice A - SGPIO_MUX_CFG(SGPIO_SLICE_A) = - (0L << 12) | // CONCAT_ORDER = 0 (self-loop) - (1L << 11) | // CONCAT_ENABLE = 1 (concatenate data) - (0L << 9) | // QUALIFIER_SLICE_MODE = X - (1L << 7) | // QUALIFIER_PIN_MODE = 1 (SGPIO9) - (3L << 5) | // QUALIFIER_MODE = 3 (external SGPIO pin) - (0L << 3) | // CLK_SOURCE_SLICE_MODE = X - (0L << 1) | // CLK_SOURCE_PIN_MODE = 0 (SGPIO8) - (1L << 0); // EXT_CLK_ENABLE = 1, external clock signal - - SGPIO_SLICE_MUX_CFG(SGPIO_SLICE_A) = - (0L << 8) | // INV_QUALIFIER = 0 (use normal qualifier) - (3L << 6) | // PARALLEL_MODE = 3 (shift 8 bits per clock) - (0L << 4) | // DATA_CAPTURE_MODE = 0 (detect rising edge) - (0L << 3) | // INV_OUT_CLK = 0 (normal clock) - (1L << 2) | // CLKGEN_MODE = 1 (use external pin clock) - (0L << 1) | // CLK_CAPTURE_MODE = 0 (use rising clock edge) - (0L << 0); // MATCH_MODE = 0 (do not match data) - - SGPIO_PRESET(SGPIO_SLICE_A) = 0; - SGPIO_COUNT(SGPIO_SLICE_A) = 0; - SGPIO_POS(SGPIO_SLICE_A) = (0x3L << 8) | (0x3L << 0); - SGPIO_REG(SGPIO_SLICE_A) = 0x80808080; // Primary output data register - SGPIO_REG_SS(SGPIO_SLICE_A) = 0x80808080; // Shadow output data register - - // Start SGPIO operation by enabling slice clocks. - SGPIO_CTRL_ENABLE = - (1L << SGPIO_SLICE_A) - ; - +void tx_test() { + sgpio_configure_for_tx(); + // LSB goes out first, samples are 0x volatile uint32_t buffer[] = { 0xda808080, @@ -160,8 +44,7 @@ void configure_sgpio_test_tx() { }; uint32_t i = 0; - // Enable codec data stream. - SGPIO_GPIO_OUTREG &= ~(1L << 10); + sgpio_cpld_stream_enable(); while(true) { while(SGPIO_STATUS_1 == 0); @@ -170,72 +53,15 @@ void configure_sgpio_test_tx() { } } -void configure_sgpio_test_rx() { - // Disable all counters during configuration - SGPIO_CTRL_ENABLE = 0; - - configure_sgpio_pin_functions(); - - // Set SGPIO output values. - SGPIO_GPIO_OUTREG = - (0L << 11) | // direction - (1L << 10); // disable - - // Enable SGPIO pin outputs. - SGPIO_GPIO_OENREG = - (1L << 11) | // direction: RX: data from CPLD - (1L << 10) | // disable - (0L << 9) | // capture - (0L << 8) | // clock - 0x00; // data: input - - SGPIO_OUT_MUX_CFG( 8) = 0; // SGPIO: Input: clock - SGPIO_OUT_MUX_CFG( 9) = 0; // SGPIO: Input: qualifier - SGPIO_OUT_MUX_CFG(10) = (0L << 4) | (4L << 0); // GPIO: Output: disable - SGPIO_OUT_MUX_CFG(11) = (0L << 4) | (4L << 0); // GPIO: Output: direction - - for(uint_fast8_t i=0; i<8; i++) { - SGPIO_OUT_MUX_CFG(i) = - (0L << 4) | // P_OE_CFG = 0 - (9L << 0); // P_OUT_CFG = 9, dout_doutm8a (8-bit mode 8a) - } - - // Slice A - SGPIO_MUX_CFG(SGPIO_SLICE_A) = - (0L << 12) | // CONCAT_ORDER = X - (0L << 11) | // CONCAT_ENABLE = 0 (concatenate data) - (0L << 9) | // QUALIFIER_SLICE_MODE = X - (1L << 7) | // QUALIFIER_PIN_MODE = 1 (SGPIO9) - (3L << 5) | // QUALIFIER_MODE = 3 (external SGPIO pin) - (0L << 3) | // CLK_SOURCE_SLICE_MODE = X - (0L << 1) | // CLK_SOURCE_PIN_MODE = 0 (SGPIO8) - (1L << 0); // EXT_CLK_ENABLE = 1, external clock signal - - SGPIO_SLICE_MUX_CFG(SGPIO_SLICE_A) = - (0L << 8) | // INV_QUALIFIER = 0 (use normal qualifier) - (3L << 6) | // PARALLEL_MODE = 3 (shift 8 bits per clock) - (0L << 4) | // DATA_CAPTURE_MODE = 0 (detect rising edge) - (0L << 3) | // INV_OUT_CLK = X - (1L << 2) | // CLKGEN_MODE = 1 (use external pin clock) - (1L << 1) | // CLK_CAPTURE_MODE = 1 (use falling clock edge) - (0L << 0); // MATCH_MODE = 0 (do not match data) - - SGPIO_PRESET(SGPIO_SLICE_A) = 0; - SGPIO_COUNT(SGPIO_SLICE_A) = 0; - SGPIO_POS(SGPIO_SLICE_A) = (0x3L << 8) | (0x3L << 0); - SGPIO_REG(SGPIO_SLICE_A) = 0xCAFEBABE; // Primary output data register - SGPIO_REG_SS(SGPIO_SLICE_A) = 0xDEADBEEF; // Shadow output data register - - // Start SGPIO operation by enabling slice clocks. - SGPIO_CTRL_ENABLE = (1L << SGPIO_SLICE_A); +void rx_test() { + sgpio_configure_for_rx(); volatile uint32_t buffer[4096]; uint32_t i = 0; int16_t magsq; int8_t sigi, sigq; - // Enable codec data stream. - SGPIO_GPIO_OUTREG &= ~(1L << 10); + sgpio_cpld_stream_enable(); gpio_set(PORT_LED1_3, (PIN_LED2)); /* LED2 on */ while(true) { @@ -293,7 +119,7 @@ int main(void) { ssp1_set_mode_max5864(); max5864_xcvr(); - configure_sgpio_test_rx(); + rx_test(); gpio_set(PORT_LED1_3, (PIN_LED2)); /* LED2 on */ while (1) { diff --git a/firmware/sgpio/Makefile b/firmware/sgpio/Makefile index 24eefbd1..1c214bbb 100644 --- a/firmware/sgpio/Makefile +++ b/firmware/sgpio/Makefile @@ -4,6 +4,7 @@ BINARY = sgpio SRC = $(BINARY).c \ ../common/hackrf_core.c \ + ../common/sgpio.c \ ../common/si5351c.c \ ../common/max2837.c \ ../common/max5864.c diff --git a/firmware/sgpio/sgpio.c b/firmware/sgpio/sgpio.c index 5d17238d..88008313 100644 --- a/firmware/sgpio/sgpio.c +++ b/firmware/sgpio/sgpio.c @@ -28,126 +28,10 @@ #include #include +#include -void configure_sgpio_pin_functions() { - scu_pinmux(SCU_PINMUX_SGPIO0, SCU_GPIO_FAST | SCU_CONF_FUNCTION3); - scu_pinmux(SCU_PINMUX_SGPIO1, SCU_GPIO_FAST | SCU_CONF_FUNCTION3); - scu_pinmux(SCU_PINMUX_SGPIO2, SCU_GPIO_FAST | SCU_CONF_FUNCTION2); - scu_pinmux(SCU_PINMUX_SGPIO3, SCU_GPIO_FAST | SCU_CONF_FUNCTION2); - scu_pinmux(SCU_PINMUX_SGPIO4, SCU_GPIO_FAST | SCU_CONF_FUNCTION2); - scu_pinmux(SCU_PINMUX_SGPIO5, SCU_GPIO_FAST | SCU_CONF_FUNCTION2); - scu_pinmux(SCU_PINMUX_SGPIO6, SCU_GPIO_FAST | SCU_CONF_FUNCTION0); - scu_pinmux(SCU_PINMUX_SGPIO7, SCU_GPIO_FAST | SCU_CONF_FUNCTION6); - scu_pinmux(SCU_PINMUX_SGPIO8, SCU_GPIO_FAST | SCU_CONF_FUNCTION6); - scu_pinmux(SCU_PINMUX_SGPIO9, SCU_GPIO_FAST | SCU_CONF_FUNCTION7); - scu_pinmux(SCU_PINMUX_SGPIO10, SCU_GPIO_FAST | SCU_CONF_FUNCTION6); - scu_pinmux(SCU_PINMUX_SGPIO11, SCU_GPIO_FAST | SCU_CONF_FUNCTION6); - scu_pinmux(SCU_PINMUX_SGPIO12, SCU_GPIO_FAST | SCU_CONF_FUNCTION6); - scu_pinmux(SCU_PINMUX_SGPIO13, SCU_GPIO_FAST | SCU_CONF_FUNCTION7); - scu_pinmux(SCU_PINMUX_SGPIO14, SCU_GPIO_FAST | SCU_CONF_FUNCTION7); - scu_pinmux(SCU_PINMUX_SGPIO15, SCU_GPIO_FAST | SCU_CONF_FUNCTION7); -} - -void test_sgpio_interface() { - const uint_fast8_t host_clock_sgpio_pin = 8; // Input - const uint_fast8_t host_capture_sgpio_pin = 9; // Input - const uint_fast8_t host_disable_sgpio_pin = 10; // Output - const uint_fast8_t host_direction_sgpio_pin = 11; // Output - - SGPIO_GPIO_OENREG = 0; // All inputs for the moment. - - // Disable all counters during configuration - SGPIO_CTRL_ENABLE = 0; - - configure_sgpio_pin_functions(); - - // Make all SGPIO controlled by SGPIO's "GPIO" registers - for (uint_fast8_t i = 0; i < 16; i++) { - SGPIO_OUT_MUX_CFG(i) = (0L << 4) | (4L << 0); - } - - // Set SGPIO output values. - SGPIO_GPIO_OUTREG = (1L << host_direction_sgpio_pin) - | (1L << host_disable_sgpio_pin); - - // Enable SGPIO pin outputs. - SGPIO_GPIO_OENREG = (1L << host_direction_sgpio_pin) - | (1L << host_disable_sgpio_pin) | (0L << host_capture_sgpio_pin) - | (0L << host_clock_sgpio_pin) | (0xFF << 0); - - // Configure SGPIO slices. - - // Enable codec data stream. - SGPIO_GPIO_OUTREG &= ~(1L << host_disable_sgpio_pin); - - while (1) { - for (uint_fast8_t i = 0; i < 8; i++) { - SGPIO_GPIO_OUTREG ^= (1L << i); - } - } -} - -void configure_sgpio_test_tx() { - // Disable all counters during configuration - SGPIO_CTRL_ENABLE = 0; - - configure_sgpio_pin_functions(); - - // Set SGPIO output values. - SGPIO_GPIO_OUTREG = - (1L << 11) | // direction - (1L << 10); // disable - - // Enable SGPIO pin outputs. - SGPIO_GPIO_OENREG = - (1L << 11) | // direction: TX: data to CPLD - (1L << 10) | // disable - (0L << 9) | // capture - (0L << 8) | // clock - 0xFF; // data: output - - SGPIO_OUT_MUX_CFG( 8) = 0; // SGPIO: Input: clock - SGPIO_OUT_MUX_CFG( 9) = 0; // SGPIO: Input: qualifier - SGPIO_OUT_MUX_CFG(10) = (0L << 4) | (4L << 0); // GPIO: Output: disable - SGPIO_OUT_MUX_CFG(11) = (0L << 4) | (4L << 0); // GPIO: Output: direction - - for(uint_fast8_t i=0; i<8; i++) { - // SGPIO pin 0 outputs slice A bit "i". - SGPIO_OUT_MUX_CFG(i) = - (0L << 4) | // P_OE_CFG = 0 - (9L << 0); // P_OUT_CFG = 9, dout_doutm8a (8-bit mode 8a) - } - - // Slice A - SGPIO_MUX_CFG(SGPIO_SLICE_A) = - (0L << 12) | // CONCAT_ORDER = 0 (self-loop) - (1L << 11) | // CONCAT_ENABLE = 1 (concatenate data) - (0L << 9) | // QUALIFIER_SLICE_MODE = X - (1L << 7) | // QUALIFIER_PIN_MODE = 1 (SGPIO9) - (3L << 5) | // QUALIFIER_MODE = 3 (external SGPIO pin) - (0L << 3) | // CLK_SOURCE_SLICE_MODE = X - (0L << 1) | // CLK_SOURCE_PIN_MODE = 0 (SGPIO8) - (1L << 0); // EXT_CLK_ENABLE = 1, external clock signal (slice) - - SGPIO_SLICE_MUX_CFG(SGPIO_SLICE_A) = - (0L << 8) | // INV_QUALIFIER = 0 (use normal qualifier) - (3L << 6) | // PARALLEL_MODE = 3 (shift 8 bits per clock) - (0L << 4) | // DATA_CAPTURE_MODE = 0 (detect rising edge) - (0L << 3) | // INV_OUT_CLK = 0 (normal clock) - (1L << 2) | // CLKGEN_MODE = 1 (use external pin clock) - (0L << 1) | // CLK_CAPTURE_MODE = 0 (use rising clock edge) - (0L << 0); // MATCH_MODE = 0 (do not match data) - - SGPIO_PRESET(SGPIO_SLICE_A) = 0; - SGPIO_COUNT(SGPIO_SLICE_A) = 0; - SGPIO_POS(SGPIO_SLICE_A) = (0x3L << 8) | (0x3L << 0); - SGPIO_REG(SGPIO_SLICE_A) = 0x80808080; // Primary output data register - SGPIO_REG_SS(SGPIO_SLICE_A) = 0x80808080; // Shadow output data register - - // Start SGPIO operation by enabling slice clocks. - SGPIO_CTRL_ENABLE = - (1L << SGPIO_SLICE_A) - ; +void tx_test() { + sgpio_configure_for_tx(); // LSB goes out first, samples are 0x volatile uint32_t buffer[] = { @@ -158,9 +42,8 @@ void configure_sgpio_test_tx() { }; uint32_t i = 0; - // Enable codec data stream. - SGPIO_GPIO_OUTREG &= ~(1L << 10); - + sgpio_cpld_stream_enable(); + while(true) { while(SGPIO_STATUS_1 == 0); SGPIO_REG_SS(SGPIO_SLICE_A) = buffer[(i++) & 3]; @@ -168,67 +51,13 @@ void configure_sgpio_test_tx() { } } -void configure_sgpio_test_rx() { - // Disable all counters during configuration - SGPIO_CTRL_ENABLE = 0; - - configure_sgpio_pin_functions(); - - // Set SGPIO output values. - SGPIO_GPIO_OUTREG = - (0L << 11) | // direction - (1L << 10); // disable - - // Enable SGPIO pin outputs. - SGPIO_GPIO_OENREG = - (1L << 11) | // direction: RX: data from CPLD - (1L << 10) | // disable - (0L << 9) | // capture - (0L << 8) | // clock - 0x00; // data: input - - SGPIO_OUT_MUX_CFG( 8) = 0; // SGPIO: Input: clock - SGPIO_OUT_MUX_CFG( 9) = 0; // SGPIO: Input: qualifier - SGPIO_OUT_MUX_CFG(10) = (0L << 4) | (4L << 0); // GPIO: Output: disable - SGPIO_OUT_MUX_CFG(11) = (0L << 4) | (4L << 0); // GPIO: Output: direction - - for(uint_fast8_t i=0; i<8; i++) { - SGPIO_OUT_MUX_CFG(i) = - (0L << 4) | // P_OE_CFG = 0 - (9L << 0); // P_OUT_CFG = 9, dout_doutm8a (8-bit mode 8a) - } - - // Slice A - SGPIO_MUX_CFG(SGPIO_SLICE_A) = - (0L << 12) | // CONCAT_ORDER = X - (0L << 11) | // CONCAT_ENABLE = 0 (concatenate data) - (0L << 9) | // QUALIFIER_SLICE_MODE = X - (1L << 7) | // QUALIFIER_PIN_MODE = 1 (SGPIO9) - (3L << 5) | // QUALIFIER_MODE = 3 (external SGPIO pin) - (0L << 3) | // CLK_SOURCE_SLICE_MODE = X - (0L << 1) | // CLK_SOURCE_PIN_MODE = 0 (SGPIO8) - (1L << 0); // EXT_CLK_ENABLE = 1, external clock signal (slice) - - SGPIO_SLICE_MUX_CFG(SGPIO_SLICE_A) = - (0L << 8) | // INV_QUALIFIER = 0 (use normal qualifier) - (3L << 6) | // PARALLEL_MODE = 3 (shift 8 bits per clock) - (0L << 4) | // DATA_CAPTURE_MODE = 0 (detect rising edge) - (0L << 3) | // INV_OUT_CLK = X - (1L << 2) | // CLKGEN_MODE = 1 (use external pin clock) - (0L << 1) | // CLK_CAPTURE_MODE = 0 (use rising clock edge) - (0L << 0); // MATCH_MODE = 0 (do not match data) - - SGPIO_PRESET(SGPIO_SLICE_A) = 0; - SGPIO_COUNT(SGPIO_SLICE_A) = 0; - SGPIO_POS(SGPIO_SLICE_A) = (3 << 8) | (3 << 0); - SGPIO_REG(SGPIO_SLICE_A) = 0xCAFEBABE; // Primary output data register - SGPIO_REG_SS(SGPIO_SLICE_A) = 0xDEADBEEF; // Shadow output data register +void rx_test() { + sgpio_configure_for_rx(); volatile uint32_t buffer[4096]; uint32_t i = 0; - // Enable codec data stream. - SGPIO_GPIO_OUTREG &= ~(1L << 10); + sgpio_cpld_stream_enable(); while(true) { while(SGPIO_STATUS_1 == 0); From 165997d09b15011a0aeeba835a4e874f10901f1c Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 10 Oct 2012 14:39:03 -0700 Subject: [PATCH 30/41] Changed USB queue head and transfer descriptor attributes to be explicitly aligned, instead of targeting a section. Added miscellaneous internal USB functions. Improved disabling of endpoints -- now clearing pending interrupts and flushing as well. --- firmware/usb_performance/usb.c | 50 ++++++++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 11 deletions(-) diff --git a/firmware/usb_performance/usb.c b/firmware/usb_performance/usb.c index 73ed3592..5054160b 100644 --- a/firmware/usb_performance/usb.c +++ b/firmware/usb_performance/usb.c @@ -33,8 +33,8 @@ usb_device_t* usb_device_usb0 = 0; -usb_queue_head_t usb_qh[12] ATTR_SECTION(".usb_qh"); -usb_transfer_descriptor_t usb_td[12] ATTR_SECTION(".usb_td"); +usb_queue_head_t usb_qh[12] ATTR_ALIGNED(2048); +usb_transfer_descriptor_t usb_td[12] ATTR_ALIGNED(64); #define USB_QH_INDEX(endpoint_address) (((endpoint_address & 0xF) * 2) + ((endpoint_address >> 7) & 1)) #define USB_TD_INDEX(endpoint_address) (((endpoint_address & 0xF) * 2) + ((endpoint_address >> 7) & 1)) @@ -83,6 +83,18 @@ static void usb_phy_enable() { CREG_CREG0 &= ~CREG_CREG0_USB0PHY; } +static void usb_clear_pending_interrupts(const uint32_t mask) { + USB0_ENDPTNAK = mask; + USB0_ENDPTNAKEN = mask; + USB0_USBSTS_D = mask; + USB0_ENDPTSETUPSTAT = USB0_ENDPTSETUPSTAT & mask; + USB0_ENDPTCOMPLETE = USB0_ENDPTCOMPLETE & mask; +} + +static void usb_clear_all_pending_interrupts() { + usb_clear_pending_interrupts(0xFFFFFFFF); +} + static void usb_wait_for_endpoint_priming_to_finish(const uint32_t mask) { // Wait until controller has parsed new transfer descriptors and prepared // receive buffers. @@ -139,6 +151,17 @@ static void usb_endpoint_enable( } } +static void usb_endpoint_clear_pending_interrupts( + const usb_endpoint_t* const endpoint +) { + const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address); + if( usb_endpoint_is_in(endpoint->address) ) { + usb_clear_pending_interrupts(USB0_ENDPTCOMPLETE_ETCE(1 << endpoint_number)); + } else { + usb_clear_pending_interrupts(USB0_ENDPTCOMPLETE_ERCE(1 << endpoint_number)); + } +} + void usb_endpoint_disable( const usb_endpoint_t* const endpoint ) { @@ -148,6 +171,8 @@ void usb_endpoint_disable( } else { USB0_ENDPTCTRL(endpoint_number) &= ~(USB0_ENDPTCTRL_RXE); } + usb_endpoint_clear_pending_interrupts(endpoint); + usb_endpoint_flush(endpoint); } void usb_endpoint_prime( @@ -215,6 +240,17 @@ bool usb_endpoint_is_ready( } } +bool usb_endpoint_is_complete( + const usb_endpoint_t* const endpoint +) { + const uint_fast8_t endpoint_number = usb_endpoint_number(endpoint->address); + if( usb_endpoint_is_in(endpoint->address) ) { + return USB0_ENDPTCOMPLETE & USB0_ENDPTCOMPLETE_ETCE(1 << endpoint_number); + } else { + return USB0_ENDPTCOMPLETE & USB0_ENDPTCOMPLETE_ERCE(1 << endpoint_number); + } +} + void usb_endpoint_stall( const usb_endpoint_t* const endpoint ) { @@ -312,14 +348,6 @@ static void usb_disable_all_endpoints() { USB0_ENDPTCTRL5 &= ~(USB0_ENDPTCTRL5_RXE | USB0_ENDPTCTRL5_TXE); } -static void usb_clear_all_pending_interrupts() { - USB0_ENDPTNAK = ~0; - USB0_ENDPTNAKEN = 0; - USB0_USBSTS_D = ~0; - USB0_ENDPTSETUPSTAT = USB0_ENDPTSETUPSTAT; - USB0_ENDPTCOMPLETE = USB0_ENDPTCOMPLETE; -} - void usb_set_address_immediate( const usb_device_t* const device, const uint_fast8_t address @@ -489,7 +517,7 @@ void usb_endpoint_schedule( ) { usb_transfer_descriptor_t* const td = usb_transfer_descriptor(endpoint->address); - // Ensure that OUT endpoint is ready to be primed. + // Ensure that endpoint is ready to be primed. // It may have been flushed due to an aborted transaction. // TODO: This should be preceded by a flush? while( usb_endpoint_is_ready(endpoint) ); From 155d81da4e8644491bdd03c69a0b968363726502 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 10 Oct 2012 14:39:41 -0700 Subject: [PATCH 31/41] Reworked USB code to pump SGPIO with an interrupt. Relocated USB buffers to be split across two AHB memory regions, so that USB endpoint priming doesn't choke SGPIO transfers. Added code to configure 2.4GHz front-end. Changed USB and SGPIO priority levels (probably unnecessary because sample corruption was due to USB priming bursts). --- firmware/usb_performance/Makefile | 5 +- firmware/usb_performance/usb_performance.c | 147 +++++++++++++++++++-- 2 files changed, 137 insertions(+), 15 deletions(-) diff --git a/firmware/usb_performance/Makefile b/firmware/usb_performance/Makefile index ea65f127..7222a2f4 100644 --- a/firmware/usb_performance/Makefile +++ b/firmware/usb_performance/Makefile @@ -29,8 +29,11 @@ SRC = $(BINARY).c \ usb_descriptor.c \ ../common/fault_handler.c \ ../common/hackrf_core.c \ + ../common/sgpio.c \ ../common/si5351c.c \ - ../common/bitband.c + ../common/max2837.c \ + ../common/max5864.c \ + ../common/rffc5071.c LDSCRIPT = ../common/LPC4330_M4_ram_only.ld include ../common/Makefile_inc.mk diff --git a/firmware/usb_performance/usb_performance.c b/firmware/usb_performance/usb_performance.c index ef38a4b4..4bc56ebf 100644 --- a/firmware/usb_performance/usb_performance.c +++ b/firmware/usb_performance/usb_performance.c @@ -21,10 +21,15 @@ #include -#include - #include #include +#include +#include + +#include +#include +#include +#include #include "usb.h" #include "usb_type.h" @@ -32,14 +37,55 @@ #include "usb_descriptor.h" #include "usb_standard_request.h" -volatile uint_fast8_t usb_bulk_buffer_index = 0; -uint8_t usb_bulk_buffer[2][16384] ATTR_SECTION(".usb_data"); -const uint_fast8_t usb_bulk_buffer_count = - sizeof(usb_bulk_buffer) / sizeof(usb_bulk_buffer[0]); +uint8_t* const usb_bulk_buffer = 0x20004000; +static volatile uint32_t usb_bulk_buffer_offset = 0; +static const uint32_t usb_bulk_buffer_mask = 32768 - 1; -static void usb_endpoint_bulk_transfer(usb_endpoint_t* const endpoint) { - usb_endpoint_schedule(endpoint, usb_bulk_buffer[usb_bulk_buffer_index], sizeof(usb_bulk_buffer[usb_bulk_buffer_index])); - usb_bulk_buffer_index = (usb_bulk_buffer_index + 1) % usb_bulk_buffer_count; +usb_transfer_descriptor_t usb_td_bulk[2] ATTR_ALIGNED(64); +const uint_fast8_t usb_td_bulk_count = sizeof(usb_td_bulk) / sizeof(usb_td_bulk[0]); + +static void usb_init_buffers_bulk() { + usb_td_bulk[0].next_dtd_pointer = USB_TD_NEXT_DTD_POINTER_TERMINATE; + usb_td_bulk[0].total_bytes + = USB_TD_DTD_TOKEN_TOTAL_BYTES(16384) + | USB_TD_DTD_TOKEN_MULTO(0) + ; + usb_td_bulk[0].buffer_pointer_page[0] = (uint32_t)&usb_bulk_buffer[0x0000]; + usb_td_bulk[0].buffer_pointer_page[1] = (uint32_t)&usb_bulk_buffer[0x1000]; + usb_td_bulk[0].buffer_pointer_page[2] = (uint32_t)&usb_bulk_buffer[0x2000]; + usb_td_bulk[0].buffer_pointer_page[3] = (uint32_t)&usb_bulk_buffer[0x3000]; + usb_td_bulk[0].buffer_pointer_page[4] = (uint32_t)&usb_bulk_buffer[0x4000]; + + usb_td_bulk[1].next_dtd_pointer = USB_TD_NEXT_DTD_POINTER_TERMINATE; + usb_td_bulk[1].total_bytes + = USB_TD_DTD_TOKEN_TOTAL_BYTES(16384) + | USB_TD_DTD_TOKEN_MULTO(0) + ; + usb_td_bulk[1].buffer_pointer_page[0] = (uint32_t)&usb_bulk_buffer[0x4000]; + usb_td_bulk[1].buffer_pointer_page[1] = (uint32_t)&usb_bulk_buffer[0x5000]; + usb_td_bulk[1].buffer_pointer_page[2] = (uint32_t)&usb_bulk_buffer[0x6000]; + usb_td_bulk[1].buffer_pointer_page[3] = (uint32_t)&usb_bulk_buffer[0x7000]; + usb_td_bulk[1].buffer_pointer_page[4] = (uint32_t)&usb_bulk_buffer[0x8000]; +} + +void usb_endpoint_schedule_no_int( + const usb_endpoint_t* const endpoint, + usb_transfer_descriptor_t* const td +) { + // Ensure that endpoint is ready to be primed. + // It may have been flushed due to an aborted transaction. + // TODO: This should be preceded by a flush? + while( usb_endpoint_is_ready(endpoint) ); + + // Configure a transfer. + td->total_bytes = + USB_TD_DTD_TOKEN_TOTAL_BYTES(16384) + /*| USB_TD_DTD_TOKEN_IOC*/ + | USB_TD_DTD_TOKEN_MULTO(0) + | USB_TD_DTD_TOKEN_STATUS_ACTIVE + ; + + usb_endpoint_prime(endpoint, td); } usb_configuration_t usb_configuration_high_speed = { @@ -97,7 +143,7 @@ usb_endpoint_t usb_endpoint_bulk_in = { .in = &usb_endpoint_bulk_in, .out = 0, .setup_complete = 0, - .transfer_complete = usb_endpoint_bulk_transfer, + .transfer_complete = 0, }; usb_endpoint_t usb_endpoint_bulk_out = { @@ -106,7 +152,7 @@ usb_endpoint_t usb_endpoint_bulk_out = { .in = 0, .out = &usb_endpoint_bulk_out, .setup_complete = 0, - .transfer_complete = usb_endpoint_bulk_transfer, + .transfer_complete = 0, }; const usb_request_handlers_t usb_request_handlers = { @@ -157,10 +203,21 @@ bool usb_set_configuration( if( device->configuration && (device->configuration->number == 1) ) { usb_endpoint_init(&usb_endpoint_bulk_in); usb_endpoint_init(&usb_endpoint_bulk_out); + + usb_init_buffers_bulk(); - usb_endpoint_bulk_transfer(&usb_endpoint_bulk_out); - //usb_endpoint_bulk_transfer(&usb_endpoint_bulk_in); + sgpio_configure_for_rx_deep(); + + nvic_set_priority(NVIC_M4_SGPIO_IRQ, 0); + nvic_enable_irq(NVIC_M4_SGPIO_IRQ); + SGPIO_SET_EN_1 = (1 << SGPIO_SLICE_A); + + sgpio_cpld_stream_enable(); } else { + sgpio_cpld_stream_disable(); + + nvic_disable_irq(NVIC_M4_SGPIO_IRQ); + usb_endpoint_disable(&usb_endpoint_bulk_in); usb_endpoint_disable(&usb_endpoint_bulk_out); } @@ -175,7 +232,45 @@ bool usb_set_configuration( return true; }; +void sgpio_irqhandler() { + SGPIO_CLR_STATUS_1 = 0xFFFFFFFF; + + uint32_t* const p32 = &usb_bulk_buffer[usb_bulk_buffer_offset]; + volatile const uint32_t* const sgpio_reg_ss_base = SGPIO_PORT_BASE + 0x100; + + __asm__( + "ldr r0, [%[sgpio_reg_ss_base], #0]\n\t" // Slice A -> p_local[7] + "ldr r1, [%[sgpio_reg_ss_base], #32]\n\t" // Slice I -> p_local[6] + "ldr r2, [%[sgpio_reg_ss_base], #16]\n\t" // Slice E -> p_local[5] + "ldr r3, [%[sgpio_reg_ss_base], #36]\n\t" // Slice J -> p_local[4] + + "str r0, [%[p], #28]\n\t" + "str r1, [%[p], #24]\n\t" + "str r2, [%[p], #20]\n\t" + "str r3, [%[p], #16]\n\t" + + "ldr r0, [%[sgpio_reg_ss_base], #8]\n\t" // Slice C -> p_local[3] + "ldr r1, [%[sgpio_reg_ss_base], #40]\n\t" // Slice K -> p_local[2] + "ldr r2, [%[sgpio_reg_ss_base], #20]\n\t" // Slice F -> p_local[1] + "ldr r3, [%[sgpio_reg_ss_base], #44]\n\t" // Slice L -> p_local[0] + + "str r0, [%[p], #12]\n\t" + "str r1, [%[p], #8]\n\t" + "str r2, [%[p], #4]\n\t" + "str r3, [%[p], #0]\n\t" + : + : [sgpio_reg_ss_base] "l" (sgpio_reg_ss_base), + [p] "l" (p32) + : "r0", "r1", "r2", "r3" + ); + + usb_bulk_buffer_offset = (usb_bulk_buffer_offset + 32) & usb_bulk_buffer_mask; +} + int main(void) { + const uint32_t freq = 2441000000U; + uint8_t switchctrl = 0; + pin_setup(); enable_1v8_power(); cpu_clock_init(); @@ -193,9 +288,33 @@ int main(void) { usb_endpoint_init(&usb_endpoint_control_out); usb_endpoint_init(&usb_endpoint_control_in); + nvic_set_priority(NVIC_M4_USB0_IRQ, 255); + usb_run(&usb_device); - while (1) { + ssp1_init(); + ssp1_set_mode_max2837(); + max2837_setup(); + /* + rffc5071_setup(); +#ifdef JAWBREAKER + switchctrl = (SWITCHCTRL_AMP_BYPASS | SWITCHCTRL_HP); +#endif + rffc5071_rx(switchctrl); + rffc5071_set_frequency(500, 0); // 500 MHz, 0 Hz (Hz ignored) + */ + max2837_set_frequency(freq); + max2837_start(); + max2837_rx(); + ssp1_set_mode_max5864(); + max5864_xcvr(); + + while(true) { + while( usb_bulk_buffer_offset < 16384 ); + usb_endpoint_schedule_no_int(&usb_endpoint_bulk_in, &usb_td_bulk[0]); + + while( usb_bulk_buffer_offset >= 16384 ); + usb_endpoint_schedule_no_int(&usb_endpoint_bulk_in, &usb_td_bulk[1]); } return 0; From 09b768631eb266485ebcafd39bf84928dcddcd33 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 10 Oct 2012 15:22:41 -0700 Subject: [PATCH 32/41] Tragic, but simple and effective libusb test program for reading data from the HackRF bulk IN endpoint, and dumping it to a file. --- host/usb_test/Makefile | 77 ++++++++++++++++++ host/usb_test/usb_test.c | 172 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 249 insertions(+) create mode 100644 host/usb_test/Makefile create mode 100644 host/usb_test/usb_test.c diff --git a/host/usb_test/Makefile b/host/usb_test/Makefile new file mode 100644 index 00000000..138ca744 --- /dev/null +++ b/host/usb_test/Makefile @@ -0,0 +1,77 @@ +# Hey Emacs, this is a -*- makefile -*- +# +# Copyright 2010 Michael Ossmann +# Copyright 2012 Jared Boone +# +# This file is part of HackRF. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +# derived primarily from Makefiles in Project Ubertooth + +CC ?= gcc +AR ?= ar +INSTALL ?= /usr/bin/install +LDCONFIG ?= /sbin/ldconfig + +OPTFLAGS = -O2 +ANGRYFLAGS = -Wall #-Wextra -pedantic +CFLAGS += $(OPTFLAGS) $(ANGRYFLAGS) + +LIB_DIR ?= /usr/lib +INCLUDE_DIR ?= /usr/include +INSTALL_DIR ?= /usr/bin + +OS = $(shell uname) +ifeq ($(OS), FreeBSD) + LIBUSB = usb + CFLAGS += -DFREEBSD +else + LIBUSB = usb-1.0 +endif + +LDFLAGS += -l$(LIBUSB) + +TOOLS = usb_test + +ifeq ($(OS), Darwin) + CFLAGS += -I/opt/local/include/ + LDFLAGS += -L/opt/local/lib/ -rpath,/opt/local/lib +else + # +endif + +TOOLS_SOURCE = $(TOOLS:%=%.c) + +all: $(TOOLS) + +$(TOOLS): $(TOOLS_SOURCE) + $(CC) $(CFLAGS) -o $@ $@.c $(LDFLAGS) + +install: $(TOOLS) + $(INSTALL) -m 0755 $(TOOLS) $(INSTALL_DIR) + +cygwin-install: $(LIB_FILE) $(STATIC_LIB_FILE) + $(INSTALL) -m 0755 $(TOOLS) $(INSTALL_DIR) + +osx-install: $(LIB_FILE) $(TOOLS) + $(INSTALL) -m 0755 $(TOOLS) $(INSTALL_DIR) + +clean: + rm -f $(TOOLS) + +.PHONY: all clean install cygwin-install osx-install \ No newline at end of file diff --git a/host/usb_test/usb_test.c b/host/usb_test/usb_test.c new file mode 100644 index 00000000..29f08a86 --- /dev/null +++ b/host/usb_test/usb_test.c @@ -0,0 +1,172 @@ +/* + * Copyright 2012 Jared Boone + * + * This file is part of HackRF. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include +#include +#include + +#include +#include + +#include + +static float +TimevalDiff(const struct timeval *a, const struct timeval *b) +{ + return (a->tv_sec - b->tv_sec) + 1e-6f * (a->tv_usec - b->tv_usec); +} + +int fd = -1; +struct timeval time_start; +volatile uint32_t byte_count = 0; + +void write_callback(struct libusb_transfer* transfer) { + if( transfer->status == LIBUSB_TRANSFER_COMPLETED ) { + byte_count += transfer->actual_length; + write(fd, transfer->buffer, transfer->actual_length); + libusb_submit_transfer(transfer); + } else { + printf("transfer status was not 'completed'\n"); + } +} + +int main(int argc, char** argv) { + if( argc != 2 ) { + printf("Usage: usb_test \n"); + return -1; + } + + const uint32_t buffer_size = 16384; + + fd = open(argv[1], O_RDWR | O_CREAT | O_TRUNC, S_IRWXU | S_IRWXG | S_IRWXO); + if( fd == -1 ) { + printf("Failed to open file for write\n"); + return -2; + } + + libusb_context* context = NULL; + int result = libusb_init(NULL); + if( result != 0 ) { + printf("libusb_init() failed: %d\n", result); + return -4; + } + + libusb_device_handle* device = libusb_open_device_with_vid_pid(context, 0x1d50, 0x604b); + if( device == NULL ) { + printf("libusb_open_device_with_vid_pid() failed\n"); + return -5; + } + + //int speed = libusb_get_device_speed(device); + //printf("device speed: %d\n", speed); + + result = libusb_set_configuration(device, 1); + if( result != 0 ) { + printf("libusb_set_configuration() failed: %d\n", result); + return -6; + } + + result = libusb_claim_interface(device, 0); + if( result != 0 ) { + printf("libusb_claim_interface() failed: %d\n", result); + return -7; + } + + unsigned char endpoint_address = 0x81; + //unsigned char endpoint_address = 0x02; + + const uint32_t transfer_count = 1024; + struct libusb_transfer* transfers[transfer_count]; + for(uint32_t transfer_index=0; transfer_indexbuffer == 0 ) { + printf("malloc() failed\n"); + return -7; + } + + int error = libusb_submit_transfer(transfers[transfer_index]); + if( error != 0 ) { + printf("libusb_submit_transfer() failed: %d\n", error); + return -8; + } + } + + ////////////////////////////////////////////////////////////// + + struct timeval timeout = { 0, 500000 }; + struct timeval time_now; + + const double progress_interval = 1.0; + gettimeofday(&time_start, NULL); + + uint32_t call_count = 0; + do { + int error = libusb_handle_events_timeout(context, &timeout); + if( error != 0 ) { + printf("libusb_handle_events_timeout() failed: %d\n", error); + return -10; + } + + if( (call_count & 0xFF) == 0 ) { + gettimeofday(&time_now, NULL); + const float time_difference = TimevalDiff(&time_now, &time_start); + if( time_difference >= progress_interval ) { + const float rate = (float)byte_count / time_difference; + printf("%.1f/%.3f = %.1f MiB/second\n", + byte_count / 1e6f, + time_difference, + rate / 1e6f + ); + time_start = time_now; + byte_count = 0; + } + } + call_count += 1; + } while(1); + + result = libusb_release_interface(device, 0); + if( result != 0 ) { + printf("libusb_release_interface() failed: %d\n", result); + return -2000; + } + + libusb_close(device); + + libusb_exit(context); + + return 0; +} From 092c5b7b0fd4c974446aff3f51b26f83132bd540 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 10 Oct 2012 15:42:30 -0700 Subject: [PATCH 33/41] Removed removing of .usbram section from .bin file output. Because there's no more .usbram section! --- firmware/common/Makefile_inc.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/common/Makefile_inc.mk b/firmware/common/Makefile_inc.mk index 1c635525..98716f86 100644 --- a/firmware/common/Makefile_inc.mk +++ b/firmware/common/Makefile_inc.mk @@ -80,7 +80,7 @@ flash: $(BINARY).flash %.bin: %.elf @#printf " OBJCOPY $(*).bin\n" - $(Q)$(OBJCOPY) -Obinary -R .usbram $(*).elf $(*).bin + $(Q)$(OBJCOPY) -Obinary $(*).elf $(*).bin %.hex: %.elf @#printf " OBJCOPY $(*).hex\n" From c02bf358d11055f4d31455da668fb1601fee557d Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 10 Oct 2012 15:50:31 -0700 Subject: [PATCH 34/41] Added license/copyright to several Makefiles. --- firmware/Makefile | 20 ++++++++++++++++++ firmware/blinky/Makefile | 21 +++++++++++++++++++ firmware/blinky_rom_to_ram/Makefile | 21 +++++++++++++++++++ firmware/sgpio-rx/Makefile | 20 ++++++++++++++++++ firmware/sgpio/Makefile | 20 ++++++++++++++++++ .../sgpio_passthrough_rom_to_ram/Makefile | 21 +++++++++++++++++++ 6 files changed, 123 insertions(+) diff --git a/firmware/Makefile b/firmware/Makefile index 9111dbd7..f50cdb58 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -1,4 +1,24 @@ # Hey Emacs, this is a -*- makefile -*- +# +# Copyright 2012 Jared Boone +# +# This file is part of HackRF. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# TARGETS = blinky \ mixertx \ diff --git a/firmware/blinky/Makefile b/firmware/blinky/Makefile index 4d1aac31..468916f3 100644 --- a/firmware/blinky/Makefile +++ b/firmware/blinky/Makefile @@ -1,4 +1,25 @@ # Hey Emacs, this is a -*- makefile -*- +# +# Copyright 2012 Michael Ossmann +# Copyright 2012 Jared Boone +# +# This file is part of HackRF. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# BINARY = blinky diff --git a/firmware/blinky_rom_to_ram/Makefile b/firmware/blinky_rom_to_ram/Makefile index d4f487b8..b93e84e6 100644 --- a/firmware/blinky_rom_to_ram/Makefile +++ b/firmware/blinky_rom_to_ram/Makefile @@ -1,4 +1,25 @@ # Hey Emacs, this is a -*- makefile -*- +# +# Copyright 2012 Michael Ossmann +# Copyright 2012 Jared Boone +# +# This file is part of HackRF. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# BINARY = blinky diff --git a/firmware/sgpio-rx/Makefile b/firmware/sgpio-rx/Makefile index 894853b0..db89574e 100644 --- a/firmware/sgpio-rx/Makefile +++ b/firmware/sgpio-rx/Makefile @@ -1,4 +1,24 @@ # Hey Emacs, this is a -*- makefile -*- +# +# Copyright 2012 Jared Boone +# +# This file is part of HackRF. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# BINARY = sgpio-rx diff --git a/firmware/sgpio/Makefile b/firmware/sgpio/Makefile index 1c214bbb..5429c192 100644 --- a/firmware/sgpio/Makefile +++ b/firmware/sgpio/Makefile @@ -1,4 +1,24 @@ # Hey Emacs, this is a -*- makefile -*- +# +# Copyright 2012 Jared Boone +# +# This file is part of HackRF. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# BINARY = sgpio diff --git a/firmware/sgpio_passthrough_rom_to_ram/Makefile b/firmware/sgpio_passthrough_rom_to_ram/Makefile index 98eb5746..073a583b 100644 --- a/firmware/sgpio_passthrough_rom_to_ram/Makefile +++ b/firmware/sgpio_passthrough_rom_to_ram/Makefile @@ -1,4 +1,25 @@ # Hey Emacs, this is a -*- makefile -*- +# +# Copyright 2012 Jared Boone +# Copyright 2012 Benjamin Vernoux +# +# This file is part of HackRF. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# BINARY = sgpio_passthrough From 8a54e09e158b11351510166ff6af78de131a0aa2 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 10 Oct 2012 16:13:37 -0700 Subject: [PATCH 35/41] Elimination of unused argument warnings. --- firmware/common/fault_handler.c | 1 + firmware/common/rffc5071.c | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/firmware/common/fault_handler.c b/firmware/common/fault_handler.c index 6127d538..7dce1f3e 100644 --- a/firmware/common/fault_handler.c +++ b/firmware/common/fault_handler.c @@ -34,6 +34,7 @@ void hard_fault_handler(void) { void hard_fault_handler_c(uint32_t* args) { + (void)args; // args[0-7]: r0, r1, r2, r3, r12, lr, pc, psr // Other interesting registers to examine: // CFSR: Configurable Fault Status Register diff --git a/firmware/common/rffc5071.c b/firmware/common/rffc5071.c index e3cc0109..590bbfb1 100644 --- a/firmware/common/rffc5071.c +++ b/firmware/common/rffc5071.c @@ -379,6 +379,8 @@ void rffc5071_tx(uint8_t gpo) { gpo |= SWITCHCTRL_NO_TX_AMP_PWR; gpo |= (SWITCHCTRL_TX | SWITCHCTRL_NO_RX_AMP_PWR); rffc5071_set_gpo(gpo); +#else + (void)gpo; #endif rffc5071_regs_commit(); @@ -403,6 +405,8 @@ void rffc5071_rx(uint8_t gpo) { gpo |= SWITCHCTRL_NO_RX_AMP_PWR; gpo |= SWITCHCTRL_NO_TX_AMP_PWR; rffc5071_set_gpo(gpo); +#else + (void)gpo; #endif rffc5071_regs_commit(); From 5dbbae6d9c27805e47ff41c0ebae40834be81971 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 10 Oct 2012 16:14:22 -0700 Subject: [PATCH 36/41] Removed unused functions to silence warnings. --- firmware/usb_performance/usb.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/firmware/usb_performance/usb.c b/firmware/usb_performance/usb.c index 5054160b..535cb52d 100644 --- a/firmware/usb_performance/usb.c +++ b/firmware/usb_performance/usb.c @@ -195,7 +195,7 @@ void usb_endpoint_prime( USB0_ENDPTPRIME = USB0_ENDPTPRIME_PERB(1 << endpoint_number); } } - +/* static bool usb_endpoint_is_priming( const usb_endpoint_t* const endpoint ) { @@ -206,7 +206,7 @@ static bool usb_endpoint_is_priming( return USB0_ENDPTPRIME & USB0_ENDPTPRIME_PERB(1 << endpoint_number); } } - +*/ void usb_endpoint_flush( const usb_endpoint_t* const endpoint ) { @@ -217,7 +217,7 @@ void usb_endpoint_flush( usb_flush_primed_endpoints(USB0_ENDPTFLUSH_FERB(1 << endpoint_number)); } } - +/* static bool usb_endpoint_is_flushing( const usb_endpoint_t* const endpoint ) { @@ -228,7 +228,7 @@ static bool usb_endpoint_is_flushing( return USB0_ENDPTFLUSH & USB0_ENDPTFLUSH_FERB(1 << endpoint_number); } } - +*/ bool usb_endpoint_is_ready( const usb_endpoint_t* const endpoint ) { From 0253642b2e334f63337bae31a004b51ff47de417 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 10 Oct 2012 16:15:12 -0700 Subject: [PATCH 37/41] Added extern for usb_set_configuration() to eliminate compiler warning. TODO: Eventually, this should be just a callback, not the complete SET_CONFIGURATION implementation. --- firmware/usb_performance/usb.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/firmware/usb_performance/usb.h b/firmware/usb_performance/usb.h index 2f2104c5..7b9c9390 100644 --- a/firmware/usb_performance/usb.h +++ b/firmware/usb_performance/usb.h @@ -31,6 +31,11 @@ #define ATTR_ALIGNED(x) __attribute__ ((aligned(x))) #define ATTR_SECTION(x) __attribute__ ((section(x))) +extern bool usb_set_configuration( + usb_device_t* const device, + const uint_fast8_t configuration_number +); + void usb_peripheral_reset(); void usb_device_init( From 693e61b31c7bf6ef4add8a813d92ed7c08f3d2ce Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 10 Oct 2012 16:17:02 -0700 Subject: [PATCH 38/41] Removed block of assembly in favor of C code. TODO: Look at assembly and compiler -O options to avoid assembly. --- firmware/usb_performance/usb_performance.c | 37 ++++++---------------- 1 file changed, 9 insertions(+), 28 deletions(-) diff --git a/firmware/usb_performance/usb_performance.c b/firmware/usb_performance/usb_performance.c index 4bc56ebf..7e90ac3f 100644 --- a/firmware/usb_performance/usb_performance.c +++ b/firmware/usb_performance/usb_performance.c @@ -235,34 +235,15 @@ bool usb_set_configuration( void sgpio_irqhandler() { SGPIO_CLR_STATUS_1 = 0xFFFFFFFF; - uint32_t* const p32 = &usb_bulk_buffer[usb_bulk_buffer_offset]; - volatile const uint32_t* const sgpio_reg_ss_base = SGPIO_PORT_BASE + 0x100; - - __asm__( - "ldr r0, [%[sgpio_reg_ss_base], #0]\n\t" // Slice A -> p_local[7] - "ldr r1, [%[sgpio_reg_ss_base], #32]\n\t" // Slice I -> p_local[6] - "ldr r2, [%[sgpio_reg_ss_base], #16]\n\t" // Slice E -> p_local[5] - "ldr r3, [%[sgpio_reg_ss_base], #36]\n\t" // Slice J -> p_local[4] - - "str r0, [%[p], #28]\n\t" - "str r1, [%[p], #24]\n\t" - "str r2, [%[p], #20]\n\t" - "str r3, [%[p], #16]\n\t" - - "ldr r0, [%[sgpio_reg_ss_base], #8]\n\t" // Slice C -> p_local[3] - "ldr r1, [%[sgpio_reg_ss_base], #40]\n\t" // Slice K -> p_local[2] - "ldr r2, [%[sgpio_reg_ss_base], #20]\n\t" // Slice F -> p_local[1] - "ldr r3, [%[sgpio_reg_ss_base], #44]\n\t" // Slice L -> p_local[0] - - "str r0, [%[p], #12]\n\t" - "str r1, [%[p], #8]\n\t" - "str r2, [%[p], #4]\n\t" - "str r3, [%[p], #0]\n\t" - : - : [sgpio_reg_ss_base] "l" (sgpio_reg_ss_base), - [p] "l" (p32) - : "r0", "r1", "r2", "r3" - ); + uint32_t* const p = (uint32_t*)&usb_bulk_buffer[usb_bulk_buffer_offset]; + p[7] = SGPIO_REG_SS(SGPIO_SLICE_A); + p[6] = SGPIO_REG_SS(SGPIO_SLICE_I); + p[5] = SGPIO_REG_SS(SGPIO_SLICE_E); + p[4] = SGPIO_REG_SS(SGPIO_SLICE_J); + p[3] = SGPIO_REG_SS(SGPIO_SLICE_C); + p[2] = SGPIO_REG_SS(SGPIO_SLICE_K); + p[1] = SGPIO_REG_SS(SGPIO_SLICE_F); + p[0] = SGPIO_REG_SS(SGPIO_SLICE_L); usb_bulk_buffer_offset = (usb_bulk_buffer_offset + 32) & usb_bulk_buffer_mask; } From 788140f79afdbeb19d4f6bba12743289623833b0 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 10 Oct 2012 16:17:23 -0700 Subject: [PATCH 39/41] Cast USB buffer address to eliminate compiler warning. --- firmware/usb_performance/usb_performance.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/usb_performance/usb_performance.c b/firmware/usb_performance/usb_performance.c index 7e90ac3f..18128d95 100644 --- a/firmware/usb_performance/usb_performance.c +++ b/firmware/usb_performance/usb_performance.c @@ -37,7 +37,7 @@ #include "usb_descriptor.h" #include "usb_standard_request.h" -uint8_t* const usb_bulk_buffer = 0x20004000; +uint8_t* const usb_bulk_buffer = (uint8_t*)0x20004000; static volatile uint32_t usb_bulk_buffer_offset = 0; static const uint32_t usb_bulk_buffer_mask = 32768 - 1; From d5db378647ab70219a73a17f1fd3dc910f1a5639 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 10 Oct 2012 16:17:57 -0700 Subject: [PATCH 40/41] Put RFFC5071 code back in place. --- firmware/usb_performance/usb_performance.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/firmware/usb_performance/usb_performance.c b/firmware/usb_performance/usb_performance.c index 18128d95..5a6989e3 100644 --- a/firmware/usb_performance/usb_performance.c +++ b/firmware/usb_performance/usb_performance.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include "usb.h" @@ -276,14 +277,14 @@ int main(void) { ssp1_init(); ssp1_set_mode_max2837(); max2837_setup(); - /* + rffc5071_setup(); #ifdef JAWBREAKER switchctrl = (SWITCHCTRL_AMP_BYPASS | SWITCHCTRL_HP); #endif rffc5071_rx(switchctrl); rffc5071_set_frequency(500, 0); // 500 MHz, 0 Hz (Hz ignored) - */ + max2837_set_frequency(freq); max2837_start(); max2837_rx(); From 3a9d7432c3847832f290f64f1ecbc155c6436a97 Mon Sep 17 00:00:00 2001 From: Jared Boone Date: Wed, 10 Oct 2012 16:27:05 -0700 Subject: [PATCH 41/41] Changed compile optimization flag to -Os from -O2. TitanMKD demonstrated conclusively that it's a good thing. --- firmware/common/Makefile_inc.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/common/Makefile_inc.mk b/firmware/common/Makefile_inc.mk index 98716f86..8ea2f6be 100644 --- a/firmware/common/Makefile_inc.mk +++ b/firmware/common/Makefile_inc.mk @@ -46,7 +46,7 @@ OBJDUMP = $(PREFIX)-objdump GDB = $(PREFIX)-gdb TOOLCHAIN_DIR := $(shell dirname `which $(CC)`)/../$(PREFIX) -CFLAGS += -std=c99 -O2 -g3 -Wall -Wextra -I$(LIBOPENCM3)/include -I../common \ +CFLAGS += -std=c99 -Os -g3 -Wall -Wextra -I$(LIBOPENCM3)/include -I../common \ -fno-common -mcpu=cortex-m4 -mthumb -MD \ -mfloat-abi=hard -mfpu=fpv4-sp-d16 \ $(HACKRF_OPTS)