|
|
View previous topic :: View next topic |
Author |
Message |
Sigma
Joined: 03 May 2004 Posts: 48 Location: Sg
|
Error: Could not run program. The Tbytestack was empty! |
Posted: Mon Jun 21, 2004 7:37 pm |
|
|
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
|
|
Posted: Tue Jun 22, 2004 3:01 am |
|
|
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
|
|
Posted: Tue Jun 22, 2004 3:16 am |
|
|
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
|
|
Posted: Tue Jun 22, 2004 4:16 am |
|
|
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
|
|
Posted: Tue Jun 22, 2004 7:09 am |
|
|
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
|
|
Posted: Tue Jun 22, 2004 8:59 am |
|
|
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
|
|
Posted: Wed Jun 23, 2004 1:27 am |
|
|
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
|
|
Posted: Wed Jun 23, 2004 11:02 am |
|
|
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
|
|
Posted: Wed Jun 23, 2004 11:14 pm |
|
|
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?
Sigma |
|
|
|
|
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
|