Prescaler, Watchdog, (Cycle-) Timer

This commit is contained in:
2024-05-13 20:53:56 +02:00
parent 3722bff281
commit af17397a1c
6 changed files with 117 additions and 91 deletions

View File

@ -201,7 +201,7 @@ public class Commands {
switch (instruction){ switch (instruction){
case 0b01100100: case 0b01100100:
System.out.println("CLRWDT"); System.out.println("CLRWDT");
//TODO WatchdogTimer.reset();
return; return;
case 0b1001: case 0b1001:
System.out.println("RETFIE"); System.out.println("RETFIE");
@ -249,6 +249,7 @@ public class Commands {
public static void addExecutionTime(int i) { public static void addExecutionTime(int i) {
totalExecutionTime += i; totalExecutionTime += i;
Timer.cycles(i);
} }
public static long getTotalExecutionTime() { public static long getTotalExecutionTime() {
@ -259,7 +260,6 @@ public class Commands {
public static void MOVWF(int file) { public static void MOVWF(int file) {
DataRegister.setRegister(file, wRegister); DataRegister.setRegister(file, wRegister);
} }
public static void CLRW() { public static void CLRW() {
@ -375,7 +375,6 @@ public class Commands {
DataRegister.setRegister(file, content); DataRegister.setRegister(file, content);
} }
DataRegister.determineZeroFlag(content); DataRegister.determineZeroFlag(content);
addExecutionTime(1);
} }
public static void IORWF(int file, int destination) { public static void IORWF(int file, int destination) {

View File

@ -110,7 +110,7 @@ public class Controller_Frontend {
e.printStackTrace(); e.printStackTrace();
} }
}); });
Thread.sleep(200); //Verzögerungszeit in Millisekunden Thread.sleep(50); //Verzögerungszeit in Millisekunden
} }
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
@ -159,12 +159,12 @@ public class Controller_Frontend {
// Befehle ausführen // Befehle ausführen
Commands.decode(prog[DataRegister.getPC()]); Commands.decode(prog[DataRegister.getPC()]);
DataRegister.increasePC(); DataRegister.increasePC();
WatchdogTimer.testAndTrigger();
Table.refresh(); Table.refresh();
Stage stage = (Stage) stepintoButton.getScene().getWindow(); Stage stage = (Stage) stepintoButton.getScene().getWindow();
CreateWindow.refreshTable(stage); CreateWindow.refreshTable(stage);
IOPorts.refreshUI(getTRISbuttons(), getPORTbuttons()); IOPorts.refreshUI(getTRISbuttons(), getPORTbuttons());
//Total Execution Time totalExecutionTimeLabel.setText("Total Execution Time: " + Commands.getTotalExecutionTime() + " µs");
totalExecutionTimeLabel.setText("Total Execution Time: " + Commands.getTotalExecutionTime() + " microsekunden");
} }

View File

