Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > alt.os.linux > #53376

ATTiny416 basic blink

From Dan Purgert <dan@djph.net>
Newsgroups alt.os.linux, alt.microcontrollers.8bit
Subject ATTiny416 basic blink
Followup-To alt.os.linux
Date 2019-01-30 12:07 +0000
Organization A noiseless patient Spider
Message-ID <slrnq534rp.61d.dan@xps-linux.djph.net> (permalink)

Cross-posted to 2 groups.

Followups directed to: alt.os.linux

Show all headers | View raw


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

x-posted to alt.microcontrollers.8bit to see if anyone's out there
(yeah, it's OT for linux...)

Came out of a side discussion with Rudy Weiser (er, sorry if I typo'd
the name, should've written it down) where we started talking a bit
about programming microcontrollers, and some pitfalls we (I?) ran into
with Microchip's latest "1-series" ATTiny demo boards.

Code below is straight out of the Microchip provided "MPLABX" IDE, using
the debug / show disassembly features.  For those more familiar with the
assembly, you probably know of a cleaner way to get it out, but, well, I
don't :). It's the "initial setup" that I do to the "PORT B" set of
pins -- on this particular demoboard, there is a LED attached to pin
"B5" (i.e. the 5th bit of the 8-bit register), and a button attached to
pin "B4".  So, I'm setting pin 5 as an output, and pin 4 as an input,
and also enabling the pullup resistor inside the ATTiny to keep pin4 at
a "high" voltage (>2.1v) when the button is not depressed.  This is to
keep the pin from "floating" (effectively, a "floating" pin is the
hardware equivalent of "undefined behavior" in your favorite programming
language).

- From here on out, it's just the code, and then pretty much me trying to
make sense of the assembly.

========================================================================   

            int main(void) {
               PORTB_DIRSET |= (1<<PB5);
                        00DD  E2E1     LDI R30, 0x21
                        00DE  E0F4     LDI R31, 0x04
                        00DF  8180     LD R24, Z
                        00E0  6280     ORI R24, 0x20
                        00E1  8380     ST Z, R24
               PORTB_DIRSET &= ~(1<<PB4);
                        00E2  8180     LD R24, Z
                        00E3  7E8F     ANDI R24, 0xEF
                        00E4  8380     ST Z, R24
               //int led=0;
               //enable input pullup
               PORTB_PIN4CTRL |= 0b00001000;
                        00E5  E3E4     LDI R30, 0x34
                        00E6  E0F4     LDI R31, 0x04
                        00E7  8180     LD R24, Z
                        00E8  6088     ORI R24, 0x08
                        00E9  8380     ST Z, R24
               PORTB_OUT |= (1<<PB5); //Make sure the LED is off
                        00EA  E2E4     LDI R30, 0x24
                        00EB  E0F4     LDI R31, 0x04
                        00EC  8180     LD R24, Z
                        00ED  6280     ORI R24, 0x20
                        00EE  8380     ST Z, R24
               }

========================================================================

Quick perusal of the datasheet says that the commands are

  - LDI -> Load Immediate, Operands : Rd, k.  
  - LD -> Load indirect, Operands Rd, X.
  - ST -> Store Indirect, Operands X, Rr.
  - ORI -> Logical OR with Immediate, Operands Rd, K
  - ANDI -> Logical AND with Immediate, Operands Rd, K

Operand definitions are:
  - Rd -> Destination (sometimes source[1]) Register
  - k -> address constant
  - K -> constant data
  - X -> Indirect Address Register (R27:R26)
  - Z -> Indirect Address Register (R31:R30)
  - Rr -> Source register


So, with this very small amount of knowledge, I think what's going on in
the initial pin setup is (the two "PORTB_DIRSET" commands)

              00DD  E2E1     LDI R30, 0x21
              00DE  E0F4     LDI R31, 0x04
              00DF  8180     LD R24, Z
              00E0  6280     ORI R24, 0x20
              00E1  8380     ST Z, R24

Set the values of Register 30,31 to 0x21 and 0x04, respectively (aka
register Z).
Load the value from register index Z into R24
Logical OR (Immediate) the value in Register 24 and and constant 0x20
Store the value of R24 into the register index 'Z'
   
              00E2  8180     LD R24, Z
              00E3  7E8F     ANDI R24, 0xEF
              00E4  8380     ST Z, R24

Load the value from register Z back into R24
Bitwise AND (Immediate) the value in R24, and constant 0xEF
Store that result back into register Z


              00E5  E3E4     LDI R30, 0x34
              00E6  E0F4     LDI R31, 0x04
              00E7  8180     LD R24, Z
              00E8  6088     ORI R24, 0x08
              00E9  8380     ST Z, R24
              

Set the values of Register 30,31 to 0x34 and 0x04, respectively (aka
register Z).
Load the value from register index Z into R24
Logical OR (Immediate) the value in Register 24 and and constant 0x08
Store the value of R24 back into register index Z

I guess that the preceding hex is the SRAM location where the command
is being stored, which is keeping us from clobbering our previous work,
maybe.  

              00EA  E2E4     LDI R30, 0x24
              00EB  E0F4     LDI R31, 0x04
              00EC  8180     LD R24, Z
              00ED  6280     ORI R24, 0x20
              00EE  8380     ST Z, R24


Set the values of Register 30,31 to 0x24 and 0x04, respectively (aka
register Z).
Load the value from register index Z into R24
Logical OR (Immediate) the value in Register 24 and and constant 0x20
Store the value of R24 back into register index Z

[1] According to the "AVR Instruction Set Manual" [2], 'Rd' is used when
a single (Direct) register is used with the operand.  'Rr' is used when
two registers are required, or you only need to READ a value.  It's a
bit terse, and probably makes more sense to people familiar with
assembly.

[2]http://ww1.microchip.com/downloads/en/devicedoc/atmel-0856-avr-instruction-set-manual.pdf

-----BEGIN PGP SIGNATURE-----

iQEzBAEBCAAdFiEEBcqaUD8uEzVNxUrujhHd8xJ5ooEFAlxRk3QACgkQjhHd8xJ5
ooEZgQf/WBhsGPv7gmbAgIvW3Ol4BPE6v8G+2RhH++Ktca9evTs4mVANdlu7kU26
5P8lHc18NpOjiPMoWfGVIPrvVQDvqdemdf6ChpvMy9kZwlM8E+T+SYDuogMDwv8e
SXCWst1OzjCNdwpYsfM/MzAcarUQrAyJtxZQdWo1dVuOGtR4JLVMzYjaZQ1qJDN8
Nq2GJakn+XR6HBdIZauGE9m+5u1dKK2OHyBa3q2F0YyUbFOLH3uOCaVYVaXWYUWL
WYAlp6YFuzwk+28ToJrr0F7LK7OB2Z2nUeIyKI+WJfMdTeZMHa5XjQJ04OejojdP
hE1mJz6omwRTOzSnjX1TqcxjGNHKFQ==
=5obN
-----END PGP SIGNATURE-----

-- 
|_|O|_| 
|_|_|O| Github: https://github.com/dpurgert
|O|O|O| PGP: 05CA 9A50 3F2E 1335 4DC5  4AEE 8E11 DDF3 1279 A281

Back to alt.os.linux | Previous | Next — Next in thread | Find similar | Unroll thread


Thread

ATTiny416 basic blink Dan Purgert <dan@djph.net> - 2019-01-30 12:07 +0000
  Re: ATTiny416 basic blink Michael Bäuerle <michael.baeuerle@stz-e.de> - 2019-01-30 15:35 +0100
    Re: ATTiny416 basic blink Dan Purgert <dan@djph.net> - 2019-01-30 15:17 +0000

csiph-web