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

RDA Int causes chip crash/reset

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



Joined: 07 Jan 2010
Posts: 4

View user's profile Send private message

RDA Int causes chip crash/reset
PostPosted: Thu Jan 07, 2010 4:37 pm     Reply with quote

Hi all,

As the title states, when I enter my RDA interrupt which is triggered by responses from a zigbee chip via the RS232 protocol, the chip resets.

Using:
Compiler -- v4
PIC -- 16f886

The purpose of this RDA interrupt is to read in the characters being sent to the MCU, do a quick determination if the message that's coming in is a broadcast (BCAST), and then if it is, determine what type.

Code below:
Code:

// delay after any Zigbee command
#define ZigbeeDelay 70

// include statement for PIC specific library/fuses and clock

//library
#include "16F886.h"                              
#fuses HS,WDT,NOPROTECT,NOLVP,INTRC_IO,NOBROWNOUT       
#use delay(clock=8000000, restart_wdt)
#use rs232(baud=19200, ERRORS, xmit=PIN_C6, rcv=PIN_C7)         

#define ADC_SCK      PIN_A0
#define MUX_EN      PIN_A3
#define MUX_A0      PIN_A4
#define MUX_A1      PIN_A5
#define MUX_A3      PIN_A6
#define MUX_A2      PIN_A7

#define ADC_DIN      PIN_B1
#define LED2      PIN_B2
#define ADC_CONV   PIN_B5
#define TempPower   PIN_B4      

#define LED1      PIN_C1         
#define EEPROM_SCL  PIN_C3
#define EEPROM_SDA  PIN_C4         


// input character for all serial reads
byte keybdbyte;
char bcast_char_array[] = {'B','C','A','S','T'};
char shift_char_array[5];
char bcast[5];   //switched from 16 to test ram
byte bcast_flag = 1;

char START_array[] = {'S','T','A','R','T'};
char END_array[] = {'E','N','D'};
char DATA_array[] = {'D','A','T','A'};
byte end_flag = 0;

// Subroutine declarations
extern void set_mux_chan(int m_chan);
extern char IsCommand(char *bc, char *ta, int len);
extern void interpret_comm();
extern void get_adc_data(int buff);
extern void clear_eeprom();
extern void EEPROMR();
extern int16 measure(int channel, int average);
extern char ZigbeeJPAN();
extern void ZigbeeInit();
extern void TempRead();
extern void ZigbeeSend();

/////////////////////////////////////////
//////////////////
// main program //
//////////////////

void main() {
   int k;
   
   setup_timer_2(T2_DIV_BY_16, 250, 8);   
   
   enable_interrupts(INT_RDA);                                          
   enable_interrupts(GLOBAL);
   
   // Ports
   set_tris_a(0b00000110);                                    
   set_tris_b(0b00000011);                               
   set_tris_c(0b01001000);

   printf("boot 1/7/2010\n\r");                              

   // indicate power-up complete
   for(k=0;k<=2;k++) {
      output_high(LED2);
      output_high(LED1);
      delay_ms(250);
      output_low(LED2);
      output_low(LED1);
      delay_ms(250);
   }   

   while(1){
      delay_ms(1000);
   }
}
////////////////////////
// INTERRUPT HANDLERS //
////////////////////////

#INT_RDA                  
void RDA_isr() {
   int n;
/*
//DIAGNOSTIC LED BLIP
   int ledtick;
   for(ledtick=0;ledtick<=2;ledtick++) {                                                
      output_high(LED2);                                 
      delay_ms(250);
      output_low(LED2);                                 
      output_high(LED1);
      delay_ms(250);
      output_low(LED1);
   }
*/
   // get character
   keybdbyte = getc();
   
   for(n = 0; n < (sizeof(shift_char_array)-1); n++) {
      shift_char_array[n] = shift_char_array[n+1];
   }
   shift_char_array[0] = keybdbyte;
   
   // test for BCAST
   if (1 == (bcast_flag = IsCommand(bcast_char_array,
      shift_char_array, sizeof(bcast_char_array)))) {
      
      // get the broadcast after the equals sign
      while(keybdbyte != '=') {
         keybdbyte = getc();
         //### add break
      }
      if (keybdbyte == '=') {
         while((keybdbyte = getc()) != '!') {
            bcast[n] = keybdbyte;
         }
      }
   }
} // end RDA interrupt