@ -93,6 +93,8 @@ public class DataRegister {
setFlags(); setFlags();
} }
} }
if (address == 1)
PreScaler.resetFromRegister();
} }
public static int getBit(int fileAddress, int bit) { public static int getBit(int fileAddress, int bit) {
@ -124,6 +126,8 @@ public class DataRegister {
} }
} }
} }
if (address == 1)
PreScaler.resetFromRegister();
} }
public static void setBit(int fileAddress, int bit) { public static void setBit(int fileAddress, int bit) {
@ -146,6 +150,8 @@ public class DataRegister {
} }
} }
} }
if (address == 1)
PreScaler.resetFromRegister();
} }
public static void setDirectBit (int fileAddress, int bit, int value){ public static void setDirectBit (int fileAddress, int bit, int value){
@ -178,6 +184,10 @@ public class DataRegister {
writeToPCL(); writeToPCL();
} }
public static void resetPC () {
programCounter = 0;
}
public static int getPC(){ public static int getPC(){
return programCounter; return programCounter;
} }

View File

@ -0,0 +1,43 @@
package fabrik.simulator.pic16f84;
public class PreScaler {
private static final int PSA = 0x3;
private static final int OPTION = 0x81;
private static int scaler = 0b111;
public static boolean isPrescalerOnTimer (){
return DataRegister.getDirectBit(OPTION, PSA) == 0;
}
public static int getFactor () {
int scale = DataRegister.getDirectRegister(OPTION) & 0b111;
int timer = isPrescalerOnTimer() ? 1 : 0;
return (int) Math.pow (2, scale+timer);
}
public static void reset (){
DataRegister.setDirectBit(OPTION, 0, 0);
DataRegister.setDirectBit(OPTION, 1, 0);
DataRegister.setDirectBit(OPTION, 2, 0);
}
public static void resetFromRegister() {
scaler = getFactor();
}
public static void decrement() {
scaler--;
if (scaler == 0) {
scaler = getFactor();
Timer.incrementFromInstructionCycle();
}
System.err.println("VT: " + scaler);
}
public static void cycles(int i) {
for (int j = 0; j < i; j++) {
decrement();
}
}
}

View File

@ -0,0 +1,40 @@
package fabrik.simulator.pic16f84;
public class Timer {
private static final int TIMERREG = 0x1;
private static final int T0IF = 0x2;
private static final int T0SE = 0x4;
private static final int T0CS = 0x5;
private static final int INTCON = 0x0B;
private static final int OPTION = 0x81;
public static void cycles(int cycles){
if (DataRegister.getDirectBit(OPTION, T0CS) == 0){
if (PreScaler.isPrescalerOnTimer()){
for (int i = 0; i < cycles; i++){
PreScaler.decrement();
}
} else {
increment();
}
}
}
public static void incrementFromInstructionCycle(){
if (DataRegister.getDirectBit(OPTION, T0CS) == 0){
increment();
}
}
private static void increment() {
int timer = DataRegister.getDirectRegister(TIMERREG);
timer++;
if (timer > 0xFF){
DataRegister.setDirectRegister(TIMERREG, 0);
DataRegister.setBit(INTCON, T0IF);
} else {
DataRegister.setDirectRegister(1, timer);
}
}
}

View File

@ -1,93 +1,27 @@
package fabrik.simulator.pic16f84; package fabrik.simulator.pic16f84;
import java.util.Timer;
import java.util.TimerTask;
public class WatchdogTimer { public class WatchdogTimer {
private int prescaler; private static long watchdogTime;
private int counter; private static long lastReset = 0;
private final int MAX_PRESCALER = 128;
public WatchdogTimer(int prescaler) { private static long getTimeFromRegister() {
return (PreScaler.isPrescalerOnTimer()) ? 18L : PreScaler.getFactor() * 18L;
this.prescaler = Math.min(prescaler, MAX_PRESCALER);
this.counter = 0;
} }
public void start() { public static void testAndTrigger () {
watchdogTime = getTimeFromRegister() * 1000;
activateWatchdog(prescaler); if (!PreScaler.isPrescalerOnTimer() && (Commands.getTotalExecutionTime() >= (watchdogTime + lastReset))){
DataRegister.resetPC();
int watchdogTime = 18 * prescaler; // Zeit in Millisekunden System.err.println("Watchdog Timer triggered");
DataRegister.clearBit(3, 4);
lastReset = Commands.getTotalExecutionTime();
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
counter++;
if (counter >= MAX_PRESCALER) {
reset();
System.out.println("Watchdog Timeout!");
} }
} }
}, 0, watchdogTime);
}
public static void reset (){
public void reset() { lastReset = Commands.getTotalExecutionTime();
counter = 0; PreScaler.reset();
} DataRegister.setBit(3, 3);
DataRegister.setBit(3, 4);
private void activateWatchdog(int prescaler) {
// Teilerfaktor entsprechend einstellen durch zweierpotenz
switch (prescaler) {
case 1:
DataRegister.setBit(0x81, 0); // Setze PS2:0 auf 000
DataRegister.setBit(0x81, 1); // Deaktiviere den Watchdog-Timer
break;
case 2:
DataRegister.clearBit(0x81, 0); // Setze PS2:0 auf 001
DataRegister.setBit(0x81, 1); // Deaktiviere den Watchdog-Timer
break;
case 4:
DataRegister.setBit(0x81, 0); // Setze PS2:0 auf 010
DataRegister.setBit(0x81, 1); // Deaktiviere den Watchdog-Timer
break;
case 8:
DataRegister.setBit(0x81, 0); // Setze PS2:0 auf 011
DataRegister.setBit(0x81, 1); // Deaktiviere den Watchdog-Timer
break;
case 16:
DataRegister.clearBit(0x81, 0); // Setze PS2:0 auf 100
DataRegister.clearBit(0x81, 1); // Aktiviere den Watchdog-Timer
break;
case 32:
DataRegister.setBit(0x81, 0); // Setze PS2:0 auf 101
DataRegister.clearBit(0x81, 1); // Aktiviere den Watchdog-Timer
break;
case 64:
DataRegister.clearBit(0x81, 0); // Setze PS2:0 auf 110
DataRegister.setBit(0x81, 1); // Aktiviere den Watchdog-Timer
break;
case 128:
DataRegister.setBit(0x81, 0); // Setze PS2:0 auf 111
DataRegister.setBit(0x81, 1); // Aktiviere den Watchdog-Timer
break;
default:
System.out.println("NÜCHTITTGGGGG für den Watchdog-Timer.");
break;
}
} }
} }