ISR action before SREG save?

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

using GCC, I basically want to quickly set a timer register before SREG is saved, for time critical reasons. saving SREG is taking 12 cycles at the beginning of the ISR, and I need to set my timer register in less than 8 cycles.

I also need to do other things in the interrupt before leaving it, but I need to get timer register set asap. the kicker is I'd like to be able to do this in C, and just examine the lss file to make sure it's proper, instead of mixing asm and C, if possible.

naked ISR should do the trick, but im not sure which asm opcodes will affect SREG, and which are safe to use in this situation, I'm sure this has been done countless times before. can anyone point me to an example such a trick? ...also is their a clever table which tells what opcodes affect SREG?

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

Quote:

but im not sure which asm opcodes

Didn't Atmel publish an opcode manual for exactly this purpose?

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

Quote:

...also is their a clever table which tells what opcodes affect SREG?

The application note "AVR Instruction Set"?

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

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

oh your right, been over a year since I had to do asm, and I should have just looked at the chart, lol...

//2nd question, how to store SREG similar to how GCC does it, if I declare ISR naked, and use C?

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

I assume this will work fine....


register U8 g_var asm("r2"); 

ISR(MY_ISR_NAME, ISR_NAKED)
{
	WHATEVER_REGISTER = g_var; //do this now!
	
	U8 sreg = SREG;
	
	//do other work...
	
	SREG = sreg;
	
	reti();
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

12oclocker wrote:
...//2nd question, how to store SREG similar to how GCC does it, if I declare ISR naked, and use C?
I'd use a GPIOR.

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

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

i just realized I will mess my stack up with that example, if my other work needs to load stuff from SRAM, humm

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

Why not just do what avr-gcc does..

__vector_1:
//==> ISR(INT0_vect){
	push r1	 ; 
	push r0	 ; 
	in r0,__SREG__	 ; ,
	push r0	 ; 
	clr __zero_reg__	 ; 
/* prologue: Signal */
/* frame size = 0 */
/* stack size = 3 */
.L__stack_usage = 3
/* epilogue start */
//==> }
	pop r0	 ; 
	out __SREG__,r0	 ; ,
	pop r0	 ; 
	pop r1	 ; 
	reti

You simply want to get in "before" this standard prologue/epiloge. So something like:

ISR(INT0_vect, ISR_NAKED) {
	// start by setting timer register at 0x37 to 123
	asm("  push r16 \n\t\
	ldi r16, 123 \n\t\
	out 0x37, r16 \n\t\
	pop r16");

	// continue with normal prologue
	asm("  push r1	 \n\t\
	push r0	 \n\t\
	in r0,__SREG__	 \n\t\
	push r0	 \n\t\
	clr __zero_reg__ ");

	// do other stuff - add PUSH/POP for anything used

	// end with normal epilogue
	asm("  pop r0	 \n\t\
	out __SREG__,r0	 \n\t\
	pop r0	 \n\t\
	pop r1	\n\t\
	reti");
}

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

thanks, that is a good idea, It would be nice to be able to get around the assembly code, and just insert something before the ISR takes off, like an ISR pre code area, that would be a cool thing to have

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

Personally I'd just put the ISR in a .S file and be done with it. The whole idea of ISRs is that they are supposed to be fast and compact so I doubt you'd ever be writing more than say 50 lines of Asm?

BTW I'm intrigued by the whole concept here you opened by saying:

Quote:
want to quickly set a timer register before SREG is saved

What register exactly. If it's the TCNT then that sounds like you really want to be using CTC. If it's anything else such as switching it off (CS=0) then why does it matter if it's 12 cycles late? Even if it's run on a bit can't you just clear pending interrupt flags and so on to "tidy up" or are you saying that it's really going to have an effect on the hardware (like setting OC outputs as a result of COM bits) then is an ISR the best way to handle it? It always takes at least 12 cycles from the interrupting even before even the first opcode of the ISR is executed, that's just the way the AVR interrupting mechanism works.

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

Why do you think it important to set a SFR quickly ?

All the same, you can just ask the Compiler to generate the ISR(). Then inspect the instructions while reading the opcode specs.

If you don't do any maths, you possibly don't ever affect SREG anyway. If you have a global sacrifice Register, you don't need to save it anyway.

However, if you say what you want to do, I suspect that there will be a better way to use the hardware.

David.

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

Quote:
It always takes at least 12 cycles from the interrupting even before even the first opcode of the ISR is executed, that's just the way the AVR interrupting mechanism works.

is this true even if you only have the one interrupt enabled?

Last Edited: Tue. Feb 26, 2013 - 07:00 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes.

Is it really too much for you to read the data sheet ?

Why not say what you want to do?

David.

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

Quote:
It always takes at least 12 cycles from the interrupting even before even the first opcode of the ISR is executed
Not true. It is 4 clocks for the interrupt to launch, 3 clocks for the JMP (or 2 if it is RJMP), plus however many clocks it takes to complete the current opcode. So it can be as little as 7 or 8 clocks.

Regards,
Steve A.

The Board helps those that help themselves.

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

sorry david, I have read the datasheets many times over the years, I will read again. I'm not sure what I want to do yet, I'm just experimenting.

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

Quote:
Not true. It is 4 clocks for the interrupt to launch, 3 clocks for the JMP (or 2 if it is RJMP), plus however many clocks it takes to complete the current opcode. So it can be as little as 7 or 8 clocks.

thanks, that what I see in the simulator too... Im basically just experimenting, I wanted to see how to fit something in before ISR does reg save, I probably don't need to do it, but now it's bugging me, and I want to do it, if that makes any sense ;-)

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

