Watchdoggo

This commit is contained in:
Mike Schwörer 2017-05-16 10:01:08 +02:00
parent 601324b2a4
commit 191c10327f
6 changed files with 1110 additions and 961 deletions

View File

@ -110,6 +110,8 @@
this.btnClockStart = new System.Windows.Forms.Button();
this.edCLockFreq = new System.Windows.Forms.TextBox();
this.WakeUpButton = new System.Windows.Forms.Button();
this.button1 = new System.Windows.Forms.Button();
this.button2 = new System.Windows.Forms.Button();
this.menuStrip1.SuspendLayout();
this.SuspendLayout();
//
@ -833,11 +835,33 @@
this.WakeUpButton.UseVisualStyleBackColor = true;
this.WakeUpButton.Click += new System.EventHandler(this.button1_Click);
//
// button1
//
this.button1.Location = new System.Drawing.Point(341, 18);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(126, 23);
this.button1.TabIndex = 64;
this.button1.Text = "Watchdog An";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click_1);
//
// button2
//
this.button2.Location = new System.Drawing.Point(341, 48);
this.button2.Name = "button2";
this.button2.Size = new System.Drawing.Size(126, 23);
this.button2.TabIndex = 65;
this.button2.Text = "Watchdog Aus";
this.button2.UseVisualStyleBackColor = true;
this.button2.Click += new System.EventHandler(this.button2_Click);
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(1298, 692);
this.Controls.Add(this.button2);
this.Controls.Add(this.button1);
this.Controls.Add(this.WakeUpButton);
this.Controls.Add(this.edCLockFreq);
this.Controls.Add(this.btnClockStart);
@ -991,6 +1015,8 @@
private System.Windows.Forms.Button btnClockStart;
private System.Windows.Forms.TextBox edCLockFreq;
private System.Windows.Forms.Button WakeUpButton;
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Button button2;
}
}

View File

@ -528,6 +528,16 @@ namespace PIC_Simulator
{
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;
}
}
}

View File

@ -127,23 +127,17 @@ namespace PIC_Simulator.PIC
public uint TaktgeberAdresse = 0;
public uint TaktgeberBitnummer = 0;
public PICTimer Zaehler;
public PICWatchDog WatchDog;
public PICProgramm()
{
Zaehler = new PICTimer(this);
WatchDog = new PICWatchDog(this);
// Anfangswerte
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;
Reset();
}
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;
@ -664,7 +658,17 @@ namespace PIC_Simulator.PIC
// of the WDT. Status bits TO and PD are
// 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)
{
@ -795,103 +799,13 @@ namespace PIC_Simulator.PIC
PCCounter++;
Stepcount++;
TimerBerechnen(cycleCount);
Zaehler.TimerBerechnen(cycleCount);
WatchDog.Aktualisieren(cycleCount, frequenz);
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)
{
// 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)));
}
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;
}
}
}

View 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));
}
}
}

View 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);
}
}
}

View File

@ -52,6 +52,8 @@
<DependentUpon>Form1.cs</DependentUpon>
</Compile>
<Compile Include="PIC\PICProgramm.cs" />
<Compile Include="PIC\PICTimer.cs" />
<Compile Include="PIC\PICWatchDog.cs" />
<Compile Include="PIC\RS232Verbindung.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />