From da0fe2ecfbe0968f07111e84358c1561b6959608 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Fri, 1 May 2015 16:15:15 +0200 Subject: [PATCH] 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) --- misoclib/com/liteusb/software/ftdi/README | 14 + .../com/liteusb/software/ftdi/__init__.py | 352 ++++++++++++++++++ misoclib/com/liteusb/software/ftdi/example.py | 81 ++++ .../ftdi/{ft2232h/libftdicom => }/fastftdi.c | 34 +- .../ftdi/{ft2232h/libftdicom => }/fastftdi.h | 8 +- .../liteusb/software/ftdi/ft2232h/.keep_me | 0 .../software/ftdi/ft2232h/libftdicom/Makefile | 15 - .../software/ftdi/ft2232h/libftdicom/crc.h | 7 - .../software/ftdi/ft2232h/libftdicom/crc32.c | 81 ---- .../ftdi/ft2232h/libftdicom/ftdicom.c | 257 ------------- .../ftdi/ft2232h/libftdicom/ftdicom.h | 104 ------ .../com/liteusb/software/ftdi/linux/Makefile | 35 ++ .../liteusb/software/ftdi/windows/Makefile | 12 + 13 files changed, 511 insertions(+), 489 deletions(-) create mode 100644 misoclib/com/liteusb/software/ftdi/README create mode 100644 misoclib/com/liteusb/software/ftdi/__init__.py create mode 100644 misoclib/com/liteusb/software/ftdi/example.py rename misoclib/com/liteusb/software/ftdi/{ft2232h/libftdicom => }/fastftdi.c (95%) rename misoclib/com/liteusb/software/ftdi/{ft2232h/libftdicom => }/fastftdi.h (96%) delete mode 100644 misoclib/com/liteusb/software/ftdi/ft2232h/.keep_me delete mode 100644 misoclib/com/liteusb/software/ftdi/ft2232h/libftdicom/Makefile delete mode 100644 misoclib/com/liteusb/software/ftdi/ft2232h/libftdicom/crc.h delete mode 100644 misoclib/com/liteusb/software/ftdi/ft2232h/libftdicom/crc32.c delete mode 100644 misoclib/com/liteusb/software/ftdi/ft2232h/libftdicom/ftdicom.c delete mode 100644 misoclib/com/liteusb/software/ftdi/ft2232h/libftdicom/ftdicom.h create mode 100644 misoclib/com/liteusb/software/ftdi/linux/Makefile create mode 100644 misoclib/com/liteusb/software/ftdi/windows/Makefile 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/ft2232h/libftdicom/fastftdi.c b/misoclib/com/liteusb/software/ftdi/fastftdi.c similarity index 95% rename from misoclib/com/liteusb/software/ftdi/ft2232h/libftdicom/fastftdi.c rename to misoclib/com/liteusb/software/ftdi/fastftdi.c index e2797c75..9f49b416 100644 --- a/misoclib/com/liteusb/software/ftdi/ft2232h/libftdicom/fastftdi.c +++ b/misoclib/com/liteusb/software/ftdi/fastftdi.c @@ -4,6 +4,7 @@ * 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 @@ -51,16 +52,14 @@ typedef struct { } FTDIStreamState; static int -DeviceInit(FTDIDevice *dev) +DeviceInit(FTDIDevice *dev, FTDIInterface interface) { - int err, interface; + int err; - 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 (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; } } @@ -69,11 +68,9 @@ DeviceInit(FTDIDevice *dev) return err; } - for (interface = 0; interface < 2; interface++) { - if ((err = libusb_claim_interface(dev->handle, interface))) { - perror("Error claiming interface"); - return err; - } + if ((err = libusb_claim_interface(dev->handle, (interface-1)))) { + perror("Error claiming interface"); + return err; } return 0; @@ -81,7 +78,7 @@ DeviceInit(FTDIDevice *dev) int -FTDIDevice_Open(FTDIDevice *dev) +FTDIDevice_Open(FTDIDevice *dev, FTDIInterface interface) { int err; @@ -93,9 +90,6 @@ FTDIDevice_Open(FTDIDevice *dev) 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, @@ -107,7 +101,7 @@ FTDIDevice_Open(FTDIDevice *dev) return LIBUSB_ERROR_NO_DEVICE; } - return DeviceInit(dev); + return DeviceInit(dev, interface); } @@ -120,7 +114,7 @@ FTDIDevice_Close(FTDIDevice *dev) int -FTDIDevice_Reset(FTDIDevice *dev) +FTDIDevice_Reset(FTDIDevice *dev, FTDIInterface interface) { int err; @@ -128,7 +122,7 @@ FTDIDevice_Reset(FTDIDevice *dev) if (err) return err; - return DeviceInit(dev); + return DeviceInit(dev, interface); } diff --git a/misoclib/com/liteusb/software/ftdi/ft2232h/libftdicom/fastftdi.h b/misoclib/com/liteusb/software/ftdi/fastftdi.h similarity index 96% rename from misoclib/com/liteusb/software/ftdi/ft2232h/libftdicom/fastftdi.h rename to misoclib/com/liteusb/software/ftdi/fastftdi.h index c7166dec..b4251427 100644 --- a/misoclib/com/liteusb/software/ftdi/ft2232h/libftdicom/fastftdi.h +++ b/misoclib/com/liteusb/software/ftdi/fastftdi.h @@ -4,6 +4,7 @@ * 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 @@ -79,9 +80,6 @@ typedef struct { #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 @@ -102,9 +100,9 @@ typedef int (FTDIStreamCallback)(uint8_t *buffer, int length, * Public Functions */ -int FTDIDevice_Open(FTDIDevice *dev); +int FTDIDevice_Open(FTDIDevice *dev, FTDIInterface interface); void FTDIDevice_Close(FTDIDevice *dev); -int FTDIDevice_Reset(FTDIDevice *dev); +int FTDIDevice_Reset(FTDIDevice *dev, FTDIInterface interface); int FTDIDevice_SetMode(FTDIDevice *dev, FTDIInterface interface, FTDIBitmode mode, uint8_t pinDirections, 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/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 -- 2.30.2