I'm sending this to the PIC list also. Since I'm using PICs in it, I thought people might be interested. If not, sue me :-) In article <1995Mar9.215858.21834@relay.nswc.navy.mil>, acorda@relay.nswc.navy.mil (Albert J. Corda) writes about the surplus Sony CDK-006 60-disc CD changers which are available from Haltek in Mountain View, CA: > Has anyone played with one of these critters yet? Yes, I have eight of them. I've converted one back to normal speed, and will eventually convert the others. > Are the control codes in the tech. manual (I hope)? Yes. The connector is a DB-37. The pinout is: pins name dir description 1-4 ECMD3..0 in command from controller 5 L/R* in local or remote control 6 HELP* out indicates changer in test mode 7 CHECK out indicates power up 8-13 subcode out 14-16 ground 17 +5V 18 EXAM* in SIRCS (IR remote control) input 19 ground 20 CLOSE out magazine present and door closed 21 EACK* out command handshake, indicates command nibble accepted 22 EREQ* in command handshake, indicates command nibble available 23 MUTING out 24 QSTB* out status strobe 25-28 QDATA3..0 out status 29-34 test ctrls in 35-36 ground 37 TEST* in The changer has a four-bit parallel input port (from its point of view), ECMD3..ECMD0. The controller drives the L/R* signal low to indicate that it wants to talk to the changer. As the controller presents each nibble of the command, it asserts the EREQ* line, waits for the changer to assert the EACK* line, deasserts thte EREQ* line, and waits for the changer to deassert EACK*. After the entire command has been handshaked out in this manner, the controller raises L/R*. The changer provides command result and status codes to the controller on a four-bit output port, QDATA3..QDATA0. There is a strobe line QSTB* which signals valid data. Since there isn't two-way handshaking on the status, the controller has to accept each status nibble within 230 uS of the falling edge of QSTB*. Typically QSTB* would be used to generate an interrupt to the controller. The changer also provides three general status lines HELP*, CLOSE, and CHECK. HELP* when asserted indicates that a serious problem has occurred and the changer has dropped into test mode. CLOSE is asserted when a magazine is in place and the front door is closed. CHECK is asserted when the changer is powered up. The player supplies 5V DC power to the connector, but the service manual claims it is only for test purposes. Basically they don't want you to draw a bunch of power from it. The interface connector also has a pin to which you can connect the output of an IR receiver/demodulator such as the Sharp GP1U5X (or some such) which is available from Radio Shack. The unit will then respond to standard Sony CD remote codes, although this is of little use if you have more than one player, and it doesn't support direct access to any disc. > I'd love to hear of anyone else's experience with this contraption. Since the CDK-006 was a fairly early player, and was primarily intended for use in radio stations, it doesn't have a particularly great D/A section. It's OK, but not audiophile quality. I've been looking at adding an AES/EBU consumer format digital output (also known as SP/DIF). It should be easy to do but I'm not sure how much jitter the resulting signal will have. There are several variations of the CDK-006 which have different digital filters and D/A chips, and the clocking is different for each. Interestingly enough, the nature of the modifications that Personics made to the changer are such that it *does* have a digital output (and an external clock input); they are unfortunately in a proprietary format. I'm using a PIC16C84 to interface it to RS-232. The PIC is converting the parallel binary to serial ASCII hex. I implemented some control codes for addressing units so I can daisy chain more than one from the serial port. The entire interface fits inside a DB-37 connector shell, and is powered from the CD changer since it only needs a few milliamps. I used RJ-11 modular connectors for the serial input and output. host (computer) interface #0 interface #1 ---------------| |---------------------------| |------------ RS232 | | | | out |------->| in ------- ------- out |------->| | | | | | | ... in |<-------| out - | | --- in |<-------| | | | | | | | | ---------------| | | | | | | | |MAX ^ --- ^ --- | |232 / \ \ / / \ \ / | | --- v --- v | | | | | | | |mux /-\ | /-\ | | | | | | | | | | | --^-- | --^-- | | | | | | | | | | | | | +---- GND | | | | | | | | | | | | | | | | ---u---------- | | | | | | | | | | | | PIC16C84 | | |---------------------| | | | | | | | | | | | | | | | | | | | | | | |---------------------| | | | | / \ | | \---/ /---\ | | \ / | | | |---------------------------| | | / \ \---/ /---\ \ / | | |---------------------------| | | | Sony CDK-006 CD Changer | | | |---------------------------| Ordinarily you can't attach multiple devices to an ordinary RS-232 port (without violating the RS-232 specifications). I considered using RS-485, which was specifically designed for multidrop applications, but then I would have had to build an RS-232 to RS-485 interface. Okay, admittedly that would be trivial, but I still would have to have DIP switches or something to assign unique addresses to the interfaces, so I decided I was best off with an active daisy chain arrangement, in which case it may as well be RS-232. The PIC16C84 doesn't have a UART, so I am bit-banging the serial. I considered using a PIC16C74 which does have a UART, and also has more available port lines, which would be an advantage in this application. Unfortunately the PIC16C74 is more expensive, harder to obtain, and takes a *LONG* time to erase, whereas the PIC16C84 is less expensive, very easy to obtain, and uses EEPROM so it erases and reprograms in seconds. Since the PIC16C84 is somewhat short on I/O pins, I use a 74HC259 addressable latch (not shown) to provide eight extra outputs, and a 74HCT151 multiplexer to provide eight extra inputs. It takes six lines from the PIC to control these chips, for a gain of ten lines. One output controls a section of a 74HC4053 multiplexer to control whether the incoming serial from upstream (the host or a lower numbered interface) is passed downstream to higher numbered interfaces. Another output controls another multiplexer section which determines whether the interface provides its own output to the upstream device, or just passes along the output of the downstream device. These multiplexers are used to allow automatic assignment of interface addresses, and to allow the interfaces to be daisy chained on a single RS-232 port. (The multiplexer control lines are not shown in the crude diagram above.) At power up, none of the interfaces has an address, and none of them forward the upstream input to the downstream interface. The host sends an "assign address zero" command. Only the first interface receives the command, so it learns that its address is zero, sends an "acknowledge" to the host, and and then enables the upstream input to be passed downstream, and the downstream input to be passed upstream. The host then sends an "assign address one" command. Interface #0 already has an address so it ignores the command. The next interace receives it and sets its address to one, sends an "acknowledge" back to the host, and sets its multiplexers. Eventually the host will send an "assign address n" command which doesn't generate an ack; then it knows that there are n interfaces. I considered avoiding the use of multiplexers by having the PIC be responsible for forwarding in the upstream and downstream directions as appropriate, but I think that there would be problems with retiming the bits as they passed through multiple daisy-chained interfaces. I don't have everything completely debugged yet. I'll be happy to give out schematics and code when it's ready, but don't hold your breath. Cheers, Eric PS: Here's some notes I wrote on the serial bit-banging that might be useful to others. Ignore them if you're uninterested. Notes on bit-banging serial --------------------------- Copyright 1995 Eric L. Smith Permission is granted to copy these notes unmodified for noncommercial use provided this Copyright notice is preserved. Real UARTS typically sample the received signal at 16 times the baud rate, so that they can accurately detect the leading edge of the start bit and hence sample the actual data bits very near the center of the bit time. This allows for a fair bit of slop between the transmiter and receiver bit rates. This diagram illustrates the best and worst case timing: ----- /-------------\-/-------------\-/-------------\-/---- | start bit / data bit 0 X data bit 1 X data bit 2 X |--------------/---------------/-\-------------/-\-------------/-\---- ------ /-------------\-/-------------\-/-------------\-/---- | start bit / data bit 0 X data bit 1 X data bit 2 X |--------------/---------------/-\-------------/-\-------------/-\---- | | | | 0000000000111111111122222222223333333333444444444455555555556666666666 0123456789012345678901234567890123456789012345678901234567890123456789 ^ ^ ^ ^ start bit detected first data bit subsequent data within first 1/16 bit sampled 24 bits sampled every time of leading edge intervals later 16 sample intervals thereafter Most UARTs will actually sample the middle of the start bit (eight sample periods after the leading edge is recognized) and verify that it is low in case the detected leading edge was just a glitch. Some UARTs will also take multiple samples in the middle of the bit time (i.e, at 23, 24, and 25 in the diagram above) and set error flags for noise if they don't all match. Many application notes on implementing software UARTs, including the Microchip ap notes, suggest sampling at two times the bit rate. This results in the following: ----- /-------------\-/-------------\-/-------------\-/---- | start bit / data bit 0 X data bit 1 X data bit 2 X |--------------/---------------/-\-------------/-\-------------/-\---- ------------- /-------------\-/-------------\-/-------------\- | start bit / data bit 0 X data bit 1 X data bit 2 X |--------------/---------------/-\-------------/-\-------------/- | | | | | 0 1 2 3 4 5 6 7 8 ^ ^ ^ ^ ^ start bit detected first data bit subsequent data within first 1/2 bit sampled 2 bits sampled every time of leading edge intervals later 2 sample intervals thereafter This results in a 1/2 bit time uncertainty regarding when the start bit actually arrived. As a consequence the data bit sampling can occur any time within the first half of the data bit, including right at the leading edge. This allows no margin for rate mismatch. An alternative would be to sample the first data bit three sample periods after the start bit is detected, and every two sample periods thereafter. This is no better as the window is then from the middle to the end of the data bit, so the bits could be sampled right at the trailing edge, again allowing no margin for rate mismatch. The Microchip ap note does at least suggest waiting 1.25 bit times from the leading edge of the start bit to sample the first data bit, which results in the sample window being in the middle 50% of the bit. That's great unless you want to do full duplex serial and use the same time base for transmit. Since you can't get a 1.25 bit time delay using a 0.5 bit time timebase, you maintain proper transmitter timing during that 1.25 bit time delay. The correct solution (IMHO) is to sample at 3 times the bit rate: ----- /------------\-/------------\-/------------\-/----------- | start bit / data bit 0 X data bit 1 X data bit 2 X |-------------/--------------/-\------------/-\------------/-\----------- ---------- /------------\-/------------\-/------------\-/------- | start bit / data bit 0 X data bit 1 X data bit 2 X |-------------/--------------/-\------------/-\------------/-\------- | | | | | 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 ^ ^ ^ ^ ^ start bit detected first data bit subsequent data within first 1/3 bit sampled 4 bits sampled every time of leading edge intervals later 3 sample intervals thereafter As you can see, this reduces the uncertainty of the timing of the start bit to 1/3 of a bit time, and guarantees that the sampling of the data bits will occur within the middle 1/3 of the bit time, thus providing better tolerance to speed variation than the 1/2 bit time scheme provides (even with the 1.25 bit time delay). It also uses fewer CPU cycles than would be required to sample at 4 times the bit rate. I've implemented this scheme on a PIC16C84 and it seems to work quite well. I use the RTCC timer to generate interrupts at three times the bit rate, and the interrupt routine has simple receive and transmit state machines to do the work. I'll make the code available after I do some more testing.