Main Page   Data Structures   File List   Data Fields   Globals   Related Pages  

gfxdriver.cpp

Go to the documentation of this file.
00001 /*  gfxdriver.cpp
00002     Graphics driver for SED1520 (or comaptible) LCDs
00003 
00004     30.06.2001: tk, after some tests and many different blit functions,
00005                 i finally changed back to the old memory layout. There's
00006                 no big performance difference, and it doesn't even make
00007                 the blit functions easier (on the contrary!!)
00008     26.12.2001: tk, changed the internal screen array: Before
00009                 the change, the array represented 4 lines that
00010                 spanned 122x8 pixel each, and made an efficient
00011                 get/putimage quite challenging to implement.
00012                 In the new layout, all bytes belonging to the a
00013                 single column (or x-coordinate) are now directly
00014                 adjacent to each other.
00015     22.12.2001: tk, implemented display mirror code, as suggested
00016                 by robert dubber, r.dubber@chello.nl (thanks!)
00017     09.06.2001: tk, initial implementation.
00018 
00019     Copyright (c)2001 by Thomas Kindler, thomas.kindler@gmx.de
00020 
00021     This program is free software; you can redistribute it and/or
00022     modify it under the terms of the GNU General Public License as
00023     published by the Free Software Foundation; either version 2 of
00024     the License, or (at your option) any later version. Read the
00025     full License at http://www.gnu.org/copyleft for more details.
00026 */
00027 
00028 #include "clib/hwapi.h"
00029 #include "clib/rtos.h"
00030 #include "bitmap.h"
00031 #include "gfxdriver.h"
00032 #include "misc.h"
00033 #include <stdio.h>
00034 #include <conio.h>
00035 #include <string.h>
00036 
00037 #ifdef  LCD_UPSIDEDOWN
00038 
00041 static near const char mirror[256] = {
00042   0x00,0x80,0x40,0xC0,0x20,0xA0,0x60,0xE0,0x10,0x90,0x50,0xD0,0x30,0xB0,0x70,0xF0,
00043   0x08,0x88,0x48,0xC8,0x28,0xA8,0x68,0xE8,0x18,0x98,0x58,0xD8,0x38,0xB8,0x78,0xF8,
00044   0x04,0x84,0x44,0xC4,0x24,0xA4,0x64,0xE4,0x14,0x94,0x54,0xD4,0x34,0xB4,0x74,0xF4,
00045   0x0C,0x8C,0x4C,0xCC,0x2C,0xAC,0x6C,0xEC,0x1C,0x9C,0x5C,0xDC,0x3C,0xBC,0x7C,0xFC,
00046   0x02,0x82,0x42,0xC2,0x22,0xA2,0x62,0xE2,0x12,0x92,0x52,0xD2,0x32,0xB2,0x72,0xF2,
00047   0x0A,0x8A,0x4A,0xCA,0x2A,0xAA,0x6A,0xEA,0x1A,0x9A,0x5A,0xDA,0x3A,0xBA,0x7A,0xFA,
00048   0x06,0x86,0x46,0xC6,0x26,0xA6,0x66,0xE6,0x16,0x96,0x56,0xD6,0x36,0xB6,0x76,0xF6,
00049   0x0E,0x8E,0x4E,0xCE,0x2E,0xAE,0x6E,0xEE,0x1E,0x9E,0x5E,0xDE,0x3E,0xBE,0x7E,0xFE,
00050   0x01,0x81,0x41,0xC1,0x21,0xA1,0x61,0xE1,0x11,0x91,0x51,0xD1,0x31,0xB1,0x71,0xF1,
00051   0x09,0x89,0x49,0xC9,0x29,0xA9,0x69,0xE9,0x19,0x99,0x59,0xD9,0x39,0xB9,0x79,0xF9,
00052   0x05,0x85,0x45,0xC5,0x25,0xA5,0x65,0xE5,0x15,0x95,0x55,0xD5,0x35,0xB5,0x75,0xF5,
00053   0x0D,0x8D,0x4D,0xCD,0x2D,0xAD,0x6D,0xED,0x1D,0x9D,0x5D,0xDD,0x3D,0xBD,0x7D,0xFD,
00054   0x03,0x83,0x43,0xC3,0x23,0xA3,0x63,0xE3,0x13,0x93,0x53,0xD3,0x33,0xB3,0x73,0xF3,
00055   0x0B,0x8B,0x4B,0xCB,0x2B,0xAB,0x6B,0xEB,0x1B,0x9B,0x5B,0xDB,0x3B,0xBB,0x7B,0xFB,
00056   0x07,0x87,0x47,0xC7,0x27,0xA7,0x67,0xE7,0x17,0x97,0x57,0xD7,0x37,0xB7,0x77,0xF7,
00057   0x0F,0x8F,0x4F,0xCF,0x2F,0xAF,0x6F,0xEF,0x1F,0x9F,0x5F,0xDF,0x3F,0xBF,0x7F,0xFF
00058 };
00059 #endif
00060 
00061 
00069 void LCD_Update(Bitmap *bm) {
00070   for (int p=0; p<LCD_PAGES; p++) {
00071     outp(LCD_IOBASE0, 0x00);
00072     outp(LCD_IOBASE0, 0xB8 + p);
00073     outp(LCD_IOBASE1, 0x00);
00074     outp(LCD_IOBASE1, 0xB8 + p);
00075 
00076 #ifndef LCD_UPSIDEDOWN
00077     char *src = &bm->bmBits[p*bm->width];
00078     asm {
00079       pushf
00080       push  cx
00081       push  dx
00082       push  si
00083       push  ds
00084       cld
00085 
00086       lds   si, src
00087       mov   cx, LCD_WIDTH/2
00088       mov   dx, LCD_IOBASE0+2
00089       rep   outsb
00090 
00091       mov   cx, LCD_WIDTH/2
00092       mov   dx, LCD_IOBASE1+2
00093       rep   outsb
00094 
00095 
00096       pop   ds
00097       pop   si
00098       pop   dx
00099       pop   cx
00100       popf
00101     }
00102 #else
00103     char *src = &bm->bmBits[(LCD_WIDTH*LCD_PAGES-1) - p*bm->width];
00104     asm {
00105       pushf
00106       push  bx
00107       push  cx
00108       push  dx
00109       push  ds
00110       push  si
00111       push  es
00112       std
00113 
00114       mov   bx, offset mirror
00115       les   si, src
00116       mov   cx, LCD_WIDTH/2
00117       mov   dx, LCD_IOBASE0+2
00118 l1:   db    0x26        // ES prefix
00119       lodsb
00120       xlat
00121       out   dx, al
00122       loop  l1
00123 
00124       mov   cx, LCD_WIDTH/2
00125       mov   dx, LCD_IOBASE1+2
00126 l2:   db    0x26        // ES prefix
00127       lodsb
00128       xlat
00129       out   dx, al
00130       loop  l2
00131 
00132       pop   es
00133       pop   si
00134       pop   ds
00135       pop   dx
00136       pop   cx
00137       pop   bx
00138       popf
00139     }
00140 #endif
00141   }
00142 }
00143 
00144 
00152 void LCD_Clear(unsigned char pattern)
00153 {
00154   for (int p=0; p<LCD_PAGES; p++) {
00155     outp(LCD_IOBASE0, 0x00);
00156     outp(LCD_IOBASE0, 0xB8 + p);
00157     outp(LCD_IOBASE1, 0x00);
00158     outp(LCD_IOBASE1, 0xB8 + p);
00159     asm {
00160       push  cx
00161       push  dx
00162       mov   al, pattern
00163 
00164       mov   dx, LCD_IOBASE0+2
00165       mov   cx, LCD_WIDTH/2
00166 l1:   out   dx, al
00167       loop  l1
00168 
00169       mov   dx, LCD_IOBASE1+2
00170       mov   cx, LCD_WIDTH/2
00171 l2:   out   dx, al
00172       loop  l2
00173       
00174       pop   dx
00175       pop   cx
00176     }
00177   }
00178 }
00179 
00180 
00190 void LCD_SetBrightness(int level)
00191 {
00192   long     period;
00193   unsigned pwmOn, pwmOff;
00194 
00195   if (level <   0) level =   0;
00196   if (level > 255) level = 255;
00197   period = hal_get_frequencies(GET_FRQ_TIMER)/LCD_CLOCK;
00198   pwmOn  = (unsigned)(period*level/255);
00199   pwmOff = (unsigned)period - pwmOn;
00200   if (pwmOn  < LCD_MINPWMON )  pwmOn  = LCD_MINPWMON;
00201   if (pwmOff < LCD_MINPWMOFF)  pwmOff = LCD_MINPWMOFF;
00202 
00203   // start timer in continuos mode
00204   //
00205   hal_init_timer(0, 1, pwmOn);
00206   hal_set_duty_cycle_waveform(0, true, pwmOff);
00207   hal_start_timer(0);
00208 }
00209 
00210 
00215 void LCD_Init()
00216 {
00217   printf("LCD_Init(): initializing SED1520..\n");
00218   pfe_enable_bus(0xff, true);
00219   pfe_enable_pcs(LCD_IOBASE0 >> 8);
00220   pfe_enable_pcs(LCD_IOBASE1 >> 8);
00221 
00222   // enable refresh timer
00223   //
00224   pfe_enable_timer(3);      // timer out 0
00225   LCD_SetBrightness(255);
00226 
00227   outp(LCD_IOBASE0, 0xe2);  // reset
00228   outp(LCD_IOBASE0, 0xa0);  // select forward adc
00229   outp(LCD_IOBASE0, 0xa4);  // static drive off
00230   outp(LCD_IOBASE0, 0xaf);  // display on
00231   outp(LCD_IOBASE1, 0xe2);
00232   outp(LCD_IOBASE1, 0xa0);
00233   outp(LCD_IOBASE1, 0xa4);
00234   outp(LCD_IOBASE1, 0xaf);
00235   LCD_Clear();
00236 }
00237 
00238 
00242 void LCD_Done()
00243 {
00244   // enter power-save mode
00245   //
00246   outp(LCD_IOBASE0, 0xa5);  // static drive on
00247   outp(LCD_IOBASE0, 0xae);  // display off
00248   outp(LCD_IOBASE1, 0xa5);
00249   outp(LCD_IOBASE1, 0xae);
00250 
00251   // disable refresh timer
00252   //
00253   hal_stop_timer(0);
00254 
00255   // switch off backlight
00256   //
00257   pfe_enable_pio(13, PIO_IPD);
00258 }

Generated on Sun Aug 4 21:47:28 2002 for k/os mp3v2 by doxygen1.2.16