summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarl Palsson <karlp@etactica.com>2016-08-18 18:35:00 +0000
committerKarl Palsson <karlp@etactica.com>2016-08-19 11:31:57 +0000
commitcb945fa6711e1fbe224e8a9d745c740f71dce279 (patch)
treef6dd14ff2ae6b05c49c79e0c4616c289ae899d29
parent3d72709fdadb5a6521e534c21f2b74e35325a66e (diff)
downloadolsndot-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-generic1
-rw-r--r--tests/rcc-legal-ranges/README.md5
-rw-r--r--tests/rcc-legal-ranges/main-stm32l1-generic.c143
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;