XMEGA-E ISR return to bad address in memory

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

Hello,
I have problem with following simple code:

/* Definition of the CPU clock speed and TC prescaler setting. */
#define F_CPU           2000000UL
#define CPU_PRESCALER   1

#include 
#include 
#include 
void init( void );

volatile uint8_t tick;

ISR(TCC4_OVF_vect)
{
	/* Toggle PD0 output after 5 switch presses. */
	//PORTD.OUTTGL = 0x01;
	tick=1;
	TCC4_INTFLAGS |= 0x01;
}
int main( void )
{
	init();
	while(1){
		if(tick==1)
		{
			tick=0;
		}
		else{
		//	tick=0;
		}
		//__asm__("nop");
	//	_delay_ms(1);
	}
}

void init( void )
{
	TCC4_PER = 0x0060;
	TCC4_CTRLA = 0x01;
	
	PMIC_CTRL = 0x07;
	TCC4_INTCTRLA = 0x01;
	sei();
	
	
}

When code is running the block inside if is never executed because xmega is still reseting (jumping to somewhere outsite of program and thus resets). When same program is stepped with breakpoint on if, then everything is fine. when line in else is uncommented then program is also running fine without reseting. Problem is resolved also by putting nop or delay under if (commented in code).

Could someone please explain me why is this happening?

Thank you.

This topic has a solution.
Last Edited: Fri. Jul 14, 2017 - 11:57 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You will have problems trying to step _delay_ms(1); and tick will ALWAYS equal 0 according to your code so it may get optmised to nothing.

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

Thank you for reply. Optimization is O0. And code as posted is returning to begining of code like in reset condition, when content of else is added or somethinf into while loop is added then everything is working as expected.

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

Hi,

Is this really all the code ? Because io.h is not included...
And also, is it something you see on the simulator, or with a debugger on real hardware ?

Have a nice day,
Kraal

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

yes, absolutelly complete. Could send also complete project in as 6.2 later today as I'm out now. Compiled without problem. Only jumping somwhere ot of code scope.

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

Quote:

Is this really all the code ? Because io.h is not included...

No worries. starts like this:

#ifndef _AVR_INTERRUPT_H_
#define _AVR_INTERRUPT_H_

#include 
...

So it's possible to include it without io.h - though possibly unorthodox as almost all AVR programs would usually start:

#include 

Anyway, to the OP, the fact is that AVR-LibC has a "catch all" mechanism described on this page:

http://www.nongnu.org/avr-libc/u...

So the likelihood is that you are inadvertently enabling an interrupt you didn't mean to and when that fires code goes to __bad_interrupt and from there to "JMP 0". Which looks like a reset.

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

adding BADISR_vect ISR routine with nop instruction inside (just to catch breakpoint there) don't resolve problem. And also this BADISR vector is not called according to breakpoint.

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

OK next thing to try is to catch the MCU status register that tells you what the reset condition is. Set it to 0. Run the code. Catch it when it gets to 0. What does that status register now show? If it's still 0 then execution simply jumped/called/branched to 0 (or a RET after PUSH 0 even). If it's non-0 the register will tell you what the CPU is doing at 0.

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

It is still 0, and code jumps to address 0xc4 which is few clicks after last instruction in program memory.
see disasembly

