Four wire SPI functions?
Mauvai
Posts: 45
Is there any support for 4 wire SPI? The shift_in() and shift_out() functions seem to only do 3 wires, no option for a second data pin... I am aware that there is a spi object in propware, but I don't even know how to begin finding if it does 4 wire....
Comments
Quote: Jens-Michael Gross
Shouldn't use 4-wire SPI mode when you're the only master in the system.
4-wire mode uses STE as input only. It does not control the slave (chip select) as every slave needs its own chip select. This is done by GPIO by your software.
STE in master mode switches the USCI into slave mode when another master wants the mcu to listen or shut up.
Personally, I think the name '4-wire' was an unlucky choice because many people thing '3 wire' means one bi-directional data line, one clock line and a chip select line,
while '4 wire' means one input, one output, one clock and one chip select.
What is 4 wire spi, if not spi with 4 wires? Clk, mosi, miso, Cs? And why should I not use CS if I have only one master, particularly if the slave device actively requires CS to change? I am aware that the CS should be controlled by GPIO...
Also finally, what do STE and USCI stand for? google turned up nothing....
Thanks
The last post (post 70) in the thread below has a SimpleIDE SPI C-library I wrote along with a number of demo programs. It can do both bidirectional I/O and separate MISO/MOSI pins. Earlier posts show the full learning experience.
Tom
http://forums.parallax.com/showthread.php/157441-Can-SPI-in-Simple-Libraries-be-speeded-up?p=1315065#post1315065
If you prefer to deal with the Simple Library:
The shift_out/shift_in functions take the data pin as the first parameter. You could use 1000 wire SPI communication if the Propeller had 1000 different pins. If you want to use dedicated pins for input and output, just call shift_out(x, ...) and shift_in(y, ....) where x and y are different pin numbers.
nCS does not belong to a "4th wire" spi standard, nCS is any GPIO that you use to set low before you start a 3wire SPI transfer.
Maybe I should be clearer... I don't have any experience with SPI. The part I am using requires that the read from it, I must shift out the address i am reading from, and then a 0xFF byte for each byte I wish to read (more or less) - each time i shift out a 0xFF on the Mosi, the Miso simultaneously returns the byte to be read. (this is for block read). Can i achieve this using shift in? Or the other spi library for that matter? It seems that shift in has no option to take a Miso pin to shift out the 0xFF byte.
I also have no idea if what the device is doing is the standard, or is really weird....
You are understandably confused, don't worry.
The methods "shift_*" are written with those names for a reason. Many CPUs that have hardware SPI communication don't have separate in/out functions - only one function. For every bit that is shifted out, another bit is shifted in. This shifting is so common, in fact, that many datasheets will tell you to send 0xFF because they're assuming you have to send something. What they really mean is "we don't care what you send, just give the device 8 clock ticks and we'll send you 8 bits of data on the MISO line and any data you might or might not send via MOSI is ignored."
Because of this shifting, most SPI masters theoretically support simultaneous input/output - but I haven't seen any slaves that actually utilize it.
You can do customs make one that shift out $00 of $ff after the initial header etc.
Or simple just toggle clk line and don't read and toggle data at all.
But I guess you are asking if shift-in in C can do it.
If you use spi library, it probably only have an option to toggle clk line if you tell it to send a 8bit byte
These bytes should be don't_care for the slave device, but users mostly send 0 or $ff
My guess for prop ware would be you need the slightly cryptic
read_par (T * par ) const : Read the value that the SPI cog just shifted in.
So I was printing with print("\nStatus word: %X", reg);
Knowing damn well %X doesn't do what I expect it to in prop code... switched it to %x and it works fine with shift_in(). Correct return values.
Thank you all, and apologies for being stupid.
To answer the lingering question on how PropWare deals with reads, 0xFF is always sent out on MOSI during a read. If a slave device requires anything other than 0xFF during a read routine, the source code would have to be modified. If that ever comes up, I hope someone will let me know and I could add an option to make this configurable.
The last line of code in the send function leaves MOSI in the high state.
I thought Send always also received a byte, which was what this meant, in your LIBs ?
read_par (T * par ) const : Read the value that the SPI cog just shifted in.
If send also clocks in data, then users have the choice of ignore, and they can send anything for Rx.
There are many Slave IO expanders that do full duplex, it is mainly memories that are essentially half-duplex.
If you have a specific device in mind that uses it, you could create an issue for it and I can make it happen. The issue doesn't need to be anything fancy - just a brief title and make sure the part number is in the description somewhere.
--Edit--
Sorry - didn't realize you have to be signed into github to create an issue. If you don't have a GitHub account, just reply or PM me with the details and I'll create the issue.
When the msbit goes out and new bit get shifted in
if you clock it 8 times, the buffer byte have gotten sent out and it now holds a completely new value, that is the 8bit input data
Most hardware SPI now-a-day use two bytes (example MSP430 USCI) and the forced-writes to be able to read is kind of just still there.
One example device is OnSemi NCV7240, but even the lowly HEF4021 used as a SPI Keypad Scanner, needs Duplex. All MCU's with HW SPI operate that in Duplex.
Duplex should be a safe-superset of SPI, if you do not care what just came in when you wrote, just ignore it.
I just wanted to say, I also own a device that uses simultaneous read-write.
It's an automotive g sensor for airbags, called SMB460.
I've already implemented a bare minimum driver for it in SPIN that time, and now I'm trying out propeller C, and was very surprised the standard library only have separate shift_in and shift_out functions.
Daniel
But I didn't. An issue has been created now - if you want to follow the progress in PropWare, see issue #28. It will be a while before I get to it - I have some other items that I think are higher priority (proper SD card support)
If someone would need a quick solution, here's how I implemented it quickly.
Please note, it doesn't contain delays. I can do that so, because my device is very fast, serial clock can be driven at 8MHz. If your device is not capable for such high speeds, delays have to inserted.
As you can see in the code it will simply send 16 bits that is given as tx, and will return with the answer. It won't release the bus, you have to add that several lines if your application needs it.