From d4fb2760f209aa12ced6f31f2d0d6bcb0fefb7e8 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sat, 21 Apr 2001 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2001-04-21 --- bitsy/clock.c | 5 +- bitsy/devuda1341.c | 231 +++++++++++++++++++++++++++------------------ bitsy/fns.h | 2 +- 3 files changed, 143 insertions(+), 95 deletions(-) diff --git a/bitsy/clock.c b/bitsy/clock.c index 10c8d7406fe28906563ba032fcd97a9937488a4c..cde343e696788230c59524d603236498c79e8394 100644 --- a/bitsy/clock.c +++ b/bitsy/clock.c @@ -106,14 +106,15 @@ delay(int ms) } void -µdelay(int µs) +µdelay(ulong µs) { ulong start; int i; + µs++; if(clockinited){ start = timerregs->oscr; - while(timerregs->oscr - start < (µs*ClockFreq)/1000000) + while(timerregs->oscr - start < 1UL+(µs*ClockFreq)/1000000UL) ; } else { while(µs-- > 0){ diff --git a/bitsy/devuda1341.c b/bitsy/devuda1341.c index cd6873c773d737b523f0ffafc86e5b6b384d88fc..fc3639ba64a239b265fff609ff26207282c003f0 100644 --- a/bitsy/devuda1341.c +++ b/bitsy/devuda1341.c @@ -44,13 +44,13 @@ static int debug = 0; * L3 setup and hold times (expressed in µs) */ enum { - L3_DataSetupTime = 10, /* 190 ns */ - L3_DataHoldTime = 10, /* 30 ns */ - L3_ModeSetupTime = 10, /* 190 ns */ - L3_ModeHoldTime = 10, /* 190 ns */ - L3_ClockHighTime = 100, /* 250 ns (min is 64*fs, 35µs @ 44.1 Khz) */ - L3_ClockLowTime = 100, /* 250 ns (min is 64*fs, 35µs @ 44.1 Khz) */ - L3_HaltTime = 10, /* 190 ns */ + L3_DataSetupTime = 1, /* 190 ns */ + L3_DataHoldTime = 1, /* 30 ns */ + L3_ModeSetupTime = 1, /* 190 ns */ + L3_ModeHoldTime = 1, /* 190 ns */ + L3_ClockHighTime = 1, /* 100 ns */ + L3_ClockLowTime = 1, /* 100 ns */ + L3_HaltTime = 1, /* 190 ns */ }; /* UDA 1341 Registers */ @@ -59,13 +59,13 @@ enum { UdaStatusDC = 0, /* 1 bit */ UdaStatusIF = 1, /* 3 bits */ UdaStatusSC = 4, /* 2 bits */ - UdaStatusRST = 6, /* 1 bit */ + UdaStatusRST = 6, /* 1 bit */ }; enum { /* Status1 register */ - UdaStatusPC = 0, /* 2 bits */ - UdaStatusDS = 2, /* 1 bit */ + UdaStatusPC = 0, /* 2 bits */ + UdaStatusDS = 2, /* 1 bit */ UdaStatusPDA = 3, /* 1 bit */ UdaStatusPAD = 4, /* 1 bit */ UdaStatusIGS = 5, /* 1 bit */ @@ -191,6 +191,8 @@ static struct [Nvol] {0} }; +static void setreg(char *name, int val, int n); + /* * Grab control of the IIC/L3 shared pins */ @@ -199,6 +201,7 @@ L3_acquirepins(void) { gpioregs->set = (GPIO_L3_SCLK_o | GPIO_L3_SDA_io); gpioregs->direction |= (GPIO_L3_SCLK_o | GPIO_L3_SDA_io); + µdelay(2); } /* @@ -208,7 +211,6 @@ static void L3_releasepins(void) { gpioregs->direction &= ~(GPIO_L3_SCLK_o | GPIO_L3_SDA_io); - gpioregs->clear = (GPIO_L3_SCLK_o | GPIO_L3_SDA_io); } /* @@ -274,7 +276,7 @@ L3_sendbyte(char data, int mode) { int i; - L3_acquirepins(); +//suspect L3_acquirepins(); switch(mode) { case 0: /* Address mode */ @@ -294,12 +296,14 @@ L3_sendbyte(char data, int mode) for (i = 0; i < 8; i++) L3_sendbit(data >> i); + µdelay(L3_ModeHoldTime); + if (mode == 0) /* Address mode */ gpioregs->set = GPIO_L3_MODE_o; µdelay(L3_ModeHoldTime); - L3_releasepins(); +//suspect L3_releasepins(); } /* @@ -315,8 +319,7 @@ L3_getbyte(int mode) char data = 0; int i; - L3_acquirepins(); - gpioregs->direction &= ~(GPIO_L3_SDA_io); +//suspect L3_acquirepins(); switch(mode) { case 0: /* Address mode - never valid */ @@ -354,10 +357,11 @@ L3_write(uchar addr, uchar *data, int len) int mode = 0; int bytes = len; + L3_acquirepins(); L3_sendbyte(addr, mode++); while(len--) L3_sendbyte(*data++, mode++); - + L3_releasepins(); return bytes; } @@ -366,19 +370,23 @@ L3_write(uchar addr, uchar *data, int len) * the data and length. The length read is returned. The register space * is encoded in the address (low two bits are set and device address is * in the upper 6 bits). - */ + + * Commented out, not used static int L3_read(uchar addr, uchar *data, int len) { int mode = 0; int bytes = len; + L3_acquirepins(); L3_sendbyte(addr, mode++); + gpioregs->direction &= ~(GPIO_L3_SDA_io); while(len--) *data++ = L3_getbyte(mode++); - + L3_releasepins(); return bytes; } + */ void audiomute(int on) @@ -445,23 +453,23 @@ audioinit(void) sspregs = mapspecial(SSPREGS, 32); } -uchar status0 = 0x22; -uchar status1 = 0x80; -uchar data00 = 0x00; /* volume control, bits 0 – 5 */ -uchar data01 = 0x40; -uchar data02 = 0x80; -ushort data0e0 = 0xe0c0; -ushort data0e1 = 0xe0c1; -ushort data0e2 = 0xf2c2; +uchar status0[1] = {0x22}; +uchar status1[1] = {0x80}; +uchar data00[1] = {0x00}; /* volume control, bits 0 – 5 */ +uchar data01[1] = {0x40}; +uchar data02[1] = {0x80}; +uchar data0e0[2] = {0xc0, 0xe0}; +uchar data0e1[2] = {0xc1, 0xe0}; +uchar data0e2[2] = {0xc2, 0xf2}; /* there is no data0e3 */ -ushort data0e4 = 0xe0c4; -ushort data0e5 = 0xe0c5; -ushort data0e6 = 0xe3c6; +uchar data0e4[2] = {0xc4, 0xe0}; +uchar data0e5[2] = {0xc5, 0xe0}; +uchar data0e6[2] = {0xc6, 0xe3}; static void enable(void) { - ushort data; + uchar data[1]; L3_init(); @@ -484,24 +492,24 @@ enable(void) delay(100); /* Reset the chip */ - data = status0 | 1<clear = EGPIO_codec_reset; gpioregs->set = EGPIO_codec_reset; /* write uda 1341 status[0] */ - L3_write(UDA1341_L3Addr | UDA1341_STATUS, (uchar*)&status0, 1 ); - L3_write(UDA1341_L3Addr | UDA1341_STATUS, (uchar*)&status1, 1); - L3_write(UDA1341_L3Addr | UDA1341_DATA0, (uchar*)&data02, 1); - L3_write(UDA1341_L3Addr | UDA1341_DATA0, (uchar*)&data0e2, 2); - L3_write(UDA1341_L3Addr | UDA1341_DATA0, (uchar*)&data0e6, 2 ); + L3_write(UDA1341_L3Addr | UDA1341_STATUS, status0, 1 ); + L3_write(UDA1341_L3Addr | UDA1341_STATUS, status1, 1); + L3_write(UDA1341_L3Addr | UDA1341_DATA0, data02, 1); + L3_write(UDA1341_L3Addr | UDA1341_DATA0, data0e2, 2); + L3_write(UDA1341_L3Addr | UDA1341_DATA0, data0e6, 2 ); if (debug) { - print("enable: status0 = 0x%2.2ux\n", status0); - print("enable: status1 = 0x%2.2ux\n", status1); - print("enable: data02 = 0x%2.2ux\n", data02); - print("enable: data0e2 = 0x%4.4ux\n", data0e2); - print("enable: data0e4 = 0x%4.4ux\n", data0e4); - print("enable: data0e6 = 0x%4.4ux\n", data0e6); + print("enable: status0 = 0x%2.2ux\n", status0[0]); + print("enable: status1 = 0x%2.2ux\n", status1[0]); + print("enable: data02 = 0x%2.2ux\n", data02[0]); + print("enable: data0e2 = 0x%4.4ux\n", data0e2[0] | data0e2[1]<<8); + print("enable: data0e4 = 0x%4.4ux\n", data0e4[0] | data0e4[1]<<8); + print("enable: data0e6 = 0x%4.4ux\n", data0e6[0] | data0e6[1]<<8); print("enable: sspregs->control0 = 0x%lux\n", sspregs->control0); print("enable: sspregs->control1 = 0x%lux\n", sspregs->control1); } @@ -529,79 +537,113 @@ mxvolume(void) { right = audio.rivol; if (left[Vmic]+right[Vmic] == 0) { /* Turn on automatic gain control (AGC) */ - data0e4 |= 0x1000; - L3_write(UDA1341_L3Addr | UDA1341_DATA0, (uchar*)&data0e4, 2 ); + data0e4[1] |= 0x10; + L3_write(UDA1341_L3Addr | UDA1341_DATA0, data0e4, 2 ); } else { int v; /* Turn on manual gain control */ v = ((left[Vmic]+right[Vmic])*0x7f/200)&0x7f; - data0e4 &= ~0x1300; - data0e5 &= ~0x1f00; - data0e4 |= (v & 0x3)<<8; - data0e5 |= (v & 0x7c)<<6; - L3_write(UDA1341_L3Addr | UDA1341_DATA0, (uchar*)&data0e4, 2 ); - L3_write(UDA1341_L3Addr | UDA1341_DATA0, (uchar*)&data0e5, 2 ); + data0e4[1] &= ~0x13; + data0e5[1] &= ~0x1f; + data0e4[1] |= v & 0x3; + data0e5[0] |= (v & 0x7c)<<6; + data0e5[1] |= (v & 0x7c)>>2; + L3_write(UDA1341_L3Addr | UDA1341_DATA0, data0e4, 2 ); + L3_write(UDA1341_L3Addr | UDA1341_DATA0, data0e5, 2 ); } if (left[Vinvert]+right[Vinvert] == 0) - status1 &= ~0x04; + status1[0] &= ~0x04; else - status1 |= 0x04; - L3_write(UDA1341_L3Addr | UDA1341_STATUS, (uchar*)&status1, 1); + status1[0] |= 0x04; + L3_write(UDA1341_L3Addr | UDA1341_STATUS, status1, 1); if (debug) { - print("mxvolume: status1 = 0x%2.2ux\n", status1); - print("mxvolume: data0e4 = 0x%4.4ux\n", data0e4); - print("mxvolume: data0e5 = 0x%4.4ux\n", data0e5); + print("mxvolume: status1 = 0x%2.2ux\n", status1[0]); + print("mxvolume: data0e4 = 0x%4.4ux\n", data0e4[0]|data0e4[0]<<8); + print("mxvolume: data0e5 = 0x%4.4ux\n", data0e5[0]|data0e5[0]<<8); } } if(audio.amode & Awrite){ left = audio.lovol; right = audio.rovol; - data00 &= ~0x3f; - data00 |= ((200-left[Vaudio]-right[Vaudio])*0x3f/200)&0x3f; + data00[0] &= ~0x3f; + data00[0] |= ((200-left[Vaudio]-right[Vaudio])*0x3f/200)&0x3f; if (left[Vtreb]+right[Vtreb] <= 100 && left[Vbass]+right[Vbass] <= 100) /* settings neutral */ - data02 &= ~0x03; + data02[0] &= ~0x03; else { - data02 |= 0x03; - data01 &= ~0x3f; - data01 |= ((left[Vtreb]+right[Vtreb]-100)*0x3/100)&0x03; - data01 |= (((left[Vbass]+right[Vbass]-100)*0xf/100)&0xf)<<2; + data02[0] |= 0x03; + data01[0] &= ~0x3f; + data01[0] |= ((left[Vtreb]+right[Vtreb]-100)*0x3/100)&0x03; + data01[0] |= (((left[Vbass]+right[Vbass]-100)*0xf/100)&0xf)<<2; } if (left[Vfilter]+right[Vfilter] == 0) - data02 &= ~0x10; + data02[0] &= ~0x10; else - data02 |= 0x10; + data02[0]|= 0x10; if (left[Vinvert]+right[Vinvert] == 0) - status1 &= ~0x10; + status1[0] &= ~0x10; else - status1 |= 0x10; - L3_write(UDA1341_L3Addr | UDA1341_STATUS, (uchar*)&status1, 1); - L3_write(UDA1341_L3Addr | UDA1341_DATA0, (uchar*)&data00, 1); - L3_write(UDA1341_L3Addr | UDA1341_DATA0, (uchar*)&data01, 1); - L3_write(UDA1341_L3Addr | UDA1341_DATA0, (uchar*)&data02, 1); + status1[0] |= 0x10; + L3_write(UDA1341_L3Addr | UDA1341_STATUS, status1, 1); + L3_write(UDA1341_L3Addr | UDA1341_DATA0, data00, 1); + L3_write(UDA1341_L3Addr | UDA1341_DATA0, data01, 1); + L3_write(UDA1341_L3Addr | UDA1341_DATA0, data02, 1); if (debug) { - print("mxvolume: status1 = 0x%2.2ux\n", status1); - print("mxvolume: data00 = 0x%2.2ux\n", data00); - print("mxvolume: data01 = 0x%2.2ux\n", data01); - print("mxvolume: data02 = 0x%2.2ux\n", data02); + print("mxvolume: status1 = 0x%2.2ux\n", status1[0]); + print("mxvolume: data00 = 0x%2.2ux\n", data00[0]); + print("mxvolume: data01 = 0x%2.2ux\n", data01[0]); + print("mxvolume: data02 = 0x%2.2ux\n", data02[0]); } } } +static void +setreg(char *name, int val, int n) +{ + uchar x[2]; + int i; + + x[0] = val; + x[1] = val>>8; + + if(strcmp(name, "pause") == 0){ + for(i = 0; i < n; i++) + µdelay(val); + return; + } + + switch(n){ + case 1: + case 2: + break; + default: + error("setreg"); + } + + if(strcmp(name, "status") == 0){ + L3_write(UDA1341_L3Addr | UDA1341_STATUS, x, n); + } else if(strcmp(name, "data0") == 0){ + L3_write(UDA1341_L3Addr | UDA1341_DATA0, x, n); + } else if(strcmp(name, "data1") == 0){ + L3_write(UDA1341_L3Addr | UDA1341_DATA1, x, n); + } else + error("setreg"); +} + static void outenable(void) { /* turn on DAC, set output gain switch */ egpiobits(EGPIO_audio_power, 1); audiomute(0); - status1 |= 0x41; - L3_write(UDA1341_L3Addr | UDA1341_STATUS, (uchar*)&status1, 1); + status1[0] |= 0x41; + L3_write(UDA1341_L3Addr | UDA1341_STATUS, status1, 1); /* set volume */ - data00 |= 0xf; - L3_write(UDA1341_L3Addr | UDA1341_DATA0, (uchar*)&data00, 1); + data00[0] |= 0xf; + L3_write(UDA1341_L3Addr | UDA1341_DATA0, data00, 1); if (debug) { - print("outenable: status1 = 0x%2.2ux\n", status1); - print("outenable: data00 = 0x%2.2ux\n", data00); + print("outenable: status1 = 0x%2.2ux\n", status1[0]); + print("outenable: data00 = 0x%2.2ux\n", data00[0]); } } @@ -611,10 +653,10 @@ outdisable(void) { /* turn off DAC, clear output gain switch */ audiomute(1); egpiobits(EGPIO_audio_power, 0); - status1 &= ~0x41; - L3_write(UDA1341_L3Addr | UDA1341_STATUS, (uchar*)&status1, 1); + status1[0] &= ~0x41; + L3_write(UDA1341_L3Addr | UDA1341_STATUS, status1, 1); if (debug) { - print("outdisable: status1 = 0x%2.2ux\n", status1); + print("outdisable: status1 = 0x%2.2ux\n", status1[0]); } egpiobits(EGPIO_audio_power, 0); } @@ -622,10 +664,10 @@ outdisable(void) { static void inenable(void) { /* turn on ADC, set input gain switch */ - status1 |= 0x22; - L3_write(UDA1341_L3Addr | UDA1341_STATUS, (uchar*)&status1, 1); + status1[0] |= 0x22; + L3_write(UDA1341_L3Addr | UDA1341_STATUS, status1, 1); if (debug) { - print("inenable: status1 = 0x%2.2ux\n", status1); + print("inenable: status1 = 0x%2.2ux\n", status1[0]); } } @@ -633,10 +675,10 @@ static void indisable(void) { dmastop(audio.i.dma); /* turn off ADC, clear input gain switch */ - status1 &= ~0x22; - L3_write(UDA1341_L3Addr | UDA1341_STATUS, (uchar*)&status1, 1); + status1[0] &= ~0x22; + L3_write(UDA1341_L3Addr | UDA1341_STATUS, status1, 1); if (debug) { - print("indisable: status1 = 0x%2.2ux\n", status1); + print("indisable: status1 = 0x%2.2ux\n", status1[0]); } } @@ -940,7 +982,6 @@ audioread(Chan *c, void *v, long n, vlong off) ulong offset = off; char *p; IOstate *s; - uchar voldata; n0 = n; p = v; @@ -1126,6 +1167,12 @@ audiowrite(Chan *c, void *vp, long n, vlong) right = 1; goto cont0; } + if(strcmp(field[i], "reg") == 0) { + if(nf < 3) + error(Evolume); + setreg(field[1], atoi(field[2]), nf == 4 ? atoi(field[3]):1); + return n0; + } error(Evolume); break; cont0:; diff --git a/bitsy/fns.h b/bitsy/fns.h index 288481e7e3f0873f869fc187fb49e9f4e816a5c0..0f97585526e498fe1f65f7859913ef9ebf8e2643 100644 --- a/bitsy/fns.h +++ b/bitsy/fns.h @@ -12,7 +12,7 @@ void clockinit(void); #define coherence() #define dcflush(a, b) void delay(int); -void µdelay(int); +void µdelay(ulong); void dmainit(void); void _doze(void); void (*doze)(void);