/*
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/>.
*/
/*
* Created on 23.04.2004
*
* To change the template for this generated file go to
* Window>Preferences>Java>Code Generation>Code and Comments
*/
package tal;
import util.Timer;
/**
* @author martin
*
* To change the template for this generated type comment go to
* Window>Preferences>Java>Code Generation>Code and Comments
*/
public class Alarm {
public static final int OFF = 0;
public static final int ON = 1;
public static final int OFF_PEND = 2;
public static final int ON_PEND = 3;
public static final int OFF_ON_PEND = 4;
public static final int ON_OFF_PEND = 5;
public static final int MB_OFF = 0;
public static final int SB1_OFF = 8;
public static final int SB2_OFF = 16;
private static volatile boolean init;
private static int[] pattern;
private static Alarm list;
private static void setPattern() {
pattern = new int[] {
0, 0, 0, 0, 0, 0, 0, 0, // OFF
1, 1, 1, 1, 1, 1, 1, 1, // ON
0, 0, 0, 1, 0, 0, 0, 1, // OFF_PEND
1, 1, 1, 0, 1, 1, 1, 0, // ON_PEND
1, 1, 1, 0, 1, 0, 1, 0, // OFF_ON_PEND
0, 0, 0, 1, 0, 1, 0, 1, // ON_OFF_PEND
};
}
// construct Alarms befor scheduling
// so we don't need to synchronize init.
private static void doInit() {
setPattern();
init = true;
list = null;
}
public static boolean isPending() {
boolean ret = false;
for (Alarm ptr = list; ptr!=null; ptr = ptr.next) {
if (ptr.state!=ON && ptr.state!=OFF) {
ret = true;
break;
}
}
return ret;
}
public static int getOldMsg() {
int val = 0;
for (Alarm ptr = list; ptr!=null; ptr = ptr.next) {
int nr = ptr.nr;
if (nr>=0) {
val |= ptr.getOldVal()<<nr;
}
// Dbg.wr("get old"); Dbg.intVal(nr); Dbg.intVal(ptr.getOldVal());
}
// Dbg.lf();
return val;
}
public static int getNewMsg() {
int val = 0;
for (Alarm ptr = list; ptr!=null; ptr = ptr.next) {
int nr = ptr.nr;
if (nr>=0) {
val |= ptr.getNewVal()<<nr;
}
// Dbg.wr("get new"); Dbg.intVal(nr); Dbg.intVal(ptr.getNewVal());
}
// Dbg.lf();
return val;
}
public static void stateTransmitted(int oldVal, int newVal) {
for (Alarm ptr = list; ptr!=null; ptr = ptr.next) {
int nr = ptr.nr;
if (nr>=0) {
ptr.stateTransmitted(
((oldVal>>nr)&1)==1,
((newVal>>nr)&1)==1
);
}
}
}
private int state;
private int nr;
private int minTime;
private int timer;
private Alarm next;
/**
* @param number Position in transmitted telegram.
* 0..7 mb, 8..15 sb1, 16..23 sb2
* @param time
*/
public Alarm(int number, int time) {
// We don't need to synchronize this as
// all alarms are allocated during initialization phase.
// Dbg.wr("new Alarm "); Dbg.intVal(number); Dbg.lf();
if (!init) doInit();
state = OFF;
nr = number;
minTime = time;
// for the first time
timer = Timer.getTimeoutSec(0);
next = list;
list = this;
}
public void setState(boolean on) {
on = timeFilter(on);
switch (state) {
case OFF:
if (on) {
state = ON_PEND;
}
break;
case ON:
if (!on) {
state = OFF_PEND;
}
break;
case OFF_PEND:
if (on) {
state = OFF_ON_PEND;
}
break;
case ON_PEND:
if (!on) {
state = ON_OFF_PEND;
}
break;
case OFF_ON_PEND:
break;
case ON_OFF_PEND:
break;
}
}
public int getState() {
return state;
}
public boolean isOn() {
return state==ON || state==ON_PEND || state==OFF_ON_PEND;
}
public boolean getLedPattern(int cnt) {
cnt &= 0x07;
return (pattern[state*8+cnt]==1);
}
private boolean timeFilter(boolean val) {
if (minTime==0) return val;
boolean is = state==ON || state==ON_PEND || state==OFF_ON_PEND;
if (is!=val) {
if (Timer.timeout(timer)) {
return val;
} else {
return is;
}
}
timer = Timer.getTimeoutSec(minTime);
return val;
}
/**
* @return
*/
private int getOldVal() {
switch (state) {
case OFF:
return 0;
case ON:
return 1;
case OFF_PEND:
return 1;
case ON_PEND:
return 0;
case OFF_ON_PEND:
return 0;
case ON_OFF_PEND:
return 1;
}
return 0;
}
/**
* @return
*/
private int getNewVal() {
switch (state) {
case OFF:
return 0;
case ON:
return 1;
case OFF_PEND:
return 0;
case ON_PEND:
return 1;
case OFF_ON_PEND:
return 1;
case ON_OFF_PEND:
return 0;
}
return 0;
}
/**
* @param on
*/
private void stateTransmitted(boolean old, boolean nw) {
switch (state) {
case OFF:
// no changes possible
break;
case ON:
// no changes possible
break;
case OFF_PEND:
if (!nw) {
state = OFF;
}
break;
case ON_PEND:
if (nw) {
state = ON;
}
break;
case OFF_ON_PEND:
if (!old && nw) {
state = ON;
}
break;
case ON_OFF_PEND:
if (old && !nw) {
state = OFF;
}
break;
}
}
}