CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

SPI data only partially good
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
object01



Joined: 13 May 2004
Posts: 90
Location: Nashville, TN

View user's profile Send private message Send e-mail Visit poster's website

SPI data only partially good
PostPosted: Fri Jan 28, 2005 4:13 pm     Reply with quote

We're having a serious problem with PIC<->PIC SPI communication, and we've tried everything that we and our certified (shout out to Gary) Microchip consultant can think of.

Our setup is 18F452 to 18F452. One is the master, in our prototype product, one is the slave, on a breadboard, designed to be a test fixture. Master SPI is setup with,

Code:
setup_spi (SPI_MASTER | SPI_CLK_DIV_16 | SPI_H_TO_L | SPI_XMIT_L_TO_H | SPI_SAMPLE_AT_END);


The master executes,

Code:
array[x] = spi_read(0b10101010);   // dummy data for scoping


in groups of three. Before a read, we set SS low, and after each read, we set SS high. After a low-read-high operation, there is a delay of 1ms.

The best way I can phrase the question is like this:

Under what circumstances would the master read anything other than 0xCC, given the following slave program?

Code:
void main (void)
{
   #byte                   SPI_DATA = 0x0FC9

   setup_spi (SPI_SLAVE | SPI_H_TO_L | SPI_XMIT_L_TO_H);

   do {
      if (spi_data_is_in()) SPI_DATA = 0xCC;
   #ignore_warnings 203
   } while (TRUE);
   #ignore_warnings NONE
}


This is the code we've been reduced to. And it performs no better than our interrupt-driven version.

The master is getting 0xCC only a fraction of the time. The rest of the time, it gets 0x00, 0xFF, 0xC4, 0x44, 0x9F, and more. The only pattern it ever seems to get into is 0xCC, 0xFF, 0xCC, 0xFF, but it rarely holds that pattern for more than several seconds. It then reverts to a long series of 0xFF. We are tying the slave's SPI high; done as a troubleshooting measure; the slave does not care about any data it receives from the master.

We have confirmed that no other peripherals on the prototype are being chip-selected during the 3-read process, so there should be no data collision on the SPI bus.

The scope shows us that sometimes the slave PIC just doesn't output anything, in spite of the SCK showing up every time. We've tried slave PICs from different lots, 3 PICs total. We know the master PIC is good, as it works in its normal configuration with other peripherals (including another 18F452!).

We are exhausted. We would sincerely appreciate any insight into this problem.

--
Jeff S.
object01



Joined: 13 May 2004
Posts: 90
Location: Nashville, TN

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Fri Jan 28, 2005 4:14 pm     Reply with quote

Both PICs are running at 24MHz.

--
Jeff S.
Ttelmah
Guest







PostPosted: Sat Jan 29, 2005 5:23 pm     Reply with quote

Try XMIT_L_TO_H at both ends.
Currently, you are saying that the idle state is high, that the clock should then drop, and that data should be sent when it then goes high again. You then sample on this last rising edge, allowing no time for the data to be established before reading. You want the data to be sent at least one clock cycle ahead of your sample point.

Best Wishes
object01



Joined: 13 May 2004
Posts: 90
Location: Nashville, TN

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Sat Jan 29, 2005 6:49 pm     Reply with quote

Ttelmah wrote:
Try XMIT_L_TO_H at both ends.
Currently, you are saying that the idle state is high, that the clock should then drop, and that data should be sent when it then goes high again. You then sample on this last rising edge, allowing no time for the data to be established before reading. You want the data to be sent at least one clock cycle ahead of your sample point.

Best Wishes


You mean try XMIT_L_TO_H without SPI_H_TO_L? 'Cause we already have XMIT_L_TO_H at both ends.

--
Jeff S.
Gary Smithson



Joined: 13 Feb 2004
Posts: 22

View user's profile Send private message Visit poster's website

PostPosted: Sun Jan 30, 2005 1:03 am     Reply with quote

Imagining your setup I'm guessing that you have two separate boards possibly each with its own power supply. You do have the grounds tied together right? And V+ is about the same voltage? Is it possible that the slave PIC is resetting unexpectedly? What is the distance between the master and slave PICs? (I remember the 25 foot ICD cable Shocked )

Hope that helps,
Gary Smithson
Ttelmah
Guest







PostPosted: Sun Jan 30, 2005 3:18 am     Reply with quote

