Undocumented features in ATtiny10

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

Lately I've been developing a Qtouch button using ATtiny10, and playing with the various configurations. As you may know, Atmel provides a utility in the Qtouch library that spits out a pre-compiled, configured hex file that you can just burn into a chip and go with it. But being the inquisitive person that I am, I took a look under the hood, and found high strangeness. For example, the first thing the device does after reset is this -

 

    clr       XL    
    ldd      XL,Y+50
    ldd      XL,Y+51
    clr       XL

 

Other than that the Y register hasn't been initialized yet, this would be unremarkable (just pointless), except that the LDD instruction isn't supported on the Tiny10. For any other device the assembler throws out an unsupported opcode, but not these. LDD instructions, using both Y and Z registers, are scattered liberally through the code. The Y register does change, so it could be different when those LDDs are executed, but the Z register is never initialized nor used for anything else.

 

Now you would think perhaps these instructions were accessing the IO registers, since the addresses fall into that space, but you'd be wrong. They don't seem to address anything. When I single step through the code, the value of the XL register (or whatever other register is specified) doesn't change. It's like the LDD is ignored, as it should be if it's an unsupported instruction. Except that a little later, this piece of code is executed -

 

    wdr        
    ldi        XL,0xD8
    out      CCP,XL
    ldi        XL,0x4E
    out      WDTCSR,XL
    ldd       XL,Z+32
    tst       XL    
    brne    PC

 

This starts off perfectly conventionally. It writes the password to the code protection register, then sets the watchdog for 64ms. But then, using the uninitialized Z register, it LDD's 0x20 and this time something happens - the XL register changes from 0x4E to 0x00. That is obviously meant to happen, because otherwise the BRNE following makes the program freeze until the watchdog time out. IO reg 0x20 is reserved, by the way, and reading it (with an LDD) previously didn't result in a change to the XL value.

 

There's a further undocumented instruction in the middle somewhere, which appears in some variations of the build but not others, as hex 0x0077.

 

Perhaps the reason nobody has ever seen any uncompiled source code for Qtouch is because what's going on in there is secret.

 

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

Not an undocumented feature, but simply the disassmbler not interpreting the opcode correctly. The ldd's should actually be the "16 bit" STS instructions. So, e.g., the LDD XL, Y+50 should really be STS 18, R26.

Regards,
Steve A.

The Board helps those that help themselves.

Last Edited: Sun. Apr 5, 2015 - 12:29 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Interesting. I ran the disassembled code back through the assembler and generated a hex file bit for bit identical with the original. However,

    sts     18,r26

causes this error -

C:\ASM\QT10A\QT10A.asm(92): error: Operand out of range

 

So no. Anyway, "sts 18,r26" would assemble to 93A0-0012. Here is the hex and the disassembly, take a proper look.

 

27AA    clr     XL

A9AA    ldd    XL,Y+50

A9AB    ldd    XL,Y+51

27AA    clr     XL

 

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

So no. Anyway, "sts 18,r26" would assemble to 93A0-0012. Here is the hex and the disassembly, take a proper look.

 

 The ldd's should actually be the "16 bit" STS instructions.

 

 

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

Damn, I feel stupid now. I vaguely remember reading about that 16 bit STS but can't remember where, nor find it now.

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

As you got the assembly error, I can only guess that you haven't told your toolchain to target a Tiny10, or perhaps the toolchain/version doesn't have full brain-dead support?

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

I vaguely remember reading about that 16 bit STS but can't remember where, nor find it now.

 

One recent thread:

https://www.avrfreaks.net/forum/m...

Ignoring the assembler's nice trick of giving you multiple assembly instructions for a single opcode, I've found two opcodes which are mutually exclusive.

They are: STS (16 bit) and LD Z+q (LDD Z).

Their opcodes are as follows.

STS (16 bit): 1010 1kkk dddd kkkk
LD Z+q (LDD Z): 10q0 qq0d dddd 0qqq

Obviously, these two instructions don't exist on the same chip. There are two STS instructions. One titled STS the other STS (16 bit) in the instruction set datasheet. Problem is, how do I know which chips have which version if they're given the same name?

Obviously larger parts are going to have the 32 bit opcode version of STS, but I looked at the datasheet for an ATTiny and it just says 'STS'. Point is, I don't think the datasheet instruction set for individual parts will allow me to differentiate the part.

How can I determine this without assembling test code for every single chip?

...

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

You are right, I didn't tell the tool what processor to expect. I ran it again just now specifying the Tiny10 and it gave me the expected 16 bit STS instructions.

 

Thank you for your help, gentlemen.