/*
 Include file for the libusb-based usbio library.

 Copyright (c) 2006 Dimtel, Inc., All Rights Reserved

 $Id: usbio.h,v 1.2 2013/09/05 03:38:23 dim Exp $
 $Date: 2013/09/05 03:38:23 $
 $Author: dim $
 $Revision: 1.2 $
 $Log: usbio.h,v $
 Revision 1.2  2013/09/05 03:38:23  dim
 New libusb interface, transaction size checking added

 Revision 1.1  2012/11/11 05:25:19  dim
 Moved from iGp12/src/usbio, updated to handle LLRF4 and iGp12

 Revision 1.2  2012/08/29 06:45:59  dim
 Added usbio_write_eeprom(), write_offsets command

 Revision 1.1.1.1  2010/10/05 16:42:44  dim
 Initial import of iGp12

 Revision 1.1.1.1  2009/06/02 20:26:02  dim
 Initial import

 Revision 1.2  2009/06/02 19:56:51  dim
 Full support for service functions (fw load, 8051 control, EEPROM) added

 Revision 1.1.1.1  2006/11/16 19:38:15  dim
 Initial import

*/

#ifndef _USBIO_H_
#define _USBIO_H_

#include <pthread.h>
#include <string.h>
#include <libusb-1.0/libusb.h>
#include <sys/time.h>

#define FX2_DEFAULT_VID	0x04b4
#define FX2_DEFAULT_PID	0x8613

/* Maximum transfer size is 1GWord-1 (= 4GB-4) */
#define USBIO_MAXLEN  1073741823
#define USBIO_MULT_MAXLEN 8192

#define USBIO_EP_WRITE 0x02
#define USBIO_EP_RDATA 0x86

/* MSB defines the R/W direction */
#define USBIO_M_RW 0x80000000

/* At 16 MB/s it takes 256 seconds to transfer 4 GB */
#define USBIO_TIMEOUT 2000

/* Endpoint 0 vendor request timeouts */
#define USBIO_VENDOR_TIMEOUT 1000

#define USBIO_FW_CHUNK 4096

#define MAX(a, b) ((a) < (b)) ? (b) : (a)
#define MIN(a, b) ((a) >= (b)) ? (b) : (a)


#ifndef deltaT
#define deltaT(tvp1, tvp2) (((tvp2)->tv_sec-(tvp1)->tv_sec)*1000000 + \
                              (tvp2)->tv_usec - (tvp1)->tv_usec)
#endif

typedef struct usbio_context
{
  pthread_mutex_t                 mutex;
  struct libusb_device_descriptor desc;
  libusb_device_handle            *handle;
} usbio_context;

usbio_context *usbio_open(int flag);
usbio_context *usbio_open_serial(int flag, char *serial);
usbio_context *usbio_open_full(int flag, char *serial, unsigned short *bcd);
void usbio_close(usbio_context *ctxt, int flag);
char *usbio_read_serial(usbio_context *ctxt);

unsigned int usbio_write(usbio_context *ctxt, unsigned int addr,
                         unsigned int data);
unsigned int usbio_block_write(usbio_context *ctxt, unsigned int addr,
                               unsigned int *data, unsigned int count);
unsigned int usbio_block_read(usbio_context *ctxt, unsigned int addr,
                              unsigned int *data, unsigned int count);
unsigned int usbio_mult_write(usbio_context *ctxt, unsigned int *addr,
                              unsigned int *data, int count);

/* Some definitions for convenience */
#define usbio_read(ctxt, addr, data) usbio_block_read(ctxt, addr, data, 1)

/* EP0 (vendor) control functions */
int usbio_if_reset(usbio_context *ctxt);
int usbio_i2c_write(usbio_context *ctxt, char addr, const void *buf, int len);
int usbio_i2c_read(usbio_context *ctxt, char addr, void *buf, int len);
int usbio_usberr_read(usbio_context *ctxt);
int usbio_write_sernum(usbio_context *ctxt, char *sernum);
int usbio_write_eeprom(usbio_context *ctxt, int addr, char *data, int length);
int usbio_cpu_reset(usbio_context *ctxt, int value);
int usbio_readram(usbio_context *ctxt, int addr, int length, unsigned char **ram);
int usbio_writeram(usbio_context *ctxt, int addr, int length, unsigned char *data);
int usbio_fw_load(usbio_context *ctxt, char *file);

/* Common functions */
int string2bytes(char *buf, char *string, int bufsize);

#endif /* _USBIO_H_ */
