001package jmri.jmrix.nce.usbdriver;
002
003import java.util.Arrays;
004import jmri.jmrix.nce.NcePortController;
005import jmri.jmrix.nce.NceSystemConnectionMemo;
006import jmri.jmrix.nce.NceTrafficController;
007
008/**
009 * Implements UsbPortAdapter for the NCE system.
010 * <p>
011 * This connects an NCE PowerCab or PowerPro via a USB port. Normally
012 * controlled by the UsbDriverFrame class.
013 *
014 * @author Bob Jacobsen Copyright (C) 2001, 2002
015 * @author Daniel Boudreau Copyright (C) 2007
016 * @author Ken Cameron Copyright (C) 2013, 2023
017 */
018public class UsbDriverAdapter extends NcePortController {
019
020    public UsbDriverAdapter() {
021        super(new NceSystemConnectionMemo());
022        option1Name = "System"; // NOI18N
023        options.put(option1Name, new Option(Bundle.getMessage("SystemLabel"), option1Values, false));
024        option2Name = "USB Version"; // NOI18N
025        options.put(option2Name, new Option(Bundle.getMessage("UsbVersionLabel"), option2Values, false));
026        // Set default USB version to V7.x.x
027        setOptionState(option2Name, getOptionChoices(option2Name)[1]);
028    }
029
030    @Override
031    public String openPort(String portName, String appName) {
032
033        // get and open the primary port
034        currentSerialPort = activatePort(portName, log);
035        if (currentSerialPort == null) {
036            log.error("failed to connect NCE USB to {}", portName);
037            return Bundle.getMessage("SerialPortNotFound", portName);
038        }
039        log.info("Connecting NCE USB to {} {}", portName, currentSerialPort);
040        
041        // try to set it for communication via SerialDriver
042        // find the baud rate value, configure comm options
043        int baud = currentBaudNumber(mBaudRate);
044        setBaudRate(currentSerialPort, baud);
045        configureLeads(currentSerialPort, true, true);
046        setFlowControl(currentSerialPort, FlowControl.NONE);
047
048        // report status
049        reportPortStatus(log, portName);
050
051        opened = true;
052
053        return null; // indicates OK return
054    }
055
056    String[] option1Values = new String[]{"PowerCab", "SB3/SB3a", "Power Pro", "Twin", "SB5"}; // NOI18N
057    String[] option2Values = new String[]{"V6.x.x", "V7.x.x"}; // NOI18N
058
059    /**
060     * Set up all of the other objects to operate with an NCE command station
061     * connected to this port.
062     */
063    @Override
064    public void configure() {
065        log.trace("configure with {}", getSystemConnectionMemo());
066        NceTrafficController tc = new NceTrafficController();
067        this.getSystemConnectionMemo().setNceTrafficController(tc);
068        tc.setAdapterMemo(this.getSystemConnectionMemo());
069
070        //set the system the USB is connected to
071        if (getOptionState(option2Name).equals(getOptionChoices(option2Name)[1])) { //if V7 (Nov 2012)
072            // is new firmware, determine functions available
073            if (getOptionState(option1Name).equals(getOptionChoices(option1Name)[4])) { //SB5
074                tc.setUsbSystem(NceTrafficController.USB_SYSTEM_SB5);
075                tc.setCmdGroups(NceTrafficController.CMDS_MEM
076                        | NceTrafficController.CMDS_AUI_READ
077                        | NceTrafficController.CMDS_OPS_PGM
078                        | NceTrafficController.CMDS_USB
079                        | NceTrafficController.CMDS_ALL_SYS);
080                this.getSystemConnectionMemo().configureCommandStation(NceTrafficController.OPTION_1_65);
081
082            } else if (getOptionState(option1Name).equals(getOptionChoices(option1Name)[3])) { //TWIN
083                tc.setUsbSystem(NceTrafficController.USB_SYSTEM_TWIN);
084                tc.setCmdGroups(NceTrafficController.CMDS_MEM
085                        | NceTrafficController.CMDS_AUI_READ
086                        | NceTrafficController.CMDS_PROGTRACK
087                        | NceTrafficController.CMDS_OPS_PGM
088                        | NceTrafficController.CMDS_USB
089                        | NceTrafficController.CMDS_ALL_SYS);
090                this.getSystemConnectionMemo().configureCommandStation(NceTrafficController.OPTION_1_65);
091            } else if (getOptionState(option1Name).equals(getOptionChoices(option1Name)[2])) { //PowerPro
092                tc.setUsbSystem(NceTrafficController.USB_SYSTEM_POWERPRO);
093                tc.setCmdGroups(NceTrafficController.CMDS_USB
094                        | NceTrafficController.CMDS_ALL_SYS);
095                this.getSystemConnectionMemo().configureCommandStation(NceTrafficController.OPTION_2006);
096            } else if (getOptionState(option1Name).equals(getOptionChoices(option1Name)[1])) { //SB3
097                tc.setUsbSystem(NceTrafficController.USB_SYSTEM_SB3);
098                tc.setCmdGroups(NceTrafficController.CMDS_OPS_PGM
099                        | NceTrafficController.CMDS_USB
100                        | NceTrafficController.CMDS_ALL_SYS);
101                this.getSystemConnectionMemo().configureCommandStation(NceTrafficController.OPTION_1_28);
102            } else { //PowerCab
103                tc.setUsbSystem(NceTrafficController.USB_SYSTEM_POWERCAB);
104                tc.setCmdGroups(NceTrafficController.CMDS_MEM
105                        | NceTrafficController.CMDS_AUI_READ
106                        | NceTrafficController.CMDS_PROGTRACK
107                        | NceTrafficController.CMDS_OPS_PGM
108                        | NceTrafficController.CMDS_USB
109                        | NceTrafficController.CMDS_ALL_SYS);
110                this.getSystemConnectionMemo().configureCommandStation(NceTrafficController.OPTION_1_65);
111            }
112        } else {
113            // old firmware, original functions
114            if (getOptionState(option1Name).equals(getOptionChoices(option1Name)[4])) {
115                tc.setUsbSystem(NceTrafficController.USB_SYSTEM_SB5);
116                tc.setCmdGroups(NceTrafficController.CMDS_OPS_PGM
117                        | NceTrafficController.CMDS_USB
118                        | NceTrafficController.CMDS_ALL_SYS);
119                this.getSystemConnectionMemo().configureCommandStation(NceTrafficController.OPTION_1_28);
120            } else if (getOptionState(option1Name).equals(getOptionChoices(option1Name)[3])) {
121                tc.setUsbSystem(NceTrafficController.USB_SYSTEM_TWIN);
122                tc.setCmdGroups(NceTrafficController.CMDS_OPS_PGM
123                        | NceTrafficController.CMDS_USB
124                        | NceTrafficController.CMDS_ALL_SYS);
125                this.getSystemConnectionMemo().configureCommandStation(NceTrafficController.OPTION_1_28);
126            } else if (getOptionState(option1Name).equals(getOptionChoices(option1Name)[2])) {
127                tc.setUsbSystem(NceTrafficController.USB_SYSTEM_POWERPRO);
128                tc.setCmdGroups(NceTrafficController.CMDS_NONE
129                        | NceTrafficController.CMDS_USB
130                        | NceTrafficController.CMDS_ALL_SYS);
131                this.getSystemConnectionMemo().configureCommandStation(NceTrafficController.OPTION_2006);
132            } else if (getOptionState(option1Name).equals(getOptionChoices(option1Name)[1])) {
133                tc.setUsbSystem(NceTrafficController.USB_SYSTEM_SB3);
134                tc.setCmdGroups(NceTrafficController.CMDS_ACCYADDR250
135                        | NceTrafficController.CMDS_OPS_PGM
136                        | NceTrafficController.CMDS_USB
137                        | NceTrafficController.CMDS_ALL_SYS);
138                this.getSystemConnectionMemo().configureCommandStation(NceTrafficController.OPTION_1_28);
139            } else {
140                tc.setUsbSystem(NceTrafficController.USB_SYSTEM_POWERCAB);
141                tc.setCmdGroups(NceTrafficController.CMDS_PROGTRACK
142                        | NceTrafficController.CMDS_OPS_PGM
143                        | NceTrafficController.CMDS_USB
144                        | NceTrafficController.CMDS_ALL_SYS);
145                this.getSystemConnectionMemo().configureCommandStation(NceTrafficController.OPTION_1_28);
146            }
147        }
148
149        tc.connectPort(this);
150
151        this.getSystemConnectionMemo().configureManagers();
152        tc.csm = new UsbCmdStationMemory();
153    }
154
155    // base class methods for the NcePortController interface
156
157    @Override
158    public boolean status() {
159        return opened;
160    }
161
162    /**
163     * {@inheritDoc}
164     */
165    @Override
166    public String[] validBaudRates() {
167        return Arrays.copyOf(validSpeeds, validSpeeds.length);
168    }
169
170    /**
171     * {@inheritDoc}
172     */
173    @Override
174    public int[] validBaudNumbers() {
175        return Arrays.copyOf(validSpeedValues, validSpeedValues.length);
176    }
177
178    private String[] validSpeeds = new String[]{Bundle.getMessage("Baud9600"), Bundle.getMessage("Baud19200")};
179    private int[] validSpeedValues = new int[]{9600, 19200};
180
181    @Override
182    public int defaultBaudIndex() {
183        return 0;
184    }
185
186    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(UsbDriverAdapter.class);
187
188}