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

Error: Could not run program. The Tbytestack was empty!

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



Joined: 03 May 2004
Posts: 48
Location: Sg

View user's profile Send private message

Error: Could not run program. The Tbytestack was empty!
PostPosted: Mon Jun 21, 2004 7:37 pm     Reply with quote

Dear friends,
I encountered a problem using ICD-S with compiler version 3.184 and MINI pic18f452 prototyping board. The clock is 20Mhz. I used to run my program in emulator mode with clock 4Mhz, and it was working fine. But when i migrate to pic18f452 icd-s, it prompts 'Error: Could not run program. The Tbytestack was empty!' after properly running for a few seconds.
My application is using a lease line modem to poll an external device. This modem provides interrupt signal to MCU when data is ready. And the PIC needs to read the modem's internal register for the data.
What i did was sending out polling data to the external device, then monitored the carrier status, enable interrupt on RB0 when carrier detected, then reads in the data, then disable the external interrupts on RB0. But the error occurs after just a few seconds' proper running.
If i comment the the ' modem_receive(3); ' in the main loop, then it is working fine. It seems that my interrupt handler is not well written, could anyone point out some errors? Thanks.


Code:

#include    <18F452.h>
#device     ICD=TRUE
#fuses        HS,NOWDT,NOPROTECT,PUT
#use        delay(clock=20000000)

//----Pin Assignment--------------------------------------------------------------
#define    SCLK       PIN_B1
#define    RDATA       PIN_B2
#define    CDATA         PIN_B3
#define   CSN      PIN_A0
#define     TX_LED        PIN_D0
#define     RX_LED        PIN_D1
#define     DCD_LED     PIN_D2
#define     RTS_LED      PIN_D3
#define     GPRS_LED    PIN_D4
//----Pin Assignment--------------------------------------------------------------

//--- Function Code----Value-----------------------------------------------------
#define  POLL            1
#define  RE_POLL         2
#define   PROCESS_DIR      3
//--- Function Code----Value-----------------------------------------------------

//------LMD Directive---Value----------------------------------------------------
#define   NoDirective      0x21
//------Directive-------Value------------------------------------------------------

//------Variables-------------------------------------------------------------------
short   lmd_Rx_done;                  //If true, means receive all the bytes expected
short   lmd_rxOK;                     //If true, means receive data correct after checking
short   lmd_timeout;

char   lmd_nRx_Data;                              //number of received data
char   lmd_index=0;
char   lmd_buf[50];
char          share_buf[280];
char   lmd_crc_hi, lmd_crc_lo;
char   lmd_current_addr;
//------Variables-------------------------------------------------------------------

void write_CBUS_byte(char cmd) {
   char i;

   output_low(CSN);                                 //enable data transfer
   delay_us(1);                                     //tNXT
    for(i=0;i<8;i++) {
       output_bit(CDATA, shift_left(&cmd,1,0) );   //MSB first
      delay_us(1);                                 //tCDS
       output_high(SCLK);
      delay_us(1);                                   //tCDH
      output_low(SCLK);
    }
   delay_us(1);                                      //tCSE
   output_high(CSN);                                //disable data transfer
}

void write_CBUS(char addr, char data) {
   char i;

   output_low(CSN);                                //enable data transfer
   delay_us(1);
    for(i=0;i<8;i++) {
       output_bit(CDATA, shift_left(&addr,1,0) );   //MSB first
      delay_us(1);                                 //tCDS
       output_high(SCLK);
      delay_us(1);
      output_low(SCLK);
    }

   delay_us(1);

    for(i=0;i<8;i++) {
       output_bit(CDATA, shift_left(&data,1,0) );   //MSB first
      delay_us(1);                                      //tCDS
       output_high(SCLK);
      delay_us(1);
      output_low(SCLK);
    }
   output_high(CSN);                      //disable data transfer
}

