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 support@ccsinfo.com

comunicating between two PICs using SPI
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
Macro



Joined: 10 Jun 2004
Posts: 9
Location: Huntsville, Al

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

comunicating between two PICs using SPI
PostPosted: Fri Jul 23, 2004 9:57 am     Reply with quote

I know this has been talked about many times before, but I'm having different problems then were addressed in the archives. I’m trying to get an 18F8720 (master) to talk to an 18F2431 (slave), both running at 20 Mhz. Both master and slave stop when they reach their first spi_read or spi_write. I've tried the methods in the two threads linked below but nothing so far has worked. I hooked up a scope and I can see that the clock is there and operating at the right frequency but is the voltage is goes from 0.5Vs when low to 1V when the clock is high. Does anyone have any ideas for what to try next?

Things I've tried:
Tried many different spi_setups for both the master and slave.
Tried having SS always grounded and tried controlling it by the master.

Threads I've looked at:
http://www.ccsinfo.com/forum/viewtopic.php?t=8657&start=0&postdays=0&postorder=asc&highlight=spi+two+pic&sid=cbbb400b2122d203b9323d19314d6122
http://www.ccsinfo.com/forum/viewtopic.php?t=17723&start=0&postdays=0&postorder=asc&highlight=spi+two+pic
_________________
David Adams
Ttelmah
Guest







Re: comunicating between two PICs using SPI
PostPosted: Fri Jul 23, 2004 10:25 am     Reply with quote

Macro wrote:
I know this has been talked about many times before, but I'm having different problems then were addressed in the archives. I’m trying to get an 18F8720 (master) to talk to an 18F2431 (slave), both running at 20 Mhz. Both master and slave stop when they reach their first spi_read or spi_write. I've tried the methods in the two threads linked below but nothing so far has worked. I hooked up a scope and I can see that the clock is there and operating at the right frequency but is the voltage is goes from 0.5Vs when low to 1V when the clock is high. Does anyone have any ideas for what to try next?

Things I've tried:
Tried many different spi_setups for both the master and slave.
Tried having SS always grounded and tried controlling it by the master.

Threads I've looked at:
http://www.ccsinfo.com/forum/viewtopic.php?t=8657&start=0&postdays=0&postorder=asc&highlight=spi+two+pic&sid=cbbb400b2122d203b9323d19314d6122
http://www.ccsinfo.com/forum/viewtopic.php?t=17723&start=0&postdays=0&postorder=asc&highlight=spi+two+pic

If the signal is only changing by 0.5v, you need to look again at the wiring. The signals should be good solid logic lines. Disable the master, and see if the line can be pulled high/low by you with somthing like a 4K resistor. If it is resistant to moving, then it is the slave that has the problem. Once you find what is wrong in the hardware, the normal problem with SPI, is speed.
If (for instance), you send a byte to the slave, and receive back whatever was left in the register at this point, then send a second byte, expecting to see a reply, there is a major problem in the time needed. The slave, has to load the 'reply' byte into the output register, before the second transmission starts. The interrupt latency, will depend on what other routines are in use, but on the larger chips, can be as much as perhaps 50 instruction times, from the point where the first byte finishes bing 'sent', to where the reply byte is ready, and worse than this if any other interrupt handlers are present...
The CCS SSP routines, are also not laid out to 'help' with handling waiting for the events efficiently. In the past I have used:
Code:

