aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorchrysn2012-03-02 21:54:23 +0100
committerchrysn2012-03-02 21:54:23 +0100
commite388056fda84a5c85430f5a31a4cfe3af3f2e35f (patch)
tree74430eb451fd13cbef6272b4f4ace2b9b0c9acb8
parenteda122180a10edc3bd71ffd6c46a4f2098a0f625 (diff)
efm32: energy management unit headers and example
-rw-r--r--examples/efm32/tinygecko/efm32-tg-stk3300/lightswitch/README8
-rw-r--r--examples/efm32/tinygecko/efm32-tg-stk3300/lightswitch/lightswitch-busywait.c40
-rw-r--r--examples/efm32/tinygecko/efm32-tg-stk3300/lightswitch/lightswitch-common.c88
-rw-r--r--examples/efm32/tinygecko/efm32-tg-stk3300/lightswitch/lightswitch-interrupt.c71
-rw-r--r--examples/efm32/tinygecko/efm32-tg-stk3300/lightswitch/lightswitch.c68
-rw-r--r--include/libopencm3/efm32/tinygecko/emu.h125
6 files changed, 335 insertions, 65 deletions
diff --git a/examples/efm32/tinygecko/efm32-tg-stk3300/lightswitch/README b/examples/efm32/tinygecko/efm32-tg-stk3300/lightswitch/README
index 4b6b333..41943dc 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 0000000..662d9df
--- /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 <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();
+ };
+}
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 0000000..0cd1204
--- /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 <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);
+}
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 0000000..f19423b
--- /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 <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();
+}
diff --git a/examples/efm32/tinygecko/efm32-tg-stk3300/lightswitch/lightswitch.c b/examples/efm32/tinygecko/efm32-tg-stk3300/lightswitch/lightswitch.c
index 7b4e0ce..b8675f8 100644
--- a/examples/efm32/tinygecko/efm32-tg-stk3300/lightswitch/lightswitch.c
+++ b/examples/efm32/tinygecko/efm32-tg-stk3300/lightswitch/lightswitch.c
@@ -17,72 +17,14 @@
* 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
* Example for switching the User LED of the EFM32-TG-STK330 eval board on and
* off using the buttons.
*/
-int main(void)
-{
- gpio_setup();
-
- 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);
-}
+#include "lightswitch-common.c"
-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 0000000..07327fd
--- /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 <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