From e388056fda84a5c85430f5a31a4cfe3af3f2e35f Mon Sep 17 00:00:00 2001 From: chrysn Date: Fri, 2 Mar 2012 21:54:23 +0100 Subject: [PATCH] efm32: energy management unit headers and example --- .../efm32-tg-stk3300/lightswitch/README | 8 +- .../lightswitch/lightswitch-busywait.c | 40 ++++++ .../lightswitch/lightswitch-common.c | 88 ++++++++++++ .../lightswitch/lightswitch-interrupt.c | 71 ++++++++++ .../lightswitch/lightswitch.c | 68 +--------- include/libopencm3/efm32/tinygecko/emu.h | 125 ++++++++++++++++++ 6 files changed, 335 insertions(+), 65 deletions(-) create mode 100644 examples/efm32/tinygecko/efm32-tg-stk3300/lightswitch/lightswitch-busywait.c create mode 100644 examples/efm32/tinygecko/efm32-tg-stk3300/lightswitch/lightswitch-common.c create mode 100644 examples/efm32/tinygecko/efm32-tg-stk3300/lightswitch/lightswitch-interrupt.c create mode 100644 include/libopencm3/efm32/tinygecko/emu.h diff --git a/examples/efm32/tinygecko/efm32-tg-stk3300/lightswitch/README b/examples/efm32/tinygecko/efm32-tg-stk3300/lightswitch/README index 4b6b3338..41943dc1 100644 --- a/examples/efm32/tinygecko/efm32-tg-stk3300/lightswitch/README +++ b/examples/efm32/tinygecko/efm32-tg-stk3300/lightswitch/README @@ -2,8 +2,12 @@ EFM32-TG-STK3300 Examples lightswitch README ============================================ -This is a small example program for GPIO input and output (and, in future, IRQ -handling). +This is a small example program for GPIO input and output, and how the device +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 PB0 is pressed, and off when PB1 is pressed. + +Various implementations are offered (-busywait, -interrupt), and can configured +in lightswitch.c. diff --git a/examples/efm32/tinygecko/efm32-tg-stk3300/lightswitch/lightswitch-busywait.c b/examples/efm32/tinygecko/efm32-tg-stk3300/lightswitch/lightswitch-busywait.c new file mode 100644 index 00000000..662d9df4 --- /dev/null +++ b/examples/efm32/tinygecko/efm32-tg-stk3300/lightswitch/lightswitch-busywait.c @@ -0,0 +1,40 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 chrysn + * + * 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 . + */ + +#include +#include + +#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(); + }; +} diff --git a/examples/efm32/tinygecko/efm32-tg-stk3300/lightswitch/lightswitch-common.c b/examples/efm32/tinygecko/efm32-tg-stk3300/lightswitch/lightswitch-common.c new file mode 100644 index 00000000..0cd12042 --- /dev/null +++ b/examples/efm32/tinygecko/efm32-tg-stk3300/lightswitch/lightswitch-common.c @@ -0,0 +1,88 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 chrysn + * + * 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 . + */ + +/** @file Common definitions used by all lightswitch implementations */ + +#include +#include + +/** 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); +} diff --git a/examples/efm32/tinygecko/efm32-tg-stk3300/lightswitch/lightswitch-interrupt.c b/examples/efm32/tinygecko/efm32-tg-stk3300/lightswitch/lightswitch-interrupt.c new file mode 100644 index 00000000..f19423ba --- /dev/null +++ b/examples/efm32/tinygecko/efm32-tg-stk3300/lightswitch/lightswitch-interrupt.c @@ -0,0 +1,71 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 chrysn + * + * 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 . + */ + +#include +#include + +#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<. */ -#include -#include - -void gpio_setup(void); -void led_on(void); -void led_off(void); -bool pb0_get(void); -bool pb1_get(void); - /** @file * Example for switching the User LED of the EFM32-TG-STK330 eval board on and * off using the buttons. */ -int main(void) -{ - gpio_setup(); +#include "lightswitch-common.c" - while(1) { - if (pb0_get()) led_on(); - if (pb1_get()) led_off(); - }; -} - -/** - * 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); -} +/** Change this include to -busywait, -interrupt, or -prs (not implemented + * yet). The overall behavior will not change, but different implementations + * will be used. */ +#include "lightswitch-busywait.c" diff --git a/include/libopencm3/efm32/tinygecko/emu.h b/include/libopencm3/efm32/tinygecko/emu.h new file mode 100644 index 00000000..07327fd2 --- /dev/null +++ b/include/libopencm3/efm32/tinygecko/emu.h @@ -0,0 +1,125 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 chrysn + * + * 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 . + */ + +/** @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 +#include + +/** 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