00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <iostream>
00027 #include <fstream>
00028
00029 #include "lcd.h"
00030 #include "pinatport.h"
00031
00032 using namespace std;
00033
00034
00035 #define ENABLE 16
00036 #define READWRITE 32
00037 #define COMMANDDATA 64
00038
00039 int lcdStartLine []={0, 0x40, 0x14, 0x20};
00040
00041
00042
00043 static int Power_onTimes[]={1500000, 410000, 10000, 3700, 152000};
00044
00045 void Lcd::LcdWriteData(unsigned char data) {
00046 ostringstream os;
00047 os << name << " WriteChar " << merke_x+1 << " " << merke_y << " " << (unsigned int)data << endl;
00048
00049 ui->Write(os.str());
00050
00051 merke_x++;
00052 SendCursorPosition();
00053 }
00054
00055 void Lcd::SendCursorPosition() {
00056 ostringstream os;
00057 os << name << " MoveCursor " << merke_x << " " << merke_y << " " << endl;
00058 ui->Write(os.str());
00059 }
00060
00061 unsigned int Lcd::LcdWriteCommand(unsigned char command) {
00062 bool lerr = false;
00063 if (command >= 0x80 ) {
00064
00065 int line;
00066 int value=command-0x80;
00067 if (value >= 0x54) {line=3; value-=0x54;} else {
00068 if (value >= 0x40) {line=1; value-=0x40;} else {
00069 if (value >= 0x14) {line=2; value-=0x14;} else {
00070 line=0; }}}
00071
00072 merke_x=value;
00073 merke_y=line;
00074
00075 merke_x++;
00076 SendCursorPosition();
00077
00078 return Power_onTimes[3];
00079 }
00080
00081 if (command >= 0x40) {
00082 cerr << "Not supported LCD command: Set Character Generator Address " << endl;
00083 return Power_onTimes[3];
00084 }
00085 if (command >= 0x20) {
00086 if ((command & 0x10)) {
00087 cerr << "Not supported LCD command: Set 8 Bit Interface ";
00088 lerr = true;
00089 }
00090 if ((command & 0x04)) {
00091 cerr << "Not supported LCD command: 5*10 char. size";
00092 lerr = true;
00093 }
00094 if (lerr == true) {
00095 cerr << endl;
00096 }
00097 return Power_onTimes[3];
00098 }
00099
00100 if (command >= 0x10) {
00101 command &= 0x0c;
00102 switch (command) {
00103 case 0:
00104 merke_x--;
00105 break;
00106 case 4:
00107 merke_x++;
00108 break;
00109 case 8:
00110 case 0x0c:
00111 cerr << "Not supported LCD command: Display shift left or right" << endl;
00112 break;
00113 default:
00114 break;
00115 }
00116 return Power_onTimes[3];
00117 }
00118
00119 if (command >= 8) {
00120 if (command != 0x0e) {
00121 cerr << "Not supported LCD command: Display off / Cursor off / Cursor Blink" << endl;
00122 }
00123 return Power_onTimes[3];
00124 }
00125
00126 if (command >= 4) {
00127 if (command != 6) {
00128 cerr << "Not supported LCD command: Set Entry Mode" << endl;
00129 }
00130 return Power_onTimes[3];
00131 }
00132
00133 if (command >= 2) {
00134 merke_x=0;
00135 merke_y=0;
00136 SendCursorPosition();
00137 return Power_onTimes[4];
00138 }
00139
00140 if (command==1) {
00141 for (merke_y=3; merke_y>=0; merke_y--) {
00142 for ( merke_x=0; merke_x<=19; ) {
00143 LcdWriteData(' ');
00144 }
00145 }
00146 merke_x=0;
00147 merke_y=0;
00148 SendCursorPosition();
00149 return Power_onTimes[4];
00150 }
00151 return 0;
00152 }
00153
00154 t_myState setInitNext(unsigned char command,t_myState myState,unsigned int *CmdExecTime_ns) {
00155 if (command == 0x30) {
00156 switch (myState) {
00157 case POWER_ON:
00158 myState = PWR_AFTER_FS1;
00159 *CmdExecTime_ns = Power_onTimes[0];
00160 break;
00161 case PWR_AFTER_FS1:
00162 myState = PWR_AFTER_FS2;
00163 *CmdExecTime_ns = Power_onTimes[1];
00164 break;
00165 case PWR_AFTER_FS2:
00166 myState = PWR_ON_FINISH;
00167 *CmdExecTime_ns = Power_onTimes[2];
00168 break;
00169 default:
00170 break;
00171 }
00172 } else {
00173 cerr << "LCD-Init: Waiting for Function Set Command. Received: 0x" << hex << (unsigned int) command << " Dismissed!" <<endl;
00174 }
00175 return myState;
00176 }
00177
00178
00179 int Lcd::Step(bool &trueHwStep, SystemClockOffset *timeToNextStepIn_ns) {
00180
00181
00182
00183 static unsigned int lcnt = 0;
00184
00185 if (CmdExecTime_ns > 0){
00186 CmdExecTime_ns --;
00187 } else {
00188 CmdExecTime_ns = 0;
00189 myd3='L';
00190 }
00191 if (lastPortValue!= myPortValue) {
00192 lastPortValue=myPortValue;
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208 if (enableOld!= ( myPortValue& ENABLE)) {
00209 enableOld= ( myPortValue& ENABLE);
00210 d3='t';
00211 if (myPortValue& ENABLE) {
00212 if ((myPortValue& READWRITE)==0) {
00213 if (CmdExecTime_ns >= 1000) {
00214 cerr << "LCD busy for another " << CmdExecTime_ns /1000 << "us" << endl;
00215
00216 }
00217 if ( readLow ==0 ) {
00218 command= (myPortValue&0x0f)<<4;
00219 switch (myState) {
00220 case POWER_ON:
00221 case PWR_AFTER_FS1:
00222 case PWR_AFTER_FS2:
00223
00224 cerr << lcnt << " Got new 8Bit value data: 0x";
00225 cerr.setf(ios::hex);
00226 cerr << (unsigned int)command << endl;
00227 cerr.unsetf(ios::hex);
00228 myState = setInitNext((command&0xf0),myState, &CmdExecTime_ns);
00229 lcnt++;
00230 myd3='L';
00231 readLow=0;
00232 break;
00233 case PWR_ON_FINISH:
00234 if ((command&0xf0) == 0x20) {
00235 CmdExecTime_ns = Power_onTimes[3];
00236 myState = CMDEXEC;
00237 myd3='H';
00238 } else {
00239 cerr << "LCD-Init: Waiting for Function Set Command with 4 Bit I/F. Received: 0x" << hex << (unsigned int)command << " Dismissed!" <<endl;
00240 }
00241 break;
00242 default:
00243 readLow=1;
00244 break;
00245 }
00246 } else {
00247 readLow=0;
00248 command|=(myPortValue&0x0f);
00249
00250 lcnt++;
00251 myd3='H';
00252 if ((myPortValue&COMMANDDATA)) {
00253
00254 LcdWriteData (command);
00255 CmdExecTime_ns = Power_onTimes[3];
00256 } else {
00257
00258
00259 switch (myState) {
00260 case POWER_ON:
00261 case PWR_AFTER_FS1:
00262 case PWR_AFTER_FS2:
00263 myd3='L';
00264 myState = setInitNext((command&0xf0),myState, &CmdExecTime_ns);
00265 break;
00266 case PWR_ON_FINISH:
00267 cerr << "LCD-Init: I/F set to not not supported 8 Bit mode! Received: 0x" << hex << (unsigned int)command << " Dismissed!" <<endl;
00268 break;
00269 case IDLE:
00270 case CMDEXEC:
00271 CmdExecTime_ns = LcdWriteCommand(command);
00272 myState = CMDEXEC;
00273 break;
00274 }
00275 }
00276 }
00277 } else {
00278 if ((myPortValue&COMMANDDATA)) {
00279 cerr << "LCD-Read: Read data not supported " << endl;
00280 }else {
00281 d3=myd3;
00282 if ((CmdExecTime_ns == 0) && (myState>=PWR_ON_FINISH)) {
00283 myState=IDLE;
00284 }
00285 }
00286 }
00287 }
00288 }
00289 }
00290 if(timeToNextStepIn_ns!=0) *timeToNextStepIn_ns=0;
00291 return 0;
00292 }
00293
00294
00295 Lcd::Lcd(UserInterface *_ui, const char *_name, const char *baseWindow):
00296 ui(_ui), name(_name),
00297 d0( &myPortValue, 1),
00298 d1( &myPortValue, 2),
00299 d2( &myPortValue, 4),
00300 d3( &myPortValue, 8),
00301 enable( &myPortValue, ENABLE),
00302 readWrite( &myPortValue, READWRITE),
00303 commandData( &myPortValue, COMMANDDATA)
00304
00305 {
00306 lastPortValue=0;
00307 readLow=0;
00308 command=0;
00309 enableOld=0;
00310
00311 allPins["d0"]=&d0;
00312 allPins["d1"]=&d1;
00313 allPins["d2"]=&d2;
00314 allPins["d3"]=&d3;
00315
00316 allPins["e"]=&enable;
00317 allPins["r"]=&readWrite;
00318 allPins["c"]=&commandData;
00319
00320 myPortValue=0;
00321
00322 myState = POWER_ON;
00323 CmdExecTime_ns = Power_onTimes[0];
00324 myd3='L';
00325
00326 merke_x=0;
00327 merke_y=0;
00328
00329
00330 ostringstream os;
00331 os << "create Lcd " << name << " " << baseWindow << " " << " 20 4" << endl;
00332 ui->Write(os.str());
00333 }
00334
00335 Lcd::~Lcd() { }
00336 Pin *Lcd::GetPin(const char *name) {
00337 return allPins[name];
00338 }
00339