summaryrefslogtreecommitdiffstats
path: root/sys/i386/isa/loran.c
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>1998-05-29 08:04:44 +0000
committerphk <phk@FreeBSD.org>1998-05-29 08:04:44 +0000
commit7181862a6f9633a273a886044c06582176e0ce83 (patch)
tree6b8f33234e3c9985c676e335154cb80623ce1c0b /sys/i386/isa/loran.c
parent10859a0eb59591b87dc70f3fd0847159a1edaa63 (diff)
downloadFreeBSD-src-7181862a6f9633a273a886044c06582176e0ce83.zip
FreeBSD-src-7181862a6f9633a273a886044c06582176e0ce83.tar.gz
most recent code for Loran driver.
Diffstat (limited to 'sys/i386/isa/loran.c')
-rw-r--r--sys/i386/isa/loran.c184
1 files changed, 120 insertions, 64 deletions
diff --git a/sys/i386/isa/loran.c b/sys/i386/isa/loran.c
index bcebc3b..9e8aa93 100644
--- a/sys/i386/isa/loran.c
+++ b/sys/i386/isa/loran.c
@@ -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,19 +234,22 @@ loranprobe(struct isa_device *dvp)
return (8);
}
-int
-loranattach(struct isa_device *isdp)
+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;
- /* We need to be a "fast-intr" */
- isdp->id_ri_flags |= RI_FAST;
-
- 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);
+ LOAD_9513(MASTER, 0x8af0);
outb(TGC, TG_LOADDP+1);
tg_init[4] = 7499 - GRI;
for (i = 0; i < 5*3; i++) {
@@ -241,19 +257,34 @@ loranattach(struct isa_device *isdp)
outb(TGD, tg_init[i] >> 8);
}
outb(TGC, TG_LOADARM+0x1f); /* let the good times roll */
+}
+
+int
+loranattach(struct isa_device *isdp)
+{
+ int i;
+
+ /* We need to be a "fast-intr" */
+ isdp->id_ri_flags |= RI_FAST;
- /* Load the VCO DAC */
- outb(PAR, 0); outb(DACA, VCO & 0xff);
- outb(PAR, MSB); outb(DACA, VCO >> 8);
+ printf("loran0: LORAN-C Receiver\n");
+
+ 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(TGC, TG_LOADDP + 0x0c);
- outb(TGD, this->phase);
- outb(TGD, this->phase >> 8);
+ outb(CODE, this->code);
- /* load next->delay into 9513 */
- outb(TGC, TG_LOADDP + 0x0a);
- outb(TGD, next->delay);
- outb(TGD, next->delay >> 8);
+ 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;
+ }
- 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;
OpenPOWER on IntegriCloud