001package jmri.jmrix.loconet.locoio; 002 003import jmri.jmrix.loconet.LnTrafficController; 004import jmri.jmrix.loconet.LocoNetMessage; 005 006/** 007 * Manage the communication to/from a LocoIO board. Deprecated since version 5.12. Will be removed 2025 version 5.13 008 * <p> 009 * Uses the LOCONETSV1MODE programming mode. 010 * <p> 011 * Uses LnProgrammer LOCOIO_PEER_CODE_SV_VER1 message format, comparable to DecoderPro LOCONETSV1MODE 012 * Since JMRI 4.11.6 the LocoIO tool does not work with the HDL LocoIO rev 3 and newer boards, 013 * with risk of breaking the stored config. Use the DecoderPro decoder definition. 014 * 015 * @see jmri.jmrix.loconet.LnOpsModeProgrammer#message(LocoNetMessage) 016 * 017 * Programming SV's 018 * <p> 019 * The SV's in a LocoIO hardware module can be programmed using LocoNet OPC_PEER_XFER messages. 020 * <p> 021 * Commands for setting SV's: 022 * <p> 023 * PC to LocoIO LocoNet message (OPC_PEER_XFER) 024 * <pre><code> 025 * Code LOCOIO_SV_READ _or_ LOCOIO_SV_WRITE ---- 026 * 0xE5 OPC_PEER_XFER 027 * 0x10 Message length 028 * SRCL 0x50 0x50 // low address byte of LocoBuffer 029 * DSTL LocoIO low address 030 * DSTH 0x01 0x01 // Fixed LocoIO high address 031 * PXCT1 032 * D1 LOCOIO_SV_READ _or_ LOCOIO_SV_WRITE // Read/Write command 033 * D2 SV number SV number 034 * D3 0x00 0x00 035 * D4 0x00 Data to Write 036 * PXCT2 037 * D5 LocoIO Sub-address 038 * D6 0x00 0x00 039 * D7 0x00 0x00 040 * D8 0x00 0x00 041 * CHK Checksum Checksum 042 * </code></pre> 043 * 044 * LocoIO to PC reply message (OPC_PEER_XFER) 045 * <pre><code> 046 * Code LOCOIO_SV_READ _or_ LOCOIO_SV_WRITE ---- 047 * 0xE5 OPC_PEER_XFER 048 * 0x10 Message length 049 * SRCL LocoIO low address 050 * DSTL 0x50 0x50 // low address byte of LocoBuffer 051 * DSTH 0x01 0x01 // high address byte of LocoBuffer 052 * PXCT1 MSB LocoIO version // High order bit of LocoIO version 053 * D1 LOCOIO_SV_READ _or_ LOCOIO_SV_WRITE // Original Command 054 * D2 SV number requested 055 * D3 LSBs LocoIO version // Lower 7 bits of LocoIO version 056 * D4 0x00 0x00 057 * PXCT2 MSB Requested Data // High order bit of requested data 058 * D5 LocoIO Sub-address 059 * D6 Requested Data 0x00 060 * D7 Requested Data + 1 0x00 061 * D8 Requested Data + 2 Written Data 062 * CHK Checksum Checksum 063 * </code></pre> 064 * 065 * @author John Plocher 2006, 2007 066 */ 067public class LocoIO { 068 069 public static final int LOCOIO_SV_WRITE = 0x01; 070 public static final int LOCOIO_SV_READ = 0x02; 071 public static final int LOCOIO_BROADCAST_ADDRESS = 0x0100; // LocoIO broadcast 072 073 public static final int LOCOIO_PEER_CODE_7BIT_ADDRS = 0x00; 074 public static final int LOCOIO_PEER_CODE_ANSI_TEXT = 0x00; // not used 075 public static final int LOCOIO_PEER_CODE_SV_VER1 = 0x08; 076 public static final int LOCOIO_PEER_CODE_SV_VER2 = 0x09; // not used 077 078 /** 079 * Create a new instance of LocoIO. 080 */ 081 public LocoIO() { 082 } 083 084 public static int SENSOR_ADR(int a1, int a2) { 085 return (((a2 & 0x0f) * 128) + (a1 & 0x7f)) + 1; 086 } 087 088 /** 089 * Compose a LocoNet message from the given ingredients for reading 090 * the value of one specific SV from a given LocoIO. 091 * 092 * @param locoIOAddress base address of the LocoIO board to read from 093 * @param locoIOSubAddress subAddress of the LocoIO board 094 * @param sv the SV index to query 095 * @return complete message to send 096 */ 097 public static LocoNetMessage readSV(int locoIOAddress, int locoIOSubAddress, int sv) { 098 int[] contents = {LOCOIO_SV_READ, sv, 0, 0, locoIOSubAddress, 0, 0, 0}; 099 int dstExtr = locoIOAddress | 0x0100; // force version 1 tag, cf. LnOpsModeProgrammer 100 101 return LocoNetMessage.makePeerXfr( 102 0x1050, // B'cast locobuffer address 103 dstExtr, 104 contents, // SV and SubAddr to read 105 LOCOIO_PEER_CODE_SV_VER1 106 ); 107 } 108 109 /** 110 * Compose a LocoNet message from the given ingredients for reading 111 * the value of one specific SV from a given LocoIO. 112 * 113 * @param locoIOAddress base address of the LocoIO board to read from 114 * @param locoIOSubAddress subAddress of the LocoIO board 115 * @param sv the SV index to change 116 * @param data the new value to store in the board's SV 117 * @return complete message to send 118 */ 119 public static LocoNetMessage writeSV(int locoIOAddress, int locoIOSubAddress, int sv, int data) { 120 int[] contents = {LOCOIO_SV_WRITE, sv, 0, data, locoIOSubAddress, 0, 0, 0}; 121 int dstExtr = locoIOAddress | 0x0100; // force version 1 tag, cf. LnOpsModeProgrammer 122 123 return LocoNetMessage.makePeerXfr( 124 0x1050, // B'cast locobuffer address 125 dstExtr, 126 contents, // SV and SubAddr to read 127 LOCOIO_PEER_CODE_SV_VER1 128 ); 129 } 130 131 /** 132 * Compose and send a message out onto LocoNet changing the LocoIO hardware board 133 * address of all connected LocoIO boards. 134 * <p> 135 * User is warned that this is a broadcast type operation. 136 * 137 * @param address the new base address of the LocoIO board to change 138 * @param subAddress the new subAddress of the board 139 * @param ln the TrafficController to use for sending the message 140 */ 141 public static void programLocoIOAddress(int address, int subAddress, LnTrafficController ln) { 142 LocoNetMessage msg; 143 msg = LocoIO.writeSV(LOCOIO_BROADCAST_ADDRESS, 0, 1, address & 0xFF); 144 ln.sendLocoNetMessage(msg); 145 if (subAddress != 0) { 146 msg = LocoIO.writeSV(LOCOIO_BROADCAST_ADDRESS, 0, 2, subAddress); 147 ln.sendLocoNetMessage(msg); 148 } 149 } 150 151 /** 152 * Send out a probe of all connected LocoIO units on a given LocoNet connection. 153 * 154 * @param ln the TrafficController to use for sending the message 155 */ 156 public static void probeLocoIOs(LnTrafficController ln) { 157 LocoNetMessage msg; 158 msg = LocoIO.readSV(LOCOIO_BROADCAST_ADDRESS, 0, 2); 159 ln.sendLocoNetMessage(msg); 160 } 161 162}