efm32: energy management unit headers and example

This commit is contained in:
chrysn 2012-03-02 21:54:23 +01:00
parent eda122180a
commit e388056fda
6 changed files with 335 additions and 65 deletions

View File

@ -2,8 +2,12 @@
EFM32-TG-STK3300 Examples lightswitch README EFM32-TG-STK3300 Examples lightswitch README
============================================ ============================================
This is a small example program for GPIO input and output (and, in future, IRQ This is a small example program for GPIO input and output, and how the device
handling). can be configured to use minimal power (although the example is merely
scratching the surface of what is possible powersaving-wise).
It's intended for the EFM32-TG-STK3300 eval board. It turn the User LED on when It's intended for the EFM32-TG-STK3300 eval board. It turn the User LED on when
PB0 is pressed, and off when PB1 is pressed. PB0 is pressed, and off when PB1 is pressed.
Various implementations are offered (-busywait, -interrupt), and can configured
in lightswitch.c.

View File

@ -0,0 +1,40 @@
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2012 chrysn <chrysn@fsfe.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <libopencm3/efm32/tinygecko/irq.h>
#include <libopencm3/efm32/tinygecko/emu.h>
#define ISER0 MMIO32(0xE000E100)
#define ICER0 MMIO32(0xE000E180)
#define ISPR0 MMIO32(0XE000E200)
#define ICPR0 MMIO32(0XE000E280)
/** @file Simplest implementation of the lightswitch mechanism. */
int main(void)
{
gpio_setup();
while(1) {
if (pb0_get())
led_on();
if (pb1_get())
led_off();
};
}

View File

@ -0,0 +1,88 @@
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2012 chrysn <chrysn@fsfe.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file Common definitions used by all lightswitch implementations */
#include <libopencm3/efm32/tinygecko/gpio.h>
#include <libopencm3/efm32/tinygecko/cmu.h>
/** The User LED is connected to PD7 to the plus side of the LED according to
* t0011_efm32_tiny_gecko_stk_user_manual.pdf figures 16.2 and 16.3 (called
* UIF_LED0)
*/
#define LED_PORT GPIO_PD
#define LED_PIN GPIO7
#define BUTTON0_PORT GPIO_PD
#define BUTTON0_PORT_EXTIPSEL GPIO_EXTIPSEL_PORTD
#define BUTTON0_PIN_NUMBER 8
#define BUTTON0_PIN GPIO8
#define BUTTON1_PORT GPIO_PB
#define BUTTON1_PORT_EXTIPSEL GPIO_EXTIPSEL_PORTB
#define BUTTON1_PIN_NUMBER 11
#define BUTTON1_PIN GPIO11
void gpio_setup(void);
void led_on(void);
void led_off(void);
bool pb0_get(void);
bool pb1_get(void);
/**
* Enable GPIO, and set up port D7 as an output pin and D8 and B11 as input.
*/
void gpio_setup(void)
{
// Before GPIO works, according to d0034_efm32tg_reference_manual.pdf
// note in section 28.3.7, we'll have to enable GPIO in CMU_HFPERCLKEN0
CMU_HFPERCLKEN0 |= CMU_HFPERCLKEN0_GPIO;
gpio_set_mode(LED_PORT, GPIO_MODE_PUSHPULL, LED_PIN);
// Button PB0 is connected to pin PD8 and pulled low when pushed,
// Botton PB1 to pin PB11 (sources as for LED). Pullups and debouncing
// are alreay in place in hardware, so no filtering or pullup is
// needed.
gpio_set_mode(BUTTON0_PORT, GPIO_MODE_INPUT, BUTTON0_PIN);
gpio_set_mode(BUTTON1_PORT, GPIO_MODE_INPUT, BUTTON1_PIN);
}
void led_on(void)
{
gpio_set(LED_PORT, LED_PIN);
}
void led_off(void)
{
gpio_clear(LED_PORT, LED_PIN);
}
bool pb0_get(void)
{
return !gpio_get(GPIO_PD, GPIO8);
}
bool pb1_get(void)
{
return !gpio_get(GPIO_PB, GPIO11);
}

