1

Dependents:   Program_R11

Revision:
17:652ab113bc2e
Parent:
16:c276b75e6585
Child:
18:bd65dc10f27f
diff -r c276b75e6585 -r 652ab113bc2e TextLCD.cpp
--- a/TextLCD.cpp	Wed Feb 20 19:37:53 2013 +0000
+++ b/TextLCD.cpp	Sat Mar 02 16:51:01 2013 +0000
@@ -3,6 +3,7 @@
  *               2013, v01: WH, Added LCD types, fixed LCD address issues, added Cursor and UDCs 
  *               2013, v02: WH, Added I2C and SPI bus interfaces  
  *               2013, v03: WH, Added support for LCD40x4 which uses 2 controllers 
+ *               2013, v04: WH, Added support for Display On/Off, improved 4bit bootprocess 
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
@@ -151,6 +152,18 @@
     
     wait_ms(20);        // Wait 20ms to ensure powered up
 
+#if(1)
+    // send "Display Settings" 3 times (Only top nibble of 0x30 as we've got 4-bit bus)    
+    for (int i=0; i<3; i++) {
+        _writeNibble(0x3);
+        wait_ms(15);     // this command takes 1.64ms, so wait for it 
+    }
+    _writeNibble(0x2);   // 4-bit mode
+    wait_us(40);         // most instructions take 40us
+#else
+//Original code. Does not comply with specification and causes problems
+//unless used right after power-on.
+
     // send "Display Settings" 3 times (Only top nibble of 0x30 as we've got 4-bit bus)
     for (int i=0; i<3; i++) {
         _writeByte(0x3);
@@ -158,6 +171,7 @@
     }
     _writeByte(0x2);     // 4-bit mode
     wait_us(40);         // most instructions take 40us
+#endif
     
     // Display is now in 4-bit mode
     switch (_type) {
@@ -214,9 +228,9 @@
                          //   S=0  (No display shift)                        
 
 //    _writeCommand(0x0C); // Display Ctrl 0000 1 D C B
-//                         //   Display On, Cursor Off, Blink Off
+//                         //   Display On, Cursor Off, Blink Off   
     setCursor(TextLCD::CurOff_BlkOff);     
-
+    setMode(TextLCD::DispOn);     
 }
 
 
@@ -228,7 +242,7 @@
     _ctrl=TextLCD::_LCDCtrl_1; // Select 2nd controller
 
     // Second LCD controller Cursor always Off
-    _setCursor(TextLCD::CurOff_BlkOff);
+    _setCursorAndDisplayMode(_currentMode, TextLCD::CurOff_BlkOff);
 
     // Second LCD controller Clearscreen
     _writeCommand(0x01); // cls, and set cursor to 0    
@@ -248,7 +262,7 @@
 
   // Restore cursormode on primary LCD controller when needed
   if(_type==LCD40x4) {
-    _setCursor(_currentCursor);
+    _setCursorAndDisplayMode(_currentMode,_currentCursor);     
   }
                    
   _row=0;          // Reset Cursor location
@@ -499,6 +513,22 @@
 }
 
 
