BeRTOS
lcd_ili9225.c
Go to the documentation of this file.
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 }