View File

@ -0,0 +1,71 @@
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2012 chrysn <chrysn@fsfe.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <libopencm3/efm32/tinygecko/irq.h>
#include <libopencm3/efm32/tinygecko/emu.h>
#define ISER0 MMIO32(0xE000E100)
void interrupt_setup()
{
// These are the ports the pin interrupts for 8 and 11 are to be
// configured to, and they should trigger on falling edge.
GPIO_EXTIPSELH = (BUTTON0_PORT_EXTIPSEL << ((BUTTON0_PIN_NUMBER-8)*4)) |
(BUTTON1_PORT_EXTIPSEL << ((BUTTON1_PIN_NUMBER-8)*4));
GPIO_EXTIFALL = BUTTON0_PIN | BUTTON1_PIN;
// Enable interrupts on the GPIO side
GPIO_INSENSE = GPIO_INSENSE_INT;
GPIO_IEN = BUTTON0_PIN | BUTTON1_PIN;
// Enable GPIO interrupts in NVIC
ISER0 = (1<<IRQ_GPIO_EVEN) | (1<<IRQ_GPIO_ODD);
}
int main(void)
{
gpio_setup();
interrupt_setup();
while(1) {
emu_sleep_em1();
};
}
void gpio_even_isr()
{
// Clearing the GPIO interrupt pending register. While the NVIC
// interrupt pending register gets cleared automatically once it jumps
// here, the pin's pending state has to be cleared explicitly.
// (Dispatch to different subroutines for different even pins that
// trigger an interrupt would happen here.)
GPIO_IFC = BUTTON0_PIN;
led_on();
}
void gpio_odd_isr()
{
// See gpio_even_isr.
GPIO_IFC = BUTTON1_PIN;
led_off();
}

View File

@ -17,72 +17,14 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <libopencm3/efm32/tinygecko/gpio.h>
#include <libopencm3/efm32/tinygecko/cmu.h>
void gpio_setup(void);
void led_on(void);
void led_off(void);
bool pb0_get(void);
bool pb1_get(void);
/** @file /** @file
* Example for switching the User LED of the EFM32-TG-STK330 eval board on and * Example for switching the User LED of the EFM32-TG-STK330 eval board on and
* off using the buttons. * off using the buttons.
*/ */
int main(void) #include "lightswitch-common.c"
{
gpio_setup();
while(1) { /** Change this include to -busywait, -interrupt, or -prs (not implemented
if (pb0_get()) led_on(); * yet). The overall behavior will not change, but different implementations
if (pb1_get()) led_off(); * will be used. */
}; #include "lightswitch-busywait.c"
}
/**
* Enable GPIO, and set up port D7 as an output pin.
*/
void gpio_setup(void)
{
// Before GPIO works, according to d0034_efm32tg_reference_manual.pdf
// note in section 28.3.7, we'll have to enable GPIO in CMU_HFPERCLKEN0
CMU_HFPERCLKEN0 |= CMU_HFPERCLKEN0_GPIO;
// The User LED is connected to PD7 to the plus side of the LED
// according to t0011_efm32_tiny_gecko_stk_user_manual.pdf figures 16.2
// and 16.3 (called UIF_LED0)
gpio_set_mode(GPIO_PD, GPIO_MODE_PUSHPULL, GPIO7);
// Button PB0 is connected to pin PD8 and pulled low when pushed,
// Botton PB1 to pin PB11 (sources as for LED). Pullups and debouncing
// are alreay in place in hardware, so no filtering or pullup is
// needed.
gpio_set_mode(GPIO_PD, GPIO_MODE_INPUT, GPIO8);
gpio_set_mode(GPIO_PB, GPIO_MODE_INPUT, GPIO11);
}
void led_on(void)
{
gpio_set(GPIO_PD, GPIO7);
}
void led_off(void)
{
gpio_clear(GPIO_PD, GPIO7);
}
bool pb0_get(void)
{
return !gpio_get(GPIO_PD, GPIO8);
}
bool pb1_get(void)
{
return !gpio_get(GPIO_PB, GPIO11);
}

