| 
	
	|  |  |  
	
		| 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
 
 |