Watchdoggo
This commit is contained in:
parent
601324b2a4
commit
191c10327f
1732
PIC_Simulator/Form1.Designer.cs
generated
1732
PIC_Simulator/Form1.Designer.cs
generated
File diff suppressed because it is too large
Load Diff
@ -528,6 +528,16 @@ namespace PIC_Simulator
|
|||||||
{
|
{
|
||||||
programm.IsSleeping = false; //Kein WatchdogTimer implementiert, Sleep durch button deaktiviert
|
programm.IsSleeping = false; //Kein WatchdogTimer implementiert, Sleep durch button deaktiviert
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void button1_Click_1(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
programm.WatchDog.Aktiviert = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void button2_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
programm.WatchDog.Aktiviert = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,23 +127,17 @@ namespace PIC_Simulator.PIC
|
|||||||
public uint TaktgeberAdresse = 0;
|
public uint TaktgeberAdresse = 0;
|
||||||
public uint TaktgeberBitnummer = 0;
|
public uint TaktgeberBitnummer = 0;
|
||||||
|
|
||||||
|
public PICTimer Zaehler;
|
||||||
|
public PICWatchDog WatchDog;
|
||||||
|
|
||||||
public PICProgramm()
|
public PICProgramm()
|
||||||
{
|
{
|
||||||
|
Zaehler = new PICTimer(this);
|
||||||
|
WatchDog = new PICWatchDog(this);
|
||||||
|
|
||||||
// Anfangswerte
|
// Anfangswerte
|
||||||
|
|
||||||
SetRegisterOhneBank(ADDR_PCL, 0x00);
|
Reset();
|
||||||
SetRegisterOhneBank(ADDR_STATUS, 0x18);
|
|
||||||
SetRegisterOhneBank(ADDR_PCLATH, 0x00);
|
|
||||||
SetRegisterOhneBank(ADDR_INTCON, 0x00);
|
|
||||||
|
|
||||||
SetRegisterOhneBank(ADDR_OPTION, 0xFF);
|
|
||||||
SetRegisterOhneBank(ADDR_TRIS_A, 0x1F);
|
|
||||||
SetRegisterOhneBank(ADDR_TRIS_B, 0xFF);
|
|
||||||
|
|
||||||
SetRegisterOhneBank(ADDR_EECON1, 0x00);
|
|
||||||
SetRegisterOhneBank(ADDR_EECON2, 0x00);
|
|
||||||
|
|
||||||
PCCounter = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Laden(string code)
|
public void Laden(string code)
|
||||||
@ -237,7 +231,7 @@ namespace PIC_Simulator.PIC
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsSleeping) return false;
|
if (IsSleeping) { WatchDog.Aktualisieren(1, frequenz); return false;}
|
||||||
|
|
||||||
uint cycleCount = 1;
|
uint cycleCount = 1;
|
||||||
|
|
||||||
@ -664,7 +658,17 @@ namespace PIC_Simulator.PIC
|
|||||||
// of the WDT. Status bits TO and PD are
|
// of the WDT. Status bits TO and PD are
|
||||||
// set.
|
// set.
|
||||||
|
|
||||||
//TODO
|
WatchDog.Reset();
|
||||||
|
|
||||||
|
if (GetRegisterOhneBank(ADDR_OPTION, OPTION_BIT_PSA))
|
||||||
|
{
|
||||||
|
SetRegisterOhneBank(ADDR_OPTION, OPTION_BIT_PS0, false);
|
||||||
|
SetRegisterOhneBank(ADDR_OPTION, OPTION_BIT_PS1, false);
|
||||||
|
SetRegisterOhneBank(ADDR_OPTION, OPTION_BIT_PS2, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
SetRegisterOhneBank(ADDR_STATUS, STATUS_BIT_TO, true);
|
||||||
|
SetRegisterOhneBank(ADDR_STATUS, STATUS_BIT_PD, true);
|
||||||
}
|
}
|
||||||
else if (aktueller_befehl.befehl == GOTO)
|
else if (aktueller_befehl.befehl == GOTO)
|
||||||
{
|
{
|
||||||
@ -795,103 +799,13 @@ namespace PIC_Simulator.PIC
|
|||||||
PCCounter++;
|
PCCounter++;
|
||||||
Stepcount++;
|
Stepcount++;
|
||||||
|
|
||||||
TimerBerechnen(cycleCount);
|
Zaehler.TimerBerechnen(cycleCount);
|
||||||
|
|
||||||
|
WatchDog.Aktualisieren(cycleCount, frequenz);
|
||||||
|
|
||||||
return PCCounter >= befehle.Count;
|
return PCCounter >= befehle.Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool prev_RA4 = false;
|
|
||||||
private void TimerBerechnen(uint cycles)
|
|
||||||
{
|
|
||||||
bool tmr_mode = GetRegisterOhneBank(ADDR_OPTION, OPTION_BIT_T0CS);
|
|
||||||
bool edge_mode = GetRegisterOhneBank(ADDR_OPTION, OPTION_BIT_T0SE);
|
|
||||||
|
|
||||||
if (!tmr_mode)
|
|
||||||
{
|
|
||||||
bool curr_A4 = GetRegisterOhneBank(ADDR_PORT_A, 4);
|
|
||||||
|
|
||||||
if (edge_mode)
|
|
||||||
{
|
|
||||||
if (prev_RA4 && !curr_A4)
|
|
||||||
{
|
|
||||||
TimerHochzaehlen(cycles);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!prev_RA4 && curr_A4)
|
|
||||||
{
|
|
||||||
TimerHochzaehlen(cycles);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
TimerHochzaehlen(cycles);
|
|
||||||
}
|
|
||||||
|
|
||||||
prev_RA4 = GetRegisterOhneBank(ADDR_PORT_A, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
private uint prescale_cntr = 0; // Zähler für timer
|
|
||||||
|
|
||||||
private void TimerHochzaehlen(uint cycles)
|
|
||||||
{
|
|
||||||
uint current = GetRegisterOhneBank(ADDR_TMR0);
|
|
||||||
uint scale = BerechneVorskalierung();
|
|
||||||
|
|
||||||
prescale_cntr += cycles;
|
|
||||||
|
|
||||||
while (prescale_cntr >= scale)
|
|
||||||
{
|
|
||||||
prescale_cntr -= scale;
|
|
||||||
|
|
||||||
uint Result = current + 1;
|
|
||||||
if (Result > 0xFF)
|
|
||||||
{
|
|
||||||
//TODO Interrupt PIT_TIMER
|
|
||||||
}
|
|
||||||
|
|
||||||
Result %= 0x100;
|
|
||||||
|
|
||||||
uint tmp_psc = prescale_cntr;
|
|
||||||
SetRegisterOhneBank(ADDR_TMR0, Result);
|
|
||||||
prescale_cntr = tmp_psc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private uint BerechneVorskalierung()
|
|
||||||
{
|
|
||||||
bool prescale_mode = GetRegisterOhneBank(ADDR_OPTION, OPTION_BIT_PSA);
|
|
||||||
|
|
||||||
uint scale = 0;
|
|
||||||
scale += GetRegisterOhneBank(ADDR_OPTION, OPTION_BIT_PS2) ? 1U : 0U;
|
|
||||||
scale *= 2;
|
|
||||||
scale += GetRegisterOhneBank(ADDR_OPTION, OPTION_BIT_PS1) ? 1U : 0U;
|
|
||||||
scale *= 2;
|
|
||||||
scale += GetRegisterOhneBank(ADDR_OPTION, OPTION_BIT_PS0) ? 1U : 0U;
|
|
||||||
|
|
||||||
return prescale_mode ? 1 : (SHL(2, scale));
|
|
||||||
}
|
|
||||||
|
|
||||||
private uint UIntPower(uint x, uint power)
|
|
||||||
{
|
|
||||||
if (power == 0)
|
|
||||||
return 1;
|
|
||||||
if (power == 1)
|
|
||||||
return x;
|
|
||||||
// ----------------------
|
|
||||||
int n = 15;
|
|
||||||
while ((power <<= 1) >= 0)
|
|
||||||
n--;
|
|
||||||
|
|
||||||
uint tmp = x;
|
|
||||||
while (--n > 0)
|
|
||||||
tmp = tmp * tmp *
|
|
||||||
(((power <<= 1) < 0) ? x : 1);
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetRegisterOhneBank(uint index, uint wert)
|
public void SetRegisterOhneBank(uint index, uint wert)
|
||||||
{
|
{
|
||||||
// register die nur einmal auf bank1 + 2 existieren
|
// register die nur einmal auf bank1 + 2 existieren
|
||||||
@ -1043,5 +957,29 @@ namespace PIC_Simulator.PIC
|
|||||||
return (byte)(bit ? (val | SHL(1, pos)) : (val & ~SHL(1, pos)));
|
return (byte)(bit ? (val | SHL(1, pos)) : (val & ~SHL(1, pos)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Reset()
|
||||||
|
{
|
||||||
|
Register = new byte[0x100];
|
||||||
|
|
||||||
|
Latch_RA = 0;
|
||||||
|
Latch_RB = 0;
|
||||||
|
|
||||||
|
Register_W = 0;
|
||||||
|
Stack.Clear();
|
||||||
|
|
||||||
|
SetRegisterOhneBank(ADDR_PCL, 0x00);
|
||||||
|
SetRegisterOhneBank(ADDR_STATUS, 0x18);
|
||||||
|
SetRegisterOhneBank(ADDR_PCLATH, 0x00);
|
||||||
|
SetRegisterOhneBank(ADDR_INTCON, 0x00);
|
||||||
|
|
||||||
|
SetRegisterOhneBank(ADDR_OPTION, 0xFF);
|
||||||
|
SetRegisterOhneBank(ADDR_TRIS_A, 0x1F);
|
||||||
|
SetRegisterOhneBank(ADDR_TRIS_B, 0xFF);
|
||||||
|
|
||||||
|
SetRegisterOhneBank(ADDR_EECON1, 0x00);
|
||||||
|
SetRegisterOhneBank(ADDR_EECON2, 0x00);
|
||||||
|
|
||||||
|
PCCounter = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
87
PIC_Simulator/PIC/PICTimer.cs
Normal file
87
PIC_Simulator/PIC/PICTimer.cs
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
|
||||||
|
namespace PIC_Simulator.PIC
|
||||||
|
{
|
||||||
|
class PICTimer
|
||||||
|
{
|
||||||
|
private PICProgramm programm;
|
||||||
|
|
||||||
|
public PICTimer(PICProgramm p)
|
||||||
|
{
|
||||||
|
programm = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool prev_RA4 = false;
|
||||||
|
public void TimerBerechnen(uint cycles)
|
||||||
|
{
|
||||||
|
bool tmr_mode = programm.GetRegisterOhneBank(PICProgramm.ADDR_OPTION, PICProgramm.OPTION_BIT_T0CS);
|
||||||
|
bool edge_mode = programm.GetRegisterOhneBank(PICProgramm.ADDR_OPTION, PICProgramm.OPTION_BIT_T0SE);
|
||||||
|
|
||||||
|
if (!tmr_mode)
|
||||||
|
{
|
||||||
|
bool curr_A4 = programm.GetRegisterOhneBank(PICProgramm.ADDR_PORT_A, 4);
|
||||||
|
|
||||||
|
if (edge_mode)
|
||||||
|
{
|
||||||
|
if (prev_RA4 && !curr_A4)
|
||||||
|
{
|
||||||
|
TimerHochzaehlen(cycles);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!prev_RA4 && curr_A4)
|
||||||
|
{
|
||||||
|
TimerHochzaehlen(cycles);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TimerHochzaehlen(cycles);
|
||||||
|
}
|
||||||
|
|
||||||
|
prev_RA4 = programm.GetRegisterOhneBank(PICProgramm.ADDR_PORT_A, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
private uint prescale_cntr = 0; // Zähler für timer
|
||||||
|
|
||||||
|
private void TimerHochzaehlen(uint cycles)
|
||||||
|
{
|
||||||
|
uint current = programm.GetRegisterOhneBank(PICProgramm.ADDR_TMR0);
|
||||||
|
uint scale = BerechneVorskalierung();
|
||||||
|
|
||||||
|
prescale_cntr += cycles;
|
||||||
|
|
||||||
|
while (prescale_cntr >= scale)
|
||||||
|
{
|
||||||
|
prescale_cntr -= scale;
|
||||||
|
|
||||||
|
uint Result = current + 1;
|
||||||
|
if (Result > 0xFF)
|
||||||
|
{
|
||||||
|
//TODO Interrupt PIT_TIMER
|
||||||
|
}
|
||||||
|
|
||||||
|
Result %= 0x100;
|
||||||
|
|
||||||
|
uint tmp_psc = prescale_cntr;
|
||||||
|
programm.SetRegisterOhneBank(PICProgramm.ADDR_TMR0, Result);
|
||||||
|
prescale_cntr = tmp_psc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private uint BerechneVorskalierung()
|
||||||
|
{
|
||||||
|
bool prescale_mode = programm.GetRegisterOhneBank(PICProgramm.ADDR_OPTION, PICProgramm.OPTION_BIT_PSA);
|
||||||
|
|
||||||
|
uint scale = 0;
|
||||||
|
scale += programm.GetRegisterOhneBank(PICProgramm.ADDR_OPTION, PICProgramm.OPTION_BIT_PS2) ? 1U : 0U;
|
||||||
|
scale *= 2;
|
||||||
|
scale += programm.GetRegisterOhneBank(PICProgramm.ADDR_OPTION, PICProgramm.OPTION_BIT_PS1) ? 1U : 0U;
|
||||||
|
scale *= 2;
|
||||||
|
scale += programm.GetRegisterOhneBank(PICProgramm.ADDR_OPTION, PICProgramm.OPTION_BIT_PS0) ? 1U : 0U;
|
||||||
|
|
||||||
|
return prescale_mode ? 1 : (PICProgramm.SHL(2, scale));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
86
PIC_Simulator/PIC/PICWatchDog.cs
Normal file
86
PIC_Simulator/PIC/PICWatchDog.cs
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
|
||||||
|
namespace PIC_Simulator.PIC
|
||||||
|
{
|
||||||
|
class PICWatchDog
|
||||||
|
{
|
||||||
|
private PICProgramm programm;
|
||||||
|
|
||||||
|
private const double TIME_OUT = 0.018; // 18ms;
|
||||||
|
|
||||||
|
public uint Prescale = 1;
|
||||||
|
|
||||||
|
private double time; // in s
|
||||||
|
|
||||||
|
public bool Aktiviert = false;
|
||||||
|
|
||||||
|
public PICWatchDog(PICProgramm p)
|
||||||
|
{
|
||||||
|
programm = p;
|
||||||
|
time = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Aktualisieren(uint cycles, float frequenz)
|
||||||
|
{
|
||||||
|
if (Aktiviert)
|
||||||
|
{
|
||||||
|
time += (1.0 / frequenz) * cycles;
|
||||||
|
|
||||||
|
if (time > TIME_OUT * GetPreScale())
|
||||||
|
{
|
||||||
|
WDReset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
time = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void WDReset()
|
||||||
|
{
|
||||||
|
if (!programm.IsSleeping)
|
||||||
|
{
|
||||||
|
// >> WATCHDOG RESET <<
|
||||||
|
|
||||||
|
time = 0;
|
||||||
|
|
||||||
|
programm.Reset();
|
||||||
|
programm.SetRegisterOhneBank(PICProgramm.ADDR_STATUS, PICProgramm.STATUS_BIT_TO, false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// >> Wake Up <<
|
||||||
|
|
||||||
|
time = 0;
|
||||||
|
|
||||||
|
programm.IsSleeping = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private uint GetPreScale()
|
||||||
|
{
|
||||||
|
bool prescale_mode = !programm.GetRegisterOhneBank(PICProgramm.ADDR_OPTION, PICProgramm.OPTION_BIT_PSA);
|
||||||
|
|
||||||
|
uint scale = 0;
|
||||||
|
scale += programm.GetRegisterOhneBank(PICProgramm.ADDR_OPTION, PICProgramm.OPTION_BIT_PS2) ? 1U : 0U;
|
||||||
|
scale *= 2;
|
||||||
|
scale += programm.GetRegisterOhneBank(PICProgramm.ADDR_OPTION, PICProgramm.OPTION_BIT_PS1) ? 1U : 0U;
|
||||||
|
scale *= 2;
|
||||||
|
scale += programm.GetRegisterOhneBank(PICProgramm.ADDR_OPTION, PICProgramm.OPTION_BIT_PS0) ? 1U : 0U;
|
||||||
|
|
||||||
|
Prescale = prescale_mode ? 1 : (PICProgramm.SHL(1, scale));
|
||||||
|
|
||||||
|
return Prescale;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Reset()
|
||||||
|
{
|
||||||
|
time = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double GetPerc()
|
||||||
|
{
|
||||||
|
return time / (TIME_OUT * Prescale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -52,6 +52,8 @@
|
|||||||
<DependentUpon>Form1.cs</DependentUpon>
|
<DependentUpon>Form1.cs</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="PIC\PICProgramm.cs" />
|
<Compile Include="PIC\PICProgramm.cs" />
|
||||||
|
<Compile Include="PIC\PICTimer.cs" />
|
||||||
|
<Compile Include="PIC\PICWatchDog.cs" />
|
||||||
<Compile Include="PIC\RS232Verbindung.cs" />
|
<Compile Include="PIC\RS232Verbindung.cs" />
|
||||||
<Compile Include="Program.cs" />
|
<Compile Include="Program.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
Loading…
Reference in New Issue
Block a user