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

View File

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

View File

@ -93,6 +93,8 @@ public class DataRegister {
setFlags();
}
}
if (address == 1)
PreScaler.resetFromRegister();
}
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) {
@ -146,6 +150,8 @@ public class DataRegister {
}
}
}
if (address == 1)
PreScaler.resetFromRegister();
}
public static void setDirectBit (int fileAddress, int bit, int value){
@ -178,6 +184,10 @@ public class DataRegister {
writeToPCL();
}
public static void resetPC () {
programCounter = 0;
}
public static int getPC(){
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;
import java.util.Timer;
import java.util.TimerTask;
public class WatchdogTimer {
private int prescaler;
private int counter;
private final int MAX_PRESCALER = 128;
private static long watchdogTime;
private static long lastReset = 0;
public WatchdogTimer(int prescaler) {
this.prescaler = Math.min(prescaler, MAX_PRESCALER);
this.counter = 0;
private static long getTimeFromRegister() {
return (PreScaler.isPrescalerOnTimer()) ? 18L : PreScaler.getFactor() * 18L;
}
public void start() {
activateWatchdog(prescaler);
int watchdogTime = 18 * prescaler; // Zeit in Millisekunden
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 void reset() {
counter = 0;
}
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;
public static void testAndTrigger () {
watchdogTime = getTimeFromRegister() * 1000;
if (!PreScaler.isPrescalerOnTimer() && (Commands.getTotalExecutionTime() >= (watchdogTime + lastReset))){
DataRegister.resetPC();
System.err.println("Watchdog Timer triggered");
DataRegister.clearBit(3, 4);
lastReset = Commands.getTotalExecutionTime();
}
}
public static void reset (){
lastReset = Commands.getTotalExecutionTime();
PreScaler.reset();
DataRegister.setBit(3, 3);
DataRegister.setBit(3, 4);
}
}