Contains necessary classes and functions for ELEC351

/media/uploads/Luka_Danilovic/elec_315_prototype_assembly.jpg

Committer:
Luka_Danilovic
Date:
Tue Jan 09 11:25:52 2018 +0000
Revision:
5:becb1545229d
Parent:
4:d463eafbabed
ELEC351 Library by Student 10497267; LCD driver is not working due to a bizarre bug I can not solve.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Luka_Danilovic 3:e84fa53173e6 1 #include "mbed.h"
Luka_Danilovic 3:e84fa53173e6 2 #include "displayMaster.hpp"
Luka_Danilovic 3:e84fa53173e6 3
Luka_Danilovic 5:becb1545229d 4 ////////////////////////////////////////////////////////////////////////////////
Luka_Danilovic 5:becb1545229d 5 // INCOMPLETE - RUN OUT OF TIME TO DEBUG //
Luka_Danilovic 5:becb1545229d 6 ////////////////////////////////////////////////////////////////////////////////
Luka_Danilovic 5:becb1545229d 7
Luka_Danilovic 3:e84fa53173e6 8 /* Instructions on using the 16x2 LCD panel are found here:
Luka_Danilovic 5:becb1545229d 9 [https://www.8051projects.net/lcd-interfacing/lcd-4-bit.php] */
Luka_Danilovic 5:becb1545229d 10 /* N.B. I did the code from scratch since I do not have the code from ELEC230 */
Luka_Danilovic 5:becb1545229d 11 /* N.B. This class contains blocking function so it goes into its own thread */
Luka_Danilovic 3:e84fa53173e6 12
Luka_Danilovic 3:e84fa53173e6 13 C_displayMaster::C_displayMaster(PinName D1, PinName D2, PinName D3 , PinName D4 , PinName RS , PinName RW, PinName EN)
Luka_Danilovic 5:becb1545229d 14 : // Initialisation of the instance
Luka_Danilovic 3:e84fa53173e6 15 _commsBus(D1, D2, D3, D4),
Luka_Danilovic 3:e84fa53173e6 16 _registerSel(RS),
Luka_Danilovic 3:e84fa53173e6 17 _modeSel(RW),
Luka_Danilovic 3:e84fa53173e6 18 _enable(EN)
Luka_Danilovic 3:e84fa53173e6 19 {
Luka_Danilovic 5:becb1545229d 20 _registerSel = INSTRUCTION; // command mode
Luka_Danilovic 5:becb1545229d 21 _modeSel = WRITE; // write mode
Luka_Danilovic 5:becb1545229d 22
Luka_Danilovic 5:becb1545229d 23 Thread::wait(20); // Wait 20ms to ensure powered up
Luka_Danilovic 5:becb1545229d 24
Luka_Danilovic 5:becb1545229d 25 for (int i=0; i<3; i++) { // Three times
Luka_Danilovic 5:becb1545229d 26 _enable = DISABLE; // Invalidate signal
Luka_Danilovic 5:becb1545229d 27 _commsBus = 0x03; // Send command for powerup
Luka_Danilovic 5:becb1545229d 28 _enable = ENABLE; // Validate signal
Luka_Danilovic 5:becb1545229d 29 Thread::wait(20); // Wait since BUSY flag is not yet available
Luka_Danilovic 5:becb1545229d 30 }
Luka_Danilovic 5:becb1545229d 31
Luka_Danilovic 5:becb1545229d 32 _enable = DISABLE; // Invalidate signal
Luka_Danilovic 5:becb1545229d 33 _commsBus = 0x03; // Send command for 4 bit mode
Luka_Danilovic 5:becb1545229d 34 _enable = ENABLE; // Validate signal
Luka_Danilovic 5:becb1545229d 35 Thread::wait(20); // Wait since BUSY flag is not yet available
Luka_Danilovic 5:becb1545229d 36
Luka_Danilovic 5:becb1545229d 37 // BUSY flag is now available, Can use "writeChar" //
Luka_Danilovic 5:becb1545229d 38
Luka_Danilovic 5:becb1545229d 39 writeChar(0x28, INSTRUCTION); // 4-bit, 2 Line, 5x7 Dots
Luka_Danilovic 5:becb1545229d 40 writeChar(0x0C, INSTRUCTION); // Display on Cursor off
Luka_Danilovic 5:becb1545229d 41 writeChar(0x04, INSTRUCTION); // Entry mode - no increment & no display shift
Luka_Danilovic 5:becb1545229d 42 clear(); // Clear display for writing (DDRAM cleared)
Luka_Danilovic 3:e84fa53173e6 43
Luka_Danilovic 5:becb1545229d 44 // writeChar(0b00100011, DATA); // Write Test "#" symbol
Luka_Danilovic 5:becb1545229d 45 // Thread::wait(1000); // Wait 1 second
Luka_Danilovic 5:becb1545229d 46 // clear(); // Clear Test "#" symbol
Luka_Danilovic 3:e84fa53173e6 47 }
Luka_Danilovic 3:e84fa53173e6 48
Luka_Danilovic 5:becb1545229d 49
Luka_Danilovic 5:becb1545229d 50 //****************************************************************************//
Luka_Danilovic 5:becb1545229d 51 void C_displayMaster::writeChar(int Char, bool REGISTER)
Luka_Danilovic 5:becb1545229d 52 {
Luka_Danilovic 5:becb1545229d 53 _enable = DISABLE; // DISABLE at start
Luka_Danilovic 5:becb1545229d 54 _commsBus[3].output(); // Reconfigure pin as output (MSB)
Luka_Danilovic 5:becb1545229d 55 _registerSel = REGISTER; // Chose register to comunicate with
Luka_Danilovic 5:becb1545229d 56 _modeSel = WRITE; // WRITE to register
Luka_Danilovic 5:becb1545229d 57
Luka_Danilovic 5:becb1545229d 58 _commsBus = (Char>>4); // Top nibble
Luka_Danilovic 5:becb1545229d 59 _enable = ENABLE; // Validate signal
Luka_Danilovic 5:becb1545229d 60 _enable = DISABLE; // Invalidate signal
Luka_Danilovic 5:becb1545229d 61 busyCheck(); // Chek if clear to write more
Luka_Danilovic 5:becb1545229d 62
Luka_Danilovic 5:becb1545229d 63 _commsBus = (Char>>0); // Bottom nibble
Luka_Danilovic 5:becb1545229d 64 _enable = ENABLE; // Validate signal
Luka_Danilovic 5:becb1545229d 65 _enable = DISABLE; // Invalidate signal
Luka_Danilovic 5:becb1545229d 66 busyCheck(); // Chek if clear to write more
Luka_Danilovic 5:becb1545229d 67 }
Luka_Danilovic 5:becb1545229d 68
Luka_Danilovic 5:becb1545229d 69
Luka_Danilovic 3:e84fa53173e6 70 void C_displayMaster::busyCheck()
Luka_Danilovic 3:e84fa53173e6 71 {
Luka_Danilovic 5:becb1545229d 72 _enable = DISABLE; // DISABLE at start
Luka_Danilovic 5:becb1545229d 73 _commsBus[3].input(); // Input to listen for BUSY flag (MSB)
Luka_Danilovic 5:becb1545229d 74 _registerSel = INSTRUCTION; // Comunicate with INSTRUCTION register
Luka_Danilovic 5:becb1545229d 75 _modeSel = READ; // READ from register
Luka_Danilovic 5:becb1545229d 76 _enable = ENABLE; // Listen for BUSY flag
Luka_Danilovic 3:e84fa53173e6 77 while(_commsBus[3]) {
Luka_Danilovic 5:becb1545229d 78 _enable != _enable; // Repeat read while BUSY flag is set
Luka_Danilovic 3:e84fa53173e6 79 }
Luka_Danilovic 5:becb1545229d 80 _enable = DISABLE; // Leave DISABLED upon exit
Luka_Danilovic 5:becb1545229d 81 _modeSel = WRITE; // Return to WRITE mode
Luka_Danilovic 5:becb1545229d 82 _commsBus[3].output(); // Reconfigure pin as output (MSB)
Luka_Danilovic 3:e84fa53173e6 83 }
Luka_Danilovic 3:e84fa53173e6 84
Luka_Danilovic 5:becb1545229d 85
Luka_Danilovic 5:becb1545229d 86 void C_displayMaster::calcDDRAM(int col, int row)
Luka_Danilovic 5:becb1545229d 87 {
Luka_Danilovic 5:becb1545229d 88 /* The following two IF statments create a continous display meaning that
Luka_Danilovic 5:becb1545229d 89 running of the right edge return you to the left edge and running of the
Luka_Danilovic 5:becb1545229d 90 bottom edge return you to the top row. */
Luka_Danilovic 5:becb1545229d 91
Luka_Danilovic 5:becb1545229d 92 if (col>16) { // If coloumn is outside of Right edge
Luka_Danilovic 5:becb1545229d 93 col = 1; // Go back to start of row
Luka_Danilovic 5:becb1545229d 94 } else if (col<1) { // OR If coloumn is outside of Left edge
Luka_Danilovic 5:becb1545229d 95 col = 1; // Go back to start of row
Luka_Danilovic 5:becb1545229d 96 } else { // Othetwise
Luka_Danilovic 5:becb1545229d 97 col = col; // No change in col
Luka_Danilovic 5:becb1545229d 98 }
Luka_Danilovic 5:becb1545229d 99
Luka_Danilovic 5:becb1545229d 100 if (row>2) { // If row is outside of Bottom edge
Luka_Danilovic 5:becb1545229d 101 row = 1; // Go back to top row
Luka_Danilovic 5:becb1545229d 102 } else if (row<1) { // OR If row is outside of Top edge
Luka_Danilovic 5:becb1545229d 103 row = 1; // Go back to top row
Luka_Danilovic 5:becb1545229d 104 } else { // Othetwise
Luka_Danilovic 5:becb1545229d 105 row = row; // No change in row
Luka_Danilovic 5:becb1545229d 106 }
Luka_Danilovic 5:becb1545229d 107
Luka_Danilovic 5:becb1545229d 108 _ADR = (1<<7)+((1<<6)*row-1)+col-1; // Recalculate DDRAM address
Luka_Danilovic 5:becb1545229d 109 }
Luka_Danilovic 5:becb1545229d 110
Luka_Danilovic 5:becb1545229d 111
Luka_Danilovic 5:becb1545229d 112 void C_displayMaster::clear()
Luka_Danilovic 3:e84fa53173e6 113 {
Luka_Danilovic 5:becb1545229d 114 writeChar(0x01, INSTRUCTION); // Clear display for writing (DDRAM cleared)
Luka_Danilovic 5:becb1545229d 115 _col = 1; // First coloumn
Luka_Danilovic 5:becb1545229d 116 _row = 1; // First row
Luka_Danilovic 5:becb1545229d 117 calcDDRAM(_col, _row); // Get DDRAM address for writing next char
Luka_Danilovic 5:becb1545229d 118 }
Luka_Danilovic 5:becb1545229d 119
Luka_Danilovic 5:becb1545229d 120
Luka_Danilovic 5:becb1545229d 121 int C_displayMaster::_getc()
Luka_Danilovic 5:becb1545229d 122 {
Luka_Danilovic 5:becb1545229d 123 return -1; // Return Fail value since function has no purpose but is needed for character Stream
Luka_Danilovic 5:becb1545229d 124 }
Luka_Danilovic 5:becb1545229d 125
Luka_Danilovic 5:becb1545229d 126
Luka_Danilovic 5:becb1545229d 127 int C_displayMaster::_putc(int character)
Luka_Danilovic 5:becb1545229d 128 {
Luka_Danilovic 5:becb1545229d 129 if (character=='\n') { // IF new line
Luka_Danilovic 5:becb1545229d 130 _row++; // Go to new row
Luka_Danilovic 5:becb1545229d 131 _col = 1; // Go to start of row
Luka_Danilovic 5:becb1545229d 132 } else if (character=='\r') { // IF carridge return
Luka_Danilovic 5:becb1545229d 133 _col = 1; // Go to start of line
Luka_Danilovic 5:becb1545229d 134 } else { // ELSE
Luka_Danilovic 5:becb1545229d 135
Luka_Danilovic 5:becb1545229d 136 calcDDRAM(_col, _row); // Get cursor new address (N.B this function also creates a continous display. More details in function).
Luka_Danilovic 5:becb1545229d 137 writeChar(_ADR, INSTRUCTION); // Set cursor to position
Luka_Danilovic 5:becb1545229d 138 writeChar(character, DATA); // Write character
Luka_Danilovic 5:becb1545229d 139
Luka_Danilovic 5:becb1545229d 140 _col++; // Increment cursor position
Luka_Danilovic 5:becb1545229d 141 if (_col>16) { // IF end of row go to new row
Luka_Danilovic 5:becb1545229d 142 _row++; // Go to new row
Luka_Danilovic 5:becb1545229d 143 _col = 1; // Go to start of row
Luka_Danilovic 5:becb1545229d 144 }
Luka_Danilovic 5:becb1545229d 145 }
Luka_Danilovic 5:becb1545229d 146 return character; // Return what was written to indicate sucess
Luka_Danilovic 3:e84fa53173e6 147 }