summaryrefslogtreecommitdiff
path: root/firmware/target/coldfire/iaudio/m5/lcd-m5.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/coldfire/iaudio/m5/lcd-m5.c')
-rw-r--r--firmware/target/coldfire/iaudio/m5/lcd-m5.c219
1 files changed, 219 insertions, 0 deletions
diff --git a/firmware/target/coldfire/iaudio/m5/lcd-m5.c b/firmware/target/coldfire/iaudio/m5/lcd-m5.c
new file mode 100644
index 0000000000..2af46b3145
--- /dev/null
+++ b/firmware/target/coldfire/iaudio/m5/lcd-m5.c
@@ -0,0 +1,219 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2007 by Jens Arnold
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#include "config.h"
20
21#include "system.h"
22#include "kernel.h"
23#include "lcd.h"
24
25/*** definitions ***/
26
27/* LCD command codes */
28#define LCD_CNTL_POWER_CONTROL 0x25
29#define LCD_CNTL_VOLTAGE_SELECT 0x2b
30#define LCD_CNTL_LINE_INVERT_DRIVE 0x36
31#define LCD_CNTL_GRAY_SCALE_PATTERN 0x39
32#define LCD_CNTL_TEMP_GRADIENT_SELECT 0x4e
33#define LCD_CNTL_OSC_FREQUENCY 0x5f
34#define LCD_CNTL_ON_OFF 0xae
35#define LCD_CNTL_OSC_ON_OFF 0xaa
36#define LCD_CNTL_OFF_MODE 0xbe
37#define LCD_CNTL_POWER_SAVE 0xa8
38#define LCD_CNTL_REVERSE 0xa6
39#define LCD_CNTL_ALL_LIGHTING 0xa4
40#define LCD_CNTL_COMMON_OUTPUT_STATUS 0xc4
41#define LCD_CNTL_COLUMN_ADDRESS_DIR 0xa0
42#define LCD_CNTL_NLINE_ON_OFF 0xe4
43#define LCD_CNTL_DISPLAY_MODE 0x66
44#define LCD_CNTL_DUTY_SET 0x6d
45#define LCD_CNTL_ELECTRONIC_VOLUME 0x81
46#define LCD_CNTL_DATA_INPUT_DIR 0x84
47#define LCD_CNTL_DISPLAY_START_LINE 0x8a
48#define LCD_CNTL_AREA_SCROLL 0x10
49
50#define LCD_CNTL_PAGE 0xb1
51#define LCD_CNTL_COLUMN 0x13
52#define LCD_CNTL_DATA_WRITE 0x1d
53
54/*** shared semi-private declarations ***/
55extern const unsigned char lcd_dibits[16] ICONST_ATTR;
56
57/*** hardware configuration ***/
58int lcd_default_contrast(void)
59{
60 return DEFAULT_CONTRAST_SETTING;
61}
62
63void lcd_set_contrast(int val)
64{
65 /* Keep val in acceptable hw range */
66 if (val < 0)
67 val = 0;
68 else if (val > 127)
69 val = 127;
70
71 lcd_write_command_ex(LCD_CNTL_ELECTRONIC_VOLUME, val, -1);
72}
73
74void lcd_set_invert_display(bool yesno)
75{
76 lcd_write_command(LCD_CNTL_REVERSE | (yesno?1:0));
77}
78
79/* turn the display upside down (call lcd_update() afterwards) */
80void lcd_set_flip(bool yesno)
81{
82 if (yesno)
83 {
84 lcd_write_command(LCD_CNTL_COLUMN_ADDRESS_DIR | 0);
85 lcd_write_command(LCD_CNTL_COMMON_OUTPUT_STATUS | 1);
86 lcd_write_command_ex(LCD_CNTL_DUTY_SET, 0x20, 2);
87 }
88 else
89 {
90 lcd_write_command(LCD_CNTL_COLUMN_ADDRESS_DIR | 1);
91 lcd_write_command(LCD_CNTL_COMMON_OUTPUT_STATUS | 0);
92 lcd_write_command_ex(LCD_CNTL_DUTY_SET, 0x20, 1);
93 }
94}
95
96void lcd_init_device(void)
97{
98 /* LCD Reset */
99 and_l(~0x00000010, &GPIO1_OUT);
100 or_l(0x00000010, &GPIO1_ENABLE);
101 or_l(0x00000010, &GPIO1_FUNCTION);
102 sleep(1);
103 or_l(0x00000010, &GPIO1_OUT);
104 sleep(1);
105
106 lcd_write_command(LCD_CNTL_ON_OFF | 1); /* LCD ON */
107 lcd_write_command(LCD_CNTL_OFF_MODE | 1); /* OFF -> VCC on drivers */
108 lcd_write_command(LCD_CNTL_REVERSE | 0); /* Reverse OFF */
109 lcd_write_command(LCD_CNTL_ALL_LIGHTING | 0); /* Normal */
110 lcd_write_command(LCD_CNTL_COMMON_OUTPUT_STATUS | 0); /* Normal dir */
111 lcd_write_command_ex(LCD_CNTL_DISPLAY_START_LINE, 4, -1);
112 lcd_write_command(LCD_CNTL_COLUMN_ADDRESS_DIR | 1); /* Reverse */
113 lcd_write_command_ex(LCD_CNTL_DISPLAY_MODE, 0, -1); /* Greyscale mode */
114 lcd_write_command_ex(LCD_CNTL_GRAY_SCALE_PATTERN, 0x53, -1);
115 lcd_write_command_ex(LCD_CNTL_DUTY_SET, 0x20, 1);
116 lcd_write_command_ex(LCD_CNTL_ELECTRONIC_VOLUME, 40, -1);
117
118 lcd_write_command(LCD_CNTL_OSC_ON_OFF | 1); /* Oscillator ON */
119 lcd_write_command(LCD_CNTL_POWER_SAVE | 0);
120 lcd_write_command_ex(LCD_CNTL_VOLTAGE_SELECT, 3, -1);
121 lcd_write_command_ex(LCD_CNTL_POWER_CONTROL, 0x17, -1);
122 lcd_write_command_ex(LCD_CNTL_OSC_FREQUENCY, 3, -1);
123 lcd_write_command(LCD_CNTL_NLINE_ON_OFF | 1); /* N-line ON */
124 lcd_write_command_ex(LCD_CNTL_LINE_INVERT_DRIVE, 0x10, -1);
125 lcd_write_command_ex(LCD_CNTL_TEMP_GRADIENT_SELECT, 0, -1);
126
127 lcd_update();
128}
129
130/*** update functions ***/
131
132/* Performance function that works with an external buffer
133 note that by and bheight are in 8-pixel units! */
134void lcd_blit(const unsigned char* data, int x, int by, int width,
135 int bheight, int stride)
136{
137 const unsigned char *src, *src_end;
138 unsigned char *dst_u, *dst_l;
139 static unsigned char upper[LCD_WIDTH] IBSS_ATTR;
140 static unsigned char lower[LCD_WIDTH] IBSS_ATTR;
141 unsigned int byte;
142
143 by *= 2;
144
145 while (bheight--)
146 {
147 src = data;
148 src_end = data + width;
149 dst_u = upper;
150 dst_l = lower;
151 do
152 {
153 byte = *src++;
154 *dst_u++ = lcd_dibits[byte & 0x0F];
155 byte >>= 4;
156 *dst_l++ = lcd_dibits[byte & 0x0F];
157 }
158 while (src < src_end);
159
160 lcd_write_command_ex(LCD_CNTL_PAGE, by++, -1);
161 lcd_write_command_ex(LCD_CNTL_COLUMN, x, -1);
162 lcd_write_command(LCD_CNTL_DATA_WRITE);
163 lcd_write_data(upper, width);
164
165 lcd_write_command_ex(LCD_CNTL_PAGE, by++, -1);
166 lcd_write_command_ex(LCD_CNTL_COLUMN, x, -1);
167 lcd_write_command(LCD_CNTL_DATA_WRITE);
168 lcd_write_data(lower, width);
169
170 data += stride;
171 }
172}
173
174
175/* Update the display.
176 This must be called after all other LCD functions that change the display. */
177void lcd_update(void) ICODE_ATTR;
178void lcd_update(void)
179{
180 int y;
181
182 /* Copy display bitmap to hardware */
183 for (y = 0; y < LCD_FBHEIGHT; y++)
184 {
185 lcd_write_command_ex(LCD_CNTL_PAGE, y, -1);
186 lcd_write_command_ex(LCD_CNTL_COLUMN, 0, -1);
187
188 lcd_write_command(LCD_CNTL_DATA_WRITE);
189 lcd_write_data (lcd_framebuffer[y], LCD_WIDTH);
190 }
191}
192
193/* Update a fraction of the display. */
194void lcd_update_rect(int, int, int, int) ICODE_ATTR;
195void lcd_update_rect(int x, int y, int width, int height)
196{
197 int ymax;
198
199 /* The Y coordinates have to work on even 8 pixel rows */
200 ymax = (y + height-1) >> 2;
201 y >>= 2;
202
203 if(x + width > LCD_WIDTH)
204 width = LCD_WIDTH - x;
205 if (width <= 0)
206 return; /* nothing left to do, 0 is harmful to lcd_write_data() */
207 if(ymax >= LCD_FBHEIGHT)
208 ymax = LCD_FBHEIGHT-1;
209
210 /* Copy specified rectange bitmap to hardware */
211 for (; y <= ymax; y++)
212 {
213 lcd_write_command_ex(LCD_CNTL_PAGE, y, -1);
214 lcd_write_command_ex(LCD_CNTL_COLUMN, x, -1);
215
216 lcd_write_command(LCD_CNTL_DATA_WRITE);
217 lcd_write_data (&lcd_framebuffer[y][x], width);
218 }
219}