+// Write a nibble using the 4-bit interface
+// Used for mbed pins, I2C bus expander or SPI shifregister
+void TextLCD::_writeNibble(int value) {
+
+// Enable is Low
+    _setEnable(true);        
+    _setData(value & 0x0F);   // Low nibble
+    wait_us(1); // Data setup time        
+    _setEnable(false);    
+    wait_us(1); // Datahold time
+
+// Enable is Low
+
+}
+
+
 // Write a byte using the 4-bit interface
 // Used for mbed pins, I2C bus expander or SPI shifregister
 void TextLCD::_writeByte(int value) {
@@ -656,14 +686,15 @@
           if (row<2) { 
             // Test to see if we need to switch between controllers  
             if (_ctrl != _LCDCtrl_0) {
+
               // Second LCD controller Cursor Off
-              _setCursor(TextLCD::CurOff_BlkOff);
+              _setCursorAndDisplayMode(_currentMode, TextLCD::CurOff_BlkOff);    
 
               // Select primary controller
               _ctrl = _LCDCtrl_0;
 
               // Restore cursormode on primary LCD controller
-              _setCursor(_currentCursor);
+              _setCursorAndDisplayMode(_currentMode, _currentCursor);    
             }           
             
             return 0x00 + (row * 0x40) + column;          
@@ -673,13 +704,13 @@
             // Test to see if we need to switch between controllers  
             if (_ctrl != _LCDCtrl_1) {
               // Primary LCD controller Cursor Off
-              _setCursor(TextLCD::CurOff_BlkOff);
+              _setCursorAndDisplayMode(_currentMode, TextLCD::CurOff_BlkOff);    
 
               // Select secondary controller
               _ctrl = _LCDCtrl_1;
 
               // Restore cursormode on secondary LCD controller
-              _setCursor(_currentCursor);
+              _setCursorAndDisplayMode(_currentMode, _currentCursor);    
             }           
                                    
             return 0x00 + ((row-2) * 0x40) + column;          
@@ -784,37 +815,66 @@
 }
 
 
-void TextLCD::setCursor(TextLCD::LCDCursor show) { 
+// Set the Cursor Mode (Cursor Off & Blink Off, Cursor On & Blink Off, Cursor Off & Blink On, Cursor On & Blink On
+void TextLCD::setCursor(TextLCD::LCDCursor cursorMode) { 
 
-  // Save new cursor mode, needed when 2 controllers are in use
-  _currentCursor = show;
+  // Save new cursor mode, needed when 2 controllers are in use or when display is switched off/on
+  _currentCursor = cursorMode;
     
-  // Configure current LCD controller
-  _setCursor(_currentCursor);
+  // Configure only current LCD controller
+  _setCursorAndDisplayMode(_currentMode, _currentCursor);
     
 }
 
-void TextLCD::_setCursor(TextLCD::LCDCursor show) { 
+// Set the Displaymode (On/Off)
+void TextLCD::setMode(TextLCD::LCDMode displayMode) { 
+
+  // Save new displayMode, needed when 2 controllers are in use or when cursor is changed
+  _currentMode = displayMode;
     
-    // Configure current LCD controller    
-    switch (show) {
-      case CurOff_BlkOff : _writeCommand(0x0C); // Cursor off and Blink Off
-                           break;
+  // Select and configure second LCD controller when needed
+  if(_type==LCD40x4) {
+    if (_ctrl==TextLCD::_LCDCtrl_0) {
+      // Configure primary LCD controller
+      _setCursorAndDisplayMode(_currentMode, _currentCursor);
 
-      case CurOn_BlkOff :  _writeCommand(0x0E); // Cursor on and Blink Off
-                           break;
+      // Select 2nd controller
+      _ctrl=TextLCD::_LCDCtrl_1;
+  
+      // Configure secondary LCD controller    
+      _setCursorAndDisplayMode(_currentMode, TextLCD::CurOff_BlkOff);
 
-      case CurOff_BlkOn :  _writeCommand(0x0D); // Cursor off and Blink On
-                           break;
+      // Restore current controller
+      _ctrl=TextLCD::_LCDCtrl_0;       
+    }
+    else {
+      // Select primary controller
+      _ctrl=TextLCD::_LCDCtrl_0;
+    
+      // Configure primary LCD controller
+      _setCursorAndDisplayMode(_currentMode, TextLCD::CurOff_BlkOff);
+       
+      // Restore current controller
+      _ctrl=TextLCD::_LCDCtrl_1;
 
-      case CurOn_BlkOn  :  _writeCommand(0x0F); // Cursor on and Blink char
-                           break;
+      // Configure secondary LCD controller    
+      _setCursorAndDisplayMode(_currentMode, _currentCursor);
 
-// Should never get here.
-      default : 
-                           break;
-                     
     }
+  }
+  else {
+    // Configure primary LCD controller
+    _setCursorAndDisplayMode(_currentMode, _currentCursor);
+  }   
+    
+}
+
+
+// Set the Displaymode (On/Off) and Cursortype for current controller
+void TextLCD::_setCursorAndDisplayMode(TextLCD::LCDMode displayMode, TextLCD::LCDCursor cursorType) { 
+    
+    // Configure current LCD controller       
+    _writeCommand(0x08 | displayMode | cursorType);
 }