test code megasquirt and digole lcd

Dependencies:   FatFileSystem mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers TextLCD.cpp Source File

TextLCD.cpp

00001 /* draft mbed TextLCD 
00002  * (c) 2007/8, sford
00003  */
00004  
00005 #include "TextLCD.h"
00006 
00007 #include "mbed.h"
00008 
00009 using namespace mbed;
00010 
00011 /*
00012  * useful info found at http://www.a-netz.de/lcd.en.php
00013  *
00014  *
00015  * Initialisation
00016  * ==============
00017  *
00018  * After attaching the supply voltage/after a reset, the display needs to be brought in to a defined state
00019  *
00020  * - wait approximately 15 ms so the display is ready to execute commands
00021  * - Execute the command 0x30 ("Display Settings") three times (wait 1,64ms after each command, the busy flag cannot be queried now). 
00022  * - 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.
00023  * - If you want to use the 4 bit mode, now you can execute the command to switch over to this mode now.
00024  * - Execute the "clear display" command
00025  *
00026  * Timing
00027  * ======
00028  *
00029  * Nearly all commands transmitted to the display need 40us for execution. 
00030  * Exceptions are the commands "Clear Display and Reset" and "Set Cursor to Start Position" 
00031  * These commands need 1.64ms for execution. These timings are valid for all displays working with an 
00032  * internal clock of 250kHz. But I do not know any displays that use other frequencies. Any time you 
00033  * can use the busy flag to test if the display is ready to accept the next command.
00034  * 
00035  * _e is kept high apart from calling clock
00036  * _rw is kept 0 (write) apart from actions that uyse it differently
00037  * _rs is set by the data/command writes
00038  */
00039 
00040 
00041 //wait(0.05);
00042 
00043 TextLCD::TextLCD(PinName rs, PinName rw, PinName e, PinName d0, PinName d1, 
00044     PinName d2, PinName d3, int columns, int rows) : _rw(rw), _rs(rs), 
00045     _e(e), _d(d0, d1, d2, d3), _columns(columns), _rows(rows) {
00046 
00047     _rows = 4;
00048     _columns = 20;
00049 wait(0.05);
00050     _rw = 0;
00051     _e  = 1;
00052     _rs = 0; // command mode
00053 wait(0.05);
00054     // Should theoretically wait 15ms, but most things will be powered up pre-reset
00055     // so i'll disable that for the minute. If implemented, could wait 15ms post reset
00056     // instead
00057     // wait(0.015); 
00058         
00059     // send "Display Settings" 3 times (Only top nibble of 0x30 as we've got 4-bit bus)
00060     for(int i=0; i<3; i++) {
00061         writeNibble(0x3);
00062         wait(0.005);      // this command takes 1.64ms, so wait for it
00063     }
00064     wait(0.1);
00065     writeNibble(0x2); // 4-bit mode
00066 wait(0.001);            
00067     writeCommand(0x28);    // Function set 001 BW N F - -  
00068 wait(0.001);
00069     writeCommand(0x0C);
00070     wait(0.001);
00071     writeCommand(0x6);  //  Cursor Direction and Display Shift : 0000 01 CD S (CD 0-left, 1-right S(hift) 0-no, 1-yes
00072     cls();
00073 }
00074 
00075 
00076 
00077 int TextLCD::_putc(int value) {
00078     if(value == '\n') {
00079         newline();
00080     } else {
00081         writeData(value);
00082     }
00083     return value;
00084 }
00085 
00086 int TextLCD::_getc() {
00087     return 0;
00088 }
00089 
00090 void TextLCD::newline() {
00091     _column = 0;
00092     _row++;
00093     if(_row >= _rows) {
00094         _row = 0;
00095     }
00096     locate(_column, _row); 
00097 }
00098 
00099 void TextLCD::locate(int column, int row) 
00100 {
00101    /* if(column < 0 || column >= _columns || row < 0 || row >= _rows) {
00102         ERROR("locate(%d,%d) out of range on %dx%d display", column, row, _columns, _rows);
00103         return;
00104     }*/
00105     
00106     _row = row;
00107       _column = column;
00108       int address=0;
00109       
00110       if (_rows > 2) {
00111         // row 0 : 0x0->0x13
00112         // row 1 : 0x40->0x53
00113         // row 2 : 0x14->0x27
00114         // row 3 : 0x54->0x67
00115         
00116         switch (_row) {
00117             case (0) : address = 0x80 + _column;
00118             break;
00119             case (1) : address = 0xc0 + _column;
00120             break;
00121             case (2) : address = 0x94 + _column;
00122             break;
00123             case (3) : address = 0xd4 + _column;
00124             break;
00125         }        
00126                 
00127       }
00128       else {
00129          // memory starts at 0x80, and is 40 chars long per row
00130           address = 0x80 + (_row * 40)  + _column; 
00131       }
00132       
00133       writeCommand(address);            
00134 }
00135 
00136 
00137 void TextLCD::rows(int rows) {
00138     _rows = rows;
00139 }
00140 
00141 
00142 void TextLCD::columns(int columns) {
00143     _columns = columns;
00144 }
00145 
00146 
00147 
00148 
00149 void TextLCD::cls() {
00150     writeCommand(0x01); // Clear Display
00151     wait(0.00164f);        // This command takes 1.64 ms
00152       locate(0, 0);
00153 }
00154 
00155 void TextLCD::reset() {
00156     cls();
00157 }
00158 
00159 void TextLCD::clock() {
00160     wait(0.00010);
00161     _e = 0;
00162     wait(0.00010);  // most instructions take 40us
00163     _e = 1;    
00164 }
00165 
00166 void TextLCD::writeNibble(int value) {
00167     _d = value;
00168     clock();
00169 }
00170 
00171 void TextLCD::writeByte(int value) {
00172     writeNibble(value >> 4);
00173     writeNibble(value >> 0);
00174 }
00175 
00176 void TextLCD::writeCommand(int command) {
00177     _rs = 0;
00178     writeByte(command);
00179 }
00180 
00181 void TextLCD::writeData(int data) {
00182     _rs = 1;
00183     writeByte(data);
00184     _column++;
00185     if(_column >= _columns) {
00186         newline();
00187     } 
00188 }