3 import lejos.rcxcomm.Opcode;
\r
5 * Supports Mindsensors NRLink RCX IR adapter.
\r
7 * @author Lawrie Griffiths <lawrie.griffiths@ntlworld.com>
\r
10 public class RCXLink extends I2CSensor implements Opcode {
\r
12 private byte[] buf = new byte[4];
\r
14 public RCXMotor A = new RCXMotor(new RCXRemoteMotorPort(this,0));
\r
15 public RCXMotor B = new RCXMotor(new RCXRemoteMotorPort(this,1));
\r
16 public RCXMotor C = new RCXMotor(new RCXRemoteMotorPort(this,2));
\r
18 private final static byte SLOW_SPEED = 0x44; // Default 2400 baud
\r
19 private final static byte FLUSH = 0x46; // Flush the FIFO buffer
\r
20 private final static byte HIGH_SPEED = 0x48; // 4800 baudprivate final static byte LONG_RANGE = 0x4C;
\r
21 private final static byte SHORT_RANGE = 0x53;
\r
22 private final static byte LONG_RANGE = 0x4c;
\r
23 private final static byte TRANSMIT_RAW_MACRO = 0x55; // Transmit Unassembled raw macro data;
\r
24 private final static byte COMMAND = 0x41;
\r
25 private final static byte RUN = 0x52;
\r
26 private final static byte ARPA_ON = 0x4E;
\r
27 private final static byte ARPA_OFF = 0x4F;
\r
28 private final static byte STATUS_REG = 0x41;
\r
29 private final static byte RX_DATA_LEN = 0x40;
\r
30 private final static byte TX_DATA_LEN = 0x40;
\r
31 private final static byte RX_DATA = 0x42;
\r
32 private final static byte TX_DATA = 0x42;
\r
34 // ROM Macro Definitions:
\r
35 public final static byte SHORT_RANGE_IR = 0x01;
\r
36 public final static byte LONG_RANGE_IR = 0x04;
\r
37 public final static byte POWER_OFF_RCX = 0x07;
\r
38 public final static byte RUN_PROGRAM_1 = 0x09;
\r
39 public final static byte RUN_PROGRAM_2 = 0x0D;
\r
40 public final static byte RUN_PROGRAM_3 = 0x11;
\r
41 public final static byte RUN_PROGRAM_4 = 0x15;
\r
42 public final static byte RUN_PROGRAM_5 = 0x19;
\r
43 public final static byte STOP_ALL_PROGRAMS = 0x1D;
\r
44 public final static byte MOTOR_A_FORWARD = 0x21;
\r
45 public final static byte MOTOR_A_REVERSED = 0x25;
\r
46 public final static byte MOTOR_B_FORWARD = 0x29;
\r
47 public final static byte MOTOR_B_REVERSED = 0x2D;
\r
48 public final static byte MOTOR_C_FORWARD = 0x31;
\r
49 public final static byte MOTOR_C_REVERSED = 0x35;
\r
51 * NOTE: The BEEP macro is unreliable.
\r
52 * It works once, and then needs another command executed
\r
53 * before it works again.
\r
55 public final static byte BEEP = 0x39;
\r
57 public final static int EEPROM_BUFFER = 0x78;
\r
58 public final static int DELAY = 10;
\r
60 public RCXLink(I2CPort port) {
\r
64 public void runMacro(int addr) {
\r
66 buf[1] = (byte) addr;
\r
68 sendData(COMMAND, buf, 2);
\r
71 public void beep() {
\r
75 public void runProgram(int programNumber) {
\r
76 runMacro(RUN_PROGRAM_1 + ((programNumber-1)*4));
\r
79 public void forwardStep(int id) { // RCX Remote Command
\r
80 runMacro(MOTOR_A_FORWARD + (id*8));
\r
83 public void backwardStep(int id) { // RCX Remote Command
\r
84 runMacro(MOTOR_A_REVERSED + (id*8));
\r
87 public void setRCXRangeShort() {
\r
88 runMacro(SHORT_RANGE_IR);
\r
91 public void setRCXRangeLong() {
\r
92 runMacro(LONG_RANGE_IR);
\r
95 public void powerOff() {
\r
96 runMacro(POWER_OFF_RCX);
\r
99 public void stopAllPrograms() {
\r
100 runMacro(STOP_ALL_PROGRAMS);
\r
103 public void flush() {
\r
104 sendData(COMMAND, FLUSH);
\r
107 public void setDefaultSpeed() {
\r
108 sendData(COMMAND, SLOW_SPEED);
\r
111 public void setHighSpeed() {
\r
112 sendData(COMMAND, HIGH_SPEED);
\r
115 public void setRangeLong() {
\r
116 sendData(COMMAND, LONG_RANGE);
\r
119 public void setRangeShort() {
\r
120 sendData(COMMAND, SHORT_RANGE);
\r
123 public void setAPDAOn() {
\r
124 sendData(COMMAND, ARPA_ON);
\r
127 public void setAPDAOff() {
\r
129 sendData(COMMAND, ARPA_OFF);
\r
132 public void defineMacro(int addr, byte[] macro) {
\r
133 sendData((byte) addr,(byte) macro.length);
\r
135 sendData((byte) addr+1, macro, macro.length);
\r
138 public int getStatus() {
\r
139 getData(STATUS_REG, buf, 1);
\r
140 return buf[0] & 0xFF;
\r
143 public int bytesAvailable() {
\r
144 getData(RX_DATA_LEN, buf, 1);
\r
145 return buf[0] & 0xFF;
\r
148 public void ping() {
\r
149 buf[0] = OPCODE_ALIVE;
\r
150 defineAndRun(buf,1);
\r
153 public void sendF7(int msg) {
\r
154 buf[0] = (byte) OPCODE_SET_MESSAGE;
\r
155 buf[1] = (byte) (msg & 0xFF);
\r
156 defineAndRun(buf,2);
\r
159 public void sendRemoteCommand(int msg) {
\r
160 buf[0] = OPCODE_REMOTE_COMMAND;
\r
161 buf[1] = (byte) (msg >> 8);
\r
162 buf[2] = (byte) (msg & 0xFF);
\r
163 defineAndRun(buf,3);
\r
166 public void setMotorPower(int id, int power) {
\r
167 buf[0] = OPCODE_SET_MOTOR_POWER;
\r
168 buf[1] = (byte) (1 << id);
\r
170 buf[3] = (byte) power;
\r
171 defineMacro(EEPROM_BUFFER, buf); // Bug: sendData cannot send more than 3 bytes
\r
173 sendData(EEPROM_BUFFER+4, (byte) power);
\r
175 runMacro(EEPROM_BUFFER);
\r
178 public void stopMotor(int id) {
\r
179 buf[0] = OPCODE_SET_MOTOR_ON_OFF;
\r
180 buf[1] = (byte) ((1 << id) | 0x40);
\r
181 defineAndRun(buf,2);
\r
184 public void startMotor(int id) {
\r
185 buf[0] = OPCODE_SET_MOTOR_ON_OFF;
\r
186 buf[1] = (byte) ((1 << id) | 0x80);
\r
187 defineAndRun(buf,2);
\r
190 public void fltMotor(int id) {
\r
191 buf[0] = OPCODE_SET_MOTOR_ON_OFF;
\r
192 buf[1] = (byte) (1 << id);
\r
193 defineAndRun(buf,2);
\r
196 public void forward(int id) {
\r
197 buf[0] = (byte) OPCODE_SET_MOTOR_DIRECTION;
\r
198 buf[1] = (byte) ((1 << id) | 0x80);
\r
199 defineAndRun(buf,2);
\r
202 public void backward(int id) {
\r
203 buf[0] = (byte) OPCODE_SET_MOTOR_DIRECTION;
\r
204 buf[1] = (byte) (1 << id);
\r
205 defineAndRun(buf,2);
\r
208 public void setRawMode() {
\r
209 sendData(COMMAND, TRANSMIT_RAW_MACRO);
\r
212 public void sendBytes(byte[] data, int len) {
\r
213 sendData(TX_DATA,data,len);
\r
215 sendData(TX_DATA_LEN, (byte) len);
\r
218 public int readBytes(byte [] data) {
\r
219 getData(RX_DATA_LEN,buf,1);
\r
220 int numBytes = buf[0];
\r
221 if (numBytes > 0) {
\r
222 if (numBytes > data.length) numBytes = data.length;
\r
224 getData(RX_DATA,data,numBytes);
\r
229 private void sleep() {
\r
231 Thread.sleep(DELAY);
\r
232 } catch (InterruptedException e) {}
\r
235 public void defineAndRun(byte[] macro, int len) {
\r
236 sendData(EEPROM_BUFFER,(byte) len);
\r
238 sendData(EEPROM_BUFFER+1, macro, len);
\r
240 runMacro(EEPROM_BUFFER);
\r