Add LCD Qt emulator.
authorbernie <bernie@38d2e660-2303-0410-9eaa-f027e97ec537>
Mon, 16 Jan 2006 03:51:35 +0000 (03:51 +0000)
committerbernie <bernie@38d2e660-2303-0410-9eaa-f027e97ec537>
Mon, 16 Jan 2006 03:51:35 +0000 (03:51 +0000)
git-svn-id: https://src.develer.com/svnoss/bertos/trunk@469 38d2e660-2303-0410-9eaa-f027e97ec537

drv/lcd_gfx_qt.cpp [new file with mode: 0755]
drv/lcd_gfx_qt.h [new file with mode: 0755]
drv/lcd_gfx_test.c [new file with mode: 0755]
drv/lcd_lm44_qt.cpp [new file with mode: 0755]
drv/lcd_lm44_qt.h [new file with mode: 0755]

diff --git a/drv/lcd_gfx_qt.cpp b/drv/lcd_gfx_qt.cpp
new file mode 100755 (executable)
index 0000000..4a3a486
--- /dev/null
@@ -0,0 +1,116 @@
+/**
+ * \file
+ * <!--
+ * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
+ * This file is part of DevLib - See README.devlib for information.
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ *
+ * \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 <emul/emul.h>
+
+#include <qpainter.h>
+#include <qimage.h>
+#include <qsizepolicy.h>
+#include <qsize.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),
+       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 <gfx/gfx.h>
+#include <cfg/debug.h>
+
+/*!
+ * 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 (executable)
index 0000000..f24e8e6
--- /dev/null
@@ -0,0 +1,69 @@
+/**
+ * \file
+ * <!--
+ * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
+ * All Rights Reserved.
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ *
+ * \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 <qframe.h>
+#include <qcolor.h>
+
+// 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 (executable)
index 0000000..50b41c6
--- /dev/null
@@ -0,0 +1,35 @@
+/**
+ * \file
+ * <!--
+ * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
+ * This file is part of DevLib - See README.devlib for information.
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ *
+ * \brief dot-matrix LCD test.
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.1  2006/01/16 03:51:35  bernie
+ *#* Add LCD Qt emulator.
+ *#*
+ *#*/
+
+#include <emul/emul.h>
+#include <drv/lcd_gfx.h>
+
+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 (executable)
index 0000000..9d5146e
--- /dev/null
@@ -0,0 +1,337 @@
+/**
+ * \file
+ * <!--
+ * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2000,2001 Bernardo Innocenti <bernie@codewiz.org>
+ * This file is part of DevLib - See README.devlib for information.
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ *
+ * \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 <qpainter.h>
+#include <qfont.h>
+#include <qsizepolicy.h>
+#include <qsize.h>
+#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 (executable)
index 0000000..9259992
--- /dev/null
@@ -0,0 +1,84 @@
+/**
+ * \file
+ * <!--
+ * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2000,2001 Bernardo Innocenti <bernie@codewiz.org>
+ * This file is part of DevLib - See README.devlib for information.
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ *
+ * \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 <qframe.h>
+#include <qfont.h>
+#include <qcolor.h>
+
+// 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)
+