I started out with the Propeller Education Kit. I added an RCA breadboard converter that I got from Parallax a while ago while working on Propeddle and L-Star (I don't think they carry the RCA plug breadboard converters anymore, that's a shame. But they still have the PE kit I think, and they just announced the new Propeller FLiP which makes breadboarding even easier).
I also added a small circuit based on a schematic that I found online:
The S/PDIF (coax) input signal is an unbalanced signal with about 0.5V peak-to-peak. It's terminated with a 75 ohm resistor conforming to the standard (75 ohm input impedance; note: the photo shows a 100 ohm resistor, that worked fine too). Then the signal goes through a capacitor which acts as a DC decoupler. Then the signal is pulled halfway between the positive and negative supply voltage of a 74HC04 inverter port using a voltage divider made of two 10K resistors (the photo at the top shows a potentiometer to adjust the input voltage but this turned out to be unnecessary). The first inverter acts as an inverting amplifier to digitize the signal so it can go into the Propeller.
The two inverters that follow, with the R/C networks at their inputs, generate delayed versions of the signal at P0. I didn't run the numbers and I don't want to connect my oscilloscope to verify it (it's buried in the garage), but my source tells me the each of the ports-with-RC-circuits (between P0 and P1, and between P1 and P2) generates a 60ns delay, so a total of about 120ns.
The highest frequency input that we want to accept is based on a 48kHz sample frequency. That means in the worst-case scenario, there are 48000 full frames of data per second on the input. Each frame is 2 subframes and each subframe is 32 bits so that's 48000 * 32 * 2 bits per second, that's a clock frequency of 3.072MHz. Since there can be up to two biphase bits per data bit, the minimum length of one biphase pulse may only be 162.7 ns (give or take, with jitter).
So the delay is shorter than the shortest bit time, and that's important. By performing an XOR on the original input and its delayed version, you can get a signal that represents each flank in the original signal by a short pulse. This takes away a big problem with the decoding: in S/PDIF the level of the signal is irrelevant, but the Propeller has to know what the state of the signal is in order to wait for it to change. By XOR'ing the signal and its delayed (noninverted) version (and by keeping the delay under the length of the shortest expected input pulse length of 162ns), the signal that the software would have to deal with, is always LOW when the S/PDIF signal stays the same, and HIGH for 120ns when the input signal changes.
During one bit clock of the original signal, two pulses can be seen on the output of the XOR for each "1" bit, and one pulse can be seen for each "0" bit. During preambles, the signal stays the same for 3 biphase bit periods so we won't see any pulses for longer than that.
I ran a couple of tests with this, and tried to put some assembly code together to verify (sort of) that this was a usable concept.
First I wrote a short PASM program to light up one LED when the signal was high and another LED when the signal was low. On an S/PDIF signal that was basically digital silence, the LEDS were equally bright, as expected.
Then I wrote a short PASM program to test pins 0 and 2 at the same time, using the "TEST maskP2P0, INA WC" instruction where maskP2P0 was set to %101. This tests whether pins 0 and 2 are high, and sets the carry flag if the parity of the result is odd. In other words: it tests whether either pin 0 is low and pin 2 is high, or pin 0 is high and pin 2 is low (basically an XOR function). I then used the MUXC and MUXNC instructions to make one LED light up when the carry flag was set, and the other one when the carry flag was cleared. It was clear to see that one of the LEDs was brighter than the other.
So that works! But now... How to write...
Read more »