Fix STM32L-Discovery clock setup - The X3 crystal is not fitted on the board

This commit is contained in:
Gregory Nutt 2013-05-20 12:17:34 -06:00
parent 5ad97e995c
commit 4b3c3b4cef
7 changed files with 75 additions and 35 deletions

View File

@ -90,6 +90,12 @@
/* Bits 19-23: Reserved */ /* Bits 19-23: Reserved */
#define RCC_CR_PLLON (1 << 24) /* Bit 24: PLL enable */ #define RCC_CR_PLLON (1 << 24) /* Bit 24: PLL enable */
#define RCC_CR_PLLRDY (1 << 25) /* Bit 25: PLL clock ready flag */ #define RCC_CR_PLLRDY (1 << 25) /* Bit 25: PLL clock ready flag */
/* Bits 26-27: Reserved */
#define RCC_CR_CSSON (1 << 28) /* Bit 16: Clock security system enable */
#define RCC_CR_RTCPRE_SHIFT (29) /* Bits 29-30: RTC/LCD prescaler */
#define RCC_CR_RTCPRE_MASK (3 << RCC_CR_RTCPRE_SHIFT)
/* Bit 31: Reserved */
#define RCC_CR_RSTVAL 0x00000300
/* Internal clock sources calibration register */ /* Internal clock sources calibration register */

View File

