001package jmri.jmrix.tmcc; 002 003import jmri.DccLocoAddress; 004import jmri.LocoAddress; 005import jmri.SpeedStepMode; 006import jmri.jmrix.AbstractThrottle; 007 008/** 009 * An implementation of DccThrottle. 010 * <p> 011 * Addresses of 99 and below are considered short addresses, and over 100 are 012 * considered long addresses. 013 * 014 * @author Bob Jacobsen Copyright (C) 2001, 2006 015 * with edits/additions by 016 * @author Timothy Jump Copyright (C) 2025 017 */ 018public class SerialThrottle extends AbstractThrottle { 019 020 /** 021 * Constructor. 022 * 023 * @param memo the connected SerialTrafficController 024 * @param address Loco ID 025 */ 026 public SerialThrottle(TmccSystemConnectionMemo memo, DccLocoAddress address) { 027 super(memo, 85); // supports 85 functions 028 tc = memo.getTrafficController(); 029 030 // cache settings. It would be better to read the 031 // actual state, but I don't know how to do this 032 synchronized(this) { 033 this.speedSetting = 0; 034 } 035 // Functions default to false 036 this.address = address; 037 this.isForward = true; 038 this.speedStepMode = SpeedStepMode.TMCC1_32; 039 } 040 041 private final DccLocoAddress address; 042 private final SerialTrafficController tc; 043 044 /** 045 * {@inheritDoc} 046 */ 047 @Override 048 public LocoAddress getLocoAddress() { 049 return address; 050 } 051 052 // Relating SERIAL_FUNCTION_CODES_TMCC1 to SpeedStepMode.TMCC1_32 and TMCC1_100; 053 // and SERIAL_FUNCTION_CODES_TMCC2 to SpeedStepMode.TMCC2_32 and TMCC2_200. 054 private long[] getFnValueArray(int number) { 055 056 if (number < 0) return new long[]{}; 057 058 if (getSpeedStepMode() == jmri.SpeedStepMode.TMCC1_32 || getSpeedStepMode() == jmri.SpeedStepMode.TMCC1_100) { 059 if (number < SERIAL_FUNCTION_CODES_TMCC1.length) { 060 return SERIAL_FUNCTION_CODES_TMCC1[number]; 061 } else { 062 return new long[]{}; 063 } 064 } else if (getSpeedStepMode() == jmri.SpeedStepMode.TMCC1TR_32 || getSpeedStepMode() == jmri.SpeedStepMode.TMCC1TR_100) { 065 if (number < SERIAL_FUNCTION_CODES_TMCC1TR.length) { 066 return SERIAL_FUNCTION_CODES_TMCC1TR[number]; 067 } else { 068 return new long[]{}; 069 } 070 } else if (getSpeedStepMode() == jmri.SpeedStepMode.TMCC2_32) { 071 if (number < SERIAL_FUNCTION_CODES_TMCC2_32.length) { 072 return SERIAL_FUNCTION_CODES_TMCC2_32[number]; 073 } else { 074 return new long[]{}; 075 } 076 } else if (getSpeedStepMode() == jmri.SpeedStepMode.TMCC2TR_32) { 077 if (number < SERIAL_FUNCTION_CODES_TMCC2TR_32.length) { 078 return SERIAL_FUNCTION_CODES_TMCC2TR_32[number]; 079 } else { 080 return new long[]{}; 081 } 082 } else if (getSpeedStepMode() == jmri.SpeedStepMode.TMCC2_200) { 083 if (number < SERIAL_FUNCTION_CODES_TMCC2_200.length) { 084 return SERIAL_FUNCTION_CODES_TMCC2_200[number]; 085 } else { 086 return new long[]{}; 087 } 088 } else if (getSpeedStepMode() == jmri.SpeedStepMode.TMCC2TR_200) { 089 if (number < SERIAL_FUNCTION_CODES_TMCC2TR_200.length) { 090 return SERIAL_FUNCTION_CODES_TMCC2TR_200[number]; 091 } else { 092 return new long[]{}; 093 } 094 } 095 return new long[]{}; 096 } 097 098 099 /** 100 * {@inheritDoc} 101 */ 102 @Override 103 public void setFunction(int func, boolean value) { 104 updateFunction(func, value); 105 106 int numberOfTriple = 0; // ordinal number of triple being processed, e.g. 1, 2, 3, ... 107 checksumAccumulator = 0; // zeroes out accumulated checksum after each instance 108 109 if (getFnValueArray(func).length >0) { 110 for (long triple : getFnValueArray(func)) { 111 numberOfTriple = numberOfTriple+1; 112 113 // process each returned command 114 if (func>=0 && func < SERIAL_FUNCTION_CODES_TMCC1.length) { 115 if ( triple > 0xFFFF ) { 116 // TMCC 2 format 117 if (triple > 0xFFFFFF ) { 118 int first = (int)(triple >> 24); 119 int second = (int)(triple & 0xFFFFFF); 120 accumulateChecksum(first); 121 accumulateChecksum(second); 122 123 // if this is the third triple, place the 124 // checksum in its lowest byte 125 if (numberOfTriple == 3) { 126 second = (second &0xFFFFFF00) | ( (~checksumAccumulator) & 0xFF); 127 } 128 129 // doubles are only sent once, not repeating 130 sendOneWordOnce(first + address.getNumber() * 512); 131 sendOneWordOnce(second + address.getNumber() * 512); 132 133 } else { 134 // single message 135 int content = (int)triple + address.getNumber() * 512; 136 accumulateChecksum(content); 137 138 // if this is the third triple, place the 139 // checksum in its lowest byte 140 if (numberOfTriple == 3) { 141 content = (content &0xFFFFFF00) | ( (~checksumAccumulator) & 0xFF); 142 } 143 144 sendFnToLayout(content, func); 145 } 146 } else { 147 // TMCC 1 format 148 sendFnToLayout((int)triple + address.getNumber() * 128, func); 149 } 150 } else { 151 super.setFunction(func, value); 152 } 153 } 154 } else { 155 super.setFunction(func, value); 156 } 157 } 158 159 // accumulate the checksum values into 160 // the checksumAccumulator variable 161 // 162 // Takes the two bottom bytes _only_ and adds them to the accumulation. 163 int checksumAccumulator = 0; 164 private void accumulateChecksum(int input) { 165 int byte1 = input&0xFF; 166 int byte2 = (input >> 8)&0xFF; 167 checksumAccumulator = (checksumAccumulator + byte1+byte2) & 0xFF; 168 } 169 170 // the argument is a long containing 3 bytes. 171 // The first byte is the message opcode 172 private void sendOneWordOnce(int word) { 173 SerialMessage m = new SerialMessage(word); 174 tc.sendSerialMessage(m, null); 175 } 176 177 // TMCC 1 Function Keys to trigger with TMCC1_32 and TMCC1_100 speed steps. 178 private final static long[][] SERIAL_FUNCTION_CODES_TMCC1 = new long[][] { 179 180 // TMCC1 Remote - Defined FnKeys 181 {0x00000D}, // Fn0 (Headlamp) 182 {0x00001D}, // Fn1 (Bell) 183 {0x00001C}, // Fn2 (Horn/Whistle) 184 {0x000005}, // Fn3 (F - Open Front Coupler) 185 {0x000006}, // Fn4 (R - Open Rear Coupler) 186 187 // TMCC1 Remote - Defined KeyPad FnKeys 188 {0x000011}, {0x000012}, {0x000013}, /* Fn5-7 */ // 1-2-3 189 {0x000014}, {0x000015}, {0x000016}, /* Fn8-10 */ // 4-5-6 190 {0x000017}, {0x000018}, {0x000019}, /* Fn11-13 */ // 7-8-9 191 {0x000010}, /* Fn14 */ // 0 192 193 // TMCC1 Remote - Defined FnKeys 194 {0x000009}, // Fn15 (Aux1) 195 {0x00001E}, // Fn16 (Letoff Sound) 196 {0x000004}, // Fn17 (Boost) 197 {0x000007}, // Fn18 (Brake) 198 {0x000028}, // Fn19 (Momentum Low) 199 {0x000029}, // Fn20 (Momentum Medium) 200 {0x00002A}, // Fn21 (Momentum High) 201 {0x00002B}, // Fn22 (Set) 202 {0x00001F}, // Fn23 (Horn 2) 203 204 // TMCC1 RR Speed FnKeys 205 {0x000064}, // Fn24 ( 4) 5mph 206 {0x00006A}, // Fn25 (10) 20mph 207 {0x00006E}, // Fn26 (14) 35mph 208 {0x000072}, // Fn27 (18) 50mph 209 {0x000078}, // Fn28 (24) 70mph 210 {0x00007F}, // Fn29 (31) Full 211 212 // TMCC1 ERR - Set SpeedSteps 213 {0x000009, 0x000010, 0x000009, 0x000010, 0x000004}, // Fn30 (Set ERR 100 SpeedSteps) 214 {0x000009, 0x000010, 0x000009, 0x000010, 0x000007}, // Fn31 (Set ERR 32 SpeedSteps) 215 216 // TMCC1 Acela/Subway FnKeys 217 {0x000009, 0x000005}, // Fn32 (Open Doors - Left) 218 {0x00000D, 0x000005, 0x00000D}, // Fn33 (Close Doors - Left) 219 {0x000009, 0x000006}, // Fn34 (Open Doors - Right) 220 {0x00000D, 0x000006, 0x00000D}, // Fn35 (Close Doors - Right) 221 {0x000009, 0x000013}, // Fn36 (Pantagraph - Automatic/Prototypical) 222 {0x000009, 0x000015}, // Fn37 (Pantagraph - Down) 223 {0x000009, 0x000016}, // Fn38 (Pantagraph - Manual Mode/Cycles Through Positions) 224 {0x000009, 0x00001C}, // Fn39 (Toggle Horn - City/Country) 225 {0x000009, 0x000018}, // Fn40 (Cab Light - Off) 226 {0x000009, 0x000019}, // Fn41 (Cab Light - On) 227 {0x000009, 0x00000D, 0x000018, 0x00000D}, // Fn42 (Interior Lights - Off) 228 {0x000009, 0x00000D, 0x000019, 0x00000D}, // Fn43 (Interior Lights - On) 229 230 // TMCC1 Break-Down B Unit 231 {0x000009, 0x000004}, // Fn44 Start Breakdown Sequence 232 {0x000009, 0x000015}, // Fn45 Made It Back to the Yard 233 {0x000009, 0x000013}, // Fn46 Restart Unit/Repairs Complete 234 235 // TMCC1 Boxcar/LiveStock Car 236 {0x000009, 0x000013}, // Fn47 Load 237 {0x000009, 0x000012}, // Fn48 Flat Wheel Sound 238 239 // TMCC1 Passenger/Dining Cars 240 {0x000009, 0x000017}, // Fn49 Station PA Arrival Dialog 241 {0x000009, 0x000012}, // Fn50 Conductor Arrival Dialog 242 243 // TMCC1 Crane/Boom Car 244 {0x000009, 0x000011, 0x000007}, // Fn51 Lower the Boom 245 {0x000009, 0x000011, 0x000004}, // Fn52 Raises the Boom 246 {0x000009, 0x000012, 0x000007}, // Fn53 Lowers Main/Large Hook 247 {0x000009, 0x000012, 0x000004}, // Fn54 Raises Main/Large Hook 248 {0x000017, 0x000013, 0x000007}, // Fn55 Lowers Small Hook 249 {0x000017, 0x000013, 0x000004}, // Fn56 Raises Small Hook 250 {0x000004, 0x000014}, // Fn57 Front Work Lights (Toggles On/Off) 251 {0x000004, 0x000015}, // Fn58 Rear Work Lights (Toggles On/Off) 252 {0x000004, 0x000016}, // Fn59 Launches Outriggers 253 {0x000009, 0x000017}, // Fn60 Crew Dialog Off 254 {0x000009, 0x000018}, // Fn61 All Sounds Off 255 {0x000009, 0x000019}, // Fn62 All Sounds On 256 257 // TMCC1 Unassigned FnKeys 258 {0x00002E}, // Fn63 Code to Trigger SerialMonFrame Message/Unassigned FnKey 259 {0x00002E}, // Fn64 Code to Trigger SerialMonFrame Message/Unassigned FnKey 260 {0x00002E}, // Fn65 Code to Trigger SerialMonFrame Message/Unassigned FnKey 261 {0x00002E}, // Fn66 Code to Trigger SerialMonFrame Message/Unassigned FnKey 262 {0x00002E}, // Fn67 Code to Trigger SerialMonFrame Message/Unassigned FnKey 263 {0x00002E}, // Fn68 Code to Trigger SerialMonFrame Message/Unassigned FnKey 264 265 // TMCC1 Aux FnKeys 266 {0x000008}, // Fnxx (Aux1 Off) 267 {0x000009}, // Fnxx (Aux1 Option 1 - On While Held) 268 {0x00000A}, // Fnxx (Aux1 Option 2 - Toggle On/Toggle Off) 269 {0x00000B}, // Fnxx (Aux1 On) 270 {0x00000C}, // Fnxx (Aux2 Off) 271 {0x00000D}, // Fnxx (Aux2 Option 1 - Toggle On/Toggle Off) 272 {0x00000E}, // Fnxx (Aux2 Option 2 - On While Held) 273 {0x00000F}, // Fnxx (Aux2 On) 274 275 }; 276 277 // TMCC 1 TR Function Keys to trigger with TMCC1TR_32 and TMCC1TR_100 speed steps. 278 private final static long[][] SERIAL_FUNCTION_CODES_TMCC1TR = new long[][] { 279 280 // TMCC1TR Remote - Defined FnKeys 281 {0x00C80D}, // Fn0 (Headlamp) 282 {0x00C81D}, // Fn1 (Bell) 283 {0x00C81C}, // Fn2 (Horn/Whistle) 284 {0x00C805}, // Fn3 (F - Open Front Coupler) 285 {0x00C806}, // Fn4 (R - Open Rear Coupler) 286 287 // TMCC1TR Remote - Defined KeyPad FnKeys 288 {0x00C811}, {0x00C812}, {0x00C813}, /* Fn5-7 */ // 1-2-3 289 {0x00C814}, {0x00C815}, {0x00C816}, /* Fn8-10 */ // 4-5-6 290 {0x00C817}, {0x00C818}, {0x00C819}, /* Fn11-13 */ // 7-8-9 291 {0x00C810}, /* Fn14 */ // 0 292 293 // TMCC1TR Remote - Defined FnKeys 294 {0x00C809}, // Fn15 (Aux1) 295 {0x00C81E}, // Fn16 (Letoff Sound) 296 {0x00C804}, // Fn17 (Boost) 297 {0x00C807}, // Fn18 (Brake) 298 {0x00C828}, // Fn19 (Momentum Low) 299 {0x00C829}, // Fn20 (Momentum Medium) 300 {0x00C82A}, // Fn21 (Momentum High) 301 {0x00C82B}, // Fn22 (Set) 302 {0x00C81F}, // Fn23 (Horn 2) 303 304 // TMCC1TR RR Speed FnKeys 305 {0x00C864}, // Fn24 ( 4) 5mph 306 {0x00C86A}, // Fn25 (10) 20mph 307 {0x00C86E}, // Fn26 (14) 35mph 308 {0x00C872}, // Fn27 (18) 50mph 309 {0x00C878}, // Fn28 (24) 70mph 310 {0x00C87F}, // Fn29 (31) Full 311 312 // TMCC1TR ERR - Set SpeedSteps 313 {0x00C809, 0x00C810, 0x00C809, 0x00C810, 0x00C804}, // Fn30 (Set ERR 100 SpeedSteps) 314 {0x00C809, 0x00C810, 0x00C809, 0x00C810, 0x00C807}, // Fn31 (Set ERR 32 SpeedSteps) 315 316 // TMCC1TR Acela/Subway FnKeys 317 {0x00C809, 0x00C805}, // Fn32 (Open Doors - Left) 318 {0x00C80D, 0x00C805, 0x00C80D}, // Fn33 (Close Doors - Left) 319 {0x00C809, 0x00C806}, // Fn34 (Open Doors - Right) 320 {0x00C80D, 0x00C806, 0x00C80D}, // Fn35 (Close Doors - Right) 321 {0x00C809, 0x00C813}, // Fn36 (Pantagraph - Automatic/Prototypical) 322 {0x00C809, 0x00C815}, // Fn37 (Pantagraph - Down) 323 {0x00C809, 0x00C816}, // Fn38 (Pantagraph - Manual Mode/Cycles Through Positions) 324 {0x00C809, 0x00C81C}, // Fn39 (Toggle Horn - City/Country) 325 {0x00C809, 0x00C818}, // Fn40 (Cab Light - Off) 326 {0x00C809, 0x00C819}, // Fn41 (Cab Light - On) 327 {0x00C809, 0x00C80D, 0x00C818, 0x00C80D}, // Fn42 (Interior Lights - Off) 328 {0x00C809, 0x00C80D, 0x00C819, 0x00C80D}, // Fn43 (Interior Lights - On) 329 330 // TMCC1TR Break-Down B Unit 331 {0x00C809, 0x00C804}, // Fn44 Start Breakdown Sequence 332 {0x00C809, 0x00C815}, // Fn45 Made It Back to the Yard 333 {0x00C809, 0x00C813}, // Fn46 Restart Unit/Repairs Complete 334 335 // TMCC1TR Boxcar/LiveStock Car 336 {0x00C809, 0x00C813}, // Fn47 Load 337 {0x00C809, 0x00C812}, // Fn48 Flat Wheel Sound 338 339 // TMCC1TR Passenger/Dining Cars 340 {0x00C809, 0x00C817}, // Fn49 Station PA Arrival Dialog 341 {0x00C809, 0x00C812}, // Fn50 Conductor Arrival Dialog 342 343 // TMCC1TR Crane/Boom Car 344 {0x00C809, 0x00C811, 0x00C807}, // Fn51 Lower the Boom 345 {0x00C809, 0x00C811, 0x00C804}, // Fn52 Raises the Boom 346 {0x00C809, 0x00C812, 0x00C807}, // Fn53 Lowers Main/Large Hook 347 {0x00C809, 0x00C812, 0x00C804}, // Fn54 Raises Main/Large Hook 348 {0x00C817, 0x00C813, 0x00C807}, // Fn55 Lowers Small Hook 349 {0x00C817, 0x00C813, 0x00C804}, // Fn56 Raises Small Hook 350 {0x00C804, 0x00C814}, // Fn57 Front Work Lights (Toggles On/Off) 351 {0x00C804, 0x00C815}, // Fn58 Rear Work Lights (Toggles On/Off) 352 {0x00C804, 0x00C816}, // Fn59 Launches Outriggers 353 {0x00C809, 0x00C817}, // Fn60 Crew Dialog Off 354 {0x00C809, 0x00C818}, // Fn61 All Sounds Off 355 {0x00C809, 0x00C819}, // Fn62 All Sounds On 356 357 // TMCC1TR Unassigned FnKeys 358 {0x00C82E}, // Fn63 Code to Trigger SerialMonFrame Message/Unassigned FnKey 359 {0x00C82E}, // Fn64 Code to Trigger SerialMonFrame Message/Unassigned FnKey 360 {0x00C82E}, // Fn65 Code to Trigger SerialMonFrame Message/Unassigned FnKey 361 {0x00C82E}, // Fn66 Code to Trigger SerialMonFrame Message/Unassigned FnKey 362 {0x00C82E}, // Fn67 Code to Trigger SerialMonFrame Message/Unassigned FnKey 363 {0x00C82E}, // Fn68 Code to Trigger SerialMonFrame Message/Unassigned FnKey 364 365 // TMCC1TR Aux FnKeys 366 {0x00C808}, // Fnxx (Aux1 Off) 367 {0x00C809}, // Fnxx (Aux1 Option 1 - On While Held) 368 {0x00C80A}, // Fnxx (Aux1 Option 2 - Toggle On/Toggle Off) 369 {0x00C80B}, // Fnxx (Aux1 On) 370 {0x00C80C}, // Fnxx (Aux2 Off) 371 {0x00C80D}, // Fnxx (Aux2 Option 1 - Toggle On/Toggle Off) 372 {0x00C80E}, // Fnxx (Aux2 Option 2 - On While Held) 373 {0x00C80F}, // Fnxx (Aux2 On) 374 375 }; 376 377 378 /** 379 * Translate TMCC1 function numbers to line characters. 380 * If the upper byte is zero, it will be replaced by 0xF8 381 * and the address will be set in the low position. 382 * If the upper byte is non-zero, that value will be sent, 383 * and the address will be set in the upper (TMCC2) position. 384 * If six bytes are specified (with the upper one non-zero), 385 * this will be interpreted as two commands to be sequentially sent, 386 * with the upper bytes sent first. 387 */ 388 389 // TMCC 2 Legacy Function Keys to trigger with TMCC2_32 speed steps. 390 private final static long[][] SERIAL_FUNCTION_CODES_TMCC2_32 = new long[][] { 391 392 // TMCC2_32 Remote - Defined FnKeys 393 {0xF8010D}, // Fn0 (Headlamp) 394 {0xF8011D}, // Fn1 (Bell) 395 {0xF8011C}, // Fn2 (Horn/Whistle) 396 {0xF80105}, // Fn3 (F - Open Front Coupler) 397 {0xF80106}, // Fn4 (R - Open Rear Coupler) 398 399 // TMCC2_32 Remote - Defined KeyPad FnKeys 400 {0xF80111}, {0xF80112}, {0xF80113}, /* Fn5-7 */ // 1-2-3 401 {0xF80114}, {0xF80115}, {0xF80116}, /* Fn8-10 */ // 4-5-6 402 {0xF80117}, {0xF80118}, {0xF80119}, /* Fn11-13 */ // 7-8-9 403 {0xF80110}, /* Fn14 */ // 0 404 405 // TMCC2_32 Remote - Defined FnKeys 406 {0xF80109}, // Fn15 (Aux1) 407 {0xF8011E}, // Fn16 (Letoff Sound) 408 {0xF80104}, // Fn17 (Boost) 409 {0xF80107}, // Fn18 (Brake) 410 {0xF80128}, // Fn19 (Momentum Low) 411 {0xF80129}, // Fn20 (Momentum Medium) 412 {0xF8012A}, // Fn21 (Momentum High) 413 {0xF8012B}, // Fn22 (Set) 414 {0xF8011F}, // Fn23 (Horn 2) 415 416 // TMCC2_32 RR Speed FnKeys 417 {0xF80164}, // Fn24 ( 4) 5mph 418 {0xF8016A}, // Fn25 (10) 20mph 419 {0xF8016E}, // Fn26 (14) 35mph 420 {0xF80172}, // Fn27 (18) 50mph 421 {0xF80178}, // Fn28 (24) 70mph 422 {0xF8017F}, // Fn29 (31) Full 423 424 // TMCC2_32 Extended Lighting FnKeys 425 {0xF8017D, 0xFB00E8, 0xFB0000}, // Fn30 (Mars Lt On) 426 {0xF8017D, 0xFB00E9, 0xFB0000}, // Fn31 (Mars Lt Off) 427 428 {0xF8017D, 0xFB00D0, 0xFB0000}, // Fn32 (Ground Lt On) 429 {0xF8017D, 0xFB00D1, 0xFB0000}, // Fn33 (Ground Lt Off) 430 {0xF8017D, 0xFB00D2, 0xFB0000}, // Fn34 (Ground Lt Auto) 431 432 {0xF8017D, 0xFB00A0, 0xFB0000}, // Fn35 (DogHouse On) 433 {0xF8017D, 0xFB00A1, 0xFB0000}, // Fn36 (DogHouse Off) 434 435 {0xF8017D, 0xFB00CC, 0xFB0000}, // Fn37 (Tender Marker On) 436 {0xF8017D, 0xFB00CD, 0xFB0000}, // Fn38 (Tender Marker Off) 437 438 {0xF8017D, 0xFB00F4, 0xFB0000}, // Fn39 (Rule 17 On) 439 {0xF8017D, 0xFB00F5, 0xFB0000}, // Fn40 (Rule 17 Off) 440 {0xF8017D, 0xFB00F6, 0xFB0000}, // Fn41 (Rule 17 Auto) 441 442 {0xF8017D, 0xFB00C0, 0xFB0000}, // Fn42 (Ditch Lt On) 443 {0xF8017D, 0xFB00C1, 0xFB0000}, // Fn43 (Ditch Lt On; Pulse Off with Horn) 444 {0xF8017D, 0xFB00C2, 0xFB0000}, // Fn44 (Ditch Lt Off; Pulse On with Horn) 445 {0xF8017D, 0xFB00C3, 0xFB0000}, // Fn45 (Ditch Lt Off) 446 447 {0xF8017D, 0xFB00F0, 0xFB0000}, // Fn46 (Cab Lt On) 448 {0xF8017D, 0xFB00F1, 0xFB0000}, // Fn47 (Cab Lt Off) 449 {0xF8017D, 0xFB00F2, 0xFB0000}, // Fn48 (Cab Lt Auto) 450 451 {0xF8017D, 0xFB00C8, 0xFB0000}, // Fn49 (Loco Marker On) 452 {0xF8017D, 0xFB00C9, 0xFB0000}, // Fn50 (Loco Marker Off) 453 454 {0xF8017D, 0xFB00B0, 0xFB0000}, // Fn51 (Hazard Lt On) 455 {0xF8017D, 0xFB00B1, 0xFB0000}, // Fn52 (Hazard Lt Off) 456 {0xF8017D, 0xFB00B2, 0xFB0000}, // Fn53 (Hazard Lt Auto) 457 458 {0xF8017D, 0xFB00E0, 0xFB0000}, // Fn54 (Strobe Lt On - Single Flash) 459 {0xF8017D, 0xFB00E1, 0xFB0000}, // Fn55 (Strobe Lt On - Double Flash) 460 {0xF8017D, 0xFB00E2, 0xFB0000}, // Fn56 (Strobe Lt Off) 461 462 {0xF8017D, 0xFB00F8, 0xFB0000}, // Fn57 (Car Cabin Lt On) 463 {0xF8017D, 0xFB00F9, 0xFB0000}, // Fn58 (Car Cabin Lt Off) 464 {0xF8017D, 0xFB00FA, 0xFB0000}, // Fn59 (Car Cabin Lt Auto) 465 466 // TMCC2 Acela/Subway FnKeys 467 {0xF80109, 0xF80112}, // Fn60 (Crew: Report Speed - Moving) 468 {0xF80109, 0xF80115}, // Fn61 (Tower: Emergency Stop/Crew: Ack - Moving) 469 {0xF8017C, 0xFB0020, 0xFB0000}, // Fn62 (Open Doors - Left) 470 {0xF8017C, 0xFB0021, 0xFB0000}, // Fn63 (Close Doors - Left) 471 {0xF8017C, 0xFB0022, 0xFB0000}, // Fn64 (Open Doors - Right) 472 {0xF8017C, 0xFB0023, 0xFB0000}, // Fn65 (Close Doors - Right) 473 {0xF8017C, 0xFB0010, 0xFB0000}, // Fn66 (Pantagraph - Up/F) 474 {0xF8017C, 0xFB0011, 0xFB0000}, // Fn67 (Pantagraph - Down/F) 475 {0xF8017C, 0xFB0012, 0xFB0000}, // Fn68 (Pantagraph - Up/R) 476 {0xF8017C, 0xFB0013, 0xFB0000}, // Fn69 (Pantagraph - Down/R) 477 478 // Only TMCC1 Break-Down B Unit 479 480 // TMCC2 Boxcar/Livestock Car 481 {0xF8017C, 0xFB0030, 0xFB0000}, // Fn70 (Option1 On) 482 {0xF8017C, 0xFB0031, 0xFB0000}, // Fn71 (Opiton1 Off) 483 {0xF8017C, 0xFB0032, 0xFB0000}, // Fn72 (Option2 On) 484 {0xF8017C, 0xFB0033, 0xFB0000}, // Fn73 (Option2 Off) 485 {0xF8017C, 0xFB0034, 0xFB0000}, // Fn74 (Load) 486 {0xF8017C, 0xFB0035, 0xFB0000}, // Fn75 (Unload) 487 {0xF8017C, 0xFB0036, 0xFB0000}, // Fn76 (FRED On) 488 {0xF8017C, 0xFB0037, 0xFB0000}, // Fn77 (FRED Off) 489 {0xF8017C, 0xFB0038, 0xFB0000}, // Fn78 (Flat Wheel On) 490 {0xF8017C, 0xFB0039, 0xFB0000}, // Fn79 (Flat Wheel Off) 491 {0xF8017C, 0xFB003A, 0xFB0000}, // Fn80 (Game On) 492 {0xF8017C, 0xFB003B, 0xFB0000}, // Fn81 (Game Off) 493 494 // Only TMCC1 Passenger/Dining Cars 495 496 // Only TMCC1 Crane/Boom Car 497 498 // TMCC2 Smoke System 499 {0xF8017C, 0xFB0000, 0xFB0000}, // Fn82 (Smoke System Off) 500 {0xF8017C, 0xFB0001, 0xFB0000}, // Fn83 (Smoke System Low) 501 {0xF8017C, 0xFB0002, 0xFB0000}, // Fn84 (Smoke System Med) 502 {0xF8017C, 0xFB0003, 0xFB0000}, // Fn85 (Smoke System High) 503 504 // TMCC2_32 Unassigned FnKeys 505 {0xF8012E}, // Fnxx Code to Trigger SerialMonFrame Message/Unassigned FnKey 506 {0xF8012E}, // Fnxx Code to Trigger SerialMonFrame Message/Unassigned FnKey 507 508 // TMCC2_32 Aux FnKeys 509 {0xF80108}, // Fnxx (Aux1 Off) 510 {0xF80109}, // Fnxx (Aux1 Option 1 - On While Held) 511 {0xF8010A}, // Fnxx (Aux1 Option 2 - Toggle On/Toggle Off) 512 {0xF8010B}, // Fnxx (Aux1 On) 513 {0xF8010C}, // Fnxx (Aux2 Off) 514 {0xF8010D}, // Fnxx (Aux2 Option 1 - Toggle On/Toggle Off) 515 {0xF8010E}, // Fnxx (Aux2 Option 2 - On While Held) 516 {0xF8010F}, // Fnxx (Aux2 On) 517 518}; 519 520 // TMCC 2 Legacy TR Function Keys to trigger with TMCC2TR_32 speed steps. 521 private final static long[][] SERIAL_FUNCTION_CODES_TMCC2TR_32 = new long[][] { 522 523 // TMCC2TR_32 Remote - Defined FnKeys 524 {0xF9010D}, // Fn0 (Headlamp) 525 {0xF9011D}, // Fn1 (Bell) 526 {0xF9011C}, // Fn2 (Horn/Whistle) 527 {0xF90105}, // Fn3 (F - Open Front Coupler) 528 {0xF90106}, // Fn4 (R - Open Rear Coupler) 529 530 // TMCC2TR_32 Remote - Defined KeyPad FnKeys 531 {0xF90111}, {0xF90112}, {0xF90113}, /* Fn5-7 */ // 1-2-3 532 {0xF90114}, {0xF90115}, {0xF90116}, /* Fn8-10 */ // 4-5-6 533 {0xF90117}, {0xF90118}, {0xF90119}, /* Fn11-13 */ // 7-8-9 534 {0xF90110}, /* Fn14 */ // 0 535 536 // TMCC2TR_32 Remote - Defined FnKeys 537 {0xF90109}, // Fn15 (Aux1) 538 {0xF9011E}, // Fn16 (Letoff Sound) 539 {0xF90104}, // Fn17 (Boost) 540 {0xF90107}, // Fn18 (Brake) 541 {0xF90128}, // Fn19 (Momentum Low) 542 {0xF90129}, // Fn20 (Momentum Medium) 543 {0xF9012A}, // Fn21 (Momentum High) 544 {0xF9012B}, // Fn22 (Set) 545 {0xF9011F}, // Fn23 (Horn 2) 546 547 // TMCC2TR_32 RR Speed FnKeys 548 {0xF90164}, // Fn24 ( 4) 5mph 549 {0xF9016A}, // Fn25 (10) 20mph 550 {0xF9016E}, // Fn26 (14) 35mph 551 {0xF90172}, // Fn27 (18) 50mph 552 {0xF90178}, // Fn28 (24) 70mph 553 {0xF9017F}, // Fn29 (31) Full 554 555 // TMCC2TR_32 Extended Lighting FnKeys 556 {0xF9017D, 0xFB00E8, 0xFB0000}, // Fn30 (Mars Lt On) 557 {0xF9017D, 0xFB00E9, 0xFB0000}, // Fn31 (Mars Lt Off) 558 559 {0xF9017D, 0xFB00D0, 0xFB0000}, // Fn32 (Ground Lt On) 560 {0xF9017D, 0xFB00D1, 0xFB0000}, // Fn33 (Ground Lt Off) 561 {0xF9017D, 0xFB00D2, 0xFB0000}, // Fn34 (Ground Lt Auto) 562 563 {0xF9017D, 0xFB00A0, 0xFB0000}, // Fn35 (DogHouse On) 564 {0xF9017D, 0xFB00A1, 0xFB0000}, // Fn36 (DogHouse Off) 565 566 {0xF9017D, 0xFB00CC, 0xFB0000}, // Fn37 (Tender Marker On) 567 {0xF9017D, 0xFB00CD, 0xFB0000}, // Fn38 (Tender Marker Off) 568 569 {0xF9017D, 0xFB00F4, 0xFB0000}, // Fn39 (Rule 17 On) 570 {0xF9017D, 0xFB00F5, 0xFB0000}, // Fn40 (Rule 17 Off) 571 {0xF9017D, 0xFB00F6, 0xFB0000}, // Fn41 (Rule 17 Auto) 572 573 {0xF9017D, 0xFB00C0, 0xFB0000}, // Fn42 (Ditch Lt On) 574 {0xF9017D, 0xFB00C1, 0xFB0000}, // Fn43 (Ditch Lt On; Pulse Off with Horn) 575 {0xF9017D, 0xFB00C2, 0xFB0000}, // Fn44 (Ditch Lt Off; Pulse On with Horn) 576 {0xF9017D, 0xFB00C3, 0xFB0000}, // Fn45 (Ditch Lt Off) 577 578 {0xF9017D, 0xFB00F0, 0xFB0000}, // Fn46 (Cab Lt On) 579 {0xF9017D, 0xFB00F1, 0xFB0000}, // Fn47 (Cab Lt Off) 580 {0xF9017D, 0xFB00F2, 0xFB0000}, // Fn48 (Cab Lt Auto) 581 582 {0xF9017D, 0xFB00C8, 0xFB0000}, // Fn49 (Loco Marker On) 583 {0xF9017D, 0xFB00C9, 0xFB0000}, // Fn50 (Loco Marker Off) 584 585 {0xF9017D, 0xFB00B0, 0xFB0000}, // Fn51 (Hazard Lt On) 586 {0xF9017D, 0xFB00B1, 0xFB0000}, // Fn52 (Hazard Lt Off) 587 {0xF9017D, 0xFB00B2, 0xFB0000}, // Fn53 (Hazard Lt Auto) 588 589 {0xF9017D, 0xFB00E0, 0xFB0000}, // Fn54 (Strobe Lt On - Single Flash) 590 {0xF9017D, 0xFB00E1, 0xFB0000}, // Fn55 (Strobe Lt On - Double Flash) 591 {0xF9017D, 0xFB00E2, 0xFB0000}, // Fn56 (Strobe Lt Off) 592 593 {0xF9017D, 0xFB00F8, 0xFB0000}, // Fn57 (Car Cabin Lt On) 594 {0xF9017D, 0xFB00F9, 0xFB0000}, // Fn58 (Car Cabin Lt Off) 595 {0xF9017D, 0xFB00FA, 0xFB0000}, // Fn59 (Car Cabin Lt Auto) 596 597 // TMCC2TR Acela/Subway FnKeys 598 {0xF90109, 0xF90112}, // Fn60 (Crew: Report Speed - Moving) 599 {0xF90109, 0xF90115}, // Fn61 (Tower: Emergency Stop/Crew: Ack - Moving) 600 {0xF9017C, 0xFB0020, 0xFB0000}, // Fn62 (Open Doors - Left) 601 {0xF9017C, 0xFB0021, 0xFB0000}, // Fn63 (Close Doors - Left) 602 {0xF9017C, 0xFB0022, 0xFB0000}, // Fn64 (Open Doors - Right) 603 {0xF9017C, 0xFB0023, 0xFB0000}, // Fn65 (Close Doors - Right) 604 {0xF9017C, 0xFB0010, 0xFB0000}, // Fn66 (Pantagraph - Up/F) 605 {0xF9017C, 0xFB0011, 0xFB0000}, // Fn67 (Pantagraph - Down/F) 606 {0xF9017C, 0xFB0012, 0xFB0000}, // Fn68 (Pantagraph - Up/R) 607 {0xF9017C, 0xFB0013, 0xFB0000}, // Fn69 (Pantagraph - Down/R) 608 609 // Only TMCC1 Break-Down B Unit 610 611 // TMCC2TR Boxcar/Livestock Car 612 {0xF9017C, 0xFB0030, 0xFB0000}, // Fn70 (Option1 On) 613 {0xF9017C, 0xFB0031, 0xFB0000}, // Fn71 (Opiton1 Off) 614 {0xF9017C, 0xFB0032, 0xFB0000}, // Fn72 (Option2 On) 615 {0xF9017C, 0xFB0033, 0xFB0000}, // Fn73 (Option2 Off) 616 {0xF9017C, 0xFB0034, 0xFB0000}, // Fn74 (Load) 617 {0xF9017C, 0xFB0035, 0xFB0000}, // Fn75 (Unload) 618 {0xF9017C, 0xFB0036, 0xFB0000}, // Fn76 (FRED On) 619 {0xF9017C, 0xFB0037, 0xFB0000}, // Fn77 (FRED Off) 620 {0xF9017C, 0xFB0038, 0xFB0000}, // Fn78 (Flat Wheel On) 621 {0xF9017C, 0xFB0039, 0xFB0000}, // Fn79 (Flat Wheel Off) 622 {0xF9017C, 0xFB003A, 0xFB0000}, // Fn80 (Game On) 623 {0xF9017C, 0xFB003B, 0xFB0000}, // Fn81 (Game Off) 624 625 // Only TMCC1 Passenger/Dining Cars 626 627 // Only TMCC1 Crane/Boom Car 628 629 // TMCC2TR Smoke System 630 {0xF9017C, 0xFB0000, 0xFB0000}, // Fn82 (Smoke System Off) 631 {0xF9017C, 0xFB0001, 0xFB0000}, // Fn83 (Smoke System Low) 632 {0xF9017C, 0xFB0002, 0xFB0000}, // Fn84 (Smoke System Med) 633 {0xF9017C, 0xFB0003, 0xFB0000}, // Fn85 (Smoke System High) 634 635 // TRMCC2TR_32 Unassigned FnKeys 636 {0xF9012E}, // Fnxx Code to Trigger SerialMonFrame Message/Unassigned FnKey 637 {0xF9012E}, // Fnxx Code to Trigger SerialMonFrame Message/Unassigned FnKey 638 639 // TRMCC2TR_32 Aux FnKeys 640 {0xF90108}, // Fnxx (Aux1 Off) 641 {0xF90109}, // Fnxx (Aux1 Option 1 - On While Held) 642 {0xF9010A}, // Fnxx (Aux1 Option 2 - Toggle On/Toggle Off) 643 {0xF9010B}, // Fnxx (Aux1 On) 644 {0xF9010C}, // Fnxx (Aux2 Off) 645 {0xF9010D}, // Fnxx (Aux2 Option 1 - Toggle On/Toggle Off) 646 {0xF9010E}, // Fnxx (Aux2 Option 2 - On While Held) 647 {0xF9010F}, // Fnxx (Aux2 On) 648 649}; 650 651 // TMCC 2 Legacy Function Keys to trigger with TMCC2_200 speed steps. 652 private final static long[][] SERIAL_FUNCTION_CODES_TMCC2_200 = new long[][] { 653 654 // TMCC2_200 Remote - Defined FnKeys 655 {0xF8010D}, // Fn0 (Headlamp) 656 {0xF8011D}, // Fn1 (Bell) 657 {0xF8011C}, // Fn2 (Horn/Whistle) 658 {0xF80105}, // Fn3 (F - Open Front Coupler) 659 {0xF80106}, // Fn4 (R - Open Rear Coupler) 660 661 // TMCC2_200 Remote - Defined KeyPad FnKeys 662 {0xF80111}, {0xF80112}, {0xF80113}, /* Fn5-7 */ // 1-2-3 663 {0xF80114}, {0xF80115}, {0xF80116}, /* Fn8-10 */ // 4-5-6 664 {0xF80117}, {0xF80118}, {0xF80119}, /* Fn11-13 */ // 7-8-9 665 {0xF80110}, /* Fn14 */ // 0 666 667 // TMCC2_200 Remote - Defined FnKeys 668 {0xF80109}, // Fn15 (Aux1) 669 {0xF8011E}, // Fn16 (Letoff Sound) 670 {0xF80104}, // Fn17 (Boost) 671 {0xF80107}, // Fn18 (Brake) 672 {0xF80128}, // Fn19 (Momentum Low) 673 {0xF80129}, // Fn20 (Momentum Medium) 674 {0xF8012A}, // Fn21 (Momentum High) 675 {0xF8012B}, // Fn22 (Set) 676 {0xF8011F}, // Fn23 (Horn 2) 677 678 // TMCC2_200 RR Speed FnKeys 679 {0xF8000A}, // Fn24 ( 10) 5mph 680 {0xF80028}, // Fn25 ( 40) 20mph 681 {0xF80046}, // Fn26 ( 70) 35mph 682 {0xF80064}, // Fn27 (100) 50mph 683 {0xF8008C}, // Fn28 (140) 70mph 684 {0xF800C7}, // Fn29 (199) Full 685 686 // TMCC2_200 Extended Lighting FnKeys 687 {0xF8017D, 0xFB00E8, 0xFB0000}, // Fn30 (Mars Lt On) 688 {0xF8017D, 0xFB00E9, 0xFB0000}, // Fn31 (Mars Lt Off) 689 690 {0xF8017D, 0xFB00D0, 0xFB0000}, // Fn32 (Ground Lt On) 691 {0xF8017D, 0xFB00D1, 0xFB0000}, // Fn33 (Ground Lt Off) 692 {0xF8017D, 0xFB00D2, 0xFB0000}, // Fn34 (Ground Lt Auto) 693 694 {0xF8017D, 0xFB00A0, 0xFB0000}, // Fn35 (DogHouse On) 695 {0xF8017D, 0xFB00A1, 0xFB0000}, // Fn36 (DogHouse Off) 696 697 {0xF8017D, 0xFB00CC, 0xFB0000}, // Fn37 (Tender Marker On) 698 {0xF8017D, 0xFB00CD, 0xFB0000}, // Fn38 (Tender Marker Off) 699 700 {0xF8017D, 0xFB00F4, 0xFB0000}, // Fn39 (Rule 17 On) 701 {0xF8017D, 0xFB00F5, 0xFB0000}, // Fn40 (Rule 17 Off) 702 {0xF8017D, 0xFB00F6, 0xFB0000}, // Fn41 (Rule 17 Auto) 703 704 {0xF8017D, 0xFB00C0, 0xFB0000}, // Fn42 (Ditch Lt On) 705 {0xF8017D, 0xFB00C1, 0xFB0000}, // Fn43 (Ditch Lt On; Pulse Off with Horn) 706 {0xF8017D, 0xFB00C2, 0xFB0000}, // Fn44 (Ditch Lt Off; Pulse On with Horn) 707 {0xF8017D, 0xFB00C3, 0xFB0000}, // Fn45 (Ditch Lt Off) 708 709 {0xF8017D, 0xFB00F0, 0xFB0000}, // Fn46 (Cab Lt On) 710 {0xF8017D, 0xFB00F1, 0xFB0000}, // Fn47 (Cab Lt Off) 711 {0xF8017D, 0xFB00F2, 0xFB0000}, // Fn48 (Cab Lt Auto) 712 713 {0xF8017D, 0xFB00C8, 0xFB0000}, // Fn49 (Loco Marker On) 714 {0xF8017D, 0xFB00C9, 0xFB0000}, // Fn50 (Loco Marker Off) 715 716 {0xF8017D, 0xFB00B0, 0xFB0000}, // Fn51 (Hazard Lt On) 717 {0xF8017D, 0xFB00B1, 0xFB0000}, // Fn52 (Hazard Lt Off) 718 {0xF8017D, 0xFB00B2, 0xFB0000}, // Fn53 (Hazard Lt Auto) 719 720 {0xF8017D, 0xFB00E0, 0xFB0000}, // Fn54 (Strobe Lt On - SingleFlash) 721 {0xF8017D, 0xFB00E1, 0xFB0000}, // Fn55 (Strobe Lt On - DoubleFlash) 722 {0xF8017D, 0xFB00E2, 0xFB0000}, // Fn56 (Strobe Lt Off) 723 724 {0xF8017D, 0xFB00F8, 0xFB0000}, // Fn57 (Car Cabin Lt On) 725 {0xF8017D, 0xFB00F9, 0xFB0000}, // Fn58 (Car Cabin Lt Off) 726 {0xF8017D, 0xFB00FA, 0xFB0000}, // Fn59 (Car Cabin Lt Auto) 727 728 // TMCC2 Acela/Subway FnKeys 729 {0xF80109, 0xF80112}, // Fn60 (Crew: Report Speed - Moving) 730 {0xF80109, 0xF80115}, // Fn61 (Tower: Emergency Stop/Crew: Ack - Moving) 731 {0xF8017C, 0xFB0020, 0xFB0000}, // Fn62 (Open Doors - Left) 732 {0xF8017C, 0xFB0021, 0xFB0000}, // Fn63 (Close Doors - Left) 733 {0xF8017C, 0xFB0022, 0xFB0000}, // Fn64 (Open Doors - Right) 734 {0xF8017C, 0xFB0023, 0xFB0000}, // Fn65 (Close Doors - Right) 735 {0xF8017C, 0xFB0010, 0xFB0000}, // Fn66 (Pantagraph - Up/F) 736 {0xF8017C, 0xFB0011, 0xFB0000}, // Fn67 (Pantagraph - Down/F) 737 {0xF8017C, 0xFB0012, 0xFB0000}, // Fn68 (Pantagraph - Up/R) 738 {0xF8017C, 0xFB0013, 0xFB0000}, // Fn69 (Pantagraph - Down/R) 739 740 // Only TMCC1 Break-Down B Unit 741 742 // TMCC2 Boxcar/Livestock Car 743 {0xF8017C, 0xFB0030, 0xFB0000}, // Fn70 (Option1 On) 744 {0xF8017C, 0xFB0031, 0xFB0000}, // Fn71 (Opiton1 Off) 745 {0xF8017C, 0xFB0032, 0xFB0000}, // Fn72 (Option2 On) 746 {0xF8017C, 0xFB0033, 0xFB0000}, // Fn73 (Option2 Off) 747 {0xF8017C, 0xFB0034, 0xFB0000}, // Fn74 (Load) 748 {0xF8017C, 0xFB0035, 0xFB0000}, // Fn75 (Unload) 749 {0xF8017C, 0xFB0036, 0xFB0000}, // Fn76 (FRED On) 750 {0xF8017C, 0xFB0037, 0xFB0000}, // Fn77 (FRED Off) 751 {0xF8017C, 0xFB0038, 0xFB0000}, // Fn78 (Flat Wheel On) 752 {0xF8017C, 0xFB0039, 0xFB0000}, // Fn79 (Flat Wheel Off) 753 {0xF8017C, 0xFB003A, 0xFB0000}, // Fn80 (Game On) 754 {0xF8017C, 0xFB003B, 0xFB0000}, // Fn81 (Game Off) 755 756 // Only TMCC1 Passenger/Dining Cars 757 758 // Only TMCC1 Crane/Boom Car 759 760 // TMCC2 Smoke System 761 {0xF8017C, 0xFB0000, 0xFB0000}, // Fn82 (Smoke System Off) 762 {0xF8017C, 0xFB0001, 0xFB0000}, // Fn83 (Smoke System Low) 763 {0xF8017C, 0xFB0002, 0xFB0000}, // Fn84 (Smoke System Med) 764 {0xF8017C, 0xFB0003, 0xFB0000}, // Fn85 (Smoke System High) 765 766 // TRMCC2_200 Unassigned FnKeys 767 {0xF8012E}, // Fnxx Code to Trigger SerialMonFrame Message/Unassigned FnKey 768 {0xF8012E}, // Fnxx Code to Trigger SerialMonFrame Message/Unassigned FnKey 769 770 // TMCC2_200 Aux FnKeys 771 {0xF80108}, // Fnxx (Aux1 Off) 772 {0xF80109}, // Fnxx (Aux1 Option 1 - On While Held) 773 {0xF8010A}, // Fnxx (Aux1 Option 2 - Toggle On/Toggle Off) 774 {0xF8010B}, // Fnxx (Aux1 On) 775 {0xF8010C}, // Fnxx (Aux2 Off) 776 {0xF8010D}, // Fnxx (Aux2 Option 1 - Toggle On/Toggle Off) 777 {0xF8010E}, // Fnxx (Aux2 Option 2 - On While Held) 778 {0xF8010F}, // Fnxx (Aux2 On) 779 780 }; 781 782 // TMCC 2 Legacy TR Function Keys to trigger with TMCC2TR_200 speed steps. 783 private final static long[][] SERIAL_FUNCTION_CODES_TMCC2TR_200 = new long[][] { 784 785 // TMCC2TR_200 Remote - Defined FnKeys 786 {0xF9010D}, // Fn0 (Headlamp) 787 {0xF9011D}, // Fn1 (Bell) 788 {0xF9011C}, // Fn2 (Horn/Whistle) 789 {0xF90105}, // Fn3 (F - Open Front Coupler) 790 {0xF90106}, // Fn4 (R - Open Rear Coupler) 791 792 // TMCC2TR_200 Remote - Defined KeyPad FnKeys 793 {0xF90111}, {0xF90112}, {0xF90113}, /* Fn5-7 */ // 1-2-3 794 {0xF90114}, {0xF90115}, {0xF90116}, /* Fn8-10 */ // 4-5-6 795 {0xF90117}, {0xF90118}, {0xF90119}, /* Fn11-13 */ // 7-8-9 796 {0xF90110}, /* Fn14 */ // 0 797 798 // TMCC2TR_200 Remote - Defined FnKeys 799 {0xF90109}, // Fn15 (Aux1) 800 {0xF9011E}, // Fn16 (Letoff Sound) 801 {0xF90104}, // Fn17 (Boost) 802 {0xF90107}, // Fn18 (Brake) 803 {0xF90128}, // Fn19 (Momentum Low) 804 {0xF90129}, // Fn20 (Momentum Medium) 805 {0xF9012A}, // Fn21 (Momentum High) 806 {0xF9012B}, // Fn22 (Set) 807 {0xF9011F}, // Fn23 (Horn 2) 808 809 // TMCC2TR_200 RR Speed FnKeys 810 {0xF9000A}, // Fn24 ( 10) 5mph 811 {0xF90028}, // Fn25 ( 40) 20mph 812 {0xF90046}, // Fn26 ( 70) 35mph 813 {0xF90064}, // Fn27 (100) 50mph 814 {0xF9008C}, // Fn28 (140) 70mph 815 {0xF900C7}, // Fn29 (199) Full 816 817 // TMCC2TR_200 Extended Lighting FnKeys 818 {0xF9017D, 0xFB00E8, 0xFB0000}, // Fn30 (Mars Lt On) 819 {0xF9017D, 0xFB00E9, 0xFB0000}, // Fn31 (Mars Lt Off) 820 821 {0xF9017D, 0xFB00D0, 0xFB0000}, // Fn32 (Ground Lt On) 822 {0xF9017D, 0xFB00D1, 0xFB0000}, // Fn33 (Ground Lt Off) 823 {0xF9017D, 0xFB00D2, 0xFB0000}, // Fn34 (Ground Lt Auto) 824 825 {0xF9017D, 0xFB00A0, 0xFB0000}, // Fn35 (DogHouse On) 826 {0xF9017D, 0xFB00A1, 0xFB0000}, // Fn36 (DogHouse Off) 827 828 {0xF9017D, 0xFB00CC, 0xFB0000}, // Fn37 (Tender Marker On) 829 {0xF9017D, 0xFB00CD, 0xFB0000}, // Fn38 (Tender Marker Off) 830 831 {0xF9017D, 0xFB00F4, 0xFB0000}, // Fn39 (Rule 17 On) 832 {0xF9017D, 0xFB00F5, 0xFB0000}, // Fn40 (Rule 17 Off) 833 {0xF9017D, 0xFB00F6, 0xFB0000}, // Fn41 (Rule 17 Auto) 834 835 {0xF9017D, 0xFB00C0, 0xFB0000}, // Fn42 (Ditch Lt On) 836 {0xF9017D, 0xFB00C1, 0xFB0000}, // Fn43 (Ditch Lt On; Pulse Off with Horn) 837 {0xF9017D, 0xFB00C2, 0xFB0000}, // Fn44 (Ditch Lt Off; Pulse On with Horn) 838 {0xF9017D, 0xFB00C3, 0xFB0000}, // Fn45 (Ditch Lt Off) 839 840 {0xF9017D, 0xFB00F0, 0xFB0000}, // Fn46 (Cab Lt On) 841 {0xF9017D, 0xFB00F1, 0xFB0000}, // Fn47 (Cab Lt Off) 842 {0xF9017D, 0xFB00F2, 0xFB0000}, // Fn48 (Cab Lt Auto) 843 844 {0xF9017D, 0xFB00C8, 0xFB0000}, // Fn49 (Loco Marker On) 845 {0xF9017D, 0xFB00C9, 0xFB0000}, // Fn50 (Loco Marker Off) 846 847 {0xF9017D, 0xFB00B0, 0xFB0000}, // Fn51 (Hazard Lt On) 848 {0xF9017D, 0xFB00B1, 0xFB0000}, // Fn52 (Hazard Lt Off) 849 {0xF9017D, 0xFB00B2, 0xFB0000}, // Fn53 (Hazard Lt Auto) 850 851 {0xF9017D, 0xFB00E0, 0xFB0000}, // Fn54 (Strobe Lt On - SingleFlash) 852 {0xF9017D, 0xFB00E1, 0xFB0000}, // Fn55 (Strobe Lt On - DoubleFlash) 853 {0xF9017D, 0xFB00E2, 0xFB0000}, // Fn56 (Strobe Lt Off) 854 855 {0xF9017D, 0xFB00F8, 0xFB0000}, // Fn57 (Car Cabin Lt On) 856 {0xF9017D, 0xFB00F9, 0xFB0000}, // Fn58 (Car Cabin Lt Off) 857 {0xF9017D, 0xFB00FA, 0xFB0000}, // Fn59 (Car Cabin Lt Auto) 858 859 // TMCC2TR Acela/Subway FnKeys 860 {0xF90109, 0xF90112}, // Fn60 (Crew: Report Speed - Moving) 861 {0xF90109, 0xF90115}, // Fn61 (Tower: Emergency Stop/Crew: Ack - Moving) 862 {0xF9017C, 0xFB0020, 0xFB0000}, // Fn62 (Open Doors - Left) 863 {0xF9017C, 0xFB0021, 0xFB0000}, // Fn63 (Close Doors - Left) 864 {0xF9017C, 0xFB0022, 0xFB0000}, // Fn64 (Open Doors - Right) 865 {0xF9017C, 0xFB0023, 0xFB0000}, // Fn65 (Close Doors - Right) 866 {0xF9017C, 0xFB0010, 0xFB0000}, // Fn66 (Pantagraph - Up/F) 867 {0xF9017C, 0xFB0011, 0xFB0000}, // Fn67 (Pantagraph - Down/F) 868 {0xF9017C, 0xFB0012, 0xFB0000}, // Fn68 (Pantagraph - Up/R) 869 {0xF9017C, 0xFB0013, 0xFB0000}, // Fn69 (Pantagraph - Down/R) 870 871 // Only TMCC1 Break-Down B Unit 872 873 // TMCC2TR Boxcar/Livestock Car 874 {0xF9017C, 0xFB0030, 0xFB0000}, // Fn70 (Option1 On) 875 {0xF9017C, 0xFB0031, 0xFB0000}, // Fn71 (Opiton1 Off) 876 {0xF9017C, 0xFB0032, 0xFB0000}, // Fn72 (Option2 On) 877 {0xF9017C, 0xFB0033, 0xFB0000}, // Fn73 (Option2 Off) 878 {0xF9017C, 0xFB0034, 0xFB0000}, // Fn74 (Load) 879 {0xF9017C, 0xFB0035, 0xFB0000}, // Fn75 (Unload) 880 {0xF9017C, 0xFB0036, 0xFB0000}, // Fn76 (FRED On) 881 {0xF9017C, 0xFB0037, 0xFB0000}, // Fn77 (FRED Off) 882 {0xF9017C, 0xFB0038, 0xFB0000}, // Fn78 (Flat Wheel On) 883 {0xF9017C, 0xFB0039, 0xFB0000}, // Fn79 (Flat Wheel Off) 884 {0xF9017C, 0xFB003A, 0xFB0000}, // Fn80 (Game On) 885 {0xF9017C, 0xFB003B, 0xFB0000}, // Fn81 (Game Off) 886 887 // Only TMCC1 Passenger/Dining Cars 888 889 // Only TMCC1 Crane/Boom Car 890 891 // TMCC2TR Smoke System 892 {0xF9017C, 0xFB0000, 0xFB0000}, // Fn82 (Smoke System Off) 893 {0xF9017C, 0xFB0001, 0xFB0000}, // Fn83 (Smoke System Low) 894 {0xF9017C, 0xFB0002, 0xFB0000}, // Fn84 (Smoke System Med) 895 {0xF9017C, 0xFB0003, 0xFB0000}, // Fn85 (Smoke System High) 896 897 // TRMCC2TR_200 Unassigned FnKeys 898 {0xF9012E}, // Fnxx Code to Trigger SerialMonFrame Message/Unassigned FnKey 899 {0xF9012E}, // Fnxx Code to Trigger SerialMonFrame Message/Unassigned FnKey 900 901 // TMCC2TR_200 Aux FnKeys 902 {0xF90108}, // Fnxx (Aux1 Off) 903 {0xF90109}, // Fnxx (Aux1 Option 1 - On While Held) 904 {0xF9010A}, // Fnxx (Aux1 Option 2 - Toggle On/Toggle Off) 905 {0xF9010B}, // Fnxx (Aux1 On) 906 {0xF9010C}, // Fnxx (Aux2 Off) 907 {0xF9010D}, // Fnxx (Aux2 Option 1 - Toggle On/Toggle Off) 908 {0xF9010E}, // Fnxx (Aux2 Option 2 - On While Held) 909 {0xF9010F}, // Fnxx (Aux2 On) 910 911 }; 912 913 914 int previousValue; 915 int newValue; 916 917 /** 918 * Set the speed. 919 * 920 * @param speed Number from 0 to 1; less than zero is emergency stop 921 */ 922 923 @Override 924 public void setSpeedSetting(float speed) { 925 float oldSpeed; 926 synchronized(this) { 927 oldSpeed = this.speedSetting; 928 this.speedSetting = speed; 929 } 930 931 // Option TMCC2_200 "Absolute" speed steps 932 if (speedStepMode == jmri.SpeedStepMode.TMCC2_200) { 933 934 // TMCC2 Legacy 200 speed step mode 935 int value = (int) (199 * speed); // max value to send is 199 in 200 step mode 936 if (value > 199) { 937 // max possible speed 938 value = 199; 939 } 940 SerialMessage m = new SerialMessage(); 941 m.setOpCode(0xF8); 942 943 if (value < 0) { 944 // System HALT (immediate stop; ALL) 945 m.putAsWord(0xFF8B); 946 947 // send to layout (send 4 times to ensure received) 948 tc.sendSerialMessage(m, null); 949 tc.sendSerialMessage(m, null); 950 tc.sendSerialMessage(m, null); 951 tc.sendSerialMessage(m, null); 952 953 } else { 954 // normal speed setting 955 m.putAsWord(0x0000 + (address.getNumber() << 9) + value); 956 957 // send to command station (send twice is set, but number of sends may need to be adjusted depending on efficiency) 958 tc.sendSerialMessage(m, null); 959 tc.sendSerialMessage(m, null); 960 } 961 } 962 963 // Option TMCC2TR_200 "Absolute" speed steps 964 if (speedStepMode == jmri.SpeedStepMode.TMCC2TR_200) { 965 966 // TMCC2 Legacy TR 200 speed step mode 967 int value = (int) (199 * speed); // max value to send is 199 in 200 step mode 968 if (value > 199) { 969 // max possible speed 970 value = 199; 971 } 972 SerialMessage m = new SerialMessage(); 973 m.setOpCode(0xF9); 974 975 if (value < 0) { 976 // System HALT (immediate stop; ALL) 977 m.putAsWord(0xFF8B); 978 979 // send to layout (send 4 times to ensure received) 980 tc.sendSerialMessage(m, null); 981 tc.sendSerialMessage(m, null); 982 tc.sendSerialMessage(m, null); 983 tc.sendSerialMessage(m, null); 984 985 } else { 986 // normal speed setting 987 m.putAsWord(0x0000 + (address.getNumber() << 9) + value); 988 989 // send to command station (send twice is set, but number of sends may need to be adjusted depending on efficiency) 990 tc.sendSerialMessage(m, null); 991 tc.sendSerialMessage(m, null); 992 } 993 } 994 995 // Option TMCC1_100 "Relative" speed steps 996 if (speedStepMode == jmri.SpeedStepMode.TMCC1_100) { 997 998 /** 999 * TMCC1 MedMomentum, HighMomentum and 100 speed step mode 1000 * purpose is to increase resolution of 32 bits 1001 * across 100 throttle 'clicks' 1002 */ 1003 1004 int value = (int) (99 * speed); // max value to send is 99 in 100 step mode 1005 if (value > 99) { 1006 // max possible speed step 1007 value = 99; 1008 } 1009 SerialMessage m = new SerialMessage(); 1010 m.setOpCode(0xFE); 1011 1012 if (value < 0) { 1013 // System HALT (immediate stop; ALL) 1014 m.putAsWord(0xFFFF); 1015 1016 // send to layout (send 4 times to ensure received) 1017 tc.sendSerialMessage(m, null); 1018 tc.sendSerialMessage(m, null); 1019 tc.sendSerialMessage(m, null); 1020 tc.sendSerialMessage(m, null); 1021 } 1022 if (value == 0) { 1023 // normal speed step setting 1024 m.putAsWord(0x0060 + address.getNumber() * 128 + value); 1025 1026 // send to layout (send twice is set, but number of sends may need to be adjusted depending on efficiency) 1027 tc.sendSerialMessage(m, null); 1028 tc.sendSerialMessage(m, null); 1029 } 1030 1031 if (value > 0) { 1032 newValue = value; 1033 if (newValue > previousValue) { 1034 // increase TMCC "Relative" speed +1 (repeat * valueChange46) 1035 int valueChange46 = (newValue - previousValue); 1036 for (int i = 0x0000; i < valueChange46; i++) { 1037 m.putAsWord(0x0046 + address.getNumber() * 128); 1038 tc.sendSerialMessage(m, null); 1039 } 1040 } 1041 if (newValue < previousValue) { 1042 // decrease TMCC "Relative" speed -1 (repeat * valueChange44) 1043 int valueChange44 = (previousValue - newValue); 1044 for (int j = 0x0000; j < valueChange44; j++) { 1045 m.putAsWord(0x0044 + address.getNumber() * 128); 1046 tc.sendSerialMessage(m, null); 1047 } 1048 } 1049 previousValue = newValue; 1050 } 1051 } 1052 1053 // Option TMCC1TR_100 "Relative" speed steps 1054 if (speedStepMode == jmri.SpeedStepMode.TMCC1TR_100) { 1055 1056 /** 1057 * TMCC1TR MedMomentum, HighMomentum and 100 speed step mode 1058 * purpose is to increase resolution of 32 bits 1059 * across 100 throttle 'clicks' 1060 */ 1061 1062 int value = (int) (99 * speed); // max value to send is 99 in 100 step mode 1063 if (value > 99) { 1064 // max possible speed step 1065 value = 99; 1066 } 1067 SerialMessage m = new SerialMessage(); 1068 m.setOpCode(0xFE); 1069 1070 if (value < 0) { 1071 // System HALT (immediate stop; ALL) 1072 m.putAsWord(0xFFFF); 1073 1074 // send to layout (send 4 times to ensure received) 1075 tc.sendSerialMessage(m, null); 1076 tc.sendSerialMessage(m, null); 1077 tc.sendSerialMessage(m, null); 1078 tc.sendSerialMessage(m, null); 1079 } 1080 if (value == 0) { 1081 // normal speed step setting 1082 m.putAsWord(0xC860 + address.getNumber() * 128 + value); 1083 1084 // send to layout (send twice is set, but number of sends may need to be adjusted depending on efficiency) 1085 tc.sendSerialMessage(m, null); 1086 tc.sendSerialMessage(m, null); 1087 } 1088 1089 if (value > 0) { 1090 newValue = value; 1091 if (newValue > previousValue) { 1092 // increase TMCC "Relative" speed +1 (repeat * valueChange46) 1093 int valueChange46 = (newValue - previousValue); 1094 for (int i = 0x0000; i < valueChange46; i++) { 1095 m.putAsWord(0xC846 + address.getNumber() * 128); 1096 tc.sendSerialMessage(m, null); 1097 } 1098 } 1099 if (newValue < previousValue) { 1100 // decrease TMCC "Relative" speed -1 (repeat * valueChange44) 1101 int valueChange44 = (previousValue - newValue); 1102 for (int j = 0x0000; j < valueChange44; j++) { 1103 m.putAsWord(0xC844 + address.getNumber() * 128); 1104 tc.sendSerialMessage(m, null); 1105 } 1106 } 1107 previousValue = newValue; 1108 } 1109 } 1110 1111 // Option TMCC2_32 "Absolute" speed steps 1112 if (speedStepMode == jmri.SpeedStepMode.TMCC2_32) { 1113 1114 // TMCC2 Legacy 32 speed step mode 1115 int value = (int) (32 * speed); 1116 if (value > 31) { 1117 // max possible speed 1118 value = 31; 1119 } 1120 SerialMessage m = new SerialMessage(); 1121 m.setOpCode(0xF8); 1122 1123 if (value < 0) { 1124 // System HALT (immediate stop; ALL) 1125 m.putAsWord(0xFF8B); 1126 1127 // send to layout (send 4 times to ensure received) 1128 tc.sendSerialMessage(m, null); 1129 tc.sendSerialMessage(m, null); 1130 tc.sendSerialMessage(m, null); 1131 tc.sendSerialMessage(m, null); 1132 1133 } else { 1134 // normal speed setting 1135 m.putAsWord(0x0160 + address.getNumber() * 512 + value); 1136 1137 // send to command station (send twice is set, but number of sends may need to be adjusted depending on efficiency) 1138 tc.sendSerialMessage(m, null); 1139 tc.sendSerialMessage(m, null); 1140 } 1141 } 1142 1143 // Option TMCC2TR_32 "Absolute" speed steps 1144 if (speedStepMode == jmri.SpeedStepMode.TMCC2TR_32) { 1145 1146 // TMCC2 Legacy TR 32 speed step mode 1147 int value = (int) (32 * speed); 1148 if (value > 31) { 1149 // max possible speed 1150 value = 31; 1151 } 1152 SerialMessage m = new SerialMessage(); 1153 m.setOpCode(0xF9); 1154 1155 if (value < 0) { 1156 // System HALT (immediate stop; ALL) 1157 m.putAsWord(0xFF8B); 1158 1159 // send to layout (send 4 times to ensure received) 1160 tc.sendSerialMessage(m, null); 1161 tc.sendSerialMessage(m, null); 1162 tc.sendSerialMessage(m, null); 1163 tc.sendSerialMessage(m, null); 1164 1165 } else { 1166 // normal speed setting 1167 m.putAsWord(0x0160 + address.getNumber() * 512 + value); 1168 1169 // send to command station (send twice is set, but number of sends may need to be adjusted depending on efficiency) 1170 tc.sendSerialMessage(m, null); 1171 tc.sendSerialMessage(m, null); 1172 } 1173 } 1174 1175 // Option TMCC1_32 "Absolute" speed steps 1176 if (speedStepMode == jmri.SpeedStepMode.TMCC1_32) { 1177 1178 // TMCC1 32 speed step mode 1179 int value = (int) (32 * speed); 1180 if (value > 31) { 1181 // max possible speed 1182 value = 31; 1183 } 1184 SerialMessage m = new SerialMessage(); 1185 m.setOpCode(0xFE); 1186 1187 if (value < 0) { 1188 // System HALT (immediate stop; ALL) 1189 m.putAsWord(0xFFFF); 1190 1191 // send to layout (send 4 times to ensure received) 1192 tc.sendSerialMessage(m, null); 1193 tc.sendSerialMessage(m, null); 1194 tc.sendSerialMessage(m, null); 1195 tc.sendSerialMessage(m, null); 1196 1197 } else { 1198 // normal speed setting 1199 m.putAsWord(0x0060 + address.getNumber() * 128 + value); 1200 1201 // send to layout (send twice is set, but number of sends may need to be adjusted depending on efficiency) 1202 tc.sendSerialMessage(m, null); 1203 tc.sendSerialMessage(m, null); 1204 } 1205 } 1206 1207 // Option TMCC1TR_32 "Absolute" speed steps 1208 if (speedStepMode == jmri.SpeedStepMode.TMCC1TR_32) { 1209 1210 // TMCC1TR 32 speed step mode 1211 int value = (int) (32 * speed); 1212 if (value > 31) { 1213 // max possible speed 1214 value = 31; 1215 } 1216 SerialMessage m = new SerialMessage(); 1217 m.setOpCode(0xFE); 1218 1219 if (value < 0) { 1220 // System HALT (immediate stop; ALL) 1221 m.putAsWord(0xFFFF); 1222 1223 // send to layout (send 4 times to ensure received) 1224 tc.sendSerialMessage(m, null); 1225 tc.sendSerialMessage(m, null); 1226 tc.sendSerialMessage(m, null); 1227 tc.sendSerialMessage(m, null); 1228 1229 } else { 1230 // normal speed setting 1231 m.putAsWord(0xC860 + address.getNumber() * 128 + value); 1232 1233 // send to layout (send twice is set, but number of sends may need to be adjusted depending on efficiency) 1234 tc.sendSerialMessage(m, null); 1235 tc.sendSerialMessage(m, null); 1236 } 1237 } 1238 1239 synchronized(this) { 1240 firePropertyChange(SPEEDSETTING, oldSpeed, this.speedSetting); 1241 } 1242 record(speed); 1243 } 1244 1245 /** 1246 * {@inheritDoc} 1247 */ 1248 @Override 1249 public void setIsForward(boolean forward) { 1250 boolean old = isForward; 1251 isForward = forward; 1252 1253 // notify layout 1254 SerialMessage m = new SerialMessage(); 1255 if (speedStepMode == jmri.SpeedStepMode.TMCC1_32 || speedStepMode == jmri.SpeedStepMode.TMCC1_100) { 1256 m.setOpCode(0xFE); 1257 if (forward) { 1258 m.putAsWord(0x0000 + address.getNumber() * 128); 1259 setSpeedSetting(0.0f); 1260 } else { 1261 m.putAsWord(0x0003 + address.getNumber() * 128); 1262 setSpeedSetting(0.0f); 1263 } 1264 } 1265 1266 if (speedStepMode == jmri.SpeedStepMode.TMCC1TR_32 || speedStepMode == jmri.SpeedStepMode.TMCC1TR_100) { 1267 m.setOpCode(0xFE); 1268 if (forward) { 1269 m.putAsWord(0xC800 + address.getNumber() * 128); 1270 setSpeedSetting(0.0f); 1271 } else { 1272 m.putAsWord(0xC803 + address.getNumber() * 128); 1273 setSpeedSetting(0.0f); 1274 } 1275 } 1276 1277 if (speedStepMode == jmri.SpeedStepMode.TMCC2_32 || speedStepMode == jmri.SpeedStepMode.TMCC2_200) { 1278 m.setOpCode(0xF8); 1279 if (forward) { 1280 m.putAsWord(0x0100 + address.getNumber() * 512); 1281 setSpeedSetting(0.0f); 1282 } else { 1283 m.putAsWord(0x0103 + address.getNumber() * 512); 1284 setSpeedSetting(0.0f); 1285 } 1286 } 1287 1288 if (speedStepMode == jmri.SpeedStepMode.TMCC2TR_32 || speedStepMode == jmri.SpeedStepMode.TMCC2TR_200) { 1289 m.setOpCode(0xF9); 1290 if (forward) { 1291 m.putAsWord(0x0100 + address.getNumber() * 512); 1292 setSpeedSetting(0.0f); 1293 } else { 1294 m.putAsWord(0x0103 + address.getNumber() * 512); 1295 setSpeedSetting(0.0f); 1296 } 1297 } 1298 1299 // send to command station (send twice is set, but number of sends may need to be adjusted depending on efficiency) 1300 tc.sendSerialMessage(m, null); 1301 tc.sendSerialMessage(m, null); 1302 1303 firePropertyChange(ISFORWARD, old, isForward); 1304 } 1305 1306 /** 1307 * Send these messages to the layout and repeat 1308 * while button is pressed/on. 1309 * @param value Content of message to be sent in three bytes 1310 * @param func The number of the function being addressed 1311 */ 1312 protected void sendFnToLayout(int value, int func) { 1313 1314 if (speedStepMode == jmri.SpeedStepMode.TMCC2_200 || speedStepMode == jmri.SpeedStepMode.TMCC2TR_200) { 1315 if (func == 24) { 1316 setSpeedSetting(0.055f); 1317 return; 1318 } 1319 if (func == 25) { 1320 setSpeedSetting(0.205f); 1321 return; 1322 } 1323 if (func == 26) { 1324 setSpeedSetting(0.355f); 1325 return; 1326 } 1327 if (func == 27) { 1328 setSpeedSetting(0.505f); 1329 return; 1330 } 1331 if (func == 28) { 1332 setSpeedSetting(0.705f); 1333 return; 1334 } 1335 if (func == 29) { 1336 setSpeedSetting(1.0f); 1337 return; 1338 } 1339 } 1340 1341 if (speedStepMode == jmri.SpeedStepMode.TMCC1_100 || speedStepMode == jmri.SpeedStepMode.TMCC1TR_100) { 1342 if (func == 24) { 1343 setSpeedSetting(0.055f); 1344 return; 1345 } 1346 if (func == 25) { 1347 setSpeedSetting(0.205f); 1348 return; 1349 } 1350 if (func == 26) { 1351 setSpeedSetting(0.355f); 1352 return; 1353 } 1354 if (func == 27) { 1355 setSpeedSetting(0.505f); 1356 return; 1357 } 1358 if (func == 28) { 1359 setSpeedSetting(0.705f); 1360 return; 1361 } 1362 if (func == 29) { 1363 setSpeedSetting(1.0f); 1364 return; 1365 } 1366 } 1367 1368 if (speedStepMode == jmri.SpeedStepMode.TMCC1_32 || speedStepMode == jmri.SpeedStepMode.TMCC1TR_32 || speedStepMode == jmri.SpeedStepMode.TMCC2_32 || speedStepMode == jmri.SpeedStepMode.TMCC2TR_32) { 1369 if (func == 24) { 1370 setSpeedSetting(0.130f); 1371 return; 1372 } 1373 if (func == 25) { 1374 setSpeedSetting(0.320f); 1375 return; 1376 } 1377 if (func == 26) { 1378 setSpeedSetting(0.450f); 1379 return; 1380 } 1381 if (func == 27) { 1382 setSpeedSetting(0.580f); 1383 return; 1384 } 1385 if (func == 28) { 1386 setSpeedSetting(0.775f); 1387 return; 1388 } 1389 if (func == 29) { 1390 setSpeedSetting(1.0f); 1391 return; 1392 } 1393 } 1394 1395 /** 1396 * This code sends FnKey presses to the command station. 1397 * Send once is set, per the need of TMCC multi-key commands that 1398 * do not work when a specific command sequence is not followed. 1399 * If these multi-key commands are integrated into single FnKeys, 1400 * this "send" section can be converted back to "send twice" as 1401 * the other send sequences througout tmcc\SerialThrottle.java. 1402 */ 1403 1404 repeatFunctionSendWhileOn(value, func); // Single FnKey Press, Single Send; FnKey Held, Repeats FnKey while pressed. 1405 } 1406 1407 /** 1408 * This code block is necessary to support the send repeats of 1409 * the repeatFunctionSendWhileOn(value, func); code above. 1410 * This code block "Sends Again" if FkKey is still pressed/on, and 1411 * repeats per the interval set in static final int REPEAT_TIME. 1412 */ 1413 1414 static final int REPEAT_TIME = 150; 1415 1416 protected void repeatFunctionSendWhileOn(int value, int func) { 1417 if (getFunction(func)) { 1418 tc.sendSerialMessage(new SerialMessage(value), null); 1419 jmri.util.ThreadingUtil.runOnLayoutDelayed(() -> { 1420 repeatFunctionSendWhileOn(value, func); 1421 }, REPEAT_TIME); 1422 } 1423 } 1424 1425 /* 1426 * Set the speed step value. 1427 * <p> 1428 * The speed step range is from 32 steps, to 100 steps, to 200 steps 1429 * 1430 * @param mode only TMCC1_32, TMCC2_32, TMCC1_100 and TMCC2_200 are allowed 1431 */ 1432 @Override 1433 public void setSpeedStepMode(jmri.SpeedStepMode mode) { 1434 if (mode == jmri.SpeedStepMode.TMCC1_32 || mode == jmri.SpeedStepMode.TMCC1TR_32 || mode == jmri.SpeedStepMode.TMCC2_32 || mode == jmri.SpeedStepMode.TMCC2TR_32 || mode == jmri.SpeedStepMode.TMCC1_100 || mode == jmri.SpeedStepMode.TMCC1TR_100 || mode == jmri.SpeedStepMode.TMCC2_200 || mode == jmri.SpeedStepMode.TMCC2TR_200) { 1435 super.setSpeedStepMode(mode); 1436 } 1437 } 1438 1439 /** 1440 * {@inheritDoc} 1441 */ 1442 @Override 1443 public void throttleDispose() { 1444 finishRecord(); 1445 } 1446 1447}