mirror of https://github.com/contiki-ng/mspsim
Improved timer and selection (PxSEL) handling
This commit is contained in:
parent
d41d5ea451
commit
dbd7fe1374
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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<wdata[1].length()/2;i++){
|
||||
int high=Integer.decode("0x"+wdata[1].substring(2*i, 2*i+1));
|
||||
int low=Integer.decode("0x"+wdata[1].substring(2*i+1, 2*i+2));
|
||||
int Val=low+high*16;
|
||||
mem.set(addr+i, Val, Memory.AccessMode.WORD);
|
||||
// cpu.memory[addr+i]=Val;
|
||||
|
||||
if(wdata[1].length()!=(len*2)) {
|
||||
System.err.println("*************************");
|
||||
System.err.println(" wrong data size!");
|
||||
System.err.println(" "+wdata[1].length()+" != "+(2*len));
|
||||
System.err.println("*************************");
|
||||
sendResponse("","wrong data size "+wdata[1].length()+" != "+(2*len));
|
||||
} else {
|
||||
for(int i=0;i<wdata[1].length()/2;i++){
|
||||
int high=Integer.decode("0x"+wdata[1].substring(2*i, 2*i+1));
|
||||
int low=Integer.decode("0x"+wdata[1].substring(2*i+1, 2*i+2));
|
||||
int Val=low+high*16;
|
||||
mem.set(addr+i, Val, Memory.AccessMode.BYTE);
|
||||
// cpu.memory[addr+i]=Val;
|
||||
}
|
||||
sendResponse(OK);
|
||||
}
|
||||
sendResponse(OK);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
@ -351,14 +359,13 @@ public class GDBStubs implements Runnable {
|
|||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void writeRegisters(String data) throws IOException {
|
||||
System.err.println(data);
|
||||
if(data.length()!=(8*16)){
|
||||
sendResponse("", "Wrong length for write register");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
for(int i=0;i<16;i++){
|
||||
String packet=data.substring(8*i, 8*i+7);
|
||||
int low = Integer.decode("0x" + packet.substring(0,1));
|
||||
|
|
@ -367,7 +374,7 @@ public class GDBStubs implements Runnable {
|
|||
}
|
||||
sendResponse(OK, "write register");
|
||||
}
|
||||
|
||||
|
||||
private void sendRegisters() throws IOException {
|
||||
String regs = "";
|
||||
for (int i = 0; i < 16; i++) {
|
||||
|
|
@ -400,14 +407,14 @@ public class GDBStubs implements Runnable {
|
|||
}
|
||||
|
||||
public void sendResponse(String resp, String info) throws IOException {
|
||||
// System.out.print("ans2: ");
|
||||
// System.out.print("ans2: ");
|
||||
String a = "";
|
||||
a += '$';
|
||||
int cs = 0;
|
||||
if (resp != null) {
|
||||
for (int i = 0; i < resp.length(); i++) {
|
||||
a += resp.charAt(i);
|
||||
// System.out.print(resp.charAt(i));
|
||||
// System.out.print(resp.charAt(i));
|
||||
cs += resp.charAt(i);
|
||||
}
|
||||
}
|
||||
|
|
@ -427,12 +434,12 @@ public class GDBStubs implements Runnable {
|
|||
c = c - 10 + 'a';
|
||||
}
|
||||
a += (char) c;
|
||||
/* if (info == "") {
|
||||
/* if (info == "") {
|
||||
System.out.println(" (" + bytesToHexString(a.getBytes()) +")");
|
||||
} else {
|
||||
System.out.println(" (" + info + "::" + bytesToHexString(a.getBytes()) +")");
|
||||
}
|
||||
*/ output.write(a.getBytes());
|
||||
*/ output.write(a.getBytes());
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue