diff --git a/examples/stm32/f1/other/rtc/rtc.c b/examples/stm32/f1/other/rtc/rtc.c index 41c5d89f..9db114ca 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 b3c698bc..be40dfd5 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 00000000..d57ea7a8 --- /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 00000000..83cccfc9 --- /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 00000000..3f193198 --- /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 00000000..8ca634ba --- /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 63232ef6..5de96a20 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 1830c4dd..82a34344 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 @@ -7,43 +22,55 @@ #include #include #include -#include +#include #include +#include #include #include "syscfg.h" 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) +{ + 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); - /* 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) +{ + /* 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 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); +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); + /* Finally enable the USART. */ + usart_enable(USART_CONSOLE); } /** @@ -53,65 +80,108 @@ void usart_setup(void) { * @param len * @return */ -int _write(int file, char *ptr, int len) { - int i; +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; + 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) { + gpio_clear(LED_DISCO_BLUE_PORT, LED_DISCO_BLUE_PIN); + state.falling = false; + exti_set_trigger(BUTTON_DISCO_USER_EXTI, EXTI_TRIGGER_RISING); + unsigned int x = TIM_CNT(TIM7); + printf("held: %u ms\n", x); + } else { + 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); + } } -void setup_buttons(void) { - /* Enable EXTI0 interrupt. */ - nvic_enable_irq(BUTTON_DISCO_USER_NVIC); +static volatile int t6ovf = 0; - 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 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); + } } -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"); - } +/* + * 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); - return 0; + 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. */ + 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); +} + +int main(void) +{ + clock_setup(); + gpio_setup(); + usart_setup(); + printf("hi guys!\n"); + setup_buttons(); + setup_tim6(); + setup_tim7(); + while (1) { + ; + } + + 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 32cf465a..d278ac4e 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 @@ -11,8 +24,8 @@ extern "C" { #endif -#include -#include +#include +#include #include #include @@ -31,10 +44,10 @@ 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; + int tickcount; + }; #ifdef __cplusplus diff --git a/examples/stm32/l1/stm32l-discovery/usart/usart.c b/examples/stm32/l1/stm32l-discovery/usart/usart.c index 3335ca8c..cc766dd9 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/common/pwr_common_all.h b/include/libopencm3/stm32/common/pwr_common_all.h new file mode 100644 index 00000000..cc9fd229 --- /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/common/rtc_common_bcd.h b/include/libopencm3/stm32/common/rtc_common_bcd.h new file mode 100644 index 00000000..130020e8 --- /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/pwr.h b/include/libopencm3/stm32/f1/pwr.h new file mode 100644 index 00000000..2875492f --- /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/f1/rtc.h b/include/libopencm3/stm32/f1/rtc.h index 04aea01d..a8a89666 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 00000000..ebc09360 --- /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/pwr.h b/include/libopencm3/stm32/f4/pwr.h index 25fb163c..c9b27fd5 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/f4/rtc.h b/include/libopencm3/stm32/f4/rtc.h new file mode 100644 index 00000000..ab8d3ee3 --- /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/flash.h b/include/libopencm3/stm32/l1/flash.h index ed0a6969..a2831b41 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/irq.yaml b/include/libopencm3/stm32/l1/irq.yaml index c2f118f7..a10e96cd 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 d89dbd65..60f1c570 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) diff --git a/include/libopencm3/stm32/l1/pwr.h b/include/libopencm3/stm32/l1/pwr.h index 309b4642..e976d464 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 @@ -53,6 +69,9 @@ /* ULP: Ultralow power mode */ #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 */ diff --git a/include/libopencm3/stm32/l1/rcc.h b/include/libopencm3/stm32/l1/rcc.h index 21b073b8..4dc51026 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 ------------------------------------------------------- */ @@ -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,8 @@ 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); void rcc_backupdomain_reset(void); diff --git a/include/libopencm3/stm32/l1/rtc.h b/include/libopencm3/stm32/l1/rtc.h new file mode 100644 index 00000000..d364fb52 --- /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/pwr.h b/include/libopencm3/stm32/pwr.h index 34b24078..1d907a9c 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/include/libopencm3/stm32/rtc.h b/include/libopencm3/stm32/rtc.h new file mode 100644 index 00000000..a927dd8e --- /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/pwr_common_all.c b/lib/stm32/common/pwr_common_all.c new file mode 100644 index 00000000..451ed1cf --- /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/common/rtc_common_bcd.c b/lib/stm32/common/rtc_common_bcd.c new file mode 100644 index 00000000..c302ea25 --- /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/f1/Makefile b/lib/stm32/f1/Makefile index 6bc21f75..ba0d4b8f 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/f2/Makefile b/lib/stm32/f2/Makefile index 3d3c7561..85e64581 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 00000000..461d0b1a --- /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 2b02281d..8ff7c6a3 100644 --- a/lib/stm32/f4/Makefile +++ b/lib/stm32/f4/Makefile @@ -32,9 +32,11 @@ 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 + 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 00000000..1b301faa --- /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 32c8fd3d..9b677aba 100644 --- a/lib/stm32/l1/Makefile +++ b/lib/stm32/l1/Makefile @@ -31,7 +31,8 @@ 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 +OBJS += rtc_common_bcd.o VPATH += ../../usb:../:../../cm3:../common diff --git a/lib/stm32/l1/pwr_chipset.c b/lib/stm32/l1/pwr.c similarity index 96% rename from lib/stm32/l1/pwr_chipset.c rename to lib/stm32/l1/pwr.c index 9f4f5996..85418515 100644 --- a/lib/stm32/l1/pwr_chipset.c +++ b/lib/stm32/l1/pwr.c @@ -17,7 +17,7 @@ * along with this library. If not, see . */ -#include +#include void pwr_set_vos_scale(vos_scale_t scale) { diff --git a/lib/stm32/l1/rcc.c b/lib/stm32/l1/rcc.c index bbba9a98..9b2df243 100644 --- a/lib/stm32/l1/rcc.c +++ b/lib/stm32/l1/rcc.c @@ -23,13 +23,13 @@ #include #include -#include +#include /* Set the default ppre1 and ppre2 peripheral clock frequencies after reset. */ 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, @@ -64,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) @@ -408,6 +437,48 @@ 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. */ + + 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. */ diff --git a/lib/stm32/l1/rtc.c b/lib/stm32/l1/rtc.c new file mode 100644 index 00000000..bc7f87ff --- /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