From: Bob J. <jac...@us...> - 2006-07-18 16:23:09
|
Update of /cvsroot/jmri/jmri/jmrix/direct In directory sc8-pr-cvs6.sourceforge.net:/tmp/cvs-serv24314 Added Files: Message.java Throttle.java ThrottleManager.java Log Message: commit changes that have been sitting around for a while. Not clear how well they function --- NEW FILE: ThrottleManager.java --- package jmri.jmrix.direct; import jmri.LocoAddress; import jmri.DccLocoAddress; import jmri.jmrix.AbstractThrottleManager; /** * Direct DCC implementation of a ThrottleManager. * <P> * When the traffic manager doesn't have anything else to * do, it comes here to get a command to send. * <P> * This is a partial implementation, which can only handle one * Throttle at a time. It also is missing logic to alternate * sending speed and function commands; right now it only * sends the first group of function packets. * * @author Bob Jacobsen Copyright (C) 2004 * @version $Revision: 1.1 $ */ public class ThrottleManager extends AbstractThrottleManager { /** * Constructor. */ public ThrottleManager() { super(); if (mInstance!=null) log.warn("Creating too many objects"); mInstance = this; } static private ThrottleManager mInstance = null; static public ThrottleManager instance() { return mInstance; } Throttle currentThrottle = null; /** * Create throttle data structures. */ public void requestThrottleSetup(LocoAddress address) { if (currentThrottle != null) { log.error("DCC direct cannot handle more than one throttle now"); return; } log.warn("requestThrottleSetup should preserve actual address object, not use ints"); currentThrottle = new Throttle(((DccLocoAddress)address).getNumber()); notifyThrottleKnown(currentThrottle, currentThrottle.getLocoAddress()); } public boolean addressTypeUnique() { return false; } public boolean canBeShortAddress(int a) { return a<128; } public boolean canBeLongAddress(int a) { return a>0; } /** * Invoked when a throttle is released, this updates * the local data structures */ void release(Throttle t) { currentThrottle = null; } static org.apache.log4j.Category log = org.apache.log4j.Category.getInstance(ThrottleManager.class.getName()); } --- NEW FILE: Message.java --- // Message.java package jmri.jmrix.direct; import jmri.Programmer; /** * Encodes a message for direct DCC * <P> * * @author Bob Jacobsen Copyright (C) 2004 * @version $Revision: 1.1 $ */ public class Message extends jmri.jmrix.AbstractMRMessage { // create a new one public Message(int i) { if (i<1) log.error("invalid length in call to ctor"); _nDataChars = i; _dataChars = new int[i]; } // copy one public Message(Message m) { if (m == null) log.error("copy ctor of null message"); _nDataChars = m._nDataChars; _dataChars = new int[_nDataChars]; for (int i = 0; i<_nDataChars; i++) _dataChars[i] = m._dataChars[i]; } public void setOpCode(int i) { _dataChars[0]=i;} public int getOpCode() {return _dataChars[0];} public String getOpCodeHex() { return "0x"+Integer.toHexString(getOpCode()); } // accessors to the bulk data public int getNumDataElements() {return _nDataChars;} public int getElement(int n) {return _dataChars[n];} public void setElement(int n, int v) { _dataChars[n] = v&0x7F; } // display format public String toString() { String s = ""; for (int i=0; i<_nDataChars; i++) { s+=(char)_dataChars[i]; } return s; } // diagnose format public boolean isKillMain() { return getOpCode() == '-'; } public boolean isEnableMain() { return getOpCode() == '+'; } // static methods to return a formatted message static public Message getEnableMain() { log.error("getEnableMain doesnt have a reasonable implementation yet"); return null; } static public Message getKillMain() { log.error("getKillMain doesnt have a reasonable implementation yet"); return null; } static public Message getProgMode() { log.error("getProgMode doesnt have a reasonable implementation yet"); return null; } static public Message getExitProgMode() { log.error("getExitProgMode doesnt have a reasonable implementation yet"); return null; } static public Message getReadCV(int cv, int mode) { Message m = new Message(5); if (mode == Programmer.PAGEMODE) { m.setOpCode('V'); } else { // Bit direct mode m.setOpCode('C'); } addSpace(m, 1); addIntAsThree(cv, m, 2); return m; } static public Message getWriteCV(int cv, int val, int mode) { Message m = new Message(9); if (mode == Programmer.PAGEMODE) { m.setOpCode('V'); } else { // Bit direct mode m.setOpCode('C'); } addSpace(m, 1); addIntAsThree(cv, m, 2); addSpace(m, 5); addIntAsThree(val, m, 6); return m; } static public Message getReadRegister(int reg) { //Vx return null; } static public Message getWriteRegister(int reg, int val) { //Sx xx return null; } // contents (private) private int _nDataChars = 0; private int _dataChars[] = null; private static String addSpace(Message m, int offset) { String s = " "; m.setElement(offset, ' '); return s; } private static String addIntAsTwo(int val, Message m, int offset) { String s = ""+val; if (s.length() != 2) s = "0"+s; // handle <10 m.setElement(offset,s.charAt(0)); m.setElement(offset+1,s.charAt(1)); return s; } private static String addIntAsThree(int val, Message m, int offset) { String s = ""+val; if (s.length() != 3) s = "0"+s; // handle <10 if (s.length() != 3) s = "0"+s; // handle <100 m.setElement(offset,s.charAt(0)); m.setElement(offset+1,s.charAt(1)); m.setElement(offset+2,s.charAt(2)); return s; } static org.apache.log4j.Category log = org.apache.log4j.Category.getInstance(Message.class.getName()); } /* @(#)Message.java */ --- NEW FILE: Throttle.java --- package jmri.jmrix.direct; import jmri.LocoAddress; import jmri.DccLocoAddress; import jmri.jmrix.AbstractThrottle; import jmri.util.StringUtil; /** * An implementation of DccThrottle with code specific to a direct * serial connection. * <P> * Addresses of 99 and below are considered short addresses, and * over 100 are considered long addresses. * <P> * * @author Bob Jacobsen Copyright (C) 2004 * @version $Revision: 1.1 $ */ public class Throttle extends AbstractThrottle { /** * Constructor. */ public Throttle(int address) { super(); // cache settings. this.speedSetting = 0; this.f0 = false; this.f1 = false; this.f2 = false; this.f3 = false; this.f4 = false; this.f5 = false; this.f6 = false; this.f7 = false; this.f8 = false; this.f9 = false; this.f10 = false; this.f11 = false; this.f12 = false; this.address = address; this.isForward = true; } int address; // store integer value for now, ignoring long/short /** * Send the message to set the state of functions F0, F1, F2, F3, F4. */ protected void sendFunctionGroup1() { byte[] result = jmri.NmraPacket.function0Through4Packet(address, (address>=100), getF0(), getF1(), getF2(), getF3(), getF4()); TrafficController.instance().sendPacket(result, 1); } /** * Send the message to set the state of * functions F5, F6, F7, F8. */ protected void sendFunctionGroup2() { byte[] result = jmri.NmraPacket.function5Through8Packet(address, (address>=100), getF5(), getF6(), getF7(), getF8()); TrafficController.instance().sendPacket(result, 1); } /** * Send the message to set the state of * functions F9, F10, F11, F12. */ protected void sendFunctionGroup3() { byte[] result = jmri.NmraPacket.function9Through12Packet(address, (address>=100), getF9(), getF10(), getF11(), getF12()); TrafficController.instance().sendPacket(result, 1); } /** * Set the speed & direction. * <P> * This intentionally skips the emergency stop value of 1. * @param speed Number from 0 to 1; less than zero is emergency stop */ public void setSpeedSetting(float speed) { this.speedSetting = speed; int value = (int)((127-1)*speed); // -1 for rescale to avoid estop if (value>0) value = value+1; // skip estop if (value>127) value = 127; // max possible speed if (value<0) value = 1; // emergency stop String step = ""+value; Message m = new Message(1+step.length()); int i = 0; // message index counter if (isForward) m.setElement(i++, '>'); else m.setElement(i++, '<'); for (int j = 0; j<step.length(); j++) { m.setElement(i++, step.charAt(j)); } // TrafficController.instance().sendMessage(m, null); } public void setIsForward(boolean forward) { isForward = forward; setSpeedSetting(speedSetting); // send the command } public LocoAddress getLocoAddress() { log.error("getLocoAddress not fully implemented yet"); return new DccLocoAddress(address, address>100); // always short address if <100 } /** * Finished with this throttle. Right now, this does nothing * except notify the ThrottleManager * but it could set the speed to zero, turn off functions, etc. */ public void release() { if (!active) log.warn("release called when not active"); ThrottleManager.instance().release(this); dispose(); } /** * Dispose when finished with this object. After this, further usage of * this Throttle object will result in a JmriException. */ public void dispose() { // if this object has registered any listeners, remove those. super.dispose(); } // initialize logging static org.apache.log4j.Category log = org.apache.log4j.Category.getInstance(Throttle.class.getName()); } |