//////////////////
//            //
// Subroutines    //
//            //
//////////////////

// checks if the array is a passed command
char IsCommand(char *bc, char *ta, int len) {
   short int a;
   char flag = 1;
   
   // test broadcast to see if it is the command
   for(a = 0; a < len; a++) {
      if (bc[a] != ta[a])
         flag = 0;
   }
   return flag;
}

// 3 commands implemented 11/20/2009: START, END, DATA
void interpret_comm() {

   if (IsCommand(bcast, START_array, sizeof(START_array))) {
      // start the data reading
      printf("start bcast received\n\r");
//      TempRead();
//      TempDataCount = TempDataCount +1;                     
   }
   
   else if (IsCommand(bcast, END_array, sizeof(END_array))) {
      // set end flag to stop readings
      end_flag = 1;
      printf("end bcast received\n\r");
   }
   
   else if (IsCommand(bcast, DATA_array, sizeof(DATA_array))) {
      // send data
      printf("data bcast received\n\r");
//      ZigbeeSend();                                     
      delay_ms(10000);                              
   }
}


I've taken out a lot of the guts of the code to get something relatively short and compilable... With the full code, however, I know based on some LED indicators (shown commented out) that I'm getting into the RDA interrupt handler... but once there I don't know where the problem is.

Thanks for the help!
_________________
Cor. 's a rough world 'innit?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Jan 07, 2010 4:50 pm     Reply with quote

Quote:
Compiler -- v4

Post the full version. Each version has different bugs affecting different PICs.

Quote:
#fuses HS,WDT,NOPROTECT,NOLVP,INTRC_IO,NOBROWNOUT

You have two oscillator fuses. You should only have one.


Quote:
#INT_RDA
void RDA_isr() {
int n;


// get character
keybdbyte = getc();

if (keybdbyte == '=') {
while((keybdbyte = getc()) != '!') {
bcast[n] = keybdbyte;

You are waiting for multiple bytes inside the #int_rda routine.
That's not the preferred way to do it. You should only get
one per pass, in the interrupt routine. Suppose all the
expected bytes don't come in. You are then locked up in
the interrupt service routine.

I suspect this is why you have the Watchdog timer enabled,
as a 'fix' for this problem. Because you don't have restart_wdt
as a parameter in your #use rs232 statement, the getc() routine
will not restart the WDT periodically. The getc() function
sits in a loop, waiting for a char. Eventually you will get a WDT reset.

The solution is to use a buffer, similar to the Ex_sisr.c example.
There are also examples in the forum archives for receiving
and decoding command strings (such as NMEA-0183 for GPS)
which show how to use #int_rda for this purpose. (Getting one
char per pass).


Quote:
while((keybdbyte = getc()) != '!') {
bcast[n] = keybdbyte;

This code looks unsafe. What if the incoming string doesn't match
your expected format. The code could write past the end of the
array and overwrite other RAM locations, causing erratic program
behavior or a crash.
edweir



Joined: 07 Jan 2010
Posts: 4

View user's profile Send private message

PostPosted: Thu Jan 07, 2010 5:01 pm     Reply with quote

Thanks for the quick replies! I'll take a look at these and get back to you as soon as I can.
_________________
Cor. 's a rough world 'innit?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Jan 07, 2010 5:17 pm     Reply with quote

MPLAB only includes the PCB compiler (to my knowledge), which is
for low-end PICs.
It doesn't include the PCM compiler, which is used for mid-range PICs
such as the 16F886.
The version number is given at the top of the .LST file, which will be in
your project directory after a successful compilation. It's a 4 digit number
in this format: 4.xxx
edweir



Joined: 07 Jan 2010
Posts: 4

View user's profile Send private message

PostPosted: Thu Jan 07, 2010 5:21 pm     Reply with quote

Thank you. The compiler is version 4.057.
_________________
Cor. 's a rough world 'innit?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Jan 07, 2010 5:34 pm     Reply with quote

I don't recall that vs. 4.057 had any particular faults with respect to
causing a program to reset.

Instead of using your code, look at Ttelmah's method for detecting
commands from the serial port:
http://www.ccsinfo.com/forum/viewtopic.php?t=31144
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