Main Site Documentation

SPI in 3Pin mode (MISO,MOSI,SCK) and user have control over CS


#1

Does any one know how to set up the SPI configuration for 3 Pin mode.

I am reading ADC where I need total control of CS line.

            SPI.Configuration spiConfig = new SPI.Configuration(
                (Cpu.Pin)USBizi.Pin.IO14, // Chip select pin
                false,      // Active state
                0,          // Setup time (ms)
                0,          // Hold time (ms)
                false,      // Clock idle (low)
                true,       // Edge (rising)
                10000,      // Clock rate (KHz)
                SPI.SPI_module.SPI2); // SPI module

The code above works find but SPI.WriteRead has control of CS.

I looked at http://msdn.microsoft.com/en-us/library/ee432004.aspx
but did not find an answer to my question.

Does any one know if it is possible to configure SPI this way?


#2

Have you tried giving SPI Config an unused pin instead?


#3

Architect,

No, I have not tried this option.

I will try it next.

Thanks for your quick reply.


#4

We could use a personal note that could be added to each our post. Architect’s would be:

“This message was created automatically by Architect’s mail system. Please do not reply”

:wink:


#5

Using an “unused pin” is normally acceptable, but something like a Cpu.Pin.GPIO_NONE would save an IO - and maybe a few clocks.
This would help on some SPI driven graphics displays - although these will probably end up in the parts box anyhow once GHI releases their new display.


#6

Interesting. Didn’t think about GPIO_NONE - even better!. Let us know if that worked.


#7

Hey Guys,

The suggestion to use GPIO_NONE works just find.
Now I have control of CS line.

There is one problem though,
Speed.

Before SPI hardware was handling the CS transitions and works find
if your hardware does not need you to control CS.

But now using USBizi IO with Write() its slow.
Unless I am doing something wrong in my code, that is slowing the CS down.

Here is what I am doing:

                ADC2_EN.Write(false); //CS Low Tells ADC to get ready
                MySPI.WriteRead(tx_data, 0, 1, rx_data, 0, 1, 0); //ushort for 16-Bit Transactions (need 16 Clock pulses for my ADC)
                ADC2_EN.Write(true);  //CS HIGH tells ADC to finish first frame

my ADC needs CS to go low and back up high per frame. that is why I need control over CS. but OutputPort.Write() is to slow.

Any ideas here?


#8

That thing CS low -> transaction -> CS high is handled by SPI libraries. Do you have to do another transition after transmition ?
If not you should let the CS controlled by SPI implementation.

By the way Architect was defeated I answered first !!!


#9

You are right in saying that I should let the SPI handle CS.

The solution that I was looking for was to tell SPI to Transition
CS from High to Low on every 16-Bit Write/Read (which is what I need on my ADC chip)

But SPI.WriteRead() defeats this purpose because It keeps CS low during
any write/Reads if I use Arrays.

In other words if I want SPI to write and read at the same time 20 times
then I was expecting CS to Transition from High to Low 20 times. But that is not the case with SPI handling CS.

Unless I am setting up SPI configuration wrong, I did not see SPI transitioning CS on every write/read operation.


#10

If you transfer and read back an ushort, the chip select should be active before the start and inactive after the transmition. At least thats what Microsoft said…

Have you tried:

ushort[] read = new ushort[1];
ushort[] write = new ushort[1];

write = 1; // Or whatever you need
MySPI.WriteRead(write, read);


#11

Pablo,

Yes, what you posted works find if what you are just doing one 16-Bit Transaction.
but if you were to do this:

ushort[] read = new ushort[10];
ushort[] write = new ushort[10];

write[0] = 1; // Or whatever you need
MySPI.WriteRead(write, read);

cs will stay low the whole 10 transactions.
it will transition from High to Low at the start of the transactions but will remain low thereafter until
the last transaction.

and that is the problem with SPI.WriteRead();


#12

Thats the way its supposed to work… But most digital potenciometers, ADCs & DACs works like you said.

I see 2 options here,
1 - Use what I said in a for loop to iterate trough your data (This would be slow)
2 - Do that in native code using RLP.


#13

Yes,

And I don’t understand why microsoft did not make the SPI interface compatible with the way most
ADCs and DACS, etc. work.

I guess they are not targeting real world projects.

I guess it is expected, after all managed code was not meant for real wold processing.

I think, I should just go back to real world c.
It is fast and with good IDE and compiler manage just as well as manage C#.


#14

Sorry I have to disagree. Managed code is used in all sorts of ‘real world’ processing.

The real question is this: why did these component manufacturers not design their stuff to work the way SPI is supposed to work? This happens all time every manufacturer does things their own way. There was a thread recently talking about a temperature and humidity sensor that uses the 1-wire protocol only it is not really exactly 1-wire compatible. Or how about the manufacturers that do some screwy serial protocol that uses a strange number of start bits and/or stop bits that no standard UART can talk to?

The SPI we are talking about here is built into the chip, it is done in hardware. I don’t think the problems you are having is the fault of MS.


#15

I don’t think a CS is regulated by the SPI hardware but driver related.


#16

[quote]Yes, what you posted works find if what you are just doing one 16-Bit Transaction.
but if you were to do this[/quote]

Let SPI implementation control CS and do 10 WriteRead’s. Is it still slow?


#17

He needs a CS toggle between each 16bit read/write. Which is not possible when you read 10 @ once.


#18

What A2D chip are you using?


#19

Guys,

Thanks for all your comments greatly appreciated.

I can manage doing 10 Write/Reads or what ever Write/Reads I need
to process my data.

The thing is it is not very efficient. I have up to 32 ADC channels to read and process.
I am also doing some software filtering, which I may consider not to in the end if things get to slow.

My ADC hardware (chip) can scan all my channels and write out the data automatically, this is the most efficient way of scanning my ADC channels because then,
I can use:

SPI.WriteRead(WBuf,0,16,RBuf,0,16,0);

and read 16 channels per SPI.WriteRead().

One thing to understand here is that the underling SPI hardware is not slow
I can get up to 20MHz on the SPI just find.

What is not working is the CS line. Because then I can’t use the above code to read 16 channels per SPI.WriteRead().

Instead, I have to do this:

for (n = 0; n<16;n++)
{
SPI.WriteRead(WBuf,0,1,RBuf,0,1,0);
mData[n] = RBuf[0];
}

Works OK, but not very efficient.


#20

I am also interested in what 16 channel ADC you are using.