my lcd

Fork of TextLCD by Simon Ford

Files at this revision

API Documentation at this revision

Comitter:
Janet
Date:
Thu Dec 17 14:55:22 2015 +0000
Parent:
8:308d188a2d3a
Commit message:
Zmiana przycisku i lcd

Changed in this revision

TextLCD.cpp Show annotated file Show diff for this revision Revisions of this file
TextLCD.h Show annotated file Show diff for this revision Revisions of this file
--- a/TextLCD.cpp	Thu Jan 02 21:07:01 2014 +0000
+++ b/TextLCD.cpp	Thu Dec 17 14:55:22 2015 +0000
@@ -23,11 +23,44 @@
 #include "TextLCD.h"
 #include "mbed.h"
 
+namespace ext_text_lcd {
+
+namespace {
+    int makeLcdAddress(const TextLCD::LCDType &type, int column, int row) {
+        return column + row * 0x40;
+    }
+    
+    int makeLcdAddress40(const TextLCD::LCDType &type, int column, int row) {
+        return column + row * 40;
+    }
+    
+    int makeLcdAddress4Rows(const TextLCD::LCDType &type, int column, int row) {
+        return column + (row % 2) * 0x40 + (row / 2) * 20;
+    }
+}
+
+const TextLCD::LCDType TextLCD::LCD16x2(16, 2, makeLcdAddress);
+const TextLCD::LCDType TextLCD::LCD16x2B(16, 2, makeLcdAddress40);
+const TextLCD::LCDType TextLCD::LCD20x2(20, 2, makeLcdAddress);
+const TextLCD::LCDType TextLCD::LCD20x4(20, 4, makeLcdAddress4Rows);
+
 TextLCD::TextLCD(PinName rs, PinName e, PinName d4, PinName d5,
-                 PinName d6, PinName d7, LCDType type) : _rs(rs),
-        _e(e), _d(d4, d5, d6, d7),
-        _type(type) {
+                 PinName d6, PinName d7, const LCDType &type) : 
+    _rs(rs), _e(e), _output(new BusOutput(d4, d5, d6, d7)),
+    _type(type)
+{
+    init();
+}
 
+TextLCD::TextLCD(PinName rs, PinName e, PortName dport, std::size_t dlsb, 
+                 const LCDType &type) :
+    _rs(rs), _e(e), _output(new PortOutput(dport, dlsb)),
+    _type(type)
+{
+    init();
+}
+
+void TextLCD::init() {
     _e  = 1;
     _rs = 0;            // command mode
 
@@ -47,12 +80,6 @@
     cls();
 }
 
-void TextLCD::character(int column, int row, int c) {
-    int a = address(column, row);
-    writeCommand(a);
-    writeData(c);
-}
-
 void TextLCD::cls() {
     writeCommand(0x01); // cls, and set cursor to 0
     wait(0.00164f);     // This command takes 1.64 ms
@@ -62,26 +89,31 @@
 void TextLCD::locate(int column, int row) {
     _column = column;
     _row = row;
+    
+    int a = address(column, row);
+    writeCommand(0x80 | a);
 }
 
 int TextLCD::_putc(int value) {
+    int column = _column;
+    int row = _row;
     if (value == '\n') {
-        _column = 0;
-        _row++;
-        if (_row >= rows()) {
-            _row = 0;
-        }
+        column = 0;
+        row = _row+1;
     } else {
-        character(_column, _row, value);
-        _column++;
-        if (_column >= columns()) {
-            _column = 0;
-            _row++;
-            if (_row >= rows()) {
-                _row = 0;
-            }
+        writeData(value);
+        column++;
+        if (column < columns()) {
+            return value;
         }
+        
+        column = 0;
+        row++;
     }
+    if (row >= rows()) {
+        row = 0;
+    }
+    locate(column, row);
     return value;
 }
 
@@ -90,12 +122,12 @@
 }
 
 void TextLCD::writeByte(int value) {
-    _d = value >> 4;
+    _output->writeNibble(value >> 4);
     wait(0.000040f); // most instructions take 40us
     _e = 0;
     wait(0.000040f);
     _e = 1;
-    _d = value >> 0;
+    _output->writeNibble(value);
     wait(0.000040f);
     _e = 0;
     wait(0.000040f);  // most instructions take 40us
@@ -112,48 +144,29 @@
     writeByte(data);
 }
 
-int TextLCD::address(int column, int row) {
-    switch (_type) {
-        case LCD20x4:
-            switch (row) {
-                case 0:
-                    return 0x80 + column;
-                case 1:
-                    return 0xc0 + column;
-                case 2:
-                    return 0x94 + column;
-                case 3:
-                    return 0xd4 + column;
-            }
-        case LCD16x2B:
-            return 0x80 + (row * 40) + column;
-        case LCD16x2:
-        case LCD20x2:
-        default:
-            return 0x80 + (row * 0x40) + column;
-    }
+void TextLCD::setDisplayControl(DisplayControl d, CursorDisplayControl c, CursorStyle b)
+{
+    writeCommand(0x08 | d | c | b);
 }
 
-int TextLCD::columns() {
-    switch (_type) {
-        case LCD20x4:
-        case LCD20x2:
-            return 20;
-        case LCD16x2:
-        case LCD16x2B:
-        default:
-            return 16;
+void TextLCD::writeToCGMem(unsigned addr, const char *buffer, std::size_t size)
+{
+    writeCommand(0x40 | (addr & 0x3f));
+    while (size > 0) {
+        writeData(*buffer);
+        size--;
+        buffer++;
     }
+    
+    locate(_column, _row);
 }
 
-int TextLCD::rows() {
-    switch (_type) {
-        case LCD20x4:
-            return 4;
-        case LCD16x2:
-        case LCD16x2B:
-        case LCD20x2:
-        default:
-            return 2;
-    }
+void TextLCD::BusOutput::writeNibble(int value) {
+    _bus = value; 
 }
+
+void TextLCD::PortOutput::writeNibble(int value) {
+    _port = value << _shift;
+}
+
+} // ext_text_lcd namespace
--- a/TextLCD.h	Thu Jan 02 21:07:01 2014 +0000
+++ b/TextLCD.h	Thu Dec 17 14:55:22 2015 +0000
@@ -1,6 +1,9 @@
-/* mbed TextLCD Library, for a 4-bit LCD based on HD44780
+/* Extended TextLCD library.
+ *
+ * Based on the mbed TextLCD Library, for a 4-bit LCD based on HD44780
  * Copyright (c) 2007-2010, sford, http://mbed.org
  *
+ * Original license:
  * 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
@@ -20,12 +23,14 @@
  * THE SOFTWARE.
  */
 
-#ifndef MBED_TEXTLCD_H
-#define MBED_TEXTLCD_H
+#ifndef EXT_TEXT_LCD_TEXTLCD_H
+#define EXT_TEXT_LCD_TEXTLCD_H
 
 #include "mbed.h"
 
-/**  A TextLCD interface for driving 4-bit HD44780-based LCDs
+namespace ext_text_lcd {
+
+/** A TextLCD interface for driving 4-bit HD44780-based LCDs
  *
  * Currently supports 16x2, 20x2 and 20x4 panels
  *
@@ -33,7 +38,8 @@
  * #include "mbed.h"
  * #include "TextLCD.h"
  * 
- * TextLCD lcd(p10, p12, p15, p16, p29, p30); // rs, e, d4-d7
+ * TextLCD lcd(p10, p12, p15, p16, p29, p30); // rs, e, d4-d7 on individual pins
+ * TextLCD lcd(p10, p12, Port2, 2); // rs, e, d4-d7 on P2.2-P2.5
  * 
  * int main() {
  *     lcd.printf("Hello World!\n");
@@ -42,14 +48,31 @@
  */
 class TextLCD : public Stream {
 public:
+    /** LCD panel format */
+    class LCDType {
+    public: 
+        int columns() const;
+        int rows() const;
+        int address(int column, int row) const;
+                
+        typedef int (*MakeAddrFunc)(const LCDType &, int, int);
+        
+    private:
+        LCDType(int columns, int rows, MakeAddrFunc makeAddr) : 
+            _columns(columns), _rows(rows), _makeAddr(makeAddr)
+        { }
 
-    /** LCD panel format */
-    enum LCDType {
-        LCD16x2     /**< 16x2 LCD panel (default) */
-        , LCD16x2B  /**< 16x2 LCD panel alternate addressing */
-        , LCD20x2   /**< 20x2 LCD panel */
-        , LCD20x4   /**< 20x4 LCD panel */
+        friend class TextLCD;
+                
+        int _columns;
+        int _rows;
+        MakeAddrFunc _makeAddr;
     };
+    
+    static const LCDType LCD16x2;
+    static const LCDType LCD16x2B;
+    static const LCDType LCD20x2;
+    static const LCDType LCD20x4;
 
     /** Create a TextLCD interface
      *
@@ -58,8 +81,18 @@
      * @param d4-d7 Data lines for using as a 4-bit interface
      * @param type  Sets the panel size/addressing mode (default = LCD16x2)
      */
-    TextLCD(PinName rs, PinName e, PinName d4, PinName d5, PinName d6, PinName d7, LCDType type = LCD16x2);
+    TextLCD(PinName rs, PinName e, PinName d4, PinName d5, PinName d6, PinName d7, const LCDType &type = LCD20x4);
 
+    /** Create a TextLCD interface
+     *
+     * @param rs    Instruction/data control line
+     * @param e     Enable line (clock)
+     * @param dport GPIO port with all data lines
+     * @param dlsb  Index of the lowest data bit in the GPIO port
+     * @param type  Sets the panel size/addressing mode (default = LCD16x2)
+     */
+    TextLCD(PinName rs, PinName e, PortName dport, std::size_t dlsb, const LCDType &type = LCD16x2);
+    
 #if DOXYGEN_ONLY
     /** Write a character to the LCD
      *
@@ -85,27 +118,77 @@
     /** Clear the screen and locate to 0,0 */
     void cls();
 
-    int rows();
-    int columns();
+    int columns() { return _type.columns(); }
+    int rows() const { return _type.rows(); }
+
+    enum DisplayControl {
+        DisplayOn = 0x04,
+        DisplayOff = 0
+    };
+    enum CursorDisplayControl {
+        CursorOn = 0x02,
+        CursorOff = 0
+    };
+    enum CursorStyle {
+        BlinkingCursor = 0x01,
+        UnderlineCursor = 0
+    }; 
+    void setDisplayControl(DisplayControl d = DisplayOn, CursorDisplayControl c = CursorOff, CursorStyle b = UnderlineCursor);
+
+    void writeToCGMem(unsigned addr, const char *buffer, std::size_t size);
 
 protected:
-
     // Stream implementation functions
     virtual int _putc(int value);
     virtual int _getc();
 
-    int address(int column, int row);
-    void character(int column, int row, int c);
+    int address(int column, int row) const { return _type.address(column, row); }
+
     void writeByte(int value);
     void writeCommand(int command);
     void writeData(int data);
 
+private:
+    void init();
+    
+    struct LcdOutput {
+        virtual void writeNibble(int value) = 0;
+        virtual ~LcdOutput() { }
+    };
+    
+    struct BusOutput : public LcdOutput {
+        BusOutput(PinName d4, PinName d5, PinName d6, PinName d7) : _bus(d4, d5, d6, d7) { }
+        virtual void writeNibble(int value);
+    private:
+        BusOut _bus;
+    };
+    
+    struct PortOutput : public LcdOutput {
+        PortOutput(PortName dport, std::size_t dlsb) : _port(dport, 0x0f << dlsb), _shift(dlsb) { }
+        virtual void writeNibble(int value);
+        
+    private:
+        PortOut _port;
+        std::size_t _shift;
+    };
+    
     DigitalOut _rs, _e;
-    BusOut _d;
+    LcdOutput *_output;
     LCDType _type;
-
     int _column;
-    int _row;
+    int _row;    
 };
 
+inline int TextLCD::LCDType::columns() const { 
+    return this->_columns; 
+}
+inline int TextLCD::LCDType::rows() const { 
+    return this->_rows; 
+}
+inline int TextLCD::LCDType::address(int column, int row) const { 
+    return this->_makeAddr(*this, column, row); 
+}
+
+} // ext_text_lcd namespace
+
 #endif