;**************************************************************************** ;* * ;* LCD Controller für Dualscan 640x480 LCD * ;* * ;* für FT245 * ;* * ;* Version 0.21 (mit Scrolling) * ;* * ;**************************************************************************** ;* * ;* Einfacher LCD Controller für ein SW 640x480 LCD, wie es in vielen alten * ;* Notebooks verbaut ist. * ;* Außer einem mega8515, einem 74x02, dem 74x573 Adresslatch im Datenbus, * ;* und einem 64kB SRAM (mit 55ns oder schneller) werden keine weiteren * ;* Bauteile benötig. Neue Daten werden über ein paralleles Interface mit * ;* bis zu 150kByte in den Speicher geladen. * ;* Aufgrund der hohen Datenrate des Parallelports und der LCD Ausgang, * ;* läuft der AVR mit 16,000MHz und steuert das LCD mit rund 60Hz an. * ;* * ;* Fuse Bit High: 11001001 = 0XC9 (CKOPT enabled) * ;* Fuse Bit Low: 00101110 = 0x2E (externer Quarz, BOD enabled) * ;* * ;* * ;* Befehle: * ;* * ;* 001 Set Cursor. Gefolgt von zwei Parametern, nämlich der Zeilen * ;* und Spaltenadresse. Die Zeilenadresse liegt im Bereich 0-239, * ;* und die Spaltenadresse im Bereich 0-79 (plus 128, falls die * ;* Position in der unteren Displayhälfte liegt.) * ;* * ;* 002 Set PWM. Stellt das Tastverhältnis des PWM Ausgangs OC1B ein. * ;* Das Tastverhältnis folgt auf diesen Befehl als Parameter. * ;* * ;* 003 Set X Start. Stellt den Startwert für den Zeilenbeginn ein. * ;* Damit lässt sich ein Ausschnitt aus dem virtuellen 1000x480 * ;* Bild im Speicher auf dem LCD anzeigen. * ;* * ;* 011 Clear LCD. Dieser Befehl löscht das LCD in extrem kurzer Zeit. * ;* Aber wie auch schon beim Clear Line Befehl, benötigt er einiges * ;* an Zeit um den kompletten Speicher zu löschen. Das LCD Timing * ;* wird zwar nicht ganz eingehalten, aber man merkt nichts davon, * ;* da ab und zu dummy Daten ans LCD gesendet werden. * ;* * ;* 192 Display Character. Mit diesem Befehl wird ein ASCII Zeichen * ;* mittels des interenen Character Generator dargestellt. Das * ;* gewünschte Zeichen wird als Parameter übergeben. Die * ;* Darstellung erfolgt als 8x8 Zeichen. Die Schriftart entspricht * ;* der auf einem PC im 640x480 Grafikmodus. * ;* * ;* Daten: Nach dem Senden eines Datenwertes wird dieser in den Speicher * ;* geschrieben, und der Adresszähler anschließend erhöht. * ;* Jedes Byte enthält 8 nebeneinanderliegende Pixel. Im SRAM * ;* werden dagegen 4 nebeneinander liegende Pixel aus der oberen, * ;* und 4 nebeneinander liegende Pixel aus der unteren Hälfte * ;* gespeichert. Das mach das Laden von Daten etwas komplizierter, * ;* vereinfacht und beschleunigt die Ausgabe aber extrem. * ;* * ;* IO Pins: * ;* * ;* PA0-7 Adr/Dat Daten/Low Adresse für den SRAM * ;* PB0-7 Daten 8 Bit Befehle/Daten für den Controller * ;* PC0-7 Adresse High Adresse für den SRAM * ;* PD0 RXF\ RX Full von FT245 * ;* PD1 RD\ Read Impuls an FT245 * ;* PD2 NC * ;* PD3 EXSCL Aktivierung für XSCL. Dieser Pin aktiviert über ein * ;* 74HC02 den Schiebetakt für die Daten * ;* PD4 LP Latchpuls. Der Impuls läd die Daten aus dem Schiebe- * ;* register ins Display. Dient als HSync. * ;* PD5 FLM VSync für das LCD. Das LCD springt in die erste Zeile. * ;* PD6 VWR\ Write Enable für den SRAM. * ;* PD7 VRD\ Output Enable für den SRAM und XSCL über den 74HC32 * ;* für das LCD. Bei jedem Lesevorgang werden die Daten ins * ;* LCD geladen * ;* PE0 EnLCD Schaltet über einen PNP und einen NPN Transistor die * ;* LCD Spannung, damit im Falle eines Fehlers (z.B. Ausfall* ;* der +5V) das LCD nicht zerstört wird. * ;* PE1 ALE Adress Latch für Low Adressen des SRAMs * ;* PE2 PWM PWM Ausgang, z.B. für Displaykontrast (geht noch nicht) * ;* * ;**************************************************************************** .include "m8515def.inc" ;@16,000MHz .def null =r0 .def voll =r1 .def tempm =r2 .def XStart =r5 ;Beginn einer Spalte ab Nibble .def XScan =r6 ;Endadresse bei der Bildausgabe in X Richtung .def temp =r16 .def temp2 =r17 .def temp3 =r18 .def NextOp =r19 ;Zähler für Parameter eines Befehls .def Flags =r20 ;Allgemeine Bits .def XAdresseLow=r26 ;Writepointer Spalte .def ZeileL =r27 ;Writepointer Zeile LSB .def AdresseLow =r28 ;Readpointer Spalte .def AdresseHigh=r29 ;Readpointer Zeile ;PortD .equ RXF =0 ;RXF\ .equ RD =1 ;RD\ .equ XSCL =3 ;Enable XSCL .equ LP =4 ;HSync .equ FLM =5 ;VSync ;PortE .equ EnLCD =0 ;LCD Spannung ein/ausschalten ;Flags .equ ZeileH =7 ;Writepointer Zeile MSB, entscheidet zwischen obere und untere Displayhälte, also zwischen High und Low Nibble eines RAM Bytes ;NextOPs ;Werte um die nächste Operation nach einem Befehl festzulegen .equ SetCurL =1 .equ SetCurH =2 .equ SetPWMV =3 .equ CGChar =4 .equ SetScroll =5 .equ Escape =14 ;Wert des Escape Zeichens (=Beginn eines Befehls) .equ CD =7 ;Bit um zwischen Befehl/Daten zu unterscheiden .equ XSize =160 ;Bildgröße in X Richtung in Nibbles .equ YSize =240 ;Bildgröße in Y Richtung pro Halbbild .equ XOScan =0 ;Anzahl der zusätzlich auszugebenden Nibbles in X Richtung .equ YOScan =2 ;Anzahl der zusätzlich auszugebenden Zielen in Y Richtung (muss >=2 sein, sonst geht z.B. das Pollin LCD kaputt !) .equ YScan =YMin+YSize+YOScan ;Endadresse bei der Bildausgabe in Y Richtung .equ XMax =250 ;Maximale Speicheradresse in XRichtung .equ YMin =4 ;Minimale Speicheradresse in Y Richtung .equ YMax =YMin+YSize ;Maximale Speicheradresse in Y Richtung .equ XPos =200 ;Position des Logos in X Richtung .equ YPos =190 ;Position des Logos in Y Richtung .equ LXSize =30 ;Größe des Logos in X Richtung durch 8 .equ LYSize =48 ;Größe des Logos in Y Richtung ;Maximale Größe des Logos: 43008 Pixel .equ FrameFreq =60 ;Bildwiederholfrequenz in Hz ;60Hz verursachen 55% CPU Auslastung bei 16MHz .equ TReload = (2000000/(FrameFreq*(YSize+YOScan)))-1 ;Wert für Timer: Timertakt/Zeilenfrequenz-1 ;**************************************************************************** ; Interrupt Vektoren ;**************************************************************************** .org 0 rjmp Reset ;**************************************************************************** ; CPU Register Initialisierung ;**************************************************************************** Reset: ldi temp, low(RAMEND) out SPL, temp ;setup stack pointer ldi temp, high(RAMEND) out SPH, temp ;setup stack pointer clr null ser temp, mov voll, temp ldi temp, (1< NextOp.Escape setzen. ret ;*** Bearbeitung der Daten *** Daten: cpi NextOp, 0 ;Paramter oder Daten ? brne Next sbi portd, XSCL ;Datenverbindung zum LCD unterbrechen sbrc Flags, ZeileH ;Pixel in der oberen oder unteren Displayhälfte ? rjmp untereHalfte obereHalfte: ld temp2, X ;Lader Wert aus SRAM andi temp2, 15 ;obere Datenhälfte der SRAM Daten behalten mov temp3, temp andi temp3, 240 ;erste Hälfte der Daten behalten or temp2, temp3 ;Beide Hälften zusammenfügen st X+,temp2 ld temp2, X andi temp2, 15 ;obere Datenhälfte der SRAM Daten behalten swap temp andi temp, 240 ;zweite Hälfte der Daten behalten or temp2, temp st X+,temp2 cpi XAdresseLow, XMax ;Spalten Adresse > Max ? brlo normal clr XAdresseLow ;Spalten Adresse = 0 inc ZeileL ;Zeilen Adresse ++ cpi ZeileL, YMax ;Zeilen Adresse > Max ? brlo normal ldi ZeileL, YMin ;Zeile = Beginn XRAM sbr Flags, (1< Max ? brlo normal clr XAdresseLow ;Spalten Adresse = 0 inc ZeileL cpi ZeileL, YMax ;Zeilen Adresse > Max ? brlo normal ldi ZeileL, YMin ;Zeile = Beginn XRAM cbr Flags, (1< Max ? brne normal2 clr XAdresseLow ;Spalten Adresse = 0 subi ZeileL, -8 ;Zeilen Adresse ++ cpi ZeileL, YMax ;Zeilen Adresse > Max ? brlo normal2 ldi ZeileL, YMin ;Zeile = Beginn XRAM ldi temp, (1<