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

Problem with int_EXT execution during fgetc()

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







Problem with int_EXT execution during fgetc()
PostPosted: Tue Jul 06, 2004 2:11 pm     Reply with quote

Dear Colegues,

We are using version 3.203 of PCWH
PIC used is 18F452

We have 3 ISRs in our software. We are using

- one hardware serial port on #int_rda (9600)

- one software serial port with interrupt only for receiving on int_EXT2 (4800)

- one interrupt on #int_EXT





Our problem is that when we are in the ISR on int_EXT2 (interrupt driven software serial port), #int_EXT is nor working. In details we tested that fgetc(SOURCE2) can not be interrupted by int_EXT.

fgetc(SOURCE2) takes about 230 uS, so as result we are loosing some interrupts.

In order to solve this problem would be very useful to have source of your fgetc() you have implemented in this compiler. This give as ability to adopt it to our needs.

Our request is to be able to realize #int_EXT interrupts also during fgetc() execution.

Thank you very much for your prompt reply.

Best regards

JOHN







1)



//************************************************************************************

//we have a change to the RXD pin

#int_EXT

EXT_isr()

{

_rx.Periods[_rx.PeriodsWritePtr]=get_timer3();

set_timer3(0);

_rx.PeriodsWritePtr++;

_rx.PeriodsWritePtr&=RXPERIODSLEN;



//store period for process by background

//flip sensor for ISR

if (_intKind)

ext_int_edge(0,L_TO_H);

else

ext_int_edge(0,H_TO_L);

_intKind^=1;

}





2)



#int_rda

void serial_isr(void)

{



_USBserial.buffer[_USBserial.WritePtr]=fgetc(USB);

_USBserial.WritePtr++;

_USBserial.WritePtr&=MAXSERIALBUF;

if(_USBserial.WritePtr==_USBserial.ReadPtr)//buffer full

{

_USBserial.ReadPtr++;

_USBserial.ReadPtr&=MAXSERIALBUF;

}

}







3)



int_EXT2

void SOURCE2RcvInt(void)

{

_SOURCE2serial.buffer[_GPSserial.WritePtr]=fgetc(SOURCE2); // 210 uS

inline_test();

_SOURCE2serial.WritePtr++;

_SOURCE2serial.WritePtr&=MAXSERIALBUF;

if(_SOURCE2serial.WritePtr==_SOURCE2serial.ReadPtr)//buffer full

{

_SOURCE2serial.ReadPtr++;

_SOURCE2serial.ReadPtr&=MAXSERIALBUF;

}

}







//************************************************************************************

//we have a change to the RXD pin

#int_EXT

EXT_isr()

{

_rx.Periods[_rx.PeriodsWritePtr]=get_timer3();

set_timer3(0);

_rx.PeriodsWritePtr++;

_rx.PeriodsWritePtr&=RXPERIODSLEN;



//store period for process by background

//flip sensor for ISR

if (_intKind)

ext_int_edge(0,L_TO_H);

else

ext_int_edge(0,H_TO_L);

_intKind^=1;

}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Jul 06, 2004 3:43 pm     Reply with quote

Quote:
In order to solve this problem would be very useful to have source of
your fgetc() you have implemented in this compiler.


You can see the assembly language source for fgetc() by looking
at the .LST file created by the compiler. Look at the assembly
language code that comes after your #use rs232() statement
for the software USART. Example:
Code:

0000   00379 .... #use rs232(baud=9600, rcv=PIN_B2, stream = SW) 
00D6 FFFF           00418 NOP(FFFF)      <-- Source code for fgetc()   
00D8 0E08           00381 MOVLW  08       
00DA 6E00           00382 MOVWF  00
00DC 8493           00383 BSF    F93.2
00DE B481           00384 BTFSC  F81.2
00E0 EF6F F000      00385 GOTO   00DE
.
.
.
etc.
C-H Wu
Guest







PostPosted: Wed Jul 07, 2004 7:28 pm     Reply with quote

>> Our problem is that when we are in the ISR on int_EXT2 (interrupt driven software serial port), #int_EXT is nor working.

If what you want is to interrupt another interrupt, i.e. nested interrupt ?

try this:

#int_EXT FAST // FAST keyword making #int_EXT become high-priority
EXT_isr()
{ ...
}

then this high-priority EXT_isr() can interrupt low-priority ISR's.
I don't quite remember if the #int_EXT is high priority be default. Anyway, check the interrupt priority bit setting and also make sure that GIE is not disabled in other ISR's.

for more details, see c:\PICC\Readme.txt
Quote:
We added some support for PIC18 priority interrupts. You can define
one interrupt as priority like this:
#INT_RTCC FAST
isr() {
...
}
A fast interrupt can interrupt another interrupt handler. The compiler
does no save/restore in a fast ISR. You should do as little as possible
and save any registers that need to be saved on your own.


BTW, I recommand 3.204 instead of 3.203, http://www.ccsinfo.com/versions.shtml
Quote:
3.204 Optimization bug from 2.203 is fixed



Best wishes

C-H Wu
ckielstra



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

View user's profile Send private message

PostPosted: Thu Jul 08, 2004 1:55 am     Reply with quote

>> Our problem is that when we are in the ISR on int_EXT2 (interrupt driven software serial port), #int_EXT is nor working.

From the PIC18Fxx8 manual:
Quote:
When an interrupt is responded to, the Global Interrupt Enable bit is cleared to disable further interrupts. If the
IPEN bit is cleared, this is the GIE bit. If interrupt priority
levels are used, this will be either the GIEH or GIEL bit.
High priority interrupt sources can interrupt a low
priority interrupt.


So your described behaviour is by design. As C-H Wu already mentioned you can use the FAST keyword to create a high priority interrupt that is capable of interrupting your #int_EXT2. If you decide on doing so, then please search this forum for more info on how to use these interrupts as there are some specific issues to be aware of, like you will have to save several registers and it's not working on older revisions of the 18F452.

Still it seems like a tricky design to me, because now your code in int_EXT will interfere with the getc() in the int_EXT2 and might cause a wrong character to be decoded. How often is int_EXT occuring? What speed is your processor running?

Another option:
Can you make your system to work like a half-duplex system? I mean, can you tell the system on the EXT-port to stop sending data while you are receiving on the EXT2-port? Maybe you have here something like RTS/CTS pins?
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