/* This file is part of JOP, the Java Optimized Processor see <http://www.jopdesign.com/> Copyright (C) 2001-2008, Martin Schoeberl (martin@jopdesign.com) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package jbe.kfl; /** * system functions and constants. * Version for BB KFL (clock frequ)! */ public class JopSys { static int byteAvail; static int triacVal; static int impCnt; /** * Simulate BB IO for benchmark. */ static int rd(int addr) { if (addr==IO_CNT) { return Native.rd(Const.IO_CNT); } else if (addr==Msg.IO_STATUS && byteAvail>0) { // simulate a byte in rs485 uart return 32; } else if (addr==Msg.IO_RS485) { if (byteAvail>0) { --byteAvail; return buf[byteAvail]; } } else if (addr==BBSys.IO_TRIAC) { // all Us are ok; return BBSys.MSK_U; } else if (addr==BBSys.IO_IADC) { if (triacVal!=0) { return Triac.MIN_STROM + (Triac.MIN_STROM<<10) + (Triac.MIN_STROM<<20); } else { return 0; } } else if (addr==BBSys.IO_SENSOR) { int sens = 0; if (triacVal!=0) { if ((cnt&0x03)==1) { sens |= BBSys.BIT_SENSI; if (Mast.state==BBSys.MS_UP) { ++impCnt; } else if (Mast.state==BBSys.MS_DOWN) { --impCnt; } } } if (impCnt<4) sens |= BBSys.BIT_SENSU; if (impCnt>20) sens |= BBSys.BIT_SENSO; return sens; } return 0; } static void wr(int val, int addr){ if (addr==BBSys.IO_WD) { Native.wr(val, Const.IO_WD); } else if (addr==BBSys.IO_TRIAC) { triacVal = val; Native.wr(val, Const.IO_LED); } } public static final int IO_CNT = 0; // is 0 in actual hardware public static final int INTERVAL = 73728/2; // five ms public static final int MS = 7373; static int min, max; static boolean first; static int simState; static int[] buf; /** * Initialization for benchmarking KFL Mast loop. */ public static void initBench() { min = 1000000000; max = 0; first = true; simState = 0; impCnt = 0; buf = new int[4]; byteAvail = 0; /* util.Dbg.initSerWait(); util.Dbg.wr("Benchmark started\n"); */ } static int cnt; static int timestamp; static int startTime; /** * Called once per loop instead of waitForNextInterval. */ public static void benchLoop() { /* if (first) { first = false; timestamp = Native.rd(Const.IO_CNT); startTime = timestamp; } else { int time = Native.rd(Const.IO_CNT); int diff = time-timestamp; if (diff > max) max = diff; if (diff < min) min = diff; timestamp = time; } */ ++cnt; if ((cnt&0x07) == 0) { masterCmd(); } else if ((cnt&0x03)==3) { masterPoll(); } // Don't wait for the next interval. // We want to measure performance of workload in // execution time. // // Timer.waitForNextInterval(); /* if (cnt==10000) { endBench(); } */ } /* static void endBench() { startTime = Native.rd(Const.IO_CNT)-startTime; util.Dbg.wr("\nBenchmark finished in "); util.Dbg.intVal(startTime); util.Dbg.wr("cycles\n"); dbgOut(); // for (;;); } */ // invoked every 8 cycles static void masterPoll() { simMsg(BBSys.CMD_STATUS, 0); } static int waitTime; static void masterCmd() { if (simState==0) { simMsg(BBSys.CMD_SET_STATE, BBSys.MS_RDY); simState = 1; } else if (simState==1) { simMsg(BBSys.CMD_SET_MAXCNT, 1000); simState = 2; waitTime = 2; } else if (simState==2) { if (Mast.state==BBSys.MS_RDY) { if (waitTime==0) { simMsg(BBSys.MS_UP, 0); // util.Dbg.wr("up "); waitTime = 4; // minimum 20 cycles (4*8) simState = 3; } else { --waitTime; } } } else if (simState==3) { if (Mast.state==BBSys.MS_RDY) { if (waitTime==0) { simMsg(BBSys.MS_DOWN, 0); // util.Dbg.wr("down "); waitTime = 4; // minimum 20 cycles (4*8) simState = 2; } else { --waitTime; } } } } static void dbgOut() { /* util.Dbg.intVal(Mast.state); util.Dbg.intVal(Mast.lastErr); util.Dbg.intVal(cnt); util.Dbg.intVal(min); util.Dbg.intVal(max); util.Dbg.wr('\n'); */ } private static final int ADDR_MSK = 0x7c0000; private static final int CMD_MSK = 0x03f000; private static final int DATA_MSK = 0x000fff; static void simMsg(int cmd, int data) { int val; int i; int addr = 1; addr <<= 18; cmd <<= 12; data &= DATA_MSK; val = 0x800000 | addr | cmd | data; val <<= 8; val |= Msg.crc(val); // append crc for (i=0; i<4; ++i) { // @WCA loop=4 buf[i] = val & 0x0ff; val >>>= 8; } byteAvail = 4; } }