Commit bae74907 authored by Thanassis Tsiodras's avatar Thanassis Tsiodras

Compile ZestSC1 USB-based communication library.

parent 0f499d65
/*******************
* Hardware details *
*******************/
#define VENDOR_ID 0x165d
#define PRODUCT_ID 0x0001
#define ANCHOR_LOAD_INTERNAL 0xA0
#define VR_SET_REG 0xD0
#define VR_GET_REG 0xD1
#define VR_START_CONFIG 0xD2
#define VR_CONFIG_STATUS 0xD3
#define VR_SET_SIGNAL_DIR 0xD4
#define VR_SET_SIGNALS 0xD5
#define VR_GET_SIGNALS 0xD6
#define VR_WRITE_EEPROM 0xD7
#define VR_READ_EEPROM 0xD8
#define VR_READBACK_READ 0xD9
#define VR_READBACK_WRITE 0xDA
#define VR_READBACK_DONE 0xDB
#define VR_GET_FIRMWARE_VER 0xDC
#define EEPROM_SERIAL_ADDRESS 0xfffc
#define EEPROM_CARDID_ADDRESS 0xfffb
#define EEPROM_FPGA_ADDRESS 0xfffa
#define EEPROM_MEMORY_SIZE_ADDRESS 0xfff6
#define CPUCS_REG_FX2 0xE600
#define EP_CTRL_WRITE (USB_ENDPOINT_OUT | USB_TYPE_VENDOR)
#define EP_CTRL_READ (USB_ENDPOINT_IN | USB_TYPE_VENDOR)
#define EP_INT_READ (USB_ENDPOINT_IN | 1)
#define EP_DATA_WRITE (USB_ENDPOINT_OUT | 2)
#define EP_CONFIG_WRITE (USB_ENDPOINT_OUT | 2)
#define EP_DATA_READ (USB_ENDPOINT_IN | 6)
#define EP_CONFIG_READ (USB_ENDPOINT_IN | 6)
#define ZESTSC1_MAX_TRANSFER_LENGTH (16*1024) // Maximum transfer in one URB under Linux
/**************
* Error macro *
**************/
extern ZESTSC1_ERROR_FUNC ZestSC1_ErrorHandler;
#define ZESTSC1_ERROR(f, x) \
{ \
if (ZestSC1_ErrorHandler!=NULL) \
ZestSC1_ErrorHandler(f, Handle, x, ZESTSC1_ERROR_STRING(x)); \
return (x); \
}
#define ZESTSC1_ERROR_GENERAL(f, x) \
{ \
if (ZestSC1_ErrorHandler!=NULL) \
ZestSC1_ErrorHandler(f, NULL, x, ZESTSC1_ERROR_STRING(x)); \
return (x); \
}
#define ZESTSC1_ERROR_STRING(x) \
ZestSC1_ErrorStrings[(x)>=ZESTSC1_ERROR_BASE ? \
(x)-ZESTSC1_ERROR_BASE+(ZESTSC1_MAX_INFO-ZESTSC1_INFO_BASE)+(ZESTSC1_MAX_WARNING-ZESTSC1_WARNING_BASE) : \
((x)>=ZESTSC1_WARNING_BASE ? (x)-ZESTSC1_WARNING_BASE+(ZESTSC1_MAX_INFO-ZESTSC1_INFO_BASE) : (x)-ZESTSC1_INFO_BASE)]
extern char *ZestSC1_ErrorStrings[];
/************************
* Card handle structure *
************************/
#define ZESTSC1_HANDLE_MAGIC 0xfeedfac0
typedef struct
{
unsigned long Magic;
usb_dev_handle *DeviceHandle;
unsigned long TimeOut;
int Interface;
} ZESTSC1_HANDLE_STRUCT;
#define ZESTSC1_CHECK_HANDLE(f, x) \
ZESTSC1_HANDLE_STRUCT *Struct = (ZESTSC1_HANDLE_STRUCT *)Handle; \
if (Struct==NULL || \
Struct->Magic!=ZESTSC1_HANDLE_MAGIC) \
ZESTSC1_ERROR(f, ZESTSC1_ILLEGAL_HANDLE);
/*************************************
* FPGA configuration image structure *
*************************************/
#define ZESTSC1_IMAGE_HANDLE_MAGIC 0xdeadbee0
typedef struct
{
unsigned long Magic;
void *Buffer;
unsigned long BufferSize;
ZESTSC1_FPGA_TYPE PartType;
} ZESTSC1_IMAGE_HANDLE_STRUCT;
#define ZESTSC1_BITFILE_NAME 0x61
#define ZESTSC1_BITFILE_PART 0x62
#define ZESTSC1_BITFILE_DATE 0x63
#define ZESTSC1_BITFILE_TIME 0x64
#define ZESTSC1_BITFILE_IMAGE 0x65
/************
* Constants *
************/
#define ZESTSC1_DEFAULT_TIMEOUT 10000
/************
* Functions *
************/
ZESTSC1_STATUS ZestSC1_Reset8051(ZESTSC1_HANDLE Handle);
ZESTSC1_STATUS ZestSC1_Transfer(ZESTSC1_HANDLE Handle, int EP, void *Buffer, int Length);
/**********************************************************
* *
* (c) 2004 Orange Tree Technologies Ltd *
* *
* ZestSC1.h *
* Version 1.0 *
* *
* Header file for ZestSC1 USB FPGA card *
* *
**********************************************************/
#ifndef __ZESTSC1_H__
#define __ZESTSC1_H__
#ifdef __cplusplus
extern "C"
{
#endif
/**********************************************************
* Handles for referencing boards and configuration images *
**********************************************************/
typedef void *ZESTSC1_HANDLE;
typedef void *ZESTSC1_IMAGE;
/************************
* Function return codes *
************************/
#define ZESTSC1_INFO_BASE 0
#define ZESTSC1_WARNING_BASE 0x4000
#define ZESTSC1_ERROR_BASE 0x8000
typedef enum
{
ZESTSC1_SUCCESS = ZESTSC1_INFO_BASE,
ZESTSC1_MAX_INFO,
ZESTSC1_MAX_WARNING = ZESTSC1_WARNING_BASE,
ZESTSC1_ILLEGAL_HANDLE = ZESTSC1_ERROR_BASE,
ZESTSC1_ILLEGAL_STATUS_CODE,
ZESTSC1_NULL_PARAMETER,
ZESTSC1_DEVICE_IN_USE,
ZESTSC1_ILLEGAL_CARD_ID,
ZESTSC1_INTERNAL_ERROR,
ZESTSC1_OUT_OF_MEMORY,
ZESTSC1_FILE_NOT_FOUND,
ZESTSC1_FILE_ERROR,
ZESTSC1_ILLEGAL_FILE,
ZESTSC1_TIMEOUT,
ZESTSC1_DRIVER_MISSING,
ZESTSC1_SIGNAL_IS_INPUT,
ZESTSC1_SIGNAL_IS_OUTPUT,
ZESTSC1_ILLEGAL_IMAGE_HANDLE,
ZESTSC1_INVALID_PART_TYPE,
ZESTSC1_MAX_ERROR
} ZESTSC1_STATUS;
typedef void (*ZESTSC1_ERROR_FUNC)(const char *Function,
ZESTSC1_HANDLE Handle,
ZESTSC1_STATUS Status,
const char *Msg);
/*******************
* Valid FPGA types *
*******************/
typedef enum
{
ZESTSC1_FPGA_UNKNOWN,
ZESTSC1_XC3S400,
ZESTSC1_XC3S1000,
} ZESTSC1_FPGA_TYPE;
/*****************************
* Card information structure *
*****************************/
typedef struct
{
unsigned long CardID;
unsigned long SerialNumber;
ZESTSC1_FPGA_TYPE FPGAType;
unsigned long MemorySize;
unsigned long TimeOut;
unsigned long FirmwareVersion;
} ZESTSC1_CARD_INFO;
/**********************
* Function prototypes *
**********************/
ZESTSC1_STATUS ZestSC1CountCards(unsigned long *NumCards,
unsigned long *CardIDs,
unsigned long *SerialNumbers,
ZESTSC1_FPGA_TYPE *FPGATypes);
ZESTSC1_STATUS ZestSC1OpenCard(unsigned long CardId,
ZESTSC1_HANDLE *Handle);
ZESTSC1_STATUS ZestSC1SetTimeOut(ZESTSC1_HANDLE Handle,
unsigned long MilliSeconds);
ZESTSC1_STATUS ZestSC1SetCardID(ZESTSC1_HANDLE Handle,
unsigned long CardID);
ZESTSC1_STATUS ZestSC1GetCardInfo(ZESTSC1_HANDLE Handle,
ZESTSC1_CARD_INFO *Info);
ZESTSC1_STATUS ZestSC1CloseCard(ZESTSC1_HANDLE Handle);
ZESTSC1_STATUS ZestSC1RegisterErrorHandler(ZESTSC1_ERROR_FUNC Function);
ZESTSC1_STATUS ZestSC1GetErrorMessage(ZESTSC1_STATUS Status,
char **Buffer);
ZESTSC1_STATUS ZestSC1ConfigureFromFile(ZESTSC1_HANDLE Handle,
char *FileName);
ZESTSC1_STATUS ZestSC1LoadFile(char *FileName,
ZESTSC1_IMAGE *Image);
ZESTSC1_STATUS ZestSC1Configure(ZESTSC1_HANDLE Handle,
ZESTSC1_IMAGE Image);
ZESTSC1_STATUS ZestSC1RegisterImage(void *Buffer,
unsigned long BufferLength,
ZESTSC1_IMAGE *Image);
ZESTSC1_STATUS ZestSC1FreeImage(ZESTSC1_IMAGE Image);
ZESTSC1_STATUS ZestSC1WriteRegister(ZESTSC1_HANDLE Handle,
unsigned long Offset,
unsigned char Value);
ZESTSC1_STATUS ZestSC1ReadRegister(ZESTSC1_HANDLE Handle,
unsigned long Offset,
unsigned char *Value);
ZESTSC1_STATUS ZestSC1ReadData(ZESTSC1_HANDLE Handle,
void *Buffer,
unsigned long Length);
ZESTSC1_STATUS ZestSC1WriteData(ZESTSC1_HANDLE Handle,
void *Buffer,
unsigned long Length);
ZESTSC1_STATUS ZestSC1SetSignalDirection(ZESTSC1_HANDLE Handle,
unsigned char Direction);
ZESTSC1_STATUS ZestSC1SetSignals(ZESTSC1_HANDLE Handle,
unsigned char Value);
ZESTSC1_STATUS ZestSC1ReadSignals(ZESTSC1_HANDLE Handle,
unsigned char *Value);
ZESTSC1_STATUS ZestSC1WaitForInterrupt(ZESTSC1_HANDLE Handle);
#ifdef __cplusplus
}
#endif
#endif // __ZESTSC1_H__
This diff is collapsed.
#include <usb.h>
#include <errno.h>
#include <memory.h>
#include <sys/ioctl.h>
#include "ZestSC1.h"
#include "Local.h"
ZESTSC1_STATUS ZestSC1_Transfer(ZESTSC1_HANDLE Handle, int EP, void *Buffer, int Length);
/******************************************************************************
* Write to a memory-mapped register on the FPGA *
******************************************************************************/
ZESTSC1_STATUS ZestSC1WriteRegister(ZESTSC1_HANDLE Handle,
unsigned long Offset,
unsigned char Value)
{
char Buffer[1];
ZESTSC1_CHECK_HANDLE("ZestSC1WriteRegister", Handle);
if (usb_control_msg(Struct->DeviceHandle, EP_CTRL_READ, VR_SET_REG,
Offset, Value, Buffer, 1, Struct->TimeOut)<=0)
{
ZESTSC1_ERROR("ZestSC1WriteRegister", ZESTSC1_INTERNAL_ERROR);
}
return ZESTSC1_SUCCESS;
}
/******************************************************************************
* Read from a memory-mapped register on the FPGA *
******************************************************************************/
ZESTSC1_STATUS ZestSC1ReadRegister(ZESTSC1_HANDLE Handle,
unsigned long Offset,
unsigned char *Value)
{
char Buffer[2] = {0,0};
ZESTSC1_CHECK_HANDLE("ZestSC1ReadRegister", Handle);
if (usb_control_msg(Struct->DeviceHandle, EP_CTRL_READ, VR_GET_REG,
Offset, 0, Buffer, 2, Struct->TimeOut)<=0)
{
ZESTSC1_ERROR("ZestSC1ReadRegister", ZESTSC1_INTERNAL_ERROR);
}
*Value = Buffer[1];
return ZESTSC1_SUCCESS;
}
/******************************************************************************
* Single function to read data from the card *
******************************************************************************/
ZESTSC1_STATUS ZestSC1ReadData(ZESTSC1_HANDLE Handle,
void *Buffer,
unsigned long Length)
{
ZESTSC1_STATUS Status;
ZESTSC1_CHECK_HANDLE("ZestSC1ReadData", Handle);
Status = ZestSC1_Transfer(Handle, EP_DATA_READ, Buffer, Length);
if (Status!=ZESTSC1_SUCCESS)
{
ZESTSC1_ERROR("ZestSC1ReadData", Status);
}
return ZESTSC1_SUCCESS;
}
/******************************************************************************
* Single function to write data to the card *
******************************************************************************/
ZESTSC1_STATUS ZestSC1WriteData(ZESTSC1_HANDLE Handle,
void *Buffer,
unsigned long Length)
{
ZESTSC1_STATUS Status;
ZESTSC1_CHECK_HANDLE("ZestSC1WriteData", Handle);
Status = ZestSC1_Transfer(Handle, EP_DATA_WRITE, Buffer, Length);
if (Status!=ZESTSC1_SUCCESS)
{
ZESTSC1_ERROR("ZestSC1WriteData", Status);
}
return ZESTSC1_SUCCESS;
}
#include <usb.h>
#include <errno.h>
#include <memory.h>
#include <linux/usbdevice_fs.h> // interface to kernel portion of user mode usb driver
#include <sys/ioctl.h>
#include <sys/time.h>
#include "ZestSC1.h"
#include "Local.h"
/******************************************************************************
* Perform bulk transfer *
* Maintain 2 active asynchronous URBs to maximise data transfer rate. *
******************************************************************************/
ZESTSC1_STATUS ZestSC1_Transfer(ZESTSC1_HANDLE Handle, int EP, void *Buffer, int Length)
{
ZESTSC1_HANDLE_STRUCT *Struct = (ZESTSC1_HANDLE_STRUCT *)Handle;
unsigned long Count = 0;
int fd = *((int *)(Struct->DeviceHandle)); // FIXME: Watch out here!
struct usbdevfs_urb *urb[2];
struct usbdevfs_urb urbs[2]; /*EC*/
int Queued[2] = {0,0};
ZESTSC1_STATUS Status = ZESTSC1_SUCCESS;
struct usbdevfs_urb *urbreap = 0;
int i;
struct timeval TimeEnd;
struct timeval TimeOut;
int Bytes = 0;
int LastTransfer;
for (i=0; i<2; i++)
{
urb[i] = &urbs[i]; /*EC*/
/* *EC*
urb[i] = malloc(sizeof(struct usbdevfs_urb));
if (urb[i]==NULL)
{
for (i--; i>=0; i--)
free(urb[i]);
return ZESTSC1_OUT_OF_MEMORY;
}
*/
}
gettimeofday(&TimeEnd, NULL);
TimeEnd.tv_sec += Struct->TimeOut/1000;
TimeEnd.tv_usec += (Struct->TimeOut%1000)*1000;
TimeOut.tv_sec = 0;
TimeOut.tv_usec = 1000; // 1msec
i = 0;
LastTransfer = 1;
for (Count=0; Count<(unsigned long)Length || LastTransfer==1; Count+=Bytes)
{
int RetVal;
if ((Length-Count)<ZESTSC1_MAX_TRANSFER_LENGTH)
Bytes = Length-Count;
else
Bytes = ZESTSC1_MAX_TRANSFER_LENGTH;
if (Bytes==0)
LastTransfer = 0;
if (Bytes!=0)
{
/*
* Submit the next URB
*/
memset(urb[i], 0, sizeof(struct usbdevfs_urb));
urb[i]->buffer_length = Bytes;
urb[i]->actual_length = Bytes;
urb[i]->buffer = ((char *)Buffer)+Count;
urb[i]->type = ((EP==EP_INT_READ) ? USBDEVFS_URB_TYPE_INTERRUPT : USBDEVFS_URB_TYPE_BULK);
urb[i]->endpoint = EP;
RetVal = ioctl(fd, USBDEVFS_SUBMITURB, urb[i]);
if (RetVal<0)
{
Status = ZESTSC1_INTERNAL_ERROR;
goto Error;
}
Queued[i] = 1;
}
i=1-i;
if (Count!=0)
{
/*
* Reap the previous URB
*/
struct timeval TimeNow;
fd_set fset;
FD_ZERO(&fset);
FD_SET(fd, &fset);
gettimeofday(&TimeNow, 0);
while ((RetVal=ioctl(fd, USBDEVFS_REAPURBNDELAY, &urbreap))==-1 &&
((TimeNow.tv_sec<TimeEnd.tv_sec) ||
(TimeNow.tv_sec==TimeEnd.tv_sec && TimeNow.tv_usec<TimeEnd.tv_usec)))
{
if (errno!=EAGAIN)
{
Status = ZESTSC1_INTERNAL_ERROR;
goto Error;
}
select(fd+1, NULL, &fset, NULL, &TimeOut);
gettimeofday(&TimeNow, 0);
}
if (RetVal==-1)
{
Status = ZESTSC1_TIMEOUT;
goto Error;
}
if (urbreap->status!=0)
{
Status = ZESTSC1_INTERNAL_ERROR;
goto Error;
}
Queued[i] = 0;
}
}
/* *EC*
for (i=0; i<2; i++)
free(urb[i]);
*/
return ZESTSC1_SUCCESS;
Error:
for (i=0; i<2; i++)
{
if (Queued[i])
{
// Cancel URB
ioctl(fd, USBDEVFS_DISCARDURB, &urb[i]);
}
/* *EC* free(urb[i]); */
}
return Status;
}
#include <usb.h>
#include <errno.h>
#include <memory.h>
#include <sys/ioctl.h>
#include "ZestSC1.h"
#include "Local.h"
/******************************************************************************
* Perform bulk transfer *
* Just forward to usb_bulk_read, original linux version doesn't work on Mac. *
******************************************************************************/
ZESTSC1_STATUS ZestSC1_Transfer(ZESTSC1_HANDLE Handle, int EP, void *Buffer, int Length)
{
ZESTSC1_CHECK_HANDLE("ZestSC1ReadData", Handle);
if (usb_bulk_read(Struct->DeviceHandle, EP, Buffer, Length, Struct->TimeOut)<=0)
{
ZESTSC1_ERROR("ZestSC1_Transfer", ZESTSC1_INTERNAL_ERROR);
}
return ZESTSC1_SUCCESS;
}
#include <usb.h>
#include "ZestSC1.h"
#include "Local.h"
/******************************************************************************
* Globals *
******************************************************************************/
char *ZestSC1_ErrorStrings[] =
{
"Success (no error)",
"Attempt to use illegal card handle",
"Status code is out of range",
"NULL was used illegally as one of the parameter values",
"The requested device is being used by another application",
"The requested card ID does not correspond to any devices in the system",
"An unspecified internal error occurred while communicating with the driver",
"Not enough memory to complete the requested operation",
"File not found",
"Error while reading file",
"File format is not recognised",
"Operation timed out",
"The device driver has not been installed correctly",
"One of the requested signals is an input and cannot be set",
"One of the requested signals is an output and cannot be waited for",
"The image handle does not point to valid configuration data",
"The configuration part type does not match the FPGA fitted to this board"
};
ZESTSC1_ERROR_FUNC ZestSC1_ErrorHandler = 0;
/******************************************************************************
* Register a user error handling function to be called *
* Set to NULL to disable error callbacks *
******************************************************************************/
ZESTSC1_STATUS ZestSC1RegisterErrorHandler(ZESTSC1_ERROR_FUNC Function)
{
ZestSC1_ErrorHandler = Function;
return ZESTSC1_SUCCESS;
}
/******************************************************************************
* Get a human-readable error string for a status code *
******************************************************************************/
ZESTSC1_STATUS ZestSC1GetErrorMessage(ZESTSC1_STATUS Status,
char **Buffer)
{
if (Status>ZESTSC1_MAX_ERROR ||
(Status<ZESTSC1_ERROR_BASE && Status>=ZESTSC1_MAX_WARNING) ||
(Status<ZESTSC1_WARNING_BASE && Status>=ZESTSC1_MAX_INFO))
{
return ZESTSC1_ILLEGAL_STATUS_CODE;
}
*Buffer = ZESTSC1_ERROR_STRING(Status);
return ZESTSC1_SUCCESS;
}
../Inc
\ No newline at end of file
This diff is collapsed.
# Compile with slower (but safer) block transfer code
SAFEMODE = 1
TARGET = Lib/libZestSC1.a
ARFLAGS = r
OBJS = Main.o Error.o Data.o Config.o
ifdef SAFEMODE
# OBJS += DataMac.o
# else
OBJS += DataLinux.o
endif
CC = gcc
ifdef SAFEMODE
# Debugging values:
CFLAGS = -c -fPIC -g -O0 -W -Wall -fno-inline -I../Inc -m32
else
# Production values:
CFLAGS = -c -O2 -W -Wall -I../Inc -m32
endif
all: $(TARGET)
clean:
rm $(TARGET)
rm $(OBJS)
$(TARGET): $(OBJS)
$(AR) $(ARFLAGS) $(TARGET) $(OBJS)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment