| 
	
	|  |  |  
	
		| View previous topic :: View next topic |  
		| Author | Message |  
		| bryant@balancebitsconsult 
 
 
 Joined: 21 Nov 2023
 Posts: 38
 
 
 
			    
 
 | 
			
				| #INT_RDA triggering at start before interrupts enabled ? |  
				|  Posted: Fri Mar 08, 2024 6:31 pm |   |  
				| 
 |  
				| Is there a reason why a PIC24 would trigger the INT_RDA interrupt handler at startup ? 
 I receive an interrupt even before I have enabled INT_RDA interrupts, or before enabling global interrupts.
 
 Is there some #FUSES I need to enable to prevent interrupts from starting before I enable them ?
 
 
 available FUSES:
 
  	  | Code: |  	  | //////// Fuses: WRT,PROTECT,NOGSSK,GSSK,FRC,FRC_PLL,PR,PR_PLL,SOSC,LPRC
 //////// Fuses: FRC_DIV_BY_16,FRC_PS,IESO,EC,XT,HS,NOPR,OSCIO,IOL1WAY,CKSFSM
 //////// Fuses: CKSNOFSM,NOCKSNOFSM,WPOSTS1,WPOSTS2,WPOSTS3,WPOSTS4,WPOSTS5
 //////// Fuses: WPOSTS6,WPOSTS7,WPOSTS8,WPOSTS9,WPOSTS10,WPOSTS11,WPOSTS12
 //////// Fuses: WPOSTS13,WPOSTS14,WPOSTS15,WPOSTS16,WPRES32,WPRES128,PLLWAIT
 //////// Fuses: WINDIS,WDT,NOPUT,PUT2,PUT4,PUT8,PUT16,PUT32,PUT64,PUT128
 //////// Fuses: BROWNOUT,ALTI2C1,ALTI2C2,ICSP3,ICSP2,ICSP1,RESET_AUX
 //////// Fuses: RESET_PRIMARY,JTAG,DEBUG,AWRT,APROTECT,NOAPLK,APLK
 
 | 
 
 
 
 Currently #FUSES are:
 
  	  | Code: |  	  | #include <24EP512GU810.h>
 #device ICSP=1
 #device ADC=12
 #use delay(clock=120MHz,oscillator=4MHz)
 
 #FUSES NOWDT                    //No Watch Dog Timer
 #FUSES GSSK                     //General Segment Key bits, use if using either WRT or PROTECT fuses
 #FUSES IESO                     //Internal External Switch Over mode enabled
 #FUSES OSCIO                    //OSC2 is general purpose output
 #FUSES NOIOL1WAY                  //Allows only one reconfiguration of peripheral pins
 #FUSES CKSFSM                   //Clock Switching is enabled, fail Safe clock monitor is enabled
 #FUSES PLLWAIT                  //Clock switch to PLL will wait until the PLL lock signal is valid
 #FUSES WINDIS                   //Watch Dog Timer in non-Window mode
 #FUSES PUT128                   //Power On Reset Timer value 128ms
 #FUSES BROWNOUT                 //Reset when brownout detected
 #FUSES RESET_PRIMARY            //Device will reset to Primary Flash Reset location
 #FUSES JTAG                     //JTAG enabled
 #FUSES APLK                     //Auxiliary Segment Key bits, use if using either AWRT or APROTECT fuses
 
 #FUSES CKSFSM                   //Clock Switching is enabled, fail Safe clock monitor is enabled
 
 | 
 |  |  
		|  |  
		| temtronic 
 
 
 Joined: 01 Jul 2010
 Posts: 9588
 Location: Greensville,Ontario
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Sat Mar 09, 2024 11:54 am |   |  
				| 
 |  
				| I would have to read the datasheet to see IF the UART buffer is internally cleared on powerup. 
 Old skool, you 'init' all the RAM and clear /set registers the way YOU need.
 Some areas come up 0,1 or ugh..... x....   (unknown..50/50 draw )
 |  |  
		|  |  
		| Ttelmah 
 
 
 Joined: 11 Mar 2010
 Posts: 19966
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Sun Mar 10, 2024 7:46 am |   |  
				| 
 |  
				| The classic reason it'd trigger at startup, is that the RX line into the UART is not rising immediately. This always happened on traditional UART's, when
 using the MAX232, since the charge pump in this took a while to build
 up it's internal voltage. A low line on the TX output of this was seen as
 received data on the device attached.
 
 The solution is simple. Make sure the RDA line is high, and the UART buffer
 is flushed _before_ you enable the interrupt,
 So you have something like:
 
  	  | Code: |  	  | #USE RS232(UART1, BAUD=57600, BITS=8, ERRORS, STREAM=SERIAL, NOINIT)
 //Depending on the chip you may not be able to read the line unless
 //NOINIT is used
 
 int error_cnt=0;
 while (input(UARTRX_PIN)==0)
 {
 delay_ms(10);
 if (error_cnt++>50)
 {
 your_error_code(); //do something to handle the error
 }
 }
 //Now iniit the UART
 setup_UART(1,SERIAL); //This starts the UART
 
 
 | 
 
 Because this does not physically start the UART, till the RX line is high
 no spurious characters are received.
 |  |  
		|  |  
		| bryant@balancebitsconsult 
 
 
 Joined: 21 Nov 2023
 Posts: 38
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Mon Mar 11, 2024 10:48 am |   |  
				| 
 |  
				| I would tend to agree with you, but I am getting an interrupt BEFORE I enable any interrupts.  In debugging I can see that I am getting a INT_RDA which is hitting the ISR breakpoint set AT STARTUP, before I even get to enabling the interrupts later on in code! 
 The serial line is even pulled up -- but that code happens after the interrupt is triggered too...
 
 It also appears that the board resets very shortly after hitting this interrupt .. I am having difficulty determining why the board is getting the serial interrupt and/or why the board is resetting so quickly after startup.
 
 I can't catch the restart code in debug code, but the restart code AFTER the first restart reports "RESTART_POWER_UP", indicating that this might be normal ??
 |  |  
		|  |  
		| Ttelmah 
 
 
 Joined: 11 Mar 2010
 Posts: 19966
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Mon Mar 11, 2024 11:35 am |   |  
				| 
 |  
				| If UART is not enabled it can't generate an interrupt. If you look at what I'm suggesting, you physically do not turn the UART on, until the
 line is seen as high. Problem is the default behaviour is to enable the
 UART right at the start of the code. Even a slight delay in the line going
 high, will lead to a character being seen, and hence a spurious interrupt.
 
 An interrupt being set, should not matter at all if it is not enabled. So
 if you don't want to delay the UART setup, just pause and read any
 characters in the UART input buffer before enabling the interrupt.
 Remember a framing error will trigger a UART interrupt, if you don't
 have the errors handled separately. This bit has to be turned off or
 this will keep triggering.
 
 The only way the interrupt handler can be called before it is enabled
 is something like a stack error, or a jump to an invalid address.
 What happens if you reduce your code to a basic flash an LED test.
 Does this work correctly???.
 
 There was a [erson with a similar problem on the Micochip forum, and
 it turned out to be inadequate smotthing on the CPU supply. I'd look
 carefully at this, and add the traps.c handler, and see if you may be
 triggering a processor trap.
 |  |  
		|  |  
		| bryant@balancebitsconsult 
 
 
 Joined: 21 Nov 2023
 Posts: 38
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Mon Mar 11, 2024 12:23 pm |   |  
				| 
 |  
				| I see it now, the NOINIT which I assume does not enable the interrupts -- so even though I am "enabling" serial interrupts later in code the enable interrupts call is redundant since my #use block has already turned the ones related to serial on. 
 I will also take a look at the power issue you mention, this situation is very possible.
 |  |  
		|  |  
		| Ttelmah 
 
 
 Joined: 11 Mar 2010
 Posts: 19966
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Wed Mar 13, 2024 5:01 am |   |  
				| 
 |  
				| No. 
 NOINIT, does not enable the peripheral. Does not configure it, and does not
 turn it on at all. The #USE does not enable the interrupt.
 
 The point is you cannot get an interrupt at all from a non enabled peripheral.
 If your code is ending up in the interrupt handler routine, with the interrupt
 disabled, it implies it is getting to this address 'another way'. So either a
 'return' with an invalid address on the stack, a jump to an address in the
 interrupt area, or a TRAP interrupt without a handler. I'd possibly suspect
 the latter.
 |  |  
		|  |  
		| bryant@balancebitsconsult 
 
 
 Joined: 21 Nov 2023
 Posts: 38
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Wed Mar 13, 2024 11:48 am |   |  
				| 
 |  
				| We are saying the same things, differently. |  |  
		|  |  
		| gaugeguy 
 
 
 Joined: 05 Apr 2011
 Posts: 350
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Wed Mar 13, 2024 1:22 pm |   |  
				| 
 |  
				| NOINIT means do not initialize and do turn on the peripheral.  It has nothing to do with interrupts at all. |  |  
		|  |  
		| Ttelmah 
 
 
 Joined: 11 Mar 2010
 Posts: 19966
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Thu Mar 14, 2024 1:40 am |   |  
				| 
 |  
				| Bryant, you said: 
  	  | Quote: |  	  | the enable interrupts call is redundant since my #use block has already turned the ones related to serial on.
 
 | 
 
 That is totally untrue.
 
 The interrupts are not enabled till you turn them on.
 A disabled interrupt can become set, but it does not call the handler.
 If the handler is being called, something else is going on. I suspect you
 have one of possibly a dozen faults, possibly with the hardware.
 You can get spurious jumps if the decoupling is not adequate.
 Or as I said you might be incorrectly executing a return without a matching
 call, or any one of a number of other hardware or software faults.
 One classic that can cause an issue on the PIC, is EMI.
 |  |  
		|  |  
		| Ttelmah 
 
 
 Joined: 11 Mar 2010
 Posts: 19966
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Sat Mar 16, 2024 12:32 pm |   |  
				| 
 |  
				| As a suggestion, add to the start of your iNR_RDA handler, the line: 
 if(interrupt_active(INT _RDA))
 delay_cycles(1);
 
 Put your breakpoint on the delay.
 
 I suspect you will find he routine is arriving here without the interrupt
 actually being set. Proof that it is getting here some other way.
 |  |  
		|  |  
		|  |  
  
	| 
 
 | 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
 
 |