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 slave mode not working on 18f4520

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
The_Duck
Guest







SPI slave mode not working on 18f4520
PostPosted: Sun Feb 08, 2009 10:47 pm     Reply with quote

Hi all,

I'm trying to get one-way SPI communication working between two PIC 18f4520's and failing miserably. I'd appreciate any help you guys can give. I have a master and slave running the following code. The slave fails to receive almost all the messages sent by the master, though occasionally a byte of the form <some zeros><some ones> (like 0b00111111) will make it through.

I have hooked an oscilloscope up to the master's clock and data outputs and the waveforms look exactly like what I expect, given what I have read about SPI. Interestingly, however, if I use mode 0 or mode 2, the master doesn't give any output on the data line (clock output is still fine)! Only mode 1 and mode 3 seem to work; this confuses me because the 18f4520 data sheet claims that all 4 SPI modes are supported. The oscilloscope also shows the slave select line working as intended (going low before a message and high again after a message).

I'm reasonably sure the wiring is correct, especially since the occasional message makes it through to the slave. I'm confused as to how the slave can simply fail to receive most of the messages--doesn't that mean it must be seeing less than 8 clock pulses before it's deselected? How can that be? And why do only certain forms of messages make it through? Why is 0b00001111 sometimes received while 0b10101010 is never received?

Is there anything wrong with my code? Failing that, how can I debug this? This has caused a lot of frustration over the past few days.

Thanks for any help you can give.

Master code:
Code:
#include <18f4520.h>
#fuses HS,NOLVP,NOWDT,NOPROTECT
#use delay(clock=40000000)

#define SPI_MODE_0  (SPI_L_TO_H | SPI_XMIT_L_TO_H)
#define SPI_MODE_1  (SPI_L_TO_H)
#define SPI_MODE_2  (SPI_H_TO_L)
#define SPI_MODE_3  (SPI_H_TO_L | SPI_XMIT_L_TO_H)

#define SS_PIN PIN_B0

void main() {
    unsigned int val;

    setup_spi(SPI_MASTER | SPI_MODE_3 | SPI_CLK_DIV_64);
   
    output_high(SS_PIN);
   
    val = 0; //val is the byte to send over SPI
    while(true) {
        delay_ms(100);
        val += 1; //we cycle through all possible messages

        //select the slave
        output_low(SS_PIN);
        delay_us(10);

        spi_write(val); //send the message
        output_d(val); //display what we're sending on some LEDs

        //deselect the slave
        delay_us(10);
        output_high(SS_PIN);
    }     
}


Slave code:
Code:
#include <18f4520.h>
#fuses HS,NOLVP,NOWDT,NOPROTECT
#use delay(clock=40000000)

#define SPI_MODE_0  (SPI_L_TO_H | SPI_XMIT_L_TO_H)
#define SPI_MODE_1  (SPI_L_TO_H)
#define SPI_MODE_2  (SPI_H_TO_L)
#define SPI_MODE_3  (SPI_H_TO_L | SPI_XMIT_L_TO_H)

