diff --git a/boards/ellduino/Makefile b/boards/ellduino/Makefile new file mode 100644 index 000000000000..37891de8e6a2 --- /dev/null +++ b/boards/ellduino/Makefile @@ -0,0 +1,4 @@ +# tell the Makefile.base which module to build +MODULE = $(BOARD)_base + +include $(RIOTBASE)/Makefile.base diff --git a/boards/ellduino/Makefile.include b/boards/ellduino/Makefile.include new file mode 100644 index 000000000000..dd7455802f8e --- /dev/null +++ b/boards/ellduino/Makefile.include @@ -0,0 +1,16 @@ +# define the cpu used by the ellduino board +export CPU = stm32f0 +export CPU_MODEL = stm32f051r8 + +# define the default port depending on the host OS +PORT_LINUX ?= /dev/ttyUSB0 +PORT_DARWIN ?= $(shell ls -1 /dev/tty.SLAB_USBtoUART* | head -n 1) + +# setup serial terminal +include $(RIOTBOARD)/Makefile.include.serial + +# this board uses openocd +include $(RIOTBOARD)/Makefile.include.openocd + +# include cortex defaults +include $(RIOTBOARD)/Makefile.include.cortexm_common diff --git a/boards/ellduino/board.c b/boards/ellduino/board.c new file mode 100644 index 000000000000..7935d0129314 --- /dev/null +++ b/boards/ellduino/board.c @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2014 ELL-i co-operative + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License v2.1. See the file LICENSE in the top level directory for more + * details. + */ + +/** + * @ingroup board_ellduino + * @{ + * + * @file + * @brief Board specific implementations for the ELL-i ellduino board + * + * @author Lari Lehtomäki + * + * @} + */ + +#include "board.h" +#include "periph/uart.h" + +static void clock_init(void); + +void board_init(void) +{ + + /* initialize the CPU */ + cpu_init(); + + /* Initialize the HSI+PLL clocks as the board does not have external + * clock source. + */ + clock_init(); +} + + +/** + * @brief Configure the controllers clock system + * + * The clock initialization makes the following assumptions: + * - the internal HSI clock is used as base clock + * - the internal PLL circuit is used for clock refinement + * + * Use the following formulas to calculate the needed values: + * + * SYSCLK = ((HSI_VALUE / CLOCK_PLL_M) * CLOCK_PLL_N) / CLOCK_PLL_P + * SDIO and RNG Clock = ((HSI_VALUE / CLOCK_PLL_M) * CLOCK_PLL_N) / CLOCK_PLL_Q + * + * The actual used values are specified in the board's `periph_conf.h` file. + * + * NOTE: currently there is no timeout for initialization of PLL and other locks + * -> when wrong values are chosen, the initialization could stall + */ +void clock_init(void) { + /* set PLL configuration */ + RCC->CFGR &= (~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMUL)); + RCC->CFGR |= (RCC_CFGR_PLLSRC_HSI_DIV2 | + RCC_CFGR_PLLXTPRE_HSE_PREDIV_DIV2 | + RCC_CFGR_PLLMUL12); + + /* enable PLL again */ + RCC->CR |= RCC_CR_PLLON; + + /* wait until PLL is stable */ + while(!(RCC->CR & RCC_CR_PLLRDY)); + + + /* configure the sysclock and the peripheral clocks */ + + /* set sysclock to be driven by the PLL clock */ + RCC->CFGR &= ~RCC_CFGR_SW; + RCC->CFGR |= RCC_CFGR_SW_PLL; + + /* wait for sysclock to be stable */ + while (!(RCC->CFGR & RCC_CFGR_SWS_PLL)); +} diff --git a/boards/ellduino/include/board.h b/boards/ellduino/include/board.h new file mode 100644 index 000000000000..8e98a00e6c26 --- /dev/null +++ b/boards/ellduino/include/board.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2014 ELL-i co-operative + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License v2.1. See the file LICENSE in the top level directory for more + * details. + */ + +/** + * @defgroup board_ellduino + * @ingroup boards + * @brief Support for the Ellduino board + * @{ + * + * @file + * @brief Board specific definitions for the ELL-i Ellduino board. + * + * @author Lari Lehtomäki + */ + +#ifndef BOARD_H +#define BOARD_H + +#include "cpu.h" + + +/** + * @name The nominal CPU core clock in this board + */ +#define F_CPU (48000000UL) + +/** + * @name Assign the peripheral timer to be used as hardware timer + */ +#define HW_TIMER TIMER_0 + +/** + * @name Assign the UART interface to be used for stdio + */ +#define STDIO UART_0 +#define STDIO_BAUDRATE (115200U) +#define STDIO_RX_BUFSIZE (64U) + +/** + * @name Dummy LED definition for startup + * STM32F0 startup assumes we would have LEDs on board. + */ +#define LD4_TOGGLE /* not available */ + +/** + * @brief Initialize board specific hardware, including clock, LEDs and std-IO + */ +void board_init(void); + +#endif /** BOARD_H */ +/** @} */ diff --git a/boards/ellduino/include/periph_conf.h b/boards/ellduino/include/periph_conf.h new file mode 100644 index 000000000000..ce84df933a12 --- /dev/null +++ b/boards/ellduino/include/periph_conf.h @@ -0,0 +1,186 @@ +/* + * Copyright (C) 2014 ELL-i co-operative + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License v2.1. See the file LICENSE in the top level directory for more + * details. + */ + +/** + * @ingroup board_ellduino + * @{ + * + * @file + * @brief Peripheral MCU configuration for the Ellduino board + * + * @author Lari Lehtomäki + */ + +#ifndef PERIPH_CONF_H +#define PERIPH_CONF_H + +/** + * @name Clock system configuration + * @{ + */ +#define CLOCK_CORECLOCK (48000000U) /* desired core clock frequency */ +/** @} */ + +/** + * @name Timer configuration + * @{ + */ +#define TIMER_NUMOF (1U) +#define TIMER_0_EN 1 +#define TIMER_IRQ_PRIO 1 + +/* Timer 0 configuration */ +#define TIMER_0_DEV TIM2 +#define TIMER_0_CHANNELS 4 +#define TIMER_0_PRESCALER (47U) +#define TIMER_0_MAX_VALUE (0xffffffff) +#define TIMER_0_CLKEN() (RCC->APB1ENR |= RCC_APB1ENR_TIM2EN) +#define TIMER_0_ISR isr_tim2 +#define TIMER_0_IRQ_CHAN TIM2_IRQn +#define TIMER_0_IRQ_PRIO 1 +/** @} */ + + +/** + * @name UART configuration + * @{ + */ +#define UART_NUMOF (1U) +#define UART_0_EN 1 +#define UART_IRQ_PRIO 1 + +/* UART 0 device configuration */ +#define UART_0_DEV USART2 +#define UART_0_CLKEN() (RCC->APB1ENR |= RCC_APB1ENR_USART2EN) +#define UART_0_CLKDIS() (RCC->APB1ENR &= (~RCC_APB1ENR_USART2EN)) +#define UART_0_IRQ USART2_IRQn +#define UART_0_ISR isr_usart2 +/* UART 0 pin configuration */ +#define UART_0_PORT GPIOA +#define UART_0_PORT_CLKEN() (RCC->AHBENR |= RCC_AHBENR_GPIOAEN) +#define UART_0_RX_PIN 15 +#define UART_0_TX_PIN 14 +#define UART_0_AF 1 +/** @} */ + + +/** + * @name GPIO configuration + * @{ + */ +#define GPIO_0_EN 1 +#define GPIO_1_EN 1 +#define GPIO_2_EN 1 +#define GPIO_3_EN 1 +#define GPIO_4_EN 1 +#define GPIO_5_EN 1 +#define GPIO_6_EN 1 +#define GPIO_7_EN 1 +#define GPIO_8_EN 1 +#define GPIO_9_EN 1 +#define GPIO_10_EN 1 +#define GPIO_11_EN 1 +#define GPIO_IRQ_PRIO 1 + +/* IRQ config */ +#define GPIO_IRQ_0 -1 /* not configured */ +#define GPIO_IRQ_1 -1 /* not configured */ +#define GPIO_IRQ_2 -1 /* not configured */ +#define GPIO_IRQ_3 -1 /* not configured */ +#define GPIO_IRQ_4 -1 /* not configured */ +#define GPIO_IRQ_5 -1 /* not configured */ +#define GPIO_IRQ_6 -1 /* not configured */ +#define GPIO_IRQ_7 -1 /* not configured */ +#define GPIO_IRQ_8 -1 /* not configured */ +#define GPIO_IRQ_9 -1 /* not configured */ +#define GPIO_IRQ_10 GPIO_0 +#define GPIO_IRQ_11 GPIO_1 +#define GPIO_IRQ_12 GPIO_2 +#define GPIO_IRQ_13 GPIO_3 +#define GPIO_IRQ_14 GPIO_4 +#define GPIO_IRQ_15 GPIO_5 + +/* GPIO channel 0 config */ +#define GPIO_0_PORT GPIOA +#define GPIO_0_PIN 10 +#define GPIO_0_CLK 17 +#define GPIO_0_EXTI_CFG() (SYSCFG->EXTICR[0] |= SYSCFG_EXTICR1_EXTI0_PA) +#define GPIO_0_IRQ EXTI0_1_IRQn +/* GPIO channel 1 config */ +#define GPIO_1_PORT GPIOA +#define GPIO_1_PIN 9 +#define GPIO_1_CLK 17 +#define GPIO_1_EXTI_CFG() (SYSCFG->EXTICR[0] |= SYSCFG_EXTICR1_EXTI0_PA) +#define GPIO_1_IRQ EXTI0_1_IRQn +/* GPIO channel 2 config */ +#define GPIO_2_PORT GPIOA +#define GPIO_2_PIN 8 +#define GPIO_2_CLK 17 +#define GPIO_2_EXTI_CFG() (SYSCFG->EXTICR[0] |= SYSCFG_EXTICR1_EXTI0_PA) +#define GPIO_2_IRQ EXTI0_1_IRQn +/* GPIO channel 3 config */ +#define GPIO_3_PORT GPIOC +#define GPIO_3_PIN 9 +#define GPIO_3_CLK 19 +#define GPIO_3_EXTI_CFG() (SYSCFG->EXTICR[0] |= SYSCFG_EXTICR1_EXTI0_PA) +#define GPIO_3_IRQ EXTI0_1_IRQn +/* GPIO channel 4 config */ +#define GPIO_4_PORT GPIOC +#define GPIO_4_PIN 8 +#define GPIO_4_CLK 19 +#define GPIO_4_EXTI_CFG() (SYSCFG->EXTICR[0] |= SYSCFG_EXTICR1_EXTI0_PA) +#define GPIO_4_IRQ EXTI0_1_IRQn +/* GPIO channel 5 config */ +#define GPIO_5_PORT GPIOA +#define GPIO_5_PIN 7 +#define GPIO_5_CLK 17 +#define GPIO_5_EXTI_CFG() (SYSCFG->EXTICR[0] |= SYSCFG_EXTICR1_EXTI0_PA) +#define GPIO_5_IRQ EXTI0_1_IRQn +/* GPIO channel 6 config */ +#define GPIO_6_PORT GPIOA +#define GPIO_6_PIN 3 +#define GPIO_6_CLK 17 +#define GPIO_6_EXTI_CFG() (SYSCFG->EXTICR[0] |= SYSCFG_EXTICR1_EXTI0_PA) +#define GPIO_6_IRQ EXTI0_1_IRQn +/* GPIO channel 7 config */ +#define GPIO_7_PORT GPIOA +#define GPIO_7_PIN 2 +#define GPIO_7_CLK 17 +#define GPIO_7_EXTI_CFG() (SYSCFG->EXTICR[0] |= SYSCFG_EXTICR1_EXTI0_PA) +#define GPIO_7_IRQ EXTI0_1_IRQn +/* GPIO channel 8 config */ +#define GPIO_8_PORT GPIOB +#define GPIO_8_PIN 10 +#define GPIO_8_CLK 18 +#define GPIO_8_EXTI_CFG() (SYSCFG->EXTICR[0] |= SYSCFG_EXTICR1_EXTI0_PA) +#define GPIO_8_IRQ EXTI0_1_IRQn +/* GPIO channel 9 config */ +#define GPIO_9_PORT GPIOB +#define GPIO_9_PIN 11 +#define GPIO_9_CLK 18 +#define GPIO_9_EXTI_CFG() (SYSCFG->EXTICR[0] |= SYSCFG_EXTICR1_EXTI0_PA) +#define GPIO_9_IRQ EXTI0_1_IRQn +/* GPIO channel 10 config */ +#define GPIO_10_PORT GPIOA +#define GPIO_10_PIN 6 +#define GPIO_10_CLK 17 +#define GPIO_10_EXTI_CFG() (SYSCFG->EXTICR[0] |= SYSCFG_EXTICR1_EXTI0_PA) +#define GPIO_10_IRQ EXTI0_1_IRQn +/* GPIO channel 11 config */ +#define GPIO_11_PORT GPIOB +#define GPIO_11_PIN 5 +#define GPIO_11_CLK 18 +#define GPIO_11_EXTI_CFG() (SYSCFG->EXTICR[0] |= SYSCFG_EXTICR1_EXTI0_PA) +#define GPIO_11_IRQ EXTI0_1_IRQn +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* PERIPH_CONF_H */ diff --git a/boards/stm32f0discovery/board.c b/boards/stm32f0discovery/board.c index 0cf5c0c74c46..19403aae161d 100644 --- a/boards/stm32f0discovery/board.c +++ b/boards/stm32f0discovery/board.c @@ -23,6 +23,8 @@ static void leds_init(void); +static void hse_init(void); + void board_init(void) { @@ -31,6 +33,9 @@ void board_init(void) /* initialize the CPU */ cpu_init(); + + /* initialize the HSE clock */ + hse_init(); } /** @@ -61,3 +66,58 @@ void leds_init(void) /* turn all LEDs off */ LED_PORT->BRR = 0x0300; } + +/* + * @brief Configure the controllers HSE clock + * + * The clock initialization makes the following assumptions: + * - the external HSE clock from an external oscillator is used as base clock + * - the internal PLL circuit is used for clock refinement + * + * Use the following formulas to calculate the needed values: + * + * SYSCLK = ((HSE_VALUE / CLOCK_PLL_M) * CLOCK_PLL_N) / CLOCK_PLL_P + * USB, SDIO and RNG Clock = ((HSE_VALUE / CLOCK_PLL_M) * CLOCK_PLL_N) / CLOCK_PLL_Q + * + * The actual used values are specified in the board's `periph_conf.h` file. + * + * NOTE: currently there is no timeout for initialization of PLL and other locks + * -> when wrong values are chosen, the initialization could stall + */ +static void hse_init(void) +{ + /* configure the HSE clock */ + + /* enable the HSE clock */ + RCC->CR |= RCC_CR_HSEON; + + /* wait for HSE to be ready */ + while (!(RCC->CR & RCC_CR_HSERDY)); + + + /* configure the PLL */ + + /* reset PLL configuration bits */ + RCC->CFGR &= ~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMUL); + /* set PLL configuration */ + RCC->CFGR |= RCC_CFGR_PLLSRC_HSE_PREDIV | RCC_CFGR_PLLXTPRE_HSE_PREDIV_DIV1 | + (((CLOCK_PLL_MUL - 2) & 0xf) << 18); + + /* enable PLL again */ + RCC->CR |= RCC_CR_PLLON; + + /* wait until PLL is stable */ + while(!(RCC->CR & RCC_CR_PLLRDY)); + + + /* configure the sysclock and the peripheral clocks */ + + /* set sysclock to be driven by the PLL clock */ + RCC->CFGR &= ~RCC_CFGR_SW; + RCC->CFGR |= RCC_CFGR_SW_PLL; + + + /* wait for sysclock to be stable */ + while (!(RCC->CFGR & RCC_CFGR_SWS_PLL)); + +} diff --git a/cpu/stm32f0/cpu.c b/cpu/stm32f0/cpu.c index a7a42fd4c1ea..9c90f185a584 100644 --- a/cpu/stm32f0/cpu.c +++ b/cpu/stm32f0/cpu.c @@ -38,18 +38,8 @@ void cpu_init(void) * @brief Configure the controllers clock system * * The clock initialization make the following assumptions: - * - the external HSE clock from an external oscillator is used as base clock - * - the internal PLL circuit is used for clock refinement - * - * Use the following formulas to calculate the needed values: - * - * SYSCLK = ((HSE_VALUE / CLOCK_PLL_M) * CLOCK_PLL_N) / CLOCK_PLL_P - * USB, SDIO and RNG Clock = ((HSE_VALUE / CLOCK_PLL_M) * CLOCK_PLL_N) / CLOCK_PLL_Q - * - * The actual used values are specified in the board's `periph_conf.h` file. - * - * NOTE: currently there is not timeout for initialization of PLL and other locks - * -> when wrong values are chosen, the initialization could stall + * - the internal HSI clock is used as base clock + * - each board defines how to configure HSE and PLL clocks after cpu_init() */ static void clock_init(void) { @@ -58,6 +48,9 @@ static void clock_init(void) /* enable the HSI clock */ RCC->CR |= RCC_CR_HSION; + /* wait until HSI is stable */ + while (!(RCC->CR & RCC_CR_HSIRDY)); + /* reset clock configuration register */ RCC->CFGR = 0; RCC->CFGR2 = 0; @@ -68,11 +61,6 @@ static void clock_init(void) /* disable all clock interrupts */ RCC->CIR = 0; - /* enable the HSE clock */ - RCC->CR |= RCC_CR_HSEON; - - /* wait for HSE to be ready */ - while (!(RCC->CR & RCC_CR_HSERDY)); /* setup the peripheral bus prescalers */ @@ -81,30 +69,10 @@ static void clock_init(void) /* set PCLK = HCLK, so its not divided */ RCC->CFGR |= RCC_CFGR_PPRE_DIV1; - /* configure the PLL */ - - /* reset PLL configuration bits */ - RCC->CFGR &= ~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMUL); - /* set PLL configuration */ - RCC->CFGR |= RCC_CFGR_PLLSRC_HSE_PREDIV | RCC_CFGR_PLLXTPRE_HSE_PREDIV_DIV1 | - (((CLOCK_PLL_MUL - 2) & 0xf) << 18); - - /* enable PLL again */ - RCC->CR |= RCC_CR_PLLON; - /* wait until PLL is stable */ - while(!(RCC->CR & RCC_CR_PLLRDY)); /* configure flash latency */ /* enable pre-fetch buffer and set flash latency to 1 cycle*/ FLASH->ACR = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY; - /* configure the sysclock and the peripheral clocks */ - - /* set sysclock to be driven by the PLL clock */ - RCC->CFGR &= ~RCC_CFGR_SW; - RCC->CFGR |= RCC_CFGR_SW_PLL; - - /* wait for sysclock to be stable */ - while (!(RCC->CFGR & RCC_CFGR_SWS_PLL)); }