#byte   SSPBUF = 0xFC9
#byte   SSPCON = 0xFC6
#byte   SSPSTAT = 0xFC7
#bit SSPREADY=SSPSTAT.0
#bit WCOL=SSPCON.7
#DEFINE       READ_SSP()   (SSPBUF)
#DEFINE   WAIT_FOR_SSP()   while(!SSPREADY)
#DEFINE   WRITE_SSP(x)   SSPBUF=(x)
#DEFINE   CLEAR_WCOL()   WCOL=0
/* Launch - Used to 'launch' communications */
void ssp_launch(int txt,int mode)
{
    int loop;
    while (true)
    {
       /* I loop till the slave responds to the header with a correct reply */
       /* This triggers the SPI transmission */
       WRITE_SSP(0xAA);
       WAIT_FOR_SSP();
       loop=READ_SSP(); //Garbage
       delay_cycles(80);
       /* This ensures the slave has time to enter the interrupt service routine */
       WRITE_SSP(mode+txt);
       /* At this point the slave should have responded with '55' */
       WAIT_FOR_SSP();
       /* Since I clocked the write, the character should be waiting for me */
       /* I delay in this routine before actually reading, to allow the other end to get ready  for the next transfer */
       if (READ_SSP()==0x55) break;
   }
   delay_cycles(30);
}

The slave, as soon as it enters the interrupt routine, puts '0x55' into the output register, and then looks at the 'instruction' sent from the master, and puts the first required byte into the output register (the 30uSec delay allows this). the master does not start sending it's data block (and receiving), from the slave, till it sees the '0x55' byte. The slave allways finishes it's packets, with a '0' terminator, so '55' cannot be seen back accidentally. The rate that is required, makes it very difficult to d interrupt driven slave handling (in my case, once the slave is in the 'handler', it stays in the routine for the entire block transfer - normally 16 bytes - it has the memory address worked out for the transfer, just uses 'wait_for_ssp', and as soon as a byte is received, loads the next byte, and processes the received one - this allows the whole transfer to be quite fast once the communication is established).
The shear 'time' involved, is much larger than you expect. The 80cycle delay, allows in my case, the slave to just be ready, if it was in my 'main' routine. However if it was in a serial interrupt handler, the loop will execute twice before the handler starts...

Best Wishes
ckielstra



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

View user's profile Send private message

PostPosted: Fri Jul 23, 2004 11:26 am     Reply with quote

If the signal of your clock line is not changing at the 0 to 5V levels, then this indicates a hardware problem and not some SPI related problem. Which pins are you using? Very likely one of these pins has an open collector output.
Macro



Joined: 10 Jun 2004
Posts: 9
Location: Huntsville, Al

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

Re: comunicating between two PICs using SPI
PostPosted: Mon Jul 26, 2004 10:04 am     Reply with quote

Ttelmah wrote:

If the signal is only changing by 0.5v, you need to look again at the wiring. The signals should be good solid logic lines. Disable the master, and see if the line can be pulled high/low by you with something like a 4K resistor. If it is resistant to moving, then it is the slave that has the problem.


I tried this and I was not able to pull the SCK line high using a 10K resistor when slave program is running. So the slave is the problem, what should I try next?

ckielstra wrote:

If the signal of your clock line is not changing at the 0 to 5V levels, then this indicates a hardware problem and not some SPI related problem. Which pins are you using? Very likely one of these pins has an open collector output.


Master pins (18F8720 page 5):
pin 44 - RC3/SCK/SCL
pin 45 - RC4/SDI/SDA
pin 46 - RC5/SDO

Slave pins (18F2431 page 4):
pin 15 - RC4/INT1/SDI/SDA
pin 16 - RC5/INT2/SCK/SCL
pin 18 - RC7/RX/DT/SDO

I was unable to find anything in either datasheet about "open collector". How to I find out if a pin has an open collector output?
_________________
David Adams
Ttelmah
Guest







Re: comunicating between two PICs using SPI
PostPosted: Mon Jul 26, 2004 10:44 am     Reply with quote

Macro wrote:
Ttelmah wrote:

If the signal is only changing by 0.5v, you need to look again at the wiring. The signals should be good solid logic lines. Disable the master, and see if the line can be pulled high/low by you with something like a 4K resistor. If it is resistant to moving, then it is the slave that has the problem.


I tried this and I was not able to pull the SCK line high using a 10K resistor when slave program is running. So the slave is the problem, what should I try next?

ckielstra wrote:

If the signal of your clock line is not changing at the 0 to 5V levels, then this indicates a hardware problem and not some SPI related problem. Which pins are you using? Very likely one of these pins has an open collector output.


