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.
This commit is contained in:
Karl Palsson
2013-01-23 00:01:46 +00:00
parent e5b3250382
commit d9fb4f7401
11 changed files with 508 additions and 17 deletions

View File

@@ -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!

View File

@@ -22,8 +22,9 @@
#include <unistd.h>
#include <libopencm3/cm3/nvic.h>
#include <libopencm3/stm32/l1/rcc.h>
#include <libopencm3/stm32/l1/gpio.h>
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/exti.h>
#include <libopencm3/stm32/timer.h>
#include <libopencm3/stm32/usart.h>
#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;

View File

@@ -24,8 +24,8 @@
extern "C" {
#endif
#include <libopencm3/stm32/l1/gpio.h>
#include <libopencm3/stm32/l1/nvic.h>
#include <libopencm3/cm3/nvic.h>
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/exti.h>
#include <libopencm3/stm32/usart.h>
@@ -46,6 +46,7 @@ extern "C" {
struct state_t {
bool falling;
int tickcount;
};