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.setLoconetUpdateSlotOnMessageCreation(Bundle.getMessage("ButtonYes").equals(getOptionState("LoconetUpdateSlotOnMessageCreation")));
062            packets.connectPort(this);
063
064            // create memo
065            /*PR3SystemConnectionMemo memo
066             = new PR3SystemConnectionMemo(packets, new SlotManager(packets));*/
067            this.getSystemConnectionMemo().setLnTrafficController(packets);
068            // do the common manager config
069            this.getSystemConnectionMemo().configureCommandStation(commandStationType,
070                    mTurnoutNoRetry, mTurnoutExtraSpace, mTranspondingAvailable, mInterrogateAtStart, mLoconetProtocolAutoDetect);  // never transponding!
071            this.getSystemConnectionMemo().configureManagersPR2();
072
073            // start operation
074            packets.startThreads();
075
076            // set mode
077            LocoNetMessage msg = new LocoNetMessage(6);
078            msg.setOpCode(0xD3);
079            msg.setElement(1, 0x10);
080            msg.setElement(2, 1);  // set PR2
081            msg.setElement(3, 0);
082            msg.setElement(4, 0);
083            packets.sendLocoNetMessage(msg);
084
085        } else {
086            // MS100 modes - connecting to a separate command station
087            // get transponding option
088            setTranspondingAvailable(getOptionState("TranspondingPresent"));
089            setInterrogateOnStart(getOptionState("InterrogateOnStart"));
090            setLoconetProtocolAutoDetect(getOptionState("LoconetProtocolAutoDetect"));
091
092            // connect to a packetizing traffic controller
093            LnPacketizer packets = getPacketizer(getOptionState(option4Name));
094            packets.setLoconetUpdateSlotOnMessageCreation(Bundle.getMessage("ButtonYes").equals(getOptionState("LoconetUpdateSlotOnMessageCreation")));
095            packets.connectPort(this);
096
097            // create memo
098            /*PR3SystemConnectionMemo memo
099             = new PR3SystemConnectionMemo(packets, new SlotManager(packets));*/
100            this.getSystemConnectionMemo().setLnTrafficController(packets);
101            // do the common manager config
102            this.getSystemConnectionMemo().configureCommandStation(commandStationType,
103                    mTurnoutNoRetry, mTurnoutExtraSpace, mTranspondingAvailable, mInterrogateAtStart, mLoconetProtocolAutoDetect);
104
105            this.getSystemConnectionMemo().configureManagersMS100();
106
107            // start operation
108            packets.startThreads();
109
110            // set mode
111            LocoNetMessage msg = new LocoNetMessage(6);
112            msg.setOpCode(0xD3);
113            msg.setElement(1, 0x10);
114            msg.setElement(2, 0);  // set MS100, no power
115            if (commandStationType == LnCommandStationType.COMMAND_STATION_STANDALONE) {
116                msg.setElement(2, 3);  // set MS100, with power
117            }
118            msg.setElement(3, 0);
119            msg.setElement(4, 0);
120            packets.sendLocoNetMessage(msg);
121        }
122    }
123
124    /**
125     * {@inheritDoc}
126     *
127     * @return String[] containing the single valid baud rate, "57,600".
128     */
129    @Override
130    public String[] validBaudRates() {
131        return new String[]{"57,600 baud"}; // NOI18N
132    }
133
134    /**
135     * {@inheritDoc}
136     * @return int[] containing the single valid baud rate, 57600.
137     */
138    @Override
139    public int[] validBaudNumbers() {
140        return new int[]{57600};
141    }
142
143    @Override
144    public int defaultBaudIndex() {
145        return 0;
146    }
147
148    // Option 1 does flow control, inherited from LocoBufferAdapter
149
150    /**
151     * The PR3 can be used as a "Standalone Programmer", or with various LocoNet
152     * command stations, or as an interface to a "Standalone LocoNet".  Provide those
153     * options.
154     *
155     * @return an array of strings containing the various command station names and
156     *      name(s) of modes without command stations
157     */
158    public String[] commandStationOptions() {
159        String[] retval = new String[commandStationNames.length + 2];
160        retval[0] = LnCommandStationType.COMMAND_STATION_PR3_ALONE.getName();
161        for (int i = 0; i < commandStationNames.length; i++) {
162            retval[i + 1] = commandStationNames[i];
163        }
164        retval[retval.length - 1] = LnCommandStationType.COMMAND_STATION_STANDALONE.getName();
165        return retval;
166    }
167
168    
169    @Override
170    public PR3SystemConnectionMemo getSystemConnectionMemo() {
171        LocoNetSystemConnectionMemo m = super.getSystemConnectionMemo();
172        if (m instanceof PR3SystemConnectionMemo) {
173            return (PR3SystemConnectionMemo) m;
174        }
175        log.error("Cannot cast the system connection memo to a PR3SystemConnection Memo.");
176        return null;
177    }
178
179    private static final Logger log = LoggerFactory.getLogger(PR3Adapter.class);
180
181}