Basic version of Watchdog implemented.

git-svn-id: https://mspsim.svn.sourceforge.net/svnroot/mspsim/mspsim@272 23d1a52b-0c3c-0410-b72d-8f29ab48fe35
This commit is contained in:
joxe 2008-05-08 21:28:40 +00:00
parent f831d5b0e6
commit 9df1f40d1d
5 changed files with 63 additions and 14 deletions

View File

@ -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;

View File

@ -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;
}

View File

@ -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() {

View File

@ -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);

View File

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