Browse Source

stm32/f1/rcc: add 25mhz in to 72mhz out clock tree setup function.

also: added support for previously undefined PLLs
pull/63/head
Jeff Ciesielski 12 years ago
parent
commit
069a758f6c
  1. 24
      include/libopencm3/stm32/f1/rcc.h
  2. 167
      lib/stm32/f1/rcc.c

24
include/libopencm3/stm32/f1/rcc.h

@ -86,7 +86,7 @@ LGPL License Terms @ref lgpl_license
#define RCC_CFGR_MCO_SYSCLK 0x4 #define RCC_CFGR_MCO_SYSCLK 0x4
#define RCC_CFGR_MCO_HSICLK 0x5 #define RCC_CFGR_MCO_HSICLK 0x5
#define RCC_CFGR_MCO_HSECLK 0x6 #define RCC_CFGR_MCO_HSECLK 0x6
#define RCC_CFGR_RMCO_PLLCLK_DIV2 0x7 #define RCC_CFGR_MCO_PLLCLK_DIV2 0x7
#define RCC_CFGR_MCO_PLL2CLK 0x8 /* (**) */ #define RCC_CFGR_MCO_PLL2CLK 0x8 /* (**) */
#define RCC_CFGR_MCO_PLL3CLK_DIV2 0x9 /* (**) */ #define RCC_CFGR_MCO_PLL3CLK_DIV2 0x9 /* (**) */
#define RCC_CFGR_MCO_XT1 0xa /* (**) */ #define RCC_CFGR_MCO_XT1 0xa /* (**) */
@ -448,6 +448,24 @@ LGPL License Terms @ref lgpl_license
#define RCC_CFGR2_PLL2MUL_PLL2_CLK_MUL16 0xe #define RCC_CFGR2_PLL2MUL_PLL2_CLK_MUL16 0xe
#define RCC_CFGR2_PLL2MUL_PLL2_CLK_MUL20 0xf #define RCC_CFGR2_PLL2MUL_PLL2_CLK_MUL20 0xf
/* PREDIV: PREDIV division factor */
#define RCC_CFGR2_PREDIV_NODIV 0x0
#define RCC_CFGR2_PREDIV_DIV2 0x1
#define RCC_CFGR2_PREDIV_DIV3 0x2
#define RCC_CFGR2_PREDIV_DIV4 0x3
#define RCC_CFGR2_PREDIV_DIV5 0x4
#define RCC_CFGR2_PREDIV_DIV6 0x5
#define RCC_CFGR2_PREDIV_DIV7 0x6
#define RCC_CFGR2_PREDIV_DIV8 0x7
#define RCC_CFGR2_PREDIV_DIV9 0x8
#define RCC_CFGR2_PREDIV_DIV10 0x9
#define RCC_CFGR2_PREDIV_DIV11 0xa
#define RCC_CFGR2_PREDIV_DIV12 0xb
#define RCC_CFGR2_PREDIV_DIV13 0xc
#define RCC_CFGR2_PREDIV_DIV14 0xd
#define RCC_CFGR2_PREDIV_DIV15 0xe
#define RCC_CFGR2_PREDIV_DIV16 0xf
/* PREDIV2: PREDIV2 division factor */ /* PREDIV2: PREDIV2 division factor */
#define RCC_CFGR2_PREDIV2_NODIV 0x0 #define RCC_CFGR2_PREDIV2_NODIV 0x0
#define RCC_CFGR2_PREDIV2_DIV2 0x1 #define RCC_CFGR2_PREDIV2_DIV2 0x1
@ -473,7 +491,7 @@ extern u32 rcc_ppre2_frequency;
/* --- Function prototypes ------------------------------------------------- */ /* --- Function prototypes ------------------------------------------------- */
typedef enum { typedef enum {
PLL, HSE, HSI, LSE, LSI PLL, PLL2, PLL3, HSE, HSI, LSE, LSI
} osc_t; } osc_t;
BEGIN_DECLS BEGIN_DECLS
@ -497,6 +515,7 @@ void rcc_peripheral_reset(volatile u32 *reg, u32 reset);
void rcc_peripheral_clear_reset(volatile u32 *reg, u32 clear_reset); void rcc_peripheral_clear_reset(volatile u32 *reg, u32 clear_reset);
void rcc_set_sysclk_source(u32 clk); void rcc_set_sysclk_source(u32 clk);
void rcc_set_pll_multiplication_factor(u32 mul); void rcc_set_pll_multiplication_factor(u32 mul);
void rcc_set_pll2_multiplication_factor(u32 mul);
void rcc_set_pll_source(u32 pllsrc); void rcc_set_pll_source(u32 pllsrc);
void rcc_set_pllxtpre(u32 pllxtpre); void rcc_set_pllxtpre(u32 pllxtpre);
void rcc_set_adcpre(u32 adcpre); void rcc_set_adcpre(u32 adcpre);
@ -512,6 +531,7 @@ void rcc_clock_setup_in_hse_8mhz_out_24mhz(void);
void rcc_clock_setup_in_hse_8mhz_out_72mhz(void); void rcc_clock_setup_in_hse_8mhz_out_72mhz(void);
void rcc_clock_setup_in_hse_12mhz_out_72mhz(void); void rcc_clock_setup_in_hse_12mhz_out_72mhz(void);
void rcc_clock_setup_in_hse_16mhz_out_72mhz(void); void rcc_clock_setup_in_hse_16mhz_out_72mhz(void);
void rcc_clock_setup_in_hse_25mhz_out_72mhz(void);
void rcc_backupdomain_reset(void); void rcc_backupdomain_reset(void);
END_DECLS END_DECLS

