SPI Trouble

Technical questions regarding the xTIMEcomposer, xSOFTip Explorer and Programming with XMOS.
User avatar
rp181
Respected Member
Posts: 395
Joined: Tue May 18, 2010 12:25 am

SPI Trouble

Postby rp181 » Sat Jul 16, 2011 1:51 am

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).

http://i.imgur.com/AcEp5.png

The code:
http://pastebin.com/CvyBWpM7

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: 843
Joined: Sun Jul 11, 2010 1:31 am

Postby segher » Sat Jul 16, 2011 12:39 pm

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

Postby rp181 » Sat Jul 16, 2011 3:54 pm

http://i.imgur.com/OyTjL.png

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

Postby jai » Mon Jul 18, 2011 7:11 am

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

Postby rp181 » Mon Jul 18, 2011 12:46 pm

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:
http://i.imgur.com/socSi.png
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

Postby rp181 » Tue Jul 19, 2011 3:15 am

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

Postby japus » Mon Sep 26, 2011 5:02 pm

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

Postby Schatz143 » Wed Mar 11, 2020 10:08 am

http://pastebin.com/CvyBWpM7
the link isnt working anymore.Any new link for this ?
Thanks

Who is online

Users browsing this forum: No registered users and 5 guests