From d7489ebfbd0798c804ed3d7073040cedaea38d26 Mon Sep 17 00:00:00 2001 From: Piotr Esden-Tempski Date: Thu, 4 Mar 2010 20:37:04 +0100 Subject: [PATCH] Added standard clock setup routines. Thanks to Thomas Otto for pointing out problems with the clock code in examples and his clock routine implementations. Based on that the most common clock combination routines were added to the library and all routines in examples setting up the clock replaced with calls to that functions. --- examples/mb525/fancyblink/fancyblink.c | 22 +---- examples/mb525/pwmleds/pwmleds.c | 19 +--- examples/stm32-h103/fancyblink/fancyblink.c | 21 +---- examples/stm32-h103/spi/spi.c | 18 +--- examples/stm32-h103/usart/usart.c | 28 ++---- include/libopenstm32/rcc.h | 2 + lib/rcc.c | 98 +++++++++++++++++++++ 7 files changed, 114 insertions(+), 94 deletions(-) diff --git a/examples/mb525/fancyblink/fancyblink.c b/examples/mb525/fancyblink/fancyblink.c index f3e7c9b9..c10715e5 100644 --- a/examples/mb525/fancyblink/fancyblink.c +++ b/examples/mb525/fancyblink/fancyblink.c @@ -21,33 +21,17 @@ #include #include -/* Set STM32 to 72 MHz. */ void clock_setup(void) { - /* Select HSI as SYSCLK source. */ - rcc_set_sysclk_source(SW_SYSCLKSEL_HSICLK); + rcc_clock_setup_in_hse_8mhz_out_72mhz(); - /* Set the PLL multiplication factor to 9. */ - rcc_set_pll_multiplication_factor(PLLMUL_PLL_CLK_MUL9); + /* Enable GPIOC clock. */ + rcc_peripheral_enable_clock(&RCC_APB2ENR, IOPCEN); - /* Select HSI/2 as PLL source. */ - rcc_set_pll_source(PLLSRC_HSI_CLK_DIV2); - - rcc_set_pllxtpre(PLLXTPRE_HSE_CLK_DIV2); - - /* Enable PLL oscillator and wait for it to stabilize. */ - rcc_osc_on(PLL); - rcc_wait_for_osc_ready(PLL); - - /* Select PLL as SYSCLK source. */ - rcc_set_sysclk_source(SW_SYSCLKSEL_PLLCLK); } void gpio_setup(void) { - /* Enable GPIOC clock. */ - rcc_peripheral_enable_clock(&RCC_APB2ENR, IOPCEN); - /* Set GPIO6 (in GPIO port C) to 'output push-pull'. */ gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO6 | GPIO7 | GPIO8 | GPIO9); diff --git a/examples/mb525/pwmleds/pwmleds.c b/examples/mb525/pwmleds/pwmleds.c index 2bff5a41..4502d11e 100644 --- a/examples/mb525/pwmleds/pwmleds.c +++ b/examples/mb525/pwmleds/pwmleds.c @@ -236,26 +236,9 @@ static const u16 gamma_table_3_0[] = { }; #endif -/* Set STM32 to 72 MHz. */ void clock_setup(void) { - /* Select HSI as SYSCLK source. */ - rcc_set_sysclk_source(SW_SYSCLKSEL_HSICLK); - - /* Set the PLL multiplication factor to 9. */ - rcc_set_pll_multiplication_factor(PLLMUL_PLL_CLK_MUL9); - - /* Select HSI/2 as PLL source. */ - rcc_set_pll_source(PLLSRC_HSI_CLK_DIV2); - - rcc_set_pllxtpre(PLLXTPRE_HSE_CLK_DIV2); - - /* Enable PLL oscillator and wait for it to stabilize. */ - rcc_osc_on(PLL); - rcc_wait_for_osc_ready(PLL); - - /* Select PLL as SYSCLK source. */ - rcc_set_sysclk_source(SW_SYSCLKSEL_PLLCLK); + rcc_clock_setup_in_hse_8mhz_out_72mhz(); /* Enable TIM3 clock. */ rcc_peripheral_enable_clock(&RCC_APB1ENR, TIM3EN); diff --git a/examples/stm32-h103/fancyblink/fancyblink.c b/examples/stm32-h103/fancyblink/fancyblink.c index 1118e4de..39652ec3 100644 --- a/examples/stm32-h103/fancyblink/fancyblink.c +++ b/examples/stm32-h103/fancyblink/fancyblink.c @@ -23,30 +23,15 @@ /* Set STM32 to 72 MHz. */ void clock_setup(void) { - /* Select HSI as SYSCLK source. */ - rcc_set_sysclk_source(SW_SYSCLKSEL_HSICLK); + rcc_clock_setup_in_hse_8mhz_out_72mhz(); - /* Set the PLL multiplication factor to 9. */ - rcc_set_pll_multiplication_factor(PLLMUL_PLL_CLK_MUL9); + /* Enable GPIOC clock. */ + rcc_peripheral_enable_clock(&RCC_APB2ENR, IOPCEN); - /* Select HSI/2 as PLL source. */ - rcc_set_pll_source(PLLSRC_HSI_CLK_DIV2); - - rcc_set_pllxtpre(PLLXTPRE_HSE_CLK_DIV2); - - /* Enable PLL oscillator and wait for it to stabilize. */ - rcc_osc_on(PLL); - rcc_wait_for_osc_ready(PLL); - - /* Select PLL as SYSCLK source. */ - rcc_set_sysclk_source(SW_SYSCLKSEL_PLLCLK); } void gpio_setup(void) { - /* Enable GPIOC clock. */ - rcc_peripheral_enable_clock(&RCC_APB2ENR, IOPCEN); - /* Set GPIO12 (in GPIO port C) to 'output push-pull'. */ gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO12); diff --git a/examples/stm32-h103/spi/spi.c b/examples/stm32-h103/spi/spi.c index bf313beb..57ac47e9 100644 --- a/examples/stm32-h103/spi/spi.c +++ b/examples/stm32-h103/spi/spi.c @@ -21,23 +21,7 @@ void clock_setup(void) { - /* Select HSI as SYSCLK source. */ - rcc_set_sysclk_source(SW_SYSCLKSEL_HSICLK); - - /* Set the PLL multiplication factor to 9. */ - rcc_set_pll_multiplication_factor(PLLMUL_PLL_CLK_MUL9); - - /* Select HSI/2 as PLL source. */ - rcc_set_pll_source(PLLSRC_HSI_CLK_DIV2); - - rcc_set_pllxtpre(PLLXTPRE_HSE_CLK_DIV2); - - /* Enable PLL oscillator and wait for it to stabilize. */ - rcc_osc_on(PLL); - rcc_wait_for_osc_ready(PLL); - - /* Select PLL as SYSCLK source. */ - rcc_set_sysclk_source(SW_SYSCLKSEL_PLLCLK); + rcc_clock_setup_in_hse_8mhz_out_72mhz(); } void spi_setup(void) diff --git a/examples/stm32-h103/usart/usart.c b/examples/stm32-h103/usart/usart.c index 7f1c343c..3776f84c 100644 --- a/examples/stm32-h103/usart/usart.c +++ b/examples/stm32-h103/usart/usart.c @@ -23,31 +23,18 @@ void clock_setup(void) { - /* Select HSI as SYSCLK source. */ - rcc_set_sysclk_source(SW_SYSCLKSEL_HSICLK); + rcc_clock_setup_in_hse_8mhz_out_72mhz(); - /* Set the PLL multiplication factor to 9. */ - rcc_set_pll_multiplication_factor(PLLMUL_PLL_CLK_MUL9); + /* Enable GPIOC clock. */ + rcc_peripheral_enable_clock(&RCC_APB2ENR, IOPCEN); - /* Select HSI/2 as PLL source. */ - rcc_set_pll_source(PLLSRC_HSI_CLK_DIV2); - - rcc_set_pllxtpre(PLLXTPRE_HSE_CLK_DIV2); - - /* Enable PLL oscillator and wait for it to stabilize. */ - rcc_osc_on(PLL); - rcc_wait_for_osc_ready(PLL); - - /* Select PLL as SYSCLK source. */ - rcc_set_sysclk_source(SW_SYSCLKSEL_PLLCLK); + /* Enable clocks for GPIO port B (for GPIO_USART3_TX) and USART3. */ + rcc_peripheral_enable_clock(&RCC_APB2ENR, IOPBEN); + rcc_peripheral_enable_clock(&RCC_APB1ENR, USART3EN); } void usart_setup(void) { - /* Enable clocks for GPIO port B (for GPIO_USART3_TX) and USART3. */ - rcc_peripheral_enable_clock(&RCC_APB2ENR, IOPBEN); - rcc_peripheral_enable_clock(&RCC_APB1ENR, USART3EN); - /* Setup GPIO pin GPIO_USART3_TX/GPIO10 on GPIO port B for transmit. */ gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_USART3_TX); @@ -66,9 +53,6 @@ void usart_setup(void) void gpio_setup(void) { - /* Enable GPIOC clock. */ - rcc_peripheral_enable_clock(&RCC_APB2ENR, IOPCEN); - /* Set GPIO12 (in GPIO port C) to 'output push-pull'. */ gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO12); diff --git a/include/libopenstm32/rcc.h b/include/libopenstm32/rcc.h index 2d9c2a00..5495edd2 100644 --- a/include/libopenstm32/rcc.h +++ b/include/libopenstm32/rcc.h @@ -398,5 +398,7 @@ void rcc_set_ppre2(u32 ppre2); void rcc_set_ppre1(u32 ppre1); void rcc_set_hpre(u32 hpre); u32 rcc_get_system_clock_source(int i); +void rcc_clock_setup_in_hsi_out_64mhz(void); +void rcc_clock_setup_in_hse_8mhz_out_72mhz(void); #endif diff --git a/lib/rcc.c b/lib/rcc.c index 23920846..92d68154 100644 --- a/lib/rcc.c +++ b/lib/rcc.c @@ -323,3 +323,101 @@ u32 rcc_system_clock_source(void) /* Return the clock source which is used as system clock. */ return ((RCC_CFGR & 0x000c) >> 2); } + + +/* + * These functions are setting up the whole clock system for the most common + * input clock and output clock configurations. + */ +void rcc_clock_setup_in_hsi_out_64mhz(void){ + + /* enable Internal High Speed Oscillator */ + rcc_osc_on(HSI); + rcc_wait_for_osc_ready(HSI); + + /* Select HSI as SYSCLK source. */ + rcc_set_sysclk_source(SW_SYSCLKSEL_HSICLK); + + /* + * set prescalers for AHB, ADC, ABP1, ABP2 + * make this before touching the PLL (why?) + */ + rcc_set_hpre(HPRE_SYSCLK_NODIV); /* Max 72MHz */ + rcc_set_adcpre(ADCPRE_PLCK2_DIV8); /* Max 14MHz */ + rcc_set_ppre1(PPRE1_HCLK_DIV2); /* Max 36MHz */ + rcc_set_ppre2(PPRE2_HCLK_NODIV); /* Max 72MHz */ + + /* sysclk is running with 64MHz -> 2 Waitstates + * 0WS from 0-24MHz + * 1WS from 24-48MHz + * 2WS from 48-72MHz + */ + flash_set_ws(FLASH_LATENCY_2WS); + + /* Set the PLL multiplication factor to 16. + * -> 8MHz (internal) * 16 (multiplier) / 2 (PLLSRC_HSI_CLK_DIV2) = 64MHz + */ + rcc_set_pll_multiplication_factor(PLLMUL_PLL_CLK_MUL16); + + /* Select HSI/2 as PLL source. */ + rcc_set_pll_source(PLLSRC_HSI_CLK_DIV2); + + + /* Enable PLL oscillator and wait for it to stabilize. */ + rcc_osc_on(PLL); + rcc_wait_for_osc_ready(PLL); + + /* Select PLL as SYSCLK source. */ + rcc_set_sysclk_source(SW_SYSCLKSEL_PLLCLK); +} + +void rcc_clock_setup_in_hse_8mhz_out_72mhz(void){ + + /* enable Internal High Speed Oscillator */ + rcc_osc_on(HSI); + rcc_wait_for_osc_ready(HSI); + + /* Select HSI as SYSCLK source. */ + rcc_set_sysclk_source(SW_SYSCLKSEL_HSICLK); + + /* enable External High Speed Oscillator 8MHz */ + rcc_osc_on(HSE); + rcc_wait_for_osc_ready(HSE); + rcc_set_sysclk_source(SW_SYSCLKSEL_HSECLK); + + /* set prescalers for AHB, ADC, ABP1, ABP2 + * do this before touching the PLL (why?) + */ + rcc_set_hpre(HPRE_SYSCLK_NODIV); // Max 72MHz + rcc_set_adcpre(ADCPRE_PLCK2_DIV8); // Max 14MHz + rcc_set_ppre1(PPRE1_HCLK_DIV2); // Max 36MHz + rcc_set_ppre2(PPRE2_HCLK_NODIV); // Max 72MHz + + /* sysclk runs with 72MHz -> 2 Waitstates + * 0WS from 0-24MHz + * 1WS from 24-48MHz + * 2WS from 48-72MHz + */ + flash_set_ws(FLASH_LATENCY_2WS); + + /* Set the PLL multiplication factor to 9. + * -> 8MHz (external) * 9 (multiplier) = 72MHz + */ + rcc_set_pll_multiplication_factor(PLLMUL_PLL_CLK_MUL10); + + /* Select HSE as PLL source. */ + rcc_set_pll_source(PLLSRC_HSE_CLK); + + /* external frequency undivided before entering pll + * (only valid/needed for HSE) + */ + rcc_set_pllxtpre(PLLXTPRE_HSE_CLK); + + /* Enable PLL oscillator and wait for it to stabilize. */ + rcc_osc_on(PLL); + rcc_wait_for_osc_ready(PLL); + + /* Select PLL as SYSCLK source. */ + rcc_set_sysclk_source(SW_SYSCLKSEL_PLLCLK); + +}