void main() {
    unsigned int val;
   
    setup_spi(SPI_SLAVE | SPI_MODE_3);
   
    while(true) {
        if(spi_data_is_in()) {
            val = spi_read();
            output_d(val); //display what we got on some LEDs
        }
    }
   
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Feb 09, 2009 12:56 am     Reply with quote

1. Post a list of SPI connections between the two PICs. Post the pin
numbers, not just the pin names. Post the package type that you're
using (DIP, TPQFP, etc.).

2. What is the distance between the two PICs ? Are they are on the
same board or different boards ? If two boards, is there is a ground
connection between the boards ?

3. What is the Vdd voltage for each PIC ? Does it come from a voltage
regulator or regulated power supply ?

4. Describe your oscillator circuit. What components are used ?
What frequency is specified on the components ?

5. Post your compiler version.
The_Duck
Guest







PostPosted: Mon Feb 09, 2009 1:37 am     Reply with quote

Disclaimer: the components are not in front of me right now so there may be inaccuracies below but I think I've got these right:

PCM programmer wrote:
1. Post a list of SPI connections between the two PICs. Post the pin
numbers, not just the pin names. Post the package type that you're
using (DIP, TPQFP, etc.).

Both master and slave are DIP packages. Here are the connections in the format master->slave:
RB0(33)->A5(7) [slave select]
RC3(17)->RC3(17) [clock]
RC5(24)->RC4(23) [master output, slave input]
RC4(23)->RC5(24) [master input, slave output (not used)]

PCM programmer wrote:
2. What is the distance between the two PICs ? Are they are on the
same board or different boards ? If two boards, is there is a ground
connection between the boards ?

They're on separate boards connected by a few inches of wire. The grounds are connected.

PCM programmer wrote:
3. What is the Vdd voltage for each PIC ? Does it come from a voltage
regulator or regulated power supply ?

Both are being supplied 5V from separate identical regulated power supplies.

PCM programmer wrote:
4. Describe your oscillator circuit. What components are used ?
What frequency is specified on the components ?

It's a 40MHz crystal oscillator supplied 5V and connected to pin 13 of the PIC. The oscillator is a CTX748-ND or something very similar.

I don't understand how the oscillator works; the PIC boards were assembled from instructions. I believe the timers and such work as expected for a 40MHz oscillator--I think this part of the circuit is fine.

PCM programmer wrote:
5. Post your compiler version.

I'm pretty sure it's 4.041.
Ttelmah
Guest







PostPosted: Mon Feb 09, 2009 8:34 am     Reply with quote

A few comments:
Change your oscillator fuse to EC. HS should work, but will result in significantly more power consumption. Basically, with HS selected, the incoming clock signal, is amplified, and echoed 'out' on the second clock pin. The ampliflier here is only rated to 25MHz, and it's consumption rises as it is clocked faster. Use the correct fuse, rather than 'pushing' the incorrect setting...
Second, try adding a line to disable the comparator. This is multiplexed with the SS pin, and might cause a problem.
What smoothing have you got _close_ to the PICs?. A surprising number of PIC problems result from noise at the PIC supply, especially at higher frequencies.
What silicon revision, are your 4520's?. If these are early chips (the A1 revision), they have probably the largest set of errata for the MSSP, of any PIC ever launched....
Are you sure that the MCLR pin is properly pulled up?. What you describe could result if this was floating.

Best Wishes
The_Duck
Guest







PostPosted: Mon Feb 09, 2009 1:10 pm     Reply with quote

Ttelmah wrote:
A few comments:
Change your oscillator fuse to EC. HS should work, but will result in significantly more power consumption. Basically, with HS selected, the incoming clock signal, is amplified, and echoed 'out' on the second clock pin. The ampliflier here is only rated to 25MHz, and it's consumption rises as it is clocked faster. Use the correct fuse, rather than 'pushing' the incorrect setting...
Second, try adding a line to disable the comparator. This is multiplexed with the SS pin, and might cause a problem.
What smoothing have you got _close_ to the PICs?. A surprising number of PIC problems result from noise at the PIC supply, especially at higher frequencies.
What silicon revision, are your 4520's?. If these are early chips (the A1 revision), they have probably the largest set of errata for the MSSP, of any PIC ever launched....
Are you sure that the MCLR pin is properly pulled up?. What you describe could result if this was floating.

Best Wishes


The power supply plugs into an adapter just an inch or two from the PIC pins it's connected to, and there's no other load on the supply except for I guess the oscillator? I put an oscilloscope across pins 11 and 12 (Vdd and Vss) and it looks pretty steady. I've no experience with power noise so I'm not sure what I would be looking for here.

There's a little circled "B3" on the PIC packages--I guess that's the revision?

Pin 1 (MCLR) is high.

I changed the HS fuse to EC on both master and slave, and I added lines to disable the comparator and the ADC on the slave, but to no avail--I'm getting the exact same behavior.

Code:
setup_comparator(NC_NC_NC_NC);
setup_adc_ports(NO_ANALOGS);


I appreciate the help--is there anything else I can try?
Ttelmah
Guest







PostPosted: Mon Feb 09, 2009 1:33 pm     Reply with quote

Being plugged in close to the PIC, is _not_ good enough. You need a small (something like 0.1uF) decoupling capacitor, with good HF performance really close to the PIC pins. HF problems will not be visible on a typical scope. I am talking about switching transients of a few nSec.
Put capacitors onto the PICs.

Best Wishes
Guest








PostPosted: Mon Feb 09, 2009 2:29 pm     Reply with quote

Ttelmah wrote:
Being plugged in close to the PIC, is _not_ good enough. You need a small (something like 0.1uF) decoupling capacitor, with good HF performance really close to the PIC pins. HF problems will not be visible on a typical scope. I am talking about switching transients of a few nSec.
Put capacitors onto the PICs.

Best Wishes


Oh! In fact there is a 1uF capacitor between pins 31 and 32 (which are the same as 12 and 11).
Guest








PostPosted: Sun Mar 01, 2009 8:33 am     Reply with quote

hi, the_duck

i have the same behavior between 2 16f877a.

do you solve this riddle???
The_Duck
Guest







PostPosted: Tue Mar 10, 2009 12:44 pm     Reply with quote

It got a lot better when instead of doing

Code:
while(true) {
    if(spi_data_is_in()) {
        val = spi_read();
    }
}


I used

Code:
while(true) {
    val = spi_read(0);
}


but it still wasn't perfect.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Mar 10, 2009 1:31 pm     Reply with quote

Try this program. It runs on one PIC. It uses a software SPI master and
a hardware SPI slave. You need to add 4 jumpers on the PIC pins,
which are listed in the program:
http://www.ccsinfo.com/forum/viewtopic.php?t=26888&start=1
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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