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 support@ccsinfo.com

CAN and SPI interrupt do not work together?

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



Joined: 14 Jun 2006
Posts: 6
Location: Manhattan, Ks

View user's profile Send private message

CAN and SPI interrupt do not work together?
PostPosted: Mon Jun 19, 2006 3:28 pm     Reply with quote

Hello, I’m trying to get a PIC18F2680 to run can_rx interrupt, along with ssp interrupt. I have both of these interrupts working fine on the same PIC individually. The problem occurs when I combine the 2, sspbuf dominates the PIC. With the SPI on, no CAN packet comes in or out of that PIC.

I’m out of ideas, is there something I’m missing?

The layout:
___
|18F| ---- SPI ---- > ADCs & MAX3100
----
| |
| \--------CAN-----> Another 18F & PC w/ PCMCIA-CAN/2
\
\------RS232---> PC monitoring
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Jun 19, 2006 3:33 pm     Reply with quote

Use the #priority statement to give the CAN interrupt priority over
the SSP interrupt.
ZackM



Joined: 14 Jun 2006
Posts: 6
Location: Manhattan, Ks

View user's profile Send private message

PostPosted: Mon Jun 19, 2006 3:59 pm     Reply with quote

Wow, you were quick. I gave #priority a run, and I also tried the fast extension with #device high_ints =true. No luck with either.

CAN packets from the 18F are also not going out. The routine that sends the CAN packets are not on a CAN interrupt but TIMER0. I can see that the timer0 interrupt works and runs the code with the debugger. Unfortunately, with SPI on, the packet never gets sent. I'm using the CAN-18F4580.c library. I can see that all the register get loaded and the transmit flag set. For some reason, having activity on SPI doesn't let anything go through. I don't know what the deal is. Does this bring any ideas to mind?

Very Happy Thanks for your speedy response!

-Zack
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Jun 19, 2006 5:16 pm     Reply with quote

1. Are you using SPI as a master or slave ? Is the SSP interrupt
for an SPI slave or a master ? If you are using it as a Master
and you if enable interrupts and the buffer is empty, you will get
continuous interrupts. The program will appear to lock up.
To prevent this, when you're in the isr, you need to check if there
is any data remaining to be sent, and if not, then disable SSP
interrupts.

2. Are you testing all this by trying to single-step through it with the
debugger, or are you testing it at full speed operation with the
program running in stand-alone mode ? There are limitations
to the ICD2 debugger. For example, the help file in MPLAB
says "You cannot single step through an interrupt".

3. When you enable interrupts, are you using two separate
enable_interrupts() statements to do so ? You need to do it that
way. Don't try to bitwise "OR" the interrupt constants together in
one statement.
ZackM



Joined: 14 Jun 2006
Posts: 6
Location: Manhattan, Ks

View user's profile Send private message

PostPosted: Mon Jun 19, 2006 7:42 pm     Reply with quote

Thanks, PCM Programmer for your time.

The answer to your questions,

#1) The program is running as Master on SPI, I wasn’t aware that SPI interrupt always went off. This code I’m developing is for telemetry and motor contol system on an electric car. There is always ADCs to be polled over SPI. To allow time for other things to be processed, I set the SPI clock to 1/64th of internal. It seems to work, as the main while loop works (There’s a code snippet below with the main while loop labeled).

#2) I’ve been testing the program with and without the Debugger. I make the clam that no packet are being sent or received with the chip running without the debugger. I make the claim that the CAN receive interrupt never gets ran from observation of setting a stop in the CAN receive interrupt routine with the debugger.

#3) All interrupts are enabled with their own and separate command.

I’ll include a cut down (snippet) of my code, as the actual thing is rather big ..

Code:

#include <18f2680.h>
#device high_ints=true
#use delay(clock=20000000)
#fuses HS,NOWDT,PUT,NOPROTECT,NOLVP
#include <can-18F4580.c>
#priority CANRX1
#use rs232(baud=19200,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)

//The main routine
void main()
{
   printf("Hello");
   //Starting up the process
   delay_ms(1000);

   SET_TRIS_B(0x00);
   SET_TRIS_C(0x4A);    //Inputs: RX, SDO, PIN_C2

   spi_setup();
   can_setup();
   serial_setup();

   //Gonna set the world in motion
   enable_interrupts(GLOBAL);

   delay_ms(1000);

   //Da main funky loop
   while (1)
   {
      //Blinky light, purdy light
      output_bit(PIN_C1,!INPUT_STATE(PIN_C1));

      Display_windmill();  //A  routine that produces a windmill on a display
                                   //connected to a display on a MAX3110
      delay_ms(17);
   }
}

void can_setup(){
   can_init();

   //Change baud to 500k
   can_set_mode(CAN_OP_CONFIG);
   BRGCON1=0x01;        //These values were created using a calc from Microchip
   BRGCON2=0xA0;
   BRGCON3=0x02;
   can_set_mode(CAN_OP_NORMAL);

   //Set additional buffers to be receivers
   can_set_functional_mode(10);        //Set ECAN to run FIFO mode
   can_enable_b_receiver(B0);
   can_enable_b_receiver(B1);
   can_enable_b_receiver(B2);
   can_enable_b_receiver(B3);
   can_enable_b_receiver(B4);
   can_enable_b_receiver(B5);

   //Code to setup up timer0 snipped

   enable_interrupts(INT_CANRX1);
   enable_interrupts(INT_TIMER0);
   enable_interrupts(INT_TIMER1);
}

