Display text on LCD displays (even on multiple ones). Allow to create windows (frames) on display, and to combine them (split, add, duplicate, scroll). See http://mbed.org/users/hlipka/notebook/lcdwindow/ for more information.
Revision 3:e5d5e2fe4bf6, committed 2010-11-28
- Comitter:
- hlipka
- Date:
- Sun Nov 28 22:09:54 2010 +0000
- Parent:
- 2:5ac5bab7daaf
- Child:
- 4:aa08e82834dc
- Commit message:
- Made LCD driver thread safe (to allow usage from timers)
Changed in this revision
--- a/dogm_spi.cpp Sat Nov 27 22:54:13 2010 +0000 +++ b/dogm_spi.cpp Sun Nov 28 22:09:54 2010 +0000 @@ -50,15 +50,18 @@ void DogmLCDSPI::character(int column, int row, int c) { int address=(row)*0x40+(column); + _guard->take(); sendCmd((char)address|0x80); wait_ms(1); sendData(c); + _guard->release(); wait_ms(1); } void DogmLCDSPI::writeText(const unsigned int column, const unsigned int row, const char text[]) { int address=(row)*0x40+(column); + _guard->take(); sendCmd((char)address|0x80); wait_ms(1); @@ -69,10 +72,13 @@ wait_ms(1); i++; } + _guard->release(); } void DogmLCDSPI::clear() { + _guard->take(); sendCmd(1); + _guard->release(); }
--- a/dogm_spi.h Sat Nov 27 22:54:13 2010 +0000 +++ b/dogm_spi.h Sun Nov 28 22:09:54 2010 +0000 @@ -1,17 +1,17 @@ /* * mbed LCDWindow library * Copyright (c) 2010 Hendrik Lipka -* +* * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: -* +* * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. -* +* * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -28,28 +28,27 @@ #include "DigitalOut.h" #include "SPI.h" +#include "semaphore.h" -using namespace mbed; +using namespace mbed; /** * class for connecting a DOGM16x LCD display, from electronic assembly (www.lcd-module.com ) */ -class DogmLCDSPI: public SPILCDBase -{ - public: - /** - * @param columns number of chars per line - * @param rows number of lines (currently only 1 and 2 work) - * @param the SPI object used for sending data (set to 1MHz) - * @param enable the pin name for the enable line (0=active, connected to /CSB) - * @param rs the pin name for the register select line (0=cmd, 1=data) - */ - DogmLCDSPI(unsigned int columns, unsigned int rows, SPI *spi, PinName enable, PinName rs); - virtual void init(); - virtual void writeText(const unsigned int column, const unsigned int row, const char text[]); - virtual void clear(); - virtual void character(int column, int row, int c); - +class DogmLCDSPI: public SPILCDBase { +public: + /** + * @param columns number of chars per line + * @param rows number of lines (currently only 1 and 2 work) + * @param the SPI object used for sending data (set to 1MHz) + * @param enable the pin name for the enable line (0=active, connected to /CSB) + * @param rs the pin name for the register select line (0=cmd, 1=data) + */ + DogmLCDSPI(unsigned int columns, unsigned int rows, SPI *spi, PinName enable, PinName rs); + virtual void init(); + virtual void writeText(const unsigned int column, const unsigned int row, const char text[]); + virtual void clear(); + virtual void character(int column, int row, int c); }; #endif \ No newline at end of file
--- a/hd44780_8bit.cpp Sat Nov 27 22:54:13 2010 +0000 +++ b/hd44780_8bit.cpp Sun Nov 28 22:09:54 2010 +0000 @@ -30,9 +30,11 @@ void HD44780LCD8bit::character(int column, int row, int c) { int address=(row)*0x40+(column); + _guard->take(); sendCmd((unsigned char)address|0x80); wait_us(30); sendData(c); + _guard->release(); wait_us(30); } @@ -40,6 +42,7 @@ void HD44780LCD8bit::writeText(const unsigned int column, const unsigned int row, const char text[]) { // printf("print to %d,%d {%s}\n",line,pos,text); int address=row*0x40+column; + _guard->take(); sendCmd((unsigned char)address|0x80); wait_us(30); @@ -49,10 +52,13 @@ wait_us(30); i++; } + _guard->release(); } void HD44780LCD8bit::clear() { + _guard->take(); sendCmd(1); + _guard->release(); } void HD44780LCD8bit::sendCmd(const unsigned char cmd) {
--- a/ks0108_8bit.cpp Sat Nov 27 22:54:13 2010 +0000 +++ b/ks0108_8bit.cpp Sun Nov 28 22:09:54 2010 +0000 @@ -39,9 +39,11 @@ } void KS0108LCD8bit::clear() { + _guard->take(); clearHalf(_left); if (NULL!=_right) clearHalf(_right); + _guard->release(); } void KS0108LCD8bit::clearHalf(DigitalOut* cs) { @@ -74,6 +76,7 @@ if (NULL==cs) return; + _guard->take(); sendCmd(0xb8|row,cs); // set x page unsigned int y=icolumn*8; @@ -85,6 +88,7 @@ sendData(font_data[c][i],cs); } + _guard->release(); } KS0108LCD8bit::KS0108LCD8bit
--- a/lcd.h Sat Nov 27 22:54:13 2010 +0000 +++ b/lcd.h Sun Nov 28 22:09:54 2010 +0000 @@ -42,9 +42,10 @@ protected: const unsigned int _columns; const unsigned int _rows; - TextLCDBase(unsigned int columns, unsigned int rows):_columns(columns),_rows(rows) + TextLCDBase(unsigned int columns, unsigned int rows):Window(),_columns(columns),_rows(rows) { - } + }; + void test(){printf("x");}; }; #endif /*LCD_H_*/
--- a/multiwindow.cpp Sat Nov 27 22:54:13 2010 +0000 +++ b/multiwindow.cpp Sun Nov 28 22:09:54 2010 +0000 @@ -23,7 +23,7 @@ #include "multiwindow.h" -MultiWindow::MultiWindow(vector<Window*> lcds) { +MultiWindow::MultiWindow(vector<Window*> lcds):Window() { _lcds=lcds; int len=_lcds.size(); _rows=0;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/semaphore.cpp Sun Nov 28 22:09:54 2010 +0000 @@ -0,0 +1,39 @@ +/** + * code from Igor Skochinsky + * taken from http://mbed.org/forum/mbed/post/799/ +*/ + +#include "semaphore.h" + + Semaphore::Semaphore(): s(SemFree) {}; + + bool Semaphore::take(bool block) + { + int oldval; +#if defined(TARGET_LPC1768) // on Cortex-M3 we can use ldrex/strex + do { + // read the semaphore value + oldval = __ldrex(&s); + // loop again if it is locked and we are blocking + // or setting it with strex failed + } + while ( (block && oldval == SemTaken) || __strex(SemTaken, &s) != 0 ); + if ( !block ) __clrex(); // clear exclusive lock set by ldrex +#else // on arm7 there's only swp + do { + // swp sets the pointed data to the given value and returns the previous one + oldval = __swp(SemTaken, &s); + // if blocking, loop until the previous value becomes 0 + // which would mean we have successfully taken the lock + } + while (block && oldval == SemTaken); +#endif + return oldval == SemFree; + } + + // release the semaphore + void Semaphore::release() + { + s = SemFree; + } + \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/semaphore.h Sun Nov 28 22:09:54 2010 +0000 @@ -0,0 +1,28 @@ +/** + * code from Igor Skochinsky + * taken from http://mbed.org/forum/mbed/post/799/ +*/ + +#ifndef SEMAPHORE_H_ +#define SEMAPHORE_H_ + +class Semaphore +{ +public: + // constructor + Semaphore(); + + // try to take the semaphore and return success + // by default block until succeeded + bool take(bool block = true); + // release the semaphore + void release(); + + private: + enum { SemFree, SemTaken }; + // semaphore value + int s; + +}; + +#endif
--- a/subwindow.cpp Sat Nov 27 22:54:13 2010 +0000 +++ b/subwindow.cpp Sun Nov 28 22:09:54 2010 +0000 @@ -25,7 +25,8 @@ #include "string.h" -SubWindow::SubWindow(Window* lcd, const unsigned int columnOffset, const unsigned int rowOffset, const unsigned int columns, const unsigned int rows) { +SubWindow::SubWindow(Window* lcd, const unsigned int columnOffset, const unsigned int rowOffset, const unsigned int columns, const unsigned int rows) +:Window() { _lcd=lcd; _columnOffset=columnOffset; _rowOffset=rowOffset;
--- a/teewindow.cpp Sat Nov 27 22:54:13 2010 +0000 +++ b/teewindow.cpp Sun Nov 28 22:09:54 2010 +0000 @@ -23,7 +23,7 @@ #include "teewindow.h" -TeeWindow::TeeWindow(vector<Window*> lcds) { +TeeWindow::TeeWindow(vector<Window*> lcds):Window() { _lcds=lcds; int len=_lcds.size(); _columns=_lcds[0]->getColumns();
--- a/terminal.cpp Sat Nov 27 22:54:13 2010 +0000 +++ b/terminal.cpp Sun Nov 28 22:09:54 2010 +0000 @@ -24,7 +24,7 @@ #include "terminal.h" #include "string.h" -Terminal::Terminal(Window* window) { +Terminal::Terminal(Window* window):Window() { _window=window; _columns=window->getColumns(); _rows=window->getRows();
--- a/window.cpp Sat Nov 27 22:54:13 2010 +0000 +++ b/window.cpp Sun Nov 28 22:09:54 2010 +0000 @@ -47,4 +47,9 @@ } } return value; +} + +Window::Window() +{ + _guard=new Semaphore(); } \ No newline at end of file
--- a/window.h Sat Nov 27 22:54:13 2010 +0000 +++ b/window.h Sun Nov 28 22:09:54 2010 +0000 @@ -25,6 +25,7 @@ #define WINDOW_H_ #include "Stream.h" +#include "semaphore.h" using namespace mbed; @@ -55,7 +56,7 @@ */ virtual void clear()=0; - /** + /** * set (internal) cursor to a screen column and row * * @param column The horizontal position from the left, indexed from 0 @@ -74,7 +75,7 @@ virtual void character(int column, int row, int c)=0; #if DOXYGEN_ONLY - /** + /** * Write a character to the LCD, on the position specified by the cursor * sets the cursor to the next position, and wraps (from right to left, next line, and from bottom back to top) * @@ -82,7 +83,7 @@ */ int putc(int c); - /** + /** * Write a formated string to the LCD, on the position specified by the cursor * does wrap around (as specified by putc) * @@ -92,6 +93,12 @@ int printf(const char* format, ...); #endif protected: + /** + * base constructor + * initializes the _guard semaphore needed for syncing parallel writes + */ + Window(); + // Stream implementation functions virtual int _putc(int value); virtual int _getc() { @@ -100,6 +107,8 @@ int _column; int _row; + + Semaphore *_guard; }; #endif /*WINDOW_H_*/