CD-changer emulator over serial to use whit mp3 players.

Following the documentation here http://q1.se/cdcemu/details.php i have come to the conclusion that it's not to hard to write a Arduino program for this, I just need a little help on the way whit it.
(I have programing knowledge from before i have done a few school projects whit embedded systems, also played around whit an accelerometer and printed out a DFT graph for a signal analysis course.)

According to the text we have the following pins i need:
Pin 1 = CD-C data line. (you need to transfer the bytes on this line) The TX on arduino
Pin 5 = RM Data (this line has data back from the head unit) The RX on arduino
Pin 4 = CD-C strobe (you need to send a 4us pulse after the first byte and last byte of packets) To a digital write on the arduino
Pin 2 = CD-C clock (you need to keep a 8uS clock signal on this line 4us on 4us off) a clock (of what type?).

And the transmission is "RS232 communication in 57600bps with RTS/CTS flow control, half duplex" adding up to a boud of 115200(i think) since "After an initial high(9ms) low(4.5ms) there follows a 32 bit sequence with a 0 encoded as 550us high,550us low and a 1 as 550us high,1.7ms low." would mean there is 2 symbols per bit right?

I guess using the pulseIn() - Arduino Reference pulseIn(RXPin,High) should do the trick for reading the RX signal.

And using digital write whit a delay for the TX, here im not sure what he ment whit "The changer to radio communication transfers the data in bytes msb first, the data is valid at the falling clock edge and a low pulse of one half clock period is sent after the first and the last byte of the transfer on the sync line..The clock period is around 8us." If some one could explain this to me i would be really happy.

And i don't have the "Most signifikant bit last" and "Least signifikant bit last" in code theory all figured out so i need some pointers on that as well.

Tl DR:
1.RS232 communication in 57600bps with RTS/CTS flow control, half duplex does this mean the baud rate is 115200 since there is 2 symbols per bit?

  1. It needs a clock of 4 µs high and 4 µs low, What kind of timer would be best.

  2. Upon writing to the radio "data is valid at the falling clock edge" i have no idea what he means by that could some one explain?

  3. I don't have the "Most signifikant bit last" and "Least signifikant bit last" in code theory all figured out so i need some pointers on that as well.

  4. Am I right to asume pulseIn(RXPin,High) should do the trick if "This remote control signal is pulse width modulated,the dataline is active high."

I searched high and low for a similar solution - turns out I was overthinking it based on the same information. The clock is not critical at all - you can actually just bitbang the data packet significantly slower. - in fact at "digitalWrite" speeds.

I initially went off on multiple tangents using timers and port manipulation and also trying to make it work using the SPI library. The answer was really simple - at least one that works for me.

/*
Basic Panasonic CQ-FX55LEN (and similar) CD Changer emulator
Steve Hennerley 2017

Requires 3 IO Pins - tested on ATMEGA 328P 16MHz

//TODO - implememnt CDC - headunit remote control 

*/
const int SCK_pin = 13; // DIN Pin 2 - Clock
const int MOSI_pin = 11;  //DIN Pin 1 - Data
const int STR_pin = 8;  // DIM Pin 4 - Strobe


//dispData - 0xCB, <disc>, <track>, <min>, <sec>, <state>, <unknown>, 0xc3, (additional zero bytes for padding between packets)
//Can all be zeros apart from the 0xCB at the start and the 0xC3 at the end
// Note that you can substitute 0xC3 for 0xD3 and the head unit thinks an MD Changer is installed
byte dispData[] = { 0xCB,0x00,0x00,0x00,0x00,0x00,0x00,0xd3,0x00,0x00,0x00,0x00 };

void setup()
{
	pinMode(SCK_pin, OUTPUT);
	pinMode(MOSI_pin, OUTPUT);	
	pinMode(STR_pin, OUTPUT);

	digitalWrite(SCK_pin, HIGH);
	digitalWrite(MOSI_pin, HIGH);
	digitalWrite(STR_pin, HIGH);
}

void loop()
{	
	for (int z = 0; z <= sizeof(dispData); z++) {  //Loop through all the bytes in the byte array
		bitBang(dispData[z]); // Transmit (bitbang) the data
	 		if ((z == 0)  || z == sizeof(dispData) ) {  //if we are after the first byte or after the last
			digitalWrite(STR_pin, LOW);		//set strobe - it doesn't seem to matter if we have the extra padding bytes
		}
				}
}


byte bitBang(byte _send)  //Bitbang the data
//TODO: change for direct port manipulation (uC specific) - may not be needed though
// becuase it seems like it works even with the very slow speed of the digitalWrite
{
	digitalWrite(STR_pin, HIGH); //reset strobe if low
		for (int i = 0; i<8; i++)  // There are 8 bits in a byte
	{
		digitalWrite(MOSI_pin, !(bitRead(_send, 7-i)));    // Set Data - 7-i to send MSB first
		digitalWrite(SCK_pin, LOW);                  // SCK high
		digitalWrite(SCK_pin, HIGH);                   // SCK low
	}
	
}