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.
This commit is contained in:
parent
3d72709fda
commit
cb945fa671
3 changed files with 119 additions and 30 deletions
|
|
@ -2,6 +2,7 @@
|
|||
BOARD = stm32l1-generic
|
||||
PROJECT = rcc-legal-ranges-$(BOARD)
|
||||
BUILD_DIR = bin-$(BOARD)
|
||||
OPT=-O0
|
||||
|
||||
SHARED_DIR = ../../shared
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue