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