XMega32A4u Interrupt I-flag

Go To Last Post
19 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

We have a project with various interrupts. The 1ms C0 timer interrupt is the lowest priority and we would like the RXC uart interrupt to be able to interrupt this timer interrupt.

 

We have added a asm("sei") instruction at the beginning of the Timer ISR but when we set the timer INTFLAG, the timer routine needs to complete before it then call the Timer ISR again. We are using the JTAG ICE. Is this normal operation?

 

The problem we have is dropped receive bytes and it appears this is due to an interrupt routine taking too long - ie two serial bytes may be received during timer ISR.

 

I guess a DMA pipe would fix this but using the DMA does not look straight forward.

Electronic System Design
http://www.esdn.com.au

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Multiple interrupts with xmega are not managed by the I flag.
Therefore, multiple interrupts of the same interrupt level are not generated.
Let TimerC 0 be a low-level interrupt and RXC be a high-level interrupt.
The sei command is useless. Because the I flag is not manipulated by xmega interrupts.

Use of multilevel interrupts requires caution. This is because unless cli is executed in the low-level interrupt, a higher level interrupt is always executed.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hefty wrote:
asm("sei") instruction at the beginning of the Timer ISR
Whoah! Talk about dodgy practice. You have to be VERY sure there's no possibility the ISR may recurse in that case !!

 

Far better is to reassess your overall design. As long as ISR() handlers are over in microseconds they should not really block others though there could be a very small jitter as their service is delayed.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks Kabasan and clawson. 

 

Kabasan, you reply is very informative. I think you are correct that the I flag is not used in interrupts and so the sei instruction is useless. I know that with other microcontrollers, the i-flag is manipulated which then allows interrupts to be blocking or non-blocking.

 

Clawson, we are trying to make this work, not break it. We are currently using USB HID and a 500kBaud UART. It looks like it is probably the USB interrupt (there are two interrupts) which takes a few us to complete. At 500kBaud, it only takes 4us to skip a byte. I have changed the speed down to 125kBaud but there is still an issue. When I set the USB interrupts to medium level priority, the USB HID driver does not run.

 

Not sure where to go now. Does anyone know how to use the JTAG ICE trace? I have been using the JTAG ICE for around a month now and it does seem very limited and is not so good at even single stepping (except in assembler).

Electronic System Design
http://www.esdn.com.au

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Here is some more info on the problem we have.

 

First, it looks like the AVR JTAG ICE does not have a trace function. So as a debugger, it does single stepping (badly), breakpoints (if you are lucky), no stopwatch and no trace.

 

With the serial data, we have 3 sources of error:

  • FERR - no stop bit detected (70% of the time)
  • Bytes lost - 2 bytes sometimes just go missing (20% of the time)
  • Timeout - serial byte no read within 5ms (10% of the time)

 

This is using the USB HID code. When we run the USB CDC code, the same serial functions work fine.

 

With the other controller, we are using the internal oscillator, so I will turn that off and see what happens. Possibly the internal oscillator is out.

Electronic System Design
http://www.esdn.com.au

Last Edited: Thu. Aug 31, 2017 - 11:17 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes, that was it. Thanks for all the help. Using the external crystal, all is ok. With internal crystal, 2 of 32 boards are out.

 

Here is the code to use the internal oscillator. If anyone can see an error, let me know. Thanks

 

void set_8MHz_osc(void)
{
i_union cal;

    CPU.CCP=CCP_IOREG_gc;    // 0xd8 Enable the clock source
    OSC.XOSCCTRL = 0x67; // enable 14MHz, 32kHz low power


    OSC.PLLCTRL = 4; // 0x4=2MHzx8=16Mhz 0x80 = 32MHz
    OSC.CTRL = OSC_PLLEN_bm; // PLLEN and RC2MEN
    while ((OSC.STATUS & (OSC_PLLEN_bm ))!=(OSC_PLLEN_bm)) {} // wait for it to become stable

    CPU.CCP=CCP_IOREG_gc; //0xd8
    CLK.CTRL = CLK_SCLKSEL_PLL_gc; // PLL is clock source now

    DFLLRC2M.CTRL = 1;

   	cal.b[0] = ReadSignatureByte(RCOSC2M);
	cal.b[1] = ReadSignatureByte(RCOSC2MA);
	/*
	* If a device has an uncalibrated value in the
	* production signature row (early sample part), load a
	* sane default calibration value.
	*/
	if (cal.u == 0xFFFF) {
		cal.u = 0x2340;
	}
//	osc_user_calibration(OSC_ID_RC2MHZ,cal);
    DFLLRC2M.CALA=cal.b[1];
	DFLLRC2M.CALB=cal.b[0];
}

 

