|
|
View previous topic :: View next topic |
Author |
Message |
JohnM Guest
|
Problem with int_EXT execution during fgetc() |
Posted: Tue Jul 06, 2004 2:11 pm |
|
|
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
|
|
Posted: Tue Jul 06, 2004 3:43 pm |
|
|
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
|
|
Posted: Wed Jul 07, 2004 7:28 pm |
|
|
>> 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
|
|
Posted: Thu Jul 08, 2004 1:55 am |
|
|
>> 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? |
|
|
|
|
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
|