1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2010 Marcin Bukat
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
29 /* TOMATO LSI 0350 - definitions and slightly tweaked functions
30 * taken from lcd-remote-iaudio.c
33 #define LCD_SET_DUTY_RATIO 0x48
34 #define LCD_SELECT_ADC 0xa0
35 #define LCD_SELECT_SHL 0xc0
36 #define LCD_SET_COM0 0x44
37 #define LCD_OSC_ON 0xab
38 #define LCD_SELECT_DCDC 0x64
39 #define LCD_SELECT_RES 0x20
40 #define LCD_SET_VOLUME 0x81
41 #define LCD_SET_BIAS 0x50
42 #define LCD_CONTROL_POWER 0x28
43 #define LCD_DISPLAY_ON 0xae
44 #define LCD_SET_INITLINE 0x40
45 #define LCD_SET_COLUMN 0x10
46 #define LCD_SET_PAGE 0xb0
47 #define LCD_SET_GRAY 0x88
48 #define LCD_SET_PWM_FRC 0x90
49 #define LCD_SET_POWER_SAVE 0xa8
50 #define LCD_REVERSE 0xa6
51 #define LCD_RESET 0xe2
54 static bool cached_invert
= false;
55 static bool cached_flip
= false;
56 static int cached_contrast
= DEFAULT_CONTRAST_SETTING
;
57 bool lcd_initialized
= false;
59 /*** hardware configuration ***/
60 int lcd_default_contrast(void)
62 return DEFAULT_CONTRAST_SETTING
;
65 void lcd_powersave(bool on
)
67 /* What is the point of having else construct here? */
70 lcd_write_command(LCD_SET_POWER_SAVE
| 1);
72 lcd_write_command(LCD_SET_POWER_SAVE
| 1);
76 void lcd_set_contrast(int val
)
78 if (val
< MIN_CONTRAST_SETTING
)
79 val
= MIN_CONTRAST_SETTING
;
80 else if (val
> MAX_CONTRAST_SETTING
)
81 val
= MAX_CONTRAST_SETTING
;
83 cached_contrast
= val
;
85 lcd_write_command_e(LCD_SET_VOLUME
, val
);
88 void lcd_set_invert_display(bool yesno
)
90 cached_invert
= yesno
;
92 lcd_write_command(LCD_REVERSE
| yesno
);
96 /* turn the display upside down (call lcd_update() afterwards) */
97 void lcd_set_flip(bool yesno
)
104 lcd_write_command(LCD_SELECT_ADC
| 1);
105 lcd_write_command(LCD_SELECT_SHL
| 0);
106 lcd_write_command_e(LCD_SET_COM0
, 0);
110 lcd_write_command(LCD_SELECT_ADC
| 0);
111 lcd_write_command(LCD_SELECT_SHL
| 8);
112 lcd_write_command_e(LCD_SET_COM0
, 0);
118 void lcd_shutdown(void)
120 /* Set power save -> Power OFF (VDD - VSS) .. that's it */
122 lcd_write_command(LCD_SET_POWER_SAVE
| 1);
125 void lcd_init_device(void)
127 and_l(~0x00000800, &GPIO_FUNCTION
); /* CS3 line */
129 /* LCD Reset GPO34 */
130 or_l(0x00000004, &GPIO1_ENABLE
); /* set as output */
131 or_l(0x00000004, &GPIO1_FUNCTION
); /* switch to secondary function - GPIO */
133 and_l(~0x00000004, &GPIO1_OUT
); /* RESET low */
134 sleep(1); /* delay at least 1000 ns */
135 or_l(0x00000004, &GPIO1_OUT
); /* RESET high */
138 /* parameters setup taken from original firmware */
139 lcd_write_command(LCD_RESET
);
140 lcd_write_command_e(LCD_SET_DUTY_RATIO
,0x80); /* 1/128 */
141 lcd_write_command(LCD_OSC_ON
);
142 lcd_write_command(LCD_SELECT_DCDC
| 3); /* DC/DC 6xboost */
143 lcd_write_command(LCD_SELECT_RES
| 7); /* Regulator resistor: 7.2 */
144 lcd_write_command(LCD_SET_BIAS
| 6); /* 1/11 */
145 lcd_write_command(LCD_SET_PWM_FRC
| 6); /* 3FRC + 12PWM */
146 lcd_write_command_e(LCD_SET_GRAY
| 0, 0x00);
147 lcd_write_command_e(LCD_SET_GRAY
| 1, 0x00);
148 lcd_write_command_e(LCD_SET_GRAY
| 2, 0x0c);
149 lcd_write_command_e(LCD_SET_GRAY
| 3, 0x00);
150 lcd_write_command_e(LCD_SET_GRAY
| 4, 0xc4);
151 lcd_write_command_e(LCD_SET_GRAY
| 5, 0x00);
152 lcd_write_command_e(LCD_SET_GRAY
| 6, 0xcc);
153 lcd_write_command_e(LCD_SET_GRAY
| 7, 0x00);
155 lcd_write_command(LCD_CONTROL_POWER
| 7); /* All circuits ON */
156 lcd_write_command(LCD_DISPLAY_ON
| 1); /* display on */
158 /* Ok we are ready */
159 lcd_initialized
= true;
161 lcd_set_flip(cached_flip
);
162 lcd_set_contrast(cached_contrast
);
163 lcd_set_invert_display(cached_invert
);
168 /* Update the display.
169 This must be called after all other LCD functions that change the display. */
170 void lcd_update(void) ICODE_ATTR
;
171 void lcd_update(void)
177 for(y
= 0;y
< LCD_FBHEIGHT
;y
++)
179 lcd_write_command(LCD_SET_PAGE
| y
);
180 lcd_write_command_e(LCD_SET_COLUMN
, 0);
181 lcd_write_data(lcd_framebuffer
[y
], LCD_WIDTH
);
187 /* Update a fraction of the display. */
188 void lcd_update_rect(int, int, int, int) ICODE_ATTR
;
189 void lcd_update_rect(int x
, int y
, int width
, int height
)
193 if (!lcd_initialized
)
197 /* The Y coordinates have to work on even 8 pixel rows */
198 ymax
= (y
+ height
-1) >> 3;
201 if(x
+ width
> LCD_WIDTH
)
202 width
= LCD_WIDTH
- x
;
204 return; /* nothing left to do, 0 is harmful to lcd_write_data() */
205 if(ymax
>= LCD_FBHEIGHT
)
206 ymax
= LCD_FBHEIGHT
-1;
208 /* Copy specified rectange bitmap to hardware */
209 for (; y
<= ymax
; y
++)
211 lcd_write_command(LCD_SET_PAGE
| y
);
212 lcd_write_command_e(LCD_SET_COLUMN
| ((x
>> 4) & 0xf), x
& 0x0f);
213 lcd_write_data (&lcd_framebuffer
[y
][x
], width
);
218 void lcd_blit_grey_phase(unsigned char *values
, unsigned char *phases
,
219 int x
, int by
, int width
, int bheight
, int stride
)
231 void lcd_blit_mono(const unsigned char *data
, int x
, int by
, int width
,
232 int bheight
, int stride
)