SPI protocol
I've just been given a challenge to program a system with the Spin Stamp to communicate with a master device using SPI protocol, but I don't have a clue where to begin. Can anyone help me understand the SPI protocol and methods of achieving this with the Spin Stamp?

Comments
For the spin stamp, you can achieve higher input clockfrequency if you
program the SPI slave driver in assembly. I am not sure up to which
input frequency but I guess >300kHz should be possible.
regards peter
The project is a digitally tunable filter, using an SPI interface to be controlled. Previously, I implemented serial communication via an RS232 port debugged through a hyperterminal program in order to issue commands and receive responses. The most common commands would be "Tune", and "Identify Current Frequency". Logically the latter of the two returns an integer containing the frequency to which the filter is tuned to, for instance "357 MHz". I have also created a version that scrapped the RS232 and replaced it with a 4x4 matrix keypad and an LCD screen. The latest version incorporates an ethernet card and is tuned via a local HTML-based page which displays the part/serial numbers, the current frequency, and a firmware version. Now, I'm interfacing the original RS232 model with an SPI instead of the 9pin connector previously used, and can't decide how to arrange the command structure. Any suggestions?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
~Some men see things as they are and ask "why?"
I dream of things that never were and ask "why not?"~
http://www.amis.com/pdf/ulp_memory/serial_srams/N256S08xxHDA_ds.pdf
- What clock edge is used for shifting your simulated shift register. Or the read and write shifts may be phase shifted so both can be specified separately.
- What polarity the clock pin is.
- What polarity the data pins are.
- What bit order is used.
- How many bits in the word.
- How the above differ when the port is used as a master or a slave.
- What the maximum clock rate is. 1-10 MHz is common but others have no problem at 100 MHz. This is only a maximum though, not what you'll actually be using.
You then need to specify what sequences will be used for reading writing the registers, addressing and the likes.
As you can see, there is no hard spec. About the only things that are a given is that the clock, read data and write data are all separate pins. ie: With SPI, the devices have free reign to have any protocol they like. This is why a chip select line is important when many devices are on the one bus.
Evan
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
~Some men see things as they are and ask "why?"
I dream of things that never were and ask "why not?"~
http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
~Some men see things as they are and ask "why?"
I dream of things that never were and ask "why not?"~
Leon
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Amateur radio callsign: G1HSM
Suzuki SV1000S motorcycle
··· I'm using SPI to communicate to the CAN controller in my own project.
····· http://propcan.moraco.us/
··· I had to start somewhere to learn how it worked as well.· One of the most
··· useful starting points I found is an object found in this forum called
··· the SPI Engine (crafted by·Beau Schwabe·of Parallax).· This is fully
··· parameterized so it works with nearly any SPI device when properly
··· configured to match the device (even your own ;-)
··· I took this driver and needed much more performance so I created
··· a specialized driver based on the SPI Engine.· On my way to a
··· version which meets my performance needs I dropped a copy
··· to the Propeller Object Exchange.·· See:
····· http://obex.parallax.com/objects/227/
····(Note the object here is NOT the final version.)
··· During my development of the driver and other drivers I
··· blogged about what I was changing and why I needed the
··· performance and how I got there.· This may be of some
··· use to you since there is both discussion and there are
··· waveforms showing captures of the actual SPI traffic.
··· See:· http://propcandev.blogspot.com/
····I've found that this group here in the propeller forum has
··· examples for nearly anything I've tried so I thought I'd
··· "remember them to you".·· I hope this helps.
··· One more thing... every time I've branched into a new
··· area wanting to interface to some new-to-me device
··· I've been able to find starting code either in the object
··· exchange, or this forum or pointed to by the propeller
··· Wiki.··You probably·don't want to miss the chance to get
··· a leg up by using code found from these sources.· I am
····constantly amazed by the open contributions from this
··· great group of people.
Regards,
Stephen, KZ0Q
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
·
{******************************************Master SPI********************************************** **************************************************************************************************} CON BitTime= 80_000_000/800_000 'Clock frequency for a single edge 400KHz appears to be MAX PUB ReadXSwitch(clk, data, ss, dest_) 'Reads the extended switches dest:=dest_ 'Save the destination flag:=@flag 'Save the destination clkMask:= |<clk 'and the pin numbers dataMask:= |<data ssMask:= |<SS cognew(@entry, 0) 'Launch the cog, but don't wait for result PUB IsBusy 'Returns the status of the SPI Master return flag DAT org 0 entry '__________________________________________Initialization_________________________________________ muxz outa,SSMask 'Make sure the SS is low muxz outa, ClkMask 'Make sure the clock is low too muxnz dira, SSMask 'SS is an output muxnz dira, ClkMask 'Clock is an output muxz dira, DataMask 'Data is an input movd rxIndirect, #switch0 'Look at the first switch mov bit, #1 'and first bit mov longs, #2 mov switch0, #0 'Clear the data registers mov switch1, #0 'Clear the data registers '___________________________________________Assert SS______________________________________________ mov bitDelay, cnt 'Get the current time add bitDelay, bitPeriod 'Add the time to wait for the first clock call #WaitBit 'Wait a couple of bits for the Slave to see SS low call #WaitBit muxnz outa, SSMask 'SS asserted call #WaitBit 'Wait a couple of bits for the Slave to see SS high call #WaitBit '__________________________________________Receive Loop____________________________________________ Loop muxnz outa, ClkMask 'Set the clock high call #WaitBit 'Wait a clock test DataMask, ina wc 'What is the bit? muxz outa, ClkMask 'Now low to read bit call #WaitBit 'Wait a clock RxIndirect if_c or 0, bit 'Toss this data on shl bit, #1 wz 'Next bit over if_z mov bit, #1 'Restart if second long if_z movd RxIndirect, #switch1 'and point to it if_nz jmp #Loop djnz longs, #Loop wz 'Until done '____________________________________________Idle SS_______________________________________________ muxnz outa, SSMask 'Z flag up, push SS down '___________________________________________Store Data_____________________________________________ wrlong switch0, dest 'save the low long add dest, #4 'Next long wrlong switch1, dest 'Now the high long mov dest, #0 'We need a zero to write wrlong dest, flag 'So write the zero to flag '______________________________________________Stop________________________________________________ cogid dest 'Get our cog# cogstop dest 'and stop it '********************************************WaitBit*********************************************** WaitBit waitcnt bitdelay, bitPeriod 'Wait for it WaitBit_Ret ret '********************************************Variables********************************************* dest long 0 'The address of the SPI structure flag long 0 'The address of the XFlag ClkMask long 0 'Which pin is clock on DataMask long 0 'Which pin is the data on SSMask long 0 'And the slave select BitPeriod long BitTime 'How long each bit is bitDelay res 1 'Used for waitcount delay switch0 res 1 'Switch data as it is put together switch1 res 1 bit res 1 'Which bit is being read longs res 1 'How many longs have been read