0
\$\begingroup\$

I am currently writing some assembly code that needs to address different I/O ports at certain times in my code. For example, at one point I may want to address PORTD4, and at another point I may want to address PORTB6. The solution that I have come up with is the following...

;Get the port number
ldi xl, lo8(port)
ldi xh, hi8(port)
ld r18, x

;Figure out which port "section" is being used, use the flags here
sbic flags, B_flag
rjmp B_port_one_on
rjmp D_port_one_on

B_port_one_on:
    out PORTB, r18
    rjmp one_delay
D_port_one_on:
    out PORTD, r18
one_delay:

This solution is okay, but I'm trying to come up with something faster. The timing in my project is crucial and although this does work, I want to give myself a little bit more elbow room. One "solution" that I want to try to implement is instead of using a sbic function and then using rjmp, I want to see if I can store the I/O port location in a register or in a byte of RAM. Then what I want to do is load that location and then use the out function to load both the port letter and number from those registers/bytes of information. As you can see, I have already done so with the port number. Now I need some way of loading the I/O address via a register or byte of memory. I have tried setting it as a register and used the X registers to load the port address, but both have come back with errors. Is what I want to do even possible or am I just going to have to deal with what I've got? (The MCU that I am using is the ATTINY4313 @20Mhz)

\$\endgroup\$

2 Answers 2

1
\$\begingroup\$

The OUT instruction takes an address that must be constant at compile time, so if you want to dynamically write to different port addresses at runtime you have two options....

  1. hard code all possible OUT ports and then select which one gets executed at run time
  2. use the the normal pointer registers to write to the PORT register using the PORT register's SRAM address. Note that the SRAM address for each PORT register is different from the IOREGISTER address that is used by the OUT instruction. Both addresses for each PORT register are listed in the datasheet.

enter image description here

\$\endgroup\$
1
  • 1
    \$\begingroup\$ I knew that those IO registers had two different addresses I just didn't think about using the SRAM address. Thank you \$\endgroup\$
    – dhout23
    Commented May 30, 2021 at 20:22
1
\$\begingroup\$

All IO registers are also available as memory mapped. Just use ST instead of OUT, and you can simply load e.g. X register contents from a variable in memory and so X will then point to correct memory address for the port you have chosen with the variable. But do note that OUT and ST have a different base so you need to convert the IO port address to memory address and such macros should be readily available.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.