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 00000000..7ef06ad9 --- /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 +## Copyright (C) 2012 chrysn +## +## 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 . +## + +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 00000000..207ed107 --- /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 00000000..1b6405f5 --- /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< + * + * 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 . + */ + +/** @file + * Demo of the LCD display aboard the EFM32-TG-STK330 eval board. + */ + +#include +#include +#include +#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<