Rod Coleman / I2CTextLCD

Files at this revision

API Documentation at this revision

Comitter:
RodColeman
Date:
Tue Oct 15 10:44:20 2013 +0000
Parent:
8:4816fdd57607
Commit message:
Init changes as proved at Dawson

Changed in this revision

I2CTextLCD.cpp Show annotated file Show diff for this revision Revisions of this file
I2CTextLCD.h Show annotated file Show diff for this revision Revisions of this file
--- a/I2CTextLCD.cpp	Thu Dec 01 13:34:17 2011 +0000
+++ b/I2CTextLCD.cpp	Tue Oct 15 10:44:20 2013 +0000
@@ -10,32 +10,6 @@
 
 using namespace mbed;
 
-/*
-     * useful info found at http://www.a-netz.de/lcd.en.php
-     *
-     *
-     * Initialisation
-     * ==============
-     *
-     * After attaching the supply voltage/after a reset, the display needs to be brought in to a defined state
-     *
-     * - wait approximately 15 ms so the display is ready to execute commands
-     * - Execute the command 0x30 ("Display Settings") three times (wait 1,64ms after each command, the busy flag cannot be queried now).
-     * - The display is in 8 bit mode, so if you have only connected 4 data pins you should only transmit the higher nibble of each command.
-     * - If you want to use the 4 bit mode, now you can execute the command to switch over to this mode now.
-         * - Execute the "clear display" command
-     *
-     * Timing
-     * ======
-     *
-     * Nearly all commands transmitted to the display need 40us for execution.
-     * Exceptions are the commands "Clear Display and Reset" and "Set Cursor to Start Position"
-     * These commands need 1.64ms for execution. These timings are valid for all displays working with an
-     * internal clock of 250kHz. But I do not know any displays that use other frequencies. Any time you
-     * can use the busy flag to test if the display is ready to accept the next command.
-     *
-     */
-
 I2CTextLCD::I2CTextLCD(PinName sda, PinName scl, int i2cAddress , int columns, int rows,
                        bool backlight) : _i2c(sda, scl) {
 
@@ -44,52 +18,33 @@
     _rows = rows;
     _backlight=backlight;
     _i2c.frequency(70000); //  RC:2011-12-1 put this back in
- // Winstar 20x4 WH2004-NYG- needs 40ms after VDD> 4,5V
-    /*
-    wait(0.5);
-    writeCommand(0x2); // 4-bit mode
-    wait(0.05);
-    writeCommand(0x28);    // Function set 001 BW N F - -
-    wait(0.05);
-    */
+
+    // Winstar 20x4 WH2004-NYG- needs 40ms after VDD> 4,5V
     //RC:2011-11-23: Newhaven 20x4 OLED data sheet method
-    writeCommand(0x2); // 4-bit mode
+    wait(0.055);
+    init8574A();         // I2C chip PCF85774A init - E high - E falls with 0x2 on the D-nibble (set 4-bit mode command)
+    writeCommand(0x2);   // 4-bit mode
     wait(0.05);
-    writeCommand(0x2); // 4-bit mode
+    writeCommand(0x2);   // 4-bit mode
     wait(0.05);
-    writeCommand(0x28); // display OFF, "Function Set". Newhaven say 0x08, but this loses 2 rows!
+    writeCommand(0x2A);  // 2012-6-22 RC: Russian font Table. was 0x28. display OFF, "Function Set". Newhaven say 0x08, but this loses 2 rows!
     wait(0.05); 
-    writeCommand(0x1); // display clear
+    writeCommand(0x1);  // display clear
     wait(0.05);
-    writeCommand(0x6); // entry mode set
+    writeCommand(0x6);  // entry mode set
     wait(0.05); 
-    writeCommand(0x2); // 4-bit mode
+    writeCommand(0x2);  // 4-bit mode
     wait(0.05);                  
     writeCommand(0x0C); // ON-OFF ctrl: turns display ON, no cursor. Use 0x0E for cursor ON.
-    /* 0x28 also works for Winstar WEH002004ALPP5N00000 OLED display. 0x29= westEuro fon table, 0x2A = UK/Russian
-*/
-    // Added RC 2011-8-11
-    /*
-    writeCommand(0x05); // clear display RAM all to 00
-    wait(0.05);        // 6.2ms specified for OLED display to recover from RAM clear
-    
-    writeCommand(0x06);  //  Entry mode Set. Cursor Direction and Display Shift : 0000 01 CD S (CD 0-left, 1-right S(hift) 0-no, 1-yes
-    wait(0.05); 
-   writeCommand(0x14);  // OLED display shift disable etc
-    wait(0.05);
-    writeCommand(0x17);  // disable graphic mode, power ON
-    //cls();
-    wait(0.05);
-    writeCommand (0x01);  //clear entire display.
-    wait(0.07);
-*/
-
+    /* 0x28 also works for Winstar WEH002004ALPP5N00000 OLED display. 0x29= westEuro fon table, 0x2A = UK/Russian*/
+    wait(0.015);        // Wait 15ms to ensure powered up
 }
 
 int I2CTextLCD::_putc(int value) {
     if (value == '\n') {
         newline();
-    } else {
+    } 
+    else {
         writeData(value);
     }
     return value;
@@ -155,51 +110,41 @@
 void I2CTextLCD::reset() {
     cls();
 }
-
-void I2CTextLCD::writeByte(int c, bool rs) {  // This is the actual I2C transfer of the display data:
-        char cmd[2]; //led = 1;
-        cmd[0]=c>>2;                  // upper nibble
-        cmd[0]=cmd[0] & 0x3c;         // mask out bits other than 5:2 for data (RS and E are enabled separately, below:)
-        cmd[1]=c<<2;                 // lower nibble
-        cmd[1]=cmd[1] & 0x3c;
-        if (rs) {
-        cmd[0]=cmd[0] | 0x01;        // RS selects display DATA or a COMMAND. It's on bit 0:
-        cmd[1]=cmd[1] | 0x01;
-        }
-        _i2c.write( _i2cAddress,cmd,1); // E=0, write upper nibble. E's on bit 1!
-        wait_us(1);
+void I2CTextLCD::init8574A(void) {  // This puts the first command on the bus with E high
+                                    // to prevent E going LOW at init with undef data lines, WS0010 does not like.
+        char cmd[2]; 
+        cmd[0]=(0x2)<<2;                 // lower nibble
+        cmd[0]=cmd[0] & 0x3c; // 3C = 0011 1100
+        //RS = 0 for commands - and for init (only), we start with E high
         cmd[0]=cmd[0]|0x02; //E=1
         _i2c.write( _i2cAddress, cmd,1); 
-        wait_us(1);
         cmd[0]=cmd[0]&0x3d; //E=0, RS preserved in bit 0
         _i2c.write( _i2cAddress, cmd,1); 
         wait_us(1);
-        cmd[0]=cmd[1]; //E=0, write lower nibble
-        wait_us(1);
+    }
+void I2CTextLCD::writeByte(int c, bool rs) {  // This is the actual I2C transfer of the display data:
+        char cmd[2]; 
+        cmd[0]=c>>2;                  // upper nibble
+        cmd[0]=cmd[0] & 0x3c;         // mask out bits other than 5:2 for data (RS and E are enabled separately, below:)
+        cmd[1]=c<<2;                 // lower nibble
+        cmd[1]=cmd[1] & 0x3c;        // 3C = 0011 1100
+        if (rs) {
+            cmd[0]=cmd[0] | 0x01;        // RS selects display DATA or a COMMAND. It's on bit 0:
+            cmd[1]=cmd[1] | 0x01;
+        }
         cmd[0]=cmd[0]|0x02; //E=1
         _i2c.write( _i2cAddress, cmd,1); 
-        wait_us(1);
-        cmd[0]=cmd[0]&0x3d; //E=0, RS preserved in bit 0
+        //wait_us(1); **  delays between nibbles not needed. At 70kHz, the time for the I2C command writes is 114us per byte
+        cmd[0]=cmd[0]&0x3d; //E=0, RS preserved in bit 0. Data latched on fall of E (tS(d) = 40ns; tH(d) = 20ns)
+        _i2c.write( _i2cAddress, cmd,1); 
+        cmd[0]=cmd[1];         // prepare lower nibble
+        cmd[0]=cmd[0]|0x02;    //E=1
+        _i2c.write( _i2cAddress, cmd,1); 
+        cmd[0]=cmd[0]&0x3d;    //E=0, RS preserved in bit 0. this preserves E low beween cycles.
         _i2c.write( _i2cAddress, cmd,1);
-        _i2c.write ( _i2cAddress,cmd,1);              
-        // led = 0;
-        wait_us(1);
+        // ****** RECOVERY TIME:
+        wait_us(300);         // specified max. recovery time for all operations, except cls(), is 600us
     }
- // This is the original authors method:
-    //void I2CTextLCD::writeByte(int data, bool rs) {
-
-
-/*
-    writeNibble(data >> 4 , rs);
-    writeNibble(data >> 0 , rs);
-    RC 2011-8-11. change to d4..d7 - PCF8574 ports P2 .. P5
-*/
-//data = data>>2;
-//data = data & 0x3c;
-//writeNibble(data , rs);
-//data = data<<2;
-//data = data & 0x3c;
-//writeNibble(data , rs);
 
 void I2CTextLCD::writeCommand(int command) {
     // RS = 0;
@@ -214,17 +159,4 @@
     if (_column >= _columns) {
         newline();
     }
-}
-
-/* void I2CTextLCD::writeI2CByte(int data) {
-    char cmd[2];
-    cmd[0] = (data & 0xFF);
-    cmd[1] = (data >> 8);
-     _i2c.write(_i2cAddress, cmd, 2);
-*/
-
-
-
-
-
-
+}
\ No newline at end of file
--- a/I2CTextLCD.h	Thu Dec 01 13:34:17 2011 +0000
+++ b/I2CTextLCD.h	Tue Oct 15 10:44:20 2013 +0000
@@ -148,6 +148,7 @@
 protected:
 
     void clock();
+    void init8574A(void);
     void writeData(int data);
     void writeCommand(int command);
     void writeByte(int value, bool rs);
@@ -178,4 +179,3 @@
 
 #endif
 
-