diff --git a/microtune/Makefile.am b/microtune/Makefile.am new file mode 100644 index 000000000..f1561c198 --- /dev/null +++ b/microtune/Makefile.am @@ -0,0 +1,49 @@ +# +# Copyright 2001 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio 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, or (at your option) +# any later version. +# +# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +MTSRCLIST = module_4937.c + +GRIO_SOURCES = \ + ppio.cc \ + i2cio.cc \ + i2cio_pp.cc \ + i2c.cc \ + microtune_4937.cc \ + microtune_eval_board.cc + +lib_LTLIBRARIES = hamlib-microtune.la +hamlib_microtune_la_SOURCES = $(MTSRCLIST) $(GRIO_SOURCES) microtune.cc +hamlib_microtune_la_LDFLAGS = -no-undefined -module -avoid-version +hamlib_microtune_la_LIBADD = $(top_builddir)/src/libhamlib.la + +noinst_HEADERS = \ + i2c.h \ + i2cio.h \ + i2cio_pp.h \ + microtune_4937.h \ + microtune_eval_board.h \ + microtune_eval_board_defs.h \ + ppio.h \ + microtune.h + +check_PROGRAMS = givelp1 + +givelp1_SOURCES = givelp1.cc + diff --git a/microtune/givelp1.cc b/microtune/givelp1.cc new file mode 100644 index 000000000..c2b8359ac --- /dev/null +++ b/microtune/givelp1.cc @@ -0,0 +1,111 @@ +/* -*-C++-*- +******************************************************************************* +* +* File: givelp1.cc +* Description: give a program direct access to LPT1 io ports +* +******************************************************************************* +*/ + +/* + * Copyright 2001,2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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, or (at your option) + * any later version. + * + * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include +#include +#include + +// which is 0, 1 or 2 to specify lp0, lp1 or lp2 + +const static int parallel_port_base[3] = { + 0x3bc, // lp0 used to be on monochome display adapter + 0x378, // lp1 most common + 0x278 // lp2 secondary +}; + + +/*! + * \brief enable direct parallel port io access from user land. + * \p is in [0,2] and specifies which parallel port to access. + * + * \returns -1 on error, else base ioport address + */ +int +enable_parallel_ioport_access (int which) +{ + errno = 0; + if (which < 0 || which >= 3) + return -1; + + if (ioperm (parallel_port_base[which], 3, 1) < 0) + return -1; + + return parallel_port_base[which]; +} + +bool +reset_eids () +{ + if (setgid (getgid ()) < 0){ + perror ("setguid"); + return false; + } + + if (setuid (getuid ()) < 0){ + perror ("setuid"); + return false; + } + + return true; +} + + +int main (int argc, char **argv) +{ + if (argc < 2){ + fprintf (stderr, "usage: givelp1 program-to-run [arg...]\n"); + exit (2); + } + + if (enable_parallel_ioport_access (1) == -1){ + if (errno != 0){ + perror ("ioperm"); + fprintf (stderr, "givelp1 must be setuid root to use ioperm system call\n"); + fprintf (stderr, "Running as root, please execute: \n"); + fprintf (stderr, " # chown root givelp1\n"); + fprintf (stderr, " # chmod u+s givelp1\n"); + exit (1); + } + } + + if (!reset_eids ()){ + fprintf (stderr, "Can't drop root permissions\n"); + exit (3); + } + + // if successful, no return + execvp (argv[1], argv+1); + + perror (argv[1]); + exit (4); +} diff --git a/microtune/i2c.cc b/microtune/i2c.cc new file mode 100644 index 000000000..512b69bc8 --- /dev/null +++ b/microtune/i2c.cc @@ -0,0 +1,136 @@ +/* -*-C++-*- +******************************************************************************* +* +* File: i2c.cc +* Description: generic i2c bus controller +* +******************************************************************************* +*/ + +/* + * Copyright 2001 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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, or (at your option) + * any later version. + * + * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "i2c.h" + +i2c::i2c (i2cio *a_io) +{ + io = a_io; + stop (); // get bus in known state +} + + +// start: +// entry: SCL = 1, SDA = 1 +// exit: SCL = 0, SDA = 0 + +void +i2c::start () +{ + set_sda (1); + set_scl (1); + set_sda (0); // SDA high -> low while SCL high + set_scl (0); +} + + +// stop: +// entry: SCL = X, SDA = X +// exit: SCL = 1, SDA = 1 + +void +i2c::stop () +{ + set_scl (0); + set_sda (0); + set_scl (1); + set_sda (1); // SDA low -> high while SCL high +} + + +// write_bit: +// entry: SCL = 0, SDA = X +// exit: SCL = 0, SDA = X + +void +i2c::write_bit (bool bit) +{ + set_sda (bit); + set_scl (1); + set_scl (0); +} + + +// write_byte: +// entry: SCL = 0, SDA = X +// exit: SCL = 0, SDA = 1 + +bool +i2c::write_byte (char t) +{ + int i; + bool ack_bit; + + for (i = 0; i < 8; i++){ + write_bit (t & 0x80); + t <<= 1; + } + + // clock #9. This is the ACK bit. + + set_sda (1); // tristate SDA + set_scl (1); + ack_bit = get_sda (); // slave should pull SDA line low + set_scl (0); + + return ack_bit == 0; +} + + +// write: the high level entry point... +// entry: SCL = 1, SDA = 1 +// exit: SCL = 1, SDA = 1 + +bool +i2c::write (int addr, const unsigned char *buf, int nbytes) +{ + bool ok = true; + + start (); + ok = write_byte ((addr << 1) | 0); // addr plus "read opcode" + + for (int i = 0; i < nbytes; i++) + ok &= write_byte (buf[i]); + + stop (); + return ok; +} + + +// read: the high level entry point... +// entry: SCL = 1, SDA = 1 +// exit: SCL = 1, SDA = 1 + +int +i2c::read (int addr, unsigned char *buf, int max_bytes) +{ + // FIXME + return 0; +} diff --git a/microtune/i2c.h b/microtune/i2c.h new file mode 100644 index 000000000..ec736440f --- /dev/null +++ b/microtune/i2c.h @@ -0,0 +1,66 @@ +/* -*-C++-*- +******************************************************************************* +* +* File: i2c.h +* Description: +* +******************************************************************************* +*/ + +/* + * Copyright 2001 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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, or (at your option) + * any later version. + * + * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _I2C_H_ +#define _I2C_H_ + +#include "i2cio.h" + +/*! + * \brief class for controlling i2c bus + */ +class i2c { + public: + + /*! i2c does not control lifetime of a_io */ + i2c (i2cio *a_io); + ~i2c () {}; + + //! \returns true iff successful + bool write (int addr, const unsigned char *buf, int nbytes); + + //! \returns number of bytes read or -1 if error + int read (int addr, unsigned char *buf, int max_bytes); + + +private: + void start (); + void stop (); + void write_bit (bool bit); + bool write_byte (char byte); + + void set_sda (bool bit) { io->set_sda (bit); } + void set_scl (bool bit) { io->set_scl (bit); } + bool get_sda () { return io->get_sda (); } + + i2cio *io; +}; + +#endif /* _I2C_H_ */ diff --git a/microtune/i2cio.cc b/microtune/i2cio.cc new file mode 100644 index 000000000..b89718e19 --- /dev/null +++ b/microtune/i2cio.cc @@ -0,0 +1,33 @@ +/* -*-C++-*- +******************************************************************************* +* +* File: i2cio.cc +* Description: +* +******************************************************************************* +*/ + +/* + * Copyright 2001 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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, or (at your option) + * any later version. + * + * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "i2cio.h" + +i2cio::~i2cio(){} diff --git a/microtune/i2cio.h b/microtune/i2cio.h new file mode 100644 index 000000000..31593b343 --- /dev/null +++ b/microtune/i2cio.h @@ -0,0 +1,68 @@ +/* -*-C++-*- +******************************************************************************* +* +* File: i2cio.h +* Description: +* +******************************************************************************* +*/ + +/* + * Copyright 2001 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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, or (at your option) + * any later version. + * + * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _I2CIO_H_ +#define _I2CIO_H_ + +/*! + * \brief abstract class that implements low level i/o for i2c bus. + */ +class i2cio { + public: + + i2cio () : + udelay_scl_lo(0), udelay_scl_hi(0), + udelay_sda_lo(0), udelay_sda_hi(0) {}; + + virtual ~i2cio (); + + virtual void set_scl (bool state) = 0; + virtual void set_sda (bool state) = 0; + virtual bool get_sda () = 0; + + void set_udelay_scl_lo (int usecs) { udelay_scl_lo = usecs; } + void set_udelay_scl_hi (int usecs) { udelay_scl_hi = usecs; } + void set_udelay_sda_lo (int usecs) { udelay_sda_lo = usecs; } + void set_udelay_sda_hi (int usecs) { udelay_sda_hi = usecs; } + + int get_udelay_scl_lo () { return udelay_scl_lo; } + int get_udelay_scl_hi () { return udelay_scl_hi; } + int get_udelay_sda_lo () { return udelay_sda_lo; } + int get_udelay_sda_hi () { return udelay_sda_hi; } + + private: + int udelay_scl_lo; + int udelay_scl_hi; + int udelay_sda_lo; + int udelay_sda_hi; +}; + + +#endif /* _I2CIO_H_ */ diff --git a/microtune/i2cio_pp.cc b/microtune/i2cio_pp.cc new file mode 100644 index 000000000..44753573a --- /dev/null +++ b/microtune/i2cio_pp.cc @@ -0,0 +1,75 @@ +/* -*-C++-*- +******************************************************************************* +* +* File: i2cio_pp.cc +* Description: +* +******************************************************************************* +*/ + +/* + * Copyright 2001 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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, or (at your option) + * any later version. + * + * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "i2cio_pp.h" +#include "microtune_eval_board_defs.h" + +i2cio_pp::i2cio_pp (ppio *a_pp) +{ + pp = a_pp; + pp->write_control (pp->read_control () & ~UT_CP_MUST_BE_ZERO); // output, no interrupts +} + +void +i2cio_pp::set_scl (bool state) +{ + int r = pp->read_control(); + + if (!state){ // active low + pp->write_control (r | UT_CP_TUNER_SCL); + } + else { + pp->write_control (r & ~UT_CP_TUNER_SCL); + } + pp->read_control (); // use for 1us delay + pp->read_control (); // use for 1us delay +} + +void +i2cio_pp::set_sda (bool state) +{ + int r = pp->read_data (); + + if (!state){ // active low + pp->write_data (r | UT_DP_TUNER_SDA_OUT); + } + else { + pp->write_data (r & ~UT_DP_TUNER_SDA_OUT); + } + pp->read_data (); // use for 1us delay + pp->read_data (); // use for 1us delay +} + +bool +i2cio_pp::get_sda () +{ + int r = pp->read_status (); + return (r & UT_SP_TUNER_SDA_IN) == 0; // eval board has an inverter on it +} diff --git a/microtune/i2cio_pp.h b/microtune/i2cio_pp.h new file mode 100644 index 000000000..7e8bd80fc --- /dev/null +++ b/microtune/i2cio_pp.h @@ -0,0 +1,53 @@ +/* -*-C-*- +******************************************************************************* +* +* File: i2cio_pp.h +* Description: i2cio class for parallel port +* +******************************************************************************* +*/ + +/* + * Copyright 2001 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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, or (at your option) + * any later version. + * + * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _I2CIO_PP_H_ +#define _I2CIO_PP_H_ + +#include "i2cio.h" +#include "ppio.h" + +/*! + * \brief concrete class that implements low level i/o for i2c bus using parallel port + */ +class i2cio_pp : public i2cio { + public: + + i2cio_pp (ppio *a_pp); + + virtual void set_scl (bool state); + virtual void set_sda (bool state); + virtual bool get_sda (); + + private: + ppio *pp; +}; + +#endif /* _I2CIO_PP_H_ */ diff --git a/microtune/microtune.cc b/microtune/microtune.cc new file mode 100644 index 000000000..2efe7087a --- /dev/null +++ b/microtune/microtune.cc @@ -0,0 +1,147 @@ +/* + * Hamlib Microtune backend - main file + * Copyright (c) 2003 by Stephane Fillod + * + * $Id: microtune.cc,v 1.1 2003-01-29 23:06:30 fillods Exp $ + * + * This library 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, 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 software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "microtune.h" +#include "microtune_eval_board.h" +#include + +/* + * TODO: allow these to be modifiable through rig_set_conf + int i2c_addr; + int reference_divider; + bool fast_tuning_p; if set, higher charge pump current: + faster tuning, worse phase noise + for distance < 10kHz to the carrier + */ + +#define M4937_I2C_ADDR (0xC2/2) +#define REF_DIVIDER 640 +#define FAST_TUNING false + +struct module_4937_priv_data { + microtune_eval_board *board; + freq_t actual_freq; +}; + +/* + * TODO: + * - status iff PLL is locked + * - returns the output frequency of the tuner in Hz (->5.75e6) //3x7702. + */ + +int module_4937_init(RIG *rig) +{ + struct module_4937_priv_data *priv; + int which = 1; // the parallel port the board is connected to + + priv = (struct module_4937_priv_data*)malloc(sizeof(struct module_4937_priv_data)); + if (!priv) { + /* whoops! memory shortage! */ + return -RIG_ENOMEM; + } + + priv->actual_freq = RIG_FREQ_NONE; + + rig_debug(RIG_DEBUG_TRACE, "microtune: if the program segfaults here," + " you require ioperm privilege. Use givelp1.\n"); + + priv->board = new microtune_eval_board(which); + if (!priv->board) { + free(priv); + return -RIG_ENOMEM; + } + + rig_debug(RIG_DEBUG_TRACE, "microtune: ioperm okay. " + "parallel port access granted.\n"); + rig->state.priv = (void*)priv; + + return RIG_OK; +} + +int module_4937_open(RIG *rig) +{ + struct module_4937_priv_data *priv = (struct module_4937_priv_data *)rig->state.priv; + + if (!priv->board->board_present_p()) { + rig_debug(RIG_DEBUG_WARN, "microtune: eval board is NOT present\n"); + return -RIG_EPROTO; + } + + return RIG_OK; +} + +int module_4937_close(RIG *rig) +{ + /* place holder.. */ + + return RIG_OK; +} + +int module_4937_cleanup(RIG *rig) +{ + struct module_4937_priv_data *priv = (struct module_4937_priv_data *)rig->state.priv; + + if (priv) { + delete priv->board; + free(priv); + } + rig->state.priv = NULL; + + return RIG_OK; +} + +/* + * It takes about 100 ms for the PLL to settle. + */ +int module_4937_set_freq(RIG *rig, vfo_t vfo, freq_t freq) +{ + double actual_freq; + bool status; + + struct module_4937_priv_data *priv = (struct module_4937_priv_data *)rig->state.priv; + + status = priv->board->set_RF_freq((double)freq, &actual_freq); + + if (!status) + return -RIG_EIO; + + priv->actual_freq = (freq_t)actual_freq; + return RIG_OK; +} + + +int module_4937_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) +{ + struct module_4937_priv_data *priv = (struct module_4937_priv_data *)rig->state.priv; + + *freq = priv->actual_freq; + + return RIG_OK; +} + diff --git a/microtune/microtune.h b/microtune/microtune.h new file mode 100644 index 000000000..964763f9b --- /dev/null +++ b/microtune/microtune.h @@ -0,0 +1,43 @@ +/* + * Hamlib Microtune backend - main header + * Copyright (c) 2001,2002 by Stephane Fillod + * + * $Id: microtune.h,v 1.1 2003-01-29 23:06:30 fillods Exp $ + * + * This library 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, 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 software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef _MICRTOUNE_H +#define _MICRTOUNE_H 1 + +#include + +__BEGIN_DECLS + +int module_4937_init(RIG *rig); +int module_4937_cleanup(RIG *rig); +int module_4937_open(RIG *rig); +int module_4937_close(RIG *rig); +int module_4937_set_freq(RIG *rig, vfo_t vfo, freq_t freq); +int module_4937_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); +extern const struct rig_caps module_4937_caps; + +extern BACKEND_EXPORT(int) initrigs_microtune(void *be_handle); + +__END_DECLS + +#endif /* _MICRTOUNE_H */ diff --git a/microtune/microtune_4937.cc b/microtune/microtune_4937.cc new file mode 100644 index 000000000..bb738a1c4 --- /dev/null +++ b/microtune/microtune_4937.cc @@ -0,0 +1,142 @@ +/* -*-C++-*- +******************************************************************************* +* +* File: microtune_4937.cc +* Description: +* +******************************************************************************* +*/ + +/* + * Copyright 2001 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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, or (at your option) + * any later version. + * + * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "microtune_4937.h" +#include +#include + +static const double first_IF = 43.75e6; + +// The tuner internally has 3 bands: VHF Low, VHF High & UHF. +// These are the recommened boundaries +static const double VHF_High_takeover = 158e6; +static const double UHF_takeover = 464e6; + +static unsigned char +control_byte_1 (bool fast_tuning_p, int reference_divisor) +{ + int c = 0x88; + + if (fast_tuning_p) + c |= 0x40; + + switch (reference_divisor){ + case 512: + c |= 0x3 << 1; break; + case 640: + c |= 0x0 << 1; break; + case 1024: + c |= 0x1 << 1; break; + default: + abort (); + } + return c; +} + +static unsigned char +control_byte_2 (double target_freq, bool shutdown_tx_PGA) +{ + int c; + + if (target_freq < VHF_High_takeover) // VHF low + c = 0xa0; + else if (target_freq < UHF_takeover) // VHF high + c = 0x90; + else // UHF + c = 0x30; + + if (shutdown_tx_PGA) + c |= 0x08; + + return c; +} + +microtune_4937::~microtune_4937 (){} + +/*! + * \brief select RF frequency to be tuned to output frequency. + * \p target_freq is the requested frequency in Hz, \p actual_freq + * is set to the actual frequency tuned. It takes about 100 ms + * for the PLL to settle. + * + * \returns true iff sucessful. + */ +bool +microtune_4937::set_RF_freq (double target_freq, double *p_actual_freq) +{ + unsigned char buf[4]; + + double target_f_osc = target_freq + first_IF; + + double f_ref = 4e6 / reference_divider; + + // f_osc = f_ref * 8 * divisor + // divisor = f_osc / (f_ref * 8) + + int divisor = (int) ((target_f_osc + (f_ref * 4)) / (f_ref * 8)); + double actual_freq = (f_ref * 8 * divisor) - first_IF; + if (p_actual_freq != 0) + *p_actual_freq = actual_freq; + + if ((divisor & ~0x7fff) != 0) // 15 bit divisor + return false; + + buf[0] = (divisor >> 8) & 0xff; // DB1 + buf[1] = divisor & 0xff; // DB2 + buf[2] = control_byte_1 (fast_tuning_p, reference_divider); + buf[3] = control_byte_2 (target_freq, true); + +#if 0 + printf ("set_RF_freq: target: %g MHz actual: %g MHz %02x %02x %02x %02x\n", + target_freq/1e6, actual_freq/1e6, buf[0], buf[1], buf[2], buf[3]); +#endif + + return i2c_write (i2c_addr, buf, 4); +} + + +/*! + * \returns true iff PLL is locked + */ +bool +microtune_4937::pll_locked_p () +{ + // FIXME + return true; +} + +/*! + * \returns the output frequency of the tuner in Hz. + */ +double +microtune_4937::get_output_freq () +{ + return 5.75e6; // 3x7702 +} diff --git a/microtune/microtune_4937.h b/microtune/microtune_4937.h new file mode 100644 index 000000000..aa68a7693 --- /dev/null +++ b/microtune/microtune_4937.h @@ -0,0 +1,79 @@ +/* -*-C++-*- +******************************************************************************* +* +* File: microtune_4937.h +* Description: +* +******************************************************************************* +*/ + +/* + * Copyright 2001 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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, or (at your option) + * any later version. + * + * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _MICROTUNE_4937_H_ +#define _MICROTUNE_4937_H_ + +/*! + * \brief abstract class for controlling microtune 4937 tuner module + */ +class microtune_4937 { +public: + microtune_4937 () : + i2c_addr (0xC2/2), reference_divider(640), fast_tuning_p (false) {}; + + virtual ~microtune_4937 (); + + /*! + * \brief select RF frequency to be tuned to output frequency. + * \p freq is the requested frequency in Hz, \p actual_freq + * is set to the actual frequency tuned. It takes about 100 ms + * for the PLL to settle. + * + * \returns true iff sucessful. + */ + bool set_RF_freq (double freq, double *actual_freq); + + /*! + * \returns true iff PLL is locked + */ + bool pll_locked_p (); + + /*! + * \returns the output frequency of the tuner in Hz. + */ + double get_output_freq (); + + private: + //! \returns true iff successful + virtual bool i2c_write (int addr, const unsigned char *buf, int nbytes) = 0; + + //! \returns number of bytes read or -1 if error + virtual int i2c_read (int addr, unsigned char *buf, int max_bytes) = 0; + + int i2c_addr; + int reference_divider; + bool fast_tuning_p; /* if set, higher charge pump current: + faster tuning, worse phase noise + for distance < 10kHz to the carrier */ +}; + + +#endif /* _MICROTUNE_4937_H_ */ diff --git a/microtune/microtune_eval_board.cc b/microtune/microtune_eval_board.cc new file mode 100644 index 000000000..b614e635f --- /dev/null +++ b/microtune/microtune_eval_board.cc @@ -0,0 +1,84 @@ +/* -*-C++-*- +******************************************************************************* +* +* File: microtune_eval_board.cc +* Description: +* +******************************************************************************* +*/ + +/* + * Copyright 2001 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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, or (at your option) + * any later version. + * + * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "microtune_eval_board.h" +#include "microtune_eval_board_defs.h" +#include "ppio.h" +#include "i2cio_pp.h" +#include "i2c.h" + +microtune_eval_board::microtune_eval_board (int which_pp) +{ + m_ppio = new ppio (which_pp); + m_i2cio = new i2cio_pp (m_ppio); + m_i2c = new i2c (m_i2cio); + + // disable upstream amplifier + int t = m_ppio->read_data (); + t &= ~(UT_DP_TX_ENABLE | UT_DP_TX_SDA | UT_DP_TX_SCL); + t |= UT_DP_TX_AS; + m_ppio->write_data (t); +} + +microtune_eval_board::~microtune_eval_board () +{ + delete m_i2c; + delete m_i2cio; + delete m_i2c; +} + + +//! is the eval board present? +bool +microtune_eval_board::board_present_p () +{ + int t = m_ppio->read_status (); + if ((t & UT_SP_SHOULD_BE_ZERO) != 0 + || (t & UT_SP_SHOULD_BE_ONE) != UT_SP_SHOULD_BE_ONE) + return false; + + // could also see if SCL is looped back or not, but that seems like overkill + + return true; +} + +// returns true iff successful +bool +microtune_eval_board::i2c_write (int addr, const unsigned char *buf, int nbytes) +{ + return m_i2c->write (addr, buf, nbytes); +} + +// returns number of bytes read or -1 if error +int +microtune_eval_board::i2c_read (int addr, unsigned char *buf, int max_bytes) +{ + return m_i2c->read (addr, buf, max_bytes); +} diff --git a/microtune/microtune_eval_board.h b/microtune/microtune_eval_board.h new file mode 100644 index 000000000..92e5a51fa --- /dev/null +++ b/microtune/microtune_eval_board.h @@ -0,0 +1,64 @@ +/* -*-C++-*- +******************************************************************************* +* +* File: microtune_eval_board.h +* Description: +* +******************************************************************************* +*/ + +/* + * Copyright 2001 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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, or (at your option) + * any later version. + * + * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _MICROTUNE_EVAL_BOARD_H_ +#define _MICROTUNE_EVAL_BOARD_H_ + +#include "microtune_4937.h" + +class ppio; +class i2cio; +class i2c; + +/*! + * \brief concrete class for controlling microtune 4937 eval board attached to parallel port + */ +class microtune_eval_board : public microtune_4937 { +public: + microtune_eval_board (int which_pp = 1); + ~microtune_eval_board (); + + //! is the eval board present? + bool board_present_p (); + +private: + //! \returns true iff successful + virtual bool i2c_write (int addr, const unsigned char *buf, int nbytes); + + //! \returns number of bytes read or -1 if error + virtual int i2c_read (int addr, unsigned char *buf, int max_bytes); + + ppio *m_ppio; + i2cio *m_i2cio; + i2c *m_i2c; +}; + + +#endif /* _MICROTUNE_EVAL_BOARD_H_ */ diff --git a/microtune/microtune_eval_board_defs.h b/microtune/microtune_eval_board_defs.h new file mode 100644 index 000000000..5245fd5ce --- /dev/null +++ b/microtune/microtune_eval_board_defs.h @@ -0,0 +1,71 @@ +/* -*-C-*- +******************************************************************************* +* +* File: microtune_eval_board_defs.h +* Description: defines for parallel port control of eval board +* +******************************************************************************* +*/ + +/* + * Copyright 2001 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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, or (at your option) + * any later version. + * + * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _MICROTUNE_EVAL_BOARD_DEFS_H_ +#define _MICROTUNE_EVAL_BOARD_DEFS_H_ + +/* + * The Microtune 4937DI5 cable modem tuner eval board is controlled + * by bit banging the PC parallel port. This file defines the relevant + * bits. + * + * The parallel port has an 8 bit data port (output), + * an 8 bit control port (output) and + * an 8 bit status port (input). + * + * Not all bits of the control and status ports may be arbitrarily used. + */ + + +// parallel port data port constants (output) + +static const int UT_DP_TX_SDA = 0x01; // upstream control bus +static const int UT_DP_TX_SCL = 0x02; // upstream control bus +static const int UT_DP_TX_AS = 0x04; // upstream control bus +static const int UT_DP_TX_ENABLE = 0x08; // upstream h/w enable +// bits 4,5,6 not used +static const int UT_DP_TUNER_SDA_OUT = 0x80; // tuner i2c bus data + +// parallel port control port constants (output) + +static const int UT_CP_TUNER_SCL = 0x08; // tuner i2c bus clock +static const int UT_CP_MUST_BE_ZERO = 0xf0; // must be zero + +// parallel port status port constants (input) + +// bits 0,1,2 not used +static const int UT_SP_TUNER_SCL_LOOP_BACK= 0x08; // inverted SCL loop back +static const int UT_SP_SHOULD_BE_ZERO = 0x10; // reads as zero +static const int UT_SP_SHOULD_BE_ONE = 0x20; // reads as one +// bit 6 not used +static const int UT_SP_TUNER_SDA_IN = 0x80; + + +#endif /* _MICROTUNE_EVAL_BOARD_DEFS_H_ */ diff --git a/microtune/module_4937.c b/microtune/module_4937.c new file mode 100644 index 000000000..3b4f26176 --- /dev/null +++ b/microtune/module_4937.c @@ -0,0 +1,104 @@ +/* + * Hamlib microtune backend - 4937 file + * Copyright (c) 2003 by Stephane Fillod + * + * $Id: module_4937.c,v 1.1 2003-01-29 23:06:30 fillods Exp $ + * + * This library 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, 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 software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "microtune.h" + +/* + * Microtune 4937 rig capabilities. + * + * TODO: set_ptt, set_agc + */ + +#define M4937_FUNC RIG_FUNC_NONE +#define M4937_LEVEL RIG_LEVEL_NONE +#define M4937_PARM RIG_PARM_NONE + +#define M4937_MODES (RIG_MODE_WFM) /* FIXME: IF */ + +#define M4937_VFO RIG_VFO_A + +const struct rig_caps module_4937_caps = { + .rig_model = RIG_MODEL_MICROTUNE_4937, + .model_name = "4937 DI5 tuner module", + .mfg_name = "Microtune", + .version = "0.1", + .copyright = "GPL", + .status = RIG_STATUS_UNTESTED, + .rig_type = RIG_TYPE_TUNER, + .targetable_vfo = 0, + .ptt_type = RIG_PTT_RIG, + .dcd_type = RIG_DCD_NONE, + .port_type = RIG_PORT_NONE, /* FIXME */ + .has_get_func = M4937_FUNC, + .has_set_func = M4937_FUNC, + .has_get_level = M4937_LEVEL, + .has_set_level = RIG_LEVEL_SET(M4937_LEVEL), + .has_get_parm = M4937_PARM, + .has_set_parm = RIG_PARM_SET(M4937_PARM), + .chan_list = { + RIG_CHAN_END, + }, + .scan_ops = RIG_SCAN_NONE, + .vfo_ops = RIG_OP_NONE, + .transceive = RIG_TRN_OFF, + .attenuator = { RIG_DBLST_END, }, + .preamp = { RIG_DBLST_END, }, + .rx_range_list2 = { {.start=MHz(55),.end=MHz(860),.modes=M4937_MODES, + .low_power=-1,.high_power=-1,M4937_VFO}, + RIG_FRNG_END, }, + .tx_range_list2 = { {.start=MHz(5),.end=MHz(42),.modes=M4937_MODES, + .low_power=mW(1),.high_power=W(1),M4937_VFO}, /* FIXME: power */ + RIG_FRNG_END, }, + + /* minimum tuning step with a reference divider of 640 (see Advance data sheet) */ + .tuning_steps = { {M4937_MODES,kHz(50)}, + RIG_TS_END, + }, + .priv = NULL, /* priv */ + + .rig_init = module_4937_init, + .rig_cleanup = module_4937_cleanup, + .rig_open = module_4937_open, + .rig_close = module_4937_close, + + .set_freq = module_4937_set_freq, + .get_freq = module_4937_get_freq, + +}; + + +int initrigs_microtune(void *be_handle) +{ + rig_debug(RIG_DEBUG_VERBOSE, "microtune: _init called\n"); + + rig_register(&module_4937_caps); + + return RIG_OK; +} + diff --git a/microtune/ppio.cc b/microtune/ppio.cc new file mode 100644 index 000000000..7b51cfd7d --- /dev/null +++ b/microtune/ppio.cc @@ -0,0 +1,97 @@ +/* -*-C++-*- +******************************************************************************* +* +* File: ppio.cc +* Description: +* +******************************************************************************* +*/ + +/* + * Copyright 2001 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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, or (at your option) + * any later version. + * + * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "ppio.h" +#include +#include + + +const static int parallel_port_base[3] = { + 0x3bc, // lp0 used to be on monochome display adapter + 0x378, // lp1 most common + 0x278 // lp2 secondary +}; + +// These control port bits are active low. +// We toggle them so that this weirdness doesn't get get propagated +// through our interface. + +static int CP_ACTIVE_LOW_BITS = 0x0B; + +// These status port bits are active low. +// We toggle them so that this weirdness doesn't get get propagated +// through our interface. + +static int SP_ACTIVE_LOW_BITS = 0x80; + +ppio::ppio (int which) +{ + if (which < 0 || which > 2) + abort (); + + base = parallel_port_base[which]; + + // try to read ports. If we don't have the appropriate + // ioperm bits set, we'll segfault here. At least it's deterministic... + + inb (base + 0); + inb (base + 1); + inb (base + 2); +} + +void +ppio::write_data (unsigned char v) +{ + outb (v, base + 0); +} + +unsigned char +ppio::read_data () +{ + return inb (base + 0); +} + +void +ppio::write_control (unsigned char v) +{ + outb (v ^ CP_ACTIVE_LOW_BITS, base + 2); +} + +unsigned char +ppio::read_control () +{ + return inb (base + 2) ^ CP_ACTIVE_LOW_BITS; +} + +unsigned char +ppio::read_status () +{ + return inb (base + 1) ^ SP_ACTIVE_LOW_BITS; +} diff --git a/microtune/ppio.h b/microtune/ppio.h new file mode 100644 index 000000000..a00b63e4e --- /dev/null +++ b/microtune/ppio.h @@ -0,0 +1,53 @@ +/* -*-C++-*- +******************************************************************************* +* +* File: ppio.h +* Description: +* +******************************************************************************* +*/ + +/* + * Copyright 2001 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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, or (at your option) + * any later version. + * + * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _PPIO_H_ +#define _PPIO_H_ + +/*! \brief provide low level access to parallel port bits */ + +class ppio { + public: + //! \p which specifies the parallel port to use [0,2] + ppio (int a_which = 1); + virtual ~ppio () {}; + + virtual void write_data (unsigned char v); + virtual unsigned char read_data (); + virtual void write_control (unsigned char v); + virtual unsigned char read_control (); + virtual unsigned char read_status (); + + private: + int base; +}; + + +#endif /* _PPIO_H_ */