aboutsummaryrefslogtreecommitdiff
path: root/examples/efm32/tinygecko/efm32-tg-stk3300/lcd_demo
diff options
context:
space:
mode:
Diffstat (limited to 'examples/efm32/tinygecko/efm32-tg-stk3300/lcd_demo')
-rw-r--r--examples/efm32/tinygecko/efm32-tg-stk3300/lcd_demo/Makefile23
-rw-r--r--examples/efm32/tinygecko/efm32-tg-stk3300/lcd_demo/README8
-rw-r--r--examples/efm32/tinygecko/efm32-tg-stk3300/lcd_demo/generate_lcd_mapping.py76
-rw-r--r--examples/efm32/tinygecko/efm32-tg-stk3300/lcd_demo/lcd_demo.c130
-rw-r--r--examples/efm32/tinygecko/efm32-tg-stk3300/lcd_demo/lcd_mapping.yaml192
5 files changed, 429 insertions, 0 deletions
diff --git a/examples/efm32/tinygecko/efm32-tg-stk3300/lcd_demo/Makefile b/examples/efm32/tinygecko/efm32-tg-stk3300/lcd_demo/Makefile
new file mode 100644
index 0000000..7ef06ad
--- /dev/null
+++ b/examples/efm32/tinygecko/efm32-tg-stk3300/lcd_demo/Makefile
@@ -0,0 +1,23 @@
+##
+## This file is part of the libopencm3 project.
+##
+## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
+## Copyright (C) 2012 chrysn <chrysn@fsfe.org>
+##
+## 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 <http://www.gnu.org/licenses/>.
+##
+
+BINARY = lcd_demo
+
+include ../Makefile.include
diff --git a/examples/efm32/tinygecko/efm32-tg-stk3300/lcd_demo/README b/examples/efm32/tinygecko/efm32-tg-stk3300/lcd_demo/README
new file mode 100644
index 0000000..207ed10
--- /dev/null
+++ b/examples/efm32/tinygecko/efm32-tg-stk3300/lcd_demo/README
@@ -0,0 +1,8 @@
+=========================================
+EFM32-TG-STK3300 Examples LCD Demo README
+=========================================
+
+This is an example on how to use the LCD peripherial on Energy Micro Tiny Gecko
+chips.
+
+It's intended for the EFM32-TG-STK3300 eval board.
diff --git a/examples/efm32/tinygecko/efm32-tg-stk3300/lcd_demo/generate_lcd_mapping.py b/examples/efm32/tinygecko/efm32-tg-stk3300/lcd_demo/generate_lcd_mapping.py
new file mode 100644
index 0000000..1b6405f
--- /dev/null
+++ b/examples/efm32/tinygecko/efm32-tg-stk3300/lcd_demo/generate_lcd_mapping.py
@@ -0,0 +1,76 @@
+#!/usr/bin/env python
+
+import yaml
+
+class Font(dict):
+ def __init__(self, letterdict):
+ for (k, v) in letterdict.items():
+ self[k] = set(v.split())
+
+class Display(object):
+ def __init__(self, data):
+ self.mapping = {}
+
+ for c, segs in enumerate(data['coms']):
+ for s, name in enumerate(segs):
+ self.mapping[name] = (c, s)
+
+ def render_text(self, text, symbols, font):
+ cursor = 1
+ segments = set()
+ for letter in text:
+ if letter == '.':
+ segments.add("a%s_dp"%(cursor-1))
+ elif letter == ':':
+ segments.add("a%s_colon"%(cursor-1))
+ elif letter in font:
+ for segment in font[letter]:
+ segments.add("a%s_%s"%(cursor, segment))
+ cursor += 1
+
+ for s in symbols:
+ segments.add(s)
+
+ coms = {}
+ for segment in segments:
+ com, seg = self.mapping[segment]
+ coms[com] = coms.get(com, 0) | (1<<seg)
+
+ return coms
+
+def main():
+ data = yaml.load(open("lcd_mapping.yaml"))
+
+ d = Display(data)
+
+ text = "{FNORD}"
+ symbols = ['gecko']
+ f = Font({
+ '-': 'g1 g2',
+ 'A': 'e f a b c g1 g2',
+ 'C': 'a f e d',
+ 'D': 'a b c d i l',
+ 'E': 'a f g1 g2 e d',
+ 'F': 'a f g1 g2 e',
+ 'H': "f b g1 g2 e c",
+ 'I': "i l a d",
+ 'L': 'f e d',
+ 'M': 'e f h j b c',
+ 'N': 'e f h m c b',
+ 'O': 'a f e d c b',
+ 'R': 'a e f g1 j m',
+ 'T': 'i l a',
+ 'U': 'f e d c b',
+ '[': 'a d e f',
+ ']': 'a b c d',
+ '{': 'a d k h g1',
+ '}': 'a j g2 m d',
+ })
+
+ for com, data in d.render_text(text, symbols, f).items():
+ print "set_bank(%d, %#08.0x);"%(com, data)
+# with open('lcd_mapping.c', 'w') as outfile:
+# for symbol in data['symbols']:
+
+if __name__ == "__main__":
+ main()
diff --git a/examples/efm32/tinygecko/efm32-tg-stk3300/lcd_demo/lcd_demo.c b/examples/efm32/tinygecko/efm32-tg-stk3300/lcd_demo/lcd_demo.c
new file mode 100644
index 0000000..d4ddb74
--- /dev/null
+++ b/examples/efm32/tinygecko/efm32-tg-stk3300/lcd_demo/lcd_demo.c
@@ -0,0 +1,130 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2012 chrysn <chrysn@fsfe.org>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+/** @file
+ * Demo of the LCD display aboard the EFM32-TG-STK330 eval board.
+ */
+
+#include <libopencm3/efm32/tinygecko/cmu.h>
+#include <libopencm3/efm32/tinygecko/gpio.h>
+#include <libopencm3/efm32/tinygecko/lcd.h>
+#include "../lightswitch/lightswitch-common.c"
+void led_toggle(void) { gpio_toggle(GPIO_PD, GPIO7); }
+
+void delay(void)
+{
+ int x;
+
+ /* Start up delay until we mess with clock stuff, so the debugger can catch up. */
+ for(x = 0; x < 10000000; ++x) led_on();
+}
+
+void lcd_init(void)
+{
+ /* LCD is a LE module. We're constantly powered on for now, so using
+ * HFCORECLK/2 */
+ CMU_HFCORECLKEN0 |= CMU_HFCORECLKEN0_LE;
+ CMU_LFCLKSEL = (CMU_LFCLKSEL & ~CMU_LFCLKSEL_LFA_MASK) | CMU_LFCLKSEL_LFA_HFCORECLKLEDIV2;
+ /* We need to get this down to reasonable 100Hz from 14MHz, 7MHz at
+ * LFACLK, 70kHz after LFA prescaler, 10kHz after FDIV. Octaplexing
+ * brings us down to about 500Hz. */
+ CMU_LFAPRESC0 |= CMU_LFAPRESC0_LCD_DIV128;
+ CMU_LCDCTRL |= CMU_LCDCTRL_FDIV_MASK; /* factor 7+1 */
+
+ /* If we don't wait for the prescaler to become ready, the "Do it" step
+ * won't pass. */
+ while (CMU_SYNCBUSY & CMU_SYNCBUSY_LFAPRESC0);
+
+ CMU_LFACLKEN0 |= CMU_LFACLKEN0_LCD;
+
+ while (CMU_SYNCBUSY & CMU_SYNCBUSY_LFACLKEN0);
+
+ /* Voltage is around 3.3V anyway, we don't need voltage boosting,
+ * leaving it disabled. I don't fully understand the implications of
+ * biasing yet, but it seems like he more biased the better, and will
+ * just affect frame rate negatively. */
+ LCD_DISPCTRL = (LCD_DISPCTRL & ~(LCD_DISPCTRL_BIAS_MASK | LCD_DISPCTRL_MUX_MASK)) | LCD_DISPCTRL_BIAS_ONEFOURTH | LCD_DISPCTRL_MUX_OCTAPLEX;
+
+ /* Segments default to disabled, enable the 20 relevant ones */
+ LCD_SEGEN = ~(~0<<5);
+
+ /* Do it */
+ LCD_CTRL |= LCD_CTRL_EN;
+
+ while (LCD_SYNCBUSY & LCD_SYNCBUSY_CTRL) led_off();
+ led_on();
+}
+
+void set_bank(u8 com, u32 data)
+{
+ switch(com)
+ {
+ case 0: LCD_SEGD0L = data; break;
+ case 1: LCD_SEGD1L = data; break;
+ case 2: LCD_SEGD2L = data; break;
+ case 3: LCD_SEGD3L = data; break;
+ case 4: LCD_SEGD4L = data; break;
+ case 5: LCD_SEGD5L = data; break;
+ case 6: LCD_SEGD6L = data; break;
+ case 7: LCD_SEGD7L = data; break;
+ }
+}
+
+int main(void)
+{
+ u8 active_bit = 0;
+ u8 active_com = 0;
+
+ gpio_setup();
+
+// delay();
+
+ lcd_init();
+
+ /* "{FNORD}" with a gecko as generated by current generate_lcd_mapping.py */
+set_bank(0, 0x000a00);
+set_bank(1, 0x0031cb);
+set_bank(2, 0x004622);
+set_bank(3, 0x0012a8);
+set_bank(4, 0x00481a);
+set_bank(5, 0x001140);
+set_bank(6, 0x004642);
+set_bank(7, 0x0051ac);
+
+ while(1)
+ {
+ if (pb0_get())
+ {
+ while(pb0_get());
+
+ set_bank(active_com, ~0);
+ active_bit = (active_bit + 1) % 21; /* one more to see where 0 is */
+ set_bank(active_com, ~(1<<active_bit));
+ }
+ if (pb1_get())
+ {
+ while(pb1_get());
+
+ set_bank(active_com, ~0);
+ active_com = (active_com + 1) % 9; /* one more to see where 0 is */
+ set_bank(active_com, ~(1<<active_bit));
+ }
+ led_toggle();
+ }
+}
diff --git a/examples/efm32/tinygecko/efm32-tg-stk3300/lcd_demo/lcd_mapping.yaml b/examples/efm32/tinygecko/efm32-tg-stk3300/lcd_demo/lcd_mapping.yaml
new file mode 100644
index 0000000..e3efbe1
--- /dev/null
+++ b/examples/efm32/tinygecko/efm32-tg-stk3300/lcd_demo/lcd_mapping.yaml
@@ -0,0 +1,192 @@
+description:
+ LCD segment layout for the EFM32TG_STK3300 kit.
+
+ Determined by trial and error.
+
+ The digit display is called D1..D4 left to right, the alphanumerics
+ A1..A7.
+
+ The 7 segment display bars are labeled a..g from top cw with g being
+ the last in the center.
+
+ The 14 segment display bars are labelled a..f as with 7-segment, g1
+ and g2 the parts of 7-segment's g from left to right, and then h, i,
+ j left to right top parts, and k, l, m left to right bottom parts.
+
+ (Labelling according to the 7 segment display Wikipedia article; for 14,
+ found in German Wikipedia.)
+
+ Sectors start at the top, CCW.
+
+ Rings are numbered from the outside startin at 0, the dot in the middle
+ being 4.
+symbols: [efm, antenna, celsius, fahrenheit]
+coms:
+ -
+ - sector_0
+ - sector_1
+ - sector_2
+ - sector_3
+ - sector_4
+ - sector_5
+ - sector_6
+ - sector_7
+ - efm
+ - a5_a
+ - a4_colon
+ - a6_a
+ - antenna
+ - battery_outline
+ - celsius
+ - fahrenheit
+ - battery_1
+ - battery_0
+ - battery_2
+ - ring0
+ -
+ - gecko
+ - a1_a
+ - a1_b
+ - a2_a
+ - a2_b
+ - a3_a
+ - a3_b
+ - a4_a
+ - a4_b
+ - a5_h
+ - a5_b
+ - a6_h
+ - a6_b
+ - a7_a
+ - a7_b
+ - d4_d
+ - d3_d
+ - d2_d
+ - d1_d
+ - ring1
+ -
+ - lock_closed
+ - a1_h
+ - a1_j
+ - a2_h
+ - a2_j
+ - a3_h
+ - a3_j
+ - a4_h
+ - a4_j
+ - a5_f
+ - a5_j
+ - a6_f
+ - a6_j
+ - a7_h
+ - a7_j
+ - d4_c
+ - d3_c
+ - d2_c
+ - d1_c
+ - ring3
+ -
+ - a_minus
+ - a1_f
+ - a1_i
+ - a2_f
+ - a2_i
+ - a3_f
+ - a3_i
+ - a4_f
+ - a4_i
+ - a5_g1
+ - a5_i
+ - a6_g1
+ - a6_i
+ - a7_f
+ - a7_i
+ - d4_e
+ - d3_e
+ - d2_e
+ - d1_e
+ - lock_open
+ -
+ - a2_colon
+ - a1_g1
+ - a1_g2
+ - a2_g1
+ - a2_g2
+ - a3_g1
+ - a3_g2
+ - a4_g1
+ - a4_g2
+ - a5_l
+ - a5_g2
+ - a6_l
+ - a6_g2
+ - a7_g1
+ - a7_g2
+ - d4_g
+ - d3_g
+ - d2_g
+ - d1_g
+ - d2_dp
+ -
+ - a2_dp
+ - a1_l
+ - a1_c
+ - a2_l
+ - a2_c
+ - a3_l
+ - a3_c
+ - a4_l
+ - a4_c
+ - a5_k
+ - a5_c
+ - a6_k
+ - a6_c
+ - a7_l
+ - a7_c
+ - d4_b
+ - d3_b
+ - d2_b
+ - d1_b
+ - d2_dp
+ -
+ - a4_dp
+ - a1_k
+ - a1_m
+ - a2_k
+ - a2_m
+ - a3_k
+ - a3_m
+ - a4_k
+ - a4_m
+ - a5_e
+ - a5_m
+ - a6_e
+ - a6_m
+ - a7_k
+ - a7_m
+ - d4_f
+ - d3_f
+ - d2_f
+ - d1_f
+ - ring4
+ -
+ - a1_dp
+ - a1_e
+ - a1_d
+ - a2_e
+ - a2_d
+ - a3_e
+ - a3_d
+ - a4_e
+ - a4_d
+ - a4_dp
+ - a5_d
+ - a5_dp
+ - a6_d
+ - a7_e
+ - a7_d
+ - d4_a
+ - d3_a
+ - d2_a
+ - d1_a
+ - ring2