001package jmri.jmrix.mrc; 002 003import java.util.ArrayList; 004import java.util.List; 005import javax.annotation.Nonnull; 006 007import jmri.ProgListener; 008import jmri.ProgrammerException; 009import jmri.ProgrammingMode; 010import org.slf4j.Logger; 011import org.slf4j.LoggerFactory; 012 013/** 014 * Provide an Ops Mode Programmer via a wrapper what works with the MRC command 015 * station object. 016 * <p> 017 * Functionally, this just creates packets to send via the command station. 018 * 019 * @see jmri.Programmer 020 * @author Bob Jacobsen Copyright (C) 2002 021 * @author Ken Cameron Copyright (C) 2014 022 * @author Kevin Dickerson Copyright (C) 2014 023 */ 024public class MrcOpsModeProgrammer extends MrcProgrammer implements jmri.AddressedProgrammer { 025 026 int mAddress; 027 boolean mLongAddr; 028 029 public MrcOpsModeProgrammer(MrcSystemConnectionMemo memo, int pAddress, boolean pLongAddr) { 030 super(memo); 031 log.debug("MRC ops mode programmer {} {}", pAddress, pLongAddr); // NOI18N 032 if (pLongAddr) { 033 addressLo = pAddress; 034 addressHi = pAddress >> 8; 035 addressHi = addressHi + 0xc0; //We add 0xc0 to the high byte. 036 } else { 037 addressLo = pAddress; 038 } 039 } 040 041 int addressLo = 0x00; 042 int addressHi = 0x00; 043 044 /** 045 * {@inheritDoc} 046 * 047 * Forward a write request to an ops-mode write operation 048 */ 049 @Override 050 public synchronized void writeCV(String CVname, int val, ProgListener p) throws ProgrammerException { 051 final int CV = Integer.parseInt(CVname); 052 log.debug("write CV={} val={}", CV, val); // NOI18N 053 MrcMessage msg = MrcMessage.getPOM(addressLo, addressHi, CV, val); 054 055 useProgrammer(p); 056 _progRead = false; 057 progState = POMCOMMANDSENT; 058 _val = val; 059 _cv = CV; 060 061 // start the error timer 062 startShortTimer(); 063 064 memo.getMrcTrafficController().sendMrcMessage(msg); 065 } 066 067 /** 068 * {@inheritDoc} 069 */ 070 @Override 071 public synchronized void readCV(String CVname, ProgListener p) throws ProgrammerException { 072 final int CV = Integer.parseInt(CVname); 073 log.debug("read CV={}", CV); 074 log.error("readCV not available in this protocol"); // NOI18N 075 throw new ProgrammerException(); 076 } 077 078 /** 079 * {@inheritDoc} 080 */ 081 @Override 082 public synchronized void confirmCV(String CV, int val, ProgListener p) throws ProgrammerException { 083 log.debug("confirm CV={}", CV); 084 log.error("confirmCV not available in this protocol"); // NOI18N 085 throw new ProgrammerException(); 086 } 087 088 /** 089 * {@inheritDoc} 090 */ 091 // add 200mSec between commands, so MRC command station queue doesn't get overrun 092 @Override 093 protected void notifyProgListenerEnd(int value, int status) { 094 log.debug("MrcOpsModeProgrammer adds 200mSec delay to response"); // NOI18N 095 try { 096 wait(200); 097 } catch (InterruptedException e) { 098 log.debug("unexpected exception", e); // NOI18N 099 } 100 super.notifyProgListenerEnd(value, status); 101 } 102 103 /** 104 * {@inheritDoc} 105 * 106 * Types implemented here. 107 */ 108 @Override 109 @Nonnull 110 public List<ProgrammingMode> getSupportedModes() { 111 List<ProgrammingMode> ret = new ArrayList<ProgrammingMode>(); 112 ret.add(ProgrammingMode.OPSBYTEMODE); 113 return ret; 114 } 115 116 /** 117 * {@inheritDoc} 118 * 119 * Can this ops-mode programmer read back values? For now, no, but maybe 120 * later. 121 * 122 * @return always false for now 123 */ 124 @Override 125 public boolean getCanRead() { 126 return false; 127 } 128 129 /** 130 * {@inheritDoc} 131 */ 132 @Override 133 public boolean getLongAddress() { 134 return mLongAddr; 135 } 136 137 /** 138 * {@inheritDoc} 139 */ 140 @Override 141 public int getAddressNumber() { 142 return mAddress; 143 } 144 145 /** 146 * {@inheritDoc} 147 */ 148 @Override 149 public String getAddress() { 150 return "" + getAddressNumber() + " " + getLongAddress(); 151 } 152 153 /** 154 * {@inheritDoc} 155 * 156 * Ops-mode programming doesn't put the command station in programming mode, 157 * so we don't have to send an exit-programming command at end. Therefore, 158 * this routine does nothing except to replace the parent routine that does 159 * something. 160 */ 161 @Override 162 void cleanup() { 163 } 164 165 // initialize logging 166 private final static Logger log = LoggerFactory.getLogger(MrcOpsModeProgrammer.class); 167 168}