char read_CBUS(char addr) {
   char i,data;

   output_low(CSN);                       //enable data transfer
   delay_us(1);                                       //tNXT
   for(i=0;i<8;i++) {
       output_bit(CDATA, shift_left(&addr,1,0) );  //MSB first
      delay_us(1);                                    //tCDS
       output_high(SCLK);
      delay_us(1);                                      //tCDH
      output_low(SCLK);
    }
   delay_us(1);                                         //tCSE

   for(i=0;i<8;i++) {
      output_high(SCLK);
      delay_us(1);
       shift_left(&data,1,input(RDATA));               //clock in the data
      delay_us(1);
      output_low(SCLK);
      delay_us(2);
   }

   output_high(CSN);                                    //disable data transfer
   return(data);
}

void modem_send(char c){

   write_CBUS(0xe3, c);                     //initialize TX DATA register
   delay_ms(8);                        //8ms needed for 1200 baud

}

void modem_receive(char numberRX_expected){

   char to=0;
   char RX_addr;
   lmd_timeout=FALSE;
   lmd_Rx_done=FALSE;
   lmd_rxOK=FALSE;
   lmd_index=0;
   lmd_nRx_Data=numberRX_expected;

   while (!(bit_test(read_CBUS(0xef), 4))){   //Wait if RX energy not detected
      delay_ms(1);                           //lmd_timeout =50ms
      to=to+1;
      if (to>50){
         lmd_timeout=TRUE;
         break;
      }
   }

   if(!lmd_timeout){
      enable_interrupts(INT_ext);            //turn on interrupts

      while (!lmd_Rx_done){                  //Wait if RX not done
         delay_ms(1);                        //lmd_timeout =50ms
         to=to+1;
         if (to>100){
            lmd_timeout=TRUE;
            break;
         }
      }
   }

   if(lmd_Rx_done){
      RX_addr=lmd_buf[0]>>3;            //lmd_buf[0] contains the header from LMD

      if(RX_addr==lmd_current_addr){         //If address matched
         lmd_rxOK = TRUE;   
                               //Receive ACK from LMD, comm finished
      }                                       //end if rx_addr matched

   }                                          //end if (lmd_Rx_done)

   disable_interrupts(INT_EXT);                //Disable interrupts

}

/**************************LMD Polling*******************************************/
void Lmd_poll(char lmd_add, char function_code, char directive){

   char   header = 0;
   char   i = 0;
   lmd_current_addr = lmd_add;

   for ( i = 0; i < 8; i++) {                //Address * 8
      header = lmd_add + header;
   }

   header = header + function_code + 1;      //function * 2 + direction (1)

   if(function_code==POLL){
      modem_send(header);
   }

}


#INT_EXT
void ext_isr() {

   char   i;

   lmd_buf[lmd_index]=read_CBUS(0xea);                     //Read in data from CBUS
   read_CBUS(0xef);                                         //Clear Rx data ready flag
   lmd_index++;

   if(lmd_index==lmd_nRx_Data) lmd_Rx_done=TRUE;

}


main(){

/**********************************interrupt*******************/
   ext_int_edge(H_TO_L);      // init interrupt
   enable_interrupts(GLOBAL);
/**********************************interrupt*******************/

   output_low(TX_LED);
   output_low(RTS_LED);
   output_low(RX_LED);
   output_low(DCD_LED);
   output_low(GPRS_LED);
   output_high(CSN);                           //disable data transfer when start up

   while(1){
      lmd_poll(0x01, POLL, NoDirective);     //Poll Address 1
      modem_receive(3);                      //Expects to receive 3 bytes, when interrupt will occur
      if(lmd_rxOK){
         lmd_rxOK=0;
      }
      delay_ms(1000);
   }
}


Sigma



Joined: 03 May 2004
Posts: 48
Location: Sg

View user's profile Send private message

PostPosted: Tue Jun 22, 2004 3:01 am     Reply with quote

FYI, the lease line modem i am using is CMX624 from CML Micro. This chip is using a custom simple serial bus for RX/TX data and modem setting.
Did anybody spot any mistakes? Or could anyone explain the meaning of this error because i really do not have any idea what is wrong.
rgds
Sigma
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Tue Jun 22, 2004 3:16 am     Reply with quote