Ttelmah wrote:
Try XMIT_L_TO_H at both ends.
Currently, you are saying that the idle state is high, that the clock should then drop, and that data should be sent when it then goes high again. You then sample on this last rising edge, allowing no time for the data to be established before reading. You want the data to be sent at least one clock cycle ahead of your sample point.

Best Wishes

No, I mean XMIT_H_TO_L. :-)

As I tried to explan, think of the states of the clock, and the data transfers. You currently have:
Code:


-----+    +----
      +---+
            Data is output, _and sampled_ here on the rising edge.

However you should be outputting the data half a clock ahead of the sample point, so:

-----+    +----
      +---+
     You want data to output here.
            Then sample here.


If you use a fixed pitch font, you will sort of see what I was trying to say.

Best Wishes
object01



Joined: 13 May 2004
Posts: 90
Location: Nashville, TN

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Sun Jan 30, 2005 4:18 pm     Reply with quote

OK, we'll try XMIT_H_TO_L on both the master and the slave. But what does XMIT_H_TO_L actually do differently than SPI_H_TO_L? I can't find any documentation on it anywhere, including my most recent readme.txt.

--
Jeff S.
object01



Joined: 13 May 2004
Posts: 90
Location: Nashville, TN

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Sun Jan 30, 2005 4:21 pm     Reply with quote

Gary Smithson wrote:
Imagining your setup I'm guessing that you have two separate boards possibly each with its own power supply. You do have the grounds tied together right? And V+ is about the same voltage? Is it possible that the slave PIC is resetting unexpectedly? What is the distance between the master and slave PICs? (I remember the 25 foot ICD cable :shock: )

Hope that helps,
Gary Smithson


The slave board is powered by the master board. We wanted to make the fixture act very much like the real unit, which is also powered by the board and works just fine so far (no SPI problems talking to its A/D converter). So V+ is 3.3 across the... boards.

I made sure that the slave PIC stays in a while() loop and never goes to sleep, and also ensured that things like the WDT are disabled.

Distance between the master and the slave is 1 ICD-U40 RJ-11 cable, the one that ships with the ICD.

--
Jeff S.
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Sun Jan 30, 2005 5:59 pm     Reply with quote

Quote:
OK, we'll try XMIT_H_TO_L on both the master and the slave. But what does XMIT_H_TO_L actually do differently than SPI_H_TO_L? I can't find any documentation on it anywhere, including my most recent readme.txt.
Documentation can be found in your PIC manual, for example figure 17-3 for the 18F458 is very helpful. I guess changing the suggested parameter won't solve your problem. I guess your problem is caused by the SPI_SAMPLE_AT_END parameter which is a Microchip extension to the Motorola SPI combinations.

Just remember, there are 4 general spi setting combinations. Motorola numbers these just 0 to 3 but Microchip and CCS use different names for the same settings. Very confusing, that's why I always use the following table:
Code:
// Added SPI Mode define because CCS and Microchip made a very confusing mess of it.
//     MOTOROLA              MICROCHIP                 CCS
//---------------------------------------------------------------------------------
//   SPI Mode 0,0   ==    CKP = 0, CKE = 1   ==   SPI_L_TO_H | SPI_XMIT_L_TO_H
//   SPI Mode 0,1   ==    CKP = 0, CKE = 0   ==   SPI_L_TO_H
//   SPI Mode 1,0   ==    CKP = 1, CKE = 1   ==   SPI_H_TO_L
//   SPI Mode 1,1   ==    CKP = 1, CKE = 0   ==   SPI_H_TO_L | SPI_XMIT_L_TO_H
Most SPI devices can communicate with each other when using the same SPI-mode settings. I don't think one mode is better than another but is dictated by the external devices. Most simple hardware devices only support 1 or 2 modes.

The PIC processors are even more versatile by offering a third parameter 'Input Sample' or 'SMP', extending the number of possible configurations to 8. In CCS this parameter is called SPI_SAMPLE_AT_END. Note that this parameter only can be used for SPI-masters and must be cleared in slave-mode. Hardware behavior for setting this bit in a slave is not defined. For Motorola compatible SPI the SPI_SAMPLE_AT_END parameter should never be set either.
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Sun Jan 30, 2005 6:03 pm     Reply with quote

You might have a hardware problem caused by to high a load on the SCK pins (try removing your scope).
See:
http://www.ccsinfo.com/forum/viewtopic.php?t=8075
http://www.ccsinfo.com/forum/viewtopic.php?t=21523
http://forum.microchip.com/tm.asp?m=67287
bas



