001package jmri.jmrix.sprog.serialdriver;
002
003import jmri.jmrix.*;
004import jmri.jmrix.sprog.SprogConstants.SprogMode;
005import jmri.jmrix.sprog.SprogPortController;
006import jmri.jmrix.sprog.SprogSystemConnectionMemo;
007import jmri.jmrix.sprog.SprogTrafficController;
008import jmri.jmrix.sprog.update.SprogType;
009
010/**
011 * Implements SerialPortAdapter for the Sprog system.
012 * <p>
013 * This connects an Sprog command station via a serial com port. Also used for
014 * the USB SPROG, which appears to the computer as a serial port.
015 * <p>
016 * The current implementation only handles the 9,600 baud rate, and does not use
017 * any other options at configuration time.
018 *
019 * Updated January 2010 for gnu io (RXTX) - Andrew Berridge.
020 *
021 * @author Bob Jacobsen Copyright (C) 2001, 2002
022 */
023public class SerialDriverAdapter extends SprogPortController {
024
025    public SerialDriverAdapter() {
026        super(new SprogSystemConnectionMemo(SprogMode.SERVICE));
027        // Set the username to match name, once refactored to handle multiple connections or user setable names/prefixes then this can be removed
028        this.baudRate = 9600;
029        this.getSystemConnectionMemo().setUserName(Bundle.getMessage("SprogProgrammerTitle"));
030        // create the traffic controller
031        this.getSystemConnectionMemo().setSprogTrafficController(new SprogTrafficController(this.getSystemConnectionMemo()));
032    }
033
034    public SerialDriverAdapter(SprogMode sm) {
035        super(new SprogSystemConnectionMemo(sm));
036        this.baudRate = 9600;
037        this.getSystemConnectionMemo().setUserName("SPROG");
038        // create the traffic controller
039        this.getSystemConnectionMemo().setSprogTrafficController(new SprogTrafficController(this.getSystemConnectionMemo()));
040    }
041
042    public SerialDriverAdapter(SprogMode sm, int baud, SprogType type) {
043        super(new SprogSystemConnectionMemo(sm, type));
044        this.baudRate = baud;
045        this.getSystemConnectionMemo().setUserName("SPROG");
046        // create the traffic controller
047        this.getSystemConnectionMemo().setSprogTrafficController(new SprogTrafficController(this.getSystemConnectionMemo()));
048    }
049
050    public SerialDriverAdapter(SprogMode sm, int baud) {
051        super(new SprogSystemConnectionMemo(sm));
052        this.baudRate = baud;
053        this.getSystemConnectionMemo().setUserName("SPROG");
054        // create the traffic controller
055        this.getSystemConnectionMemo().setSprogTrafficController(new SprogTrafficController(this.getSystemConnectionMemo()));
056    }
057
058    private int baudRate = -1;
059
060    @Override
061    public String openPort(String portName, String appName) {
062        // get and open the primary port
063        currentSerialPort = activatePort(portName, log);
064        if (currentSerialPort == null) {
065            log.error("failed to connect SPROG to {}", portName);
066            return Bundle.getMessage("SerialPortNotFound", portName);
067        }
068        log.info("Connecting SPROG to {} {}", portName, currentSerialPort);
069
070        // try to set it for communication via SerialDriver
071        setBaudRate(currentSerialPort, baudRate);
072        configureLeads(currentSerialPort, true, true);
073        setFlowControl(currentSerialPort, FlowControl.NONE);
074
075        // add Sprog Traffic Controller as event listener
076        currentSerialPort.addDataListener( new SerialPortDataListener() {
077            @Override
078            public int getListeningEvents() {
079                log.trace("getListeningEvents");
080                return SerialPort.LISTENING_EVENT_DATA_AVAILABLE;
081            }
082            @Override
083            public void serialEvent(SerialPortEvent event) {
084                log.trace("serial event start");
085                // invoke
086                getSystemConnectionMemo().getSprogTrafficController().handleOneIncomingReply();
087                log.trace("serial event end");
088            }
089        }
090        );
091
092        // report status
093        reportPortStatus(log, portName);
094
095        opened = true;
096        return null; // indicates OK return
097
098    }
099
100    /**
101     * Set the flow control. This method hide the
102     * actual serial port behind this object
103     * @param flow Set flow control to RTS/CTS when true
104     */
105    public void setHandshake(FlowControl flow) {
106        setFlowControl(currentSerialPort, flow);
107    }
108
109    /**
110     * {@inheritDoc}
111     * Currently only 9,600 bps
112     */
113    @Override
114    public String[] validBaudRates() {
115        return new String[]{"9,600 bps"};
116    }
117
118    /**
119     * {@inheritDoc}
120     */
121    @Override
122    public int[] validBaudNumbers() {
123        return new int[]{9600};
124    }
125
126    @Override
127    public int defaultBaudIndex() {
128        return 0;
129    }
130
131    protected int numSlots = 1;
132
133    /**
134     * Set up all of the other objects to operate with an Sprog command station
135     * connected to this port.
136     */
137    @Override
138    public void configure() {
139        // connect to the traffic controller
140        this.getSystemConnectionMemo().getSprogTrafficController().connectPort(this);
141
142        log.debug("Configure command station");
143        this.getSystemConnectionMemo().configureCommandStation(numSlots, getOptionState("TrackPowerState"));
144        this.getSystemConnectionMemo().configureManagers();
145
146        if (getOptionState("TrackPowerState") != null && getOptionState("TrackPowerState").equals(Bundle.getMessage("PowerStateOn"))) {
147            try {
148                this.getSystemConnectionMemo().getPowerManager().setPower(jmri.PowerManager.ON);
149            } catch (jmri.JmriException e) {
150                log.error("Error setting power on {}", e.toString());
151            }
152        }
153    }
154
155    @Override
156    public void dispose() {
157        // if we've started a traffic controller, dispose of it
158        if (this.getSystemConnectionMemo() != null) {
159            if ( (this.getSystemConnectionMemo()).getSprogTrafficController() != null)
160                (this.getSystemConnectionMemo()).getSprogTrafficController().dispose();
161        }
162        super.dispose();
163    }
164
165    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(SerialDriverAdapter.class);
166
167}