View previous topic :: View next topic |
Author |
Message |
Dave
Joined: 05 Feb 2005 Posts: 314 Location: OR
|
Posted: Sat May 11, 2019 5:35 pm Post subject: xm32e5 external interrupt problem |
|
|
Hello All.
I've been trying to port xm256a3u code to a xm32e5 chip. First I tried for two days to get the mcs bootloader to work. I finally found the problem and solution on this forum, thanks to enniom and Mark for that. Here is the link to the bootloader solution: https://www.mcselec.com/index2.php?option=com_forum&Itemid=59&page=viewtopic&t=13194&highlight=32e5
Now I find that there is a problem with external interrupts. The code works until the first interrupt then the interrupt routine runs over and over even after the interrupt has ended. So it appears the interrupt flag is not being reset at the end of the isr as expected. The code works as expected in the simulator, the problem only happens in my hardware. I've included code that will run in the simulator. Given the problem with the bootloader running in the xm332e5 I'm assuming the problem is with the chip and not the code but if anybody sees a problem in my code or has any suggestions I would like to here them. Also if anybody could try this on there xm32e5 that would be great also.
Code: |
$sim
$crystal = 32000000
$regfile = "xm32E5def.dat"
'$regfile = "xm256A3Udef.dat"
$hwstack = 42 '32 min. w/interrupts
$swstack = 16 '16 min.
$framesize = 34 '24 min.
'$lib "xmega.lib"
CONFIG SUBMODE = NEW
Config Osc = Disabled , 32mhzosc = Enabled
Config Sysclock = 32mhz , Prescalea = 1 , Prescalebc = 1_1
Config Priority = Static , Vector = Application , Lo = Disabled , Med = Enabled , Hi = Disabled
Config Com3 = 115200 , Mode = Asynchroneous , Parity = None , Stopbits = 1 , Databits = 8
Open "Com3:" For Binary As #3
print #3, version(3)
print #3, version()
print #3,
Config Pinc.0 = input
'set portc.0
'Config Xpin = portc.0 , Sense = LOW_LEVEL , outpull = pullup
'Config Xpin = portc.0 , Sense = falling , outpull = pullup
PortC_pin0ctrl = &B00_000_010 'Totem and falling edge
PortC_int0mask = &B0000_0001 'include PIN0 in INT0 Mask
On PortC_int0 rfm_nIRQ_int
Enable PortC_int0
enable interrupts
dim b as byte
do
incr b
wait 1
print #3,b;" ";bin(portc_intflags)
loop
sub rfm_nIRQ_int()
b=0
print #3,
print #3,bin(portc_intflags)
'portc_intflags=0
'print #3,bin(portc_intflags)
end sub
|
(BASCOM-AVR version : 2.0.8.1 )
Last edited by Dave on Sat May 11, 2019 7:19 pm; edited 1 time in total |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Sat May 11, 2019 6:52 pm Post subject: Re: xm32e5 external interrupt problem |
|
|
Since when are interrupt flags cleared by writing them to zero? |
|
Back to top |
|
|
Dave
Joined: 05 Feb 2005 Posts: 314 Location: OR
|
Posted: Sat May 11, 2019 7:14 pm Post subject: |
|
|
Quote: | Since when are interrupt flags cleared by writing them to zero?
|
They are not. That line is commented out but that does not show well here. They should be cleared by reti. I've tried writing both one and zero just as a test but it still does not clear in my hardware.
edit: opps it was not commented out. |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Sat May 11, 2019 10:29 pm Post subject: |
|
|
Dave wrote: | They should be cleared by reti. |
Normally flags are cleared by execution of the interrupt vector, but the manual for the E5 doesn't mention such behavior.
As also Bascom's sample for XMega's external interrupt explicitely clears the flag, I'd say that's the way to follow. |
|
Back to top |
|
|
Dave
Joined: 05 Feb 2005 Posts: 314 Location: OR
|
Posted: Sun May 12, 2019 11:19 pm Post subject: |
|
|
@MWS - Thanks for your reply.
Quote: | As also Bascom's sample for XMega's external interrupt explicitely clears the flag, I'd say that's the way to follow. |
I can't find this file. Can you please post the name of the file or better yet cut and past the isr and post here.
Quote: | Normally flags are cleared by execution of the interrupt vector, but the manual for the E5 doesn't mention such behavior. |
This is from the ATXMEGA-E Manual:
The PMIC status register contains state information that ensures that the PMIC returns to the correct interrupt level when
the RETI (interrupt return) instruction is executed at the end of an interrupt handler. Returning from an interrupt will return
the PMIC to the state it had before entering the interrupt. The status register (SREG) is not saved automatically upon an
interrupt request. The RET (subroutine return) instruction cannot be used when returning from the interrupt handler
routine, as this will not return the PMIC to its correct state.
That's what made me think the RETI should do the reset but maybe not? |
|
Back to top |
|
|
EDC
Joined: 26 Mar 2014 Posts: 971
|
|
Back to top |
|
|
Dave
Joined: 05 Feb 2005 Posts: 314 Location: OR
|
Posted: Mon May 13, 2019 4:08 pm Post subject: |
|
|
Problem solved.
Add portc_intflags.0=1 to the isr to clear the flag.
Thanks EDC and MWS for the help. |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Mon May 13, 2019 7:55 pm Post subject: |
|
|
Dave wrote: | That's what made me think the RETI should do the reset but maybe not? |
RETI does not clear the flag, it only - beside returning - re-enables global interrupts by setting the I-flag of SREG.
If you look up the interrupt flags for non-XMega 8bit AVRs, you will find it is explicitly described, for example ATMega32:
Quote: | The flag is cleared when the interrupt routine is executed. |
Which can not be found in the XMega manual.
For non-XMegas it's a common programmers trap that if more of the same interrupt events occur while executing the ISR, the flags are set again and the ISR is immediately executed again, as soon RETI re-enables the interrupts.
It was and is an advice then, to clear the flag latest possible, immediately before returning.
The need of clearing interrupt flags by user code imho takes care of this issue. |
|
Back to top |
|
|
|