diff --git a/se/sics/mspsim/core/EventQueue.java b/se/sics/mspsim/core/EventQueue.java index 21bec18..70782ce 100644 --- a/se/sics/mspsim/core/EventQueue.java +++ b/se/sics/mspsim/core/EventQueue.java @@ -56,8 +56,8 @@ public class EventQueue { } public void addEvent(TimeEvent event) { - if (event.scheduled) { - removeEvent(event); + if (event.scheduledIn != null) { + event.remove(); } if (first == null) { first = event; @@ -84,7 +84,7 @@ public class EventQueue { } else { nextTime = 0; } - event.scheduled = true; + event.scheduledIn = this; eventCount++; } @@ -117,7 +117,7 @@ public class EventQueue { } // System.out.println("Removed =>"); // print(); - event.scheduled = false; + event.scheduledIn = null; eventCount--; return true; } @@ -135,7 +135,8 @@ public class EventQueue { } else { nextTime = 0; } - tmp.scheduled = false; + // No longer scheduled! + tmp.scheduledIn = null; eventCount--; return tmp; } @@ -147,7 +148,7 @@ public class EventQueue { t = t.nextEvent; clr.nextEvent = null; clr.time = 0; - clr.scheduled = false; + clr.scheduledIn = null; } first = null; eventCount = 0; diff --git a/se/sics/mspsim/core/MSP430Core.java b/se/sics/mspsim/core/MSP430Core.java index 7524d21..106832c 100644 --- a/se/sics/mspsim/core/MSP430Core.java +++ b/se/sics/mspsim/core/MSP430Core.java @@ -455,10 +455,11 @@ public class MSP430Core extends Chip implements MSP430Constants { * @param event * @param time */ - public void scheduleTimeEventMillis(TimeEvent event, double msec) { + public long scheduleTimeEventMillis(TimeEvent event, double msec) { long time = (long) (getTime() + msec / 1000 * BasicClockModule.MAX_DCO_FRQ); // System.out.println("Scheduling at: " + time + " (" + msec + ") getTime: " + getTime()); scheduleTimeEvent(event, time); + return time; } diff --git a/se/sics/mspsim/core/TimeEvent.java b/se/sics/mspsim/core/TimeEvent.java index 1976405..bd7ee48 100644 --- a/se/sics/mspsim/core/TimeEvent.java +++ b/se/sics/mspsim/core/TimeEvent.java @@ -45,7 +45,9 @@ public abstract class TimeEvent { // For linking events... TimeEvent nextEvent; TimeEvent prevEvent; - boolean scheduled = false; + + // Keeps track of where this is scheduled + EventQueue scheduledIn = null; String name; protected long time; @@ -63,6 +65,17 @@ public abstract class TimeEvent { return time; } + public boolean isScheduled() { + return scheduledIn != null; + } + + public boolean remove() { + if (scheduledIn != null) { + return scheduledIn.removeEvent(this); + } + return false; + } + public abstract void execute(long t); public String getShort() { diff --git a/se/sics/mspsim/core/Timer.java b/se/sics/mspsim/core/Timer.java index 52963a1..e774dc6 100644 --- a/se/sics/mspsim/core/Timer.java +++ b/se/sics/mspsim/core/Timer.java @@ -666,7 +666,7 @@ public class Timer extends IOUnit { time = cycles + 1000; } - if (!timerTrigger.scheduled) { + if (timerTrigger.scheduledIn == null) { // System.out.println(getName() + " new trigger (nothing sch) ..." + time + " re:" + // smallest + " => " + (smallest > 0 ? expCaptureTime[smallest] + " > " + expCompare[smallest]: // nextTimerTrigger) + " C:"+ cycles); diff --git a/se/sics/mspsim/core/Watchdog.java b/se/sics/mspsim/core/Watchdog.java index 11e7dbd..263c9be 100644 --- a/se/sics/mspsim/core/Watchdog.java +++ b/se/sics/mspsim/core/Watchdog.java @@ -40,12 +40,15 @@ */ package se.sics.mspsim.core; +import se.sics.mspsim.util.Utils; + /** * @author joakim * */ public class Watchdog extends IOUnit { - + private static final boolean DEBUG = false; + private static final int WDTCTL = 0x120; private static final int WDTHOLD = 0x80; @@ -55,10 +58,23 @@ public class Watchdog extends IOUnit { private static final int RESET_VECTOR = 15; + private static final int[] DELAY = { + 32768, 8192, 512, 64 + }; + private int wdtctl; private boolean wdtOn = true; + private boolean hold = false; private MSP430Core cpu; + // The current "delay" when started/clered (or hold) + private int delay; + // The target time for this timer + private long targetTime; + // Timer ACLK + private boolean sourceACLK = false; + + private TimeEvent wdtTrigger = new TimeEvent(0) { public void execute(long t) { // System.out.println(getName() + " **** executing update timers at " + t + " cycles=" + core.cycles); @@ -83,7 +99,8 @@ public class Watchdog extends IOUnit { private void triggerWDT(long time) { // Here the WDT triggered!!! -// System.out.println("WDT trigger - should reset?!?!"); + System.out.println("WDT trigger - should reset?!?!"); + cpu.flagInterrupt(RESET_VECTOR, this, true); } public int read(int address, boolean word, long cycles) { @@ -95,16 +112,33 @@ public class Watchdog extends IOUnit { public void write(int address, int value, boolean word, long cycles) { if (address == WDTCTL) { if ((value >> 8) == 0x5a) { -// System.out.println("Wrote to WDTCTL: " + Utils.hex8(wdtctl)); wdtctl = value & 0xff; + if (DEBUG) System.out.println(getName() + " Wrote to WDTCTL: " + Utils.hex8(wdtctl)); // Is it on? wdtOn = (value & 0x80) == 0; + boolean lastACLK = sourceACLK; + sourceACLK = (value & WDTSSEL) != 0; if ((value & WDTCNTCL) != 0) { - // Clear timer - reschedule the event! + // Clear timer => reset the delay + delay = DELAY[value & WDTISx]; + } + // Start it if it should be started! + if (wdtOn) { + if (DEBUG) System.out.println("Setting WDTCNT to count: " + delay); + if (sourceACLK) { + if (DEBUG) System.out.println("setting delay in ms (ACLK): " + 1000.0 * delay / cpu.aclkFrq); + targetTime = cpu.scheduleTimeEventMillis(wdtTrigger, 1000.0 * delay / cpu.aclkFrq); + } else { + if (DEBUG) System.out.println("setting delay in cycles"); + cpu.scheduleCycleEvent(wdtTrigger, targetTime = cpu.cycles + delay); + } + } else { + // Stop it and remember current "delay" left! + wdtTrigger.remove(); } } else { // Trigger reset!! -// System.out.println("WDTCTL: illegal write - should reset!!!! " + value); +// System.out.println("WDTCTL: illegal write - should reset!!!! " + value); cpu.flagInterrupt(RESET_VECTOR, this, true); } }