Spi configuration for fez panda and AD5206 digital pot

Hey, I’m trying to use the fez panda to connect to the AD5206 digital potentiometer, basically attempting to replicate a project that was using the arduino to do the same thing but I’m getting caught up doing the configuration of SPI. Im not really sure what all the configuration elements are for or how they may relate to using the AD5206.
Here is the project I’m trying to copy:

The cs pin and the module I think I understand, but what about the other options in SPI configuration?

Start with the free ebook chapter:

What does it mean when it says “using SPI1 in code is using SPI0 on the processor”? If the fez panda seems to have just the SPI1 should I use SPI2 when referring to it in code?

There are two SPI ports on the Panda…

SPI0 is on pins D11 /D12 (Enumerated in software as SPI1).
SPI1 is on the UEXT pins 7 / 8 (Enumerated in software as SPI2).

( They are not called SPI on the schematics, Master In Slave Out… MISO and Master Out Slave In… MOSI )

Cheers Ian

thanks for the replies guys, the ebook answers most of my questions except i am still struggling understanding the necessary WriteRead(). if i need to write 2 bytes (one for the address and one for the value) to the digital potentiometer do i need to just use a byte array like:

byte[] tx_data = new byte[2];
tx_data[0] = (byte)0x00;//digipot address (pot 1)
tx_data[1] = (byte)0xFF;//value to put pot (255 max)

byte[] rx_data = new byte[2];//does the length of this array matter?
MySPI.WriteRead(tx_data, rx_data);

i am assuming that using the WriteRead like this gets you away from having to set the CS (does it in the background, getting it from config?), so that you are just focused on the data you are sending. is that right?

FYI, this is to use the fez panda replace the servo control in my xbox 360 headtracking project here:
[url]Xbox 360 headtracking using Wii and servo control - YouTube

in answer to:

[quote]i am assuming that using the WriteRead like this gets you away from having to set the CS (does it in the background, getting it from config?), so that you are just focused on the data you are sending. is that right?
The info on SPI at [url]http://www.microframeworkprojects.com/index.php?title=Serial_Interfaces#SPI[/url] is actually quite helpful here.

SPI transactions are always write followed by read; so WriteRead does lots of things in the middle, but that includes setting the appropriate CS line and toggling the CLK while first pushing bits out and then reading bits in; In the distant past (you know, those 8-bit uC’s that were programmed with compiled C or ASM) you’d do the CS yourself as well as the writing/reading bits onto the MOSI/MISO lines and take care of timing; now netmf does it all for you.

That also goes to answer your “how big is my RX array” question too, and confirms the approach you’re using looks right.

why does it assume that there must always be a read? that seems unusual especially since there are devices like the AD5206 dont even have a MISO type of pin (only SDI which, correct me if im wrong, is the MOSI)? why dint they write a Write() method alone instead of coupling it with the read?

I think you misunderstand. That seems like a core part of the way SPI works. There is always a read associated with a write, even if you discard the data that comes back. Each device handles that differently; some give you a status message, some nothing; you need to check the devices’ datasheet.

SPI is also an often mis-used method of serial communications to something that is not really an SPI device but behaves similarly, using a clocking signal and data signal. If you look at your data sheet, it doesn’t say it’s an SPI device it says SPI-compatble. That’s why it has SDI and no SDO, and why the writeread for you means not a lot. But if you want to use SPI you need to keep using it that way; even if nothing comes back for you.

Bret is right, SPI works by clocking data both ways at the same time. That is how it works. Even if your device really has nothing to say the SPI transceiver is still looking at the input line.

ok, but how do i determine what the byte array should be for a device? my first example was using 2 bytes, ive seen other docs that say “send address then value”, but the documentation for the device for the device says an

bit serial data word into the SDI (Serial Data Input) pin. The
format of this data word is three address bits, MSB first, followed
by eight data bits, MSB first. [/quote]
the WriteRead() only takes byte arrays. can someone tanslate? whats it looking for?

you’re going to have to deal with the bit structure yourself.

SPI works with 8-bits of data.

You’re going to combine the “address” and the first of your bits into your first byte, then deal with the next 3 bits into the next byte.

Or you could do this a different way, it seems that you don’t need strict timing (from my real quick look at the data sheet; not considering your application) so you could bit-bang this yourself.

Or now RLP is more accessable, you could write a 11-bit SPI interface just for this kind of device.

I am looking at the AD5254 instead… I2C interface so it will work ok… Or do you need 6 outputs.

11 bits is a bit messy, and it depends how confident you are with RLP and bit banging.

The AD5254 is also non volatile… Just a suggestion.

Cheers Ian

ok, so what you are saying is that instead of 2 individual bytes each containing the address and the value, they are instead both squeezed mostly into the first byte with 3 bits in the second byte to make 11 total bits in 2 bytes? like this:

zero (0) resistance on pot1
00000000 as 0x00
00000000 as 0x00

full (255) resistance on pot1
00011111 as 0x1F
11100000 as 0xE0

because the address can only be 0-5 so it only needs the first 3 bits to represent the address and those bits are combined with the first 5 bits of the value to make the first byte. the second byte is made of the last 3 bits of the value with 5 zeros added to complete the full second byte? sorry if i sound like an idiot but this is a stretch from the web/db programming i am used to…

You can also use ushort version

public void Write(ushort[] writeBuffer);

So the value to write can be formed like this:

ushort val = (ushort)((addr << 13) | (byteValue << 5));

Architect… Will this work? Won’t 5 extra clock cycles mess up the internal circuitry of the pot?

Cheers Ian

I have to look at the datasheet. I was just pointing out that there is ushort version of spi Write method.

are you saying that it wont work because of the additional 5 zeros on the end of the second byte? i dont get what you are doing with the ushort

According to the datasheet the register latches on the CS pin going high so the leading 5 bits might have to be dummies not the trailing 5 bits!

I think its trial and error…

The ushort is an overload on the write function so you can write 16 bits directly.

Cheers Ian

then how do i send the last 3 bits of the value if i dont append the trailing zeros? what should the second byte look like if not 11100000

Send the address as a byte then send the value as a byte.

00000xxx -> address.
xxxxxxxx -> pot value.

hopefully the first 5 zero’s with be clocked out (It does mention in the datasheet that they can be daisy chained )

Cheers Ian