Master pins (18F8720 page 5):
pin 44 - RC3/SCK/SCL
pin 45 - RC4/SDI/SDA
pin 46 - RC5/SDO

Slave pins (18F2431 page 4):
pin 15 - RC4/INT1/SDI/SDA
pin 16 - RC5/INT2/SCK/SCL
pin 18 - RC7/RX/DT/SDO

I was unable to find anything in either datasheet about "open collector". How to I find out if a pin has an open collector output?

They don't.
This would only apply with soft SPI. Also if this was th problem, the resistor would still pull the input up fine.
You are aware that the SDO pin on one chip needs to connect to the SDI pin on the other (only the clock connects directly)?. The behaviour you are describing would be exactly what I'd expect if SDO was connected to SDO, instead of SDI. The lines 'cross over' between the chips.
Are you using 'fast_io' in the code?. If so, how are you setting the TRIS register for the pins?.

Best Wishes
Macro



Joined: 10 Jun 2004
Posts: 9
Location: Huntsville, Al

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

Re: comunicating between two PICs using SPI
PostPosted: Mon Jul 26, 2004 12:36 pm     Reply with quote

Ttelmah wrote:
They don't.
This would only apply with soft SPI. Also if this was th problem, the resistor would still pull the input up fine.
You are aware that the SDO pin on one chip needs to connect to the SDI pin on the other (only the clock connects directly)?. The behaviour you are describing would be exactly what I'd expect if SDO was connected to SDO, instead of SDI. The lines 'cross over' between the chips.
Are you using 'fast_io' in the code?. If so, how are you setting the TRIS register for the pins?.

Best Wishes


I used this as my guide to wire up the SPI and I was careful to make sure the master SDO was connected to the slave SDI and the master SDI was connected to the slave SDO. I thought I might have messed up the wiring so I tried swapping the SDO and SDI on the slave side but that didn't work. As for 'fast_io' I have not tried to use it yet. The only setup I'm doing for the chips is:
setup_spi(spi_master | spi_l_to_h | spi_clk_div_64 ); // for the master
setup_spi(spi_slave | spi_l_to_h ); // for the slave


I called Microchip and they thought that my problem most likely software related but they also suggested that I use a 4.7K resistor to pull up the SCK line (which had no effect). They also said I should be able to see a clock pulse when the master SCK is not connected to slave, which I cannot see. When the master is running and the slave in not connected all I see is a constant voltage (~.8V) on the SCK line.

If this is a hardware problem, what should I try next?
_________________
David Adams
SherpaDoug



Joined: 07 Sep 2003
Posts: 1640
Location: Cape Cod Mass USA

View user's profile Send private message

PostPosted: Mon Jul 26, 2004 1:10 pm     Reply with quote

How about writing a simple program to toggle the clock and data lines. That will tell you if the lines are stuck from a hardware fault. Toggle them from low to high Z to exercise the pull-up resistors. Toggle one at a time to be sure they are not shorted together.
If they move under direct software control the problem must be your SPI software.
_________________
The search for better is endless. Instead simply find very good and get the job done.
Ttelmah
Guest







Re: comunicating between two PICs using SPI
PostPosted: Mon Jul 26, 2004 2:37 pm     Reply with quote

Macro wrote:
Ttelmah wrote:
They don't.
This would only apply with soft SPI. Also if this was th problem, the resistor would still pull the input up fine.
You are aware that the SDO pin on one chip needs to connect to the SDI pin on the other (only the clock connects directly)?. The behaviour you are describing would be exactly what I'd expect if SDO was connected to SDO, instead of SDI. The lines 'cross over' between the chips.
Are you using 'fast_io' in the code?. If so, how are you setting the TRIS register for the pins?.

Best Wishes


