00001
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 #include "lcd_hx8347.h"
00071
00072 #include "hw/hw_hx8347.h"
00073 #include <cfg/debug.h>
00074 #include <drv/timer.h>
00075
00076
00077 #define HX8347_ID_HIMAX 0x47
00078
00079
00080 static uint16_t lcd_row[LCD_WIDTH];
00081
00082
00083 struct lcd_hx8347_reg
00084 {
00085 uint8_t cmd;
00086 uint8_t data;
00087 };
00088
00089 static const struct lcd_hx8347_reg init_seq[] =
00090 {
00091
00092 { 0x19, 0x49 },
00093 { 0x93, 0x0C },
00094
00095
00096 { 0x44, 0x4D },
00097 { 0x45, 0x11 },
00098 { 0x20, 0x40 },
00099 { 0x1D, 0x07 },
00100 { 0x1E, 0x00 },
00101 { 0x1F, 0x04 },
00102
00103 { 0x1C, 0x04 },
00104 { 0x1B, 0x10 },
00105 { 0xFF, 50 },
00106
00107 { 0x43, 0x80 },
00108 { 0xFF, 50 },
00109
00110 #if 0
00111
00112 { 0x46, 0x95 },
00113 { 0x47, 0x51 },
00114 { 0x48, 0x00 },
00115 { 0x49, 0x36 },
00116 { 0x4A, 0x11 },
00117 { 0x4B, 0x66 },
00118 { 0x4C, 0x14 },
00119 { 0x4D, 0x77 },
00120 { 0x4E, 0x13 },
00121 { 0x4F, 0x4C },
00122 { 0x50, 0x46 },
00123 { 0x51, 0x46 },
00124 #endif
00125
00126
00127 { 0x02, 0x00 },
00128 { 0x03, 0x00 },
00129 { 0x04, 0x00 },
00130 { 0x05, 0xEF },
00131 { 0x06, 0x00 },
00132 { 0x07, 0x00 },
00133 { 0x08, 0x01 },
00134 { 0x09, 0x3F },
00135
00136
00137 { 0x01, 0x06 },
00138
00139 { 0x16, 0x68 },
00140 { 0x23, 0x95 },
00141 { 0x24, 0x95 },
00142 { 0x25, 0xFF },
00143 { 0x27, 0x06 },
00144 { 0x28, 0x06 },
00145 { 0x29, 0x06 },
00146 { 0x2A, 0x06 },
00147 { 0x2C, 0x06 },
00148 { 0x2D, 0x06 },
00149 { 0x3A, 0x01 },
00150 { 0x3B, 0x01 },
00151 { 0x3C, 0xF0 },
00152 { 0x3D, 0x00 },
00153 { 0x3E, 0x38 },
00154 { 0x40, 0x0F },
00155 { 0x41, 0xF0 },
00156 };
00157
00158
00159
00160
00161 static void regWrite(uint8_t reg, uint16_t val)
00162 {
00163 hx8347_cmd(reg);
00164 hx8347_write(val);
00165 }
00166
00167
00168
00169
00170 static uint16_t regRead(uint8_t reg)
00171 {
00172 hx8347_cmd(reg);
00173 return hx8347_read();
00174 }
00175
00176
00177
00178
00179 static void bufferWrite(const uint16_t *buf, uint16_t size)
00180 {
00181 uint16_t i;
00182 for (i = 0 ; i < size; ++i)
00183 hx8347_write(buf[i]);
00184 }
00185
00186 static void lcd_setCursor(uint16_t x, uint16_t y)
00187 {
00188 regWrite(0x02, x >> 8);
00189 regWrite(0x03, x & 0xff);
00190 regWrite(0x06, y >> 8);
00191 regWrite(0x07, y & 0xff);
00192 }
00193
00194 static void lcd_setWindow(uint16_t x, uint16_t y, uint16_t width, uint16_t height)
00195 {
00196 ASSERT(x + width <= LCD_WIDTH);
00197 ASSERT(y + height <= LCD_HEIGHT);
00198 ASSERT(width > 0);
00199 ASSERT(height > 0);
00200
00201
00202 width--;
00203 height--;
00204
00205 lcd_setCursor(x, y);
00206
00207 regWrite(0x04, (x + width) >> 8);
00208 regWrite(0x05, (x + width) & 0xff);
00209 regWrite(0x08, (y + height) >> 8);
00210 regWrite(0x09, (y + height) & 0xff);
00211 }
00212
00213
00214
00215
00216 void lcd_hx8347_blitBitmap(const Bitmap *bm)
00217 {
00218 uint8_t mask;
00219 int i, l, r;
00220
00221 lcd_setWindow(0, 0, bm->width, bm->height);
00222 hx8347_cmd(0x22);
00223
00224 for (l = 0; l < bm->height / 8; l++)
00225 {
00226 for (mask = 1; mask; mask <<= 1)
00227 {
00228 for (i = 0; i < bm->width; i++)
00229 {
00230 if (bm->raster[l * bm->width + i] & mask)
00231 lcd_row[i] = 0x0000;
00232 else
00233 lcd_row[i] = 0xFFFF;
00234 }
00235 bufferWrite(lcd_row, bm->width);
00236 }
00237 }
00238
00239 for (r = 0, mask = 1; r < bm->height % 8; r++, mask <<= 1)
00240 {
00241 for (i = 0; i < bm->width; i++)
00242 {
00243 if (bm->raster[l * bm->width + i] & mask)
00244 lcd_row[i] = 0x0000;
00245 else
00246 lcd_row[i] = 0xFFFF;
00247 }
00248 bufferWrite(lcd_row, bm->width);
00249 }
00250 }
00251
00252
00253
00254
00255 void lcd_hx8347_blitBitmap24(int x, int y, int width, int height, const char *bmp)
00256 {
00257 int l, r;
00258
00259 lcd_setWindow(x, y, width, height);
00260 hx8347_cmd(0x22);
00261
00262 for (l = 0; l < height; l++)
00263 {
00264 for (r = 0; r < width; r++)
00265 {
00266 lcd_row[r] =
00267 (((uint16_t)bmp[0] << 8) & 0xF800) |
00268 (((uint16_t)bmp[1] << 3) & 0x07E0) |
00269 (((uint16_t)bmp[2] >> 3) & 0x001F);
00270 bmp += 3;
00271 }
00272 bufferWrite(lcd_row, width);
00273 }
00274 }
00275
00279 void lcd_hx8347_off(void)
00280 {
00281 regWrite(0x90, 0);
00282 regWrite(0x26, 0);
00283 }
00284
00288 void lcd_hx8347_on(void)
00289 {
00290 regWrite(0x90, 0x7F);
00291 regWrite(0x26, 0x04);
00292 timer_delay(100);
00293 regWrite(0x26, 0x24);
00294 regWrite(0x26, 0x2C);
00295 timer_delay(100);
00296 regWrite(0x26, 0x3C);
00297 }
00298
00302 void lcd_hx8347_init(void)
00303 {
00304 unsigned i;
00305 uint16_t chip_id;
00306
00307 hx8347_busInit();
00308 lcd_hx8347_off();
00309
00310
00311 if ((chip_id = regRead(0x67)) != HX8347_ID_HIMAX)
00312 {
00313 kprintf("HX8347 chip id read error or wrong id (0x%x), skipping initialization.\n", chip_id);
00314 return;
00315 }
00316
00317 for (i = 0; i < countof(init_seq); i++)
00318 {
00319 if (init_seq[i].cmd != 0xFF)
00320 regWrite(init_seq[i].cmd, init_seq[i].data);
00321 else
00322 timer_delay(init_seq[i].data);
00323 }
00324
00325 lcd_hx8347_on();
00326 }