ccplumb@rose.waterloo.edu (Colin Plumb) (10/16/89)
I was recently talking with someone about the possibility of hooking Amy up to control theatre lighting. It seems there are two multiplex standards used to control dimmers. One is an analog 0-5V system that would require custom hardware any way it's cut, but the DMX512 (Digital MultipleX, 512 dimmers) standard is vanilla RS422 (RS232+differential line driver) run at a 4us (250Kbaud) bit time with 8 bits, no parity, 2 stop bits. Asynchronous, so you don't need to spit out a byte every 44us, but it's nice to get reasonably close. You send at least 88us of break (low), followed by 1 bit time (3.92 to 4.08 us) of high, then a zero byte (values 1-255 reserved for future expansion), then the control byte for dimmer 1 (0-255), dimmer 2, etc. as many as you have. After #dimmers bytes, you can start over again. There can be an arbitrarily long delay (well, the spec says 1sec max) between bytes, but the null byte must start 1 bit time after the trailing edge of the break. Two possibilities came to mind. Both are sick, sick ideas for use by lazy bums who don't want to build a little UARRT & buffer kludge to stick on the parallel port or some such, let alone build a proper Zorro board. I wonder what everyone thinks? Possibility 1: The floppy drive can send data at 4us/bit. Actually, it's 2.5% faster than that, which is slightly off spec, but it'll probably work. The only problem is the NRZI encoding the floppy chip does to the data stream, so you'd have to add a sense line to see what the state of the data line is so you could flip it, and do some diddling to the input data stream to get it to come out right. And gate things so the bus could be shared with other floppy drives... The big disadvantage is sharing the floppy bus, as I don't know if there's a way to get the trackdisk.device to cleanly release the thing, and even if there was, 1 track's read, 1/6 sec, is a bit long to leave the lights alone at busy moments. You should refresh them at *least* once a second. Possibility 2: Use the standard serial port. It can be set to pretty close to the right baud rate, the problem is driving it that fast and getting that initial break and first byte close enough together. The normal way to send a break, as far as I know, is to drop the baud rate really low and send a null byte (up to 15 null bits, actually). So to send >88us break followed by a byte, assume the serial port reloads its counter from the SERPER register every bit (is this wrong?), and - drop the baud rate - put a lot of 0's into the SERDAT register, with 1 stop bit, and *while this is being sent* - put the null byte (1100000000 with 2 stop bits) into the register, and - raise the baud rate back to 250Kbaud. The last few bits of the break will be sent at high speed (no matter), then 1 bit time of high for its stop bit, then the null byte immediately thereafter. Normal software can take it from here. But: interrupt-per-character is still highly inefficient. If there was a deepish FIFO (16 bytes or so) it might be bearable, but this is going to crawl. We want DMA... h'm... Flash! Use the copper! We can put the bytes into the copper list at the apropriate times and let it copy the data. We only have to fix things up at the end of the frame, to ensure nothing gets sent twice. Restricting the number of dimmers so everything fits into one frame would make things easier, but it's possible in principle to have a list that spans two video frames. You know the baud rate and the video clock (yes, I know the ECS and productivity mode will break this badly, but NTSC/PAL doesn't change too often and can be allowed for), so turning off handshaking is fine. Just leave a little slop and it'll work fine. Only problem: all the user copper list support in the graphics.library handles lists in each ViewPort, translating to View coordinates and truncating undisplayed portions. Great for some applications, but truncating *this* copper list Would Be Bad. Does anyone know the cleanest way to install such an absolute copper list? I'm hoping that the struct CopList *DspIns element of a CopList is in global coordinates, so you can MakeVPort(), then mess with this list to add your own toys, then MrgCop() will make everyone happy. Or maybe it's posible to put negative coordinates in a user copper list, so MakeVPort() will create the right DspIns list. No, it'll still get truncated... Making this work with intuition will require more unsupported tricks. Basically, you need to make sure Intuition doesn't try to MakeVport() while the munged copprt list is running. And get the thing cleared out again... wait for the start of frame, then MakeScreen() and RethinkDisplay() to force a MrgCop(). Hopefully, RethinkDisplay() doesn't take too long if no MakeVPort's need to be done... Anyway, any opinions? Can anyone think of a better derogatory term than "sick"? -- -Colin
33014-18@sjsumcs.sjsu.edu (Eduardo Horvath) (10/16/89)
In article <17243@watdragon.waterloo.edu> ccplumb@rose.waterloo.edu (Colin Plumb) writes: >I was recently talking with someone about the possibility of hooking Amy >up to control theatre lighting. It seems there are two multiplex standards [ gulp ] >The normal way to send a break, as far as I know, is to drop the baud rate >really low and send a null byte (up to 15 null bits, actually). While I have not been working with the Amiga serial port hardware, I have recently been working with an embedded system that has a MC68681 ( I think I have the right part number ) which is a DUART chip. To send a break with that, you set the break time, and give a special command. The DUART does all the rest. >-- > -Colin =============================================================================== x = MEN AT WORK x X X x Try: 33014-18@sjsumcs.SJSU.EDU = x X X X x = This space x X X x Eduardo Horvath = is x = UNDER = CONSTRUCTION ^Doesn't look much like Boing!, does it? = ==============================================================================
ccplumb@rose.waterloo.edu (Colin Plumb) (10/19/89)
In article <1989Oct16.143322.29737@sjsumcs.sjsu.edu> 33014-18@sjsumcs.SJSU.EDU (Eduardo Horvath) writes: >In article <17243@watdragon.waterloo.edu> ccplumb@rose.waterloo.edu (Colin Plumb) writes: >> The normal way to send a break, as far as I know, is to drop the baud rate >> really low and send a null byte (up to 15 null bits, actually). > > While I have not been working with the Amiga serial port hardware, > I have recently been working with an embedded system that has a MC68681 > ( I think I have the right part number ) which is a DUART chip. To send > a break with that, you set the break time, and give a special command. > The DUART does all the rest. I should have been clearer... the normal way to send a break *with the Amiga serial hardware* is to play tricks with the baud rate. Other chips have different techniques. The Z8530 has a control register bit that forces a space condition on the line until the bit is cleared. There are other approaches. -- -Colin
bartonr@jove.cs.pdx.edu (Robert Barton) (10/20/89)
ccplumb@rose.waterloo.edu (Colin Plumb) writes: > Does anyone know the cleanest way to install such an absolute copper list? > I'm hoping that the struct CopList *DspIns element of a CopList is ViewPort-------^^^^^^^ > in global coordinates, so you can MakeVPort(), then mess with this > list to add your own toys, then MrgCop() will make everyone happy. > Or maybe it's posible to put negative coordinates in a user copper list, > so MakeVPort() will create the right DspIns list. No, it'll still > get truncated... ViewPort.DspIns is viewport-relative. One idea I've seen suggested before is to write your own copper list and then use ViewPort.UCopIns instructions to set up the copper location registers and jump to this list. Negative vertical coordinates are certainly ok. For example WAIT -1,0 would mean wait for the beginning of the first line before the top of this ViewPort. This allows you to do something like set up the new colors for a ViewPort before it gets displayed. This is also why ViewPorts have to be separated by at least one blank line. > Basically, you need to make sure Intuition doesn't try to MakeVport() > while the munged copprt list is running. And get the thing cleared > out again... wait for the start of frame, then MakeScreen() and > RethinkDisplay() to force a MrgCop(). Hopefully, RethinkDisplay() > doesn't take too long if no MakeVPort's need to be done... OpenScreen() does a RemakeDisplay(), so you'll have to avoid that. Moving or depth-arranging screens will call MrgCop() by way of RethinkDisplay().