/*****************************************************************************/

/*
 *      fpga.h  --  FPGA test library exports (and imports).
 *
 *      Copyright (C) 1998, 1999, 2000  Thomas Sailer (sailer@ife.ee.ethz.ch)
 *
 *      This program is free software; you can redistribute it and/or modify
 *      it under the terms of the GNU General Public License as published by
 *      the Free Software Foundation; either version 2 of the License, or
 *      (at your option) any later version.
 *
 *      This program is distributed in the hope that it will be useful,
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *      GNU General Public License for more details.
 *
 *      You should have received a copy of the GNU General Public License
 *      along with this program; if not, write to the Free Software
 *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *  Please note that the GPL allows you to use the driver, NOT the radio.
 *  In order to use the radio, you need a license from the communications
 *  authority of your country.
 *
 */

/*****************************************************************************/

#ifndef _FPGA_H
#define _FPGA_H

/* ---------------------------------------------------------------------- */

#include "sysdeps.h"
#include "parport.h"

/* ---------------------------------------------------------------------- */

struct adapter_config {
	unsigned int fclk;
	unsigned int bitrate;
	unsigned int intclk;
	unsigned int extmodem;
	unsigned int loopback;
	unsigned int extstat;
        unsigned int pttmute;
	unsigned int filtmode;
	unsigned int gain;
};

/* ---------------------------------------------------------------------- */

extern void printconfig(const struct adapter_config *cfg);
extern void parseconfig(struct adapter_config *cfg, const char *modestr);

extern int adapter_start_no_firmware(void);
extern int adapter_start_eppchk(void);
extern int adapter_start_epp(struct adapter_config *cfg);
extern int adapter_start_ecp(struct adapter_config *cfg);
extern int adapter_start_eppafsk(struct adapter_config *cfg);
extern int adapter_start_sppafsk(struct adapter_config *cfg);
extern int adapter_start_eppsamp(struct adapter_config *cfg);

/* ---------------------------------------------------------------------- */

extern inline void sppafsk_wrcmd(unsigned char d)
{
	parport_write_data(d);
	parport_write_control(LPTCTRL_PROGRAM | 0x09);
	parport_write_control(LPTCTRL_PROGRAM | 0x08);
}

extern inline void sppafsk_wrdata(unsigned char d)
{
	parport_write_data(d);
	parport_write_control(LPTCTRL_PROGRAM | 0x01);
	parport_write_control(LPTCTRL_PROGRAM | 0x00);
}

extern inline unsigned char sppafsk_rdcmd(void)
{
	unsigned char d1, d2;

	parport_write_control(LPTCTRL_PROGRAM | 0x0b);
	parport_read_status();
	d2 = parport_read_status();
	d1 = ((d2 & 0xe0) | ((d2 << 1) & 0x10)) >> 4;
	parport_write_control(LPTCTRL_PROGRAM | 0x0a);
	parport_read_status();
	d2 = parport_read_status();
	d1 |= (d2 & 0xe0) | ((d2 << 1) & 0x10);
	return d1;
}

extern inline unsigned char sppafsk_rddata(void)
{
	unsigned char d1, d2;

	parport_write_control(LPTCTRL_PROGRAM | 0x03);
	parport_read_status();
	d2 = parport_read_status();
	d1 = ((d2 & 0xe0) | ((d2 << 1) & 0x10)) >> 4;
	parport_write_control(LPTCTRL_PROGRAM | 0x02);
	parport_read_status();
	d2 = parport_read_status();
	d1 |= (d2 & 0xe0) | ((d2 << 1) & 0x10);
	return d1;
}

/* ---------------------------------------------------------------------- */

/*
 * description of the test procedures defined
 */

extern const struct eppfpgatests {
	const char *name;
	const char *desc;
	int (*func)(struct adapter_config *);
} eppfpgatests[];

/* ---------------------------------------------------------------------- */

/*
 * provided externally!
 */

extern int lprintf(unsigned vl, const char *format, ...)
__attribute__ ((format (printf, 2, 3)));

extern int tprintf(const char *format, ...)
__attribute__ ((format (printf, 1, 2)));

extern int idle_callback(unsigned us_delay);

/* ---------------------------------------------------------------------- */

extern int snprintpkt(char *buf, size_t sz, const u_int8_t *pkt, unsigned len);

/* ---------------------------------------------------------------------- */

extern inline void reset_modem(void)
{
	unsigned char null = 0;

	parport_epp_write_addr(&null, 1);
	parport_write_control(LPTCTRL_ADDRSTB);
}

/* ---------------------------------------------------------------------- */

extern inline unsigned readboundary(const unsigned char *b, unsigned x)
{
	return (b[x >> 3] >> (x & 7)) & 1;
}

extern inline void writeboundary(unsigned char *b, unsigned x, int v)
{
	b[x >> 3] &= ~(1 << (x & 7));
	b[x >> 3] |= (v & 1) << (x & 7);
}

/* ---------------------------------------------------------------------- */

extern void boundary(unsigned int blen, const unsigned char *in, unsigned char *out, unsigned char eppdata);

/* ---------------------------------------------------------------------- */
#endif /* _FPGA_H */
