#pragma once
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <string.h> // memcpy
// Im Gegensatz zu früheren Implementierungen
// werden Flash-String-Zeiger durch gesetztes Bit 15 markiert.
// Im Endeffekt wird der Speicher von-neumannisiert wie bei PIC16F1454.
// Das klappt nur bei ≤ 32 KByte Flash — oder bei ≤ 32 KByte Flash-Strings.
// Schade, dass die gcc-Standardbibliothek nicht genauso verfährt.
// (Genauso könnte der EEROM ab 0x4000 von-neumannisiert sein.)
#define F(s) (PSTR(s)+0x8000) // Flash-String, bspw. F("Hallo")
#define FP(s) ((s)+0x8000) // Flash-Pointer, bspw. const PROGMEM char k[]="Welt"; const char*p=FP(k);
typedef uint8_t byte;
typedef uint16_t word;
#if __GNUC__ == 4 && __GNUC_MINOR__ == 3 // WinAVR 2010
# define _packed __attribute__((packed))
#else
# define _packed
#endif
// Die Vorlage für diese Klasse war
// http://www.tu-chemnitz.de/~heha/Mikrocontroller/Displays/utft/Kalender.zip/ILI9341/UTFT.h?auto=CPP
// Die Routinen wurden auf BYTE-Parameter gekürzt,
// für eine maximale Displaygröße von 256×256 Pixel.
// Als Folge gibt es keine Nullbreite oder Nullhöhe,
// und Endwerte gelten stets inklusive (also nicht right=letztes Pixel+1 wie unter Windows)
// Erkenntnis: Keiner der beiden Ansätze hat sonderliche Vor- oder Nachteile.
// Allerdings kann ein Buchstabe bei 256 Pixel Display-Breite nicht am rechten Rand überhängend
// abgeschnitten werden, weil nicht klar ist, ob dieser rechts oder links überhängt!
// Clipping erfordert mit diesem n-1-System mehr Grübelei.
// Die Bits sind bei diesem Display nach rechts aufsteigend, also LSBfirst.
// Nicht wie bei alten VGA-Karten.
struct _current_font{
char cx; // Zeichenbreite, negativ für Proportionalfonts (Mindestbreite)
byte cy; // Zeichenhöhe
byte first; // Kode erstes Zeichen
byte count; // Anzahl Kodes
const byte*bits; // Bitmap im RAM oder Flash
};
struct POINT {byte x,y;};
// Vollgrafisches Display mit Proportionalschrift
// Der Textmodus wird nicht benutzt, ging mit dem vorliegenden LCD nicht richtig
struct DISP {
void init();
_packed enum{
PIXEL_X =240,
PIXEL_Y =64,
BYTES_X =PIXEL_X>>3,
CHAR_X =40,
CHAR_Y =6,
R2_ZERO =0b00000000,
R2_NOTCOPYPEN =0b00000011,
R2_XORPEN =0b00000110,
R2_COPYPEN =0b00001100, // unteres Nibble von flags = binärer Rasteroperationskode (ROP2)
R2_ONES =0x00001111,
COLOR =0b00010000, // 1 = schwarz, 0 = Weiß
TRANS =0b00100000, // 0-Bits der Quelle belassen Hintergrund unverändert (bitblt)
COOKED =0b01000000, // Zeichenausgabe verarbeitet L'\n' gesondert
MOVE =0b10000000, // Koordinaten verschieben aktuelle Position (einmalig)
};
void clear();
void setClip(byte l, byte t, byte r, byte b) {clip.L=l; clip.T=t; clip.R=r; clip.B=b;}
void andClipX(byte l, byte r); // Clipping-Bereich verkleinern
void andClipY(byte t, byte b) {((DISP*)((byte*)this+1))->andClipX(t,b);}
void andClip(byte l, byte t, byte r, byte b) {andClipX(l,r);andClipY(t,b);}
void clrClip() {setClip(0,0,getXMax(),getYMax());}
void saveClrClip();
void restoreClip();
void gotoXY(byte x, byte y) {X=x; Y=y;}
void targetXY(byte x, byte y) {L=X; T=Y; R=x; B=y; J=K=0;} // Rechteck bauen (Align stets left+top)
void unsetWindow();
bool gotoLTRB(byte l, byte t, byte r, byte b) {gotoXY(l,t);targetXY(r,b);return clipRect();}
void drawPixel() {setPixel();}
void drawPixel(byte x, byte y) {gotoXY(x,y);drawPixel();}
void lineTo(byte x, byte y);
void drawLine(byte x, byte y, byte xe, byte ye) {gotoXY(x,y);lineTo(xe,ye);}
void drawRect(byte l, byte t, byte r, byte b);
void fillRect(byte l, byte t, byte r, byte b) {if (gotoLTRB(l,t,r,b)) fillRect();}
void patRect(byte l, byte t, byte r, byte b) {if (gotoLTRB(l,t,r,b)) patRect();}
void fillRect(); // füllt Rechteck mit flags.COLOR
void fillClip() {memcpy(&L,&clip.L,4);fillRect();}
void patRect(); // füllt Rechteck mit brush[]
byte getXMax() const {return PIXEL_X-1;}
byte getYMax() const {return PIXEL_Y-1;}
byte whereX() const {return X;}
byte whereY() const {return Y;}
void print(wchar_t c); // rückt X vor
void print(const char*s);
void print(const char*s,int x,int y) {gotoXY(x,y); print(s);}
void newline();
void beep() {::beep(44,100);}
void setFont(const byte*font);
int getFontHeight() const {return cfont.cy;}
int getTextExtent(wchar_t c);
int getTextExtent(const char*s);
void drawBitmap(byte l, byte t, byte r, byte b,
const byte*data, int bitsperline, int startbit=0)
{if (gotoLTRB(l,t,r,b)) bitblt(data,bitsperline,startbit);}
void bitblt(const byte*data,int bitsperline,int startbit=0);
void readLine(word yy, byte*data); // Zeile von L bis R rücklesen (byte-ausgerichtet)
void scroll(int dx, int dy); // Display muss rücklesbar sein, das Rechteck L,T,R,B
// Die Scrollrichtung ist positiv nach oben oder links!
// Benötigt und beschreibt globales „byte sbuf[30]“
void bltPixel(bool p);
static void bltByte(word xy, byte rop, byte p, byte m);
// Großbuchstaben = Display-Koordinaten
byte X,Y; // Startpunkt, Cursor
byte L,T,R,B; // Zielkoordinaten einer bitblt-Operation
byte J,K; // Startoffset durch Clipping (zur Korrektur der Quellbitmap-Startadresse)
struct{
byte L,T,R,B; // Clipping-Bereich in Display-Koordinaten
}clip;
byte brush[8]; // Füllmuster 8×8 Pixel
// Farben (wenig gehaltvoll bei SW-Display)
// byte fc,bc; // 1 = schwarz, 0 = grün; nur Bit 0
_current_font cfont;
// Sonstige Variablen
// byte orient; // ungenutzt
byte flags;
// byte align; // Textausrichtung (ungenutzt)
byte width; // Linienbreite
byte clipbuf[4];
protected:
static void addrXY(word xy); // setzt lineare Byte-Adresse (HD61830-spezifisch)
void patLine(word yy, byte p); // Linie ab Zeilenstartadresse yy von L nach R
void bltLine(word yy, const byte*data, int startbit);
// bitblt einer Zeile, aus RAM oder Flash
void copyLine(byte,byte,int); // Zeile von Quelle nach Ziel bewegen und dabei ggf. horizontal verschieben
void setPixel();
bool clipX();
bool clipY() {return ((DISP*)((byte*)this+1))->clipX();}
bool clipOk() const; // prüft X und Y auf Clipping-Bereich
bool clipRect() {return clipX() && clipY();}
void advance(); // for bitblt: relalize character escapement for next bitblt
static wchar_t take_wchar(const char*&);
private:
static byte instr(byte c, byte d);
static void instr16(byte c, word d);
byte buf[32]; // 256 Bits Platz (zum Scrollen) für copyLine
};
extern DISP d;
Detected encoding: UTF-8 | 0
|