/* * This file is part of the libopencm3 project. * * 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 . */ /** @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<