SPI Trouble

Technical questions regarding the XTC tools and programming with XMOS.
User avatar
rp181
Respected Member
Posts: 395
Joined: Tue May 18, 2010 12:25 am

SPI Trouble

Post by rp181 »

I am trying to read an ADC (AD7928) with the provided SPI class. However, I can't seem to get it to work. At this point, I am just trying to get the MISO line to output what I am outputting. This is a screenshot from the Logic. Ignore MOSI, as the ADC wasn't on (even if it was, same thing happens).



The code:


the clock div in the master spi class header is 10.

The logic shows as i am sending 0000 10000 0001 0001 (Changes every time). I am trying to send 1000 0011 0010. I tried adding 4 zeros on the end of the send variable, but to no avail.

Also, why is the clock look like that? Shouldn't it be constant? When I try and set the div to 5, it throws:

Code: Select all

xrun: Program received signal ET_ECALL, Application exception.
      0x00010372 in configure_clock_rate.coersed..f.7b0.7d.28ui.2cui.2cui.29 ()


User avatar
segher
XCore Expert
Posts: 844
Joined: Sun Jul 11, 2010 1:31 am

Post by segher »

rp181 wrote:I am trying to read an ADC (AD7928) with the provided SPI class. However, I can't seem to get it to work. At this point, I am just trying to get the MISO line to output what I am outputting. This is a screenshot from the Logic. Ignore MOSI, as the ADC wasn't on (even if it was, same thing happens).
You should output on MOSI and input on MISO.
The logic shows as i am sending 0000 10000 0001 0001 (Changes every time). I am trying to send 1000 0011 0010.
It shows you sent 0000 1000 0011 0010 actually, sampled on rising edge of clock. But
the data sheet says the device samples on the falling edge, so you need to configure that
somehow.
Also, why is the clock look like that? Shouldn't it be constant?
It doesn't matter. Ideally you want the pauses to be as short as possible, so you
can fit in as much as possible, but your code was too slow.
When I try and set the div to 5, it throws:
You can only set the divisor to even numbers (or disable it).
User avatar
rp181
Respected Member
Posts: 395
Joined: Tue May 18, 2010 12:25 am

Post by rp181 »



So there was an option on Logic to switch it, so now what I am sending matches. However, I always recieve that same signal, which basically says I am reading channel 1 and it is 0, when I am really reading channel 0.

In the timing diagrams, it shows the MOSI and MISO transactions occurring simultaneously. Does this really matter?

EDIT: Did you mean change it on the XMOS, so it sends out on the falling edge? I read some threads, and they basically concluded that the XMOS can't do it, except for some messy work-arounds (couldn't find what these were).

EDIT EDIT: So I established that the SPI mode of the ADC is mode 2, whereas the class is mode 3. Are there any mode 2 classes available? Are there any things that can hinder the possibility?
User avatar
jai
Member
Posts: 15
Joined: Wed Jun 15, 2011 9:20 am

Post by jai »

Hope the device is initialized as described on page 23 and 23 of the Data sheet.
AD7928 Datasheet says
when SEQ and SHADOW are 0, the analog input channel selected for each individual conversion is determined by the contents of the ADD0 through ADD2 channel address bits in each prior write operation. (where each write to the AD7908/AD7918/AD7928 selects the channel for next conversion).
The screen shot indicates that you're performing a 32 bit write, from which first 12 bits will go into the control register.
The first transfer of control data 0x8320 will configure the device for the next transfer.
(Selects channel 0, Normal Mode).
What is the data that you're getting from MISO on the next transfer cycle?
(By repeating the same write cycle as above)

.
User avatar
rp181
Respected Member
Posts: 395
Joined: Tue May 18, 2010 12:25 am

Post by rp181 »

It's actually not a 32 bit word; its a 16 bit word. The device is full duplex; so the data is read out while you write to the register for the next read cycle. The chip select goes high in between.
Here is a bit banged version:

This one works much better, but a couple of the channels do not line up with the output. Also, my max speed is limited too much but that is optimization.
User avatar
rp181
Respected Member
Posts: 395
Joined: Tue May 18, 2010 12:25 am

Post by rp181 »

I looked at it again, and it looks like it is working - if I read the MISO line on the rising edge. Is this (sending out on the falling edge, and receiving on the rising edge) correct? I compared it with a 1v reference, and it is showing to be very accurate and stable.

On the MOSI line, I bit-banged the 12 bits to start the sequencer. This is very slow (i can get up to 2 MHz, out of 20 MHz possible), but doesn't matter as it is a one time thing. Now, i just need to read it.

What is the simplest way of detecting a rising edge and reading it? I have been manually toggling the sclk pin in loops, as this is how i bit bang it. Is it possible to put this into a clock block after its been used like this? And can you monitor it to read?
User avatar
japus
Member
Posts: 14
Joined: Tue Oct 26, 2010 12:18 pm

Post by japus »

I know the question was asked some time ago but still, my reply.

What I find very useful to detect a rising or falling edge is the 'pinseq' function. It basically waits untill the specified port contains the wanted value.

You use it like this: portname when pinseq (value) :> void; Value is 0 or 1 of course.

I hope it helps

Jasper
Schatz143
Member++
Posts: 31
Joined: Mon Jan 20, 2020 9:54 am

Post by Schatz143 »


the link isnt working anymore.Any new link for this ?
Thanks