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 "hweeprom.h"
00027 #include "global.h"
00028 #include "avrdevice.h"
00029 #include "systemclock.h"
00030 #include "irqsystem.h"
00031 #include "avrerror.h"
00032 #include <assert.h>
00033
00034 using namespace std;
00035
00036 HWEeprom::HWEeprom(AvrDevice *_core,
00037 HWIrqSystem *_irqSystem,
00038 unsigned int size,
00039 unsigned int irqVec,
00040 int devMode):
00041 Hardware(_core),
00042 Memory(size),
00043 TraceValueRegister(_core, "EEPROM"),
00044 core(_core),
00045 irqSystem(_irqSystem),
00046 irqVectorNo(irqVec),
00047 eearh_reg(this, "EEARH",
00048 this, &HWEeprom::GetEearh, &HWEeprom::SetEearh),
00049 eearl_reg(this, "EEARL",
00050 this, &HWEeprom::GetEearl, &HWEeprom::SetEearl),
00051 eedr_reg(this, "EEDR",
00052 this, &HWEeprom::GetEedr, &HWEeprom::SetEedr),
00053 eecr_reg(this, "EECR",
00054 this, &HWEeprom::GetEecr, &HWEeprom::SetEecr)
00055 {
00056 if(irqSystem)
00057 irqSystem->DebugVerifyInterruptVector(irqVectorNo, this);
00058
00059
00060 for(unsigned int tt = 0; tt < size; tt++)
00061 myMemory[tt] = 0xff;
00062
00063
00064 if(devMode == DEVMODE_NORMAL) {
00065 eraseWriteDelayTime = 8500000LL;
00066 eraseDelayTime = 0LL;
00067 writeDelayTime = 0LL;
00068 } else {
00069 eraseWriteDelayTime = 3400000LL;
00070 eraseDelayTime = 1800000LL;
00071 writeDelayTime = 1800000LL;
00072 }
00073
00074
00075 if(devMode == DEVMODE_NORMAL)
00076 eecr_mask = 0x0f;
00077 else
00078 eecr_mask = 0x3f;
00079 eecr = 0;
00080
00081 eear_mask = (size - 1);
00082
00083
00084 eear = 0;
00085
00086 opState = OPSTATE_READY;
00087
00088 Reset();
00089 }
00090
00091 void HWEeprom::Reset() {
00092 eecr &= 0x32;
00093
00094 eedr = 0;
00095
00096 opEnableCycles = 0;
00097 cpuHoldCycles = 0;
00098 }
00099
00100
00101 HWEeprom::~HWEeprom() {
00102 avr_free(myMemory);
00103 myMemory = NULL;
00104 }
00105
00106 void HWEeprom::SetEearl(unsigned char val) {
00107 eear = ((eear & 0xff00) + val) & eear_mask;
00108 if(core->trace_on == 1)
00109 traceOut << "EEAR=0x" << hex << eear << dec;
00110 }
00111
00112 void HWEeprom::SetEearh(unsigned char val) {
00113 eear = ((eear & 0x00ff) + (val << 8)) & eear_mask;
00114 if(core->trace_on == 1)
00115 traceOut << "EEAR=0x" << hex << eear << dec;
00116 }
00117
00118 void HWEeprom::SetEedr(unsigned char val) {
00119 eedr = val;
00120 if(core->trace_on == 1)
00121 traceOut << "EEDR=0x"<< hex << (unsigned int)eedr << dec;
00122 }
00123
00124 void HWEeprom::SetEecr(unsigned char newval) {
00125 if(core->trace_on == 1)
00126 traceOut << "EECR=0x" << hex << (unsigned int)newval << dec;
00127
00128 eecr = newval & eecr_mask;
00129
00130 switch(opState) {
00131
00132 default:
00133 case OPSTATE_READY:
00134
00135 if((eecr & CTRL_ENABLE) == CTRL_ENABLE) {
00136 opState = OPSTATE_ENABLED;
00137 opEnableCycles = 4;
00138 core->AddToCycleList(this);
00139 }
00140
00141 if((eecr & CTRL_READ) == CTRL_READ) {
00142 cpuHoldCycles = 4;
00143 assert(eear < size);
00144 eedr = myMemory[eear];
00145 eecr &= ~CTRL_READ;
00146 core->AddToCycleList(this);
00147 if(core->trace_on == 1)
00148 traceOut << " EEPROM: Read = 0x" << hex << (unsigned int)eedr << dec;
00149 }
00150
00151 eecr &= ~CTRL_WRITE;
00152 break;
00153
00154 case OPSTATE_ENABLED:
00155
00156 eecr |= CTRL_ENABLE;
00157
00158 if((eecr & CTRL_READ) == CTRL_READ) {
00159 cpuHoldCycles = 4;
00160 assert(eear < size);
00161 eedr = myMemory[eear];
00162 eecr &= ~CTRL_READ;
00163 if(core->trace_on == 1)
00164 traceOut << " EEPROM: Read = 0x" << hex << (unsigned int)eedr << dec;
00165 break;
00166 }
00167
00168 if((eecr & CTRL_WRITE) == CTRL_WRITE) {
00169 cpuHoldCycles = 2;
00170
00171 opMode = eecr & CTRL_MODES;
00172 opAddr = eear;
00173 assert(opAddr < size);
00174 opState = OPSTATE_WRITE;
00175 opEnableCycles = 0;
00176 eecr &= ~CTRL_ENABLE;
00177
00178 SystemClockOffset t;
00179 switch(opMode & CTRL_MODES) {
00180 default:
00181 case CTRL_MODE_ERASEWRITE:
00182 t = eraseWriteDelayTime;
00183 break;
00184 case CTRL_MODE_ERASE:
00185 t = eraseDelayTime;
00186 break;
00187 case CTRL_MODE_WRITE:
00188 t = writeDelayTime;
00189 break;
00190 }
00191 writeDoneTime = SystemClock::Instance().GetCurrentTime() + t;
00192 if(core->trace_on == 1)
00193 traceOut << " EEPROM: Write start";
00194 }
00195 break;
00196
00197 case OPSTATE_WRITE:
00198
00199 if((eecr & CTRL_ENABLE) == CTRL_ENABLE) {
00200 opEnableCycles = 4;
00201 }
00202
00203 eecr &= ~CTRL_READ;
00204
00205 eecr |= CTRL_WRITE;
00206 break;
00207
00208 }
00209 }
00210
00211 unsigned int HWEeprom::CpuCycle() {
00212
00213
00214 if(opEnableCycles > 0) {
00215 opEnableCycles--;
00216 if(opEnableCycles == 0) {
00217 eecr &= ~CTRL_ENABLE;
00218 if(opState == OPSTATE_ENABLED)
00219 opState = OPSTATE_READY;
00220 if(core->trace_on == 1)
00221 traceOut << " EEPROM: WriteEnable cleared";
00222 }
00223 }
00224
00225
00226 if(opState == OPSTATE_WRITE) {
00227 if(SystemClock::Instance().GetCurrentTime() >= writeDoneTime) {
00228
00229 opState = OPSTATE_READY;
00230
00231 eecr &= ~CTRL_WRITE;
00232 assert(opAddr < size);
00233
00234 switch(opMode & CTRL_MODES) {
00235 default:
00236 case CTRL_MODE_ERASEWRITE:
00237 myMemory[opAddr] = eedr;
00238 break;
00239 case CTRL_MODE_ERASE:
00240 myMemory[opAddr] = 0xff;
00241 break;
00242 case CTRL_MODE_WRITE:
00243 myMemory[opAddr] = eedr & myMemory[opAddr];
00244 break;
00245 }
00246 if(core->trace_on == 1)
00247 traceOut << " EEPROM: Write done";
00248
00249 if((irqSystem != NULL) && ((eecr & CTRL_IRQ) == CTRL_IRQ))
00250 irqSystem->SetIrqFlag(this, irqVectorNo);
00251 }
00252 }
00253
00254
00255 if((opState == OPSTATE_READY) && (cpuHoldCycles == 0) && (opEnableCycles == 0))
00256 core->RemoveFromCycleList(this);
00257
00258
00259 if(cpuHoldCycles > 0) {
00260 cpuHoldCycles--;
00261 return 1;
00262 } else
00263 return 0;
00264
00265 }
00266
00267 void HWEeprom::ClearIrqFlag(unsigned int vector) {
00268 if(vector == irqVectorNo)
00269 irqSystem->ClearIrqFlag(irqVectorNo);
00270 }
00271
00272 void HWEeprom::WriteAtAddress(unsigned int addr, unsigned char val) {
00273 myMemory[addr] = val;
00274 }
00275
00276 unsigned char HWEeprom::ReadFromAddress( unsigned int addr) {
00277 return myMemory[addr];
00278 }
00279
00280 void HWEeprom::WriteMem( unsigned char *src, unsigned int offset, unsigned int secSize) {
00281 for(unsigned int tt = 0; tt < secSize; tt++) {
00282 if(tt + offset < size) {
00283 *(myMemory + tt + offset) = src[tt];
00284 }
00285 }
00286 }
00287