I've never seen this error message before. I guess it is some special ICD-S debugger message and has a hardware relation. When searching the archive I could only find one reference to this error message http://www.ccsinfo.com/forum/viewtopic.php?t=5977&highlight=tbytestack.
This thread also suggests a hardware relation.

I don't know whether you are using Low Voltage Programming, but when connected to a debugger it's always good advice to add NOLVP to your #fuses statement.

Another improvement to your code is to clear the INT_ext interrupt flag before enabling the interrupt. Just assume that you had an unhandled interrupt some (long) time before you entered your modem_receive() routine, then the interrupt flag is still pending when you call enable_interrupts(INT_ext) and the interrupt routine is called immediately and your receive will be out of sync. Add a call to clear_interrupt(INT_EXT) to the start of your modem_receive routine.
Sigma



Joined: 03 May 2004
Posts: 48
Location: Sg

View user's profile Send private message

PostPosted: Tue Jun 22, 2004 4:16 am     Reply with quote

Thank you, ckielstra. I see your points. But if the error is hardware related, why the error no longer occurs after removing the modem_receive() routine?
Feedback to you after i add in the NOLVP and clear_interrupt(INT_EXT) in the program. Thx.
Sigma
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Tue Jun 22, 2004 7:09 am     Reply with quote

I just spotted another error:

Code:
 header = header + function_code + 1;      //function * 2 + direction (1)

Your code and comment are not matching, you missed the '*2' in the code.

Remark: You are multiplying the variables to get them to match a certain bit value. A nicer method is to use the shift instruction for this, this shows more clearly what you want to achieve and is much faster to execute for the processor.

Your function Lmd_poll can then be rewritten to:
Code:

void Lmd_poll(char lmd_add, char function_code, char directive)
{
   char   header;

   lmd_current_addr = lmd_add;

   header = lmd_add << 3;           // Address
   header += (function_code << 1);  // function
   header += 1;                     // direction (1)

   if(function_code==POLL){
      modem_send(header);
   }
}
Douglas Kennedy



Joined: 07 Sep 2003
Posts: 755
Location: Florida

View user's profile Send private message AIM Address

PostPosted: Tue Jun 22, 2004 8:59 am     Reply with quote

I may be wrong but this error comes from the debugger that uses pin B3. Your code has action going to pin B3 and if this is connected through to the debugger it could be interacting with the ICD and then onto the PC development environment where the byte stack error likely occurs. If you use pin B3 in your application it should be isolated from the debugger.
Sigma



Joined: 03 May 2004
Posts: 48
Location: Sg

View user's profile Send private message

PostPosted: Wed Jun 23, 2004 1:27 am     Reply with quote

Thanks, ckielstra. Before posting onto the forum, i made some minor changes, which introduce some mistakes. Sorry for that. And to Kennedy, do u mean that if i do not use the B3 pin under this icd-u, the problem will not occur? Because my icd not with me now, can not test.
But anyway, after burning the program into the mcu, the program seems working fine. Hopefully it is an icd hardware related error.
Sigma
Douglas Kennedy



Joined: 07 Sep 2003
Posts: 755
Location: Florida

View user's profile Send private message AIM Address

PostPosted: Wed Jun 23, 2004 11:02 am     Reply with quote

If you are going to use B3 on your board you need to isolate it from the ICD. The debugger interface will see pin b3 if it is not isolated. Any signal you have is passed through to the debugger if you do not isolate it. I would expect this to probably cause errors when CCS tries to accept it into an object Tbyte which expects a RS232 type sentence that is terminated with a CR or LF. Now you can drive a car without brakes. The fact that a car can be driven shouldn't be used as proof brakes aren't needed.
You may get by without isolating B3 but I suspect it is just luck.
Sigma



Joined: 03 May 2004
Posts: 48
Location: Sg

View user's profile Send private message

PostPosted: Wed Jun 23, 2004 11:14 pm     Reply with quote

Thanks, Kennedy.
But i need some clarification of several points:
1. If as what you suspected, it was a debugger error. Does that mean it will not occur when the code is burnt into a physical MCU?
2. How to isolate PIN_B3 from the ICD? Rolling Eyes
Sigma
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