@ -67,6 +67,7 @@
static inline void rcc_reset(void) static inline void rcc_reset(void)
{ {
#if 0 /* None of this is necessary if only called from power up */
uint32_t regval; uint32_t regval;
/* Make sure that all devices are out of reset */ /* Make sure that all devices are out of reset */
@ -82,9 +83,14 @@ static inline void rcc_reset(void)
putreg32(0, STM32_RCC_APB1ENR); /* Disable APB1 Peripheral Clock */ putreg32(0, STM32_RCC_APB1ENR); /* Disable APB1 Peripheral Clock */
/* Set the Internal clock sources calibration register to its reset value. /* Set the Internal clock sources calibration register to its reset value.
* MSI to the default frequency (nomially 2.097MHz), MSITRIM=0, HSITRIM=0x10 */ * MSI to the default frequency (nominally 2.097MHz), MSITRIM=0, HSITRIM=0x10.
* Preserve the factory HSICAL and MSICAL settings.
*/
putreg32(RCC_ICSR_RSTVAL, STM32_RCC_ICSCR); regval = getreg32(STM32_RCC_ICSCR);
regval &= (RCC_ICSCR_HSICAL_MASK | RCC_ICSCR_MSICAL_MASK);
regval |= (RCC_ICSR_RSTVAL & ~(RCC_ICSCR_HSICAL_MASK | RCC_ICSCR_MSICAL_MASK));
putreg32(regval, STM32_RCC_ICSCR);
/* Enable the internal MSI */ /* Enable the internal MSI */
@ -106,12 +112,12 @@ static inline void rcc_reset(void)
while ((getreg32(STM32_RCC_CFGR) & RCC_CFGR_SWS_MASK) != RCC_CFGR_SWS_MSI); while ((getreg32(STM32_RCC_CFGR) & RCC_CFGR_SWS_MASK) != RCC_CFGR_SWS_MSI);
/* Now we can disable the alternative clock sources: HSE, HSI, and PLL. Also, /* Now we can disable the alternative clock sources: HSE, HSI, PLL, CSS and RTCPRE. Also,
* reset the HSE bypass. * reset the HSE bypass. This restores the RCC CR to its reset state.
*/ */
regval = getreg32(STM32_RCC_CR); /* Disable the HSE and the PLL */ regval = getreg32(STM32_RCC_CR); /* Disable the HSE and the PLL */
regval &= ~(RCC_CR_HSION | RCC_CR_HSEON | RCC_CR_PLLON); regval &= ~(RCC_CR_HSION | RCC_CR_HSEON | RCC_CR_PLLON | RCC_CR_CSSON | RCC_CR_RTCPRE_MASK);
putreg32(regval, STM32_RCC_CR); putreg32(regval, STM32_RCC_CR);
regval = getreg32(STM32_RCC_CR); /* Reset HSEBYP bit */ regval = getreg32(STM32_RCC_CR); /* Reset HSEBYP bit */
@ -146,6 +152,7 @@ static inline void rcc_reset(void)
putreg32(regval, STM32_FLASH_ACR); putreg32(regval, STM32_FLASH_ACR);
/* Check that 32-bit access is taken into account by reading FLASH_ACR */ /* Check that 32-bit access is taken into account by reading FLASH_ACR */
#endif
} }
/**************************************************************************** /****************************************************************************
@ -483,19 +490,40 @@ static void stm32_stdclockconfig(void)
{ {
uint32_t regval; uint32_t regval;
/* If the PLL is using the HSE, or the HSE is the system clock */ /* First, enable the source clock only the PLL (via HSE or HSI), HSE, and HSI
* are supported in this implementation.
*/
#if (STM32_CFGR_PLLSRC == RCC_CFGR_PLLSRC) || (STM32_SYSCLK_SW == RCC_CFGR_SW_HSE) #if (STM32_CFGR_PLLSRC == RCC_CFGR_PLLSRC) || (STM32_SYSCLK_SW == RCC_CFGR_SW_HSE)
/* Enable HSE clocking */ /* The PLL is using the HSE, or the HSE is the system clock. In either
* case, we need to enable HSE clocking.
*/
if (!stm32_rcc_enablehse()) if (!stm32_rcc_enablehse())
{ {
/* In the case of a timeout starting the HSE, we really don't have a /* In the case of a timeout starting the HSE, we really don't have a
* strategy. This is almost always a hardware failure or misconfiguration. * strategy. This is almost always a hardware failure or
* misconfiguration (for example, if no crystal is fitted on the board.
*/ */
return; return;
} }
#elif (STM32_CFGR_PLLSRC == 0) || (STM32_SYSCLK_SW == RCC_CFGR_SW_HSI)
/* The PLL is using the HSI, or the HSI is the system clock. In either
* case, we need to enable HSI clocking.
*/
regval = getreg32(STM32_RCC_CR); /* Enable the HSI */
regval |= RCC_CR_HSION;
putreg32(regval, STM32_RCC_CR);
/* Wait until the HSI clock is ready. Since this is an internal clock, no
* timeout is expected
*/
while ((getreg32(STM32_RCC_CR) & RCC_CR_HSIRDY) == 0);
#endif #endif
/* Increasing the CPU frequency (in the same voltage range): /* Increasing the CPU frequency (in the same voltage range):

View File

@ -444,6 +444,11 @@ GND and (external) 5V are available on both P1 and P2. Note: These signals
may be at lower voltage levels and, hence, may not properly drive an external may be at lower voltage levels and, hence, may not properly drive an external
RS-232 transceiver. RS-232 transceiver.
NOTE: The crystal X3 is not installed on the STM32L3-Discovery. As a
result, the HSE clock is not availabled and the less acurate HSI must be
used. This may limit the accuracy of the computed baud, especially at
higher BAUD.
A USB serial console is another option. A USB serial console is another option.
Debugging Debugging
@ -707,6 +712,8 @@ Where <subdir> is one of the following:
USB converter. The UART1 TX and RX pins should be available on USB converter. The UART1 TX and RX pins should be available on
PA9 and PA10, respectively. PA9 and PA10, respectively.
The serial console is configured for 57600 8N1
3. Support for NSH built-in applications is *not* enabled. 3. Support for NSH built-in applications is *not* enabled.
4. By default, this configuration uses the CodeSourcery toolchain 4. By default, this configuration uses the CodeSourcery toolchain

View File

@ -60,7 +60,8 @@
* - HSI high-speed internal oscillator clock * - HSI high-speed internal oscillator clock
* Generated from an internal 16 MHz RC oscillator * Generated from an internal 16 MHz RC oscillator
* - HSE high-speed external oscillator clock * - HSE high-speed external oscillator clock
* Driven by the 8MHz crystal (X1) on the OSC_IN and OSC_OUT pins * Normally driven by an external crystal (X3). However, this crystal is not fitted
* on the STM32L-Discovery board.
* - PLL clock * - PLL clock
* - MSI multispeed internal oscillator clock * - MSI multispeed internal oscillator clock
* The MSI clock signal is generated from an internal RC oscillator. Seven frequency * The MSI clock signal is generated from an internal RC oscillator. Seven frequency
@ -74,7 +75,7 @@
* Driven by 32.768KHz crystal (X2) on the OSC32_IN and OSC32_OUT pins. * Driven by 32.768KHz crystal (X2) on the OSC32_IN and OSC32_OUT pins.
*/ */
#define STM32_BOARD_XTAL 8000000ul /* X1 on board */ #define STM32_BOARD_XTAL 8000000ul /* X3 on board (not fitted)*/
#define STM32_HSI_FREQUENCY 16000000ul /* Approximately 16MHz */ #define STM32_HSI_FREQUENCY 16000000ul /* Approximately 16MHz */
#define STM32_HSE_FREQUENCY STM32_BOARD_XTAL #define STM32_HSE_FREQUENCY STM32_BOARD_XTAL
@ -84,11 +85,11 @@
/* PLL Configuration /* PLL Configuration
* *
* - PLL source is HSE/1 -> 8MHz input * - PLL source is HSI -> 16MHz input (nominal)
* - PLL multipler is 8 -> 64MHz PLL VCO clock output * - PLL multipler is 4 -> 64MHz PLL VCO clock output
* - PLL output divider 2 -> 32MHz divided down PLL VCO clock output * - PLL output divider 2 -> 32MHz divided down PLL VCO clock output
* *
* Resulting SYSCLK frequency is 8MHz (XTAL) x 8 / 2 = 32MHz * Resulting SYSCLK frequency is 16MHz x 4 / 2 = 32MHz
* *
* USB/SDIO: * USB/SDIO:
* If the USB or SDIO interface is used in the application, the PLL VCO * If the USB or SDIO interface is used in the application, the PLL VCO
@ -105,10 +106,10 @@
* The minimum input clock frequency for PLL is 2 MHz (when using HSE as PLL source). * The minimum input clock frequency for PLL is 2 MHz (when using HSE as PLL source).
*/ */
#define STM32_CFGR_PLLSRC RCC_CFGR_PLLSRC /* Source is 8MHz HSE */ #define STM32_CFGR_PLLSRC 0 /* Source is 16MHz HSI */
#define STM32_CFGR_PLLMUL RCC_CFGR_PLLMUL_CLKx8 /* PLLMUL = 8 */ #define STM32_CFGR_PLLMUL RCC_CFGR_PLLMUL_CLKx4 /* PLLMUL = 4 */
#define STM32_CFGR_PLLDIV RCC_CFGR_PLLDIV_2 /* PLLDIV = 2 */ #define STM32_CFGR_PLLDIV RCC_CFGR_PLLDIV_2 /* PLLDIV = 2 */
#define STM32_PLL_FREQUENCY (8*STM32_BOARD_XTAL) /* PLL VCO Frequency is 64MHz */ #define STM32_PLL_FREQUENCY (4*STM32_HSE_FREQUENCY) /* PLL VCO Frequency is 64MHz */
/* Use the PLL and set the SYSCLK source to be the diveded down PLL VCO output /* Use the PLL and set the SYSCLK source to be the diveded down PLL VCO output
* frequency (STM32_PLL_FREQUENCY divided by the PLLDIV value). * frequency (STM32_PLL_FREQUENCY divided by the PLLDIV value).
@ -292,7 +293,7 @@ extern "C" {
* *
************************************************************************************/ ************************************************************************************/
EXTERN void stm32_boardinitialize(void); void stm32_boardinitialize(void);
/************************************************************************************ /************************************************************************************
* Name: stm32_ledinit, stm32_setled, and stm32_setleds * Name: stm32_ledinit, stm32_setled, and stm32_setleds
@ -305,9 +306,9 @@ EXTERN void stm32_boardinitialize(void);
************************************************************************************/ ************************************************************************************/
#ifndef CONFIG_ARCH_LEDS #ifndef CONFIG_ARCH_LEDS
EXTERN void stm32_ledinit(void); void stm32_ledinit(void);
EXTERN void stm32_setled(int led, bool ledon); void stm32_setled(int led, bool ledon);
EXTERN void stm32_setleds(uint8_t ledset); void stm32_setleds(uint8_t ledset);
#endif #endif
/************************************************************************************ /************************************************************************************
@ -334,10 +335,10 @@ EXTERN void stm32_setleds(uint8_t ledset);
************************************************************************************/ ************************************************************************************/
#ifdef CONFIG_ARCH_BUTTONS #ifdef CONFIG_ARCH_BUTTONS
EXTERN void up_buttoninit(void); void up_buttoninit(void);
EXTERN uint8_t up_buttons(void); uint8_t up_buttons(void);
#ifdef CONFIG_ARCH_IRQBUTTONS #ifdef CONFIG_ARCH_IRQBUTTONS
EXTERN xcpt_t up_irqbutton(int id, xcpt_t irqhandler); xcpt_t up_irqbutton(int id, xcpt_t irqhandler);
#endif #endif
#endif #endif

