1/*
2 *Copyright (C) 2015 The Android Open Source Project
3 *
4 *Licensed under the Apache License, Version 2.0 (the "License");
5 *you may not use this file except in compliance with the License.
6 *You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 *Unless required by applicable law or agreed to in writing, software
11 *distributed under the License is distributed on an "AS IS" BASIS,
12 *WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 *See the License for the specific language governing permissions and
14 *limitations under the License.
15 *
16 * This file was copied from https://github.com/devttys0/libmpsse.git (sha1
17 * f1a6744b), and modified to suite the Chromium OS project.
18 */
19
20#ifndef TRUNKS_FTDI_MPSSE_H_
21#define TRUNKS_FTDI_MPSSE_H_
22
23#include <libftdi1/ftdi.h>
24#include <stdint.h>
25
26#define MPSSE_OK 0
27#define MPSSE_FAIL -1
28
29#define MSB 0x00
30#define LSB 0x08
31
32#define CHUNK_SIZE 65535
33#define SPI_RW_SIZE (63 * 1024)
34#define SPI_TRANSFER_SIZE 512
35#define I2C_TRANSFER_SIZE 64
36
37#define LATENCY_MS 2
38#define TIMEOUT_DIVISOR 1000000
39#define USB_TIMEOUT 120000
40#define SETUP_DELAY 25000
41
42#define BITMODE_RESET 0
43#define BITMODE_MPSSE 2
44
45#define CMD_SIZE 3
46#define MAX_SETUP_COMMANDS 10
47#define SS_TX_COUNT 3
48
49#define LOW 0
50#define HIGH 1
51#define NUM_GPIOL_PINS 4
52#define NUM_GPIO_PINS 12
53
54#define NULL_CONTEXT_ERROR_MSG "NULL MPSSE context pointer!"
55
56#ifdef __cplusplus
57extern "C" {
58#endif
59
60/* FTDI interfaces */
61enum interface {
62  IFACE_ANY = INTERFACE_ANY,
63  IFACE_A = INTERFACE_A,
64  IFACE_B = INTERFACE_B,
65  IFACE_C = INTERFACE_C,
66  IFACE_D = INTERFACE_D
67};
68
69/* Common clock rates */
70enum clock_rates {
71  ONE_HUNDRED_KHZ = 100000,
72  FOUR_HUNDRED_KHZ = 400000,
73  ONE_MHZ = 1000000,
74  TWO_MHZ = 2000000,
75  FIVE_MHZ = 5000000,
76  SIX_MHZ = 6000000,
77  TEN_MHZ = 10000000,
78  TWELVE_MHZ = 12000000,
79  FIFTEEN_MHZ = 15000000,
80  THIRTY_MHZ = 30000000,
81  SIXTY_MHZ = 60000000
82};
83
84/* Supported MPSSE modes */
85enum modes {
86  SPI0 = 1,
87  SPI1 = 2,
88  SPI2 = 3,
89  SPI3 = 4,
90  I2C = 5,
91  GPIO = 6,
92  BITBANG = 7,
93};
94
95enum pins {
96  SK = 1,
97  DO = 2,
98  DI = 4,
99  CS = 8,
100  GPIO0 = 16,
101  GPIO1 = 32,
102  GPIO2 = 64,
103  GPIO3 = 128
104};
105
106enum gpio_pins {
107  GPIOL0 = 0,
108  GPIOL1 = 1,
109  GPIOL2 = 2,
110  GPIOL3 = 3,
111  GPIOH0 = 4,
112  GPIOH1 = 5,
113  GPIOH2 = 6,
114  GPIOH3 = 7,
115  GPIOH4 = 8,
116  GPIOH5 = 9,
117  GPIOH6 = 10,
118  GPIOH7 = 11
119};
120
121enum i2c_ack { ACK = 0, NACK = 1 };
122
123/* SK/DO/CS and GPIOs are outputs, DI is an input */
124#define DEFAULT_TRIS (SK | DO | CS | GPIO0 | GPIO1 | GPIO2 | GPIO3)
125#define DEFAULT_PORT (SK | CS) /* SK and CS are high, all others low */
126
127enum mpsse_commands {
128  INVALID_COMMAND = 0xAB,
129  ENABLE_ADAPTIVE_CLOCK = 0x96,
130  DISABLE_ADAPTIVE_CLOCK = 0x97,
131  ENABLE_3_PHASE_CLOCK = 0x8C,
132  DISABLE_3_PHASE_CLOCK = 0x8D,
133  TCK_X5 = 0x8A,
134  TCK_D5 = 0x8B,
135  CLOCK_N_CYCLES = 0x8E,
136  CLOCK_N8_CYCLES = 0x8F,
137  PULSE_CLOCK_IO_HIGH = 0x94,
138  PULSE_CLOCK_IO_LOW = 0x95,
139  CLOCK_N8_CYCLES_IO_HIGH = 0x9C,
140  CLOCK_N8_CYCLES_IO_LOW = 0x9D,
141  TRISTATE_IO = 0x9E,
142};
143
144enum low_bits_status { STARTED, STOPPED };
145
146struct vid_pid {
147  int vid;
148  int pid;
149  char* description;
150};
151
152struct mpsse_context {
153  char* description;
154  struct ftdi_context ftdi;
155  enum modes mode;
156  enum low_bits_status status;
157  int flush_after_read;
158  int vid;
159  int pid;
160  int clock;
161  int xsize;
162  uint8_t endianess;
163  uint8_t opened;
164  uint8_t tris;
165  uint8_t pstart;
166  uint8_t pstop;
167  uint8_t pidle;
168  uint8_t gpioh;
169  uint8_t trish;
170  uint8_t bitbang;
171  uint8_t tx;
172  uint8_t rx;
173  uint8_t txrx;
174  uint8_t tack;
175  uint8_t rack;
176};
177
178struct mpsse_context* MPSSE(enum modes mode, int freq, int endianess);
179struct mpsse_context* Open(int vid,
180                           int pid,
181                           enum modes mode,
182                           int freq,
183                           int endianess,
184                           int interface,
185                           const char* description,
186                           const char* serial);
187struct mpsse_context* OpenIndex(int vid,
188                                int pid,
189                                enum modes mode,
190                                int freq,
191                                int endianess,
192                                int interface,
193                                const char* description,
194                                const char* serial,
195                                int index);
196void Close(struct mpsse_context* mpsse);
197const char* ErrorString(struct mpsse_context* mpsse);
198int SetMode(struct mpsse_context* mpsse, int endianess);
199void EnableBitmode(struct mpsse_context* mpsse, int tf);
200int SetClock(struct mpsse_context* mpsse, uint32_t freq);
201int GetClock(struct mpsse_context* mpsse);
202int GetVid(struct mpsse_context* mpsse);
203int GetPid(struct mpsse_context* mpsse);
204const char* GetDescription(struct mpsse_context* mpsse);
205int SetLoopback(struct mpsse_context* mpsse, int enable);
206void SetCSIdle(struct mpsse_context* mpsse, int idle);
207int Start(struct mpsse_context* mpsse);
208int Write(struct mpsse_context* mpsse, const void* data, int size);
209int Stop(struct mpsse_context* mpsse);
210int GetAck(struct mpsse_context* mpsse);
211void SetAck(struct mpsse_context* mpsse, int ack);
212void SendAcks(struct mpsse_context* mpsse);
213void SendNacks(struct mpsse_context* mpsse);
214void FlushAfterRead(struct mpsse_context* mpsse, int tf);
215int PinHigh(struct mpsse_context* mpsse, int pin);
216int PinLow(struct mpsse_context* mpsse, int pin);
217int SetDirection(struct mpsse_context* mpsse, uint8_t direction);
218int WriteBits(struct mpsse_context* mpsse, char bits, size_t size);
219char ReadBits(struct mpsse_context* mpsse, int size);
220int WritePins(struct mpsse_context* mpsse, uint8_t data);
221int ReadPins(struct mpsse_context* mpsse);
222int PinState(struct mpsse_context* mpsse, int pin, int state);
223int Tristate(struct mpsse_context* mpsse);
224char Version(void);
225
226#ifdef SWIGPYTHON
227typedef struct swig_string_data {
228  int size;
229  char* data;
230} swig_string_data;
231
232swig_string_data Read(struct mpsse_context* mpsse, int size);
233swig_string_data Transfer(struct mpsse_context* mpsse, char* data, int size);
234#else
235uint8_t* Read(struct mpsse_context* mpsse, int size);
236uint8_t* Transfer(struct mpsse_context* mpsse,
237                        uint8_t* data, int size);
238
239int FastWrite(struct mpsse_context* mpsse, char* data, int size);
240int FastRead(struct mpsse_context* mpsse, char* data, int size);
241int FastTransfer(struct mpsse_context* mpsse,
242                 char* wdata,
243                 char* rdata,
244                 int size);
245#endif
246#ifdef __cplusplus
247}
248#endif
249#endif  /* TRUNKS_FTDI_MPSSE_H_ */
250