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

incorporating two interrupts (rda and ext)

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



Joined: 20 Nov 2004
Posts: 2
Location: Edinburgh, Scotland

View user's profile Send private message

incorporating two interrupts (rda and ext)
PostPosted: Sat Nov 20, 2004 12:10 pm     Reply with quote

I have a problem incorporating two interrupts (rda and ext) on the PIC18F452. I have an application that transmits data from flash to a server using xmodem via a mobile phone. This is working fine, but yesterday I added a simple trigger for this process using the external interupt ext. I find that when I add the ISR for the external interupt the serial interrupt stops working. When I break the code it appears the GIE (INTCON.7) is set to 0, but I cannot find where this occurs. Interestingly PEIE remains set. Its as if its already inside an ISR ? I have included snippets of code below.

Could someone point out what I am doing wrong please ?

I guess my real problem is I don't really understand when to use enable_interrupts(global) if I am switching on and off the rda enable bit (PIE.5) through the code. Is it each time I change the bit or only once at the beginning.


Code:
void main()
{
   initialise();
   do
   {
      //sleep();
      MakeThatCall();
   } while (status != ERROR);

   IndicateError();
}


//*************************************************************************
//******************************** PIC ***********************************
//*************************************************************************

//------------------------------------------------------------------------
#int_rda
void serial_isr(void)
{
   TempBuffer=getc();
   if ((TempBuffer!=CR)&&(TempBuffer!=LF)&&(TempBuffer!=SP))
   {
      *RxBufferTop++=TempBuffer;
      if (RxBufferTop>(RxBuffer+BUFFER_SIZE))
      {
         RxBufferTop=RxBuffer;               // Reset pointer
      }
   }
}

//------------------------------------------------------------------------
#int_ext
void PermissionToSend_isr(void)
{   
/*   if (INTEDG0) // if detected edge is rising
   {
      FlashYellowLedFast(2);         // testing !!!!!!!!!!!!      
      Reset_CPU();
   }
   else
   {
      delay_cycles(1);
   } */
}

//------------------------------------------------------------------------
int8 EnableRegistration()
{
   int8 i;
   for(i=0; i<10; i++)
   {
      delay_ms(150);
      FlushRS232();
      ClearBuffer();
      SERIAL_ON;
      GLOBAL_INTERUPTS;
      printf("AT+COPS=0\r\n");
      if (WaitModemResponseOKLong())
         return TRUE;
   }
   return FALSE;
}

//------------------------------------------------------------------------
int8 WaitModemResponseOKLong()
// Waits for each tick period and examines the RxBuffer for 'OK'
// If a timeout occurs status set to error
{
   WaitCounter=0;
   do
   {
      delay_ms(TICK);
      if(WaitCounter++>AWAIT_OK_LONG)
      {
         status = ERROR;
         return FALSE;
      }
      if(strstr(RxBuffer, ERRORR))
         return FALSE;
   } while(!(strstr(RxBuffer, OK)));

   SERIAL_OFF;
   GLOBAL_INTERUPTS;
   return TRUE;
}

_________________
Harry.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Nov 20, 2004 3:32 pm     Reply with quote

I don't think you gave enough information yet.
You need to post your #use rs232() statement.
It wouldn't hurt to post your #use delay() and
#fuses statements, too.

Also post the lines where you define these macros:
SERIAL_ON;
SERIAL_OFF;
GLOBAL_INTERUPTS;
If they have #bit or #byte statements in them,
then post those too.
harry_bach



Joined: 20 Nov 2004
Posts: 2
Location: Edinburgh, Scotland

View user's profile Send private message

PostPosted: Sun Nov 21, 2004 1:32 pm     Reply with quote

Just to explain further MakeThatCall() uses a series of sub-functions including EnableRegistration(). All these sub functions follow the same pattern sending an AT command and await a response using functions like WaitModemResponseOKLong(), which compare a fixed string responds with an RxBuffer which in turn is filled by the RDA ISR. The code works in its current form, but if I add any code in the int_ext ISR the GIE bit sets to 0 somewhere and so when serial data is received the serial ISR is not called (even with the enable_interrupts(INT_EXT) commented out in the initialise() function.

Code:
#use delay(clock=4000000)
#fuses XT,NOWDT,WDT1
#use RS232 (baud=9600, xmit=PIN_C6, RCV=PIN_C7, bits=8, ERRORS)
#use i2c (master)

#define GLOBAL_INTERUPTS   enable_interrupts(global)
#define SERIAL_ON          enable_interrupts(int_rda)
#define SERIAL_OFF         disable_interrupts(int_rda)

void initialise(void)
{
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_CLOCK_DIV_2);
   setup_psp(PSP_DISABLED);
   setup_spi(FALSE);
   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);

   MODEM_OFF;
   //PD_FLOAT;      // need PD to float or as input on old board 4.3 phone board
   PD_LOW;         // Need to set PD as an O/P on the daughter board
   status=IDLE;

   FlashLedFast(2);
   //ext_int_edge(0, H_TO_L);   // Set edge to trigger on
   //enable_interrupts(INT_EXT);
   //enable_interrupts(GLOBAL);
}

_________________
Harry.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Nov 21, 2004 4:48 pm     Reply with quote

A few comments:

1. You should have NOLVP in your #fuses statement. Without that,
you risk having random lock-ups.

2. I'm not sure why you have WDT1 in your #fuses statement.
I would have only NOWDT during the debugging process.

3. I don't know why you want to shut off RS-232 interrupts periodically.
I would just let them run. You have a circular buffer to receive
the characters. If you're not going to check the buffer for a long
time, then perhaps set a global flag if the buffer overflows.
Or perhaps just clear the buffer, before you go to use it again.

4. I would enable interrupts for INT_RDA and GLOBAL once, near the
start of the program, in main().

5. You have this line:
Quote:
#use i2c (master)

It compiles without error, but you should specify the SDA and SCL pins.
Without those pins, it looks to me like the compiler is generating semi-garbage code and that's not good.

6. I'm not sure what the purpose of you INT_EXT routine is:
Code:
#int_ext
void PermissionToSend_isr(void)
{   
/*   if (INTEDG0) // if detected edge is rising
   {
      FlashYellowLedFast(2);         // testing !!!!!!!!!!!!       
      Reset_CPU();
   }
   else
   {
      delay_cycles(1);
   } */
}

So if you get an external interrupt, you want to reset the CPU ?
What's the definition of 'INTEDG0' ?
I wonder if the CPU is getting reset at a time when you don't intend it to ?
Your basic complaint is that INT_RDA stops when you "add code" to the
INT_EXT routine. Well, adding code that resets the CPU on some edge
(or noise on the pin), is not my idea of a good test.
I would strip out everything in that routine except the delay_cycles(1)
and see if your problem goes away.
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