Quote:

if that makes any sense

No, not a lot. Why do you NEED this?

BTW I just tried this in 6.1Beta simulator and the bloody I bit in SREG is worse than ever. Previously it would not work correctly when stepping over SEI/CLI/RETI while now it just randomly switches from being set to cleared. About 8 cycles after I start a timer an SEI the bit just returns to 0 and when the interrupt condition occurs nothing happens. :-(

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

Quote:
Why do you NEED this?

He does not know:
Quote:
I'm not sure what I want to do yet

To me, it sounds very much like a screwdriver looking for a nail... :wink:

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

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

lol, I made a motor controller some time ago, and it's already working, I have nothing to do right now, so I'm looking at some code and thought I could improve it because I'm bored. I do silly things like this, forgive me, lol

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

No problem.

However it would be wise to explain your current method. Preferably by posting code.

Most Timer or PWM control can take advantage of the AVR hardware. This generally takes all the strain off of execution speed. For example, you can use the COM bits to tell the hardware what to do 'in the future'. You can use CTC mode to keep perfect timing.

David.

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

No, no problem at all. Toying around just for the sake of it can be a good learning experience, and lead to very innovative ideas.

Just make sure when you ask a question that you state that you are in the toying-around-state. Otherwise we will read a perceived objective/goal into your question and try to understand the underlying design/goal. Then the usual hell will break loose, i.e. "what is it you really want to do, and why are you determined to do it in this awkward way?" etc.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

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

We still haven't found out this "need". As the others have implied/asked, if you tell us then perhaps recommendations can be made to avoid the race.

IME it would be a rare "real" app that would have >>only<< this ISR enabled. All the cycle-counting goes up in smoke if e.g. a USART interrupt is being serviced.

>>If<< you can convince the compiler to let you use a register for your personal use, then LDI/OUT (or LDI/STS) or a pair of them for a 16-bit register does not disturb SREG.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

The fastest method I can imagine is to place asm("out ...") as the first op-code in your IRQ vector. Then you can put the rest of your IRQ within +-2kw range so that:

out TCCRxn,dedicated_reg ;IRQ delay is 4 clocks
rjmp continue_nearby

fits into 2w space between adjacent vectors (on chips with jmp).
But if you do not use next vectors then no rjmp is needed.

No RSTDISBL, no fun!

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

SREG never neeeds to be protected from pushes, pops, moves, loads, stores, ins or outs that do not name SREG.
You can assign timer registers to your heart's content without affecting SREG.
Just don't do run-time arithmetic.

International Theophysical Year seems to have been forgotten..
Anyone remember the song Jukebox Band?