View previous topic :: View next topic |
Author |
Message |
kender
Joined: 09 Aug 2004 Posts: 768 Location: Silicon Valley
|
SPI mode 0 |
Posted: Tue Jun 28, 2011 12:21 am |
|
|
Colleagues,
I’m trying to communicate with LTC2484 over SPI. I think it requires SPI mode 0 (definition of the SPI modes came from this post). Here’s what the LTC2484 datasheet says:
LTC2484 datasheet wrote: | The input data is then shifted in via the SDI pin on the rising edge of SCK (including the first rising edge) and the output data is shifted out of the SDO pin on each falling edge of SCK. This enables external circuitry to latch the output on the rising edge of SCK. |
So, I wrote this
Code: | #use spi(DI=PIN_D2, DO=PIN_D3, CLK=PIN_D4, BITS=8)
...
setup_spi(SPI_MASTER | SPI_L_TO_H | SPI_XMIT_L_TO_H | SPI_CLK_DIV_64); // Settings for LTC2484.
0EAE: BCF FC6.5
0EB0: BCF F94.7
0EB2: BSF F93.0
0EB4: BCF F93.1
0EB6: MOVLW 22
0EB8: MOVWF FC6
0EBA: MOVLW 40
0EBC: MOVWF FC7 |
Unfortunately, it sets the 1st bit after the first raising edge of the clock. For the test, I’ve been doing spi_xfer(0xFF)
Any suggestion, insight or reference is really appreciated!
- Nick
P.S. I’m using PIC18F4550 and PCWH 4.081
P.P.S. If anyone could post working code for LTC2484, that would be great too.
EDIT: Hmmm… I’m using the bit-banged SPI and the built-in bit-banger. May be that has something to do with my woes. May be I’ll have to write my own SPI bit banger. _________________ Read the label, before opening a can of worms. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19518
|
|
Posted: Tue Jun 28, 2011 2:13 am |
|
|
Read what it is saying, and think....
"output data is shifted out of the SDO pin on each falling edge of SCK"
Is this "SPI_XMIT_L_TO_H"?.
Best Wishes |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Tue Jun 28, 2011 4:34 am |
|
|
Ttelmah wrote: | "output data is shifted out of the SDO pin on each falling edge of SCK"
Is this "SPI_XMIT_L_TO_H"?. | I noticed this before, and it confused me a lot. Studying the datasheets I could only conclude that CCS came up with a wrong name. Can you confirm this? Otherwise I have to correct my post in the other thread. |
|
|
kender
Joined: 09 Aug 2004 Posts: 768 Location: Silicon Valley
|
|
Posted: Tue Jun 28, 2011 11:12 am |
|
|
Here’s what’s interesting. This:
Code: | setup_spi(SPI_MASTER | SPI_L_TO_H | SPI_XMIT_L_TO_H | SPI_CLK_DIV_64);
spi_xfer(0xFF); |
and this:
Code: | setup_spi(SPI_MASTER | SPI_L_TO_H | SPI_CLK_DIV_64);
spi_xfer(0xFF); |
Result in the same waveform on SPI bus. First bit on MOSI is set after the first raising edge of the clock. Looks like SPI_XMIT_L_TO_H doesn’t make a difference in my case.
- Nick _________________ Read the label, before opening a can of worms. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
kender
Joined: 09 Aug 2004 Posts: 768 Location: Silicon Valley
|
|
Posted: Tue Jun 28, 2011 3:44 pm |
|
|
PCM programmer wrote: | The LTC2484 data sheet shows in this diagram on page 20 that it uses SPI mode 0.
LTC2484 datasheet wrote: |
Figure 5. External Serial Clock, Single Cycle Operation |
You can see in Figure 5 that SCK idles at a low level and it samples incoming data on the SDI pin on the rising edge. That's mode 0 [...] |
Thank you for confirming that it's mode 0 !
I remember your advice. It worked then, but it doesn't seem to do the trick this time. Here's an oscilloscope screenshot. As far as i understand, in mode 0, the 1st data bit on MOSI should be set before the 1st raising edge of the clock (SCLK). Something like the red dotted line.
_________________ Read the label, before opening a can of worms. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jun 28, 2011 3:57 pm |
|
|
Post your very short test program that's making those waveforms. |
|
|
kender
Joined: 09 Aug 2004 Posts: 768 Location: Silicon Valley
|
|
Posted: Tue Jun 28, 2011 4:28 pm |
|
|
PCM programmer wrote: | Post your very short test program that's making those waveforms. |
Here it is:
Code: |
#use spi(DI=PIN_D2, DO=PIN_D3, CLK=PIN_D4, BITS=8) // bit-banged SPI on digital I/O pins
setup_spi(SPI_MASTER | SPI_L_TO_H | SPI_XMIT_L_TO_H | SPI_CLK_DIV_64);
spi_xfer(0x80);
|
_________________ Read the label, before opening a can of worms. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jun 28, 2011 4:42 pm |
|
|
Quote: | #use spi(DI=PIN_D2, DO=PIN_D3, CLK=PIN_D4, BITS=8) // bit-banged SPI on digital I/O pins
|
This is using software SPI. You didn't specify the SPI mode, or whether
it's MSB first or LSB first. It will very likely default to something you
don't want.
Quote: |
setup_spi(SPI_MASTER | SPI_L_TO_H | SPI_XMIT_L_TO_H | SPI_CLK_DIV_64);
|
The above code sets up the hardware SPI module on pins B1, B0, and C7
on the 18F4550. Those are different pins than you specified in the top line.
This function works with the #use spi() line. It's using pins D2, D3 and D4.
Can you clarify which one you actually want to use: Hardware SPI or
software SPI. Hardware SPI must be on the dedicated SCK, SDO, SDI
pins. Software SPI can use any general purpose i/o pins. Which type
do you want to use, and which specific pins do you want to use for SPI ? |
|
|
kender
Joined: 09 Aug 2004 Posts: 768 Location: Silicon Valley
|
|
Posted: Tue Jun 28, 2011 5:16 pm |
|
|
PCM programmer wrote: | Can you clarify which one you actually want to use: Hardware SPI or software SPI. Hardware SPI must be on the dedicated SCK, SDO, SDI
pins. |
The SPI lines on the board didn’t get connected to dedicated hardware SPI pins. So, I would prefer software SPI. The required data rate is only 1kbps, so software SPI should be able to handle it. But then again, rewiring to dedicated hardware SPI pins is also an option.
Here’s another caveat. There are 2 different devices on the same SPI bus. They need different SPI modes. _________________ Read the label, before opening a can of worms. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jun 28, 2011 6:17 pm |
|
|
I looked at it for a while and maybe I'm doing something wrong, but I
think the CCS software SPI is screwed up. It's not doing Mode 0 correctly
or the other modes either. The 1st pulse (with data = 0x80) is either late
or it's clocked out on the wrong edge. I tried using SAMPLE_RISE and
IDLE to set it up manually and that didn't work either. I tested this with
vs. 4.121 and vs. 4.122 on an 18F4550 and an 18F452.
I would advise dumping #use spi(), and do it manually in code with a
for() loop. Then you can at least control everything and make it work
correctly.
Or you could re-wire your board to use the hardware SPI pins. Those work
correctly with the #use spi() library code. But in the 18F4550, there's
a conflict between the SDO and RX pins. They're shared on the same pin.
So it's probably better to do software SPI manually. |
|
|
|