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