package lejos.nxt.comm; import lejos.nxt.*; import java.io.*; /** * * Provides a USB connection * Supports both packetized, raw and stream based communincation. * Blocking and non-blocking I/O. * * Notes * When using the low level read/write functions no buffering is provided. This * means that for read operations te entire packet must be read or data will * be lost. A USB packet has a max size of 64 bytes. The Stream based functions * take care of this automatically. * * When operating in RAW mode low level USB packets may be read and written. * however this mode has no concept of EOF or start of a connection. * When using PACKET mode each packet has a single byte header added to it. This * is used to provide a simple start of connection/EOF model. */ public class USBConnection extends NXTConnection { static final int HDRSZ = 1; private static final int CLOSETIMEOUT2 = 100; public USBConnection(int mode) { state = CS_CONNECTED; bufSz = USB.BUFSZ; inBuf = new byte[USB.BUFSZ]; outBuf = new byte[USB.BUFSZ]; is = null; os = null; setIOMode(mode); } /** * Write all of the current output buffer to the device. * NOTE: To ensure correct operation of packet mode, this function should * only return 1 if all of the data will eventually be written. It should * avoid writing part of the data. * @param wait if true wait until the output has been written * @return -ve if error 0 if not written +ve if written */ int flushBuffer(boolean wait) { // assert(outCnt <= USB.BUFSZ) if (outCnt <= 0) return 1; int len; //LCD.drawString(" ", 8, 2); //LCD.drawInt(outCnt, 4, 0, 2); while ((len = USB.usbWrite(outBuf, 0, outCnt)) == 0 && wait && state >= CS_CONNECTED) //Thread.yield(); try{wait(1);}catch(Exception e){} if (len <= 0) return len; //LCD.drawInt(len, 8, 2); // assert (len == outCnt || len == 0) outCnt = 0; return len; } /** * Get any available data into the input buffer. * @param wait if true wait for data to be available. * @return -ve if error, 0 if not read, +ve if read */ int fillBuffer(boolean wait) { if (inCnt > 0) return inCnt; int cnt; while ((cnt = USB.usbRead(inBuf, 0, inBuf.length)) == 0 && wait && state >= CS_CONNECTED) //Thread.yield(); try{wait(1);}catch(Exception e){} //if (cnt != 0) LCD.drawInt(cnt, 4, 8, 1); inOffset = 0; if (cnt > 0) inCnt = cnt; return cnt; } /** * Close the USB stream connection. */ void disconnect() { USB.waitForDisconnect(this, CLOSETIMEOUT2); super.disconnect(); } /** * Tell the lower levels that they can release any resources for this * connection. */ void freeConnection() { USB.usbDisable(); } /** * Set the IO mode to be used for this connection. * USB has a 1 byte header, and does not use packet mode for LCP data. * @param mode */ public void setIOMode(int mode) { // Only packet modes uses a header for USB if (mode == PACKET) setHeader(HDRSZ); else setHeader(0); } }