From: Florent Kermarrec Date: Fri, 1 May 2015 14:15:15 +0000 (+0200) Subject: liteusb: refactor software (use python instead of libftdicom in C) and provide simple... X-Git-Tag: 24jan2021_ls180~2282 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=da0fe2ecfbe0968f07111e84358c1561b6959608;p=litex.git liteusb: refactor software (use python instead of libftdicom in C) and provide simple example. small modifications to fastftdi.c are also done to select our interface (A or B) and mode (synchronous, asynchronous) --- diff --git a/misoclib/com/liteusb/software/ftdi/README b/misoclib/com/liteusb/software/ftdi/README new file mode 100644 index 00000000..81aa546f --- /dev/null +++ b/misoclib/com/liteusb/software/ftdi/README @@ -0,0 +1,14 @@ +[> Libftdicom +------------------------------ + +[> Windows build +-------------------------- +1. Install MinGW32 +2. Download libusbx windows binaries (tested version: libusbx-1.0.17-win) +3. Put libusb-1.0.dll.a in mingw lib directory +4. Download Zadig and use WinUSB driver for Interface A and Interface B +5. make all in libftdicom/win + +[> Linux build +-------------------------- +1. make all in libftdicom/linux \ No newline at end of file diff --git a/misoclib/com/liteusb/software/ftdi/__init__.py b/misoclib/com/liteusb/software/ftdi/__init__.py new file mode 100644 index 00000000..49b68af2 --- /dev/null +++ b/misoclib/com/liteusb/software/ftdi/__init__.py @@ -0,0 +1,352 @@ +import platform +import ctypes +import os +import time +import queue +import threading + +_lpath = (os.path.dirname(__file__)) +if _lpath == '': + _lpath = '.' +if platform.system() == "Windows": + libftdicom = ctypes.cdll.LoadLibrary(_lpath + "/libftdicom.dll") +else: + libftdicom = ctypes.cdll.LoadLibrary(_lpath + "/libftdicom.so") + + +class FTDI_Device(ctypes.Structure): + _fields_ = [ + ('_1', ctypes.c_void_p), + ('_2', ctypes.c_void_p), + ] + +pFTDI_Device = ctypes.POINTER(FTDI_Device) + +# FTDIDevice_Open +FTDIDevice_Open = libftdicom.FTDIDevice_Open +FTDIDevice_Open.argtypes = [ + pFTDI_Device, # Dev + ctypes.c_int # Interface + ] +FTDIDevice_Open.restype = ctypes.c_int + +# FTDIDevice_Close +FTDIDevice_Close = libftdicom.FTDIDevice_Close +FTDIDevice_Close.argtypes = [pFTDI_Device] + +FTDIDevice_SetMode = libftdicom.FTDIDevice_SetMode +FTDIDevice_SetMode.argtypes = [ + pFTDI_Device, # Dev + ctypes.c_int, # Interface + ctypes.c_int, # Mode + ctypes.c_char, # PinDirection + ctypes.c_char, # baudrate + ] + + +FTDIDevice_Write = libftdicom.FTDIDevice_Write +FTDIDevice_Write.argtypes = [ + pFTDI_Device, # Dev + ctypes.c_int, # Interface + ctypes.c_char_p, # Buf + ctypes.c_size_t, # N + ctypes.c_bool, # async + ] +FTDIDevice_Write.restype = ctypes.c_int + +p_cb_StreamCallback = ctypes.CFUNCTYPE( + ctypes.c_int, # retval + ctypes.POINTER(ctypes.c_uint8), # buf + ctypes.c_int, # length + ctypes.c_void_p, # progress + ctypes.c_void_p) # userdata + +FTDIDevice_ReadStream = libftdicom.FTDIDevice_ReadStream +FTDIDevice_ReadStream.argtypes = [ + pFTDI_Device, # dev + ctypes.c_int, # interface + p_cb_StreamCallback, # callback + ctypes.c_void_p, # userdata + ctypes.c_int, # packetsPerTransfer + ctypes.c_int, # numTransfers + ] +FTDIDevice_ReadStream.restype = ctypes.c_int + +FTDI_INTERFACE_A = 1 +FTDI_INTERFACE_B = 2 + +FTDI_BITMODE_SYNC_FIFO = (1 << 6) + + +class FTDIDevice: + def __init__(self, interface, mode): + self.__is_open = False + self._dev = FTDI_Device() + self.interface = interface + self.mode = mode + + def __del__(self): + if self.__is_open: + self.__is_open = False + FTDIDevice_Close(self._dev) + + def open(self): + err = FTDIDevice_Open(self._dev, self.interface) + if err: + return err + else: + self.__is_open = True + + if self.mode == "synchronous": + err = FTDIDevice_SetMode(self._dev, interface, FTDI_BITMODE_SYNC_FIFO, 0xFF, 0) + + return err + + def write(self, intf, buf, async=False): + if not isinstance(buf, bytes): + raise TypeError("buf must be bytes") + + return FTDIDevice_Write(self._dev, intf, buf, len(buf), async) + + def read(self, intf, n): + buf = [] + + def callback(b, prog): + buf.extend(b) + return int(len(buf) >= n) + + self.read_async(intf, callback, 4, 4) + + return buf + + def read_async(self, intf, callback, packetsPerTransfer, numTransfers): + def callback_wrapper(buf, ll, prog, user): + if ll: + b = ctypes.string_at(buf, ll) + else: + b = b'' + return callback(b, prog) + + cb = p_cb_StreamCallback(callback_wrapper) + + return FTDIDevice_ReadStream(self._dev, intf, cb, + None, packetsPerTransfer, numTransfers) + + +class ProtocolError(Exception): + pass + + +class TimeoutError(Exception): + pass + + +INCOMPLETE = -1 +UNMATCHED = 0 +class BaseService: + def match_identifier(self, byt): + r = True + r = r and (byt[0] == 0x5A) + r = r and (byt[1] == 0xA5) + r = r and (byt[2] == 0x5A) + r = r and (byt[3] == 0xA5) + r = r and (byt[4] == self.tag) + return r + + def get_needed_size_for_identifier(self): + return self.NEEDED_FOR_SIZE + + def present_bytes(self, b): + if len(b) < self.get_needed_size_for_identifier(): + return INCOMPLETE + + if not self.match_identifier(b): + return UNMATCHED + + size = self.get_packet_size(b) + + if len(b) < size: + return INCOMPLETE + + self.consume(b[:size]) + + return size + + +class UART: + class __UARTService(BaseService): + NEEDED_FOR_SIZE = 9 + + def __init__(self, tag): + self.tag = tag + self.q = queue.Queue() + + def get_packet_size(self, buf): + return 10 + + def consume(self, buf): + self.q.put(buf[9]) + + def __init__(self, tag): + self.tag = tag + self.service = UART.__UARTService(self.tag) + + def do_read(self, timeout=None): + try: + resp = self.service.q.get(True, timeout) + except queue.Empty: + return -1 + return resp + + def do_write(self, value): + msg = [0x5A, 0xA5, 0x5A, 0xA5, self.tag, 0x00, 0x00, 0x00, 1, value&0xFF] + self.service.write(bytes(msg)) + + +class DMA: + class __DMAService(BaseService): + NEEDED_FOR_SIZE = 9 + + def __init__(self, tag): + self.tag = tag + self.q = queue.Queue() + + def get_packet_size(self, buf): + payload_size = buf[5] << 24 + payload_size |= buf[6] << 16 + payload_size |= buf[7] << 8 + payload_size |= buf[8] << 0 + return 9 + payload_size + + def consume(self, buf): + self.q.put(buf[9:]) + + def __init__(self, tag): + self.tag = tag + self.service = DMA.__DMAService(self.tag) + + def do_read(self, timeout=None): + try: + resp = list(self.service.q.get(True, timeout)) + except queue.Empty: + raise TimeoutError("DMA read timed out") + return resp + + def do_write(self, data): + length = len(data) + msg = [0x5A, 0xA5, 0x5A, 0xA5, self.tag, + (length & 0xff000000) >> 24, + (length & 0x00ff0000) >> 16, + (length & 0x0000ff00) >> 8, + (length & 0x000000ff) >> 0] + msg += data + self.service.write(bytes(msg)) + + +class FTDIComDevice: + def __init__(self, interface, mode, uart_tag=0, dma_tag=1, verbose=False): + self.__is_open = False + + self.interface = interface + self.mode = mode + + self.dev = FTDIDevice(interface, mode) + self.verbose = verbose + + self.uart = UART(uart_tag) + self.dma = DMA(dma_tag) + + self.__services = [self.uart.service, self.dma.service] + + # Inject a write function into the services + for service in self.__services: + def write(msg): + if self.verbose: + print("< %s" % " ".join("%02x" % i for i in msg)) + + self.dev.write(self.interface, msg, async=False) + + service.write = write + + def __comms(self): + self.__buf = b"" + + def callback(b, prog): + try: + if self.verbose and b: + print("> %s" % " ".join("%02x" % i for i in b)) + + self.__buf += b + + incomplete = False + + while self.__buf and not incomplete: + for service in self.__services: + code = service.present_bytes(self.__buf) + if code == INCOMPLETE: + incomplete = True + break + elif code: + self.__buf = self.__buf[code:] + break + else: + self.__buf = self.__buf[1:] + + return int(self.__comm_term) + except Exception as e: + self.__comm_term = True + self.__comm_exc = e + return 1 + + while not self.__comm_term: + self.dev.read_async(self.interface, callback, 8, 16) + + if self.__comm_exc: + raise self.__comm_exc + + def __del__(self): + if self.__is_open: + self.close() + + def open(self): + if self.__is_open: + raise ValueError("FTDICOMDevice doubly opened") + + stat = self.dev.open() + if stat: + print("USB: Error opening device\n") + return stat + + self.commthread = threading.Thread(target=self.__comms, daemon=True) + self.__comm_term = False + self.__comm_exc = None + + self.commthread.start() + + self.__comm_term = False + self.__is_open = True + + def close(self): + if not self.__is_open: + raise ValueError("FTDICOMDevice doubly closed") + + self.__comm_term = True + self.commthread.join() + + self.__is_open = False + + def uartflush(self, timeout=0.25): + while (self.uartread(timeout) != -1): + pass + + def uartread(self, timeout=None): + return self.uart.do_read(timeout) + + def uartwrite(self, value): + return self.uart.do_write(value) + + def dmaread(self): + return self.dma.do_read() + + def dmawrite(self, data): + return self.dma.do_write(data) diff --git a/misoclib/com/liteusb/software/ftdi/example.py b/misoclib/com/liteusb/software/ftdi/example.py new file mode 100644 index 00000000..b1cdbba8 --- /dev/null +++ b/misoclib/com/liteusb/software/ftdi/example.py @@ -0,0 +1,81 @@ +import platform +import os +import sys +import time +import threading + +# XXX FTDI Communication POC + +sys.path.append("../") +from ftdi import FTDIComDevice, FTDI_INTERFACE_B + +def uart_console(ftdi_com): + def read(): + while True: + print(chr(ftdi_com.uartread()), end="") + + readthread = threading.Thread(target=read, daemon=True) + readthread.start() + + def write(): + while True: + for e in input(): + c = ord(e) + ftdi_com.uartwrite(c) + ftdi_com.uartwrite(ord("\n")) + + + writethread = threading.Thread(target=write, daemon=True) + writethread.start() + + +def uart_virtual(ftdi_com): + import pty, serial + master, slave = pty.openpty() + s_name = os.ttyname(slave) + ser = serial.Serial(s_name) + + def read(): + while True: + s = ftdi_com.uartread() + s = bytes(chr(s).encode('utf-8')) + os.write(master, s) + + readthread = threading.Thread(target=read, daemon=True) + readthread.start() + + def write(): + while True: + for c in list(os.read(master, 100)): + ftdi_com.uartwrite(c) + + writethread = threading.Thread(target=write, daemon=True) + writethread.start() + + return s_name + + +ftdi_map = { + "uart": 0, + "dma": 1 +} +ftdi_com = FTDIComDevice(FTDI_INTERFACE_B, + mode="asynchronous", + uart_tag=ftdi_map["uart"], + dma_tag=ftdi_map["dma"], + verbose=False) +ftdi_com.open() +# test DMA +for i in range(256): + ftdi_com.dmawrite([i]) + print("%02x" %(ftdi_com.dmaread()[0]), end="") + sys.stdout.flush() +print("") +# test UART +if platform.system() == "Windows": + uart_console(ftdi_com) # redirect uart to console since pty does not exist on Windows platforms +else: + s_name = uart_virtual(ftdi_com) + print(s_name) +while True: + time.sleep(1) diff --git a/misoclib/com/liteusb/software/ftdi/fastftdi.c b/misoclib/com/liteusb/software/ftdi/fastftdi.c new file mode 100644 index 00000000..9f49b416 --- /dev/null +++ b/misoclib/com/liteusb/software/ftdi/fastftdi.c @@ -0,0 +1,548 @@ +/* + * fastftdi.c - A minimal FTDI FT2232H interface for which supports bit-bang + * mode, but focuses on very high-performance support for + * synchronous FIFO mode. Requires libusb-1.0 + * + * Copyright (C) 2009 Micah Elizabeth Scott + * Copyright (C) 2015 Florent Kermarrec + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include +#include +#include +#include "fastftdi.h" + +#if defined _WIN32 || defined _WIN64 + #include + #include + int gettimeofday (struct timeval *tp, void *tz) + { + struct _timeb timebuffer; + _ftime (&timebuffer); + tp->tv_sec = timebuffer.time; + tp->tv_usec = timebuffer.millitm * 1000; + return 0; + } +#endif + +typedef struct { + FTDIStreamCallback *callback; + void *userdata; + int result; + FTDIProgressInfo progress; +} FTDIStreamState; + +static int +DeviceInit(FTDIDevice *dev, FTDIInterface interface) +{ + int err; + + if (libusb_kernel_driver_active(dev->handle, (interface-1)) == 1) { + if ((err = libusb_detach_kernel_driver(dev->handle, (interface-1)))) { + perror("Error detaching kernel driver"); + return err; + } + } + + if ((err = libusb_set_configuration(dev->handle, 1))) { + perror("Error setting configuration"); + return err; + } + + if ((err = libusb_claim_interface(dev->handle, (interface-1)))) { + perror("Error claiming interface"); + return err; + } + + return 0; +} + + +int +FTDIDevice_Open(FTDIDevice *dev, FTDIInterface interface) +{ + int err; + + memset(dev, 0, sizeof *dev); + + if ((err = libusb_init(&dev->libusb))) { + return err; + } + + libusb_set_debug(dev->libusb, 0); + + + if (!dev->handle) { + dev->handle = libusb_open_device_with_vid_pid(dev->libusb, + FTDI_VENDOR, + FTDI_PRODUCT_FT2232H); + } + + if (!dev->handle) { + return LIBUSB_ERROR_NO_DEVICE; + } + + return DeviceInit(dev, interface); +} + + +void +FTDIDevice_Close(FTDIDevice *dev) +{ + libusb_close(dev->handle); + libusb_exit(dev->libusb); +} + + +int +FTDIDevice_Reset(FTDIDevice *dev, FTDIInterface interface) +{ + int err; + + err = libusb_reset_device(dev->handle); + if (err) + return err; + + return DeviceInit(dev, interface); +} + + +int +FTDIDevice_SetMode(FTDIDevice *dev, FTDIInterface interface, + FTDIBitmode mode, uint8_t pinDirections, + int baudRate) +{ + int err; + + err = libusb_control_transfer(dev->handle, + LIBUSB_REQUEST_TYPE_VENDOR + | LIBUSB_RECIPIENT_DEVICE + | LIBUSB_ENDPOINT_OUT, + FTDI_SET_BITMODE_REQUEST, + pinDirections | (mode << 8), + interface, + NULL, 0, + FTDI_COMMAND_TIMEOUT); + if (err) + return err; + + if (baudRate) { + int divisor; + + if (mode == FTDI_BITMODE_BITBANG) + baudRate <<= 2; + + divisor = 240000000 / baudRate; + if (divisor < 1 || divisor > 0xFFFF) { + return LIBUSB_ERROR_INVALID_PARAM; + } + + err = libusb_control_transfer(dev->handle, + LIBUSB_REQUEST_TYPE_VENDOR + | LIBUSB_RECIPIENT_DEVICE + | LIBUSB_ENDPOINT_OUT, + FTDI_SET_BAUD_REQUEST, + divisor, + interface, + NULL, 0, + FTDI_COMMAND_TIMEOUT); + if (err) + return err; + } + + return err; +} + + +/* + * Internal callback for cleaning up async writes. + */ + +static void +WriteAsyncCallback(struct libusb_transfer *transfer) +{ + free(transfer->buffer); + libusb_free_transfer(transfer); +} + + +/* + * Write to an FTDI interface, either synchronously or asynchronously. + * Async writes have no completion callback, they finish 'eventually'. + */ + +int +FTDIDevice_Write(FTDIDevice *dev, FTDIInterface interface, + uint8_t *data, size_t length, bool async) +{ + int err; + + if (async) { + struct libusb_transfer *transfer = libusb_alloc_transfer(0); + + if (!transfer) { + return LIBUSB_ERROR_NO_MEM; + } + + libusb_fill_bulk_transfer(transfer, dev->handle, FTDI_EP_OUT(interface), + malloc(length), length, (libusb_transfer_cb_fn) WriteAsyncCallback, 0, 0); + + if (!transfer->buffer) { + libusb_free_transfer(transfer); + return LIBUSB_ERROR_NO_MEM; + } + + memcpy(transfer->buffer, data, length); + err = libusb_submit_transfer(transfer); + + } else { + int transferred; + err = libusb_bulk_transfer(dev->handle, FTDI_EP_OUT(interface), + data, length, &transferred, + FTDI_COMMAND_TIMEOUT); + } + + if (err < 0) + return err; + else + return 0; +} + + +int +FTDIDevice_WriteByteSync(FTDIDevice *dev, FTDIInterface interface, uint8_t byte) +{ + return FTDIDevice_Write(dev, interface, &byte, sizeof byte, false); +} + + +int +FTDIDevice_ReadByteSync(FTDIDevice *dev, FTDIInterface interface, uint8_t *byte) +{ + /* + * This is a simplified synchronous read, intended for bit-banging mode. + * Ignores the modem/buffer status bytes, returns just the data. + * + */ + + uint8_t packet[3]; + int transferred, err; + + err = libusb_bulk_transfer(dev->handle, FTDI_EP_IN(interface), + packet, sizeof packet, &transferred, + FTDI_COMMAND_TIMEOUT); + if (err < 0) { + return err; + } + if (transferred != sizeof packet) { + return -1; + } + + if (byte) { + *byte = packet[sizeof packet - 1]; + } + + return 0; +} + + +/* + * Internal callback for one transfer's worth of stream data. + * Split it into packets and invoke the callbacks. + */ + +static void +ReadStreamCallback(struct libusb_transfer *transfer) +{ + FTDIStreamState *state = transfer->user_data; + + if (state->result == 0) { + if (transfer->status == LIBUSB_TRANSFER_COMPLETED) { + + int i; + uint8_t *ptr = transfer->buffer; + int length = transfer->actual_length; + int numPackets = (length + FTDI_PACKET_SIZE - 1) >> FTDI_LOG_PACKET_SIZE; + + for (i = 0; i < numPackets; i++) { + int payloadLen; + int packetLen = length; + + if (packetLen > FTDI_PACKET_SIZE) + packetLen = FTDI_PACKET_SIZE; + + payloadLen = packetLen - FTDI_HEADER_SIZE; + state->progress.current.totalBytes += payloadLen; + + state->result = state->callback(ptr + FTDI_HEADER_SIZE, payloadLen, + NULL, state->userdata); + if (state->result) + break; + + ptr += packetLen; + length -= packetLen; + } + + } else { + state->result = LIBUSB_ERROR_IO; + } + } + + if (state->result == 0) { + transfer->status = -1; + state->result = libusb_submit_transfer(transfer); + } +} + + +static double +TimevalDiff(const struct timeval *a, const struct timeval *b) +{ + return (a->tv_sec - b->tv_sec) + 1e-6 * (a->tv_usec - b->tv_usec); +} + + +/* + * Use asynchronous transfers in libusb-1.0 for high-performance + * streaming of data from a device interface back to the PC. This + * function continuously transfers data until either an error occurs + * or the callback returns a nonzero value. This function returns + * a libusb error code or the callback's return value. + * + * For every contiguous block of received data, the callback will + * be invoked. + */ + +int +FTDIDevice_ReadStream(FTDIDevice *dev, FTDIInterface interface, + FTDIStreamCallback *callback, void *userdata, + int packetsPerTransfer, int numTransfers) +{ + struct libusb_transfer **transfers; + FTDIStreamState state = { callback, userdata }; + int bufferSize = packetsPerTransfer * FTDI_PACKET_SIZE; + int xferIndex; + int err = 0; + + /* + * Set up all transfers + */ + + transfers = calloc(numTransfers, sizeof *transfers); + if (!transfers) { + err = LIBUSB_ERROR_NO_MEM; + goto cleanup; + } + + for (xferIndex = 0; xferIndex < numTransfers; xferIndex++) { + struct libusb_transfer *transfer; + + transfer = libusb_alloc_transfer(0); + transfers[xferIndex] = transfer; + if (!transfer) { + err = LIBUSB_ERROR_NO_MEM; + goto cleanup; + } + + libusb_fill_bulk_transfer(transfer, dev->handle, FTDI_EP_IN(interface), + malloc(bufferSize), bufferSize, (libusb_transfer_cb_fn) ReadStreamCallback, + &state, 0); + + if (!transfer->buffer) { + err = LIBUSB_ERROR_NO_MEM; + goto cleanup; + } + + transfer->status = -1; + err = libusb_submit_transfer(transfer); + if (err) + goto cleanup; + } + + /* + * Run the transfers, and periodically assess progress. + */ + + gettimeofday(&state.progress.first.time, NULL); + + do { + FTDIProgressInfo *progress = &state.progress; + const double progressInterval = 0.1; + struct timeval timeout = { 0, 10000 }; + struct timeval now; + + int err = libusb_handle_events_timeout(dev->libusb, &timeout); + if (!state.result) { + state.result = err; + } + + // If enough time has elapsed, update the progress + gettimeofday(&now, NULL); + if (TimevalDiff(&now, &progress->current.time) >= progressInterval) { + + progress->current.time = now; + + if (progress->prev.totalBytes) { + // We have enough information to calculate rates + + double currentTime; + + progress->totalTime = TimevalDiff(&progress->current.time, + &progress->first.time); + currentTime = TimevalDiff(&progress->current.time, + &progress->prev.time); + + progress->totalRate = progress->current.totalBytes / progress->totalTime; + progress->currentRate = (progress->current.totalBytes - + progress->prev.totalBytes) / currentTime; + } + + state.result = state.callback(NULL, 0, progress, state.userdata); + progress->prev = progress->current; + } + } while (!state.result); + + /* + * Cancel any outstanding transfers, and free memory. + */ + + cleanup: + if (transfers) { + bool done_cleanup = false; + while (!done_cleanup) + { + done_cleanup = true; + + for (xferIndex = 0; xferIndex < numTransfers; xferIndex++) { + struct libusb_transfer *transfer = transfers[xferIndex]; + + if (transfer) { + // If a transfer is in progress, cancel it + if (transfer->status == -1) { + libusb_cancel_transfer(transfer); + + // And we need to wait until we get a clean sweep + done_cleanup = false; + + // If a transfer is complete or cancelled, nuke it + } else if (transfer->status == 0 || + transfer->status == LIBUSB_TRANSFER_CANCELLED) { + free(transfer->buffer); + libusb_free_transfer(transfer); + transfers[xferIndex] = NULL; + } + } + } + + // pump events + struct timeval timeout = { 0, 10000 }; + libusb_handle_events_timeout(dev->libusb, &timeout); + } + free(transfers); + } + + if (err) + return err; + else + return state.result; +} + +/* MPSSE mode support -- see + * http://www.ftdichip.com/Support/Documents/AppNotes/AN_108_Command_Processor_for_MPSSE_and_MCU_Host_Bus_Emulation_Modes.pdf + */ + +int +FTDIDevice_MPSSE_Enable(FTDIDevice *dev, FTDIInterface interface) +{ + int err; + + /* Reset interface */ + + err = FTDIDevice_SetMode(dev, interface, FTDI_BITMODE_RESET, 0, 0); + if (err) + return err; + + /* Enable MPSSE mode */ + + err = FTDIDevice_SetMode(dev, interface, FTDI_BITMODE_MPSSE, + FTDI_SET_BITMODE_REQUEST, 0); + + return err; +} + +int +FTDIDevice_MPSSE_SetDivisor(FTDIDevice *dev, FTDIInterface interface, + uint8_t ValueL, uint8_t ValueH) +{ + uint8_t buf[3] = {FTDI_MPSSE_SETDIVISOR, 0, 0}; + + buf[1] = ValueL; + buf[2] = ValueH; + + return FTDIDevice_Write(dev, interface, buf, 3, false); +} + +int +FTDIDevice_MPSSE_SetLowByte(FTDIDevice *dev, FTDIInterface interface, uint8_t data, uint8_t dir) +{ + uint8_t buf[3] = {FTDI_MPSSE_SETLOW, 0, 0}; + + buf[1] = data; + buf[2] = dir; + + return FTDIDevice_Write(dev, interface, buf, 3, false); +} + +int +FTDIDevice_MPSSE_SetHighByte(FTDIDevice *dev, FTDIInterface interface, uint8_t data, uint8_t dir) +{ + uint8_t buf[3] = {FTDI_MPSSE_SETHIGH, 0, 0}; + + buf[1] = data; + buf[2] = dir; + + return FTDIDevice_Write(dev, interface, buf, 3, false); +} + +int +FTDIDevice_MPSSE_GetLowByte(FTDIDevice *dev, FTDIInterface interface, uint8_t *byte) +{ + int err; + + err = FTDIDevice_WriteByteSync(dev, interface, FTDI_MPSSE_GETLOW); + if (err) + return err; + + return FTDIDevice_ReadByteSync(dev, interface, byte); +} + +int +FTDIDevice_MPSSE_GetHighByte(FTDIDevice *dev, FTDIInterface interface, uint8_t *byte) +{ + int err; + + err = FTDIDevice_WriteByteSync(dev, interface, FTDI_MPSSE_GETHIGH); + if (err) + return err; + + return FTDIDevice_ReadByteSync(dev, interface, byte); +} diff --git a/misoclib/com/liteusb/software/ftdi/fastftdi.h b/misoclib/com/liteusb/software/ftdi/fastftdi.h new file mode 100644 index 00000000..b4251427 --- /dev/null +++ b/misoclib/com/liteusb/software/ftdi/fastftdi.h @@ -0,0 +1,133 @@ +/* + * fastftdi.h - A minimal FTDI FT232H interface for Linux which supports + * bit-bang mode, but focuses on very high-performance support + * for synchronous FIFO mode. + * + * Copyright (C) 2009 Micah Elizabeth Scott + * Copyright (C) 2015 Florent Kermarrec + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef __FASTFTDI_H +#define __FASTFTDI_H + +#include +#include +#include + +typedef enum { + FTDI_BITMODE_RESET = 0, + FTDI_BITMODE_BITBANG = 1 << 0, + FTDI_BITMODE_MPSSE = 1 << 1, + FTDI_BITMODE_SYNC_BITBANG = 1 << 2, + FTDI_BITMODE_MCU = 1 << 3, + FTDI_BITMODE_OPTO = 1 << 4, + FTDI_BITMODE_CBUS = 1 << 5, + FTDI_BITMODE_SYNC_FIFO = 1 << 6, +} FTDIBitmode; + +typedef enum { + FTDI_MPSSE_SETLOW = 0x80, + FTDI_MPSSE_SETHIGH = 0x82, + FTDI_MPSSE_GETLOW = 0x81, + FTDI_MPSSE_GETHIGH = 0x83, + FTDI_MPSSE_SETDIVISOR = 0x86, +} FTDIMPSSEOpcode; + +typedef enum { + FTDI_INTERFACE_A = 1, + FTDI_INTERFACE_B = 2, +} FTDIInterface; + +typedef struct { + libusb_context *libusb; + libusb_device_handle *handle; +} FTDIDevice; + +typedef struct { + struct { + uint64_t totalBytes; + struct timeval time; + } first, prev, current; + + double totalTime; + double totalRate; + double currentRate; +} FTDIProgressInfo; + + +/* + * USB Constants + */ + +#define FTDI_VENDOR 0x0403 +#define FTDI_PRODUCT_FT2232H 0x6010 + +#define FTDI_COMMAND_TIMEOUT 1000 + +#define FTDI_SET_BAUD_REQUEST 0x03 +#define FTDI_SET_BITMODE_REQUEST 0x0B + +#define FTDI_EP_IN(i) (0x81 + (i-1)*2) +#define FTDI_EP_OUT(i) (0x02 + (i-1)*2) + +#define FTDI_PACKET_SIZE 512 // Specific to FT2232H +#define FTDI_LOG_PACKET_SIZE 9 // 512 == 1 << 9 +#define FTDI_HEADER_SIZE 2 + +typedef int (FTDIStreamCallback)(uint8_t *buffer, int length, + FTDIProgressInfo *progress, void *userdata); + + +/* + * Public Functions + */ + +int FTDIDevice_Open(FTDIDevice *dev, FTDIInterface interface); +void FTDIDevice_Close(FTDIDevice *dev); +int FTDIDevice_Reset(FTDIDevice *dev, FTDIInterface interface); + +int FTDIDevice_SetMode(FTDIDevice *dev, FTDIInterface interface, + FTDIBitmode mode, uint8_t pinDirections, + int baudRate); + +int FTDIDevice_Write(FTDIDevice *dev, FTDIInterface interface, + uint8_t *data, size_t length, bool async); + +int FTDIDevice_WriteByteSync(FTDIDevice *dev, FTDIInterface interface, uint8_t byte); +int FTDIDevice_ReadByteSync(FTDIDevice *dev, FTDIInterface interface, uint8_t *byte); + +int FTDIDevice_ReadStream(FTDIDevice *dev, FTDIInterface interface, + FTDIStreamCallback *callback, void *userdata, + int packetsPerTransfer, int numTransfers); + +int FTDIDevice_MPSSE_Enable(FTDIDevice *dev, FTDIInterface interface); +int FTDIDevice_MPSSE_SetDivisor(FTDIDevice *dev, FTDIInterface interface, + uint8_t ValueL, uint8_t ValueH); + +int FTDIDevice_MPSSE_SetLowByte(FTDIDevice *dev, FTDIInterface interface, + uint8_t data, uint8_t dir); +int FTDIDevice_MPSSE_SetHighByte(FTDIDevice *dev, FTDIInterface interface, + uint8_t data, uint8_t dir); + +int FTDIDevice_MPSSE_GetLowByte(FTDIDevice *dev, FTDIInterface interface, uint8_t *byte); +int FTDIDevice_MPSSE_GetHighByte(FTDIDevice *dev, FTDIInterface interface, uint8_t *byte); + +#endif /* __FASTFTDI_H */ diff --git a/misoclib/com/liteusb/software/ftdi/ft2232h/.keep_me b/misoclib/com/liteusb/software/ftdi/ft2232h/.keep_me deleted file mode 100644 index e69de29b..00000000 diff --git a/misoclib/com/liteusb/software/ftdi/ft2232h/libftdicom/Makefile b/misoclib/com/liteusb/software/ftdi/ft2232h/libftdicom/Makefile deleted file mode 100644 index 65755af5..00000000 --- a/misoclib/com/liteusb/software/ftdi/ft2232h/libftdicom/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -CC=gcc -CFLAGS =-Wall -O0 -CFLAGS_DLL =-Wall -O0 -g -shared -Wl,--out-implib,libftdicom.a -INC=-I. -I../libusb -LIBS_PATHS= -L. -L../libusb -LIBS_DLL= -lusb-1.0 -lpthreadGC2 - -all: libftdicom.dll - -libftdicom.dll: crc32.c fastftdi.c ftdicom.c - $(CC) $(INC) -o $@ $(CFLAGS_DLL) $^ $(LIBS_PATHS) $(LIBS_DLL) - -clean: - rm libftdicom.a - rm libftdicom.dll \ No newline at end of file diff --git a/misoclib/com/liteusb/software/ftdi/ft2232h/libftdicom/crc.h b/misoclib/com/liteusb/software/ftdi/ft2232h/libftdicom/crc.h deleted file mode 100644 index 61cc036b..00000000 --- a/misoclib/com/liteusb/software/ftdi/ft2232h/libftdicom/crc.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __CRC_H -#define __CRC_H - -unsigned short crc16(const unsigned char *buffer, int len); -unsigned int crc32(const unsigned char *buffer, unsigned int len); - -#endif diff --git a/misoclib/com/liteusb/software/ftdi/ft2232h/libftdicom/crc32.c b/misoclib/com/liteusb/software/ftdi/ft2232h/libftdicom/crc32.c deleted file mode 100644 index 29b9b994..00000000 --- a/misoclib/com/liteusb/software/ftdi/ft2232h/libftdicom/crc32.c +++ /dev/null @@ -1,81 +0,0 @@ -/* crc32.c -- compute the CRC-32 of a data stream - * Copyright (C) 1995-1998 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include - -static const unsigned int crc_table[256] = { - 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, - 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, - 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, - 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, - 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, - 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, - 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, - 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, - 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, - 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, - 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, - 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, - 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, - 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, - 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, - 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, - 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, - 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, - 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, - 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, - 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, - 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, - 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, - 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, - 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, - 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, - 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, - 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, - 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, - 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, - 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, - 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, - 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, - 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, - 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, - 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, - 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, - 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, - 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, - 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, - 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, - 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, - 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, - 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, - 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, - 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, - 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, - 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, - 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, - 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, - 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, - 0x2d02ef8dL -}; - -#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8); -#define DO2(buf) DO1(buf); DO1(buf); -#define DO4(buf) DO2(buf); DO2(buf); -#define DO8(buf) DO4(buf); DO4(buf); - -unsigned int crc32(const unsigned char *buffer, unsigned int len) -{ - unsigned int crc; - crc = 0; - crc = crc ^ 0xffffffffL; - while(len >= 8) { - DO8(buffer); - len -= 8; - } - if(len) do { - DO1(buffer); - } while(--len); - return crc ^ 0xffffffffL; -} diff --git a/misoclib/com/liteusb/software/ftdi/ft2232h/libftdicom/fastftdi.c b/misoclib/com/liteusb/software/ftdi/ft2232h/libftdicom/fastftdi.c deleted file mode 100644 index e2797c75..00000000 --- a/misoclib/com/liteusb/software/ftdi/ft2232h/libftdicom/fastftdi.c +++ /dev/null @@ -1,554 +0,0 @@ -/* - * fastftdi.c - A minimal FTDI FT2232H interface for which supports bit-bang - * mode, but focuses on very high-performance support for - * synchronous FIFO mode. Requires libusb-1.0 - * - * Copyright (C) 2009 Micah Elizabeth Scott - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include -#include -#include -#include -#include "fastftdi.h" - -#if defined _WIN32 || defined _WIN64 - #include - #include - int gettimeofday (struct timeval *tp, void *tz) - { - struct _timeb timebuffer; - _ftime (&timebuffer); - tp->tv_sec = timebuffer.time; - tp->tv_usec = timebuffer.millitm * 1000; - return 0; - } -#endif - -typedef struct { - FTDIStreamCallback *callback; - void *userdata; - int result; - FTDIProgressInfo progress; -} FTDIStreamState; - -static int -DeviceInit(FTDIDevice *dev) -{ - int err, interface; - - for (interface = 0; interface < 2; interface++) { - if (libusb_kernel_driver_active(dev->handle, interface) == 1) { - if ((err = libusb_detach_kernel_driver(dev->handle, interface))) { - perror("Error detaching kernel driver"); - return err; - } - } - } - - if ((err = libusb_set_configuration(dev->handle, 1))) { - perror("Error setting configuration"); - return err; - } - - for (interface = 0; interface < 2; interface++) { - if ((err = libusb_claim_interface(dev->handle, interface))) { - perror("Error claiming interface"); - return err; - } - } - - return 0; -} - - -int -FTDIDevice_Open(FTDIDevice *dev) -{ - int err; - - memset(dev, 0, sizeof *dev); - - if ((err = libusb_init(&dev->libusb))) { - return err; - } - - libusb_set_debug(dev->libusb, 0); - - dev->handle = libusb_open_device_with_vid_pid(dev->libusb, - LITEUSB_VENDOR, - LITEUSB_PRODUCT); - - if (!dev->handle) { - dev->handle = libusb_open_device_with_vid_pid(dev->libusb, - FTDI_VENDOR, - FTDI_PRODUCT_FT2232H); - } - - if (!dev->handle) { - return LIBUSB_ERROR_NO_DEVICE; - } - - return DeviceInit(dev); -} - - -void -FTDIDevice_Close(FTDIDevice *dev) -{ - libusb_close(dev->handle); - libusb_exit(dev->libusb); -} - - -int -FTDIDevice_Reset(FTDIDevice *dev) -{ - int err; - - err = libusb_reset_device(dev->handle); - if (err) - return err; - - return DeviceInit(dev); -} - - -int -FTDIDevice_SetMode(FTDIDevice *dev, FTDIInterface interface, - FTDIBitmode mode, uint8_t pinDirections, - int baudRate) -{ - int err; - - err = libusb_control_transfer(dev->handle, - LIBUSB_REQUEST_TYPE_VENDOR - | LIBUSB_RECIPIENT_DEVICE - | LIBUSB_ENDPOINT_OUT, - FTDI_SET_BITMODE_REQUEST, - pinDirections | (mode << 8), - interface, - NULL, 0, - FTDI_COMMAND_TIMEOUT); - if (err) - return err; - - if (baudRate) { - int divisor; - - if (mode == FTDI_BITMODE_BITBANG) - baudRate <<= 2; - - divisor = 240000000 / baudRate; - if (divisor < 1 || divisor > 0xFFFF) { - return LIBUSB_ERROR_INVALID_PARAM; - } - - err = libusb_control_transfer(dev->handle, - LIBUSB_REQUEST_TYPE_VENDOR - | LIBUSB_RECIPIENT_DEVICE - | LIBUSB_ENDPOINT_OUT, - FTDI_SET_BAUD_REQUEST, - divisor, - interface, - NULL, 0, - FTDI_COMMAND_TIMEOUT); - if (err) - return err; - } - - return err; -} - - -/* - * Internal callback for cleaning up async writes. - */ - -static void -WriteAsyncCallback(struct libusb_transfer *transfer) -{ - free(transfer->buffer); - libusb_free_transfer(transfer); -} - - -/* - * Write to an FTDI interface, either synchronously or asynchronously. - * Async writes have no completion callback, they finish 'eventually'. - */ - -int -FTDIDevice_Write(FTDIDevice *dev, FTDIInterface interface, - uint8_t *data, size_t length, bool async) -{ - int err; - - if (async) { - struct libusb_transfer *transfer = libusb_alloc_transfer(0); - - if (!transfer) { - return LIBUSB_ERROR_NO_MEM; - } - - libusb_fill_bulk_transfer(transfer, dev->handle, FTDI_EP_OUT(interface), - malloc(length), length, (libusb_transfer_cb_fn) WriteAsyncCallback, 0, 0); - - if (!transfer->buffer) { - libusb_free_transfer(transfer); - return LIBUSB_ERROR_NO_MEM; - } - - memcpy(transfer->buffer, data, length); - err = libusb_submit_transfer(transfer); - - } else { - int transferred; - err = libusb_bulk_transfer(dev->handle, FTDI_EP_OUT(interface), - data, length, &transferred, - FTDI_COMMAND_TIMEOUT); - } - - if (err < 0) - return err; - else - return 0; -} - - -int -FTDIDevice_WriteByteSync(FTDIDevice *dev, FTDIInterface interface, uint8_t byte) -{ - return FTDIDevice_Write(dev, interface, &byte, sizeof byte, false); -} - - -int -FTDIDevice_ReadByteSync(FTDIDevice *dev, FTDIInterface interface, uint8_t *byte) -{ - /* - * This is a simplified synchronous read, intended for bit-banging mode. - * Ignores the modem/buffer status bytes, returns just the data. - * - */ - - uint8_t packet[3]; - int transferred, err; - - err = libusb_bulk_transfer(dev->handle, FTDI_EP_IN(interface), - packet, sizeof packet, &transferred, - FTDI_COMMAND_TIMEOUT); - if (err < 0) { - return err; - } - if (transferred != sizeof packet) { - return -1; - } - - if (byte) { - *byte = packet[sizeof packet - 1]; - } - - return 0; -} - - -/* - * Internal callback for one transfer's worth of stream data. - * Split it into packets and invoke the callbacks. - */ - -static void -ReadStreamCallback(struct libusb_transfer *transfer) -{ - FTDIStreamState *state = transfer->user_data; - - if (state->result == 0) { - if (transfer->status == LIBUSB_TRANSFER_COMPLETED) { - - int i; - uint8_t *ptr = transfer->buffer; - int length = transfer->actual_length; - int numPackets = (length + FTDI_PACKET_SIZE - 1) >> FTDI_LOG_PACKET_SIZE; - - for (i = 0; i < numPackets; i++) { - int payloadLen; - int packetLen = length; - - if (packetLen > FTDI_PACKET_SIZE) - packetLen = FTDI_PACKET_SIZE; - - payloadLen = packetLen - FTDI_HEADER_SIZE; - state->progress.current.totalBytes += payloadLen; - - state->result = state->callback(ptr + FTDI_HEADER_SIZE, payloadLen, - NULL, state->userdata); - if (state->result) - break; - - ptr += packetLen; - length -= packetLen; - } - - } else { - state->result = LIBUSB_ERROR_IO; - } - } - - if (state->result == 0) { - transfer->status = -1; - state->result = libusb_submit_transfer(transfer); - } -} - - -static double -TimevalDiff(const struct timeval *a, const struct timeval *b) -{ - return (a->tv_sec - b->tv_sec) + 1e-6 * (a->tv_usec - b->tv_usec); -} - - -/* - * Use asynchronous transfers in libusb-1.0 for high-performance - * streaming of data from a device interface back to the PC. This - * function continuously transfers data until either an error occurs - * or the callback returns a nonzero value. This function returns - * a libusb error code or the callback's return value. - * - * For every contiguous block of received data, the callback will - * be invoked. - */ - -int -FTDIDevice_ReadStream(FTDIDevice *dev, FTDIInterface interface, - FTDIStreamCallback *callback, void *userdata, - int packetsPerTransfer, int numTransfers) -{ - struct libusb_transfer **transfers; - FTDIStreamState state = { callback, userdata }; - int bufferSize = packetsPerTransfer * FTDI_PACKET_SIZE; - int xferIndex; - int err = 0; - - /* - * Set up all transfers - */ - - transfers = calloc(numTransfers, sizeof *transfers); - if (!transfers) { - err = LIBUSB_ERROR_NO_MEM; - goto cleanup; - } - - for (xferIndex = 0; xferIndex < numTransfers; xferIndex++) { - struct libusb_transfer *transfer; - - transfer = libusb_alloc_transfer(0); - transfers[xferIndex] = transfer; - if (!transfer) { - err = LIBUSB_ERROR_NO_MEM; - goto cleanup; - } - - libusb_fill_bulk_transfer(transfer, dev->handle, FTDI_EP_IN(interface), - malloc(bufferSize), bufferSize, (libusb_transfer_cb_fn) ReadStreamCallback, - &state, 0); - - if (!transfer->buffer) { - err = LIBUSB_ERROR_NO_MEM; - goto cleanup; - } - - transfer->status = -1; - err = libusb_submit_transfer(transfer); - if (err) - goto cleanup; - } - - /* - * Run the transfers, and periodically assess progress. - */ - - gettimeofday(&state.progress.first.time, NULL); - - do { - FTDIProgressInfo *progress = &state.progress; - const double progressInterval = 0.1; - struct timeval timeout = { 0, 10000 }; - struct timeval now; - - int err = libusb_handle_events_timeout(dev->libusb, &timeout); - if (!state.result) { - state.result = err; - } - - // If enough time has elapsed, update the progress - gettimeofday(&now, NULL); - if (TimevalDiff(&now, &progress->current.time) >= progressInterval) { - - progress->current.time = now; - - if (progress->prev.totalBytes) { - // We have enough information to calculate rates - - double currentTime; - - progress->totalTime = TimevalDiff(&progress->current.time, - &progress->first.time); - currentTime = TimevalDiff(&progress->current.time, - &progress->prev.time); - - progress->totalRate = progress->current.totalBytes / progress->totalTime; - progress->currentRate = (progress->current.totalBytes - - progress->prev.totalBytes) / currentTime; - } - - state.result = state.callback(NULL, 0, progress, state.userdata); - progress->prev = progress->current; - } - } while (!state.result); - - /* - * Cancel any outstanding transfers, and free memory. - */ - - cleanup: - if (transfers) { - bool done_cleanup = false; - while (!done_cleanup) - { - done_cleanup = true; - - for (xferIndex = 0; xferIndex < numTransfers; xferIndex++) { - struct libusb_transfer *transfer = transfers[xferIndex]; - - if (transfer) { - // If a transfer is in progress, cancel it - if (transfer->status == -1) { - libusb_cancel_transfer(transfer); - - // And we need to wait until we get a clean sweep - done_cleanup = false; - - // If a transfer is complete or cancelled, nuke it - } else if (transfer->status == 0 || - transfer->status == LIBUSB_TRANSFER_CANCELLED) { - free(transfer->buffer); - libusb_free_transfer(transfer); - transfers[xferIndex] = NULL; - } - } - } - - // pump events - struct timeval timeout = { 0, 10000 }; - libusb_handle_events_timeout(dev->libusb, &timeout); - } - free(transfers); - } - - if (err) - return err; - else - return state.result; -} - -/* MPSSE mode support -- see - * http://www.ftdichip.com/Support/Documents/AppNotes/AN_108_Command_Processor_for_MPSSE_and_MCU_Host_Bus_Emulation_Modes.pdf - */ - -int -FTDIDevice_MPSSE_Enable(FTDIDevice *dev, FTDIInterface interface) -{ - int err; - - /* Reset interface */ - - err = FTDIDevice_SetMode(dev, interface, FTDI_BITMODE_RESET, 0, 0); - if (err) - return err; - - /* Enable MPSSE mode */ - - err = FTDIDevice_SetMode(dev, interface, FTDI_BITMODE_MPSSE, - FTDI_SET_BITMODE_REQUEST, 0); - - return err; -} - -int -FTDIDevice_MPSSE_SetDivisor(FTDIDevice *dev, FTDIInterface interface, - uint8_t ValueL, uint8_t ValueH) -{ - uint8_t buf[3] = {FTDI_MPSSE_SETDIVISOR, 0, 0}; - - buf[1] = ValueL; - buf[2] = ValueH; - - return FTDIDevice_Write(dev, interface, buf, 3, false); -} - -int -FTDIDevice_MPSSE_SetLowByte(FTDIDevice *dev, FTDIInterface interface, uint8_t data, uint8_t dir) -{ - uint8_t buf[3] = {FTDI_MPSSE_SETLOW, 0, 0}; - - buf[1] = data; - buf[2] = dir; - - return FTDIDevice_Write(dev, interface, buf, 3, false); -} - -int -FTDIDevice_MPSSE_SetHighByte(FTDIDevice *dev, FTDIInterface interface, uint8_t data, uint8_t dir) -{ - uint8_t buf[3] = {FTDI_MPSSE_SETHIGH, 0, 0}; - - buf[1] = data; - buf[2] = dir; - - return FTDIDevice_Write(dev, interface, buf, 3, false); -} - -int -FTDIDevice_MPSSE_GetLowByte(FTDIDevice *dev, FTDIInterface interface, uint8_t *byte) -{ - int err; - - err = FTDIDevice_WriteByteSync(dev, interface, FTDI_MPSSE_GETLOW); - if (err) - return err; - - return FTDIDevice_ReadByteSync(dev, interface, byte); -} - -int -FTDIDevice_MPSSE_GetHighByte(FTDIDevice *dev, FTDIInterface interface, uint8_t *byte) -{ - int err; - - err = FTDIDevice_WriteByteSync(dev, interface, FTDI_MPSSE_GETHIGH); - if (err) - return err; - - return FTDIDevice_ReadByteSync(dev, interface, byte); -} diff --git a/misoclib/com/liteusb/software/ftdi/ft2232h/libftdicom/fastftdi.h b/misoclib/com/liteusb/software/ftdi/ft2232h/libftdicom/fastftdi.h deleted file mode 100644 index c7166dec..00000000 --- a/misoclib/com/liteusb/software/ftdi/ft2232h/libftdicom/fastftdi.h +++ /dev/null @@ -1,135 +0,0 @@ -/* - * fastftdi.h - A minimal FTDI FT232H interface for Linux which supports - * bit-bang mode, but focuses on very high-performance support - * for synchronous FIFO mode. - * - * Copyright (C) 2009 Micah Elizabeth Scott - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef __FASTFTDI_H -#define __FASTFTDI_H - -#include -#include -#include - -typedef enum { - FTDI_BITMODE_RESET = 0, - FTDI_BITMODE_BITBANG = 1 << 0, - FTDI_BITMODE_MPSSE = 1 << 1, - FTDI_BITMODE_SYNC_BITBANG = 1 << 2, - FTDI_BITMODE_MCU = 1 << 3, - FTDI_BITMODE_OPTO = 1 << 4, - FTDI_BITMODE_CBUS = 1 << 5, - FTDI_BITMODE_SYNC_FIFO = 1 << 6, -} FTDIBitmode; - -typedef enum { - FTDI_MPSSE_SETLOW = 0x80, - FTDI_MPSSE_SETHIGH = 0x82, - FTDI_MPSSE_GETLOW = 0x81, - FTDI_MPSSE_GETHIGH = 0x83, - FTDI_MPSSE_SETDIVISOR = 0x86, -} FTDIMPSSEOpcode; - -typedef enum { - FTDI_INTERFACE_A = 1, - FTDI_INTERFACE_B = 2, -} FTDIInterface; - -typedef struct { - libusb_context *libusb; - libusb_device_handle *handle; -} FTDIDevice; - -typedef struct { - struct { - uint64_t totalBytes; - struct timeval time; - } first, prev, current; - - double totalTime; - double totalRate; - double currentRate; -} FTDIProgressInfo; - - -/* - * USB Constants - */ - -#define FTDI_VENDOR 0x0403 -#define FTDI_PRODUCT_FT2232H 0x6010 - -#define LITEUSB_VENDOR 0x1d50 -#define LITEUSB_PRODUCT 0x607c - -#define FTDI_COMMAND_TIMEOUT 1000 - -#define FTDI_SET_BAUD_REQUEST 0x03 -#define FTDI_SET_BITMODE_REQUEST 0x0B - -#define FTDI_EP_IN(i) (0x81 + (i-1)*2) -#define FTDI_EP_OUT(i) (0x02 + (i-1)*2) - -#define FTDI_PACKET_SIZE 512 // Specific to FT2232H -#define FTDI_LOG_PACKET_SIZE 9 // 512 == 1 << 9 -#define FTDI_HEADER_SIZE 2 - -typedef int (FTDIStreamCallback)(uint8_t *buffer, int length, - FTDIProgressInfo *progress, void *userdata); - - -/* - * Public Functions - */ - -int FTDIDevice_Open(FTDIDevice *dev); -void FTDIDevice_Close(FTDIDevice *dev); -int FTDIDevice_Reset(FTDIDevice *dev); - -int FTDIDevice_SetMode(FTDIDevice *dev, FTDIInterface interface, - FTDIBitmode mode, uint8_t pinDirections, - int baudRate); - -int FTDIDevice_Write(FTDIDevice *dev, FTDIInterface interface, - uint8_t *data, size_t length, bool async); - -int FTDIDevice_WriteByteSync(FTDIDevice *dev, FTDIInterface interface, uint8_t byte); -int FTDIDevice_ReadByteSync(FTDIDevice *dev, FTDIInterface interface, uint8_t *byte); - -int FTDIDevice_ReadStream(FTDIDevice *dev, FTDIInterface interface, - FTDIStreamCallback *callback, void *userdata, - int packetsPerTransfer, int numTransfers); - -int FTDIDevice_MPSSE_Enable(FTDIDevice *dev, FTDIInterface interface); -int FTDIDevice_MPSSE_SetDivisor(FTDIDevice *dev, FTDIInterface interface, - uint8_t ValueL, uint8_t ValueH); - -int FTDIDevice_MPSSE_SetLowByte(FTDIDevice *dev, FTDIInterface interface, - uint8_t data, uint8_t dir); -int FTDIDevice_MPSSE_SetHighByte(FTDIDevice *dev, FTDIInterface interface, - uint8_t data, uint8_t dir); - -int FTDIDevice_MPSSE_GetLowByte(FTDIDevice *dev, FTDIInterface interface, uint8_t *byte); -int FTDIDevice_MPSSE_GetHighByte(FTDIDevice *dev, FTDIInterface interface, uint8_t *byte); - -#endif /* __FASTFTDI_H */ diff --git a/misoclib/com/liteusb/software/ftdi/ft2232h/libftdicom/ftdicom.c b/misoclib/com/liteusb/software/ftdi/ft2232h/libftdicom/ftdicom.c deleted file mode 100644 index 19bacf0d..00000000 --- a/misoclib/com/liteusb/software/ftdi/ft2232h/libftdicom/ftdicom.c +++ /dev/null @@ -1,257 +0,0 @@ -/* - * ftdicom.c - Low Level USB communication interface - * - * Provides UART and DMA low level communication - * functions for FT2232H in slave fifo mode. - * - * Copyright (C) 2014 florent@enjoy-digital.fr - * - */ - -#include -#include -#include -#include -#include "ftdicom.h" -#include "crc.h" - -/* - * Open / close functions - */ -int ftdicom_open(FTDICom *com) -{ - int err = 0; - err = FTDIDevice_Open(com->dev); - if (err) - return err; - - com->raw_tx_buf = malloc(RAW_BUFFER_SIZE); - com->raw_rx_buf = malloc(RAW_BUFFER_SIZE); - com->uart_rx_buf = malloc(UART_RINGBUFFER_SIZE_RX); - - err = FTDIDevice_SetMode(com->dev, FTDI_INTERFACE_A, FTDI_BITMODE_SYNC_FIFO, 0xFF, 0); - if (err) - return err; - - com->raw_rx_buf_length = 0; - - pthread_t thread; - com->thread = &thread; - pthread_create(com->thread, NULL, ftdicom_read_thread, com); - - return 0; -} - -void ftdicom_close(FTDICom *com) -{ - free(com->raw_tx_buf); - free(com->raw_rx_buf); - free(com->uart_rx_buf); - FTDIDevice_Close(com->dev); - free(com->thread); -} - -/* - * Write (Tx) functions - */ -int ftdicom_write(FTDICom *com, uint8_t tag, uint8_t *data, size_t length, uint8_t with_crc) -{ - unsigned int computed_crc; - - com->raw_tx_buf[0] = 0x5A; - com->raw_tx_buf[1] = 0xA5; - com->raw_tx_buf[2] = 0x5A; - com->raw_tx_buf[3] = 0xA5; - com->raw_tx_buf[4] = tag; - if (with_crc) - length += 4; - com->raw_tx_buf[5] = (length >> 24) & 0xff; - com->raw_tx_buf[6] = (length >> 16) & 0xff; - com->raw_tx_buf[7] = (length >> 8) & 0xff; - com->raw_tx_buf[8] = (length >> 0) & 0xff; - - memcpy(com->raw_tx_buf+9, data, length); - if (with_crc) { - computed_crc = crc32(data, length-4); - com->raw_tx_buf[9+length-1] = (computed_crc >> 24) & 0xff; - com->raw_tx_buf[9+length-2] = (computed_crc >> 16) & 0xff; - com->raw_tx_buf[9+length-3] = (computed_crc >> 8) & 0xff; - com->raw_tx_buf[9+length-4] = (computed_crc >> 0) & 0xff; - } - return FTDIDevice_Write(com->dev, FTDI_INTERFACE_A, com->raw_tx_buf, 9+length, false); -} - -/* - * Read (Rx) common functions - */ - -int ftdicom_present_bytes(uint8_t tag, uint8_t *buffer, int length) -{ - if (length < NEEDED_FOR_SIZE) - return INCOMPLETE; - - if (buffer[0] != 0x5A || - buffer[1] != 0xA5 || - buffer[2] != 0x5A || - buffer[3] != 0xA5 || - buffer[4] != tag) - return UNMATCHED; - - int size = NEEDED_FOR_SIZE; - size += buffer[5] << 24; - size += buffer[6] << 16; - size += buffer[7] << 8; - size += buffer[8]; - - if (length < size) - return INCOMPLETE; - - return size; -} - -int ftdicom_uart_present_bytes(uint8_t *buffer, int length) -{ - return ftdicom_present_bytes(UART_TAG, buffer, length); -} - -int ftdicom_dma_present_bytes(uint8_t *buffer, int length) -{ - return ftdicom_present_bytes(DMA_TAG, buffer, length); -} - -int ftdicom_read_callback(uint8_t *buffer, int length, FTDIProgressInfo *progress, void *userdata) -{ - FTDICom *com = (FTDICom *) userdata; - - // Concatenate buffer & raw_rx_buf - memcpy(com->raw_rx_buf + com->raw_rx_buf_length, buffer, length); - com->raw_rx_buf_length += length; - - int code = 0; - int incomplete = 0; - int i = 0; - - // Search frames in raw_rx_buf - while (i != com->raw_rx_buf_length && !incomplete) - { - code = 0; - - // UART - code = ftdicom_uart_present_bytes(com->raw_rx_buf + i, com->raw_rx_buf_length-i); - if (code == INCOMPLETE) - { - incomplete = 1; - break; - } else if (code) - { - ftdicom_uart_read_callback(com, com->raw_rx_buf + i + NEEDED_FOR_SIZE, code-NEEDED_FOR_SIZE); - i += code-1; - } - - // DMA - code = ftdicom_dma_present_bytes(com->raw_rx_buf + i, com->raw_rx_buf_length-i); - if (code == INCOMPLETE) - { - incomplete = 1; - break; - } else if (code) - { - ftdicom_dma_read_callback(com, com->raw_rx_buf + i + NEEDED_FOR_SIZE, code-NEEDED_FOR_SIZE); - i += code; - } - - // Nothing found, increment index - if (code == UNMATCHED) - i=i+1; - - } - - // Prepare raw_rx_buf for next callback - if (incomplete == 1) - { - com->raw_rx_buf_length = com->raw_rx_buf_length - i; - memcpy(com->raw_rx_buf, com->raw_rx_buf + i, com->raw_rx_buf_length); - } else { - com->raw_rx_buf_length = 0; - } - - return 0; -} - -void *ftdicom_read_thread(void *userdata) -{ - FTDICom *com = (FTDICom *) userdata; - FTDIDevice_ReadStream(com->dev, FTDI_INTERFACE_A, ftdicom_read_callback, com, 8, 16); - return 0; -} - -/* - * UART functions - */ - -int ftdicom_uart_write_buffer(FTDICom *com, uint8_t *data, size_t length) -{ - return ftdicom_write(com, UART_TAG, data, length, 0); -} - -int ftdicom_uart_write(FTDICom *com, uint8_t c) -{ - return ftdicom_write(com, UART_TAG, &c, 1, 0); -} - -void ftdicom_uart_read_callback(FTDICom *com, uint8_t *buffer, int length) -{ - while (length > 0) { - com->uart_rx_buf[com->uart_rx_produce] = buffer[0]; - com->uart_rx_produce = (com->uart_rx_produce + 1) & UART_RINGBUFFER_MASK_RX; - length -=1; - buffer +=1; - } -} - -uint8_t ftdicom_uart_read(FTDICom *com) -{ - uint8_t c; - - while(com->uart_rx_consume == com->uart_rx_produce); - c = com->uart_rx_buf[com->uart_rx_consume]; - com->uart_rx_consume = (com->uart_rx_consume + 1) & UART_RINGBUFFER_MASK_RX; - return c; -} - -int ftdicom_uart_read_nonblock(FTDICom *com) -{ - return (com->uart_rx_consume != com->uart_rx_produce); -} - -/* - * DMA functions - */ -int ftdicom_dma_write(FTDICom *com, uint8_t *data, size_t length) -{ - return ftdicom_write(com, DMA_TAG, data, length, 1); -} - -void ftdicom_dma_read_set_callback(FTDICom *com, dma_read_ext_callback_t callback, void *userdata) -{ - com->dma_read_ext_callback = callback; - com->userdata = userdata; -} - -int ftdicom_dma_read_callback(FTDICom *com, uint8_t *buffer, int length) -{ - unsigned int received_crc; - unsigned int computed_crc; - - received_crc = ((unsigned int)buffer[length-1] << 24) - |((unsigned int)buffer[length-2] << 16) - |((unsigned int)buffer[length-3] << 8) - |((unsigned int)buffer[length-4]); - computed_crc = crc32(buffer, length-4); - if(received_crc != computed_crc) return -1; - - if (com->dma_read_ext_callback != NULL) - return com->dma_read_ext_callback(buffer, length-4, com->userdata); - else - return -1; -} \ No newline at end of file diff --git a/misoclib/com/liteusb/software/ftdi/ft2232h/libftdicom/ftdicom.h b/misoclib/com/liteusb/software/ftdi/ft2232h/libftdicom/ftdicom.h deleted file mode 100644 index 67ccd45d..00000000 --- a/misoclib/com/liteusb/software/ftdi/ft2232h/libftdicom/ftdicom.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * ftdicom.c - Low Level USB communication interface - * - * Provides UART and DMA low level communication - * functions for FT2232H in slave fifo mode. - * - * Copyright (C) 2014 florent@enjoy-digital.fr - * - */ - -#ifndef __FTDICOM_H -#define __FTDICOM_H - -#include -#include -#include - -#include "fastftdi.h" - -/* - * Protocol Constants - */ - -#define UART_TAG 0 -#define DMA_TAG 1 - -#define NEEDED_FOR_SIZE 9 -#define PAYLOAD_OFFSET 10 - -#define INCOMPLETE -1 -#define UNMATCHED 0 - - -/* - * Buffer Constants - * - * Buffer sizes must be a power of 2 so that modulos can be computed - * with logical AND. - */ - -// RAW -#define RAW_BUFFER_SIZE 20*1024*1024 - -// UART -#define UART_RINGBUFFER_SIZE_RX 4096 -#define UART_RINGBUFFER_MASK_RX (UART_RINGBUFFER_SIZE_RX-1) - -// DMA -#define DMA_BUFFER_SIZE_TX 20*1024*1024 -#define DMA_BUFFER_SIZE_RX 20*1024*1024 - - -/* - * Struct - */ -typedef int (*dma_read_ext_callback_t)(uint8_t *buffer, int length, void *userdata); -typedef struct { - FTDIDevice *dev; - - uint8_t *raw_tx_buf; - uint8_t *raw_rx_buf; - unsigned int raw_rx_buf_length; - - char *uart_rx_buf; - volatile unsigned int uart_rx_produce; - volatile unsigned int uart_rx_consume; - - pthread_t *thread; - dma_read_ext_callback_t dma_read_ext_callback; - - void *userdata; -} FTDICom; - -/* - * Public Functions - */ - -int ftdicom_open(FTDICom *com); -void ftdicom_close(FTDICom *com); - -int ftdicom_uart_write_buffer(FTDICom *com, uint8_t *data, size_t length); -int ftdicom_uart_write(FTDICom *com, uint8_t c); -uint8_t ftdicom_uart_read(FTDICom *com); -int ftdicom_uart_read_nonblock(FTDICom *com); - -int ftdicom_dma_write(FTDICom *com, uint8_t *data, size_t length); -void ftdicom_dma_read_set_callback(FTDICom *com, dma_read_ext_callback_t callback, void *userdata); - -/* - * Private Functions - */ -int ftdicom_write(FTDICom *com, uint8_t tag, uint8_t *data, size_t length, uint8_t with_crc); - -int ftdicom_present_bytes(uint8_t tag, uint8_t *buffer, int length); -int ftdicom_uart_present_bytes(uint8_t *buffer, int length); -int ftdicom_dma_present_bytes(uint8_t *buffer, int length); -int ftdicom_read_callback(uint8_t *buffer, int length, FTDIProgressInfo *progress, void *userdata); -void *ftdicom_read_thread(void *userdata); - -void ftdicom_uart_read_callback(FTDICom *com, uint8_t *buffer, int length); -int ftdicom_dma_read_callback(FTDICom *com, uint8_t *buffer, int length); - - -#endif /* __FTDICOM_H */ diff --git a/misoclib/com/liteusb/software/ftdi/linux/Makefile b/misoclib/com/liteusb/software/ftdi/linux/Makefile new file mode 100644 index 00000000..14af27e7 --- /dev/null +++ b/misoclib/com/liteusb/software/ftdi/linux/Makefile @@ -0,0 +1,35 @@ +UNAME := $(shell uname) + +LIBNAME := libftdicom + + +# Load libusb via pkg-config +PACKAGES := libusb-1.0 +CFLAGS += $(shell pkg-config --cflags $(PACKAGES)) +LDFLAGS += $(shell pkg-config --libs $(PACKAGES)) + +# Large file support +CFLAGS += $(shell getconf LFS_CFLAGS) + +CFLAGS += -fPIC + +SO := $(LIBNAME).so +SO_LDFLAGS := $(LDFLAGS) -shared + +# Local headers +CFLAGS += -I../include + +SO_OBJS := ../fastftdi.o + +CFLAGS += -O3 -g --std=c99 + +all: $(SO) + cp libftdicom.so ../libftdicom.so + +$(SO): $(SO_OBJS) + cc -o $@ $^ $(SO_LDFLAGS) + +*.o: *.h Makefile + +clean: + rm -f $(SO) $(OBJS) $(SO_OBJS) diff --git a/misoclib/com/liteusb/software/ftdi/windows/Makefile b/misoclib/com/liteusb/software/ftdi/windows/Makefile new file mode 100644 index 00000000..61e41b49 --- /dev/null +++ b/misoclib/com/liteusb/software/ftdi/windows/Makefile @@ -0,0 +1,12 @@ +CC=gcc +CFLAGS_DLL =-Wall -O0 -g -shared -Wl,--subsystem,windows -DDLL +LIBS= -lusb-1.0 + +all: libftdicom.dll + cp libftdicom.dll ../libftdicom.dll + +libftdicom.dll: ../fastftdi.c + $(CC) -o $@ $(CFLAGS_DLL) $^ $(LIBS) + +clean: + rm -f libftdicom.dll ../libftdicom.dll