blob: 330cc266bca1098625e16c12118bd65f1d2a86ea [file] [log] [blame]
Jens Arnoldad4e3d62007-03-26 07:52:13 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
Jens Arnold8f872e82007-04-03 19:06:14 +00008 * $Id$
Jens Arnoldad4e3d62007-03-26 07:52:13 +00009 *
10 * Copyright (C) 2007 by Jens Arnold
11 * Based on the work of Alan Korr, Kjell Ericson and others
12 *
Daniel Stenberg2acc0ac2008-06-28 18:10:04 +000013 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
Jens Arnoldad4e3d62007-03-26 07:52:13 +000017 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ****************************************************************************/
22
23#include "config.h"
24#include <string.h>
25#include "hwcompat.h"
26#include "system.h"
27#include "lcd.h"
Jens Arnold54ea2e42007-03-31 09:58:49 +000028#include "lcd-charcell.h"
Jens Arnoldad4e3d62007-03-26 07:52:13 +000029
Jens Arnold04306322007-04-03 19:04:33 +000030#define OLD_LCD_DDRAM ((char)0xB0) /* Display data (characters) */
31#define OLD_LCD_CGRAM ((char)0x80) /* Character generator (patterns) */
32#define OLD_LCD_ICONRAM ((char)0xE0)
Jens Arnoldad4e3d62007-03-26 07:52:13 +000033#define OLD_LCD_CONTRAST_SET ((char)0xA8)
Jens Arnold61350bf2007-04-03 21:22:48 +000034#define OLD_LCD_NOP ((char)0x00)
Jens Arnold04306322007-04-03 19:04:33 +000035#define OLD_LCD_SYSTEM_SET ((char)0x60)
36#define OLD_LCD_SET_POWER_SAVE_OSC_CONTROL ((char)0x40)
37#define OLD_LCD_SET_POWER_CONTROL ((char)0x50)
38#define OLD_LCD_SET_DISPLAY_CONTROL ((char)0x30)
Jens Arnoldad4e3d62007-03-26 07:52:13 +000039
Jens Arnold04306322007-04-03 19:04:33 +000040#define NEW_LCD_DDRAM ((char)0x80) /* Display data (characters) */
41#define NEW_LCD_CGRAM ((char)0xC0) /* Character generator (patterns) */
42#define NEW_LCD_ICONRAM ((char)0x40)
Jens Arnoldad4e3d62007-03-26 07:52:13 +000043#define NEW_LCD_CONTRAST_SET ((char)0x50)
Jens Arnold61350bf2007-04-03 21:22:48 +000044#define NEW_LCD_NOP ((char)0x00)
Jens Arnold04306322007-04-03 19:04:33 +000045#define NEW_LCD_FUNCTION_SET ((char)0x10)
46#define NEW_LCD_SET_POWER_SAVE_OSC_CONTROL ((char)0x0c)
47#define NEW_LCD_SET_POWER_CONTROL_REG ((char)0x20)
48#define NEW_LCD_SET_DISPLAY_CONTROL ((char)0x28)
49#define NEW_LCD_SET_DOUBLE_HEIGHT ((char)0x08)
Jens Arnoldad4e3d62007-03-26 07:52:13 +000050
Jens Arnold04306322007-04-03 19:04:33 +000051#define LCD_CURSOR(x,y) ((char)(lcd_ddram+((y)*16+(x))))
52#define LCD_ICON(i) ((char)(lcd_iconram+i))
Jens Arnoldad4e3d62007-03-26 07:52:13 +000053
54static bool new_lcd;
55static char lcd_contrast_set;
Jens Arnold04306322007-04-03 19:04:33 +000056static char lcd_ddram;
57static char lcd_cgram;
58static char lcd_iconram;
Jens Arnoldad4e3d62007-03-26 07:52:13 +000059
60/* hardware configuration */
61
62int lcd_default_contrast(void)
63{
64 return 30;
65}
66
67void lcd_set_contrast(int val)
68{
69 lcd_write_command_e(lcd_contrast_set, 31 - val);
70}
71
72/* charcell specific */
73
74void lcd_double_height(bool on)
75{
76 if(new_lcd)
77 lcd_write_command(on ? (NEW_LCD_SET_DOUBLE_HEIGHT|1)
78 : NEW_LCD_SET_DOUBLE_HEIGHT);
79}
80
Jens Arnoldad4e3d62007-03-26 07:52:13 +000081void lcd_icon(int icon, bool enable)
82{
83 static const struct {
84 char pos;
85 char mask;
86 } icontab[] = {
87 { 0, 0x02}, { 0, 0x08}, { 0, 0x04}, { 0, 0x10}, /* Battery */
88 { 2, 0x04}, /* USB */
89 { 3, 0x10}, /* Play */
90 { 4, 0x10}, /* Record */
91 { 5, 0x02}, /* Pause */
92 { 5, 0x10}, /* Audio */
93 { 6, 0x02}, /* Repeat */
94 { 7, 0x01}, /* 1 */
95 { 9, 0x04}, /* Volume */
96 { 9, 0x02}, { 9, 0x01}, {10, 0x08}, {10, 0x04}, {10, 0x01}, /* Vol 1-5 */
97 {10, 0x10}, /* Param */
98 };
99 static char icon_mirror[11] = {0};
100
101 int pos, mask;
102
103 pos = icontab[icon].pos;
104 mask = icontab[icon].mask;
105
106 if (enable)
107 icon_mirror[pos] |= mask;
108 else
109 icon_mirror[pos] &= ~mask;
110
111 lcd_write_command_e(LCD_ICON(pos), icon_mirror[pos]);
112}
113
114/* device specific init */
115void lcd_init_device(void)
116{
117 unsigned char data_vector[64];
118
Jens Arnold61350bf2007-04-03 21:22:48 +0000119 /* LCD init for cold start */
120 PBCR2 &= 0xff00; /* Set PB0..PB3 to GPIO */
121 or_b(0x0f, &PBDRL); /* ... high */
122 or_b(0x0f, &PBIORL); /* ... and output */
123
Jens Arnoldad4e3d62007-03-26 07:52:13 +0000124 new_lcd = is_new_player();
125
126 if (new_lcd)
127 {
128 lcd_contrast_set = NEW_LCD_CONTRAST_SET;
Jens Arnold04306322007-04-03 19:04:33 +0000129 lcd_ddram = NEW_LCD_DDRAM;
130 lcd_cgram = NEW_LCD_CGRAM;
131 lcd_iconram = NEW_LCD_ICONRAM;
Jens Arnoldad4e3d62007-03-26 07:52:13 +0000132
Jens Arnold04306322007-04-03 19:04:33 +0000133 lcd_write_command(NEW_LCD_FUNCTION_SET|1); /* CGRAM selected */
Jens Arnoldad4e3d62007-03-26 07:52:13 +0000134 lcd_write_command_e(NEW_LCD_CONTRAST_SET, 0x08);
Jens Arnold04306322007-04-03 19:04:33 +0000135 lcd_write_command(NEW_LCD_SET_POWER_SAVE_OSC_CONTROL|2);
136 /* oscillator on */
137 lcd_write_command(NEW_LCD_SET_POWER_CONTROL_REG|7);
138 /* opamp buffer + voltage booster on */
Jens Arnoldad4e3d62007-03-26 07:52:13 +0000139
140 memset(data_vector, 0x20, 64);
Jens Arnold04306322007-04-03 19:04:33 +0000141 lcd_write_command(NEW_LCD_DDRAM); /* Set DDRAM address */
142 lcd_write_data(data_vector, 64); /* all spaces */
Jens Arnoldad4e3d62007-03-26 07:52:13 +0000143
144 memset(data_vector, 0, 64);
Jens Arnold04306322007-04-03 19:04:33 +0000145 lcd_write_command(NEW_LCD_CGRAM); /* Set CGRAM address */
146 lcd_write_data(data_vector, 64); /* zero out */
147 lcd_write_command(NEW_LCD_ICONRAM); /* Set ICONRAM address */
148 lcd_write_data(data_vector, 16); /* zero out */
Jens Arnoldad4e3d62007-03-26 07:52:13 +0000149
Jens Arnold04306322007-04-03 19:04:33 +0000150 lcd_write_command(NEW_LCD_SET_DISPLAY_CONTROL|1); /* display on */
Jens Arnoldad4e3d62007-03-26 07:52:13 +0000151 }
152 else
153 {
154 lcd_contrast_set = OLD_LCD_CONTRAST_SET;
Jens Arnold04306322007-04-03 19:04:33 +0000155 lcd_ddram = OLD_LCD_DDRAM;
156 lcd_cgram = OLD_LCD_CGRAM;
157 lcd_iconram = OLD_LCD_ICONRAM;
Jens Arnoldad4e3d62007-03-26 07:52:13 +0000158
Jens Arnold61350bf2007-04-03 21:22:48 +0000159 lcd_write_command(OLD_LCD_NOP);
Jens Arnold04306322007-04-03 19:04:33 +0000160 lcd_write_command(OLD_LCD_SYSTEM_SET|1); /* CGRAM selected */
161 lcd_write_command(OLD_LCD_SET_POWER_SAVE_OSC_CONTROL|2);
162 /* oscillator on */
163 lcd_write_command(OLD_LCD_SET_POWER_CONTROL|7);
164 /* voltage regulator, voltage follower and booster on */
Jens Arnoldad4e3d62007-03-26 07:52:13 +0000165
166 memset(data_vector, 0x24, 13);
Jens Arnold04306322007-04-03 19:04:33 +0000167 lcd_write_command(OLD_LCD_DDRAM); /* Set DDRAM address */
168 lcd_write_data(data_vector, 13); /* all spaces */
169 lcd_write_command(OLD_LCD_DDRAM + 0x10);
Jens Arnoldad4e3d62007-03-26 07:52:13 +0000170 lcd_write_data(data_vector, 13);
Jens Arnold04306322007-04-03 19:04:33 +0000171 lcd_write_command(OLD_LCD_DDRAM + 0x20);
Jens Arnoldad4e3d62007-03-26 07:52:13 +0000172 lcd_write_data(data_vector, 13);
173
174 memset(data_vector, 0, 32);
Jens Arnold04306322007-04-03 19:04:33 +0000175 lcd_write_command(OLD_LCD_CGRAM); /* Set CGRAM address */
176 lcd_write_data(data_vector, 32); /* zero out */
177 lcd_write_command(OLD_LCD_ICONRAM); /* Set ICONRAM address */
178 lcd_write_data(data_vector, 13); /* zero out */
179 lcd_write_command(OLD_LCD_ICONRAM + 0x10);
Jens Arnoldad4e3d62007-03-26 07:52:13 +0000180 lcd_write_data(data_vector, 13);
181
Jens Arnold61350bf2007-04-03 21:22:48 +0000182 sleep(HZ/10);
Jens Arnold04306322007-04-03 19:04:33 +0000183 lcd_write_command(OLD_LCD_SET_DISPLAY_CONTROL|1); /* display on */
Jens Arnoldad4e3d62007-03-26 07:52:13 +0000184 }
185 lcd_set_contrast(lcd_default_contrast());
186}
Jens Arnold54ea2e42007-03-31 09:58:49 +0000187
188/*** Update functions ***/
189
190void lcd_update(void)
191{
192 int y;
193
194 for (y = 0; y < lcd_pattern_count; y++)
195 {
196 if (lcd_patterns[y].count > 0)
197 {
Jens Arnold04306322007-04-03 19:04:33 +0000198 lcd_write_command(lcd_cgram | (y << 3));
Jens Arnold54ea2e42007-03-31 09:58:49 +0000199 lcd_write_data(lcd_patterns[y].pattern, 7);
200 }
201 }
202 for (y = 0; y < LCD_HEIGHT; y++)
203 {
204 lcd_write_command(LCD_CURSOR(0, y));
205 lcd_write_data(lcd_charbuffer[y], LCD_WIDTH);
206 }
207 if (lcd_cursor.visible)
208 {
209 lcd_write_command_e(LCD_CURSOR(lcd_cursor.x, lcd_cursor.y),
210 lcd_cursor.hw_char);
211 }
212}