|
|
View previous topic :: View next topic |
Author |
Message |
fedetouz
Joined: 01 Aug 2007 Posts: 14
|
problems with RDA and EXT interrupts |
Posted: Fri Aug 31, 2007 8:56 am |
|
|
Hi, all , i have a this problem, when active RDA only the program works fine!, but when active EXT , RDA don't work, i try everything, i can solve the problem, EXT is for software UART, i post a part of the code:
Code: |
#use delay(clock=4M)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=Xbee232,ERRORS)
#use rs232(baud=1200,parity=N,xmit=PIN_B4,rcv=PIN_B0,bits=8,stream=GSM,ERRORS,sample_early,DISABLE_INTS)
|
Code: |
#include <config.h>
#include "driver_LCD.h"
#include "xbee.h"
#define inicio 1
#define enviar_Xbee 2
int estados,modo;
#define AT 1
#define API 2
#define BUFFER_SIZE 32
char buffer[BUFFER_SIZE+1];
int8 buf_index = 0;
char buffer_gsm[BUFFER_SIZE+1];
int8 buf_index_gsm = 0;
uint8 newChar;
uint8 buffer_API[BUFFER_SIZE];
uint8 next_in = 0;
uint8 next_out = 0;
/**Respuestas del XBEE**/
char ok[] = { "OK" };
//=====================================================================
uint8 *p;
uint8 *packet;
void XBee_SendPacket( XBeePacket* packet, int size );
int XBee_GetPacket( XBeePacket* packet);
void XBee_InitPacket( XBeePacket* packet );
uint8* XBee_GetPacketDataPointer( XBeePacket* packet );
int XBee_GetIOValues( XBeePacket* packet, int *inputs );
void Senal_DB(void);
int t;
//====================================================================
#use delay(clock=4M)
#int_RDA
void RDA_isr(void)
{
disable_interrupts(INT_RDA);
switch(modo){
case AT:
// Don't exceed the size of the buffer
if (buf_index < BUFFER_SIZE)
{
buffer[buf_index]=fgetc(Xbee232);
//printf(lcd_putc,"\n%c",buffer[buf_index]);
//delay_ms(300);
buf_index++;
// Terminate our string
buffer[buf_index] = 0;
}break;
case API:
buffer_API[next_in]=fgetc(Xbee232);
t=next_in;
next_in=(next_in+1) % BUFFER_SIZE;
if(next_in==next_out){
next_in=t;}
break;
}
enable_interrupts(INT_RDA);
}
#define bkbhit (next_in!=next_out)
uint8 bgetc() {
BYTE c;
while(!bkbhit) ;
c=buffer_API[next_out];
next_out=(next_out+1) % BUFFER_SIZE;
return(c);
}
void clear_buffer(void)
{
int erase=0;
disable_interrupts(INT_RDA);
buf_index = 0;
buffer[0] = 0;
while(erase!=BUFFER_SIZE){
buffer[erase] = 0x00;
erase++;}
enable_interrupts(INT_RDA);
}
void clear_buffer_API(void)
{
int erase=0;
disable_interrupts(INT_RDA);
buf_index = 0;
next_in=0;
next_out=0;
while(erase!=BUFFER_SIZE){
buffer_API[erase] = 0x00;
erase++;}
enable_interrupts(INT_RDA);
}
#inline
void delay_sec (void)
{
delay_ms(1000);
}
char *Xbee_response(
char *s,
int16 timeout) /* wait ms */
{
char *p;
while (TRUE)
{
p = STRSTR(buffer, s);
if (p)
{
/*fprintf(GSM,"encontrado\r");*/
return (P); //drop out of function
}
if (timeout)
{
timeout--;
if (!timeout)
{
/*fprintf(GSM,"timeout\r");*/
/*timeout Buffer */
return (NULL);
}
}
}
}
//========================================================
#int_EXT
void EXT_isr(void)
{
if(kbhit(GSM))
{
if (buf_index_gsm < BUFFER_SIZE)
{
buffer_gsm[buf_index_gsm]=fgetc(GSM);
//printf(lcd_putc,"\n%c",buffer_gsm[buf_index_gsm]);
buf_index_gsm++;
// Terminate our string
buffer_gsm[buf_index_gsm] = 0;
}
}
}
void clear_buffer_gsm(void)
{
int erase=0;
buf_index_gsm = 0;
buffer_gsm[0] = 0;
while(erase!=BUFFER_SIZE){
buffer_gsm[erase] = 0x00;
erase++;}
}
char *gprs_response(
char *s, /* String that we are looking for */
int16 timeout) /* How long to wait in miliseconds */
{
char *p;
while (TRUE)
{
p = STRSTR(buffer_gsm, s);
if (p)
{
/*fprintf(GSM,"encontrado\r");*/
return (P); //drop out of function
}
if (timeout)
{
timeout--;
if (!timeout)
{
/*fprintf(GSM,"timeout\r");*/
/*timeout Buffer */
return (NULL);
}
}
}
}
//=======================================================================================
//MAIN
//======================================================================================
void main(void)
{
XBeePacket myPacket, *packet, myPacket1 , myPacket2;
XBee_TXStatus Status_buffer,*Status;
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
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);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
setup_low_volt_detect(FALSE);
ext_int_edge( 0, H_TO_L );
enable_interrupts (INT_EXT);
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
lcd_init();
printf(lcd_putc,"\fIniciando Sistema\n");
delay_sec();
packet = &myPacket;
packet->apiId = XBEE_COMM_TX16; // we're going to send a packet with a 16-bit address
packet->tx16.frameID = 0x01;
packet->tx16.destination[0] = 0x50; // 0xFFFF is the broadcast address
packet->tx16.destination[1] = 0x01;
packet->tx16.options = 0x00; // no options
packet->tx16.data[0] = 'H'; // now pack in the data
packet->tx16.data[1] = 'e';
packet->tx16.data[2] = 'l';
packet->tx16.data[3] = 'l';
packet->tx16.data[4] = 'o';
// finally, send the packet indicating that we're sending 3 bytes of data - "ABC"
packet= &myPacket1;
packet->apiId = XBEE_COMM_TX16; // we're going to send a packet with a 16-bit address
packet->tx16.frameID = 0x01;
packet->tx16.destination[0] = 0x50; // 0xFFFF is the broadcast address
packet->tx16.destination[1] = 0x02;
packet->tx16.options = 0x00; // no options
packet->tx16.data[0] = 'Z'; // now pack in the data
packet->tx16.data[1] = 'X';
packet->tx16.data[2] = 'Y';
// finally, send the packet indicating that we're sending 3 bytes of data - "ABC"
estados=inicio;
while(1){
switch(estados){
case inicio:
clear_buffer_gsm();
fprintf(GSM,"AT\r");
while(gprs_response(ok,8000)==0)
{
lcd_gotoxy(1,2);
printf(lcd_putc,"############");
}
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
modo=AT;
clear_buffer();
printf(lcd_putc,"\nIniciando Zigbee..\f");
delay_sec();
fprintf(Xbee232,"+++");
if(Xbee_response(ok,20000)==0){printf(lcd_putc,"\f +++");break;}
clear_buffer();
fprintf(Xbee232,"ATAP1\r");
if(Xbee_response(ok,20000)==0){printf(lcd_putc,"\f ATAP1");break;}
clear_buffer();
fprintf(Xbee232,"ATCE1\r");
if(Xbee_response(ok,20000)==0){printf(lcd_putc,"\f ATCE1");break;}
clear_buffer();
fprintf(Xbee232,"ATMY5000\r");
if(Xbee_response(ok,20000)==0){printf(lcd_putc,"\f ATMY5000");break;}
clear_buffer();
fprintf(Xbee232,"ATST1388\r");
if(Xbee_response(ok,20000)==0){printf(lcd_putc,"\f ATCE1");break;}
clear_buffer();
fprintf(Xbee232,"ATSP226\r");
if(Xbee_response(ok,20000)==0){printf(lcd_putc,"\f ATCE1");break;}
clear_buffer();
fprintf(Xbee232,"ATCN\r");
if(Xbee_response(ok,20000)==0){printf(lcd_putc,"\f ATCN");break;}
else{ estados=enviar_Xbee;break;}
case enviar_Xbee:
modo=API;
//delay_ms(2000);
clear_buffer_API();
XBee_SendPacket( &mypacket, 5 );
XBee_InitPacket( &myPacket2 );
while(XBee_GetPacket( &myPacket2)==0)
{
delay_ms(100);
}
//delay_ms(1000);
packet= &myPacket2;
printf(lcd_putc,"\fNODO 5001:");
if(packet->txStatus.status==0x00&&packet->txStatus.frameID==0x75)
{
printf(lcd_putc," OK!");
}
else{printf(lcd_putc," ALERTA!!!");}
//delay_ms(3000);
clear_buffer_API();
XBee_SendPacket( &mypacket1, 3 );
XBee_InitPacket( &myPacket2 );
while(XBee_GetPacket(&myPacket2)==0)
{
delay_ms(100);
}
//delay_ms(1000);
packet= &myPacket2;
printf(lcd_putc,"\nNODO 5002:");
if(packet->txStatus.status==0x00&&packet->txStatus.frameID==0x75)
{ printf(lcd_putc," OK!");
}
else{printf(lcd_putc," ALERTA!!!");}
//delay_ms(1000);
break;
}
}
}
|
this is part of the code, i have ICD2 debuger and see buffer_API empty when active EXT interrupt.
Thanks for help! |
|
|
Ttelmah Guest
|
|
Posted: Fri Aug 31, 2007 9:27 am |
|
|
Start wth the RDA ISR. Now, if the buffer is full, you don't read the character. This will result in the interrupt re-triggering indefinately, and hanging the program.
It is possible that the problem is sply that becaue of the extra event, the buffer is getting fuller, and running into this.
As a 'comment', don't disable/enable the interrupts. It is not needed. The hardware already disables interrupts when the handler is called.
Best Wishes |
|
|
Humberto
Joined: 08 Sep 2003 Posts: 1215 Location: Buenos Aires, La Reina del Plata
|
|
Posted: Fri Aug 31, 2007 2:09 pm |
|
|
It seems that when it enter in INT_EXT routine but do not leave. One approach is
to activate some debug flags that will "trace" the steps done inside the interrupt
handler and will show the "last time alive" once in hung state.
Code: |
#int_EXT
void EXT_isr(void)
{
output_high(LED1); // ****************
if(kbhit(GSM))
{
if (buf_index_gsm < BUFFER_SIZE)
{
output_high(LED2); // ****************
buffer_gsm[buf_index_gsm]=fgetc(GSM);
//printf(lcd_putc,"\n%c",buffer_gsm[buf_index_gsm]);
buf_index_gsm++;
// Terminate our string
buffer_gsm[buf_index_gsm] = 0;
output_high(LED3); // ****************
}
}
}
|
Humberto |
|
|
|
|
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
|