View previous topic :: View next topic |
Author |
Message |
gokulrred
Joined: 22 Nov 2011 Posts: 32 Location: puducherry
|
PROBLEM IN RECEIVING 16 BIT SPI DATA |
Posted: Fri Feb 17, 2012 4:43 am |
|
|
hi..
i was trying to receive 16 bit data in SPI using
spi_xfer function.
i am able to receive values correctly when i receive values in main...
i am not able to receive values when i use ISR for receiving 16 bit data.
misses one value for every two values in 16 bit...
misses 3 values for 32 bit...
using ISR, SPI will not receive 16 bit or 32 bit data????????
PIC: 18F4431
here is my code.
MASTER:
Code: |
#include <18F4431.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#FUSES SSP_RD //SCK/SCL=RD3, SDA/SDI=RD2, SDO=RD1
#use delay(clock=20000000)
#USE SPI (MASTER, FORCE_HW, BITS=16)
#use fixed_IO(C_outputs = PIN_C6)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
long val1;
void main()
{
setup_spi(SPI_MASTER | SPI_H_TO_L | SPI_CLK_DIV_4);
val1= 0x00;
while(true)
{
printf(" value 1 = %Ld \r\n\r\n", val1);
spi_xfer(val1);
val1=val1+0x01;
delay_ms(100);
}
}
|
SLAVE :
Code: |
#include <18F4431.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#FUSES SSP_RD //SCK/SCL=RD3, SDA/SDI=RD2, SDO=RD1
#use delay(clock=20000000)
#USE SPI (SLAVE, FORCE_HW, BITS=32)
#use fixed_IO(C_outputs = PIN_C6)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
long val2;
#int_SSP
SSP_isr()
{
val2=spi_xfer(0);
}
void main()
{
enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);
setup_spi(SPI_SLAVE | SPI_H_TO_L |SPI_SS_DISABLED);
val2=0;
while(true)
{
printf(" value 2 = %Ld \r\n\r\n", val2);
}
}
|
OUTPUT:
1
3
5
7
9
.
.
.
. |
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Fri Feb 17, 2012 4:56 am |
|
|
The data sheets make it clear that SPI transmits/receives eight bits at a time. Its byte-based. SPI isn't actually, in theory you can transmit/receive any reasonable number of bits in each transfer, but nearly all SPI hardware on microcontrollers, such as PICs, is byte-based for historical reasons. To send 16 bits you have to send it as two bytes in a row. Simple.
However... if you transmit pairs of bytes you have to be prepared to receive them too, so you have to buffer received data so your ISR is a little more complicated.
As you don't buffer your incoming data, what's probably happening is that a byte comes in and you start printing it on the serial port, but that takes too long, and the next SPI transfer is ignored.
Also you should NOT disable slave select on the slave! Its important, you need to get slave select working.
RF Developer |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Fri Feb 17, 2012 9:44 am |
|
|
I guess, the final reason for data loss in the present application is a too high SPI data rate. The slave can only buffer one byte. If a second byte is transmitted during the interrupt latency, the buffer will overflow.
You're presently also receiving 32 bit, but sending 16 bit. This means, that the processor needs to wait 100 ms in the middle of the interrupt function.
Last edited by FvM on Fri Feb 17, 2012 10:21 am; edited 1 time in total |
|
|
gokulrred
Joined: 22 Nov 2011 Posts: 32 Location: puducherry
|
|
Posted: Fri Feb 17, 2012 9:58 am |
|
|
Hi RF_Developer...
first of all
thanks for your interest u took in this ...
i know that data transmission is byte based...
but one issue:
i could not receive 16 bit data in ISR...
but i could successfully receive 16 bit data when i continuously read data in while loop in main.
in short: receiving 16 bit data in main but couldn't in SSP_ISR
----------------------------------------------------------------------------------------------------------------------------------
hi FVM,
first of all
thanks for your interest u took in this ...
sorry..
while simulating it was 16 at both places.
when i tried trial and error for diff possibilities i would have typed wrongly and posted.
when it was 16 bit both at master and slave the output was as said earlier. |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Fri Feb 17, 2012 10:24 am |
|
|
Yes, I see. The 32 bit settings makes no sense at all. I assume, that the interrupt reception works if you either reduce the SPI speed, or send two bytes with a short delay. |
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1933 Location: Norman, OK
|
|
Posted: Fri Feb 17, 2012 2:51 pm |
|
|
From section 18.2 of the datasheet:
Quote: | SPI mode allows 8 bits of data to be synchronously
transmitted and received simultaneously. |
The ISR fires when the 8bit recv buffer is full.... _________________ Google and Forum Search are some of your best tools!!!! |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Fri Feb 17, 2012 5:26 pm |
|
|
Quote: | The ISR fires when the 8bit recv buffer is full.... |
Yes, but it's no problem to receive the succeding bytes in the same interrupt, if the first byte is read from the receive buffer before the second byte comes in. This apparently doesn't work. |
|
|
gokulrred
Joined: 22 Nov 2011 Posts: 32 Location: puducherry
|
|
Posted: Sat Feb 18, 2012 1:15 am |
|
|
so..
Can i take conclusion like this:
ISR receives 8bit only synchronously but not 16 or 32 bit...
But in main it is possible to receive 16 bit data without problem....
right???? |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Sat Feb 18, 2012 3:15 am |
|
|
Quote: | ISR receives 8bit only synchronously but not 16 or 32 bit... |
You should think about the meaning of synchronously. The SPI interface (SSP) doesn't provide a FIFO. It triggers an interrupt, when the data is transferred from the shift register (SSPSR) to the buffer (SSPBUF), see figure 19-4 in PIC18 familiy reference manual. When the second BYTE is immediately send after the first, the first byte need to be read within 32 instruction cycles with SPI_CLK_DIV_4. Most likely, the interrupt latency is longer than 32 cycles.
When receiving the data in polling mode, the response is faster if no delays are involved in the loop.
In other words, it's not the problem to read multiple bytes in the ISR. The problem is the delay before reading the first byte. I mentioned possible solutions in my first post. |
|
|
gokulrred
Joined: 22 Nov 2011 Posts: 32 Location: puducherry
|
|
Posted: Sat Feb 18, 2012 4:44 am |
|
|
FvM sir,,,,,,,,,,,
i can't get you.......
sorry.......
is there any possibilities to receive 16 bit data or 32 bit data in ISR????????? |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Sat Feb 18, 2012 7:35 am |
|
|
As said, it should be possible with lower SPI speed, or a gap between individual SPI bytes. |
|
|
|