diff --git a/firmware/blinky/blinky.c b/firmware/blinky/blinky.c index fdaf3ef7a..4bd111068 100644 --- a/firmware/blinky/blinky.c +++ b/firmware/blinky/blinky.c @@ -45,13 +45,13 @@ int main(void) led_on(LED2); led_on(LED3); - delay(2000000); + delay_ms(150); led_off(LED1); led_off(LED2); led_off(LED3); - delay(2000000); + delay_ms(150); } return 0; diff --git a/firmware/common/clock_gen.c b/firmware/common/clock_gen.c index 22f461c2d..8a75074f8 100644 --- a/firmware/common/clock_gen.c +++ b/firmware/common/clock_gen.c @@ -148,7 +148,7 @@ clock_source_t activate_best_clock_source(void) /* Enable PortaPack reference oscillator (if present), and check for valid clock. */ if (portapack_reference_oscillator && portapack()) { portapack_reference_oscillator(true); - delay(510000); /* loop iterations @ 204MHz for >10ms for oscillator to enable. */ + delay_ms(18); // for oscillator to enable. if (si5351c_clkin_signal_valid(&si5351c)) { source = CLOCK_SOURCE_PORTAPACK; } else { diff --git a/firmware/common/cpu_clock.c b/firmware/common/cpu_clock.c index 325de76fd..32fd012c0 100644 --- a/firmware/common/cpu_clock.c +++ b/firmware/common/cpu_clock.c @@ -33,6 +33,9 @@ #include "i2c_lpc.h" #include "si5351c.h" +/* We start with the CPU clock at 96MHz */ +unsigned int cpu_clock_mhz = 96; + /* Configure PLL1 (Main MCU Clock) to max speed (204MHz). Note: PLL1 clock is used by M4/M0 core, Peripheral, APB1. @@ -51,11 +54,14 @@ static void cpu_clock_pll1_max_speed(void) reg_val |= CGU_BASE_M4_CLK_CLK_SEL(CGU_SRC_IRC) | CGU_BASE_M4_CLK_AUTOBLOCK(1); CGU_BASE_M4_CLK = reg_val; + /* CPU is now at 12MHz */ + cpu_clock_mhz = 12; + /* 2. Enable the crystal oscillator. */ CGU_XTAL_OSC_CTRL &= ~CGU_XTAL_OSC_CTRL_ENABLE_MASK; /* 3. Wait 250us. */ - delay_us_at_mhz(250, 12); + delay_us(250); /* 4. Set the AUTOBLOCK bit. */ CGU_PLL1_CTRL |= CGU_PLL1_CTRL_AUTOBLOCK(1); @@ -95,11 +101,17 @@ static void cpu_clock_pll1_max_speed(void) reg_val |= CGU_BASE_M4_CLK_CLK_SEL(CGU_SRC_PLL1); CGU_BASE_M4_CLK = reg_val; + /* CPU is now at 102MHz */ + cpu_clock_mhz = 102; + /* 9. Wait 50us. */ - delay_us_at_mhz(50, 102); + delay_us(50); /* 10. Set the PLL1 P-divider to direct output mode (DIRECT=1). */ CGU_PLL1_CTRL |= CGU_PLL1_CTRL_DIRECT_MASK; + + /* CPU is now at 204MHz */ + cpu_clock_mhz = 204; } /* clock startup for LPC4320 configure PLL1 to max speed (204MHz). diff --git a/firmware/common/cpu_clock.h b/firmware/common/cpu_clock.h index 92ad64412..049296435 100644 --- a/firmware/common/cpu_clock.h +++ b/firmware/common/cpu_clock.h @@ -27,6 +27,9 @@ extern "C" { void cpu_clock_init(void); +// Current clock speed in MHz, updated on clock changes. +extern unsigned int cpu_clock_mhz; + #ifdef __cplusplus } #endif diff --git a/firmware/common/delay.c b/firmware/common/delay.c index ceb7693e1..b74389b2b 100644 --- a/firmware/common/delay.c +++ b/firmware/common/delay.c @@ -21,16 +21,9 @@ #include "delay.h" -void delay(uint32_t duration) -{ - uint32_t i; - - for (i = 0; i < duration; i++) { - __asm__("nop"); - } -} +#include "cpu_clock.h" -void delay_us_at_mhz(uint32_t us, uint32_t mhz) +static void delay_us_at_mhz(uint32_t us, uint32_t mhz) { #if defined(LPC43XX_M4) // The loop below takes 3 cycles per iteration. @@ -52,3 +45,13 @@ void delay_us_at_mhz(uint32_t us, uint32_t mhz) #error "No delay loop implementation" #endif } + +void delay_us(uint32_t us) +{ + delay_us_at_mhz(us, cpu_clock_mhz); +} + +void delay_ms(uint32_t ms) +{ + delay_us_at_mhz(ms * 1000, cpu_clock_mhz); +} diff --git a/firmware/common/delay.h b/firmware/common/delay.h index 870ba39e9..eed806bbd 100644 --- a/firmware/common/delay.h +++ b/firmware/common/delay.h @@ -27,8 +27,8 @@ extern "C" { #include -void delay(uint32_t duration); -void delay_us_at_mhz(uint32_t us, uint32_t mhz); +void delay_us(uint32_t us); +void delay_ms(uint32_t ms); #ifdef __cplusplus } diff --git a/firmware/common/fpga_selftest.c b/firmware/common/fpga_selftest.c index 06f2e8eea..7170422c3 100644 --- a/firmware/common/fpga_selftest.c +++ b/firmware/common/fpga_selftest.c @@ -200,7 +200,7 @@ bool fpga_if_xcvr_selftest(void) // Capture 1: 4 Msps, tone at 0.5 MHz, narrowband filter OFF sample_rate_set(SR_FP_MHZ(4), true); - delay_us_at_mhz(1000, 204); + delay_ms(1); if (rx_samples(num_samples, 2000000) == -1) { timeout = true; } @@ -211,7 +211,7 @@ bool fpga_if_xcvr_selftest(void) // Capture 2: 4 Msps, tone at 0.5 MHz, narrowband filter ON narrowband_filter_set(1); - delay_us_at_mhz(1000, 204); + delay_ms(1); if (rx_samples(num_samples, 2000000) == -1) { timeout = true; } @@ -224,7 +224,7 @@ bool fpga_if_xcvr_selftest(void) fpga_set_tx_nco_pstep(&fpga, 255); sample_rate_set(SR_FP_MHZ(20), true); narrowband_filter_set(0); - delay_us_at_mhz(1000, 204); + delay_ms(1); if (rx_samples(num_samples, 2000000) == -1) { timeout = true; } @@ -235,7 +235,7 @@ bool fpga_if_xcvr_selftest(void) // Capture 4: 20 Msps, tone at 5 MHz, narrowband filter ON narrowband_filter_set(1); - delay_us_at_mhz(1000, 204); + delay_ms(1); if (rx_samples(num_samples, 2000000) == -1) { timeout = true; } diff --git a/firmware/common/ice40_spi.c b/firmware/common/ice40_spi.c index 2685092a4..880e0be29 100644 --- a/firmware/common/ice40_spi.c +++ b/firmware/common/ice40_spi.c @@ -112,14 +112,14 @@ bool ice40_spi_syscfg_program( gpio_clear(drv->gpio_select); // Wait a minimum of 200 ns. - delay_us_at_mhz(1, 204 / 4); // 250 ns. + delay_us(1); // Release CRESET_B or drive CRESET_B = 1. gpio_set(drv->gpio_creset); // Wait a minimum of 1200 μs to clear internal configuration memory. // Testing showed us that we need to wait longer. Let's wait 1800 μs. - delay_us_at_mhz(1800, 204); + delay_us(1800); // Set SPI_SS = 1, Send 8 dummy clocks. gpio_set(drv->gpio_select); diff --git a/firmware/common/leds.c b/firmware/common/leds.c index ab9b56fba..e1fd507b7 100644 --- a/firmware/common/leds.c +++ b/firmware/common/leds.c @@ -84,17 +84,17 @@ void set_leds(const uint8_t state) } } -void halt_and_flash(const uint32_t duration) +void halt_and_flash(const uint32_t period_ms) { /* blink LED1, LED2, and LED3 */ while (1) { led_on(LED1); led_on(LED2); led_on(LED3); - delay(duration); + delay_ms(period_ms / 2); led_off(LED1); led_off(LED2); led_off(LED3); - delay(duration); + delay_ms(period_ms / 2); } } diff --git a/firmware/common/operacake_sctimer.c b/firmware/common/operacake_sctimer.c index 76453e57b..c5ec8a3b9 100644 --- a/firmware/common/operacake_sctimer.c +++ b/firmware/common/operacake_sctimer.c @@ -75,7 +75,7 @@ void operacake_sctimer_init(void) // there are additional instructions that fill the time. If the duration of // the actions from here to the first access to the SCTimer is changed, then // this delay may need to be increased. - delay(8); + delay_us(1); // Pin definitions for the HackRF // U2CTRL0 diff --git a/firmware/common/platform_detect.c b/firmware/common/platform_detect.c index 7c9fb53d9..475ad1e1f 100644 --- a/firmware/common/platform_detect.c +++ b/firmware/common/platform_detect.c @@ -194,11 +194,11 @@ void detect_hardware_platform(void) /* activate internal pull-down */ scu_pinmux(P5_0, SCU_GPIO_PDN | SCU_CONF_FUNCTION0); scu_pinmux(P6_10, SCU_GPIO_PDN | SCU_CONF_FUNCTION0); - delay_us_at_mhz(4, 96); + delay_us(4); /* tri-state for a moment before testing input */ scu_pinmux(P5_0, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION0); scu_pinmux(P6_10, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION0); - delay_us_at_mhz(4, 96); + delay_us(4); /* if input rose quickly, there must be an external pull-up */ detected_resistors |= (gpio_read(&gpio2_9_on_P5_0)) ? P5_0_PUP : 0; detected_resistors |= (gpio_read(&gpio3_6_on_P6_10)) ? P6_10_PUP : 0; @@ -207,12 +207,12 @@ void detect_hardware_platform(void) scu_pinmux(P5_0, SCU_GPIO_PUP | SCU_CONF_FUNCTION0); scu_pinmux(P6_10, SCU_GPIO_PUP | SCU_CONF_FUNCTION0); scu_pinmux(P6_5, SCU_GPIO_PUP | SCU_CONF_FUNCTION0); - delay_us_at_mhz(4, 96); + delay_us(4); /* tri-state for a moment before testing input */ scu_pinmux(P5_0, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION0); scu_pinmux(P6_10, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION0); scu_pinmux(P6_5, SCU_GPIO_NOPULL | SCU_CONF_FUNCTION0); - delay_us_at_mhz(4, 96); + delay_us(4); /* if input fell quickly, there must be an external pull-down */ detected_resistors |= (gpio_read(&gpio2_9_on_P5_0)) ? 0 : P5_0_PDN; detected_resistors |= (gpio_read(&gpio3_6_on_P6_10)) ? 0 : P6_10_PDN; @@ -221,37 +221,37 @@ void detect_hardware_platform(void) switch (detected_resistors) { case JAWBREAKER_RESISTORS: if (!(supported_platform() & PLATFORM_JAWBREAKER)) { - halt_and_flash(3000000); + halt_and_flash(500); } platform = BOARD_ID_JAWBREAKER; return; case RAD1O_RESISTORS: if (!(supported_platform() & PLATFORM_RAD1O)) { - halt_and_flash(3000000); + halt_and_flash(500); } platform = BOARD_ID_RAD1O; return; case HACKRF1_OG_RESISTORS: if (!(supported_platform() & PLATFORM_HACKRF1_OG)) { - halt_and_flash(3000000); + halt_and_flash(500); } platform = BOARD_ID_HACKRF1_OG; break; case HACKRF1_R9_RESISTORS: if (!(supported_platform() & PLATFORM_HACKRF1_R9)) { - halt_and_flash(3000000); + halt_and_flash(500); } platform = BOARD_ID_HACKRF1_R9; break; case PRALINE_RESISTORS: if (!(supported_platform() & PLATFORM_PRALINE)) { - halt_and_flash(3000000); + halt_and_flash(500); } platform = BOARD_ID_PRALINE; break; default: platform = BOARD_ID_UNRECOGNIZED; - halt_and_flash(1000000); + halt_and_flash(150); } uint32_t adc0_3 = check_pin_strap(3); diff --git a/firmware/common/portapack.c b/firmware/common/portapack.c index d3d848fcf..0c3cbce2e 100644 --- a/firmware/common/portapack.c +++ b/firmware/common/portapack.c @@ -31,12 +31,6 @@ #include "platform_gpio.h" #include "platform_scu.h" -static void portapack_sleep_milliseconds(const uint32_t milliseconds) -{ - /* NOTE: Naively assumes 204 MHz instruction cycle clock and five instructions per count */ - delay(milliseconds * 40800); -} - typedef struct { gpio_t gpio_dir; gpio_t gpio_lcd_rdx; @@ -244,7 +238,7 @@ static void portapack_lcd_sleep_out(void) // "It will be necessary to wait 120msec after sending Sleep Out // command (when in Sleep In Mode) before Sleep In command can be // sent." - portapack_sleep_milliseconds(120); + delay_ms(120); } static void portapack_lcd_display_on(void) @@ -310,11 +304,11 @@ static void portapack_lcd_wake(void) static void portapack_lcd_reset(void) { portapack_lcd_reset_state(false); - portapack_sleep_milliseconds(1); + delay_ms(1); portapack_lcd_reset_state(true); - portapack_sleep_milliseconds(10); + delay_ms(10); portapack_lcd_reset_state(false); - portapack_sleep_milliseconds(120); + delay_ms(120); } static void portapack_lcd_init(void) diff --git a/firmware/common/power.c b/firmware/common/power.c index 1256e5953..70c8c0f18 100644 --- a/firmware/common/power.c +++ b/firmware/common/power.c @@ -132,7 +132,7 @@ static inline void enable_rf_power_praline(void) gpio_clear(platform_gpio()->vaa_disable); /* Let the voltage stabilize */ - delay(1000000); + delay_ms(35); } static inline void disable_rf_power_praline(void) @@ -147,7 +147,7 @@ static inline void enable_rf_power_rad1o(void) gpio_set(platform_gpio()->vaa_enable); /* Let the voltage stabilize */ - delay(1000000); + delay_ms(35); } static inline void disable_rf_power_rad1o(void) diff --git a/firmware/common/rad1o/display.c b/firmware/common/rad1o/display.c index 91813aab9..c0c090b32 100644 --- a/firmware/common/rad1o/display.c +++ b/firmware/common/rad1o/display.c @@ -10,12 +10,6 @@ #include "gpio_lpc.h" #include "delay.h" -static void delayms(const uint32_t milliseconds) -{ - /* NOTE: Naively assumes 204 MHz instruction cycle clock and five instructions per count */ - delay(milliseconds * 40800); -} - static struct gpio gpio_lcd_cs = GPIO(4, 12); /* P9_0 */ static struct gpio gpio_lcd_bl_en = GPIO(0, 8); /* P1_1 */ static struct gpio gpio_lcd_reset = GPIO(5, 17); /* P9_4 */ @@ -85,9 +79,9 @@ void rad1o_lcdInit(void) // Reset the display gpio_clear(&gpio_lcd_reset); - delayms(100); + delay_ms(100); gpio_set(&gpio_lcd_reset); - delayms(100); + delay_ms(100); select(); @@ -115,7 +109,7 @@ void rad1o_lcdInit(void) (1 << 12) | (0 << 13) | (0 << 14) | 0); write(0, 0x01); /* most color displays need the pause */ - delayms(10); + delay_ms(10); size_t i = 0; while (i < sizeof(initseq_d)) { diff --git a/firmware/common/rffc5071.c b/firmware/common/rffc5071.c index 2a1866d26..df25987c7 100644 --- a/firmware/common/rffc5071.c +++ b/firmware/common/rffc5071.c @@ -163,13 +163,13 @@ void rffc5071_lock_test(rffc5071_driver_t* const drv) rffc5071_enable(drv); // Wait 1ms. - delay_us_at_mhz(1000, 204); + delay_ms(1); // Check for lock. lock = rffc5071_check_lock(drv); rffc5071_disable(drv); - delay_us_at_mhz(100, 204); + delay_us(100); selftest.mixer_locks[i] = lock; } diff --git a/firmware/common/si5351c.c b/firmware/common/si5351c.c index 77d777033..6672b3b01 100644 --- a/firmware/common/si5351c.c +++ b/firmware/common/si5351c.c @@ -224,7 +224,7 @@ void si5351c_reset_plls(si5351c_driver_t* const drv, si5351c_pll_mask_t mask) set_PLLA_RST(drv, (mask & SI5351C_PLL_MASK_A) ? true : false); set_PLLB_RST(drv, (mask & SI5351C_PLL_MASK_B) ? true : false); si5351c_regs_commit(drv); - delay_us_at_mhz(2000, 204); + delay_ms(2); si5351c_enable_clock_outputs(drv); } diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index 5d71fa80b..f9a4e40b8 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -433,7 +433,7 @@ int main(void) if (board_id != BOARD_ID_RAD1O) { clock_gen_shutdown(); } - delay_us_at_mhz(10000, 96); + delay_ms(10); pins_setup(); #ifdef IS_PRALINE if (IS_PRALINE) { @@ -491,7 +491,7 @@ int main(void) #ifdef IS_NOT_PRALINE if (IS_NOT_PRALINE) { if (!cpld_jtag_sram_load(&jtag_cpld)) { - halt_and_flash(6000000); + halt_and_flash(1000); } } #endif @@ -503,7 +503,7 @@ int main(void) #else fpga_image_load(&fpga_loader, 0); #endif - delay_us_at_mhz(100, 204); + delay_us(100); fpga_spi_selftest(); fpga_sgpio_selftest(); } diff --git a/firmware/hackrf_usb/usb_api_cpld.c b/firmware/hackrf_usb/usb_api_cpld.c index 391b93667..38103c811 100644 --- a/firmware/hackrf_usb/usb_api_cpld.c +++ b/firmware/hackrf_usb/usb_api_cpld.c @@ -76,7 +76,7 @@ void cpld_update(void) cpld_xsvf_buffer, refill_cpld_buffer); if (error == 0) { - halt_and_flash(6000000); + halt_and_flash(1000); } else { /* LED3 (Red) steady on error */ led_on(LED3);