View File

@ -0,0 +1,125 @@
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2012 chrysn <chrysn@fsfe.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file
* @see EFM32TG_EMU
*/
/** Definitions for the EMU subsystem (Energy Management Unit).
*
* This corresponds to the description in d0034_efm32tg_reference_manual.pdf
* section 10.
*
* @defgroup EFM32TG_EMU EFM32 Tiny Gecko EMU
* @{
*/
#ifndef LIBOPENCM3_EFM32_TINYGECKO_EMU_H
#define LIBOPENCM3_EFM32_TINYGECKO_EMU_H
#include <libopencm3/cm3/common.h>
#include <libopencm3/efm32/memorymap.h>
/** Register definitions and register value definitions for the EMU subsystem
*
* @defgroup EFM32TG_EMU_regsandvals EFM32 Tiny Gecko EMU registers and values
* @{
*/
/** These definitions reflect d0034_efm32tg_reference_manual.pdf section 10.4
*
* @defgroup EFM32TG_EMU_registers EFM32 Tiny Gecko EMU registers
* @{
*/
#define EMU_CTRL MMIO32(EMU_BASE + 0x000) /**< @see EFM32TG_EMU_CTRL_bits */
#define EMU_LOCK MMIO32(EMU_BASE + 0x008) /**< @see EFM32TG_EMU_LOCK_values */
#define EMU_AUXCTRL MMIO32(EMU_BASE + 0x024) /**< @see EFM32TG_EMU_AUXCTRL_bits */
/** @} */
/** Bit states for the EMU_CTRL register
*
* See d0034_efm32tg_reference_manual.pdf section 10.5.1 for definitions, and
* 10.3.2 for details (especially on why EM4CTRL_TWO and _THREE are defined).
*
* @defgroup EFM32TG_EMU_CTRL_bits EFM32 Tiny Gecko EMU CTRL bits
* @{
*/
#define EMU_CTRL_EM4CTRL_TWO (2<<2)
#define EMU_CTRL_EM4CTRL_THREE (3<<2)
#define EMU_CTRL_EM2BLOCK (1<<1) /**< When this bit is set, no mode lower than EM1 will be entered */
#define EMU_CTRL_EMVREG (1<<0) /**< When this bit is set, the voltage regulator will stay on in modes lower than EM1 */
/** @} */
/** Values for the EMU_LOCK register
*
* See d0034_efm32tg_reference_manual.pdf section 10.5.2. There seems not to be
* another mention of it.
*
* @defgroup EFM32TG_EMU_LOCK_values EFM32 Tiny Gecko EMU LOCK values
* @{
*/
#define EMU_LOCK_IS_UNLOCKED 0 /**< When the LOCK register reads as this value, it is open */
#define EMU_LOCK_IS_LOCKED 1 /**< When the LOCK register reads as this value, it is locked */
#define EMU_LOCK_SET_LOCKED 0 /**< Write this to the LOCK register to lock the EMU */
#define EMU_LOCK_SET_UNLOCKED 0xade8 /**< Write this to the LOCK register to unlock the EMU */
/** @} */
/** Bit states for the EMU_AUXCTRL register
*
* See d0034_efm32tg_reference_manual.pdf section 10.5.3 for definition, and
* 9.5.3 for details.
*
* @defgroup EFM32TG_EMU_AUXCTRL_bits EFM32 Tiny Gecko EMU AUXCTRL bits
* @{
*/
#define EMU_AUXCTRL_HRCCLR (1<<0)
/** @} */
/** @} */
/** EMU convenience functions
*
* These functions can be used to send the chip to low energy modes.
*
* @todo Implement other sleep modes than EM1. Implement WFI vs WFE waits.
*
* @defgroup EFM32TG_EMU_convenience EFM32 Tiny Gecko EMU convenience functions
* @{
*/
/** Put the system into EM1 low energy mode. */
static void emu_sleep_em1(void)
{
/* FIXME: set SLEEPDEEP to 0 */
__asm__("wfi");
}
/** @} */
/** @} */
#endif