I used this as my guide to wire up the SPI and I was careful to make sure the master SDO was connected to the slave SDI and the master SDI was connected to the slave SDO. I thought I might have messed up the wiring so I tried swapping the SDO and SDI on the slave side but that didn't work. As for 'fast_io' I have not tried to use it yet. The only setup I'm doing for the chips is:
setup_spi(spi_master | spi_l_to_h | spi_clk_div_64 ); // for the master
setup_spi(spi_slave | spi_l_to_h ); // for the slave


I called Microchip and they thought that my problem most likely software related but they also suggested that I use a 4.7K resistor to pull up the SCK line (which had no effect). They also said I should be able to see a clock pulse when the master SCK is not connected to slave, which I cannot see. When the master is running and the slave in not connected all I see is a constant voltage (~.8V) on the SCK line.

If this is a hardware problem, what should I try next?

Remove both chips, and verify that the lines do not connect to anything else!...
However a really good session with the DVM, should allow this to be checked. I must admit, I'd be most suspicious of a solder whisker, or some similar problem.
Write a simple program for the slave, that gets rid of the SPI initialisation, and has something like:
#use fast_io(c)

and in the start of the main function, have:
set_tris_d(0xFF);

This will turn the entire port to input.
Then on the master, try:

#use fast_io(c)

and code something like:
int count;
set_tris_d(0);
while (true) {
for (count=0,count<255;count++) {
output_c(count);
delay_us(2);
}
}

Then a scope should show a set of square waves on C0 to C7, with the frequency of each, half that of the one below. If any waveform is distorted, or missing, there is a hardware problem on this line. If some pins are conncted to other hardware, you would need to mask them off (change the value used in the TRIS).

Best Wishes
Macro



Joined: 10 Jun 2004
Posts: 9
Location: Huntsville, Al

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

PostPosted: Tue Jul 27, 2004 9:52 am     Reply with quote

SherpaDoug wrote:
How about writing a simple program to toggle the clock and data lines. That will tell you if the lines are stuck from a hardware fault. Toggle them from low to high Z to exercise the pull-up resistors. Toggle one at a time to be sure they are not shorted together.
If they move under direct software control the problem must be your SPI software.


Thanks for the idea, I tried this exercise and it worked perfectly on all three lines.

Ttelmah wrote:
Remove both chips, and verify that the lines do not connect to anything else!...
However a really good session with the DVM, should allow this to be checked. I must admit, I'd be most suspicious of a solder whisker, or some similar problem.


I thought it might be a wire problem but I removed all unnecessary wires yesterday and checked for solder whiskers but I couldn't find any.

I also tried your code with slight modification (set_tris_c instead of set_tris_d). All the lines that I'm using (RC3, RC4, RC5) worked properly with your test.

I also checked the values of the SSPSTAT, SSPCON1, and TRISC registers and they were as follows:


SSPSTAT: 00000000
Input data sampled at middle of data output time
Transmit occurs on transition from idle to active clock state
receive not complete, SSPBUF is empty

SSPCON1: 00100010
SPI master mode, clock = Fosc/64
Idle state for clock is a low level
Enables serial port and configures SCK, SDO, SDI, and SS as serial port pins

TRISC: 11010111

From what I've read from the 18F8720 datasheet those are the correct settings for those registers but I still cannot see a clock pulse when the master is not connected to the slave.
_________________
David Adams
Macro



Joined: 10 Jun 2004
Posts: 9
Location: Huntsville, Al

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

Master working
PostPosted: Tue Jul 27, 2004 1:48 pm     Reply with quote

I was able to get the master working alone using this code:

setup_spi(spi_master | spi_l_to_h | spi_clk_div_64 );

while(true)
{
byte2 = spi_read(21); //start swapping bytes
delay_us(50);
}

I was able to see the clock and the SDO acting properly. When I hooked it up to the slave, the SDO line stayed correct but the clock was knocked down to a 0-1V scale. I looked into the TRISC register on the slave and compared it to the 18F2431 datasheet. The port C values (0xDF) were exactly what the document said they would be,
"*SDI must have TRISC<4> set
*SDO must have TRISC<5> cleared
*SCK (Slave mode) must have TRISC<3> set (edit: corrected)"

