Contains necessary classes and functions for ELEC351

/media/uploads/Luka_Danilovic/elec_315_prototype_assembly.jpg

Revision:
5:becb1545229d
Parent:
4:d463eafbabed
--- a/displayMaster/displayMaster.cpp	Thu Dec 28 12:34:20 2017 +0000
+++ b/displayMaster/displayMaster.cpp	Tue Jan 09 11:25:52 2018 +0000
@@ -1,73 +1,147 @@
 #include "mbed.h"
 #include "displayMaster.hpp"
 
+////////////////////////////////////////////////////////////////////////////////
+//                      INCOMPLETE - RUN OUT OF TIME TO DEBUG                 //
+////////////////////////////////////////////////////////////////////////////////
+
 /* Instructions on using the 16x2 LCD panel are found here:
-[https://www.8051projects.net/lcd-interfacing/lcd-4-bit.php] */
-
-/* N.B. This class contains blocking function */
+[https://www.8051projects.net/lcd-interfacing/lcd-4-bit.php]                  */
+/* N.B. I did the code from scratch since I do not have the code from ELEC230 */
+/* N.B. This class contains blocking function so it goes into its own thread  */
 
 C_displayMaster::C_displayMaster(PinName D1, PinName D2, PinName D3 , PinName D4 , PinName RS , PinName RW, PinName EN)
-    :
+    :   // Initialisation of the instance
     _commsBus(D1, D2, D3, D4),
     _registerSel(RS),
     _modeSel(RW),
     _enable(EN)
 {
-    _enable      = DISABLE;          // DISABLE at start
-    _commsBus[3].output();           // Reconfigure pin as output (MSB)
-    Thread::wait(20);                // Powerup time
-    _commsBus = 0x03;                // Pannel config instruction 1
-    _enable      = ENABLE;           // Validate instruction
-    _enable      = DISABLE;
-    Thread::wait(15);                // Wait since BUSY flag not available yet
-    _commsBus = 0x03;                // Pannel config instruction 2
-    _enable      = ENABLE;           // Validate instruction
-    _enable      = DISABLE;
-    Thread::wait(5);                 // Wait since BUSY flag not available yet
-    _commsBus = 0x03;                // Pannel config instruction 3
-    _enable      = ENABLE;           // Validate instruction
-    _enable      = DISABLE;
-    Thread::wait(2);                 // Wait since BUSY flag not available yet
-    _commsBus = 0x02;                // Pannel config instruction (4 bit mode)
-    _enable      = ENABLE;           // Validate instruction
-    _enable      = DISABLE;
-    Thread::wait(2);                 // Wait since BUSY flag not available yet
-    writeChar(0x28, INSTRUCTION);    // Function Set: 4-bit, 2 Line, 5x7 Dots
-    //writeChar(0x01, INSTRUCTION);    // Clear Display (also clear DDRAM content)
-    writeChar(0x0C, INSTRUCTION);    // Display = on, Cursor = off
-    writeChar(0x06, INSTRUCTION);    // Entry Mode (Auto increment)
-    
-    writeChar(0x23, DATA);
+    _registerSel    = INSTRUCTION;  // command mode
+    _modeSel        = WRITE;        // write mode
+
+    Thread::wait(20);               // Wait 20ms to ensure powered up
+
+    for (int i=0; i<3; i++) {       // Three times
+        _enable     = DISABLE;      // Invalidate signal
+        _commsBus   = 0x03;         // Send command for powerup
+        _enable     = ENABLE;       // Validate signal
+        Thread::wait(20);           // Wait since BUSY flag is not yet available
+    }
+
+    _enable     = DISABLE;          // Invalidate signal
+    _commsBus   = 0x03;             // Send command for 4 bit mode
+    _enable     = ENABLE;           // Validate signal
+    Thread::wait(20);               // Wait since BUSY flag is not yet available
+
+    // BUSY flag is now available, Can use "writeChar"                        //
+
+    writeChar(0x28, INSTRUCTION);   // 4-bit, 2 Line, 5x7 Dots
+    writeChar(0x0C, INSTRUCTION);   // Display on Cursor off
+    writeChar(0x04, INSTRUCTION);   // Entry mode - no increment & no display shift
+    clear();                        // Clear display for writing (DDRAM cleared)
 
+//    writeChar(0b00100011, DATA);    // Write Test "#" symbol
+//    Thread::wait(1000);             // Wait 1 second
+//    clear();                        // Clear Test "#" symbol
 }
 
+
+//****************************************************************************//
+void C_displayMaster::writeChar(int Char, bool REGISTER)
+{
+    _enable      = DISABLE;         // DISABLE at start
+    _commsBus[3].output();          // Reconfigure pin as output (MSB)
+    _registerSel = REGISTER;        // Chose register to comunicate with
+    _modeSel     = WRITE;           // WRITE to register
+
+    _commsBus    = (Char>>4);       // Top nibble
+    _enable      = ENABLE;          // Validate signal
+    _enable = DISABLE;              // Invalidate signal
+    busyCheck();                    // Chek if clear to write more
+
+    _commsBus    = (Char>>0);       // Bottom nibble
+    _enable      = ENABLE;          // Validate signal
+    _enable = DISABLE;              // Invalidate signal
+    busyCheck();                    // Chek if clear to write more
+}
+
+
 void C_displayMaster::busyCheck()
 {
-    _enable      = DISABLE;          // DISABLE at start
-    _commsBus[3].input();            // Input to listen for BUSY flag (MSB)
-    _registerSel = INSTRUCTION;      // Comunicate with INSTRUCTION register
-    _modeSel     = READ;             // READ from register
-    _enable      = ENABLE;           // Listen for BUSY flag
+    _enable      = DISABLE;         // DISABLE at start
+    _commsBus[3].input();           // Input to listen for BUSY flag (MSB)
+    _registerSel = INSTRUCTION;     // Comunicate with INSTRUCTION register
+    _modeSel     = READ;            // READ from register
+    _enable      = ENABLE;          // Listen for BUSY flag
     while(_commsBus[3]) {
-        _enable != _enable;          // Repeat read while BUSY flag is set
+        _enable != _enable;         // Repeat read while BUSY flag is set
     }
-    _enable      = DISABLE;          // Leave DISABLED upon exit
-    _modeSel     = WRITE;            // Return to WRITE mode
-    _commsBus[3].output();           // Reconfigure pin as output (MSB)
+    _enable      = DISABLE;         // Leave DISABLED upon exit
+    _modeSel     = WRITE;           // Return to WRITE mode
+    _commsBus[3].output();          // Reconfigure pin as output (MSB)
 }
 
-void C_displayMaster::writeChar(char instructions, bool REGISTER)
+
+void C_displayMaster::calcDDRAM(int col, int row)
+{
+    /* The following two IF statments create a continous display meaning that
+    running of the right edge return you to the left edge and running of the
+    bottom edge return you to the top row.                                    */
+
+    if (col>16) {                   // If coloumn is outside of Right edge
+        col =  1;                   // Go back to start of row
+    } else if (col<1) {             // OR If coloumn is outside of Left edge
+        col =  1;                   // Go back to start of row
+    } else {                        // Othetwise
+        col = col;                  // No change in col
+    }
+
+    if (row>2) {                    // If row is outside of Bottom edge
+        row =  1;                   // Go back to top row
+    } else if (row<1) {             // OR If row is outside of Top edge
+        row =  1;                   // Go back to top row
+    } else {                        // Othetwise
+        row = row;                  // No change in row
+    }
+
+    _ADR = (1<<7)+((1<<6)*row-1)+col-1;   // Recalculate DDRAM address
+}
+
+
+void C_displayMaster::clear()
 {
-    _enable      = DISABLE;          // DISABLE at start
-    _commsBus[3].output();           // Reconfigure pin as output (MSB)
-    _registerSel = REGISTER;         // Chose register to comunicate with
-    _modeSel     = WRITE;            // WRITE to register
-    _commsBus    = (instructions>>4);// Top nibble
-    _enable      = ENABLE;           // validate signal
-    Thread::wait(20);
-   // busyCheck();
-    _commsBus    = (instructions);   // Bottom nibble
-    _enable      = ENABLE;           // validate signal
-   // busyCheck();
-   Thread::wait(20);
+    writeChar(0x01, INSTRUCTION);   // Clear display for writing (DDRAM cleared)
+    _col = 1;                       // First coloumn
+    _row = 1;                       // First row
+    calcDDRAM(_col, _row);          // Get DDRAM address for writing next char
+}
+
+
+int C_displayMaster::_getc()
+{
+    return -1;                      // Return Fail value since function has no purpose but is needed for character Stream
+}
+
+
+int C_displayMaster::_putc(int character)
+{
+    if (character=='\n') {          // IF new line
+        _row++;                     // Go to new row
+        _col = 1;                   // Go to start of row
+    } else if (character=='\r') {   // IF carridge return
+        _col = 1;                   // Go to start of line
+    } else {                        // ELSE
+        
+        calcDDRAM(_col, _row);          // Get cursor new address (N.B this function also creates a continous display. More details in function).
+        writeChar(_ADR, INSTRUCTION);   // Set cursor to position
+        writeChar(character, DATA);     // Write character
+        
+        _col++;                     // Increment cursor position
+        if (_col>16) {              // IF end of row go to new row
+            _row++;                 // Go to new row
+            _col = 1;               // Go to start of row
+        }
+    }
+    return character;               // Return what was written to indicate sucess
 }
\ No newline at end of file