BeRTOS
|
00001 00041 /* ---------------------------------------------------------------------------- 00042 * ATMEL Microcontroller Software Support 00043 * ---------------------------------------------------------------------------- 00044 * Copyright (c) 2010, Atmel Corporation 00045 * 00046 * All rights reserved. 00047 * 00048 * Redistribution and use in source and binary forms, with or without 00049 * modification, are permitted provided that the following conditions are met: 00050 * 00051 * - Redistributions of source code must retain the above copyright notice, 00052 * this list of conditions and the disclaimer below. 00053 * 00054 * Atmel's name may not be used to endorse or promote products derived from 00055 * this software without specific prior written permission. 00056 * 00057 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR 00058 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 00059 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE 00060 * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, 00061 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00062 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 00063 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00064 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00065 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 00066 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 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 * Display row buffer. When refreshing display one full row of 00083 * graphics data is transferred with DMA, to speed up transfer and 00084 * reduce CPU usage. 00085 */ 00086 static uint16_t lcd_row[LCD_WIDTH]; 00087 00088 00089 struct lcd_ili9225_reg 00090 { 00091 uint8_t cmd; // Register index, if 0xFF wait for value ms 00092 uint16_t data; // Register value 00093 }; 00094 00095 static const struct lcd_ili9225_reg init_seq[] = 00096 { 00097 {0x01, 0x011c}, // Set SS, SM, GS and NL bits 00098 {0x02, 0x0100}, // Set 1 line inversion 00099 {0x03, 0x1030}, // Entry Mode set GRAM write direction and BGR=1 00100 {0x08, 0x0808}, // Set BP and FP 00101 {0x0C, 0x0001}, // RGB Input Interface Control: 16-bit RGB interface 00102 {0x0F, 0x0A01}, // Set frame rate: 83Hz 00103 {0x20, LCD_WIDTH}, // Set GRAM Address 00104 {0x21, LCD_HEIGHT}, // Set GRAM Address 00105 00106 /* power on sequence */ 00107 {0x10, 0x0A00}, // Set asp DSTB,STB 00108 {0x11, 0x1038}, // SET APON PON AON VCI1EN VC 00109 {0xFF, 50}, // Wait 50 ms 00110 00111 {0x12, 0x1121}, // Internal reference voltage = VCI 00112 {0x13, 0x06CE}, // Set GVDD 00113 {0x14, 0x676F}, // Set VCOMH/VCOML voltage 00114 00115 // Set gram area 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 // Set gamma curve 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 * Refresh a raw image on screen 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 // TODO 00186 } 00187 00188 /* 00189 * Refresh a bitmap on screen 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 * Blit a 24 bit color raw raster directly on screen 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 }