From a08ff2655e6d37b5b9e6e11d78d75b6fdc1b7d0b Mon Sep 17 00:00:00 2001 From: bernie Date: Mon, 16 Jan 2006 03:51:35 +0000 Subject: [PATCH] Add LCD Qt emulator. git-svn-id: https://src.develer.com/svnoss/bertos/trunk@469 38d2e660-2303-0410-9eaa-f027e97ec537 --- drv/lcd_gfx_qt.cpp | 116 +++++++++++++++ drv/lcd_gfx_qt.h | 69 +++++++++ drv/lcd_gfx_test.c | 35 +++++ drv/lcd_lm44_qt.cpp | 337 ++++++++++++++++++++++++++++++++++++++++++++ drv/lcd_lm44_qt.h | 84 +++++++++++ 5 files changed, 641 insertions(+) create mode 100755 drv/lcd_gfx_qt.cpp create mode 100755 drv/lcd_gfx_qt.h create mode 100755 drv/lcd_gfx_test.c create mode 100755 drv/lcd_lm44_qt.cpp create mode 100755 drv/lcd_lm44_qt.h diff --git a/drv/lcd_gfx_qt.cpp b/drv/lcd_gfx_qt.cpp new file mode 100755 index 00000000..4a3a4863 --- /dev/null +++ b/drv/lcd_gfx_qt.cpp @@ -0,0 +1,116 @@ +/** + * \file + * + * + * \version $Id$ + * + * \author Bernardo Innocenti + * + * \brief Custom control for graphics LCD emulation (interface) + */ + +/*#* + *#* $Log$ + *#* Revision 1.1 2006/01/16 03:51:35 bernie + *#* Add LCD Qt emulator. + *#* + *#*/ + +#include "lcd_gfx_qt.h" +#include + +#include +#include +#include +#include + +// Display colors +#define LCD_FG_COLOR 0x0, 0x0, 0x0 +#define LCD_BG_COLOR 0xBB, 0xCC, 0xBB + + +EmulLCD::EmulLCD(QWidget *parent, const char *name) : + QFrame(parent, name, WRepaintNoErase | WResizeNoErase), + fg_color(LCD_FG_COLOR), + bg_color(LCD_BG_COLOR) +{ + // initialize bitmap + memset(raster, 0xAA, sizeof(raster)); + + // set widget frame + setFrameStyle(QFrame::Panel | QFrame::Sunken); + frame_width = frameWidth(); +} + + +EmulLCD::~EmulLCD() +{ + // nop +} + + +QSizePolicy EmulLCD::sizePolicy() const +{ + return QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed, false); +} + + +QSize EmulLCD::sizeHint() const +{ + return QSize( + WIDTH + frame_width * 2, + HEIGHT + frame_width * 2); +} + + +void EmulLCD::drawContents(QPainter *p) +{ + QImage img(raster, WIDTH, HEIGHT, 1, NULL, 0, QImage::IgnoreEndian); + + p->setBackgroundMode(OpaqueMode); + p->setPen(fg_color); + p->setBackgroundColor(bg_color); + p->drawImage(frame_width, frame_width, img); +} + +void EmulLCD::writeRaster(uint8_t *new_raster) +{ + memcpy(raster, new_raster, sizeof(raster)); + + QPainter p(this); + drawContents(&p); +} + + + +#include +#include + +/*! + * Raster buffer to draw into. + * Bits in the bitmap bytes have vertical orientation, + * as required by the LCD driver. + */ +DECLARE_WALL(wall_before_raster, WALL_SIZE) +static uint8_t lcd_raster[EmulLCD::WIDTH * ((EmulLCD::HEIGHT + 7) / 8)]; +DECLARE_WALL(wall_after_raster, WALL_SIZE) + +/*! Default LCD bitmap */ +struct Bitmap lcd_bitmap; + +extern "C" void lcd_init(void) +{ + gfx_bitmapInit(&lcd_bitmap, lcd_raster, EmulLCD::WIDTH, EmulLCD::HEIGHT); + gfx_bitmapClear(&lcd_bitmap); +} + +extern "C" void lcd_blit_bitmap(Bitmap *bm) +{ + emul->emulLCD->writeRaster(bm->raster); +} + +#include "lcd_gfx_qt_moc.cpp" + diff --git a/drv/lcd_gfx_qt.h b/drv/lcd_gfx_qt.h new file mode 100755 index 00000000..f24e8e6d --- /dev/null +++ b/drv/lcd_gfx_qt.h @@ -0,0 +1,69 @@ +/** + * \file + * + * + * \version $Id$ + * + * \author Bernardo Innocenti + * + * \brief Custom control for graphics LCD emulation (interface) + */ + +/*#* + *#* $Log$ + *#* Revision 1.1 2006/01/16 03:51:35 bernie + *#* Add LCD Qt emulator. + *#* + *#*/ + +#ifndef DRV_LCD_GFX_QT_H +#define DRV_LCD_GFX_QT_H + +#include +#include + +// fwd decls +class QSizePolicy; +class QPaintEvent; +class QResizeEvent; + + +class EmulLCD : public QFrame +{ + Q_OBJECT + +public: +// Attributes + enum { WIDTH = 128, HEIGHT = 64 }; + +// Construction + EmulLCD(QWidget *parent = 0, const char *name = 0); + virtual ~EmulLCD(); + +// Base class overrides +protected: + virtual QSizePolicy sizePolicy() const; + virtual QSize sizeHint() const; +// virtual void paintEvent(QPaintEvent *event); + virtual void drawContents(QPainter *p); + +// Operations +public: + void writeRaster(uint8_t *raster); + +// Implementation +protected: + /// Frame thickness + int frame_width; + + /// LCD colors + QColor fg_color, bg_color; + + /// Pixel storage + unsigned char raster[(WIDTH * HEIGHT) / 8]; +}; + +#endif // DRV_LCD_GFX_QT_H diff --git a/drv/lcd_gfx_test.c b/drv/lcd_gfx_test.c new file mode 100755 index 00000000..50b41c6c --- /dev/null +++ b/drv/lcd_gfx_test.c @@ -0,0 +1,35 @@ +/** + * \file + * + * + * \version $Id$ + * + * \author Bernardo Innocenti + * + * \brief dot-matrix LCD test. + */ + +/*#* + *#* $Log$ + *#* Revision 1.1 2006/01/16 03:51:35 bernie + *#* Add LCD Qt emulator. + *#* + *#*/ + +#include +#include + +int main(int argc, char *argv[]) +{ + emul_init(&argc, argv); + lcd_init(); + + for(;;) + emul_idle(); + + emul_cleanup(); + return 0; +} diff --git a/drv/lcd_lm44_qt.cpp b/drv/lcd_lm44_qt.cpp new file mode 100755 index 00000000..9d5146e7 --- /dev/null +++ b/drv/lcd_lm44_qt.cpp @@ -0,0 +1,337 @@ +/** + * \file + * + * + * \version $Id$ + * + * \author Bernardo Innocenti + * + * \brief Custom Qt widget for emulating a graphics LCD display (implementation) + */ + +/*#* + *#* $Log$ + *#* Revision 1.1 2006/01/16 03:51:35 bernie + *#* Add LCD Qt emulator. + *#* + *#*/ + +#include +#include +#include +#include +#include "EmulLCD.h" +#include "Emul.h" + + +// Display colors +#define LCD_FG_COLOR 0x0, 0x0, 0x0 +#define LCD_BG_COLOR 0xBB, 0xCC, 0xBB + + +EmulLCD::EmulLCD(QWidget *parent, const char *name) : + QFrame(parent, name, WRepaintNoErase | WResizeNoErase), + lcd_font("courier", 18), + fg_color(LCD_FG_COLOR), + bg_color(LCD_BG_COLOR), + cr_row(0), + cr_col(0), + cgramaddr(-1), + show_cursor(true) +{ + // initialize DDRAM + memcpy(ddram, + "01234567890123456789" + "abcdefghijhlmnopqrst" + "ABCDEFGHIJKLMNOPQRST" + "!@#$%^&*()_+|{}':?><", + sizeof(ddram)); + + // setup font + lcd_font.setFixedPitch(true); + setFont(lcd_font); + + // get exact font size + QFontMetrics fm(lcd_font); + font_width = fm.width(QChar(' ')); + font_height = fm.height(); + + // set widget frame + setFrameStyle(QFrame::Panel | QFrame::Sunken); +// setLineWidth(2); + frame_width = frameWidth(); +} + + +EmulLCD::~EmulLCD() +{ + // nop +} + + +QSizePolicy EmulLCD::sizePolicy() const +{ + return QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed, false); +} + + +QSize EmulLCD::sizeHint() const +{ + return QSize( + font_width * COLS + frame_width * 2, + font_height * ROWS + frame_width * 2); +} + + +void EmulLCD::drawContents(QPainter *p) +{ + RedrawText(*p); +} + + +void EmulLCD::SetPainter(QPainter & p) +{ + p.setBackgroundMode(OpaqueMode); + p.setPen(fg_color); + p.setBackgroundColor(bg_color); +} + + +void EmulLCD::RedrawText(QPainter & p) +{ + int r, c; + + SetPainter(p); + + for (r = 0; r < ROWS; r++) + for (c = 0; c < COLS; c++) + PrintChar(p, r, c); +} + + +void EmulLCD::PrintChar(QPainter & p, int row, int col) +{ + // Fetch char from DD RAM + unsigned char c = ddram[row][col]; + + // Map some Hitachi characters to ISO Latin1 + switch(c) + { + case 0xDF: + c = 0xBA; // "degrees" glyph + break; + + case 0xE4: + c = 0xB5; // "micro" glyph + break; + + default: // all others + break; + } + + // Draw char on display + int x = col * font_width + frame_width; + int y = row * font_height + frame_width; + bool restore_colors = false; + + if (show_cursor && (row == cr_row) && (col == cr_col)) + { + // Exchange FG/BG colors + p.setPen(bg_color); + p.setBackgroundColor(fg_color); + restore_colors = true; + } + + p.drawText(x, y, x + font_width, y + font_height, 0 /*tf*/, + QString(QChar(c)), 1); + + if (restore_colors) + { + // Restore FG/BG colors + p.setPen(fg_color); + p.setBackgroundColor(bg_color); + } +} + + +void EmulLCD::MoveCursor(int r, int c) +{ + // Save old cursor position + int old_row = cr_row; + int old_col = cr_col; + + // Move the cursor + cgramaddr = -1; + cr_row = r; + cr_col = c; + + if (show_cursor && (old_col != cr_col || old_row != cr_row)) + { + QPainter p(this); + SetPainter(p); + + // Draw new cursor + PrintChar(p, cr_row, cr_col); + + // Erase old cursor + PrintChar(p, old_row, old_col); + } +} + + +void EmulLCD::ShowCursor(bool show) +{ + show_cursor = show; + + // Draw (or erase) cursor + QPainter p(this); + SetPainter(p); + PrintChar(p, cr_row, cr_col); +} + + +void EmulLCD::AdvanceCursor() +{ + // Move the cursor + if (cr_col == COLS - 1) + { + if (cr_row == ROWS - 1) + MoveCursor(0, 0); + else + MoveCursor(cr_row + 1, 0); + } + else + MoveCursor(cr_row, cr_col + 1); +} + + +void EmulLCD::PutChar(unsigned char c) +{ + if (cgramaddr != -1) + { + // Write data in CGRAM + cgram[cgramaddr] = c; + + // Auto increment CGRAM address + cgramaddr = (cgramaddr + 1) & 0x3F; + } + else + { + // Writing in DDRAM + ddram[cr_row][cr_col] = c; + + // Update display + { + QPainter p(this); + SetPainter(p); + PrintChar(p, cr_row, cr_col); + } + AdvanceCursor(); + } +} + + +char EmulLCD::GetChar() +{ + char c = ddram[cr_row][cr_col]; + AdvanceCursor(); + return c; +} + + +void EmulLCD::Clear() +{ + memset(ddram, ' ', sizeof(ddram)); + cr_row = cr_col = 0; + + QPainter p(this); + RedrawText(p); +} + + +void EmulLCD::SetCGRamAddr(unsigned char addr) +{ + cgramaddr = addr & (sizeof(cgram) - 1); +} + + +// Hitachi LM044L register-level emulation + +#define INI_DISPLAY 0x30 +#define INI_OP_DISP 0x38 /* 8 bits, 2 lines, 5x7 dots */ +#define ON_DISPLAY 0x0F /* Switch on display */ +#define OFF_DISPLAY 0x08 /* Switch off display */ +#define CLR_DISPLAY 0x01 /* Clear display */ +#define CURSOR_BLOCK 0x0D /* Show cursor (block) */ +#define CURSOR_LINE 0x0F /* Show cursor (line) */ +#define CURSOR_OFF 0x0C /* Hide cursor */ +#define MODE_DISPL 0x06 +#define SHIFT_DISPLAY 0x18 +#define MOVESHIFT_LEFT 0x00 +#define MOVESHIFT_RIGHT 0x04 +#define LCD_CGRAMADDR (1<<6) +#define LCD_DDRAMADDR (1<<7) + + +extern "C" void Emul_LCDWriteReg(unsigned char d) +{ + static const unsigned char lcd_rowaddress[EmulLCD::ROWS] = { 0x80, 0xC0, 0x94, 0xD4 }; + + switch(d) + { + case CLR_DISPLAY: + emul->emulLCD->Clear(); + break; + + case CURSOR_BLOCK: + case CURSOR_LINE: + emul->emulLCD->ShowCursor(true); + break; + + case CURSOR_OFF: + emul->emulLCD->ShowCursor(false); + break; + + default: + // Set DDRAM address? + if (d & LCD_DDRAMADDR) + { + for (int i = 0; i < EmulLCD::ROWS; i++) + { + if ((d >= lcd_rowaddress[i]) && (d < lcd_rowaddress[i] + EmulLCD::COLS)) + { + emul->emulLCD->MoveCursor(i, d - lcd_rowaddress[i]); + break; + } + } + } + else if (d & LCD_CGRAMADDR) + emul->emulLCD->SetCGRamAddr(d); + break; + } +} + + +extern "C" unsigned char Emul_LCDReadReg(void) +{ + return 0; /* This LCD model is never busy ;-) */ +} + + +extern "C" void Emul_LCDWriteData(unsigned char d) +{ + emul->emulLCD->PutChar(d); +} + + +extern "C" unsigned char Emul_LCDReadData(void) +{ + return emul->emulLCD->GetChar(); +} + +#include "EmulLCD.moc" + diff --git a/drv/lcd_lm44_qt.h b/drv/lcd_lm44_qt.h new file mode 100755 index 00000000..9259992d --- /dev/null +++ b/drv/lcd_lm44_qt.h @@ -0,0 +1,84 @@ +/** + * \file + * + * + * \version $Id$ + * + * \author Bernardo Innocenti + * + * \brief Custom Qt widget for emulating a graphics LCD display (implementation) + */ + +/*#* + *#* $Log$ + *#* Revision 1.1 2006/01/16 03:51:35 bernie + *#* Add LCD Qt emulator. + *#* + *#*/ + +#ifndef EMULLCD_H +#define EMULLCD_H + +#include +#include +#include + +// fwd decls +class QSizePolicy; +class QPaintEvent; +class QResizeEvent; + +/** + * Qt widget to emulate a dot-matrix LCD display. + */ +class EmulLCD : public QFrame +{ + Q_OBJECT + +public: +// Attributes + enum { COLS = 20, ROWS = 4 }; + +// Construction + EmulLCD(QWidget *parent = 0, const char *name = 0); + virtual ~EmulLCD(); + +// Base class overrides +protected: + virtual QSizePolicy sizePolicy() const; + virtual QSize sizeHint() const; + virtual void drawContents(QPainter *p); + +// Operations +public: + void MoveCursor (int col, int row); + void ShowCursor (bool show = true); + void PutChar (unsigned char c); + char GetChar (); + void Clear (); + void SetCGRamAddr (unsigned char addr); + +// Implementation +protected: + void SetPainter(QPainter & p); + void RedrawText(QPainter & p); + void PrintChar(QPainter & p, int row, int col); + void AdvanceCursor(); + + QFont lcd_font; ///< Display character font + QColor fg_color, bg_color; ///< LCD colors + int font_width, font_height; ///< Font dimensions + int frame_width; ///< Frame width (and height) + int cr_row, cr_col; ///< Cursor position + int cgramaddr; ///< CGRAM Address (-1 disabled) + unsigned char ddram[ROWS][COLS];///< Display data RAM + unsigned char cgram[8*8]; ///< CGRAM + bool show_cursor; ///< Cursor enabled? +}; + +#endif // !defined(EMULLCD_H) + -- 2.25.1