diff --git a/mcdp/.classpath b/mcdp/.classpath new file mode 100644 index 0000000..15e8e18 --- /dev/null +++ b/mcdp/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/mcdp/.project b/mcdp/.project new file mode 100644 index 0000000..5499f83 --- /dev/null +++ b/mcdp/.project @@ -0,0 +1,19 @@ + + + mcdp + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jem.workbench.JavaEMFNature + org.eclipse.jdt.core.javanature + org.eclipse.jem.beaninfo.BeanInfoNature + + diff --git a/mcdp/.settings/org.eclipse.jdt.core.prefs b/mcdp/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..6f26031 --- /dev/null +++ b/mcdp/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,12 @@ +#Wed Oct 26 15:55:07 CEST 2005 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.5 diff --git a/mcdp/.settings/org.eclipse.jdt.ui.prefs b/mcdp/.settings/org.eclipse.jdt.ui.prefs new file mode 100644 index 0000000..1b61afb --- /dev/null +++ b/mcdp/.settings/org.eclipse.jdt.ui.prefs @@ -0,0 +1,3 @@ +#Thu Oct 06 09:12:32 CEST 2005 +eclipse.preferences.version=1 +internal.default.compliance=default diff --git a/mcdp/resources/targets/mc68332/registerDictionary.dtd b/mcdp/resources/targets/mc68332/registerDictionary.dtd new file mode 100644 index 0000000..b77ba24 --- /dev/null +++ b/mcdp/resources/targets/mc68332/registerDictionary.dtd @@ -0,0 +1,15 @@ + + + + + + + + + + diff --git a/mcdp/resources/targets/mc68332/registerDictionary.xml b/mcdp/resources/targets/mc68332/registerDictionary.xml new file mode 100644 index 0000000..7c3c91b --- /dev/null +++ b/mcdp/resources/targets/mc68332/registerDictionary.xml @@ -0,0 +1,402 @@ + + + + + + + + + + sim module configuration register + + + clock synthesizer control + + + system protection control + + + + chip select pin assignment register 0 + + + + + chip select pin assignment register 1 + + + + CSBOOT base address register + + + CSBOOT option register + + + + chip select 0 base address register + + + chip select 0 option register + + + chip select 1 base address register + + + chip select 1 option register + + + chip select 2 base address register + + + chip select 2 option register + + + chip select 3 base address register + + + chip select 3 option register + + + chip select 4 base address register + + + chip select 4 option register + + + chip select 5 base address register + + + chip select 5 option register + + + chip select 6 base address register + + + chip select 6 option register + + + chip select 7 base address register + + + chip select 7 option register + + + chip select 8 base address register + + + chip select 8 option register + + + chip select 9 base address register + + + chip select 9 option register + + + + + + + TPURAM module configuration register + + + TPURAM base address and status register + + + + TPU module control register + + + TPU configuration register + + + development support control register + + + development support status register + + + TPU interrupt configuration register + + + TPU interrupt enable register + + + channel function select register 0 + + + channel function select register 1 + + + channel function select register 2 + + + channel function select register 3 + + + host sequence register 0 + + + host sequence register 1 + + + host service request register 0 + + + host service request register 1 + + + channel priority register 0 + + + channel priority register 1 + + + TPU interrupt status register + + + ??? + + + service grant latch register + + + decoded channel number register + + + + + + Port E data register 0 + + + Port E data register 1 + + + Port E data direction register + + + Port E pin assignment register + + + + + + Port F data register 0 + + + Port F data register 1 + + + Port F data direction register + + + Port F pin assignment register + + + + + + TPU parameter ram start address + + + TPU parameter ram start address + + + TPU parameter ram start address + + + TPU parameter ram start address + + + TPU parameter ram start address + + + TPU parameter ram start address + + + TPU parameter ram start address + + + TPU parameter ram start address + + + TPU parameter ram start address + + + TPU parameter ram start address + + + TPU parameter ram start address + + + TPU parameter ram start address + + + TPU parameter ram start address + + + TPU parameter ram start address + + + TPU parameter ram start address + + + TPU parameter ram start address + + + + + + QSM configuration register + + + QSM test register + + + QSM interrupt level register + + + QSM interrupt vector register + + + SCI control register 0 + + + SCI control register 1 + + + SCI status register + + + SCI data register + + + + QSM port data register + + + QSM pin assignment register + + + QSM data direction register + + + QSPI control register 0 + + + QSPI control register 1 + + + QSPI control register 2 + + + QSPI control register 3 + + + QSPI status register + + + + QSPI receive data + + + QSPI transmit data + + + QSPI command control + + + \ No newline at end of file diff --git a/mcdp/scrapBook.jpage b/mcdp/scrapBook.jpage new file mode 100644 index 0000000..5356119 --- /dev/null +++ b/mcdp/scrapBook.jpage @@ -0,0 +1,108 @@ +short i = (short) 0x8613; +return i;(short) -31213 +++++++ +int i = -15; +System.out.println(i & 0xFF); +++++++ +int x; for (int i = -10000; i < 10000; i++) { + x = (i & 0xFF); + if (x < 0){ + System.out.println(i & 0xFF); + } +} +++++++ +int b = -15; +int c = (b & 0xFF); +System.out.println(c); +++++++ +byte b = (byte) 0x80; +b |= 0x40; +b |= 0x20; +System.out.println(b); +++++++ +int word = -1; // 0x00010000; +int shift = 27; +byte b = (byte) ((word >>> 21) & 0x0FF); +int i = (word >>> shift); +System.out.println(word + "\t" + shift); +System.out.println(b); +System.out.println(i); +++++++ +int word = 0xFF3; +byte b = (byte) ((word & 0x07) << 5); +System.out.println(b); +++++++ +System.out.println(64 >>> 1); +++++++ +int word = 0xFF0F0F0F; boolean lengthBit = false, controlBit = true; +byte b = (byte) 0x80; +if (lengthBit) { + b |= 0x40; +} +if (controlBit) { + b |= 0x20; +} b |= (byte) (word >>> 27); System.out.print(b + "\t"); +b = (byte) ((word >>> 19) & 0xFF); System.out.print(b + "\t"); +b = (byte) ((word >>> 11) & 0xFF); System.out.print(b + "\t"); +b = (byte) ((word >>> 3) & 0xFF); System.out.print(b + "\t"); +b = (byte) ((word & 0x07) << 5); System.out.println(b); +++++++ +byte[] data = new byte[5]; +data[0] = 0x00; data[1] = 0x00; data[2] = 0x00; data[3] = 0x29; data[4] = (byte) 0x80; +int retValue = ((data[0] << 3) + ((data[1] & 0xFF) >>> 5)) << 24; +System.out.println("0x" + Integer.toHexString(retValue)); +// second byte +retValue += (((data[1] << 3) & 0xFF) + ((data[2] & 0xFF) >>> 5)) << 16; +System.out.println("0x" + Integer.toHexString(retValue)); +// third byte +retValue += (((data[2] << 3) & 0xFF) + ((data[3] & 0xFF) >>> 5)) << 8; +System.out.println("0x" + Integer.toHexString(retValue)); +// fourth byte +retValue += ((data[3] << 3) & 0xFF) + ((data[4] & 0xFF) >>> 5); +System.out.println("0x" + Integer.toHexString(retValue)); +++++++ +byte b = 0x7D; +System.out.println((b & 0x80)); +++++++ +int i1 = 0x12345678, i2 = 0x56789012; +long l = ((long) i1 << 32) + i2; +System.out.println(Long.toHexString(l)); +++++++ +int val = 5; +for (int i = 0; i <= 7; i++) { + int cmd = 0xFC00010C + (7 - i) * 0x800000 + ((val >>> i*4) & 0xF)*0x1000; + System.out.println(i + "\t0x" + Integer.toHexString(cmd)); +} +++++++ +System.out.println("0x" + Integer.toHexString((0x20 << 3) & 0xFF)); +++++++ +int data = 0x1111; +byte b; +b = (byte) ((data >>> 9) & 0xFF); +System.out.println("0x" + Integer.toHexString(b)); +b = (byte) ((data >>> 1) & 0xFF); +System.out.println("0x" + Integer.toHexString(b)); +b = (byte) ((data & 0x01) << 7); +System.out.println("0x" + Integer.toHexString(b)); +++++++ +byte[] data = new byte[3]; +data[0] = (byte) 0xFF; data[1] = 0x01; data[2] = 0x00; +byte b = 0; +for (int bit = 0; bit <= 7; bit++) { + if ((data[1] & (1 << bit)) > 0) { + b += 1 << (7 - bit); + } +} +int retValue = (b & 0xFF) << 8; +// turn LSB +b = 0; +for (int bit = 0; bit <= 7; bit++) { + if ((data[0] & (1 << bit)) > 0) { + b += 1 << (7 - bit); + } +} +retValue += (b & 0xFF); +System.out.println("0x" + Integer.toHexString(retValue)); +++++++ +System.out.println(((512 - 6) / 2) & 0xFFFC); +++++++ diff --git a/mcdp/src/ch/ntb/mcdp/bdi/BDI332.java b/mcdp/src/ch/ntb/mcdp/bdi/BDI332.java new file mode 100644 index 0000000..c7ad9e3 --- /dev/null +++ b/mcdp/src/ch/ntb/mcdp/bdi/BDI332.java @@ -0,0 +1,876 @@ +package ch.ntb.mcdp.bdi; + +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; + +public class BDI332 { + + // BDI subtypes + /** + * 17 Bit Packet to BDI + */ + private static final byte STYPE_BDI_17IN = 0x10; + + /** + * 17 Bit Packet from BDI + */ + private static final byte STYPE_BDI_17OUT = 0x11; + + /** + * Fast Download Data to download to target (Fill) + */ + private static final byte STYPE_BDI_17FILL_BYTE_WORD = 0x12; + + /** + * Fast Download Data to download to target (Fill) + */ + private static final byte STYPE_BDI_17FILL_LONG = 0x13; + + /** + * Dump target memory (Dump) + */ + private static final byte STYPE_BDI_17DUMP = 0x14; + + /** + * Hard Reset + */ + private static final byte STYPE_BDI_HARD_RESET_332 = 0x07; + + /** + * Get status of Freeze-Signal + */ + private static final byte STYPE_BDI_GET_FREEZE = 0x08; + + /** + * Fast Download successfully finished (Fill) + */ + private static final byte STYPE_BDI_SUCCESS_FD = 0x60; + + /** + * HARD_RESET done + */ + private static final byte STYPE_BDI_HARD_RESET_SUCCESS = 0x61; + + /** + * Freeze-Signal status (length = 1 byte) + */ + private static final byte STYPE_BDI_FREEZE_RESULT = 0x62; + + /** + * Fast Download Data received from target (Dump) + */ + private static final byte STYPE_BDI_DUMP_DATA = 0x63; + + /** + * Unknown STYPE + */ + private static final byte STYPE_BDI_UNKNOWN_STYPE = 0x70; + + /** + * Error if length in FD (Fast Download) packet too small + */ + private static final byte STYPE_BDI_ERROR_FD_LENGTH = 0x71; + + /** + * General FD Error + */ + private static final byte STYPE_BDI_ERROR_FD_GENERAL = 0x72; + + /** + * Dump error + */ + private static final byte STYPE_BDI_DUMP_ERROR = 0x74; + + private static final int BDI_DATA17_LENGTH = 3; + + /** + * no operation + */ + private static final int NOP = 0x0000; + + /** + * asserts RESET for 512 clock cycles (CPU is not affected) + */ + private static final int RST = 0x0400; + + /** + * resume execution + */ + private static final int GO = 0x0C00; + + /** + * read data register + */ + private static final int RDREG = 0x2180; + + /** + * write data register + */ + private static final int WDREG = 0x2080; + + /** + * read system register + */ + private static final int RSREG = 0x2580; + + /** + * write system register + */ + private static final int WSREG = 0x2480; + + /** + * write memory byte + */ + private static final int WRITEB = 0x1800; + + /** + * write memory word + */ + private static final int WRITEW = 0x1840; + + /** + * write memory long + */ + private static final int WRITEL = 0x1880; + + /** + * read memory byte + */ + private static final int READB = 0x1900; + + /** + * read memory word + */ + private static final int READW = 0x1940; + + /** + * read memory long + */ + private static final int READL = 0x1980; + + /** + * fill memory byte + */ + private static final int FILLB = 0x1C00; + + /** + * fill memory word + */ + private static final int FILLW = 0x1C40; + + /** + * fill memory long + */ + private static final int FILLL = 0x1C80; + + /** + * dump memory long + */ + private static final int DUMPB = 0x1D00; + + /** + * dump memory long + */ + private static final int DUMPW = 0x1D40; + + /** + * dump memory long + */ + private static final int DUMPL = 0x1D80; + + /** + * BDI return Code: Command Complete; Status OK + */ + private static final int STATUS_OK = 0xFFFF; + + /** + * Maximal number of words or bytes (1 or 2 bytes) for one usb-packet to + * download (fill).
+ * Note that no status bit is used. Therefore one data entity is only 16 + * bits wide (not 17 bits like normal commands).
+ * MAX_NOF_WORDS_FAST_DOWNLOAD is a multiple of 4 (FILLB/W + + * data). + */ + public static final int MAX_NOF_BYTES_WORDS_FILL = (USB.MAX_DATA_SIZE + - DataPacket.PACKET_MIN_LENGTH - 2) / 4; + + /** + * Maximal number of longs (4 bytes) for one usb-packet to download (fill). + * Note that no status bit is used. Therefore one data entity is only 16 + * bits wide (not 17 bits like normal commands).
+ * MAX_NOF_WORDS_FAST_DOWNLOAD is a multiple of 6 (FILLW + MS + * data + LS data). + */ + public static final int MAX_NOF_LONGS_FILL = (USB.MAX_DATA_SIZE + - DataPacket.PACKET_MIN_LENGTH - 2) / 6; + + private static boolean targetInDebugMode = false; + + private static byte[] sendData; + + private static int readMemSize = 0, writeMemSize = 0;; + + static { + sendData = new byte[USB.MAX_DATA_SIZE]; + } + + /** + * Transmit a packet to the USB-target. The length transmitted over USB is + * dataLength + DataPacket.PACKET_MIN_LENGTH. + * + * @param STYPE + * subtype of the packet STYPE_BDI_* + * @param dataLength + * length of the data to be sent + * @return resulting response from target + * @throws USBException + * @throws DispatchException + * @throws BDIException + */ + private static DataPacket transmit(byte STYPE, int dataLength) + throws USBException, DispatchException, BDIException { + // initialize packet + sendData[0] = Dispatch.PACKET_HEADER; + sendData[1] = Dispatch.MTYPE_BDI; + sendData[2] = STYPE; + sendData[3] = (byte) (dataLength / 0x100); // length + sendData[4] = (byte) (dataLength & 0xFF); + sendData[Dispatch.PACKET_DATA_OFFSET + dataLength] = Dispatch.PACKET_END; + + // write USB-command + USBDevice.write(sendData, dataLength + DataPacket.PACKET_MIN_LENGTH); + + // read result + DataPacket data = Dispatch.readBDI(); + if (data.subtype == STYPE_BDI_UNKNOWN_STYPE) { + throw new BDIException("unknown subtype: " + data.subtype); + } + return data; + } + + /** + * Inserts 17-bits of data (3 bytes) into the send buffer. + * + * @param data + * 17 bits (3 bytes) of data + * @param offset + * the offset from the beginning of the data + */ + private static void fillPacket(int data, int offset) { + + // refer to CPU32 Reference Manual, Section 7.2.7 + // bit16 = 0 + 16 bits of data (bit15 .. bit0) + // TODO check this: + // sendData[Dispatch.PACKET_DATA_OFFSET + offset] = (byte) (((data >>> + // 9) & 0x7F) | 0x80); + sendData[Dispatch.PACKET_DATA_OFFSET + offset] = (byte) ((data >>> 9) & 0x7F); + sendData[Dispatch.PACKET_DATA_OFFSET + offset + 1] = (byte) ((data >>> 1) & 0xFF); + sendData[Dispatch.PACKET_DATA_OFFSET + offset + 2] = (byte) ((data & 0x01) << 7); + } + + /** + * Send one BDI instruction (17 bits) to the target without any other data. + * + * @param data + * BDI instruction + * @return resulting response from target + * @throws USBException + * @throws DispatchException + * @throws BDIException + */ + public static DataPacket transfer(int data) throws USBException, + DispatchException, BDIException { + + fillPacket(data, 0); + + return transmit(STYPE_BDI_17IN, BDI_DATA17_LENGTH); + } + + /** + * Checks the result for error conditions and converts the byte data to an + * integer. + * + * @param data + * DataPacket to be parsed + * @return data received from the target as an integer + * @throws BDIException + * @throws USBException + * @throws DispatchException + */ + private static int parseResult17(DataPacket data) throws BDIException, + USBException, DispatchException { + if (data.subtype != STYPE_BDI_17OUT) { + throw new BDIException("wrong subtype: " + data.subtype); + } + // we receive the data LSBit first! + // 16 data bits + // last bit is status control bit + + boolean statusControlBit = (data.data[0] & 0x80) > 0; + int retValue = (((data.data[0] << 1) & 0xFF) + ((data.data[1] & 0x80) >>> 7)) << 8; + retValue += ((data.data[1] << 1) & 0xFF) + + ((data.data[2] & 0x80) >>> 7); + + if (statusControlBit) { + switch (retValue) { + case 0x0000: + // Not Ready + return 0; + case 0x0001: + // Data Invalid + throw new BDIException( + "BERR Terminated Bus Cycle; Data Invalid"); + case 0xFFFF: + // Illegal Command + throw new BDIException("Illegal Command"); + default: + // invalid case + throw new BDIException("invalid case: 0x" + + Integer.toHexString(retValue)); + } + } + // retValue = 0xxxxx -> Valid Data Transfer + // retValue = 0xFFFF -> Command Complete; Status OK + return retValue; + } + + /** + * Combines the transfer(int data) and + * parseResult17(DataPacket data) methods.
+ * Use this for a normal BDI transfer. + * + * @param data + * @return + * @throws USBException + * @throws DispatchException + * @throws BDIException + */ + private static int transferAndParse17(int data) throws USBException, + DispatchException, BDIException { + return parseResult17(transfer(data)); + } + + /** + * Sends NOPs to the target until a STATUS_OK result is + * received. + * + * @throws USBException + * @throws DispatchException + * @throws BDIException + */ + public static void nopsToLegalCmd() throws USBException, DispatchException, + BDIException { + final int NOF_NOPS_TO_LEGAL_CMD = 4; + for (int i = 0; i < NOF_NOPS_TO_LEGAL_CMD; i++) { + if (transferAndParse17(NOP) == STATUS_OK) { + return; + } + } + throw new BDIException("timeout, tried " + NOF_NOPS_TO_LEGAL_CMD + + " times"); + } + + /** + * Signals a breakpoint and enters debug mode. + * + * @throws USBException + * @throws DispatchException + * @throws BDIException + */ + public static void break_() throws USBException, DispatchException, + BDIException { + transferAndParse17(NOP); + if (transferAndParse17(NOP) != STATUS_OK) { + throw new BDIException("no STATUS_OK received"); + } + targetInDebugMode = isFreezeAsserted(); + } + + public static void go() throws USBException, DispatchException, + BDIException { + if (!targetInDebugMode) { + throw new BDIException("target not in debug mode"); + } + transferAndParse17(GO); + targetInDebugMode = isFreezeAsserted(); + } + + private static void hard_reset() throws USBException, DispatchException, + BDIException { + DataPacket data = transmit(STYPE_BDI_HARD_RESET_332, 0); + if (data == null) { + throw new BDIException("no data from device"); + } + if (data.subtype != STYPE_BDI_HARD_RESET_SUCCESS) { + throw new BDIException("wrong subtype: " + data.subtype); + } + } + + /** + * Reset the target and put it into debug mode. + * + * @throws USBException + * @throws DispatchException + * @throws BDIException + */ + public static void reset_target() throws USBException, DispatchException, + BDIException { + // hard reset + hard_reset(); + // break + break_(); + } + + public static void reset_peripherals() throws USBException, + DispatchException, BDIException { + // hard reset + transferAndParse17(RST); + // wait for 50ms + try { + Thread.sleep(50); + } catch (InterruptedException e) { + e.printStackTrace(); + } + // break + break_(); + } + + /** + * Check if the freeze signal is asserted. + * + * @return + * @throws USBException + * @throws DispatchException + * @throws BDIException + */ + public static boolean isFreezeAsserted() throws USBException, + DispatchException, BDIException { + DataPacket data = transmit(STYPE_BDI_GET_FREEZE, 0); + if (data == null) { + throw new BDIException("no data from device"); + } + if (data.subtype != STYPE_BDI_FREEZE_RESULT) { + throw new BDIException("wrong subtype: " + data.subtype); + } + if ((data.data[0] != 0) && (data.data[0] != 1)) { + throw new BDIException("wrong data: " + data.data[0]); + } + targetInDebugMode = data.data[0] == 1; + return targetInDebugMode; + } + + /** + * Fill is used in conjunction with the writeMem command to + * fill large blocks of memory.
+ * The maximal number of words is defined by + * MAX_NOF_WORDS_FAST_DOWNLOAD for 1 and 2 byte (word) data. + * For 4 byte (long) data, only half the size of + * MAX_NOF_WORDS_FAST_DOWNLOAD is available as 4 bytes of + * data has to be split in two packets (2 x 2 bytes).
+ * Befor using fillMem, writeMem has to be + * called to set up the start address and size. + * + * @param downloadData + * Data to be downloaded (size depending on size set up with + * writeMem) + * @param dataLength + * Number of bytes, words or longs (1, 2, 4 bytes) + * @throws BDIException + * @throws DispatchException + * @throws USBException + */ + public static void fillMem(int[] downloadData, int dataLength) + throws BDIException, USBException, DispatchException { + // check if data fits into USB-packet + int currentIndex = 0; + DataPacket data; + System.out.println(dataLength); + switch (writeMemSize) { + case 1: + if (dataLength > MAX_NOF_BYTES_WORDS_FILL) { + throw new BDIException( + "data larger than MAX_NOF_WORDS_FAST_DOWNLOAD_BYTE_WORD"); + } + while (currentIndex < dataLength) { + // FILLB + sendData[Dispatch.PACKET_DATA_OFFSET + currentIndex * 4] = (byte) ((FILLB >>> 8) & 0xFF); + sendData[Dispatch.PACKET_DATA_OFFSET + currentIndex * 4 + 1] = (byte) (FILLB & 0xFF); + // DATA (address) + sendData[Dispatch.PACKET_DATA_OFFSET + currentIndex * 4 + 2] = 0; + sendData[Dispatch.PACKET_DATA_OFFSET + currentIndex * 4 + 3] = (byte) (downloadData[currentIndex] & 0xFF); + currentIndex++; + } + // send NOP to get result of last write + sendData[Dispatch.PACKET_DATA_OFFSET + currentIndex * 4] = 0; + sendData[Dispatch.PACKET_DATA_OFFSET + currentIndex * 4 + 1] = 0; + data = transmit(STYPE_BDI_17FILL_BYTE_WORD, dataLength * 4 + 2); + break; + case 2: + if (dataLength > MAX_NOF_BYTES_WORDS_FILL) { + throw new BDIException( + "data larger than MAX_NOF_WORDS_FAST_DOWNLOAD_BYTE_WORD"); + } + while (currentIndex < dataLength) { + // FILLW + sendData[Dispatch.PACKET_DATA_OFFSET + currentIndex * 4] = (byte) ((FILLW >>> 8) & 0xFF); + sendData[Dispatch.PACKET_DATA_OFFSET + currentIndex * 4 + 1] = (byte) (FILLW & 0xFF); + // DATA (address) + sendData[Dispatch.PACKET_DATA_OFFSET + currentIndex * 4 + 2] = (byte) ((downloadData[currentIndex] >>> 8) & 0xFF); + sendData[Dispatch.PACKET_DATA_OFFSET + currentIndex * 4 + 3] = (byte) (downloadData[currentIndex] & 0xFF); + currentIndex++; + } + // send NOP to get result of last write + sendData[Dispatch.PACKET_DATA_OFFSET + currentIndex * 4] = 0; + sendData[Dispatch.PACKET_DATA_OFFSET + currentIndex * 4 + 1] = 0; + data = transmit(STYPE_BDI_17FILL_BYTE_WORD, dataLength * 4 + 2); + break; + case 4: + if (dataLength > (MAX_NOF_LONGS_FILL)) { + throw new BDIException( + "data larger than MAX_NOF_WORDS_FAST_DOWNLOAD_LONG"); + } + while (currentIndex < dataLength) { + // FILL + sendData[Dispatch.PACKET_DATA_OFFSET + currentIndex * 6] = (byte) ((FILLL >>> 8) & 0xFF); + sendData[Dispatch.PACKET_DATA_OFFSET + currentIndex * 6 + 1] = (byte) (FILLL & 0xFF); + // MS data + sendData[Dispatch.PACKET_DATA_OFFSET + currentIndex * 6 + 2] = (byte) ((downloadData[currentIndex] >>> 24) & 0xFF); + sendData[Dispatch.PACKET_DATA_OFFSET + currentIndex * 6 + 3] = (byte) ((downloadData[currentIndex] >>> 16) & 0xFF); + // LS data + sendData[Dispatch.PACKET_DATA_OFFSET + currentIndex * 6 + 4] = (byte) ((downloadData[currentIndex] >>> 8) & 0xFF); + sendData[Dispatch.PACKET_DATA_OFFSET + currentIndex * 6 + 5] = (byte) (downloadData[currentIndex] & 0xFF); + currentIndex++; + } + // send NOP to get result of last write + sendData[Dispatch.PACKET_DATA_OFFSET + currentIndex * 6] = 0; + sendData[Dispatch.PACKET_DATA_OFFSET + currentIndex * 6 + 1] = 0; + data = transmit(STYPE_BDI_17FILL_LONG, dataLength * 6 + 2); + break; + default: + throw new BDIException("invalid writeMemSize: " + writeMemSize); + } + + if (data == null) { + throw new BDIException("no data from device"); + } + + switch (data.subtype) { + case STYPE_BDI_SUCCESS_FD: + + break; + case STYPE_BDI_ERROR_FD_LENGTH: + throw new BDIException("length smaller than BDI_DATA17_LENGTH"); + case STYPE_BDI_ERROR_FD_GENERAL: + throw new BDIException("general fast download error"); + default: + throw new BDIException("wrong subtype: " + data.subtype); + } + } + + /** + * Dump is used in conjunction with the readMem(...) command + * to dump large blocks of memory. The size depends on the size set up with + * readMem(...) and is internally stored. + * + * @param nofData + * @return + * @throws USBException + * @throws DispatchException + * @throws BDIException + */ + public static int[] dumpMem(int nofData) throws USBException, + DispatchException, BDIException { + + int dataSize; + switch (readMemSize) { + case 1: + if (nofData > MAX_NOF_BYTES_WORDS_FILL) + nofData = MAX_NOF_BYTES_WORDS_FILL; + // fill the packet with {DUMPB} + 1 NOP at the end + int i; + for (i = 0; i < nofData; i++) { + sendData[Dispatch.PACKET_DATA_OFFSET + i * 2] = (byte) ((DUMPB >>> 8) & 0xFF); + sendData[Dispatch.PACKET_DATA_OFFSET + i * 2 + 1] = (byte) (DUMPB & 0xFF); + } + sendData[Dispatch.PACKET_DATA_OFFSET + i * 2] = (byte) ((NOP >>> 8) & 0xFF); + sendData[Dispatch.PACKET_DATA_OFFSET + i * 2 + 1] = (byte) (NOP & 0xFF); + dataSize = i * 2 + 2; + break; + case 2: + if (nofData > MAX_NOF_BYTES_WORDS_FILL) + nofData = MAX_NOF_BYTES_WORDS_FILL; + // fill the packet with {DUMPW} + 1 NOP at the end + for (i = 0; i < nofData; i++) { + sendData[Dispatch.PACKET_DATA_OFFSET + i * 2] = (byte) ((DUMPW >>> 8) & 0xFF); + sendData[Dispatch.PACKET_DATA_OFFSET + i * 2 + 1] = (byte) (DUMPW & 0xFF); + } + sendData[Dispatch.PACKET_DATA_OFFSET + i * 2] = (byte) ((NOP >>> 8) & 0xFF); + sendData[Dispatch.PACKET_DATA_OFFSET + i * 2 + 1] = (byte) (NOP & 0xFF); + dataSize = i * 2 + 2; + break; + case 4: + if (nofData > MAX_NOF_LONGS_FILL) + nofData = MAX_NOF_LONGS_FILL; + // fill the packet with {DUMPL + NOP} + 1 NOP at the end + for (i = 0; i < nofData; i++) { + sendData[Dispatch.PACKET_DATA_OFFSET + i * 4] = (byte) ((DUMPL >>> 8) & 0xFF); + sendData[Dispatch.PACKET_DATA_OFFSET + i * 4 + 1] = (byte) (DUMPL & 0xFF); + sendData[Dispatch.PACKET_DATA_OFFSET + i * 4 + 2] = (byte) ((NOP >>> 8) & 0xFF); + sendData[Dispatch.PACKET_DATA_OFFSET + i * 4 + 3] = (byte) (NOP & 0xFF); + } + sendData[Dispatch.PACKET_DATA_OFFSET + i * 4] = (byte) ((NOP >>> 8) & 0xFF); + sendData[Dispatch.PACKET_DATA_OFFSET + i * 4 + 1] = (byte) (NOP & 0xFF); + dataSize = i * 4 + 2; + break; + default: + throw new BDIException("invalid readMemSize: " + readMemSize); + } + + DataPacket res = transmit(STYPE_BDI_17DUMP, dataSize); + /* + * The resulting data is not 17 bits wide, but only 16 bits. The status + * bit is checked on the USB-Controller. If an error occurs, a + * STYPE_BDI_DUMP_ERROR packet is returned. + */ + if (res == null) { + throw new BDIException("no data from device"); + } + + int[] result; + switch (res.subtype) { + case STYPE_BDI_DUMP_DATA: + switch (readMemSize) { + case 1: + case 2: + result = new int[(res.data.length - DataPacket.PACKET_MIN_LENGTH) / 2]; + // MS Result before LS Result + int resIndex = 0; + while (resIndex * 2 < res.data.length) { + result[resIndex] = ((res.data[resIndex * 2] << 8) & 0xFFFF) + + (res.data[resIndex * 2 + 1] & 0xFF); + resIndex++; + } + return result; + case 4: + result = new int[(res.data.length) / 4]; + // MS Result before LS Result + resIndex = 0; + while (resIndex * 4 < res.data.length) { + result[resIndex] = (res.data[resIndex * 4] << 24) + + ((res.data[resIndex * 4 + 1] << 16) & 0xFFFFFF) + + ((res.data[resIndex * 4 + 2] << 8) & 0xFFFF) + + (res.data[resIndex * 4 + 3] & 0xFF); + resIndex++; + } + return result; + // the default case is handled above + } + case STYPE_BDI_DUMP_ERROR: + // thows BDI exceptions, but not for "Not Ready" + throw new BDIException("STYPE_BDI_DUMP_ERROR"); + default: + throw new BDIException("wrong subtype: " + res.subtype); + } + } + + public static void writeMem(int addr, int value, int size) + throws USBException, DispatchException, BDIException { + + if (!targetInDebugMode) { + throw new BDIException("target not in debug mode"); + } + + System.out.println("writeMem: 0x" + Integer.toHexString(addr >>> 16) + + " 0x" + Integer.toHexString(addr & 0xFFFF)); + System.out.println("writeMem: 0x" + Integer.toHexString(value >>> 16) + + " 0x" + Integer.toHexString(value & 0xFFFF)); + + writeMemSize = size; + switch (size) { + case 1: + // put instr. + transferAndParse17(WRITEB); + // put MS ADDR + transferAndParse17(addr >>> 16); + // put LS ADDR + transferAndParse17(addr & 0xFFFF); + // put data (byte) + transferAndParse17(value & 0xFFFF); + break; + case 2: + // put instr. + transferAndParse17(WRITEW); + // put MS ADDR + transferAndParse17(addr >>> 16); + // put LS ADDR + transferAndParse17(addr & 0xFFFF); + // put data (word) + transferAndParse17(value & 0xFFFF); + break; + case 4: + // put instr. + transferAndParse17(WRITEL); + // put MS ADDR + transferAndParse17(addr >>> 16); + // put LS ADDR + transferAndParse17(addr & 0xFFFF); + // put MS data (long) + transferAndParse17(value >>> 16); + // put LS data (long) + transferAndParse17(value & 0xFFFF); + break; + default: + writeMemSize = 0; + throw new BDIException("wrong size: " + size + + " (should be 1, 2 or 4)"); + } + // check status + if (transferAndParse17(NOP) != STATUS_OK) { + // throw new BDIException("error on writeMem"); + } + } + + public static int readMem(int addr, int size) throws USBException, + DispatchException, BDIException { + + if (!targetInDebugMode) { + throw new BDIException("target not in debug mode"); + } + + System.out.println("readMem: 0x" + Integer.toHexString(addr >>> 16) + + Integer.toHexString(addr & 0xFFFF)); + + readMemSize = size; + switch (size) { + case 1: + // put instr. + transferAndParse17(READB); + // put MS ADDR + transferAndParse17(addr >>> 16); + // put LS ADDR + transferAndParse17(addr & 0xFFFF); + // get data (byte) + return transferAndParse17(NOP); + case 2: + // put instr. + transferAndParse17(READW); + // put MS ADDR + transferAndParse17(addr >>> 16); + // put LS ADDR + transferAndParse17(addr & 0xFFFF); + // get data (word) + return transferAndParse17(NOP); + case 4: + // put instr. + transferAndParse17(READL); + // put MS ADDR + transferAndParse17(addr >>> 16); + // put LS ADDR + transferAndParse17(addr & 0xFFFF); + // get MS data (long) + int valMS = transferAndParse17(NOP); + // get LS data (long) + return (valMS << 16) + transferAndParse17(NOP); + default: + readMemSize = 0; + throw new BDIException("wrong size: " + size + + " (should be 1, 2 or 4 bytes)"); + } + } + + public static int readUserReg(int reg) throws USBException, + DispatchException, BDIException { + + if (!targetInDebugMode) { + throw new BDIException("target not in debug mode"); + } + + // put instr. + transferAndParse17(RDREG + (reg & 0x0F)); + // get MS data (long) + int valMS = transferAndParse17(NOP); + // get LS data (long) + return (valMS << 16) + transferAndParse17(NOP); + } + + public static void writeUserReg(int reg, int value) throws USBException, + DispatchException, BDIException { + + if (!targetInDebugMode) { + throw new BDIException("target not in debug mode"); + } + + // put instr. + transferAndParse17(WDREG + (reg & 0x0F)); + // put MS data (long) + transferAndParse17(value >>> 16); + // put LS data (long) + transferAndParse17(value); + // check status + if (transferAndParse17(NOP) != STATUS_OK) { + throw new BDIException("error on writeUserReg"); + } + } + + public static int readSysReg(int reg) throws USBException, + DispatchException, BDIException { + + if (!targetInDebugMode) { + throw new BDIException("target not in debug mode"); + } + + // put instr. + transferAndParse17(RSREG + (reg & 0x0F)); + // get MS data (long) + int valMS = transferAndParse17(NOP); + // get LS data (long) + return (valMS << 16) + transferAndParse17(NOP); + } + + public static void writeSysReg(int reg, int value) throws USBException, + DispatchException, BDIException { + + if (!targetInDebugMode) { + throw new BDIException("target not in debug mode"); + } + System.out.println("0x" + Integer.toHexString(reg) + " " + "0x" + + Integer.toHexString(value)); + System.out.println("0x" + Integer.toHexString(WSREG + (reg & 0xF)) + + " 0x" + Integer.toHexString(value >>> 16) + " 0x" + + Integer.toHexString(value)); + + // put instr. + transferAndParse17(WSREG + (reg & 0x0F)); + // put MS data (long) + transferAndParse17(value >>> 16); + // put LS data (long) + transferAndParse17(value); + // check status + if (transferAndParse17(NOP) != STATUS_OK) { + throw new BDIException("error on writeUserReg"); + } + } + + // TODO: remove + public static void nop() throws USBException, DispatchException, + BDIException { + System.out.println("0x" + Integer.toHexString(transferAndParse17(NOP))); + } + + /** + * Return the last known state of the freeze signal. This value may not be + * up to date as the target state may have changed meanwhile. To get the up + * to date value use isFreezeAsserted which will issue an USB + * request, read the freeze signal and update the internal value returned by + * this method. + * + * @return the last known state of the freeze signal + */ + public static boolean isTargetInDebugMode() { + return targetInDebugMode; + } +} diff --git a/mcdp/src/ch/ntb/mcdp/bdi/BDI555.java b/mcdp/src/ch/ntb/mcdp/bdi/BDI555.java new file mode 100644 index 0000000..0d00dcf --- /dev/null +++ b/mcdp/src/ch/ntb/mcdp/bdi/BDI555.java @@ -0,0 +1,793 @@ +package ch.ntb.mcdp.bdi; + +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; + +public class BDI555 { + + // BDI subtypes + /** + * 35 Bit Packet to BDI + */ + private static final byte STYPE_BDI_35IN = 0x01; + + /** + * 35 Bit Packet from BDI + */ + private static final byte STYPE_BDI_35OUT = 0x02; + + /** + * 10 Bit Packet to BDI + */ + private static final byte STYPE_BDI_10IN = 0x03; + + /** + * 10 Bit Packet from BDI + */ + private static final byte STYPE_BDI_10OUT = 0x04; + + /** + * Fast Download Data + */ + private static final byte STYPE_BDI_35FD_DATA = 0x05; + + /** + * Hard Reset + */ + private static final byte STYPE_BDI_HARD_RESET_555 = 0x06; + + /** + * Get status of Freeze-Signal + */ + private static final byte STYPE_BDI_GET_FREEZE = 0x08; + + /** + * Fast Download successfully finished + */ + private static final byte STYPE_BDI_SUCCESS_FD = 0x60; + + /** + * HARD_RESET done + */ + private static final byte STYPE_BDI_HARD_RESET_SUCCESS = 0x61; + + /** + * Freeze-Signal status (length = 1 byte) + */ + private static final byte STYPE_BDI_FREEZE_RESULT = 0x62; + + /** + * Unknown STYPE + */ + private static final byte STYPE_BDI_UNKNOWN_STYPE = 0x70; + + /** + * Error if length in FD (Fast Download) packet too small + */ + private static final byte STYPE_BDI_ERROR_FD_LENGTH = 0x71; + + /** + * General FD Error + */ + private static final byte STYPE_BDI_ERROR_FD_GENERAL = 0x72; + + /** + * General FD Error + */ + private static final byte STYPE_BDI_ERROR_TIMEOUT = 0x73; + + private static final int BDI_DATA35_LENGTH = 5; + + /** + * no operation, nop = ori 0,0,0 + */ + private static final int NOP = 0x60000000; + + /** + * return from interrupt + */ + private static final int RFI = 0x4C000064; + + /** + * mtspr DPDR, Rx + */ + private static final int MRTDPDR = 0x7C169BA6; + + /** + * mfspr Rx, DPDR + */ + private static final int MDPDRTR = 0x7C169AA6; + + /** + * mtspr spr, R30 + */ + private static final int MR30TSPR = 0x7FC003A6; + + /** + * mfspr R30, spr + */ + private static final int MSPRTR30 = 0x7FC002A6; + + /** + * mftbr R30, tbr + */ + private static final int MTBRTR30 = 0x7FC002E6; + + private static final int NULL_INDICATION = -1; + + public static final int MAX_NOF_WORDS_FAST_DOWNLOAD = ((USB.MAX_DATA_SIZE - DataPacket.PACKET_MIN_LENGTH) / BDI_DATA35_LENGTH); + + private static boolean fastDownloadStarted = false; + + private static boolean targetInDebugMode = false; + + private static byte[] sendData; + + private static int gpr30, gpr31, ecr; + + static { + sendData = new byte[USB.MAX_DATA_SIZE]; + } + + private static void initPacket(byte STYPE, int dataLength) { + sendData[0] = Dispatch.PACKET_HEADER; + sendData[1] = Dispatch.MTYPE_BDI; + sendData[2] = STYPE; + sendData[3] = (byte) (dataLength / 0x100); // length + sendData[4] = (byte) (dataLength & 0xFF); + sendData[Dispatch.PACKET_DATA_OFFSET + dataLength] = Dispatch.PACKET_END; + } + + private static DataPacket transmit(int dataLength) throws USBException, + DispatchException, BDIException { + // write USB-command + USBDevice.write(sendData, dataLength + DataPacket.PACKET_MIN_LENGTH); + + // read result + DataPacket data = Dispatch.readBDI(); + if (data.subtype == STYPE_BDI_UNKNOWN_STYPE) { + throw new BDIException("unknown subtype: " + data.subtype); + }else if (data.subtype == STYPE_BDI_ERROR_TIMEOUT) { + // receive invalid packet + Dispatch.readBDI(); + throw new BDIException("timeout error (DSDO not low)"); + } + return data; + } + + private static void fillPacket(boolean lengthBit, boolean controlBit, + int data, int offset) { + + // startBit = 1 | lengthBit | controlBit | 32 bits of data + byte b = (byte) 0x80; + if (lengthBit) { + b |= 0x40; + } + if (controlBit) { + b |= 0x20; + } + b |= (byte) (data >>> 27); + sendData[Dispatch.PACKET_DATA_OFFSET + offset] = b; + sendData[Dispatch.PACKET_DATA_OFFSET + offset + 1] = (byte) ((data >>> 19) & 0xFF); + sendData[Dispatch.PACKET_DATA_OFFSET + offset + 2] = (byte) ((data >>> 11) & 0xFF); + sendData[Dispatch.PACKET_DATA_OFFSET + offset + 3] = (byte) ((data >>> 3) & 0xFF); + sendData[Dispatch.PACKET_DATA_OFFSET + offset + 4] = (byte) ((data & 0x07) << 5); + } + + private static DataPacket transfer(boolean lengthBit, boolean controlBit, + int data) throws USBException, DispatchException, BDIException { + + initPacket(STYPE_BDI_35IN, BDI_DATA35_LENGTH); + + fillPacket(lengthBit, controlBit, data, 0); + + return transmit(BDI_DATA35_LENGTH); + } + + private static int parseResult35(DataPacket data) throws BDIException { + if (data.subtype != STYPE_BDI_35OUT) { + throw new BDIException("wrong subtype: " + data.subtype); + } + // 1 bit is always 0 (Ready Bit) + // 2 + 3 bit are status bits + // 32 data bits + if ((data.data[0] & 0x80) > 0) { + throw new BDIException("ready bit is not 0: 0x" + + Integer.toHexString(data.data[0] & 0xFF)); + } + switch ((data.data[0] >>> 5) & 0x03) { + case 0: + // first byte + int retValue = (((data.data[0] << 3) & 0xFF) + ((data.data[1] & 0xFF) >>> 5)) << 24; + // second byte + retValue += (((data.data[1] << 3) & 0xFF) + ((data.data[2] & 0xFF) >>> 5)) << 16; + // third byte + retValue += (((data.data[2] << 3) & 0xFF) + ((data.data[3] & 0xFF) >>> 5)) << 8; + // fourth byte + retValue += ((data.data[3] << 3) & 0xFF) + + ((data.data[4] & 0xFF) >>> 5); + return retValue; + case 1: + throw new BDIException("Sequencing Error: " + data.toString()); + case 2: + throw new BDIException("CPU Exception: " + data.toString()); + case 3: + return NULL_INDICATION; + default: + throw new BDIException("invalid case"); + } + } + + private static int transferAndParse35(boolean lengthBit, + boolean controlBit, int data) throws USBException, + DispatchException, BDIException { + return parseResult35(transfer(lengthBit, controlBit, data)); + } + + private static void epilogue() throws USBException, DispatchException, + BDIException { + // restore GPR30 + // put instr mfspr: GPR30, DPDR + transferAndParse35(false, false, 0x7FF69AA6); + // put GPR30 in DPDR + transferAndParse35(false, true, gpr30); + + // restore GPR31 + // put instr. mfspr: GPR31, DPDR + transferAndParse35(false, false, 0x7FF69AA6); + // put GPR31 in DPDR + transferAndParse35(false, true, gpr31); + + // return from interrupt - normal execution follows + // put instr. rfi + transferAndParse35(false, false, RFI); + } + + private static void prologue() throws USBException, DispatchException, + BDIException { + final int EBRK_bit = 1; + + // save GPR30 + // put instr. mtspr DPDR, GPR30 + transferAndParse35(false, false, 0x7FD69BA6); + + // nop + gpr30 = transferAndParse35(false, false, NOP); + + // read ECR for exception cause + // put instr. mfspr GPR30, ECR + transferAndParse35(false, false, 0x7FD422A6); + // put instr. mtspr DPDR, GPR30 + transferAndParse35(false, false, 0x7FD69BA6); + + // save GPR31 + // put instr. mtspr DPDR, GPR31 + ecr = transferAndParse35(false, false, 0x7FF69BA6); + // nop + gpr31 = transferAndParse35(false, false, NOP); + + if ((ecr & EBRK_bit * 2) > 0) { + // TODO: change exception string + System.out.println("Exception Cause Register = " + "0x" + + Integer.toHexString(ecr)); + } + } + + public static void break_() throws USBException, DispatchException, + BDIException { + // assert maskable breakpoint + // TODO: check this + if (transferAndParse35(true, true, 0x7E000000) == NULL_INDICATION) { + prologue(); + } + targetInDebugMode = isFreezeAsserted(); + // negate breakpoint + transferAndParse35(true, true, 0x3E000000); + } + + public static void go() throws USBException, DispatchException, + BDIException { + + if (!targetInDebugMode) { + throw new BDIException("target not in debug mode"); + } + + epilogue(); + targetInDebugMode = isFreezeAsserted(); + } + + private static void hard_reset() throws USBException, DispatchException, + BDIException { + initPacket(STYPE_BDI_HARD_RESET_555, 0); + DataPacket data = transmit(0); + if (data == null) { + throw new BDIException("no data from device"); + } + if (data.subtype != STYPE_BDI_HARD_RESET_SUCCESS) { + throw new BDIException("wrong subtype: " + data.subtype); + } + fastDownloadStarted = false; + targetInDebugMode = isFreezeAsserted(); + } + + public static void reset_target() throws USBException, DispatchException, + BDIException { + // hard reset + hard_reset(); + // read ECR for exception cause + // put instr. mfspr GPR30, ECR + transferAndParse35(false, false, 0x7FD422A6); + // put instr. mtspr DPDR, GPR30 + transferAndParse35(false, false, 0x7FD69BA6); + // nop + ecr = transferAndParse35(false, false, NOP); + // if (ecr != 0x01) { // TODO: change exception string + // throw new BDIException("ecr != 0x01: ecr = " + // + Integer.toHexString(ecr)); + // } + } + + public static boolean isFreezeAsserted() throws USBException, + DispatchException, BDIException { + initPacket(STYPE_BDI_GET_FREEZE, 0); + DataPacket data = transmit(0); + if (data == null) { + throw new BDIException("no data from device"); + } + if (data.subtype != STYPE_BDI_FREEZE_RESULT) { + throw new BDIException("wrong subtype: " + data.subtype); + } + if ((data.data[0] != 0) && (data.data[0] != 1)) { + throw new BDIException("wrong data: " + data.data[0]); + } + targetInDebugMode = data.data[0] == 1; + return targetInDebugMode; + } + + /** + * Called to start the fast download procedure. If a prior download + * procedure is still running, a BDIException will be thrown. + * + * @param startAddr + * Address to which the data will be downloaded. + * @throws USBException + * @throws DispatchException + * @throws BDIException + */ + public static void startFastDownload(int startAddr) throws USBException, + DispatchException, BDIException { + if (!targetInDebugMode) { + throw new BDIException("target not in debug mode"); + } + + transferAndParse35(false, false, 0x7FD69AA6); + + transferAndParse35(false, true, startAddr - 4); + + transferAndParse35(true, true, 0xC6000000); + fastDownloadStarted = true; + } + + /** + * Fill one USB-Packet with data to download. The maximal number of words is + * defined by MAX_NOF_WORDS_FAST_DOWNLOAD
+ * startFastDownload has to be called before to set up the + * start address. + * + * @param downloadData + * Data to be downloaded (32 bit wide) + * @param nofWords + * Number of words + * @throws BDIException + * @throws DispatchException + * @throws USBException + */ + public static void fastDownload(int[] downloadData, int nofWords) + throws BDIException, USBException, DispatchException { + + if (!fastDownloadStarted) { + throw new BDIException("start fast download first"); + } + // check if data fits into USB-packet + if (nofWords > MAX_NOF_WORDS_FAST_DOWNLOAD) { + throw new BDIException( + "data larger than MAX_NOF_WORDS_FAST_DOWNLOAD"); + } + int currentIndex = 0; + initPacket(STYPE_BDI_35FD_DATA, nofWords * BDI_DATA35_LENGTH); + while (currentIndex < nofWords) { + fillPacket(false, true, downloadData[currentIndex], currentIndex + * BDI_DATA35_LENGTH); + currentIndex++; + } + + DataPacket data = transmit(nofWords * BDI_DATA35_LENGTH); + if (data == null) { + throw new BDIException("no data from device"); + } + + switch (data.subtype) { + case STYPE_BDI_SUCCESS_FD: + + break; + case STYPE_BDI_ERROR_FD_LENGTH: + throw new BDIException("length smaller than BDI_DATA35_LENGTH"); + case STYPE_BDI_ERROR_FD_GENERAL: + throw new BDIException("general fast download error"); + default: + throw new BDIException("wrong subtype: " + data.subtype); + } + } + + public static void stopFastDownload() throws USBException, + DispatchException, BDIException { + fastDownloadStarted = false; + + // stop fast download + int result = transferAndParse35(true, true, 0x86000000); + System.out.println("stopFastDownload:" + result); + // if (result != 0x5F) { + // // TODO: change exception string + // throw new BDIException("result != 0x5F: " + result); + // } + // terminate gracefully + transferAndParse35(false, true, 0); + } + + public static void writeMem(int addr, int value, int size) + throws USBException, DispatchException, BDIException { + + if (!targetInDebugMode) { + throw new BDIException("target not in debug mode"); + } + + // put instr. mfspr GPR30, DPDR + transferAndParse35(false, false, 0x7FD69AA6); + // put adr into DPDR + transferAndParse35(false, true, addr); + // put instr. mfspr GPR31, DPDR + transferAndParse35(false, false, 0x7FF69AA6); + // put val into DPDR + transferAndParse35(false, true, value); + switch (size) { + case 1: + // put instr. stbu 31, 0(30) + transferAndParse35(false, false, 0x9FFE0000); + break; + case 2: + // put instr. sthu 31, 0(30) + transferAndParse35(false, false, 0x0B7FE0000); + break; + case 4: + // put instr. stwu 31, 0(30) + transferAndParse35(false, false, 0x97FE0000); + break; + default: + throw new BDIException("wrong size: " + size + + " (should be 1, 2 or 4)"); + } + } + + public static int readMem(int addr, int size) throws USBException, + DispatchException, BDIException { + + if (!targetInDebugMode) { + throw new BDIException("target not in debug mode"); + } + + // put instr. mfspr GPR30, DPDR + transferAndParse35(false, false, 0x7FD69AA6); + // put adr into DPDR + transferAndParse35(false, true, addr); + switch (size) { + case 1: + // put instr. lbzu 31, 0(30) + transferAndParse35(false, false, 0x8FFE0000); + break; + case 2: + // put instr. lhzu 31, 0(30) + transferAndParse35(false, false, 0x0A7FE0000); + break; + case 4: + // put instr. lwzu 31, 0(30) + transferAndParse35(false, false, 0x87FE0000); + break; + default: + throw new BDIException("wrong size: " + size + + " (should be 1, 2 or 4)"); + } + // put instr. mtspr DPDR, GPR31 + transferAndParse35(false, false, 0x7FF69BA6); + // put instr. nop + return transferAndParse35(false, false, NOP); + } + + public static void writeMemSeq(int value, int size) throws USBException, + DispatchException, BDIException { + + if (!targetInDebugMode) { + throw new BDIException("target not in debug mode"); + } + + // put instr. mfspr GPR30, DPDR + transferAndParse35(false, false, 0x7FF69AA6); + // put val into DPDR + transferAndParse35(false, true, value); + switch (size) { + case 1: + // put instr. stbu 31, 1(30) + transferAndParse35(false, false, 0x9FFE0001); + break; + case 2: + // put instr. sthu 31, 2(30) + transferAndParse35(false, false, 0x0B7FE0002); + break; + case 4: + // put instr. stwu 31, 4(30) + transferAndParse35(false, false, 0x97FE0004); + break; + default: + throw new BDIException("wrong size: " + size + + " (should be 1, 2 or 4)"); + } + } + + public static int readMemSeq(int size) throws USBException, + DispatchException, BDIException { + + if (!targetInDebugMode) { + throw new BDIException("target not in debug mode"); + } + + switch (size) { + case 1: + // put instr. lbzu 31, 1(30) + transferAndParse35(false, false, 0x8FFE0001); + break; + case 2: + // put instr. lhzu 31, 2(30) + transferAndParse35(false, false, 0x0A7FE0002); + break; + case 4: + // put instr. lwzu 31, 4(30) + transferAndParse35(false, false, 0x87FE0004); + break; + default: + throw new BDIException("wrong size: " + size + + " (should be 1, 2 or 4)"); + } + // put instr. mtspr DPDR, GPR31 + transferAndParse35(false, false, 0x7FF69BA6); + // put instr. nop + return transferAndParse35(false, false, NOP); + } + + public static int readGPR(int gpr) throws USBException, DispatchException, + BDIException { + if (!targetInDebugMode) { + throw new BDIException("target not in debug mode"); + } + + if (gpr == 30) { + return gpr30; + } else if (gpr == 31) { + return gpr31; + } + int cmd = MRTDPDR + (gpr * 0x200000); + + // put instr. mtspr DPDR, GPRx + transferAndParse35(false, false, cmd); + // put instr. nop + return transferAndParse35(false, false, NOP); + } + + public static void writeGPR(int gpr, int value) throws USBException, + DispatchException, BDIException { + if (!targetInDebugMode) { + throw new BDIException("target not in debug mode"); + } + + if (gpr == 30) { + gpr30 = gpr; + return; + } else if (gpr == 31) { + gpr31 = gpr; + return; + } + int cmd = MDPDRTR + (gpr * 0x200000); + + // put instr. mfspr GPRx, DPDR + transferAndParse35(false, false, cmd); + // put data + transferAndParse35(false, true, value); + } + + public static int readSPR(int spr) throws USBException, DispatchException, + BDIException { + if (!targetInDebugMode) { + throw new BDIException("target not in debug mode"); + } + + int cmd = ((spr & 0xFF) * 0x20 + (spr >>> 6)) * 0x800; + if ((spr == 268) || (spr == 269)) { + cmd += MTBRTR30; + } else { + cmd += MSPRTR30; + } + + // put instr. mfspr GPR30, SPRxxx + transferAndParse35(false, false, cmd); + // put instr. mtspr DPDR, GPR30 + transferAndParse35(false, false, 0x7FD69BA6); + // put instr. nop + return transferAndParse35(false, false, NOP); + } + + public static void writeSPR(int spr, int value) throws USBException, + DispatchException, BDIException { + if (!targetInDebugMode) { + throw new BDIException("target not in debug mode"); + } + int cmd = MR30TSPR + ((spr & 0xFF) * 0x20 + (spr >>> 6)) * 0x800; + + // put instr. mfspr GPR30, DPDR + transferAndParse35(false, false, 0x7FD69AA6); + // put data + transferAndParse35(false, true, value); + // put instr. mtspr SPRxxx, GPR30 + transferAndParse35(false, false, cmd); + } + + public static int readMSR() throws USBException, DispatchException, + BDIException { + if (!targetInDebugMode) { + throw new BDIException("target not in debug mode"); + } + + // put instr. mfmsr GPR30, MSR + transferAndParse35(false, false, 0x7FC000A6); + // put instr. mtspr DPDR, GPR30 + transferAndParse35(false, false, 0x7FD69BA6); + // put instr. nop + return transferAndParse35(false, false, NOP); + } + + public static void writeMSR(int value) throws USBException, + DispatchException, BDIException { + if (!targetInDebugMode) { + throw new BDIException("target not in debug mode"); + } + // put instr. mfspr GPR30, DPDR + transferAndParse35(false, false, 0x7FD69AA6); + // put data + transferAndParse35(false, true, value); + // put instr. mtmsr MSR, GPR30 + transferAndParse35(false, false, 0x7FC00124); + } + + public static long readFPR(int fpr, int tmpMemAddr) throws USBException, + DispatchException, BDIException { + if (!targetInDebugMode) { + throw new BDIException("target not in debug mode"); + } + // set FP bit + writeMSR(0x2002); + + // set r30 to tmpMemAddr + // put instr. mfspr r30, DPDR + transferAndParse35(false, false, MDPDRTR + (30 * 0x200000)); + // put tmpMemAddr + transferAndParse35(false, false, tmpMemAddr); + + // put instr. stfd frS, 0(r30) + transferAndParse35(false, false, 0x0D81E0000 + fpr * 0x200000); + // read data from tmpMemAddr + return ((long) readMem(tmpMemAddr, 4) << 32) + + readMem(tmpMemAddr + 4, 4); + } + + public static void writeFPR(int fpr, int tmpMemAddr, long value) + throws USBException, DispatchException, BDIException { + if (!targetInDebugMode) { + throw new BDIException("target not in debug mode"); + } + // set FP bit + writeMSR(0x2002); + + // write data to tmpMemAddr + writeMem(tmpMemAddr, (int) (value >>> 32), 4); + writeMem(tmpMemAddr, (int) value, 4); + + // set r30 to tmpMemAddr + // put instr. mfspr r30, DPDR + transferAndParse35(false, false, MDPDRTR + (30 * 0x200000)); + // put tmpMemAddr + transferAndParse35(false, true, tmpMemAddr); + + // put instr. lfd frS, 0(r30) + transferAndParse35(false, false, 0x0C81E0000 + fpr * 0x200000); + // nop + transferAndParse35(false, false, NOP); + } + + public static int readCR() throws USBException, DispatchException, + BDIException { + if (!targetInDebugMode) { + throw new BDIException("target not in debug mode"); + } + + // put instr. mfcr GPR30 + transferAndParse35(false, false, 0x7FC00026); + // put instr. mtspr DPDR, GPR30 + transferAndParse35(false, false, 0x7FD69BA6); + // nop + return transferAndParse35(false, false, NOP); + } + + public static void writeCR(int value) throws USBException, + DispatchException, BDIException { + if (!targetInDebugMode) { + throw new BDIException("target not in debug mode"); + } + // put instr. mfspr GPR30, DPDR + transferAndParse35(false, false, 0x7FD69AA6); + // put data + transferAndParse35(false, true, value); + + // put instr. mtcrf CRM=all, GPR30 + transferAndParse35(false, false, 0x7FCFF120); + } + + public static int readFPSCR() throws USBException, DispatchException, + BDIException { + if (!targetInDebugMode) { + throw new BDIException("target not in debug mode"); + } + // save CR + int cr = readCR(); + // set FP bit + writeMSR(0x2002); + // put instr. mcrfs crf0, crf0 + transferAndParse35(false, false, 0xFC000080); + // put instr. mcrfs crf1, crf1 + transferAndParse35(false, false, 0xFC840080); + // put instr. mcrfs crf2, crf2 + transferAndParse35(false, false, 0xFD080080); + // put instr. mcrfs crf3, crf3 + transferAndParse35(false, false, 0xFD8C0080); + // put instr. mcrfs crf4, crf4 + transferAndParse35(false, false, 0xFE100080); + // put instr. mcrfs crf5, crf5 + transferAndParse35(false, false, 0xFE940080); + // put instr. mcrfs crf6, crf6 + transferAndParse35(false, false, 0xFF180080); + // put instr. mcrfs crf7, crf7 + transferAndParse35(false, false, 0xFF9C0080); + int retVal = readCR(); + writeCR(cr); + return retVal; + } + + public static void writeFPSCR(int value) throws USBException, + DispatchException, BDIException { + if (!targetInDebugMode) { + throw new BDIException("target not in debug mode"); + } + // set FP bit + writeMSR(0x2002); + for (int i = 0; i < 7; i++) { + int cmd = 0xFC00010C + (7 - i) * 0x800000 + + ((value >>> i * 4) & 0xF) * 0x1000; + // put instr. mtfsfi crfx, imm + transferAndParse35(false, false, cmd); + } + } + + public static boolean isTargetInDebugMode() { + return targetInDebugMode; + } +} diff --git a/mcdp/src/ch/ntb/mcdp/bdi/BDIException.java b/mcdp/src/ch/ntb/mcdp/bdi/BDIException.java new file mode 100644 index 0000000..df2c516 --- /dev/null +++ b/mcdp/src/ch/ntb/mcdp/bdi/BDIException.java @@ -0,0 +1,14 @@ +package ch.ntb.mcdp.bdi; + +public class BDIException extends Exception { + + public BDIException(String string) { + super(string); + } + + /** + * + */ + private static final long serialVersionUID = -3800838568826846479L; + +} diff --git a/mcdp/src/ch/ntb/mcdp/bdi/test/BDI332App.java b/mcdp/src/ch/ntb/mcdp/bdi/test/BDI332App.java new file mode 100644 index 0000000..e70ea5f --- /dev/null +++ b/mcdp/src/ch/ntb/mcdp/bdi/test/BDI332App.java @@ -0,0 +1,210 @@ +package ch.ntb.mcdp.bdi.test; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +import ch.ntb.mcdp.usb.USBDevice; +import ch.ntb.usb.USBException; + +public class BDI332App { + + private Shell sShell = null; // @jve:decl-index=0:visual-constraint="10,10" + + private Button button1 = null; + + private Button button2 = null; + + private Button button3 = null; + + private Button button4 = null; + + private Button button5 = null; + + private Button button6 = null; + + private Button button7 = null; + + private Button button8 = null; + + private Button button9 = null; + + private Button button10 = null; + + private Button button15 = null; + + private Button button11 = null; + + private Button button12 = null; + + private Button button13 = null; + + private Button button14 = null; + + /** + * This method initializes sShell + */ + private void createSShell() { + sShell = new Shell(); + sShell.setText("Shell"); + sShell.setLayout(new RowLayout()); + sShell.setSize(new org.eclipse.swt.graphics.Point(312,110)); + button1 = new Button(sShell, SWT.NONE); + button1.setText("testBdiTransaction"); + button1 + .addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() { + public void widgetSelected( + org.eclipse.swt.events.SelectionEvent e) { + BDI332test.button1(); + } + }); + button2 = new Button(sShell, SWT.NONE); + button2.setText("reset_target"); + button2 + .addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() { + public void widgetSelected( + org.eclipse.swt.events.SelectionEvent e) { + BDI332test.button2(); + } + }); + button3 = new Button(sShell, SWT.NONE); + button3.setText("go"); + button3 + .addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() { + public void widgetSelected( + org.eclipse.swt.events.SelectionEvent e) { + BDI332test.button3(); + } + }); + button4 = new Button(sShell, SWT.NONE); + button4.setText("break_"); + button4 + .addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() { + public void widgetSelected( + org.eclipse.swt.events.SelectionEvent e) { + BDI332test.button4(); + } + }); + button5 = new Button(sShell, SWT.NONE); + button5.setText("freeze"); + button6 = new Button(sShell, SWT.NONE); + button6.setText("writeMem"); + button6 + .addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() { + public void widgetSelected( + org.eclipse.swt.events.SelectionEvent e) { + BDI332test.button6(); + } + }); + button7 = new Button(sShell, SWT.NONE); + button7.setText("readMem"); + button8 = new Button(sShell, SWT.NONE); + button8.setText("dumpMem"); + button8 + .addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() { + public void widgetSelected( + org.eclipse.swt.events.SelectionEvent e) { + BDI332test.button8(); + } + }); + button9 = new Button(sShell, SWT.NONE); + button9.setText("NOP"); + button10 = new Button(sShell, SWT.NONE); + button10.setText("fillMem"); + button11 = new Button(sShell, SWT.NONE); + button11.setText("initTarget"); + button11.addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() { + public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) { + BDI332test.button11(); + } + }); + button12 = new Button(sShell, SWT.NONE); + button12.setText("-------"); + button12.addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() { + public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) { + BDI332test.button12(); + } + }); + button13 = new Button(sShell, SWT.NONE); + button13.setText("-------"); + button13.addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() { + public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) { + BDI332test.button13(); + } + }); + button14 = new Button(sShell, SWT.NONE); + button14.setText("-------"); + button14.addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() { + public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) { + BDI332test.button14(); + } + }); + button15 = new Button(sShell, SWT.NONE); + button15.setText("resetUSB"); + button15.addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() { + public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) { + BDI332test.button15(); + } + }); + button10 + .addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() { + public void widgetSelected( + org.eclipse.swt.events.SelectionEvent e) { + BDI332test.button10(); + } + }); + button9 + .addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() { + public void widgetSelected( + org.eclipse.swt.events.SelectionEvent e) { + BDI332test.button9(); + } + }); + button7 + .addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() { + public void widgetSelected( + org.eclipse.swt.events.SelectionEvent e) { + BDI332test.button7(); + } + }); + button5 + .addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() { + public void widgetSelected( + org.eclipse.swt.events.SelectionEvent e) { + BDI332test.button5(); + } + }); + } + + public static void main(String[] args) { + BDI332App app = new BDI332App(); + app.createSShell(); + app.sShell.open(); + + Display display = app.sShell.getDisplay(); + + try { + USBDevice.open(); + System.out.println("open device..."); + } catch (USBException e) { + e.printStackTrace(); + return; + } + + while (!app.sShell.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + + try { + USBDevice.close(); + System.out.println("closing device..."); + } catch (USBException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } +} diff --git a/mcdp/src/ch/ntb/mcdp/bdi/test/BDI332test.java b/mcdp/src/ch/ntb/mcdp/bdi/test/BDI332test.java new file mode 100644 index 0000000..ace312a --- /dev/null +++ b/mcdp/src/ch/ntb/mcdp/bdi/test/BDI332test.java @@ -0,0 +1,340 @@ +package ch.ntb.mcdp.bdi.test; + +import ch.ntb.mcdp.bdi.BDI332; +import ch.ntb.mcdp.bdi.BDIException; +import ch.ntb.mcdp.mc68332.IMCBTargetBoard; +import ch.ntb.mcdp.usb.DataPacket; +import ch.ntb.mcdp.usb.DispatchException; +import ch.ntb.mcdp.usb.USBDevice; +import ch.ntb.usb.USBException; + +public class BDI332test { + + private static void testBdiTransaction() { + // test bdi transaction + DataPacket result = null; + try { + result = BDI332.transfer(0x0C00); + } catch (USBException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } catch (DispatchException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } catch (BDIException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + if (result != null) { + result.toString(); + } + } + + private static void reset_target() { + try { + BDI332.reset_target(); + } catch (USBException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } catch (DispatchException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } catch (BDIException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + private static void freeze() { + try { + System.out + .println("isFreezeAsserted: " + BDI332.isFreezeAsserted()); + } catch (USBException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (DispatchException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (BDIException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } + + private static void break_() { + try { + BDI332.break_(); + } catch (USBException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (DispatchException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (BDIException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + private static void go() { + try { + BDI332.go(); + } catch (USBException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (DispatchException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (BDIException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + private static void writeMem() { + final int BASE_ADDR = 0x105624; + try { + BDI332.writeMem(BASE_ADDR, 0x123456, 4); + BDI332.writeMem(BASE_ADDR + 4, 0x123457, 4); + BDI332.writeMem(BASE_ADDR + 8, 0x123458, 4); + } catch (USBException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (DispatchException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (BDIException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + private static void readMem() { + final int BASE_ADDR = 0x105624; + try { + StringBuffer sb = new StringBuffer("0x" + + Integer.toHexString(BDI332.readMem(BASE_ADDR, 4)) + "\n"); + sb.append("0x" + + Integer.toHexString(BDI332.readMem(BASE_ADDR + 4, 4)) + + "\n"); + sb.append("0x" + + Integer.toHexString(BDI332.readMem(BASE_ADDR + 8, 4)) + + "\n"); + System.out.println(sb.toString()); + } catch (USBException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (DispatchException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (BDIException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + // private static void fastDownload() { + // int[] testData = new int[120]; + // for (int i = 0; i < testData.length; i++) { + // testData[i] = i; + // } + // try { + // BDI332.startFastDownload(0x800000); + // BDI332.fastDownload(testData, BDI332.MAX_NOF_WORDS_FAST_DOWNLOAD); + // BDI332.stopFastDownload(); + // } catch (USBException e) { + // // TODO Auto-generated catch block + // e.printStackTrace(); + // } catch (DispatchException e) { + // // TODO Auto-generated catch block + // e.printStackTrace(); + // } catch (BDIException e) { + // // TODO Auto-generated catch block + // e.printStackTrace(); + // } + // } + + // private static void readMemSeq() { + // int startAddr = 0x800000; + // try { + // StringBuffer sb = new StringBuffer(0 + "\tData: 0x" + // + Integer.toHexString(BDI332.readMem(startAddr, 4)) + "\n"); + // for (int i = 1; i < 120; i++) { + // sb.append(i + "\tData: 0x" + // + Integer.toHexString(BDI332.readMemSeq(4)) + "\n"); + // } + // System.out.println(sb.toString()); + // } catch (USBException e) { + // // TODO Auto-generated catch block + // e.printStackTrace(); + // } catch (DispatchException e) { + // // TODO Auto-generated catch block + // e.printStackTrace(); + // } catch (BDIException e) { + // // TODO Auto-generated catch block + // e.printStackTrace(); + // } + // } + + public static void button1() { + System.out.println("testBdiTransaction()"); + testBdiTransaction(); + } + + public static void button2() { + System.out.println("reset_target()"); + reset_target(); + } + + public static void button3() { + System.out.println("go()"); + go(); + } + + public static void button4() { + System.out.println("break_()"); + break_(); + } + + public static void button5() { + System.out.println("freeze()"); + freeze(); + } + + public static void button6() { + System.out.println("writeMem()"); + writeMem(); + } + + public static void button7() { + System.out.println("readMem()"); + readMem(); + } + + public static void button8() { + + final int BASE_ADDR = 0x105624; + int[] result; + + System.out.println("dump()"); + try { + System.out.println("Data: 0x" + + Integer.toHexString(BDI332.readMem(BASE_ADDR, 4)) + " "); + result = BDI332.dumpMem(BDI332.MAX_NOF_LONGS_FILL); + for (int i = 0; i < result.length; i++) { + System.out.print("0x" + Integer.toHexString(result[i]) + " "); + } + System.out.println(); + + } catch (USBException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (DispatchException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (BDIException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + public static void button9() { + try { + BDI332.nop(); + } catch (USBException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (DispatchException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (BDIException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + public static void button10() { + + final int BASE_ADDR = 0x105624; + + System.out.println("fill"); + try { + BDI332.writeMem(BASE_ADDR, 0, 4); + int[] data = new int[BDI332.MAX_NOF_LONGS_FILL]; + for (int i = 0; i < data.length; i++) { + data[i] = i; + } + BDI332.fillMem(data, data.length); + } catch (USBException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (DispatchException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (BDIException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + public static void button11() { + System.out.println("initTarget()"); + try { + IMCBTargetBoard.init(); + } catch (USBException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (DispatchException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (BDIException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + public static void button12() { + System.out.println("readMem()"); + readMem(); + } + + public static void button13() { + System.out.println("readMem()"); + readMem(); + } + + public static void button14() { + System.out.println("readMem()"); + readMem(); + } + + public static void button15() { + System.out.println("resetUSB()"); + try { + USBDevice.reset(); + } catch (USBException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + // public static void main(String[] args) { + // boolean testRunning = true; + // + // while (testRunning) { + // // testBdiTransaction(); + // // reset_target(); + // // freeze(); + // // go(); + // // System.out.println(); + // + // try { + // Thread.sleep(5000); + // } catch (InterruptedException e) { + // e.printStackTrace(); + // } + // } + // + // } +} diff --git a/mcdp/src/ch/ntb/mcdp/bdi/test/BDI555App.java b/mcdp/src/ch/ntb/mcdp/bdi/test/BDI555App.java new file mode 100644 index 0000000..0413790 --- /dev/null +++ b/mcdp/src/ch/ntb/mcdp/bdi/test/BDI555App.java @@ -0,0 +1,154 @@ +package ch.ntb.mcdp.bdi.test; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +import ch.ntb.mcdp.usb.USBDevice; +import ch.ntb.usb.USBException; + +public class BDI555App { + + private Shell sShell = null; // @jve:decl-index=0:visual-constraint="10,10" + + private Button button1 = null; + + private Button button2 = null; + + private Button button3 = null; + + private Button button4 = null; + + private Button button5 = null; + + private Button button6 = null; + + private Button button7 = null; + + private Button button8 = null; + + private Button button9 = null; + + private Button button10 = null; + + /** + * This method initializes sShell + */ + private void createSShell() { + sShell = new Shell(); + sShell.setText("Shell"); + sShell.setLayout(new RowLayout()); + sShell.setSize(new org.eclipse.swt.graphics.Point(348,83)); + button1 = new Button(sShell, SWT.NONE); + button1.setText("testBdiTransaction"); + button1 + .addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() { + public void widgetSelected( + org.eclipse.swt.events.SelectionEvent e) { + BDI555test.button1(); + } + }); + button2 = new Button(sShell, SWT.NONE); + button2.setText("reset_target"); + button2 + .addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() { + public void widgetSelected( + org.eclipse.swt.events.SelectionEvent e) { + BDI555test.button2(); + } + }); + button3 = new Button(sShell, SWT.NONE); + button3.setText("go"); + button3 + .addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() { + public void widgetSelected( + org.eclipse.swt.events.SelectionEvent e) { + BDI555test.button3(); + } + }); + button4 = new Button(sShell, SWT.NONE); + button4.setText("break_"); + button4 + .addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() { + public void widgetSelected( + org.eclipse.swt.events.SelectionEvent e) { + BDI555test.button4(); + } + }); + button5 = new Button(sShell, SWT.NONE); + button5.setText("freeze"); + button6 = new Button(sShell, SWT.NONE); + button6.setText("writeMem"); + button6.addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() { + public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) { + BDI555test.button6(); + } + }); + button7 = new Button(sShell, SWT.NONE); + button7.setText("readMem"); + button8 = new Button(sShell, SWT.NONE); + button8.setText("readMemSeq"); + button8.addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() { + public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) { + BDI555test.button8(); + } + }); + button9 = new Button(sShell, SWT.NONE); + button9.setText("Button9"); + button10 = new Button(sShell, SWT.NONE); + button10.setText("fastDownload"); + button10.addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() { + public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) { + BDI555test.button10(); + } + }); + button9.addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() { + public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) { + BDI555test.button9(); + } + }); + button7.addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() { + public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) { + BDI555test.button7(); + } + }); + button5 + .addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() { + public void widgetSelected( + org.eclipse.swt.events.SelectionEvent e) { + BDI555test.button5(); + } + }); + } + + public static void main(String[] args) { + BDI555App app = new BDI555App(); + app.createSShell(); + app.sShell.open(); + + Display display = app.sShell.getDisplay(); + + try { + USBDevice.open(); + } catch (USBException e) { + e.printStackTrace(); + return; + } + + while (!app.sShell.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + + try { + USBDevice.close(); + } catch (USBException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } +} diff --git a/mcdp/src/ch/ntb/mcdp/bdi/test/BDI555test.java b/mcdp/src/ch/ntb/mcdp/bdi/test/BDI555test.java new file mode 100644 index 0000000..fdc572e --- /dev/null +++ b/mcdp/src/ch/ntb/mcdp/bdi/test/BDI555test.java @@ -0,0 +1,246 @@ +package ch.ntb.mcdp.bdi.test; + +import ch.ntb.mcdp.bdi.BDI555; +import ch.ntb.mcdp.bdi.BDIException; +import ch.ntb.mcdp.usb.DataPacket; +import ch.ntb.mcdp.usb.DispatchException; +import ch.ntb.usb.USBException; + +public class BDI555test { + + // private static void testBdiTransaction() { + // // test bdi transaction + // DataPacket result = null; + // try { + // result = BDI555.transfer(false, false, 0x7FD69BA6); + // result = BDI555.transfer(false, false, 0x60000000); + // } catch (USBException e1) { + // // TODO Auto-generated catch block + // e1.printStackTrace(); + // } catch (DispatchException e1) { + // // TODO Auto-generated catch block + // e1.printStackTrace(); + // } catch (BDIException e) { + // // TODO Auto-generated catch block + // e.printStackTrace(); + // } + // if (result != null) { + // result.toString(); + // } + // } + + private static void reset_target() { + try { + BDI555.reset_target(); + // assign pin to Freeze output + BDI555.writeMem(0x02FC000, 0x40000, 4); + // enable bus monitor, disable watchdog timer + BDI555.writeMem(0x02FC004, 0x0FFFFFF83, 4); + // SCCR, switch off EECLK for download + BDI555.writeMem(0x02FC280, 0x08121C100, 4); + } catch (USBException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } catch (DispatchException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } catch (BDIException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + private static void freeze() { + try { + System.out + .println("isFreezeAsserted: " + BDI555.isFreezeAsserted()); + } catch (USBException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (DispatchException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (BDIException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } + + private static void break_() { + try { + BDI555.break_(); + } catch (USBException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (DispatchException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (BDIException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + private static void go() { + try { + BDI555.go(); + } catch (USBException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (DispatchException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (BDIException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + private static void writeMem() { + try { + BDI555.writeMem(0x800000, 0x123456, 4); + } catch (USBException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (DispatchException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (BDIException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + private static void readMem() { + try { + StringBuffer sb = new StringBuffer("0x" + + Integer.toHexString(BDI555.readMem(0x800000, 4)) + "\n"); + sb.append("0x" + Integer.toHexString(BDI555.readMem(0x800004, 4)) + + "\n"); + sb.append("0x" + Integer.toHexString(BDI555.readMem(0x800008, 4)) + + "\n"); + System.out.println(sb.toString()); + } catch (USBException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (DispatchException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (BDIException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + private static void fastDownload() { + int[] testData = new int[120]; + for (int i = 0; i < testData.length; i++) { + testData[i] = i; + } + try { + BDI555.startFastDownload(0x800000); + BDI555.fastDownload(testData, BDI555.MAX_NOF_WORDS_FAST_DOWNLOAD); + BDI555.stopFastDownload(); + } catch (USBException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (DispatchException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (BDIException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + private static void readMemSeq() { + int startAddr = 0x800000; + try { + StringBuffer sb = new StringBuffer(0 + "\tData: 0x" + + Integer.toHexString(BDI555.readMem(startAddr, 4)) + "\n"); + for (int i = 1; i < 120; i++) { + sb.append(i + "\tData: 0x" + + Integer.toHexString(BDI555.readMemSeq(4)) + "\n"); + } + System.out.println(sb.toString()); + } catch (USBException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (DispatchException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (BDIException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + public static void button1() { + // System.out.println("testBdiTransaction()"); + // testBdiTransaction(); + } + + public static void button2() { + System.out.println("reset_target()"); + reset_target(); + } + + public static void button3() { + System.out.println("go()"); + go(); + } + + public static void button4() { + System.out.println("break_()"); + break_(); + } + + public static void button5() { + System.out.println("freeze()"); + freeze(); + } + + public static void button6() { + System.out.println("writeMem()"); + writeMem(); + } + + public static void button7() { + System.out.println("readMem()"); + readMem(); + } + + public static void button8() { + System.out.println("readMemSeq()"); + readMemSeq(); + } + + public static void button9() { + System.out.println(""); + } + + public static void button10() { + System.out.println("fastDownload()"); + fastDownload(); + } + + // public static void main(String[] args) { + // boolean testRunning = true; + // + // while (testRunning) { + // // testBdiTransaction(); + // // reset_target(); + // // freeze(); + // // go(); + // // System.out.println(); + // + // try { + // Thread.sleep(5000); + // } catch (InterruptedException e) { + // e.printStackTrace(); + // } + // } + // + // } +} diff --git a/mcdp/src/ch/ntb/mcdp/mc68332/IMCBTargetBoard.java b/mcdp/src/ch/ntb/mcdp/mc68332/IMCBTargetBoard.java new file mode 100644 index 0000000..8d921ab --- /dev/null +++ b/mcdp/src/ch/ntb/mcdp/mc68332/IMCBTargetBoard.java @@ -0,0 +1,79 @@ +package ch.ntb.mcdp.mc68332; + +import ch.ntb.mcdp.bdi.BDI332; +import ch.ntb.mcdp.bdi.BDIException; +import ch.ntb.mcdp.usb.DispatchException; +import ch.ntb.usb.USBException; + +public class IMCBTargetBoard { + + private static void writeRegister(String name, int value) + throws USBException, DispatchException, BDIException { + System.out.println("0x" + Integer.toHexString(readRegister(name))); + System.out.println("writeRegister: " + name + ", value: 0x" + + Integer.toHexString(value)); + Register r = RegisterDict.getRegister(name); + switch (r.type) { + case Register.CtrReg: + System.out.println("writeMem"); + BDI332.writeMem(r.addr, value, r.size); + break; + case Register.SysReg: + System.out.println("writeSysReg"); + BDI332.writeSysReg(r.addr, value); + break; + case Register.UserReg: + System.out.println("writeUserReg"); + BDI332.writeUserReg(r.addr, value); + break; + } + System.out.println("0x" + Integer.toHexString(readRegister(name))); + } + + private static int readRegister(String name) throws USBException, + DispatchException, BDIException { + System.out.print("readRegister: " + name); + Register r = RegisterDict.getRegister(name); + switch (r.type) { + case Register.CtrReg: + System.out.println("\treadMem"); + return BDI332.readMem(r.addr, r.size); + case Register.SysReg: + System.out.println("\treadSysReg"); + return BDI332.readSysReg(r.addr); + case Register.UserReg: + System.out.println("\treadUserReg"); + return BDI332.readUserReg(r.addr); + } + return -1; + } + + public static void init() throws USBException, DispatchException, + BDIException { + + BDI332.reset_target(); + + // RegisterDict.printRegisters(); + + writeRegister("SR", 0x2700); + writeRegister("SFC", 0x05); + writeRegister("DFC", 0x05); + writeRegister("VBR", 0x100000); + + writeRegister("SIMCR", 0x0404F); + writeRegister("SYNCR", 0x7F80); + writeRegister("SYPCR", 0x04); + writeRegister("CSPAR0", 0x03FF); + writeRegister("CSPAR1", 0x01); + writeRegister("CSBARBT", 0x07); + writeRegister("CSORBT", 0x06830); + writeRegister("CSBAR0", 0x07); + writeRegister("CSOR0", 0x07430); + writeRegister("CSBAR1", 0x01005); + writeRegister("CSOR1", 0x06C30); + writeRegister("CSBAR2", 0x01005); + writeRegister("CSOR2", 0x05030); + writeRegister("CSBAR3", 0x01005); + writeRegister("CSOR3", 0x03030); + } +} diff --git a/mcdp/src/ch/ntb/mcdp/mc68332/Register.java b/mcdp/src/ch/ntb/mcdp/mc68332/Register.java new file mode 100644 index 0000000..75c0382 --- /dev/null +++ b/mcdp/src/ch/ntb/mcdp/mc68332/Register.java @@ -0,0 +1,33 @@ +package ch.ntb.mcdp.mc68332; + +class Register { + + public final static int UserReg = 0; + + public final static int SysReg = 1; + + public final static int CtrReg = 2; + + Register(String name, int type, int addr, int size, String description) { + this.name = name; + this.type = type; + this.addr = addr; + this.size = size; + this.description = description; + } + + public final String name; + + public final int type; + + /** + * Absolute address of this register.
+ * For system and user register this value is used as BDI specific + * identifier. + */ + public final int addr; + + public final int size; + + public final String description; +} diff --git a/mcdp/src/ch/ntb/mcdp/mc68332/RegisterDict.java b/mcdp/src/ch/ntb/mcdp/mc68332/RegisterDict.java new file mode 100644 index 0000000..0b4eb90 --- /dev/null +++ b/mcdp/src/ch/ntb/mcdp/mc68332/RegisterDict.java @@ -0,0 +1,279 @@ +package ch.ntb.mcdp.mc68332; + +import java.io.File; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.UnsupportedEncodingException; +import java.io.Writer; +import java.util.Iterator; +import java.util.LinkedList; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; + +import org.w3c.dom.Document; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.ErrorHandler; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; +import org.xml.sax.helpers.DefaultHandler; + +public class RegisterDict { + + private static LinkedList registers; + + private static final long serialVersionUID = -582382284126896830L; + + private static final String REGISTER_DEFINITIONS = "registerDefinitions"; + + private static final String REGISTER_GROUP = "registerGroup"; + + private static final String REG_GROUP_ATTR_BASEADDR = "baseAddress"; + + private static final String REGISTER = "register"; + + private static final String DESCRIPTON = "description"; + + private static final String REG_ATTR_NAME = "name"; + + private static final String REG_ATTR_TYPE = "type"; + + private static final String REG_ATTR_OFFSET = "offset"; + + private static final String REG_ATTR_SIZE = "size"; + + private static final String REG_ATTR_TYPE_CTRLREG = "CtrlReg"; + + private static final String REG_ATTR_TYPE_USERREG = "UserReg"; + + private static final String REG_ATTR_TYPE_SYSREG = "SysReg"; + + static { + registers = new LinkedList(); + + // data registers + add("D0", Register.UserReg, 0x0, 4, "data register 0"); + add("D1", Register.UserReg, 0x1, 4, "data register 1"); + add("D2", Register.UserReg, 0x2, 4, "data register 2"); + add("D3", Register.UserReg, 0x3, 4, "data register 3"); + add("D4", Register.UserReg, 0x4, 4, "data register 4"); + add("D5", Register.UserReg, 0x5, 4, "data register 5"); + add("D6", Register.UserReg, 0x6, 4, "data register 6"); + add("D7", Register.UserReg, 0x7, 4, "data register 7"); + + // address registers + add("A0", Register.UserReg, 0x8, 4, "address register 0"); + add("A1", Register.UserReg, 0x9, 4, "address register 1"); + add("A2", Register.UserReg, 0xA, 4, "address register 2"); + add("A3", Register.UserReg, 0xB, 4, "address register 3"); + add("A4", Register.UserReg, 0xC, 4, "address register 4"); + add("A5", Register.UserReg, 0xD, 4, "address register 5"); + add("A6", Register.UserReg, 0xE, 4, "address register 6"); + add("A7", Register.UserReg, 0xF, 4, "address register 7"); + + // system registers + add("RPC", Register.SysReg, 0x0, 4, "return program counter"); + add("PCC", Register.SysReg, 0x1, 4, + "current instruction program counter"); + add("SR", Register.SysReg, 0xB, 2, "status register"); + add("USP", Register.SysReg, 0xC, 4, "user stack pointer (A7)"); + add("SSP", Register.SysReg, 0xD, 4, "supervisor stack pointer"); + add("SFC", Register.SysReg, 0xE, 4, "source function code register"); + add("DFC", Register.SysReg, 0xF, 4, + "destination function code register"); + add("ATEMP", Register.SysReg, 0x8, 4, "temporary register A"); + add("FAR", Register.SysReg, 0x9, 4, "fault address register"); + add("VBR", Register.SysReg, 0xA, 4, "vector base register"); + + // TODO: remove + try { + addRegistersFromFile("resources/targets/mc68332/registerDictionary.xml"); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (ParserConfigurationException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (SAXException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + private static void add(String name, int type, int addr, int size, + String description) { + // remove before add for updates + for (Iterator i = registers.iterator(); i.hasNext();) { + if (i.next().name.equals(name)) { + i.remove(); + } + } + registers.add(new Register(name, type, addr, size, description)); + } + + private static int parseInt(String s) { + if (s == "") + return 0; + if (s.indexOf('x') > 0) { + // is hex number + if (s.length() <= 2) { // exception for "0x" + throw new NumberFormatException("string too short: " + s); + } + if ((s.length() > 10)) { // exception for e.g. 0x112345678 + throw new NumberFormatException("number too large: " + s); + } + // check if string too long (max + return (int) Long.parseLong(s.substring(s.indexOf('x') + 1, s + .length()), 16); + } else { + // is decimal number + return Integer.parseInt(s); + } + } + + public static Register getRegister(String name) { + for (Iterator i = registers.iterator(); i.hasNext();) { + Register r = i.next(); + if (r.name.equals(name)) { + return r; + } + } + return null; + } + + public static void printRegisters() { + System.out + .println("******************** register dictionary *********************"); + System.out.println("Name \t Type \t\t Address \t Size \t Description"); + System.out + .println("**************************************************************"); + for (Iterator i = registers.iterator(); i.hasNext();) { + Register r = i.next(); + String type; + switch (r.type) { + case Register.CtrReg: + type = "CtrReg"; + break; + case Register.SysReg: + type = "SysReg"; + break; + case Register.UserReg: + type = "UserReg"; + break; + default: + type = Integer.toString(r.type); + } + System.out.println(r.name + "\t" + type + "\t\t0x" + + Integer.toHexString(r.addr) + "\t\t" + r.size + "\t" + + r.description); + } + System.out + .println("**************************************************************"); + } + + /** + * Adds the registers from the specified xml-file to the register + * dictionary.
+ * The xml-file must be structured according to + * registerDictionary.dtd. Include + * + * in your xml file. + * + * @param xmlPathname + * @throws IOException + * @throws ParserConfigurationException + * @throws SAXException + */ + public static void addRegistersFromFile(String xmlPathname) + throws IOException, ParserConfigurationException, SAXException { + Document document; + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setValidating(true); + DocumentBuilder builder = factory.newDocumentBuilder(); + builder.setErrorHandler(new ErrorHandler() { + // ignore fatal errors (an exception is guaranteed) + public void fatalError(SAXParseException exception) + throws SAXException { + } + + // treat validation errors as fatal error + public void error(SAXParseException e) throws SAXParseException { + throw e; + } + + // treat warnings errors as fatal error + public void warning(SAXParseException e) throws SAXParseException { + throw e; + } + }); + document = builder.parse(new File(xmlPathname)); + NodeList list = document.getElementsByTagName(REGISTER_DEFINITIONS); + for (int i = 0; i < list.getLength(); i++) { + if (list.item(i).getNodeName().equals(REGISTER_DEFINITIONS)) { + list = list.item(i).getChildNodes(); + } + for (int j = 0; j < list.getLength(); j++) { + if (list.item(j).getNodeName().equals(REGISTER_GROUP)) { + NamedNodeMap attributes = list.item(j).getAttributes(); + for (int k = 0; k < attributes.getLength(); k++) { + if (attributes.item(k).getNodeName().equals( + REG_GROUP_ATTR_BASEADDR)) { + int baseAddr = parseInt(attributes.item(k) + .getNodeValue()); + parseRegisterGroup(list.item(j), baseAddr); + } + } + } + } + } + } + + private static void parseRegisterGroup(Node registerGroup, int baseAddr) + throws SAXException { + NodeList list = registerGroup.getChildNodes(); + for (int i = 0; i < list.getLength(); i++) { + if (list.item(i).getNodeName().equals(REGISTER)) { + NamedNodeMap attributes = list.item(i).getAttributes(); + // attributes: name, type, offset, size + Node n = attributes.getNamedItem(REG_ATTR_NAME); + String name = n.getNodeValue(); + n = attributes.getNamedItem(REG_ATTR_TYPE); + String typeStr = n.getNodeValue(); + int type; + if (typeStr.equals(REG_ATTR_TYPE_CTRLREG)) { + type = Register.CtrReg; + } else if (typeStr.equals(REG_ATTR_TYPE_SYSREG)) { + type = Register.SysReg; + } else if (typeStr.equals(REG_ATTR_TYPE_USERREG)) { + type = Register.UserReg; + } else { + throw new SAXException("invalid register definition: " + + list.item(i).getNodeName()); + } + n = attributes.getNamedItem(REG_ATTR_OFFSET); + int offset = parseInt(n.getNodeValue()); + n = attributes.getNamedItem(REG_ATTR_SIZE); + int size = parseInt(n.getNodeValue()); + + parseRegister(list.item(i), name, type, baseAddr + offset, size); + } + } + } + + private static void parseRegister(Node register, String name, int type, + int addr, int size) throws SAXException { + NodeList list = register.getChildNodes(); + String description = ""; + for (int i = 0; i < list.getLength(); i++) { + if (list.item(i).getNodeName().equals(DESCRIPTON)) { + description = list.item(i).getTextContent(); + } + } + add(name, type, addr, size, description); + } +} diff --git a/mcdp/src/ch/ntb/mcdp/uart/Uart0.java b/mcdp/src/ch/ntb/mcdp/uart/Uart0.java new file mode 100644 index 0000000..e8cd76f --- /dev/null +++ b/mcdp/src/ch/ntb/mcdp/uart/Uart0.java @@ -0,0 +1,16 @@ +package ch.ntb.mcdp.uart; + +public class Uart0 { + + // UART 0 Subtypes + /** + * Data to UART 0 + */ + private static final byte STYPE_UART_0_IN = 0x11; + + /** + * Data from UART 0 + */ + private static final byte STYPE_UART_0_OUT = 0x22; + +} diff --git a/mcdp/src/ch/ntb/mcdp/usb/DataPacket.java b/mcdp/src/ch/ntb/mcdp/usb/DataPacket.java new file mode 100644 index 0000000..98d90b9 --- /dev/null +++ b/mcdp/src/ch/ntb/mcdp/usb/DataPacket.java @@ -0,0 +1,29 @@ +package ch.ntb.mcdp.usb; + +public class DataPacket { + + /** + * minimal Length of a packet (no payload) + */ + public static final int PACKET_MIN_LENGTH = 6; + + public int subtype; + + public byte[] data; + + DataPacket(int subtype, byte[] data) { + this.subtype = subtype; + this.data = data; + } + + @Override + public String toString() { + StringBuffer sb = new StringBuffer("Subtype: 0x" + + String.format("%1$02X", subtype) + "\t"); + sb.append("Data: "); + for (int i = 0; i < data.length; i++) { + sb.append("0x" + String.format("%1$02X", data[i]) + " "); + } + return sb.toString(); + } +} diff --git a/mcdp/src/ch/ntb/mcdp/usb/Dispatch.java b/mcdp/src/ch/ntb/mcdp/usb/Dispatch.java new file mode 100644 index 0000000..0d980b5 --- /dev/null +++ b/mcdp/src/ch/ntb/mcdp/usb/Dispatch.java @@ -0,0 +1,146 @@ +package ch.ntb.mcdp.usb; + +import java.util.LinkedList; + +import ch.ntb.usb.USB; +import ch.ntb.usb.USBException; + +public class Dispatch { + + // Packet Constants + /** + * first byte of header + */ + public static final byte PACKET_HEADER = 0x5B; + + /** + * last byte of packet + */ + public static final byte PACKET_END = 0x1F; + + /** + * offset to the first byte of data + */ + public static final byte PACKET_DATA_OFFSET = 5; + + // Main Types + /** + * general errors + */ + public static final byte MTYPE_ERROR = 0x01; + + /** + * BDI specific errors + */ + public static final byte MTYPE_BDI = 0x02; + + /** + * UART specific errors + */ + public static final byte MTYPE_UART_0 = 0x03; + + // Sub Types + // ERRORS + /** + * Unknown MTYPE + */ + public static final byte STYPE_ERROR_UNKNOWN_MTYPE = 0x70; + + /** + * Header of packet wrong + */ + public static final byte STYPE_ERROR_HEADER = 0x71; + + /** + * Packet end wrong + */ + public static final byte STYPE_ERROR_PACKET_END = 0x72; + + private static byte[] usbData = new byte[USB.MAX_DATA_SIZE]; + + private static LinkedList bdiData, uart0Data; + + static { + bdiData = new LinkedList(); + uart0Data = new LinkedList(); + } + + public static void emptyBuffers() { + bdiData.clear(); + uart0Data.clear(); + } + + private static void dispatch(byte[] data, int size) + throws DispatchException { + int index = 0, mainType, subtype; + byte[] packetData; + while (index < size) { + if (data[index++] != PACKET_HEADER) { + throw new DispatchException("PACKET_HEADER wrong: " + + data[index - 1]); + } + mainType = data[index++]; + subtype = data[index++]; + int dataLen = data[index++] * 0x100 + data[index++]; + if (data[index + dataLen] != PACKET_END) { + throw new DispatchException("PACKET_END or packetLen (" + + dataLen + " bytes) wrong"); + } + + switch (mainType) { + case MTYPE_ERROR: + switch (subtype) { + case STYPE_ERROR_HEADER: + throw new DispatchException( + "MTYPE_ERROR: STYPE_ERROR_HEADER"); + case STYPE_ERROR_PACKET_END: + throw new DispatchException( + "MTYPE_ERROR: STYPE_ERROR_PACKET_END"); + case STYPE_ERROR_UNKNOWN_MTYPE: + throw new DispatchException( + "MTYPE_ERROR: STYPE_ERROR_UNKNOWN_MTYPE"); + default: + throw new DispatchException("MTYPE_ERROR: Unknown S_TYPE: " + + subtype); + } + case MTYPE_BDI: + packetData = new byte[dataLen]; + // copy data to bdiData + for (int i = 0; i < dataLen; i++) { + packetData[i] = data[index + i]; + } + bdiData.add(new DataPacket(subtype, packetData)); + break; + case MTYPE_UART_0: + packetData = new byte[dataLen]; + // copy data to uartData + for (int i = 0; i < dataLen; i++) { + packetData[i] = data[index + i]; + } + uart0Data.add(new DataPacket(subtype, packetData)); + break; + default: + throw new DispatchException("Unknown MTYPE: " + mainType); + } + index += dataLen + 1; + } + } + + public static DataPacket readBDI() throws USBException, DispatchException { + if (!bdiData.isEmpty()) { + return bdiData.poll(); + } + int dataLength = USBDevice.read(usbData, USB.MAX_DATA_SIZE); + dispatch(usbData, dataLength); + return bdiData.poll(); + } + + public static DataPacket readUART0() throws USBException, DispatchException { + if (!uart0Data.isEmpty()) { + return uart0Data.poll(); + } + int dataLength = USBDevice.read(usbData, USB.MAX_DATA_SIZE); + dispatch(usbData, dataLength); + return uart0Data.poll(); + } +} diff --git a/mcdp/src/ch/ntb/mcdp/usb/DispatchException.java b/mcdp/src/ch/ntb/mcdp/usb/DispatchException.java new file mode 100644 index 0000000..13697c7 --- /dev/null +++ b/mcdp/src/ch/ntb/mcdp/usb/DispatchException.java @@ -0,0 +1,14 @@ +package ch.ntb.mcdp.usb; + +public class DispatchException extends Exception{ + + public DispatchException(String string) { + super(string); + } + + /** + * + */ + private static final long serialVersionUID = -3507511795478700742L; + +} diff --git a/mcdp/src/ch/ntb/mcdp/usb/USBDevice.java b/mcdp/src/ch/ntb/mcdp/usb/USBDevice.java new file mode 100644 index 0000000..3f77e2b --- /dev/null +++ b/mcdp/src/ch/ntb/mcdp/usb/USBDevice.java @@ -0,0 +1,57 @@ +package ch.ntb.mcdp.usb; + +import ch.ntb.usb.USB; +import ch.ntb.usb.USBException; + +public class USBDevice { + + private final static short IdVendor = (short) 0x8235; + + private final static short IdProduct = 0x0100; + + private final static int Configuration = 1; + + private final static int Interface = 0; + + private final static int Altinterface = 0; + + private static final int OUT_Endpoint = 0x02; + + private static final int IN_Endpoint = 0x86; + + private static final int Timeout = 2000; + + static { + // set data for our device + USB.setIdVendor(IdVendor); + USB.setIdProduct(IdProduct); + USB.setConfiguration(Configuration); + USB.setInterface(Interface); + USB.setAltinterface(Altinterface); + USB.setOUT_Endpoint(OUT_Endpoint); + USB.setIN_Endpoint(IN_Endpoint); + USB.setTimeout(Timeout); + // reset USB + USB.reset(); + } + + public static void open() throws USBException { + USB.openUsbDevice(); + } + + public static void close() throws USBException { + USB.closeUsbDevice(); + } + + public static void reset() throws USBException { + USB.resetUsbDevie(); + } + + public static void write(byte[] data, int length) throws USBException { + USB.write(data, length); + } + + public static synchronized int read(byte[] data, int size) throws USBException { + return USB.read(data, size); + } +} diff --git a/mcdp/src/ch/ntb/usb/LibusbWin.java b/mcdp/src/ch/ntb/usb/LibusbWin.java new file mode 100644 index 0000000..8b20ab2 --- /dev/null +++ b/mcdp/src/ch/ntb/usb/LibusbWin.java @@ -0,0 +1,296 @@ +package ch.ntb.usb; + +public class LibusbWin { + + // Core + /** + * Just like the name implies, usb_init sets up some internal + * structures. usb_init must be called before any other + * libusb functions. + */ + public static native void usb_init(); + + /** + * usb_find_busses will find all of the busses on the system. + * + * @return Returns the number of changes since previous call to this + * function (total of new busses and busses removed). + */ + public static native int usb_find_busses(); + + /** + * usb_find_devices will find all of the devices on each bus. + * This should be called after usb_find_busses. + * + * @return Returns the number of changes since the previous call to this + * function (total of new device and devices removed). + */ + public static native int usb_find_devices(); + + /** + * usb_get_busses simply returns the value of the global + * variable usb_busses. This was implemented for those languages that + * support C calling convention and can use shared libraries, but don't + * support C global variables (like Delphi). + * + * @return The structure of all busses and devices. Note: The java + * objects are copies of the C structs. + */ + public static native Usb_Bus usb_get_busses(); + + // Device Operations + /** + * usb_open is to be used to open up a device for use. + * usb_open must be called before attempting to perform any + * operations to the device. + * + * @param dev + * The device to open. + * @return Returns a handle used in future communication with the device. + */ + public static native int usb_open(Usb_Device dev); + + /** + * usb_close closes a device opened with + * usb_open. + * + * @param dev_handle + * The handle to the device. + * @return + */ + public static native int usb_close(int dev_handle); + + /** + * Sets the active configuration of a device + * + * @param dev_handle + * The handle to the device. + * @param configuration + * The value as specified in the descriptor field + * bConfigurationValue. + * @return 0 on success or < 0 on error. + */ + public static native int usb_set_configuration(int dev_handle, + int configuration); + + /** + * Sets the active alternate setting of the current interface + * + * @param dev_handle + * The handle to the device. + * @param alternate + * The value as specified in the descriptor field + * bAlternateSetting. + * @return 0 on success or < 0 on error. + */ + public static native int usb_set_altinterface(int dev_handle, int alternate); + + /** + * Clears any halt status on an endpoint. + * + * @param dev_handle + * The handle to the device. + * @param ep + * The value specified in the descriptor field bEndpointAddress. + * @return 0 on success or < 0 on error. + */ + public static native int usb_clear_halt(int dev_handle, int ep); + + /** + * Resets a device by sending a RESET down the port it is connected to.
+ *
+ * Causes re-enumeration: After calling usb_reset, + * the device will need to re-enumerate and thusly, requires you to find the + * new device and open a new handle. The handle used to call + * usb_reset will no longer work. + * + * @param dev_handle + * The handle to the device. + * @return Returns 0 on success or < 0 on error. + */ + public static native int usb_reset(int dev_handle); + + /** + * Claim an interface of a device.
+ *
+ * Must be called!: usb_claim_interface must be + * called before you perform any operations related to this interface (like + * usb_set_altinterface, usb_bulk_write, etc). + * + * @param dev_handle + * The handle to the device. + * @param interface_ + * The value as specified in the descriptor field + * bInterfaceNumber. + * @return 0 on success or < 0 on error. + */ + public static native int usb_claim_interface(int dev_handle, int interface_); + + /** + * Releases a previously claimed interface + * + * @param dev_handle + * The handle to the device. + * @param interface_ + * The value as specified in the descriptor field + * bInterfaceNumber. + * @return 0 on success or < 0 on error. + */ + public static native int usb_release_interface(int dev_handle, + int interface_); + + // Control Transfers + /** + * Performs a control request to the default control pipe on a device. The + * parameters mirror the types of the same name in the USB specification. + * + * @param dev_handle + * The handle to the device. + * @param requesttype + * @param request + * @param value + * @param index + * @param bytes + * @param size + * @param timeout + * @return number of bytes written/read or < 0 on error. + */ + public static native int usb_control_msg(int dev_handle, int requesttype, + int request, int value, int index, byte[] bytes, int size, + int timeout); + + /** + * Retrieves the string descriptor specified by index and langid from a + * device. + * + * @param dev_handle + * The handle to the device. + * @param index + * @param langid + * @param buf + * @param buflen + * @return number of bytes returned in buf or < 0 on error. + */ + public static native int usb_get_string(int dev_handle, int index, + int langid, String buf, int buflen); + + /** + * usb_get_string_simple is a wrapper around + * usb_get_string that retrieves the string description + * specified by index in the first language for the descriptor. + * + * @param dev_handle + * The handle to the device. + * @param index + * @param buf + * @param buflen + * @return number of bytes returned in buf or < 0 on error. + */ + public static native int usb_get_string_simple(int dev_handle, int index, + String buf, int buflen); + + /** + * Retrieves a descriptor from the device identified by the type and index + * of the descriptor from the default control pipe.
+ *
+ * See usb_get_descriptor_by_endpoint for a function that + * allows the control endpoint to be specified. + * + * @param dev_handle + * The handle to the device. + * @param type + * @param index + * @param buf + * @param size + * @return number of bytes read for the descriptor or < 0 on error. + */ + public static native int usb_get_descriptor(int dev_handle, byte type, + byte index, String buf, int size); + + /** + * Retrieves a descriptor from the device identified by the type and index + * of the descriptor from the control pipe identified by ep. + * + * @param dev_handle + * The handle to the device. + * @param ep + * @param type + * @param index + * @param buf + * @param size + * @return number of bytes read for the descriptor or < 0 on error. + */ + public static native int usb_get_descriptor_by_endpoint(int dev_handle, + int ep, byte type, byte index, String buf, int size); + + // Bulk Transfers + /** + * Performs a bulk write request to the endpoint specified by ep. + * + * @param dev_handle + * The handle to the device. + * @param ep + * @param bytes + * @param size + * @param timeout + * @return number of bytes written on success or < 0 on error. + */ + public static native int usb_bulk_write(int dev_handle, int ep, + byte[] bytes, int size, int timeout); + + /** + * Performs a bulk read request to the endpoint specified by ep. + * + * @param dev_handle + * The handle to the device. + * @param ep + * @param bytes + * @param size + * @param timeout + * @return number of bytes read on success or < 0 on error. + */ + public static native int usb_bulk_read(int dev_handle, int ep, + byte[] bytes, int size, int timeout); + + // Interrupt Transfers + /** + * Performs an interrupt write request to the endpoint specified by ep. + * + * @param dev_handle + * The handle to the device. + * @param ep + * @param bytes + * @param size + * @param timeout + * @return number of bytes written on success or < 0 on error. + */ + public static native int usb_interrupt_write(int dev_handle, int ep, + byte[] bytes, int size, int timeout); + + /** + * Performs a interrupt read request to the endpoint specified by ep. + * + * @param dev_handle + * The handle to the device. + * @param ep + * @param bytes + * @param size + * @param timeout + * @return number of bytes read on success or < 0 on error. + */ + public static native int usb_interrupt_read(int dev_handle, int ep, + byte[] bytes, int size, int timeout); + + /** + * Returns the error string after an error occured. + * + * @return error sring. + */ + public static native String usb_strerror(); + + /*******************************************************************/ + + static { + System.loadLibrary("LibusbWin"); + } +} \ No newline at end of file diff --git a/mcdp/src/ch/ntb/usb/USB.java b/mcdp/src/ch/ntb/usb/USB.java new file mode 100644 index 0000000..bc1d8eb --- /dev/null +++ b/mcdp/src/ch/ntb/usb/USB.java @@ -0,0 +1,264 @@ +package ch.ntb.usb; + +import ch.ntb.usb.LibusbWin; +import ch.ntb.usb.Usb_Bus; +import ch.ntb.usb.Usb_Device; +import ch.ntb.usb.Usb_Device_Descriptor; + +public class USB { + + public static final int MAX_DATA_SIZE = 512; + + private static final int TIMEOUT_ERROR_CODE = -116; + + private static final boolean DEBUG_ON = false; + + private static Usb_Bus bus; + + private static int usb_dev_handle = 0; + + private static short IdVendor = -1; + + private static short IdProduct = -1; + + private static int Timeout = 3000; + + private static int Configuration = -1; + + private static int Interface = -1; + + private static int Altinterface = -1; + + private static int OUT_Endpoint = -1; + + private static int IN_Endpoint = -1; + + public static void reset() { + bus = null; + usb_dev_handle = 0; + + if (DEBUG_ON) { + System.out.println("reset done"); + } + } + + public static void openUsbDevice() throws USBException { + + int res; + + // open bus + if (bus == null) { + LibusbWin.usb_init(); + LibusbWin.usb_find_busses(); + LibusbWin.usb_find_devices(); + + bus = LibusbWin.usb_get_busses(); + if (bus == null) { + throw new USBException("LibusbWin.usb_get_busses(): " + + LibusbWin.usb_strerror()); + } + } + // search for device + if (usb_dev_handle <= 0) { + + while (bus != null) { + Usb_Device dev = bus.devices; + while (dev != null) { + // Usb_Device_Descriptor + Usb_Device_Descriptor defDesc = dev.descriptor; + if ((defDesc.idVendor == IdVendor) + && (defDesc.idProduct == IdProduct)) { + if (DEBUG_ON) { + System.out.println("Open device: " + dev.filename); + } + res = LibusbWin.usb_open(dev); + if (res <= 0) { + throw new USBException("LibusbWin.usb_open: " + + LibusbWin.usb_strerror()); + } else { + usb_dev_handle = res; + } + } + dev = dev.next; + } + bus = bus.next; + } + if (usb_dev_handle <= 0) { + throw new USBException("UsbDevice with idVendor " + IdVendor + + " and idProduct " + IdProduct + " not found"); + } + } + claim_interface(usb_dev_handle, Configuration, Interface, Altinterface); + + if (DEBUG_ON) { + System.out.println("device opened, interface claimed"); + } + } + + public static void closeUsbDevice() throws USBException { + release_interface(usb_dev_handle, Interface); + if (LibusbWin.usb_close(usb_dev_handle) < 0) { + throw new USBException("LibusbWin.usb_close: " + + LibusbWin.usb_strerror()); + } + + if (DEBUG_ON) { + System.out.println("device closed"); + } + } + + public static void resetUsbDevie() throws USBException { + if (LibusbWin.usb_reset(usb_dev_handle) < 0) { + throw new USBException("LibusbWin.usb_reset: " + + LibusbWin.usb_strerror()); + } + + if (DEBUG_ON) { + System.out.println("resetUsbDevie done"); + } + } + + public static void write(byte[] data, int length) throws USBException { + if (data == null) { + throw new USBException("data must not be null"); + } + if (length <= 0) { + throw new USBException("size must be > 0"); + } + int lenWritten = LibusbWin.usb_bulk_write(usb_dev_handle, OUT_Endpoint, + data, length, Timeout); + if (lenWritten < 0) { + if (lenWritten == TIMEOUT_ERROR_CODE) { + throw new USBTimeoutException("LibusbWin.usb_bulk_write: " + + LibusbWin.usb_strerror()); + } + throw new USBException("LibusbWin.usb_bulk_write: " + + LibusbWin.usb_strerror()); + } + + if (DEBUG_ON) { + System.out.print("write_bulkdata: " + lenWritten + " Bytes sent: "); + for (int i = 0; i < lenWritten; i++) { + System.out.print("0x" + String.format("%1$02X", data[i]) + " "); + } + System.out.println(); + } + } + + public static int read(byte[] data, int size) throws USBException { + if (data == null) { + throw new USBException("data must not be null"); + } + if (size <= 0) { + throw new USBException("size must be > 0"); + } + int lenRead = LibusbWin.usb_bulk_read(usb_dev_handle, IN_Endpoint, + data, size, Timeout); + if (lenRead < 0) { + if (lenRead == TIMEOUT_ERROR_CODE) { + throw new USBTimeoutException("LibusbWin.usb_bulk_read: " + + LibusbWin.usb_strerror()); + } + throw new USBException("LibusbWin.usb_bulk_read: " + + LibusbWin.usb_strerror()); + } + + if (DEBUG_ON) { + System.out.print("read_bulkdata: " + lenRead + " Bytes received: "); + System.out.print("Data: "); + for (int i = 0; i < lenRead; i++) { + System.out.print("0x" + String.format("%1$02X", data[i]) + " "); + } + System.out.println(); + } + return lenRead; + } + + private static void claim_interface(int dev_handle, int configuration, + int interface_, int altinterface) throws USBException { + if (LibusbWin.usb_set_configuration(usb_dev_handle, configuration) < 0) { + throw new USBException("LibusbWin.usb_set_configuration: " + + LibusbWin.usb_strerror()); + } + if (LibusbWin.usb_claim_interface(dev_handle, interface_) < 0) { + throw new USBException("LibusbWin.usb_claim_interface: " + + LibusbWin.usb_strerror()); + } + if (LibusbWin.usb_set_altinterface(dev_handle, altinterface) < 0) { + throw new USBException("LibusbWin.usb_set_altinterface: " + + LibusbWin.usb_strerror()); + } + } + + private static void release_interface(int dev_handle, int interface_) + throws USBException { + if (LibusbWin.usb_release_interface(dev_handle, interface_) < 0) { + throw new USBException("LibusbWin.usb_release_interface: " + + LibusbWin.usb_strerror()); + } + } + + public static short getIdProduct() { + return IdProduct; + } + + public static void setIdProduct(short idProduct) { + IdProduct = idProduct; + } + + public static short getIdVendor() { + return IdVendor; + } + + public static void setIdVendor(short idVendor) { + IdVendor = idVendor; + } + + public static int getConfiguration() { + return Configuration; + } + + public static void setConfiguration(int configuration) { + Configuration = configuration; + } + + public static int getIN_Endpoint() { + return IN_Endpoint; + } + + public static void setIN_Endpoint(int in_endpoint) { + IN_Endpoint = in_endpoint; + } + + public static int getInterface() { + return Interface; + } + + public static void setInterface(int interface_) { + Interface = interface_; + } + + public static int getOUT_Endpoint() { + return OUT_Endpoint; + } + + public static void setOUT_Endpoint(int out_endpoint) { + OUT_Endpoint = out_endpoint; + } + + public static int getTimeout() { + return Timeout; + } + + public static void setTimeout(int timeout) { + Timeout = timeout; + } + + public static int getAltinterface() { + return Altinterface; + } + + public static void setAltinterface(int altinterface) { + Altinterface = altinterface; + } +} diff --git a/mcdp/src/ch/ntb/usb/USBException.java b/mcdp/src/ch/ntb/usb/USBException.java new file mode 100644 index 0000000..4c19e14 --- /dev/null +++ b/mcdp/src/ch/ntb/usb/USBException.java @@ -0,0 +1,18 @@ +package ch.ntb.usb; + +public class USBException extends Exception{ + + public class USBTimeoutException { + + } + + public USBException(String string) { + super(string); + } + + /** + * + */ + private static final long serialVersionUID = 1690857437804284710L; + +} diff --git a/mcdp/src/ch/ntb/usb/USBTimeoutException.java b/mcdp/src/ch/ntb/usb/USBTimeoutException.java new file mode 100644 index 0000000..db0c81d --- /dev/null +++ b/mcdp/src/ch/ntb/usb/USBTimeoutException.java @@ -0,0 +1,14 @@ +package ch.ntb.usb; + +public class USBTimeoutException extends USBException { + + public USBTimeoutException(String string) { + super(string); + } + + /** + * + */ + private static final long serialVersionUID = -1065328371159778249L; + +} diff --git a/mcdp/src/ch/ntb/usb/Usb_Bus.java b/mcdp/src/ch/ntb/usb/Usb_Bus.java new file mode 100644 index 0000000..4dbbcf0 --- /dev/null +++ b/mcdp/src/ch/ntb/usb/Usb_Bus.java @@ -0,0 +1,23 @@ +package ch.ntb.usb; + +public class Usb_Bus { + + public Usb_Bus next, prev; + + public String dirname; + + public Usb_Device devices; + + public long location; + + public Usb_Device root_dev; + + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("** Usb_Bus **\n"); + sb.append("\tdirname: " + dirname + "\n"); + sb.append("\tlocation: " + location + "\n"); + return sb.toString(); + } + +} \ No newline at end of file diff --git a/mcdp/src/ch/ntb/usb/Usb_Config_Descriptor.java b/mcdp/src/ch/ntb/usb/Usb_Config_Descriptor.java new file mode 100644 index 0000000..ebe75ca --- /dev/null +++ b/mcdp/src/ch/ntb/usb/Usb_Config_Descriptor.java @@ -0,0 +1,40 @@ +package ch.ntb.usb; + +public class Usb_Config_Descriptor { + public byte bLength; + + public byte bDescriptorType; + + public short wTotalLength; + + public byte bNumInterfaces; + + public byte bConfigurationValue; + + public byte iConfiguration; + + public byte bmAttributes; + + public byte MaxPower; + + public Usb_Interface []interface_; + + // TODO: Extra descriptors are not interpreted because of their unknown structure + public Usb_Config_Descriptor extra; /* Extra descriptors */ + + public int extralen; + + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("** Usb_Config_Descriptor **\n"); + sb.append("\tblenght: " + bLength + "\n"); + sb.append("\tbDescriptorType: " + bDescriptorType + "\n"); + sb.append("\tbNumInterfaces: " + bNumInterfaces + "\n"); + sb.append("\tbConfigurationValue: " + bConfigurationValue + "\n"); + sb.append("\tiConfiguration: " + iConfiguration + "\n"); + sb.append("\tbmAttributes: " + bmAttributes + "\n"); + sb.append("\tMaxPower: " + MaxPower + "\n"); + return sb.toString(); + } + +} \ No newline at end of file diff --git a/mcdp/src/ch/ntb/usb/Usb_Device.java b/mcdp/src/ch/ntb/usb/Usb_Device.java new file mode 100644 index 0000000..f0771b5 --- /dev/null +++ b/mcdp/src/ch/ntb/usb/Usb_Device.java @@ -0,0 +1,29 @@ +package ch.ntb.usb; + +public class Usb_Device { + public Usb_Device next, prev; + + public String filename; + + public Usb_Bus bus; + + public Usb_Device_Descriptor descriptor; + + public Usb_Config_Descriptor[] config; + + public byte devnum; + + public byte num_children; + + public Usb_Device children; + + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("** Usb_Device **\n"); + sb.append("\tfilename: " + filename + "\n"); + sb.append("\tdevnum: " + devnum + "\n"); + sb.append("\tnum_children: " + num_children + "\n"); + return sb.toString(); + } + +} \ No newline at end of file diff --git a/mcdp/src/ch/ntb/usb/Usb_Device_Descriptor.java b/mcdp/src/ch/ntb/usb/Usb_Device_Descriptor.java new file mode 100644 index 0000000..45b81b4 --- /dev/null +++ b/mcdp/src/ch/ntb/usb/Usb_Device_Descriptor.java @@ -0,0 +1,52 @@ +package ch.ntb.usb; + +public class Usb_Device_Descriptor { + public byte bLength; + + public byte bDescriptorType; + + public short bcdUSB; + + public byte bDeviceClass; + + public byte bDeviceSubClass; + + public byte bDeviceProtocol; + + public byte bMaxPacketSize0; + + public short idVendor; + + public short idProduct; + + public short bcdDevice; + + public byte iManufacturer; + + public byte iProduct; + + public byte iSerialNumber; + + public byte bNumConfigurations; + + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("** Usb_Device_Descriptor **\n"); + sb.append("\tblenght: " + bLength + "\n"); + sb.append("\tbDescriptorType: " + bDescriptorType + "\n"); + sb.append("\tbcdUSB: " + bcdUSB + "\n"); + sb.append("\tbDeviceClass: " + bDeviceClass + "\n"); + sb.append("\tbDeviceSubClass: " + bDeviceSubClass + "\n"); + sb.append("\tbDeviceProtocol: " + bDeviceProtocol + "\n"); + sb.append("\tbMaxPacketSize0: " + bMaxPacketSize0 + "\n"); + sb.append("\tidVendor: " + idVendor + "\n"); + sb.append("\tidProduct: " + idProduct + "\n"); + sb.append("\tbcdDevice: " + bcdDevice + "\n"); + sb.append("\tiManufacturer: " + iManufacturer + "\n"); + sb.append("\tiProduct: " + iProduct + "\n"); + sb.append("\tiSerialNumber: " + iSerialNumber + "\n"); + sb.append("\tbNumConfigurations: " + bNumConfigurations + "\n"); + return sb.toString(); + } + +}; \ No newline at end of file diff --git a/mcdp/src/ch/ntb/usb/Usb_Endpoint_Descriptor.java b/mcdp/src/ch/ntb/usb/Usb_Endpoint_Descriptor.java new file mode 100644 index 0000000..2ab7306 --- /dev/null +++ b/mcdp/src/ch/ntb/usb/Usb_Endpoint_Descriptor.java @@ -0,0 +1,38 @@ +package ch.ntb.usb; + +public class Usb_Endpoint_Descriptor { + public byte bLength; + + public byte bDescriptorType; + + public byte bEndpointAddress; + + public byte bmAttributes; + + public short wMaxPacketSize; + + public byte bInterval; + + public byte bRefresh; + + public byte bSynchAddress; + + // TODO: Extra descriptors are not interpreted because of their unknown structure + public Usb_Endpoint_Descriptor extra; /* Extra descriptors */ + + public int extralen; + + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("**Usb_Endpoint_Descriptor**\n"); + sb.append("\tblenght: " + bLength + "\n"); + sb.append("\tbDescriptorType: " + bDescriptorType + "\n"); + sb.append("\tbEndpointAddress: " + bEndpointAddress + "\n"); + sb.append("\tbmAttributes: " + bmAttributes + "\n"); + sb.append("\twMaxPacketSize: " + wMaxPacketSize + "\n"); + sb.append("\tbInterval: " + bInterval + "\n"); + sb.append("\tbRefresh: " + bRefresh + "\n"); + sb.append("\tbSynchAddress: " + bSynchAddress + "\n"); + return sb.toString(); + } +} diff --git a/mcdp/src/ch/ntb/usb/Usb_Interface.java b/mcdp/src/ch/ntb/usb/Usb_Interface.java new file mode 100644 index 0000000..ed80163 --- /dev/null +++ b/mcdp/src/ch/ntb/usb/Usb_Interface.java @@ -0,0 +1,15 @@ +package ch.ntb.usb; + +public class Usb_Interface { + public Usb_Interface_Descriptor[] altsetting; + + public int num_altsetting; + + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("** Usb_Interface **\n"); + sb.append("\tnum_altsetting: " + num_altsetting + "\n"); + return sb.toString(); + } + +} diff --git a/mcdp/src/ch/ntb/usb/Usb_Interface_Descriptor.java b/mcdp/src/ch/ntb/usb/Usb_Interface_Descriptor.java new file mode 100644 index 0000000..354fcd6 --- /dev/null +++ b/mcdp/src/ch/ntb/usb/Usb_Interface_Descriptor.java @@ -0,0 +1,43 @@ +package ch.ntb.usb; + +public class Usb_Interface_Descriptor { + public byte bLength; + + public byte bDescriptorType; + + public byte bInterfaceNumber; + + public byte bAlternateSetting; + + public byte bNumEndpoints; + + public byte bInterfaceClass; + + public byte bInterfaceSubClass; + + public byte bInterfaceProtocol; + + public byte iInterface; + + public Usb_Endpoint_Descriptor[] endpoint; + + // TODO: Extra descriptors are not interpreted because of their unknown structure + public Usb_Interface_Descriptor extra; /* Extra descriptors */ + + public int extralen; + + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("** Usb_Interface_Descriptor **\n"); + sb.append("\tblenght: " + bLength + "\n"); + sb.append("\tbDescriptorType: " + bDescriptorType + "\n"); + sb.append("\tbInterfaceNumber: " + bInterfaceNumber + "\n"); + sb.append("\tbAlternateSetting: " + bAlternateSetting + "\n"); + sb.append("\tbNumEndpoints: " + bNumEndpoints + "\n"); + sb.append("\tbInterfaceClass: " + bInterfaceClass + "\n"); + sb.append("\tbInterfaceSubClass: " + bInterfaceSubClass + "\n"); + sb.append("\tbInterfaceProtocol: " + bInterfaceProtocol + "\n"); + sb.append("\tiInterface: " + iInterface + "\n"); + return sb.toString(); + } +} diff --git a/mcdp/src/ch/ntb/usb/Utils.java b/mcdp/src/ch/ntb/usb/Utils.java new file mode 100644 index 0000000..b2d6edb --- /dev/null +++ b/mcdp/src/ch/ntb/usb/Utils.java @@ -0,0 +1,66 @@ +package ch.ntb.usb; + +public class Utils { + + public static void logUsb(Usb_Bus bus) { + while (bus != null) { + System.out.println(bus.toString()); + Usb_Device dev = bus.devices; + while (dev != null) { + System.out.println("\t" + dev.toString()); + // Usb_Device_Descriptor + Usb_Device_Descriptor defDesc = dev.descriptor; + System.out.println("\t" + defDesc.toString()); + // Usb_Config_Descriptor + Usb_Config_Descriptor[] confDesc = dev.config; + for (int i = 0; i < confDesc.length; i++) { + System.out.println("\t" + confDesc[i].toString()); + Usb_Interface[] int_ = confDesc[i].interface_; + if (int_ != null) { + for (int j = 0; j < int_.length; j++) { + System.out.println("\t" + int_[j].toString()); + Usb_Interface_Descriptor[] intDesc = int_[j].altsetting; + if (intDesc != null) { + for (int k = 0; k < intDesc.length; k++) { + System.out.println("\t" + + intDesc[k].toString()); + Usb_Endpoint_Descriptor[] epDesc = intDesc[k].endpoint; + if (epDesc != null) { + for (int e = 0; e < epDesc.length; e++) { + System.out.println("\t" + + epDesc[e].toString()); + } + } + } + } + } + } + } + dev = dev.next; + } + bus = bus.next; + } + } + + public static int openUsb_Device(Usb_Bus bus, short idVendor, short idProduct) { + int handle = -1; + + while (bus != null) { + Usb_Device dev = bus.devices; + while (dev != null) { + // Usb_Device_Descriptor + Usb_Device_Descriptor defDesc = dev.descriptor; + if ((defDesc.idVendor == idVendor) + && (defDesc.idProduct == idProduct)) { + System.out.println("Open device: " + dev.filename); + return LibusbWin.usb_open(dev); + } + dev = dev.next; + } + bus = bus.next; + } + + return handle; + } + +} diff --git a/mcdp/src/ch/ntb/usb/test/TestApp.java b/mcdp/src/ch/ntb/usb/test/TestApp.java new file mode 100644 index 0000000..424fe52 --- /dev/null +++ b/mcdp/src/ch/ntb/usb/test/TestApp.java @@ -0,0 +1,395 @@ +package ch.ntb.usb.test; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.RowData; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; + +public class TestApp { + + private static final int HEX_WIDTH = 5; + private Shell rootShell = null; // @jve:decl-index=0:visual-constraint="10,10" + private Group vendorIDGroup = null; + private Text vendorID = null; + private Group productIDGroup = null; + private Text productID = null; + private Group configGroup = null; + private Text configuration = null; + private Group interfaceGroup = null; + private Text interface_ = null; + private Group altIntGroup = null; + private Text altInt = null; + private Group deviceGroup = null; + private Group endpointGroup = null; + private Group deviceGroup2 = null; + private Group outEPGroup = null; + private Text outEP = null; + private Group inEPGroup = null; + private Text inEP = null; + private Group timeoutGroup = null; + private Text timeout = null; + private Group dataGroup = null; + private Composite dataButtonComp = null; + private Button sendButton = null; + private Button recButton = null; + private Composite devComp = null; + private Composite devButtonComp = null; + private Button devOpenButton = null; + private Button devCloseButton = null; + private Group dataFieldGoup = null; + private Text dataField = null; + private Button resetButton = null; + /** + * This method initializes sShell + */ + private int parseInt(String s){ + if (s == "") return 0; + if (s.indexOf('x') > 0) { + // is hex number + if (s.length() <= 2){ // exception for "0x" + return 0; + } + return Integer.parseInt(s.substring(s.indexOf('x') + 1, s.length()), 16); + } else { + // is decimal number + return Integer.parseInt(s); + } + } + + private byte[] parseByteArray(String s){ + StringBuffer sb = new StringBuffer(); + int stringIndex = 0, spaceIndex = 0; + String ss; + while (stringIndex + 3 < s.length()){ + ss = s.substring(spaceIndex, spaceIndex + 4); + spaceIndex = s.indexOf(' ', stringIndex) + 1; + sb.append((char) parseInt(ss)); + stringIndex += HEX_WIDTH; + } + return sb.toString().getBytes(); + } + + private void createSShell() { + RowLayout rowLayout = new RowLayout(); + rowLayout.type = org.eclipse.swt.SWT.VERTICAL; + rowLayout.justify = true; + rowLayout.fill = true; + rootShell = new Shell(); + rootShell.setText("Usb TestApplication"); + rootShell.setLayout(rowLayout); + createDeviceGroup(); + createDataGroup(); + rootShell.setSize(new org.eclipse.swt.graphics.Point(466,315)); + } + + /** + * This method initializes vendorIDGroup + * + */ + private void createVendorIDGroup() { + vendorIDGroup = new Group(deviceGroup2, SWT.NONE); + vendorIDGroup.setText("VendorID"); + vendorID = new Text(vendorIDGroup, SWT.BORDER | SWT.RIGHT); + vendorID.setBounds(new org.eclipse.swt.graphics.Rectangle(7,23,76,19)); + vendorID.setText("0x8235"); + TestAppUsb.IdVendor = (short) parseInt(vendorID.getText()); + vendorID.addModifyListener(new org.eclipse.swt.events.ModifyListener() { + public void modifyText(org.eclipse.swt.events.ModifyEvent e) { + TestAppUsb.IdVendor = (short) parseInt(vendorID.getText()); + } + }); + } + + /** + * This method initializes productIDGroup + * + */ + private void createProductIDGroup() { + productIDGroup = new Group(deviceGroup2, SWT.NONE); + productIDGroup.setText("ProductID"); + productID = new Text(productIDGroup, SWT.BORDER | SWT.RIGHT); + productID.setBounds(new org.eclipse.swt.graphics.Rectangle(4,24,76,19)); + productID.setText("0x0100"); + TestAppUsb.IdProduct = (short) parseInt(productID.getText()); + productID.addModifyListener(new org.eclipse.swt.events.ModifyListener() { + public void modifyText(org.eclipse.swt.events.ModifyEvent e) { + TestAppUsb.IdProduct = (short) parseInt(productID.getText()); + } + }); + } + + /** + * This method initializes group + * + */ + private void createGroup() { + configGroup = new Group(deviceGroup2, SWT.NONE); + configGroup.setText("Configuration"); + configuration = new Text(configGroup, SWT.BORDER | SWT.RIGHT); + configuration.setBounds(new org.eclipse.swt.graphics.Rectangle(4,24,75,19)); + configuration.setText("1"); + configuration.addModifyListener(new org.eclipse.swt.events.ModifyListener() { + public void modifyText(org.eclipse.swt.events.ModifyEvent e) { + TestAppUsb.CONFIGURATION = parseInt(configuration.getText()); + } + }); + } + + /** + * This method initializes group + * + */ + private void createGroup2() { + interfaceGroup = new Group(deviceGroup2, SWT.NONE); + interfaceGroup.setText("Interface"); + interface_ = new Text(interfaceGroup, SWT.BORDER | SWT.RIGHT); + interface_.setBounds(new org.eclipse.swt.graphics.Rectangle(4,24,57,19)); + interface_.setText("0"); + interface_.addModifyListener(new org.eclipse.swt.events.ModifyListener() { + public void modifyText(org.eclipse.swt.events.ModifyEvent e) { + TestAppUsb.INTERFACE = parseInt(interface_.getText()); + } + }); + } + + /** + * This method initializes group + * + */ + private void createGroup3() { + altIntGroup = new Group(deviceGroup2, SWT.NONE); + altIntGroup.setText("Alternative Int"); + altInt = new Text(altIntGroup, SWT.BORDER | SWT.RIGHT); + altInt.setBounds(new Rectangle(4, 24, 76, 19)); + altInt.setText("0"); + altInt.addModifyListener(new org.eclipse.swt.events.ModifyListener() { + public void modifyText(org.eclipse.swt.events.ModifyEvent e) { + TestAppUsb.ALTINTERFACE = parseInt(altInt.getText()); + } + }); + } + + /** + * This method initializes deviceGroup + * + */ + private void createDeviceGroup() { + RowLayout rowLayout1 = new RowLayout(); + rowLayout1.type = org.eclipse.swt.SWT.VERTICAL; + rowLayout1.fill = true; + deviceGroup = new Group(rootShell, SWT.NONE); + deviceGroup.setText("Device Settings"); + createDeviceGroup2(); + deviceGroup.setLayout(rowLayout1); + createDevComp(); + } + + /** + * This method initializes endpointGroup + * + */ + private void createEndpointGroup() { + endpointGroup = new Group(devComp, SWT.NONE); + endpointGroup.setLayout(new RowLayout()); + createGroup4(); + createGroup5(); + createGroup6(); + } + + /** + * This method initializes deviceGroup2 + * + */ + private void createDeviceGroup2() { + deviceGroup2 = new Group(deviceGroup, SWT.NONE); + deviceGroup2.setLayout(new RowLayout()); + createVendorIDGroup(); + createProductIDGroup(); + createGroup(); + createGroup2(); + createGroup3(); + } + + /** + * This method initializes group + * + */ + private void createGroup4() { + outEPGroup = new Group(endpointGroup, SWT.NONE); + outEPGroup.setText("OUT EP"); + outEP = new Text(outEPGroup, SWT.BORDER | SWT.RIGHT); + outEP.setBounds(new org.eclipse.swt.graphics.Rectangle(4,24,46,19)); + outEP.setText("0x02"); + outEP.addModifyListener(new org.eclipse.swt.events.ModifyListener() { + public void modifyText(org.eclipse.swt.events.ModifyEvent e) { + TestAppUsb.OUT_ENDPOINT = parseInt(outEP.getText()); + } + }); + } + + /** + * This method initializes group + * + */ + private void createGroup5() { + inEPGroup = new Group(endpointGroup, SWT.NONE); + inEPGroup.setText("IN EP"); + inEP = new Text(inEPGroup, SWT.BORDER | SWT.RIGHT); + inEP.setBounds(new org.eclipse.swt.graphics.Rectangle(4,24,46,19)); + inEP.setText("0x86"); + inEP.addModifyListener(new org.eclipse.swt.events.ModifyListener() { + public void modifyText(org.eclipse.swt.events.ModifyEvent e) { + TestAppUsb.IN_ENDPOINT = parseInt(inEP.getText()); + } + }); + } + + /** + * This method initializes group + * + */ + private void createGroup6() { + timeoutGroup = new Group(endpointGroup, SWT.NONE); + timeoutGroup.setText("Timeout"); + timeout = new Text(timeoutGroup, SWT.BORDER | SWT.RIGHT); + timeout.setBounds(new Rectangle(4, 24, 46, 19)); + timeout.setText("2000"); + timeout.addModifyListener(new org.eclipse.swt.events.ModifyListener() { + public void modifyText(org.eclipse.swt.events.ModifyEvent e) { + TestAppUsb.TIMEOUT = parseInt(timeout.getText()); + } + }); + } + + /** + * This method initializes dataGroup + * + */ + private void createDataGroup() { + RowLayout rowLayout5 = new RowLayout(); + rowLayout5.type = org.eclipse.swt.SWT.HORIZONTAL; + rowLayout5.spacing = 10; + dataGroup = new Group(rootShell, SWT.NONE); + dataGroup.setText("Send and Receive Data"); + dataGroup.setLayout(rowLayout5); + createDataFieldGoup(); + createButtonComp(); + } + + /** + * This method initializes buttonComp + * + */ + private void createButtonComp() { + RowLayout rowLayout3 = new RowLayout(); + rowLayout3.type = org.eclipse.swt.SWT.VERTICAL; + rowLayout3.justify = true; + rowLayout3.fill = true; + dataButtonComp = new Composite(dataGroup, SWT.NONE); + sendButton = new Button(dataButtonComp, SWT.NONE); + sendButton.setText("Send"); + sendButton.addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() { + public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) { + byte[] b = parseByteArray(dataField.getText()); + TestAppUsb.write(b, b.length); + } + }); + recButton = new Button(dataButtonComp, SWT.NONE); + dataButtonComp.setLayout(rowLayout3); + recButton.setText("Receive"); + recButton.addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() { + public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) { + TestAppUsb.read(); + } + }); + } + + /** + * This method initializes devComp + * + */ + private void createDevComp() { + RowLayout rowLayout4 = new RowLayout(); + rowLayout4.fill = true; + rowLayout4.spacing = 50; + devComp = new Composite(deviceGroup, SWT.NONE); + createEndpointGroup(); + devComp.setLayout(rowLayout4); + createDevButtonComp(); + } + + /** + * This method initializes devButtonComp + * + */ + private void createDevButtonComp() { + RowLayout rowLayout2 = new RowLayout(); + rowLayout2.marginHeight = 25; + rowLayout2.spacing = 5; + devButtonComp = new Composite(devComp, SWT.NONE); + devButtonComp.setLayout(rowLayout2); + devOpenButton = new Button(devButtonComp, SWT.NONE); + devOpenButton.setText("Open Device"); + devOpenButton + .addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() { + public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) { + TestAppUsb.openUsbDevice(); + } + }); + devCloseButton = new Button(devButtonComp, SWT.NONE); + devCloseButton.setText("Close Device"); + resetButton = new Button(devButtonComp, SWT.NONE); + resetButton.setText("Reset"); + resetButton.addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() { + public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) { + TestAppUsb.reset(); + } + }); + devCloseButton + .addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() { + public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) { + TestAppUsb.closeUsbDevice(); + } + }); + } + + /** + * This method initializes dataFieldGoup + * + */ + private void createDataFieldGoup() { + RowData rowData = new org.eclipse.swt.layout.RowData(); + rowData.width = 340; + RowLayout rowLayout6 = new RowLayout(); + rowLayout6.fill = true; + rowLayout6.marginHeight = 5; + rowLayout6.justify = true; + dataFieldGoup = new Group(dataGroup, SWT.NONE); + dataFieldGoup.setText("Data to send [hex]"); + dataFieldGoup.setLayout(rowLayout6); + dataField = new Text(dataFieldGoup, SWT.BORDER); + // 33 5B 02 01 00 05 01 03 07 0F 7F 1F + dataField.setText("0x5B 0x02 0x01 0x00 0x05 0x01 0x03 0x07 0x0F 0x7F 0x1F"); + dataField.setLayoutData(rowData); + } + + public static void main(String[] args) { + TestApp app = new TestApp(); + app.createSShell(); + app.rootShell.open(); + + Display display = app.rootShell.getDisplay(); + + while (!app.rootShell.isDisposed()) { + if(!display.readAndDispatch()) { + display.sleep(); + } + } + } +} diff --git a/mcdp/src/ch/ntb/usb/test/TestAppUsb.java b/mcdp/src/ch/ntb/usb/test/TestAppUsb.java new file mode 100644 index 0000000..0823911 --- /dev/null +++ b/mcdp/src/ch/ntb/usb/test/TestAppUsb.java @@ -0,0 +1,206 @@ +package ch.ntb.usb.test; + +import ch.ntb.usb.LibusbWin; +import ch.ntb.usb.Usb_Bus; +import ch.ntb.usb.Usb_Device; +import ch.ntb.usb.Usb_Device_Descriptor; + +public class TestAppUsb { + + static Usb_Bus bus; + + static int usb_dev_handle = 0; + + static short IdVendor = 0x04B4; + + static short IdProduct = (short) 0x1004; + + static int TIMEOUT = 1000; + + static int CONFIGURATION = 1; + + static int INTERFACE = 0; + + static int ALTINTERFACE = 0; + + static int OUT_ENDPOINT = 0x02; + + static int IN_ENDPOINT = 0x86; + + static final int MAX_BYTEARRAY_SIZE = 512; + + static boolean dev_opened = false; + + static void reset() { + bus = null; + usb_dev_handle = 0; + dev_opened = false; + System.out.println("reset done"); + } + + static void openUsbDevice() { + + int res; + + // open bus + if (bus == null) { + LibusbWin.usb_init(); + LibusbWin.usb_find_busses(); + LibusbWin.usb_find_devices(); + + bus = LibusbWin.usb_get_busses(); + if (bus == null) { + System.err.println("Error on LibusbWin.usb_get_busses(): " + + LibusbWin.usb_strerror()); + return; + } + } + // search for device + dev_opened = false; + if (usb_dev_handle <= 0) { + + while (bus != null) { + Usb_Device dev = bus.devices; + while (dev != null) { + // Usb_Device_Descriptor + Usb_Device_Descriptor defDesc = dev.descriptor; + if ((defDesc.idVendor == IdVendor) + && (defDesc.idProduct == IdProduct)) { + System.out.println("Open device: " + dev.filename); + res = LibusbWin.usb_open(dev); + if (res <= 0) { + System.err.println("Error on LibusbWin.usb_open: " + + LibusbWin.usb_strerror()); + return; + } else { + usb_dev_handle = res; + } + } + dev = dev.next; + } + bus = bus.next; + } + if (usb_dev_handle <= 0) { + System.out.println("UsbDevice with idVendor 0x" + + Integer.toHexString(IdVendor) + " and idProduct 0x" + + Integer.toHexString(IdProduct) + " not found"); + return; + } + } + if (!claim_interface(usb_dev_handle, CONFIGURATION, INTERFACE, + ALTINTERFACE)) { + System.err.println("Error on claim_interface"); + return; + } + dev_opened = true; + System.out.println("device opened, interface claimed"); + } + + static void closeUsbDevice() { + if (!release_interface(usb_dev_handle, INTERFACE)) { + System.err.println("Error on release_interface"); + } + int res = LibusbWin.usb_close(usb_dev_handle); + if (res < 0) { + System.err.println("Error on LibusbWin.usb_close: " + + LibusbWin.usb_strerror()); + } + dev_opened = false; + bus = null; + usb_dev_handle = -1; + System.out.println("device closed"); + } + + static void write(byte[] data, int length) { + if (!dev_opened) { + System.out.println("Open Device first"); + return; + } + int res = LibusbWin.usb_bulk_write(usb_dev_handle, OUT_ENDPOINT, data, + length, TIMEOUT); + if (res < 0) { + System.err.println("Error on LibusbWin.usb_bulk_write: " + + LibusbWin.usb_strerror()); + } + System.out.print("write_bulkdata: " + res + " Bytes sent: "); + for (int i = 0; i < res; i++) { + System.out.print("0x" + String.format("%1$02X", data[i]) + " "); + } + System.out.println(); + } + + static void read() { + if (!dev_opened) { + System.out.println("Open Device first"); + return; + } + byte[] data = new byte[MAX_BYTEARRAY_SIZE]; + int res = LibusbWin.usb_bulk_read(usb_dev_handle, IN_ENDPOINT, data, + MAX_BYTEARRAY_SIZE, TIMEOUT); + if (res < 0) { + System.err.println("Error on LibusbWin.usb_bulk_read: " + + LibusbWin.usb_strerror()); + } + System.out.print("read_bulkdata: " + res + " Bytes received: "); + System.out.print("Data: "); + for (int i = 0; i < res; i++) { + System.out.print("0x" + String.format("%1$02X", data[i]) + " "); + } + System.out.println(); + + } + + private static boolean claim_interface(int dev_handle, int configuration, + int interface_, int altinterface) { + int res = LibusbWin + .usb_set_configuration(usb_dev_handle, configuration); + if (res < 0) { + System.err.println("Error on LibusbWin.usb_set_configuration: " + + LibusbWin.usb_strerror()); + return res >= 0; + } + res = LibusbWin.usb_claim_interface(dev_handle, interface_); + if (res < 0) { + System.err.println("Error on LibusbWin.usb_claim_interface: " + + LibusbWin.usb_strerror()); + return res >= 0; + } + res = LibusbWin.usb_set_altinterface(dev_handle, altinterface); + if (res < 0) { + System.err.println("Error on LibusbWin.usb_set_altinterface: " + + LibusbWin.usb_strerror()); + } + return res >= 0; + } + + private static boolean release_interface(int dev_handle, int interface_) { + int res = LibusbWin.usb_release_interface(dev_handle, interface_); + if (res < 0) { + System.err.println("Error on LibusbWin.usb_release_interface: " + + LibusbWin.usb_strerror()); + } + return res >= 0; + } + + // private static int write_bulkdata(int dev_handle, int endpoint, + // byte[] data, int length, int timeout) { + // int res = LibusbWin.usb_bulk_write(dev_handle, endpoint, data, length, + // timeout); + // if (res < 0) { + // System.err.println("Error on LibusbWin.usb_bulk_write: " + // + LibusbWin.usb_strerror()); + // } + // return res; + // } + // + // private static int read_bulkdata(int dev_handle, int interface_, + // int altinterface, int endpoint, byte[] data, int size, int timeout) { + // int res = LibusbWin.usb_bulk_read(dev_handle, endpoint, data, size, + // timeout); + // if (res < 0) { + // System.err.println("Error on LibusbWin.usb_bulk_read: " + // + LibusbWin.usb_strerror()); + // } + // return res; + // } +} diff --git a/mcdp/src/ch/ntb/usb/test/TestUsb.java b/mcdp/src/ch/ntb/usb/test/TestUsb.java new file mode 100644 index 0000000..c7e8888 --- /dev/null +++ b/mcdp/src/ch/ntb/usb/test/TestUsb.java @@ -0,0 +1,262 @@ +package ch.ntb.usb.test; + +import java.io.IOException; + +import ch.ntb.usb.*; + +public class TestUsb { + + static Usb_Bus bus; + + static final short EZ_USB_DevKit_idVendor = 0x04B4; + + static final short EZ_USB_DevKit_idProduct = (short) 0x1004; // 0x8613; + + static final int TIMEOUT = 3000; + + static final int CONFIGURATION = 1; + + static final int INTERFACE = 0; + + static final int ALTINTERFACE = 0; // 1; + + static final int OUT_ENDPOINT = 0x02; // 0x04; + + static final int IN_ENDPOINT = 0x86; // 0x88; + + static final int MAX_BYTEARRAY_SIZE = 512; + + static final int PACKET_HEADER_1 = 0x33; // first byte of header + static final int PACKET_HEADER_2 = 0x5B; // second byte of header + static final int PACKET_END = 0x1F; // last byte of packet + static final int PACKET_DATA_OFFSET = 6; // offset to the first byte of data + static final int PACKET_MIN_LENGTH = 7; // minimal Length of a packet (no payload) + + +// Main Types + static final int MTYPE_ERROR = 0x01; // Errors before dispatching data + static final int MTYPE_BDI = 0x02; + static final int MTYPE_UART_1 = 0x03; + +// Sub Types +// ERRORS + static final int STYPE_ERROR_HEADER = 0x01; // Header of packet wrong + static final int STYPE_ERROR_PACKET_END = 0x02; // Packet end wrong + +// BDI + static final int STYPE_BDI_35IN = 0x01; // 35 Bit Packet to BDI + static final int STYPE_BDI_35OUT = 0x02; // 35 Bit Packet from BDI + static final int STYPE_BDI_10IN = 0x03; // 10 Bit Packet to BDI + static final int STYPE_BDI_10OUT = 0x04; // 10 Bit Packet from BDI + static final int STYPE_BDI_FD_DATA = 0x05; // Fast Download Data + static final int STYPE_BDI_ERROR_FD_LENGTH = 0x06; // Error if length in FD packet too small + +// UART 1 + static final int STYPE_UART_1_IN = 0x11; // Data to UART 1 + static final int STYPE_UART_1_OUT = 0x22; // Data from UART 1 + + private static void do_read(Usb_Bus bus, int dev_handle) { + byte[] data = new byte[MAX_BYTEARRAY_SIZE]; + int res = read_bulkdata(dev_handle, CONFIGURATION, INTERFACE, ALTINTERFACE, + IN_ENDPOINT, data, MAX_BYTEARRAY_SIZE, TIMEOUT); + if (res <= 0) { + System.err.println("Error on read_bulkdata " + + LibusbWin.usb_strerror()); + return; + } + System.out.println("read_bulkdata length: " + res); + System.out.print("Data: "); + for (int i = 0; i < res; i++) { + System.out.print("0x" + String.format("%1$02X", data[i]) + " "); + } + System.out.println(); + // System.out.println("Data: " + logBytesAsChars(data)); + } + + private static String logBytesAsChars(byte[] data) { + StringBuffer sb = new StringBuffer(MAX_BYTEARRAY_SIZE); + int i = 0; + while ((data[i] != 0) && (i < MAX_BYTEARRAY_SIZE)) { + sb.append((char) data[i]); + i++; + } + return sb.toString(); + } + + private static void findFirstDevice() { + // find a valid device + Usb_Device dev; + while (bus != null) { + dev = bus.devices; + while (dev != null) { + System.out.println("dev.devnum " + dev.devnum); + int dev_handle = LibusbWin.usb_open(dev); + System.out.println("dev_handle " + dev_handle); + if (dev_handle > 0) { + if (LibusbWin.usb_close(dev_handle) < 0) { + System.err + .println("error on usb.usb_close(dev_handle)"); + } + return; + } + dev = dev.next; + } + bus = bus.next; + } + } + + private static void openDevice(Usb_Bus bus) { + int handle = Utils.openUsb_Device(bus, EZ_USB_DevKit_idVendor, + EZ_USB_DevKit_idProduct); + if (handle > 0) { + System.out.println("Usb_device_handle: " + handle); + System.out.println("closed: " + LibusbWin.usb_close(handle)); + } + } + + private static int write_bulkdata(int dev_handle, int configuration, + int interface_, int altinterface, int endpoint, byte[] data, + int length, int timeout) { + int res = LibusbWin.usb_set_configuration(dev_handle, configuration); + if (res < 0) { + System.err.println("Error on usb_set_configuration: " + + LibusbWin.usb_strerror()); + return res; + } + res = LibusbWin.usb_claim_interface(dev_handle, interface_); + if (res < 0) { + System.err.println("Error on usb_claim_interface: " + + LibusbWin.usb_strerror()); + return res; + } + LibusbWin.usb_set_altinterface(dev_handle, altinterface); + res = LibusbWin.usb_bulk_write(dev_handle, endpoint, data, length, + timeout); + LibusbWin.usb_release_interface(dev_handle, interface_); + if (res <= 0) { + System.err.println("Error on usb_bulk_write: " + + LibusbWin.usb_strerror()); + } + return res; + } + + private static int read_bulkdata(int dev_handle, int configuration, + int interface_, int altinterface, int endpoint, byte[] data, + int size, int timeout) { + int res = LibusbWin.usb_set_configuration(dev_handle, configuration); + if (res < 0) { + System.err.println("Error on usb_set_configuration: " + + LibusbWin.usb_strerror()); + return res; + } + res = LibusbWin.usb_claim_interface(dev_handle, interface_); + if (res < 0) { + System.err.println("Error on read_bulkdata: " + + LibusbWin.usb_strerror()); + return res; + } + LibusbWin.usb_set_altinterface(dev_handle, altinterface); + res = LibusbWin + .usb_bulk_read(dev_handle, endpoint, data, size, timeout); + LibusbWin.usb_release_interface(dev_handle, interface_); + if (res <= 0) { + System.err.println("Error on usb_bulk_read: " + + LibusbWin.usb_strerror()); + return res; + } + return res; + } + + private static void do_write(Usb_Bus bus, int dev_handle) { + // byte[] data = new String("Data to send...").getBytes(); + byte[] data = new byte[512]; + data[0] = PACKET_HEADER_1; // header + data[1] = (byte) PACKET_HEADER_2; // header + data[2] = MTYPE_BDI; // header + data[3] = STYPE_BDI_35IN; // header + data[4] = 0x00; // length of payload + data[5] = 0x05; + data[6] = 0x01; // payload + data[7] = 0x03; + data[8] = 0x07; + data[9] = 0x0F; + data[10] = 0x7F; + data[11] = (byte) PACKET_END; // packet end + int length = 12; + + int res = write_bulkdata(dev_handle, CONFIGURATION, INTERFACE, ALTINTERFACE, + OUT_ENDPOINT, data, length, TIMEOUT); + if ( res <= 0) { + System.err.println("Error on write_bulkdata"); + return; + } + System.out.print(res + " Bytes sent: "); + for (int i = 0; i < res; i++) { + System.out.print("0x" + String.format("%1$02X", data[i]) + " "); + } + System.out.println(); + + System.out.println("write_bulkdata done"); + } + + private static String logBytes(byte[] data) { + StringBuffer sb = new StringBuffer(MAX_BYTEARRAY_SIZE); + for (int i = 0; i < data.length; i++) { + sb.append(data[i]); + sb.append(" "); + } + return sb.toString(); + } + + private static void do_write_read(Usb_Bus bus) { + int dev_handle = Utils.openUsb_Device(bus, EZ_USB_DevKit_idVendor, + EZ_USB_DevKit_idProduct); + if (dev_handle <= 0) { + System.err.println("Error on openUsb_Device: " + dev_handle); + return; + } + boolean run = true; + char c = 'a'; + while(run){ + try { + c = (char) System.in.read(); + } catch (IOException e) { + e.printStackTrace(); + run = false; + } + switch (c) { + case 'w': + do_write(bus, dev_handle); + break; + case 'r': + do_read(bus, dev_handle); + break; + case 'x': + run = false; + break; + default: + break; + } + } + LibusbWin.usb_close(dev_handle); + } + + public static void main(String[] args) { + LibusbWin.usb_init(); + LibusbWin.usb_find_busses(); + LibusbWin.usb_find_devices(); + + bus = LibusbWin.usb_get_busses(); + if (bus == null) { + System.err.println("Error on usb.usb_get_busses(): " + + LibusbWin.usb_strerror()); + return; + } + // Utils.logUsb(bus); + // openDevice(bus); + + do_write_read(bus); + + System.out.println("LibusbWin done"); + } +}