mirror of
https://github.com/opnsense/src.git
synced 2026-06-09 16:50:25 -04:00
most recent code for Loran driver.
This commit is contained in:
parent
f74e1ace9c
commit
bfb925ba31
1 changed files with 124 additions and 68 deletions
|
|
@ -6,7 +6,7 @@
|
|||
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* $Id: loran.c,v 1.3 1998/04/05 19:26:08 phk Exp $
|
||||
* $Id: loran.c,v 1.4 1998/04/19 15:36:12 bde Exp $
|
||||
*
|
||||
* This device-driver helps the userland controlprogram for a LORAN-C
|
||||
* receiver avoid monopolizing the CPU.
|
||||
|
|
@ -49,6 +49,7 @@ struct datapoint {
|
|||
u_int gri;
|
||||
u_int agc;
|
||||
u_int phase;
|
||||
u_int width;
|
||||
u_int par;
|
||||
u_int isig;
|
||||
u_int qsig;
|
||||
|
|
@ -58,7 +59,12 @@ struct datapoint {
|
|||
TAILQ_ENTRY(datapoint) list;
|
||||
double ival;
|
||||
double qval;
|
||||
double sval;
|
||||
double mval;
|
||||
u_char status;
|
||||
u_int vco;
|
||||
int count;
|
||||
int remain;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -70,19 +76,19 @@ struct datapoint {
|
|||
#define INTEG_36us 2
|
||||
#define INTEG_SHORT 3
|
||||
#define GATE 0x0C /* gate source mask */
|
||||
#define GATE_OPEN 0x4
|
||||
#define GATE_GRI 0x8
|
||||
#define GATE_PCI 0xc
|
||||
#define GATE_STB 0xf
|
||||
#define GATE_OPEN 0x0
|
||||
#define GATE_GRI 0x4
|
||||
#define GATE_PCI 0x8
|
||||
#define GATE_STB 0xc
|
||||
#define MSB 0x10 /* load dac high-order bits */
|
||||
#define IEN 0x20 /* enable interrupt bit */
|
||||
#define EN5 0x40 /* enable counter 5 bit */
|
||||
#define ENG 0x80 /* enable gri bit */
|
||||
|
||||
#define VCO 2048 /* initial vco dac (0 V)*/
|
||||
|
||||
#ifdef KERNEL
|
||||
|
||||
#define VCO 2048 /* initial vco dac (0 V)*/
|
||||
|
||||
#define PORT 0x0300 /* controller port address */
|
||||
|
||||
|
|
@ -111,6 +117,11 @@ struct datapoint {
|
|||
#define DACA PORT+4 /* vco (dac a) buffer (w) */
|
||||
#define DACB PORT+5 /* agc (dac b) buffer (w) */
|
||||
|
||||
#define LOAD_DAC(dac, val) if (0) { } else { \
|
||||
par &= ~MSB; outb(PAR, par); outb((dac), (val) & 0xff); \
|
||||
par |= MSB; outb(PAR, par); outb((dac), ((val) >> 8) & 0xff); \
|
||||
}
|
||||
|
||||
/*
|
||||
* Pulse-code generator (CODE) hardware definitions
|
||||
* Note: bits are shifted out from the lsb first
|
||||
|
|
@ -166,6 +177,11 @@ struct datapoint {
|
|||
#define DSABPFW 0xF9 /* disable prefetch for write */
|
||||
#define TG_RESET 0xFF /* master reset */
|
||||
|
||||
#define LOAD_9513(index, val) if (0) {} else { \
|
||||
outb(TGC, TG_LOADDP + (index)); \
|
||||
outb(TGD, (val) & 0xff); \
|
||||
outb(TGD, ((val) >> 8) & 0xff); \
|
||||
}
|
||||
|
||||
#define NENV 40 /* size of envelope filter */
|
||||
#define CLOCK 50 /* clock period (clock) */
|
||||
|
|
@ -173,14 +189,6 @@ struct datapoint {
|
|||
#define PCX (NENV * CLOCK) /* envelope gate (clock) */
|
||||
#define STROBE 50 /* strobe gate (clock) */
|
||||
|
||||
u_short tg_init[] = { /* stc initialization vector */
|
||||
0x0562, 12, 13, /* counter 1 (p0) */
|
||||
0x0262, PGUARD, GRI, /* counter 2 (gri) */
|
||||
0x8562, PCX, 5000 - PCX, /* counter 3 (pcx) */
|
||||
0xc562, 0, STROBE, /* counter 4 (stb) */
|
||||
0x052a, 0, 0 /* counter 5 (out) */
|
||||
};
|
||||
|
||||
/**********************************************************************/
|
||||
|
||||
static TAILQ_HEAD(qhead, datapoint) qdone, qready;
|
||||
|
|
@ -196,7 +204,12 @@ static struct datapoint *this, *next;
|
|||
static MALLOC_DEFINE(M_LORAN, "Loran", "Loran datapoints");
|
||||
|
||||
static int loranerror;
|
||||
static char lorantext[40];
|
||||
static char lorantext[80];
|
||||
|
||||
static u_int vco_is;
|
||||
static u_int vco_should;
|
||||
|
||||
static int lorantc_magic;
|
||||
|
||||
/**********************************************************************/
|
||||
|
||||
|
|
@ -221,6 +234,31 @@ loranprobe(struct isa_device *dvp)
|
|||
return (8);
|
||||
}
|
||||
|
||||
u_short tg_init[] = { /* stc initialization vector */
|
||||
0x0562, 12, 13, /* counter 1 (p0) */
|
||||
0x0262, PGUARD, GRI, /* counter 2 (gri) */
|
||||
0x8562, PCX, 5000 - PCX, /* counter 3 (pcx) */
|
||||
0xc562, 0, STROBE, /* counter 4 (stb) */
|
||||
0x052a, 0, 0 /* counter 5 (out) */
|
||||
};
|
||||
|
||||
void
|
||||
init_tgc(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Initialize the 9513A */
|
||||
outb(TGC, TG_RESET); outb(TGC, LOAD+0x1f); /* reset STC chip */
|
||||
LOAD_9513(MASTER, 0x8af0);
|
||||
outb(TGC, TG_LOADDP+1);
|
||||
tg_init[4] = 7499 - GRI;
|
||||
for (i = 0; i < 5*3; i++) {
|
||||
outb(TGD, tg_init[i]);
|
||||
outb(TGD, tg_init[i] >> 8);
|
||||
}
|
||||
outb(TGC, TG_LOADARM+0x1f); /* let the good times roll */
|
||||
}
|
||||
|
||||
int
|
||||
loranattach(struct isa_device *isdp)
|
||||
{
|
||||
|
|
@ -231,29 +269,22 @@ loranattach(struct isa_device *isdp)
|
|||
|
||||
printf("loran0: LORAN-C Receiver\n");
|
||||
|
||||
/* Initialize the 9513A */
|
||||
outb(TGC, TG_RESET); outb(TGC, LOAD+0x1f); /* reset STC chip */
|
||||
outb(TGC, TG_LOADDP+MASTER); outb(TGD, 0xf0); outb(TGD, 0x8a);
|
||||
outb(TGC, TG_LOADDP+1);
|
||||
tg_init[4] = 7499 - GRI;
|
||||
for (i = 0; i < 5*3; i++) {
|
||||
outb(TGD, tg_init[i]);
|
||||
outb(TGD, tg_init[i] >> 8);
|
||||
}
|
||||
outb(TGC, TG_LOADARM+0x1f); /* let the good times roll */
|
||||
|
||||
/* Load the VCO DAC */
|
||||
outb(PAR, 0); outb(DACA, VCO & 0xff);
|
||||
outb(PAR, MSB); outb(DACA, VCO >> 8);
|
||||
vco_is = VCO;
|
||||
LOAD_DAC(DACA, VCO);
|
||||
|
||||
init_tgc();
|
||||
|
||||
init_timecounter(loran_timecounter);
|
||||
|
||||
TAILQ_INIT(&qdone);
|
||||
TAILQ_INIT(&qready);
|
||||
|
||||
dummy.agc = 2000;
|
||||
dummy.code = 0x55;
|
||||
dummy.agc = 4095;
|
||||
dummy.code = 0xac;
|
||||
dummy.delay = PGUARD - GRI;
|
||||
dummy.gri = PGUARD;
|
||||
dummy.phase = 50;
|
||||
dummy.width = 50;
|
||||
|
||||
TAILQ_INSERT_HEAD(&qready, &dummy, list);
|
||||
this = &dummy;
|
||||
|
|
@ -282,6 +313,7 @@ loranopen (dev_t dev, int flags, int fmt, struct proc *p)
|
|||
write_eflags(ef);
|
||||
FREE(this, M_LORAN);
|
||||
}
|
||||
init_tgc();
|
||||
loranerror = 0;
|
||||
return(0);
|
||||
}
|
||||
|
|
@ -369,10 +401,12 @@ loranwrite(dev_t dev, struct uio * uio, int ioflag)
|
|||
err = uiomove((caddr_t)this, c, uio);
|
||||
if (!err && this->gri == 0)
|
||||
err = EINVAL;
|
||||
if (!err)
|
||||
if (!err) {
|
||||
loranenqueue(this);
|
||||
else
|
||||
vco_should = this->vco;
|
||||
} else {
|
||||
FREE(this, M_LORAN);
|
||||
}
|
||||
return(err);
|
||||
}
|
||||
|
||||
|
|
@ -380,11 +414,33 @@ void
|
|||
loranintr(int unit)
|
||||
{
|
||||
u_long ef;
|
||||
int status, count = 0;
|
||||
int status = 0, count = 0, i;
|
||||
|
||||
ef = read_eflags();
|
||||
disable_intr();
|
||||
|
||||
if (this != &dummy) {
|
||||
outb(TGC, DSABDPS);
|
||||
outb(TGC, TG_LOADDP + 0x12); /* hold counter #2 */
|
||||
this->remain = -1;
|
||||
i = 2;
|
||||
for (i = 0; i < 2; i++) {
|
||||
count = this->remain;
|
||||
do {
|
||||
outb(TGC, TG_SAVE + 0x12);
|
||||
this->remain = inb(TGD) & 0xff;
|
||||
this->remain |= inb(TGD) << 8;
|
||||
} while (count == this->remain);
|
||||
}
|
||||
lorantc_magic = 1;
|
||||
nanotime(&this->actual);
|
||||
lorantc_magic = 0;
|
||||
outb(TGC, TG_LOADDP + 0x0a);
|
||||
this->count = inb(TGD);
|
||||
this->count |= inb(TGD) << 8;
|
||||
LOAD_9513(0x12, GRI)
|
||||
}
|
||||
|
||||
this->ssig = inb(ADC);
|
||||
|
||||
par &= ~(ENG | IEN);
|
||||
|
|
@ -407,7 +463,6 @@ loranintr(int unit)
|
|||
this->epoch = ticker;
|
||||
|
||||
if (this != &dummy) {
|
||||
nanotime(&this->actual); /* XXX */
|
||||
TAILQ_INSERT_TAIL(&qdone, this, list);
|
||||
wakeup((caddr_t)&qdone);
|
||||
}
|
||||
|
|
@ -433,48 +488,49 @@ loranintr(int unit)
|
|||
|
||||
/* load this->params */
|
||||
par &= ~(INTEG|GATE);
|
||||
par |= this->par;
|
||||
par |= this->par & (INTEG|GATE);
|
||||
|
||||
par &= ~MSB; outb(PAR, par); outb(DACB, this->agc);
|
||||
par |= MSB; outb(PAR, par); outb(DACB, this->agc>>8);
|
||||
LOAD_DAC(DACB, this->agc);
|
||||
|
||||
switch (this->code) {
|
||||
case 256+0: outb(CODE, MPCA); break;
|
||||
case 256+1: outb(CODE, MPCB); break;
|
||||
case 256+2: outb(CODE, SPCA); break;
|
||||
case 256+3: outb(CODE, SPCB); break;
|
||||
default: outb(CODE, this->code); break;
|
||||
outb(CODE, this->code);
|
||||
|
||||
LOAD_9513(0x0a, next->delay);
|
||||
|
||||
/*
|
||||
* We need to load this from the opposite register * due to some
|
||||
* weirdness which you can read about in in the 9513 manual on
|
||||
* page 1-26 under "LOAD"
|
||||
*/
|
||||
LOAD_9513(0x0c, this->phase);
|
||||
LOAD_9513(0x14, this->phase);
|
||||
outb(TGC, TG_LOADARM + 0x08);
|
||||
LOAD_9513(0x14, this->width);
|
||||
|
||||
if (vco_is != vco_should) {
|
||||
LOAD_DAC(DACA, vco_should);
|
||||
vco_is = vco_should;
|
||||
}
|
||||
|
||||
outb(TGC, TG_LOADDP + 0x0c);
|
||||
outb(TGD, this->phase);
|
||||
outb(TGD, this->phase >> 8);
|
||||
|
||||
/* load next->delay into 9513 */
|
||||
outb(TGC, TG_LOADDP + 0x0a);
|
||||
outb(TGD, next->delay);
|
||||
outb(TGD, next->delay >> 8);
|
||||
|
||||
|
||||
status = inb(TGC);
|
||||
status &= 0x1c;
|
||||
this->status = inb(TGC);
|
||||
#if 1
|
||||
/* Check if we overran */
|
||||
status = this->status & 0x1c;
|
||||
|
||||
if (status) {
|
||||
outb(TGC, TG_SAVE + 2); /* save counter #2 */
|
||||
outb(TGC, TG_LOADDP +0x12); /* hold counter #2 */
|
||||
count = inb(TGD & 0xff);
|
||||
outb(TGC, TG_LOADDP + 0x12); /* hold counter #2 */
|
||||
count = inb(TGD);
|
||||
count |= inb(TGD) << 8;
|
||||
outb(TGC, TG_LOADDP +0x12); /* hold counter #2 */
|
||||
outb(TGD, GRI & 0xff);
|
||||
outb(TGD, GRI >> 8);
|
||||
LOAD_9513(0x12, GRI)
|
||||
}
|
||||
#endif
|
||||
|
||||
par |= ENG | IEN;
|
||||
outb(PAR, par);
|
||||
|
||||
if (status) {
|
||||
sprintf(lorantext, "Missed: %02x %d %d\n",
|
||||
status, count, next->delay);
|
||||
sprintf(lorantext, "Missed: %02x %d %d this:%p next:%p (dummy=%p)\n",
|
||||
status, count, next->delay, this, next, &dummy);
|
||||
loranerror = 1;
|
||||
}
|
||||
if (next->delay < PGUARD - GRI) {
|
||||
|
|
@ -488,17 +544,18 @@ loranintr(int unit)
|
|||
|
||||
/**********************************************************************/
|
||||
|
||||
static u_int64_t
|
||||
static unsigned
|
||||
loran_get_timecount(void)
|
||||
{
|
||||
u_int32_t count;
|
||||
unsigned count;
|
||||
u_long ef;
|
||||
u_int high, low;
|
||||
|
||||
ef = read_eflags();
|
||||
disable_intr();
|
||||
|
||||
outb(TGC, TG_SAVE + 0x10); /* save counter #5 */
|
||||
if (!lorantc_magic)
|
||||
outb(TGC, TG_SAVE + 0x10); /* save counter #5 */
|
||||
outb(TGC, TG_LOADDP +0x15); /* hold counter #5 */
|
||||
count = inb(TGD);
|
||||
count |= inb(TGD) << 8;
|
||||
|
|
@ -508,7 +565,6 @@ loran_get_timecount(void)
|
|||
}
|
||||
|
||||
static struct timecounter loran_timecounter[3] = {
|
||||
0, /* get_timedelta */
|
||||
loran_get_timecount, /* get_timecount */
|
||||
0xffff, /* counter_mask */
|
||||
5000000, /* frequency */
|
||||
|
|
@ -539,7 +595,7 @@ static void loran_drvinit(void *unused)
|
|||
{
|
||||
dev_t dev;
|
||||
|
||||
if( ! loran_devsw_installed ) {
|
||||
if(!loran_devsw_installed) {
|
||||
dev = makedev(CDEV_MAJOR, 0);
|
||||
cdevsw_add(&dev,&loran_cdevsw, NULL);
|
||||
loran_devsw_installed = 1;
|
||||
|
|
|
|||
Loading…
Reference in a new issue