diff options
author | phk <phk@FreeBSD.org> | 1998-05-29 08:04:44 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 1998-05-29 08:04:44 +0000 |
commit | 7181862a6f9633a273a886044c06582176e0ce83 (patch) | |
tree | 6b8f33234e3c9985c676e335154cb80623ce1c0b /sys/i386/isa/loran.c | |
parent | 10859a0eb59591b87dc70f3fd0847159a1edaa63 (diff) | |
download | FreeBSD-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.c | 184 |
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; |