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