void spi_setup()

setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_XMIT_L_TO_H|SPI_CLK_DIV_64);

   //Setup MAX3110 for Display
   CHNL_SEL(CHNL_DISPLAY);
   spi_read(MAX_WRITE_CONFIG | MAX_TBE_ON);
   spi_read(MAX_96BAUD);
   CHNL_SEL(CHNL_NONE);

   //Additional so TBE interrupt starts going
   CHNL_SEL(CHNL_DISPLAY);
   spi_read(MAX_WRITE_DATA);
   spi_read('_');
   CHNL_SEL(CHNL_NONE);

   //Time for the display to powerup
   delay_ms(500);

   enable_interrupts(INT_SSP);

   //Allow for spi to pick a task
   spi_root();
}

spi_root(){
   //Snipped
   //Code here assigns what to talk to on SPI, every option ends with
   //loading the SSPBUF
}

#INT_SSP
void spi_isr()
{  //Snipped
    //Stores data, and also loads SSPBUF when required, when finished
    //talking to device it calls spi_root again.
}

#INT_TIMER0
void can_isr_timer(){
   can_tx();   //Code that decides what to send, and ends with a
                    //can_putd();
}

#INT_CANRX1 FAST
void can_rx_isr(){
   can_fifo_getd(rx_id,&rxdata[0],rx_len,rxstat);

   //Code that processes this data was snipped
}

void serial_setup()
{
   //Snip
   enable_interrupts(INT_RDA);
}

#INT_RDA
void serial_rda_isr()
{  ser_rx_buf = RCREG;
   ser_tx_char(ser_rx_buf); //This enables INT_TBE
   if (ser_rx_buf == '`')
   {  serMode = 1;   //Starts a process of unloading the data on the serial

   }
}

#INT_TBE
void serial_tbe()
{
   TXREG = ser_tx_buf[ser_tx_tail];
   //Snip
   //Unloads all the data it has stored
   //Ends with disable_interrupt(INT_TBE);
}


There is serial, in this code. It has never been a problem and it only executes when I send it a backtick for testing. I've seen no change in the problem with the serial added/removed from the code.

Thanks, PCM for looking at this thread and trying to help. I'm very grateful for that.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Jun 19, 2006 8:32 pm     Reply with quote

I see one immediate problem. You have declared this isr to be FAST.
Quote:
#INT_CANRX1 FAST
void can_rx_isr(){
can_fifo_getd(rx_id,&rxdata[0],rx_len,rxstat);

//Code that processes this data was snipped
}

Here is what the CCS manual says about this:
Quote:

An interrupt marked FAST is performed without saving or
restoring any registers. You should do as little as possible
and save any registers that need to be saved on your own.

But you're not doing that.

I think that you actually want to use the 'HIGH' keyword instead of 'FAST'.

Read Ttelmah's article on interrupts near the end of this thread:
http://www.ccsinfo.com/forum/viewtopic.php?t=26093
ZackM



Joined: 14 Jun 2006
Posts: 6
Location: Manhattan, Ks

View user's profile Send private message

PostPosted: Mon Jun 19, 2006 9:39 pm     Reply with quote

I add FAST by accident. I was just trying to set some priority to the routine so I could recieve some CAN messages.

I switch it to HIGH. My problem still exists, the PIC can neither send or recieve when it uses it SPI routines.

Thanks for the information, though. I didn't know that about FAST.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Jun 19, 2006 10:13 pm     Reply with quote

In your code, you have set_tris_x() statements. But you don't have a
#use fast_io() statement. So the compiler's functions, which you use
after the set_tris_x() statements, will change the TRIS.

In the code below, you set the TRIS for port C to 0x4A.
Quote:
SET_TRIS_C(0x4A); //Inputs: RX, SDO, PIN_C2
spi_setup();
can_setup();
serial_setup();


But in the .LST file shown below, the setup_spi() function sets up
the TRIS for the hardware SPI pins. These TRIS values don't match
what you have specified in set_tris_c(0x4A). Are you trying to use
non-hardware pins for the SPI ? The CCS spi functions only work
with the hardware pins.
Code:

bit:         7654 3210
set_tris_c:  0100 1010
setup_spi:     01 0               


Code:
... setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_XMIT_L_TO_H|SPI_CLK_DIV_64); 
00138:  BCF    SSPCON.5
0013A:  BCF    TRISC.5  // TRISC5 = 0
0013C:  BSF    TRISC.4  // TRISC4 = 1
0013E:  BCF    TRISC.3  // TRISC3 = 0
00140:  MOVLW  22
00142:  MOVWF  SSPCON
00144:  MOVLW  40
00146:  MOVWF  SSPSTAT
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