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

Retrieving a value from Slave using SPI

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



Joined: 26 Nov 2003
Posts: 151
Location: Grayson, GA

View user's profile Send private message

Retrieving a value from Slave using SPI
PostPosted: Thu Jul 17, 2008 7:02 pm     Reply with quote

I am struggling to finish this piece of code. I am using the Master PIC, 18F67J50 to send multiple bytes of data to the Slave PIC, 16F887 without problems.
In the Slave I capture the SPI data using the interrupt and a buffer:

Code:
#int_ssp
void ssp_isr(void) {
   spi_buffer[next_in] = spi_read(buffer[10]);
   next_in++;
   if(next_in >= BUFFER_SIZE)
      next_in = 0;
}


In the Master I send the data like this.

Code:
void spi_send(int8 data) {

   delay_ms(1);
   buffer[7] = spi_read(data);
   delay_ms(1);
}


I would expect buffer[7] in the Master to take the value of buffer[10] from the Slave during the write from Master to Slave but this is not happening correctly. It appears the interrupt routine is hanging unless I remove the buffer[10] from the spi_read(.....) statement.
RLScott



Joined: 10 Jul 2007
Posts: 465

View user's profile Send private message

Re: Retreiving a value from Slave using SPI
PostPosted: Thu Jul 17, 2008 8:56 pm     Reply with quote

I don't think spi_read(data) is meant to be using inside an interrupt routine. The int_ssp interrupt occurs after the transfer is over. By then it is too late to load the buffer[10] value into the SPI data register. I think spi_read(data) is meant to be used from non-interrupt code. As such, it probably starts out by clearing the very condition that caused the interrupt. On the other hand, I think spi_read() with no argument is just a read of the current value of the SPI data register, and as such it cannot hang.
_________________
Robert Scott
Real-Time Specialties
Embedded Systems Consulting
bwhiten



Joined: 26 Nov 2003
Posts: 151
Location: Grayson, GA

View user's profile Send private message

PostPosted: Thu Jul 17, 2008 9:06 pm     Reply with quote

Any recommendations on how to efficiently get rid of the interrupt routine? It does work well on capturing incoming data.
RLScott



Joined: 10 Jul 2007
Posts: 465

View user's profile Send private message

PostPosted: Fri Jul 18, 2008 5:40 am     Reply with quote

I don't generally use the built-in functions for SPI, so I would probably talk directly to the hardware registers. The slave needs to write buffer[10] to the SSPBUF register before the interrupt occurs. Then when the interrupt occurs, it can read SSPBUF to get the data that was sent from the master, then it must again write buffer[10] (or whatever data you want the slave to send on the next SPI transaction) to the SSPBUF register.

The CCS library function, spi_write() may do more than just write to the SSPBUF register. I can't tell from the documentation. That is why I am reluctant to use the library functions for this.
_________________
Robert Scott
Real-Time Specialties
Embedded Systems Consulting
Ttelmah
Guest







PostPosted: Fri Jul 18, 2008 7:06 am     Reply with quote

Hurrah!... Smile
Agree wholeheartedly on using the inbuilt functions. Especially if going interrupt driven.
Have posted my own macros for SPI here in the past for exactly this reason.
The documentation for the inbuilt functions is also poor, so you have to do things like PCM's test, to find out what they do.

Best Wishes
bwhiten



Joined: 26 Nov 2003
Posts: 151
Location: Grayson, GA

View user's profile Send private message

PostPosted: Fri Jul 18, 2008 7:34 pm     Reply with quote

Alright, without rewriting code I paid to use, how can I do a single read, with the Master, to get a value from the Slave, outside the interrupt routine? I am also using the Slave Select pin.
RLScott



Joined: 10 Jul 2007
Posts: 465

View user's profile Send private message

PostPosted: Sat Jul 19, 2008 5:25 am     Reply with quote

It is no big loss to throw away the SPI library code, and you will have the advantage of knowing exactly what is happening if you write your own code. But, OK, let's use the library code.

Initially, the master calls, for example,

setup_spi(spi_master |spi_l_to_h | spi_clk_div_16 );

and the slave calls:

setup_spi(spi_slave |spi_l_to_h | spi_clk_div_16 );

Now, before any SPI transaction takes place, the slave needs to load its buffer[10] into the SSPBUF register so that it will be sent back to the master the next time the master issues an SPI transaction. I think that spi_write(buffer[10]) will do that, even though the documentation says it generates 8 clocks, I think it only does that if you are the master.

Then the master issues an SPI transaction by lowering the output that goes to the SS input and calling

buffer[7] = spi_read(data);

This will send "data" to the slave and receive "buffer[10]" from the slave and put it in buffer[7]. (Raise the SS pin now.)

Now to get ready for the next SPI transaction, the slave needs to recognize that a transaction has already taken place. It can use the function spi_data_is_in(). When this function returns TRUE, then the slave can write another buffer[10] into the SSPBUF register using spi_write(). The use of spi_read(buffer[10]) by the slave is fairly useless because it hangs the slave indefinitely.

That's my best guess on how to use the library functions to accomplish SPI between a master and a slave. But if I were talking directly to the SPI registers, I would not have to guess.
_________________
Robert Scott
Real-Time Specialties
Embedded Systems Consulting
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