From 48eed286b98c6f5389c91be4a82e4e2bef6fc99d Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Tue, 22 Jan 2013 21:51:24 +0000 Subject: [l1] fix whitespace and missing license info Earlier additions to the L1 support were not correctly using linux coding guidelines as specified in /HACKING. Some examples were also missing license information. --- .../l1/stm32l-discovery/button-irq-printf/main.c | 174 ++++++++++++--------- .../l1/stm32l-discovery/button-irq-printf/syscfg.h | 24 ++- examples/stm32/l1/stm32l-discovery/usart/usart.c | 88 ++++++----- include/libopencm3/stm32/l1/flash.h | 54 +++---- include/libopencm3/stm32/l1/pwr.h | 28 ++-- lib/stm32/l1/rcc.c | 3 +- 6 files changed, 203 insertions(+), 168 deletions(-) diff --git a/examples/stm32/l1/stm32l-discovery/button-irq-printf/main.c b/examples/stm32/l1/stm32l-discovery/button-irq-printf/main.c index 1830c4d..762fdd9 100644 --- a/examples/stm32/l1/stm32l-discovery/button-irq-printf/main.c +++ b/examples/stm32/l1/stm32l-discovery/button-irq-printf/main.c @@ -1,5 +1,20 @@ /* - * Karl Palsson, 2012 + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . */ #include @@ -15,35 +30,38 @@ static struct state_t state; -void clock_setup(void) { - /* Lots of things on all ports... */ - rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_GPIOAEN); - rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_GPIOBEN); +void clock_setup(void) +{ + /* Lots of things on all ports... */ + rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_GPIOAEN); + rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_GPIOBEN); - /* Enable clocks for USART2. */ - rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_USART2EN); + /* Enable clocks for USART2. */ + rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_USART2EN); } -void gpio_setup(void) { - gpio_mode_setup(LED_DISCO_GREEN_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED_DISCO_GREEN_PIN); +void gpio_setup(void) +{ + gpio_mode_setup(LED_DISCO_GREEN_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED_DISCO_GREEN_PIN); - /* Setup GPIO pins for USART2 transmit. */ - gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO2); + /* Setup GPIO pins for USART2 transmit. */ + gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO2); - /* Setup USART2 TX pin as alternate function. */ - gpio_set_af(GPIOA, GPIO_AF7, GPIO2); + /* Setup USART2 TX pin as alternate function. */ + gpio_set_af(GPIOA, GPIO_AF7, GPIO2); } -void usart_setup(void) { - usart_set_baudrate(USART_CONSOLE, 115200); - usart_set_databits(USART_CONSOLE, 8); - usart_set_stopbits(USART_CONSOLE, USART_STOPBITS_1); - usart_set_mode(USART_CONSOLE, USART_MODE_TX); - usart_set_parity(USART_CONSOLE, USART_PARITY_NONE); - usart_set_flow_control(USART_CONSOLE, USART_FLOWCONTROL_NONE); - - /* Finally enable the USART. */ - usart_enable(USART_CONSOLE); +void usart_setup(void) +{ + usart_set_baudrate(USART_CONSOLE, 115200); + usart_set_databits(USART_CONSOLE, 8); + usart_set_stopbits(USART_CONSOLE, USART_STOPBITS_1); + usart_set_mode(USART_CONSOLE, USART_MODE_TX); + usart_set_parity(USART_CONSOLE, USART_PARITY_NONE); + usart_set_flow_control(USART_CONSOLE, USART_FLOWCONTROL_NONE); + + /* Finally enable the USART. */ + usart_enable(USART_CONSOLE); } /** @@ -53,65 +71,69 @@ void usart_setup(void) { * @param len * @return */ -int _write(int file, char *ptr, int len) { - int i; - - if (file == STDOUT_FILENO || file == STDERR_FILENO) { - for (i = 0; i < len; i++) { - if (ptr[i] == '\n') { - usart_send_blocking(USART_CONSOLE, '\r'); - } - usart_send_blocking(USART_CONSOLE, ptr[i]); - } - return i; - } - errno = EIO; - return -1; +int _write(int file, char *ptr, int len) +{ + int i; + + if (file == STDOUT_FILENO || file == STDERR_FILENO) { + for (i = 0; i < len; i++) { + if (ptr[i] == '\n') { + usart_send_blocking(USART_CONSOLE, '\r'); + } + usart_send_blocking(USART_CONSOLE, ptr[i]); + } + return i; + } + errno = EIO; + return -1; } -void BUTTON_DISCO_USER_isr(void) { - exti_reset_request(BUTTON_DISCO_USER_EXTI); - if (state.falling) { - state.falling = false; - exti_set_trigger(BUTTON_DISCO_USER_EXTI, EXTI_TRIGGER_RISING); - // ILOG("fell: %d\n", TIM_CNT(TIM7)); - puts("fell!\n"); - } else { - puts("Rose!\n"); - // TIM_CNT(TIM7) = 0; - state.falling = true; - exti_set_trigger(BUTTON_DISCO_USER_EXTI, EXTI_TRIGGER_FALLING); - } +void BUTTON_DISCO_USER_isr(void) +{ + exti_reset_request(BUTTON_DISCO_USER_EXTI); + if (state.falling) { + state.falling = false; + exti_set_trigger(BUTTON_DISCO_USER_EXTI, EXTI_TRIGGER_RISING); + // ILOG("fell: %d\n", TIM_CNT(TIM7)); + puts("fell!\n"); + } else { + puts("Rose!\n"); + // TIM_CNT(TIM7) = 0; + state.falling = true; + exti_set_trigger(BUTTON_DISCO_USER_EXTI, EXTI_TRIGGER_FALLING); + } } -void setup_buttons(void) { - /* Enable EXTI0 interrupt. */ - nvic_enable_irq(BUTTON_DISCO_USER_NVIC); +void setup_buttons(void) +{ + /* Enable EXTI0 interrupt. */ + nvic_enable_irq(BUTTON_DISCO_USER_NVIC); - gpio_mode_setup(BUTTON_DISCO_USER_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, BUTTON_DISCO_USER_PIN); + gpio_mode_setup(BUTTON_DISCO_USER_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, BUTTON_DISCO_USER_PIN); - /* Configure the EXTI subsystem. */ - exti_select_source(BUTTON_DISCO_USER_EXTI, BUTTON_DISCO_USER_PORT); - state.falling = false; - exti_set_trigger(BUTTON_DISCO_USER_EXTI, EXTI_TRIGGER_RISING); - exti_enable_request(BUTTON_DISCO_USER_EXTI); + /* Configure the EXTI subsystem. */ + exti_select_source(BUTTON_DISCO_USER_EXTI, BUTTON_DISCO_USER_PORT); + state.falling = false; + exti_set_trigger(BUTTON_DISCO_USER_EXTI, EXTI_TRIGGER_RISING); + exti_enable_request(BUTTON_DISCO_USER_EXTI); } -int main(void) { - int i; - int j = 0; - clock_setup(); - gpio_setup(); - usart_setup(); - puts("hi guys!\n"); - setup_buttons(); - while (1) { - puts("tick:"); - putchar('a' + (j++ % 26)); - gpio_toggle(GPIOB, GPIO7); /* LED on/off */ - for (i = 0; i < 100000; i++) /* Wait a bit. */ - __asm__("NOP"); - } - - return 0; +int main(void) +{ + int i; + int j = 0; + clock_setup(); + gpio_setup(); + usart_setup(); + puts("hi guys!\n"); + setup_buttons(); + while (1) { + puts("tick:"); + putchar('a' + (j++ % 26)); + gpio_toggle(GPIOB, GPIO7); /* LED on/off */ + for (i = 0; i < 100000; i++) /* Wait a bit. */ + __asm__("NOP"); + } + + return 0; } diff --git a/examples/stm32/l1/stm32l-discovery/button-irq-printf/syscfg.h b/examples/stm32/l1/stm32l-discovery/button-irq-printf/syscfg.h index 32cf465..be54502 100644 --- a/examples/stm32/l1/stm32l-discovery/button-irq-printf/syscfg.h +++ b/examples/stm32/l1/stm32l-discovery/button-irq-printf/syscfg.h @@ -1,7 +1,20 @@ /* - * General configuration of the device + * This file is part of the libopencm3 project. * - * Karl Palsson 2012 + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . */ #ifndef SYSCFG_H @@ -31,10 +44,9 @@ extern "C" { #define BUTTON_DISCO_USER_isr exti0_isr #define BUTTON_DISCO_USER_NVIC NVIC_EXTI0_IRQ - - struct state_t { - bool falling; - }; + struct state_t { + bool falling; + }; #ifdef __cplusplus diff --git a/examples/stm32/l1/stm32l-discovery/usart/usart.c b/examples/stm32/l1/stm32l-discovery/usart/usart.c index 3335ca8..cc766dd 100644 --- a/examples/stm32/l1/stm32l-discovery/usart/usart.c +++ b/examples/stm32/l1/stm32l-discovery/usart/usart.c @@ -22,59 +22,63 @@ #include #include -void clock_setup(void) { - /* We are running on MSI after boot. */ - /* Enable GPIOD clock for LED & USARTs. */ - rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_GPIOAEN); - rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_GPIOBEN); +void clock_setup(void) +{ + /* We are running on MSI after boot. */ + /* Enable GPIOD clock for LED & USARTs. */ + rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_GPIOAEN); + rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_GPIOBEN); - /* Enable clocks for USART2. */ - rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_USART2EN); + /* Enable clocks for USART2. */ + rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_USART2EN); } -void usart_setup(void) { - /* Setup USART2 parameters. */ - usart_set_baudrate(USART2, 38400); - usart_set_databits(USART2, 8); - usart_set_stopbits(USART2, USART_STOPBITS_1); - usart_set_mode(USART2, USART_MODE_TX); - usart_set_parity(USART2, USART_PARITY_NONE); - usart_set_flow_control(USART2, USART_FLOWCONTROL_NONE); +void usart_setup(void) +{ + /* Setup USART2 parameters. */ + usart_set_baudrate(USART2, 38400); + usart_set_databits(USART2, 8); + usart_set_stopbits(USART2, USART_STOPBITS_1); + usart_set_mode(USART2, USART_MODE_TX); + usart_set_parity(USART2, USART_PARITY_NONE); + usart_set_flow_control(USART2, USART_FLOWCONTROL_NONE); - /* Finally enable the USART. */ - usart_enable(USART2); + /* Finally enable the USART. */ + usart_enable(USART2); } -void gpio_setup(void) { - /* Setup GPIO pin GPIO7 on GPIO port B for Green LED. */ - gpio_mode_setup(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO7); +void gpio_setup(void) +{ + /* Setup GPIO pin GPIO7 on GPIO port B for Green LED. */ + gpio_mode_setup(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO7); - /* Setup GPIO pins for USART2 transmit. */ - gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO2); + /* Setup GPIO pins for USART2 transmit. */ + gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO2); - /* Setup USART2 TX pin as alternate function. */ - gpio_set_af(GPIOA, GPIO_AF7, GPIO2); + /* Setup USART2 TX pin as alternate function. */ + gpio_set_af(GPIOA, GPIO_AF7, GPIO2); } -int main(void) { - int i, j = 0, c = 0; +int main(void) +{ + int i, j = 0, c = 0; - clock_setup(); - gpio_setup(); - usart_setup(); + clock_setup(); + gpio_setup(); + usart_setup(); - /* Blink the LED (PD12) on the board with every transmitted byte. */ - while (1) { - gpio_toggle(GPIOB, GPIO7); /* LED on/off */ - usart_send_blocking(USART2, c + '0'); /* USART2: Send byte. */ - c = (c == 9) ? 0 : c + 1; /* Increment c. */ - if ((j++ % 80) == 0) { /* Newline after line full. */ - usart_send_blocking(USART2, '\r'); - usart_send_blocking(USART2, '\n'); - } - for (i = 0; i < 100000; i++) /* Wait a bit. */ - __asm__("NOP"); - } + /* Blink the LED (PD12) on the board with every transmitted byte. */ + while (1) { + gpio_toggle(GPIOB, GPIO7); /* LED on/off */ + usart_send_blocking(USART2, c + '0'); /* USART2: Send byte. */ + c = (c == 9) ? 0 : c + 1; /* Increment c. */ + if ((j++ % 80) == 0) { /* Newline after line full. */ + usart_send_blocking(USART2, '\r'); + usart_send_blocking(USART2, '\n'); + } + for (i = 0; i < 100000; i++) /* Wait a bit. */ + __asm__("NOP"); + } - return 0; + return 0; } diff --git a/include/libopencm3/stm32/l1/flash.h b/include/libopencm3/stm32/l1/flash.h index ed0a696..a2831b4 100644 --- a/include/libopencm3/stm32/l1/flash.h +++ b/include/libopencm3/stm32/l1/flash.h @@ -33,10 +33,10 @@ #define FLASH_ACR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x00) #define FLASH_PECR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x04) -#define FLASH_PDKEYR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x08) -#define FLASH_PEKEYR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x0C) -#define FLASH_PRGKEYR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x10) -#define FLASH_OPTKEYR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x14) +#define FLASH_PDKEYR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x08) +#define FLASH_PEKEYR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x0C) +#define FLASH_PRGKEYR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x10) +#define FLASH_OPTKEYR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x14) #define FLASH_SR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x18) #define FLASH_OBR MMIO32(FLASH_MEM_INTERFACE_BASE + 0x1c) #define FLASH_WRPR1 MMIO32(FLASH_MEM_INTERFACE_BASE + 0x20) @@ -46,9 +46,9 @@ /* --- FLASH_ACR values ---------------------------------------------------- */ #define FLASH_RUNPD (1 << 4) -#define FLASH_SLEEPPD (1 << 3) +#define FLASH_SLEEPPD (1 << 3) #define FLASH_ACC64 (1 << 2) -#define FLASH_PRFTEN (1 << 1) +#define FLASH_PRFTEN (1 << 1) #define FLASH_LATENCY_0WS 0x00 #define FLASH_LATENCY_1WS 0x01 @@ -85,30 +85,30 @@ /* --- FLASH_SR values ----------------------------------------------------- */ -#define FLASH_OPTVERRUSR (1 << 12) -#define FLASH_OPTVERR (1 << 11) -#define FLASH_SIZEERR (1 << 10) -#define FLASH_PGAERR (1 << 9) -#define FLASH_WRPERR (1 << 8) -#define FLASH_READY (1 << 3) -#define FLASH_ENDHV (1 << 2) -#define FLASH_EOP (1 << 1) -#define FLASH_BSY (1 << 0) +#define FLASH_OPTVERRUSR (1 << 12) +#define FLASH_OPTVERR (1 << 11) +#define FLASH_SIZEERR (1 << 10) +#define FLASH_PGAERR (1 << 9) +#define FLASH_WRPERR (1 << 8) +#define FLASH_READY (1 << 3) +#define FLASH_ENDHV (1 << 2) +#define FLASH_EOP (1 << 1) +#define FLASH_BSY (1 << 0) /* --- FLASH_OBR values ----------------------------------------------------- */ -#define FLASH_BFB2 (1 << 23) +#define FLASH_BFB2 (1 << 23) #define FLASH_NRST_STDBY (1 << 22) -#define FLASH_NRST_STOP (1 << 21) -#define FLASH_IWDG_SW (1 << 20) -#define FLASH_BOR_OFF (0x0 << 16) -#define FLASH_BOR_LEVEL_1 (0x8 << 16) -#define FLASH_BOR_LEVEL_2 (0x9 << 16) -#define FLASH_BOR_LEVEL_3 (0xa << 16) -#define FLASH_BOR_LEVEL_4 (0xb << 16) -#define FLASH_BOR_LEVEL_5 (0xc << 16) -#define FLASH_RDPRT_LEVEL_0 (0xaa) -#define FLASH_RDPRT_LEVEL_1 (0x00) -#define FLASH_RDPRT_LEVEL_2 (0xcc) +#define FLASH_NRST_STOP (1 << 21) +#define FLASH_IWDG_SW (1 << 20) +#define FLASH_BOR_OFF (0x0 << 16) +#define FLASH_BOR_LEVEL_1 (0x8 << 16) +#define FLASH_BOR_LEVEL_2 (0x9 << 16) +#define FLASH_BOR_LEVEL_3 (0xa << 16) +#define FLASH_BOR_LEVEL_4 (0xb << 16) +#define FLASH_BOR_LEVEL_5 (0xc << 16) +#define FLASH_RDPRT_LEVEL_0 (0xaa) +#define FLASH_RDPRT_LEVEL_1 (0x00) +#define FLASH_RDPRT_LEVEL_2 (0xcc) /* --- Function prototypes ------------------------------------------------- */ diff --git a/include/libopencm3/stm32/l1/pwr.h b/include/libopencm3/stm32/l1/pwr.h index 309b464..41992d7 100644 --- a/include/libopencm3/stm32/l1/pwr.h +++ b/include/libopencm3/stm32/l1/pwr.h @@ -33,49 +33,47 @@ /* Bits [31:15]: Reserved */ /* LPRUN: Low power run mode */ -#define PWR_CR_LPRUN (1 << 14) +#define PWR_CR_LPRUN (1 << 14) /* VOS[12:11]: Regulator voltage scaling output selection */ -#define PWR_CR_VOS_LSB 11 +#define PWR_CR_VOS_LSB 11 /** @defgroup pwr_vos Voltage Scaling Output level selection @ingroup STM32F_pwr_defines @{*/ -#define PWR_CR_VOS_RANGE1 (0x1 << PWR_CR_VOS_LSB) -#define PWR_CR_VOS_RANGE2 (0x2 << PWR_CR_VOS_LSB) -#define PWR_CR_VOS_RANGE3 (0x3 << PWR_CR_VOS_LSB) +#define PWR_CR_VOS_RANGE1 (0x1 << PWR_CR_VOS_LSB) +#define PWR_CR_VOS_RANGE2 (0x2 << PWR_CR_VOS_LSB) +#define PWR_CR_VOS_RANGE3 (0x3 << PWR_CR_VOS_LSB) /**@}*/ -#define PWR_CR_VOS_MASK (0x3 << PWR_CR_VOS_LSB) +#define PWR_CR_VOS_MASK (0x3 << PWR_CR_VOS_LSB) /* FWU: Fast wakeup */ -#define PWR_CR_FWU (1 << 10) +#define PWR_CR_FWU (1 << 10) /* ULP: Ultralow power mode */ -#define PWR_CR_ULP (1 << 9) +#define PWR_CR_ULP (1 << 9) /* --- PWR_CSR values ------------------------------------------------------- */ /* Bits [31:11]: Reserved */ /* EWUP3: Enable WKUP3 pin */ -#define PWR_CSR_EWUP3 (1 << 10) +#define PWR_CSR_EWUP3 (1 << 10) /* EWUP2: Enable WKUP2 pin */ -#define PWR_CSR_EWUP2 (1 << 9) +#define PWR_CSR_EWUP2 (1 << 9) /* EWUP1: Enable WKUP1 pin */ -#define PWR_CSR_EWUP1 PWR_CSR_EWUP +#define PWR_CSR_EWUP1 PWR_CSR_EWUP /* REGLPF : Regulator LP flag */ -#define PWR_CSR_REGLPF (1 << 5) +#define PWR_CSR_REGLPF (1 << 5) /* VOSF: Voltage Scaling select flag */ -#define PWR_CSR_VOSF (1 << 4) +#define PWR_CSR_VOSF (1 << 4) /* VREFINTRDYF: Internal voltage reference (VREFINT) ready flag */ #define PWR_CSR_VREFINTRDYF (1 << 3) - - /* --- Function prototypes ------------------------------------------------- */ typedef enum { diff --git a/lib/stm32/l1/rcc.c b/lib/stm32/l1/rcc.c index bbba9a9..4864731 100644 --- a/lib/stm32/l1/rcc.c +++ b/lib/stm32/l1/rcc.c @@ -29,8 +29,7 @@ u32 rcc_ppre1_frequency = 2097000; u32 rcc_ppre2_frequency = 2097000; -const clock_scale_t clock_vrange1_config[CLOCK_VRANGE1_END] = -{ +const clock_scale_t clock_vrange1_config[CLOCK_VRANGE1_END] ={ { /* 24MHz PLL from HSI */ .pll_source = RCC_CFGR_PLLSRC_HSI_CLK, .pll_mul = RCC_CFGR_PLLMUL_MUL3, -- cgit v1.2.3 From df5e3e5ff115af6c145d0d7ccd23631dffaeebd9 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Tue, 22 Jan 2013 22:27:38 +0000 Subject: [l1] PWR: fix style for common code Code added for L1 to support the PWR Control block didn't properly follow the HACKING_COMMON_DOC guidelines. The naming was wrong, and some headers were missing. This commit has no functional changes, it only addresses the style and structure problems. --- include/libopencm3/stm32/common/pwr_common_all.h | 119 +++++++++++++ include/libopencm3/stm32/f1/pwr.h | 40 +++++ include/libopencm3/stm32/f4/pwr.h | 19 +- include/libopencm3/stm32/l1/pwr.h | 53 ++++-- include/libopencm3/stm32/l1/rcc.h | 2 +- include/libopencm3/stm32/pwr.h | 122 ++----------- lib/stm32/common/pwr_common_all.c | 217 +++++++++++++++++++++++ lib/stm32/f1/Makefile | 2 +- lib/stm32/f4/Makefile | 1 + lib/stm32/l1/Makefile | 2 +- lib/stm32/l1/pwr.c | 37 ++++ lib/stm32/l1/pwr_chipset.c | 37 ---- lib/stm32/l1/rcc.c | 2 +- 13 files changed, 482 insertions(+), 171 deletions(-) create mode 100644 include/libopencm3/stm32/common/pwr_common_all.h create mode 100644 include/libopencm3/stm32/f1/pwr.h create mode 100644 lib/stm32/common/pwr_common_all.c create mode 100644 lib/stm32/l1/pwr.c delete mode 100644 lib/stm32/l1/pwr_chipset.c diff --git a/include/libopencm3/stm32/common/pwr_common_all.h b/include/libopencm3/stm32/common/pwr_common_all.h new file mode 100644 index 0000000..cc9fd22 --- /dev/null +++ b/include/libopencm3/stm32/common/pwr_common_all.h @@ -0,0 +1,119 @@ +/** @addtogroup pwr_defines */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY, BUT ONLY VIA PWR.H */ + +#ifndef LIBOPENCM3_PWR_COMMON_ALL_H +#define LIBOPENCM3_PWR_COMMON_ALL_H + +/**@{*/ + +#include + +/* --- PWR registers ------------------------------------------------------- */ + +/* Power control register (PWR_CR) */ +#define PWR_CR MMIO32(POWER_CONTROL_BASE + 0x00) + +/* Power control/status register (PWR_CSR) */ +#define PWR_CSR MMIO32(POWER_CONTROL_BASE + 0x04) + +/* --- PWR_CR values ------------------------------------------------------- */ + +/* Bits [31:9]: Reserved, must be kept at reset value. */ + +/* DBP: Disable backup domain write protection */ +#define PWR_CR_DBP (1 << 8) + +/* PLS[7:5]: PVD level selection */ +#define PWR_CR_PLS_LSB 5 +/** @defgroup pwr_pls PVD level selection +@ingroup STM32F_pwr_defines + +@{*/ +#define PWR_CR_PLS_2V2 (0x0 << PWR_CR_PLS_LSB) +#define PWR_CR_PLS_2V3 (0x1 << PWR_CR_PLS_LSB) +#define PWR_CR_PLS_2V4 (0x2 << PWR_CR_PLS_LSB) +#define PWR_CR_PLS_2V5 (0x3 << PWR_CR_PLS_LSB) +#define PWR_CR_PLS_2V6 (0x4 << PWR_CR_PLS_LSB) +#define PWR_CR_PLS_2V7 (0x5 << PWR_CR_PLS_LSB) +#define PWR_CR_PLS_2V8 (0x6 << PWR_CR_PLS_LSB) +#define PWR_CR_PLS_2V9 (0x7 << PWR_CR_PLS_LSB) +/**@}*/ +#define PWR_CR_PLS_MASK (0x7 << PWR_CR_PLS_LSB) + +/* PVDE: Power voltage detector enable */ +#define PWR_CR_PVDE (1 << 4) + +/* CSBF: Clear standby flag */ +#define PWR_CR_CSBF (1 << 3) + +/* CWUF: Clear wakeup flag */ +#define PWR_CR_CWUF (1 << 2) + +/* PDDS: Power down deepsleep */ +#define PWR_CR_PDDS (1 << 1) + +/* LPDS: Low-power deepsleep */ +#define PWR_CR_LPDS (1 << 0) + +/* --- PWR_CSR values ------------------------------------------------------ */ + +/* Bits [31:9]: Reserved, must be kept at reset value. */ + +/* EWUP: Enable WKUP pin */ +#define PWR_CSR_EWUP (1 << 8) + +/* Bits [7:3]: Reserved, must be kept at reset value. */ + +/* PVDO: PVD output */ +#define PWR_CSR_PVDO (1 << 2) + +/* SBF: Standby flag */ +#define PWR_CSR_SBF (1 << 1) + +/* WUF: Wakeup flag */ +#define PWR_CSR_WUF (1 << 0) + +/* --- PWR function prototypes ------------------------------------------- */ + +BEGIN_DECLS + +void pwr_disable_backup_domain_write_protect(void); +void pwr_enable_backup_domain_write_protect(void); +void pwr_enable_power_voltage_detect(u32 pvd_level); +void pwr_disable_power_voltage_detect(void); +void pwr_clear_standby_flag(void); +void pwr_clear_wakeup_flag(void); +void pwr_set_standby_mode(void); +void pwr_set_stop_mode(void); +void pwr_voltage_regulator_on_in_stop(void); +void pwr_voltage_regulator_low_power_in_stop(void); +void pwr_enable_wakeup_pin(void); +void pwr_disable_wakeup_pin(void); +bool pwr_voltage_high(void); +bool pwr_get_standby_flag(void); +bool pwr_get_wakeup_flag(void); + +END_DECLS + +/**@}*/ +#endif diff --git a/include/libopencm3/stm32/f1/pwr.h b/include/libopencm3/stm32/f1/pwr.h new file mode 100644 index 0000000..2875492 --- /dev/null +++ b/include/libopencm3/stm32/f1/pwr.h @@ -0,0 +1,40 @@ +/** @defgroup pwr_defines PWR Defines + +@brief Defined Constants and Types for the STM32F1xx PWR Control + +@ingroup STM32F1xx_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2012 Ken Sarkies + +@date 5 December 2012 + +LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_PWR_H +#define LIBOPENCM3_PWR_H + +#include +#include + +#endif + diff --git a/include/libopencm3/stm32/f4/pwr.h b/include/libopencm3/stm32/f4/pwr.h index 25fb163..c9b27fd 100644 --- a/include/libopencm3/stm32/f4/pwr.h +++ b/include/libopencm3/stm32/f4/pwr.h @@ -1,3 +1,15 @@ +/** @defgroup pwr_defines PWR Defines + +@brief Defined Constants and Types for the STM32F4xx Power Control + +@ingroup STM32F4xx_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2011 Stephen Caudle + +LGPL License Terms @ref lgpl_license + */ /* * This file is part of the libopencm3 project. * @@ -17,10 +29,11 @@ * along with this library. If not, see . */ -#ifndef LIBOPENCM3_PWR_F4_H -#define LIBOPENCM3_PWR_F4_H +#ifndef LIBOPENCM3_PWR_H +#define LIBOPENCM3_PWR_H -#include +#include +#include /* * This file extends the common STM32 version with definitions only diff --git a/include/libopencm3/stm32/l1/pwr.h b/include/libopencm3/stm32/l1/pwr.h index 41992d7..e976d46 100644 --- a/include/libopencm3/stm32/l1/pwr.h +++ b/include/libopencm3/stm32/l1/pwr.h @@ -1,3 +1,18 @@ +/** @defgroup pwr_defines PWR Defines + +@brief Defined Constants and Types for the STM32L1xx Power Control + +@ingroup STM32L1xx_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2011 Stephen Caudle +@author @htmlonly © @endhtmlonly 2012 Karl Palsson + +@date 1 July 2012 + +LGPL License Terms @ref lgpl_license + */ /* * This file is part of the libopencm3 project. * @@ -18,10 +33,11 @@ * along with this library. If not, see . */ -#ifndef LIBOPENCM3_PWR_L1_H -#define LIBOPENCM3_PWR_L1_H +#ifndef LIBOPENCM3_PWR_H +#define LIBOPENCM3_PWR_H -#include +#include +#include /* * This file extends the common STM32 version with definitions only @@ -33,47 +49,52 @@ /* Bits [31:15]: Reserved */ /* LPRUN: Low power run mode */ -#define PWR_CR_LPRUN (1 << 14) +#define PWR_CR_LPRUN (1 << 14) /* VOS[12:11]: Regulator voltage scaling output selection */ -#define PWR_CR_VOS_LSB 11 +#define PWR_CR_VOS_LSB 11 /** @defgroup pwr_vos Voltage Scaling Output level selection @ingroup STM32F_pwr_defines @{*/ -#define PWR_CR_VOS_RANGE1 (0x1 << PWR_CR_VOS_LSB) -#define PWR_CR_VOS_RANGE2 (0x2 << PWR_CR_VOS_LSB) -#define PWR_CR_VOS_RANGE3 (0x3 << PWR_CR_VOS_LSB) +#define PWR_CR_VOS_RANGE1 (0x1 << PWR_CR_VOS_LSB) +#define PWR_CR_VOS_RANGE2 (0x2 << PWR_CR_VOS_LSB) +#define PWR_CR_VOS_RANGE3 (0x3 << PWR_CR_VOS_LSB) /**@}*/ -#define PWR_CR_VOS_MASK (0x3 << PWR_CR_VOS_LSB) +#define PWR_CR_VOS_MASK (0x3 << PWR_CR_VOS_LSB) /* FWU: Fast wakeup */ -#define PWR_CR_FWU (1 << 10) +#define PWR_CR_FWU (1 << 10) /* ULP: Ultralow power mode */ -#define PWR_CR_ULP (1 << 9) +#define PWR_CR_ULP (1 << 9) + +/* LPSDSR: Low-power deepsleep/sleep/low power run */ +#define PWR_CR_LPSDSR (1 << 0) /* masks common PWR_CR_LPDS */ /* --- PWR_CSR values ------------------------------------------------------- */ /* Bits [31:11]: Reserved */ /* EWUP3: Enable WKUP3 pin */ -#define PWR_CSR_EWUP3 (1 << 10) +#define PWR_CSR_EWUP3 (1 << 10) /* EWUP2: Enable WKUP2 pin */ -#define PWR_CSR_EWUP2 (1 << 9) +#define PWR_CSR_EWUP2 (1 << 9) /* EWUP1: Enable WKUP1 pin */ -#define PWR_CSR_EWUP1 PWR_CSR_EWUP +#define PWR_CSR_EWUP1 PWR_CSR_EWUP /* REGLPF : Regulator LP flag */ -#define PWR_CSR_REGLPF (1 << 5) +#define PWR_CSR_REGLPF (1 << 5) /* VOSF: Voltage Scaling select flag */ -#define PWR_CSR_VOSF (1 << 4) +#define PWR_CSR_VOSF (1 << 4) /* VREFINTRDYF: Internal voltage reference (VREFINT) ready flag */ #define PWR_CSR_VREFINTRDYF (1 << 3) + + /* --- Function prototypes ------------------------------------------------- */ typedef enum { diff --git a/include/libopencm3/stm32/l1/rcc.h b/include/libopencm3/stm32/l1/rcc.h index 21b073b..f301ce3 100644 --- a/include/libopencm3/stm32/l1/rcc.h +++ b/include/libopencm3/stm32/l1/rcc.h @@ -46,7 +46,7 @@ LGPL License Terms @ref lgpl_license #include #include -#include +#include /* --- RCC registers ------------------------------------------------------- */ diff --git a/include/libopencm3/stm32/pwr.h b/include/libopencm3/stm32/pwr.h index 34b2407..1d907a9 100644 --- a/include/libopencm3/stm32/pwr.h +++ b/include/libopencm3/stm32/pwr.h @@ -1,22 +1,8 @@ -/** @defgroup STM32F_pwr_defines PWR Defines +/* This provides unification of code over STM32F subfamilies */ -@ingroup STM32F_defines - -@brief libopencm3 STM32F Power Control - -@version 1.0.0 - -@author @htmlonly © @endhtmlonly 2010 Thomas Otto - -@date 17 August 2012 - -LGPL License Terms @ref lgpl_license - */ /* * This file is part of the libopencm3 project. * - * Copyright (C) 2010 Thomas Otto - * * This library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or @@ -31,101 +17,15 @@ LGPL License Terms @ref lgpl_license * along with this library. If not, see . */ -/**@{*/ - -#ifndef LIBOPENCM3_PWR_H -#define LIBOPENCM3_PWR_H - -#include -#include - -/* --- PWR registers ------------------------------------------------------- */ - -/* Power control register (PWR_CR) */ -#define PWR_CR MMIO32(POWER_CONTROL_BASE + 0x00) - -/* Power control/status register (PWR_CSR) */ -#define PWR_CSR MMIO32(POWER_CONTROL_BASE + 0x04) - -/* --- PWR_CR values ------------------------------------------------------- */ - -/* Bits [31:9]: Reserved, must be kept at reset value. */ - -/* DBP: Disable backup domain write protection */ -#define PWR_CR_DBP (1 << 8) - -/* PLS[7:5]: PVD level selection */ -#define PWR_CR_PLS_LSB 5 -/** @defgroup pwr_pls PVD level selection -@ingroup STM32F_pwr_defines - -@{*/ -#define PWR_CR_PLS_2V2 (0x0 << PWR_CR_PLS_LSB) -#define PWR_CR_PLS_2V3 (0x1 << PWR_CR_PLS_LSB) -#define PWR_CR_PLS_2V4 (0x2 << PWR_CR_PLS_LSB) -#define PWR_CR_PLS_2V5 (0x3 << PWR_CR_PLS_LSB) -#define PWR_CR_PLS_2V6 (0x4 << PWR_CR_PLS_LSB) -#define PWR_CR_PLS_2V7 (0x5 << PWR_CR_PLS_LSB) -#define PWR_CR_PLS_2V8 (0x6 << PWR_CR_PLS_LSB) -#define PWR_CR_PLS_2V9 (0x7 << PWR_CR_PLS_LSB) -/**@}*/ -#define PWR_CR_PLS_MASK (0x7 << PWR_CR_PLS_LSB) - -/* PVDE: Power voltage detector enable */ -#define PWR_CR_PVDE (1 << 4) - -/* CSBF: Clear standby flag */ -#define PWR_CR_CSBF (1 << 3) - -/* CWUF: Clear wakeup flag */ -#define PWR_CR_CWUF (1 << 2) - -/* PDDS: Power down deepsleep */ -#define PWR_CR_PDDS (1 << 1) - -/* LPDS: Low-power deepsleep */ -#define PWR_CR_LPDS (1 << 0) - -/* --- PWR_CSR values ------------------------------------------------------ */ - -/* Bits [31:9]: Reserved, must be kept at reset value. */ - -/* EWUP: Enable WKUP pin */ -#define PWR_CSR_EWUP (1 << 8) - -/* Bits [7:3]: Reserved, must be kept at reset value. */ - -/* PVDO: PVD output */ -#define PWR_CSR_PVDO (1 << 2) - -/* SBF: Standby flag */ -#define PWR_CSR_SBF (1 << 1) - -/* WUF: Wakeup flag */ -#define PWR_CSR_WUF (1 << 0) - -/* --- PWR function prototypes ------------------------------------------- */ - -BEGIN_DECLS - -void pwr_disable_backup_domain_write_protect(void); -void pwr_enable_backup_domain_write_protect(void); -void pwr_enable_power_voltage_detect(u32 pvd_level); -void pwr_disable_power_voltage_detect(void); -void pwr_clear_standby_flag(void); -void pwr_clear_wakeup_flag(void); -void pwr_set_standby_mode(void); -void pwr_set_stop_mode(void); -void pwr_voltage_regulator_on_in_stop(void); -void pwr_voltage_regulator_low_power_in_stop(void); -void pwr_enable_wakeup_pin(void); -void pwr_disable_wakeup_pin(void); -bool pwr_voltage_high(void); -bool pwr_get_standby_flag(void); -bool pwr_get_wakeup_flag(void); - -END_DECLS - +#if defined(STM32F1) +# include +#elif defined(STM32F2) +# include +#elif defined(STM32F4) +# include +#elif defined(STM32L1) +# include +#else +# error "stm32 family not defined." #endif -/**@}*/ diff --git a/lib/stm32/common/pwr_common_all.c b/lib/stm32/common/pwr_common_all.c new file mode 100644 index 0000000..451ed1c --- /dev/null +++ b/lib/stm32/common/pwr_common_all.c @@ -0,0 +1,217 @@ +/** @defgroup STM32F1xx-pwr-file PWR + +@ingroup STM32F1xx + +@brief libopencm3 STM32F1xx Power Control + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2012 Ken Sarkies + +@date 18 August 2012 + +This library supports the power control system for the +STM32F1 series of ARM Cortex Microcontrollers by ST Microelectronics. + +LGPL License Terms @ref lgpl_license +*/ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Ken Sarkies + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include + +/*---------------------------------------------------------------------------*/ +/** @brief Disable Backup Domain Write Protection. + +This allows backup domain registers to be changed. These registers are write +protected after a reset. +*/ + +void pwr_disable_backup_domain_write_protect(void) +{ + PWR_CR |= PWR_CR_DBP; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Re-enable Backup Domain Write Protection. + +This protects backup domain registers from inadvertent change. +*/ + +void pwr_enable_backup_domain_write_protect(void) +{ + PWR_CR &= ~PWR_CR_DBP; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Enable Power Voltage Detector. + +This provides voltage level threshold detection. The result of detection is +provided in the power voltage detector output flag (see @ref pwr_voltage_high) +or by setting the EXTI16 interrupt (see datasheet for configuration details). + +@param[in] pvd_level u32. Taken from @ref pwr_pls. +*/ + +void pwr_enable_power_voltage_detect(u32 pvd_level) +{ + PWR_CR &= ~PWR_CR_PLS_MASK; + PWR_CR |= (PWR_CR_PVDE | pvd_level); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Disable Power Voltage Detector. + +*/ + +void pwr_disable_power_voltage_detect(void) +{ + PWR_CR &= ~PWR_CR_PVDE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Clear the Standby Flag. + +This is set when the processor returns from a standby mode. +*/ + +void pwr_clear_standby_flag(void) +{ + PWR_CR |= PWR_CR_CSBF; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Clear the Wakeup Flag. + +This is set when the processor receives a wakeup signal. +*/ + +void pwr_clear_wakeup_flag(void) +{ + PWR_CR |= PWR_CR_CWUF; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Set Standby Mode in Deep Sleep. + +*/ + +void pwr_set_standby_mode(void) +{ + PWR_CR |= PWR_CR_PDDS; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Set Stop Mode in Deep Sleep. + +*/ + +void pwr_set_stop_mode(void) +{ + PWR_CR &= ~PWR_CR_PDDS; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Voltage Regulator On in Stop Mode. + +*/ + +void pwr_voltage_regulator_on_in_stop(void) +{ + PWR_CR &= ~PWR_CR_LPDS; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Voltage Regulator Low Power in Stop Mode. + +*/ + +void pwr_voltage_regulator_low_power_in_stop(void) +{ + PWR_CR |= PWR_CR_LPDS; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Enable Wakeup Pin. + +The wakeup pin is used for waking the processor from standby mode. +*/ + +void pwr_enable_wakeup_pin(void) +{ + PWR_CSR |= PWR_CSR_EWUP; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Release Wakeup Pin. + +The wakeup pin is used for general purpose I/O. +*/ + +void pwr_disable_wakeup_pin(void) +{ + PWR_CSR &= ~PWR_CSR_EWUP; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Get Voltage Detector Output. + +The voltage detector threshold must be set when the power voltage detector is +enabled, see @ref pwr_enable_power_voltage_detect. + +@returns boolean: TRUE if the power voltage is above the preset voltage +threshold. +*/ + +bool pwr_voltage_high(void) +{ + return (PWR_CSR & PWR_CSR_PVDO); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Get Standby Flag. + +The standby flag is set when the processor returns from a standby state. It is +cleared by software (see @ref pwr_clear_standby_flag). + +@returns boolean: TRUE if the processor was in standby state. +*/ + +bool pwr_get_standby_flag(void) +{ + return (PWR_CSR & PWR_CSR_SBF); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Get Wakeup Flag. + +The wakeup flag is set when a wakeup event has been received. It is +cleared by software (see @ref pwr_clear_wakeup_flag). + +@returns boolean: TRUE if a wakeup event was received. +*/ + +bool pwr_get_wakeup_flag(void) +{ + return (PWR_CSR & PWR_CSR_WUF); +} +/**@}*/ + diff --git a/lib/stm32/f1/Makefile b/lib/stm32/f1/Makefile index 6bc21f7..ba0d4b8 100644 --- a/lib/stm32/f1/Makefile +++ b/lib/stm32/f1/Makefile @@ -30,7 +30,7 @@ CFLAGS = -Os -g -Wall -Wextra -I../../../include -fno-common \ ARFLAGS = rcs OBJS = rcc.o gpio.o adc.o flash.o rtc.o dma.o exti.o ethernet.o \ usb_f103.o usb.o usb_control.o usb_standard.o can.o \ - timer.o usb_f107.o desig.o pwr.o \ + timer.o usb_f107.o desig.o pwr_common_all.o \ usb_fx07_common.o \ gpio_common_all.o dma_common_f13.o spi_common_all.o \ dac_common_all.o usart_common_all.o iwdg_common_all.o \ diff --git a/lib/stm32/f4/Makefile b/lib/stm32/f4/Makefile index 2b02281..ee7f953 100644 --- a/lib/stm32/f4/Makefile +++ b/lib/stm32/f4/Makefile @@ -32,6 +32,7 @@ ARFLAGS = rcs OBJS = rcc.o gpio.o flash.o exti2.o pwr.o timer.o \ usb.o usb_standard.o usb_control.o usb_fx07_common.o usb_f107.o \ usb_f207.o adc.o dma.o \ + pwr_common_all.o \ gpio_common_all.o gpio_common_f24.o dma_common_f24.o spi_common_all.o \ dac_common_all.o usart_common_all.o iwdg_common_all.o i2c_common_all.o \ crc_common_all.o diff --git a/lib/stm32/l1/Makefile b/lib/stm32/l1/Makefile index 32c8fd3..c4e767f 100644 --- a/lib/stm32/l1/Makefile +++ b/lib/stm32/l1/Makefile @@ -31,7 +31,7 @@ ARFLAGS = rcs OBJS = rcc.o desig.o crc.o usart.o exti2.o flash.o timer.o OBJS += gpio_common_all.o gpio_common_f24.o spi_common_all.o crc_common_all.o OBJS += dac_common_all.o usart_common_all.o iwdg_common_all.o i2c_common_all.o -OBJS += pwr_chipset.o # TODO, get pwr.o to fix f2/f4 first... pwr.o +OBJS += pwr_common_all.o pwr.o VPATH += ../../usb:../:../../cm3:../common diff --git a/lib/stm32/l1/pwr.c b/lib/stm32/l1/pwr.c new file mode 100644 index 0000000..8541851 --- /dev/null +++ b/lib/stm32/l1/pwr.c @@ -0,0 +1,37 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include + +void pwr_set_vos_scale(vos_scale_t scale) +{ + PWR_CR &= ~(PWR_CR_VOS_MASK); + switch (scale) { + case RANGE1: + PWR_CR |= PWR_CR_VOS_RANGE1; + break; + case RANGE2: + PWR_CR |= PWR_CR_VOS_RANGE2; + break; + case RANGE3: + PWR_CR |= PWR_CR_VOS_RANGE3; + break; + } +} + diff --git a/lib/stm32/l1/pwr_chipset.c b/lib/stm32/l1/pwr_chipset.c deleted file mode 100644 index 9f4f599..0000000 --- a/lib/stm32/l1/pwr_chipset.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2012 Karl Palsson - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - */ - -#include - -void pwr_set_vos_scale(vos_scale_t scale) -{ - PWR_CR &= ~(PWR_CR_VOS_MASK); - switch (scale) { - case RANGE1: - PWR_CR |= PWR_CR_VOS_RANGE1; - break; - case RANGE2: - PWR_CR |= PWR_CR_VOS_RANGE2; - break; - case RANGE3: - PWR_CR |= PWR_CR_VOS_RANGE3; - break; - } -} - diff --git a/lib/stm32/l1/rcc.c b/lib/stm32/l1/rcc.c index 4864731..b2fce8c 100644 --- a/lib/stm32/l1/rcc.c +++ b/lib/stm32/l1/rcc.c @@ -23,7 +23,7 @@ #include #include -#include +#include /* Set the default ppre1 and ppre2 peripheral clock frequencies after reset. */ u32 rcc_ppre1_frequency = 2097000; -- cgit v1.2.3 From 2306c907abc5d7e0f54318a6c14bf198706cee0b Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Tue, 22 Jan 2013 22:43:48 +0000 Subject: [l1] Update to newest ref man definitions Support for the Medium+ and High density parts, mostly by way of extra irqs and register definitions. --- include/libopencm3/stm32/l1/irq.yaml | 19 ++++++++++++++++--- include/libopencm3/stm32/l1/memorymap.h | 7 +++++-- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/include/libopencm3/stm32/l1/irq.yaml b/include/libopencm3/stm32/l1/irq.yaml index c2f118f..a10e96c 100644 --- a/include/libopencm3/stm32/l1/irq.yaml +++ b/include/libopencm3/stm32/l1/irq.yaml @@ -4,8 +4,8 @@ partname_doxygen: STM32L1 irqs: - wwdg - pvd - - tamper - - rtc + - tamper_stamp + - rtc_wkup - flash - rcc - exti0 @@ -44,6 +44,19 @@ irqs: - usart3 - exti15_10 - rtc_alarm - - usb_wakeup + - usb_fs_wakeup - tim6 - tim7 + # below here is medium+/high density + - sdio + - tim5 + - spi3 + - uart4 + - uart5 + - dma2_ch1 + - dma2_ch2 + - dma2_ch3 + - dma2_ch4 + - dma2_ch5 + - aes + - comp_acq \ No newline at end of file diff --git a/include/libopencm3/stm32/l1/memorymap.h b/include/libopencm3/stm32/l1/memorymap.h index d89dbd6..60f1c57 100644 --- a/include/libopencm3/stm32/l1/memorymap.h +++ b/include/libopencm3/stm32/l1/memorymap.h @@ -47,7 +47,6 @@ #define IWDG_BASE (PERIPH_BASE_APB1 + 0x3000) /* PERIPH_BASE_APB1 + 0x3400 (0x4000 3400 - 0x4000 37FF): Reserved */ #define SPI2_BASE (PERIPH_BASE_APB1 + 0x3800) -// datasheet has an error? here #define SPI3_BASE (PERIPH_BASE_APB1 + 0x3c00) /* PERIPH_BASE_APB1 + 0x4000 (0x4000 4000 - 0x4000 3FFF): Reserved */ #define USART2_BASE (PERIPH_BASE_APB1 + 0x4400) @@ -61,6 +60,7 @@ /* gap */ #define POWER_CONTROL_BASE (PERIPH_BASE_APB1 + 0x7000) #define DAC_BASE (PERIPH_BASE_APB1 + 0x7400) +#define OPAMP_BASE (PERIPH_BASE_APB1 + 0x7c5c) #define COMP_BASE (PERIPH_BASE_APB1 + 0x7c00) #define ROUTING_BASE (PERIPH_BASE_APB1 + 0x7c04) @@ -85,13 +85,16 @@ #define GPIO_PORT_D_BASE (PERIPH_BASE_AHB + 0x00c00) #define GPIO_PORT_E_BASE (PERIPH_BASE_AHB + 0x01000) #define GPIO_PORT_H_BASE (PERIPH_BASE_AHB + 0x01400) +#define GPIO_PORT_F_BASE (PERIPH_BASE_AHB + 0x01800) +#define GPIO_PORT_G_BASE (PERIPH_BASE_AHB + 0x01c00) /* gap */ #define CRC_BASE (PERIPH_BASE_AHB + 0x03000) /* gap */ #define RCC_BASE (PERIPH_BASE_AHB + 0x03800) #define FLASH_MEM_INTERFACE_BASE (PERIPH_BASE_AHB + 0x03c00) /* gap */ -#define DMA_BASE (PERIPH_BASE_AHB + 0x06000) +#define DMA1_BASE (PERIPH_BASE_AHB + 0x06000) +#define DMA2_BASE (PERIPH_BASE_AHB + 0x04000) /* PPIB */ #define DBGMCU_BASE (PPBI_BASE + 0x00042000) -- cgit v1.2.3 From b6ee57a5b9fbac7fb1cfe62b6ed8a341bee5543e Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Tue, 22 Jan 2013 22:52:36 +0000 Subject: [l1] rcc: support MSI clocking Some new definitions and helpers. Main change really that the list of preconfigured clock configs is no longer restricted to HSI/PLL --- include/libopencm3/stm32/l1/rcc.h | 44 +++++++++++++++++++++---- lib/stm32/l1/rcc.c | 68 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 105 insertions(+), 7 deletions(-) diff --git a/include/libopencm3/stm32/l1/rcc.h b/include/libopencm3/stm32/l1/rcc.h index f301ce3..a751def 100644 --- a/include/libopencm3/stm32/l1/rcc.h +++ b/include/libopencm3/stm32/l1/rcc.h @@ -82,11 +82,31 @@ LGPL License Terms @ref lgpl_license #define RCC_CR_RTCPRE_DIV2 0 #define RCC_CR_RTCPRE_DIV4 1 #define RCC_CR_RTCPRE_DIV8 2 -#define RCC_CR_RTCPRE_DIV18 3 +#define RCC_CR_RTCPRE_DIV16 3 +#define RCC_CR_RTCPRE_SHIFT 29 +#define RCC_CR_RTCPRE_MASK 0x3 /* --- RCC_ICSCR values ---------------------------------------------------- */ -// TODO +#define RCC_ICSCR_MSITRIM_SHIFT 24 +#define RCC_ICSCR_MSITRIM_MASK 0xff +#define RCC_ICSCR_MSICAL_SHIFT 16 +#define RCC_ICSCR_MSICAL_MASK 0xff + +#define RCC_ICSCR_MSIRANGE_SHIFT 13 +#define RCC_ICSCR_MSIRANGE_MASK 0x7 +#define RCC_ICSCR_MSIRANGE_65KHZ 0x0 +#define RCC_ICSCR_MSIRANGE_131KHZ 0x1 +#define RCC_ICSCR_MSIRANGE_262KHZ 0x2 +#define RCC_ICSCR_MSIRANGE_524KHZ 0x3 +#define RCC_ICSCR_MSIRANGE_1MHZ 0x4 +#define RCC_ICSCR_MSIRANGE_2MHZ 0x5 +#define RCC_ICSCR_MSIRANGE_4MHZ 0x6 + +#define RCC_ICSCR_HSITRIM_SHIFT 8 +#define RCC_ICSCR_HSITRIM_MASK 0x1f +#define RCC_ICSCR_HSICAL_SHIFT 0 +#define RCC_ICSCR_HSICAL_MASK 0xff /* --- RCC_CFGR values ----------------------------------------------------- */ @@ -347,7 +367,14 @@ LGPL License Terms @ref lgpl_license #define RCC_CSR_RMVF (1 << 24) #define RCC_CSR_RTCRST (1 << 23) #define RCC_CSR_RTCEN (1 << 22) -/* RTCSEL[1:0] */ +#define RCC_CSR_RTCSEL_SHIFT (16) +#define RCC_CSR_RTCSEL_MASK (0x3) +#define RCC_CSR_RTCSEL_NONE (0x0) +#define RCC_CSR_RTCSEL_LSE (0x1) +#define RCC_CSR_RTCSEL_LSI (0x2) +#define RCC_CSR_RTCSEL_HSI (0x3) +#define RCC_CSR_LSECSSD (1 << 12) +#define RCC_CSR_LSECSSON (1 << 11) #define RCC_CSR_LSEBYP (1 << 10) #define RCC_CSR_LSERDY (1 << 9) #define RCC_CSR_LSEON (1 << 8) @@ -365,16 +392,20 @@ typedef struct { vos_scale_t voltage_scale; uint32_t apb1_frequency; uint32_t apb2_frequency; + uint8_t msi_range; } clock_scale_t; typedef enum { CLOCK_VRANGE1_HSI_PLL_24MHZ, CLOCK_VRANGE1_HSI_PLL_32MHZ, CLOCK_VRANGE1_HSI_RAW_16MHZ, - CLOCK_VRANGE1_END -} clock_volt_range1_t; + CLOCK_VRANGE1_HSI_RAW_4MHZ, + CLOCK_VRANGE1_MSI_RAW_4MHZ, + CLOCK_VRANGE1_MSI_RAW_2MHZ, + CLOCK_CONFIG_END +} clock_config_entry_t; -extern const clock_scale_t clock_vrange1_config[CLOCK_VRANGE1_END]; +extern const clock_scale_t clock_config[CLOCK_CONFIG_END]; /* --- Variable definitions ------------------------------------------------ */ @@ -413,6 +444,7 @@ void rcc_set_ppre1(u32 ppre1); void rcc_set_hpre(u32 hpre); void rcc_set_usbpre(u32 usbpre); u32 rcc_get_system_clock_source(int i); +void rcc_clock_setup_msi(const clock_scale_t *clock); void rcc_clock_setup_hsi(const clock_scale_t *clock); void rcc_clock_setup_pll(const clock_scale_t *clock); void rcc_backupdomain_reset(void); diff --git a/lib/stm32/l1/rcc.c b/lib/stm32/l1/rcc.c index b2fce8c..c1d8fa9 100644 --- a/lib/stm32/l1/rcc.c +++ b/lib/stm32/l1/rcc.c @@ -29,7 +29,8 @@ u32 rcc_ppre1_frequency = 2097000; u32 rcc_ppre2_frequency = 2097000; -const clock_scale_t clock_vrange1_config[CLOCK_VRANGE1_END] ={ +const clock_scale_t clock_config[CLOCK_CONFIG_END] = +{ { /* 24MHz PLL from HSI */ .pll_source = RCC_CFGR_PLLSRC_HSI_CLK, .pll_mul = RCC_CFGR_PLLMUL_MUL3, @@ -63,6 +64,35 @@ const clock_scale_t clock_vrange1_config[CLOCK_VRANGE1_END] ={ .apb1_frequency = 16000000, .apb2_frequency = 16000000, }, + { /* 4MHz HSI raw */ + .hpre = RCC_CFGR_HPRE_SYSCLK_DIV4, + .ppre1 = RCC_CFGR_PPRE1_HCLK_NODIV, + .ppre2 = RCC_CFGR_PPRE2_HCLK_NODIV, + .voltage_scale = RANGE1, + .flash_config = FLASH_LATENCY_0WS, + .apb1_frequency = 4000000, + .apb2_frequency = 4000000, + }, + { /* 4MHz MSI raw */ + .hpre = RCC_CFGR_HPRE_SYSCLK_NODIV, + .ppre1 = RCC_CFGR_PPRE1_HCLK_NODIV, + .ppre2 = RCC_CFGR_PPRE2_HCLK_NODIV, + .voltage_scale = RANGE1, + .flash_config = FLASH_LATENCY_0WS, + .apb1_frequency = 4194000, + .apb2_frequency = 4194000, + .msi_range = RCC_ICSCR_MSIRANGE_4MHZ, + }, + { /* 2MHz MSI raw */ + .hpre = RCC_CFGR_HPRE_SYSCLK_NODIV, + .ppre1 = RCC_CFGR_PPRE1_HCLK_NODIV, + .ppre2 = RCC_CFGR_PPRE2_HCLK_NODIV, + .voltage_scale = RANGE1, + .flash_config = FLASH_LATENCY_0WS, + .apb1_frequency = 2097000, + .apb2_frequency = 2097000, + .msi_range = RCC_ICSCR_MSIRANGE_2MHZ, + }, }; void rcc_osc_ready_int_clear(osc_t osc) @@ -407,6 +437,42 @@ u32 rcc_system_clock_source(void) return ((RCC_CFGR & 0x000c) >> 2); } +void rcc_clock_setup_msi(const clock_scale_t *clock) +{ + /* Enable internal multi-speed oscillator. */ + + u32 reg = RCC_ICSCR; + reg &= ~(RCC_ICSCR_MSIRANGE_MASK << RCC_ICSCR_MSIRANGE_SHIFT); + reg |= (clock->msi_range << RCC_ICSCR_MSIRANGE_SHIFT); + RCC_ICSCR = reg; + + rcc_osc_on(MSI); + rcc_wait_for_osc_ready(MSI); + + /* Select MSI as SYSCLK source. */ + rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_MSICLK); + + /* + * Set prescalers for AHB, ADC, ABP1, ABP2. + * Do this before touching the PLL (TODO: why?). + */ + rcc_set_hpre(clock->hpre); + rcc_set_ppre1(clock->ppre1); + rcc_set_ppre2(clock->ppre2); + + pwr_set_vos_scale(clock->voltage_scale); + + // I guess this should be in the settings? + flash_64bit_enable(); + flash_prefetch_enable(); + /* Configure flash settings. */ + flash_set_ws(clock->flash_config); + + /* Set the peripheral clock frequencies used. */ + rcc_ppre1_frequency = clock->apb1_frequency; + rcc_ppre2_frequency = clock->apb2_frequency; +} + void rcc_clock_setup_hsi(const clock_scale_t *clock) { /* Enable internal high-speed oscillator. */ -- cgit v1.2.3 From e5b32503825c53d278d09a34d7165020e1b5cad4 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Tue, 22 Jan 2013 23:37:54 +0000 Subject: [stm32] Support the "new" BCD style RTC peripheral Add the register definitions and some of the most basic helper functions for the new style BCD RTC module found on the F2, F4, L1, F3 and F0. This tries to keep as close to HACKING_COMMON_DOC as possible, while maintaining sane names. --- include/libopencm3/stm32/common/rtc_common_bcd.h | 302 +++++++++++++++++++++++ include/libopencm3/stm32/f1/rtc.h | 5 + include/libopencm3/stm32/f2/rtc.h | 39 +++ include/libopencm3/stm32/f4/rtc.h | 39 +++ include/libopencm3/stm32/l1/rtc.h | 39 +++ include/libopencm3/stm32/rtc.h | 31 +++ lib/stm32/common/rtc_common_bcd.c | 78 ++++++ lib/stm32/f2/Makefile | 3 +- lib/stm32/f2/rtc.c | 27 ++ lib/stm32/f4/Makefile | 3 +- lib/stm32/f4/rtc.c | 27 ++ lib/stm32/l1/Makefile | 1 + lib/stm32/l1/rtc.c | 27 ++ 13 files changed, 619 insertions(+), 2 deletions(-) create mode 100644 include/libopencm3/stm32/common/rtc_common_bcd.h create mode 100644 include/libopencm3/stm32/f2/rtc.h create mode 100644 include/libopencm3/stm32/f4/rtc.h create mode 100644 include/libopencm3/stm32/l1/rtc.h create mode 100644 include/libopencm3/stm32/rtc.h create mode 100644 lib/stm32/common/rtc_common_bcd.c create mode 100644 lib/stm32/f2/rtc.c create mode 100644 lib/stm32/f4/rtc.c create mode 100644 lib/stm32/l1/rtc.c diff --git a/include/libopencm3/stm32/common/rtc_common_bcd.h b/include/libopencm3/stm32/common/rtc_common_bcd.h new file mode 100644 index 0000000..130020e --- /dev/null +++ b/include/libopencm3/stm32/common/rtc_common_bcd.h @@ -0,0 +1,302 @@ +/** @addtogroup rtc_defines */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY, BUT ONLY VIA RTC.H */ + +/* + * This covers the "version 2" RTC peripheral. This is completely different + * to the v1 RTC periph on the F1 series devices. It has BCD counters, with + * automatic leapyear corrections and daylight savings support. + * This peripheral is used on the F0, F2, F3, F4 and L1 devices, though some + * only support a subset. + */ + +#ifndef LIBOPENCM3_RTC2_H +#define LIBOPENCM3_RTC2_H + +/**@{*/ + +#include +#include + +/* RTC time register (RTC_TR) */ +#define RTC_TR MMIO32(RTC_BASE + 0x00) + +/* RTC date register (RTC_DR) */ +#define RTC_DR MMIO32(RTC_BASE + 0x04) + +/* RTC control register (RTC_CR) */ +#define RTC_CR MMIO32(RTC_BASE + 0x08) + +/* RTC initialization and status register (RTC_ISR) */ +#define RTC_ISR MMIO32(RTC_BASE + 0x0c) + +/* RTC prescaler register (RTC_PRER) */ +#define RTC_PRER MMIO32(RTC_BASE + 0x10) + +/* RTC wakeup timer register (RTC_WUTR) */ +#define RTC_WUTR MMIO32(RTC_BASE + 0x14) + +/* RTC calibration register (RTC_CALIBR) NB: see also RTC_CALR */ +#define RTC_CALIBR MMIO32(RTC_BASE + 0x18) + +/* RTC alarm X register (RTC_ALRMxR) */ +#define RTC_ALRMAR MMIO32(RTC_BASE + 0x1c) +#define RTC_ALRMBR MMIO32(RTC_BASE + 0x20) + +/* RTC write protection register (RTC_WPR)*/ +#define RTC_WPR MMIO32(RTC_BASE + 0x24) + +/* RTC sub second register (RTC_SSR) (high and med+ only) */ +#define RTC_SSR MMIO32(RTC_BASE + 0x28) + +/* RTC shift control register (RTC_SHIFTR) (high and med+ only) */ +#define RTC_SHIFTR MMIO32(RTC_BASE + 0x2c) + +/* RTC time stamp time register (RTC_TSTR) */ +#define RTC_TSTR MMIO32(RTC_BASE + 0x30) +/* RTC time stamp date register (RTC_TSDR) */ +#define RTC_TSDR MMIO32(RTC_BASE + 0x34) +/* RTC timestamp sub second register (RTC_TSSSR) (high and med+ only) */ +#define RTC_TSSSR MMIO32(RTC_BASE + 0x38) + +/* RTC calibration register (RTC_CALR) (high and med+ only) */ +#define RTC_CALR MMIO32(RTC_BASE + 0x3c) + +/* RTC tamper and alternate function configuration register (RTC_TAFCR) */ +#define RTC_TAFCR MMIO32(RTC_BASE + 0x40) + +/* RTC alarm X sub second register (RTC_ALRMxSSR) (high and med+ only) */ +#define RTC_ALRMASSR MMIO32(RTC_BASE + 0x44) +#define RTC_ALRMBSSR MMIO32(RTC_BASE + 0x48) + +/* RTC backup registers (RTC_BKPxR) */ +#define RTC_BKP_BASE (RTC_BASE + 0x50) +#define RTC_BKPXR(reg) MMIO32(RTC_BKP_BASE + (4*reg)) + + +/* RTC time register (RTC_TR) bits */ +#define RTC_TR_TR_PM (1 << 22) +#define RTC_TR_HT_SHIFT (20) +#define RTC_TR_HT_MASK (0x3) +#define RTC_TR_HU_SHIFT (16) +#define RTC_TR_HU_MASK (0xf) +#define RTC_TR_MNT_SHIFT (12) +#define RTC_TR_MNT_MASK (0x7) +#define RTC_TR_MNU_SHIFT (8) +#define RTC_TR_MNU_MASK (0xf) +#define RTC_TR_ST_SHIFT (4) +#define RTC_TR_ST_MASK (0x3) +#define RTC_TR_SU_SHIFT (0) +#define RTC_TR_SU_MASK (0xf) + +/* RTC date register (RTC_DR) bits */ +#define RTC_DR_YT_SHIFT (20) +#define RTC_DR_YT_MASK (0xf) +#define RTC_DR_YU_SHIFT (16) +#define RTC_DR_YU_MASK (0xf) +#define RTC_DR_WDU_SHIFT (13) +#define RTC_DR_WDU_MASK (0x7) +#define RTC_DR_MT (1<<12) +#define RTC_DR_MU_SHIFT (8) +#define RTC_DR_MU_MASK (0xf) +#define RTC_DR_DT_SHIFT (4) +#define RTC_DR_DT_MASK (0x3) +#define RTC_DR_DU_SHIFT (0) +#define RTC_DR_DU_MASK (0xf) + +/* RTC control register (RTC_CR) bits */ +#define RTC_CR_COE (1<<23) + +/* These bits are used to select the flag to be routed to AFO_ALARM RTC output */ +#define RTC_CR_OSEL_SHIFT 21 +#define RTC_CR_OSEL_MASK (0x3) +#define RTC_CR_OSEL_DISABLED (0x0) +#define RTC_CR_OSEL_ALARMA (0x1) +#define RTC_CR_OSEL_ALARMB (0x2) +#define RTC_CR_OSEL_WAKEUP (0x3) + +#define RTC_CR_POL (1<<20) +#define RTC_CR_COSEL (1<<19) +#define RTC_CR_BKP (1<<18) +#define RTC_CR_SUB1H (1<<17) +#define RTC_CR_ADD1H (1<<16) +#define RTC_CR_TSIE (1<<15) +#define RTC_CR_WUTIE (1<<14) +#define RTC_CR_ALRBIE (1<<13) +#define RTC_CR_ALRAIE (1<<12) +#define RTC_CR_TSE (1<<11) +#define RTC_CR_WUTE (1<<10) +#define RTC_CR_ALRBE (1<<9) +#define RTC_CR_ALRAE (1<<8) +#define RTC_CR_DCE (1<<7) +#define RTC_CR_FMT (1<<6) +#define RTC_CR_BYPSHAD (1<<5) +#define RTC_CR_REFCKON (1<<4) +#define RTC_CR_TSEDGE (1<<3) +#define RTC_CR_TSEDGE (1<<3) +#define RTC_CR_WUCLKSEL_SHIFT (0) +#define RTC_CR_WUCLKSEL_MASK (0x7) +#define RTC_CR_WUCLKSEL_RTC_DIV16 (0x0) +#define RTC_CR_WUCLKSEL_RTC_DIV8 (0x1) +#define RTC_CR_WUCLKSEL_RTC_DIV4 (0x2) +#define RTC_CR_WUCLKSEL_RTC_DIV2 (0x3) +#define RTC_CR_WUCLKSEL_SPRE (0x4) +#define RTC_CR_WUCLKSEL_SPRE_216 (0x6) + +/* RTC initialization and status register (RTC_ISR) bits */ +#define RTC_ISR_RECALPF (1<<16) +#define RTC_ISR_TAMP3F (1<<15) +#define RTC_ISR_TAMP2F (1<<14) +#define RTC_ISR_TAMP1F (1<<13) +#define RTC_ISR_TSOVF (1<<12) +#define RTC_ISR_TSF (1<<11) +#define RTC_ISR_WUTF (1<<10) +#define RTC_ISR_ALRBF (1<<9) +#define RTC_ISR_ALRAF (1<<8) +#define RTC_ISR_INIT (1<<7) +#define RTC_ISR_INITF (1<<6) +#define RTC_ISR_RSF (1<<5) +#define RTC_ISR_INITS (1<<4) +#define RTC_ISR_SHPF (1<<3) +#define RTC_ISR_WUTWF (1<<2) +#define RTC_ISR_ALRBWF (1<<1) +#define RTC_ISR_ALRAWF (1<<0) + +/* RTC prescaler register (RTC_PRER) bits */ +#define RTC_PRER_PREDIV_A_SHIFT (16) +#define RTC_PRER_PREDIV_A_MASK (0x7f) +#define RTC_PRER_PREDIV_S_SHIFT (0) +#define RTC_PRER_PREDIV_S_MASK (0x7fff) + +/* RTC calibration register (RTC_CALIBR) bits */ +// FIXME - TODO + +/* RTC Alarm register bits Applies to RTC_ALRMAR and RTC_ALRMBR */ +#define RTC_ALRMXR_MSK4 (1<<31) +#define RTC_ALRMXR_WDSEL (1<<30) +#define RTC_ALRMXR_DT_SHIFT (28) +#define RTC_ALRMXR_DT_MASK (0x3) +#define RTC_ALRMXR_DU_SHIFT (24) +#define RTC_ALRMXR_DU_MASK (0xf) +#define RTC_ALRMXR_MSK3 (1<<23) +#define RTC_ALRMXR_PM (1<<22) +#define RTC_ALRMXR_HT_SHIFT (20) +#define RTC_ALRMXR_HT_MASK (0x3) +#define RTC_ALRMXR_HU_SHIFT (16) +#define RTC_ALRMXR_HU_MASK (0xf) +#define RTC_ALRMXR_MSK2 (1<<15) +#define RTC_ALRMXR_MNT_SHIFT (12) +#define RTC_ALRMXR_MNT_MASK (0x7) +#define RTC_ALRMXR_MNU_SHIFT (8) +#define RTC_ALRMXR_MNU_MASK (0xf) +#define RTC_ALRMXR_MSK1 (1<<7) +#define RTC_ALRMXR_ST_SHIFT (4) +#define RTC_ALRMXR_ST_MASK (0x7) +#define RTC_ALRMXR_SU_SHIFT (0) +#define RTC_ALRMXR_SU_MASK (0xf) + +/* RTC shift control register (RTC_SHIFTR) */ +// FIXME - TODO + +/* RTC time stamp time register (RTC_TSTR) bits */ +#define RTC_TSTR_PM (1<<22) +#define RTC_TSTR_HT_SHIFT (20) +#define RTC_TSTR_HT_MASK (0x3) +#define RTC_TSTR_HU_SHIFT (16) +#define RTC_TSTR_HU_MASK (0xf) +#define RTC_TSTR_MNT_SHIFT (12) +#define RTC_TSTR_MNT_MASK (0x7) +#define RTC_TSTR_MNU_SHIFT (8) +#define RTC_TSTR_MNU_MASK (0xf) +#define RTC_TSTR_ST_SHIFT (4) +#define RTC_TSTR_ST_MASK (0x7) +#define RTC_TSTR_SU_SHIFT (0) +#define RTC_TSTR_SU_MASK (0xf) + +/* RTC time stamp date register (RTC_TSDR) bits */ +#define RTC_TSDR_WDU_SHIFT (13) +#define RTC_TSDR_WDU_MASK (0x7) +#define RTC_TSDR_MT (1<<12) +#define RTC_TSDR_MU_SHIFT (8) +#define RTC_TSDR_MU_MASK (0xf) +#define RTC_TSDR_DT_SHIFT (4) +#define RTC_TSDR_DT_MASK (0x3) +#define RTC_TSDR_DU_SHIFT (0) +#define RTC_TSDR_DU_MASK (0xf) + +/* RTC calibration register (RTC_CALR) bits */ +// FIXME - TODO + +/* RTC tamper and alternate function configuration register (RTC_TAFCR) bits */ +#define RTC_TAFCR_ALARMOUTTYPE (1<<18) +#define RTC_TAFCR_TAMPPUDIS (1<<15) + +#define RTC_TAFCR_TAMPPRCH_SHIFT (13) +#define RTC_TAFCR_TAMPPRCH_MASK (0x3) +#define RTC_TAFCR_TAMPPRCH_1RTC (0x0) +#define RTC_TAFCR_TAMPPRCH_2RTC (0x1) +#define RTC_TAFCR_TAMPPRCH_4RTC (0x2) +#define RTC_TAFCR_TAMPPRCH_8RTC (0x3) + +#define RTC_TAFCR_TAMPFLT_SHIFT (11) +#define RTC_TAFCR_TAMPFLT_MASK (0x3) +#define RTC_TAFCR_TAMPFLT_EDGE1 (0x0) +#define RTC_TAFCR_TAMPFLT_EDGE2 (0x1) +#define RTC_TAFCR_TAMPFLT_EDGE4 (0x2) +#define RTC_TAFCR_TAMPFLT_EDGE8 (0x3) + +#define RTC_TAFCR_TAMPFREQ_SHIFT (8) +#define RTC_TAFCR_TAMPFREQ_MASK (0x7) +#define RTC_TAFCR_TAMPFREQ_RTCDIV32K (0x0) +#define RTC_TAFCR_TAMPFREQ_RTCDIV16K (0x1) +#define RTC_TAFCR_TAMPFREQ_RTCDIV8K (0x2) +#define RTC_TAFCR_TAMPFREQ_RTCDIV4K (0x3) +#define RTC_TAFCR_TAMPFREQ_RTCDIV2K (0x4) +#define RTC_TAFCR_TAMPFREQ_RTCDIV1K (0x5) +#define RTC_TAFCR_TAMPFREQ_RTCDIV512 (0x6) +#define RTC_TAFCR_TAMPFREQ_RTCDIV256 (0x7) + +#define RTC_TAFCR_TAMPTS (1<<7) +#define RTC_TAFCR_TAMP3TRG (1<<6) +#define RTC_TAFCR_TAMP3E (1<<5) +#define RTC_TAFCR_TAMP2TRG (1<<4) +#define RTC_TAFCR_TAMP2E (1<<3) +#define RTC_TAFCR_TAMPIE (1<<2) +#define RTC_TAFCR_TAMP1TRG (1<<1) +#define RTC_TAFCR_TAMP1E (1<<0) + +/* RTC alarm X sub second register */ +// FIXME - TODO + + + +BEGIN_DECLS + +void rtc_set_prescaler(u32 sync, u32 async); +void rtc_wait_for_synchro(void); +void rtc_lock(void); +void rtc_unlock(void); + +END_DECLS +/**@}*/ + +#endif /* RTC2_H */ + diff --git a/include/libopencm3/stm32/f1/rtc.h b/include/libopencm3/stm32/f1/rtc.h index 04aea01..a8a8966 100644 --- a/include/libopencm3/stm32/f1/rtc.h +++ b/include/libopencm3/stm32/f1/rtc.h @@ -17,6 +17,11 @@ * along with this library. If not, see . */ +/* + * The F1 RTC is a straight timestamp, a completely different peripheral to + * that found in the F2, F3, F4, L1 and F0. + */ + #ifndef LIBOPENCM3_RTC_H #define LIBOPENCM3_RTC_H diff --git a/include/libopencm3/stm32/f2/rtc.h b/include/libopencm3/stm32/f2/rtc.h new file mode 100644 index 0000000..ebc0936 --- /dev/null +++ b/include/libopencm3/stm32/f2/rtc.h @@ -0,0 +1,39 @@ +/** @defgroup rtc_defines RTC Defines + +@brief Defined Constants and Types for the STM32F2xx RTC + +@ingroup STM32F2xx_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2012 Ken Sarkies + +@date 5 December 2012 + +LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_RTC_H +#define LIBOPENCM3_RTC_H + +#include +#include + +#endif \ No newline at end of file diff --git a/include/libopencm3/stm32/f4/rtc.h b/include/libopencm3/stm32/f4/rtc.h new file mode 100644 index 0000000..ab8d3ee --- /dev/null +++ b/include/libopencm3/stm32/f4/rtc.h @@ -0,0 +1,39 @@ +/** @defgroup rtc_defines RTC Defines + +@brief Defined Constants and Types for the STM32F4xx RTC + +@ingroup STM32F4xx_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2012 Ken Sarkies + +@date 5 December 2012 + +LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_RTC_H +#define LIBOPENCM3_RTC_H + +#include +#include + +#endif \ No newline at end of file diff --git a/include/libopencm3/stm32/l1/rtc.h b/include/libopencm3/stm32/l1/rtc.h new file mode 100644 index 0000000..d364fb5 --- /dev/null +++ b/include/libopencm3/stm32/l1/rtc.h @@ -0,0 +1,39 @@ +/** @defgroup rtc_defines RTC Defines + +@brief Defined Constants and Types for the STM32L1xx RTC + +@ingroup STM32L1xx_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2012 Ken Sarkies + +@date 5 December 2012 + +LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_RTC_H +#define LIBOPENCM3_RTC_H + +#include +#include + +#endif \ No newline at end of file diff --git a/include/libopencm3/stm32/rtc.h b/include/libopencm3/stm32/rtc.h new file mode 100644 index 0000000..a927dd8 --- /dev/null +++ b/include/libopencm3/stm32/rtc.h @@ -0,0 +1,31 @@ +/* This provides unification of code over STM32 subfamilies */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#if defined(STM32F1) +# include +#elif defined(STM32F2) +# include +#elif defined(STM32F4) +# include +#elif defined(STM32L1) +# include +#else +# error "stm32 family not defined." +#endif + diff --git a/lib/stm32/common/rtc_common_bcd.c b/lib/stm32/common/rtc_common_bcd.c new file mode 100644 index 0000000..c302ea2 --- /dev/null +++ b/lib/stm32/common/rtc_common_bcd.c @@ -0,0 +1,78 @@ +/** @addtogroup rtc_file */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include + +/*---------------------------------------------------------------------------*/ +/** @brief Set RTC prescalars. + +This sets the RTC synchronous and asynchronous prescalars. +*/ + +void rtc_set_prescaler(u32 sync, u32 async) { + /* + * Even if only one of the two fields needs to be changed, + * 2 separate write accesses must be performed to the RTC_PRER register. + */ + RTC_PRER = (sync & RTC_PRER_PREDIV_S_MASK); + RTC_PRER |= (async << RTC_PRER_PREDIV_A_SHIFT); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Wait for RTC registers to be synchronised with the APB1 bus + + Time and Date are accessed through shadow registers which must be synchronized +*/ + +void rtc_wait_for_synchro(void) { + /* Unlock RTC registers */ + RTC_WPR = 0xca; + RTC_WPR = 0x53; + + RTC_ISR &= ~(RTC_ISR_RSF); + + while (!(RTC_ISR & RTC_ISR_RSF)) { + ; + } + /* disable write protection again */ + RTC_WPR = 0xff; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Unlock write access to the RTC registers + +*/ +void rtc_unlock(void) { + RTC_WPR = 0xca; + RTC_WPR = 0x53; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Lock write access to the RTC registers + +*/ +void rtc_lock(void) { + RTC_WPR = 0xff; +} + +/**@}*/ diff --git a/lib/stm32/f2/Makefile b/lib/stm32/f2/Makefile index 3d3c756..85e6458 100644 --- a/lib/stm32/f2/Makefile +++ b/lib/stm32/f2/Makefile @@ -31,7 +31,8 @@ ARFLAGS = rcs OBJS = rcc.o gpio.o flash.o exti2.o timer.o \ gpio_common_all.o gpio_common_f24.o dma_common_f24.o spi_common_all.o \ dac_common_all.o usart_common_all.o iwdg_common_all.o i2c_common_all.o \ - crc_common_all.o + crc_common_all.o \ + rtc_common_bcd.o VPATH += ../../usb:../:../../cm3:../common diff --git a/lib/stm32/f2/rtc.c b/lib/stm32/f2/rtc.c new file mode 100644 index 0000000..461d0b1 --- /dev/null +++ b/lib/stm32/f2/rtc.c @@ -0,0 +1,27 @@ +/** @defgroup rtc_file RTC + +@ingroup STM32F2xx + +@brief libopencm3 STM32F2xx RTC + +*/ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include diff --git a/lib/stm32/f4/Makefile b/lib/stm32/f4/Makefile index ee7f953..8ff7c6a 100644 --- a/lib/stm32/f4/Makefile +++ b/lib/stm32/f4/Makefile @@ -35,7 +35,8 @@ OBJS = rcc.o gpio.o flash.o exti2.o pwr.o timer.o \ pwr_common_all.o \ gpio_common_all.o gpio_common_f24.o dma_common_f24.o spi_common_all.o \ dac_common_all.o usart_common_all.o iwdg_common_all.o i2c_common_all.o \ - crc_common_all.o + crc_common_all.o \ + rtc_common_bcd.o VPATH += ../../usb:../:../../cm3:../common diff --git a/lib/stm32/f4/rtc.c b/lib/stm32/f4/rtc.c new file mode 100644 index 0000000..1b301fa --- /dev/null +++ b/lib/stm32/f4/rtc.c @@ -0,0 +1,27 @@ +/** @defgroup rtc_file RTC + +@ingroup STM32F4xx + +@brief libopencm3 STM32F4xx RTC + +*/ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include diff --git a/lib/stm32/l1/Makefile b/lib/stm32/l1/Makefile index c4e767f..9b677ab 100644 --- a/lib/stm32/l1/Makefile +++ b/lib/stm32/l1/Makefile @@ -32,6 +32,7 @@ OBJS = rcc.o desig.o crc.o usart.o exti2.o flash.o timer.o OBJS += gpio_common_all.o gpio_common_f24.o spi_common_all.o crc_common_all.o OBJS += dac_common_all.o usart_common_all.o iwdg_common_all.o i2c_common_all.o OBJS += pwr_common_all.o pwr.o +OBJS += rtc_common_bcd.o VPATH += ../../usb:../:../../cm3:../common diff --git a/lib/stm32/l1/rtc.c b/lib/stm32/l1/rtc.c new file mode 100644 index 0000000..bc7f87f --- /dev/null +++ b/lib/stm32/l1/rtc.c @@ -0,0 +1,27 @@ +/** @defgroup rtc_file RTC + +@ingroup STM32L1xx + +@brief libopencm3 STM32L1xx RTC + +*/ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include -- cgit v1.2.3 From d9fb4f7401b8bf546cc7e6ddeb9f22d343f0622d Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Wed, 23 Jan 2013 00:01:46 +0000 Subject: Add examples making use of the RTC Add an example using the RTC to help with a lower power design. This is a sister example to the existing "button-irq-printf", which is functionally identical, but uses far less power. There's more tricks that can be done to lower the power even further, but this shows a few of the early steps that can be done, using the RTC wakeup instead of a timer. --- examples/stm32/f1/other/rtc/rtc.c | 2 +- examples/stm32/f1/stm32vl-discovery/rtc/rtc.c | 2 +- .../button-irq-printf-lowpower/Makefile | 24 ++ .../button-irq-printf-lowpower/README | 18 ++ .../button-irq-printf-lowpower/main.c | 300 +++++++++++++++++++++ .../button-irq-printf-lowpower/syscfg.h | 61 +++++ .../l1/stm32l-discovery/button-irq-printf/README | 32 +++ .../l1/stm32l-discovery/button-irq-printf/main.c | 74 ++++- .../l1/stm32l-discovery/button-irq-printf/syscfg.h | 5 +- include/libopencm3/stm32/l1/rcc.h | 1 + lib/stm32/l1/rcc.c | 6 + 11 files changed, 508 insertions(+), 17 deletions(-) create mode 100644 examples/stm32/l1/stm32l-discovery/button-irq-printf-lowpower/Makefile create mode 100644 examples/stm32/l1/stm32l-discovery/button-irq-printf-lowpower/README create mode 100644 examples/stm32/l1/stm32l-discovery/button-irq-printf-lowpower/main.c create mode 100644 examples/stm32/l1/stm32l-discovery/button-irq-printf-lowpower/syscfg.h diff --git a/examples/stm32/f1/other/rtc/rtc.c b/examples/stm32/f1/other/rtc/rtc.c index 41c5d89..9db114c 100644 --- a/examples/stm32/f1/other/rtc/rtc.c +++ b/examples/stm32/f1/other/rtc/rtc.c @@ -19,7 +19,7 @@ #include #include -#include +#include #include #include #include diff --git a/examples/stm32/f1/stm32vl-discovery/rtc/rtc.c b/examples/stm32/f1/stm32vl-discovery/rtc/rtc.c index b3c698b..be40dfd 100644 --- a/examples/stm32/f1/stm32vl-discovery/rtc/rtc.c +++ b/examples/stm32/f1/stm32vl-discovery/rtc/rtc.c @@ -20,7 +20,7 @@ #include #include -#include +#include #include #include #include diff --git a/examples/stm32/l1/stm32l-discovery/button-irq-printf-lowpower/Makefile b/examples/stm32/l1/stm32l-discovery/button-irq-printf-lowpower/Makefile new file mode 100644 index 0000000..d57ea7a --- /dev/null +++ b/examples/stm32/l1/stm32l-discovery/button-irq-printf-lowpower/Makefile @@ -0,0 +1,24 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see . +## + +BINARY = main +LDSCRIPT = ../../../../../lib/stm32/l1/stm32l15xxb.ld + +include ../../Makefile.include + diff --git a/examples/stm32/l1/stm32l-discovery/button-irq-printf-lowpower/README b/examples/stm32/l1/stm32l-discovery/button-irq-printf-lowpower/README new file mode 100644 index 0000000..83cccfc --- /dev/null +++ b/examples/stm32/l1/stm32l-discovery/button-irq-printf-lowpower/README @@ -0,0 +1,18 @@ +This is _functionally_ identical to the "button-irq-printf" +example, but has been modified to use some low power features. + +There is a 115200@8n1 console on PA2, which prints a tick count every second, +and when the user push button is pressed, the time it is held down for is +timed (in milliseconds) + +Instead of free running timers and busy loops, this version uses the RTC +module and attempts to sleep as much as possible, including while the button +is pressed. + +Status +~~~~~~ +Only very basic power savings are done! + +Current consumption, led off/on, 16Mhz HSI: 2.7mA/5.4mA +Current consumption, led off/on, 4Mhz HSI: 1.4mA/?.?mA +Current consumption, led off/on, 4Mhz MSI: 0.9mA/?.?mA diff --git a/examples/stm32/l1/stm32l-discovery/button-irq-printf-lowpower/main.c b/examples/stm32/l1/stm32l-discovery/button-irq-printf-lowpower/main.c new file mode 100644 index 0000000..3f19319 --- /dev/null +++ b/examples/stm32/l1/stm32l-discovery/button-irq-printf-lowpower/main.c @@ -0,0 +1,300 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "syscfg.h" + +static volatile struct state_t state; + +__attribute__((always_inline)) static inline void __WFI(void) +{ + __asm volatile ("wfi"); +} + +void gpio_setup(void) +{ + /* green led for ticking, blue for button feedback */ + gpio_mode_setup(LED_DISCO_GREEN_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED_DISCO_GREEN_PIN); + gpio_mode_setup(LED_DISCO_BLUE_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED_DISCO_BLUE_PIN); + + /* Setup GPIO pins for USART2 transmit. */ + gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO2); + + /* Setup USART2 TX pin as alternate function. */ + gpio_set_af(GPIOA, GPIO_AF7, GPIO2); +} + +void BUTTON_DISCO_USER_isr(void) +{ + exti_reset_request(BUTTON_DISCO_USER_EXTI); + state.pressed = true; + if (state.falling) { + state.falling = false; + exti_set_trigger(BUTTON_DISCO_USER_EXTI, EXTI_TRIGGER_RISING); + state.hold_time = TIM_CNT(TIMER_BUTTON_PRESS); + } else { + state.falling = true; + exti_set_trigger(BUTTON_DISCO_USER_EXTI, EXTI_TRIGGER_FALLING); + state.hold_time = TIM_CNT(TIMER_BUTTON_PRESS) = 0; + } +} + +void setup_buttons(void) +{ + /* Enable EXTI0 interrupt. */ + nvic_enable_irq(BUTTON_DISCO_USER_NVIC); + + gpio_mode_setup(BUTTON_DISCO_USER_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, BUTTON_DISCO_USER_PIN); + + /* Configure the EXTI subsystem. */ + exti_select_source(BUTTON_DISCO_USER_EXTI, BUTTON_DISCO_USER_PORT); + state.falling = false; + exti_set_trigger(BUTTON_DISCO_USER_EXTI, EXTI_TRIGGER_RISING); + exti_enable_request(BUTTON_DISCO_USER_EXTI); +} + +void usart_setup(void) +{ + usart_set_baudrate(USART_CONSOLE, 115200); + usart_set_databits(USART_CONSOLE, 8); + usart_set_stopbits(USART_CONSOLE, USART_STOPBITS_1); + usart_set_mode(USART_CONSOLE, USART_MODE_TX); + usart_set_parity(USART_CONSOLE, USART_PARITY_NONE); + usart_set_flow_control(USART_CONSOLE, USART_FLOWCONTROL_NONE); + + /* Finally enable the USART. */ + usart_enable(USART_CONSOLE); +} + +/** + * Use USART_CONSOLE as a console. + * @param file + * @param ptr + * @param len + * @return + */ +int _write(int file, char *ptr, int len) +{ + int i; + + if (file == STDOUT_FILENO || file == STDERR_FILENO) { + for (i = 0; i < len; i++) { + if (ptr[i] == '\n') { + usart_send_blocking(USART_CONSOLE, '\r'); + } + usart_send_blocking(USART_CONSOLE, ptr[i]); + } + return i; + } + errno = EIO; + return -1; +} + +/* + * Free running ms timer. + */ +void setup_button_press_timer(void) +{ + timer_reset(TIMER_BUTTON_PRESS); + timer_set_prescaler(TIMER_BUTTON_PRESS, 3999); // 4Mhz/1000hz - 1 + timer_set_period(TIMER_BUTTON_PRESS, 0xffff); + timer_enable_counter(TIMER_BUTTON_PRESS); +} + +int setup_rtc(void) +{ + /* turn on power block to enable unlocking */ + rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_PWREN); + pwr_disable_backup_domain_write_protect(); + + /* reset rtc */ + RCC_CSR |= RCC_CSR_RTCRST; + RCC_CSR &= ~RCC_CSR_RTCRST; + + /* We want to use the LSE fitted on the discovery board */ + rcc_osc_on(LSE); + rcc_wait_for_osc_ready(LSE); + + /* Select the LSE as rtc clock */ + rcc_rtc_select_clock(RCC_CSR_RTCSEL_LSE); + + /* ?! Stdperiph examples don't turn this on until _afterwards_ which + * simply doesn't work. It must be on at least to be able to configure it */ + RCC_CSR |= RCC_CSR_RTCEN; + + rtc_unlock(); + + /* enter init mode */ + RTC_ISR |= RTC_ISR_INIT; + while ((RTC_ISR & RTC_ISR_INITF) == 0) + ; + + /* set synch prescaler, using defaults for 1Hz out */ + u32 sync = 255; + u32 async = 127; + rtc_set_prescaler(sync, async); + + /* load time and date here if desired, and hour format */ + + /* exit init mode */ + RTC_ISR &= ~(RTC_ISR_INIT); + + /* and write protect again */ + rtc_lock(); + + /* and finally enable the clock */ + RCC_CSR |= RCC_CSR_RTCEN; + + /* And wait for synchro.. */ + rtc_wait_for_synchro(); + return 0; +} + +int setup_rtc_wakeup(int period) +{ + rtc_unlock(); + + /* ensure wakeup timer is off */ + RTC_CR &= ~RTC_CR_WUTE; + + /* Wait until we can write */ + while ((RTC_ISR & RTC_ISR_WUTWF) == 0) + ; + + RTC_WUTR = period - 1; + + /* Use the 1Hz clock as source */ + RTC_CR &= ~(RTC_CR_WUCLKSEL_MASK << RTC_CR_WUCLKSEL_SHIFT); + RTC_CR |= (RTC_CR_WUCLKSEL_SPRE << RTC_CR_WUCLKSEL_SHIFT); + + /* Restart WakeUp unit */ + RTC_CR |= RTC_CR_WUTE; + + /* interrupt configuration */ + + /* also, let's have an interrupt */ + RTC_CR |= RTC_CR_WUTIE; + + /* done with rtc registers, lock them again */ + rtc_lock(); + + + nvic_enable_irq(NVIC_RTC_WKUP_IRQ); + + // EXTI configuration + /* Configure the EXTI subsystem. */ + // not needed, this chooses ports exti_select_source(EXTI20, BUTTON_DISCO_USER_PORT); + exti_set_trigger(EXTI20, EXTI_TRIGGER_RISING); + exti_enable_request(EXTI20); + return 0; +} + +void rtc_wkup_isr(void) +{ + /* clear flag, not write protected */ + RTC_ISR &= ~(RTC_ISR_WUTF); + exti_reset_request(EXTI20); + state.rtc_ticked = true; +} + +int process_state(volatile struct state_t *st) +{ + if (st->rtc_ticked) { + st->rtc_ticked = 0; + printf("Tick: %x\n", (unsigned int) RTC_TR); +#if FULL_USER_EXPERIENCE + gpio_toggle(LED_DISCO_GREEN_PORT, LED_DISCO_GREEN_PIN); +#else + gpio_clear(LED_DISCO_GREEN_PORT, LED_DISCO_GREEN_PIN); +#endif + } + if (st->pressed) { + st->pressed = false; + if (st->falling) { + gpio_set(LED_DISCO_BLUE_PORT, LED_DISCO_BLUE_PIN); + printf("Pushed down!\n"); + } else { + gpio_clear(LED_DISCO_BLUE_PORT, LED_DISCO_BLUE_PIN); + printf("held: %u ms\n", st->hold_time); + } + } + return 0; +} + +void reset_clocks(void) +{ + /* 4MHz MSI raw range 2*/ + clock_scale_t myclock_config = { + .hpre = RCC_CFGR_HPRE_SYSCLK_NODIV, + .ppre1 = RCC_CFGR_PPRE1_HCLK_NODIV, + .ppre2 = RCC_CFGR_PPRE2_HCLK_NODIV, + .voltage_scale = RANGE2, + .flash_config = FLASH_LATENCY_0WS, + .apb1_frequency = 4194000, + .apb2_frequency = 4194000, + .msi_range = RCC_ICSCR_MSIRANGE_4MHZ, + }; + rcc_clock_setup_msi(&myclock_config); + + /* buttons and uarts */ + rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_GPIOAEN); + /* user feedback leds */ + rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_GPIOBEN); + /* Enable clocks for USART2. */ + rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_USART2EN); + /* And a timers for button presses */ + rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_TIM7EN); +} + +int main(void) +{ + reset_clocks(); + gpio_setup(); + usart_setup(); + setup_buttons(); + setup_button_press_timer(); + printf("we're awake!\n"); + + setup_rtc(); + setup_rtc_wakeup(1); + + while (1) { + PWR_CR |= PWR_CR_LPSDSR; + pwr_set_stop_mode(); + __WFI(); + reset_clocks(); + process_state(&state); + } + + return 0; +} \ No newline at end of file diff --git a/examples/stm32/l1/stm32l-discovery/button-irq-printf-lowpower/syscfg.h b/examples/stm32/l1/stm32l-discovery/button-irq-printf-lowpower/syscfg.h new file mode 100644 index 0000000..8ca634b --- /dev/null +++ b/examples/stm32/l1/stm32l-discovery/button-irq-printf-lowpower/syscfg.h @@ -0,0 +1,61 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef SYSCFG_H +#define SYSCFG_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include + + +#define USART_CONSOLE USART2 +#define USE_NASTYLOG 1 + +#define LED_DISCO_GREEN_PORT GPIOB +#define LED_DISCO_GREEN_PIN GPIO7 +#define LED_DISCO_BLUE_PORT GPIOB +#define LED_DISCO_BLUE_PIN GPIO6 + +#define BUTTON_DISCO_USER_PORT GPIOA +#define BUTTON_DISCO_USER_PIN GPIO0 +#define BUTTON_DISCO_USER_EXTI EXTI0 +#define BUTTON_DISCO_USER_isr exti0_isr +#define BUTTON_DISCO_USER_NVIC NVIC_EXTI0_IRQ +#define TIMER_BUTTON_PRESS TIM7 + + struct state_t { + bool falling; + bool pressed; + int rtc_ticked; + int hold_time; + }; + + +#ifdef __cplusplus +} +#endif + +#endif /* SYSCFG_H */ + diff --git a/examples/stm32/l1/stm32l-discovery/button-irq-printf/README b/examples/stm32/l1/stm32l-discovery/button-irq-printf/README index 63232ef..5de96a2 100644 --- a/examples/stm32/l1/stm32l-discovery/button-irq-printf/README +++ b/examples/stm32/l1/stm32l-discovery/button-irq-printf/README @@ -1,3 +1,35 @@ * Prints to the screen when the button is pushed/released (irq driven) 115200@8n1 console on PA2 (tx only) +* uses basic timer 6 with overflows to generate a 1ms counter (not an ideal + use, but shows some api methods and can be demoed on the disco board) +* uses basic timer 7 with the exti interrupts to do ghetto input capture. + Not as fast or precise as the real input capture modes, but can be used + on any gpio pin. + +No effort at saving power is made here. Current consumption on the Disco board +is ~7.5mA when the green tick led is off, and about 10.5mA when it is on. + +example output: + +hi guys! +TICK 0 +TICK 1 +TICK 2 +Pushed down! +held: 443 ms +Pushed down! +TICK 3 +held: 217 ms +Pushed down! +held: 99 ms +Pushed down! +TICK 4 +held: 73 ms +Pushed down! +held: 60 ms +TICK 5 +Pushed down! +held: 98 ms +Pushed down! + diff --git a/examples/stm32/l1/stm32l-discovery/button-irq-printf/main.c b/examples/stm32/l1/stm32l-discovery/button-irq-printf/main.c index 762fdd9..82a3434 100644 --- a/examples/stm32/l1/stm32l-discovery/button-irq-printf/main.c +++ b/examples/stm32/l1/stm32l-discovery/button-irq-printf/main.c @@ -22,8 +22,9 @@ #include #include #include -#include +#include #include +#include #include #include "syscfg.h" @@ -32,17 +33,25 @@ static struct state_t state; void clock_setup(void) { + rcc_clock_setup_pll(&clock_config[CLOCK_VRANGE1_HSI_PLL_24MHZ]); /* Lots of things on all ports... */ rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_GPIOAEN); rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_GPIOBEN); /* Enable clocks for USART2. */ rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_USART2EN); + + /* And timers. */ + rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_TIM6EN); + rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_TIM7EN); + } void gpio_setup(void) { + /* green led for ticking, blue for button feedback */ gpio_mode_setup(LED_DISCO_GREEN_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED_DISCO_GREEN_PIN); + gpio_mode_setup(LED_DISCO_BLUE_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED_DISCO_BLUE_PIN); /* Setup GPIO pins for USART2 transmit. */ gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO2); @@ -92,18 +101,61 @@ void BUTTON_DISCO_USER_isr(void) { exti_reset_request(BUTTON_DISCO_USER_EXTI); if (state.falling) { + gpio_clear(LED_DISCO_BLUE_PORT, LED_DISCO_BLUE_PIN); state.falling = false; exti_set_trigger(BUTTON_DISCO_USER_EXTI, EXTI_TRIGGER_RISING); - // ILOG("fell: %d\n", TIM_CNT(TIM7)); - puts("fell!\n"); + unsigned int x = TIM_CNT(TIM7); + printf("held: %u ms\n", x); } else { - puts("Rose!\n"); - // TIM_CNT(TIM7) = 0; + gpio_set(LED_DISCO_BLUE_PORT, LED_DISCO_BLUE_PIN); + printf("Pushed down!\n"); + TIM_CNT(TIM7) = 0; state.falling = true; exti_set_trigger(BUTTON_DISCO_USER_EXTI, EXTI_TRIGGER_FALLING); } } +static volatile int t6ovf = 0; + +void tim6_isr(void) +{ + TIM_SR(TIM6) &= ~TIM_SR_UIF; + if (t6ovf++ > 1000) { + printf("TICK %d\n", state.tickcount++); + t6ovf = 0; + gpio_toggle(LED_DISCO_GREEN_PORT, LED_DISCO_GREEN_PIN); + } +} + +/* + * Another ms timer, this one used to generate an overflow interrupt at 1ms + * It is used to toggle leds and write tick counts + */ +void setup_tim6(void) +{ + timer_reset(TIM6); + // 24Mhz / 10khz -1. + timer_set_prescaler(TIM6, 2399); // 24Mhz/10000hz - 1 + // 10khz for 10 ticks = 1 khz overflow = 1ms overflow interrupts + timer_set_period(TIM6, 10); + + nvic_enable_irq(NVIC_TIM6_IRQ); + timer_enable_update_event(TIM6); // default at reset! + timer_enable_irq(TIM6, TIM_DIER_UIE); + timer_enable_counter(TIM6); +} + +/* + * Free running ms timer. + */ +void setup_tim7(void) +{ + timer_reset(TIM7); + timer_set_prescaler(TIM7, 23999); // 24Mhz/1000hz - 1 + timer_set_period(TIM7, 0xffff); + timer_enable_counter(TIM7); +} + void setup_buttons(void) { /* Enable EXTI0 interrupt. */ @@ -120,19 +172,15 @@ void setup_buttons(void) int main(void) { - int i; - int j = 0; clock_setup(); gpio_setup(); usart_setup(); - puts("hi guys!\n"); + printf("hi guys!\n"); setup_buttons(); + setup_tim6(); + setup_tim7(); while (1) { - puts("tick:"); - putchar('a' + (j++ % 26)); - gpio_toggle(GPIOB, GPIO7); /* LED on/off */ - for (i = 0; i < 100000; i++) /* Wait a bit. */ - __asm__("NOP"); + ; } return 0; diff --git a/examples/stm32/l1/stm32l-discovery/button-irq-printf/syscfg.h b/examples/stm32/l1/stm32l-discovery/button-irq-printf/syscfg.h index be54502..d278ac4 100644 --- a/examples/stm32/l1/stm32l-discovery/button-irq-printf/syscfg.h +++ b/examples/stm32/l1/stm32l-discovery/button-irq-printf/syscfg.h @@ -24,8 +24,8 @@ extern "C" { #endif -#include -#include +#include +#include #include #include @@ -46,6 +46,7 @@ extern "C" { struct state_t { bool falling; + int tickcount; }; diff --git a/include/libopencm3/stm32/l1/rcc.h b/include/libopencm3/stm32/l1/rcc.h index a751def..4dc5102 100644 --- a/include/libopencm3/stm32/l1/rcc.h +++ b/include/libopencm3/stm32/l1/rcc.h @@ -444,6 +444,7 @@ void rcc_set_ppre1(u32 ppre1); void rcc_set_hpre(u32 hpre); void rcc_set_usbpre(u32 usbpre); u32 rcc_get_system_clock_source(int i); +void rcc_rtc_select_clock(u32 clock); void rcc_clock_setup_msi(const clock_scale_t *clock); void rcc_clock_setup_hsi(const clock_scale_t *clock); void rcc_clock_setup_pll(const clock_scale_t *clock); diff --git a/lib/stm32/l1/rcc.c b/lib/stm32/l1/rcc.c index c1d8fa9..9b2df24 100644 --- a/lib/stm32/l1/rcc.c +++ b/lib/stm32/l1/rcc.c @@ -437,6 +437,12 @@ u32 rcc_system_clock_source(void) return ((RCC_CFGR & 0x000c) >> 2); } +void rcc_rtc_select_clock(u32 clock) +{ + RCC_CSR &= ~(RCC_CSR_RTCSEL_MASK << RCC_CSR_RTCSEL_SHIFT); + RCC_CSR |= (clock << RCC_CSR_RTCSEL_SHIFT); +} + void rcc_clock_setup_msi(const clock_scale_t *clock) { /* Enable internal multi-speed oscillator. */ -- cgit v1.2.3