|  | /* | 
|  | *Copyright (C) 2015 The Android Open Source Project | 
|  | * | 
|  | *Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | *you may not use this file except in compliance with the License. | 
|  | *You may obtain a copy of the License at | 
|  | * | 
|  | *     http://www.apache.org/licenses/LICENSE-2.0 | 
|  | * | 
|  | *Unless required by applicable law or agreed to in writing, software | 
|  | *distributed under the License is distributed on an "AS IS" BASIS, | 
|  | *WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | *See the License for the specific language governing permissions and | 
|  | *limitations under the License. | 
|  | * | 
|  | * This file was copied from https://github.com/devttys0/libmpsse.git (sha1 | 
|  | * f1a6744b), and modified to suite the Chromium OS project. | 
|  | */ | 
|  |  | 
|  | #ifndef TRUNKS_FTDI_MPSSE_H_ | 
|  | #define TRUNKS_FTDI_MPSSE_H_ | 
|  |  | 
|  | #include <libftdi1/ftdi.h> | 
|  | #include <stdint.h> | 
|  |  | 
|  | #define MPSSE_OK 0 | 
|  | #define MPSSE_FAIL -1 | 
|  |  | 
|  | #define MSB 0x00 | 
|  | #define LSB 0x08 | 
|  |  | 
|  | #define CHUNK_SIZE 65535 | 
|  | #define SPI_RW_SIZE (63 * 1024) | 
|  | #define SPI_TRANSFER_SIZE 512 | 
|  | #define I2C_TRANSFER_SIZE 64 | 
|  |  | 
|  | #define LATENCY_MS 2 | 
|  | #define TIMEOUT_DIVISOR 1000000 | 
|  | #define USB_TIMEOUT 120000 | 
|  | #define SETUP_DELAY 25000 | 
|  |  | 
|  | #define BITMODE_RESET 0 | 
|  | #define BITMODE_MPSSE 2 | 
|  |  | 
|  | #define CMD_SIZE 3 | 
|  | #define MAX_SETUP_COMMANDS 10 | 
|  | #define SS_TX_COUNT 3 | 
|  |  | 
|  | #define LOW 0 | 
|  | #define HIGH 1 | 
|  | #define NUM_GPIOL_PINS 4 | 
|  | #define NUM_GPIO_PINS 12 | 
|  |  | 
|  | #define NULL_CONTEXT_ERROR_MSG "NULL MPSSE context pointer!" | 
|  |  | 
|  | #ifdef __cplusplus | 
|  | extern "C" { | 
|  | #endif | 
|  |  | 
|  | /* FTDI interfaces */ | 
|  | enum interface { | 
|  | IFACE_ANY = INTERFACE_ANY, | 
|  | IFACE_A = INTERFACE_A, | 
|  | IFACE_B = INTERFACE_B, | 
|  | IFACE_C = INTERFACE_C, | 
|  | IFACE_D = INTERFACE_D | 
|  | }; | 
|  |  | 
|  | /* Common clock rates */ | 
|  | enum clock_rates { | 
|  | ONE_HUNDRED_KHZ = 100000, | 
|  | FOUR_HUNDRED_KHZ = 400000, | 
|  | ONE_MHZ = 1000000, | 
|  | TWO_MHZ = 2000000, | 
|  | FIVE_MHZ = 5000000, | 
|  | SIX_MHZ = 6000000, | 
|  | TEN_MHZ = 10000000, | 
|  | TWELVE_MHZ = 12000000, | 
|  | FIFTEEN_MHZ = 15000000, | 
|  | THIRTY_MHZ = 30000000, | 
|  | SIXTY_MHZ = 60000000 | 
|  | }; | 
|  |  | 
|  | /* Supported MPSSE modes */ | 
|  | enum modes { | 
|  | SPI0 = 1, | 
|  | SPI1 = 2, | 
|  | SPI2 = 3, | 
|  | SPI3 = 4, | 
|  | I2C = 5, | 
|  | GPIO = 6, | 
|  | BITBANG = 7, | 
|  | }; | 
|  |  | 
|  | enum pins { | 
|  | SK = 1, | 
|  | DO = 2, | 
|  | DI = 4, | 
|  | CS = 8, | 
|  | GPIO0 = 16, | 
|  | GPIO1 = 32, | 
|  | GPIO2 = 64, | 
|  | GPIO3 = 128 | 
|  | }; | 
|  |  | 
|  | enum gpio_pins { | 
|  | GPIOL0 = 0, | 
|  | GPIOL1 = 1, | 
|  | GPIOL2 = 2, | 
|  | GPIOL3 = 3, | 
|  | GPIOH0 = 4, | 
|  | GPIOH1 = 5, | 
|  | GPIOH2 = 6, | 
|  | GPIOH3 = 7, | 
|  | GPIOH4 = 8, | 
|  | GPIOH5 = 9, | 
|  | GPIOH6 = 10, | 
|  | GPIOH7 = 11 | 
|  | }; | 
|  |  | 
|  | enum i2c_ack { ACK = 0, NACK = 1 }; | 
|  |  | 
|  | /* SK/DO/CS and GPIOs are outputs, DI is an input */ | 
|  | #define DEFAULT_TRIS (SK | DO | CS | GPIO0 | GPIO1 | GPIO2 | GPIO3) | 
|  | #define DEFAULT_PORT (SK | CS) /* SK and CS are high, all others low */ | 
|  |  | 
|  | enum mpsse_commands { | 
|  | INVALID_COMMAND = 0xAB, | 
|  | ENABLE_ADAPTIVE_CLOCK = 0x96, | 
|  | DISABLE_ADAPTIVE_CLOCK = 0x97, | 
|  | ENABLE_3_PHASE_CLOCK = 0x8C, | 
|  | DISABLE_3_PHASE_CLOCK = 0x8D, | 
|  | TCK_X5 = 0x8A, | 
|  | TCK_D5 = 0x8B, | 
|  | CLOCK_N_CYCLES = 0x8E, | 
|  | CLOCK_N8_CYCLES = 0x8F, | 
|  | PULSE_CLOCK_IO_HIGH = 0x94, | 
|  | PULSE_CLOCK_IO_LOW = 0x95, | 
|  | CLOCK_N8_CYCLES_IO_HIGH = 0x9C, | 
|  | CLOCK_N8_CYCLES_IO_LOW = 0x9D, | 
|  | TRISTATE_IO = 0x9E, | 
|  | }; | 
|  |  | 
|  | enum low_bits_status { STARTED, STOPPED }; | 
|  |  | 
|  | struct vid_pid { | 
|  | int vid; | 
|  | int pid; | 
|  | char* description; | 
|  | }; | 
|  |  | 
|  | struct mpsse_context { | 
|  | char* description; | 
|  | struct ftdi_context ftdi; | 
|  | enum modes mode; | 
|  | enum low_bits_status status; | 
|  | int flush_after_read; | 
|  | int vid; | 
|  | int pid; | 
|  | int clock; | 
|  | int xsize; | 
|  | uint8_t endianess; | 
|  | uint8_t opened; | 
|  | uint8_t tris; | 
|  | uint8_t pstart; | 
|  | uint8_t pstop; | 
|  | uint8_t pidle; | 
|  | uint8_t gpioh; | 
|  | uint8_t trish; | 
|  | uint8_t bitbang; | 
|  | uint8_t tx; | 
|  | uint8_t rx; | 
|  | uint8_t txrx; | 
|  | uint8_t tack; | 
|  | uint8_t rack; | 
|  | }; | 
|  |  | 
|  | struct mpsse_context* MPSSE(enum modes mode, int freq, int endianess); | 
|  | struct mpsse_context* Open(int vid, | 
|  | int pid, | 
|  | enum modes mode, | 
|  | int freq, | 
|  | int endianess, | 
|  | int interface, | 
|  | const char* description, | 
|  | const char* serial); | 
|  | struct mpsse_context* OpenIndex(int vid, | 
|  | int pid, | 
|  | enum modes mode, | 
|  | int freq, | 
|  | int endianess, | 
|  | int interface, | 
|  | const char* description, | 
|  | const char* serial, | 
|  | int index); | 
|  | void Close(struct mpsse_context* mpsse); | 
|  | const char* ErrorString(struct mpsse_context* mpsse); | 
|  | int SetMode(struct mpsse_context* mpsse, int endianess); | 
|  | void EnableBitmode(struct mpsse_context* mpsse, int tf); | 
|  | int SetClock(struct mpsse_context* mpsse, uint32_t freq); | 
|  | int GetClock(struct mpsse_context* mpsse); | 
|  | int GetVid(struct mpsse_context* mpsse); | 
|  | int GetPid(struct mpsse_context* mpsse); | 
|  | const char* GetDescription(struct mpsse_context* mpsse); | 
|  | int SetLoopback(struct mpsse_context* mpsse, int enable); | 
|  | void SetCSIdle(struct mpsse_context* mpsse, int idle); | 
|  | int Start(struct mpsse_context* mpsse); | 
|  | int Write(struct mpsse_context* mpsse, const void* data, int size); | 
|  | int Stop(struct mpsse_context* mpsse); | 
|  | int GetAck(struct mpsse_context* mpsse); | 
|  | void SetAck(struct mpsse_context* mpsse, int ack); | 
|  | void SendAcks(struct mpsse_context* mpsse); | 
|  | void SendNacks(struct mpsse_context* mpsse); | 
|  | void FlushAfterRead(struct mpsse_context* mpsse, int tf); | 
|  | int PinHigh(struct mpsse_context* mpsse, int pin); | 
|  | int PinLow(struct mpsse_context* mpsse, int pin); | 
|  | int SetDirection(struct mpsse_context* mpsse, uint8_t direction); | 
|  | int WriteBits(struct mpsse_context* mpsse, char bits, size_t size); | 
|  | char ReadBits(struct mpsse_context* mpsse, int size); | 
|  | int WritePins(struct mpsse_context* mpsse, uint8_t data); | 
|  | int ReadPins(struct mpsse_context* mpsse); | 
|  | int PinState(struct mpsse_context* mpsse, int pin, int state); | 
|  | int Tristate(struct mpsse_context* mpsse); | 
|  | char Version(void); | 
|  |  | 
|  | #ifdef SWIGPYTHON | 
|  | typedef struct swig_string_data { | 
|  | int size; | 
|  | char* data; | 
|  | } swig_string_data; | 
|  |  | 
|  | swig_string_data Read(struct mpsse_context* mpsse, int size); | 
|  | swig_string_data Transfer(struct mpsse_context* mpsse, char* data, int size); | 
|  | #else | 
|  | uint8_t* Read(struct mpsse_context* mpsse, int size); | 
|  | uint8_t* Transfer(struct mpsse_context* mpsse, uint8_t* data, int size); | 
|  |  | 
|  | int FastWrite(struct mpsse_context* mpsse, char* data, int size); | 
|  | int FastRead(struct mpsse_context* mpsse, char* data, int size); | 
|  | int FastTransfer(struct mpsse_context* mpsse, | 
|  | char* wdata, | 
|  | char* rdata, | 
|  | int size); | 
|  | #endif | 
|  | #ifdef __cplusplus | 
|  | } | 
|  | #endif | 
|  | #endif /* TRUNKS_FTDI_MPSSE_H_ */ |