diff options
author | Karl Palsson <karlp@etactica.com> | 2016-08-18 18:35:00 +0000 |
---|---|---|
committer | Karl Palsson <karlp@etactica.com> | 2016-08-19 11:31:57 +0000 |
commit | cb945fa6711e1fbe224e8a9d745c740f71dce279 (patch) | |
tree | f6dd14ff2ae6b05c49c79e0c4616c289ae899d29 | |
parent | 3d72709fdadb5a6521e534c21f2b74e35325a66e (diff) | |
download | olsndot-cb945fa6711e1fbe224e8a9d745c740f71dce279.tar.gz olsndot-cb945fa6711e1fbe224e8a9d745c740f71dce279.tar.bz2 olsndot-cb945fa6711e1fbe224e8a9d745c740f71dce279.zip |
rcc-legal-ranges: run through a range of clocks
blink fast/slow for each clock configuration tested, then finish by
blinking idly.
As of this commit, this test fails quickly on most L1 boards tested.
An update to libopencm3 is required to fix this.
-rw-r--r-- | tests/rcc-legal-ranges/Makefile.stm32l1-generic | 1 | ||||
-rw-r--r-- | tests/rcc-legal-ranges/README.md | 5 | ||||
-rw-r--r-- | tests/rcc-legal-ranges/main-stm32l1-generic.c | 143 |
3 files changed, 119 insertions, 30 deletions
diff --git a/tests/rcc-legal-ranges/Makefile.stm32l1-generic b/tests/rcc-legal-ranges/Makefile.stm32l1-generic index bdb721e..b9ecc71 100644 --- a/tests/rcc-legal-ranges/Makefile.stm32l1-generic +++ b/tests/rcc-legal-ranges/Makefile.stm32l1-generic @@ -2,6 +2,7 @@ BOARD = stm32l1-generic PROJECT = rcc-legal-ranges-$(BOARD) BUILD_DIR = bin-$(BOARD) +OPT=-O0 SHARED_DIR = ../../shared diff --git a/tests/rcc-legal-ranges/README.md b/tests/rcc-legal-ranges/README.md index 2720e56..2313ebd 100644 --- a/tests/rcc-legal-ranges/README.md +++ b/tests/rcc-legal-ranges/README.md @@ -5,8 +5,9 @@ turning on and selecting different clocks, power ranges and flash wait state configuration are robust enough. ## PASSING -The board should issue a series of blinks at various rates before -settling on a steady rate +On boot you should get two slow blinks. +After boot, you should get continuous 5/2 fast/slow blinks as it +continuously shuffles and resets clock configurations. ## FAILING The board stops blinking at any point in the sequence diff --git a/tests/rcc-legal-ranges/main-stm32l1-generic.c b/tests/rcc-legal-ranges/main-stm32l1-generic.c index 4418827..8c97bad 100644 --- a/tests/rcc-legal-ranges/main-stm32l1-generic.c +++ b/tests/rcc-legal-ranges/main-stm32l1-generic.c @@ -2,6 +2,7 @@ * Aug 2016 Karl Palsson <karlp@tweak.net.au> */ +#include <stdlib.h> #include <libopencm3/stm32/flash.h> #include <libopencm3/stm32/gpio.h> #include <libopencm3/stm32/pwr.h> @@ -11,6 +12,85 @@ #define LEDPORT GPIOB #define LEDPIN GPIO6 +#ifndef ARRAY_LENGTH +#define ARRAY_LENGTH(array) (sizeof((array))/sizeof((array)[0])) +#endif + +/* + * A set of valid clock configurations with HSI as the source. + * thankfully, L1 allows apb1/apb2 to reach full ahb speed in all cases. + */ +struct rcc_clock_scale valid_hsi_clocks[] = { + { + /* 8Mhz, hsi/div2, max perf for range 2 with 0 ws */ + .hpre = RCC_CFGR_HPRE_SYSCLK_DIV2, + .ppre1 = RCC_CFGR_PPRE1_HCLK_NODIV, + .ppre2 = RCC_CFGR_PPRE2_HCLK_NODIV, + .voltage_scale = PWR_SCALE2, + .flash_config = FLASH_ACR_LATENCY_0WS, + .ahb_frequency = 8e6, + .apb1_frequency = 8e6, + .apb2_frequency = 8e6, + }, + { + /* Slowest hsi possible */ + .hpre = RCC_CFGR_HPRE_SYSCLK_DIV512, + .ppre1 = RCC_CFGR_PPRE1_HCLK_NODIV, + .ppre2 = RCC_CFGR_PPRE1_HCLK_NODIV, + .voltage_scale = PWR_SCALE3, + .flash_config = FLASH_ACR_LATENCY_0WS, + .ahb_frequency = 31250, + .apb1_frequency = 31250, + .apb2_frequency = 31250, + }, + { + /* Fastest HSI possible, range 1, 0ws */ + .hpre = RCC_CFGR_HPRE_SYSCLK_NODIV, + .ppre1 = RCC_CFGR_PPRE1_HCLK_NODIV, + .ppre2 = RCC_CFGR_PPRE1_HCLK_NODIV, + .voltage_scale = PWR_SCALE1, + .flash_config = FLASH_ACR_LATENCY_0WS, + .ahb_frequency = 16e6, + .apb1_frequency = 16e6, + .apb2_frequency = 16e6, + }, + { + /* highest perf for range 3 with 0 wait states */ + .hpre = RCC_CFGR_HPRE_SYSCLK_DIV8, + .ppre1 = RCC_CFGR_PPRE1_HCLK_NODIV, + .ppre2 = RCC_CFGR_PPRE1_HCLK_NODIV, + .voltage_scale = PWR_SCALE3, + .flash_config = FLASH_ACR_LATENCY_0WS, + .ahb_frequency = 2e6, + .apb1_frequency = 2e6, + .apb2_frequency = 2e6, + }, + { + /* Fastest HSI for range 2, 0ws */ + .hpre = RCC_CFGR_HPRE_SYSCLK_NODIV, + .ppre1 = RCC_CFGR_PPRE1_HCLK_NODIV, + .ppre2 = RCC_CFGR_PPRE1_HCLK_NODIV, + .voltage_scale = PWR_SCALE1, + .flash_config = FLASH_ACR_LATENCY_0WS, + .ahb_frequency = 16e6, + .apb1_frequency = 16e6, + .apb2_frequency = 16e6, + }, + { + /* highest perf for range 3 */ + .hpre = RCC_CFGR_HPRE_SYSCLK_DIV4, + .ppre1 = RCC_CFGR_PPRE1_HCLK_NODIV, + .ppre2 = RCC_CFGR_PPRE1_HCLK_NODIV, + .voltage_scale = PWR_SCALE3, + .flash_config = FLASH_ACR_LATENCY_1WS, + .ahb_frequency = 4e6, + .apb1_frequency = 4e6, + .apb2_frequency = 4e6, + }, +}; + +int shuffled[ARRAY_LENGTH(valid_hsi_clocks)]; + /** * blink led count times, with vile hack * 1000 asm nops */ @@ -24,43 +104,50 @@ static void hack_blink(int count, int hack) } } +/* Stack overflow, wiki, whathaveyou */ +/* FIXME oh yeah, did I mention that rand() is always zero? */ +static void shuffle_fisher_yates(int *array, size_t n) +{ + if (n > 1) { + size_t i; + for (i = 0; i < n - 1; i++) { + size_t j = i + rand() / (RAND_MAX / (n - i) + 1); + int t = array[j]; + array[j] = array[i]; + array[i] = t; + } + } +} + +static void run_clock_set(void) +{ + shuffle_fisher_yates(shuffled, ARRAY_LENGTH(shuffled)); + + struct rcc_clock_scale *clock; + for (size_t i = 0; i < ARRAY_LENGTH(shuffled); i++) { + clock = &valid_hsi_clocks[i]; + rcc_clock_setup_hsi(clock); + /** blink quickly/slowly as we run through these */ + hack_blink(10, clock->ahb_frequency / (500 * 1000)); + hack_blink(4, clock->ahb_frequency / (200 * 1000)); + } +} + int main(void) { - int i; - int j = 0; /* Allow leds on any port */ RCC_AHBENR |= 0xff; gpio_mode_setup(LEDPORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LEDPIN); /* blink twice with slow msi reset clock */ hack_blink(4, 60); + + /* ok, now, "randomly" sort the list of clocks to try them out */ + for (size_t i = 0; i < ARRAY_LENGTH(shuffled); i++) { + shuffled[i] = i; + } - /* step forward to HSI/2, 8Mhz */ - struct rcc_clock_scale v2_8low = { - .hpre = RCC_CFGR_HPRE_SYSCLK_DIV2, - .ppre1 = RCC_CFGR_PPRE1_HCLK_NODIV, - .ppre2 = RCC_CFGR_PPRE2_HCLK_NODIV, - .voltage_scale = PWR_SCALE2, - .flash_config = FLASH_ACR_LATENCY_0WS, - .ahb_frequency = 8000000, - .apb1_frequency = 8000000, - .apb2_frequency = 8000000, - }; - rcc_clock_setup_hsi(&v2_8low); - /* blink twice again, different rate */ - hack_blink(4, 60); - - /* step forward to HSI->PLL@32Mhz, range 1 */ - rcc_clock_setup_pll(&rcc_clock_config[RCC_CLOCK_VRANGE1_HSI_PLL_32MHZ]); - /* blink twice again */ - hack_blink(4, 400); - - /* back down again */ - rcc_clock_setup_hsi(&v2_8low); - hack_blink(4, 60); - - /* just keep blinking */ while (1) { - hack_blink(1, 400); + run_clock_set(); } return 0; |