From af17397a1c962749de496725e808f48953f81b3d Mon Sep 17 00:00:00 2001 From: paulmart-n Date: Mon, 13 May 2024 20:53:56 +0200 Subject: [PATCH] Prescaler, Watchdog, (Cycle-) Timer --- .../fabrik/simulator/pic16f84/Commands.java | 7 +- .../pic16f84/Controller_Frontend.java | 6 +- .../simulator/pic16f84/DataRegister.java | 10 ++ .../fabrik/simulator/pic16f84/PreScaler.java | 43 ++++++++ .../java/fabrik/simulator/pic16f84/Timer.java | 40 +++++++ .../simulator/pic16f84/WatchdogTimer.java | 102 ++++-------------- 6 files changed, 117 insertions(+), 91 deletions(-) create mode 100644 src/main/java/fabrik/simulator/pic16f84/PreScaler.java create mode 100644 src/main/java/fabrik/simulator/pic16f84/Timer.java diff --git a/src/main/java/fabrik/simulator/pic16f84/Commands.java b/src/main/java/fabrik/simulator/pic16f84/Commands.java index 4998a4d..9679ed8 100644 --- a/src/main/java/fabrik/simulator/pic16f84/Commands.java +++ b/src/main/java/fabrik/simulator/pic16f84/Commands.java @@ -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) { diff --git a/src/main/java/fabrik/simulator/pic16f84/Controller_Frontend.java b/src/main/java/fabrik/simulator/pic16f84/Controller_Frontend.java index 37ad3fd..7d4d35e 100644 --- a/src/main/java/fabrik/simulator/pic16f84/Controller_Frontend.java +++ b/src/main/java/fabrik/simulator/pic16f84/Controller_Frontend.java @@ -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"); } diff --git a/src/main/java/fabrik/simulator/pic16f84/DataRegister.java b/src/main/java/fabrik/simulator/pic16f84/DataRegister.java index 8888b4f..8c0b2f3 100644 --- a/src/main/java/fabrik/simulator/pic16f84/DataRegister.java +++ b/src/main/java/fabrik/simulator/pic16f84/DataRegister.java @@ -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; } diff --git a/src/main/java/fabrik/simulator/pic16f84/PreScaler.java b/src/main/java/fabrik/simulator/pic16f84/PreScaler.java new file mode 100644 index 0000000..b188682 --- /dev/null +++ b/src/main/java/fabrik/simulator/pic16f84/PreScaler.java @@ -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(); + } + } +} diff --git a/src/main/java/fabrik/simulator/pic16f84/Timer.java b/src/main/java/fabrik/simulator/pic16f84/Timer.java new file mode 100644 index 0000000..cf29aab --- /dev/null +++ b/src/main/java/fabrik/simulator/pic16f84/Timer.java @@ -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); + } + } +} diff --git a/src/main/java/fabrik/simulator/pic16f84/WatchdogTimer.java b/src/main/java/fabrik/simulator/pic16f84/WatchdogTimer.java index 76dd504..665625f 100644 --- a/src/main/java/fabrik/simulator/pic16f84/WatchdogTimer.java +++ b/src/main/java/fabrik/simulator/pic16f84/WatchdogTimer.java @@ -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); + } }