--- No source file -------------------------------------------------------------
00000000  JMP 0x00000056		Jump 
00000002  JMP 0x00000068		Jump 
00000004  JMP 0x00000068		Jump 
00000006  JMP 0x00000068		Jump 
00000008  JMP 0x00000068		Jump 
0000000A  JMP 0x00000068		Jump 
0000000C  JMP 0x00000068		Jump 
0000000E  JMP 0x00000068		Jump 
00000010  JMP 0x00000068		Jump 
00000012  JMP 0x00000068		Jump 
00000014  JMP 0x00000068		Jump 
00000016  JMP 0x00000068		Jump 
00000018  JMP 0x0000006A		Jump 
0000001A  JMP 0x00000068		Jump 
0000001C  JMP 0x00000068		Jump 
0000001E  JMP 0x00000068		Jump 
00000020  JMP 0x00000068		Jump 
00000022  JMP 0x00000068		Jump 
00000024  JMP 0x00000068		Jump 
00000026  JMP 0x00000068		Jump 
00000028  JMP 0x00000068		Jump 
0000002A  JMP 0x00000068		Jump 
0000002C  JMP 0x00000068		Jump 
0000002E  JMP 0x00000068		Jump 
00000030  JMP 0x00000068		Jump 
00000032  JMP 0x00000068		Jump 
00000034  JMP 0x00000068		Jump 
00000036  JMP 0x00000068		Jump 
00000038  JMP 0x00000068		Jump 
0000003A  JMP 0x00000068		Jump 
0000003C  JMP 0x00000068		Jump 
0000003E  JMP 0x00000068		Jump 
00000040  JMP 0x00000068		Jump 
00000042  JMP 0x00000068		Jump 
00000044  JMP 0x00000068		Jump 
00000046  JMP 0x00000068		Jump 
00000048  JMP 0x00000068		Jump 
0000004A  JMP 0x00000068		Jump 
0000004C  JMP 0x00000068		Jump 
0000004E  JMP 0x00000068		Jump 
00000050  JMP 0x00000068		Jump 
00000052  JMP 0x00000068		Jump 
00000054  JMP 0x00000068		Jump 
00000056  CLR R1		Clear Register 
00000057  OUT 0x3F,R1		Out to I/O location 
00000058  SER R28		Set Register 
00000059  OUT 0x3D,R28		Out to I/O location 
0000005A  LDI R29,0x2F		Load immediate 
0000005B  OUT 0x3E,R29		Out to I/O location 
0000005C  LDI R18,0x20		Load immediate 
0000005D  LDI R26,0x00		Load immediate 
0000005E  LDI R27,0x20		Load immediate 
0000005F  RJMP PC+0x0002		Relative jump 
00000060  ST X+,R1		Store indirect and postincrement 
00000061  CPI R26,0x01		Compare with immediate 
00000062  CPC R27,R18		Compare with carry 
00000063  BRNE PC-0x03		Branch if not equal 
00000064  CALL 0x00000094		Call subroutine 
00000066  JMP 0x000000BF		Jump 
00000068  JMP 0x00000000		Jump 
--- C:\Documents and Settings\User\Plocha\xmega timer test\xmega timer test\Debug/.././TC_example.c 
{
0000006A  PUSH R1		Push register on stack 
0000006B  PUSH R0		Push register on stack 
0000006C  LDS R0,0x003F		Load direct from data space 
0000006E  PUSH R0		Push register on stack 
0000006F  CLR R1		Clear Register 
00000070  PUSH R18		Push register on stack 
00000071  PUSH R19		Push register on stack 
00000072  PUSH R24		Push register on stack 
00000073  PUSH R25		Push register on stack 
00000074  PUSH R30		Push register on stack 
00000075  PUSH R31		Push register on stack 
00000076  PUSH R28		Push register on stack 
00000077  PUSH R29		Push register on stack 
00000078  IN R28,0x3D		In from I/O location 
00000079  IN R29,0x3E		In from I/O location 
	tick=1;
0000007A  LDI R24,0x01		Load immediate 
0000007B  STS 0x2000,R24		Store direct to data space 
	TCC4_INTFLAGS |= 0x01;
0000007D  LDI R24,0x0C		Load immediate 
0000007E  LDI R25,0x08		Load immediate 
0000007F  LDI R18,0x0C		Load immediate 
00000080  LDI R19,0x08		Load immediate 
00000081  MOVW R30,R18		Copy register pair 
00000082  LDD R18,Z+0		Load indirect with displacement 
00000083  ORI R18,0x01		Logical OR with immediate 
00000084  MOVW R30,R24		Copy register pair 
00000085  STD Z+0,R18		Store indirect with displacement 
}
00000086  POP R29		Pop register from stack 
00000087  POP R28		Pop register from stack 
00000088  POP R31		Pop register from stack 
00000089  POP R30		Pop register from stack 
0000008A  POP R25		Pop register from stack 
0000008B  POP R24		Pop register from stack 
0000008C  POP R19		Pop register from stack 
0000008D  POP R18		Pop register from stack 
0000008E  POP R0		Pop register from stack 
0000008F  STS 0x003F,R0		Store direct to data space 
00000091  POP R0		Pop register from stack 
00000092  POP R1		Pop register from stack 
00000093  RETI 		Interrupt return 
{
00000094  PUSH R28		Push register on stack 
00000095  PUSH R29		Push register on stack 
00000096  IN R28,0x3D		In from I/O location 
00000097  IN R29,0x3E		In from I/O location 
	init();
00000098  CALL 0x000000A1		Call subroutine 
		if(tick==1)
0000009A  LDS R24,0x2000		Load direct from data space 
0000009C  CPI R24,0x01		Compare with immediate 
0000009D  BRNE PC+0x03		Branch if not equal 
			tick=0;
0000009E  STS 0x2000,R1		Store direct to data space 
	}