Unfortunately, the pin diagram contradicts that statement. The pin diagram says that the pin 15 is "RC4/INT1/SDI/SDA", pin 16 is "RC5/INT2/SCK/SCL", and pin 18 is "RC7/RXDT/SDO". That explains why the clock was always being pulled down. The clock pin on the slave was always configured as an output not as an input. I then tried wiring the slave like the TRISC comment said to, which also did not work. I also tried changing the value in TRISC to (7F) which stopped the clock from being pulled down. So now I have the master properly outputting the clock and the SDO to the slave but no response from the slave (constant 5V).
_________________
David Adams


Last edited by Macro on Tue Jul 27, 2004 2:17 pm; edited 1 time in total
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

PostPosted: Tue Jul 27, 2004 2:07 pm     Reply with quote

Put this is the slave

Code:

   While(1)
   {  x = spi_read(0xAA);
   }
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

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

PostPosted: Tue Jul 27, 2004 2:10 pm     Reply with quote

Your statement:
Quote:

"*SDI must have TRISC<4> set
*SDO must have TRISC<5> cleared
*SCK (Slave mode) must have TRISC<3> cleared"


From the datasheet:
Quote:

• SDI must have TRISC<4> set
• SDO must have TRISC<5> cleared
• SCK (Master mode) must have TRISC<3>
cleared
• SCK (Slave mode) must have TRISC<3> set
• SS must have TRISA<5> set and ADCON must
be configured such that RA5 is a digital I/O



As you already stated, this section of the datasheet is wrong. The registers given are the more commonly ones used in the other PICs like say PIC18Fxx2's.
Ttelmah
Guest







PostPosted: Tue Jul 27, 2004 3:01 pm     Reply with quote

Mark wrote:
Your statement:
Quote:

"*SDI must have TRISC<4> set
*SDO must have TRISC<5> cleared
*SCK (Slave mode) must have TRISC<3> cleared"


From the datasheet:
Quote:

• SDI must have TRISC<4> set
• SDO must have TRISC<5> cleared
• SCK (Master mode) must have TRISC<3>
cleared
• SCK (Slave mode) must have TRISC<3> set
• SS must have TRISA<5> set and ADCON must
be configured such that RA5 is a digital I/O



As you already stated, this section of the datasheet is wrong. The registers given are the more commonly ones used in the other PICs like say PIC18Fxx2's.

This is the sort of thing that can give anybody headaches!.
For instance, on the 18Fxx2, when dealing with the UART, the TRIS settings, have to differ between operating on the MicroChip ICE, and the real chips. The ICE follows the data sheet, while the real chip reverses the TRIS settings for these bits...
Looking at both the data sheets for other chips, and the 'errata' entries for similar chips often shows the problem. I'd suspect the CCS code, is following the data sheet, and has not been tested on these chips, and would suggest going 'DIY' on the SPI routines on the receiver, and trying the different possibilities with the TRIS register, and seeing what happens.

Best Wishes
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

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

PostPosted: Tue Jul 27, 2004 5:34 pm     Reply with quote

Quote:

For instance, on the 18Fxx2, when dealing with the UART, the TRIS settings, have to differ between operating on the MicroChip ICE, and the real chips. The ICE follows the data sheet, while the real chip reverses the TRIS settings for these bits...


Could you explain this a bit more. Are you talking about RC6 and RC7? I use the 252's and 452's with and ICE2000 and ICD2 and don't remember having to do anything different.
Macro



Joined: 10 Jun 2004
Posts: 9
Location: Huntsville, Al

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

PostPosted: Wed Jul 28, 2004 10:01 am     Reply with quote

Neutone wrote:
Put this is the slave

Code:

   While(1)
   {  x = spi_read(0xAA);
   }


Using that code on the slave and changing TRISC to 0x7F I was able to get the value of 'x' to be the value the master sent over. Unfortunately, the slave is still not outputting anything (constant 5V).
_________________
David Adams
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