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_ili9225.h"
00071
00072 #include "hw/hw_ili9225.h"
00073
00074 #include <drv/timer.h>
00075 #include <io/kfile.h>
00076 #include <cpu/byteorder.h>
00077
00078
00079 static struct KFile *spi;
00080
00081
00082
00083
00084
00085
00086 static uint16_t lcd_row[LCD_WIDTH];
00087
00088
00089 struct lcd_ili9225_reg
00090 {
00091 uint8_t cmd;
00092 uint16_t data;
00093 };
00094
00095 static const struct lcd_ili9225_reg init_seq[] =
00096 {
00097 {0x01, 0x011c},
00098 {0x02, 0x0100},
00099 {0x03, 0x1030},
00100 {0x08, 0x0808},
00101 {0x0C, 0x0001},
00102 {0x0F, 0x0A01},
00103 {0x20, LCD_WIDTH},
00104 {0x21, LCD_HEIGHT},
00105
00106
00107 {0x10, 0x0A00},
00108 {0x11, 0x1038},
00109 {0xFF, 50},
00110
00111 {0x12, 0x1121},
00112 {0x13, 0x06CE},
00113 {0x14, 0x676F},
00114
00115
00116 {0x30, 0x0000},
00117 {0x31, 0x00DB},
00118 {0x32, 0x0000},
00119 {0x33, 0x0000},
00120 {0x34, 0x00DB},
00121 {0x35, 0x0000},
00122 {0x36, LCD_WIDTH},
00123 {0x37, 0x0000},
00124 {0x38, LCD_HEIGHT},
00125 {0x39, 0x0000},
00126
00127
00128 {0x50, 0x0000},
00129 {0x51, 0x060A},
00130 {0x52, 0x0D0A},
00131 {0x53, 0x0303},
00132 {0x54, 0x0A0D},
00133 {0x55, 0x0A06},
00134 {0x56, 0x0000},
00135 {0x57, 0x0303},
00136 {0x58, 0x0000},
00137 {0x59, 0x0000},
00138 };
00139
00140 static void lcd_cmd(uint8_t cmd)
00141 {
00142 LCD_CS_LOW();
00143 LCD_RS_LOW();
00144 kfile_write(spi, &cmd, sizeof(cmd));
00145 }
00146
00147 static void lcd_data(uint16_t *data, size_t count)
00148 {
00149 kfile_flush(spi);
00150 LCD_RS_HIGH();
00151 kfile_write(spi, data, count*2);
00152 kfile_flush(spi);
00153 LCD_CS_HIGH();
00154 }
00155
00156 static void lcd_regWrite(uint8_t reg, uint16_t data)
00157 {
00158 uint16_t word = cpu_to_be16(data);
00159
00160 lcd_cmd(reg);
00161 lcd_data(&word, 1);
00162 }
00163
00164 static void lcd_startBlit(uint8_t x, uint8_t y, uint8_t width, uint8_t height)
00165 {
00166 ASSERT((x + width) <= LCD_WIDTH);
00167 ASSERT((y + height) <= LCD_HEIGHT);
00168
00169 lcd_regWrite(0x36, x + width);
00170 lcd_regWrite(0x37, x);
00171 lcd_regWrite(0x38, y + height);
00172 lcd_regWrite(0x39, y);
00173
00174 lcd_regWrite(0x20, x);
00175 lcd_regWrite(0x21, y);
00176 }
00177
00178
00179
00180
00181 void lcd_ili9225_blitRaw(UNUSED_ARG(const uint8_t *, data),
00182 uint8_t x, uint8_t y, uint8_t width, uint8_t height)
00183 {
00184 lcd_startBlit(x, y, width, height);
00185
00186 }
00187
00188
00189
00190
00191 void lcd_ili9225_blitBitmap(const Bitmap *bm)
00192 {
00193 uint8_t mask;
00194 int i, l, r;
00195
00196 lcd_startBlit(0, 0, bm->width, bm->height);
00197
00198 for (l = 0; l < bm->height / 8; l++)
00199 {
00200 for (mask = 1; mask; mask <<= 1)
00201 {
00202 for (i = 0; i < bm->width; i++)
00203 {
00204 if (bm->raster[l * bm->width + i] & mask)
00205 lcd_row[i] = 0x0000;
00206 else
00207 lcd_row[i] = 0xFFFF;
00208 }
00209 lcd_cmd(0x22);
00210 lcd_data(lcd_row, bm->width);
00211 }
00212 }
00213
00214 for (r = 0, mask = 1; r < bm->height % 8; r++, mask <<= 1)
00215 {
00216 for (i = 0; i < bm->width; i++)
00217 {
00218 if (bm->raster[l * bm->width + i] & mask)
00219 lcd_row[i] = 0x0000;
00220 else
00221 lcd_row[i] = 0xFFFF;
00222 }
00223 lcd_cmd(0x22);
00224 lcd_data(lcd_row, bm->width);
00225 }
00226 }
00227
00228
00229
00230
00231 void lcd_ili9225_blitBitmap24(int x, int y, int width, int height, const char *bmp)
00232 {
00233 int l, r;
00234
00235 lcd_startBlit(x, y, width, height);
00236
00237 for (l = 0; l < height; l++)
00238 {
00239 for (r = 0; r < width; r++)
00240 {
00241 lcd_row[r] =
00242 (((uint16_t)bmp[1] << 11) & 0xE000) |
00243 (((uint16_t)bmp[2] << 5) & 0x1F00) |
00244 (((uint16_t)bmp[0] << 0) & 0x00F8) |
00245 (((uint16_t)bmp[1] >> 5) & 0x0007);
00246 bmp += 3;
00247 }
00248
00249 lcd_cmd(0x22);
00250 lcd_data(lcd_row, width);
00251 }
00252 }
00253
00257 void lcd_ili9225_off(void)
00258 {
00259 lcd_regWrite(0x07, 0x0000);
00260 }
00261
00265 void lcd_ili9225_on(void)
00266 {
00267 lcd_regWrite(0x07, 0x1017);
00268 }
00269
00273 static void lcd_reset(void)
00274 {
00275 LCD_RESET_LOW();
00276 timer_delay(20);
00277 LCD_RESET_HIGH();
00278 timer_delay(50);
00279 }
00280
00284 void lcd_ili9225_init(struct KFile *_spi)
00285 {
00286 unsigned i;
00287
00288 ASSERT(_spi);
00289 spi = _spi;
00290 lcd_ili9225_hw_bus_init();
00291
00292 lcd_reset();
00293 lcd_ili9225_off();
00294
00295 for (i = 0; i < countof(init_seq); i++)
00296 {
00297 if (init_seq[i].cmd != 0xFF)
00298 lcd_regWrite(init_seq[i].cmd, init_seq[i].data);
00299 else
00300 timer_delay(init_seq[i].data);
00301 }
00302
00303 lcd_ili9225_on();
00304 }