/*
* Config.java
*/
/**
* Configuration object takes care about storing and retrieving configuration data
* from internal EEPROM of the 68HC11 processor. Configuration data is stored at
* the beginning of the EEPROM and integrity of data is verified by the signature
* and the checksum. If signature or checksum doesn't match (usually after first
* powerup after application download) then the default configuration record is
* created. <p>
* Failure to write into EEPROM will cause system to halt. This is indicated by
* repeated double flash of the activity LED.
*/
class Config
{
/** Flag to indicate EEPROM byte erase mode */
private static final int ERASE_BYTE = 1;
/** Flag to indicate EEPROM bulk erase mode */
private static final int ERASE_BULK = 2;
/** Magic value for configuration data signature */
private static final int SIGNATURE = 0xAB;
/* Starting address of the internal EEPROM */
private static final int CONFIG_ADDR = 0xB600;
/** Network ID of this node */
private byte NodeID = 1;
/** Brief description of this node */
private byte[] NodeName = { (byte)'R',(byte)'S',(byte)'4',(byte)'8',(byte)'5',(byte)' ',(byte)'N',(byte)'o',(byte)'d',(byte)'e',(byte)' ',(byte)'#',(byte)'1',(byte)' ',(byte)' ',(byte)' ' };
/** Debounce time in ms for StartButton */
private short Debounce = 150;
/** Disable time in ms for StartButton and StartLight */
private short Disable = 400;
/** Debounce time in ms for CounterIn/CounterOut counters */
private short CntDebounce = 40;
/** System reset timout value in seconds */
private byte Timeout = 60;
/** Byte array containg the software version number */
private byte[] Version = new byte[5];
/** Checksum of configuration data */
private short CheckSum = 0;
/** System reset timeout in ms */
private int msTimeout;
/**
* Constructor for configuration object. It tries to read configuration
* data from internal EEPROM. If it doesn't succed a new configuration
* record will be created with default values.
*/
Config()
{
EE_setAddress(CONFIG_ADDR);
byte prevNodeID = EE_readByte();
EE_setAddress(CONFIG_ADDR+17);
short prevDebounce = EE_readShort();
short prevDisable = EE_readShort();
short prevCntDebounce = EE_readShort();
byte prevTimeout = EE_readByte();
byte signat = EE_readByte();
int chsum = (short)(prevNodeID + prevDebounce + prevDisable +
prevCntDebounce + prevTimeout + SIGNATURE);
if (signat == SIGNATURE && chsum == EE_readShort())
{
EE_setAddress(CONFIG_ADDR+1);
EE_read(NodeName, 0, NodeName.length);
NodeID = prevNodeID;
Debounce = prevDebounce;
Disable = prevDisable;
CntDebounce = prevCntDebounce;
Timeout = prevTimeout;
}
else
WriteConfig();
// Timeout in secs -> millisec (approx)
msTimeout = (Timeout << 10);
LoadVersion(Version);
SetParams(NodeID, Debounce, Disable, CntDebounce);
}
/**
* Writes the current configuration data into EEPROM. If it fails, system
* will 'hang' and indicate this situation with flashing Led.
* Note: Failure to write into EEPROM is considered as critical and no
* further activity is allowed as this may indicate problem with
* the CPU.
*/
void WriteConfig()
{
boolean ok;
EE_setAddress(CONFIG_ADDR);
ok = EE_writeByte(NodeID);
if (ok)
EE_write(NodeName, 0, NodeName.length);
if (ok)
EE_writeShort(Debounce);
if (ok)
EE_writeShort(Disable);
if (ok)
EE_writeShort(CntDebounce);
if (ok)
EE_writeByte(Timeout);
if (ok)
EE_writeByte((byte)SIGNATURE);
if (ok)
{
short chsum = (short)(NodeID + Debounce + Disable + CntDebounce +
Timeout + SIGNATURE);
EE_writeShort(chsum);
}
else
JackSystem.FailFlash(2, 2500);
}
/**
* Writes the new configuration data into EEPROM. New config. data will
* be activated after next system reset.
* Note: Failure to write into EEPROM is considered as critical and no
* further activity is allowed as this may indicate problem with
* the CPU.
*
* @param newConf byte array containg the new configuration data.
*/
void Set(byte[] newConf)
{
boolean ok = true, changed = false;
int chsum = SIGNATURE;
// Node ID
if (newConf[2] > 0)
{
EE_setAddress(CONFIG_ADDR);
ok = EE_writeByte(newConf[2]);
if (ok)
EE_write(newConf, 3, NodeName.length);
chsum += newConf[2];
changed = true;
}
else
chsum += NodeID;
// start button debounce time
int val = (newConf[19] << 8) + newConf[20];
if (val > 0)
{
EE_setAddress(CONFIG_ADDR+17);
if (ok)
ok = EE_writeShort((short)val);
chsum += val;
changed = true;
}
else
chsum += Debounce;
// start button disable time
val = (newConf[21] << 8) + newConf[22];
if (val > 0)
{
EE_setAddress(CONFIG_ADDR+19);
if (ok)
ok = EE_writeShort((short)val);
chsum += val;
changed = true;
}
else
chsum += Disable;
// counters in/out debounce time
val = (newConf[23] << 8) + newConf[24];
if (val > 0)
{
EE_setAddress(CONFIG_ADDR+21);
if (ok)
ok = EE_writeShort((short)val);
chsum += val;
changed = true;
}
else
chsum += CntDebounce;
// auto-reset timeout
if (newConf[25] > 0)
{
EE_setAddress(CONFIG_ADDR+23);
if (ok)
ok = EE_writeByte(newConf[25]);
chsum += newConf[25];
changed = true;
}
else
chsum += Timeout;
if (ok && changed)
{
EE_setAddress(CONFIG_ADDR+25);
ok = EE_writeShort((short)chsum);
}
if (!ok)
JackSystem.FailFlash(2, 2500);
}
/**
* Gets the software version number.
*
* @param Dest byte array into which software version has to be copied
* @param Start starting position in the array
*/
void GetVersion(byte[] Dest, int Start)
{
if (Start+Version.length <= Dest.length)
JackSystem.arraycopy(Version, 0, Dest, Start, 5);
}
/**
* Returns the node ID.
*
* @return Node ID.
*/
byte GetNodeID()
{
return NodeID;
}
/**
* Copies the node name into provided byte array at the start position.
*
* @param Dest byte array into which to copy node name
* @param Start starting position in the array
*/
void GetNodeName(byte[] Dest, int Start)
{
if (Start+NodeName.length <= Dest.length)
JackSystem.arraycopy(NodeName, 0, Dest, Start, NodeName.length);
}
/**
* Returns the start button debounce time.
*
* @return Debounce time.
*/
short GetDebounce()
{
return Debounce;
}
/**
* Returns the start button disable time.
*
* @return Disable time.
*/
short GetDisable()
{
return Disable;
}
/**
* returns the counters in/out debounce time.
*
* @return Counters debounce time.
*/
short GetCntDebounce()
{
return CntDebounce;
}
/**
* Returns system reset timeout in millisecs.
*
* @return Timeout in milliseconds.
*/
int GetTimeout()
{
return msTimeout;
}
/**
* Sets the starting EEPROM address.
*
* @param Addr EEPROM address.
*/
private static native void EE_setAddress(int Addr);
/**
* Writes the byte value into EEPROM at current address. If successful
* address is incremented by one.
*
* @param Value byte value
* @return True if write was successful, otherwise false is returned.
*/
private static native boolean EE_writeByte(byte Value);
/**
* Writes the short value into EEPROM at current address. If successful
* address is incremented by two.
*
* @param Value short value
* @return True if write was successful, otherwise false is returned.
*/
private static native boolean EE_writeShort(short Value);
/**
* Writes the byte array from starting position into EEPROM at current
* address. If successful address is incremented by number of written
* bytes.
*
* @param Value byte array containg data to be written
* @param Start starting position in the array
* @param Length number of bytes to write
* @return True if write was successful, otherwise false is returned.
*/
private static native boolean EE_write(byte[] Value, int Start, int Length);
/**
* Reads the byte from EEPROM at current address. Address is
* incremented by one.
*
* @return Byte value
*/
private static native byte EE_readByte();
/**
* Reads the short from EEPROM at current address. Address is
* incremented by two.
*
* @return Short value
*/
private static native short EE_readShort();
/**
* Reads the number of bytes from EEPROM at current address. Bytes are
* copied into provided byte array at starting position. Address is
* incremented by number of read bytes.
*
* @param Value byte array into which data are copied
* @param Start starting position in the array
* @param Length number of bytes to read from EEPROM and write into byte
* array
*/
private static native void EE_read(byte[] Value, int Start, int Length);
/**
* Erases the byte or the whole EEPROM.
*
* @param EraseType erase type can have two values:
* BYTE_ERASE specifies that a byte will be erased. SetAddress
* should be used to specify location of the byte to be erased.
* BULK_ERASE indicates that whole EEPROM to be erased.
*
* @return true if erase operation was successful, otherwise false is
* returned.
*/
private static native boolean EE_erase(int EraseType);
/**
* Loads application version number into array. Version number is
* five bytes long.
*
* @param Var reference to destination array.
*/
private static native void LoadVersion(byte[] Ver);
/**
* Sets the configuration parameters for interrupts routines.
*
* @param NodeID ID of this node
* @param Debounce Start button debounce time
* @param Disable Start button disable time
* @param CntDebounce counters in/out debounce time
*/
private static native void SetParams(byte NodeID, short Debounce,
short Disable, short CntDebounce);
}