; ********************************************************************************************
; ********************************************************************************************
; Datei: lcd-routines-bib_header.asm
; enthält die Definitionen zu Routinen zum Steuern einer LCD-Einheit 
; an den unteren (LCD_data = lower_port)  oder oberen Porthälfte (LCD_data = upper_port)
; Die Steuerleitungen sind frei wählbar und werden auch über die Headerdatei 
; lcd-routines-bib_header.asm eingestellt
 ; ============================================================================
 ; =============================================================================
; ********************************************************************************************
; ********************************************************************************************
;
; Bibliotheksroutinen zur Ausgabe von Daten auf ein LCD
;
; ********************************************************************************************
; ********************************************************************************************
; ********************************************************************************************
; Benutzung des Moduls bekannt machen
	.equ lcd_asm = 1
	
; Portbereich für LCD-Daten festlegen
	.equ lower_port = 0		; 
	.equ upper_port = 1
	.equ LC_data = upper_port

; Die Variable XTAL muss die Taktfrequenz haben
.ifndef xtal
	.equ xtal = takt				; 16 MHz
.endif

; Wir legen die Portleitungen fest
.if lcd_asm == 1						; Wenn ein LCD angeschlossen ist, brauchen wir das
	.equ LCD_PORT = PORTB
	.equ LCD_DDR  = DDRB
	.equ rs_port = portb
	.equ rs_ddr = ddrb
	.equ e_port = portb
	.equ e_ddr = ddrb				;
.if lc_data == upper_port
	; Datenbits: LCD_PORT.4 .. 7	; just for info
	.equ maskdata = 0b11110000		; Maske für Datenleitungen
.endif

.if lc_data == lower_port
	; Datenbits: LCD_PORT.0 .. 3	; just for info
	.equ maskdata = 0b00001111		; Maske für Datenleitungen
.endif

	.equ maskport = ~maskdata		; Invertieren für Portmaske
	.equ PIN_RS   = 0
;	.equ PIN_E2   = 5				; not used
	.equ PIN_E    = 1
	; LCD-Pin -RW liegt auf Masse	
.endif
; **********************************************************************************************
;
;
; ********************************************************************************************
; Das kommt in den Programmtext oder in eine Include-Datei
; **********************************************************************************************
;
; Das Definitionsfile für den Prozessortyp wird im Hauptprogramm eingebunden
; ==============================================================================
; interface
; ==============================================================================
;
; Falls die Variable duodisplay im Hauptprogramm definiert ist,
; werden die Routinen dafür eingebunden
;
; mit gesetztem T-Flag wird die untere Hälfte von Displays mit 
;		zwei Controllern angesteuert
;
; lcd_data (temp1) - ein Zeichen in Temp1 übergeben zur Ausgabe
; lcd_command (temp1) - einen Befehlscode in temp1 übergeben
; lcd_enable - Übernahmebefehl (strobe)
; lcd_enable2 - bei 4-zeiligem Display die unteren 2 Zeilen
; delay50us - 50 us Sekunden Pause machen
; delay5ms - 5 ms warten
; lcd_init - Display initialisieren (4Bit Betrieb)
; Powerupwait - Warten zum Betriebsstart, bis Spannung steht
; lcd_clear - Display löschen, Cursor home
; lcd_home - Cursor in Homeposition
; lcd_position - Cursor an Position Spalte (temp1) Zeile (temp2), 
; lcd_cursor - Display-Cursor-Blinken an/aus
;		Bit2 -> Display; Bit1 -> cursor; Bit0 -> Blinken
; lcd_flash_string - einen String aus dem Programmspeicher (Flash) ausgeben
;       der String ist 0-terminiert, das z-Register enthält die Textadresse (mal 2!)
;       ldi zl, low(textadresse*2)
;       ldi zh, high(textadresse*2)
; lcd_number (temp1) - Zahl in Register temp1 dezimal ausgeben
; lcd_number_hex (temp1) - Zahl in Register temp1 als Hexadezimalzahl ausgeben.
; lcd_binout - Binärzahl in akku b ausgeben, Binär-Stellenzahl in temp2
;		mit bin2asc nach buffer wandeln, Ziffern-Stellenzahl + 1 in temp2
; 		der bufferzeiger z steht auf der Null des String-Endes
; ==============================================================================
; interface ende
; ==============================================================================


.equ entry_mode    = 0b00000100	; Cursorbewegung und Displayverschiebung 
.equ inccp = 1 		; increase Cursor Position  bei Ausgabe eines Zeichens
.equ sdisp = 0		; scroll Display, wenn Cursor Randposition erreicht hat

.equ onoff_control = 0b00001000	; Display, Cursor, Cursor Blinken - an / aus
.equ dispon = 2 	; Display off
.equ curson = 1		; cursor ein
.equ cursbl = 0		; cursor blinken lassen

.equ cursor_scroll = 0b00010000	; Cursor move, Display scroll, links/rechts
.equ dispscr = 3	; setzen = display scrollen / clear = cursor bewegen
.equ movright = 2	; setzen = rechts / clear = links

.equ config =        0b00100000	; Interface Configuration, zeilenmodus, font
.equ achtbit = 4	; Datenbreite 1 = 8 Bit/ 0 = 4 bit an B4..B7
.equ twoline = 3	; 1 = zweizeilig / 0 = einzeilig
.equ bigfont = 2	; 1 = 5x11 Pixel / 0 = 5x7 Pixel

.equ cram_addr = 0b01000000	; Character RAM Adresse setzen
							; 0b01aaaaaa enthält die Zeichenram-Adresse, ab der 
							; geschrieben werden soll. Es folgen 8 Byte, welche 
							; die Pixeldaten des zu definierenden Zeichens enthalten
							; !!! Befehl mit "Display RAM Address Set" abschließen!!!
							; Ausführungszeit 40 µs

.equ dram_addr = 0b10000000	; Positioniert den Cursor neu an die übergebene Adresse
							; 0b1zaaaaaa 
.equ zeile = 6				; Zeilennummer Bit
							; z = Zeilennummer 0 oder 1
							; aaaaaa = 6-Bit Spaltennummer (0..63)
							; Ausführungszeit 40 µs
;
.equ t50us = ( XTAL * 50 / 5 ) / 1000000
.equ t5ms = ( XTAL * 5 / 606 ) / 1000

