atmega328 Interupt Optimization

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

hello, I disassembled and interupt that gcc created and rewrote it to be over 2x faster.  Although I'm new to the AVR chips, is there any way to optimize what I have done any better...

 

 asm volatile(

"out	0x0b, r20 \n\t"	// Always out to PortD first
"in	r2, 0x3f \n\t"	//; 63 Save SREG
"mov	r3,r30 \n\t" //Save R30
"mov	r4,r31 \n\t" //Save r31
"subi	r17, -1 \n\t" // trick to Inc Sequencer
"cp	r16, r17 \n\t" //compare Seqencer and SizeOfSequence
"brcc	.+2  \n\t"     	//; 0x182 <__vector_11+0x22>
"ldi	r17, 0x00 \n\t"	//; 0
//Array Index
"lds	r30, 0x013C \n\t"
"lds	r31, 0x013D \n\t"	//; 0
"add	r30, r17 \n\t"	//; 0
//"adc	r31, r1 \n\t"//	; 255//?? This is not needed unless the array crosses page bounds  Bug alert if things stop working
"ld	r20, Z \n\t" //Load PORTDOUTPUT with next Sequence from Arry
"mov	r31,r4 \n\t" //restore r31
"mov	r30,r3 \n\t" //restore r30
"out	0x3f, r2 \n\t"	//; 63 Restore SREG
"reti \n\t"
);

 

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

use movw

 

make sure that the compiler don't need the value in r16 r17 r2..r4
both r16 and r17 could be placed in low registers (use dec register).

 

for real speed save Z (with movw) in registers aswell.

Last Edited: Sat. Jan 16, 2016 - 09:53 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks, I'll look it over...

 

Edit:

 

This what I have now, picked up speed... Is this what you meant?

 

ISR(TIMER1_COMPA_vect,ISR_NAKED)          // timer compare interrupt service routine
{
	
	
 asm volatile(

"out	0x0b, r20 \n\t"	// Always out to PortD first
"in	r2, 0x3f \n\t"	//; 63 Save SREG
"movw r4,r30 \n\t" // move r30:r31 into r4:r5
//"mov	r3,r30 \n\t" //Save R30
//"mov	r4,r31 \n\t" //Save r31
"inc r17 \n\t"
//"subi	r17, -1 \n\t" // trick to Inc Sequencer
"cp	r16, r17 \n\t" //compare Seqencer and SizeOfSequence
"brcc	.+2  \n\t"     	//; 0x182 <__vector_11+0x22>
"ldi	r17, 0x00 \n\t"	//; 0
//Array Index
"movw r30,r6 \n\t"// move saved array pointer into Z
//"lds	r30, 0x013C \n\t"
//"lds	r31, 0x013D \n\t"	//; 0
"add	r30, r17 \n\t"	//; 0
//"adc	r31, r1 \n\t"//	; 255//?? This is not needed unless the array crosses page bounds  Bug alert if things stop working
"ld	r20, Z \n\t" //Load PORTDOUTPUT with next Sequence from Array
"movw r30,r4 \n\t"// restore r30:r31
//"mov	r31,r4 \n\t" //restore r31
//"mov	r30,r3 \n\t" //restore r30
"out	0x3f, r2 \n\t"	//; 63 Restore SREG
"reti \n\t"
);

 

Last Edited: Sun. Jan 17, 2016 - 01:04 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

yes

I need to know more of the flow to make it better.

 

 

 

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

There is no real flow, its the main part...  The registers used in the interrupt are reserved for that purpose... The compiler can work around them...  This one day will be multi-chip oscillators to emulate the 2A03 Nes audio and SID and maybe even a couple others.   The rest of program just controls the oscillator and communicates thru spi to a master controller.   The interrupt continuously reads a predefined waveform and outputs it to a 8 bit r2r dac.  Thanks for your help.  I'm sure I'll need it again.