View File

@ -406,7 +406,7 @@ CONFIG_USART1_SERIAL_CONSOLE=y
# #
CONFIG_USART1_RXBUFSIZE=64 CONFIG_USART1_RXBUFSIZE=64
CONFIG_USART1_TXBUFSIZE=64 CONFIG_USART1_TXBUFSIZE=64
CONFIG_USART1_BAUD=115200 CONFIG_USART1_BAUD=57600
CONFIG_USART1_BITS=8 CONFIG_USART1_BITS=8
CONFIG_USART1_PARITY=0 CONFIG_USART1_PARITY=0
CONFIG_USART1_2STOP=0 CONFIG_USART1_2STOP=0

View File

@ -112,7 +112,7 @@ void stm32_setled(int led, bool ledon)
{ {
ledcfg = GPIO_LED1; ledcfg = GPIO_LED1;
} }
else if (led == BOARD_LED1) else if (led == BOARD_LED2)
{ {
ledcfg = GPIO_LED2; ledcfg = GPIO_LED2;
} }

View File

@ -63,20 +63,19 @@
#endif #endif
/* STM32L-Discovery GPIOs ***************************************************************************/ /* STM32L-Discovery GPIOs ***************************************************************************/
/* The STM32L-Discovery board has four LEDs. Two of these are controlled by /* The STM32L-Discovery board has four LEDs. Two of these are controlled by logic on the board and
* logic on the board and are not available for software control: * are not available for software control:
* *
* LD1 COM: LD2 default status is red. LD2 turns to green to indicate that * LD1 COM: LD2 default status is red. LD2 turns to green to indicate that communications are in
* communications are in progress between the PC and the ST-LINK/V2. * progress between the PC and the ST-LINK/V2.
* LD2 PWR: Red LED indicates that the board is powered. * LD2 PWR: Red LED indicates that the board is powered.
* *
* And two LEDs can be controlled by software: * And two LEDs can be controlled by software:
* *
* User LD3: Green LED is a user LED connected to the I/O PB7 of the STM32L152 * User LD3: Green LED is a user LED connected to the I/O PB7 of the STM32L152 MCU.
* MCU. * User LD4: Blue LED is a user LED connected to the I/O PB6 of the STM32L152 MCU.
* User LD4: Blue LED is a user LED connected to the I/O PB6 of the STM32L152
* MCU.
* *
* The other side of the LED connects to ground so high value will illuminate the LED.
*/ */
#define GPIO_LED1 (GPIO_OUTPUT | GPIO_PUSHPULL | GPIO_SPEED_10MHz | \ #define GPIO_LED1 (GPIO_OUTPUT | GPIO_PUSHPULL | GPIO_SPEED_10MHz | \
@ -85,8 +84,7 @@
GPIO_OUTPUT_CLEAR | GPIO_PORTB | GPIO_PIN6) GPIO_OUTPUT_CLEAR | GPIO_PORTB | GPIO_PIN6)
/* Button definitions *******************************************************************************/ /* Button definitions *******************************************************************************/
/* The STM32L-Discovery supports two buttons; only one button is controllable by /* The STM32L-Discovery supports two buttons; only one button is controllable by software:
* software:
* *
* B1 USER: user and wake-up button connected to the I/O PA0 of the STM32F303VCT6. * B1 USER: user and wake-up button connected to the I/O PA0 of the STM32F303VCT6.
* B2 RESET: pushbutton connected to NRST is used to RESET the STM32F303VCT6. * B2 RESET: pushbutton connected to NRST is used to RESET the STM32F303VCT6.