Improved timer and selection (PxSEL) handling

This commit is contained in:
Heintz 2018-11-16 10:48:21 +01:00
parent d41d5ea451
commit dbd7fe1374
7 changed files with 87 additions and 42 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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