Joined: 30 Jan 2005
Posts: 4

View user's profile Send private message Send e-mail

Yes, but....
PostPosted: Sun Jan 30, 2005 6:27 pm     Reply with quote

We have a total of three 18F452's involved now--the main (master SPI), the audio (slave SPI), and the simulator on the breadboard (slave SPI). All three are running at 24 MHz.

The audio PIC's slave SPU port is set up as Jeff said

setup_spi (SPI_SLAVE | SPI_H_TO_L | SPI_XMIT_L_TO_H);

and it works with no problem.

But, in any matter, it seems to me that if the master and slave or both L_TO_H or H_TO_L, the problem will be the same. Doesn't one transition (say, H_TO_L) need to tell the slave to put the data bit to the output pin, and the next transition (in this case, L_TO_H) tell the master to latch that data bit? In other words, the slave puts on the falling edge and the master samples on the rising edge?

I guess I am unclear on the difference between SPI_ and SPI_XMIT in this case.

I don't think the PIC is resetting, Gary. MCLR is tied high with about a 20k resistor. We learned that after the 16C745 episode....

We're not using the RJ11 to connect the breadboard to the prototype board, but we're using connectors so we're sure contact is good, and the total wire distance is about 8" or so.
bas



Joined: 30 Jan 2005
Posts: 4

View user's profile Send private message Send e-mail

Loading problem
PostPosted: Sun Jan 30, 2005 8:07 pm     Reply with quote

Oh yeah--

With respect to loading with the scope, we're not always probing it, and we see the same results whether we're probing or not.

I've found that we usually don't have a problem as long as we use a probe with a 10x setting, which increases the input impedance of the probe to a level that a PIC GPIO can drive with no problem, even at pretty high frequencies.

That problem has tripped me up in the past, though. For example, it's almost impossible to measure the oscillator on a PIC by probing with a 1x probe. The capacitance is so large that is loads the oscillator and destabilizes it so that it no longer runs. We found that one out the hard way!
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

Re: SPI data only partially good
PostPosted: Mon Jan 31, 2005 10:11 am     Reply with quote

object01 wrote:
The master executes,

Code:
array[x] = spi_read(0b10101010);   // dummy data for scoping


in groups of three. Before a read, we set SS low, and after each read, we set SS high. After a low-read-high operation, there is a delay of 1ms.
Jeff S.


I wrote some code that runs full duplex between PIC's.
Have a look at this link.

http://www.ccsinfo.com/forum/viewtopic.php?t=2676&highlight=spi
object01



Joined: 13 May 2004
Posts: 90
Location: Nashville, TN

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Mon Jan 31, 2005 10:13 am     Reply with quote

If the following statement,

Code:
spi_setup(SPI_MASTER, SPI_H_TO_L, SPI_XMIT_L_TO_H);


sets up an SPI master to transmit on the rising edge, then we can conclude that it receives on the falling edge.

If the slave uses,

Code:
spi_setup(SPI_SLAVE, SPI_H_TO_L, SPI_XMIT_L_TO_H);


then it is also transmitting on the rising edge and receiving on the falling edge.

Therefore, the master is transmitting on the rising edge, and the slave is receiving on the falling edge.

Now, what if the slave is chip selected while SCK is high? At first glance, it seems to me like the slave will sample the first bit before the master transmits it.

Is the device smart enough to know to wait for the defined SCK idle state before shifting bits in?

--
Jeff S.
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Mon Jan 31, 2005 2:54 pm     Reply with quote

Quote:
If the following statement,

Code:
spi_setup(SPI_MASTER, SPI_H_TO_L, SPI_XMIT_L_TO_H);


sets up an SPI master to transmit on the rising edge, then we can conclude that it receives on the falling edge.
Your conclusion is wrong, SPI is working in a different way. Both the master and slave will start transmitting data in the first half clock period, then on the second clock edge both parties will latch the data on the bus. It's not like the slave waiting for the master or something like that, but both transmitting simultaneously. In your setup the non-active level is a high level and data is clocked-in at the rising edge.

Like I said before, have a good look at the 'SPI MODE WAVEFORM (MASTER MODE)' figure in the PIC-processor manual, it's all in there. I pointed to figure 17-3 in the PIC18F458 manual, for your PIC18F452 that's figure 15-3.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group