167
lib/stm32/f1/rcc.c

@ -71,6 +71,12 @@ void rcc_osc_ready_int_clear(osc_t osc)
case PLL: case PLL:
RCC_CIR |= RCC_CIR_PLLRDYC; RCC_CIR |= RCC_CIR_PLLRDYC;
break; break;
case PLL2:
RCC_CIR |= RCC_CIR_PLL2RDYC;
break;
case PLL3:
RCC_CIR |= RCC_CIR_PLL3RDYC;
break;
case HSE: case HSE:
RCC_CIR |= RCC_CIR_HSERDYC; RCC_CIR |= RCC_CIR_HSERDYC;
break; break;
@ -98,6 +104,12 @@ void rcc_osc_ready_int_enable(osc_t osc)
case PLL: case PLL:
RCC_CIR |= RCC_CIR_PLLRDYIE; RCC_CIR |= RCC_CIR_PLLRDYIE;
break; break;
case PLL2:
RCC_CIR |= RCC_CIR_PLL2RDYIE;
break;
case PLL3:
RCC_CIR |= RCC_CIR_PLL3RDYIE;
break;
case HSE: case HSE:
RCC_CIR |= RCC_CIR_HSERDYIE; RCC_CIR |= RCC_CIR_HSERDYIE;
break; break;
@ -125,6 +137,12 @@ void rcc_osc_ready_int_disable(osc_t osc)
case PLL: case PLL:
RCC_CIR &= ~RCC_CIR_PLLRDYIE; RCC_CIR &= ~RCC_CIR_PLLRDYIE;
break; break;
case PLL2:
RCC_CIR &= ~RCC_CIR_PLL2RDYIE;
break;
case PLL3:
RCC_CIR &= ~RCC_CIR_PLL3RDYIE;
break;
case HSE: case HSE:
RCC_CIR &= ~RCC_CIR_HSERDYIE; RCC_CIR &= ~RCC_CIR_HSERDYIE;
break; break;
@ -153,6 +171,12 @@ int rcc_osc_ready_int_flag(osc_t osc)
case PLL: case PLL:
return ((RCC_CIR & RCC_CIR_PLLRDYF) != 0); return ((RCC_CIR & RCC_CIR_PLLRDYF) != 0);
break; break;
case PLL2:
return ((RCC_CIR & RCC_CIR_PLL2RDYF) != 0);
break;
case PLL3:
return ((RCC_CIR & RCC_CIR_PLL3RDYF) != 0);
break;
case HSE: case HSE:
return ((RCC_CIR & RCC_CIR_HSERDYF) != 0); return ((RCC_CIR & RCC_CIR_HSERDYF) != 0);
break; break;
@ -203,6 +227,12 @@ void rcc_wait_for_osc_ready(osc_t osc)
case PLL: case PLL:
while ((RCC_CR & RCC_CR_PLLRDY) == 0); while ((RCC_CR & RCC_CR_PLLRDY) == 0);
break; break;
case PLL2:
while ((RCC_CR & RCC_CR_PLL2RDY) == 0);
break;
case PLL3:
while ((RCC_CR & RCC_CR_PLL3RDY) == 0);
break;
case HSE: case HSE:
while ((RCC_CR & RCC_CR_HSERDY) == 0); while ((RCC_CR & RCC_CR_HSERDY) == 0);
break; break;
@ -238,6 +268,12 @@ void rcc_osc_on(osc_t osc)
case PLL: case PLL:
RCC_CR |= RCC_CR_PLLON; RCC_CR |= RCC_CR_PLLON;
break; break;
case PLL2:
RCC_CR |= RCC_CR_PLL2ON;
break;
case PLL3:
RCC_CR |= RCC_CR_PLL3ON;
break;
case HSE: case HSE:
RCC_CR |= RCC_CR_HSEON; RCC_CR |= RCC_CR_HSEON;
break; break;
@ -273,6 +309,12 @@ void rcc_osc_off(osc_t osc)
case PLL: case PLL:
RCC_CR &= ~RCC_CR_PLLON; RCC_CR &= ~RCC_CR_PLLON;
break; break;
case PLL2:
RCC_CR &= ~RCC_CR_PLL2ON;
break;
case PLL3:
RCC_CR &= ~RCC_CR_PLL3ON;
break;
case HSE: case HSE:
RCC_CR &= ~RCC_CR_HSEON; RCC_CR &= ~RCC_CR_HSEON;
break; break;
@ -331,6 +373,8 @@ void rcc_osc_bypass_enable(osc_t osc)
RCC_BDCR |= RCC_BDCR_LSEBYP; RCC_BDCR |= RCC_BDCR_LSEBYP;
break; break;
case PLL: case PLL:
case PLL2:
case PLL3:
case HSI: case HSI:
case LSI: case LSI:
/* Do nothing, only HSE/LSE allowed here. */ /* Do nothing, only HSE/LSE allowed here. */
@ -361,6 +405,8 @@ void rcc_osc_bypass_disable(osc_t osc)
RCC_BDCR &= ~RCC_BDCR_LSEBYP; RCC_BDCR &= ~RCC_BDCR_LSEBYP;
break; break;
case PLL: case PLL:
case PLL2:
case PLL3:
case HSI: case HSI:
case LSI: case LSI:
/* Do nothing, only HSE/LSE allowed here. */ /* Do nothing, only HSE/LSE allowed here. */
@ -484,6 +530,40 @@ void rcc_set_pll_multiplication_factor(u32 mul)
RCC_CFGR = (reg32 | (mul << 18)); RCC_CFGR = (reg32 | (mul << 18));
} }
/*-----------------------------------------------------------------------------*/
/** @brief RCC Set the PLL2 Multiplication Factor.
@note This only has effect when the PLL is disabled.
@param[in] mul Unsigned int32. PLL multiplication factor @ref rcc_cfgr_pmf
*/
void rcc_set_pll2_multiplication_factor(u32 mul)
{
u32 reg32;
reg32 = RCC_CFGR2;
reg32 &= ~((1 << 11) | (1 << 10) | (1 << 9) | (1 << 8));
RCC_CFGR2 = (reg32 | (mul << 8));
}
/*-----------------------------------------------------------------------------*/
/** @brief RCC Set the PLL3 Multiplication Factor.
@note This only has effect when the PLL is disabled.
@param[in] mul Unsigned int32. PLL multiplication factor @ref rcc_cfgr_pmf
*/
void rcc_set_pll3_multiplication_factor(u32 mul)
{
u32 reg32;
reg32 = RCC_CFGR2;
reg32 &= ~((1 << 15) | (1 << 14) | (1 << 13) | (1 << 12));
RCC_CFGR2 = (reg32 | (mul << 12));
}
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/** @brief RCC Set the PLL Clock Source. /** @brief RCC Set the PLL Clock Source.
@ -602,6 +682,36 @@ void rcc_set_usbpre(u32 usbpre)
RCC_CFGR = (reg32 | (usbpre << 22)); RCC_CFGR = (reg32 | (usbpre << 22));
} }
void rcc_set_prediv1(u32 prediv)
{
u32 reg32;
reg32 = RCC_CFGR2;
reg32 &= ~(1 << 3) | (1 << 2) | (1 << 1) | (1 << 0);
RCC_CFGR2 |= (reg32 | prediv);
}
void rcc_set_prediv2(u32 prediv)
{
u32 reg32;
reg32 = RCC_CFGR2;
reg32 &= ~(1 << 7) | (1 << 6) | (1 << 5) | (1 << 4);
RCC_CFGR2 |= (reg32 | (prediv << 4));
}
void rcc_set_prediv1_source(u32 rccsrc)
{
RCC_CFGR2 &= ~(1 << 16);
RCC_CFGR2 |= (rccsrc << 16);
}
void rcc_set_mco(u32 mcosrc)
{
u32 reg32;
reg32 = RCC_CFGR;
reg32 &= ~((1 << 27) | (1 << 26) | (1 << 25) | (1 << 24));
RCC_CFGR |= (reg32 | (mcosrc << 24));
}
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/** @brief RCC Get the System Clock Source. /** @brief RCC Get the System Clock Source.
@ -1030,6 +1140,63 @@ void rcc_clock_setup_in_hse_16mhz_out_72mhz(void)
rcc_ppre2_frequency = 72000000; rcc_ppre2_frequency = 72000000;
} }
/*-----------------------------------------------------------------------------*/
/** @brief RCC Set System Clock PLL at 72MHz from HSE at 25MHz
*/
void rcc_clock_setup_in_hse_25mhz_out_72mhz(void)
{
/* Enable external high-speed oscillator 25MHz. */
rcc_osc_on(HSE);
rcc_wait_for_osc_ready(HSE);
rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_HSECLK);
/*
* 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 prescalers for AHB, ADC, ABP1, ABP2.
* Do this before touching the PLL (TODO: why?).
*/
rcc_set_hpre(RCC_CFGR_HPRE_SYSCLK_NODIV); /* Set. 72MHz Max. 72MHz */
rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV6); /* Set. 12MHz Max. 14MHz */
rcc_set_ppre1(RCC_CFGR_PPRE1_HCLK_DIV2); /* Set. 36MHz Max. 36MHz */
rcc_set_ppre2(RCC_CFGR_PPRE2_HCLK_NODIV); /* Set. 72MHz Max. 72MHz */
/* Set pll2 prediv and multiplier */
rcc_set_prediv2(RCC_CFGR2_PREDIV2_DIV5);
rcc_set_pll2_multiplication_factor(RCC_CFGR2_PLL2MUL_PLL2_CLK_MUL8);
/* Enable PLL2 oscillator and wait for it to stabilize */
rcc_osc_on(PLL2);
rcc_wait_for_osc_ready(PLL2);
/* Set pll1 prediv/multiplier, prediv1 src, and usb predivider */
rcc_set_pllxtpre(RCC_CFGR_PLLXTPRE_HSE_CLK);
rcc_set_prediv1_source(RCC_CFGR2_PREDIV1SRC_PLL2_CLK);
rcc_set_prediv1(RCC_CFGR2_PREDIV_DIV5);
rcc_set_pll_multiplication_factor(RCC_CFGR_PLLMUL_PLL_CLK_MUL9);
rcc_set_pll_source(RCC_CFGR_PLLSRC_PREDIV1_CLK);
rcc_set_usbpre(RCC_CFGR_USBPRE_PLL_VCO_CLK_DIV3);
/* enable PLL1 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(RCC_CFGR_SW_SYSCLKSEL_PLLCLK);
/* Set the peripheral clock frequencies used */
rcc_ppre1_frequency = 36000000;
rcc_ppre2_frequency = 72000000;
}
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/** @brief RCC Reset the backup domain /** @brief RCC Reset the backup domain

Loading…
Cancel
Save