OSDN Git Service

lejos_NXJ_win32_0_5_0beta.zip
[nxt-jsp/lejos_nxj.git] / nxtOSEK / lejos_nxj / src / java / classes / lejos / rcxcomm / Serial.java
diff --git a/nxtOSEK/lejos_nxj/src/java/classes/lejos/rcxcomm/Serial.java b/nxtOSEK/lejos_nxj/src/java/classes/lejos/rcxcomm/Serial.java
new file mode 100644 (file)
index 0000000..2709ca1
--- /dev/null
@@ -0,0 +1,251 @@
+package lejos.rcxcomm;\r
+\r
+import lejos.nxt.*;\r
+\r
+/**\r
+ * Emulation of the RCX Serial class with mindstorms NRLINK adapter.\r
+ * \r
+ * @author Lawrie Griffiths\r
+ *\r
+ */\r
+public class Serial {\r
+       private static RCXLink link;\r
+       private static byte[] buf1 = new byte[1];\r
+       private static byte[] packet = new byte[32];\r
+       private static boolean gotOpcode = false;\r
+       private static boolean gotPacket = false;\r
+       private static boolean skipping = false;\r
+       private static int paramsRead;\r
+       private static int paramsRequired;\r
+       private static int checkSum;\r
+       private static byte lastOpcode = 0;\r
+               \r
+       private Serial() {              \r
+       }\r
+       \r
+       /**\r
+        * Set the sensor port\r
+        * \r
+        * @param port the sensor port the link is connected to\r
+        */\r
+       public static void setPort(SensorPort port) {\r
+               link = new RCXLink(port);\r
+               link.setDefaultSpeed();\r
+               link.flush();\r
+       }\r
+\r
+       /**\r
+        * Read an assembled packet. NRLink only seems to read\r
+        * one byte at a time reliably, and does not\r
+        * return zero bytes. \r
+        * \r
+        * @param aBuffer the buffer to return the packet into\r
+        * @return the number of bytes in the packet\r
+        */\r
+       public static int readPacket (byte[] aBuffer) {\r
+               if (!gotPacket) return 0;\r
+               gotPacket = false;\r
+               gotOpcode = false;\r
+               for(int i=0;i<paramsRequired+1;i++) aBuffer[i] = packet[i];\r
+               return paramsRequired+1;\r
+       }\r
+       \r
+       /**\r
+        * Test if a packet is available\r
+        * \r
+        * @return true iff a packiet is available\r
+        */\r
+       public static boolean isPacketAvailable() {\r
+               if (gotPacket) return true;\r
+               \r
+               int available = link.bytesAvailable();\r
+               \r
+               // After a failure, skip to next header\r
+               \r
+               if (skipping) {\r
+                       while(available> 0) {\r
+                               readByte(buf1);\r
+                               //LCD.drawInt(buf1[0] & 0xFF, 4, 8, 7);\r
+                               //LCD.refresh();\r
+                               try {Thread.sleep(50);} catch (InterruptedException e) {}\r
+                               available--;\r
+                               if (headerByte(buf1[0])) {\r
+                                       skipping = false;\r
+                                       break;\r
+                               }\r
+                       }\r
+                       if (skipping) return false;\r
+                       gotOpcode = false;\r
+                       available = link.bytesAvailable();\r
+               }\r
+               \r
+               // If we don't have the opcode yet, skip header bytes\r
+               \r
+               if (!gotOpcode) {\r
+                       byte op = 0;\r
+                       \r
+                       // skip header bytes, and check complement \r
+                       // for candidate opcode.\r
+                       \r
+                       while (available > 1) { // Need 2 bytes\r
+                               readByte(buf1);\r
+                               available--;\r
+                               op = buf1[0];\r
+                               if (!headerByte(op)) {\r
+                                       readByte(buf1);\r
+                                       available--;\r
+                                       if (complement(buf1[0], op)) {\r
+                                               gotOpcode = true;\r
+                                               break;\r
+                                       } else {                                        \r
+                                               // Skip to header if complement check failed                            \r
+                                               skipping = true;\r
+                                               return false;\r
+                                       }\r
+                               }\r
+                       }\r
+                       \r
+                       // If we have the op code, calculate number of parameters\r
+                       // and start the checksum\r
+                       \r
+                       if (!gotOpcode) return false;                   \r
+                       available = link.bytesAvailable();\r
+                       packet[0] = op;\r
+                       int pq = op & 0x7;\r
+                       paramsRequired = 0;\r
+                       if (pq > 1 && pq < 6) paramsRequired = pq; \r
+                       if (pq == 7) paramsRequired = 1;\r
+                       paramsRead = 0;\r
+                       checkSum = (op & 0xFF);\r
+                       //LCD.drawInt(opCode & 0xFF,4, 0,6);\r
+                       //LCD.drawInt(paramsRequired,4, 0,7);\r
+                       //LCD.refresh();\r
+                       //try {Thread.sleep(500);} catch (InterruptedException e) {}\r
+               }\r
+               \r
+               // If we don't have all the parameters, get them\r
+               // and check the complements\r
+               \r
+        if (paramsRead < paramsRequired) {\r
+               while (available > 1) {\r
+                       readByte(buf1);\r
+                       available--;\r
+                       byte param = buf1[0];\r
+                       readByte(buf1);\r
+                       available--;\r
+                       if (complement(buf1[0], param)) {\r
+                               paramsRead++;\r
+                               checkSum += (param & 0xFF);\r
+                               packet[paramsRead] = param;\r
+                       } else {\r
+                               skipping = true;\r
+                               //LCD.drawInt(param &0xFF, 4,  0, 4);\r
+                               //LCD.drawInt(buf1[0] & 0xFF, 4, 8, 4);\r
+                               //LCD.refresh();\r
+                               return false;\r
+                       }\r
+                       if (paramsRead == paramsRequired) break;\r
+               }\r
+               if (paramsRead != paramsRequired) return false;\r
+               available = link.bytesAvailable();\r
+        }\r
+\r
+        // Check the checksum and its complement\r
+        \r
+               if (available > 1) {\r
+                       readByte(buf1);\r
+                       available--;\r
+                       byte checkDigit = buf1[0];\r
+                       readByte(buf1);\r
+                       available--;\r
+                       //LCD.drawInt(checkDigit &0xFF, 4,  0, 5);\r
+                       //LCD.drawInt(checkSum & 0xFF, 4, 8, 5);\r
+                       //LCD.refresh();\r
+                       if (complement(buf1[0], checkDigit) &&\r
+                           (checkDigit & 0xFF) == (checkSum & 0xFF)) {\r
+                               gotPacket = true;\r
+                               lastOpcode = packet[0];\r
+                       } else {\r
+                               // Skip to header if complement check\r
+                               // or checksum fails\r
+                               skipping = true;\r
+                       }\r
+               }\r
+\r
+               return gotPacket;\r
+       }\r
+       \r
+       /**\r
+        * Send a packet\r
+        * \r
+        * @param aBuffer the buffer containing the packet\r
+        * @param aOffset the offset in the buffer - must be zero\r
+        * @param aLen the length of the packet\r
+        * @return true iff the packet was successfully sent\r
+        */\r
+       public static boolean sendPacket (byte[] aBuffer, int aOffset, int aLen) {\r
+               sleep();\r
+               link.defineAndRun(aBuffer, aLen); // assumes offset 0\r
+               sleep();\r
+               return true;\r
+       }\r
+\r
+       /**\r
+        * Set long range\r
+        *\r
+        */\r
+       public static void setRangeLong() {\r
+               link.setRangeLong();\r
+       }\r
+        \r
+       /**\r
+        * Set short range\r
+        * \r
+        */\r
+       public static void setRangeShort() {\r
+                link.setRangeLong();\r
+       }\r
+        \r
+       /**\r
+        * Reset the link - null\r
+        *\r
+        */\r
+       public static void resetSerial() {\r
+       }\r
+        \r
+       /**\r
+        * Wait until the packet is sent - null\r
+        *\r
+        */\r
+       public static void waitTillSent() {      \r
+       }\r
+        \r
+       /**\r
+        * Get the RCXLink object associated with the Serial class\r
+        * \r
+        * @return the link\r
+        */\r
+       public static RCXLink getLink() {\r
+                return link;\r
+       }\r
+\r
+       private static void sleep() {\r
+               try {\r
+                        Thread.sleep(100);\r
+                } catch (InterruptedException e) {}\r
+       }\r
+       \r
+       private static boolean headerByte(byte b) {\r
+               return(b == 0x55 || b == (byte) 0xFF || b == 0x00);\r
+               \r
+       }\r
+       \r
+       private static void readByte(byte [] b) {\r
+               b[0] = 0;\r
+               link.readBytes(b);\r
+       }\r
+       \r
+       private static boolean complement(byte b1, byte b2) {\r
+               return ((b1 &0xFF) + (b2 & 0xFF) == 0xFF);\r
+       }\r
+}\r