From dbd7fe13745e0c7bf204cc746a90cb2bf0bac530 Mon Sep 17 00:00:00 2001 From: Heintz Date: Fri, 16 Nov 2018 10:48:21 +0100 Subject: [PATCH] Improved timer and selection (PxSEL) handling --- se/sics/mspsim/chip/Button.java | 9 +++- se/sics/mspsim/core/IOPort.java | 17 ++++--- se/sics/mspsim/core/MSP430Core.java | 5 ++ se/sics/mspsim/core/Timer.java | 44 ++++++++++++----- .../platform/MSPEXP430F5438/Exp5438Gui.java | 2 +- se/sics/mspsim/util/ELF.java | 5 +- se/sics/mspsim/util/GDBStubs.java | 47 +++++++++++-------- 7 files changed, 87 insertions(+), 42 deletions(-) diff --git a/se/sics/mspsim/chip/Button.java b/se/sics/mspsim/chip/Button.java index 04334e7..2cdcd1c 100644 --- a/se/sics/mspsim/chip/Button.java +++ b/se/sics/mspsim/chip/Button.java @@ -84,7 +84,12 @@ public class Button extends Chip implements ActionListener { return Up_Down & Ren; } - + public boolean isPullDown() { + boolean Ren = ((this.port.getRegister(PortReg.REN) & (1 << this.pin)) != 0); + boolean Up_Down = ((this.port.getRegister(PortReg.OUT) & (1 << this.pin)) != 0); + return !Up_Down & Ren; + } + public void setPressed(boolean isPressed) { if (this.isPressed != isPressed) { this.isPressed = isPressed; @@ -108,7 +113,7 @@ public class Button extends Chip implements ActionListener { public void SetState() { boolean isHigh = this.isPressed ^ (!this.polarity); stateChanged(this.isPressed ? 1 : 0); - if((btnTyp==Btn_Typ.HighOpen)&!isPullUp()) isHigh=false; + if((btnTyp==Btn_Typ.HighOpen)&isPullDown()) isHigh=false; if (DEBUG) log(this.isPressed ? "pressed" : "released"); port.setPinState(pin, isHigh ? IOPort.PinState.HI : IOPort.PinState.LOW); diff --git a/se/sics/mspsim/core/IOPort.java b/se/sics/mspsim/core/IOPort.java index 3278635..3d53cb2 100644 --- a/se/sics/mspsim/core/IOPort.java +++ b/se/sics/mspsim/core/IOPort.java @@ -87,6 +87,7 @@ public class IOPort extends IOUnit { private int iv; /* low / high */ private Timer[] timerCapture = new Timer[8]; + private int[] ccr_index = new int[8]; private IOPort ioPair; @@ -189,13 +190,20 @@ public class IOPort extends IOUnit { portInListener = PortListenerProxy.removePortListener(portInListener, oldListener); } - public void setTimerCapture(Timer timer, int pin) { + public void setTimerCapture(Timer timer, int pin, int ccr_i) { if (DEBUG) { log("Setting timer capture for pin: " + pin); } timerCapture[pin] = timer; + ccr_index[pin]=ccr_i; } + public void removeTimerCapture(int pin) { + if (DEBUG) { + log("Remove timer capture for pin: " + pin); + } + timerCapture[pin] = null; + } private void updateIV() { int bitval = 0x01; iv = 0; @@ -469,11 +477,8 @@ public class IOPort extends IOUnit { } if (timerCapture[pin] != null) { - /* should not be pin and 0 here - * pin might need configuration and 0 can maybe also be 1? - */ - // if (DEBUG) log("Notifying timer of changed pin value"); - timerCapture[pin].capture(pin, 0, state); + if(((sel&(1 << pin))!=0)&&((sel2&(1 << pin))==0)) + timerCapture[pin].capture(ccr_index[pin], 0, state); } } diff --git a/se/sics/mspsim/core/MSP430Core.java b/se/sics/mspsim/core/MSP430Core.java index 0dc3deb..fd2bfcf 100644 --- a/se/sics/mspsim/core/MSP430Core.java +++ b/se/sics/mspsim/core/MSP430Core.java @@ -1077,6 +1077,11 @@ public class MSP430Core extends Chip implements MSP430Constants { // When is PC increased probably immediately (e.g. here)? pc += 2; + if(pc>0xFFFF) { + System.out.println("PC overflow => reset"); + reset(); + return -1; + } writeRegister(PC, pc); diff --git a/se/sics/mspsim/core/Timer.java b/se/sics/mspsim/core/Timer.java index 5be2c11..c526ee3 100644 --- a/se/sics/mspsim/core/Timer.java +++ b/se/sics/mspsim/core/Timer.java @@ -37,6 +37,7 @@ package se.sics.mspsim.core; +import se.sics.mspsim.chip.CC2420.Reg; import se.sics.mspsim.core.EmulationLogger.WarningType; import se.sics.mspsim.core.MSP430Config.MUXConfig; import se.sics.mspsim.util.Utils; @@ -271,21 +272,21 @@ public class Timer extends IOUnit { + ": " + tccr); } - ccrEvent(this); - // Set the interrupt flag... - tcctl |= CC_IFG; if (captureOn) { // Write the expected capture time to the register (counter could // differ slightly) - tccr = expCompare; + //tccr = expCompare; // Update capture times... for next capture - expCompare = (expCompare + expCapInterval) & WrapValue(); - expCaptureTime += expCapInterval * cyclesMultiplicator; + //expCompare = (expCompare + expCapInterval) & WrapValue(); + //expCaptureTime += expCapInterval * cyclesMultiplicator; if (DEBUG) { log("setting expCaptureTime to next capture: " + expCaptureTime); } } else { + ccrEvent(this); + // Set the interrupt flag... + tcctl |= CC_IFG; int steps = calcNextEvent() + diff; // Update expected compare time for this compare/cap register expCaptureTime = expCaptureTime @@ -293,10 +294,10 @@ public class Timer extends IOUnit { if (DEBUG) { log("setting expCaptureTime to full wrap: " + expCaptureTime); } + if(tccr!=0) triggerInterrupt(cycles); } /* schedule again! */ update(); - triggerInterrupt(cycles); } } @@ -760,6 +761,10 @@ public class Timer extends IOUnit { ccr[lastTIV / 2].tcctl &= ~CC_IFG; } + reEvaluteCCR1Interrupt(cycles); + } + + public void reEvaluteCCR1Interrupt(long cycles) { /* flag this interrupt off */ cpu.flagInterrupt(ccr1Vector, this, false); lastTIV = 0; @@ -775,7 +780,7 @@ public class Timer extends IOUnit { if (lastTIV == 0 && interruptEnable & interruptPending) { lastTIV = timerOverflow; cpu.flagInterrupt(ccr1Vector, this, true); - } + } } public void write(int address, int data, boolean word, long cycles) { @@ -870,6 +875,7 @@ public class Timer extends IOUnit { // Control register... int index = (iAddress - TCCTL0) / 2; CCR reg = ccr[index]; + int oldtcctl=reg.tcctl; reg.tcctl = data; reg.outMode = (data >> 5) & 7; boolean oldCapture = reg.captureOn; @@ -879,7 +885,7 @@ public class Timer extends IOUnit { int src = reg.inputSrc = srcMap[4 + index * 4 + reg.inputSel]; reg.capMode = (data >> 14) & 3; - /* capture a port state? */ + /* capture a port state? if (!oldCapture && reg.captureOn && (src & SRC_PORT) != 0) { int port = (src & 0xff) >> 4; int pin = src & 0x0f; @@ -887,6 +893,23 @@ public class Timer extends IOUnit { if (DEBUG) log("Assigning Port: " + port + " pin: " + pin + " for capture"); ioPort.setTimerCapture(this, pin); + } */ + + if (!oldCapture) + for (MUXConfig con : reg.PortCon) { + IOPort ioPort = cpu.getIOUnit(IOPort.class, "P" + con.Port); + if(reg.captureOn ) { + if (DEBUG) + log("Assigning Port: " + con.Port + " pin: " + con.Pin + " for capture"); + ioPort.setTimerCapture(this, con.Pin,index); + } else { + ioPort.removeTimerCapture(con.Pin); + if (DEBUG) + log("Remove Port: " + con.Port + " pin: " + con.Pin + " for capture"); + } + } + if(((reg.tcctl&CC_IFG)==0)&&((oldtcctl&CC_IFG)!=0)) { + reEvaluteCCR1Interrupt(cycles); } updateCounter(cycles); @@ -1114,8 +1137,7 @@ public class Timer extends IOUnit { + " at cycles: " + cpu.cycles + " servicing delay: " + (cpu.cycles - triggerTime)); } - /* old method is replaced */ - /* triggerInterrupts(cpu.cycles); */ + } public int getModeMax() { diff --git a/se/sics/mspsim/platform/MSPEXP430F5438/Exp5438Gui.java b/se/sics/mspsim/platform/MSPEXP430F5438/Exp5438Gui.java index e555819..150b688 100644 --- a/se/sics/mspsim/platform/MSPEXP430F5438/Exp5438Gui.java +++ b/se/sics/mspsim/platform/MSPEXP430F5438/Exp5438Gui.java @@ -80,7 +80,7 @@ public class Exp5438Gui extends AbstractNodeGUI { }; public Exp5438Gui(Exp5438Node node) { - super("MSPSIM fork by Prof. Rüdiger Heintz 0.4.23", "images/MSP-EXP430F5438.jpg"); + super("MSPSIM fork by Prof. Rüdiger Heintz 0.4.25", "images/MSP-EXP430F5438.jpg"); this.node = node; Action scaleDownAction = new AbstractAction() { private static final long serialVersionUID = 1L; diff --git a/se/sics/mspsim/util/ELF.java b/se/sics/mspsim/util/ELF.java index c5c72ae..caf5895 100644 --- a/se/sics/mspsim/util/ELF.java +++ b/se/sics/mspsim/util/ELF.java @@ -330,8 +330,9 @@ public class ELF { System.out.println("Loading " + len + " bytes into " + Integer.toString(addr, 16) + " fill " + fill); } - for (int i = 0, n = len; i < n; i++) { - memory[addr++] = elfData[offset++] & 0xff; + for (int i = 0, n = len; i < n; i++) { + //System.out.print( Integer.toHexString(0x100 |(elfData[offset] & 0xff)).substring(1)); + memory[addr++] = elfData[offset++] & 0xff; } // Flash is overridden but I want to define the values in the flash class // if (fill > len) { diff --git a/se/sics/mspsim/util/GDBStubs.java b/se/sics/mspsim/util/GDBStubs.java index b65c255..5c00bc9 100755 --- a/se/sics/mspsim/util/GDBStubs.java +++ b/se/sics/mspsim/util/GDBStubs.java @@ -150,7 +150,7 @@ public class GDBStubs implements Runnable { private void stepSource() { node.stop(); node.step(1); - } + } /** * @param cmd @@ -168,7 +168,7 @@ public class GDBStubs implements Runnable { */ private void handleCmd(String cmd, Integer[] cmdBytes, int cmdLen) throws IOException, EmulationException { -// System.out.println("cmd: " + cmd); + //System.out.println("cmd: " + cmd); char c = cmd.charAt(0); String parts[]; switch (c) { @@ -230,7 +230,7 @@ public class GDBStubs implements Runnable { break; case 'P': // write Register sendResponse("", "command unknown"); -/* parts = cmd.split("="); + /* parts = cmd.split("="); if (parts.length == 2) { String Val = parts[1].substring(2, 4) + parts[1].substring(0, 2); cpu.writeRegister(Integer.parseInt(parts[0].substring(1)), @@ -277,7 +277,7 @@ public class GDBStubs implements Runnable { cmd2 = wdata[0]; } parts = cmd2.split(","); - + int addr = Integer.decode("0x" + parts[0]); int len = Integer.decode("0x" + parts[1]); String data = ""; @@ -295,15 +295,23 @@ public class GDBStubs implements Runnable { } else { System.out.println("Writing to memory at: " + Integer.toHexString(addr) + " len = " + len + " with: " + ((wdata.length > 1) ? wdata[1] : "")); - - for(int i=0;i