1
0
mirror of git://projects.qi-hardware.com/iris.git synced 2024-07-05 01:35:27 +03:00
iris/boot-programs/lcd.ccp
2009-07-04 16:21:28 +02:00

158 lines
3.8 KiB
COBOL

#pypp 0
// Iris: micro-kernel for a capability-based operating system.
// boot-programs/lcd.ccp: Display driver.
// Copyright 2009 Bas Wijnen <wijnen@debian.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 "devices.hh"
#define ARCH
#include "arch.hh"
// Pin definitions, all in port 2.
#define PWM_ENABLE (1 << 30)
#define SPEN (1 << 0) //LCD_SPL
#define SPCK (1 << 1) //LCD_CLS
#define SPDA (1 << 2) //LCD_PS
#define LCD_RET (1 << 3) //LCD_REV //use for lcd reset
static void set_backlight (bool state):
if state:
PWM_DUT (0) = 300
PWM_CTR (0) = 0xbf
GPIO_GPDR (2) |= PWM_ENABLE
else:
PWM_DUT (0) = 0
PWM_CTR (0) = 0x3f
GPIO_GPDR (2) &= ~PWM_ENABLE
// Write to a register. Value must be in range [0, 0xff].
static void write_reg (unsigned reg, unsigned value):
unsigned data = (reg << 0xa) | 0x200 | value
GPIO_GPDR (2) |= SPEN
GPIO_GPDR (2) = (GPIO_GPDR (2) & ~SPDA) | SPCK
GPIO_GPDR (2) &= ~SPEN
udelay(25)
for unsigned i = 0; i < 16; ++i:
GPIO_GPDR (2) &= ~SPCK
if data & 0x8000:
GPIO_GPDR (2) |= SPDA
else:
GPIO_GPDR (2) &= ~SPDA
udelay (25)
GPIO_GPDR (2) |= SPCK
udelay (25)
data <<= 1
GPIO_GPDR (2) |= SPEN
udelay(200)
static void lcd_enable ():
udelay (50)
GPIO_GPDR (2) &= ~LCD_RET
udelay(150000)
GPIO_GPDR (2) |= LCD_RET
udelay(10000)
// These values have been copied from the linux source.
// I have no idea what they do.
write_reg (0x00, 0x03)
write_reg (0x01, 0x40)
write_reg (0x02, 0x11)
write_reg (0x03, 0xcd)
write_reg (0x04, 0x32)
write_reg (0x05, 0x0e)
write_reg (0x07, 0x03)
write_reg (0x08, 0x08)
write_reg (0x09, 0x32)
write_reg (0x0A, 0x88)
write_reg (0x0B, 0xc6)
write_reg (0x0C, 0x20)
write_reg (0x0D, 0x20)
set_backlight (true)
static void lcd_disable ():
write_reg (0x00, 0x03)
set_backlight (false)
static void reset ():
gpio_as_pwm ()
gpio_as_lcd_master ()
GPIO_GPDR (2) &= ~PWM_ENABLE
PWM_CTR (0) = 0x3f
PWM_PER (0) = 300
pwm_set_duty (0, 300)
pwm_set_full_duty (0)
// initialize things.
GPIO_GPIER (2) &= ~(PWM_ENABLE | LCD_RET | SPEN | SPCK | SPDA)
GPIO_GPDIR (2) |= PWM_ENABLE | LCD_RET | SPEN | SPCK | SPDA
udelay (50)
GPIO_GPDR (2) &= ~LCD_RET
udelay (150000)
GPIO_GPDR (2) |= LCD_RET
udelay (10000)
lcd_enable ()
// For now, support only 16 bpp.
// Screen is 800x480 tft.
LCD_CTRL = LCD_CTRL_BPP_16 | LCD_CTRL_BST_16
LCD_VSYNC = 20
LCD_HSYNC = 80
LCD_DAV = (20 << 16) | 500
LCD_DAH = (80 << 16) | 880
LCD_VAT = (880 << 16) | 500
//LCD_CFG = MODE_TFT_GEN | PCLK_N | VSYNC_N
// Stop lcd.
CPM_MSCR |= 1 << 7
unsigned pclk = 60 * (800 * 3 + 80) * 500
unsigned pllout = cpm_get_pllout ()
CPM_CFCR2 = pllout / pclk - 1
unsigned v = pllout / (pclk * 4) - 1
while v < 0xf && pllout / (v + 1) > 150000000:
++v
CPM_CFCR = (CPM_CFCR & ~CPM_CFCR_LFR_MASK) | (v << CPM_CFCR_LFR_BIT) | CPM_CFCR_UPE
// Start lcd.
CPM_MSCR &= ~(1 << 7)
udelay (1000)
int main ():
map_gpio ()
map_pwm0 ()
map_lcd ()
map_cpm ()
reset ()
while true:
set_backlight (false)
kdebug (0)
set_backlight (true)
kdebug (0)
schedule ()
while true:
Message msg
if !wait (&msg):
continue
switch msg.protected_data:
case LCD_BACKLIGHT:
set_backlight (msg.data[0])
break
case LCD_RESET:
reset ()
break