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 Interrupt problem (interrupt every 16 bits, not every 8)

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



Joined: 26 Oct 2005
Posts: 19

View user's profile Send private message

SPI Interrupt problem (interrupt every 16 bits, not every 8)
PostPosted: Wed Oct 26, 2005 7:22 am     Reply with quote

Hi Everyone,

I am having a problem with using interrupts to signal SPI data is ready. I have a PIC 18F458-E and am running the following code:

Code:

#include <stdlib.h>
#include <9356spi.c>

#use delay(clock=40000000)
#use rs232(baud=9600, parity=n, BITS=8, xmit=PIN_C6, rcv=PIN_C7)

void main() {
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   setup_spi(SPI_SLAVE|SPI_SS_DISABLED|spi_l_to_h);

   // Now everything is setup, enable the interrupts
   enable_interrupts(INT_SSP);
   enable_interrupts(GLOBAL);

   printf("Waiting for Data\n\r");

   while(1) {} //Wait for interrupts

}

#INT_SSP
SPI_ISR() {
   int8 writedata=8;
   int8 readdata;

   disable_interrupts(INT_SSP); // Disable SPI interrupts while in it's ISR

   readdata = spi_read(writedata);
   printf("Read: %X\n\r", readdata);

   enable_interrupts(INT_SSP);
}


I am sending data from a TI DSP running as a master sending 8-bits at a time, and had no troubles when I was not using the interrupt handler. Since I have started using the SPI interrupt I am only receiving data every second time I send it. It seems as though the PIC is waiting for 16 bits before triggering the interrupt. I am sure this makes sense somehow, but I am expecting an interrupt every 8-bits that are clocked in.

I am using version 3.224 of the compiler. Can anyone shed any light on this problem for me?

Matthew
asmallri



Joined: 12 Aug 2004
Posts: 1635
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Wed Oct 26, 2005 7:47 am     Reply with quote

Remove the enable and disable SPI interrupts from the interrupt handler. The PIC is not re-entrant and an SPI interrupt cannot interrupt itself.
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
mdares



Joined: 26 Oct 2005
Posts: 19

View user's profile Send private message

PostPosted: Wed Oct 26, 2005 7:54 am     Reply with quote

That makes sense, and is done, but is still doesn't fix my every other byte interrupt problem. Any ideas there?

Matthew
asmallri



Joined: 12 Aug 2004
Posts: 1635
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Wed Oct 26, 2005 8:02 am     Reply with quote

Take the printf out of the interrupt handler
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
mdares



Joined: 26 Oct 2005
Posts: 19

View user's profile Send private message

PostPosted: Wed Oct 26, 2005 8:24 am     Reply with quote

I understand how I would not want that there eventually, but for testing it should be fine, I am using a software breakpoint on my DSP, so the ISR has seconds to run in between transmissions.

In either event, I tried it for completeness and it is still the same problem. The ISR is only running after 2 8-bit messages have been clocked out by the DSP. Any other suggestions?

Matthew
Ttelmah
Guest







PostPosted: Wed Oct 26, 2005 8:50 am     Reply with quote

Though you are very confident the printf will not cause a problem, remove it anyway...
The time needed for the print, is going to be very significant (perhaps 11mSec), with the handler returning after about 8mSec, which is plenty of time for it to have missed one SPI transaction. The interrupt flag, is cleared at the _end_ of the interrupt handler, so if a second SPI interrupt occurs inside the handler, this is lost.
Having it here, also implies that interrupts will be disabled in any external print operations, which chile there are none shown inside your wait, could also cause problems...
If you must print a status for debugging, just use a 'putc', to send the single character received, which with the hardware buffer, should avoid problems provided no more than acouple of characters arrive in rapid succession.

Best Wishes
asmallri



Joined: 12 Aug 2004
Posts: 1635
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Wed Oct 26, 2005 8:55 am     Reply with quote

What happens if the DSP sends three bytes? Just wondering if you have the matching SPI config at both ends.
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
mdares



Joined: 26 Oct 2005
Posts: 19

View user's profile Send private message

PostPosted: Wed Oct 26, 2005 9:05 am     Reply with quote

Ttelmah,

you misunderstand. I have removed it, and the problem persists. But it shouldn't be a timing issue because the DSP has a software breakpoint set before each transmission (Hence it can only send data with user interaction, making it at least a full second between transmissions).

Andrew,

The first byte is ignored, the second is printed, the third ignored and the forth printed... and so on. While I wouldn't discount the idea of it being a DSP configuration problem, I think it is unlikely as the setup works fine when I am not relying on the PIC to set that interrupt. (i.e. I just do an SPI_READ and wait for data in the main loop). This leads me to believe the PIC is requiring 16 bits of data to trigger the interrupt, which doesn't make sense to me.

I am sorry if this is at all confusing,
Matthew
asmallri



Joined: 12 Aug 2004
Posts: 1635
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Wed Oct 26, 2005 10:27 am     Reply with quote

Obviously I have not used the SPI with interrupts before...

The problem is in the handler. What is happening is an interrupt is received and the byte is read from the SPI port. A this point a new SPI command is issued - writing out the writedata value. The code is then loops until the byte has been serialised out onto the wire. Once the byte is serialised out the interrupt flag will be set. However the interrupt handler now clears the interrupt flag so this interrupt condition is lost.

Code:
.................... #INT_SSP 
.................... SPI_ISR()   
....................    { 
....................    int8 writedata=8; 
*
0758:  MOVLW  08
075A:  MOVLB  1
075C:  MOVWF  xAD
....................    int8 readdata; 
....................   
....................    readdata = spi_read(writedata); 
075E:  MOVF   FC9,W
0760:  MOVFF  1AD,FC9
0764:  BTFSS  FC7.0
0766:  BRA    0764
0768:  MOVFF  FC9,1AE
....................    }   
....................   
....................   
....................   
....................   
076C:  BCF    F9E.3
076E:  MOVLB  0
0770:  GOTO   0066



IMHO the compiler is at fault. It should not loop until the character has been serialized out. Here is a work around:
Code:

#INT_SSP
SPI_ISR()
   {
   int8 writedata=8;

   read_first_byte = spi_read(writedata);
   read_second_data = spi_read();
   }

_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
mdares



Joined: 26 Oct 2005
Posts: 19

View user's profile Send private message

PostPosted: Wed Oct 26, 2005 10:36 am     Reply with quote

Ah,

So I was stuck without an interrupt until the master clocked again. Thank you SO much for your time andrew! It's people like you that make these forums work and keep people like me sane.

Matthew
Ttelmah
Guest







PostPosted: Wed Oct 26, 2005 10:52 am     Reply with quote

You will find quite a lot of posts in the archives about SPI. Wha is shown here is a fairly 'classic' problem (sorry I misunderstood that you had already tried without the printf). The SPI code as written by CCS, is not really very well 'suited' to use in an interrupt driven system. I use my own defines for all the SSP interrupts, and have found them a lot less trouble. :-)
Code:

/* Now the SSP handler code. Using my own, since the supplied routines test the wrong way round for my needs */
#DEFINE READ_SSP()   (SSPBUF)
#DEFINE   WAIT_FOR_SSP()   while((SSPSTAT & 1)==0)
#DEFINE   WRITE_SSP(x)   SSPBUF=(x)
#DEFINE   CLEAR_WCOL()   SSPCON=SSPCON & 0x3F


For me, these proved a lot simpler. On an interrupt, I can just read the character, and write the 'reply' if required into the output buffer, without any testing involved.

Best Wishes
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