Return | Jackpot | Comms | HostInterface | Config | Timer | JackSystem

/*
 * 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);
}


Return | Jackpot | Comms | HostInterface | Config | Timer | JackSystem