diff options
| author | Keith Packard <keithp@keithp.com> | 2012-04-09 22:17:33 -0700 | 
|---|---|---|
| committer | Keith Packard <keithp@keithp.com> | 2012-04-09 22:17:33 -0700 | 
| commit | 51aef5d4fc29986353ad887f4a67ed2fe35f8c8e (patch) | |
| tree | 537602d5a0ed6fdae7e4ce8830f3c24a4a87aca5 | |
| parent | 1dcfbb05531767e67df45c2799a2fe533834fb71 (diff) | |
altos: Make STM clock configuration per-product. Fix 32MHz CPU speed
This moves all of the STM clock configuration into ao_pins.h so that
each product can configure it separately. While doing this, I
discovered that the flash memory mode (64-bit, prefetch, latency 1)
wasn't actually getting set, which is why the CPU refused to work at
32MHz.
Signed-off-by: Keith Packard <keithp@keithp.com>
| -rw-r--r-- | src/megametrum-v0.1/ao_pins.h | 23 | ||||
| -rw-r--r-- | src/stm-demo/ao_pins.h | 17 | ||||
| -rw-r--r-- | src/stm/ao_arch.h | 25 | ||||
| -rw-r--r-- | src/stm/ao_beep_stm.c | 2 | ||||
| -rw-r--r-- | src/stm/ao_serial_stm.c | 8 | ||||
| -rw-r--r-- | src/stm/ao_timer.c | 73 | ||||
| -rw-r--r-- | src/stm/stm32l.h | 3 | 
7 files changed, 113 insertions, 38 deletions
| diff --git a/src/megametrum-v0.1/ao_pins.h b/src/megametrum-v0.1/ao_pins.h index 803678b2..f5789cf9 100644 --- a/src/megametrum-v0.1/ao_pins.h +++ b/src/megametrum-v0.1/ao_pins.h @@ -18,6 +18,29 @@  #ifndef _AO_PINS_H_  #define _AO_PINS_H_ +/* 8MHz High speed external crystal */ +#define AO_HSE			8000000 + +/* PLLVCO = 96MHz (so that USB will work*/ +#define AO_PLLMUL		12 +#define AO_RCC_CFGR_PLLMUL	(STM_RCC_CFGR_PLLMUL_12) + +/* SYSCLK = 32MHz (no need to go faster than CPU) */ +#define AO_PLLDIV		3 +#define AO_RCC_CFGR_PLLDIV	(STM_RCC_CFGR_PLLDIV_3) + +/* HCLK = 32MHz (CPU clock) */ +#define AO_AHB_PRESCALER	1 +#define AO_RCC_CFGR_HPRE_DIV	STM_RCC_CFGR_HPRE_DIV_1 + +/* Run APB1 at 16MHz (HCLK/2) */ +#define AO_APB1_PRESCALER	2 +#define AO_RCC_CFGR_PPRE1_DIV	STM_RCC_CFGR_PPRE2_DIV_2 + +/* Run APB2 at 16MHz (HCLK/2) */ +#define AO_APB2_PRESCALER	2 +#define AO_RCC_CFGR_PPRE2_DIV	STM_RCC_CFGR_PPRE2_DIV_2 +  #define HAS_SERIAL_1		1  #define USE_SERIAL_1_STDIN	1  #define SERIAL_1_PB6_PB7	0 diff --git a/src/stm-demo/ao_pins.h b/src/stm-demo/ao_pins.h index 9fd1175d..3192c2b7 100644 --- a/src/stm-demo/ao_pins.h +++ b/src/stm-demo/ao_pins.h @@ -18,6 +18,23 @@  #ifndef _AO_PINS_H_  #define _AO_PINS_H_ +/* No external crystal */ +#define AO_HSE		0 + +#define AO_AHB_PRESCALER	1 +#define AO_RCC_CFGR_HPRE_DIV	STM_RCC_CFGR_HPRE_DIV_1 + +#define AO_APB1_PRESCALER	2 +#define AO_RCC_CFGR_PPRE1_DIV	STM_RCC_CFGR_PPRE2_DIV_2 + +#define AO_APB2_PRESCALER	2 +#define AO_RCC_CFGR_PPRE2_DIV	STM_RCC_CFGR_PPRE2_DIV_2 + +#define AO_PLLMUL		6 +#define AO_PLLDIV		4 +#define AO_RCC_CFGR_PLLMUL	(STM_RCC_CFGR_PLLMUL_6) +#define AO_RCC_CFGR_PLLDIV	(STM_RCC_CFGR_PLLDIV_4) +  #define HAS_SERIAL_1		1  #define USE_SERIAL_1_STDIN	1  #define SERIAL_1_PB6_PB7	1 diff --git a/src/stm/ao_arch.h b/src/stm/ao_arch.h index ce3a22e2..dd9579f1 100644 --- a/src/stm/ao_arch.h +++ b/src/stm/ao_arch.h @@ -148,7 +148,30 @@ extern const uint16_t ao_serial_number;  /*   * For now, we're running at a weird frequency   */ -#define STM_APB1	(16000000 * 6 / 4) + +#if AO_HSE +#define AO_PLLSRC	AO_HSE +#else +#define AO_PLLSRC	STM_HSI_FREQ +#endif + +#define AO_PLLVCO	(AO_PLLSRC * AO_PLLMUL) +#define AO_SYSCLK	(AO_PLLVCO / AO_PLLDIV) +#define AO_HCLK		(AO_SYSCLK / AO_AHB_PRESCALER) +#define AO_PCLK1	(AO_HCLK / AO_APB1_PRESCALER) +#define AO_PCLK2	(AO_HCLK / AO_APB2_PRESCALER) + +#if AO_APB1_PRESCALER == 1 +#define AO_TIM23467_CLK		AO_PCLK1 +#else +#define AO_TIM23467_CLK		(2 * AO_PCLK1) +#endif + +#if AO_APB2_PRESCALER == 1 +#define AO_TIM91011_CLK		AO_PCLK2 +#else +#define AO_TIM91011_CLK		(2 * AO_PCLK2) +#endif  void ao_lcd_stm_init(void); diff --git a/src/stm/ao_beep_stm.c b/src/stm/ao_beep_stm.c index 8c0c0ee3..37c30e25 100644 --- a/src/stm/ao_beep_stm.c +++ b/src/stm/ao_beep_stm.c @@ -41,7 +41,7 @@ ao_beep(uint8_t beep)  		/* Set prescaler to match cc1111 clocks  		 */ -		stm_tim3.psc = STM_APB1 / 750000; +		stm_tim3.psc = AO_TIM23467_CLK / 750000;  		/* 1. Select the counter clock (internal, external, prescaler).  		 * diff --git a/src/stm/ao_serial_stm.c b/src/stm/ao_serial_stm.c index f8db6883..3cebc094 100644 --- a/src/stm/ao_serial_stm.c +++ b/src/stm/ao_serial_stm.c @@ -116,16 +116,16 @@ static const struct {  	uint32_t brr;  } ao_usart_speeds[] = {  	[AO_SERIAL_SPEED_4800] = { -		STM_APB1 / 4800 +		AO_PCLK1 / 4800  	},  	[AO_SERIAL_SPEED_9600] = { -		STM_APB1 / 9600 +		AO_PCLK1 / 9600  	},  	[AO_SERIAL_SPEED_19200] = { -		STM_APB1 / 19200 +		AO_PCLK1 / 19200  	},  	[AO_SERIAL_SPEED_57600] = { -		STM_APB1 / 57600 +		AO_PCLK1 / 57600  	},  }; diff --git a/src/stm/ao_timer.c b/src/stm/ao_timer.c index 387df184..e7f1ddfe 100644 --- a/src/stm/ao_timer.c +++ b/src/stm/ao_timer.c @@ -69,7 +69,7 @@ ao_timer_set_adc_interval(uint8_t interval) __critical  }  #endif -#define TIMER_10kHz	(STM_APB1 / 10000) +#define TIMER_10kHz	(AO_PCLK1 / 10000)  void  ao_timer_init(void) @@ -107,44 +107,41 @@ ao_clock_init(void)  	uint32_t	cr;  	/* Set flash latency to tolerate 32MHz SYSCLK  -> 1 wait state */ -	uint32_t	acr = stm_flash.acr;  	/* Enable 64-bit access and prefetch */ -	acr |= (1 << STM_FLASH_ACR_ACC64) | (1 << STM_FLASH_ACR_PRFEN); -	stm_flash.acr = acr; +	stm_flash.acr |= (1 << STM_FLASH_ACR_ACC64); +	stm_flash.acr |= (1 << STM_FLASH_ACR_PRFEN);  	/* Enable 1 wait state so the CPU can run at 32MHz */  	/* (haven't managed to run the CPU at 32MHz yet, it's at 16MHz) */ -	acr |= (1 << STM_FLASH_ACR_LATENCY); -	stm_flash.acr = acr; +	stm_flash.acr |= (1 << STM_FLASH_ACR_LATENCY); +  	/* HCLK to 16MHz -> AHB prescaler = /1 */  	cfgr = stm_rcc.cfgr;  	cfgr &= ~(STM_RCC_CFGR_HPRE_MASK << STM_RCC_CFGR_HPRE); -	cfgr |= (STM_RCC_CFGR_HPRE_DIV_1 << STM_RCC_CFGR_HPRE); +	cfgr |= (AO_RCC_CFGR_HPRE_DIV << STM_RCC_CFGR_HPRE);  	stm_rcc.cfgr = cfgr;  	while ((stm_rcc.cfgr & (STM_RCC_CFGR_HPRE_MASK << STM_RCC_CFGR_HPRE)) != -	       (STM_RCC_CFGR_HPRE_DIV_1 << STM_RCC_CFGR_HPRE)) +	       (AO_RCC_CFGR_HPRE_DIV << STM_RCC_CFGR_HPRE))  		asm ("nop"); -#define STM_AHB_PRESCALER	1 -	/* PCLK1 to 16MHz -> APB1 Prescaler = 1 */ +	/* APB1 Prescaler = AO_APB1_PRESCALER */  	cfgr = stm_rcc.cfgr;  	cfgr &= ~(STM_RCC_CFGR_PPRE1_MASK << STM_RCC_CFGR_PPRE1); -	cfgr |= (STM_RCC_CFGR_PPRE1_DIV_1 << STM_RCC_CFGR_PPRE1); +	cfgr |= (AO_RCC_CFGR_PPRE1_DIV << STM_RCC_CFGR_PPRE1);  	stm_rcc.cfgr = cfgr; -#define STM_APB1_PRESCALER	1 -	/* PCLK2 to 16MHz -> APB2 Prescaler = 1 */ +	/* APB2 Prescaler = AO_APB2_PRESCALER */  	cfgr = stm_rcc.cfgr;  	cfgr &= ~(STM_RCC_CFGR_PPRE2_MASK << STM_RCC_CFGR_PPRE2); -	cfgr |= (STM_RCC_CFGR_PPRE2_DIV_1 << STM_RCC_CFGR_PPRE2); +	cfgr |= (AO_RCC_CFGR_PPRE2_DIV << STM_RCC_CFGR_PPRE2);  	stm_rcc.cfgr = cfgr; -#define STM_APB2_PRESCALER	1  	/* Enable power interface clock */  	stm_rcc.apb1enr |= (1 << STM_RCC_APB1ENR_PWREN); +  	/* Set voltage range to 1.8V */  	/* poll VOSF bit in PWR_CSR. Wait until it is reset to 0 */ @@ -161,23 +158,42 @@ ao_clock_init(void)  	while ((stm_pwr.csr & (1 << STM_PWR_CSR_VOSF)) != 0)  		asm("nop"); +#if AO_HSE +	/* Enable HSE clock */ +	if (!(stm_rcc.cr & (1 << STM_RCC_CR_HSERDY))) { +		stm_rcc.cr |= (1 << STM_RCC_CR_HSEON); +		while (!(stm_rcc.cr & (1 << STM_RCC_CR_HSERDY))) +			asm("nop"); +	} +#define STM_RCC_CFGR_SWS_TARGET_CLOCK		(STM_RCC_CFGR_SWS_HSE << STM_RCC_CFGR_SWS) +#define STM_RCC_CFGR_SW_TARGET_CLOCK		(STM_RCC_CFGR_SW_HSE) +#define STM_PLLSRC				AO_HSE +#define STM_RCC_CFGR_PLLSRC_TARGET_CLOCK	(1 << STM_RCC_CFGR_PLLSRC) +#else +#define STM_HSI 				16000000 +#define STM_RCC_CFGR_SWS_TARGET_CLOCK		(STM_RCC_CFGR_SWS_HSI << STM_RCC_CFGR_SWS) +#define STM_RCC_CFGR_SW_TARGET_CLOCK		(STM_RCC_CFGR_SW_HSI) +#define STM_PLLSRC				STM_HSI +#define STM_RCC_CFGR_PLLSRC_TARGET_CLOCK	(0 << STM_RCC_CFGR_PLLSRC) +#endif + +#if !AO_HSE || HAS_ADC  	/* Enable HSI RC clock 16MHz */  	if (!(stm_rcc.cr & (1 << STM_RCC_CR_HSIRDY))) {  		stm_rcc.cr |= (1 << STM_RCC_CR_HSION);  		while (!(stm_rcc.cr & (1 << STM_RCC_CR_HSIRDY)))  			asm("nop");  	} -#define STM_HSI 16000000 - -	/* Switch to direct HSI for SYSCLK */ +#endif +	/* Switch to direct high speed clock for SYSCLK */  	if ((stm_rcc.cfgr & (STM_RCC_CFGR_SWS_MASK << STM_RCC_CFGR_SWS)) != -	    (STM_RCC_CFGR_SWS_HSI << STM_RCC_CFGR_SWS)) { +	    STM_RCC_CFGR_SWS_TARGET_CLOCK) {  		cfgr = stm_rcc.cfgr;  		cfgr &= ~(STM_RCC_CFGR_SW_MASK << STM_RCC_CFGR_SW); -		cfgr |= (STM_RCC_CFGR_SW_HSI << STM_RCC_CFGR_SW); +		cfgr |= STM_RCC_CFGR_SW_TARGET_CLOCK;  		stm_rcc.cfgr = cfgr;  		while ((stm_rcc.cfgr & (STM_RCC_CFGR_SWS_MASK << STM_RCC_CFGR_SWS)) != -		       (STM_RCC_CFGR_SWS_HSI << STM_RCC_CFGR_SWS)) +		       STM_RCC_CFGR_SWS_TARGET_CLOCK);  			asm("nop");  	} @@ -191,19 +207,12 @@ ao_clock_init(void)  	cfgr &= ~(STM_RCC_CFGR_PLLMUL_MASK << STM_RCC_CFGR_PLLMUL);  	cfgr &= ~(STM_RCC_CFGR_PLLDIV_MASK << STM_RCC_CFGR_PLLDIV); -//	cfgr |= (STM_RCC_CFGR_PLLMUL_6 << STM_RCC_CFGR_PLLMUL); -//	cfgr |= (STM_RCC_CFGR_PLLDIV_3 << STM_RCC_CFGR_PLLDIV); - -	cfgr |= (STM_RCC_CFGR_PLLMUL_6 << STM_RCC_CFGR_PLLMUL); -	cfgr |= (STM_RCC_CFGR_PLLDIV_4 << STM_RCC_CFGR_PLLDIV); +	cfgr |= (AO_RCC_CFGR_PLLMUL << STM_RCC_CFGR_PLLMUL); +	cfgr |= (AO_RCC_CFGR_PLLDIV << STM_RCC_CFGR_PLLDIV); -#define STM_PLLMUL	6 -#define STM_PLLDIV	4 - -	/* PLL source to HSI */ +	/* PLL source */  	cfgr &= ~(1 << STM_RCC_CFGR_PLLSRC); - -#define STM_PLLSRC	STM_HSI +	cfgr |= STM_RCC_CFGR_PLLSRC_TARGET_CLOCK;  	stm_rcc.cfgr = cfgr; diff --git a/src/stm/stm32l.h b/src/stm/stm32l.h index 39dd710d..b922b6bc 100644 --- a/src/stm/stm32l.h +++ b/src/stm/stm32l.h @@ -303,6 +303,9 @@ struct stm_rcc {  extern struct stm_rcc stm_rcc; +/* Nominal high speed internal oscillator frequency is 16MHz */ +#define STM_HSI_FREQ		16000000 +  #define STM_RCC_CR_RTCPRE	(29)  #define  STM_RCC_CR_RTCPRE_HSE_DIV_2	0  #define  STM_RCC_CR_RTCPRE_HSE_DIV_4	1 | 
