001package jmri.jmrix.marklin; 002 003/** 004 * Encodes a message to a Marklin command station. 005 * <p> 006 * The {@link MarklinReply} class handles the response from the command station. 007 * Packages of length 13 are interpreted as can-bus packages: 008 * 4 bytes Can-bus-ID (BigEndian or network order), 009 * 1-byte length and 010 * 8 bytes of data, if necessary with null bytes to fill in. 011 * <p> 012 * The message ID is divided into the areas of lower priority (priority), 013 * command (command), response and hash. 014 * The communication is based on the following format: 015 * Prio - 2 +2bit 016 * Command 8 bit 017 * Resp - 1 bit 018 * Hash - 16bit 019 * DLC - 4bit (ie CAN message length) 020 * CAN message 8 BYTES 021 * Can Message Bytes 0 to 3 are the address bytes, with byte 0 High, byte 3 low 022 * @author Kevin Dickerson Copyright (C) 2001, 2008 023 */ 024public class MarklinMessage extends jmri.jmrix.AbstractMRMessage { 025 026 static int MY_UID = 0x12345678; 027 028 MarklinMessage() { 029 _dataChars = new int[13]; 030 _nDataChars = 13; 031 setBinary(true); 032 for (int i = 0; i < 13; i++) { 033 _dataChars[i] = 0x00; 034 } 035 } 036 037 // create a new one from an array 038 public MarklinMessage(int[] d) { 039 this(); 040 System.arraycopy(d, 0, _dataChars, 0, d.length); 041 } 042 043 // create a new one from a byte array, as a service 044 public MarklinMessage(byte[] d) { 045 this(); 046 for (int i = 0; i < d.length; i++) { 047 _dataChars[i] = d[i] & 0xFF; 048 } 049 } 050 051 // create a new one 052 public MarklinMessage(int i) { 053 this(); 054 } 055 056 // copy one 057 public MarklinMessage(MarklinMessage m) { 058 super(m); 059 } 060 061 // static methods to return a formatted message 062 public static MarklinMessage getEnableMain() { 063 MarklinMessage m = new MarklinMessage(); 064 m.setElement(0, MarklinConstants.SYSCOMMANDSTART & 0xFF); 065 m.setElement(1, 0x00 & 0xFF); 066 m.setElement(2, MarklinConstants.HASHBYTE1 & 0xFF); 067 m.setElement(3, MarklinConstants.HASHBYTE2 & 0xFF); 068 m.setElement(4, 0x05 & 0xFF); //five bytes; 069 //5, 6, 7, 8 Address but this is a global command 070 m.setElement(9, MarklinConstants.CMDGOSYS & 0xFF); //Turn main on 0x01 071 return m; 072 } 073 074 public static MarklinMessage getKillMain() { 075 MarklinMessage m = new MarklinMessage(); 076 m.setElement(0, MarklinConstants.SYSCOMMANDSTART & 0xFF); 077 m.setElement(1, 0x00 & 0xFF); 078 m.setElement(2, MarklinConstants.HASHBYTE1 & 0xFF); 079 m.setElement(3, MarklinConstants.HASHBYTE2 & 0xFF); 080 m.setElement(4, 0x05 & 0xFF); //five bytes; 081 //5, 6, 7, 8 Address but this is a global command 082 m.setElement(9, MarklinConstants.CMDSTOPSYS & 0xFF); //Turn main off 0x00 083 return m; 084 } 085 086 //static public MarklinMessage get 087 public static MarklinMessage getSetTurnout(int addr, int state, int power) { 088 MarklinMessage m = new MarklinMessage(); 089 m.setElement(0, (MarklinConstants.ACCCOMMANDSTART >> 7) & 0xFF); 090 m.setElement(1, (MarklinConstants.ACCCOMMANDSTART << 1) & 0xFF); 091 m.setElement(2, MarklinConstants.HASHBYTE1 & 0xFF); 092 m.setElement(3, MarklinConstants.HASHBYTE2 & 0xFF); 093 m.setElement(4, 0x06 & 0xFF); //five bytes; 094 m.setElement(MarklinConstants.CANADDRESSBYTE1, (addr >> 24) & 0xFF); 095 m.setElement(MarklinConstants.CANADDRESSBYTE2, (addr >> 16) & 0xFF); 096 m.setElement(MarklinConstants.CANADDRESSBYTE3, (addr >> 8) & 0xFF); 097 m.setElement(MarklinConstants.CANADDRESSBYTE4, (addr) & 0xFF); 098 m.setElement(9, state & 0xff); 099 m.setElement(10, power & 0xff); 100 return m; 101 } 102 103 public static MarklinMessage getQryLocoSpeed(int addr) { 104 MarklinMessage m = new MarklinMessage(); 105 m.setElement(0, (MarklinConstants.LOCOSPEED >> 7) & 0xFF); 106 m.setElement(1, (MarklinConstants.LOCOSPEED << 1) & 0xFF); 107 m.setElement(2, MarklinConstants.HASHBYTE1 & 0xFF); 108 m.setElement(3, MarklinConstants.HASHBYTE2 & 0xFF); 109 m.setElement(4, 0x04 & 0xFF); 110 m.setElement(MarklinConstants.CANADDRESSBYTE1, (addr >> 24) & 0xFF); 111 m.setElement(MarklinConstants.CANADDRESSBYTE2, (addr >> 16) & 0xFF); 112 m.setElement(MarklinConstants.CANADDRESSBYTE3, (addr >> 8) & 0xFF); 113 m.setElement(MarklinConstants.CANADDRESSBYTE4, (addr) & 0xFF); 114 return m; 115 } 116 117 public static MarklinMessage setLocoSpeed(int addr, int speed) { 118 MarklinMessage m = new MarklinMessage(); 119 m.setElement(0, (MarklinConstants.LOCOSPEED >> 7) & 0xFF); 120 m.setElement(1, (MarklinConstants.LOCOSPEED << 1) & 0xFF); 121 m.setElement(2, MarklinConstants.HASHBYTE1 & 0xFF); 122 m.setElement(3, MarklinConstants.HASHBYTE2 & 0xFF); 123 m.setElement(4, 0x06 & 0xFF); 124 m.setElement(MarklinConstants.CANADDRESSBYTE1, (addr >> 24) & 0xFF); 125 m.setElement(MarklinConstants.CANADDRESSBYTE2, (addr >> 16) & 0xFF); 126 m.setElement(MarklinConstants.CANADDRESSBYTE3, (addr >> 8) & 0xFF); 127 m.setElement(MarklinConstants.CANADDRESSBYTE4, (addr) & 0xFF); 128 m.setElement(9, (speed >> 8) & 0xff); 129 m.setElement(10, speed & 0xff); 130 return m; 131 } 132 133 public static MarklinMessage setLocoEmergencyStop(int addr) { 134 MarklinMessage m = new MarklinMessage(); 135 m.setElement(0, MarklinConstants.SYSCOMMANDSTART & 0xFF); 136 m.setElement(1, 0x00 & 0xFF); 137 m.setElement(2, MarklinConstants.HASHBYTE1 & 0xFF); 138 m.setElement(3, MarklinConstants.HASHBYTE2 & 0xFF); 139 m.setElement(4, 0x05 & 0xFF); //five bytes; 140 m.setElement(MarklinConstants.CANADDRESSBYTE1, (addr >> 24) & 0xFF); 141 m.setElement(MarklinConstants.CANADDRESSBYTE2, (addr >> 16) & 0xFF); 142 m.setElement(MarklinConstants.CANADDRESSBYTE3, (addr >> 8) & 0xFF); 143 m.setElement(MarklinConstants.CANADDRESSBYTE4, (addr) & 0xFF); 144 m.setElement(9, MarklinConstants.LOCOEMERGENCYSTOP & 0xFF); 145 return m; 146 } 147 148 public static MarklinMessage setLocoSpeedSteps(int addr, int step) { 149 MarklinMessage m = new MarklinMessage(); 150 m.setElement(0, MarklinConstants.SYSCOMMANDSTART & 0xFF); 151 m.setElement(1, 0x00 & 0xFF); 152 m.setElement(2, MarklinConstants.HASHBYTE1 & 0xFF); 153 m.setElement(3, MarklinConstants.HASHBYTE2 & 0xFF); 154 m.setElement(4, 0x05 & 0xFF); //five bytes; 155 m.setElement(MarklinConstants.CANADDRESSBYTE1, (addr >> 24) & 0xFF); 156 m.setElement(MarklinConstants.CANADDRESSBYTE2, (addr >> 16) & 0xFF); 157 m.setElement(MarklinConstants.CANADDRESSBYTE3, (addr >> 8) & 0xFF); 158 m.setElement(MarklinConstants.CANADDRESSBYTE4, (addr) & 0xFF); 159 m.setElement(9, 0x05 & 0xFF); 160 m.setElement(10, step & 0xFF); 161 return m; 162 } 163 164 public static MarklinMessage getQryLocoDirection(int addr) { 165 MarklinMessage m = new MarklinMessage(); 166 m.setElement(0, (MarklinConstants.LOCODIRECTION >> 7) & 0xFF); 167 m.setElement(1, (MarklinConstants.LOCODIRECTION << 1) & 0xFF); 168 m.setElement(2, MarklinConstants.HASHBYTE1 & 0xFF); 169 m.setElement(3, MarklinConstants.HASHBYTE2 & 0xFF); 170 m.setElement(4, 0x04 & 0xFF); 171 m.setElement(MarklinConstants.CANADDRESSBYTE1, (addr >> 24) & 0xFF); 172 m.setElement(MarklinConstants.CANADDRESSBYTE2, (addr >> 16) & 0xFF); 173 m.setElement(MarklinConstants.CANADDRESSBYTE3, (addr >> 8) & 0xFF); 174 m.setElement(MarklinConstants.CANADDRESSBYTE4, (addr) & 0xFF); 175 return m; 176 } 177 178 public static MarklinMessage setLocoDirection(int addr, int dir) { 179 MarklinMessage m = new MarklinMessage(); 180 m.setElement(0, (MarklinConstants.LOCODIRECTION >> 7) & 0xFF); 181 m.setElement(1, (MarklinConstants.LOCODIRECTION << 1) & 0xFF); 182 m.setElement(2, MarklinConstants.HASHBYTE1 & 0xFF); 183 m.setElement(3, MarklinConstants.HASHBYTE2 & 0xFF); 184 m.setElement(4, 0x05 & 0xFF); 185 m.setElement(MarklinConstants.CANADDRESSBYTE1, (addr >> 24) & 0xFF); 186 m.setElement(MarklinConstants.CANADDRESSBYTE2, (addr >> 16) & 0xFF); 187 m.setElement(MarklinConstants.CANADDRESSBYTE3, (addr >> 8) & 0xFF); 188 m.setElement(MarklinConstants.CANADDRESSBYTE4, (addr) & 0xFF); 189 m.setElement(9, dir & 0xff); 190 return m; 191 } 192 193 public static MarklinMessage getQryLocoFunction(int addr, int funct) { 194 MarklinMessage m = new MarklinMessage(); 195 m.setElement(0, (MarklinConstants.LOCOFUNCTION >> 7) & 0xFF); 196 m.setElement(1, (MarklinConstants.LOCOFUNCTION << 1) & 0xFF); 197 m.setElement(2, MarklinConstants.HASHBYTE1 & 0xFF); 198 m.setElement(3, MarklinConstants.HASHBYTE2 & 0xFF); 199 m.setElement(4, 0x05 & 0xFF); 200 m.setElement(MarklinConstants.CANADDRESSBYTE1, (addr >> 24) & 0xFF); 201 m.setElement(MarklinConstants.CANADDRESSBYTE2, (addr >> 16) & 0xFF); 202 m.setElement(MarklinConstants.CANADDRESSBYTE3, (addr >> 8) & 0xFF); 203 m.setElement(MarklinConstants.CANADDRESSBYTE4, (addr) & 0xFF); 204 m.setElement(9, (funct) & 0xFF); 205 return m; 206 } 207 208 public static MarklinMessage setLocoFunction(int addr, int funct, int state) { 209 MarklinMessage m = new MarklinMessage(); 210 m.setElement(0, (MarklinConstants.LOCOFUNCTION >> 7) & 0xFF); 211 m.setElement(1, (MarklinConstants.LOCOFUNCTION << 1) & 0xFF); 212 m.setElement(2, MarklinConstants.HASHBYTE1 & 0xFF); 213 m.setElement(3, MarklinConstants.HASHBYTE2 & 0xFF); 214 m.setElement(4, 0x06 & 0xFF); 215 m.setElement(MarklinConstants.CANADDRESSBYTE1, (addr >> 24) & 0xFF); 216 m.setElement(MarklinConstants.CANADDRESSBYTE2, (addr >> 16) & 0xFF); 217 m.setElement(MarklinConstants.CANADDRESSBYTE3, (addr >> 8) & 0xFF); 218 m.setElement(MarklinConstants.CANADDRESSBYTE4, (addr) & 0xFF); 219 m.setElement(9, funct & 0xff); 220 m.setElement(10, state & 0xff); 221 m.getAddress(); 222 return m; 223 } 224 225 public static MarklinMessage sensorPollMessage(int module) { 226 MarklinMessage m = new MarklinMessage(); 227 m.setElement(0, (MarklinConstants.FEECOMMANDSTART >> 7) & 0xFF); 228 m.setElement(1, (MarklinConstants.FEECOMMANDSTART << 1) & 0xFF); 229 m.setElement(2, MarklinConstants.HASHBYTE1 & 0xFF); 230 m.setElement(3, MarklinConstants.HASHBYTE2 & 0xFF); 231 m.setElement(4, 0x05 & 0xFF); //five bytes; 232 m.setElement(MarklinConstants.CANADDRESSBYTE1, (MY_UID >> 24) & 0xFF); 233 m.setElement(MarklinConstants.CANADDRESSBYTE2, (MY_UID >> 16) & 0xFF); 234 m.setElement(MarklinConstants.CANADDRESSBYTE3, (MY_UID >> 8) & 0xFF); 235 m.setElement(MarklinConstants.CANADDRESSBYTE4, (MY_UID) & 0xFF); 236 m.setElement(9, module & 0xFF); 237 return m; 238 } 239 240 public long getAddress() { 241 long addr = getElement(MarklinConstants.CANADDRESSBYTE1); 242 addr = (addr << 8) + getElement(MarklinConstants.CANADDRESSBYTE2); 243 addr = (addr << 8) + getElement(MarklinConstants.CANADDRESSBYTE3); 244 addr = (addr << 8) + getElement(MarklinConstants.CANADDRESSBYTE4); 245 246 return addr; 247 } 248 249 public static MarklinMessage getProgMode() { 250 return new MarklinMessage(); 251 } 252 253 public static MarklinMessage getExitProgMode() { 254 return new MarklinMessage(); 255 } 256 257 public static MarklinMessage getReadPagedCV(int cv) { //Rxxx 258 return new MarklinMessage(); 259 } 260 261 public static MarklinMessage getWritePagedCV(int cv, int val) { //Pxxx xxx 262 return new MarklinMessage(); 263 } 264 265 public static MarklinMessage getReadRegister(int reg) { //Vx 266 return new MarklinMessage(); 267 } 268 269 public static MarklinMessage getWriteRegister(int reg, int val) { //Sx xxx 270 return new MarklinMessage(); 271 } 272 273 public static MarklinMessage getReadDirectCV(int cv) { //Rxxx 274 return new MarklinMessage(); 275 } 276 277 public static MarklinMessage getWriteDirectCV(int cv, int val) { //Pxxx xxx 278 return new MarklinMessage(); 279 } 280}