001package jmri.jmrix.loconet.pr3;
002
003import jmri.jmrix.loconet.LnCommandStationType;
004import jmri.jmrix.loconet.LocoNetSystemConnectionMemo;
005import jmri.jmrix.loconet.LnPacketizer;
006import jmri.jmrix.loconet.LocoNetMessage;
007import jmri.jmrix.loconet.locobuffer.LocoBufferAdapter;
008import org.slf4j.Logger;
009import org.slf4j.LoggerFactory;
010
011/**
012 * Update the code in jmri.jmrix.loconet.locobuffer so that it refers to the
013 * switch settings on the new Digitrax PR3
014 *
015 * @author Bob Jacobsen Copyright (C) 2004, 2005, 2006, 2008
016 */
017public class PR3Adapter extends LocoBufferAdapter {
018
019    public PR3Adapter() {
020        super(new PR3SystemConnectionMemo());
021
022        options.remove(option2Name);
023        options.put(option2Name, new Option(Bundle.getMessage("CommandStationTypeLabel"), commandStationOptions(), false));
024
025    }
026
027    @Override
028    protected void reportOpen(String portName) {
029        log.info("Connecting PR3 via {} {}", portName, currentSerialPort);
030    }
031
032    /**
033     * Always on flow control
034     */
035    @Override
036    protected void setLocalFlowControl() {
037        FlowControl flow = FlowControl.RTSCTS;
038        setFlowControl(currentSerialPort, flow);
039    }
040
041    /**
042     * Set up all of the other objects to operate with a PR3 connected to this
043     * port. This overrides the version in loconet.locobuffer, but it has to
044     * duplicate much of the functionality there, so the code is basically
045     * copied.
046     */
047    @Override
048    public void configure() {
049        setCommandStationType(getOptionState(option2Name));
050        setTurnoutHandling(getOptionState(option3Name));
051        if (commandStationType == LnCommandStationType.COMMAND_STATION_PR3_ALONE) {
052            // PR3 standalone case
053            // connect to a packetizing traffic controller
054            // that does echoing
055            //
056            // Note - already created a LocoNetSystemConnectionMemo, so re-use 
057            // it when creating a PR2 Packetizer.  (If create a new one, will
058            // end up with two "LocoNet" menus...)
059            jmri.jmrix.loconet.pr2.LnPr2Packetizer packets = 
060                    new jmri.jmrix.loconet.pr2.LnPr2Packetizer(this.getSystemConnectionMemo());
061            packets.connectPort(this);
062
063            // create memo
064            /*PR3SystemConnectionMemo memo
065             = new PR3SystemConnectionMemo(packets, new SlotManager(packets));*/
066            this.getSystemConnectionMemo().setLnTrafficController(packets);
067            // do the common manager config
068            this.getSystemConnectionMemo().configureCommandStation(commandStationType,
069                    mTurnoutNoRetry, mTurnoutExtraSpace, mTranspondingAvailable, mInterrogateAtStart, mLoconetProtocolAutoDetect);  // never transponding!
070            this.getSystemConnectionMemo().configureManagersPR2();
071
072            // start operation
073            packets.startThreads();
074
075            // set mode
076            LocoNetMessage msg = new LocoNetMessage(6);
077            msg.setOpCode(0xD3);
078            msg.setElement(1, 0x10);
079            msg.setElement(2, 1);  // set PR2
080            msg.setElement(3, 0);
081            msg.setElement(4, 0);
082            packets.sendLocoNetMessage(msg);
083
084        } else {
085            // MS100 modes - connecting to a separate command station
086            // get transponding option
087            setTranspondingAvailable(getOptionState("TranspondingPresent"));
088            setInterrogateOnStart(getOptionState("InterrogateOnStart"));
089            setLoconetProtocolAutoDetect(getOptionState("LoconetProtocolAutoDetect"));
090
091            // connect to a packetizing traffic controller
092            LnPacketizer packets = getPacketizer(getOptionState(option4Name));
093            packets.connectPort(this);
094
095            // create memo
096            /*PR3SystemConnectionMemo memo
097             = new PR3SystemConnectionMemo(packets, new SlotManager(packets));*/
098            this.getSystemConnectionMemo().setLnTrafficController(packets);
099            // do the common manager config
100            this.getSystemConnectionMemo().configureCommandStation(commandStationType,
101                    mTurnoutNoRetry, mTurnoutExtraSpace, mTranspondingAvailable, mInterrogateAtStart, mLoconetProtocolAutoDetect);
102
103            this.getSystemConnectionMemo().configureManagersMS100();
104
105            // start operation
106            packets.startThreads();
107
108            // set mode
109            LocoNetMessage msg = new LocoNetMessage(6);
110            msg.setOpCode(0xD3);
111            msg.setElement(1, 0x10);
112            msg.setElement(2, 0);  // set MS100, no power
113            if (commandStationType == LnCommandStationType.COMMAND_STATION_STANDALONE) {
114                msg.setElement(2, 3);  // set MS100, with power
115            }
116            msg.setElement(3, 0);
117            msg.setElement(4, 0);
118            packets.sendLocoNetMessage(msg);
119        }
120    }
121
122    /**
123     * {@inheritDoc}
124     *
125     * @return String[] containing the single valid baud rate, "57,600".
126     */
127    @Override
128    public String[] validBaudRates() {
129        return new String[]{"57,600 baud"}; // NOI18N
130    }
131
132    /**
133     * {@inheritDoc}
134     * @return int[] containing the single valid baud rate, 57600.
135     */
136    @Override
137    public int[] validBaudNumbers() {
138        return new int[]{57600};
139    }
140
141    @Override
142    public int defaultBaudIndex() {
143        return 0;
144    }
145
146    // Option 1 does flow control, inherited from LocoBufferAdapter
147
148    /**
149     * The PR3 can be used as a "Standalone Programmer", or with various LocoNet
150     * command stations, or as an interface to a "Standalone LocoNet".  Provide those
151     * options.
152     *
153     * @return an array of strings containing the various command station names and
154     *      name(s) of modes without command stations
155     */
156    public String[] commandStationOptions() {
157        String[] retval = new String[commandStationNames.length + 2];
158        retval[0] = LnCommandStationType.COMMAND_STATION_PR3_ALONE.getName();
159        for (int i = 0; i < commandStationNames.length; i++) {
160            retval[i + 1] = commandStationNames[i];
161        }
162        retval[retval.length - 1] = LnCommandStationType.COMMAND_STATION_STANDALONE.getName();
163        return retval;
164    }
165
166    
167    @Override
168    public PR3SystemConnectionMemo getSystemConnectionMemo() {
169        LocoNetSystemConnectionMemo m = super.getSystemConnectionMemo();
170        if (m instanceof PR3SystemConnectionMemo) {
171            return (PR3SystemConnectionMemo) m;
172        }
173        log.error("Cannot cast the system connection memo to a PR3SystemConnection Memo.");
174        return null;
175    }
176
177    private final static Logger log = LoggerFactory.getLogger(PR3Adapter.class);
178
179}