// Copyright 2015 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// 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
//

#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <unistd.h>

#include "trunks/ftdi/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));
}
