00001 /* 00002 **************************************************************************** 00003 * 00004 * simulavr - A simulator for the Atmel AVR family of microcontrollers. 00005 * Copyright (C) 2001, 2002, 2003, 2004 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 "serialrx.h" 00027 #include "systemclock.h" 00028 #include "systemclocktypes.h" 00029 00030 using namespace std; 00031 00032 SerialRxBasic::SerialRxBasic(){ 00033 rx.RegisterCallback(this); 00034 allPins["rx"]= ℞ 00035 sendInHex = false; 00036 Reset(); 00037 } 00038 00039 void SerialRxBasic::PinStateHasChanged(Pin* p){ 00040 if (!*p) { //Low 00041 if (rxState== RX_WAIT_LOWEDGE) { 00042 rxState=RX_READ_STARTBIT; 00043 SystemClock::Instance().Add(this); //as next Step() is called 00044 } 00045 } 00046 } 00047 00048 void SerialRxBasic::Reset(){ 00049 baudrate=115200; 00050 maxBitCnt=10; //Start+8Data+Stop 00051 rxState=RX_WAIT_LOWEDGE; 00052 } 00053 00054 Pin* SerialRxBasic::GetPin(const char* name){ 00055 return allPins[name]; 00056 } 00057 00058 int SerialRxBasic::Step(bool &trueHwStep, SystemClockOffset *timeToNextStepIn_ns){ 00059 switch (rxState) { 00060 case RX_READ_STARTBIT: //wait until first edge of databit 00061 *timeToNextStepIn_ns= (SystemClockOffset)1e9/baudrate/16*7; 00062 rxState=RX_READ_DATABIT_FIRST; 00063 dataByte=0; 00064 bitCnt=0; 00065 break; 00066 00067 case RX_READ_DATABIT_FIRST: //(1/7) 00068 *timeToNextStepIn_ns= (SystemClockOffset)1e9/baudrate/16; 00069 rxState= RX_READ_DATABIT_SECOND; 00070 if (rx) { 00071 highCnt++; 00072 } 00073 break; 00074 00075 case RX_READ_DATABIT_SECOND: //(1/8) 00076 *timeToNextStepIn_ns= (SystemClockOffset)1e9/baudrate/16; 00077 rxState= RX_READ_DATABIT_THIRD; 00078 if (rx) { 00079 highCnt++; 00080 } 00081 00082 break; 00083 00084 case RX_READ_DATABIT_THIRD: //(1/9) 00085 rxState= RX_READ_DATABIT_FIRST; 00086 if (rx) { 00087 highCnt++; 00088 } 00089 00090 if (highCnt>1) { 00091 dataByte|=0x8000; //highest bit is here set to bit 31 00092 } 00093 00094 highCnt=0; 00095 00096 dataByte=dataByte>>1; 00097 bitCnt++; 00098 if (bitCnt>=maxBitCnt) { 00099 // this bit IS STOP BIT... 00100 *timeToNextStepIn_ns= -1; //nothing more please 00101 rxState= RX_WAIT_LOWEDGE; 00102 00104 unsigned char c=(unsigned char)((dataByte>>(16-maxBitCnt))&0xff); 00105 CharReceived(c); 00106 } else { 00107 *timeToNextStepIn_ns= (SystemClockOffset)1e9/baudrate/16*(7+7); //read middle of next bit 00108 rxState=RX_READ_DATABIT_FIRST; 00109 } 00110 00111 break; 00112 00113 default: 00114 break; 00115 } 00116 00117 return 0; 00118 } 00119 00120 void SerialRxBasic::SetBaudRate(SystemClockOffset baud){ 00121 baudrate = baud; 00122 } 00123 00124 void SerialRxBasic::SetHexOutput(bool newValue){ 00125 sendInHex = newValue; 00126 } 00127 00128 00129 // =========================================================================== 00130 // =========================================================================== 00131 // =========================================================================== 00132 00133 void SerialRxBuffered::CharReceived(unsigned char c){ 00134 buffer.push_back(c); 00135 } 00136 00137 unsigned char SerialRxBuffered::Get(){ 00138 unsigned char c = buffer[0]; 00139 buffer.erase(buffer.begin()); 00140 return c; 00141 } 00142 00143 long SerialRxBuffered::Size(){ 00144 return buffer.size(); 00145 } 00146 00147 00148 // =========================================================================== 00149 // =========================================================================== 00150 // =========================================================================== 00151 00152 00153 SerialRx::SerialRx(UserInterface *_ui, const char *_name, const char *baseWindow): 00154 ui(_ui), name(_name) { 00155 rx.RegisterCallback(this); 00156 00157 ostringstream os; 00158 os << "create SerialRx " << name << " " << baseWindow << endl; 00159 ui->Write(os.str()); 00160 ui->AddExternalType(name, this); 00161 Reset(); 00162 00163 /* 00164 ui->SendUiNewState(name, 't'); 00165 ui->SendUiNewState(name, 'e'); 00166 ui->SendUiNewState(name, 's'); 00167 ui->SendUiNewState(name, 't'); 00168 */ 00169 } 00170 00171 void SerialRx::CharReceived(unsigned char c){ 00172 ostringstream os; 00173 00174 os << "set" << " " << name << " "; 00175 if (sendInHex) { 00176 os << hex << "0x" << (unsigned int)c; 00177 } else if (isprint(c)) { 00178 if (isspace(c)) { 00179 os << '_'; 00180 } else { 00181 os << c; 00182 } 00183 } else { 00184 os << "0x" << (unsigned int)c; 00185 } 00186 00187 os << endl; 00188 ui->Write(os.str()); 00189 } 00190 00191 00192 //not used 00193 void SerialRx::SetNewValueFromUi(const string &){ 00194 }