|
|
View previous topic :: View next topic |
Author |
Message |
Bollo
Joined: 01 Dec 2010 Posts: 25
|
spi_read(X) not behaving as expected |
Posted: Wed Jan 11, 2012 8:07 pm |
|
|
This is some test code running on an SPI slave.
Code: |
#include <18F46K20.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES INTRC_IO //High speed osc with HW enabled 4X PLL
#FUSES MCLR //Master Clear pin enabled
#use delay(clock=64000000)
unsigned int8 temp=0;
#INT_SSP
void int_spi()
{
temp=spi_read(55);
}
void initialise()
{
setup_oscillator(OSC_64MHZ);
setup_spi(SPI_SLAVE | SPI_L_TO_H | SPI_XMIT_L_TO_H);
enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);
}
void main() {
initialise();
while(1);
}
|
The SPI master is confirmed to be sending the sequence 10,11,12,13,14 (oscilloscope). Each number has it's corresponding clock train of 8 pulses, everything looks good on SDO (from master perspective). However SDI i.e. the data coming from the slave is 55,10,55,12,55 (oscilloscope). It surely should be 55,55,55,55,55 given all the SSP ISR has in it is temp=spi_read(55);
The manual states Quote: | If a value is passed to spi_read() the data will be clocked out and the data received will be returned. If no data is ready, spi_read() will wait for the data if A SLAVE or return the last DATA clocked in from spi_write.
|
Now I'm dumping the 11,12,13,14,15 in a temp variable on the slave side and forgetting about it. How is it being returned to the master every other clock train?
Just to rule out hardware error (crossed data lines or something) holding the slave in reset (so it is still electrically connected results in the expected - i.e. nothing is returned. The oscilloscope also shows the signals are clean.
I feel I must be missing something very easy here. But it seems as if spi_read(X) is not behaving how I would expect.
This is with compiler version 4.120. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19551
|
|
Posted: Thu Jan 12, 2012 3:24 am |
|
|
You don't show the master code.
My 'guess' would be that the key is _time_.
You send '10' from the master, which receives what is currently in the slaves holding register.
Slave receives '10'. 10 is currently in the holding register
Now takes perhaps 3uSec to get into the interrupt, retrieve the byte from the holding register and load '55'. 55 is now in the holding register.
At some point here the master sends a new byte, and retrieves what is in the slaves holding register at the same time. What it gets, depends on whether it does this before the register is reloaded or after.
If you send the bytes without pause, you will get behaviour like you are describing, as you read what is still in the register from effectively the last transfer, before the next one has completed.
A couple of the threads PCM_programmer has pointed you to make mention of this.
Best Wishes |
|
|
Bollo
Joined: 01 Dec 2010 Posts: 25
|
|
Posted: Thu Jan 12, 2012 3:51 am |
|
|
Thanks for the replies. There is already a delay_us(10) between each spi_write(10-14) on the master. I will attempt to increase that delay to see if it has any effect later tonight, I'll also post the code. |
|
|
|
|
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
|