Electronic System Design
http://www.esdn.com.au

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

@Hefty said:

 I think you are correct that the I flag is not used in interrupts and so the sei instruction is useless.

Wrong!  The I-flag enables/disables interrupt.  If this flag is clear, no interrupts.  With the XMEGAs, in addition to setting the I-flag, you also have to

  1. Configure the peripheral to one of the three interrupt priority levels
  2. Make sure the priority level you selected in step 1 is enabled on the PMIC (Programmable Multilevel Interrupt Controller)

 

The PMIC allows you to enable/disable specific priority levels.  The I-flag turns all (maskable) interrupts off or on.

Greg Muth

Portland, OR, US

Xplained Boards mostly

Atmel Studio 7.0 on Windows 10

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Greg, thanks for the reply.

 

Yes, the sei/cli instructions do work, but I was specifically referring to inside the interrupt.

 

For example, if an interrupt is called, and the sei instruction is used to re-enable interrupts within the ISR and the same interrupt flag trigger gets set, the next interrupt will not get called until after the first interrupt finishes. I did test this in the JTAG ICE. This is not a major deal breaker but could cause some issues if it is not understood.

 

In the end, the issue I had was not related to this - it was to do with some very rough oscillator calibration.

 

 

Electronic System Design
http://www.esdn.com.au

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hefty wrote:
and the same interrupt flag trigger gets set, the next interrupt will not get called until after the first interrupt finishes.
That does not sound right. When I is enabled then on every opcode fetch the AVR checks the set of interrupt trigger flags and will then vector to any it finds set. So if you are in UART ISR, then you SEI, then the UART trigger happens again you should find yourself back at the start of the UART ISR having interrupted the only half finished previous service. That is why I mentioned recursion above!

 

Perhaps Xmega have some different way to handle this compare to Tiny/Mega ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So ...
Even when xmega enters the interrupt service routine,

it does not automatically clear the I flag.

 

Multiple interrupts with xmega are not managed by the I flag.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

Perhaps Xmega have some different way to handle this compare to Tiny/Mega ?

And indeed it has. The PMIC ensure that an ongoing interrupt can't be interrupted by another interrupt that has a lower or equal priority.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

@kabasan said:

So ...

Even when xmega enters the interrupt service routine,

it does not automatically clear the I flag.

 

Of course it doesn't.  How could a high priority interrupt interrupt a low priority interrupt if the I-flag were clear?  From the A Manual:

 

 

 

Greg Muth

Portland, OR, US

Xplained Boards mostly

Atmel Studio 7.0 on Windows 10

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It seems you are spending a lot of time servicing the timer interrupt.  Can't it just set a flag and return?  Whatever you have as an "operating system" could then do what needs to be done as a result of the timer interrupt, as a normal interruptible task?

Last Edited: Fri. Sep 1, 2017 - 11:28 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What are you talking about?

 

The interrupt service routine does not clear the I flag.
If I flag is cleared, no interrupt is generated.

Both are correct but totally different story.

Last Edited: Sat. Sep 2, 2017 - 02:13 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The counter/timer is a big beast.  It can generate several interrupts.  Some of the interrupt request flags are cleared when the interrupt is taken.  At least one other is not cleared automatically.  You have to read a register.  If that interrupt flag is not cleared it would generate constant interrupts.  I don't see any other way the counter/timer could cause overruns in the usart. 

 

Well if the counter/timer was set up to generate a million interrupts a second, that could wreak havoc.

Last Edited: Sun. Sep 3, 2017 - 01:45 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Please read # 8.
This thread is already closed.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This thread is already closed.

Then mark it as such.  Find the post which most closely qualifies as the solution, and click the button.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

He's not the OP ;-) 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

He's not the OP ;-) 

Whoops!  Shouldn't post when I'm sleepy ;-)

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]