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 }