From: "Jong-Jin, Kim" <jongjin.kim....@gmail.com>

 Hi, this patch supports USBee DX analog feature. Actually, I didn't want
to change original files too much, but because of USBee DX's unusual
hardware design, especially analog is just working with EP6FIFO, I had to
move common files below hw/cwav-usbeedx-unified directory and made changes.

 Changes are followings.
 - changed endpoint to EP6 (USBee DX's analog part is working with GPIF
   Slave FIFO and its endpoint is fixed to EP6. It's hard-wired.)
 - added acquistion modes for USBee DX digital and analog.
        - normal mode : it works like original source code. so fx2lafw
          driver will work with this mode, if endpoint is changed to EP6.
        - dx digital mode : same with the original code but just GPIF
          waveform is changed to generate ADC clock.
        - dx clock only mode : just generate ADC clock without digital
          capture.
        - dx analog mode : USBee's analog FX2 is working with this mode
          (Slave FIFO).

 - added read eeprom vendor command to use analog calibration data.
 - added acquisition stop vendor command.

---
 configure.ac                               |   1 +
 hw/Makefile.am                             |   1 +
 hw/cwav-usbeedx-unified/Makefile.am        |  26 +++
 hw/cwav-usbeedx-unified/Makefile.inc       |  60 +++++
 hw/cwav-usbeedx-unified/command.h          |  60 +++++
 hw/cwav-usbeedx-unified/dscr.a51           |  24 ++
 hw/cwav-usbeedx-unified/dscr.inc           | 211 ++++++++++++++++++
 hw/cwav-usbeedx-unified/fx2lafw.c          | 313 ++++++++++++++++++++++++++
 hw/cwav-usbeedx-unified/gpif-acquisition.c | 340 +++++++++++++++++++++++++++++
 hw/cwav-usbeedx-unified/gpif-acquisition.h |  32 +++
 10 files changed, 1068 insertions(+)
 create mode 100644 hw/cwav-usbeedx-unified/Makefile.am
 create mode 100644 hw/cwav-usbeedx-unified/Makefile.inc
 create mode 100644 hw/cwav-usbeedx-unified/command.h
 create mode 100644 hw/cwav-usbeedx-unified/dscr.a51
 create mode 100644 hw/cwav-usbeedx-unified/dscr.inc
 create mode 100644 hw/cwav-usbeedx-unified/fx2lafw.c
 create mode 100644 hw/cwav-usbeedx-unified/gpif-acquisition.c
 create mode 100644 hw/cwav-usbeedx-unified/gpif-acquisition.h

diff --git a/configure.ac b/configure.ac
index 1150b80..c972e93 100644
--- a/configure.ac
+++ b/configure.ac
@@ -78,6 +78,7 @@ AC_CONFIG_FILES([Makefile
                 hw/braintechnology-usb-lps/Makefile
                 hw/cwav-usbeeax/Makefile
                 hw/cwav-usbeedx/Makefile
+                hw/cwav-usbeedx-unified/Makefile
                 hw/cwav-usbeesx/Makefile
                 hw/cypress-fx2/Makefile
                 hw/saleae-logic/Makefile
diff --git a/hw/Makefile.am b/hw/Makefile.am
index 6f7f5c9..bf3defc 100644
--- a/hw/Makefile.am
+++ b/hw/Makefile.am
@@ -21,6 +21,7 @@
 SUBDIRS = braintechnology-usb-lps \
          cwav-usbeeax \
          cwav-usbeedx \
+         cwav-usbeedx-unified \
          cwav-usbeesx \
          cypress-fx2 \
          saleae-logic
diff --git a/hw/cwav-usbeedx-unified/Makefile.am 
b/hw/cwav-usbeedx-unified/Makefile.am
new file mode 100644
index 0000000..2a4f9fb
--- /dev/null
+++ b/hw/cwav-usbeedx-unified/Makefile.am
@@ -0,0 +1,26 @@
+##
+## This file is part of the sigrok-firmware-fx2lafw project.
+##
+## Copyright (C) 2013 Uwe Hermann <u...@hermann-uwe.de>
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+##
+
+BASENAME = fx2lafw-cwav-usbeedx-unified
+
+all-local: $(BASENAME).fw
+
+include Makefile.inc
+
diff --git a/hw/cwav-usbeedx-unified/Makefile.inc 
b/hw/cwav-usbeedx-unified/Makefile.inc
new file mode 100644
index 0000000..e4e875c
--- /dev/null
+++ b/hw/cwav-usbeedx-unified/Makefile.inc
@@ -0,0 +1,60 @@
+##
+## This file is part of the sigrok-firmware-fx2lafw project.
+##
+## Copyright (C) 2013 Uwe Hermann <u...@hermann-uwe.de>
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+##
+
+EXTRA_DIST = dscr.a51
+
+fx2lafw: fx2lafw.rel gpif-acquisition.rel
+
+.c.rel:
+       $(AM_V_GEN)$(SDCC) -mmcs51 -I$(srcdir) -I$(top_srcdir)/include 
-I${top_srcdir}/fx2lib/include -c $< -o $@
+
+if FOUND_OBJCOPY
+$(BASENAME).fw: $(BASENAME).ihx
+       $(AM_V_GEN)$(OBJCOPY) -Iihex $(BASENAME).ihx -Obinary $@
+else
+if FOUND_MAKEBIN
+$(BASENAME).fw: $(BASENAME).ihx
+       $(AM_V_GEN)$(MAKEBIN) -p < $(BASENAME).ihx > $@
+endif
+endif
+
+RELS = $(builddir)/fx2lafw.rel ${builddir}/gpif-acquisition.rel \
+       ${builddir}/dscr.rel
+
+$(builddir)/dscr.rel: dscr.a51
+       $(AM_V_at)if test "x${abs_top_srcdir}" != "x${abs_top_builddir}"; then \
+               $(INSTALL_DATA) ${srcdir}/dscr.a51 ${builddir}; \
+       fi
+       $(AM_V_GEN)$(SDAS8051) -logs -I${top_srcdir}/include dscr.a51
+
+$(BASENAME).ihx: $(RELS) $(top_builddir)/fx2lib/lib/fx2.lib 
$(top_builddir)/fx2lib/lib/interrupts/ints.lib
+       $(AM_V_GEN)$(SDCC) -mmcs51 $(SDCC_FLAGS) -o $@ $(RELS) 
-L$(top_builddir)/fx2lib/lib fx2.lib interrupts/ints.lib
+
+install-data-local: $(BASENAME).fw
+       $(AM_V_at)$(MKDIR_P) $(DESTDIR)$(FIRMWARE_DIR)
+       $(AM_V_at)$(INSTALL_DATA) $(BASENAME).fw $(DESTDIR)$(FIRMWARE_DIR)
+
+uninstall-local:
+       $(AM_V_at)-rm -f $(DESTDIR)$(FIRMWARE_DIR)/$(BASENAME).fw
+
+clean-local:
+       $(AM_V_at)-rm -f *.lst *.rel *.rst *.sym *.lnk *.map *.mem *.ihx *.fw
+       $(AM_V_at)-rm -f *.cdb *.lk *.omf
+
diff --git a/hw/cwav-usbeedx-unified/command.h 
b/hw/cwav-usbeedx-unified/command.h
new file mode 100644
index 0000000..0af2925
--- /dev/null
+++ b/hw/cwav-usbeedx-unified/command.h
@@ -0,0 +1,60 @@
+/*
+ * This file is part of the sigrok-firmware-fx2lafw project.
+ *
+ * Copyright (C) 2012 Joel Holdsworth <j...@airwebreathe.org.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#ifndef FX2LAFW_INCLUDE_COMMAND_H
+#define FX2LAFW_INCLUDE_COMMAND_H
+
+#include <stdint.h>
+
+/* Protocol commands */
+#define CMD_GET_FW_VERSION             0xb0
+#define CMD_START                      0xb1
+#define CMD_GET_REVID_VERSION          0xb2
+#define CMD_STOP                       0xb3
+#define CMD_READ_EEPROM                0xb4
+
+#define CMD_START_FLAGS_MODE_POS       0
+#define CMD_START_FLAGS_WIDE_POS       5
+#define CMD_START_FLAGS_CLK_SRC_POS    6
+
+#define CMD_START_FLAGS_SAMPLE_8BIT    (0 << CMD_START_FLAGS_WIDE_POS)
+#define CMD_START_FLAGS_SAMPLE_16BIT   (1 << CMD_START_FLAGS_WIDE_POS)
+
+#define CMD_START_FLAGS_CLK_30MHZ      (0 << CMD_START_FLAGS_CLK_SRC_POS)
+#define CMD_START_FLAGS_CLK_48MHZ      (1 << CMD_START_FLAGS_CLK_SRC_POS)
+
+#define CMD_START_FLAGS_MODE_MASK      0x03
+#define CMD_START_FLAGS_MODE_NORMAL    (0 << CMD_START_FLAGS_MODE_POS)
+#define CMD_START_FLAGS_MODE_DX_DIGITAL (1 << CMD_START_FLAGS_MODE_POS)
+#define CMD_START_FLAGS_MODE_DX_CLK_ONLY (2 << CMD_START_FLAGS_MODE_POS)
+#define CMD_START_FLAGS_MODE_DX_ANALOG (3 << CMD_START_FLAGS_MODE_POS)
+
+struct version_info {
+       uint8_t major;
+       uint8_t minor;
+};
+
+struct cmd_start_acquisition {
+       uint8_t flags;
+       uint8_t sample_delay_h;
+       uint8_t sample_delay_l;
+};
+
+#endif
diff --git a/hw/cwav-usbeedx-unified/dscr.a51 b/hw/cwav-usbeedx-unified/dscr.a51
new file mode 100644
index 0000000..8586b1f
--- /dev/null
+++ b/hw/cwav-usbeedx-unified/dscr.a51
@@ -0,0 +1,24 @@
+;;
+;; This file is part of the sigrok-firmware-fx2lafw project.
+;;
+;; Copyright (C) 2012 Ivan Fedorov <ox...@oxyum.ru>
+;;
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2 of the License, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; if not, write to the Free Software
+;; Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+;;
+
+VID = 0xa908   ; Manufacturer ID (0x08a9)
+PID = 0x1500   ; Product ID (0x0015)
+
+.include "dscr.inc"
diff --git a/hw/cwav-usbeedx-unified/dscr.inc b/hw/cwav-usbeedx-unified/dscr.inc
new file mode 100644
index 0000000..8b47c4e
--- /dev/null
+++ b/hw/cwav-usbeedx-unified/dscr.inc
@@ -0,0 +1,211 @@
+;;
+;; This file is part of the sigrok-firmware-fx2lafw project.
+;;
+;; Copyright (C) 2011-2012 Uwe Hermann <u...@hermann-uwe.de>
+;; Copyright (C) 2012 Joel Holdsworth <j...@airwebreathe.org.uk>
+;;
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2 of the License, or
+;; (at your option) any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; if not, write to the Free Software
+;; Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+;;
+
+.module DEV_DSCR
+
+; Descriptor types
+DSCR_DEVICE_TYPE       = 1
+DSCR_CONFIG_TYPE       = 2
+DSCR_STRING_TYPE       = 3
+DSCR_INTERFACE_TYPE    = 4
+DSCR_ENDPOINT_TYPE     = 5
+DSCR_DEVQUAL_TYPE      = 6
+
+; Descriptor lengths
+DSCR_INTERFACE_LEN     = 9
+DSCR_ENDPOINT_LEN      = 7
+
+; Endpoint types
+ENDPOINT_TYPE_CONTROL  = 0
+ENDPOINT_TYPE_ISO      = 1
+ENDPOINT_TYPE_BULK     = 2
+ENDPOINT_TYPE_INT      = 3
+
+.globl _dev_dscr, _dev_qual_dscr, _highspd_dscr, _fullspd_dscr, _dev_strings, 
_dev_strings_end
+.area DSCR_AREA (CODE)
+
+; -----------------------------------------------------------------------------
+; Device descriptor
+; -----------------------------------------------------------------------------
+_dev_dscr:
+       .db     dev_dscr_end - _dev_dscr
+       .db     DSCR_DEVICE_TYPE
+       .dw     0x0002                  ; USB 2.0
+       .db     0xff                    ; Class (vendor specific)
+       .db     0xff                    ; Subclass (vendor specific)
+       .db     0xff                    ; Protocol (vendor specific)
+       .db     64                      ; Max. EP0 packet size
+       .dw     VID                     ; Manufacturer ID
+       .dw     PID                     ; Product ID
+       .dw     0x0100                  ; Product version (0.01)
+       .db     1                       ; Manufacturer string index
+       .db     2                       ; Product string index
+       .db     0                       ; Serial number string index (none)
+       .db     1                       ; Number of configurations
+dev_dscr_end:
+
+; -----------------------------------------------------------------------------
+; Device qualifier (for "other device speed")
+; -----------------------------------------------------------------------------
+_dev_qual_dscr:
+       .db     dev_qualdscr_end - _dev_qual_dscr
+       .db     DSCR_DEVQUAL_TYPE
+       .dw     0x0002                  ; USB 2.0
+       .db     0xff                    ; Class (vendor specific)
+       .db     0xff                    ; Subclass (vendor specific)
+       .db     0xff                    ; Protocol (vendor specific)
+       .db     64                      ; Max. EP0 packet size
+       .db     1                       ; Number of configurations
+       .db     0                       ; Extra reserved byte
+dev_qualdscr_end:
+
+; -----------------------------------------------------------------------------
+; High-Speed configuration descriptor
+; -----------------------------------------------------------------------------
+_highspd_dscr:
+       .db     highspd_dscr_end - _highspd_dscr
+       .db     DSCR_CONFIG_TYPE
+       ; Total length of the configuration (1st line LSB, 2nd line MSB)
+       .db     (highspd_dscr_realend - _highspd_dscr) % 256
+       .db     (highspd_dscr_realend - _highspd_dscr) / 256
+       .db     1                       ; Number of interfaces
+       .db     1                       ; Configuration number
+       .db     0                       ; Configuration string (none)
+       .db     0x80                    ; Attributes (bus powered, no wakeup)
+       .db     0x32                    ; Max. power (100mA)
+highspd_dscr_end:
+
+       ; Interfaces (only one in our case)
+       .db     DSCR_INTERFACE_LEN
+       .db     DSCR_INTERFACE_TYPE
+       .db     0                       ; Interface index
+       .db     0                       ; Alternate setting index
+       .db     1                       ; Number of endpoints
+       .db     0xff                    ; Class (vendor specific)
+       .db     0xff                    ; Subclass (vendor specific)
+       .db     0xff                    ; Protocol (vendor specific)
+       .db     0                       ; String index (none)
+
+       ; Endpoint 6 (IN)
+       .db     DSCR_ENDPOINT_LEN
+       .db     DSCR_ENDPOINT_TYPE
+       .db     0x86                    ; EP number (6), direction (IN)
+       .db     ENDPOINT_TYPE_BULK      ; Endpoint type (bulk)
+       .db     0x00                    ; Max. packet size, LSB (512 bytes)
+       .db     0x02                    ; Max. packet size, MSB (512 bytes)
+       .db     0x00                    ; Polling interval
+
+highspd_dscr_realend:
+
+       .even
+
+; -----------------------------------------------------------------------------
+; Full-Speed configuration descriptor
+; -----------------------------------------------------------------------------
+_fullspd_dscr:
+       .db     fullspd_dscr_end - _fullspd_dscr
+       .db     DSCR_CONFIG_TYPE
+       ; Total length of the configuration (1st line LSB, 2nd line MSB)
+       .db     (fullspd_dscr_realend - _fullspd_dscr) % 256
+       .db     (fullspd_dscr_realend - _fullspd_dscr) / 256
+       .db     1                       ; Number of interfaces
+       .db     1                       ; Configuration number
+       .db     0                       ; Configuration string (none)
+       .db     0x80                    ; Attributes (bus powered, no wakeup)
+       .db     0x32                    ; Max. power (100mA)
+fullspd_dscr_end:
+
+       ; Interfaces (only one in our case)
+       .db     DSCR_INTERFACE_LEN
+       .db     DSCR_INTERFACE_TYPE
+       .db     0                       ; Interface index
+       .db     0                       ; Alternate setting index
+       .db     1                       ; Number of endpoints
+       .db     0xff                    ; Class (vendor specific)
+       .db     0xff                    ; Subclass (vendor specific)
+       .db     0xff                    ; Protocol (vendor specific)
+       .db     0                       ; String index (none)
+
+       ; Endpoint 6 (IN)
+       .db     DSCR_ENDPOINT_LEN
+       .db     DSCR_ENDPOINT_TYPE
+       .db     0x86                    ; EP number (6), direction (IN)
+       .db     ENDPOINT_TYPE_BULK      ; Endpoint type (bulk)
+       .db     0x40                    ; Max. packet size, LSB (64 bytes)
+       .db     0x00                    ; Max. packet size, MSB (64 bytes)
+       .db     0x00                    ; Polling interval
+
+fullspd_dscr_realend:
+
+       .even
+
+; -----------------------------------------------------------------------------
+; Strings
+; -----------------------------------------------------------------------------
+
+_dev_strings:
+
+; See http://www.usb.org/developers/docs/USB_LANGIDs.pdf for the full list.
+_string0:
+       .db     string0end - _string0
+       .db     DSCR_STRING_TYPE
+       .db     0x09, 0x04              ; Language code 0x0409 (English, US)
+string0end:
+
+_string1:
+       .db     string1end - _string1
+       .db     DSCR_STRING_TYPE
+       .ascii  's'
+       .db     0
+       .ascii  'i'
+       .db     0
+       .ascii  'g'
+       .db     0
+       .ascii  'r'
+       .db     0
+       .ascii  'o'
+       .db     0
+       .ascii  'k'
+       .db     0
+string1end:
+
+_string2:
+       .db     string2end - _string2
+       .db     DSCR_STRING_TYPE
+       .ascii  'f'
+       .db     0
+       .ascii  'x'
+       .db     0
+       .ascii  '2'
+       .db     0
+       .ascii  'l'
+       .db     0
+       .ascii  'a'
+       .db     0
+       .ascii  'f'
+       .db     0
+       .ascii  'w'
+       .db     0
+string2end:
+
+_dev_strings_end:
+       .dw 0x0000
+
diff --git a/hw/cwav-usbeedx-unified/fx2lafw.c 
b/hw/cwav-usbeedx-unified/fx2lafw.c
new file mode 100644
index 0000000..5515d62
--- /dev/null
+++ b/hw/cwav-usbeedx-unified/fx2lafw.c
@@ -0,0 +1,313 @@
+/*
+ * This file is part of the sigrok-firmware-fx2lafw project.
+ *
+ * Copyright (C) 2011-2012 Uwe Hermann <u...@hermann-uwe.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+/*
+ * fx2lafw is an open-source firmware for Cypress FX2 based logic analyzers.
+ *
+ * It is written in C, using fx2lib as helper library, and sdcc as compiler.
+ * The code is licensed under the terms of the GNU GPL, version 2 or later.
+ *
+ * Technical notes:
+ *
+ *  - We use the FX2 in GPIF mode to sample the data (asynchronously).
+ *  - We use the internal 48MHz clock for GPIF.
+ *  - The 8 channels/pins we sample (the GPIF data bus) are PB0-PB7,
+ *    or PB0-PB7 + PD0-PD7 for 16-channel sampling. 
+ *  - Endpoint 2 (quad-buffered) is used for data transfers from FX2 to host.
+ *
+ * Documentation:
+ *
+ *  - See http://sigrok.org/wiki/Fx2lafw
+ */
+
+#include <fx2regs.h>
+#include <fx2macros.h>
+#include <delay.h>
+#include <setupdat.h>
+#include <eputils.h>
+#include <gpif.h>
+#include <i2c.h>
+#include <command.h>
+#include <fx2lafw.h>
+#include <gpif-acquisition.h>
+
+/* ... */
+volatile __bit got_sud;
+BYTE vendor_command;
+
+extern uint8_t acquisition_mode;
+
+static void setup_endpoints(void)
+{
+       /* Setup EP6 (IN). */
+       EP6CFG = (1 << 7) |               /* EP is valid/activated */
+                (1 << 6) |               /* EP direction: IN */
+                (1 << 5) | (0 << 4) |    /* EP Type: bulk */
+                (0 << 3) |               /* EP buffer size: 512 */
+                (0 << 2) |               /* Reserved. */
+                (0 << 1) | (0 << 0);     /* EP buffering: quad buffering */
+       SYNCDELAY();
+
+       /* Disable all other EPs (EP1, EP2, EP4, and EP8). */
+       EP1INCFG &= ~bmVALID;
+       SYNCDELAY();
+       EP1OUTCFG &= ~bmVALID;
+       SYNCDELAY();
+       EP2CFG &= ~bmVALID;
+       SYNCDELAY();
+       EP4CFG &= ~bmVALID;
+       SYNCDELAY();
+       EP8CFG &= ~bmVALID;
+       SYNCDELAY();
+
+       /* EP6: Reset the FIFOs. */
+       /* Note: RESETFIFO() gets the EP number WITHOUT bit 7 set/cleared. */
+       RESETFIFO(0x06)
+
+       /* EP6: Enable AUTOIN mode. Set FIFO width to 8bits. */
+       EP6FIFOCFG = bmAUTOIN;
+       SYNCDELAY();
+
+       /* EP6: Auto-commit 512 (0x200) byte packets (due to AUTOIN = 1). */
+       EP6AUTOINLENH = 0x02;
+       SYNCDELAY();
+       EP6AUTOINLENL = 0x00;
+       SYNCDELAY();
+
+       /* EP6: Set the GPIF flag to 'full'. */
+       EP6GPIFFLGSEL = (1 << 1) | (0 << 1);
+       SYNCDELAY();
+}
+
+static void send_fw_version(void)
+{
+       /* Populate the buffer. */
+       struct version_info *const vi = (struct version_info *)EP0BUF;
+       vi->major = FX2LAFW_VERSION_MAJOR;
+       vi->minor = FX2LAFW_VERSION_MINOR;
+
+       /* Send the message. */
+       EP0BCH = 0;
+       EP0BCL = sizeof(struct version_info);
+}
+
+static void send_revid_version(void)
+{
+       uint8_t *p;
+
+       /* Populate the buffer. */
+       p = (uint8_t *)EP0BUF;
+       *p = REVID;
+
+       /* Send the message. */
+       EP0BCH = 0;
+       EP0BCL = 1;
+}
+
+#define EEPROM_I2C_ADDR 0x50
+static void read_eeprom(void)
+{
+       struct cmd_read_eeprom *cmd;
+       uint8_t addr;
+       uint8_t len;
+
+       /* I2C clock : 400KHz */
+       I2CTL = bm400KHZ;
+
+       cmd = (struct cmd_read_eeprom *) EP0BUF;
+       addr = SETUPDAT[2];             /* wValue LSB */
+       len = SETUPDAT[4] & 0x3f;       /* wIndex LSB */
+       eeprom_read(EEPROM_I2C_ADDR, addr, len, EP0BUF);
+
+       /* Send the message. */
+       EP0BCH = 0;
+       EP0BCL = len;
+}
+
+BOOL handle_vendorcommand(BYTE cmd)
+{
+       /* Protocol implementation */
+       switch (cmd) {
+       case CMD_START:
+               vendor_command = cmd;
+               EP0BCL = 0;
+               return TRUE;
+               break;
+       case CMD_GET_FW_VERSION:
+               send_fw_version();
+               return TRUE;
+               break;
+       case CMD_GET_REVID_VERSION:
+               send_revid_version();
+               return TRUE;
+               break;
+       case CMD_STOP:
+               gpif_acquisition_stop();
+               return TRUE;
+               break;
+       case CMD_READ_EEPROM:
+               read_eeprom();
+               return TRUE;
+               break;
+       }
+
+       return FALSE;
+}
+
+BOOL handle_get_interface(BYTE ifc, BYTE *alt_ifc)
+{
+       /* We only support interface 0, alternate interface 0. */
+       if (ifc != 0)
+               return FALSE;
+
+       *alt_ifc = 0;
+       return TRUE;
+}
+
+BOOL handle_set_interface(BYTE ifc, BYTE alt_ifc)
+{
+       /* We only support interface 0, alternate interface 0. */
+       if (ifc != 0 || alt_ifc != 0)
+               return FALSE;
+
+       /* Perform procedure from TRM, section 2.3.7: */
+
+       /* (1) TODO. */
+
+       /* (2) Reset data toggles of the EPs in the interface. */
+       /* Note: RESETTOGGLE() gets the EP number WITH bit 7 set/cleared. */
+       RESETTOGGLE(0x86);
+
+       /* (3) Restore EPs to their default conditions. */
+       /* Note: RESETFIFO() gets the EP number WITHOUT bit 7 set/cleared. */
+       RESETFIFO(0x06);
+       /* TODO */
+
+       /* (4) Clear the HSNAK bit. Not needed, fx2lib does this. */
+
+       return TRUE;
+}
+
+BYTE handle_get_configuration(void)
+{
+       /* We only support configuration 1. */
+       return 1;
+}
+
+BOOL handle_set_configuration(BYTE cfg)
+{
+       /* We only support configuration 1. */
+       return (cfg == 1) ? TRUE : FALSE;
+}
+
+void sudav_isr(void) __interrupt SUDAV_ISR
+{
+       got_sud = TRUE;
+       CLEAR_SUDAV();
+}
+
+void sof_isr(void) __interrupt SOF_ISR __using 1
+{
+       CLEAR_SOF();
+}
+
+void usbreset_isr(void) __interrupt USBRESET_ISR
+{
+       handle_hispeed(FALSE);
+       CLEAR_USBRESET();
+}
+
+void hispeed_isr(void) __interrupt HISPEED_ISR
+{
+       handle_hispeed(TRUE);
+       CLEAR_HISPEED();
+}
+
+void fx2lafw_init(void)
+{
+       /* Set DYN_OUT and ENH_PKT bits, as recommended by the TRM. */
+       REVCTL = bmNOAUTOARM | bmSKIPCOMMIT;
+
+       got_sud = FALSE;
+       vendor_command = 0;
+
+       /* Renumerate. */
+       RENUMERATE_UNCOND();
+
+       SETCPUFREQ(CLK_48M);
+
+       USE_USB_INTS();
+
+       /* TODO: Does the order of the following lines matter? */
+       ENABLE_SUDAV();
+       ENABLE_SOF();
+       ENABLE_HISPEED();
+       ENABLE_USBRESET();
+
+       /* Global (8051) interrupt enable. */
+       EA = 1;
+
+       /* Setup the endpoints. */
+       setup_endpoints();
+
+       /* Put the FX2 into GPIF master mode and setup the GPIF. */
+       gpif_init_la();
+}
+
+void fx2lafw_poll(void)
+{
+       if (got_sud) {
+               handle_setupdata();
+               got_sud = FALSE;
+       }
+
+       if (vendor_command) {
+               switch (vendor_command) {
+               case CMD_START:
+                       if ((EP0CS & bmEPBUSY) != 0)
+                               break;
+
+                       if (EP0BCL == sizeof(struct cmd_start_acquisition)) {
+                               gpif_acquisition_start(
+                                (const struct cmd_start_acquisition *)EP0BUF);
+                       }
+
+                       /* Acknowledge the vendor command. */
+                       vendor_command = 0;
+                       break;
+               default:
+                       /* Unimplemented command. */
+                       vendor_command = 0;
+                       break;
+               }
+       }
+
+       /* USBEE_DX_ANALOG mode is using GPIF Slave FIFO mode */
+       if (acquisition_mode != CMD_START_FLAGS_MODE_DX_ANALOG) {
+               gpif_poll();
+       }
+}
+
+void main(void)
+{
+       fx2lafw_init();
+       while (1)
+               fx2lafw_poll();
+}
diff --git a/hw/cwav-usbeedx-unified/gpif-acquisition.c 
b/hw/cwav-usbeedx-unified/gpif-acquisition.c
new file mode 100644
index 0000000..30c0a24
--- /dev/null
+++ b/hw/cwav-usbeedx-unified/gpif-acquisition.c
@@ -0,0 +1,340 @@
+/*
+ * This file is part of the sigrok-firmware-fx2lafw project.
+ *
+ * Copyright (C) 2011-2012 Uwe Hermann <u...@hermann-uwe.de>
+ * Copyright (C) 2012 Joel Holdsworth <j...@airwebreathe.org.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <eputils.h>
+#include <fx2regs.h>
+#include <fx2macros.h>
+#include <delay.h>
+#include <gpif.h>
+#include <fx2lafw.h>
+#include <gpif-acquisition.h>
+
+__bit gpif_acquiring;
+
+static void gpif_reset_waveforms(void)
+{
+       int i;
+
+       /* Reset WAVEDATA. */
+       AUTOPTRSETUP = 0x03;
+       AUTOPTRH1 = 0xe4;
+       AUTOPTRL1 = 0x00;
+       for (i = 0; i < 128; i++)
+               EXTAUTODAT1 = 0;
+}
+
+static void gpif_setup_registers(void)
+{
+       /* TODO. Value probably irrelevant, as we don't use RDY* signals? */
+       GPIFREADYCFG = 0;
+
+       /*
+        * Set TRICTL = 0, thus CTL0-CTL5 are CMOS outputs.
+        * TODO: Probably irrelevant, as we don't use CTL0-CTL5?
+        */
+       GPIFCTLCFG = 0;
+       /*GPIFCTLCFG = 0x80;*/  /* for USBee DX */
+
+       /* When GPIF is idle, tri-state the data bus. */
+       /* Bit 7: DONE, bit 0: IDLEDRV. TODO: Set/clear DONE bit? */
+       GPIFIDLECS = (0 << 0);
+
+       /* When GPIF is idle, set CTL0-CTL5 to 0. */
+       GPIFIDLECTL = 0;
+       /*GPIFIDLECTL = 0x77;*/ /* for USBee DX */
+
+       /*
+        * Map index 0 in WAVEDATA to FIFORD. The rest is assigned too,
+        * but not used by us.
+        *
+        * GPIFWFSELECT: [7:6] = SINGLEWR index, [5:4] = SINGLERD index,
+        *               [3:2] = FIFOWR index, [1:0] = FIFORD index
+        */
+       GPIFWFSELECT = (0x3 << 6) | (0x2 << 4) | (0x1 << 2) | (0x0 << 0);
+
+       /* Contains RDY* pin values. Read-only according to TRM. */
+       GPIFREADYSTAT = 0;
+
+       /* Make GPIF stop on transaction count not flag. */
+       EP6GPIFPFSTOP = (0 << 0);
+}
+
+static void gpif_init_addr_pins(void)
+{
+       /*
+        * Configure the 9 GPIF address pins (GPIFADR[8:0], which consist of
+        * PORTC[7:0] and PORTE[7]), and output an initial address (zero).
+        * TODO: Probably irrelevant, the 56pin FX2 has no ports C and E.
+        */
+       PORTCCFG = 0xff;    /* Set PORTC[7:0] as alt. func. (GPIFADR[7:0]). */
+       OEC = 0xff;         /* Configure PORTC[7:0] as outputs. */
+       PORTECFG |= 0x80;   /* Set PORTE[7] as alt. func. (GPIFADR[8]). */
+       OEE |= 0x80;        /* Configure PORTE[7] as output. */
+       SYNCDELAY();
+       GPIFADRL = 0x00;    /* Clear GPIFADR[7:0]. */
+       SYNCDELAY();
+       GPIFADRH = 0x00;    /* Clear GPIFADR[8]. */
+}
+
+static void gpif_init_flowstates(void)
+{
+       /* Clear all flowstate registers, we don't use this functionality. */
+       FLOWSTATE = 0;
+       FLOWLOGIC = 0;
+       FLOWEQ0CTL = 0;
+       FLOWEQ1CTL = 0;
+       FLOWHOLDOFF = 0;
+       FLOWSTB = 0;
+       FLOWSTBEDGE = 0;
+       FLOWSTBHPERIOD = 0;
+}
+
+void gpif_init_la(void)
+{
+       /*
+        * Setup the FX2 in GPIF master mode, using the internal clock
+        * (non-inverted) at 48MHz, and using async sampling.
+        */
+       IFCONFIG = 0xee;
+
+       /* Abort currently executing GPIF waveform (if any). */
+       GPIFABORT = 0xff;
+
+       /* Setup the GPIF registers. */
+       gpif_setup_registers();
+
+       /* Reset WAVEDATA. */
+       gpif_reset_waveforms();
+
+       /* Initialize GPIF address pins, output initial values. */
+       gpif_init_addr_pins();
+
+       /* Initialize flowstate registers (not used by us). */
+       gpif_init_flowstates();
+
+       /* Reset the status. */
+       gpif_acquiring = FALSE;
+}
+
+static void gpif_make_delay_state(volatile BYTE *pSTATE,
+       uint8_t delay, uint8_t output)
+{
+       /*
+        * DELAY
+        * Delay cmd->sample_delay clocks.
+        */
+       pSTATE[0] = delay;
+
+       /*
+        * OPCODE
+        * SGL=0, GIN=0, INCAD=0, NEXT=0, DATA=0, DP=0
+        * Collect data in this state.
+        */
+       pSTATE[8] = 0x00;
+
+       /*
+        * OUTPUT
+        * OE[0:3]=0, CTL[0:3]=0
+        */
+       pSTATE[16] = output;
+
+       /*
+        * LOGIC FUNCTION
+        * Not used.
+        */
+       pSTATE[24] = 0x00;
+}
+
+static void gpid_make_data_dp_state(volatile BYTE *pSTATE, uint8_t data, 
uint8_t output)
+{
+       /*
+        * BRANCH
+        * Branch to IDLE if condition is true, back to S0 otherwise.
+        */
+       pSTATE[0] = (7 << 3) | (0 << 0);
+
+       /*
+        * OPCODE
+        * SGL=0, GIN=0, INCAD=0, NEXT=0, DATA=1, DP=1
+        */
+       pSTATE[8] = (data << 1) | (1 << 0);
+
+       /*
+        * OUTPUT
+        * OE[0:3]=0, CTL[0:3]=0
+        */
+       pSTATE[16] = output;
+
+       /*
+        * LOGIC FUNCTION
+        * Evaluate if the FIFO full flag is set.
+        * LFUNC=0 (AND), TERMA=6 (FIFO Flag), TERMB=6 (FIFO Flag)
+        */
+       pSTATE[24] = (6 << 3) | (6 << 0);
+}
+
+void acquisition_mode_init(uint8_t flags)
+{
+       switch (flags & CMD_START_FLAGS_MODE_MASK) {
+       case CMD_START_FLAGS_MODE_NORMAL :
+               break;
+       case CMD_START_FLAGS_MODE_DX_DIGITAL :
+       case CMD_START_FLAGS_MODE_DX_CLK_ONLY :
+               /*
+                * GPIFCTLCFG : TRICTL 0 CTL5 CTL4  CTL3 CTL2 CTL1 CTL0
+                * CTL2 and CTL1 is controlled during FIFO transaction to make a
+                * signal for ADC and USBee DX Analog FX2.
+                */
+               GPIFCTLCFG = 0x80;      /* CTL[3:0] is Tri-statable */
+
+               /*
+                * GPIFIDLECTL : CTLOE3 CTLOE2 CTLOE1 CTLOE0  CTL3 CTL2 CTL1 
CTL0
+                * CTL2 and CTL1 is high during IDLE for DX.
+                */
+               GPIFIDLECTL = 0x77;
+
+               RESETFIFO(6);
+               break;
+       case CMD_START_FLAGS_MODE_DX_ANALOG :
+               /* USBee Analog is working with GPIF Slave FIFO mode. */
+               IFCONFIG |= (bmIFCFG1 | bmIFCFG0);
+               SYNCDELAY();
+
+               RESETFIFO(6);
+               break;
+       }
+}
+
+uint8_t acquisition_mode;
+
+#define USBEE_DX_DELAY_CTL_OUTPUT      0x77    /* 0 1 1 1 / 0 1 1 1 */
+#define USBEE_DX_DP_CTL_OUTPUT         0x71    /* 0 1 1 1 / 0 0 0 1 */
+
+bool gpif_acquisition_start(const struct cmd_start_acquisition *cmd)
+{
+       int i;
+       volatile BYTE *pSTATE = &GPIF_WAVE_DATA;
+       uint8_t output;
+       uint8_t data;
+
+       /* Ensure GPIF is idle before reconfiguration. */
+       while (!(GPIFTRIG & 0x80));
+
+       /* Configure the EP6 FIFO. */
+       if (cmd->flags & CMD_START_FLAGS_SAMPLE_16BIT) {
+               EP6FIFOCFG = bmAUTOIN | bmWORDWIDE;
+       } else {
+               EP6FIFOCFG = bmAUTOIN;
+       }
+       SYNCDELAY();
+
+       /* Set IFCONFIG to the correct clock source. */
+       if (cmd->flags & CMD_START_FLAGS_CLK_48MHZ) {
+               IFCONFIG = bmIFCLKSRC | bm3048MHZ | bmIFCLKOE | bmASYNC |
+                          bmGSTATE | bmIFGPIF;
+       } else {
+               IFCONFIG = bmIFCLKSRC | bmIFCLKOE | bmASYNC |
+                          bmGSTATE | bmIFGPIF;
+       }
+
+       /* Populate delay states. */
+       if ((cmd->sample_delay_h == 0 && cmd->sample_delay_l == 0) ||
+           cmd->sample_delay_h >= 6)
+               return false;
+
+       acquisition_mode = cmd->flags & CMD_START_FLAGS_MODE_MASK;
+
+       acquisition_mode_init(cmd->flags);
+
+       if (acquisition_mode == CMD_START_FLAGS_MODE_DX_ANALOG) {
+               gpif_acquiring = FALSE;
+               return true;
+       }
+
+       output = acquisition_mode ? USBEE_DX_DELAY_CTL_OUTPUT : 0x00;
+
+       for (i = 0; i < cmd->sample_delay_h; i++)
+               gpif_make_delay_state(pSTATE++, 0, output);
+
+       if (cmd->sample_delay_l != 0)
+               gpif_make_delay_state(pSTATE++, cmd->sample_delay_l, output);
+
+       output = acquisition_mode ? USBEE_DX_DP_CTL_OUTPUT : 0x00;
+
+       data = (acquisition_mode == CMD_START_FLAGS_MODE_DX_CLK_ONLY) ? 0 : 1;
+
+       /* Populate S1 - the decision point. */
+       gpid_make_data_dp_state(pSTATE++, data, output);
+
+       /* Execute the whole GPIF waveform once. */
+       gpif_set_tc16(1);
+
+       /* Perform the initial GPIF read. */
+       gpif_fifo_read(GPIF_EP6);
+
+       /* Update the status. */
+       gpif_acquiring = TRUE;
+
+       return true;
+}
+
+bool gpif_acquisition_stop(void)
+{
+       /* Abort currently executing GPIF waveform (if any). */
+       GPIFABORT = 0xff;
+
+       /* Populate the buffer. */
+       EP0BUF[0] = 0;
+
+       /* Send the message. */
+       EP0BCH = 0;
+       EP0BCL = 1;
+
+       return true;
+}
+
+void gpif_poll(void)
+{
+       /* Detect if acquisition has completed. */
+       if (gpif_acquiring && (GPIFTRIG & 0x80)) {
+               /* Activate NAK-ALL to avoid race conditions. */
+               FIFORESET = 0x80;
+               SYNCDELAY();
+
+               /* Switch to manual mode. */
+               EP6FIFOCFG = 0;
+               SYNCDELAY();
+
+               /* Reset EP. */
+               FIFORESET = 0x06;
+               SYNCDELAY();
+
+               /* Return to auto mode. */
+               EP6FIFOCFG = bmAUTOIN;
+               SYNCDELAY();
+
+               /* Release NAK-ALL. */
+               FIFORESET = 0x00;
+               SYNCDELAY();
+
+               gpif_acquiring = FALSE;
+       }
+}
diff --git a/hw/cwav-usbeedx-unified/gpif-acquisition.h 
b/hw/cwav-usbeedx-unified/gpif-acquisition.h
new file mode 100644
index 0000000..4ec2fb4
--- /dev/null
+++ b/hw/cwav-usbeedx-unified/gpif-acquisition.h
@@ -0,0 +1,32 @@
+/*
+ * This file is part of the sigrok-firmware-fx2lafw project.
+ *
+ * Copyright (C) 2012 Joel Holdsworth <j...@airwebreathe.org.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#ifndef FX2LAFW_INCLUDE_GPIF_ACQUISITION_H
+#define FX2LAFW_INCLUDE_GPIF_ACQUISITION_H
+
+#include <stdbool.h>
+#include <command.h>
+
+void gpif_init_la(void);
+bool gpif_acquisition_start(const struct cmd_start_acquisition *cmd);
+bool gpif_acquisition_stop(void);
+void gpif_poll(void);
+
+#endif
-- 
1.8.1.2


------------------------------------------------------------------------------
Rapidly troubleshoot problems before they affect your business. Most IT 
organizations don't have a clear picture of how application performance 
affects their revenue. With AppDynamics, you get 100% visibility into your 
Java,.NET, & PHP application. Start your 15-day FREE TRIAL of AppDynamics Pro!
http://pubads.g.doubleclick.net/gampad/clk?id=84349831&iu=/4140/ostg.clktrk
_______________________________________________
sigrok-devel mailing list
sigrok-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sigrok-devel

Reply via email to