Commits

Anonymous committed 5138f7f

initial lib file import

Comments (0)

Files changed (24)

+*.asm
+*.rel
+*.lst
+*.sym
+Before building this library, you need sdcc installed and in your path.
+
+ http://sdcc.sf.net
+
+To build this library, run make in the lib folder.
+
+> cd lib
+> make
+
+You get lib/fx2.lib
+
+To use routines included with this library in your own firmware, 
+add the include files to your include path and the lib file to your compile command:
+
+> sdcc -mmcs51 -I<path to includes> <your c file> fx2.lib -L <path to fx2.lib dir> 
+
+Enjoy!
+Comments, Patches, all welcome.
+
+
+Notes on Various things I've learned about SDCC and the FX2
+
 * libusb on Linux
 * cycfx2prog: http://www.triplespark.net/elec/periph/USB-FX2/software/index.html
 * sdcc has sdcc/support/scripts/keil2sdcc.pl which I used to create the fx2regs.h file from the keil header. 
+/**
+ * Copyright (C) 2008 Ubixum, Inc. 
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ **/
+
+#ifndef DELAY_H
+#define DELAY_H
+
+#include "fx2types.h"
+
+/**
+ * 0-65536 millis
+ **/
+void delay(WORD millis);
+
+/**
+ * See TRM 15-14,15-15
+ * some registers (r/w) require syncdelay after
+ *
+ * up to the programmer to determine which sync is needed.
+ * for standard 48mhz clock w/ 48mhz IFCONFIG 3 nops is sufficient.
+ *
+ * slower clock and faster ifclock require more delay
+ *
+ * min delay = roof ( 1.5 x (ifclock/clkout + 1) )
+ *
+ * Minimum IFCLOCK is 5mhz but you have to use an
+ * external clock source to go below 30mhz
+ * IFCLKSRC 1 = internal, 0=external
+ * 3048mhz 0 = 30mhz, 1 = 48mzh
+ * figure your own sync delay out if IFCLKSRC=0
+ * 
+ **/
+
+#define NOP _asm nop _endasm
+
+//ifcfg/clk
+// 48/12
+// ceil(1.5 * (20.8 / 83.3 + 1)) = 2
+#define SYNCDELAY2 NOP; NOP
+
+// 48/24
+#define SYNCDELAY3 NOP; NOP; NOP
+
+// 48/48
+// also needs 3
+
+// 30/12
+// also use 3
+
+// 30/24
+// also use 3
+
+// 30/48
+#define SYNCDELAY4 NOP; NOP; NOP; NOP
+
+#endif
+
+/**
+ * Copyright (C) 2008 Ubixum, Inc. 
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ **/
+
+#ifndef EPUTILS_H
+#define EPUTILS_H
+
+#include "fx2types.h"
+
+#define RESETFIFOS() {FIFORESET=0x80; SYNCDELAY();\
+                     FIFORESET=0x02; SYNCDELAY();\
+                     FIFORESET=0x04; SYNCDELAY();\
+                     FIFORESET=0x06; SYNCDELAY();\
+                     FIFORESET=0x08; SYNCDELAY();\
+                     FIFORESET=0x00; SYNCDELAY();}
+
+
+void readep0( BYTE* dst, WORD len );
+
+
+
+#endif
+/**
+ * Copyright (C) 2008 Ubixum, Inc. 
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ **/
+
+#ifndef FX2MACROS_H
+#define FX2MACROS_H
+
+#include "fx2regs.h"
+#include "fx2types.h"
+
+#define MSB(addr) (BYTE)((addr >> 8) & 0xff)
+#define LSB(addr) (BYTE)(addr & 0xff)
+#define MAKEWORD(msb,lsb) (((WORD)msb << 8) | lsb)
+
+#define MSW(dword) (WORD)((dword >> 16) & 0xffff)
+#define LSW(dword) (WORD)(dword & 0xffff)
+#define MAKEDWORD(msw,lsw) (((DWORD)msw << 16) | lsw)
+
+// clock stuff
+
+typedef enum { CLK_12M =0, CLK_24M, CLK_48M} CLK_SPD;
+#define CPUFREQ (CLK_SPD)((CPUCS & bmCLKSPD) >> 3)
+#define SETCPUFREQ(SPD) CPUCS = (CPUCS & ~bmCLKSPD) | (SPD << 3)
+
+#define XTAL (CPUFREQ==CLK_12M ? 12000000L :\
+              CPUFREQ==CLK_24M ? 24000000L : 48000000L)
+
+
+// i2c stuff
+#define I2CFREQ ((I2CTL & bm400KHZ) ? 400000L : 100000L)
+
+
+// endpoints 
+#define IFFREQ (IFCONFIG & bm3048MHZ ? 48000000L : 30000000L)
+#define SETIF30MHZ() IFCONFIG &= ~bm3048MHZ
+#define SETIF48MHZ() IFCONFIG |= bm3048MHZ
+
+
+// eeprom stuff
+#define EEPROM_TWO_BYTE (I2CS & bmBIT4)
+
+
+#endif
+/**
+ * Copyright (C) 2008 Ubixum, Inc. 
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ **/
+
+#ifndef FX2REGS_H 
+#define FX2REGS_H
+
+#include "fx2types.h"
+
+xdata at 0xE400 volatile BYTE GPIF_WAVE_DATA;
+xdata at 0xE480 volatile BYTE RES_WAVEDATA_END;
+
+// General Configuration
+
+xdata at 0xE600 volatile BYTE CPUCS;  // Control & Status
+xdata at 0xE601 volatile BYTE IFCONFIG;  // Interface Configuration
+xdata at 0xE602 volatile BYTE PINFLAGSAB;  // FIFO FLAGA and FLAGB Assignments
+xdata at 0xE603 volatile BYTE PINFLAGSCD;  // FIFO FLAGC and FLAGD Assignments
+xdata at 0xE604 volatile BYTE FIFORESET;  // Restore FIFOS to default state
+xdata at 0xE605 volatile BYTE BREAKPT;  // Breakpoint
+xdata at 0xE606 volatile BYTE BPADDRH;  // Breakpoint Address H
+xdata at 0xE607 volatile BYTE BPADDRL;  // Breakpoint Address L
+xdata at 0xE608 volatile BYTE UART230;  // 230 Kbaud clock for T0,T1,T2
+xdata at 0xE609 volatile BYTE FIFOPINPOLAR;  // FIFO polarities
+xdata at 0xE60A volatile BYTE REVID;  // Chip Revision
+xdata at 0xE60B volatile BYTE REVCTL;  // Chip Revision Control
+
+// Endpoint Configuration
+
+xdata at 0xE610 volatile BYTE EP1OUTCFG;  // Endpoint 1-OUT Configuration
+xdata at 0xE611 volatile BYTE EP1INCFG;  // Endpoint 1-IN Configuration
+xdata at 0xE612 volatile BYTE EP2CFG;  // Endpoint 2 Configuration
+xdata at 0xE613 volatile BYTE EP4CFG;  // Endpoint 4 Configuration
+xdata at 0xE614 volatile BYTE EP6CFG;  // Endpoint 6 Configuration
+xdata at 0xE615 volatile BYTE EP8CFG;  // Endpoint 8 Configuration
+xdata at 0xE618 volatile BYTE EP2FIFOCFG;  // Endpoint 2 FIFO configuration
+xdata at 0xE619 volatile BYTE EP4FIFOCFG;  // Endpoint 4 FIFO configuration
+xdata at 0xE61A volatile BYTE EP6FIFOCFG;  // Endpoint 6 FIFO configuration
+xdata at 0xE61B volatile BYTE EP8FIFOCFG;  // Endpoint 8 FIFO configuration
+xdata at 0xE620 volatile BYTE EP2AUTOINLENH;  // Endpoint 2 Packet Length H (IN only)
+xdata at 0xE621 volatile BYTE EP2AUTOINLENL;  // Endpoint 2 Packet Length L (IN only)
+xdata at 0xE622 volatile BYTE EP4AUTOINLENH;  // Endpoint 4 Packet Length H (IN only)
+xdata at 0xE623 volatile BYTE EP4AUTOINLENL;  // Endpoint 4 Packet Length L (IN only)
+xdata at 0xE624 volatile BYTE EP6AUTOINLENH;  // Endpoint 6 Packet Length H (IN only)
+xdata at 0xE625 volatile BYTE EP6AUTOINLENL;  // Endpoint 6 Packet Length L (IN only)
+xdata at 0xE626 volatile BYTE EP8AUTOINLENH;  // Endpoint 8 Packet Length H (IN only)
+xdata at 0xE627 volatile BYTE EP8AUTOINLENL;  // Endpoint 8 Packet Length L (IN only)
+xdata at 0xE630 volatile BYTE EP2FIFOPFH;  // EP2 Programmable Flag trigger H
+xdata at 0xE631 volatile BYTE EP2FIFOPFL;  // EP2 Programmable Flag trigger L
+xdata at 0xE632 volatile BYTE EP4FIFOPFH;  // EP4 Programmable Flag trigger H
+xdata at 0xE633 volatile BYTE EP4FIFOPFL;  // EP4 Programmable Flag trigger L
+xdata at 0xE634 volatile BYTE EP6FIFOPFH;  // EP6 Programmable Flag trigger H
+xdata at 0xE635 volatile BYTE EP6FIFOPFL;  // EP6 Programmable Flag trigger L
+xdata at 0xE636 volatile BYTE EP8FIFOPFH;  // EP8 Programmable Flag trigger H
+xdata at 0xE637 volatile BYTE EP8FIFOPFL;  // EP8 Programmable Flag trigger L
+xdata at 0xE640 volatile BYTE EP2ISOINPKTS;  // EP2 (if ISO) IN Packets per frame (1-3)
+xdata at 0xE641 volatile BYTE EP4ISOINPKTS;  // EP4 (if ISO) IN Packets per frame (1-3)
+xdata at 0xE642 volatile BYTE EP6ISOINPKTS;  // EP6 (if ISO) IN Packets per frame (1-3)
+xdata at 0xE643 volatile BYTE EP8ISOINPKTS;  // EP8 (if ISO) IN Packets per frame (1-3)
+xdata at 0xE648 volatile BYTE INPKTEND;  // Force IN Packet End
+xdata at 0xE649 volatile BYTE OUTPKTEND;  // Force OUT Packet End
+
+// Interrupts
+
+xdata at 0xE650 volatile BYTE EP2FIFOIE;  // Endpoint 2 Flag Interrupt Enable
+xdata at 0xE651 volatile BYTE EP2FIFOIRQ;  // Endpoint 2 Flag Interrupt Request
+xdata at 0xE652 volatile BYTE EP4FIFOIE;  // Endpoint 4 Flag Interrupt Enable
+xdata at 0xE653 volatile BYTE EP4FIFOIRQ;  // Endpoint 4 Flag Interrupt Request
+xdata at 0xE654 volatile BYTE EP6FIFOIE;  // Endpoint 6 Flag Interrupt Enable
+xdata at 0xE655 volatile BYTE EP6FIFOIRQ;  // Endpoint 6 Flag Interrupt Request
+xdata at 0xE656 volatile BYTE EP8FIFOIE;  // Endpoint 8 Flag Interrupt Enable
+xdata at 0xE657 volatile BYTE EP8FIFOIRQ;  // Endpoint 8 Flag Interrupt Request
+xdata at 0xE658 volatile BYTE IBNIE;  // IN-BULK-NAK Interrupt Enable
+xdata at 0xE659 volatile BYTE IBNIRQ;  // IN-BULK-NAK interrupt Request
+xdata at 0xE65A volatile BYTE NAKIE;  // Endpoint Ping NAK interrupt Enable
+xdata at 0xE65B volatile BYTE NAKIRQ;  // Endpoint Ping NAK interrupt Request
+xdata at 0xE65C volatile BYTE USBIE;  // USB Int Enables
+xdata at 0xE65D volatile BYTE USBIRQ;  // USB Interrupt Requests
+xdata at 0xE65E volatile BYTE EPIE;  // Endpoint Interrupt Enables
+xdata at 0xE65F volatile BYTE EPIRQ;  // Endpoint Interrupt Requests
+xdata at 0xE660 volatile BYTE GPIFIE;  // GPIF Interrupt Enable
+xdata at 0xE661 volatile BYTE GPIFIRQ;  // GPIF Interrupt Request
+xdata at 0xE662 volatile BYTE USBERRIE;  // USB Error Interrupt Enables
+xdata at 0xE663 volatile BYTE USBERRIRQ;  // USB Error Interrupt Requests
+xdata at 0xE664 volatile BYTE ERRCNTLIM;  // USB Error counter and limit
+xdata at 0xE665 volatile BYTE CLRERRCNT;  // Clear Error Counter EC[3..0]
+xdata at 0xE666 volatile BYTE INT2IVEC;  // Interupt 2 (USB) Autovector
+xdata at 0xE667 volatile BYTE INT4IVEC;  // Interupt 4 (FIFOS & GPIF) Autovector
+xdata at 0xE668 volatile BYTE INTSETUP;  // Interrupt 2&4 Setup
+
+// Input/Output
+
+xdata at 0xE670 volatile BYTE PORTACFG;  // I/O PORTA Alternate Configuration
+xdata at 0xE671 volatile BYTE PORTCCFG;  // I/O PORTC Alternate Configuration
+xdata at 0xE672 volatile BYTE PORTECFG;  // I/O PORTE Alternate Configuration
+xdata at 0xE678 volatile BYTE I2CS;  // Control & Status
+xdata at 0xE679 volatile BYTE I2DAT;  // Data
+xdata at 0xE67A volatile BYTE I2CTL;  // I2C Control
+xdata at 0xE67B volatile BYTE XAUTODAT1;  // Autoptr1 MOVX access
+xdata at 0xE67C volatile BYTE XAUTODAT2;  // Autoptr2 MOVX access
+
+#define EXTAUTODAT1 XAUTODAT1
+#define EXTAUTODAT2 XAUTODAT2
+
+// USB Control
+
+xdata at 0xE680 volatile BYTE USBCS;  // USB Control & Status
+xdata at 0xE681 volatile BYTE SUSPEND;  // Put chip into suspend
+xdata at 0xE682 volatile BYTE WAKEUPCS;  // Wakeup source and polarity
+xdata at 0xE683 volatile BYTE TOGCTL;  // Toggle Control
+xdata at 0xE684 volatile BYTE USBFRAMEH;  // USB Frame count H
+xdata at 0xE685 volatile BYTE USBFRAMEL;  // USB Frame count L
+xdata at 0xE686 volatile BYTE MICROFRAME;  // Microframe count, 0-7
+xdata at 0xE687 volatile BYTE FNADDR;  // USB Function address
+
+// Endpoints
+
+xdata at 0xE68A volatile BYTE EP0BCH;  // Endpoint 0 Byte Count H
+xdata at 0xE68B volatile BYTE EP0BCL;  // Endpoint 0 Byte Count L
+xdata at 0xE68D volatile BYTE EP1OUTBC;  // Endpoint 1 OUT Byte Count
+xdata at 0xE68F volatile BYTE EP1INBC;  // Endpoint 1 IN Byte Count
+xdata at 0xE690 volatile BYTE EP2BCH;  // Endpoint 2 Byte Count H
+xdata at 0xE691 volatile BYTE EP2BCL;  // Endpoint 2 Byte Count L
+xdata at 0xE694 volatile BYTE EP4BCH;  // Endpoint 4 Byte Count H
+xdata at 0xE695 volatile BYTE EP4BCL;  // Endpoint 4 Byte Count L
+xdata at 0xE698 volatile BYTE EP6BCH;  // Endpoint 6 Byte Count H
+xdata at 0xE699 volatile BYTE EP6BCL;  // Endpoint 6 Byte Count L
+xdata at 0xE69C volatile BYTE EP8BCH;  // Endpoint 8 Byte Count H
+xdata at 0xE69D volatile BYTE EP8BCL;  // Endpoint 8 Byte Count L
+xdata at 0xE6A0 volatile BYTE EP0CS;  // Endpoint  Control and Status
+xdata at 0xE6A1 volatile BYTE EP1OUTCS;  // Endpoint 1 OUT Control and Status
+xdata at 0xE6A2 volatile BYTE EP1INCS;  // Endpoint 1 IN Control and Status
+xdata at 0xE6A3 volatile BYTE EP2CS;  // Endpoint 2 Control and Status
+xdata at 0xE6A4 volatile BYTE EP4CS;  // Endpoint 4 Control and Status
+xdata at 0xE6A5 volatile BYTE EP6CS;  // Endpoint 6 Control and Status
+xdata at 0xE6A6 volatile BYTE EP8CS;  // Endpoint 8 Control and Status
+xdata at 0xE6A7 volatile BYTE EP2FIFOFLGS;  // Endpoint 2 Flags
+xdata at 0xE6A8 volatile BYTE EP4FIFOFLGS;  // Endpoint 4 Flags
+xdata at 0xE6A9 volatile BYTE EP6FIFOFLGS;  // Endpoint 6 Flags
+xdata at 0xE6AA volatile BYTE EP8FIFOFLGS;  // Endpoint 8 Flags
+xdata at 0xE6AB volatile BYTE EP2FIFOBCH;  // EP2 FIFO total byte count H
+xdata at 0xE6AC volatile BYTE EP2FIFOBCL;  // EP2 FIFO total byte count L
+xdata at 0xE6AD volatile BYTE EP4FIFOBCH;  // EP4 FIFO total byte count H
+xdata at 0xE6AE volatile BYTE EP4FIFOBCL;  // EP4 FIFO total byte count L
+xdata at 0xE6AF volatile BYTE EP6FIFOBCH;  // EP6 FIFO total byte count H
+xdata at 0xE6B0 volatile BYTE EP6FIFOBCL;  // EP6 FIFO total byte count L
+xdata at 0xE6B1 volatile BYTE EP8FIFOBCH;  // EP8 FIFO total byte count H
+xdata at 0xE6B2 volatile BYTE EP8FIFOBCL;  // EP8 FIFO total byte count L
+xdata at 0xE6B3 volatile BYTE SUDPTRH;  // Setup Data Pointer high address byte
+xdata at 0xE6B4 volatile BYTE SUDPTRL;  // Setup Data Pointer low address byte
+xdata at 0xE6B5 volatile BYTE SUDPTRCTL;  // Setup Data Pointer Auto Mode
+xdata at 0xE6B8 volatile BYTE SETUPDAT[8];  // 8 bytes of SETUP data
+
+// GPIF
+
+xdata at 0xE6C0 volatile BYTE GPIFWFSELECT;  // Waveform Selector
+xdata at 0xE6C1 volatile BYTE GPIFIDLECS;  // GPIF Done, GPIF IDLE drive mode
+xdata at 0xE6C2 volatile BYTE GPIFIDLECTL;  // Inactive Bus, CTL states
+xdata at 0xE6C3 volatile BYTE GPIFCTLCFG;  // CTL OUT pin drive
+xdata at 0xE6C4 volatile BYTE GPIFADRH;  // GPIF Address H
+xdata at 0xE6C5 volatile BYTE GPIFADRL;  // GPIF Address L
+
+xdata at 0xE6CE volatile BYTE GPIFTCB3;  // GPIF Transaction Count Byte 3
+xdata at 0xE6CF volatile BYTE GPIFTCB2;  // GPIF Transaction Count Byte 2
+xdata at 0xE6D0 volatile BYTE GPIFTCB1;  // GPIF Transaction Count Byte 1
+xdata at 0xE6D1 volatile BYTE GPIFTCB0;  // GPIF Transaction Count Byte 0
+
+xdata at 0xE6D2 volatile BYTE EP2GPIFFLGSEL;  // EP2 GPIF Flag select
+xdata at 0xE6D3 volatile BYTE EP2GPIFPFSTOP;  // Stop GPIF EP2 transaction on prog. flag
+xdata at 0xE6D4 volatile BYTE EP2GPIFTRIG;  // EP2 FIFO Trigger
+xdata at 0xE6DA volatile BYTE EP4GPIFFLGSEL;  // EP4 GPIF Flag select
+xdata at 0xE6DB volatile BYTE EP4GPIFPFSTOP;  // Stop GPIF EP4 transaction on prog. flag
+xdata at 0xE6DC volatile BYTE EP4GPIFTRIG;  // EP4 FIFO Trigger
+xdata at 0xE6E2 volatile BYTE EP6GPIFFLGSEL;  // EP6 GPIF Flag select
+xdata at 0xE6E3 volatile BYTE EP6GPIFPFSTOP;  // Stop GPIF EP6 transaction on prog. flag
+xdata at 0xE6E4 volatile BYTE EP6GPIFTRIG;  // EP6 FIFO Trigger
+xdata at 0xE6EA volatile BYTE EP8GPIFFLGSEL;  // EP8 GPIF Flag select
+xdata at 0xE6EB volatile BYTE EP8GPIFPFSTOP;  // Stop GPIF EP8 transaction on prog. flag
+xdata at 0xE6EC volatile BYTE EP8GPIFTRIG;  // EP8 FIFO Trigger
+xdata at 0xE6F0 volatile BYTE XGPIFSGLDATH;  // GPIF Data H (16-bit mode only)
+xdata at 0xE6F1 volatile BYTE XGPIFSGLDATLX;  // Read/Write GPIF Data L & trigger transac
+xdata at 0xE6F2 volatile BYTE XGPIFSGLDATLNOX;  // Read GPIF Data L, no transac trigger
+xdata at 0xE6F3 volatile BYTE GPIFREADYCFG;  // Internal RDY,Sync/Async, RDY5CFG
+xdata at 0xE6F4 volatile BYTE GPIFREADYSTAT;  // RDY pin states
+xdata at 0xE6F5 volatile BYTE GPIFABORT;  // Abort GPIF cycles
+
+// UDMA
+
+xdata at 0xE6C6 volatile BYTE FLOWSTATE; //Defines GPIF flow state
+xdata at 0xE6C7 volatile BYTE FLOWLOGIC; //Defines flow/hold decision criteria
+xdata at 0xE6C8 volatile BYTE FLOWEQ0CTL; //CTL states during active flow state
+xdata at 0xE6C9 volatile BYTE FLOWEQ1CTL; //CTL states during hold flow state
+xdata at 0xE6CA volatile BYTE FLOWHOLDOFF;
+xdata at 0xE6CB volatile BYTE FLOWSTB; //CTL/RDY Signal to use as master data strobe 
+xdata at 0xE6CC volatile BYTE FLOWSTBEDGE; //Defines active master strobe edge
+xdata at 0xE6CD volatile BYTE FLOWSTBHPERIOD; //Half Period of output master strobe
+xdata at 0xE60C volatile BYTE GPIFHOLDAMOUNT; //Data delay shift 
+xdata at 0xE67D volatile BYTE UDMACRCH; //CRC Upper byte
+xdata at 0xE67E volatile BYTE UDMACRCL; //CRC Lower byte
+xdata at 0xE67F volatile BYTE UDMACRCQUAL; //UDMA In only, host terminated use only
+
+// Endpoint Buffers
+
+xdata at 0xE740 volatile BYTE EP0BUF[64];  // EP0 IN-OUT buffer
+xdata at 0xE780 volatile BYTE EP1OUTBUF[64];  // EP1-OUT buffer
+xdata at 0xE7C0 volatile BYTE EP1INBUF[64];  // EP1-IN buffer
+xdata at 0xF000 volatile BYTE EP2FIFOBUF[1024];  // 512/1024-byte EP2 buffer (IN or OUT)
+xdata at 0xF400 volatile BYTE EP4FIFOBUF[1024];  // 512 byte EP4 buffer (IN or OUT)
+xdata at 0xF800 volatile BYTE EP6FIFOBUF[1024];  // 512/1024-byte EP6 buffer (IN or OUT)
+xdata at 0xFC00 volatile BYTE EP8FIFOBUF[1024];  // 512 byte EP8 buffer (IN or OUT)
+
+// Error Correction Code (ECC) Registers (FX2LP/FX1 only)
+
+xdata at 0xE628 volatile BYTE ECCCFG;  // ECC Configuration
+xdata at 0xE629 volatile BYTE ECCRESET;  // ECC Reset
+xdata at 0xE62A volatile BYTE ECC1B0;  // ECC1 Byte 0
+xdata at 0xE62B volatile BYTE ECC1B1;  // ECC1 Byte 1
+xdata at 0xE62C volatile BYTE ECC1B2;  // ECC1 Byte 2
+xdata at 0xE62D volatile BYTE ECC2B0;  // ECC2 Byte 0
+xdata at 0xE62E volatile BYTE ECC2B1;  // ECC2 Byte 1
+xdata at 0xE62F volatile BYTE ECC2B2;  // ECC2 Byte 2
+
+// Feature Registers  (FX2LP/FX1 only)
+xdata at 0xE50D volatile BYTE GPCR2;  // Chip Features
+
+/**
+ * SFRs below
+ *  According to TRM 15.2, only rows 0 and 8 of the SFRs are bit addressible
+ *  row 0: IOA, IOB, IOC, IOD, SCON1, PSW, ACC, B
+ *  row 8: TCON, SCON0, IE, IP, T2CON, IECON, EIE, EIP
+ *
+ *  All others have to move a byte to the SRF address
+ **/
+
+sfr at 0x80 IOA;
+         /*  IOA  */
+         sbit at 0x80 + 0 PA0;
+         sbit at 0x80 + 1 PA1;
+         sbit at 0x80 + 2 PA2;
+         sbit at 0x80 + 3 PA3;
+         sbit at 0x80 + 4 PA4;
+         sbit at 0x80 + 5 PA5;
+         sbit at 0x80 + 6 PA6;
+         sbit at 0x80 + 7 PA7;
+sfr at 0x81 SP;
+sfr at 0x82 DPL;
+sfr at 0x83 DPH;
+sfr at 0x84 DPL1;
+sfr at 0x85 DPH1;
+sfr at 0x86 DPS;
+sfr at 0x87 PCON;
+sfr at 0x88 TCON;
+         /*  TCON  */
+         sbit at 0x88+0 IT0;
+         sbit at 0x88+1 IE0;
+         sbit at 0x88+2 IT1;
+         sbit at 0x88+3 IE1;
+         sbit at 0x88+4 TR0;
+         sbit at 0x88+5 TF0;
+         sbit at 0x88+6 TR1;
+         sbit at 0x88+7 TF1;
+sfr at 0x89 TMOD;
+sfr at 0x8A TL0;
+sfr at 0x8B TL1;
+sfr at 0x8C TH0;
+sfr at 0x8D TH1;
+sfr at 0x8E CKCON;
+sfr at 0x90 IOB;
+         /*  IOB  */
+         sbit at 0x90 + 0 PB0;
+         sbit at 0x90 + 1 PB1;
+         sbit at 0x90 + 2 PB2;
+         sbit at 0x90 + 3 PB3;
+         sbit at 0x90 + 4 PB4;
+         sbit at 0x90 + 5 PB5;
+         sbit at 0x90 + 6 PB6;
+         sbit at 0x90 + 7 PB7;
+sfr at 0x91 EXIF;
+         
+//sfr at 0x92 MPAGE;
+sfr at 0x92 _XPAGE; // same as MPAGE for pdata sfr access w/ sdcc
+sfr at 0x98 SCON0;
+         /*  SCON0  */
+         sbit at 0x98+0 RI;
+         sbit at 0x98+1 TI;
+         sbit at 0x98+2 RB8;
+         sbit at 0x98+3 TB8;
+         sbit at 0x98+4 REN;
+         sbit at 0x98+5 SM2;
+         sbit at 0x98+6 SM1;
+         sbit at 0x98+7 SM0;
+sfr at 0x99 SBUF0;
+
+sfr at 0x9A AUTOPTRH1; 
+sfr at 0x9B AUTOPTRL1; 
+sfr at 0x9D AUTOPTRH2;
+sfr at 0x9E AUTOPTRL2; 
+
+sfr at 0xA0 IOC;
+         /*  IOC  */
+         sbit at 0xA0 + 0 PC0;
+         sbit at 0xA0 + 1 PC1;
+         sbit at 0xA0 + 2 PC2;
+         sbit at 0xA0 + 3 PC3;
+         sbit at 0xA0 + 4 PC4;
+         sbit at 0xA0 + 5 PC5;
+         sbit at 0xA0 + 6 PC6;
+         sbit at 0xA0 + 7 PC7;
+sfr at 0xA1 INT2CLR;
+sfr at 0xA2 INT4CLR;
+
+sfr at 0xA8 IE;
+         /*  IE  */
+         sbit at 0xA8+0 EX0;
+         sbit at 0xA8+1 ET0;
+         sbit at 0xA8+2 EX1;
+         sbit at 0xA8+3 ET1;
+         sbit at 0xA8+4 ES0;
+         sbit at 0xA8+5 ET2;
+         sbit at 0xA8+6 ES1;
+         sbit at 0xA8+7 EA;
+
+sfr at 0xAA EP2468STAT;
+sfr at 0xAB EP24FIFOFLGS;
+sfr at 0xAC EP68FIFOFLGS;
+sfr at 0xAF AUTOPTRSETUP;
+sfr at 0xB0 IOD;
+         /*  IOD  */
+         sbit at 0xB0 + 0 PD0;
+         sbit at 0xB0 + 1 PD1;
+         sbit at 0xB0 + 2 PD2;
+         sbit at 0xB0 + 3 PD3;
+         sbit at 0xB0 + 4 PD4;
+         sbit at 0xB0 + 5 PD5;
+         sbit at 0xB0 + 6 PD6;
+         sbit at 0xB0 + 7 PD7;
+sfr at 0xB1 IOE;
+sfr at 0xB2 OEA;
+sfr at 0xB3 OEB;
+sfr at 0xB4 OEC;
+sfr at 0xB5 OED;
+sfr at 0xB6 OEE;
+
+sfr at 0xB8 IP;
+         /*  IP  */
+         sbit at 0xB8+0 PX0;
+         sbit at 0xB8+1 PT0;
+         sbit at 0xB8+2 PX1;
+         sbit at 0xB8+3 PT1;
+         sbit at 0xB8+4 PS0;
+         sbit at 0xB8+5 PT2;
+         sbit at 0xB8+6 PS1;
+
+sfr at 0xBA EP01STAT;
+sfr at 0xBB GPIFTRIG;
+
+sfr at 0xBD GPIFSGLDATH;
+sfr at 0xBE GPIFSGLDATLX;
+sfr at 0xBF GPIFSGLDATLNOX;
+
+sfr at 0xC0 SCON1;
+         /*  SCON1  */
+         sbit at 0xC0+0 RI1;
+         sbit at 0xC0+1 TI1;
+         sbit at 0xC0+2 RB81;
+         sbit at 0xC0+3 TB81;
+         sbit at 0xC0+4 REN1;
+         sbit at 0xC0+5 SM21;
+         sbit at 0xC0+6 SM11;
+         sbit at 0xC0+7 SM01;
+sfr at 0xC1 SBUF1;
+sfr at 0xC8 T2CON;
+         /*  T2CON  */
+         sbit at 0xC8+0 CP_RL2;
+         sbit at 0xC8+1 C_T2;
+         sbit at 0xC8+2 TR2;
+         sbit at 0xC8+3 EXEN2;
+         sbit at 0xC8+4 TCLK;
+         sbit at 0xC8+5 RCLK;
+         sbit at 0xC8+6 EXF2;
+         sbit at 0xC8+7 TF2;
+sfr at 0xCA RCAP2L;
+sfr at 0xCB RCAP2H;
+sfr at 0xCC TL2;
+sfr at 0xCD TH2;
+sfr at 0xD0 PSW;
+         /*  PSW  */
+         sbit at 0xD0+0 P;
+         sbit at 0xD0+1 FL;
+         sbit at 0xD0+2 OV;
+         sbit at 0xD0+3 RS0;
+         sbit at 0xD0+4 RS1;
+         sbit at 0xD0+5 F0;
+         sbit at 0xD0+6 AC;
+         sbit at 0xD0+7 CY;
+sfr at 0xD8 EICON; // Was WDCON in DS80C320; Bit Values differ from Reg320
+         /*  EICON  */
+         sbit at 0xD8+3 INT6;
+         sbit at 0xD8+4 RESI;
+         sbit at 0xD8+5 ERESI;
+         sbit at 0xD8+7 SMOD1;
+sfr at 0xE0 ACC;
+sfr at 0xE8 EIE; // EIE Bit Values differ from Reg320
+         /*  EIE  */
+         sbit at 0xE8+0 EUSB;
+         sbit at 0xE8+1 EI2C;
+         sbit at 0xE8+2 EIEX4;
+         sbit at 0xE8+3 EIEX5;
+         sbit at 0xE8+4 EIEX6;
+sfr at 0xF0 B;
+sfr at 0xF8 EIP; // EIP Bit Values differ from Reg320
+         /*  EIP  */
+         sbit at 0xF8+0 PUSB;
+         sbit at 0xF8+1 PI2C;
+         sbit at 0xF8+2 EIPX4;
+         sbit at 0xF8+3 EIPX5;
+         sbit at 0xF8+4 EIPX6;
+
+
+/* CPU Control & Status Register (CPUCS) */
+#define bmPRTCSTB    bmBIT5
+#define bmCLKSPD     (bmBIT4 | bmBIT3)
+#define bmCLKSPD1    bmBIT4
+#define bmCLKSPD0    bmBIT3
+#define bmCLKINV     bmBIT2
+#define bmCLKOE      bmBIT1
+#define bm8051RES    bmBIT0
+/* Port Alternate Configuration Registers */
+/* Port A (PORTACFG) */
+#define bmFLAGD      bmBIT7
+#define bmINT1       bmBIT1
+#define bmINT0       bmBIT0
+/* Port C (PORTCCFG) */
+#define bmGPIFA7     bmBIT7
+#define bmGPIFA6     bmBIT6
+#define bmGPIFA5     bmBIT5
+#define bmGPIFA4     bmBIT4
+#define bmGPIFA3     bmBIT3
+#define bmGPIFA2     bmBIT2
+#define bmGPIFA1     bmBIT1
+#define bmGPIFA0     bmBIT0
+/* Port E (PORTECFG) */
+#define bmGPIFA8     bmBIT7
+#define bmT2EX       bmBIT6
+#define bmINT6       bmBIT5
+#define bmRXD1OUT    bmBIT4
+#define bmRXD0OUT    bmBIT3
+#define bmT2OUT      bmBIT2
+#define bmT1OUT      bmBIT1
+#define bmT0OUT      bmBIT0
+
+/* I2C Control & Status Register (I2CS) */
+#define bmSTART      bmBIT7
+#define bmSTOP       bmBIT6
+#define bmLASTRD     bmBIT5
+#define bmID         (bmBIT4 | bmBIT3)
+#define bmBERR       bmBIT2
+#define bmACK        bmBIT1
+#define bmDONE       bmBIT0
+/* I2C Control Register (I2CTL) */
+#define bmSTOPIE     bmBIT1
+#define bm400KHZ     bmBIT0
+/* Interrupt 2 (USB) Autovector Register (INT2IVEC) */
+#define bmIV4        bmBIT6
+#define bmIV3        bmBIT5
+#define bmIV2        bmBIT4
+#define bmIV1        bmBIT3
+#define bmIV0        bmBIT2
+/* USB Interrupt Request & Enable Registers (USBIE/USBIRQ) */
+#define bmEP0ACK     bmBIT6
+#define bmHSGRANT    bmBIT5
+#define bmURES       bmBIT4
+#define bmSUSP       bmBIT3
+#define bmSUTOK      bmBIT2
+#define bmSOF        bmBIT1
+#define bmSUDAV      bmBIT0
+/* USBERRIE/IRQ */
+#define bmERRLIMIT  bmBIT0
+#define bmISOEP2    bmBIT4
+#define bmISOEP4    bmBIT5
+#define bmISOEP6    bmBIT6
+#define bmISOEP8    bmBIT7
+
+/* Endpoint Interrupt & Enable Registers (EPIE/EPIRQ) */
+#define bmEP0IN     bmBIT0
+#define bmEP0OUT    bmBIT1
+#define bmEP1IN     bmBIT2
+#define bmEP1OUT    bmBIT3
+#define bmEP2       bmBIT4
+#define bmEP4       bmBIT5
+#define bmEP6       bmBIT6
+#define bmEP8       bmBIT7
+/* Breakpoint register (BREAKPT) */
+#define bmBREAK      bmBIT3
+#define bmBPPULSE    bmBIT2
+#define bmBPEN       bmBIT1
+/* Interrupt 2 & 4 Setup (INTSETUP) */
+#define bmAV2EN      bmBIT3
+#define INT4IN       bmBIT1
+#define bmAV4EN      bmBIT0
+/* USB Control & Status Register (USBCS) */
+#define bmHSM        bmBIT7
+#define bmDISCON     bmBIT3
+#define bmNOSYNSOF   bmBIT2
+#define bmRENUM      bmBIT1
+#define bmSIGRESUME  bmBIT0
+/* Wakeup Control and Status Register (WAKEUPCS) */
+#define bmWU2        bmBIT7
+#define bmWU         bmBIT6
+#define bmWU2POL     bmBIT5
+#define bmWUPOL      bmBIT4
+#define bmDPEN       bmBIT2
+#define bmWU2EN      bmBIT1
+#define bmWUEN       bmBIT0
+/* End Point 0 Control & Status Register (EP0CS) */
+#define bmHSNAK      bmBIT7
+/* End Point 0-1 Control & Status Registers (EP0CS/EP1OUTCS/EP1INCS) */
+#define bmEPBUSY     bmBIT1
+#define bmEPSTALL    bmBIT0
+/* End Point 2-8 Control & Status Registers (EP2CS/EP4CS/EP6CS/EP8CS) */
+#define bmNPAK       (bmBIT6 | bmBIT5 | bmBIT4)
+#define bmEPFULL     bmBIT3
+#define bmEPEMPTY    bmBIT2
+/* Endpoint Status (EP2468STAT) SFR bits */
+#define bmEP8FULL    bmBIT7
+#define bmEP8EMPTY   bmBIT6
+#define bmEP6FULL    bmBIT5
+#define bmEP6EMPTY   bmBIT4
+#define bmEP4FULL    bmBIT3
+#define bmEP4EMPTY   bmBIT2
+#define bmEP2FULL    bmBIT1
+#define bmEP2EMPTY   bmBIT0
+/* Endpoint Config (EP[24]CFG) */
+#define bmBUF       (bmBIT0|bmBIT1)
+/* Endpoint Config (EP[2468]CFG) */
+#define bmSIZE      bmBIT3
+#define bmTYPE      (bmBIT4|bmBIT5)
+#define bmDIR       bmBIT6
+#define bmVALID     bmBIT7
+/* SETUP Data Pointer Auto Mode (SUDPTRCTL) */
+#define bmSDPAUTO    bmBIT0
+/* Endpoint Data Toggle Control (TOGCTL) */
+#define bmQUERYTOGGLE  bmBIT7
+#define bmSETTOGGLE    bmBIT6
+#define bmRESETTOGGLE  bmBIT5
+#define bmTOGCTLEPMASK bmBIT3 | bmBIT2 | bmBIT1 | bmBIT0
+/* IBN (In Bulk Nak) enable and request bits (IBNIE/IBNIRQ) */
+#define bmEP8IBN     bmBIT5
+#define bmEP6IBN     bmBIT4
+#define bmEP4IBN     bmBIT3
+#define bmEP2IBN     bmBIT2
+#define bmEP1IBN     bmBIT1
+#define bmEP0IBN     bmBIT0
+
+/* PING-NAK enable and request bits (NAKIE/NAKIRQ) */
+#define bmEP8PING     bmBIT7
+#define bmEP6PING     bmBIT6
+#define bmEP4PING     bmBIT5
+#define bmEP2PING     bmBIT4
+#define bmEP1PING     bmBIT3
+#define bmEP0PING     bmBIT2
+#define bmIBN         bmBIT0
+
+/* Interface Configuration bits (IFCONFIG) */
+#define bmIFCLKSRC    bmBIT7
+#define bm3048MHZ     bmBIT6
+#define bmIFCLKOE     bmBIT5
+#define bmIFCLKPOL    bmBIT4
+#define bmASYNC       bmBIT3
+#define bmGSTATE      bmBIT2
+#define bmIFCFG1      bmBIT1
+#define bmIFCFG0      bmBIT0
+#define bmIFCFGMASK   (bmIFCFG0 | bmIFCFG1)
+#define bmIFGPIF      bmIFCFG1
+
+/* EP 2468 FIFO Configuration bits (EP2FIFOCFG,EP4FIFOCFG,EP6FIFOCFG,EP8FIFOCFG) */
+#define bmINFM       bmBIT6
+#define bmOEP        bmBIT5
+#define bmAUTOOUT    bmBIT4
+#define bmAUTOIN     bmBIT3
+#define bmZEROLENIN  bmBIT2
+#define bmWORDWIDE   bmBIT0
+
+/* Chip Revision Control Bits (REVCTL) - used to ebable/disable revision specidic
+   features */ 
+#define bmNOAUTOARM    bmBIT1
+#define bmSKIPCOMMIT   bmBIT0
+
+/* Fifo Reset bits (FIFORESET) */
+#define bmNAKALL       bmBIT7
+
+/* Chip Feature Register (GPCR2) */
+#define bmFULLSPEEDONLY    bmBIT4
+
+#endif   /* FX2REGS_H */
+/**
+ * Copyright (C) 2008 Ubixum, Inc. 
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ **/
+
+
+#ifndef FXTYPES_H
+#define FXTYPES_H
+
+typedef unsigned int WORD;
+typedef unsigned char BYTE;
+typedef unsigned long DWORD;
+typedef unsigned char BOOL; 
+typedef enum {
+ FALSE=0,
+ TRUE
+} BOOL_VALS;
+
+/*-----------------------------------------------------------------------------
+   Bit Masks
+-----------------------------------------------------------------------------*/
+
+#define bmBIT0	1
+#define bmBIT1	2
+#define bmBIT2	4
+#define bmBIT3	8
+#define bmBIT4	16
+#define bmBIT5	32
+#define bmBIT6	64
+#define bmBIT7	128
+
+#endif
+/**
+ * Copyright (C) 2008 Ubixum, Inc. 
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ **/
+
+#ifndef GPIF_H
+#define GPIF_H
+
+#include "fx2types.h"
+
+
+/**
+ * Gpif designer generates a c file with waveform data.
+ * Copy the WaveData[128] array
+ * and the InitData[7] to your code somewhere
+ * Then this function is pretty much the reset of the generated
+ * code but ported to sdcc.
+ *
+ * uses syncdelay of 4 which might not be long enough if peripheral
+ * runs slower than 30mhz
+ *
+ * IFCONFIG is set with IFCFG[1:0] = 10 for GPIF master but you still
+ * have to set the ifclk, polarity, and the rest of the bits
+ **/
+
+void gpif_init( BYTE* waveform, BYTE* initdata );
+
+/**
+ * Uses the correct bytes from your flowstates array.
+ * This may or may not be needed depending on whether
+ * your waveform data uses flowstates.  If you don't
+ * know if you need them or not, you probably don't.
+ *
+ * flowstates should have 36 elements.
+ * bank should be 0-3
+ **/
+void gpif_setflowstate( BYTE* flowstates, BYTE bank);
+
+
+
+// These defines/functions pretty much out of the TRM 10.4
+#define GPIFTRGWR 0
+#define GPIFTRGRD 4
+typedef enum {
+    GPIF_EP2 = 0,
+    GPIF_EP4 = 1,
+    GPIF_EP6 = 2,
+    GPIF_EP8 = 3
+} GPIF_EP_NUM;
+
+/**
+ * Use the gpif to read a single byte at a time.
+ * Read len bytes and store in res
+ *
+ * This is coded to use 16 bit data bus.  Len
+ * Should be multiple of 2.  Should this function
+ * be coded to be smart enough for 8 bit bus and 16 both
+ * or should there be a different function?
+ **/
+void gpif_single_read( BYTE* res , WORD len) ;
+
+void gpif_fifo_read ( GPIF_EP_NUM ep_num );
+
+void gpif_fifo_write( GPIF_EP_NUM ep_num );
+
+#endif
+/**
+ * Copyright (C) 2008 Ubixum, Inc. 
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ **/
+
+
+#ifndef I2C_H
+#define I2C_H
+
+#include "fx2types.h"
+
+void i2c_write ( BYTE addr, WORD len, BYTE* buf);
+
+void i2c_read ( BYTE addr, WORD len, BYTE* buf);
+
+void eeprom_read( BYTE prom_addr, WORD addr, WORD len, BYTE* buf);
+
+void eeprom_write( BYTE prom_addr, WORD addr, WORD len, BYTE* buf);
+
+#endif
+/**
+ * Copyright (C) 2008 Ubixum, Inc. 
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ **/
+
+#ifndef LIGHTS_H
+#define LIGHTS_H
+
+#include "fx2types.h"
+#include "delay.h"
+
+volatile xdata at 0x8800 BYTE D2ON;
+volatile xdata at 0x8000 BYTE D2OFF;
+volatile xdata at 0x9800 BYTE D3ON;
+volatile xdata at 0x9000 BYTE D3OFF;
+volatile xdata at 0xA800 BYTE D4ON;
+volatile xdata at 0xA000 BYTE D4OFF;
+volatile xdata at 0xB800 BYTE D5ON;
+volatile xdata at 0xB000 BYTE D5OFF;
+extern xdata BYTE light_dummy;
+
+/**
+ * easier to use macros defined below 
+**/
+//void activate_light ( volatile BYTE xdata *light ) ;
+#define activate_light(LIGHT_ADDR) light_dummy=*(LIGHT_ADDR)
+#define activate_light_delay(LIGHT_ADDR,millis) activate_light(LIGHT_ADDR); delay(millis)
+//void activate_light_delay ( volatile BYTE xdata* light, WORD millis );
+
+#define d2on() activate_light(&D2ON)
+#define d2off() activate_light(&D2OFF)
+#define d3on() activate_light(&D3ON)
+#define d3off() activate_light(&D3OFF)
+#define d4on() activate_light(&D4ON)
+#define d4off() activate_light(&D4OFF)
+#define d5on() activate_light(&D5ON)
+#define d5off() activate_light(&D5OFF)
+
+#endif
+/**
+ * Copyright (C) 2008 Ubixum, Inc. 
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ **/
+
+#include "fx2types.h"
+
+
+/**
+ * This function inits sio0 to use T2CON (timer 2)
+ * See TRM 14.3.4.1 (Table 14-16)
+ * Certain baud rates have too high an error rate to work.  All baud rates are .16%
+ * except:
+ *          12MHZ      24MHZ
+ *   57600  -6.99%
+ *   38400  -2.34%     -2.34%
+ *   19200  -2.34%
+ *
+ *   Possible Baud rates:
+ *    2400
+ *    4800
+ *    9600
+ *    19200
+ *    28800
+ *    38400
+ *    57600
+ *
+ *    Any of these rates should work except 57600 at 12mhz.  -2.34% is pushing
+ *    most hardware specs for working.  All rates at 48mhz work at .16%
+ **/
+
+void sio0_init( WORD baud_rate ) __critical ; // baud_rate max should be 57600 since int=2 bytes
+/*
+ putchar('\n') or putchar('\r') both transmit \r\n
+ Just use one or the other. (This makes terminal echo easy)
+*/
+void putchar(char c);
+char getchar();
+/**
+ * Copyright (C) 2008 Ubixum, Inc. 
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ **/
+
+#ifndef SETUPDAT_H
+#define SETUPDAT_H
+
+#include "fx2regs.h"
+#include "delay.h"
+
+/*
+ This module needs initialized with a device descriptor.
+ NOTE that your descriptors need to be located in code memory
+ to use the SUDPTRH:L to auto transfer the data
+ 
+ and vendor commands handler.  You have to provide callbacks.
+
+DEVICE DESCRIPTORS
+ 
+ // copy the dscr_asm file from the lib dir to your
+ // own project directory, change it how
+ // you want, and link it against your project
+
+VENDOR COMMANDS
+
+  0xA0 is handled by ez-usb firmware.  (Upload/Download ram)
+  0xA1-0xAF is reserved for other ez-usb functions so don't use that
+  Any other value (Above 0x0C anyway) can be used for device specific
+  commands.
+  
+  If you include this file, you need to define a function for vendor
+  commands even if you don't want to implement any vendor commands.
+  The function should return TRUE if you handled the command and FALSE
+  if you didn't.  The handle_setup function calls
+  EP0CS |= bmHSNAK;
+  before returning so there is no reason to set that bit in your
+  vendor command handler.  (You do need to Set EP0 data and
+  byte counts appropriately though.)
+  
+  // return TRUE if you handle the command 
+  // you can directly get SETUPDAT[0-7] for the data sent with the command
+  BOOL handle_vendorcommand(BYTE cmd) { return FALSE; }
+  // a note  on vencor commands
+  // this from the usb spec for requesttype
+        D7 Data Phase Transfer Direction
+        0 = Host to Device
+        1 = Device to Host
+        D6..5 Type
+        0 = Standard
+        1 = Class
+        2 = Vendor
+        3 = Reserved
+        D4..0 Recipient
+        0 = Device
+        1 = Interface
+        2 = Endpoint
+        3 = Other
+        4..31 = Reserved
+  // if you want libusb to send data back to the host via ep0, you need to make
+  // sure the requesttype had 1 in bit 7.  This is for libusb on linux anyway.
+  
+  
+  // set *alt_ifc to the current alt interface for ifc
+  BOOL handle_get_interface(BYTE ifc, BYTE* alt_ifc) { *ifc=0;*alt_ifc=0;}
+  // return TRUE if you set the interface requested
+  // NOTE this function should reconfigure and reset the endpoints
+  // according to the interface descriptors you provided.
+  BOOL handle_set_interface(BYTE ifc,BYTE alt_ifc) { return TRUE; }
+  // handle getting and setting the configuration
+  // 0 is the default.  If you support more than one config
+  // keep track of the config number and return the correct number
+  // config numbers are set int the dscr file.
+  BYTE handle_get_configuration() { return 1; }
+  // return TRUE if you handle this request
+  // NOTE changing config requires the device to reset all the endpoints
+  BOOL handle_set_configuration(BYTE cfg) { return FALSE; }
+  // ep num (byte 7 is dir 1=IN,0=OUT)
+  // client needs to reset the endpoint to default state
+  void handle_reset_ep(BYTE ep) { }
+*/
+
+// for ease functions
+
+#define STALLEP0() EP0CS |= bmEPSTALL
+// to use this, the endpoint needs bit 8 to be IN=1,OUT=0
+#define RESETTOGGLE(ep) TOGCTL = (ep&0x0F) + ((ep&0x80)>>3); TOGCTL |= bmRESETTOGGLE
+#define RENUMERATE() USBCS|=bmDISCON|bmRENUM;delay(1500);USBCS &= ~bmDISCON
+
+#define SETUP_VALUE() MAKEWORD(SETUPDAT[3],SETUPDAT[2])
+#define SETUP_INDEX() MAKEWORD(SETUPDAT[5],SETUPDAT[4])
+#define SETUP_LENGTH() MAKEWORD(SETUPDAT[7],SETUPDAT[6]) 
+
+
+// see TRM 2-3
+// here are the usb setup data commands
+// these are the usb spec pretty much
+
+typedef enum {
+    GET_STATUS,
+    CLEAR_FEATURE,
+    // 0x02 is reserved
+    SET_FEATURE=0x03,
+    // 0x04 is reserved
+    SET_ADDRESS=0x05, // this is handled by EZ-USB core unless RENUM=0
+    GET_DESCRIPTOR,
+    SET_DESCRIPTOR,
+    GET_CONFIGURATION,
+    SET_CONFIGURATION,
+    GET_INTERFACE,
+    SET_INTERFACE,
+    SYNC_FRAME
+} SETUP_DATA;
+
+
+/**
+ * returns the control/status register for an end point
+ * (bit 7=1 for IN, 0 for out
+ **/
+xdata BYTE* ep_addr(BYTE ep);
+
+/*
+ You can call this function directly if you are polling
+ for setup data in your main loop.
+ You can also use the usbjt and enable the sudav isr
+ and call the function from withing the sudav isr routine
+*/
+void handle_setupdata();
+
+
+/**
+    For devices to properly handle usb hispeed
+    (This is if your descriptor has high speed and full speed versions
+     and it should since the fx2lp is a high speed capable device
+    )
+    enable both USBRESET and HISPEED interrupts and
+    call this function to switch the descriptors
+**/
+void handle_hispeed();
+
+
+/* descriptor types */
+#define DSCR_DEVICE_TYPE 1
+#define DSCR_CONFIG_TYPE 2
+#define DSCR_STRING_TYPE 3
+#define DSCR_DEVQUAL_TYPE 6
+#define DSCR_OTHERSPD_TYPE 7
+
+/* usb spec 2 */
+#define DSCR_BCD 2
+
+
+/* device descriptor */
+#define DSCR_DEVICE_LEN 18
+
+typedef struct {
+    BYTE dsc_len; // descriptor length (18 for this )
+    BYTE dsc_type; // dscr type
+    WORD bcd; // bcd
+    BYTE dev_class; // device class
+    BYTE dev_subclass; // sub class
+    BYTE dev_protocol; // sub sub class
+    BYTE max_pkt; // max packet size
+    WORD vendor_id;
+    WORD product_id;
+    WORD dev_version; // product version id
+    BYTE idx_manstr; //  manufacturer string index
+    BYTE idx_devstr; // product string index
+    BYTE idx_serstr; // serial number index
+    BYTE num_configs; // number of configurations
+        
+} DEVICE_DSCR;
+
+
+/* config descriptor */
+#define DSCR_CONFIG_LEN 9
+typedef struct {
+    BYTE dsc_len; // 9 for this one
+    BYTE dsc_type; // dscr type
+    
+} CONFIG_DSCR;
+
+/* string descriptor */
+typedef struct {
+    BYTE dsc_len;
+    BYTE dsc_type;
+    BYTE pstr;
+} STRING_DSCR;
+
+
+#endif
+/**
+ * Copyright (C) 2008 Ubixum, Inc. 
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ **/
+
+/**
+ * To use usbjt, you must tell the linker where to put the IN2JT.
+ * It must lie on a page boundary or your interrupts won't work right.
+ *
+ * example:
+ * -Wl"-b INT2JT = 0x1A00"
+ *
+ * Make sure that INT2JT doesn't overlap your other stuff!
+ **/
+
+#ifndef USBJT_H
+#define USBJT_H
+
+#include "fx2regs.h"
+
+
+
+
+// this causes usbjt to be included from the lib
+// not used for anything
+extern volatile BYTE INT2JT;
+// enable all interrupts (EA=1) separate from this macro
+#define USE_USB_INTS() {BYTE dummy=INT2JT;\
+                        EUSB=1;\
+                        INTSETUP|=bmAV2EN;}
+// don't use this if you want external pin generated int4 interrupts
+#define USE_GPIF_INTS() {BYTE dummy=INT2JT;\
+                        EIEX4=1;\
+                        INTSETUP|=bmAV4EN|INT4IN;}
+             
+
+
+#define CLEAR_USBINT() EXIF &= ~0x10
+#define CLEAR_GPIF() EXIF &= ~0x40
+
+#define ENABLE_SUDAV() USBIE|=bmSUDAV
+#define CLEAR_SUDAV() CLEAR_USBINT(); USBIRQ=bmSUDAV
+
+#define ENABLE_SOF() USBIE|=bmSOF
+#define CLEAR_SOF() CLEAR_USBINT(); USBIRQ=bmSOF
+
+#define ENABLE_SUSPEND() USBIE|=bmSUSP
+#define CLEAR_SUSPEND() CLEAR_USBINT(); USBIRQ=bmSUSP
+
+#define ENABLE_USBRESET() USBIE|= bmURES
+#define CLEAR_USBRESET() CLEAR_USBINT(); USBIRQ=bmURES
+
+#define ENABLE_HISPEED() USBIE|=bmHSGRANT
+#define CLEAR_HISPEED() CLEAR_USBINT(); USBIRQ=bmHSGRANT
+
+#define ENABLE_EP1IN() EPIE|=bmEP1IN;
+#define CLEAR_EP1IN() CLEAR_USBINT(); EPIRQ=bmEP1IN
+
+#define ENABLE_EP2() EPIE|=bmEP2;
+#define CLEAR_EP2() CLEAR_USBINT(); EPIRQ=bmEP2;
+
+#define ENABLE_EP2ISOERR() USBERRIE |= bmISOEP2;
+#define CLEAR_EP2ISOERR() CLEAR_USBINT(); USBERRIRQ = bmISOEP2
+
+
+#define ENABLE_GPIFDONE() GPIFIE |= 0x01;
+#define CLEAR_GPIFDONE() CLEAR_GPIF(); GPIFIRQ = 0x01;
+
+#define ENABLE_GPIFWF() GPIFIE |= 0x02;
+#define CLEAR_GPIFWF() GLEAR_GPIF(); GPIFIRQ = 0x02;
+
+/**
+ * ez-usb has 12 built in ISRs, to get
+ * sdcc to put these USB ISRs immediately
+ * after the other ISRs (and not waste space)
+ * we start at 13
+ **/
+typedef enum {
+  SUDAV_ISR=13,
+  SOF_ISR,
+  SUTOK_ISR,
+  SUSPEND_ISR,
+  USBRESET_ISR,
+  HISPEED_ISR,
+  EP0ACK_ISR,  
+  EP0IN_ISR,
+  EP0OUT_ISR,
+  EP1IN_ISR,
+  EP1OUT_ISR,
+  EP2_ISR,
+  EP4_ISR,
+  EP6_ISR,
+  EP8_ISR,
+  IBN_ISR,
+  EP0PING_ISR,
+  EP1PING_ISR,
+  EP2PING_ISR,
+  EP4PING_ISR,
+  EP6PING_ISR,
+  EP8PING_ISR,
+  ERRLIMIT_ISR,  
+  EP2ISOERR_ISR,
+  EP4ISOERR_ISR,
+  EP6ISOERR_ISR,
+  EP8ISOERR_ISR,
+  RESERVED_ISR,
+  EP2PF_ISR,
+  EP4PF_ISR,
+  EP6PF_ISR,
+  EP8PF_ISR,
+  EP2EF_ISR,
+  EP4EF_ISR,
+  EP6EF_ISR,
+  EP8EF_ISR,
+  EP2FF_ISR,
+  EP4FF_ISR,
+  EP6FF_ISR,
+  EP8FF_ISR,
+  GPIFDONE_ISR,
+  GPIFWF_ISR
+} USB_ISR;
+
+// you must include the predef of these in the file with your main
+// so lets just define them here
+
+void sudav_isr() interrupt SUDAV_ISR;
+void sof_isr() interrupt SOF_ISR;
+void sutok_isr() interrupt SUTOK_ISR;
+void suspend_isr() interrupt SUSPEND_ISR;
+void usbreset_isr() interrupt USBRESET_ISR;
+void hispeed_isr() interrupt HISPEED_ISR;
+void ep0ack_isr() interrupt EP0ACK_ISR;
+void ep0in_isr() interrupt EP0IN_ISR;
+void ep0out_isr() interrupt EP0OUT_ISR;
+void ep1in_isr() interrupt EP1IN_ISR;
+void ep1out_isr() interrupt EP1OUT_ISR;
+void ep2_isr() interrupt EP2_ISR;
+void ep4_isr() interrupt EP4_ISR;
+void ep6_isr() interrupt EP6_ISR;
+void ep8_isr() interrupt EP8_ISR;
+void ibn_isr() interrupt IBN_ISR;
+void ep0ping_isr() interrupt EP0PING_ISR;
+void ep1ping_isr() interrupt EP1PING_ISR;
+void ep2ping_isr() interrupt EP2PING_ISR;
+void ep4ping_isr() interrupt EP4PING_ISR;
+void ep6ping_isr() interrupt EP6PING_ISR;
+void ep8ping_isr() interrupt EP8PING_ISR;
+void errlimit_isr() interrupt ERRLIMIT_ISR;
+void ep2isoerr_isr() interrupt EP2ISOERR_ISR;
+void ep4isoerr_isr() interrupt EP4ISOERR_ISR;
+void ep6isoerr_isr() interrupt EP6ISOERR_ISR;
+void ep8isoerr_isr() interrupt EP8ISOERR_ISR;
+void spare_isr() interrupt RESERVED_ISR; // not used
+// gpif ints
+void ep2pf_isr() interrupt EP2PF_ISR;
+void ep4pf_isr() interrupt EP4PF_ISR;
+void ep6pf_isr() interrupt EP6PF_ISR;
+void ep8pf_isr() interrupt EP8PF_ISR;
+void ep2ef_isr() interrupt EP2EF_ISR;
+void ep4ef_isr() interrupt EP4EF_ISR;
+void ep6ef_isr() interrupt EP6EF_ISR;
+void ep8ef_isr() interrupt EP8EF_ISR;
+void ep2ff_isr() interrupt EP2FF_ISR;
+void ep4ff_isr() interrupt EP4FF_ISR;
+void ep6ff_isr() interrupt EP6FF_ISR;
+void ep8ff_isr() interrupt EP8FF_ISR;
+void gpifdone_isr() interrupt GPIFDONE_ISR;
+void gpifwf_isr() interrupt GPIFWF_ISR;
+
+
+// and for ease, here is a quick section you can copy paste
+// into your own code somewhere
+
+/*
+void sudav_isr() interrupt SUDAV_ISR {}
+void sof_isr() interrupt SOF_ISR {}
+void sutok_isr() interrupt SUTOK_ISR {}
+void suspend_isr() interrupt SUSPEND_ISR {}
+void usbreset_isr() interrupt USBRESET_ISR {}
+void hispeed_isr() interrupt HISPEED_ISR {}
+void ep0ack_isr() interrupt EP0ACK_ISR {}
+void ep0in_isr() interrupt EP0IN_ISR {}
+void ep0out_isr() interrupt EP0OUT_ISR {}
+void ep1in_isr() interrupt EP1IN_ISR {}
+void ep1out_isr() interrupt EP1OUT_ISR {}
+void ep2_isr() interrupt EP2_ISR {}
+void ep4_isr() interrupt EP4_ISR {}
+void ep6_isr() interrupt EP6_ISR {}
+void ep8_isr() interrupt EP8_ISR {}
+void ibn_isr() interrupt IBN_ISR {}
+void ep0ping_isr() interrupt EP0PING_ISR {}
+void ep1ping_isr() interrupt EP1PING_ISR {}
+void ep2ping_isr() interrupt EP2PING_ISR {}
+void ep4ping_isr() interrupt EP4PING_ISR {}
+void ep6ping_isr() interrupt EP6PING_ISR {}
+void ep8ping_isr() interrupt EP8PING_ISR {}
+void errlimit_isr() interrupt ERRLIMIT_ISR {}
+void ep2isoerr_isr() interrupt EP2ISOERR_ISR {}
+void ep4isoerr_isr() interrupt EP4ISOERR_ISR {}
+void ep6isoerr_isr() interrupt EP6ISOERR_ISR {}
+void ep8isoerr_isr() interrupt EP8ISOERR_ISR {}
+void spare_isr() interrupt RESERVED_ISR {}
+void ep2pf_isr() interrupt EP2PF_ISR{}
+void ep4pf_isr() interrupt EP4PF_ISR{}
+void ep6pf_isr() interrupt EP6PF_ISR{}
+void ep8pf_isr() interrupt EP8PF_ISR{}
+void ep2ef_isr() interrupt EP2EF_ISR{}
+void ep4ef_isr() interrupt EP4EF_ISR{}
+void ep6ef_isr() interrupt EP6EF_ISR{}
+void ep8ef_isr() interrupt EP8EF_ISR{}
+void ep2ff_isr() interrupt EP2FF_ISR{}
+void ep4ff_isr() interrupt EP4FF_ISR{}
+void ep6ff_isr() interrupt EP6FF_ISR{}
+void ep8ff_isr() interrupt EP8FF_ISR{}
+void gpifdone_isr() interrupt GPIFDONE_ISR{}
+void gpifwf_isr() interrupt GPIFWF_ISR{}
+*/
+
+
+#endif
+
+fx2.lib
+# Copyright (C) 2008 Ubixum, Inc. 
+# 
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+# 
+# This library 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
+# Lesser General Public License for more details.
+# 
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+SOURCES = serial.c i2c.c delay.c lights.c setupdat.c gpif.c eputils.c
+FX2_OBJS = $(patsubst %.c,%.rel, $(SOURCES)) usbjt.rel
+INCLUDES = -I../include
+SDCC = sdcc -mmcs51
+LIBS = fx2.lib
+
+all: $(LIBS)
+
+$(LIBS): $(FX2_OBJS)
+	sdcclib fx2.lib $?
+
+usbjt.rel: usbjt.asm
+	asx8051 -logs usbjt.asm
+
+usbjt.asm: usbjt_asm
+	cp usbjt_asm usbjt.asm
+
+%.rel: %.c
+	$(SDCC) $(INCLUDES) -c $?
+
+clean:
+	rm -f *.{asm,ihx,lnk,lst,map,mem,rel,rst,sym,adb,cdb,lib}
+
+/**
+ * Copyright (C) 2008 Ubixum, Inc. 
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ **/
+
+#include <fx2regs.h>
+#include <fx2macros.h>
+#include <delay.h>
+
+void delay(WORD millis) {
+    /**
+     * It takes 12 crystal pulses to make 1 machine cycle (8051.com)
+     * ez-usb trm 1.13
+     *  83.3 ns at 48mhz per instruction cycle
+     *  (assume 166.6ns at 24mhz)
+     *  (assume 333.3ns at 12mhz)
+     * ez-usb trm 12.1
+     *  Includes the cycles for each instruction
+     **/    
+    WORD loop_count;
+    volatile WORD count;  // NOTE perhaps use different solutions w/ out volatile
+    
+    
+    // set count to the number of times we need to
+    // go around a loop for 1 millisecond
+    
+    // then do that loop millis times. (1000 us=1ms)
+    
+    // 48mhz: 1000 us / (17 cycles * 83.3 ns / cycle / 1000 ns/us) = 706
+    // 24mhz: 353
+    // 12mhz: 177
+    // recalculate if the number of cycles changes
+    // like if you change the loop below
+    loop_count = CPUFREQ == CLK_12M ? 177 :
+                 CPUFREQ == CLK_24M ? 353 : 706;
+    
+    // sdcc generated assembly
+    /*  cycles   code
+                ;   delay.c:31: do {
+                00101$:
+                ;   delay.c:32: } while ( --count );
+        2           dec _delay_count_1_1
+        2           mov a,#0xff
+        4           cjne    a,_delay_count_1_1,00121$
+        2           dec (_delay_count_1_1 + 1)
+                00121$:
+        2           mov a,_delay_count_1_1
+        2           orl a,(_delay_count_1_1 + 1)
+        3           jnz 00101$
+        
+        Total 17
+    */
+    
+    do {
+        count = loop_count;
+        do {            
+        } while ( --count );        
+    } while ( --millis );
+    
+}
+; Copyright (C) 2008 Ubixum, Inc. 
+;
+; This library is free software; you can redistribute it and/or
+; modify it under the terms of the GNU Lesser General Public
+; License as published by the Free Software Foundation; either
+; version 2.1 of the License, or (at your option) any later version.
+; 
+; This library 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
+; Lesser General Public License for more details.
+; 
+; You should have received a copy of the GNU Lesser General Public
+; License along with this library; if not, write to the Free Software
+; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+; this is a the default 
+; full speed and high speed 
+; descriptors found in the TRM
+; change however you want but leave 
+; the descriptor pointers so the setupdat.c file works right
+ 
+
+.module DEV_DSCR 
+
+; descriptor types
+; same as setupdat.h
+DSCR_DEVICE_TYPE=1
+DSCR_CONFIG_TYPE=2
+DSCR_STRING_TYPE=3
+DSCR_INTERFACE_TYPE=4
+DSCR_ENDPOINT_TYPE=5
+DSCR_DEVQUAL_TYPE=6
+
+; for the repeating interfaces
+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
+; These need to be in code memory.  If
+; they aren't you'll have to manully copy them somewhere
+; in code memory otherwise SUDPTRH:L don't work right
+    .area	CSEG	(CODE)
+
+_dev_dscr:
+	.db	dev_dscr_end-_dev_dscr    ; len
+	.db	DSCR_DEVICE_TYPE		  ; type
+	.dw	0x0002					  ; usb 2.0
+	.db	0xff  					  ; class (vendor specific)
+	.db	0xff					  ; subclass (vendor specific)
+	.db	0xff					  ; protocol (vendor specific)
+	.db	64						  ; packet size (ep0)
+	.dw	0xB404					  ; vendor id 
+	.dw	0x1386					  ; product id
+	.dw	0x0100					  ; version id
+	.db	0		                  ; manufacturure str idx				
+	.db	2				          ; product str idx	
+	.db	0				          ; serial str idx 
+	.db	1			              ; n configurations
+dev_dscr_end:
+
+_dev_qual_dscr:
+	.db	dev_qualdscr_end-_dev_qual_dscr
+	.db	DSCR_DEVQUAL_TYPE
+	.dw	0x0002                              ; usb 2.0
+	.db	0xff
+	.db	0xff
+	.db	0xff
+	.db	64                                  ; max packet
+	.db	1									; n configs
+	.db	0									; extra reserved byte
+dev_qualdscr_end:
+
+_highspd_dscr:
+	.db	highspd_dscr_end-_highspd_dscr      ; dscr len											;; Descriptor length
+	.db	DSCR_CONFIG_TYPE
+    ; can't use .dw because byte order is different
+	.db	(highspd_dscr_realend-_highspd_dscr) % 256 ; total length of config lsb
+	.db	(highspd_dscr_realend-_highspd_dscr) / 256 ; total length of config msb
+	.db	1								 ; n interfaces
+	.db	1								 ; config number
+	.db	0								 ; config string
+	.db	0x80                             ; attrs = bus powered, no wakeup
+	.db	0x32                             ; max power = 100ma
+highspd_dscr_end:
+
+; all the interfaces next 
+; NOTE the default TRM actually has more alt interfaces
+; but you can add them back in if you need them.
+; here, we just use the default alt setting 1 from the trm
+	.db	DSCR_INTERFACE_LEN
+	.db	DSCR_INTERFACE_TYPE
+	.db	0				 ; index
+	.db	0				 ; alt setting idx
+	.db	6				 ; n endpoints	
+	.db	0xff			 ; class
+	.db	0xff
+	.db	0xff
+	.db	0	             ; string index	
+
+; endpoint 1 out
+	.db	DSCR_ENDPOINT_LEN
+	.db	DSCR_ENDPOINT_TYPE
+	.db	0x01				;  ep1 dir=out and address
+	.db	ENDPOINT_TYPE_BULK	; type
+	.db	0x00				; max packet LSB
+	.db	0x02				; max packet size=512 bytes
+	.db	0x00				; polling interval
+      
+; endpoint 1 in 
+	.db	DSCR_ENDPOINT_LEN
+	.db	DSCR_ENDPOINT_TYPE
+	.db	0x81				;  ep1 dir=in and address
+	.db	ENDPOINT_TYPE_BULK	; type
+	.db	0x00				; max packet LSB
+	.db	0x02				; max packet size=512 bytes
+	.db	0x00				; polling interval
+
+; endpoint 2 out
+	.db	DSCR_ENDPOINT_LEN
+	.db	DSCR_ENDPOINT_TYPE
+	.db	0x02				;  ep2 dir=OUT and address
+	.db	ENDPOINT_TYPE_BULK	; type
+	.db	0x00				; max packet LSB
+	.db	0x02				; max packet size=512 bytes
+	.db	0x00				; polling interval
+
+; endpoint 4 out
+	.db	DSCR_ENDPOINT_LEN
+	.db	DSCR_ENDPOINT_TYPE
+	.db	0x04				;  ep4 dir=OUT and address
+	.db	ENDPOINT_TYPE_BULK	; type
+	.db	0x00				; max packet LSB
+	.db	0x02				; max packet size=512 bytes
+	.db	0x00				; polling interval
+
+; endpoint 6 in
+	.db	DSCR_ENDPOINT_LEN
+	.db	DSCR_ENDPOINT_TYPE
+	.db	0x86				;  ep6 dir=in and address
+	.db	ENDPOINT_TYPE_BULK	; type
+	.db	0x00				; max packet LSB
+	.db	0x02				; max packet size=512 bytes
+	.db	0x00				; polling interval
+
+; endpoint 8 in
+	.db	DSCR_ENDPOINT_LEN
+	.db	DSCR_ENDPOINT_TYPE
+	.db	0x88				;  ep8 dir=in and address
+	.db	ENDPOINT_TYPE_BULK	; type
+	.db	0x00				; max packet LSB
+	.db	0x02				; max packet size=512 bytes
+	.db	0x00				; polling interval
+highspd_dscr_realend:
+
+_fullspd_dscr:
+	.db	fullspd_dscr_end-_fullspd_dscr      ; dscr len
+	.db	DSCR_CONFIG_TYPE
+    ; can't use .dw because byte order is different
+	.db	(fullspd_dscr_realend-_fullspd_dscr) % 256 ; total length of config lsb
+	.db	(fullspd_dscr_realend-_fullspd_dscr) / 256 ; total length of config msb
+	.db	1								 ; n interfaces
+	.db	1								 ; config number
+	.db	0								 ; config string
+	.db	0x80                             ; attrs = bus powered, no wakeup
+	.db	0x32                             ; max power = 100ma
+fullspd_dscr_end:
+
+; all the interfaces next 
+; NOTE the default TRM actually has more alt interfaces
+; but you can add them back in if you need them.
+; here, we just use the default alt setting 1 from the trm
+	.db	DSCR_INTERFACE_LEN
+	.db	DSCR_INTERFACE_TYPE
+	.db	0				 ; index
+	.db	0				 ; alt setting idx
+	.db	6				 ; n endpoints	
+	.db	0xff			 ; class
+	.db	0xff
+	.db	0xff
+	.db	0	             ; string index	
+
+; endpoint 1 out
+	.db	DSCR_ENDPOINT_LEN
+	.db	DSCR_ENDPOINT_TYPE
+	.db	0x01				;  ep1 dir=out and address
+	.db	ENDPOINT_TYPE_BULK	; type
+	.db	0x40				; max packet LSB
+	.db	0x00				; max packet size=64 bytes
+	.db	0x00				; polling interval
+      
+; endpoint 1 in 
+	.db	DSCR_ENDPOINT_LEN
+	.db	DSCR_ENDPOINT_TYPE
+	.db	0x81				;  ep1 dir=in and address
+	.db	ENDPOINT_TYPE_BULK	; type
+	.db	0x40				; max packet LSB
+	.db	0x00				; max packet size=64 bytes
+	.db	0x00				; polling interval
+
+; endpoint 2 out
+	.db	DSCR_ENDPOINT_LEN
+	.db	DSCR_ENDPOINT_TYPE
+	.db	0x02				;  ep2 dir=OUT and address
+	.db	ENDPOINT_TYPE_BULK	; type
+	.db	0x40				; max packet LSB
+	.db	0x00				; max packet size=64 bytes
+	.db	0x00				; polling interval
+
+; endpoint 4 out
+	.db	DSCR_ENDPOINT_LEN
+	.db	DSCR_ENDPOINT_TYPE
+	.db	0x04				;  ep4 dir=OUT and address
+	.db	ENDPOINT_TYPE_BULK	; type
+	.db	0x40				; max packet LSB
+	.db	0x00				; max packet size=64 bytes
+	.db	0x00				; polling interval
+
+; endpoint 6 in
+	.db	DSCR_ENDPOINT_LEN
+	.db	DSCR_ENDPOINT_TYPE
+	.db	0x86				;  ep6 dir=in and address
+	.db	ENDPOINT_TYPE_BULK	; type
+	.db	0x40				; max packet LSB
+	.db	0x00				; max packet size=64 bytes
+	.db	0x00				; polling interval
+; endpoint 6 in
+	.db	DSCR_ENDPOINT_LEN
+	.db	DSCR_ENDPOINT_TYPE
+	.db	0x88				;  ep6 dir=in and address
+	.db	ENDPOINT_TYPE_BULK	; type
+	.db	0x40				; max packet LSB
+	.db	0x00				; max packet size=64 bytes
+	.db	0x00				; polling interval
+fullspd_dscr_realend:
+
+_dev_strings:
+; sample string
+_string0:
+	.db	string0end-_string0 ; len
+	.db	DSCR_STRING_TYPE
+    .db 0x09, 0x04 ; 0x0409 is the language code for English.  Possible to add more codes after this. 
+string0end:
+; add more strings here
+
+
+_dev_strings_end:
+    .dw 0x0000  ; in case you wanted to look at memory between _dev_strings and _dev_strings_end
+/**
+ * Copyright (C) 2008 Ubixum, Inc. 
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ **/
+
+
+
+
+#include <eputils.h>
+
+#include <fx2regs.h>
+
+
+void readep0( BYTE* dst, WORD len) {
+    WORD read = 0; // n bytes read
+    BYTE c,avail;
+    while (read < len) {
+        EP0BCH = 0;
+        // NOTE need syncdelay?
+        EP0BCL = 0; // re-arm ep so host can send more
+        while (EP0CS & bmEPBUSY);
+        avail = EP0BCL; // max size fits in one byte (64 bytes)
+        for (c=0;c<avail;++c)
+            dst[read+c] = EP0BUF[c];
+        read += avail;
+    }
+}
+/**
+ * Copyright (C) 2008 Ubixum, Inc. 
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ **/
+
+
+#include <fx2regs.h>
+#include <fx2macros.h>
+#include <delay.h>
+
+#include <gpif.h>
+
+#define SYNCDELAY() SYNCDELAY4
+
+void gpif_init( BYTE* wavedata, BYTE* initdata ) {
+    
+    BYTE i;
+ 
+  // Registers which require a synchronization delay, see section 15.14
+  // FIFORESET        FIFOPINPOLAR
+  // INPKTEND         OUTPKTEND
+  // EPxBCH:L         REVCTL
+  // GPIFTCB3         GPIFTCB2
+  // GPIFTCB1         GPIFTCB0
+  // EPxFIFOPFH:L     EPxAUTOINLENH:L
+  // EPxFIFOCFG       EPxGPIFFLGSEL
+  // PINFLAGSxx       EPxFIFOIRQ
+  // EPxFIFOIE        GPIFIRQ
+  // GPIFIE           GPIFADRH:L
+  // UDMACRCH:L       EPxGPIFTRIG
+  // GPIFTRIG
+  
+  // Note: The pre-REVE EPxGPIFTCH/L register are affected, as well...
+  //      ...these have been replaced by GPIFTC[B3:B0] registers
+ 
+  // 8051 doesn't have access to waveform memories 'til
+  // the part is in GPIF mode.
+ 
+  // IFCLKSRC=1   , FIFOs executes on internal clk source
+  // xMHz=1       , 48MHz internal clk rate
+  // IFCLKOE=0    , Don't drive IFCLK pin signal at 48MHz
+  // IFCLKPOL=0   , Don't invert IFCLK pin signal from internal clk
+  // ASYNC=1      , master samples asynchronous
+  // GSTATE=1     , Drive GPIF states out on PORTE[2:0], debug WF
+  // IFCFG[1:0]=10, FX2 in GPIF master mode  IFCONFIG
+  IFCONFIG &= ~0xfc; // turn off IFCFG[1:0]
+  IFCONFIG |= 0x02; // set's IFCFG[1:0] to 10 to put in GPIF master mode.
+  
+ 
+  GPIFABORT = 0xFF;  // abort any waveforms pending
+ 
+  GPIFREADYCFG = initdata[ 0 ];
+  GPIFCTLCFG = initdata[ 1 ];
+  GPIFIDLECS = initdata[ 2 ];
+  GPIFIDLECTL = initdata[ 3 ];
+  GPIFWFSELECT = initdata[ 5 ];
+  GPIFREADYSTAT = initdata[ 6 ];
+ 
+  // use dual autopointer feature... 
+  AUTOPTRSETUP = 0x07;          // inc both pointers, 
+                                // ...warning: this introduces pdata hole(s)
+                                // ...at E67B (XAUTODAT1) and E67C (XAUTODAT2)
+  
+  // source
+  AUTOPTRH1 = MSB( (WORD)wavedata );
+  AUTOPTRL1 = LSB( (WORD)wavedata );
+  
+  // destination
+  AUTOPTRH2 = 0xE4;
+  AUTOPTRL2 = 0x00;
+ 
+  // transfer
+  for ( i = 0x00; i < 128; i++ )
+  {
+    EXTAUTODAT2 = EXTAUTODAT1;
+  }
+ 
+// Configure GPIF Address pins, output initial value,
+// these instructions don't do anything on the
+// smaller chips (e.g., 56 pin model only has ports a,b,d)
+  PORTCCFG = 0xFF;    // [7:0] as alt. func. GPIFADR[7:0]
+  OEC = 0xFF;         // and as outputs
+  PORTECFG |= 0x80;   // [8] as alt. func. GPIFADR[8]
+  OEE |= 0x80;        // and as output
+ 
+// ...OR... tri-state GPIFADR[8:0] pins
+//  PORTCCFG = 0x00;  // [7:0] as port I/O
+//  OEC = 0x00;       // and as inputs
+//  PORTECFG &= 0x7F; // [8] as port I/O
+//  OEE &= 0x7F;      // and as input
+ 
+// GPIF address pins update when GPIFADRH/L written
+  SYNCDELAY();                    // 
+  GPIFADRH = 0x00;    // bits[7:1] always 0
+  SYNCDELAY();                    // 
+  GPIFADRL = 0x00;    // point to PERIPHERAL address 0x0000
+
+// set the initial flowstates to be all 0 in case flow states are not used
+
+  FLOWSTATE = 0;
+  FLOWLOGIC = 0;
+  FLOWEQ0CTL = 0;
+  FLOWEQ1CTL = 0;
+  FLOWHOLDOFF = 0;
+  FLOWSTB = 0;
+  FLOWSTBEDGE = 0;
+  FLOWSTBHPERIOD = 0;
+}
+
+void gpif_setflowstate( BYTE* flowstates, BYTE bank) {
+  BYTE base = 9*bank;
+  FLOWSTATE = flowstates[ base ];
+  FLOWLOGIC = flowstates[ base+1 ];
+  FLOWEQ0CTL = flowstates[ base+2 ];
+  FLOWEQ1CTL = flowstates[ base+3 ];
+  FLOWHOLDOFF = flowstates[ base+4 ];
+  FLOWSTB = flowstates[ base+5 ];
+  FLOWSTBEDGE = flowstates[ base+6 ];
+  FLOWSTBHPERIOD = flowstates[ base+7 ];
+}
+
+void gpif_single_read( BYTE* res, WORD len ){
+    BYTE c;
+    while (!(GPIFTRIG & 0x80)); // wait done
+    // dummy read to trigger real read
+    res[0] = XGPIFSGLDATLX;
+    for (c=0;c<len;c+=2) {
+     while ( !(GPIFTRIG & 0x80) ); // wait done
+     // real read
+     res[c] = GPIFSGLDATH;
+     // whether or not to do another transfer
+     res[c+1] = c==len-2 ? GPIFSGLDATLNOX : GPIFSGLDATLX;
+    }
+}
+
+void gpif_fifo_read ( GPIF_EP_NUM ep_num ) {
+    while ( !(GPIFTRIG & 0x80 ) ); // wait until things are finished
+    GPIFTRIG = GPIFTRGRD | ep_num;
+}
+
+void gpif_fifo_write ( GPIF_EP_NUM ep_num ) {
+    while ( !(GPIFTRIG & 0x80) ); // wait until things are finished
+    GPIFTRIG = ep_num; // R/W=0, E[1:0] = ep_num
+}
+/**
+ * Copyright (C) 2008 Ubixum, Inc. 
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ **/
+
+#include <stdio.h> // NOTE this needs deleted
+
+#include <fx2regs.h>
+#include <fx2macros.h>
+#include <i2c.h>
+#include <delay.h>
+
+
+/**
+ *
+    1. Set START=1. If BERR=1, start timer*.
+    2. Write the 7-bit peripheral address and the direction bit (0 for a write) to I2DAT.
+    3. Wait for DONE=1 or for timer to expire*. If BERR=1, go to step 1.
+    4. If ACK=0, go to step 9.
+    5. Load I2DAT with a data byte.
+    6. Wait for DONE=1*. If BERR=1, go to step 1.
+    7. If ACK=0, go to step 9.
+    8. Repeat steps 5-7 for each byte until all bytes have been transferred.
+    9. Set STOP=1. Wait for STOP = 0 before initiating another transfer.
+ **/
+void i2c_write ( BYTE addr, WORD len, BYTE *dat ) {
+    
+    WORD cur_byte;
+    //BOOL wait=FALSE; // use timer if needed
+    
+    // 9. Set STOP=1. Wait for STOP = 0 before initiating another transfer.
+    // not setting STOP here though
+    step9:
+        while ( I2CS & bmSTOP ); // WAIT for STOP = 0 before another transfer
+    
+    // 1. Set START=1. If BERR=1, start timer*.
+    step1:
+        cur_byte=0;
+        I2CS |= bmSTART;
+        if ( I2CS & bmBERR ) {
+            printf ( "Woops.. need to do the timer\n" );
+            delay(10); // way too long
+            goto step1;
+            }
+    
+    // 2. Write the 7-bit peripheral address and the direction bit (0 for a write) to I2DAT.
+        I2DAT = addr << 1;
+