I'm working on a project that involves connecting directly from the TRS jack of an iPhone to a SPI port on a microcontroller.

So the iPhone is the master and the microcontroller is the slave

So let's say the left speaker channel of the iPhone is responsible for generating clock signals

Now how do I transmit for example a single ASCII byte 'A' from the master to the slave?

I can see that each time the clock edge rises ( let's say passes zero ), both master and slave read off a new bit -- whatever the state of the respective MISO/MOSI

But how to byte-align?

Binary for 'A' is 0100 0001

How do we distinguish that leading 0 from the silence that preceded?

It seems to me that a sensible protocol would be to use 0xFF or something as a start Sentinel, and have the next byte dictate the number of bytes ( between 1 and 256 ) in the packet that is to come.

And then these bytes get sent one after the other, may be followed by a parity byte.

Maybe each byte would have parity bit...?

As soon as this ' packet ' has arrived, the decoder could start looking for another start Sentinel.

So that's how I would go about designing SPI. so I'm trying to find some documentation that tells me how it is actually done.

But I'm getting really frustrated bouncing around Google / Wikipedia / IRC

Is there someone out there who understands this protocol, and wouldn't mind giving me a really simple example usage -- sending the single character 'A' via SPI

  • 1
    \$\begingroup\$ I'm not sure how easy this will be to do. The audio output from an iPhone (and basically every other headphone-jack) is both AC-coupled, and has filters that block frequencies above 20Khz and below 20Hz. \$\endgroup\$ Apr 26 '12 at 5:27
  • 1
    \$\begingroup\$ You may have to look into 8b/10b encoding, to achieve a proper DC balance, due to the AC-coupled nature of the headphone interface. Also, your voltage levels will likely need some thresholding and level-translation. You will not be able to just plug wire the MCU directly onto the headphone connector. \$\endgroup\$ Apr 26 '12 at 5:29
  • \$\begingroup\$ Lastly, I would think this would be much easier to do with bit-banged SPI, rather then trying to finangle a MCU's onboard SPI module into handling the unusual start and stop conditions. By doing the deciding in software, you could have much finer control over the behaviour of the decoder, and handle start and stop conditions more cleanly. \$\endgroup\$ Apr 26 '12 at 5:31
  • \$\begingroup\$ Incidentally, 0xAA and 0x55 are more commonly used for frame synchronization then ascii "A". 0xAA is 10101010 in binary, and 0x55 is 01010101. The repeating patterns make them easy to recognize. \$\endgroup\$ Apr 26 '12 at 5:33

SPI devices also typically have a chip-select signal (sometimes referred to as a frame sync) that is used to multiplex devices on a single SPI bus. Thus, SPI is often referred to as a 3-wire or 4-wire interface (MISO, MOSI, CS, and CLK; for unidirectional devices, either MISO or MOSI can be omitted). A frame is typically assumed to start at the first bit after the chip-select signal is asserted, but every device has its own protocol. You'll need to adhere to whatever the other side of the link expects.

  • \$\begingroup\$ Does the microcontroller have an I²C port? Maybe that would be better? "arbitrarily low clock frequencies are also allowed." \$\endgroup\$
    – endolith
    Mar 29 '12 at 19:53
  • \$\begingroup\$ @endolith - Assuming he does not need addressing or anything else of that nature, I think a simple data and clock architecture would be much simpler. It's not really a pure SPI implementation at that point, but it should be easy to work. \$\endgroup\$ Apr 26 '12 at 5:35

SPI transmits data on clock edges. Whether it's the rising or falling edge is determined by what's doing the sending and/or receiving. Since that's the case, you should be able to use your clock pulses as your frame.

Most devices will have MISO, MOSI, CLK, and CS. In slave mode you can ground the CS and always have the microcontroller "listen" for any SPI transmission. The iPhone is the master and controls the MOSI and CLK. It shouldn't matter what the iPhone does to with MOSI output when the clock is not running since the slave microcontroller won't read in data. In the end, all that matters is that the MOSI output data is valid on the correct clock edges.

You didn't specify what microcontroller you're using, but Atmel has a good app note about their implementation of SPI in their AVR series. You might consider and interrupt based scheme to poll the SPI data.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.