1 /* JTAG GNU/Linux FTDI FT2232 low-level I/O
2 
3 Copyright (C) 2006 Dmitry Teytelman
4 
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
18 
19 
20 #ifndef IOFTDI_H
21 #define IOFTDI_H
22 
23 #include "config.h"
24 
25 #ifdef WINDOWS
26 	#include <windows.h>
27 	#include "ftd2xx.h"
28 	#define USE_FTD2XX
29 #else
30 	#include <ftdi.h>
31 	#include <usb.h>
32 #endif
33 
34 #include "iobase.h"
35 
36 #define VENDOR 0x0403
37 #define DEVICE 0x6010
38 
39 #define FTDI_NO_EN 0
40 #define FTDI_IKDA  1
41 
42 #define TX_BUF (4096)
43 
44 
45 
46 /* Shifting commands IN MPSSE Mode*/
47 #define MPSSE_WRITE_NEG 0x01   /* Write TDI/DO on negative TCK/SK edge*/
48 #define MPSSE_BITMODE   0x02   /* Write bits, not bytes */
49 #define MPSSE_READ_NEG  0x04   /* Sample TDO/DI on negative TCK/SK edge */
50 #define MPSSE_LSB       0x08   /* LSB first */
51 #define MPSSE_DO_WRITE  0x10   /* Write TDI/DO */
52 #define MPSSE_DO_READ   0x20   /* Read TDO/DI */
53 #define MPSSE_WRITE_TMS 0x40   /* Write TMS/CS */
54 
55 /* FTDI MPSSE commands */
56 #define SET_BITS_LOW   0x80
57 /*BYTE DATA*/
58 /*BYTE Direction*/
59 #define SET_BITS_HIGH  0x82
60 /*BYTE DATA*/
61 /*BYTE Direction*/
62 #define GET_BITS_LOW   0x81
63 #define GET_BITS_HIGH  0x83
64 #define LOOPBACK_START 0x84
65 #define LOOPBACK_END   0x85
66 #define TCK_DIVISOR    0x86
67 /* Value Low */
68 /* Value HIGH */ /*rate is 12000000/((1+value)*2) */
69 #define DIV_VALUE(rate) (rate > 6000000)?0:((6000000/rate -1) > 0xffff)? 0xffff: (6000000/rate -1)
70 
71 /* Commands in MPSSE and Host Emulation Mode */
72 #define SEND_IMMEDIATE 0x87
73 #define WAIT_ON_HIGH   0x88
74 #define WAIT_ON_LOW    0x89
75 
76 /* Commands in Host Emulation Mode */
77 #define READ_SHORT     0x90
78 /* Address_Low */
79 #define READ_EXTENDED  0x91
80 /* Address High */
81 /* Address Low  */
82 #define WRITE_SHORT    0x92
83 /* Address_Low */
84 #define WRITE_EXTENDED 0x93
85 /* Address High */
86 /* Address Low  */
87 
88 
89 
90 class IOFtdi : public IOBase
91 {
92  protected:
93 #if defined (USE_FTD2XX)
94   FT_HANDLE ftdi;
95 #else
96   struct ftdi_context ftdi;
97 #endif
98   unsigned char usbuf[TX_BUF];
99   int buflen;
100 #if defined(USE_FTD2XX)
101   DWORD bptr;
102 #else
103   int bptr;
104 #endif
105   int calls_rd, calls_wr, subtype, retries;
106 
107  public:
108   IOFtdi(int vendor, int product, char const *desc, char const *serial, int subtype);
109   ~IOFtdi();
110 
111  public:
112   void settype(int subtype);
113   void txrx_block(const unsigned char *tdi, unsigned char *tdo, int length, bool last);
114   void tx_tms(unsigned char *pat, int length);
115   void flush(void);
116 
117  private:
118   void deinit(void);
119   void mpsse_add_cmd(unsigned char const *buf, int len);
120   void mpsse_send(void);
121   unsigned int readusb(unsigned char * rbuf, unsigned long len);
122   void cycleTCK(int n, bool tdi);
123 };
124 
125 
126 #endif // IOFTDI_H
127