| /* | 
 |  *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. | 
 |  * | 
 |  * Main libmpsse source file. | 
 |  * | 
 |  * Craig Heffner | 
 |  * 27 December 2011 | 
 |  */ | 
 |  | 
 | #define _XOPEN_SOURCE 500 | 
 | #include <stdlib.h> | 
 | #include <string.h> | 
 | #include <stdint.h> | 
 | #include <unistd.h> | 
 |  | 
 | #include "support.h" | 
 |  | 
 | /* List of known FT2232-based devices */ | 
 | struct vid_pid supported_devices[] = { | 
 |     {0x0403, 0x6010, "FT2232 Future Technology Devices International, Ltd"}, | 
 |     {0x0403, 0x6011, "FT4232 Future Technology Devices International, Ltd"}, | 
 |     {0x0403, 0x6014, "FT232H Future Technology Devices International, Ltd"}, | 
 |  | 
 |     /* These devices are based on FT2232 chips, but have not been tested. */ | 
 |     {0x0403, 0x8878, "Bus Blaster v2 (channel A)"}, | 
 |     {0x0403, 0x8879, "Bus Blaster v2 (channel B)"}, | 
 |     {0x0403, 0xBDC8, "Turtelizer JTAG/RS232 Adapter A"}, | 
 |     {0x0403, 0xCFF8, "Amontec JTAGkey"}, | 
 |     {0x0403, 0x8A98, "TIAO Multi Protocol Adapter"}, | 
 |     {0x15BA, 0x0003, "Olimex Ltd. OpenOCD JTAG"}, | 
 |     {0x15BA, 0x0004, "Olimex Ltd. OpenOCD JTAG TINY"}, | 
 |  | 
 |     {0, 0, NULL}}; | 
 |  | 
 | /* | 
 |  * Opens and initializes the first FTDI device found. | 
 |  * | 
 |  * @mode      - Mode to open the device in. One of enum modes. | 
 |  * @freq      - Clock frequency to use for the specified mode. | 
 |  * @endianess - Specifies how data is clocked in/out (MSB, LSB). | 
 |  * | 
 |  * Returns a pointer to an MPSSE context structure if succeeded, NULL otherwise. | 
 |  */ | 
 | struct mpsse_context* MPSSE(enum modes mode, int freq, int endianess) { | 
 |   int i = 0; | 
 |   struct mpsse_context* mpsse = NULL; | 
 |  | 
 |   for (i = 0; supported_devices[i].vid != 0; i++) { | 
 |     mpsse = Open(supported_devices[i].vid, supported_devices[i].pid, mode, freq, | 
 |                  endianess, IFACE_A, NULL, NULL); | 
 |     if (mpsse) { | 
 |       mpsse->description = supported_devices[i].description; | 
 |       return mpsse; | 
 |     } | 
 |   } | 
 |  | 
 |   return NULL; | 
 | } | 
 |  | 
 | /* | 
 |  * Open device by VID/PID | 
 |  * | 
 |  * @vid         - Device vendor ID. | 
 |  * @pid         - Device product ID. | 
 |  * @mode        - MPSSE mode, one of enum modes. | 
 |  * @freq        - Clock frequency to use for the specified mode. | 
 |  * @endianess   - Specifies how data is clocked in/out (MSB, LSB). | 
 |  * @interface   - FTDI interface to use (IFACE_A - IFACE_D). | 
 |  * @description - Device product description (set to NULL if not needed). | 
 |  * @serial      - Device serial number (set to NULL if not needed). | 
 |  * | 
 |  * Returns a pointer to an MPSSE context structure on success. | 
 |  */ | 
 | struct mpsse_context* Open(int vid, | 
 |                            int pid, | 
 |                            enum modes mode, | 
 |                            int freq, | 
 |                            int endianess, | 
 |                            int interface, | 
 |                            const char* description, | 
 |                            const char* serial) { | 
 |   return OpenIndex(vid, pid, mode, freq, endianess, interface, description, | 
 |                    serial, 0); | 
 | } | 
 |  | 
 | /* | 
 |  * Open device by VID/PID/index | 
 |  * | 
 |  * @vid         - Device vendor ID. | 
 |  * @pid         - Device product ID. | 
 |  * @mode        - MPSSE mode, one of enum modes. | 
 |  * @freq        - Clock frequency to use for the specified mode. | 
 |  * @endianess   - Specifies how data is clocked in/out (MSB, LSB). | 
 |  * @interface   - FTDI interface to use (IFACE_A - IFACE_D). | 
 |  * @description - Device product description (set to NULL if not needed). | 
 |  * @serial      - Device serial number (set to NULL if not needed). | 
 |  * @index       - Device index (set to 0 if not needed). | 
 |  * | 
 |  * Returns a pointer to an MPSSE context structure. | 
 |  * On success, mpsse->open will be set to 1. | 
 |  * On failure, mpsse->open will be set to 0. | 
 |  */ | 
 | 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) { | 
 |   int status = 0; | 
 |   struct mpsse_context* mpsse = NULL; | 
 |  | 
 |   mpsse = malloc(sizeof(struct mpsse_context)); | 
 |   if (!mpsse) | 
 |     return NULL; | 
 |  | 
 |   memset(mpsse, 0, sizeof(struct mpsse_context)); | 
 |  | 
 |   /* Legacy; flushing is no longer needed, so disable it by default. */ | 
 |   FlushAfterRead(mpsse, 0); | 
 |  | 
 |   /* ftdilib initialization */ | 
 |   if (ftdi_init(&mpsse->ftdi)) { | 
 |     free(mpsse); | 
 |     return NULL; | 
 |   } | 
 |  | 
 |   /* Set the FTDI interface  */ | 
 |   ftdi_set_interface(&mpsse->ftdi, interface); | 
 |  | 
 |   /* Open the specified device */ | 
 |   if (!ftdi_usb_open_desc_index(&mpsse->ftdi, vid, pid, description, serial, | 
 |                                 index)) { | 
 |     mpsse->mode = mode; | 
 |     mpsse->vid = vid; | 
 |     mpsse->pid = pid; | 
 |     mpsse->status = STOPPED; | 
 |     mpsse->endianess = endianess; | 
 |  | 
 |     /* Set the appropriate transfer size for the requested protocol */ | 
 |     if (mpsse->mode == I2C) | 
 |       mpsse->xsize = I2C_TRANSFER_SIZE; | 
 |     else | 
 |       mpsse->xsize = SPI_RW_SIZE; | 
 |  | 
 |     status |= ftdi_usb_reset(&mpsse->ftdi); | 
 |     status |= ftdi_set_latency_timer(&mpsse->ftdi, LATENCY_MS); | 
 |     status |= ftdi_write_data_set_chunksize(&mpsse->ftdi, CHUNK_SIZE); | 
 |     status |= ftdi_read_data_set_chunksize(&mpsse->ftdi, CHUNK_SIZE); | 
 |     status |= ftdi_set_bitmode(&mpsse->ftdi, 0, BITMODE_RESET); | 
 |  | 
 |     if (status == 0) { | 
 |       /* Set the read and write timeout periods */ | 
 |       set_timeouts(mpsse, USB_TIMEOUT); | 
 |  | 
 |       if (mpsse->mode != BITBANG) { | 
 |         ftdi_set_bitmode(&mpsse->ftdi, 0, BITMODE_MPSSE); | 
 |  | 
 |         if (SetClock(mpsse, freq) == MPSSE_OK) { | 
 |           if (SetMode(mpsse, endianess) == MPSSE_OK) { | 
 |             mpsse->opened = 1; | 
 |  | 
 |             /* Give the chip a few mS to initialize */ | 
 |             usleep(SETUP_DELAY); | 
 |  | 
 |             /* | 
 |              * Not all FTDI chips support all the commands that SetMode may | 
 |              * have sent. | 
 |              * This clears out any errors from unsupported commands that | 
 |              * might have been sent during set up. | 
 |              */ | 
 |             ftdi_usb_purge_buffers(&mpsse->ftdi); | 
 |           } | 
 |         } | 
 |       } else { | 
 |         /* Skip the setup functions if we're just operating in BITBANG mode | 
 |          */ | 
 |         if (!ftdi_set_bitmode(&mpsse->ftdi, 0xFF, BITMODE_BITBANG)) | 
 |           mpsse->opened = 1; | 
 |       } | 
 |     } | 
 |   } | 
 |  | 
 |   if (mpsse && !mpsse->opened) { | 
 |     Close(mpsse); | 
 |     mpsse = NULL; | 
 |   } | 
 |  | 
 |   return mpsse; | 
 | } | 
 |  | 
 | /* | 
 |  * Closes the device, deinitializes libftdi, and frees the MPSSE context | 
 |  *pointer. | 
 |  * | 
 |  * @mpsse - MPSSE context pointer. | 
 |  * | 
 |  * Returns void. | 
 |  */ | 
 | void Close(struct mpsse_context* mpsse) { | 
 |   if (!mpsse) | 
 |     return; | 
 |  | 
 |   if (mpsse->opened) { | 
 |     /* Shut these down only if initialization succeeded before. */ | 
 |     ftdi_set_bitmode(&mpsse->ftdi, 0, BITMODE_RESET); | 
 |     ftdi_usb_close(&mpsse->ftdi); | 
 |   } | 
 |   ftdi_deinit(&mpsse->ftdi); | 
 |   free(mpsse); | 
 | } | 
 |  | 
 | /* Enables bit-wise data transfers. | 
 |  * Must be called after MPSSE() / Open() / OpenIndex(). | 
 |  * | 
 |  * Returns void. | 
 |  */ | 
 | void EnableBitmode(struct mpsse_context* mpsse, int tf) { | 
 |   if (is_valid_context(mpsse)) { | 
 |     if (tf) { | 
 |       mpsse->tx |= MPSSE_BITMODE; | 
 |       mpsse->rx |= MPSSE_BITMODE; | 
 |       mpsse->txrx |= MPSSE_BITMODE; | 
 |     } else { | 
 |       mpsse->tx &= ~MPSSE_BITMODE; | 
 |       mpsse->rx &= ~MPSSE_BITMODE; | 
 |       mpsse->txrx &= ~MPSSE_BITMODE; | 
 |     } | 
 |   } | 
 | } | 
 |  | 
 | /* | 
 |  * Sets the appropriate transmit and receive commands based on the requested | 
 |  *mode and byte order. | 
 |  * | 
 |  * @mpsse     - MPSSE context pointer. | 
 |  * @endianess - MPSSE_MSB or MPSSE_LSB. | 
 |  * | 
 |  * Returns MPSSE_OK on success. | 
 |  * Returns MPSSE_FAIL on failure. | 
 |  */ | 
 | int SetMode(struct mpsse_context* mpsse, int endianess) { | 
 |   int retval = MPSSE_OK, i = 0, setup_commands_size = 0; | 
 |   uint8_t buf[CMD_SIZE] = {0}; | 
 |   uint8_t setup_commands[CMD_SIZE * MAX_SETUP_COMMANDS] = {0}; | 
 |  | 
 |   /* Do not call is_valid_context() here, as the FTDI chip may not be completely | 
 |    * configured when SetMode is called */ | 
 |   if (mpsse) { | 
 |     /* Read and write commands need to include endianess */ | 
 |     mpsse->tx = MPSSE_DO_WRITE | endianess; | 
 |     mpsse->rx = MPSSE_DO_READ | endianess; | 
 |     mpsse->txrx = MPSSE_DO_WRITE | MPSSE_DO_READ | endianess; | 
 |  | 
 |     /* Clock, data out, chip select pins are outputs; all others are inputs. */ | 
 |     mpsse->tris = DEFAULT_TRIS; | 
 |  | 
 |     /* Clock and chip select pins idle high; all others are low */ | 
 |     mpsse->pidle = mpsse->pstart = mpsse->pstop = DEFAULT_PORT; | 
 |  | 
 |     /* During reads and writes the chip select pin is brought low */ | 
 |     mpsse->pstart &= ~CS; | 
 |  | 
 |     /* Disable FTDI internal loopback */ | 
 |     SetLoopback(mpsse, 0); | 
 |  | 
 |     /* Send ACKs by default */ | 
 |     SetAck(mpsse, ACK); | 
 |  | 
 |     /* Ensure adaptive clock is disabled */ | 
 |     setup_commands[setup_commands_size++] = DISABLE_ADAPTIVE_CLOCK; | 
 |  | 
 |     switch (mpsse->mode) { | 
 |       case SPI0: | 
 |         /* SPI mode 0 clock idles low */ | 
 |         mpsse->pidle &= ~SK; | 
 |         mpsse->pstart &= ~SK; | 
 |         mpsse->pstop &= ~SK; | 
 |         /* SPI mode 0 propogates data on the falling edge and read data on the | 
 |          * rising edge of the clock */ | 
 |         mpsse->tx |= MPSSE_WRITE_NEG; | 
 |         mpsse->rx &= ~MPSSE_READ_NEG; | 
 |         mpsse->txrx |= MPSSE_WRITE_NEG; | 
 |         mpsse->txrx &= ~MPSSE_READ_NEG; | 
 |         break; | 
 |       case SPI3: | 
 |         /* SPI mode 3 clock idles high */ | 
 |         mpsse->pidle |= SK; | 
 |         mpsse->pstart |= SK; | 
 |         /* Keep the clock low while the CS pin is brought high to ensure we | 
 |          * don't accidentally clock out an extra bit */ | 
 |         mpsse->pstop &= ~SK; | 
 |         /* SPI mode 3 propogates data on the falling edge and read data on the | 
 |          * rising edge of the clock */ | 
 |         mpsse->tx |= MPSSE_WRITE_NEG; | 
 |         mpsse->rx &= ~MPSSE_READ_NEG; | 
 |         mpsse->txrx |= MPSSE_WRITE_NEG; | 
 |         mpsse->txrx &= ~MPSSE_READ_NEG; | 
 |         break; | 
 |       case SPI1: | 
 |         /* SPI mode 1 clock idles low */ | 
 |         mpsse->pidle &= ~SK; | 
 |         /* Since this mode idles low, the start condition should ensure that the | 
 |          * clock is low */ | 
 |         mpsse->pstart &= ~SK; | 
 |         /* Even though we idle low in this mode, we need to keep the clock line | 
 |          * high when we set the CS pin high to prevent | 
 |          * an unintended clock cycle from being sent by the FT2232. This way, | 
 |          * the clock goes high, but does not go low until | 
 |          * after the CS pin goes high. | 
 |          */ | 
 |         mpsse->pstop |= SK; | 
 |         /* Data read on falling clock edge */ | 
 |         mpsse->rx |= MPSSE_READ_NEG; | 
 |         mpsse->tx &= ~MPSSE_WRITE_NEG; | 
 |         mpsse->txrx |= MPSSE_READ_NEG; | 
 |         mpsse->txrx &= ~MPSSE_WRITE_NEG; | 
 |         break; | 
 |       case SPI2: | 
 |         /* SPI 2 clock idles high */ | 
 |         mpsse->pidle |= SK; | 
 |         mpsse->pstart |= SK; | 
 |         mpsse->pstop |= SK; | 
 |         /* Data read on falling clock edge */ | 
 |         mpsse->rx |= MPSSE_READ_NEG; | 
 |         mpsse->tx &= ~MPSSE_WRITE_NEG; | 
 |         mpsse->txrx |= MPSSE_READ_NEG; | 
 |         mpsse->txrx &= ~MPSSE_WRITE_NEG; | 
 |         break; | 
 |       case I2C: | 
 |         /* I2C propogates data on the falling clock edge and reads data on the | 
 |          * falling (or rising) clock edge */ | 
 |         mpsse->tx |= MPSSE_WRITE_NEG; | 
 |         mpsse->rx &= ~MPSSE_READ_NEG; | 
 |         /* In I2C, both the clock and the data lines idle high */ | 
 |         mpsse->pidle |= DO | DI; | 
 |         /* I2C start bit == data line goes from high to low while clock line is | 
 |          * high */ | 
 |         mpsse->pstart &= ~DO & ~DI; | 
 |         /* I2C stop bit == data line goes from low to high while clock line is | 
 |          * high - set data line low here, so the transition to the idle state | 
 |          * triggers the stop condition. */ | 
 |         mpsse->pstop &= ~DO & ~DI; | 
 |         /* Enable three phase clock to ensure that I2C data is available on both | 
 |          * the rising and falling clock edges */ | 
 |         setup_commands[setup_commands_size++] = ENABLE_3_PHASE_CLOCK; | 
 |         break; | 
 |       case GPIO: | 
 |         break; | 
 |       default: | 
 |         retval = MPSSE_FAIL; | 
 |     } | 
 |  | 
 |     /* Send any setup commands to the chip */ | 
 |     if (retval == MPSSE_OK && setup_commands_size > 0) { | 
 |       retval = raw_write(mpsse, setup_commands, setup_commands_size); | 
 |     } | 
 |  | 
 |     if (retval == MPSSE_OK) { | 
 |       /* Set the idle pin states */ | 
 |       set_bits_low(mpsse, mpsse->pidle); | 
 |  | 
 |       /* All GPIO pins are outputs, set low */ | 
 |       mpsse->trish = 0xFF; | 
 |       mpsse->gpioh = 0x00; | 
 |  | 
 |       buf[i++] = SET_BITS_HIGH; | 
 |       buf[i++] = mpsse->gpioh; | 
 |       buf[i++] = mpsse->trish; | 
 |  | 
 |       retval = raw_write(mpsse, buf, i); | 
 |     } | 
 |   } else { | 
 |     retval = MPSSE_FAIL; | 
 |   } | 
 |  | 
 |   return retval; | 
 | } | 
 |  | 
 | /* | 
 |  * Sets the appropriate divisor for the desired clock frequency. | 
 |  * | 
 |  * @mpsse - MPSSE context pointer. | 
 |  * @freq  - Desired clock frequency in hertz. | 
 |  * | 
 |  * Returns MPSSE_OK on success. | 
 |  * Returns MPSSE_FAIL on failure. | 
 |  */ | 
 | int SetClock(struct mpsse_context* mpsse, uint32_t freq) { | 
 |   int retval = MPSSE_FAIL; | 
 |   uint32_t system_clock = 0; | 
 |   uint16_t divisor = 0; | 
 |   uint8_t buf[CMD_SIZE] = {0}; | 
 |  | 
 |   /* Do not call is_valid_context() here, as the FTDI chip may not be completely | 
 |    * configured when SetClock is called */ | 
 |   if (mpsse) { | 
 |     if (freq > SIX_MHZ) { | 
 |       buf[0] = TCK_X5; | 
 |       system_clock = SIXTY_MHZ; | 
 |     } else { | 
 |       buf[0] = TCK_D5; | 
 |       system_clock = TWELVE_MHZ; | 
 |     } | 
 |  | 
 |     if (raw_write(mpsse, buf, 1) == MPSSE_OK) { | 
 |       if (freq <= 0) { | 
 |         divisor = 0xFFFF; | 
 |       } else { | 
 |         divisor = freq2div(system_clock, freq); | 
 |       } | 
 |  | 
 |       buf[0] = TCK_DIVISOR; | 
 |       buf[1] = (divisor & 0xFF); | 
 |       buf[2] = ((divisor >> 8) & 0xFF); | 
 |  | 
 |       if (raw_write(mpsse, buf, 3) == MPSSE_OK) { | 
 |         mpsse->clock = div2freq(system_clock, divisor); | 
 |         retval = MPSSE_OK; | 
 |       } | 
 |     } | 
 |   } | 
 |  | 
 |   return retval; | 
 | } | 
 |  | 
 | /* | 
 |  * Retrieves the last error string from libftdi. | 
 |  * | 
 |  * @mpsse - MPSSE context pointer. | 
 |  * | 
 |  * Returns a pointer to the last error string. | 
 |  */ | 
 | const char* ErrorString(struct mpsse_context* mpsse) { | 
 |   if (mpsse != NULL) { | 
 |     return ftdi_get_error_string(&mpsse->ftdi); | 
 |   } | 
 |  | 
 |   return NULL_CONTEXT_ERROR_MSG; | 
 | } | 
 |  | 
 | /* | 
 |  * Gets the currently configured clock rate. | 
 |  * | 
 |  * @mpsse - MPSSE context pointer. | 
 |  * | 
 |  * Returns the existing clock rate in hertz. | 
 |  */ | 
 | int GetClock(struct mpsse_context* mpsse) { | 
 |   int clock = 0; | 
 |  | 
 |   if (is_valid_context(mpsse)) { | 
 |     clock = mpsse->clock; | 
 |   } | 
 |  | 
 |   return clock; | 
 | } | 
 |  | 
 | /* | 
 |  * Returns the vendor ID of the FTDI chip. | 
 |  * | 
 |  * @mpsse - MPSSE context pointer. | 
 |  * | 
 |  * Returns the integer value of the vendor ID. | 
 |  */ | 
 | int GetVid(struct mpsse_context* mpsse) { | 
 |   int vid = 0; | 
 |  | 
 |   if (is_valid_context(mpsse)) { | 
 |     vid = mpsse->vid; | 
 |   } | 
 |  | 
 |   return vid; | 
 | } | 
 |  | 
 | /* | 
 |  * Returns the product ID of the FTDI chip. | 
 |  * | 
 |  * @mpsse - MPSSE context pointer. | 
 |  * | 
 |  * Returns the integer value of the product ID. | 
 |  */ | 
 | int GetPid(struct mpsse_context* mpsse) { | 
 |   int pid = 0; | 
 |  | 
 |   if (is_valid_context(mpsse)) { | 
 |     pid = mpsse->pid; | 
 |   } | 
 |  | 
 |   return pid; | 
 | } | 
 |  | 
 | /* | 
 |  * Returns the description of the FTDI chip, if any. | 
 |  * | 
 |  * @mpsse - MPSSE context pointer. | 
 |  * | 
 |  * Returns the description of the FTDI chip. | 
 |  */ | 
 | const char* GetDescription(struct mpsse_context* mpsse) { | 
 |   char* description = NULL; | 
 |  | 
 |   if (is_valid_context(mpsse)) { | 
 |     description = mpsse->description; | 
 |   } | 
 |  | 
 |   return description; | 
 | } | 
 |  | 
 | /* | 
 |  * Enable / disable internal loopback. | 
 |  * | 
 |  * @mpsse  - MPSSE context pointer. | 
 |  * @enable - Zero to disable loopback, 1 to enable loopback. | 
 |  * | 
 |  * Returns MPSSE_OK on success. | 
 |  * Returns MPSSE_FAIL on failure. | 
 |  */ | 
 | int SetLoopback(struct mpsse_context* mpsse, int enable) { | 
 |   uint8_t buf[1] = {0}; | 
 |   int retval = MPSSE_FAIL; | 
 |  | 
 |   if (is_valid_context(mpsse)) { | 
 |     if (enable) { | 
 |       buf[0] = LOOPBACK_START; | 
 |     } else { | 
 |       buf[0] = LOOPBACK_END; | 
 |     } | 
 |  | 
 |     retval = raw_write(mpsse, buf, 1); | 
 |   } | 
 |  | 
 |   return retval; | 
 | } | 
 |  | 
 | /* | 
 |  * Sets the idle state of the chip select pin. CS idles high by default. | 
 |  * | 
 |  * @mpsse - MPSSE context pointer. | 
 |  * @idle  - Set to 1 to idle high, 0 to idle low. | 
 |  * | 
 |  * Returns void. | 
 |  */ | 
 | void SetCSIdle(struct mpsse_context* mpsse, int idle) { | 
 |   if (is_valid_context(mpsse)) { | 
 |     if (idle > 0) { | 
 |       /* Chip select idles high, active low */ | 
 |       mpsse->pidle |= CS; | 
 |       mpsse->pstop |= CS; | 
 |       mpsse->pstart &= ~CS; | 
 |     } else { | 
 |       /* Chip select idles low, active high */ | 
 |       mpsse->pidle &= ~CS; | 
 |       mpsse->pstop &= ~CS; | 
 |       mpsse->pstart |= CS; | 
 |     } | 
 |   } | 
 |  | 
 |   return; | 
 | } | 
 |  | 
 | /* | 
 |  * Enables or disables flushing of the FTDI chip's RX buffers after each read | 
 |  *operation. | 
 |  * Flushing is disable by default. | 
 |  * | 
 |  * @mpsse - MPSSE context pointer. | 
 |  * @tf    - Set to 1 to enable flushing, or 0 to disable flushing. | 
 |  * | 
 |  * Returns void. | 
 |  */ | 
 | void FlushAfterRead(struct mpsse_context* mpsse, int tf) { | 
 |   mpsse->flush_after_read = tf; | 
 |   return; | 
 | } | 
 |  | 
 | /* | 
 |  * Send data start condition. | 
 |  * | 
 |  * @mpsse - MPSSE context pointer. | 
 |  * | 
 |  * Returns MPSSE_OK on success. | 
 |  * Returns MPSSE_FAIL on failure. | 
 |  */ | 
 | int Start(struct mpsse_context* mpsse) { | 
 |   int status = MPSSE_OK; | 
 |  | 
 |   if (is_valid_context(mpsse)) { | 
 |     if (mpsse->mode == I2C && mpsse->status == STARTED) { | 
 |       /* Set the default pin states while the clock is low since this is an I2C | 
 |        * repeated start condition */ | 
 |       status |= set_bits_low(mpsse, (mpsse->pidle & ~SK)); | 
 |  | 
 |       /* Make sure the pins are in their default idle state */ | 
 |       status |= set_bits_low(mpsse, mpsse->pidle); | 
 |     } | 
 |  | 
 |     /* Set the start condition */ | 
 |     status |= set_bits_low(mpsse, mpsse->pstart); | 
 |  | 
 |     /* | 
 |      * Hackish work around to properly support SPI mode 3. | 
 |      * SPI3 clock idles high, but needs to be set low before sending out | 
 |      * data to prevent unintenteded clock glitches from the FT2232. | 
 |      */ | 
 |     if (mpsse->mode == SPI3) { | 
 |       status |= set_bits_low(mpsse, (mpsse->pstart & ~SK)); | 
 |     } | 
 |     /* | 
 |      * Hackish work around to properly support SPI mode 1. | 
 |      * SPI1 clock idles low, but needs to be set high before sending out | 
 |      * data to preven unintended clock glitches from the FT2232. | 
 |      */ | 
 |     else if (mpsse->mode == SPI1) { | 
 |       status |= set_bits_low(mpsse, (mpsse->pstart | SK)); | 
 |     } | 
 |  | 
 |     mpsse->status = STARTED; | 
 |   } else { | 
 |     status = MPSSE_FAIL; | 
 |     mpsse->status = STOPPED; | 
 |   } | 
 |  | 
 |   return status; | 
 | } | 
 |  | 
 | /* | 
 |  * Performs a bit-wise write of up to 8 bits at a time. | 
 |  * | 
 |  * @mpsse - MPSSE context pointer. | 
 |  * @bits  - A byte containing the desired bits to write. | 
 |  * @size  - The number of bits from the 'bits' byte to write. | 
 |  * | 
 |  * Returns MPSSE_OK on success, MPSSE_FAIL on failure. | 
 |  */ | 
 | int WriteBits(struct mpsse_context* mpsse, char bits, size_t size) { | 
 |   uint8_t data[8] = {0}; | 
 |   size_t i = 0; | 
 |   int retval = MPSSE_OK; | 
 |  | 
 |   if (size > sizeof(data)) { | 
 |     size = sizeof(data); | 
 |   } | 
 |  | 
 |   /* Convert each bit in bits to an array of bytes */ | 
 |   for (i = 0; i < size; i++) { | 
 |     if (bits & (1 << i)) { | 
 |       /* Be sure to honor endianess */ | 
 |       if (mpsse->endianess == LSB) { | 
 |         data[i] = '\xFF'; | 
 |       } else { | 
 |         data[size - i - 1] = '\xFF'; | 
 |       } | 
 |     } | 
 |   } | 
 |  | 
 |   /* Enable bit mode before writing, then disable it afterwards. */ | 
 |   EnableBitmode(mpsse, 1); | 
 |   retval = Write(mpsse, data, size); | 
 |   EnableBitmode(mpsse, 0); | 
 |  | 
 |   return retval; | 
 | } | 
 |  | 
 | /* | 
 |  * Send data out via the selected serial protocol. | 
 |  * | 
 |  * @mpsse - MPSSE context pointer. | 
 |  * @data  - Buffer of data to send. | 
 |  * @size  - Size of data. | 
 |  * | 
 |  * Returns MPSSE_OK on success. | 
 |  * Returns MPSSE_FAIL on failure. | 
 |  */ | 
 | int Write(struct mpsse_context* mpsse, const void* vdata, int size) { | 
 |   const uint8_t* data = vdata; | 
 |   uint8_t* buf = NULL; | 
 |   int retval = MPSSE_FAIL, buf_size = 0, txsize = 0, n = 0; | 
 |  | 
 |   if (is_valid_context(mpsse)) { | 
 |     if (mpsse->mode) { | 
 |       while (n < size) { | 
 |         txsize = size - n; | 
 |         if (txsize > mpsse->xsize) { | 
 |           txsize = mpsse->xsize; | 
 |         } | 
 |  | 
 |         /* | 
 |          * For I2C we need to send each byte individually so that we can | 
 |          * read back each individual ACK bit, so set the transmit size to 1. | 
 |          */ | 
 |         if (mpsse->mode == I2C) { | 
 |           txsize = 1; | 
 |         } | 
 |  | 
 |         buf = build_block_buffer(mpsse, mpsse->tx, data + n, txsize, &buf_size); | 
 |         if (buf) { | 
 |           retval = raw_write(mpsse, buf, buf_size); | 
 |           n += txsize; | 
 |           free(buf); | 
 |  | 
 |           if (retval == MPSSE_FAIL) { | 
 |             break; | 
 |           } | 
 |  | 
 |           /* Read in the ACK bit and store it in mpsse->rack */ | 
 |           if (mpsse->mode == I2C) { | 
 |             raw_read(mpsse, (uint8_t*)&mpsse->rack, 1); | 
 |           } | 
 |         } else { | 
 |           break; | 
 |         } | 
 |       } | 
 |     } | 
 |  | 
 |     if (retval == MPSSE_OK && n == size) { | 
 |       retval = MPSSE_OK; | 
 |     } | 
 |   } | 
 |  | 
 |   return retval; | 
 | } | 
 |  | 
 | /* Performs a read. For internal use only; see Read() and ReadBits(). */ | 
 | static uint8_t* InternalRead(struct mpsse_context* mpsse, int size) { | 
 |   uint8_t *data = NULL, *buf = NULL; | 
 |   uint8_t sbuf[SPI_RW_SIZE] = {0}; | 
 |   int n = 0, rxsize = 0, data_size = 0, retval = 0; | 
 |  | 
 |   if (is_valid_context(mpsse)) { | 
 |     if (mpsse->mode) { | 
 |       buf = malloc(size); | 
 |       if (buf) { | 
 |         memset(buf, 0, size); | 
 |  | 
 |         while (n < size) { | 
 |           rxsize = size - n; | 
 |           if (rxsize > mpsse->xsize) { | 
 |             rxsize = mpsse->xsize; | 
 |           } | 
 |  | 
 |           data = build_block_buffer(mpsse, mpsse->rx, sbuf, rxsize, &data_size); | 
 |           if (data) { | 
 |             retval = raw_write(mpsse, data, data_size); | 
 |             free(data); | 
 |  | 
 |             if (retval == MPSSE_OK) { | 
 |               n += raw_read(mpsse, buf + n, rxsize); | 
 |             } else { | 
 |               break; | 
 |             } | 
 |           } else { | 
 |             break; | 
 |           } | 
 |         } | 
 |       } | 
 |     } | 
 |   } | 
 |  | 
 |   return buf; | 
 | } | 
 |  | 
 | /* | 
 |  * Reads data over the selected serial protocol. | 
 |  * | 
 |  * @mpsse - MPSSE context pointer. | 
 |  * @size  - Number of bytes to read. | 
 |  * | 
 |  * Returns a pointer to the read data on success. | 
 |  * Returns NULL on failure. | 
 |  */ | 
 | #ifdef SWIGPYTHON | 
 | swig_string_data Read(struct mpsse_context* mpsse, int size) | 
 | #else | 
 | uint8_t* Read(struct mpsse_context* mpsse, int size) | 
 | #endif | 
 | { | 
 |   uint8_t* buf = NULL; | 
 |  | 
 |   buf = InternalRead(mpsse, size); | 
 |  | 
 | #ifdef SWIGPYTHON | 
 |   swig_string_data sdata = {0}; | 
 |   sdata.size = size; | 
 |   sdata.data = buf; | 
 |   return sdata; | 
 | #else | 
 |   return buf; | 
 | #endif | 
 | } | 
 |  | 
 | /* | 
 |  * Performs a bit-wise read of up to 8 bits. | 
 |  * | 
 |  * @mpsse - MPSSE context pointer. | 
 |  * @size  - Number of bits to read. | 
 |  * | 
 |  * Returns an 8-bit byte containing the read bits. | 
 |  */ | 
 | char ReadBits(struct mpsse_context* mpsse, int size) { | 
 |   char bits = 0; | 
 |   uint8_t* rdata = NULL; | 
 |  | 
 |   if (size > 8) { | 
 |     size = 8; | 
 |   } | 
 |  | 
 |   EnableBitmode(mpsse, 1); | 
 |   rdata = InternalRead(mpsse, size); | 
 |   EnableBitmode(mpsse, 0); | 
 |  | 
 |   if (rdata) { | 
 |     /* The last byte in rdata will have all the read bits set or unset as | 
 |      * needed. */ | 
 |     bits = rdata[size - 1]; | 
 |  | 
 |     if (mpsse->endianess == MSB) { | 
 |       /* | 
 |        * In MSB mode, bits are sifted in from the left. If less than 8 bits were | 
 |        * read, we need to shift them left accordingly. | 
 |        */ | 
 |       bits = bits << (8 - size); | 
 |     } else if (mpsse->endianess == LSB) { | 
 |       /* | 
 |        * In LSB mode, bits are shifted in from the right. If less than 8 bits | 
 |        * were | 
 |        * read, we need to shift them right accordingly. | 
 |        */ | 
 |       bits = bits >> (8 - size); | 
 |     } | 
 |  | 
 |     free(rdata); | 
 |   } | 
 |  | 
 |   return bits; | 
 | } | 
 |  | 
 | /* | 
 |  * Reads and writes data over the selected serial protocol (SPI only). | 
 |  * | 
 |  * @mpsse - MPSSE context pointer. | 
 |  * @data  - Buffer containing bytes to write. | 
 |  * @size  - Number of bytes to transfer. | 
 |  * | 
 |  * Returns a pointer to the read data on success. | 
 |  * Returns NULL on failure. | 
 |  */ | 
 | #ifdef SWIGPYTHON | 
 | swig_string_data Transfer(struct mpsse_context* mpsse, char* data, int size) | 
 | #else | 
 | uint8_t* Transfer(struct mpsse_context* mpsse, uint8_t* data, int size) | 
 | #endif | 
 | { | 
 |   uint8_t *txdata = NULL, *buf = NULL; | 
 |   int n = 0, data_size = 0, rxsize = 0, retval = 0; | 
 |  | 
 |   if (is_valid_context(mpsse)) { | 
 |     /* Make sure we're configured for one of the SPI modes */ | 
 |     if (mpsse->mode >= SPI0 && mpsse->mode <= SPI3) { | 
 |       buf = malloc(size); | 
 |       if (buf) { | 
 |         memset(buf, 0, size); | 
 |  | 
 |         while (n < size) { | 
 |           /* When sending and recieving, FTDI chips don't seem to like large | 
 |            * data blocks. Limit the size of each block to SPI_TRANSFER_SIZE */ | 
 |           rxsize = size - n; | 
 |           if (rxsize > SPI_TRANSFER_SIZE) { | 
 |             rxsize = SPI_TRANSFER_SIZE; | 
 |           } | 
 |  | 
 |           txdata = build_block_buffer(mpsse, mpsse->txrx, data + n, rxsize, | 
 |                                       &data_size); | 
 |           if (txdata) { | 
 |             retval = raw_write(mpsse, txdata, data_size); | 
 |             free(txdata); | 
 |  | 
 |             if (retval == MPSSE_OK) { | 
 |               n += raw_read(mpsse, (buf + n), rxsize); | 
 |             } else { | 
 |               break; | 
 |             } | 
 |           } else { | 
 |             break; | 
 |           } | 
 |         } | 
 |       } | 
 |     } | 
 |   } | 
 |  | 
 | #ifdef SWIGPYTHON | 
 |   swig_string_data sdata = {0}; | 
 |   sdata.size = n; | 
 |   sdata.data = (char*)buf; | 
 |   return sdata; | 
 | #else | 
 |   return buf; | 
 | #endif | 
 | } | 
 |  | 
 | /* | 
 |  * Returns the last received ACK bit. | 
 |  * | 
 |  * @mpsse - MPSSE context pointer. | 
 |  * | 
 |  * Returns either an ACK (0) or a NACK (1). | 
 |  */ | 
 | int GetAck(struct mpsse_context* mpsse) { | 
 |   int ack = 0; | 
 |  | 
 |   if (is_valid_context(mpsse)) { | 
 |     ack = (mpsse->rack & 0x01); | 
 |   } | 
 |  | 
 |   return ack; | 
 | } | 
 |  | 
 | /* | 
 |  * Sets the transmitted ACK bit. | 
 |  * | 
 |  * @mpsse - MPSSE context pointer. | 
 |  * @ack   - 0 to send ACKs, 1 to send NACKs. | 
 |  * | 
 |  * Returns void. | 
 |  */ | 
 | void SetAck(struct mpsse_context* mpsse, int ack) { | 
 |   if (is_valid_context(mpsse)) { | 
 |     if (ack == NACK) { | 
 |       mpsse->tack = 0xFF; | 
 |     } else { | 
 |       mpsse->tack = 0x00; | 
 |     } | 
 |   } | 
 |  | 
 |   return; | 
 | } | 
 |  | 
 | /* | 
 |  * Causes libmpsse to send ACKs after each read byte in I2C mode. | 
 |  * | 
 |  * @mpsse - MPSSE context pointer. | 
 |  * | 
 |  * Returns void. | 
 |  */ | 
 | void SendAcks(struct mpsse_context* mpsse) { | 
 |   return SetAck(mpsse, ACK); | 
 | } | 
 |  | 
 | /* | 
 |  * Causes libmpsse to send NACKs after each read byte in I2C mode. | 
 |  * | 
 |  * @mpsse - MPSSE context pointer. | 
 |  * | 
 |  * Returns void. | 
 |  */ | 
 | void SendNacks(struct mpsse_context* mpsse) { | 
 |   return SetAck(mpsse, NACK); | 
 | } | 
 |  | 
 | /* | 
 |  * Send data stop condition. | 
 |  * | 
 |  * @mpsse - MPSSE context pointer. | 
 |  * | 
 |  * Returns MPSSE_OK on success. | 
 |  * Returns MPSSE_FAIL on failure. | 
 |  */ | 
 | int Stop(struct mpsse_context* mpsse) { | 
 |   int retval = MPSSE_OK; | 
 |  | 
 |   if (is_valid_context(mpsse)) { | 
 |     /* In I2C mode, we need to ensure that the data line goes low while the | 
 |      * clock line is low to avoid sending an inadvertent start condition */ | 
 |     if (mpsse->mode == I2C) { | 
 |       retval |= set_bits_low(mpsse, (mpsse->pidle & ~DO & ~SK)); | 
 |     } | 
 |  | 
 |     /* Send the stop condition */ | 
 |     retval |= set_bits_low(mpsse, mpsse->pstop); | 
 |  | 
 |     if (retval == MPSSE_OK) { | 
 |       /* Restore the pins to their idle states */ | 
 |       retval |= set_bits_low(mpsse, mpsse->pidle); | 
 |     } | 
 |  | 
 |     mpsse->status = STOPPED; | 
 |   } else { | 
 |     retval = MPSSE_FAIL; | 
 |     mpsse->status = STOPPED; | 
 |   } | 
 |  | 
 |   return retval; | 
 | } | 
 |  | 
 | /* | 
 |  * Sets the specified pin high. | 
 |  * | 
 |  * @mpsse - MPSSE context pointer. | 
 |  * @pin   - Pin number to set high. | 
 |  * | 
 |  * Returns MPSSE_OK on success. | 
 |  * Returns MPSSE_FAIL on failure. | 
 |  */ | 
 | int PinHigh(struct mpsse_context* mpsse, int pin) { | 
 |   int retval = MPSSE_FAIL; | 
 |  | 
 |   if (is_valid_context(mpsse)) { | 
 |     retval = gpio_write(mpsse, pin, HIGH); | 
 |   } | 
 |  | 
 |   return retval; | 
 | } | 
 |  | 
 | /* | 
 |  * Sets the specified pin low. | 
 |  * | 
 |  * @mpsse - MPSSE context pointer. | 
 |  * @pin   - Pin number to set low. | 
 |  * | 
 |  * Returns MPSSE_OK on success. | 
 |  * Returns MPSSE_FAIL on failure. | 
 |  */ | 
 | int PinLow(struct mpsse_context* mpsse, int pin) { | 
 |   int retval = MPSSE_FAIL; | 
 |  | 
 |   if (is_valid_context(mpsse)) { | 
 |     retval = gpio_write(mpsse, pin, LOW); | 
 |   } | 
 |  | 
 |   return retval; | 
 | } | 
 |  | 
 | /* | 
 |  * Sets the input/output direction of all pins. For use in BITBANG mode only. | 
 |  * | 
 |  * @mpsse     - MPSSE context pointer. | 
 |  * @direction - Byte indicating input/output direction of each bit.  1 is out. | 
 |  * | 
 |  * Returns MPSSE_OK if direction could be set, MPSSE_FAIL otherwise. | 
 |  */ | 
 | int SetDirection(struct mpsse_context* mpsse, uint8_t direction) { | 
 |   int retval = MPSSE_FAIL; | 
 |  | 
 |   if (is_valid_context(mpsse)) { | 
 |     if (mpsse->mode == BITBANG) { | 
 |       if (ftdi_set_bitmode(&mpsse->ftdi, direction, BITMODE_BITBANG) == 0) { | 
 |         retval = MPSSE_OK; | 
 |       } | 
 |     } | 
 |   } | 
 |  | 
 |   return retval; | 
 | } | 
 |  | 
 | /* | 
 |  * Sets the input/output value of all pins. For use in BITBANG mode only. | 
 |  * | 
 |  * @mpsse - MPSSE context pointer. | 
 |  * @data  - Byte indicating bit hi/low value of each bit. | 
 |  * | 
 |  * Returns MPSSE_OK if direction could be set, MPSSE_FAIL otherwise. | 
 |  */ | 
 | int WritePins(struct mpsse_context* mpsse, uint8_t data) { | 
 |   int retval = MPSSE_FAIL; | 
 |  | 
 |   if (is_valid_context(mpsse)) { | 
 |     if (mpsse->mode == BITBANG) { | 
 |       if (ftdi_write_data(&mpsse->ftdi, &data, 1) == 0) { | 
 |         retval = MPSSE_OK; | 
 |       } | 
 |     } | 
 |   } | 
 |  | 
 |   return retval; | 
 | } | 
 |  | 
 | /* | 
 |  * Reads the state of the chip's pins. For use in BITBANG mode only. | 
 |  * | 
 |  * @mpsse - MPSSE context pointer. | 
 |  * | 
 |  * Returns a byte with the corresponding pin's bits set to 1 or 0. | 
 |  */ | 
 | int ReadPins(struct mpsse_context* mpsse) { | 
 |   uint8_t val = 0; | 
 |  | 
 |   if (is_valid_context(mpsse)) { | 
 |     ftdi_read_pins((struct ftdi_context*)&mpsse->ftdi, (uint8_t*)&val); | 
 |   } | 
 |  | 
 |   return (int)val; | 
 | } | 
 |  | 
 | /* | 
 |  * Checks if a specific pin is high or low. For use in BITBANG mode only. | 
 |  * | 
 |  * @mpsse - MPSSE context pointer. | 
 |  * @pin   - The pin number. | 
 |  * @state - The state of the pins, as returned by ReadPins. | 
 |  *          If set to -1, ReadPins will automatically be called. | 
 |  * | 
 |  * Returns a 1 if the pin is high, 0 if the pin is low. | 
 |  */ | 
 | int PinState(struct mpsse_context* mpsse, int pin, int state) { | 
 |   if (state == -1) { | 
 |     state = ReadPins(mpsse); | 
 |   } | 
 |  | 
 |   /* If not in bitbang mode, the specified pin should be one of GPIOLx. Convert | 
 |    * these defines into an absolute pin number. */ | 
 |   if (mpsse->mode != BITBANG) { | 
 |     pin += NUM_GPIOL_PINS; | 
 |   } | 
 |  | 
 |   return ((state & (1 << pin)) >> pin); | 
 | } | 
 |  | 
 | /* | 
 |  * Places all I/O pins into a tristate mode. | 
 |  * | 
 |  * @mpsse - MPSSE context pointer. | 
 |  * | 
 |  * Returns MPSSE_OK on success, MPSSE_FAIL on failure. | 
 |  */ | 
 | int Tristate(struct mpsse_context* mpsse) { | 
 |   uint8_t cmd[CMD_SIZE] = {0}; | 
 |  | 
 |   /* Tristate the all I/O pins (FT232H only) */ | 
 |   cmd[0] = TRISTATE_IO; | 
 |   cmd[1] = 0xFF; | 
 |   cmd[2] = 0xFF; | 
 |  | 
 |   return raw_write(mpsse, cmd, sizeof(cmd)); | 
 | } |