Path: utzoo!utgpu!watmath!watdragon!rose!ccplumb From: ccplumb@rose.waterloo.edu (Colin Plumb) Newsgroups: comp.sys.amiga.tech Subject: Sick, sick idea... Summary: Getting 250Kbits/sec serial Keywords: DMX512, lighting Message-ID: <17243@watdragon.waterloo.edu> Date: 15 Oct 89 23:47:29 GMT Sender: daemon@watdragon.waterloo.edu Reply-To: ccplumb@rose.waterloo.edu (Colin Plumb) Organization: U. of Waterloo, Ontario Lines: 92 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