summaryrefslogtreecommitdiff
path: root/tests/rcc-legal-ranges/main-stm32l1-generic.c
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 /tests/rcc-legal-ranges/main-stm32l1-generic.c
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.
Diffstat (limited to 'tests/rcc-legal-ranges/main-stm32l1-generic.c')
-rw-r--r--tests/rcc-legal-ranges/main-stm32l1-generic.c143
1 files changed, 115 insertions, 28 deletions
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;