00001 /* 00002 **************************************************************************** 00003 * 00004 * simulavr - A simulator for the Atmel AVR family of microcontrollers. 00005 * Copyright (C) 2001, 2002, 2003 Klaus Rudolph 00006 * 00007 * This program is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 2 of the License, or 00010 * (at your option) any later version. 00011 * 00012 * This program is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with this program; if not, write to the Free Software 00019 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00020 * 00021 **************************************************************************** 00022 * 00023 * $Id$ 00024 */ 00025 00026 #include <time.h> 00027 #include "externaltype.h" 00028 #include "ui.h" 00029 #include "hardware.h" 00030 #include "pin.h" 00031 #include "systemclock.h" 00032 #include "avrerror.h" 00033 #include <sstream> 00034 00035 using namespace std; 00036 00037 UserInterface::UserInterface(int port, bool _withUpdateControl): Socket(port), updateOn(1), pollFreq(100000) { 00038 if (_withUpdateControl) { 00039 waitOnAckFromTclRequest=0; 00040 waitOnAckFromTclDone=0; 00041 ostringstream os; 00042 os << "create UpdateControl dummy dummy " << endl; 00043 Write(os.str()); 00044 AddExternalType("UpdateControl", this); 00045 } 00046 } 00047 00048 UserInterface::~UserInterface() { 00049 } 00050 00051 void UserInterface::SwitchUpdateOnOff(bool yesNo) { 00052 updateOn=yesNo; 00053 } 00054 00055 00056 int UserInterface::Step(bool &dummy1, SystemClockOffset *nextStepIn_ns) { 00057 if (nextStepIn_ns!=0) { 00058 *nextStepIn_ns=pollFreq; 00059 } 00060 00061 static time_t oldTime=0; 00062 time_t newTime=time(NULL); 00063 00064 if (updateOn || (newTime!=oldTime)) { 00065 oldTime=newTime; 00066 00067 do { 00068 if (Poll()!=0) { 00069 ssize_t len = 0; 00070 len=Read(dummy); 00071 00072 //string debug=dummy; 00073 00074 while (len>0) { 00075 00076 string::size_type pos; 00077 00078 pos=dummy.find(" "); 00079 00080 string net=dummy.substr(0, pos); 00081 string rest=dummy.substr(pos+1); //vfrom pos+1 to end 00082 00083 if (net == "exit" ) 00084 avr_error("Exiting at external UI request"); 00085 00086 string par; 00087 int pos2=rest.find(" "); 00088 00089 if (pos2<=0) break; 00090 00091 par= rest.substr(0, pos2); 00092 dummy=rest.substr(pos2+1); 00093 00094 // cerr << "UI: net=" << net << "- rest=" << rest << endl; 00095 if (net == "__ack" ) { 00096 waitOnAckFromTclDone++; 00097 } else { 00098 map<string, ExternalType*>::iterator ii; 00099 ii=extMembers.find(net); 00100 if (ii != extMembers.end() ) { 00101 (ii->second)->SetNewValueFromUi(par); 00102 } else { 00103 // cerr << "Netz nicht gefunden:" << net << endl; 00104 // cerr << "Start with string >>" << net << "<<" << endl; 00105 } 00106 00107 //if (trace_on!=0) traceOut << "Net: " << net << "changed to " << par << endl; 00108 00109 } //__ack 00110 00111 len=dummy.size(); //recalc size from rest of string 00112 00113 } // len > 0 00114 } //poll 00115 }while (waitOnAckFromTclRequest > waitOnAckFromTclDone+500); 00116 00117 00118 if (waitOnAckFromTclRequest!=waitOnAckFromTclDone) { 00119 waitOnAckFromTclRequest=waitOnAckFromTclDone=0; 00120 } 00121 00122 } //if (update_on | look for reenable again) 00123 00124 return 0; 00125 } 00126 00127 00128 00129 void UserInterface::SendUiNewState(const string &s, const char &c) { 00130 ostringstream os; 00131 //static map<string, char> LastState; 00132 00133 if (LastState[s]==c) { 00134 return; 00135 } 00136 LastState[s]=c; 00137 00138 os << "set " << s << " " << c << endl; 00139 Write(os.str()); 00140 00141 // SystemClock::Instance().Rescedule(this, 1000); //read ack back as fast as possible 00142 } 00143 00144 void UserInterface::SetNewValueFromUi(const string &value){ 00145 if (value=="0") { 00146 updateOn=false; 00147 } else { 00148 updateOn=true; 00149 } 00150 00151 } 00152 00153 void UserInterface::Write(const string &s) { 00154 if (updateOn) { 00155 00156 for (unsigned int tt = 0; tt< s.length() ; tt++) { 00157 if (s[tt]=='\n') { 00158 waitOnAckFromTclRequest++; 00159 } 00160 } 00161 Socket::Write(s); 00162 } 00163 } 00164