mirror of https://github.com/contiki-ng/mspsim
Improved support for emulation of msp430f2xxx series
This commit is contained in:
parent
b207699337
commit
0f1d0ff978
|
|
@ -49,7 +49,17 @@ import se.sics.mspsim.util.Utils;
|
|||
|
||||
public class MSP430f2617Config extends MSP430Config {
|
||||
|
||||
|
||||
private static final String portConfig[] = {
|
||||
"P1=0,IN 20,OUT 21,DIR 22,IFG 23,IES 24,IE 25,SEL 26,SEL2 41,REN 27",
|
||||
"P2=0,IN 28,OUT 29,DIR 2A,IFG 2B,IES 2C,IE 2D,SEL 2E,SEL2 42,REN 2F",
|
||||
"P3=0,IN 18,OUT 19,DIR 1A,SEL 1B,SEL2 43,REN 10",
|
||||
"P4=0,IN 1C,OUT 1D,DIR 1E,SEL 1F,SEL2 44,REN 11",
|
||||
"P5=0,IN 30,OUT 31,DIR 32,SEL 33,SEL2 45,REN 12",
|
||||
"P6=0,IN 34,OUT 35,DIR 36,SEL 37,SEL2 46,REN 13",
|
||||
"P7=0,IN 38,OUT 3A,DIR 3C,SEL 3E,SEL2 47,REN 14",
|
||||
"P8=0,IN 39,OUT 3B,DIR 3D,SEL 3F,SEL2 48,REN 15"
|
||||
};
|
||||
|
||||
public MSP430f2617Config() {
|
||||
/* 32 vectors for the MSP430X series */
|
||||
maxInterruptVector = 31;
|
||||
|
|
@ -62,9 +72,9 @@ public class MSP430f2617Config extends MSP430Config {
|
|||
|
||||
/* TX Vec, RX Vec, TX Bit, RX Bit, SFR-reg, Offset, Name, A?*/
|
||||
UARTConfig uA0 = new UARTConfig(22, 23, 1, 0, 1, 0x60, "USCI A0", true);
|
||||
UARTConfig uB0 = new UARTConfig(22, 23, 3, 2, 1, 0x60, "USCI B0", false);
|
||||
UARTConfig uB0 = new UARTConfig(22, 23, 3, 2, 1, 0x68, "USCI B0", false);
|
||||
UARTConfig uA1 = new UARTConfig(16, 17, 1, 0, 6, 0xD0, "USCI A1", true);
|
||||
UARTConfig uB1 = new UARTConfig(16, 17, 3, 2, 6, 0xD0, "USCI B1", false);
|
||||
UARTConfig uB1 = new UARTConfig(16, 17, 3, 2, 6, 0xD8, "USCI B1", false);
|
||||
uartConfig = new UARTConfig[] {uA0, uB0, uA1, uB1};
|
||||
|
||||
/* configure memory */
|
||||
|
|
@ -103,13 +113,12 @@ public class MSP430f2617Config extends MSP430Config {
|
|||
|
||||
// Add port 1,2 with interrupt capability!
|
||||
// IOPorts will add themselves to the CPU
|
||||
ioUnits.add(new IOPort(cpu, 1, 4, cpu.memory, 0x20));
|
||||
ioUnits.add(new IOPort(cpu, 2, 1, cpu.memory, 0x28));
|
||||
IOPort last = null;
|
||||
ioUnits.add(last = IOPort.parseIOPort(cpu, 18, portConfig[0], last));
|
||||
ioUnits.add(last = IOPort.parseIOPort(cpu, 19, portConfig[1], last));
|
||||
|
||||
// Add port 3,4 & 5,6
|
||||
for (int i = 0, n = 2; i < n; i++) {
|
||||
ioUnits.add(new IOPort(cpu, (3 + i), 0, cpu.memory, 0x18 + i * 4));
|
||||
ioUnits.add(new IOPort(cpu, (5 + i), 0, cpu.memory, 0x30 + i * 4));
|
||||
for (int i = 2; i < portConfig.length; i++) {
|
||||
ioUnits.add(last = IOPort.parseIOPort(cpu, 0, portConfig[i], last));
|
||||
}
|
||||
|
||||
ADC12 adc12 = new ADC12(cpu);
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
package se.sics.mspsim.config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import se.sics.mspsim.core.ClockSystem;
|
||||
import se.sics.mspsim.core.GenericUSCI;
|
||||
import se.sics.mspsim.core.IOPort;
|
||||
import se.sics.mspsim.core.IOUnit;
|
||||
|
|
@ -43,6 +44,7 @@ import se.sics.mspsim.core.MSP430Config;
|
|||
import se.sics.mspsim.core.MSP430Core;
|
||||
import se.sics.mspsim.core.Multiplier32;
|
||||
import se.sics.mspsim.core.Timer;
|
||||
import se.sics.mspsim.core.UnifiedClockSystem;
|
||||
import se.sics.mspsim.util.Utils;
|
||||
|
||||
public class MSP430f5437Config extends MSP430Config {
|
||||
|
|
@ -113,12 +115,12 @@ public class MSP430f5437Config extends MSP430Config {
|
|||
// System.out.println("Adding IOUnit USCI: " + usci.getName());
|
||||
ioUnits.add(usci);
|
||||
}
|
||||
|
||||
ioUnits.add(IOPort.parseIOPort(cpu, 47, portConfig[0]));
|
||||
ioUnits.add(IOPort.parseIOPort(cpu, 42, portConfig[1]));
|
||||
IOPort last = null;
|
||||
ioUnits.add(last = IOPort.parseIOPort(cpu, 47, portConfig[0], last));
|
||||
ioUnits.add(last = IOPort.parseIOPort(cpu, 42, portConfig[1], last));
|
||||
|
||||
for (int i = 2; i < portConfig.length; i++) {
|
||||
ioUnits.add(IOPort.parseIOPort(cpu, 0, portConfig[i]));
|
||||
ioUnits.add(last = IOPort.parseIOPort(cpu, 0, portConfig[i], last));
|
||||
}
|
||||
|
||||
return portConfig.length + uartConfig.length;
|
||||
|
|
@ -129,4 +131,9 @@ public class MSP430f5437Config extends MSP430Config {
|
|||
return Utils.hex20(addr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClockSystem createClockSystem(MSP430Core cpu, int[] memory, Timer[] timers) {
|
||||
return new UnifiedClockSystem(cpu, memory, 0, timers);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright (c) 2007, Swedish Institute of Computer Science.
|
||||
* Copyright (c) 2007-2012, Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
@ -36,47 +36,14 @@
|
|||
*/
|
||||
|
||||
package se.sics.mspsim.core;
|
||||
import java.util.Arrays;
|
||||
import se.sics.mspsim.util.Utils;
|
||||
|
||||
public class IOPort extends IOUnit {
|
||||
|
||||
public enum PinState { LOW, HI };
|
||||
|
||||
private final int port;
|
||||
private final int interrupt;
|
||||
|
||||
// External pin state!
|
||||
private PinState pinState[] = new PinState[8];
|
||||
|
||||
/* NOTE: The offset needs to be configurable since the new IOPorts on
|
||||
* the 5xxx series are located at other addresses.
|
||||
* Maybe create another IOPort that just convert IOAddress to this 'old' mode?
|
||||
* - will be slightly slower on IOWrite/read but very easy to implement.
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
enum PortReg {IN, OUT, DIR, SEL, IFG, IES, IE, REN, DS, IV_L, IV_H};
|
||||
|
||||
public static final int IN = 0;
|
||||
public static final int OUT = 1;
|
||||
public static final int DIR = 2;
|
||||
public static final int SEL = 4; /* what about SEL2? */
|
||||
public static final int IFG = 5;
|
||||
public static final int IES = 6;
|
||||
public static final int IE = 7;
|
||||
public static final int REN = 8;
|
||||
public static final int DS = 9;
|
||||
public static final int IV_L = 10;
|
||||
public static final int IV_H = 11;
|
||||
|
||||
private static final String[] names = {
|
||||
"IN", "OUT", "DIR", "SEL", "IFG", "IES", "IE", "REN", "DS" };
|
||||
|
||||
public enum PortReg {IN, OUT, DIR, SEL, SEL2, IFG, IES, IE, REN, DS, IV_L, IV_H};
|
||||
|
||||
/* portmaps for 1611 */
|
||||
private static final PortReg[] PORTMAP_INTERRUPT =
|
||||
|
|
@ -84,10 +51,15 @@ public class IOPort extends IOUnit {
|
|||
private static final PortReg[] PORTMAP_NO_INTERRUPT =
|
||||
{PortReg.IN, PortReg.OUT, PortReg.DIR, PortReg.SEL};
|
||||
|
||||
private final int port;
|
||||
private final int interrupt;
|
||||
|
||||
// External pin state!
|
||||
private final PinState pinState[] = new PinState[8];
|
||||
|
||||
private final PortReg[] portMap;
|
||||
|
||||
private PortListener portListener = null;
|
||||
// represents the direction register
|
||||
|
||||
/* Registers for Digital I/O */
|
||||
|
||||
|
|
@ -95,11 +67,12 @@ public class IOPort extends IOUnit {
|
|||
private int out;
|
||||
private int dir;
|
||||
private int sel;
|
||||
private int sel2;
|
||||
private int ie;
|
||||
private int ifg;
|
||||
private int ies; /* edge select */
|
||||
private int ren;
|
||||
// private int ds;
|
||||
private int ds;
|
||||
|
||||
private int iv; /* low / high */
|
||||
|
||||
|
|
@ -136,7 +109,7 @@ public class IOPort extends IOUnit {
|
|||
}
|
||||
}
|
||||
|
||||
public static IOPort parseIOPort(MSP430Core cpu, int interrupt, String specification) {
|
||||
public static IOPort parseIOPort(MSP430Core cpu, int interrupt, String specification, IOPort last) {
|
||||
/* Specification = Px=Offset,REG Off, ... */
|
||||
String[] specs = specification.split(",");
|
||||
int port = specs[0].charAt(1) - '0';
|
||||
|
|
@ -148,10 +121,17 @@ public class IOPort extends IOUnit {
|
|||
String[] preg = specs[i].split(" ");
|
||||
PortReg pr = PortReg.valueOf(preg[0]);
|
||||
int offs = Integer.parseInt(preg[1], 16);
|
||||
if (offs >= portMap.length) {
|
||||
portMap = Arrays.copyOf(portMap, offs + 1);
|
||||
}
|
||||
portMap[offs] = pr;
|
||||
}
|
||||
|
||||
return new IOPort(cpu, port, interrupt, cpu.memory, offset, portMap);
|
||||
IOPort newPort = new IOPort(cpu, port, interrupt, cpu.memory, offset, portMap);
|
||||
if (last != null && offset == last.offset && offset > 0) {
|
||||
// This port is a pair with previous port to allow 16 bits writes
|
||||
last.ioPair = newPort;
|
||||
}
|
||||
return newPort;
|
||||
}
|
||||
|
||||
public int getPort() {
|
||||
|
|
@ -202,7 +182,37 @@ public class IOPort extends IOUnit {
|
|||
}
|
||||
//System.out.println("*** Setting IV to: " + iv + " ifg: " + ifg);
|
||||
}
|
||||
|
||||
|
||||
public int getRegister(PortReg register) {
|
||||
switch(register) {
|
||||
case DIR:
|
||||
return dir;
|
||||
case IE:
|
||||
return ie;
|
||||
case IES:
|
||||
return ies;
|
||||
case IFG:
|
||||
return ifg;
|
||||
case IN:
|
||||
return in;
|
||||
case IV_H:
|
||||
return (iv >> 8) & 0xff;
|
||||
case IV_L:
|
||||
return iv & 0xff;
|
||||
case OUT:
|
||||
return out;
|
||||
case REN:
|
||||
return ren;
|
||||
case DS:
|
||||
return ds;
|
||||
case SEL:
|
||||
return sel;
|
||||
case SEL2:
|
||||
return sel2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* only byte access!!! */
|
||||
int read_port(PortReg function, long cycles) {
|
||||
switch(function) {
|
||||
|
|
@ -222,6 +232,10 @@ public class IOPort extends IOUnit {
|
|||
return ies;
|
||||
case SEL:
|
||||
return sel;
|
||||
case SEL2:
|
||||
return sel2;
|
||||
case DS:
|
||||
return ds;
|
||||
case IV_L:
|
||||
return iv & 0xff;
|
||||
case IV_H:
|
||||
|
|
@ -282,7 +296,13 @@ public class IOPort extends IOUnit {
|
|||
case SEL:
|
||||
sel = data;
|
||||
break;
|
||||
case SEL2:
|
||||
sel2 = data;
|
||||
break;
|
||||
/* Can IV be written ? */
|
||||
case DS:
|
||||
ds = data;
|
||||
break;
|
||||
case IV_L:
|
||||
iv = (iv & 0xff00) | data;
|
||||
break;
|
||||
|
|
@ -381,9 +401,7 @@ public class IOPort extends IOUnit {
|
|||
public void reset(int type) {
|
||||
int oldValue = out | (~dir) & 0xff;
|
||||
|
||||
for (int i = 0, n = 8; i < n; i++) {
|
||||
pinState[i] = PinState.LOW;
|
||||
}
|
||||
Arrays.fill(pinState, PinState.LOW);
|
||||
in = 0;
|
||||
dir = 0;
|
||||
ren = 0;
|
||||
|
|
@ -401,12 +419,13 @@ public class IOPort extends IOUnit {
|
|||
|
||||
public String info() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
/* TODO: USE PORTMAP FOR THIS!!! */
|
||||
String[] regs = names;
|
||||
sb.append('$').append(Utils.hex16(offset)).append(':');
|
||||
for (int i = 0, n = regs.length; i < n; i++) {
|
||||
sb.append(' ').append(regs[i]).append(":$")
|
||||
.append(Utils.hex8(0));
|
||||
sb.append(" $").append(Utils.hex(offset, 2)).append(':');
|
||||
for (int i = 0, n = portMap.length; i < n; i++) {
|
||||
PortReg reg = portMap[i];
|
||||
if (reg != null) {
|
||||
sb.append(' ').append(reg).append("($").append(Utils.hex(i, 2)).append("):$")
|
||||
.append(Utils.hex(0, 2));
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -143,5 +143,8 @@ public abstract class MSP430Config {
|
|||
maxMemIO = size;
|
||||
}
|
||||
|
||||
public ClockSystem createClockSystem(MSP430Core cpu, int[] memory, Timer[] timers) {
|
||||
return new BasicClockModule(cpu, memory, 0, timers);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -239,13 +239,7 @@ public class MSP430Core extends Chip implements MSP430Constants {
|
|||
timers[i] = t;
|
||||
}
|
||||
|
||||
// XXX this should be handled by the config, but we do it here to
|
||||
// avoid changing too much of the mspsim architecture for now
|
||||
if (MSP430XArch) {
|
||||
bcs = new UnifiedClockSystem(this, memory, 0, timers);
|
||||
} else {
|
||||
bcs = new BasicClockModule(this, memory, 0, timers);
|
||||
}
|
||||
bcs = config.createClockSystem(this, memory, timers);
|
||||
ioSegment.setIORange(bcs.getAddressRangeMin(), bcs.getAddressRangeMax() - bcs.getAddressRangeMin() + 1, bcs);
|
||||
|
||||
// SFR and Basic clock system.
|
||||
|
|
|
|||
|
|
@ -168,12 +168,12 @@ public class Multiplier32 extends IOUnit {
|
|||
public void write(int address, int data, boolean word, long cycles) {
|
||||
address = address - offset;
|
||||
if (DEBUG) {
|
||||
log("write to: " + Utils.hex(address, 4) + " data = " + data + " word = " + word);
|
||||
log("write to: $" + Utils.hex(address, 4) + " data=" + data + " word=" + word);
|
||||
}
|
||||
switch(address) {
|
||||
case MPY:
|
||||
op1 = mpy = data;
|
||||
if (DEBUG) log("Write to MPY: " + data);
|
||||
op1 = mpy = data;
|
||||
signed = false;
|
||||
accumulating = false;
|
||||
break;
|
||||
|
|
|
|||
Loading…
Reference in New Issue