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

Address error on 30F3011

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



Joined: 31 Dec 2007
Posts: 2

View user's profile Send private message

Address error on 30F3011
PostPosted: Mon Dec 31, 2007 4:25 pm     Reply with quote

Hello!
I'm experiencing serious problems with the software I'm writing for a 30F3011 dsPIC.
In particular, even disabling interrupt nesting, my PIC still resetting itself with the ADDRERR exception. The problem appears when I try to use Timer1, 4 and 5 with a short interval between each interrupt.
In particular, I have a printf in timer1 interrupt handle and two PWM routines in timer 4 and 5. Except for the printf routine, there are few instructions in each interrupt handles, but I'm quite sure that that the problem is in the time taken by the printf to perform the write on the serial port.
So, I have timer1 configured to give an interrupt every 0.85 sec and the printf has to transmit more or less 120 characters @38400bps; if I set the timer 4 and 5 with a long period -more than 0.5msec-, I get no problem at all.
When the period begins to be short (in my case, when I want to update the PWM often, about 0.3msec) I begin to get garbage character on serial port even with the DISABLE_INT command in the #use rs232 directive, and when the period is *really* short -less than 0.3msec- the PIC "panics" and resets itself entering in the ADDRERR trap.
Setting interrupts priorities had no effect...
Do you have any idea about how to solve this problem?
Well, of course, sorry for my english, I hope that my problem is clear enough! Embarassed
rnielsen



Joined: 23 Sep 2003
Posts: 852
Location: Utah

View user's profile Send private message

PostPosted: Mon Dec 31, 2007 5:48 pm     Reply with quote

First of all, one thing about interrupts, they should be short and sweet.

You stated that you 'only' have one printf in your interrupt. Never _ever_ place a printf in an interrupt. Printf generates a ton of code and your processor will puke. Interrupts should contain as little code as possible. Something like setting a few flags or variables and then exit. Don't do any interrupt_enable() or interrupt_disable() commands inside and interrupt either.

Without seeing any code it's hard to know what else there might need to be changed.

Ronald
gpaolo79



Joined: 31 Dec 2007
Posts: 2

View user's profile Send private message

PostPosted: Mon Dec 31, 2007 7:09 pm     Reply with quote

rnielsen wrote:
First of all, one thing about interrupts, they should be short and sweet.

You stated that you 'only' have one printf in your interrupt. Never _ever_ place a printf in an interrupt. Printf generates a ton of code and your processor will puke. Interrupts should contain as little code as possible. Something like setting a few flags or variables and then exit. Don't do any interrupt_enable() or interrupt_disable() commands inside and interrupt either.

Without seeing any code it's hard to know what else there might need to be changed.

Ronald


Eheh, ok, thanks for the answer, I had the idea that the problem was in the lenght of that interrupt.
But I choose to do that because I knew no way to do it otherwise... I mean, what I need to have is telemetry sent at regular intervals in background, and the only way I found to do it -no matter what the PIC was doing- was to put the printf in the interrupt.
Maybe with some suggestion about how to solve the telemetry problem, I may change the interrupt routine.

These are the interrupt routines:

Code:

#INT_EXT0 //Switch anteriore
void switch1_check() {
   if (input(PIN_E8)) {toccato_av=1; INTCON2=INTCON2|0x0001;}
   else {toccato_av=0; bloccato_av=0; INTCON2=INTCON2&0xFFFE;}
}


#INT_EXT2 //TX Occupato
void TX_check() {
   if (input(PIN_D1)) {tx_busy=1; INTCON2=INTCON2|0x0004;}
   else {tx_busy=0; INTCON2=INTCON2&0xFFFB;}
}


(NOTE: I had to take TIMER2 offline because it caused the address error too...)
/*#INT_TIMER2 //Tempo esecuzione istruzione
void time()
{time_index++;
#asm
DISI #1
#endasm
}*/


#INT_TIMER1                       
void invia_telemetria()
{if (tx_busy==0)
   {if (strlen(buffer_tx)>0)
      {TRISD=TRISD&0xFFFD;
      output_bit( PIN_D1, 1); //RD1 diventa output e portato ad 1
      printf("%s",buffer_tx);
      TRISD=TRISD|0x0002;
      buffer_tx[0]=0x00;
      }
   }
#asm
DISI #4
#endasm
}



#INT_TIMER4                       
void speed_control_x()
{if (toccato_av==0) // GESTIRE IL TOCCO AVANTI E INDIETRO??
   {if (posizione_x>PDC1) PDC1++;
   else if (posizione_x<PDC1) PDC1--;
   else if (posizione_x==PDC1) T4CON=T4CON&0x7FFF; //Disabilita timer4
   }
else {if ((PDC2+1)<MAX_SU) {PDC2++; delay_ms(1);}
   else {bloccato_av=1; posizione_x=PDC1; T4CON=T4CON&0x7FFF;}
   }
#asm
DISI #4
#endasm
}

#INT_TIMER5                       
void speed_control_y()
{if (posizione_y==PDC2) T5CON=T5CON&0x7FFF; //Disabilita timer4
else if (posizione_y>PDC2) PDC2++;
else if (posizione_y<PDC2) PDC2--;
#asm
DISI #4
#endasm
}

#INT_RDA
void serial_rx()
{buffer_rx[rx_idx]=getc();
if (buffer_rx[rx_idx]<0x7F)
   {if (buffer_rx[rx_idx]==0x0A)
      rx_complete_stat=1;
   else if ((rx_idx+1)<MAX_BUFFER) rx_idx++;}
}


Tell me if you need other code, the program is quite long and I still working on it, so it may be not too clear right now...
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