000000A0  RJMP PC-0x0006		Relative jump 
--- C:\Documents and Settings\User\Plocha\xmega timer test\xmega timer test\Debug/.././TC_example.c 
{
000000A1  PUSH R28		Push register on stack 
000000A2  PUSH R29		Push register on stack 
000000A3  IN R28,0x3D		In from I/O location 
000000A4  IN R29,0x3E		In from I/O location 
	TCC4_PER = 0x0060;
000000A5  LDI R24,0x26		Load immediate 
000000A6  LDI R25,0x08		Load immediate 
000000A7  LDI R18,0x60		Load immediate 
000000A8  LDI R19,0x00		Load immediate 
000000A9  MOVW R30,R24		Copy register pair 
000000AA  STD Z+0,R18		Store indirect with displacement 
000000AB  STD Z+1,R19		Store indirect with displacement 
	TCC4_CTRLA = 0x01;
000000AC  LDI R24,0x00		Load immediate 
000000AD  LDI R25,0x08		Load immediate 
000000AE  LDI R18,0x01		Load immediate 
000000AF  MOVW R30,R24		Copy register pair 
000000B0  STD Z+0,R18		Store indirect with displacement 
	PMIC_CTRL = 0x07;
000000B1  LDI R24,0xA2		Load immediate 
000000B2  LDI R25,0x00		Load immediate 
000000B3  LDI R18,0x07		Load immediate 
000000B4  MOVW R30,R24		Copy register pair 
000000B5  STD Z+0,R18		Store indirect with displacement 
	TCC4_INTCTRLA = 0x01;
000000B6  LDI R24,0x06		Load immediate 
000000B7  LDI R25,0x08		Load immediate 
000000B8  LDI R18,0x01		Load immediate 
000000B9  MOVW R30,R24		Copy register pair 
000000BA  STD Z+0,R18		Store indirect with displacement 
	sei();
000000BB  SEI 		Global Interrupt Enable 
}
000000BC  POP R29		Pop register from stack 
000000BD  POP R28		Pop register from stack 
000000BE  RET 		Subroutine return 
--- No source file -------------------------------------------------------------
000000BF  CLI 		Global Interrupt Disable 
000000C0  RJMP PC-0x0000		Relative jump 
000000C1  NOP 		Undefined 
000000C2  NOP 		Undefined 
000000C3  NOP 		Undefined 
000000C4  NOP 		Undefined 
000000C5  NOP 		Undefined 
000000C6  NOP 		Undefined 
000000C7  NOP 		Undefined 
000000C8  NOP 		Undefined 
000000C9  NOP 		Undefined 
000000CA  NOP 		Undefined 

sometimes it stuck here and sometimes it just starts from begining of the code, this seems to be dependent to when pause/stop combination is invoked. As far as I know.

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

Below is whole project in as6.2 in case that someone is interested in tests.

Attachment(s): 

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Wow that code looks horrendous but then I noticed:

Quote:

Optimization is O0.

it shouldn't matter but why on earth would you build -O0?

Other than that I think (though I have limited knowledge of Xmega) that the code looks right. The header says:

#define TCC4_OVF_vect      _VECTOR(12)  /* Overflow Interrupt */

And 0x0C * 2 = 0x18 and you find:

00000018  JMP 0x0000006A      Jump

which is the only one of the vectors not jumping to bad interrupt" at 0x68. At 0x6A you have the ISR code that again (apart from the mess that -O0 causes!) looks like it does what you wrote - clearly "ticks" is at location 0x2000. It also OR's 1 into location 0x80C which agrees with the header:

#define TCC4_INTFLAGS  _SFR_MEM8(0x080C)

And main(void) implements:

   init();
00000098  CALL 0x000000A1      Call subroutine
      if(tick==1)
0000009A  LDS R24,0x2000      Load direct from data space
0000009C  CPI R24,0x01      Compare with immediate
0000009D  BRNE PC+0x03      Branch if not equal
         tick=0;
0000009E  STS 0x2000,R1      Store direct to data space
   }
000000A0  RJMP PC-0x0006      Relative jump

which again appears to be what you wrote. So I cannot see any obvious problem in the generated code.

Just for the pig iron, what happens if you build -O1 - though, as I say, it shouldn't make any difference - you'll just get code that doesn't look like it was written by a 3 year old ;-)

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

Thank you for hints. I used -O0 just to ensure that problem is not caused by optimizing. (just poor man try :) ).

