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