Today's Message Index:
----------------------
1. 12:02 PM - CDx-828? (Ethan)
2. 06:15 PM - Re: CDx-828? (Matt Dralle)
Message 1
INDEX | Back to Main INDEX |
NEXT | Skip to NEXT Message |
LIST | Reply to LIST Regarding this Message |
SENDER | Reply to SENDER Regarding this Message |
|
--> XDP4000X-List message posted by: Ethan <telmnstr@757.org>
Anyone know of any CDX-828 or other Sony digital Unilink changers for sale
cheap? My attempts at getting the ?CDX-725? firmware to trigger the 210EQ
to go digital didn't go so well. Then a friend stepped on one of the
boards from my CDX-725 and cracked it. Ooops.
My only real goal is to capture the unilink traffic so I can make the open
source GNUnilink adaptor tell the 210EQ that it's digital, so I can use a
DVD player's digital output with the 210EQ.
Granted, I could just buy a better DVD player that has quality analog
outputs, but no adventure in that.
--
// Ethan O'Toole
// http://users.757.org/~ethan
Message 2
INDEX | Back to Main INDEX |
PREVIOUS | Skip to PREVIOUS Message |
NEXT | Skip to NEXT Message |
LIST | Reply to LIST Regarding this Message |
SENDER | Reply to SENDER Regarding this Message |
|
--> XDP4000X-List message posted by: Matt Dralle <dralle@matronics.com>
At 12:01 PM 11/29/2005 Tuesday, you wrote:
>--> XDP4000X-List message posted by: Ethan <telmnstr@757.org>
>
>
>Anyone know of any CDX-828 or other Sony digital Unilink changers for sale
>cheap? My attempts at getting the ?CDX-725? firmware to trigger the 210EQ
>to go digital didn't go so well. Then a friend stepped on one of the
>boards from my CDX-725 and cracked it. Ooops.
>
>My only real goal is to capture the unilink traffic so I can make the open
>source GNUnilink adaptor tell the 210EQ that it's digital, so I can use a
>DVD player's digital output with the 210EQ.
>
>Granted, I could just buy a better DVD player that has quality analog
>outputs, but no adventure in that.
>
>--
> // Ethan O'Toole
> // http://users.757.org/~ethan
Ethan,
Below is a code snippet from my 8051 controller-based Full Unilink Slave Emulation.
In it, you will find all the great mysteries of proper Unilink initialization.
Basically, there is a single bit in one of the init bytes that signals
the head unit whether the input will be analog or digital. This is commented
well in my code below. I also included a couple of other nifty things that make
my Unilink emulation 100% Sony compatible such as the Slave Break device calculation.
Party on,
Matt Dralle
// If Packet Checksum is
good, process it...
if( packet_checksum( PacketIn, PacketPtrIn, IN_INTERRUPT ) )
{
// Here we got a Master Time
Poll, but we hadn't yet receved
// an Anyone command. This
indicates that the deck was soft-
// powered down, and the
master has just started re-polling
// slaves without initializing
the bus. If we don't answer
// any Master polls that
are sent to us within 1 retry (2 requests)
// the Master will reinit
the bus and all addresses will need
// to be reassiged.
if( !AppointsComplete ) // Split these Ifs Statements
to speed up Normal Operation
{ // xx 10 01 12 xx 00
- Time Poll to Slave XX
if( Valid_EEPROM_Data && (strncmp( PacketIn + 1, "\020\001\022", 3 )
== 0) )
{
AppointsComplete = 1; // We're Done Init'ing our
Slaves
LinkOn = ON; // Turn on next external
Slave's BusOn line
}
}
if( !AppointsComplete )
{ // Anyone? Command from
Master
// 18 10 01 02 2b 00
if( strncmp( PacketIn, "\030\020\001\002\053\000", SHORT ) == 0 )
{
// Skip Slaves that are disabled.
while( !Slave[ SlavePtr ].Enabled ) SlavePtr++;
// Got an Anyone command
so forget about any
// previously assigned addresses
from the Master.
Valid_EEPROM_Data = 0;
PacketOut[ DST ] = MASTER;
PacketOut[ CMD1 ] = 0x8c; // Init string Command
switch( Slave[ SlavePtr ].Group )
{
/*
Sample Slave Inits:
DA SA
C1 C2 P1 D1 D2 D3 D4 P2 ZB
--------------------------------
Phatbox: 10 31
8c 00 cd 04 a8 1f af 47 00 HD-Based Player
Sony CDX-848X 10 31
8c 00 cd 0c a8 1f af 4f 00 10-disc CD Changer - Digital Mode
Sony CDX-848X 10 31
8c 00 cd 04 a8 1f af 47 00 10-disc CD Changer - Analog Mode
Sony CDX-606 10 31
8c a0 6d 04 a8 25 a0 de 00 10-disc CD Changer - Analog only
Sony MDX-40 10 d2
8c 00 6e 04 48 00 00 ba 00 4-disc MD Changer
XA-300 10 81
8c 00 1d 00 00 40 00 5d 00 AUX Input Slave on XA-300
10 31
8c 00 cd 04 a8 20 a0 39 00 CD 1 Input Slave on XA-300
10 32
8c 00 ce 04 a8 20 a0 3a 00 CD 2 Input Slave on XA-300
10 33
8c 00 cf 04 a8 20 a0 3b 00 CD 3 Input Slave on XA-300
*/
case GROUP_TUNER: // Load Tuner Init Profile
PacketOut[ SRC ] = GROUP_TUNER;
PacketOut[ CMD2 ] = 0x00; //
PacketOut[ D1 ] = 0x0d; // xxxx1xxx = Digital
Output, xxxx0xxx = Analog Output
PacketOut[ D2 ] = 0x20; // HIGH Nib = Internal/External
(xx01 = Int, xx10 = Ext)
PacketOut[ D3 ] = 0x10; // HIGN Nib = Custom File
(xx01 = Yes, xx10 = No)
PacketOut[ D4 ] = 0xaf; // HIGH Nib = Number of
discs supported (0 = 1 disc), LOW Nib = Extended Init (0=N 0xf=Y)
break;
case GROUP_CASS: // Load Cassette Changer
Init Profile
PacketOut[ SRC ] = GROUP_CASS;
PacketOut[ CMD2 ] = 0x00; //
PacketOut[ D1 ] = 0x0d; // xxxx1xxx = Digital
Output, xxxx0xxx = Analog Output
PacketOut[ D2 ] = 0x20; // HIGH Nib = Internal/External
(xx01 = Int, xx10 = Ext)
PacketOut[ D3 ] = 0x10; // HIGN Nib = Custom File
(xx01 = Yes, xx10 = No)
PacketOut[ D4 ] = 0xaf; // HIGH Nib = Number of
discs supported (0 = 1 disc), LOW Nib = Extended Init (0=N 0xf=Y)
break;
case GROUP_MD: // Load MD Changer Init
Profile
PacketOut[ SRC ] = GROUP_MD;
PacketOut[ CMD2 ] = 0x00; //
PacketOut[ D1 ] = 0x04; // xxxx1xxx = Digital
Output, xxxx0xxx = Analog Output
PacketOut[ D2 ] = 0x48; // HIGH Nib = Internal/External
(xx01 = Int, xx10 = Ext)
PacketOut[ D3 ] = 0x1f; // HIGN Nib = Custom File
(xx01 = Yes, xx10 = No)
PacketOut[ D4 ] = 0xa0; // HIGH Nib = Number of
discs supported (0 = 1 disc), LOW Nib = Extended Init (0=N 0xf=Y)
break;
case GROUP_AUX: // Load Auxiliary Init Profile
PacketOut[ SRC ] = GROUP_AUX;
PacketOut[ CMD2 ] = 0x00; //
PacketOut[ D1 ] = 0x0d; // xxxx1xxx = Digital
Output, xxxx0xxx = Analog Output
PacketOut[ D2 ] = 0x20; // HIGH Nib = Internal/External
(xx01 = Int, xx10 = Ext)
PacketOut[ D3 ] = 0x10; // HIGN Nib = Custom File
(xx01 = Yes, xx10 = No)
PacketOut[ D4 ] = 0xaf; // HIGH Nib = Number of
discs supported (0 = 1 disc), LOW Nib = Extended Init (0=N 0xf=Y)
break;
case GROUP_CD:
default: // Load CD Changer Init
Profile
PacketOut[ SRC ] = GROUP_CD;
PacketOut[ CMD2 ] = 0x00; //
PacketOut[ D1 ] = 0x04; // xxxx1xxx = Digital
Output, xxxx0xxx = Analog Output
PacketOut[ D2 ] = 0xa8; // HIGH Nib = Internal/External
(xx01 = Int, xx10 = Ext)
PacketOut[ D3 ] = 0x1f; // HIGN Nib = Custom File
(xx01 = Yes, xx10 = No)
PacketOut[ D4 ] = 0xaf; // HIGH Nib = Number of
discs supported (0 = 1 disc), LOW Nib = Extended Init (0=N 0xf=Y)
break;
}
PacketLenOut = MEDIUM;
add_checksum(); // Overlay calculated check
sum(s)
UnilinkDataOutEnable(); // Put SPI MISO pin into
Push-Pull (normal) mode
SFRPAGE = SPI0_PAGE;
SPI0DAT = PacketOut[0];
PacketPtrOut = 1;
}
// Appoint - Command From
Master (Assign slave new Address & Serial)
// 10 02
else if( strncmp( PacketIn + 1, "\020\002", 2 ) == 0 )
{
// Master assigned new address
Slave[ SlavePtr ].Address = PacketIn[ DST ];
// Master assigned new Device
number
Slave[ SlavePtr ].Device = PacketIn[ CMD2 ];
PacketOut[ SRC ] = PacketIn[ DST ];
PacketLenOut = MEDIUM;
add_checksum(); // Overlay calculated check
sum(s)
UnilinkDataOutEnable(); // Put SPI MISO pin into
Push-Pull (normal) mode
SFRPAGE = SPI0_PAGE;
SPI0DAT = PacketOut[0];
PacketPtrOut = 1;
SlavePtr++;
}
// Appoint Adtl Info Request
From Master to SPECIFIC SLAVE
// Slave responds with additional
information. This appears
// to be triggered by bit
0000x000 in the D4 byte of the
// Appoint initialization
string.
// 10 01 05
else if( strncmp( PacketIn + 1, "\020\001\005", 3 ) == 0 )
{
PacketOut[ DST ] = MASTER;
PacketOut[ SRC ] = Slave[ SlavePtr - 1 ].Address;
PacketOut[ CMD1 ] = 0x8d; // Additional Init string
Command
PacketOut[ CMD2 ] = 0xf0; //
PacketOut[ D1 ] = 0x00; //
PacketOut[ D2 ] = 0x00; //
PacketOut[ D3 ] = 0x00; //
PacketOut[ D4 ] = 0x00; //
PacketLenOut = MEDIUM;
add_checksum(); // Overlay calculated check
sum(s)
UnilinkDataOutEnable(); // Put SPI MISO pin into
Push-Pull (normal) mode
SFRPAGE = SPI0_PAGE;
SPI0DAT = PacketOut[0];
PacketPtrOut = 1;
}
// Appoint End From Master
(Type 1) to BROADCAST
// 18 10 01 04 2d 00
else if( strncmp( PacketIn, "\030\020\001\004\055\000", 6 ) == 0 )
{
}
// Wait for first free slave-transmit
sequence, then enable LinkON
else if( SlavePtr == SLAVE_COUNT && PacketPtrIn == 1 )
{
AppointsComplete = 1; // We're Done Init'ing our
Slaves
LinkOn = ON; // Turn on next external
Slave's BusOn line
Update_EEPROM_Data = 1; // Signal Main() that NV
parameters need to be written out
}
}
else if( PacketIn[ DST ] == BROADCAST ) // Packet's for Broadcast
{
switch( PacketIn[ SRC ] )
{
case MASTER: // From Master
switch( PacketIn[ CMD1 ] )
{
case 0x01: // Master Requests
switch( PacketIn[ CMD2 ] )
{
case 0x15: // Response to a Slave
Break
// Find which slave
did the Slave Break...
for( SlavePtr = 0; SlavePtr < SLAVE_COUNT; SlavePtr++
)
{ // Slave X Response
to Master Poll
if( !Slave[ SlavePtr ].Enabled ) continue;
// Skip Slaves that aren't Enabled
if( Slave[ SlavePtr ].SlaveBreak == SLAVE_BREAK_PENDING
)
{
PacketOut[ DST ] = MASTER;
PacketOut[ SRC ] = BROADCAST;
PacketOut[ CMD1 ] = 0x82;
// Slave Break Response String
PacketOut[ CMD2 ] = 0x00;
//
PacketOut[ D1 ] = 0x00; //
PacketOut[ D2 ] = 0x00; //
PacketOut[ D3 ] = 0x00; //
PacketOut[ D4 ] = 0x00; //
// HIGH
Nib of the device number tells us which PacketOut
// byte
to use in a Slave Break response. It also
// will
indicate whether or not the LOW Nib should be
// shifted
left by 4 places or not. The device number
// assigned
by the master at Appoint and is in the
// CMD2,
D1, D2, D3, or D4byte of the PacketOut. Devices
// are
according to the following table:
//
/*
------------------------
---- DEVICE NUMBERS ----
------------------------
Logical Encode Assign Packet_Byte High/Low_Nib
--------------------------------------------------------
0 0x10 0x01 CMD2 (3) H
1 0x20 0x02 CMD2 (3) H
2 0x40 0x04 CMD2 (3) H
3 0x80 0x08 CMD2 (3) H
4 0x01 0x11 CMD2 (3) L
5 0x02 0x12 CMD2 (3) L
6 0x04 0x14 CMD2 (3) L
7 0x08 0x18 CMD2 (3) L
8 0x10 0x21 D1 (5) H
9 0x20 0x22 D1 (5) H
10 0x40 0x24 D1 (5) H
11 0x80 0x28 D1 (5) H
12 0x01 0x31 D1 (5) L
13 0x02 0x32 D1 (5) L
14 0x04 0x34 D1 (5) L
15 0x08 0x38 D1 (5) L
16 0x10 0x41 D2 (6) H
17 0x20 0x42 D2 (6) H
18 0x40 0x44 D2 (6) H
19 0x80 0x48 D2 (6) H
20 0x01 0x51 D2 (6) L
21 0x02 0x52 D2 (6) L
22 0x04 0x54 D2 (6) L
23 0x08 0x58 D2 (6) L
24 0x10 0x61 D3 (7) H
25 0x20 0x62 D3 (7) H
26 0x40 0x64 D3 (7) H
27 0x80 0x68 D3 (7) H
28 0x01 0x71 D3 (7) L
29 0x02 0x72 D3 (7) L
30 0x04 0x74 D3 (7) L
31 0x08 0x78 D3 (7) L
32 0x10 0x81 D4 (8) H
33 0x20 0x82 D4 (8) H
34 0x40 0x84 D4 (8) H
35 0x80 0x88 D4 (8) H
36 0x01 0x91 D4 (8) L
37 0x02 0x92 D4 (8) L
38 0x04 0x94 D4 (8) L
39 0x08 0x98 D4 (8) L */
//
// These
are then mapped into the Slave Break Response Packet as
// follows:
//
/*
00 01 02 03 04 05 06 07 08 09 10
-------------------------------------
01 : 00 00 00 10 PP 00 00 00 00 PP 00
02 : 00 00 00 20 PP 00 00 00 00 PP 00
04 : 00 00 00 40 PP 00 00 00 00 PP 00
08 : 00 00 00 80 PP 00 00 00 00 PP 00
11 : 00 00 00 01 PP 00 00 00 00 PP 00
12 : 00 00 00 02 PP 00 00 00 00 PP 00
14 : 00 00 00 04 PP 00 00 00 00 PP 00
18 : 00 00 00 08 PP 00 00 00 00 PP 00
21 : 00 00 00 00 PP 10 00 00 00 PP 00
22 : 00 00 00 00 PP 20 00 00 00 PP 00
24 : 00 00 00 00 PP 40 00 00 00 PP 00
28 : 00 00 00 00 PP 80 00 00 00 PP 00
31 : 00 00 00 00 PP 01 00 00 00 PP 00
32 : 00 00 00 00 PP 02 00 00 00 PP 00
34 : 00 00 00 00 PP 04 00 00 00 PP 00
38 : 00 00 00 00 PP 08 00 00 00 PP 00
41 : 00 00 00 00 PP 00 10 00 00 PP 00
42 : 00 00 00 00 PP 00 20 00 00 PP 00
44 : 00 00 00 00 PP 00 40 00 00 PP 00
48 : 00 00 00 00 PP 00 80 00 00 PP 00
51 : 00 00 00 00 PP 00 01 00 00 PP 00
52 : 00 00 00 00 PP 00 02 00 00 PP 00
54 : 00 00 00 00 PP 00 04 00 00 PP 00
58 : 00 00 00 00 PP 00 08 00 00 PP 00
61 : 00 00 00 00 PP 00 00 10 00 PP 00
62 : 00 00 00 00 PP 00 00 20 00 PP 00
64 : 00 00 00 00 PP 00 00 40 00 PP 00
68 : 00 00 00 00 PP 00 00 80 00 PP 00
71 : 00 00 00 00 PP 00 00 01 00 PP 00
72 : 00 00 00 00 PP 00 00 02 00 PP 00
74 : 00 00 00 00 PP 00 00 04 00 PP 00
78 : 00 00 00 00 PP 00 00 08 00 PP 00
81 : 00 00 00 00 PP 00 00 00 10 PP 00
82 : 00 00 00 00 PP 00 00 00 20 PP 00
84 : 00 00 00 00 PP 00 00 00 40 PP 00
88 : 00 00 00 00 PP 00 00 00 80 PP 00
91 : 00 00 00 00 PP 00 00 00 01 PP 00
92 : 00 00 00 00 PP 00 00 00 02 PP 00
94 : 00 00 00 00 PP 00 00 00 04 PP 00
98 : 00 00 00 00 PP 00 00 00 08 PP 00 */
//
// For
example, if our Master assigned us device number
//
"0x28", then our Slave Break response PacketOut will be:
//
10 18 82 00 xx 80 00 00 00 xx 00
// The
address "0x41" would be:
//
10 18 82 00 xx 00 10 00 00 xx 00
// The
address "0x32" would be:
//
10 18 82 00 xx 02 00 00 00 xx 00
// Believe
it or not, this one line of code will correctly calculate the
// proper
slave break response device number and stick it in the correct
// byte
in the packet...
PacketOut[ ((Slave[ SlavePtr ].Device & 0xf0)
< 0x20) ? CMD2 : (((Slave[ SlavePtr ].Device & 0xf0) >> 5) + PARITY1) ] = \
(Slave[ SlavePtr ].Device & 0x10)
? (Slave[ SlavePtr ].Device & 0x0f) : ((Slave[ SlavePtr ].Device
// Set
the next phase of the Slavebreak
Slave[ SlavePtr ].SlaveBreak = SLAVE_BREAK_READY;
PacketLenOut = MEDIUM;
add_checksum(); // Overlay
calculated check sum(s)
UnilinkDataOutEnable(); //
Put SPI MISO pin into Push-Pull (normal) mode
SFRPAGE = SPI0_PAGE;
SPI0DAT = PacketOut[0];
PacketPtrOut = 1;
SlavePtr = SLAVE_COUNT; //
Only one Slavebreak at a time!
continue;
}
}
break;
}
break;
}
break;
}
}
else if( PacketIn[ DST ] == MASTER ) // Packet's for the Master
{
}
else
{
for( SlavePtr = 0; SlavePtr < SLAVE_COUNT; SlavePtr++ )
{
if( !Slave[ SlavePtr ].Enabled ) continue; //
Skip Slaves that aren't Enabled
if( PacketIn[ DST ] == Slave[ SlavePtr ].Address )
// Packet's For Slave X
{
switch( PacketIn[ CMD1 ] )
{
case 0x01: // Master-to-Slave Request
// Master Request...
if( Slave[ SlavePtr ].SlaveBreak == SLAVE_BREAK_PENDING )//
Something went wrong on the bus and left us hanging, so clear
{
Slave[ SlavePtr ].SlaveBreak = SLAVE_BREAK_IDLE;
DoSlaveBreak = 0;
}
switch( PacketIn[ CMD2 ] )
{
case 0x12:
// Time Poll Request To Slave X
PacketOut[ DST ] = MASTER;
PacketOut[ SRC ] = Slave[ SlavePtr ].Address;
PacketOut[ CMD1 ] = 0x00;
PacketOut[ CMD2 ] = Slave[ SlavePtr ].Mode;
PacketLenOut = SHORT;
add_checksum();
Slave[ SlavePtr ].SlaveBreak = SLAVE_BREAK_DOTX;
UnilinkDataOutEnable();
// Put SPI MISO pin into Push-Pull (normal) mode
SFRPAGE = SPI0_PAGE;
SPI0DAT = PacketOut[0];
PacketPtrOut = 1;
SlavePtr = SLAVE_COUNT;
// Only one Slavebreak at a time
break;
case 0x13: // Request Time Poll (Master gave us permission
to talk on the bus following our SlaveBreak...)
if( PacketQueueStatusOut == QUEUED && Slave[ SlavePtr
].SlaveBreak == SLAVE_BREAK_READY )
{
memcpy( PacketOut, PacketBufferOut[ PacketQueueOutPost
], PacketLenBufferOut[ PacketQueueOutPost ] );
PacketLenOut = PacketLenBufferOut[ PacketQueueOutPost
];
add_checksum();
Slave[ SlavePtr ].SlaveBreak = SLAVE_BREAK_DOTX;
UnilinkDataOutEnable();
// Put SPI MISO pin into Push-Pull (normal) mode
SFRPAGE = SPI0_PAGE;
SPI0DAT = PacketOut[0];
PacketPtrOut = 1;
SlavePtr = SLAVE_COUNT;
// Only one Slavebreak at a time
if( PacketQueueOutPost < BUFFEROUT ) PacketQueueOutPost++;
else PacketQueueOutPost = 0;
if( PacketQueueOutPost == PacketQueueOutPre )
{
PacketQueueStatusOut = EMPTY;
}
continue;
}
break;
default:
break;
}
break;
default:
break;
}
}
}
}
}
Other Matronics Email List Services
These Email List Services are sponsored solely by Matronics and through the generous Contributions of its members.
-- Please support this service by making your Contribution today! --
|