unexpected behavior of ATtiny26 LD Rn,Z+

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

It seems that doing a LD R24,Z+ on an ATtiny26 resets the high byte of Z to 0x00. This is totally unexpected to me"” the tiny26 data sheet says that Z is a full 16-bit register, but even on parts for which the postincrement only affects 8 bits, it just ignores the high byte, right? Is this a silicon bug / defective part, or did I miss something in the datasheet?

FWIW, my tiny26 is marked 0533D, presumably that means revision D from 2005 wk. 33?

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

Post some code which can be assembled and run in the simulator please.

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

Quote:
...the tiny26 data sheet says that Z is a full 16-bit register, but even on parts for which the postincrement only affects 8 bits, it just ignores the high byte, right?
Nope, it increments the 16 bit Z value, same as any other such "var" .

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

indianajones11 wrote:
Nope, it increments the 16 bit Z value, same as any other such "var" .

Well, the instruction set reference has this to say:

doc0856 wrote:
Note that only the low byte of the Z-pointer is updated in devices with no more than 256 bytes data space. For such devices, the high byte of the pointer is not used by this instruction and can be used for other purposes.

But the tiny26's documentation suggests that the X,Y,Z postincrements apply to the full 16 bits even though the part only has 0xE0 bytes of data space (including registers and IO). So it's slightly ambiguous, I guess, but even so, I'd expect the high byte to be either left alone, or to be incremented on carry from the low byte (which in practice means left alone :) ). The compiler expected the same thing, I guess, and we were both surprised when the program went off the rails. :?

js, I'll see if I can trim my program down to a minimal case to post…

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

Quote:
But the tiny26's documentation suggests that the X,Y,Z postincrements apply to the full 16 bits even though the part only has 0xE0 bytes of data space
So you HAVE your answer, the opcode documentation would be general and not necessarily T26 specific
Quote:
– 128 Bytes Internal SRAM
what would be the point of incrementing the high byte? Or even going past 0x7f?

edit if it wouldn't reset ZH then the pointer would be pointing to outer space.

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

On ATTiny26, LD Rd,Z+ does indeed clear r31.
Also, like attiny13, it actually has LPM Rd, Z+ in the silicon. Only it is not listed as a valid instruction, as it will clear r31.

The simulator disagrees. For something like this, you need the hardware.

LPM was removed from the datasheet 2010.03, and the LD Rd,Z+ one reported to atmel (not by me) in 2011.01.

(edit)
My best suggestion is to, if you are using a C compiler, have the C compiler produce assembler, patch the assembler file using your favourite automated search/replace tool, and assemble:

With GCC this errata usually triggers when the stack pointer is loaded into a 16 bit pointer, LD Rd,Z+ is used to increment, and Z then compared to the old value plus some. This in turn is because of another funny little thing, GCC's stack pointer read/write code. It attempts to load the high part of SP, which is unimplemented. Normally this is not a problem, as the high 8 bits of memory is ignored.
So to avoid running into the hardware errata, work around the software errata:
replace "IN register, SPH" with "IN register, SOME_SFR_THAT_IS_0". Often "CLR register" is cleaner, but beware of the flags if just doing blind replace.

/Kasper

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

This hardware bug was known and will not be corrected.

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

http://www.mikrocontroller.net/a...
This program runs faulty on the ATtiny26,
but correct on the ATtiny261.
Thus I would suggest to use the ATtiny261 for new projects.

Peter

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

In my Tiny26 assembler projects i implement a little 'zplus' routine - especially useful for the LPM instruction:

; helper program to inc Z
zplus:	inc	ZL
	brne	zplusa
	inc	ZH
zplusa: ret
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

mschoeldgen wrote:
In my Tiny26 assembler projects i implement a little 'zplus' routine - especially useful for the LPM instruction:

; helper program to inc Z
zplus:	inc	ZL
	brne	zplusa
	inc	ZH
zplusa: ret

Very clever. Why not just use a single word inline adiw ZL,1 instead of a 4-word subroutine?

Warning: Grumpy Old Chuff. Reading this post may severely damage your mental health.

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

Hehe, because when i implemented my first Tiny26 programs i didn't know about ADIW :D. As my recent projects all went down the drain by a server crash i looked up some of my old code. Now the OP has a bunch of routines to select from :P

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

mschoeldgen wrote:
Now the OP has a bunch of routines to select from :P
I'm quite sure he shouldn't be glad to dig into a heap of garbage :D

Warning: Grumpy Old Chuff. Reading this post may severely damage your mental health.

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

On Mouser the ATtiny261 was cheaper, than the ATtiny26.
So no need to stick on the faulty device and do some awkward tricks.

Peter

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

OK, I'm glad I wasn't just hallucinating. It's really frustrating that Atmel doesn't put this in their errata list though!

KKP wrote:
With GCC this errata usually triggers when the stack pointer is loaded into a 16 bit pointer, LD Rd,Z+ is used to increment, and Z then compared to the old value plus some. This in turn is because of another funny little thing, ...

Yes, that is exactly the situation that started me down this road. Depending on exactly what was in the loop, the compiler would use that code sequence, or a different (working) sequence.

I'm building a newer version of avr-gcc now to see if it will avoid generating code that provokes this bug... in any event, now that I know what to look for, I can also check the assembly for the problem, as KKP suggests. Thanks, everyone.

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

KKP wrote:
On ATTiny26, LD Rd,Z+ does indeed clear r31.

[...] With GCC this errata usually triggers when the stack pointer is loaded into a 16 bit pointer, LD Rd,Z+ is used to increment, and Z then compared to the old value plus some. This in turn is because of another funny little thing, GCC's stack pointer read/write code. It attempts to load the high part of SP, which is unimplemented.

This is a bug in avr-gcc, see PR51002. It is fixed in 4.6.3 as far as the code generation by the compiler is concerned.

Unfortunately, libgcc mixes devices with 8-bit SP and devices with 16-bit SP so that there will still be bogus code from libgcc's __epilogue_restores__ and __prologue_saves__. The reason is that at the time libgcc is built, there is no way to get the actual SP size and SP is used as 16-bit register no matter what.

These two functions might be used when setting -mcall-prologues. Notice that avr-libc and libgcc are generated with this option on, so you might still get these functions even if you don't set -mcall-prologues in your project.

avrfreaks does not support Opera. Profile inactive.

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

SprinterSB wrote:
This is a bug in avr-gcc, see PR51002.

Indeed, PR51002 is the bug I filed after posting this thread. Check the usernames. :D

It's really two bugs— one in the attiny26 silicon, one in gcc. Either one by itself wouldn't cause me a problem, but together they do.