Jens Arnold | ad4e3d6 | 2007-03-26 07:52:13 +0000 | [diff] [blame] | 1 | /*************************************************************************** |
| 2 | * __________ __ ___. |
| 3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ |
| 4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / |
| 5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < |
| 6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ |
| 7 | * \/ \/ \/ \/ \/ |
Jens Arnold | 8f872e8 | 2007-04-03 19:06:14 +0000 | [diff] [blame] | 8 | * $Id$ |
Jens Arnold | ad4e3d6 | 2007-03-26 07:52:13 +0000 | [diff] [blame] | 9 | * |
| 10 | * Copyright (C) 2007 by Jens Arnold |
| 11 | * Based on the work of Alan Korr, Kjell Ericson and others |
| 12 | * |
Daniel Stenberg | 2acc0ac | 2008-06-28 18:10:04 +0000 | [diff] [blame^] | 13 | * 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 Arnold | ad4e3d6 | 2007-03-26 07:52:13 +0000 | [diff] [blame] | 17 | * |
| 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 Arnold | 54ea2e4 | 2007-03-31 09:58:49 +0000 | [diff] [blame] | 28 | #include "lcd-charcell.h" |
Jens Arnold | ad4e3d6 | 2007-03-26 07:52:13 +0000 | [diff] [blame] | 29 | |
Jens Arnold | 0430632 | 2007-04-03 19:04:33 +0000 | [diff] [blame] | 30 | #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 Arnold | ad4e3d6 | 2007-03-26 07:52:13 +0000 | [diff] [blame] | 33 | #define OLD_LCD_CONTRAST_SET ((char)0xA8) |
Jens Arnold | 61350bf | 2007-04-03 21:22:48 +0000 | [diff] [blame] | 34 | #define OLD_LCD_NOP ((char)0x00) |
Jens Arnold | 0430632 | 2007-04-03 19:04:33 +0000 | [diff] [blame] | 35 | #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 Arnold | ad4e3d6 | 2007-03-26 07:52:13 +0000 | [diff] [blame] | 39 | |
Jens Arnold | 0430632 | 2007-04-03 19:04:33 +0000 | [diff] [blame] | 40 | #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 Arnold | ad4e3d6 | 2007-03-26 07:52:13 +0000 | [diff] [blame] | 43 | #define NEW_LCD_CONTRAST_SET ((char)0x50) |
Jens Arnold | 61350bf | 2007-04-03 21:22:48 +0000 | [diff] [blame] | 44 | #define NEW_LCD_NOP ((char)0x00) |
Jens Arnold | 0430632 | 2007-04-03 19:04:33 +0000 | [diff] [blame] | 45 | #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 Arnold | ad4e3d6 | 2007-03-26 07:52:13 +0000 | [diff] [blame] | 50 | |
Jens Arnold | 0430632 | 2007-04-03 19:04:33 +0000 | [diff] [blame] | 51 | #define LCD_CURSOR(x,y) ((char)(lcd_ddram+((y)*16+(x)))) |
| 52 | #define LCD_ICON(i) ((char)(lcd_iconram+i)) |
Jens Arnold | ad4e3d6 | 2007-03-26 07:52:13 +0000 | [diff] [blame] | 53 | |
| 54 | static bool new_lcd; |
| 55 | static char lcd_contrast_set; |
Jens Arnold | 0430632 | 2007-04-03 19:04:33 +0000 | [diff] [blame] | 56 | static char lcd_ddram; |
| 57 | static char lcd_cgram; |
| 58 | static char lcd_iconram; |
Jens Arnold | ad4e3d6 | 2007-03-26 07:52:13 +0000 | [diff] [blame] | 59 | |
| 60 | /* hardware configuration */ |
| 61 | |
| 62 | int lcd_default_contrast(void) |
| 63 | { |
| 64 | return 30; |
| 65 | } |
| 66 | |
| 67 | void lcd_set_contrast(int val) |
| 68 | { |
| 69 | lcd_write_command_e(lcd_contrast_set, 31 - val); |
| 70 | } |
| 71 | |
| 72 | /* charcell specific */ |
| 73 | |
| 74 | void 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 Arnold | ad4e3d6 | 2007-03-26 07:52:13 +0000 | [diff] [blame] | 81 | void 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 */ |
| 115 | void lcd_init_device(void) |
| 116 | { |
| 117 | unsigned char data_vector[64]; |
| 118 | |
Jens Arnold | 61350bf | 2007-04-03 21:22:48 +0000 | [diff] [blame] | 119 | /* 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 Arnold | ad4e3d6 | 2007-03-26 07:52:13 +0000 | [diff] [blame] | 124 | new_lcd = is_new_player(); |
| 125 | |
| 126 | if (new_lcd) |
| 127 | { |
| 128 | lcd_contrast_set = NEW_LCD_CONTRAST_SET; |
Jens Arnold | 0430632 | 2007-04-03 19:04:33 +0000 | [diff] [blame] | 129 | lcd_ddram = NEW_LCD_DDRAM; |
| 130 | lcd_cgram = NEW_LCD_CGRAM; |
| 131 | lcd_iconram = NEW_LCD_ICONRAM; |
Jens Arnold | ad4e3d6 | 2007-03-26 07:52:13 +0000 | [diff] [blame] | 132 | |
Jens Arnold | 0430632 | 2007-04-03 19:04:33 +0000 | [diff] [blame] | 133 | lcd_write_command(NEW_LCD_FUNCTION_SET|1); /* CGRAM selected */ |
Jens Arnold | ad4e3d6 | 2007-03-26 07:52:13 +0000 | [diff] [blame] | 134 | lcd_write_command_e(NEW_LCD_CONTRAST_SET, 0x08); |
Jens Arnold | 0430632 | 2007-04-03 19:04:33 +0000 | [diff] [blame] | 135 | 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 Arnold | ad4e3d6 | 2007-03-26 07:52:13 +0000 | [diff] [blame] | 139 | |
| 140 | memset(data_vector, 0x20, 64); |
Jens Arnold | 0430632 | 2007-04-03 19:04:33 +0000 | [diff] [blame] | 141 | lcd_write_command(NEW_LCD_DDRAM); /* Set DDRAM address */ |
| 142 | lcd_write_data(data_vector, 64); /* all spaces */ |
Jens Arnold | ad4e3d6 | 2007-03-26 07:52:13 +0000 | [diff] [blame] | 143 | |
| 144 | memset(data_vector, 0, 64); |
Jens Arnold | 0430632 | 2007-04-03 19:04:33 +0000 | [diff] [blame] | 145 | 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 Arnold | ad4e3d6 | 2007-03-26 07:52:13 +0000 | [diff] [blame] | 149 | |
Jens Arnold | 0430632 | 2007-04-03 19:04:33 +0000 | [diff] [blame] | 150 | lcd_write_command(NEW_LCD_SET_DISPLAY_CONTROL|1); /* display on */ |
Jens Arnold | ad4e3d6 | 2007-03-26 07:52:13 +0000 | [diff] [blame] | 151 | } |
| 152 | else |
| 153 | { |
| 154 | lcd_contrast_set = OLD_LCD_CONTRAST_SET; |
Jens Arnold | 0430632 | 2007-04-03 19:04:33 +0000 | [diff] [blame] | 155 | lcd_ddram = OLD_LCD_DDRAM; |
| 156 | lcd_cgram = OLD_LCD_CGRAM; |
| 157 | lcd_iconram = OLD_LCD_ICONRAM; |
Jens Arnold | ad4e3d6 | 2007-03-26 07:52:13 +0000 | [diff] [blame] | 158 | |
Jens Arnold | 61350bf | 2007-04-03 21:22:48 +0000 | [diff] [blame] | 159 | lcd_write_command(OLD_LCD_NOP); |
Jens Arnold | 0430632 | 2007-04-03 19:04:33 +0000 | [diff] [blame] | 160 | 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 Arnold | ad4e3d6 | 2007-03-26 07:52:13 +0000 | [diff] [blame] | 165 | |
| 166 | memset(data_vector, 0x24, 13); |
Jens Arnold | 0430632 | 2007-04-03 19:04:33 +0000 | [diff] [blame] | 167 | 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 Arnold | ad4e3d6 | 2007-03-26 07:52:13 +0000 | [diff] [blame] | 170 | lcd_write_data(data_vector, 13); |
Jens Arnold | 0430632 | 2007-04-03 19:04:33 +0000 | [diff] [blame] | 171 | lcd_write_command(OLD_LCD_DDRAM + 0x20); |
Jens Arnold | ad4e3d6 | 2007-03-26 07:52:13 +0000 | [diff] [blame] | 172 | lcd_write_data(data_vector, 13); |
| 173 | |
| 174 | memset(data_vector, 0, 32); |
Jens Arnold | 0430632 | 2007-04-03 19:04:33 +0000 | [diff] [blame] | 175 | 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 Arnold | ad4e3d6 | 2007-03-26 07:52:13 +0000 | [diff] [blame] | 180 | lcd_write_data(data_vector, 13); |
| 181 | |
Jens Arnold | 61350bf | 2007-04-03 21:22:48 +0000 | [diff] [blame] | 182 | sleep(HZ/10); |
Jens Arnold | 0430632 | 2007-04-03 19:04:33 +0000 | [diff] [blame] | 183 | lcd_write_command(OLD_LCD_SET_DISPLAY_CONTROL|1); /* display on */ |
Jens Arnold | ad4e3d6 | 2007-03-26 07:52:13 +0000 | [diff] [blame] | 184 | } |
| 185 | lcd_set_contrast(lcd_default_contrast()); |
| 186 | } |
Jens Arnold | 54ea2e4 | 2007-03-31 09:58:49 +0000 | [diff] [blame] | 187 | |
| 188 | /*** Update functions ***/ |
| 189 | |
| 190 | void 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 Arnold | 0430632 | 2007-04-03 19:04:33 +0000 | [diff] [blame] | 198 | lcd_write_command(lcd_cgram | (y << 3)); |
Jens Arnold | 54ea2e4 | 2007-03-31 09:58:49 +0000 | [diff] [blame] | 199 | 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 | } |