// Copyright 2015 The Chromium OS Authors. All rights reserved.
// 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));
}
