Yet another SPI question

Technical questions regarding the XTC tools and programming with XMOS.
User avatar
boeserbaer
Active Member
Posts: 51
Joined: Fri Jan 29, 2010 4:36 pm

Yet another SPI question

Post by boeserbaer »

Hi all. I have a custom board with an L1-128 driving an opto-isolated SPI bus. On a second board I have a uchip 23s17 IO expander, ads7844 adc and a tlv5604 DAC. I can read and write THE ADC and IO expander sucessfully, but I have a one bit shift error on the DAC. Unfortunately it is the wrong way, and I cannot feed it the MSB which is part of the channel select.

I am using a derivation of the SPI master code, running with a clock divisor of 16 which i think is 3.125Mhz
I am tempted to ditch the buffered port and just bit bang the thing. Any comments? My ADC is limited to 3.3Mhz clock, so speed is not that critical, although it would be nice to get more speed where I can since All of the peripherals are on a single SPI bus.

I guess at this point I have to get down and dirty with the data sheet and try to understand why it is not working on the DAC

Regards Mike


User avatar
Berni
Respected Member
Posts: 363
Joined: Thu Dec 10, 2009 10:17 pm

Post by Berni »

SPi is such a simple protocol you can quickly throw together a little code to bit bang it. You can later verify your timing by running it inside the simulator and looking at the traces. You can use the bit bang method to reach about 33Mhz.

Also make sure you are clocking on the right edge. Most spi stuff has the rising edge active, but there are chips that need the opposite edge (this can make 1 bit shifted data).
User avatar
segher
XCore Expert
Posts: 844
Joined: Sun Jul 11, 2010 1:31 am

Post by segher »

Looking at the datasheet, the TLV5604 indeed uses the negative edges of the clock
for input.

For many SPI devices, it is also important what level is on the clock at rest; but this
chip doesn't seem to care.

Finally, this chip has a "chip select" and a "frame select"; check that you have that
connected correctly as well (chip select tied low, frame select connected to SPI
slave select).


Segher
User avatar
boeserbaer
Active Member
Posts: 51
Joined: Fri Jan 29, 2010 4:36 pm

Post by boeserbaer »

I went to bit bang mode, and created proper clock and data relationships separately for each device on the SPI bus, and all is well now. I wish I had just done it that way to begin with. Using highly unoptimized XC instructions, 6.125Mhz is working fine, 10Mhz works, but things don't always happen when scheduled (the clock is assymetical). For now I am not going to push things as It does the job I require, and in fact my ADC is limited to 300ns clock period. the IO expander is 10Mhz, and the DAC is 20Mhz, so later I can try to push things if I really need to.

For you experts, I noticed in the simulator that the first call to a pin takes longer to complete than subsequent calls, and caused a "runt" pulse. I got around this by calling an initialization routine which deselects all devices, and then toggles all the pins. Then calls to the SPI modules seem to work normally. What is the best way to deal with this? is it a simulator artifact only?

regards Mike
User avatar
Berni
Respected Member
Posts: 363
Joined: Thu Dec 10, 2009 10:17 pm

Post by Berni »

I haven't noticed that, but changing the optimization settings has a huge effect on bit banged stuff. Cause with no optimistically ( -O0 ) it may take like 3 instructions to set a pin to 1 while with higher optimization its just 1 instruction. This can sometimes even break your code since it can make it run too fast in some cases. Using timed outputs uses a few more instructions but it will not speed up unexpectedly in optimized compile. Best method is using a clocked buffed port to automatically shift out the data, alto there is a problem if you want falling edge clock (But there is some sort of cheat around it by sacrificing a pin or something)
User avatar
boeserbaer
Active Member
Posts: 51
Joined: Fri Jan 29, 2010 4:36 pm

Post by boeserbaer »

I am using timed outputs, and I agree that technically it would be preferred to use the buffered ports, my dac uses a different edge than the other 2 devices, and since they share the same pins, it makes it tricky. I suspect that I would have to reinitialize the buffered port very time I work with a different device on the S
pI bus. Also, as a practical matter, I don't have any spare 1 bit ports (or 4 bit 8 16 or 32).

I haven't even looked at the optimization, I am using the 10.4 eclipse IDE out of the box so to speak.