From 49257e60e30f4c416c3f6be2b4e05d956a3a41be Mon Sep 17 00:00:00 2001 From: Dominic Spill Date: Tue, 14 Feb 2017 17:59:29 -0700 Subject: [PATCH 1/4] Remove Jellybean support from firmware - nobody has a jellybean board --- firmware/common/hackrf_core.c | 103 +++---------------------------- firmware/common/hackrf_core.h | 26 +------- firmware/common/max2837.h | 10 --- firmware/common/max2837_target.c | 31 ---------- firmware/common/si5351c.c | 53 ---------------- host/libhackrf/src/hackrf.c | 11 ++-- 6 files changed, 12 insertions(+), 222 deletions(-) diff --git a/firmware/common/hackrf_core.c b/firmware/common/hackrf_core.c index 185dc5b7..b41870d5 100644 --- a/firmware/common/hackrf_core.c +++ b/firmware/common/hackrf_core.c @@ -62,21 +62,17 @@ static struct gpio_t gpio_max2837_select = GPIO(0, 15); static struct gpio_t gpio_max2837_enable = GPIO(2, 6); static struct gpio_t gpio_max2837_rx_enable = GPIO(2, 5); static struct gpio_t gpio_max2837_tx_enable = GPIO(2, 4); -#ifdef JELLYBEAN -static struct gpio_t gpio_max2837_rxhp = GPIO(2, 0); -static struct gpio_t gpio_max2837_b1 = GPIO(2, 9); -static struct gpio_t gpio_max2837_b2 = GPIO(2, 10); -static struct gpio_t gpio_max2837_b3 = GPIO(2, 11); -static struct gpio_t gpio_max2837_b4 = GPIO(2, 12); -static struct gpio_t gpio_max2837_b5 = GPIO(2, 13); -static struct gpio_t gpio_max2837_b6 = GPIO(2, 14); -static struct gpio_t gpio_max2837_b7 = GPIO(2, 15); -#endif /* MAX5864 SPI chip select (AD_CS) GPIO PinMux */ static struct gpio_t gpio_max5864_select = GPIO(2, 7); +/* RFFC5071 GPIO serial interface PinMux */ #if (defined JAWBREAKER || defined HACKRF_ONE || defined RAD1O) +static struct gpio_t gpio_rffc5072_select = GPIO(2, 13); +static struct gpio_t gpio_rffc5072_clock = GPIO(5, 6); +static struct gpio_t gpio_rffc5072_data = GPIO(3, 3); +static struct gpio_t gpio_rffc5072_reset = GPIO(2, 14); + /* static struct gpio_t gpio_sync_in_a = GPIO(3, 8); static struct gpio_t gpio_sync_in_b = GPIO(3, 9); @@ -232,16 +228,6 @@ max2837_driver_t max2837 = { .gpio_enable = &gpio_max2837_enable, .gpio_rx_enable = &gpio_max2837_rx_enable, .gpio_tx_enable = &gpio_max2837_tx_enable, -#ifdef JELLYBEAN - .gpio_rxhp = &gpio_max2837_rxhp, - .gpio_b1 = &gpio_max2837_b1, - .gpio_b2 = &gpio_max2837_b2, - .gpio_b3 = &gpio_max2837_b3, - .gpio_b4 = &gpio_max2837_b4, - .gpio_b5 = &gpio_max2837_b5, - .gpio_b6 = &gpio_max2837_b6, - .gpio_b7 = &gpio_max2837_b7, -#endif .target_init = max2837_target_init, .set_mode = max2837_target_set_mode, }; @@ -434,53 +420,6 @@ bool sample_rate_frac_set(uint32_t rate_num, uint32_t rate_denom) } bool sample_rate_set(const uint32_t sample_rate_hz) { -#ifdef JELLYBEAN - /* Due to design issues, Jellybean/Lemondrop frequency plan is limited. - * Long version of the story: The MAX2837 reference frequency - * originates from the same PLL as the sample clocks, and in order to - * keep the sample clocks in phase and keep jitter noise down, the MAX2837 - * and sample clocks must be integer-related. - */ - uint32_t r_div_sample = 2; - uint32_t r_div_sgpio = 1; - - switch( sample_rate_hz ) { - case 5000000: - r_div_sample = 3; /* 800 MHz / 20 / 8 = 5 MHz */ - r_div_sgpio = 2; /* 800 MHz / 20 / 4 = 10 MHz */ - break; - - case 10000000: - r_div_sample = 2; /* 800 MHz / 20 / 4 = 10 MHz */ - r_div_sgpio = 1; /* 800 MHz / 20 / 2 = 20 MHz */ - break; - - case 20000000: - r_div_sample = 1; /* 800 MHz / 20 / 2 = 20 MHz */ - r_div_sgpio = 0; /* 800 MHz / 20 / 1 = 40 MHz */ - break; - - default: - return false; - } - - hackrf_ui_setSampleRate(sample_rate_hz); - - /* NOTE: Because MS1, 2, 3 outputs are slaved to PLLA, the p1, p2, p3 - * values are irrelevant. */ - - /* MS0/CLK1 is the source for the MAX5864 codec. */ - si5351c_configure_multisynth(&clock_gen, 1, 4608, 0, 1, r_div_sample); - - /* MS0/CLK2 is the source for the CPLD codec clock (same as CLK1). */ - si5351c_configure_multisynth(&clock_gen, 2, 4608, 0, 1, r_div_sample); - - /* MS0/CLK3 is the source for the SGPIO clock. */ - si5351c_configure_multisynth(&clock_gen, 3, 4608, 0, 1, r_div_sgpio); - - return true; -#endif - #if (defined JAWBREAKER || defined HACKRF_ONE || defined RAD1O) uint32_t p1 = 4608; uint32_t p2 = 0; @@ -574,29 +513,6 @@ void cpu_clock_init(void) si5351c_configure_pll_sources(&clock_gen); si5351c_configure_pll_multisynth(&clock_gen); -#ifdef JELLYBEAN - /* - * Jellybean/Lemondrop clocks: - * CLK0 -> MAX2837 - * CLK1 -> MAX5864/CPLD.GCLK0 - * CLK2 -> CPLD.GCLK1 - * CLK3 -> CPLD.GCLK2 - * CLK4 -> LPC4330 - * CLK5 -> RFFC5072 - * CLK6 -> extra - * CLK7 -> extra - */ - - /* MS0/CLK0 is the source for the MAX2837 clock input. */ - si5351c_configure_multisynth(&clock_gen, 0, 2048, 0, 1, 0); /* 40MHz */ - - /* MS4/CLK4 is the source for the LPC43xx microcontroller. */ - si5351c_configure_multisynth(&clock_gen, 4, 8021, 0, 3, 0); /* 12MHz */ - - /* MS5/CLK5 is the source for the RFFC5071 mixer. */ - si5351c_configure_multisynth(&clock_gen, 5, 1536, 0, 1, 0); /* 50MHz */ -#endif - #if (defined JAWBREAKER || defined HACKRF_ONE) /* * Jawbreaker clocks: @@ -674,11 +590,6 @@ void cpu_clock_init(void) //FIXME a lot of the details here should be in a CGU driver -#ifdef JELLYBEAN - /* configure xtal oscillator for external clock input signal */ - CGU_XTAL_OSC_CTRL |= CGU_XTAL_OSC_CTRL_BYPASS; -#endif - /* set xtal oscillator to low frequency mode */ CGU_XTAL_OSC_CTRL &= ~CGU_XTAL_OSC_CTRL_HF_MASK; @@ -936,7 +847,7 @@ void pin_setup(void) { scu_pinmux(SCU_PINMUX_EN1V8, SCU_GPIO_NOPULL); /* Configure USB indicators */ -#if (defined JELLYBEAN || defined JAWBREAKER) +#ifdef JAWBREAKER scu_pinmux(SCU_PINMUX_USB_LED0, SCU_CONF_FUNCTION3); scu_pinmux(SCU_PINMUX_USB_LED1, SCU_CONF_FUNCTION3); #endif diff --git a/firmware/common/hackrf_core.h b/firmware/common/hackrf_core.h index 82cfc52c..fbace49f 100644 --- a/firmware/common/hackrf_core.h +++ b/firmware/common/hackrf_core.h @@ -44,15 +44,10 @@ extern "C" #include "cpld_jtag.h" /* hardware identification number */ -#define BOARD_ID_JELLYBEAN 0 #define BOARD_ID_JAWBREAKER 1 #define BOARD_ID_HACKRF_ONE 2 #define BOARD_ID_RAD1O 3 -#ifdef JELLYBEAN -#define BOARD_ID BOARD_ID_JELLYBEAN -#endif - #ifdef JAWBREAKER #define BOARD_ID BOARD_ID_JAWBREAKER #endif @@ -86,7 +81,7 @@ extern "C" #define SCU_PINMUX_BOOT3 (P2_9) /* GPIO1[10] on P2_9 */ /* USB peripheral */ -#if (defined JELLYBEAN || defined JAWBREAKER) +#ifdef JAWBREAKER #define SCU_PINMUX_USB_LED0 (P6_8) #define SCU_PINMUX_USB_LED1 (P6_7) #endif @@ -117,9 +112,6 @@ extern "C" #define SCU_PINMUX_SGPIO5 (P6_6) #define SCU_PINMUX_SGPIO6 (P2_2) #define SCU_PINMUX_SGPIO7 (P1_0) -#ifdef JELLYBEAN -#define SCU_PINMUX_SGPIO8 (P1_12) -#endif #if (defined JAWBREAKER || defined HACKRF_ONE || defined RAD1O) #define SCU_PINMUX_SGPIO8 (P9_6) #endif @@ -132,16 +124,6 @@ extern "C" #define SCU_PINMUX_SGPIO15 (P4_10) /* MAX2837 GPIO (XCVR_CTL) PinMux */ -#ifdef JELLYBEAN -#define SCU_XCVR_RXHP (P4_0) /* GPIO2[0] on P4_0 */ -#define SCU_XCVR_B1 (P5_0) /* GPIO2[9] on P5_0 */ -#define SCU_XCVR_B2 (P5_1) /* GPIO2[10] on P5_1 */ -#define SCU_XCVR_B3 (P5_2) /* GPIO2[11] on P5_2 */ -#define SCU_XCVR_B4 (P5_3) /* GPIO2[12] on P5_3 */ -#define SCU_XCVR_B5 (P5_4) /* GPIO2[13] on P5_4 */ -#define SCU_XCVR_B6 (P5_5) /* GPIO2[14] on P5_5 */ -#define SCU_XCVR_B7 (P5_6) /* GPIO2[15] on P5_6 */ -#endif #ifdef RAD1O #define SCU_XCVR_RXHP (P8_1) /* GPIO[] on P8_1 */ #define SCU_XCVR_B6 (P8_2) /* GPIO[] on P8_2 */ @@ -157,12 +139,6 @@ extern "C" #define SCU_AD_CS (P5_7) /* GPIO2[7] on P5_7 */ /* RFFC5071 GPIO serial interface PinMux */ -#ifdef JELLYBEAN -#define SCU_MIXER_ENX (P7_0) /* GPIO3[8] on P7_0 */ -#define SCU_MIXER_SCLK (P7_1) /* GPIO3[9] on P7_1 */ -#define SCU_MIXER_SDATA (P7_2) /* GPIO3[10] on P7_2 */ -#define SCU_MIXER_RESETX (P7_3) /* GPIO3[11] on P7_3 */ -#endif #if (defined JAWBREAKER || defined HACKRF_ONE) #define SCU_MIXER_ENX (P5_4) /* GPIO2[13] on P5_4 */ #define SCU_MIXER_SCLK (P2_6) /* GPIO5[6] on P2_6 */ diff --git a/firmware/common/max2837.h b/firmware/common/max2837.h index dcf6829c..a353b88f 100644 --- a/firmware/common/max2837.h +++ b/firmware/common/max2837.h @@ -48,16 +48,6 @@ struct max2837_driver_t { gpio_t gpio_enable; gpio_t gpio_rx_enable; gpio_t gpio_tx_enable; -#ifdef JELLYBEAN - gpio_t gpio_rxhp; - gpio_t gpio_b1; - gpio_t gpio_b2; - gpio_t gpio_b3; - gpio_t gpio_b4; - gpio_t gpio_b5; - gpio_t gpio_b6; - gpio_t gpio_b7; -#endif void (*target_init)(max2837_driver_t* const drv); void (*set_mode)(max2837_driver_t* const drv, const max2837_mode_t new_mode); max2837_mode_t mode; diff --git a/firmware/common/max2837_target.c b/firmware/common/max2837_target.c index dc78b4fa..13cc7165 100644 --- a/firmware/common/max2837_target.c +++ b/firmware/common/max2837_target.c @@ -34,16 +34,6 @@ void max2837_target_init(max2837_driver_t* const drv) { scu_pinmux(SCU_XCVR_CS, SCU_GPIO_FAST); /* Configure XCVR_CTL GPIO pins. */ -#ifdef JELLYBEAN - scu_pinmux(SCU_XCVR_RXHP, SCU_GPIO_FAST); - scu_pinmux(SCU_XCVR_B1, SCU_GPIO_FAST); - scu_pinmux(SCU_XCVR_B2, SCU_GPIO_FAST); - scu_pinmux(SCU_XCVR_B3, SCU_GPIO_FAST); - scu_pinmux(SCU_XCVR_B4, SCU_GPIO_FAST); - scu_pinmux(SCU_XCVR_B5, SCU_GPIO_FAST); - scu_pinmux(SCU_XCVR_B6, SCU_GPIO_FAST); - scu_pinmux(SCU_XCVR_B7, SCU_GPIO_FAST); -#endif scu_pinmux(SCU_XCVR_ENABLE, SCU_GPIO_FAST); scu_pinmux(SCU_XCVR_RXENABLE, SCU_GPIO_FAST); scu_pinmux(SCU_XCVR_TXENABLE, SCU_GPIO_FAST); @@ -52,27 +42,6 @@ void max2837_target_init(max2837_driver_t* const drv) { gpio_output(drv->gpio_enable); gpio_output(drv->gpio_rx_enable); gpio_output(drv->gpio_tx_enable); -#ifdef JELLYBEAN - gpio_output(drv->gpio_rxhp); - gpio_output(drv->gpio_b1); - gpio_output(drv->gpio_b2); - gpio_output(drv->gpio_b3); - gpio_output(drv->gpio_b4); - gpio_output(drv->gpio_b5); - gpio_output(drv->gpio_b6); - gpio_output(drv->gpio_b7); -#endif - -#ifdef JELLYBEAN - gpio_set(drv->gpio_rxhp); - gpio_set(drv->gpio_b1); - gpio_set(drv->gpio_b2); - gpio_set(drv->gpio_b3); - gpio_set(drv->gpio_b4); - gpio_set(drv->gpio_b5); - gpio_set(drv->gpio_b6); - gpio_set(drv->gpio_b7); -#endif } void max2837_target_set_mode(max2837_driver_t* const drv, const max2837_mode_t new_mode) { diff --git a/firmware/common/si5351c.c b/firmware/common/si5351c.c index 89932191..465b2370 100644 --- a/firmware/common/si5351c.c +++ b/firmware/common/si5351c.c @@ -164,59 +164,6 @@ void si5351c_configure_multisynth(si5351c_driver_t* const drv, si5351c_write(drv, data, sizeof(data)); } -#ifdef JELLYBEAN -/* - * Registers 16 through 23: CLKx Control - * CLK0: - * CLK0_PDN=0 (powered up) - * MS0_INT=1 (integer mode) - * MS0_SRC=0 (PLLA as source for MultiSynth 0) - * CLK0_INV=0 (not inverted) - * CLK0_SRC=3 (MS0 as input source) - * CLK0_IDRV=3 (8mA) - * CLK1: - * CLK1_PDN=0 (powered up) - * MS1_INT=1 (integer mode) - * MS1_SRC=0 (PLLA as source for MultiSynth 1) - * CLK1_INV=0 (not inverted) - * CLK1_SRC=2 (MS0 as input source) - * CLK1_IDRV=3 (8mA) - * CLK2: - * CLK2_PDN=0 (powered up) - * MS2_INT=1 (integer mode) - * MS2_SRC=0 (PLLA as source for MultiSynth 2) - * CLK2_INV=0 (not inverted) - * CLK2_SRC=2 (MS0 as input source) - * CLK2_IDRV=3 (8mA) - * CLK3: - * CLK3_PDN=0 (powered up) - * MS3_INT=1 (integer mode) - * MS3_SRC=0 (PLLA as source for MultiSynth 3) - * CLK3_INV=0 (inverted) - * CLK3_SRC=2 (MS0 as input source) - * CLK3_IDRV=3 (8mA) - * CLK4: - * CLK4_PDN=0 (powered up) - * MS4_INT=0 (fractional mode -- to support 12MHz to LPC for USB DFU) - * MS4_SRC=0 (PLLA as source for MultiSynth 4) - * CLK4_INV=0 (not inverted) - * CLK4_SRC=3 (MS4 as input source) - * CLK4_IDRV=3 (8mA) - * CLK5: - * CLK5_PDN=0 (powered up) - * MS5_INT=1 (integer mode) - * MS5_SRC=0 (PLLA as source for MultiSynth 5) - * CLK5_INV=0 (not inverted) - * CLK5_SRC=3 (MS5 as input source) - * CLK5_IDRV=3 (8mA) - */ -void si5351c_configure_clock_control(si5351c_driver_t* const drv) -{ - uint8_t data[] = { 16, 0x4F, 0x4B, 0x4B, 0x4B, 0x0F, 0x4F, 0xC0, 0xC0 }; - si5351c_write(drv, data, sizeof(data)); -} -#endif - #if (defined JAWBREAKER || defined HACKRF_ONE) void si5351c_configure_clock_control(si5351c_driver_t* const drv, const enum pll_sources source) { diff --git a/host/libhackrf/src/hackrf.c b/host/libhackrf/src/hackrf.c index 151f4e8e..809d6618 100644 --- a/host/libhackrf/src/hackrf.c +++ b/host/libhackrf/src/hackrf.c @@ -80,10 +80,7 @@ typedef enum { HACKRF_VENDOR_REQUEST_RESET = 30, } hackrf_vendor_request; -typedef enum { - USB_CONFIG_STANDARD = 0x1, - USB_CONFIG_CPLD_UPDATE = 0x2, -} hackrf_usb_configurations; +#define USB_CONFIG_STANDARD 0x1 typedef enum { HACKRF_TRANSCEIVER_MODE_OFF = 0, @@ -385,9 +382,9 @@ hackrf_device_list_t* ADDCALL hackrf_device_list() { ssize_t i; libusb_device_handle* usb_device = NULL; - uint_fast8_t serial_descriptor_index; + uint8_t serial_descriptor_index; char serial_number[64]; - int serial_number_length; + uint8_t idx, serial_number_length; hackrf_device_list_t* list = calloc(1, sizeof(*list)); if ( list == NULL ) @@ -412,7 +409,7 @@ hackrf_device_list_t* ADDCALL hackrf_device_list() if((device_descriptor.idProduct == hackrf_one_usb_pid) || (device_descriptor.idProduct == hackrf_jawbreaker_usb_pid) || (device_descriptor.idProduct == rad1o_usb_pid)) { - int idx = list->devicecount++; + idx = list->devicecount++; list->usb_board_ids[idx] = device_descriptor.idProduct; list->usb_device_index[idx] = i; From c6be7dea3eea7bbe355b12f4a22f7a103491a1d8 Mon Sep 17 00:00:00 2001 From: Dominic Spill Date: Tue, 14 Feb 2017 18:29:14 -0700 Subject: [PATCH 2/4] Fix build warnings for unused GPIO pins --- firmware/common/hackrf_core.c | 36 +++++++---------------------------- 1 file changed, 7 insertions(+), 29 deletions(-) diff --git a/firmware/common/hackrf_core.c b/firmware/common/hackrf_core.c index b41870d5..9bdcf9d6 100644 --- a/firmware/common/hackrf_core.c +++ b/firmware/common/hackrf_core.c @@ -67,28 +67,17 @@ static struct gpio_t gpio_max2837_tx_enable = GPIO(2, 4); static struct gpio_t gpio_max5864_select = GPIO(2, 7); /* RFFC5071 GPIO serial interface PinMux */ -#if (defined JAWBREAKER || defined HACKRF_ONE || defined RAD1O) -static struct gpio_t gpio_rffc5072_select = GPIO(2, 13); -static struct gpio_t gpio_rffc5072_clock = GPIO(5, 6); -static struct gpio_t gpio_rffc5072_data = GPIO(3, 3); -static struct gpio_t gpio_rffc5072_reset = GPIO(2, 14); +// #ifdef RAD1O +// static struct gpio_t gpio_rffc5072_select = GPIO(2, 13); +// static struct gpio_t gpio_rffc5072_clock = GPIO(5, 6); +// static struct gpio_t gpio_rffc5072_data = GPIO(3, 3); +// static struct gpio_t gpio_rffc5072_reset = GPIO(2, 14); +// #endif -/* -static struct gpio_t gpio_sync_in_a = GPIO(3, 8); -static struct gpio_t gpio_sync_in_b = GPIO(3, 9); -static struct gpio_t gpio_sync_out_a = GPIO(3, 10); -static struct gpio_t gpio_sync_out_b = GPIO(3, 11); -*/ static struct gpio_t gpio_sync_in_a = GPIO(3, 10); static struct gpio_t gpio_sync_in_b = GPIO(3, 11); static struct gpio_t gpio_sync_out_a = GPIO(3, 8); static struct gpio_t gpio_sync_out_b = GPIO(3, 9); -#endif - -/* RF LDO control */ -// #ifdef JAWBREAKER -// static struct gpio_t gpio_rf_ldo_enable = GPIO(2, 9); -// #endif /* RF supply (VAA) control */ #ifdef HACKRF_ONE @@ -132,19 +121,10 @@ static struct gpio_t gpio_tx_amp = GPIO(2, 15); static struct gpio_t gpio_rx_lna = GPIO(5, 15); #endif -#if 0 -/* GPIO Input */ -static struct gpio_t gpio_boot[] = { - GPIO(0, 8), - GPIO(0, 9), - GPIO(5, 7), - GPIO(1, 10), -}; -#endif /* CPLD JTAG interface GPIO pins */ static struct gpio_t gpio_cpld_tdo = GPIO(5, 18); static struct gpio_t gpio_cpld_tck = GPIO(3, 0); -#if defined HACKRF_ONE || defined RAD1O +#if (defined HACKRF_ONE || defined RAD1O) static struct gpio_t gpio_cpld_tms = GPIO(3, 4); static struct gpio_t gpio_cpld_tdi = GPIO(3, 1); #else @@ -420,7 +400,6 @@ bool sample_rate_frac_set(uint32_t rate_num, uint32_t rate_denom) } bool sample_rate_set(const uint32_t sample_rate_hz) { -#if (defined JAWBREAKER || defined HACKRF_ONE || defined RAD1O) uint32_t p1 = 4608; uint32_t p2 = 0; uint32_t p3 = 0; @@ -481,7 +460,6 @@ bool sample_rate_set(const uint32_t sample_rate_hz) { si5351c_configure_multisynth(&clock_gen, 2, p1, 0, 1, 0);//p1 doesn't matter return true; -#endif } bool baseband_filter_bandwidth_set(const uint32_t bandwidth_hz) { From 9e3b69a9b76da51858f54b57584050a757ad4688 Mon Sep 17 00:00:00 2001 From: Dominic Spill Date: Tue, 14 Feb 2017 21:08:45 -0700 Subject: [PATCH 3/4] Remove source for development firmwares --- firmware/mixertx/CMakeLists.txt | 32 - firmware/mixertx/README | 26 - firmware/mixertx/mixertx.c | 50 - firmware/sgpio-rx/CMakeLists.txt | 33 - firmware/sgpio-rx/README | 1 - firmware/sgpio-rx/sgpio-rx.c | 101 - firmware/sgpio-rx/table.py | 57 - firmware/sgpio/CMakeLists.txt | 32 - firmware/sgpio/README | 2 - firmware/sgpio/sgpio_test.c | 80 - firmware/sgpio_passthrough/CMakeLists.txt | 33 - firmware/sgpio_passthrough/README | 5 - .../sgpio_passthrough/Test_SGPIO0_to15.ods | Bin 12245 -> 0 bytes .../sgpio_passthrough/Test_SGPIO0_to15.pdf | Bin 54376 -> 0 bytes ...t_SGPIO_GPIO_mode_test_sgpio_interface.txt | 68 - .../sgpio_passthrough/sgpio_passthrough.c | 362 --- firmware/simpletx/CMakeLists.txt | 32 - firmware/simpletx/README | 23 - firmware/simpletx/simpletx.c | 48 - firmware/spiflash/CMakeLists.txt | 34 - firmware/spiflash/README | 1 - firmware/spiflash/spiflash.c | 56 - firmware/startup/CMakeLists.txt | 32 - firmware/startup/README | 11 - firmware/startup/startup.c | 62 - firmware/startup_systick/CMakeLists.txt | 32 - firmware/startup_systick/README | 12 - firmware/startup_systick/startup_systick.c | 159 -- firmware/startup_systick_perfo/CMakeLists.txt | 33 - firmware/startup_systick_perfo/README | 20 - firmware/startup_systick_perfo/perf_mips.c | 2217 ----------------- .../result_exec_from_SPIFI.txt | 33 - .../result_exec_from_SRAM.txt | 22 - .../startup_systick_perfo/startup_systick.c | 206 -- 34 files changed, 3915 deletions(-) delete mode 100644 firmware/mixertx/CMakeLists.txt delete mode 100644 firmware/mixertx/README delete mode 100644 firmware/mixertx/mixertx.c delete mode 100644 firmware/sgpio-rx/CMakeLists.txt delete mode 100644 firmware/sgpio-rx/README delete mode 100644 firmware/sgpio-rx/sgpio-rx.c delete mode 100644 firmware/sgpio-rx/table.py delete mode 100644 firmware/sgpio/CMakeLists.txt delete mode 100644 firmware/sgpio/README delete mode 100644 firmware/sgpio/sgpio_test.c delete mode 100644 firmware/sgpio_passthrough/CMakeLists.txt delete mode 100644 firmware/sgpio_passthrough/README delete mode 100644 firmware/sgpio_passthrough/Test_SGPIO0_to15.ods delete mode 100644 firmware/sgpio_passthrough/Test_SGPIO0_to15.pdf delete mode 100644 firmware/sgpio_passthrough/Test_SGPIO_GPIO_mode_test_sgpio_interface.txt delete mode 100644 firmware/sgpio_passthrough/sgpio_passthrough.c delete mode 100644 firmware/simpletx/CMakeLists.txt delete mode 100644 firmware/simpletx/README delete mode 100644 firmware/simpletx/simpletx.c delete mode 100644 firmware/spiflash/CMakeLists.txt delete mode 100644 firmware/spiflash/README delete mode 100644 firmware/spiflash/spiflash.c delete mode 100644 firmware/startup/CMakeLists.txt delete mode 100644 firmware/startup/README delete mode 100644 firmware/startup/startup.c delete mode 100644 firmware/startup_systick/CMakeLists.txt delete mode 100644 firmware/startup_systick/README delete mode 100644 firmware/startup_systick/startup_systick.c delete mode 100644 firmware/startup_systick_perfo/CMakeLists.txt delete mode 100644 firmware/startup_systick_perfo/README delete mode 100644 firmware/startup_systick_perfo/perf_mips.c delete mode 100644 firmware/startup_systick_perfo/result_exec_from_SPIFI.txt delete mode 100644 firmware/startup_systick_perfo/result_exec_from_SRAM.txt delete mode 100644 firmware/startup_systick_perfo/startup_systick.c diff --git a/firmware/mixertx/CMakeLists.txt b/firmware/mixertx/CMakeLists.txt deleted file mode 100644 index 84a911d7..00000000 --- a/firmware/mixertx/CMakeLists.txt +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright 2014 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. -# - -cmake_minimum_required(VERSION 2.8.9) -set(CMAKE_TOOLCHAIN_FILE ../toolchain-arm-cortex-m.cmake) - -project(mixertx) - -include(../hackrf-common.cmake) - -set(SRC_M4 - mixertx.c -) - -DeclareTargets() diff --git a/firmware/mixertx/README b/firmware/mixertx/README deleted file mode 100644 index bed2f6bf..00000000 --- a/firmware/mixertx/README +++ /dev/null @@ -1,26 +0,0 @@ -This program activates the MAX2837 transceiver to transmit an unmodulated -carrier. It also configures the RFFC5071 to downconvert the carrier to a lower -frequency. - -Required Lemondrop -> Jellybean connections: - -SCK: Lemondrop P3 pin 2 -> Jellybean P9 2 -MOSI: Lemondrop P3 pin 4 -> Jellybean P9 4 -MISO: Lemondrop P3 pin 6 -> Jellybean P9 6 -SSEL: Lemondrop P3 pin 3 -> Jellybean P9 3 -SCL: Lemondrop P7 pin 3 -> Jellybean P6 pin 3 -SDA: Lemondrop P7 pin 5 -> Jellybean P6 pin 5 -SDA: Lemondrop P7 pin 6 -> Jellybean P6 pin 6 -VCC: Lemondrop P4 pin 2, 4, or 6 -> Jellybean P17 pin 2, 4, or 6 -1V8: Lemondrop P11 pin 2, 4, or 6 -> Jellybean P16 pin 2, 4, or 6 -GND: Lemondrop P5 -> Jellybean P13 - -Required Lollipop -> Jellybean connections: -GND: Lollipop P8 pin 1, 3, or 5 -> Jellybean P17 pin 1, 3, or 5 -VCC: Lollipop P8 pin 2, 4, or 6 -> Jellybean P17 pin 2, 4, or 6 -ENX: Lollipop P4 pin 5 -> Jellybean P5 pin 2 -SCLK: Lollipop P4 pin 3 -> Jellybean P5 pin 4 -SDATA: Lollipop P4 pin 1 -> Jellybean P5 pin 6 - -Also RF connectors, and you're on your own to get the RF switches configured -properly. diff --git a/firmware/mixertx/mixertx.c b/firmware/mixertx/mixertx.c deleted file mode 100644 index fc537c66..00000000 --- a/firmware/mixertx/mixertx.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 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. - */ - -#include "hackrf_core.h" - -int main(void) -{ - const uint32_t freq = 2441000000U; - - pin_setup(); - enable_1v8_power(); -#ifdef HACKRF_ONE - enable_rf_power(); -#endif - cpu_clock_init(); - - led_on(LED1); - - ssp1_set_mode_max2837(); - max2837_setup(&max2837); - mixer_setup(&mixer); - led_on(LED2); - - max2837_set_frequency(&max2837, freq); - max2837_start(&max2837); - max2837_tx(&max2837); - led_on(LED3); - while (1); - max2837_stop(&max2837); - - return 0; -} diff --git a/firmware/sgpio-rx/CMakeLists.txt b/firmware/sgpio-rx/CMakeLists.txt deleted file mode 100644 index 26d91d0e..00000000 --- a/firmware/sgpio-rx/CMakeLists.txt +++ /dev/null @@ -1,33 +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. -# - -cmake_minimum_required(VERSION 2.8.9) -set(CMAKE_TOOLCHAIN_FILE ../toolchain-arm-cortex-m.cmake) - -project(sgpio-rx) - -include(../hackrf-common.cmake) - -set(SRC_M4 - sgpio-rx.c - ${PATH_HACKRF_FIRMWARE_COMMON}/tuning.c -) - -DeclareTargets() diff --git a/firmware/sgpio-rx/README b/firmware/sgpio-rx/README deleted file mode 100644 index 6c8cfec5..00000000 --- a/firmware/sgpio-rx/README +++ /dev/null @@ -1 +0,0 @@ -This is a variation of sgpio.c for testing RX. diff --git a/firmware/sgpio-rx/sgpio-rx.c b/firmware/sgpio-rx/sgpio-rx.c deleted file mode 100644 index 4eec4133..00000000 --- a/firmware/sgpio-rx/sgpio-rx.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 2012 Michael Ossmann - * Copyright (C) 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 tx_test() { - // LSB goes out first, samples are 0x - volatile uint32_t buffer[] = { - 0xda808080, - 0xda80ff80, - 0x26808080, - 0x26800180, - }; - uint32_t i = 0; - - rf_path_set_direction(&rf_path, RF_PATH_DIRECTION_TX); - sgpio_cpld_stream_enable(&sgpio_config); - - while(true) { - while(SGPIO_STATUS_1 == 0); - SGPIO_REG_SS(SGPIO_SLICE_A) = buffer[(i++) & 3]; - SGPIO_CLR_STATUS_1 = 1; - } -} - -void rx_test() { - volatile uint32_t buffer[4096]; - uint32_t i = 0; - uint32_t magsq; - int8_t sigi, sigq; - - rf_path_set_direction(&rf_path, RF_PATH_DIRECTION_RX); - sgpio_cpld_stream_enable(&sgpio_config); - - led_on(LED2); - while(true) { - while(SGPIO_STATUS_1 == 0); - led_on(LED1); - SGPIO_CLR_STATUS_1 = 1; - buffer[i & 4095] = SGPIO_REG_SS(SGPIO_SLICE_A); - - /* find the magnitude squared */ - sigi = buffer[i & 4095] & 0xff; - sigq = (buffer[i & 4095] >> 8) & 0xff; - magsq = sigi * sigi + sigq * sigq; - - /* illuminate LED3 only when magsq exceeds threshold */ - if (magsq > 0x1000) - led_on(LED3); - else - led_off(LED3); - i++; - } -} - -int main(void) { - - const uint64_t freq = 2441000000U; - - sgpio_set_slice_mode(&sgpio_config, false); - pin_setup(); - enable_1v8_power(); -#ifdef HACKRF_ONE - enable_rf_power(); -#endif - cpu_clock_init(); - rf_path_init(&rf_path); - - set_freq(freq); - - rx_test(); - led_on(LED2); - - while (1) { - - } - - return 0; -} diff --git a/firmware/sgpio-rx/table.py b/firmware/sgpio-rx/table.py deleted file mode 100644 index b7319a2c..00000000 --- a/firmware/sgpio-rx/table.py +++ /dev/null @@ -1,57 +0,0 @@ -mossmann@grumio ~/github/hackrf/firmware/simpletx $ python -Python 2.7.3 (default, Jun 22 2012, 11:10:47) -[GCC 4.5.3] on linux2 -Type "help", "copyright", "credits" or "license" for more information. ->>> import math ->>> def y(i,max): -... return int(127.5*(math.sin(tau*i/max)+1)) -... ->>> tau=math.pi*2 ->>> def x(i,max): -... return int(127.5*(math.cos(tau*i/max)+1)) -... ->>> def table(max): -... for i in range(0, max, 2): -... print "%02x%02x%02x%02x," % (y(i+1,max), x(i+1,max), y(i,max), x(i,max)) -... ->>> table(32) -98fc7fff, -c6e9b0f5, -e9c6d9d9, -fc98f5b0, -fc66ff7f, -e938f54e, -c615d925, -9802b009, -66027f00, -38154e09, -15382525, -0266094e, -0298007f, -15c609b0, -38e925d9, -66fc4ef5, - - ->>> def table(max): -... for i in range(0, max, 2): -... print "0x%02x%02x%02x%02x," % (y(i+1,max), x(i+1,max), y(i,max), x(i,max)) -... ->>> table(32) -0x98fc7fff, -0xc6e9b0f5, -0xe9c6d9d9, -0xfc98f5b0, -0xfc66ff7f, -0xe938f54e, -0xc615d925, -0x9802b009, -0x66027f00, -0x38154e09, -0x15382525, -0x0266094e, -0x0298007f, -0x15c609b0, -0x38e925d9, -0x66fc4ef5, - diff --git a/firmware/sgpio/CMakeLists.txt b/firmware/sgpio/CMakeLists.txt deleted file mode 100644 index 1125ae21..00000000 --- a/firmware/sgpio/CMakeLists.txt +++ /dev/null @@ -1,32 +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. -# - -cmake_minimum_required(VERSION 2.8.9) -set(CMAKE_TOOLCHAIN_FILE ../toolchain-arm-cortex-m.cmake) - -project(sgpio_test) - -include(../hackrf-common.cmake) - -set(SRC_M4 - sgpio_test.c -) - -DeclareTargets() diff --git a/firmware/sgpio/README b/firmware/sgpio/README deleted file mode 100644 index 8c7856fc..00000000 --- a/firmware/sgpio/README +++ /dev/null @@ -1,2 +0,0 @@ -A program to demonstrate TX control of the MAX5864 DAC, via the -SGPIO CPLD interface. \ No newline at end of file diff --git a/firmware/sgpio/sgpio_test.c b/firmware/sgpio/sgpio_test.c deleted file mode 100644 index 8215983e..00000000 --- a/firmware/sgpio/sgpio_test.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2012 Michael Ossmann - * Copyright (C) 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 - -volatile uint32_t buffer[4096]; - -void tx_test() { - sgpio_set_slice_mode(&sgpio_config, false); - sgpio_configure(&sgpio_config, TRANSCEIVER_MODE_TX); - - // LSB goes out first, samples are 0x - buffer[0] = 0xda808080; - buffer[1] = 0xda80ff80; - buffer[2] = 0x26808080; - buffer[3] = 0x26800180; - - uint32_t i = 0; - - sgpio_cpld_stream_enable(&sgpio_config); - - while(true) { - while(SGPIO_STATUS_1 == 0); - SGPIO_REG_SS(SGPIO_SLICE_A) = buffer[(i++) & 3]; - SGPIO_CLR_STATUS_1 = 1; - } -} - -void rx_test() { - sgpio_set_slice_mode(&sgpio_config, false); - sgpio_configure(&sgpio_config, TRANSCEIVER_MODE_RX); - - uint32_t i = 0; - - sgpio_cpld_stream_enable(&sgpio_config); - - while(true) { - while(SGPIO_STATUS_1 == 0); - SGPIO_CLR_STATUS_1 = 1; - buffer[i++ & 4095] = SGPIO_REG_SS(SGPIO_SLICE_A); - } -} - -int main(void) { - pin_setup(); - enable_1v8_power(); - cpu_clock_init(); - - led_on(LED1); - - ssp1_set_mode_max5864(); - max5864_setup(&max5864); - max5864_xcvr(&max5864); - - while (1) { - - } - - return 0; -} diff --git a/firmware/sgpio_passthrough/CMakeLists.txt b/firmware/sgpio_passthrough/CMakeLists.txt deleted file mode 100644 index 80c50612..00000000 --- a/firmware/sgpio_passthrough/CMakeLists.txt +++ /dev/null @@ -1,33 +0,0 @@ -# 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. -# - -cmake_minimum_required(VERSION 2.8.9) -set(CMAKE_TOOLCHAIN_FILE ../toolchain-arm-cortex-m.cmake) - -project(sgpio_passthrough) - -include(../hackrf-common.cmake) - -set(SRC_M4 - sgpio_passthrough.c -) - -DeclareTargets() diff --git a/firmware/sgpio_passthrough/README b/firmware/sgpio_passthrough/README deleted file mode 100644 index 2489f791..00000000 --- a/firmware/sgpio_passthrough/README +++ /dev/null @@ -1,5 +0,0 @@ -A program to test SGPIO with CPLD passthrough Input & Output via the SGPIO CPLD interface (P8 BANK2_AUX). -For this test connect P10 BANK1_AUX AUX9 pin to +1V8 (in order to have P8 BANK2_AUX AUX1 to 16 as Output). -This test requires: - * JellyBean+Lemondrop(to set clock at 204MHz). - * CPLD X2C64A hardware\jellybean\sgpio_if_passthrough\sgpio_if_passthrough.svf to be loaded first. diff --git a/firmware/sgpio_passthrough/Test_SGPIO0_to15.ods b/firmware/sgpio_passthrough/Test_SGPIO0_to15.ods deleted file mode 100644 index a3843c9e33571f88e27f913abca37525925e2363..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12245 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 sQofPui?$O?*whhE0i&fLXZjI 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 diff --git a/firmware/sgpio_passthrough/Test_SGPIO_GPIO_mode_test_sgpio_interface.txt b/firmware/sgpio_passthrough/Test_SGPIO_GPIO_mode_test_sgpio_interface.txt deleted file mode 100644 index 6c2f3ba9..00000000 --- a/firmware/sgpio_passthrough/Test_SGPIO_GPIO_mode_test_sgpio_interface.txt +++ /dev/null @@ -1,68 +0,0 @@ - -Test SGPIO GPIO mode, with LPC4330@204MHz (JellyBean+Lemondrop) and code executed in RAM. - -Test1: ------- -while(1) -{ - for (uint_fast8_t i = 0; i < 8; i++) - { - SGPIO_GPIO_OUTREG ^= (1L << i); - - } -} -Oscilloscope result (on SGPIO0): Frequency 750KHz => 272 cycles - -Test2: ------- -while(1) -{ - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - SGPIO_GPIO_OUTREG ^= 0x5555; -} -Oscilloscope result (on SGPIO0): 3.923 MHz => 52 cycles - -Test3: ------- -while(1) -{ - SGPIO_GPIO_OUTREG ^= 0x5555; -} -Oscilloscope result (on SGPIO0): Frequency 7.28MHz => 28 cycles - -Test4: ------- -while(1) -{ - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - SGPIO_GPIO_OUTREG = 0x5555; - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - SGPIO_GPIO_OUTREG = 0xAAAA; -} -Oscilloscope result (on SGPIO0): Frequency 17MHz => 12 cycles - -Test5: ------- -while(1) -{ - SGPIO_GPIO_OUTREG = 0x5555; - SGPIO_GPIO_OUTREG = 0xAAAA; -} -Oscilloscope result (on SGPIO0): Frequency 25.5MHz => 8 cycles diff --git a/firmware/sgpio_passthrough/sgpio_passthrough.c b/firmware/sgpio_passthrough/sgpio_passthrough.c deleted file mode 100644 index 57810ee6..00000000 --- a/firmware/sgpio_passthrough/sgpio_passthrough.c +++ /dev/null @@ -1,362 +0,0 @@ -/* - * Copyright 2012 Michael Ossmann - * Copyright (C) 2012 Jared Boone - * Copyright (C) 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. - */ - -#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_sliceA_D(void) -{ - SGPIO_GPIO_OENREG = 0; // All inputs for the moment. - - // Disable all counters during configuration - SGPIO_CTRL_ENABLE = 0; - - // Configure pin functions. - configure_sgpio_pin_functions(); - - /****************************************************/ - /* Enable SGPIO pin outputs. */ - /****************************************************/ - SGPIO_GPIO_OENREG = - 0xFFFF; // data: output for SGPIO0 to SGPIO15 - - /*******************************************************************************/ - /* SGPIO pin 0 outputs slice A bit 0. (see Table 212. Output pin multiplexing) */ - /*******************************************************************************/ - SGPIO_OUT_MUX_CFG(0) = - (0L << 4) | // P_OE_CFG = X - (0L << 0); // P_OUT_CFG = 0, dout_doutm1 (1-bit mode) - - // SGPIO pin 12 outputs slice D bit 0. (see Table 212. Output pin multiplexing) - SGPIO_OUT_MUX_CFG(12) = - (0L << 4) | // P_OE_CFG = X - (0L << 0); // P_OUT_CFG = 0, dout_doutm1 (1-bit mode) - - /****************************************************/ - /* 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 - (0L << 7) | // QUALIFIER_PIN_MODE = X - (0L << 5) | // QUALIFIER_MODE = 0 (enable) - (0L << 3) | // CLK_SOURCE_SLICE_MODE = 0, slice D - (0L << 1) | // CLK_SOURCE_PIN_MODE = X - (0L << 0); // EXT_CLK_ENABLE = 0, internal clock signal (slice) - - SGPIO_SLICE_MUX_CFG(SGPIO_SLICE_A) = - (0L << 8) | // INV_QUALIFIER = 0 (use normal qualifier) - (0L << 6) | // PARALLEL_MODE = 0 (shift 1 bit per clock) - (0L << 4) | // DATA_CAPTURE_MODE = 0 (detect rising edge) - (0L << 3) | // INV_OUT_CLK = 0 (normal clock) - (0L << 2) | // CLKGEN_MODE = 0 (use clock from COUNTER) - (0L << 1) | // CLK_CAPTURE_MODE = 0 (use rising clock edge) - (0L << 0); // MATCH_MODE = 0 (do not match data) - - SGPIO_PRESET(SGPIO_SLICE_A) = 1; - SGPIO_COUNT(SGPIO_SLICE_A) = 0; - SGPIO_POS(SGPIO_SLICE_A) = (0x1FL << 8) | (0x1FL << 0); - SGPIO_REG(SGPIO_SLICE_A) = 0xAAAAAAAA; // Primary output data register - SGPIO_REG_SS(SGPIO_SLICE_A) = 0xAAAAAAAA; // Shadow output data register - - /****************************************************/ - /* Slice D (clock for Slice A) */ - /****************************************************/ - SGPIO_MUX_CFG(SGPIO_SLICE_D) = - (0L << 12) | // CONCAT_ORDER = 0 (self-loop) - (1L << 11) | // CONCAT_ENABLE = 1 (concatenate data) - (0L << 9) | // QUALIFIER_SLICE_MODE = X - (0L << 7) | // QUALIFIER_PIN_MODE = X - (0L << 5) | // QUALIFIER_MODE = 0 (enable) - (0L << 3) | // CLK_SOURCE_SLICE_MODE = 0, slice D - (0L << 1) | // CLK_SOURCE_PIN_MODE = X - (0L << 0); // EXT_CLK_ENABLE = 0, internal clock signal (slice) - - SGPIO_SLICE_MUX_CFG(SGPIO_SLICE_D) = - (0L << 8) | // INV_QUALIFIER = 0 (use normal qualifier) - (0L << 6) | // PARALLEL_MODE = 0 (shift 1 bit per clock) - (0L << 4) | // DATA_CAPTURE_MODE = 0 (detect rising edge) - (0L << 3) | // INV_OUT_CLK = 0 (normal clock) - (0L << 2) | // CLKGEN_MODE = 0 (use clock from COUNTER) - (0L << 1) | // CLK_CAPTURE_MODE = 0 (use rising clock edge) - (0L << 0); // MATCH_MODE = 0 (do not match data) - - SGPIO_PRESET(SGPIO_SLICE_D) = 0; - SGPIO_COUNT(SGPIO_SLICE_D) = 0; - SGPIO_POS(SGPIO_SLICE_D) = (0x1FL << 8) | (0x1FL << 0); - SGPIO_REG(SGPIO_SLICE_D) = 0xAAAAAAAA; // Primary output data register - SGPIO_REG_SS(SGPIO_SLICE_D) = 0xAAAAAAAA; // Shadow output data register - - - /****************************************************/ - /* Start SGPIO operation by enabling slice clocks. */ - /****************************************************/ - SGPIO_CTRL_ENABLE = - (1L << SGPIO_SLICE_D) | // Slice D - (1L << SGPIO_SLICE_A); // Slice A - // Start SGPIO operation by enabling slice clocks. - - /* - Expected: - SGPIO12 = MCU Freq/2 - SGPIO0 = SGPIO12/2 MHz= 51MHz (SliceD/2) - */ - -} - - -/*******************************************************************************/ -/* Output 1bit table (see Table 212. Output pin multiplexing) */ -/* SGPIO pin 00 outputs slice A bit 0. */ -/* SGPIO pin 01 outputs slice I bit 0. */ -/* SGPIO pin 02 outputs slice E bit 0. */ -/* SGPIO pin 03 outputs slice J bit 0. */ -/* SGPIO pin 04 outputs slice C bit 0. */ -/* SGPIO pin 05 outputs slice K bit 0. */ -/* SGPIO pin 06 outputs slice F bit 0. */ -/* SGPIO pin 07 outputs slice L bit 0. */ -/* SGPIO pin 08 outputs slice B bit 0. */ -/* SGPIO pin 09 outputs slice M bit 0. */ -/* SGPIO pin 10 outputs slice G bit 0. */ -/* SGPIO pin 11 outputs slice N bit 0. */ -/* SGPIO pin 12 outputs slice D bit 0. */ -/* SGPIO pin 13 outputs slice O bit 0. */ -/* SGPIO pin 14 outputs slice H bit 0. */ -/* SGPIO pin 15 outputs slice P bit 0. */ -/*******************************************************************************/ -const uint8_t slice_preset_tab[16] = -{ - 0, /* Idx00 = Slice A => SGPIO0 Freq Div by 1=0 */ - 8, /* Idx01 = Slice B => SGPIO8 Freq Div by 9=8 */ - 4, /* Idx02 = Slice C => SGPIO4 Freq Div by 5=4 */ - 12, /* Idx03 = Slice D => SGPIO12 Freq Div by 13=12 */ - 2, /* Idx04 = Slice E => SGPIO2 Freq Div by 3=2 */ - 6, /* Idx05 = Slice F => SGPIO6 Freq Div by 7=6 */ - 10, /* Idx06 = Slice G => SGPIO10 Freq Div by 11=10 */ - 14, /* Idx07 = Slice H => SGPIO14 Freq Div by 15=14 */ - 1, /* Idx08 = Slice I => SGPIO1 Freq Div by 2=1 */ - 3, /* Idx09 = Slice J => SGPIO3 Freq Div by 4=3 */ - 5, /* Idx10 = Slice K => SGPIO5 Freq Div by 6=5 */ - 7, /* Idx11 = Slice L => SGPIO7 Freq Div by 8=7 */ - 9, /* Idx12 = Slice M => SGPIO9 Freq Div by 10=9 */ - 11, /* Idx13 = Slice N => SGPIO11 Freq Div by 12=11 */ - 13, /* Idx14 = Slice O => SGPIO13 Freq Div by 14=13 */ - 15 /* Idx15 = Slice P => SGPIO15 Freq Div by 16=15 */ -}; - -void test_sgpio_all_slices(void) -{ - - SGPIO_GPIO_OENREG = 0; // All inputs for the moment. - - // Disable all counters during configuration - SGPIO_CTRL_ENABLE = 0; - - // Configure pin functions. - configure_sgpio_pin_functions(); - - /****************************************************/ - /* Enable SGPIO pin outputs. */ - /****************************************************/ - SGPIO_GPIO_OENREG = - 0xFFFF; // data: output for SGPIO0 to SGPIO15 - - for(uint_fast8_t i=0; i<16; i++) - { - SGPIO_OUT_MUX_CFG(i) = - (0L << 4) | // P_OE_CFG = X - (0L << 0); // P_OUT_CFG = 0, dout_doutm1 (1-bit mode) - } - - /****************************************************/ - /* Slice A to P */ - /****************************************************/ - for(uint_fast8_t i=0; i<16; i++) - { - SGPIO_MUX_CFG(i) = - (0L << 12) | // CONCAT_ORDER = 0 (self-loop) - (1L << 11) | // CONCAT_ENABLE = 1 (concatenate data) - (0L << 9) | // QUALIFIER_SLICE_MODE = X - (0L << 7) | // QUALIFIER_PIN_MODE = X - (0L << 5) | // QUALIFIER_MODE = 0 (enable) - (0L << 3) | // CLK_SOURCE_SLICE_MODE = 0, slice D - (0L << 1) | // CLK_SOURCE_PIN_MODE = X - (0L << 0); // EXT_CLK_ENABLE = 0, internal clock signal (slice) - - SGPIO_SLICE_MUX_CFG(i) = - (0L << 8) | // INV_QUALIFIER = 0 (use normal qualifier) - (0L << 6) | // PARALLEL_MODE = 0 (shift 1 bit per clock) - (0L << 4) | // DATA_CAPTURE_MODE = 0 (detect rising edge) - (0L << 3) | // INV_OUT_CLK = 0 (normal clock) - (0L << 2) | // CLKGEN_MODE = 0 (use clock from COUNTER) - (0L << 1) | // CLK_CAPTURE_MODE = 0 (use rising clock edge) - (0L << 0); // MATCH_MODE = 0 (do not match data) - - SGPIO_PRESET(i) = slice_preset_tab[i]; - SGPIO_COUNT(i) = 0; - SGPIO_POS(i) = (0x1FL << 8) | (0x1FL << 0); - SGPIO_REG(i) = 0xAAAAAAAA; // Primary output data register - SGPIO_REG_SS(i) = 0xAAAAAAAA; // Shadow output data register - } - - /****************************************************/ - /* Start SGPIO operation by enabling slice clocks. */ - /****************************************************/ - SGPIO_CTRL_ENABLE = 0xFFFF; /* Start all slices A to P */ -/* - (1L << SGPIO_SLICE_D) | // Slice D - (1L << SGPIO_SLICE_A); // Slice A - // Start SGPIO operation by enabling slice clocks. -*/ - /* - Expected: - MCU Freq MHz = 204 - SGPIO Theorical Freq MHz - SGPIO00 = 102,00000 - SGPIO01 = 51,00000 - SGPIO02 = 34,00000 - SGPIO03 = 25,50000 - SGPIO04 = 20,40000 - SGPIO05 = 17,00000 - SGPIO06 = 14,57143 - SGPIO07 = 12,75000 - SGPIO08 = 11,33333 - SGPIO09 = 10,20000 - SGPIO10 = 9,27273 - SGPIO11 = 8,50000 - SGPIO12 = 7,84615 - SGPIO13 = 7,28571 - SGPIO14 = 6,80000 - SGPIO15 = 6,37500 - TitanMKD: I have problems with my boards and this test see document Test_SGPIO0_to15.ods / Test_SGPIO0_to15.pdf - */ -} - -void test_sgpio_interface(void) -{ - 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); - } - - // Enable SGPIO pin outputs (SGPIO0 to 15). - SGPIO_GPIO_OENREG = 0xFFFF; - - /* Set values for SGPIO0 to 15 */ - while (1) - { - // 750KHz => 272 cycles - /* - for (uint_fast8_t i = 0; i < 8; i++) { - SGPIO_GPIO_OUTREG ^= (1L << i); - - } - */ - - // 3.923 MHz => 52 cycles - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - SGPIO_GPIO_OUTREG ^= 0x5555; - - // 7.28 MHz => 28 cycles - /* - SGPIO_GPIO_OUTREG ^= 0x5555; - */ - - // 17 MHz => 12 cycles - /* - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - SGPIO_GPIO_OUTREG = 0x5555; - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - SGPIO_GPIO_OUTREG = 0xAAAA; - */ - // 25.50 MHz => 8 cycles - /* - SGPIO_GPIO_OUTREG = 0x5555; - SGPIO_GPIO_OUTREG = 0xAAAA; - */ - } - - /* TitanMKD: I have problems with my board with this test (see test_sgpio_all_slices()) */ -} - -int main(void) -{ - pin_setup(); - enable_1v8_power(); - cpu_clock_init(); - led_on(LED1); - - //test_sgpio_sliceA_D(); - test_sgpio_interface(); - //test_sgpio_all_slices(); - - while(1); - - return 0; -} diff --git a/firmware/simpletx/CMakeLists.txt b/firmware/simpletx/CMakeLists.txt deleted file mode 100644 index 01f7b394..00000000 --- a/firmware/simpletx/CMakeLists.txt +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright 2014 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. -# - -cmake_minimum_required(VERSION 2.8.9) -set(CMAKE_TOOLCHAIN_FILE ../toolchain-arm-cortex-m.cmake) - -project(simpletx) - -include(../hackrf-common.cmake) - -set(SRC_M4 - simpletx.c -) - -DeclareTargets() diff --git a/firmware/simpletx/README b/firmware/simpletx/README deleted file mode 100644 index 43b2fd91..00000000 --- a/firmware/simpletx/README +++ /dev/null @@ -1,23 +0,0 @@ -This program activates the MAX2837 transceiver to transmit an unmodulated -carrier. - -Required Lemondrop -> Jellybean connections: - -SCK: Lemondrop P3 pin 2 -> Jellybean P9 2 -CS_XCVR: Lemondrop P3 pin 3 -> Jellybean P9 3 -MOSI: Lemondrop P3 pin 4 -> Jellybean P9 4 -CS_AD: Lemondrop P3 pin 5 -> Jellybean P9 5 -MISO: Lemondrop P3 pin 6 -> Jellybean P9 6 -ENABLE: Lemondrop P6 pin 12 -> Jellybean P7 pin 12 -RXENABLE: Lemondrop P6 pin 13 -> Jellybean P7 pin 13 -TXENABLE: Lemondrop P6 pin 15 -> Jellybean P7 pin 15 -SCL: Lemondrop P7 pin 3 -> Jellybean P6 pin 3 -SDA: Lemondrop P7 pin 5 -> Jellybean P6 pin 5 -SDA: Lemondrop P7 pin 6 -> Jellybean P6 pin 6 -VCC: Lemondrop P4 pin 2, 4, or 6 -> Jellybean P17 pin 2, 4, or 6 -GND: Lemondrop P5 -> Jellybean P13 - -For now we are running everything at 3.3 V, but in the future we may also -require: - -1V8: Lemondrop P11 pin 2, 4, or 6 -> Jellybean P16 pin 2, 4, or 6 diff --git a/firmware/simpletx/simpletx.c b/firmware/simpletx/simpletx.c deleted file mode 100644 index 900d876e..00000000 --- a/firmware/simpletx/simpletx.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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. - */ - -#include "hackrf_core.h" - -int main(void) -{ - const uint32_t freq = 2441000000U; - - pin_setup(); - enable_1v8_power(); -#ifdef HACKRF_ONE - enable_rf_power(); -#endif - cpu_clock_init(); - - led_on(LED1); - - ssp1_set_mode_max2837(); - max2837_setup(&max2837); - led_on(LED2); - max2837_set_frequency(&max2837, freq); - max2837_start(&max2837); - max2837_tx(&max2837); - led_on(LED3); - while (1); - max2837_stop(&max2837); - - return 0; -} diff --git a/firmware/spiflash/CMakeLists.txt b/firmware/spiflash/CMakeLists.txt deleted file mode 100644 index 160caa37..00000000 --- a/firmware/spiflash/CMakeLists.txt +++ /dev/null @@ -1,34 +0,0 @@ -# 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. -# - -cmake_minimum_required(VERSION 2.8.9) -set(CMAKE_TOOLCHAIN_FILE ../toolchain-arm-cortex-m.cmake) - -project(spiflash) - -include(../hackrf-common.cmake) - -set(SRC_M4 - spiflash.c - "${PATH_HACKRF_FIRMWARE_COMMON}/w25q80bv.c" -) - -DeclareTargets() diff --git a/firmware/spiflash/README b/firmware/spiflash/README deleted file mode 100644 index 088abd77..00000000 --- a/firmware/spiflash/README +++ /dev/null @@ -1 +0,0 @@ -This is a test program for SPI flash programming. diff --git a/firmware/spiflash/spiflash.c b/firmware/spiflash/spiflash.c deleted file mode 100644 index 73185b77..00000000 --- a/firmware/spiflash/spiflash.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2010 - 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. - */ - -#include "hackrf_core.h" - -int main(void) -{ - int i; - uint8_t buf[515]; - - pin_setup(); - - enable_1v8_power(); - - cpu_clock_init(); - - /* program test data to SPI flash */ - for (i = 0; i < 515; i++) - buf[i] = (i * 3) & 0xFF; - w25q80bv_setup(&w25q80bv); - w25q80bv_chip_erase(&w25q80bv); - w25q80bv_program(&w25q80bv, 790, 515, &buf[0]); - - /* blink LED1 and LED3 */ - while (1) - { - led_on(LED1); - led_on(LED3); - for (i = 0; i < 8000000; i++) /* Wait a bit. */ - __asm__("nop"); - led_off(LED1); - led_off(LED3); - for (i = 0; i < 8000000; i++) /* Wait a bit. */ - __asm__("nop"); - } - - return 0; -} diff --git a/firmware/startup/CMakeLists.txt b/firmware/startup/CMakeLists.txt deleted file mode 100644 index 28e1a3f4..00000000 --- a/firmware/startup/CMakeLists.txt +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright 2014 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. -# - -cmake_minimum_required(VERSION 2.8.9) -set(CMAKE_TOOLCHAIN_FILE ../toolchain-arm-cortex-m.cmake) - -project(startup) - -include(../hackrf-common.cmake) - -set(SRC_M4 - startup.c -) - -DeclareTargets() diff --git a/firmware/startup/README b/firmware/startup/README deleted file mode 100644 index 5c184f43..00000000 --- a/firmware/startup/README +++ /dev/null @@ -1,11 +0,0 @@ -This program is an example of the startup sequence for HackRF (Jellybean with -Lemondrop attached). LED1, LED2, and LED3 are illuminated upon success. - -Required Lemondrop -> Jellybean connections: - -SCL: Lemondrop P7 pin 3 -> Jellybean P6 pin 3 -SDA: Lemondrop P7 pin 5 -> Jellybean P6 pin 5 -SDA: Lemondrop P7 pin 6 -> Jellybean P6 pin 6 -VCC: Lemondrop P4 pin 2, 4, or 6 -> Jellybean P17 pin 2, 4, or 6 -1V8: Lemondrop P11 pin 2, 4, or 6 -> Jellybean P16 pin 2, 4, or 6 -GND: Lemondrop P5 -> Jellybean P13 diff --git a/firmware/startup/startup.c b/firmware/startup/startup.c deleted file mode 100644 index 3dfe78a5..00000000 --- a/firmware/startup/startup.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2010 - 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. - */ - -#include "hackrf_core.h" - -int main(void) -{ - uint32_t i; - - pin_setup(); - - enable_1v8_power(); - - cpu_clock_init(); - - led_on(LED1); - led_on(LED2); - led_on(LED3); - - while (1) - { - led_on(LED1); - for (i = 0; i < 2000000; i++) /* Wait a bit. */ - __asm__("nop"); - - led_on(LED2); - for (i = 0; i < 2000000; i++) /* Wait a bit. */ - __asm__("nop"); - - led_on(LED3); - for (i = 0; i < 2000000; i++) /* Wait a bit. */ - __asm__("nop"); - - led_off(LED1); - led_off(LED2); - led_off(LED3); - for (i = 0; i < 2000000; i++) /* Wait a bit. */ - __asm__("nop"); - } - - - - return 0; -} diff --git a/firmware/startup_systick/CMakeLists.txt b/firmware/startup_systick/CMakeLists.txt deleted file mode 100644 index f2190caf..00000000 --- a/firmware/startup_systick/CMakeLists.txt +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright 2014 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. -# - -cmake_minimum_required(VERSION 2.8.9) -set(CMAKE_TOOLCHAIN_FILE ../toolchain-arm-cortex-m.cmake) - -project(startup_systick) - -include(../hackrf-common.cmake) - -set(SRC_M4 - startup_systick.c -) - -DeclareTargets() diff --git a/firmware/startup_systick/README b/firmware/startup_systick/README deleted file mode 100644 index c99ad470..00000000 --- a/firmware/startup_systick/README +++ /dev/null @@ -1,12 +0,0 @@ -This program is an example of the startup sequence for HackRF (Jellybean with -Lemondrop attached). -LED1, LED2, and LED3 are blinking at exactly a frequency of 1Hz upon success. - -Required Lemondrop -> Jellybean connections: - -SCL: Lemondrop P7 pin 3 -> Jellybean P6 pin 3 -SDA: Lemondrop P7 pin 5 -> Jellybean P6 pin 5 -SDA: Lemondrop P7 pin 6 -> Jellybean P6 pin 6 -VCC: Lemondrop P4 pin 2, 4, or 6 -> Jellybean P17 pin 2, 4, or 6 -1V8: Lemondrop P11 pin 2, 4, or 6 -> Jellybean P16 pin 2, 4, or 6 -GND: Lemondrop P5 -> Jellybean P13 diff --git a/firmware/startup_systick/startup_systick.c b/firmware/startup_systick/startup_systick.c deleted file mode 100644 index 57fcb91e..00000000 --- a/firmware/startup_systick/startup_systick.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * 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. - */ - -#include -#include -#include - -#include "hackrf_core.h" - -/* Global counter incremented by SysTick Interrupt each millisecond */ -volatile uint32_t g_ulSysTickCount; -uint32_t g_NbCyclePerSecond; - -void systick_setup(void) -{ - uint32_t systick_reload_val; - g_ulSysTickCount = 0; - - /* Disable IRQ globally */ - __asm__("cpsid i"); - - /* Set processor Clock as Source Clock */ - systick_set_clocksource(STK_CTRL_CLKSOURCE); - - /* Get SysTick calibration value to obtain by default 1 tick = 10ms */ - systick_reload_val = systick_get_calib(); - /* - * Calibration seems wrong on LPC43xx(TBC) for default Freq it assume System Clock is 12MHz but it is 12*17=204MHz - * Fix the Calibration value bu multiplication by 17 - */ - systick_reload_val = (systick_reload_val*17); - - /* To obtain 1ms per tick just divide by 10 the 10ms base tick and set the reload */ - systick_reload_val = systick_reload_val/10; - systick_set_reload(systick_reload_val); - - systick_interrupt_enable(); - - /* Start counting. */ - systick_counter_enable(); - - /* Set SysTick Priority to maximum */ - nvic_set_priority(NVIC_SYSTICK_IRQ, 0xFF); - - /* Enable IRQ globally */ - __asm__("cpsie i"); -} - -void scs_dwt_cycle_counter_enabled(void) -{ - SCS_DEMCR |= SCS_DEMCR_TRCENA; - SCS_DWT_CTRL |= SCS_DWT_CTRL_CYCCNTENA; -} - -uint32_t sys_tick_get_time_ms(void) -{ - return g_ulSysTickCount; -} - -uint32_t sys_tick_delta_time_ms(uint32_t start, uint32_t end) -{ - #define MAX_T_U32 ((2^32)-1) - uint32_t diff; - - if(end > start) - { - diff=end-start; - }else - { - diff=MAX_T_U32-(start-end)+1; - } - - return diff; -} - -void sys_tick_wait_time_ms(uint32_t wait_ms) -{ - uint32_t start, end; - uint32_t tickms; - - start = sys_tick_get_time_ms(); - - do - { - end = sys_tick_get_time_ms(); - tickms = sys_tick_delta_time_ms(start, end); - }while(tickms < wait_ms); -} - -/* Called each 1ms/1000Hz by interrupt - 1) Count the number of cycle per second. - 2) Increment g_ulSysTickCount counter. -*/ -void sys_tick_handler(void) -{ - if(g_ulSysTickCount==0) - { - /* Clear Cycle Counter*/ - SCS_DWT_CYCCNT = 0; - }else if(g_ulSysTickCount==1000) - { - /* Capture number of cycle elapsed during 1 second */ - g_NbCyclePerSecond = SCS_DWT_CYCCNT; - } - - g_ulSysTickCount++; -} - -int main(void) -{ - pin_setup(); - - enable_1v8_power(); - - cpu_clock_init(); - - scs_dwt_cycle_counter_enabled(); - - systick_setup(); - - led_on(LED1); - led_on(LED2); - led_on(LED3); - - while (1) - { - led_on(LED1); - led_on(LED2); - led_on(LED3); - - sys_tick_wait_time_ms(500); - - led_off(LED1); - led_off(LED2); - led_off(LED3); - - sys_tick_wait_time_ms(500); - } - - return 0; -} diff --git a/firmware/startup_systick_perfo/CMakeLists.txt b/firmware/startup_systick_perfo/CMakeLists.txt deleted file mode 100644 index 6d8905d1..00000000 --- a/firmware/startup_systick_perfo/CMakeLists.txt +++ /dev/null @@ -1,33 +0,0 @@ -# Copyright 2014 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. -# - -cmake_minimum_required(VERSION 2.8.9) -set(CMAKE_TOOLCHAIN_FILE ../toolchain-arm-cortex-m.cmake) - -project(startup_systick_perfo_SPIFI) - -include(../hackrf-common.cmake) - -set(SRC_M4 - startup_systick.c - perf_mips.c -) - -DeclareTargets() diff --git a/firmware/startup_systick_perfo/README b/firmware/startup_systick_perfo/README deleted file mode 100644 index 525ca664..00000000 --- a/firmware/startup_systick_perfo/README +++ /dev/null @@ -1,20 +0,0 @@ -This program is an example of the startup sequence for HackRF (Jellybean with -Lemondrop attached). -Test number of instruction per second (MIPS) slow blink ON 1s, OFF 1s -Then after 16s (the 16tests) it blink LED1/2/3 ON/OFF each 250ms. -This example compute the number of instructions per second executed called also MIPS (Millions of Instructions Per Second) - -This example code run from SRAM so maximum performance expected is 204MIPS. -See result details in result_exec_from_SRAM.txt - -This example code run from SPIFI (SPI Quad mode) and the tests check different loop size to compute the cache size used with SPIFI and estimated to less than 256Bytes (about 128 instructions in best case and in Thumb2). -See result_exec_from_SPIFI.txt for more details. - -Required Lemondrop -> Jellybean connections: - -SCL: Lemondrop P7 pin 3 -> Jellybean P6 pin 3 -SDA: Lemondrop P7 pin 5 -> Jellybean P6 pin 5 -SDA: Lemondrop P7 pin 6 -> Jellybean P6 pin 6 -VCC: Lemondrop P4 pin 2, 4, or 6 -> Jellybean P17 pin 2, 4, or 6 -1V8: Lemondrop P11 pin 2, 4, or 6 -> Jellybean P16 pin 2, 4, or 6 -GND: Lemondrop P5 -> Jellybean P13 diff --git a/firmware/startup_systick_perfo/perf_mips.c b/firmware/startup_systick_perfo/perf_mips.c deleted file mode 100644 index ea9c9d83..00000000 --- a/firmware/startup_systick_perfo/perf_mips.c +++ /dev/null @@ -1,2217 +0,0 @@ -/* - * Copyright 2010 - 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. - */ - -#include -#include -#include - -#include "hackrf_core.h" - -/* Global counter incremented by SysTick Interrupt each millisecond */ -extern volatile uint32_t g_ulSysTickCount; -extern uint32_t g_NbCyclePerSecond; - -extern uint32_t sys_tick_get_time_ms(void); -extern uint32_t sys_tick_delta_time_ms(uint32_t start, uint32_t end); -extern void sys_tick_wait_time_ms(uint32_t wait_ms); - - -uint32_t test_nb_instruction_per_sec_100_nop_asm(void) -{ - register uint32_t val __asm__("r0"); - - __asm__(" ldr r1, =g_ulSysTickCount"); - __asm__(" ldr r2, [r1]"); /* g_ulSysTickCount */ - __asm__(" push {r4}"); - __asm__(" movs r0, #0"); /* nb_instructions_per_sec = 0; */ - __asm__(" movw r4, #999"); /* wait_ms = 1000; */ - - __asm__("test_nb_instruction_per_sec_loop_100_nop:"); -/* Start 100 nop */ - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); -/* End 100 nop */ - - __asm__(" ldr r3, [r1]"); /* tickms = g_ulSysTickCount */ - __asm__(" adds r0, #108"); /* nb_instructions_per_sec += 108 */ - __asm__(" cmp r2, r3"); - __asm__(" it CS"); /* IF THEN Higher or same */ - __asm__(" addcs r3, #34"); - __asm__(" subs r3, r3, r2"); - __asm__(" cmp r3, r4"); - __asm__(" bls test_nb_instruction_per_sec_loop_100_nop"); /* tickms < wait_ms ? */ - - __asm__(" POP {r4}"); - - return val; -}; - -uint32_t test_nb_instruction_per_sec_105_nop_asm(void) -{ - register uint32_t val __asm__("r0"); - - __asm__(" ldr r1, =g_ulSysTickCount"); - __asm__(" ldr r2, [r1]"); /* g_ulSysTickCount */ - __asm__(" push {r4}"); - __asm__(" movs r0, #0"); /* nb_instructions_per_sec = 0; */ - __asm__(" movw r4, #999"); /* wait_ms = 1000; */ - - __asm__("test_nb_instruction_per_sec_loop_105_nop:"); -/* Start 100 nop */ - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); -/* End 100 nop */ - -/* Start 5 nop */ - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); -/* End 5 nop */ -/* Total 105 nop */ - - __asm__(" ldr r3, [r1]"); /* tickms = g_ulSysTickCount */ - __asm__(" adds r0, #113"); /* nb_instructions_per_sec += 105+8=113; */ - __asm__(" cmp r2, r3"); - __asm__(" it CS"); /* IF THEN Higher or same */ - __asm__(" addcs r3, #34"); - __asm__(" subs r3, r3, r2"); - __asm__(" cmp r3, r4"); - __asm__(" bls test_nb_instruction_per_sec_loop_105_nop"); /* tickms < wait_ms ? */ - - __asm__(" POP {r4}"); - - return val; -}; - -uint32_t test_nb_instruction_per_sec_110_nop_asm(void) -{ - register uint32_t val __asm__("r0"); - - __asm__(" ldr r1, =g_ulSysTickCount"); - __asm__(" ldr r2, [r1]"); /* g_ulSysTickCount */ - __asm__(" push {r4}"); - __asm__(" movs r0, #0"); /* nb_instructions_per_sec = 0; */ - __asm__(" movw r4, #999"); /* wait_ms = 1000; */ - - __asm__("test_nb_instruction_per_sec_loop_110_nop:"); -/* Start 100 nop */ - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); -/* End 100 nop */ - -/* Start 10 nop */ - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); -/* End 10 nop */ -/* Total 110 nop */ - - __asm__(" ldr r3, [r1]"); /* tickms = g_ulSysTickCount */ - __asm__(" adds r0, #118"); /* nb_instructions_per_sec += 118; */ - __asm__(" cmp r2, r3"); - __asm__(" it CS"); /* IF THEN Higher or same */ - __asm__(" addcs r3, #34"); - __asm__(" subs r3, r3, r2"); - __asm__(" cmp r3, r4"); - __asm__(" bls test_nb_instruction_per_sec_loop_110_nop"); /* tickms < wait_ms ? */ - - __asm__(" POP {r4}"); - - return val; -}; - -uint32_t test_nb_instruction_per_sec_115_nop_asm(void) -{ - register uint32_t val __asm__("r0"); - - __asm__(" ldr r1, =g_ulSysTickCount"); - __asm__(" ldr r2, [r1]"); /* g_ulSysTickCount */ - __asm__(" push {r4}"); - __asm__(" movs r0, #0"); /* nb_instructions_per_sec = 0; */ - __asm__(" movw r4, #999"); /* wait_ms = 1000; */ - - __asm__("test_nb_instruction_per_sec_loop_115_nop:"); -/* Start 100 nop */ - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); -/* End 100 nop */ - -/* Start 15 nop */ - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); -/* End 15 nop */ -/* Total 115 nop */ - - __asm__(" ldr r3, [r1]"); /* tickms = g_ulSysTickCount */ - __asm__(" adds r0, #123"); /* nb_instructions_per_sec += 115+8 = 123; */ - __asm__(" cmp r2, r3"); - __asm__(" it CS"); /* IF THEN Higher or same */ - __asm__(" addcs r3, #34"); - __asm__(" subs r3, r3, r2"); - __asm__(" cmp r3, r4"); - __asm__(" bls test_nb_instruction_per_sec_loop_115_nop"); /* tickms < wait_ms ? */ - - __asm__(" POP {r4}"); - - return val; -}; - -uint32_t test_nb_instruction_per_sec_120_nop_asm(void) -{ - register uint32_t val __asm__("r0"); - - __asm__(" ldr r1, =g_ulSysTickCount"); - __asm__(" ldr r2, [r1]"); /* g_ulSysTickCount */ - __asm__(" push {r4}"); - __asm__(" movs r0, #0"); /* nb_instructions_per_sec = 0; */ - __asm__(" movw r4, #999"); /* wait_ms = 1000; */ - - __asm__("test_nb_instruction_per_sec_loop_120_nop:"); -/* Start 100 nop */ - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); -/* End 100 nop */ - -/* Start 20 nop */ - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); -/* End 20 nop */ -/* Total 120 nop */ - - __asm__(" ldr r3, [r1]"); /* tickms = g_ulSysTickCount */ - __asm__(" adds r0, #128"); /* nb_instructions_per_sec += 128; */ - __asm__(" cmp r2, r3"); - __asm__(" it CS"); /* IF THEN Higher or same */ - __asm__(" addcs r3, #34"); - __asm__(" subs r3, r3, r2"); - __asm__(" cmp r3, r4"); - __asm__(" bls test_nb_instruction_per_sec_loop_120_nop"); /* tickms < wait_ms ? */ - - __asm__(" POP {r4}"); - - return val; -}; - -uint32_t test_nb_instruction_per_sec_150_nop_asm(void) -{ - register uint32_t val __asm__("r0"); - - __asm__(" ldr r1, =g_ulSysTickCount"); - __asm__(" ldr r2, [r1]"); /* g_ulSysTickCount */ - __asm__(" push {r4}"); - __asm__(" movs r0, #0"); /* nb_instructions_per_sec = 0; */ - __asm__(" movw r4, #999"); /* wait_ms = 1000; */ - - __asm__("test_nb_instruction_per_sec_loop_150_nop:"); -/* Start 100 nop */ - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); -/* End 100 nop */ - -/* Start 50 nop */ - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); -/* End 50 nop */ -/* Total 150 nop */ - - __asm__(" ldr r3, [r1]"); /* tickms = g_ulSysTickCount */ - __asm__(" adds r0, #158"); /* nb_instructions_per_sec += 158; */ - __asm__(" cmp r2, r3"); - __asm__(" it CS"); /* IF THEN Higher or same */ - __asm__(" addcs r3, #34"); - __asm__(" subs r3, r3, r2"); - __asm__(" cmp r3, r4"); - __asm__(" bls test_nb_instruction_per_sec_loop_150_nop"); /* tickms < wait_ms ? */ - - __asm__(" POP {r4}"); - - return val; -}; - -uint32_t test_nb_instruction_per_sec_200_nop_asm(void) -{ - register uint32_t val __asm__("r0"); - - __asm__(" ldr r1, =g_ulSysTickCount"); - __asm__(" ldr r2, [r1]"); /* g_ulSysTickCount */ - __asm__(" push {r4}"); - __asm__(" movs r0, #0"); /* nb_instructions_per_sec = 0; */ - __asm__(" movw r4, #999"); /* wait_ms = 1000; */ - - __asm__("test_nb_instruction_per_sec_loop_200_nop:"); -/* Start 100 nop */ - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); -/* End 100 nop */ - -/* Start 100 nop */ - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); -/* End 100 nop */ -/* Total 200 nop */ - - __asm__(" ldr r3, [r1]"); /* tickms = g_ulSysTickCount */ - __asm__(" adds r0, #208"); /* nb_instructions_per_sec += 208; */ - __asm__(" cmp r2, r3"); - __asm__(" it CS"); /* IF THEN Higher or same */ - __asm__(" addcs r3, #34"); - __asm__(" subs r3, r3, r2"); - __asm__(" cmp r3, r4"); - __asm__(" bls test_nb_instruction_per_sec_loop_200_nop"); /* tickms < wait_ms ? */ - - __asm__(" POP {r4}"); - - return val; -}; - -uint32_t test_nb_instruction_per_sec_1000_nop_asm(void) -{ - register uint32_t val __asm__("r0"); - - __asm__(" ldr r1, =g_ulSysTickCount"); - __asm__(" ldr r2, [r1]"); /* g_ulSysTickCount */ - __asm__(" push {r4}"); - __asm__(" movs r0, #0"); /* nb_instructions_per_sec = 0; */ - __asm__(" movw r4, #999"); /* wait_ms = 1000; */ - - __asm__("test_nb_instruction_per_sec_loop_1000nop:"); -/* Start 100 nop */ - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); -/* End 100 nop */ - -/* Start 100 nop */ - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); -/* End 100 nop */ - -/* Start 100 nop */ - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); -/* End 100 nop */ - -/* Start 100 nop */ - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); -/* End 100 nop */ - -/* Start 100 nop */ - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); -/* End 100 nop */ - -/* Start 100 nop */ - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); -/* End 100 nop */ - -/* Start 100 nop */ - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); -/* End 100 nop */ - -/* Start 100 nop */ - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); -/* End 100 nop */ - -/* Start 100 nop */ - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); -/* End 100 nop */ - -/* Start 100 nop */ - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); - __asm__(" nop"); -/* End 100 nop */ -/* Total 200 nop */ - - __asm__(" ldr r3, [r1]"); /* tickms = g_ulSysTickCount */ - __asm__(" adds r0, #1008"); /* nb_instructions_per_sec += 1008; */ - __asm__(" cmp r2, r3"); - __asm__(" it CS"); /* IF THEN Higher or same */ - __asm__(" addcs r3, #34"); - __asm__(" subs r3, r3, r2"); - __asm__(" cmp r3, r4"); - __asm__(" bls test_nb_instruction_per_sec_loop_1000nop"); /* tickms < wait_ms ? */ - - __asm__(" POP {r4}"); - - return val; -}; diff --git a/firmware/startup_systick_perfo/result_exec_from_SPIFI.txt b/firmware/startup_systick_perfo/result_exec_from_SPIFI.txt deleted file mode 100644 index 4d335b33..00000000 --- a/firmware/startup_systick_perfo/result_exec_from_SPIFI.txt +++ /dev/null @@ -1,33 +0,0 @@ -Frequency MCU Core M4 = 204MHz - -"nb_inst_per_sec" 0x10000008 - nb_inst_per_sec[0] 195609816 test_nb_instruction_per_sec_100_nop_asm(); - nb_inst_per_sec[1] 195577462 test_nb_instruction_per_sec_105_nop_asm(); - nb_inst_per_sec[2] 195525410 test_nb_instruction_per_sec_110_nop_asm(); - nb_inst_per_sec[3] 35423508 test_nb_instruction_per_sec_115_nop_asm(); - nb_inst_per_sec[4] 5058688 test_nb_instruction_per_sec_120_nop_asm(); - nb_inst_per_sec[5] 5094868 test_nb_instruction_per_sec_150_nop_asm(); - nb_inst_per_sec[6] 5162144 test_nb_instruction_per_sec_200_nop_asm(); - nb_inst_per_sec[7] 5505696 test_nb_instruction_per_sec_1000_nop_asm(); - - nb_inst_per_sec[8] 195600420 test_nb_instruction_per_sec_100_nop_asm(); - nb_inst_per_sec[9] 195578027 test_nb_instruction_per_sec_105_nop_asm(); - nb_inst_per_sec[10] 195525882 test_nb_instruction_per_sec_110_nop_asm(); - nb_inst_per_sec[11] 35422647 test_nb_instruction_per_sec_115_nop_asm(); - nb_inst_per_sec[12] 5058688 test_nb_instruction_per_sec_120_nop_asm(); - nb_inst_per_sec[13] 5094868 test_nb_instruction_per_sec_150_nop_asm(); - nb_inst_per_sec[14] 5162144 test_nb_instruction_per_sec_200_nop_asm(); - nb_inst_per_sec[15] 5505696 test_nb_instruction_per_sec_1000_nop_asm(); - -Real speed expected from SPIFI without cache (with lot of nop) -Oscilloscope Freq SPIFI SCK = 22.50MHz to 22.83MHz (in reality 22.67MHz => 204/9 => SPIFI_CLK connected to IDIVB & IDIVB default=9) -So worst case 22.50Mbits*4 = 90Mbits/s => 11.25MBytes/s with an overhead of about 50% due to SPIFI protocol addr ... => 5.625MB -1 nop = 2 bytes (THUMB 0x00 0xBF) => Max 5.625 Millions instruction per second - -110 NOP is in fact 110 + 9 (including loop overhead) -119*2 = 238 bytes - -115NOP + 9 => does not enter in cache !! (248bytes) -Internal Cache size is about 256Bytes maybe shared Code/Data. - -SPIFI obtained min=5.05 MIPS, max=195.6 MIPS \ No newline at end of file diff --git a/firmware/startup_systick_perfo/result_exec_from_SRAM.txt b/firmware/startup_systick_perfo/result_exec_from_SRAM.txt deleted file mode 100644 index ce4a4299..00000000 --- a/firmware/startup_systick_perfo/result_exec_from_SRAM.txt +++ /dev/null @@ -1,22 +0,0 @@ -Frequency MCU Core M4 = 204MHz - -"nb_inst_per_sec" 0x10080008 - nb_inst_per_sec[0] 202091544 test_nb_instruction_per_sec_100_nop_asm(); - nb_inst_per_sec[1] 202172820 test_nb_instruction_per_sec_105_nop_asm(); - nb_inst_per_sec[2] 202247988 test_nb_instruction_per_sec_110_nop_asm(); - nb_inst_per_sec[3] 202317165 test_nb_instruction_per_sec_115_nop_asm(); - nb_inst_per_sec[4] 202381696 test_nb_instruction_per_sec_120_nop_asm(); - nb_inst_per_sec[5] 202680030 test_nb_instruction_per_sec_150_nop_asm(); - nb_inst_per_sec[6] 202986160 test_nb_instruction_per_sec_200_nop_asm(); - nb_inst_per_sec[7] 203760144 test_nb_instruction_per_sec_1000_nop_asm(); - - nb_inst_per_sec[8] 202091220 test_nb_instruction_per_sec_100_nop_asm(); - nb_inst_per_sec[9] 202172820 test_nb_instruction_per_sec_105_nop_asm(); - nb_inst_per_sec[10] 202247988 test_nb_instruction_per_sec_110_nop_asm(); - nb_inst_per_sec[11] 202317165 test_nb_instruction_per_sec_115_nop_asm(); - nb_inst_per_sec[12] 202381696 test_nb_instruction_per_sec_120_nop_asm(); - nb_inst_per_sec[13] 202680030 test_nb_instruction_per_sec_150_nop_asm(); - nb_inst_per_sec[14] 202986160 test_nb_instruction_per_sec_200_nop_asm(); - nb_inst_per_sec[15] 203760144 test_nb_instruction_per_sec_1000_nop_asm(); - -SRAM execution, expected 204 MIPS best case obtained min=202 MIPS, max=203.7 MIPS diff --git a/firmware/startup_systick_perfo/startup_systick.c b/firmware/startup_systick_perfo/startup_systick.c deleted file mode 100644 index f07982be..00000000 --- a/firmware/startup_systick_perfo/startup_systick.c +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright 2010 - 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. - */ - -#include -#include -#include - -#include "hackrf_core.h" - -/* Global counter incremented by SysTick Interrupt each millisecond */ -volatile uint32_t g_ulSysTickCount; -uint32_t g_NbCyclePerSecond; - -void systick_setup(void) -{ - uint32_t systick_reload_val; - g_ulSysTickCount = 0; - - /* Disable IRQ globally */ - __asm__("cpsid i"); - - /* Set processor Clock as Source Clock */ - systick_set_clocksource(STK_CTRL_CLKSOURCE); - - /* Get SysTick calibration value to obtain by default 1 tick = 10ms */ - systick_reload_val = systick_get_calib(); - /* - * Calibration seems wrong on LPC43xx(TBC) for default Freq it assume System Clock is 12MHz but it is 12*17=204MHz - * Fix the Calibration value bu multiplication by 17 - */ - systick_reload_val = (systick_reload_val*17); - - /* To obtain 1ms per tick just divide by 10 the 10ms base tick and set the reload */ - systick_reload_val = systick_reload_val/10; - systick_set_reload(systick_reload_val); - - systick_interrupt_enable(); - - /* Start counting. */ - systick_counter_enable(); - - /* Set SysTick Priority to maximum */ - nvic_set_priority(NVIC_SYSTICK_IRQ, 0xFF); - - /* Enable IRQ globally */ - __asm__("cpsie i"); -} - -void scs_dwt_cycle_counter_enabled(void) -{ - SCS_DEMCR |= SCS_DEMCR_TRCENA; - SCS_DWT_CTRL |= SCS_DWT_CTRL_CYCCNTENA; -} - -uint32_t sys_tick_get_time_ms(void) -{ - return g_ulSysTickCount; -} - -uint32_t sys_tick_delta_time_ms(uint32_t start, uint32_t end) -{ - #define MAX_T_U32 ((2^32)-1) - uint32_t diff; - - if(end > start) - { - diff=end-start; - }else - { - diff=MAX_T_U32-(start-end)+1; - } - - return diff; -} - -void sys_tick_wait_time_ms(uint32_t wait_ms) -{ - uint32_t start, end; - uint32_t tickms; - - start = sys_tick_get_time_ms(); - - do - { - end = sys_tick_get_time_ms(); - tickms = sys_tick_delta_time_ms(start, end); - }while(tickms < wait_ms); -} - -/* Called each 1ms/1000Hz by interrupt - 1) Count the number of cycle per second. - 2) Increment g_ulSysTickCount counter. -*/ -void sys_tick_handler(void) -{ - if(g_ulSysTickCount==0) - { - /* Clear Cycle Counter*/ - SCS_DWT_CYCCNT = 0; - }else if(g_ulSysTickCount==1000) - { - /* Capture number of cycle elapsed during 1 second */ - g_NbCyclePerSecond = SCS_DWT_CYCCNT; - } - - g_ulSysTickCount++; -} - -uint32_t nb_inst_per_sec[16]; - -extern uint32_t test_nb_instruction_per_sec_100_nop_asm(); -extern uint32_t test_nb_instruction_per_sec_105_nop_asm(); -extern uint32_t test_nb_instruction_per_sec_110_nop_asm(); -extern uint32_t test_nb_instruction_per_sec_115_nop_asm(); -extern uint32_t test_nb_instruction_per_sec_120_nop_asm(); -extern uint32_t test_nb_instruction_per_sec_150_nop_asm(); -extern uint32_t test_nb_instruction_per_sec_200_nop_asm(); -extern uint32_t test_nb_instruction_per_sec_1000_nop_asm(); - -#define LED1_TOGGLE() (led_toggle(LED1)) - -int main(void) -{ - pin_setup(); - - enable_1v8_power(); - - cpu_clock_init(); - - scs_dwt_cycle_counter_enabled(); - - systick_setup(); - - led_off(LED1); - - /* Test number of instruction per second (MIPS) slow blink ON 1s, OFF 1s */ -LED1_TOGGLE(); - nb_inst_per_sec[0] = test_nb_instruction_per_sec_100_nop_asm(); -LED1_TOGGLE(); - nb_inst_per_sec[1]= test_nb_instruction_per_sec_105_nop_asm(); -LED1_TOGGLE(); - nb_inst_per_sec[2]= test_nb_instruction_per_sec_110_nop_asm(); -LED1_TOGGLE(); - nb_inst_per_sec[3]= test_nb_instruction_per_sec_115_nop_asm(); -LED1_TOGGLE(); - nb_inst_per_sec[4] = test_nb_instruction_per_sec_120_nop_asm(); -LED1_TOGGLE(); - nb_inst_per_sec[5] = test_nb_instruction_per_sec_150_nop_asm(); -LED1_TOGGLE(); - nb_inst_per_sec[6] = test_nb_instruction_per_sec_200_nop_asm(); -LED1_TOGGLE(); - nb_inst_per_sec[7] = test_nb_instruction_per_sec_1000_nop_asm(); -LED1_TOGGLE(); - nb_inst_per_sec[8] = test_nb_instruction_per_sec_100_nop_asm(); -LED1_TOGGLE(); - nb_inst_per_sec[9]= test_nb_instruction_per_sec_105_nop_asm(); -LED1_TOGGLE(); - nb_inst_per_sec[10]= test_nb_instruction_per_sec_110_nop_asm(); -LED1_TOGGLE(); - nb_inst_per_sec[11]= test_nb_instruction_per_sec_115_nop_asm(); -LED1_TOGGLE(); - nb_inst_per_sec[12] = test_nb_instruction_per_sec_120_nop_asm(); -LED1_TOGGLE(); - nb_inst_per_sec[13] = test_nb_instruction_per_sec_150_nop_asm(); -LED1_TOGGLE(); - nb_inst_per_sec[14] = test_nb_instruction_per_sec_200_nop_asm(); -LED1_TOGGLE(); - nb_inst_per_sec[15] = test_nb_instruction_per_sec_1000_nop_asm(); -LED1_TOGGLE(); - - /* Test finished fast blink */ - while (1) - { - led_on(LED1); - led_on(LED2); - led_on(LED3); - - sys_tick_wait_time_ms(250); - - led_off(LED1); - led_off(LED2); - led_off(LED3); - - sys_tick_wait_time_ms(250); - } - - return 0; -} From 09eb15cb53a2c09e43dfbb4e326f6aaee79fcc64 Mon Sep 17 00:00:00 2001 From: Dominic Spill Date: Tue, 14 Feb 2017 21:09:34 -0700 Subject: [PATCH 4/4] Remove unused development firmware from build --- firmware/CMakeLists.txt | 7 ------- 1 file changed, 7 deletions(-) diff --git a/firmware/CMakeLists.txt b/firmware/CMakeLists.txt index 1f9ae191..3f21fc5a 100644 --- a/firmware/CMakeLists.txt +++ b/firmware/CMakeLists.txt @@ -26,11 +26,4 @@ set(CMAKE_TOOLCHAIN_FILE toolchain-arm-cortex-m.cmake) project (hackrf_firmware_all) add_subdirectory(blinky) -add_subdirectory(mixertx) -add_subdirectory(sgpio) -add_subdirectory(sgpio-rx) -add_subdirectory(simpletx) -add_subdirectory(startup) -add_subdirectory(startup_systick) -add_subdirectory(startup_systick_perfo) add_subdirectory(hackrf_usb)