Originaly i compiled it with -Os but problem was same. I will try -O1 later today when I will be at dev board (in simulator is everything working, only during debug or running on board problem exists.

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

Did you see this thread?

http://www.avrfreaks.net/index.p...

Towards the end there's a post by snigelen with some TCC4 OVF interrupt code for avr-gcc. Try that - he always writes very sensible posts here and I would trust whatever he suggests.

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

Thank you clawson for link. Code from snigelen works without problem even with -O0. But when I modified it (just to do what I need) it stops working.

#include 
#include 


volatile uint8_t tick=0;

ISR(TCC4_OVF_vect)
{
	// Clear interrupt flag
	TCC4.INTFLAGS = TC4_OVFIF_bm;
	// Toggle a pin to tell we were here
	//PORTA.OUTTGL = PIN0_bm;
	tick=1;
}

void dispatch(void)
{
	
	tick=2;
}

int main(void)
{
	// PA0 output
	PORTA.DIR = PIN0_bm;
	// TCC4 1MHz timer tick, 1kHz overflow if F_CPU=2MHz
	TCC4.PER = 999;
	// Low level overflow interrupt
	TCC4.INTCTRLA = TC45_OVFINTLVL_LO_gc;
	// Start timer with presc. 1:2
	TCC4.CTRLA = TC45_CLKSEL_DIV2_gc;

	// Enable low level interrupts
	PMIC.CTRL |= PMIC_LOLVLEN_bm;
	sei();

	while(1)
	{
		if(tick==1){
			tick=0;
			dispatch();
		}
	}
}

function dispatch is never executed, also if is also not processed as breakpoint on it just never stops. After ISR is finished, jump to PC-0x0000 (on 0xc7) is repeatedly called.

00000000  JMP 0x00000056		Jump 
00000002  JMP 0x00000068		Jump 
00000004  JMP 0x00000068		Jump 
00000006  JMP 0x00000068		Jump 
00000008  JMP 0x00000068		Jump 
0000000A  JMP 0x00000068		Jump 
0000000C  JMP 0x00000068		Jump 
0000000E  JMP 0x00000068		Jump 
00000010  JMP 0x00000068		Jump 
00000012  JMP 0x00000068		Jump 
00000014  JMP 0x00000068		Jump 
00000016  JMP 0x00000068		Jump 
00000018  JMP 0x0000006A		Jump 
0000001A  JMP 0x00000068		Jump 
0000001C  JMP 0x00000068		Jump 
0000001E  JMP 0x00000068		Jump 
00000020  JMP 0x00000068		Jump 
00000022  JMP 0x00000068		Jump 
00000024  JMP 0x00000068		Jump 
00000026  JMP 0x00000068		Jump 
00000028  JMP 0x00000068		Jump 
0000002A  JMP 0x00000068		Jump 
0000002C  JMP 0x00000068		Jump 
0000002E  JMP 0x00000068		Jump 
00000030  JMP 0x00000068		Jump 
00000032  JMP 0x00000068		Jump 
00000034  JMP 0x00000068		Jump 
00000036  JMP 0x00000068		Jump 
00000038  JMP 0x00000068		Jump 
0000003A  JMP 0x00000068		Jump 
0000003C  JMP 0x00000068		Jump 
0000003E  JMP 0x00000068		Jump 
00000040  JMP 0x00000068		Jump 
00000042  JMP 0x00000068		Jump 
00000044  JMP 0x00000068		Jump 
00000046  JMP 0x00000068		Jump 
00000048  JMP 0x00000068		Jump 
0000004A  JMP 0x00000068		Jump 
0000004C  JMP 0x00000068		Jump 
0000004E  JMP 0x00000068		Jump 
00000050  JMP 0x00000068		Jump 
00000052  JMP 0x00000068		Jump 
00000054  JMP 0x00000068		Jump 
00000056  CLR R1		Clear Register 
00000057  OUT 0x3F,R1		Out to I/O location 
00000058  SER R28		Set Register 
00000059  OUT 0x3D,R28		Out to I/O location 
0000005A  LDI R29,0x2F		Load immediate 
0000005B  OUT 0x3E,R29		Out to I/O location 
0000005C  LDI R18,0x20		Load immediate 
0000005D  LDI R26,0x00		Load immediate 
0000005E  LDI R27,0x20		Load immediate 
0000005F  RJMP PC+0x0002		Relative jump 
00000060  ST X+,R1		Store indirect and postincrement 
00000061  CPI R26,0x01		Compare with immediate 
00000062  CPC R27,R18		Compare with carry 
00000063  BRNE PC-0x03		Branch if not equal 
00000064  CALL 0x00000098		Call subroutine 
00000066  JMP 0x000000C6		Jump 
00000068  JMP 0x00000000		Jump 
--- C:\Documents and Settings\User\Plocha\xmega timer test\xmega timer test\Debug/.././TC_example.c 
{
0000006A  PUSH R1		Push register on stack 
0000006B  PUSH R0		Push register on stack 
0000006C  LDS R0,0x003F		Load direct from data space 
0000006E  PUSH R0		Push register on stack 
0000006F  CLR R1		Clear Register 
00000070  PUSH R18		Push register on stack 
00000071  PUSH R24		Push register on stack 
00000072  PUSH R25		Push register on stack 
00000073  PUSH R30		Push register on stack 
00000074  PUSH R31		Push register on stack 
00000075  PUSH R28		Push register on stack 
00000076  PUSH R29		Push register on stack 
00000077  IN R28,0x3D		In from I/O location 
00000078  IN R29,0x3E		In from I/O location 
	TCC4.INTFLAGS = TC4_OVFIF_bm;
00000079  LDI R24,0x00		Load immediate 
0000007A  LDI R25,0x08		Load immediate 
0000007B  LDI R18,0x01		Load immediate 
0000007C  MOVW R30,R24		Copy register pair 
0000007D  STD Z+12,R18		Store indirect with displacement 
	tick=1;
0000007E  LDI R24,0x01		Load immediate 
0000007F  STS 0x2000,R24		Store direct to data space 
}
00000081  POP R29		Pop register from stack 
00000082  POP R28		Pop register from stack 
00000083  POP R31		Pop register from stack 
00000084  POP R30		Pop register from stack 
00000085  POP R25		Pop register from stack 
00000086  POP R24		Pop register from stack 
00000087  POP R18		Pop register from stack 
00000088  POP R0		Pop register from stack 
00000089  STS 0x003F,R0		Store direct to data space 
--- C:\Documents and Settings\User\Plocha\xmega timer test\xmega timer test\Debug/.././TC_example.c 
0000008B  POP R0		Pop register from stack 
0000008C  POP R1		Pop register from stack 
0000008D  RETI 		Interrupt return 
{
0000008E  PUSH R28		Push register on stack 
0000008F  PUSH R29		Push register on stack 
00000090  IN R28,0x3D		In from I/O location 
00000091  IN R29,0x3E		In from I/O location 
	tick=2;
00000092  LDI R24,0x02		Load immediate 
00000093  STS 0x2000,R24		Store direct to data space 
}
00000095  POP R29		Pop register from stack 
00000096  POP R28		Pop register from stack 
00000097  RET 		Subroutine return 
{
00000098  PUSH R28		Push register on stack 
00000099  PUSH R29		Push register on stack 
0000009A  IN R28,0x3D		In from I/O location 
0000009B  IN R29,0x3E		In from I/O location 
	PORTA.DIR = PIN0_bm;
0000009C  LDI R24,0x00		Load immediate 
0000009D  LDI R25,0x06		Load immediate 
0000009E  LDI R18,0x01		Load immediate 
0000009F  MOVW R30,R24		Copy register pair 
000000A0  STD Z+0,R18		Store indirect with displacement 
	TCC4.PER = 999;
000000A1  LDI R24,0x00		Load immediate 
000000A2  LDI R25,0x08		Load immediate 
000000A3  LDI R18,0xE7		Load immediate 
000000A4  LDI R19,0x03		Load immediate 
000000A5  MOVW R30,R24		Copy register pair 
000000A6  STD Z+38,R18		Store indirect with displacement 
000000A7  STD Z+39,R19		Store indirect with displacement 
	TCC4.INTCTRLA = TC45_OVFINTLVL_LO_gc;
000000A8  LDI R24,0x00		Load immediate 
000000A9  LDI R25,0x08		Load immediate 
--- C:\Documents and Settings\User\Plocha\xmega timer test\xmega timer test\Debug/.././TC_example.c 
000000AA  LDI R18,0x01		Load immediate 
000000AB  MOVW R30,R24		Copy register pair 
000000AC  STD Z+6,R18		Store indirect with displacement 
	TCC4.CTRLA = TC45_CLKSEL_DIV2_gc;
000000AD  LDI R24,0x00		Load immediate 
000000AE  LDI R25,0x08		Load immediate 
000000AF  LDI R18,0x02		Load immediate 
000000B0  MOVW R30,R24		Copy register pair 
000000B1  STD Z+0,R18		Store indirect with displacement 
	PMIC.CTRL |= PMIC_LOLVLEN_bm;
000000B2  LDI R24,0xA0		Load immediate 
000000B3  LDI R25,0x00		Load immediate 
000000B4  LDI R18,0xA0		Load immediate 
000000B5  LDI R19,0x00		Load immediate 
000000B6  MOVW R30,R18		Copy register pair 
000000B7  LDD R18,Z+2		Load indirect with displacement 
000000B8  ORI R18,0x01		Logical OR with immediate 
000000B9  MOVW R30,R24		Copy register pair 
000000BA  STD Z+2,R18		Store indirect with displacement 
	sei();
000000BB  SEI 		Global Interrupt Enable 
		if(tick==1){
000000BC  LDS R24,0x2000		Load direct from data space 
000000BE  CPI R24,0x01		Compare with immediate 
000000BF  BRNE PC+0x06		Branch if not equal 
			tick=0;
000000C0  STS 0x2000,R1		Store direct to data space 
			dispatch();
000000C2  CALL 0x0000008E		Call subroutine 
	}
000000C4  RJMP PC-0x0008		Relative jump 
000000C5  RJMP PC-0x0009		Relative jump 
--- No source file -------------------------------------------------------------
000000C6  CLI 		Global Interrupt Disable 
000000C7  RJMP PC-0x0000		Relative jump 
000000C8  NOP 		Undefined 
000000C9  NOP 		Undefined 
000000CA  NOP 		Undefined 

When optimize is turned on -O1 or higher, then above code works again. Why optimization changes functionality?

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

OK, I see, FAQ#4 in your signature :). Don't use -O0.
Well thank you all for help and mostly thanks to clawson for his time.

Answer for everybody else is here http://www.avrfreaks.net/forum/t...

Last Edited: Fri. Jul 14, 2017 - 11:56 AM