mirror of
https://github.com/Hamlib/Hamlib.git
synced 2024-09-21 18:37:18 +00:00
* upstream upgrade from GNU Radio project (0.8cvs current 030928)
* added AGC level set * no more raw parallel port access -> use portable Hamlib // primitives git-svn-id: https://hamlib.svn.sourceforge.net/svnroot/hamlib/trunk@1541 7ae35d74-ebe9-4afe-98af-79ac388436b8
This commit is contained in:
parent
94e9f06973
commit
5556fe9a6d
@ -21,7 +21,6 @@
|
|||||||
MTSRCLIST = module_4937.c
|
MTSRCLIST = module_4937.c
|
||||||
|
|
||||||
GRIO_SOURCES = \
|
GRIO_SOURCES = \
|
||||||
ppio.cc \
|
|
||||||
i2cio.cc \
|
i2cio.cc \
|
||||||
i2cio_pp.cc \
|
i2cio_pp.cc \
|
||||||
i2c.cc \
|
i2c.cc \
|
||||||
@ -40,10 +39,5 @@ noinst_HEADERS = \
|
|||||||
microtune_4937.h \
|
microtune_4937.h \
|
||||||
microtune_eval_board.h \
|
microtune_eval_board.h \
|
||||||
microtune_eval_board_defs.h \
|
microtune_eval_board_defs.h \
|
||||||
ppio.h \
|
|
||||||
microtune.h
|
microtune.h
|
||||||
|
|
||||||
check_PROGRAMS = givelp1
|
|
||||||
|
|
||||||
givelp1_SOURCES = givelp1.cc
|
|
||||||
|
|
||||||
|
@ -1,111 +0,0 @@
|
|||||||
/* -*-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 <sys/io.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
}
|
|
@ -30,10 +30,14 @@
|
|||||||
|
|
||||||
#include "i2c.h"
|
#include "i2c.h"
|
||||||
|
|
||||||
i2c::i2c (i2cio *a_io)
|
i2c::i2c (i2cio *io)
|
||||||
{
|
{
|
||||||
io = a_io;
|
d_io = io;
|
||||||
|
d_io->lock ();
|
||||||
|
|
||||||
stop (); // get bus in known state
|
stop (); // get bus in known state
|
||||||
|
|
||||||
|
d_io->unlock ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -113,6 +117,7 @@ i2c::write (int addr, const unsigned char *buf, int nbytes)
|
|||||||
{
|
{
|
||||||
bool ok = true;
|
bool ok = true;
|
||||||
|
|
||||||
|
d_io->lock ();
|
||||||
start ();
|
start ();
|
||||||
ok = write_byte ((addr << 1) | 0); // addr plus "read opcode"
|
ok = write_byte ((addr << 1) | 0); // addr plus "read opcode"
|
||||||
|
|
||||||
@ -120,6 +125,7 @@ i2c::write (int addr, const unsigned char *buf, int nbytes)
|
|||||||
ok &= write_byte (buf[i]);
|
ok &= write_byte (buf[i]);
|
||||||
|
|
||||||
stop ();
|
stop ();
|
||||||
|
d_io->unlock ();
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,6 +137,10 @@ i2c::write (int addr, const unsigned char *buf, int nbytes)
|
|||||||
int
|
int
|
||||||
i2c::read (int addr, unsigned char *buf, int max_bytes)
|
i2c::read (int addr, unsigned char *buf, int max_bytes)
|
||||||
{
|
{
|
||||||
|
d_io->lock ();
|
||||||
|
|
||||||
// FIXME
|
// FIXME
|
||||||
|
|
||||||
|
d_io->unlock ();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ class i2c {
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
/*! i2c does not control lifetime of a_io */
|
/*! i2c does not control lifetime of a_io */
|
||||||
i2c (i2cio *a_io);
|
i2c (i2cio *io);
|
||||||
~i2c () {};
|
~i2c () {};
|
||||||
|
|
||||||
//! \returns true iff successful
|
//! \returns true iff successful
|
||||||
@ -56,11 +56,11 @@ private:
|
|||||||
void write_bit (bool bit);
|
void write_bit (bool bit);
|
||||||
bool write_byte (char byte);
|
bool write_byte (char byte);
|
||||||
|
|
||||||
void set_sda (bool bit) { io->set_sda (bit); }
|
void set_sda (bool bit) { d_io->set_sda (bit); }
|
||||||
void set_scl (bool bit) { io->set_scl (bit); }
|
void set_scl (bool bit) { d_io->set_scl (bit); }
|
||||||
bool get_sda () { return io->get_sda (); }
|
bool get_sda () { return d_io->get_sda (); }
|
||||||
|
|
||||||
i2cio *io;
|
i2cio *d_io;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _I2C_H_ */
|
#endif /* _I2C_H_ */
|
||||||
|
@ -57,6 +57,9 @@ class i2cio {
|
|||||||
int get_udelay_sda_lo () { return udelay_sda_lo; }
|
int get_udelay_sda_lo () { return udelay_sda_lo; }
|
||||||
int get_udelay_sda_hi () { return udelay_sda_hi; }
|
int get_udelay_sda_hi () { return udelay_sda_hi; }
|
||||||
|
|
||||||
|
virtual void lock () = 0;
|
||||||
|
virtual void unlock () = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int udelay_scl_lo;
|
int udelay_scl_lo;
|
||||||
int udelay_scl_hi;
|
int udelay_scl_hi;
|
||||||
|
@ -31,45 +31,64 @@
|
|||||||
#include "i2cio_pp.h"
|
#include "i2cio_pp.h"
|
||||||
#include "microtune_eval_board_defs.h"
|
#include "microtune_eval_board_defs.h"
|
||||||
|
|
||||||
i2cio_pp::i2cio_pp (ppio *a_pp)
|
i2cio_pp::i2cio_pp (port_t *pp)
|
||||||
{
|
{
|
||||||
pp = a_pp;
|
unsigned char r;
|
||||||
pp->write_control (pp->read_control () & ~UT_CP_MUST_BE_ZERO); // output, no interrupts
|
d_pp = pp;
|
||||||
|
par_lock (d_pp);
|
||||||
|
par_read_control (d_pp, &r);
|
||||||
|
par_write_control (d_pp, r & ~UT_CP_MUST_BE_ZERO); // output, no interrupts
|
||||||
|
par_unlock (d_pp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
i2cio_pp::set_scl (bool state)
|
i2cio_pp::set_scl (bool state)
|
||||||
{
|
{
|
||||||
int r = pp->read_control();
|
unsigned char r;
|
||||||
|
par_read_control(d_pp, &r);
|
||||||
|
|
||||||
if (!state){ // active low
|
if (!state){ // active low
|
||||||
pp->write_control (r | UT_CP_TUNER_SCL);
|
par_write_control (d_pp, r | UT_CP_TUNER_SCL);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pp->write_control (r & ~UT_CP_TUNER_SCL);
|
par_write_control (d_pp, r & ~UT_CP_TUNER_SCL);
|
||||||
}
|
}
|
||||||
pp->read_control (); // use for 1us delay
|
par_read_control (d_pp, &r); // use for 1us delay
|
||||||
pp->read_control (); // use for 1us delay
|
par_read_control (d_pp, &r); // use for 1us delay
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
i2cio_pp::set_sda (bool state)
|
i2cio_pp::set_sda (bool state)
|
||||||
{
|
{
|
||||||
int r = pp->read_data ();
|
unsigned char r;
|
||||||
|
par_read_data (d_pp, &r);
|
||||||
|
|
||||||
if (!state){ // active low
|
if (!state){ // active low
|
||||||
pp->write_data (r | UT_DP_TUNER_SDA_OUT);
|
par_write_data (d_pp, r | UT_DP_TUNER_SDA_OUT);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pp->write_data (r & ~UT_DP_TUNER_SDA_OUT);
|
par_write_data (d_pp, r & ~UT_DP_TUNER_SDA_OUT);
|
||||||
}
|
}
|
||||||
pp->read_data (); // use for 1us delay
|
par_read_data (d_pp, &r); // use for 1us delay
|
||||||
pp->read_data (); // use for 1us delay
|
par_read_data (d_pp, &r); // use for 1us delay
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
i2cio_pp::get_sda ()
|
i2cio_pp::get_sda ()
|
||||||
{
|
{
|
||||||
int r = pp->read_status ();
|
unsigned char r;
|
||||||
|
par_read_status (d_pp, &r);
|
||||||
return (r & UT_SP_TUNER_SDA_IN) == 0; // eval board has an inverter on it
|
return (r & UT_SP_TUNER_SDA_IN) == 0; // eval board has an inverter on it
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
i2cio_pp::lock ()
|
||||||
|
{
|
||||||
|
par_lock (d_pp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
i2cio_pp::unlock ()
|
||||||
|
{
|
||||||
|
par_unlock (d_pp);
|
||||||
|
}
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
#define _I2CIO_PP_H_
|
#define _I2CIO_PP_H_
|
||||||
|
|
||||||
#include "i2cio.h"
|
#include "i2cio.h"
|
||||||
#include "ppio.h"
|
#include "serial.h"
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief concrete class that implements low level i/o for i2c bus using parallel port
|
* \brief concrete class that implements low level i/o for i2c bus using parallel port
|
||||||
@ -40,14 +40,17 @@
|
|||||||
class i2cio_pp : public i2cio {
|
class i2cio_pp : public i2cio {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
i2cio_pp (ppio *a_pp);
|
i2cio_pp (port_t *a_pp);
|
||||||
|
|
||||||
virtual void set_scl (bool state);
|
virtual void set_scl (bool state);
|
||||||
virtual void set_sda (bool state);
|
virtual void set_sda (bool state);
|
||||||
virtual bool get_sda ();
|
virtual bool get_sda ();
|
||||||
|
|
||||||
|
virtual void lock ();
|
||||||
|
virtual void unlock ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ppio *pp;
|
port_t *d_pp;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _I2CIO_PP_H_ */
|
#endif /* _I2CIO_PP_H_ */
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* Hamlib Microtune backend - main file
|
* Hamlib Microtune backend - main file
|
||||||
* Copyright (c) 2003 by Stephane Fillod
|
* Copyright (c) 2003 by Stephane Fillod
|
||||||
*
|
*
|
||||||
* $Id: microtune.cc,v 1.1 2003-01-29 23:06:30 fillods Exp $
|
* $Id: microtune.cc,v 1.2 2003-09-28 15:28:37 fillods Exp $
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -58,7 +58,6 @@ struct module_4937_priv_data {
|
|||||||
int module_4937_init(RIG *rig)
|
int module_4937_init(RIG *rig)
|
||||||
{
|
{
|
||||||
struct module_4937_priv_data *priv;
|
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));
|
priv = (struct module_4937_priv_data*)malloc(sizeof(struct module_4937_priv_data));
|
||||||
if (!priv) {
|
if (!priv) {
|
||||||
@ -68,17 +67,6 @@ int module_4937_init(RIG *rig)
|
|||||||
|
|
||||||
priv->actual_freq = RIG_FREQ_NONE;
|
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;
|
rig->state.priv = (void*)priv;
|
||||||
|
|
||||||
return RIG_OK;
|
return RIG_OK;
|
||||||
@ -88,8 +76,14 @@ int module_4937_open(RIG *rig)
|
|||||||
{
|
{
|
||||||
struct module_4937_priv_data *priv = (struct module_4937_priv_data *)rig->state.priv;
|
struct module_4937_priv_data *priv = (struct module_4937_priv_data *)rig->state.priv;
|
||||||
|
|
||||||
if (!priv->board->board_present_p()) {
|
priv->board = new microtune_eval_board(&rig->state.rigport);
|
||||||
|
if (!priv->board) {
|
||||||
|
return -RIG_ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 && !priv->board->board_present_p()) {
|
||||||
rig_debug(RIG_DEBUG_WARN, "microtune: eval board is NOT present\n");
|
rig_debug(RIG_DEBUG_WARN, "microtune: eval board is NOT present\n");
|
||||||
|
delete priv->board;
|
||||||
return -RIG_EPROTO;
|
return -RIG_EPROTO;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,7 +92,9 @@ int module_4937_open(RIG *rig)
|
|||||||
|
|
||||||
int module_4937_close(RIG *rig)
|
int module_4937_close(RIG *rig)
|
||||||
{
|
{
|
||||||
/* place holder.. */
|
struct module_4937_priv_data *priv = (struct module_4937_priv_data *)rig->state.priv;
|
||||||
|
|
||||||
|
delete priv->board;
|
||||||
|
|
||||||
return RIG_OK;
|
return RIG_OK;
|
||||||
}
|
}
|
||||||
@ -108,7 +104,6 @@ int module_4937_cleanup(RIG *rig)
|
|||||||
struct module_4937_priv_data *priv = (struct module_4937_priv_data *)rig->state.priv;
|
struct module_4937_priv_data *priv = (struct module_4937_priv_data *)rig->state.priv;
|
||||||
|
|
||||||
if (priv) {
|
if (priv) {
|
||||||
delete priv->board;
|
|
||||||
free(priv);
|
free(priv);
|
||||||
}
|
}
|
||||||
rig->state.priv = NULL;
|
rig->state.priv = NULL;
|
||||||
@ -145,3 +140,21 @@ int module_4937_get_freq(RIG *rig, vfo_t vfo, freq_t *freq)
|
|||||||
return RIG_OK;
|
return RIG_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Assumes rig!=NULL, rig->state.priv!=NULL
|
||||||
|
*/
|
||||||
|
int module_4937_set_ext_level(RIG *rig, vfo_t vfo, token_t token, value_t val)
|
||||||
|
{
|
||||||
|
struct module_4937_priv_data *priv = (struct module_4937_priv_data *)rig->state.priv;
|
||||||
|
|
||||||
|
switch(token) {
|
||||||
|
case TOK_AGCGAIN:
|
||||||
|
priv->board->set_AGC(val.f*1000);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -RIG_EINVAL;
|
||||||
|
}
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* Hamlib Microtune backend - main header
|
* Hamlib Microtune backend - main header
|
||||||
* Copyright (c) 2001-2003 by Stephane Fillod
|
* Copyright (c) 2001-2003 by Stephane Fillod
|
||||||
*
|
*
|
||||||
* $Id: microtune.h,v 1.2 2003-04-16 22:30:41 fillods Exp $
|
* $Id: microtune.h,v 1.3 2003-09-28 15:28:37 fillods Exp $
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -25,15 +25,20 @@
|
|||||||
#define _MICRTOUNE_H 1
|
#define _MICRTOUNE_H 1
|
||||||
|
|
||||||
#include <hamlib/rig.h>
|
#include <hamlib/rig.h>
|
||||||
|
#include <token.h>
|
||||||
|
|
||||||
__BEGIN_DECLS
|
__BEGIN_DECLS
|
||||||
|
|
||||||
|
#define TOK_AGCGAIN TOKEN_BACKEND(1)
|
||||||
|
|
||||||
|
|
||||||
int module_4937_init(RIG *rig);
|
int module_4937_init(RIG *rig);
|
||||||
int module_4937_cleanup(RIG *rig);
|
int module_4937_cleanup(RIG *rig);
|
||||||
int module_4937_open(RIG *rig);
|
int module_4937_open(RIG *rig);
|
||||||
int module_4937_close(RIG *rig);
|
int module_4937_close(RIG *rig);
|
||||||
int module_4937_set_freq(RIG *rig, vfo_t vfo, freq_t freq);
|
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);
|
int module_4937_get_freq(RIG *rig, vfo_t vfo, freq_t *freq);
|
||||||
|
int module_4937_set_ext_level(RIG *rig, vfo_t vfo, token_t token, value_t val);
|
||||||
extern const struct rig_caps module_4937_caps;
|
extern const struct rig_caps module_4937_caps;
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,14 +1,6 @@
|
|||||||
/* -*-C++-*-
|
/* -*- c++-*- */
|
||||||
*******************************************************************************
|
|
||||||
*
|
|
||||||
* File: microtune_4937.cc
|
|
||||||
* Description:
|
|
||||||
*
|
|
||||||
*******************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2001 Free Software Foundation, Inc.
|
* Copyright 2001,2003 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* This file is part of GNU Radio
|
* This file is part of GNU Radio
|
||||||
*
|
*
|
||||||
@ -39,6 +31,8 @@ static const double first_IF = 43.75e6;
|
|||||||
static const double VHF_High_takeover = 158e6;
|
static const double VHF_High_takeover = 158e6;
|
||||||
static const double UHF_takeover = 464e6;
|
static const double UHF_takeover = 464e6;
|
||||||
|
|
||||||
|
static int PLL_I2C_ADDR = 0x61;
|
||||||
|
|
||||||
static unsigned char
|
static unsigned char
|
||||||
control_byte_1 (bool fast_tuning_p, int reference_divisor)
|
control_byte_1 (bool fast_tuning_p, int reference_divisor)
|
||||||
{
|
{
|
||||||
@ -78,6 +72,12 @@ control_byte_2 (double target_freq, bool shutdown_tx_PGA)
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
microtune_4937::microtune_4937 ()
|
||||||
|
{
|
||||||
|
d_reference_divider = 640;
|
||||||
|
d_fast_tuning_p = false;
|
||||||
|
}
|
||||||
|
|
||||||
microtune_4937::~microtune_4937 (){}
|
microtune_4937::~microtune_4937 (){}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -95,7 +95,7 @@ microtune_4937::set_RF_freq (double target_freq, double *p_actual_freq)
|
|||||||
|
|
||||||
double target_f_osc = target_freq + first_IF;
|
double target_f_osc = target_freq + first_IF;
|
||||||
|
|
||||||
double f_ref = 4e6 / reference_divider;
|
double f_ref = 4e6 / d_reference_divider;
|
||||||
|
|
||||||
// f_osc = f_ref * 8 * divisor
|
// f_osc = f_ref * 8 * divisor
|
||||||
// divisor = f_osc / (f_ref * 8)
|
// divisor = f_osc / (f_ref * 8)
|
||||||
@ -110,7 +110,7 @@ microtune_4937::set_RF_freq (double target_freq, double *p_actual_freq)
|
|||||||
|
|
||||||
buf[0] = (divisor >> 8) & 0xff; // DB1
|
buf[0] = (divisor >> 8) & 0xff; // DB1
|
||||||
buf[1] = divisor & 0xff; // DB2
|
buf[1] = divisor & 0xff; // DB2
|
||||||
buf[2] = control_byte_1 (fast_tuning_p, reference_divider);
|
buf[2] = control_byte_1 (d_fast_tuning_p, d_reference_divider);
|
||||||
buf[3] = control_byte_2 (target_freq, true);
|
buf[3] = control_byte_2 (target_freq, true);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
@ -118,7 +118,18 @@ microtune_4937::set_RF_freq (double target_freq, double *p_actual_freq)
|
|||||||
target_freq/1e6, actual_freq/1e6, buf[0], buf[1], buf[2], buf[3]);
|
target_freq/1e6, actual_freq/1e6, buf[0], buf[1], buf[2], buf[3]);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return i2c_write (i2c_addr, buf, 4);
|
return i2c_write (PLL_I2C_ADDR, buf, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
double
|
||||||
|
microtune_4937::set_RF_freq (double target_freq)
|
||||||
|
{
|
||||||
|
double actual_freq = 0.0;
|
||||||
|
|
||||||
|
if (set_RF_freq (target_freq, &actual_freq))
|
||||||
|
return actual_freq;
|
||||||
|
|
||||||
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -131,11 +142,11 @@ microtune_4937::pll_locked_p ()
|
|||||||
// FIXME
|
// FIXME
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \returns the output frequency of the tuner in Hz.
|
* \returns the output frequency of the tuner in Hz.
|
||||||
*/
|
*/
|
||||||
double
|
double
|
||||||
microtune_4937::get_output_freq ()
|
microtune_4937::get_output_freq ()
|
||||||
{
|
{
|
||||||
return 5.75e6; // 3x7702
|
return 5.75e6; // 3x7702
|
||||||
|
@ -1,14 +1,6 @@
|
|||||||
/* -*-C++-*-
|
/* -*- c++ -*- */
|
||||||
*******************************************************************************
|
|
||||||
*
|
|
||||||
* File: microtune_4937.h
|
|
||||||
* Description:
|
|
||||||
*
|
|
||||||
*******************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2001 Free Software Foundation, Inc.
|
* Copyright 2001,2003 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* This file is part of GNU Radio
|
* This file is part of GNU Radio
|
||||||
*
|
*
|
||||||
@ -36,8 +28,7 @@
|
|||||||
*/
|
*/
|
||||||
class microtune_4937 {
|
class microtune_4937 {
|
||||||
public:
|
public:
|
||||||
microtune_4937 () :
|
microtune_4937 ();
|
||||||
i2c_addr (0xC2/2), reference_divider(640), fast_tuning_p (false) {};
|
|
||||||
|
|
||||||
virtual ~microtune_4937 ();
|
virtual ~microtune_4937 ();
|
||||||
|
|
||||||
@ -51,13 +42,16 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool set_RF_freq (double freq, double *actual_freq);
|
bool set_RF_freq (double freq, double *actual_freq);
|
||||||
|
|
||||||
|
// returns actual freq or 0 if error (easier interface for SWIG)
|
||||||
|
double set_RF_freq (double freq);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \returns true iff PLL is locked
|
* \returns true iff PLL is locked
|
||||||
*/
|
*/
|
||||||
bool pll_locked_p ();
|
bool pll_locked_p ();
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \returns the output frequency of the tuner in Hz.
|
* \returns the output frequency (IF center freq) of the tuner in Hz.
|
||||||
*/
|
*/
|
||||||
double get_output_freq ();
|
double get_output_freq ();
|
||||||
|
|
||||||
@ -68,12 +62,10 @@ public:
|
|||||||
//! \returns number of bytes read or -1 if error
|
//! \returns number of bytes read or -1 if error
|
||||||
virtual int i2c_read (int addr, unsigned char *buf, int max_bytes) = 0;
|
virtual int i2c_read (int addr, unsigned char *buf, int max_bytes) = 0;
|
||||||
|
|
||||||
int i2c_addr;
|
int d_reference_divider;
|
||||||
int reference_divider;
|
bool d_fast_tuning_p; /* if set, higher charge pump current:
|
||||||
bool fast_tuning_p; /* if set, higher charge pump current:
|
|
||||||
faster tuning, worse phase noise
|
faster tuning, worse phase noise
|
||||||
for distance < 10kHz to the carrier */
|
for distance < 10kHz to the carrier */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif /* _MICROTUNE_4937_H_ */
|
#endif /* _MICROTUNE_4937_H_ */
|
||||||
|
@ -30,21 +30,27 @@
|
|||||||
|
|
||||||
#include "microtune_eval_board.h"
|
#include "microtune_eval_board.h"
|
||||||
#include "microtune_eval_board_defs.h"
|
#include "microtune_eval_board_defs.h"
|
||||||
#include "ppio.h"
|
#include "serial.h"
|
||||||
#include "i2cio_pp.h"
|
#include "i2cio_pp.h"
|
||||||
#include "i2c.h"
|
#include "i2c.h"
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
microtune_eval_board::microtune_eval_board (int which_pp)
|
static int AGC_DAC_I2C_ADDR = 0x2C;
|
||||||
|
|
||||||
|
microtune_eval_board::microtune_eval_board (port_t *port)
|
||||||
{
|
{
|
||||||
m_ppio = new ppio (which_pp);
|
m_ppio = port;
|
||||||
m_i2cio = new i2cio_pp (m_ppio);
|
m_i2cio = new i2cio_pp (m_ppio);
|
||||||
m_i2c = new i2c (m_i2cio);
|
m_i2c = new i2c (m_i2cio);
|
||||||
|
|
||||||
// disable upstream amplifier
|
// disable upstream amplifier
|
||||||
int t = m_ppio->read_data ();
|
par_lock (m_ppio);
|
||||||
|
unsigned char t;
|
||||||
|
par_read_data (m_ppio, &t);
|
||||||
t &= ~(UT_DP_TX_ENABLE | UT_DP_TX_SDA | UT_DP_TX_SCL);
|
t &= ~(UT_DP_TX_ENABLE | UT_DP_TX_SDA | UT_DP_TX_SCL);
|
||||||
t |= UT_DP_TX_AS;
|
t |= UT_DP_TX_AS;
|
||||||
m_ppio->write_data (t);
|
par_write_data (m_ppio, t);
|
||||||
|
par_unlock (m_ppio);
|
||||||
}
|
}
|
||||||
|
|
||||||
microtune_eval_board::~microtune_eval_board ()
|
microtune_eval_board::~microtune_eval_board ()
|
||||||
@ -59,14 +65,19 @@ microtune_eval_board::~microtune_eval_board ()
|
|||||||
bool
|
bool
|
||||||
microtune_eval_board::board_present_p ()
|
microtune_eval_board::board_present_p ()
|
||||||
{
|
{
|
||||||
int t = m_ppio->read_status ();
|
bool result = true;
|
||||||
|
par_lock (m_ppio);
|
||||||
|
|
||||||
|
unsigned char t;
|
||||||
|
par_read_status (m_ppio, &t);
|
||||||
if ((t & UT_SP_SHOULD_BE_ZERO) != 0
|
if ((t & UT_SP_SHOULD_BE_ZERO) != 0
|
||||||
|| (t & UT_SP_SHOULD_BE_ONE) != UT_SP_SHOULD_BE_ONE)
|
|| (t & UT_SP_SHOULD_BE_ONE) != UT_SP_SHOULD_BE_ONE)
|
||||||
return false;
|
result = false;
|
||||||
|
|
||||||
// could also see if SCL is looped back or not, but that seems like overkill
|
// could also see if SCL is looped back or not, but that seems like overkill
|
||||||
|
|
||||||
return true;
|
par_unlock (m_ppio);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns true iff successful
|
// returns true iff successful
|
||||||
@ -82,3 +93,103 @@ microtune_eval_board::i2c_read (int addr, unsigned char *buf, int max_bytes)
|
|||||||
{
|
{
|
||||||
return m_i2c->read (addr, buf, max_bytes);
|
return m_i2c->read (addr, buf, max_bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ----------------------------------------------------------------
|
||||||
|
* AGC stuff
|
||||||
|
*
|
||||||
|
* We're using a MAX518 8-bit 5V dual dac for setting the AGC's
|
||||||
|
* ----------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
microtune_eval_board::write_dac (int which, int value)
|
||||||
|
{
|
||||||
|
unsigned char cmd[2];
|
||||||
|
cmd[0] = which & 1;
|
||||||
|
cmd[1] = value;
|
||||||
|
i2c_write (AGC_DAC_I2C_ADDR, cmd, sizeof (cmd));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
microtune_eval_board::write_both_dacs (int value0, int value1)
|
||||||
|
{
|
||||||
|
unsigned char cmd[4];
|
||||||
|
cmd[0] = 0;
|
||||||
|
cmd[1] = value0;
|
||||||
|
cmd[2] = 1;
|
||||||
|
cmd[3] = value1;
|
||||||
|
i2c_write (AGC_DAC_I2C_ADDR, cmd, sizeof (cmd));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int scale_volts (float volts)
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
n = (int) rint (volts * (256 / 5.0));
|
||||||
|
if (n < 0)
|
||||||
|
n = 0;
|
||||||
|
if (n > 255)
|
||||||
|
n = 255;
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
microtune_eval_board::set_RF_AGC_voltage (float volts)
|
||||||
|
{
|
||||||
|
write_dac (0, scale_volts (volts));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
microtune_eval_board::set_IF_AGC_voltage (float volts)
|
||||||
|
{
|
||||||
|
write_dac (1, scale_volts (volts));
|
||||||
|
}
|
||||||
|
|
||||||
|
static const float RF_MIN_V = 1.5; // RF AGC control voltages
|
||||||
|
static const float RF_MAX_V = 4.0;
|
||||||
|
static const float IF_MIN_V = 2.0; // IF AGC control voltages
|
||||||
|
static const float IF_MAX_V = 4.0;
|
||||||
|
|
||||||
|
static const float MIN_AGC = 0; // bottom of synthetic range
|
||||||
|
static const float MAX_AGC = 1000; // top of synthetic range
|
||||||
|
|
||||||
|
static const float CUTOVER_POINT = 667;
|
||||||
|
|
||||||
|
|
||||||
|
// linear is in the range MIN_AGC to MAX_AGC
|
||||||
|
|
||||||
|
static float
|
||||||
|
linear_to_RF_AGC_voltage (float linear)
|
||||||
|
{
|
||||||
|
if (linear >= CUTOVER_POINT)
|
||||||
|
return RF_MAX_V;
|
||||||
|
|
||||||
|
float slope = (RF_MAX_V - RF_MIN_V) / CUTOVER_POINT;
|
||||||
|
return RF_MIN_V + linear * slope;
|
||||||
|
}
|
||||||
|
|
||||||
|
static float
|
||||||
|
linear_to_IF_AGC_voltage (float linear)
|
||||||
|
{
|
||||||
|
if (linear < CUTOVER_POINT)
|
||||||
|
return IF_MIN_V;
|
||||||
|
|
||||||
|
float slope = (IF_MAX_V - IF_MIN_V) / (MAX_AGC - CUTOVER_POINT);
|
||||||
|
return IF_MIN_V + (linear - CUTOVER_POINT) * slope;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
microtune_eval_board::set_AGC (float v)
|
||||||
|
{
|
||||||
|
if (v < MIN_AGC)
|
||||||
|
v = MIN_AGC;
|
||||||
|
|
||||||
|
if (v > MAX_AGC)
|
||||||
|
v = MAX_AGC;
|
||||||
|
|
||||||
|
float rf_agc_voltage = linear_to_RF_AGC_voltage (v);
|
||||||
|
float if_agc_voltage = linear_to_IF_AGC_voltage (v);
|
||||||
|
|
||||||
|
set_RF_AGC_voltage (rf_agc_voltage);
|
||||||
|
set_IF_AGC_voltage (if_agc_voltage);
|
||||||
|
}
|
||||||
|
@ -32,8 +32,8 @@
|
|||||||
#define _MICROTUNE_EVAL_BOARD_H_
|
#define _MICROTUNE_EVAL_BOARD_H_
|
||||||
|
|
||||||
#include "microtune_4937.h"
|
#include "microtune_4937.h"
|
||||||
|
#include "serial.h"
|
||||||
|
|
||||||
class ppio;
|
|
||||||
class i2cio;
|
class i2cio;
|
||||||
class i2c;
|
class i2c;
|
||||||
|
|
||||||
@ -42,12 +42,28 @@ class i2c;
|
|||||||
*/
|
*/
|
||||||
class microtune_eval_board : public microtune_4937 {
|
class microtune_eval_board : public microtune_4937 {
|
||||||
public:
|
public:
|
||||||
microtune_eval_board (int which_pp = 1);
|
microtune_eval_board (port_t *port);
|
||||||
~microtune_eval_board ();
|
~microtune_eval_board ();
|
||||||
|
|
||||||
//! is the eval board present?
|
//! is the eval board present?
|
||||||
bool board_present_p ();
|
bool board_present_p ();
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief set RF and IF AGC control voltages ([0, 5] volts)
|
||||||
|
*/
|
||||||
|
void set_RF_AGC_voltage (float volts);
|
||||||
|
void set_IF_AGC_voltage (float volts);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief set RF and IF AGC levels together (scale [0, 1000])
|
||||||
|
*
|
||||||
|
* This provides a simple linear interface for adjusting both
|
||||||
|
* the RF and IF gain in consort. This is the easy to use interface.
|
||||||
|
* 0 corresponds to minimum gain. 1000 corresponds to maximum gain.
|
||||||
|
*/
|
||||||
|
void set_AGC (float value_0_1000);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//! \returns true iff successful
|
//! \returns true iff successful
|
||||||
virtual bool i2c_write (int addr, const unsigned char *buf, int nbytes);
|
virtual bool i2c_write (int addr, const unsigned char *buf, int nbytes);
|
||||||
@ -55,7 +71,10 @@ private:
|
|||||||
//! \returns number of bytes read or -1 if error
|
//! \returns number of bytes read or -1 if error
|
||||||
virtual int i2c_read (int addr, unsigned char *buf, int max_bytes);
|
virtual int i2c_read (int addr, unsigned char *buf, int max_bytes);
|
||||||
|
|
||||||
ppio *m_ppio;
|
void write_dac (int which, int value);
|
||||||
|
void write_both_dacs (int val0, int val1);
|
||||||
|
|
||||||
|
port_t *m_ppio;
|
||||||
i2cio *m_i2cio;
|
i2cio *m_i2cio;
|
||||||
i2c *m_i2c;
|
i2c *m_i2c;
|
||||||
};
|
};
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* Hamlib microtune backend - 4937 file
|
* Hamlib microtune backend - 4937 file
|
||||||
* Copyright (c) 2003 by Stephane Fillod
|
* Copyright (c) 2003 by Stephane Fillod
|
||||||
*
|
*
|
||||||
* $Id: module_4937.c,v 1.2 2003-04-16 22:30:41 fillods Exp $
|
* $Id: module_4937.c,v 1.3 2003-09-28 15:28:37 fillods Exp $
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -33,29 +33,37 @@
|
|||||||
/*
|
/*
|
||||||
* Microtune 4937 rig capabilities.
|
* Microtune 4937 rig capabilities.
|
||||||
*
|
*
|
||||||
* TODO: set_ptt, set_agc
|
* TODO: set_ptt
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define M4937_FUNC RIG_FUNC_NONE
|
#define M4937_FUNC RIG_FUNC_NONE
|
||||||
#define M4937_LEVEL RIG_LEVEL_NONE
|
#define M4937_LEVEL RIG_LEVEL_NONE
|
||||||
#define M4937_PARM RIG_PARM_NONE
|
#define M4937_PARM RIG_PARM_NONE
|
||||||
|
|
||||||
#define M4937_MODES (RIG_MODE_WFM) /* FIXME: IF */
|
#define M4937_MODES (RIG_MODE_NONE) /* FIXME: IF */
|
||||||
|
|
||||||
#define M4937_VFO RIG_VFO_A
|
#define M4937_VFO RIG_VFO_A
|
||||||
|
|
||||||
|
static const struct confparams module_4937_ext_parms[] = {
|
||||||
|
{ TOK_AGCGAIN, "agcgain", "AGC gain level", "RF and IF AGC levels",
|
||||||
|
NULL, RIG_CONF_NUMERIC, { .n = { 0, 1, .001 } }
|
||||||
|
},
|
||||||
|
{ RIG_CONF_END, NULL, }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
const struct rig_caps module_4937_caps = {
|
const struct rig_caps module_4937_caps = {
|
||||||
.rig_model = RIG_MODEL_MICROTUNE_4937,
|
.rig_model = RIG_MODEL_MICROTUNE_4937,
|
||||||
.model_name = "4937 DI5 tuner module",
|
.model_name = "4937 DI5 tuner module",
|
||||||
.mfg_name = "Microtune",
|
.mfg_name = "Microtune",
|
||||||
.version = "0.1",
|
.version = "0.2",
|
||||||
.copyright = "GPL",
|
.copyright = "GPL",
|
||||||
.status = RIG_STATUS_UNTESTED,
|
.status = RIG_STATUS_UNTESTED,
|
||||||
.rig_type = RIG_TYPE_TUNER,
|
.rig_type = RIG_TYPE_TUNER,
|
||||||
.targetable_vfo = 0,
|
.targetable_vfo = 0,
|
||||||
.ptt_type = RIG_PTT_RIG,
|
.ptt_type = RIG_PTT_RIG,
|
||||||
.dcd_type = RIG_DCD_NONE,
|
.dcd_type = RIG_DCD_NONE,
|
||||||
.port_type = RIG_PORT_NONE, /* FIXME */
|
.port_type = RIG_PORT_PARALLEL,
|
||||||
.has_get_func = M4937_FUNC,
|
.has_get_func = M4937_FUNC,
|
||||||
.has_set_func = M4937_FUNC,
|
.has_set_func = M4937_FUNC,
|
||||||
.has_get_level = M4937_LEVEL,
|
.has_get_level = M4937_LEVEL,
|
||||||
@ -81,6 +89,7 @@ const struct rig_caps module_4937_caps = {
|
|||||||
.tuning_steps = { {M4937_MODES,kHz(50)},
|
.tuning_steps = { {M4937_MODES,kHz(50)},
|
||||||
RIG_TS_END,
|
RIG_TS_END,
|
||||||
},
|
},
|
||||||
|
.extparms = module_4937_ext_parms,
|
||||||
.priv = NULL, /* priv */
|
.priv = NULL, /* priv */
|
||||||
|
|
||||||
.rig_init = module_4937_init,
|
.rig_init = module_4937_init,
|
||||||
@ -90,7 +99,7 @@ const struct rig_caps module_4937_caps = {
|
|||||||
|
|
||||||
.set_freq = module_4937_set_freq,
|
.set_freq = module_4937_set_freq,
|
||||||
.get_freq = module_4937_get_freq,
|
.get_freq = module_4937_get_freq,
|
||||||
|
.set_ext_level = module_4937_set_ext_level,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -102,4 +111,3 @@ DECLARE_INITRIG_BACKEND(microtune)
|
|||||||
|
|
||||||
return RIG_OK;
|
return RIG_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,97 +0,0 @@
|
|||||||
/* -*-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 <stdlib.h>
|
|
||||||
#include <sys/io.h>
|
|
||||||
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
@ -1,53 +0,0 @@
|
|||||||
/* -*-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_ */
|
|
Loading…
Reference in New Issue
Block a user