From 0664c04506e8d83ed68d92823f8217b1133a6cb5 Mon Sep 17 00:00:00 2001 From: schlaepfer Date: Fri, 18 Nov 2005 14:59:13 +0000 Subject: [PATCH] - uart support added git-svn-id: https://svn.code.sf.net/p/libusbjava/code/trunk@56 94ad28fe-ef68-46b1-9651-e7ae4fcf1c4c --- mcdp/src/ch/ntb/mcdp/uart/Uart.java | 57 +++++++++++++ mcdp/src/ch/ntb/mcdp/uart/UartDispatch.java | 79 +++++++++++++++++++ .../src/ch/ntb/mcdp/uart/UartInputStream.java | 75 ++++++++++++++++++ .../ch/ntb/mcdp/uart/UartOutputStream.java | 51 ++++++++++++ 4 files changed, 262 insertions(+) create mode 100644 mcdp/src/ch/ntb/mcdp/uart/Uart.java create mode 100644 mcdp/src/ch/ntb/mcdp/uart/UartDispatch.java create mode 100644 mcdp/src/ch/ntb/mcdp/uart/UartInputStream.java create mode 100644 mcdp/src/ch/ntb/mcdp/uart/UartOutputStream.java diff --git a/mcdp/src/ch/ntb/mcdp/uart/Uart.java b/mcdp/src/ch/ntb/mcdp/uart/Uart.java new file mode 100644 index 0000000..4f6159d --- /dev/null +++ b/mcdp/src/ch/ntb/mcdp/uart/Uart.java @@ -0,0 +1,57 @@ +package ch.ntb.mcdp.uart; + +import java.io.InputStream; +import java.io.OutputStream; +import java.util.LinkedList; + +public abstract class Uart { + + private UartOutputStream out; + + UartInputStream in; + + Uart(LinkedList list) { + list.add(this); + out = new UartOutputStream(getSTYPE_IN()); + in = new UartInputStream(); + } + + /** + * Get the stream to write to the target device. + * + * @return OutputStream to write to target device + */ + OutputStream getOutputStream() { + return out; + } + + /** + * Get the stream to read from the target device. + * + * @return InputStream to read from target device + */ + InputStream getInputStream() { + return in; + } + + /** + * The packet subtype specified for this UART packet (from target to PC). + *
+ * Note: This direction is different from the input/output direction of the + * streams. + * + * @return packet subtype + */ + abstract byte getSTYPE_OUT(); + + /** + * The packet subtype specified for this UART packet (from PC to target). + *
+ * Note: This direction is different from the input/output direction of the + * streams. + * + * @return packet subtype + */ + abstract byte getSTYPE_IN(); + +} diff --git a/mcdp/src/ch/ntb/mcdp/uart/UartDispatch.java b/mcdp/src/ch/ntb/mcdp/uart/UartDispatch.java new file mode 100644 index 0000000..52d85c7 --- /dev/null +++ b/mcdp/src/ch/ntb/mcdp/uart/UartDispatch.java @@ -0,0 +1,79 @@ +package ch.ntb.mcdp.uart; + +import java.util.LinkedList; + +import ch.ntb.mcdp.usb.DataPacket; +import ch.ntb.mcdp.usb.Dispatch; +import ch.ntb.mcdp.usb.DispatchException; +import ch.ntb.mcdp.usb.USBDevice; +import ch.ntb.usb.USB; +import ch.ntb.usb.USBException; +import ch.ntb.usb.USBTimeoutException; + +public class UartDispatch { + + public static final int MAX_UART_PAYLOAD = USB.MAX_DATA_SIZE + - DataPacket.PACKET_MIN_LENGTH; + + private static boolean running = false; + + static Thread dispatchThread; + + static LinkedList uarts = new LinkedList(); + + public static void start() { + if (dispatchThread == null) { + dispatchThread = new Thread() { + @Override + public void run() { + while (running) { + DataPacket data; + try { + data = Dispatch.readUART(); + if (data != null) { + while (uarts.iterator().hasNext()) { + Uart obj = uarts.iterator().next(); + if (obj.getSTYPE_OUT() == data.subtype) { + obj.in.bufferList.add(data); + } + } + } + } catch (USBTimeoutException e) { + // ignore TimeoutExceptions + } catch (USBException e) { + // TODO: Exceptionhandling + e.printStackTrace(); + } catch (DispatchException e) { + // TODO: Exceptionhandling + e.printStackTrace(); + } + } + } + }; + } else { + running = true; + dispatchThread.start(); + } + } + + public static void stop() { + running = false; + } + + public LinkedList getUartList() { + return uarts; + } + + public static void write(byte packetSubType, byte[] data, int len) + throws USBException { + byte[] usbData = new byte[len + DataPacket.PACKET_MIN_LENGTH]; + usbData[0] = DataPacket.PACKET_HEADER; + usbData[1] = Dispatch.MTYPE_UART; + usbData[2] = packetSubType; + for (int i = 0; i < len; i++) { + usbData[DataPacket.PACKET_DATA_OFFSET + i] = data[i]; + } + usbData[DataPacket.PACKET_DATA_OFFSET + len] = DataPacket.PACKET_END; + USBDevice.write_UART(data, len); + } +} diff --git a/mcdp/src/ch/ntb/mcdp/uart/UartInputStream.java b/mcdp/src/ch/ntb/mcdp/uart/UartInputStream.java new file mode 100644 index 0000000..8ab1851 --- /dev/null +++ b/mcdp/src/ch/ntb/mcdp/uart/UartInputStream.java @@ -0,0 +1,75 @@ +package ch.ntb.mcdp.uart; + +import java.io.IOException; +import java.io.InputStream; +import java.util.LinkedList; + +import ch.ntb.mcdp.usb.DataPacket; + +public class UartInputStream extends InputStream { + + private int bufferPos = 0; + + LinkedList bufferList = new LinkedList(); + + @Override + public int read() throws IOException { + while (!bufferList.isEmpty()) { + if (bufferPos >= bufferList.element().data.length) { + // remove element, reset bufferPos + bufferList.remove(); + bufferPos = 0; + } else { + return bufferList.element().data[bufferPos++]; + } + } + return -1; + } + + @Override + public int read(byte b[]) throws IOException { + return read(b, 0, b.length); + } + + @Override + public int read(byte b[], int off, int len) throws IOException { + if (b == null) { + throw new NullPointerException(); + } else if ((off < 0) || (off > b.length) || (len < 0) + || ((off + len) > b.length) || ((off + len) < 0)) { + throw new IndexOutOfBoundsException(); + } else if (len == 0) { + return 0; + } + + // TODO: optimize + int c = read(); + if (c == -1) { + return -1; + } + b[off] = (byte) c; + + int i = 1; + try { + for (; i < len; i++) { + c = read(); + if (c == -1) { + break; + } + if (b != null) { + b[off + i] = (byte) c; + } + } + } catch (IOException ee) { + } + return i; + } + + @Override + public int available() throws IOException { + if (bufferList.isEmpty()) + return 0; + return bufferList.element().data.length; + } + +} diff --git a/mcdp/src/ch/ntb/mcdp/uart/UartOutputStream.java b/mcdp/src/ch/ntb/mcdp/uart/UartOutputStream.java new file mode 100644 index 0000000..562ed6d --- /dev/null +++ b/mcdp/src/ch/ntb/mcdp/uart/UartOutputStream.java @@ -0,0 +1,51 @@ +package ch.ntb.mcdp.uart; + +import java.io.IOException; +import java.io.OutputStream; + +import ch.ntb.usb.USBException; + +public class UartOutputStream extends OutputStream { + + private byte packetSubType; + + UartOutputStream(byte packetSubType) { + this.packetSubType = packetSubType; + } + + @Override + public void write(int b) throws IOException { + byte[] data = new byte[1]; + try { + UartDispatch.write(packetSubType, data, 1); + } catch (USBException e) { + throw new IOException(e.getMessage()); + } + } + + @Override + public void write(byte b[], int off, int len) throws IOException { + if (b == null) { + throw new NullPointerException(); + } else if ((off < 0) || (off > b.length) || (len < 0) + || ((off + len) > b.length) || ((off + len) < 0)) { + throw new IndexOutOfBoundsException(); + } else if (len == 0) { + return; + } + int newLen = 0; + do { + newLen = Math.min(len, UartDispatch.MAX_UART_PAYLOAD); + byte[] data = new byte[newLen]; + for (int i = 0; i < newLen; i++) { + data[i] = b[off + i]; + } + try { + UartDispatch.write(packetSubType, data, newLen); + } catch (USBException e) { + throw new IOException(e.getMessage()); + } + len -= newLen; + } while (len > UartDispatch.MAX_UART_PAYLOAD); + } +}