Go Down

Topic: Assembler doesn't recognize correct value for PORTx in e.g. 'sbi PORTD, PD7' (Read 114 times) previous topic - next topic

roger99

I'm writing an assembly 'library' for a new application (I've written them before), but I guess this is the first time I've used sbi, sbic, sbis, etc in one. If I write

    sbi PORTD, PD7

the assembler complains with

 Error: number must be positive and less than 32

If I replace PORTD with its I/O address 0x0b, everything assembles OK. So it recognizes the bit numbers (PD7), but gets the value for PORTD wrong. I would suspect that it may be using its memory-space address (0x2b) instead of the I/O address.

I'm using Arduino v1.0.3 and an EtherMega board (ATmega2560).

In my library .S file I have

#include <avr/io.h>

I would expect this to be a common complaint, but I can't seem to get a handle on it with google and forum searches.


Coding Badly


roger99

Further information:

If I insert a (junk) line in my assembly file

   ldi r16, PORTD

and then compile the sketch (and 'library') it assembles with a value of 0x2b for PORTD

        144: 0b e2       ldi r16, 0x2B ; 43  

Now  port and bit values are #defined  in iomxx0_1.h, which is #included by iom2560.h e.g.

   
   #define PORTD   _SFR_IO8(0x0B)
   #define PD7     7
   #define PD6     6
   #define PD5     5

To confirm that this is where the values are really coming from, I altered the #define of PD7 to have a value of 3. I then recompiled my sketch, and the line

   sbi 0x0b, PD7        then compiled as

        142: 5b 9a       sbi 0x0b, 3 ; 11

From this it would appear that the assembler thinks that PORTD has a value of 0x2b, despite the values contained in iomxx0_1.h

Where is the problem??





roger99

Ah,... thanks Coding Badly. I didn't see your post until after my second post.

So, does this need to be applied to all I/O register addresses (up to 0x3f) when I need them to be treated as I/O addresses?

If I want to access one of these registers via its memory-space address (e.g. lds r16, xxx) then I simply use

    lds r16, PORTD

Correct??

Can you point me to where I find all this documented, please?

Regards,

Coding Badly

So, does this need to be applied to all I/O register addresses (up to 0x3f) when I need them to be treated as I/O addresses?
http://www.nongnu.org/avr-libc/user-manual/group__avr__sfr__notes.html

Apparently, ASSEMBLER (appears to actually be __ASSEMBLER__ in the header file) needs to be defined before including io.h.

Quote
If I want to access one of these registers via its memory-space address (e.g. lds r16, xxx) then I simply use "lds r16, PORTD" Correct??
I have no idea.  I have only done inline assembly.

Quote
Can you point me to where I find all this documented, please?
Other than Google, no.

https://www.google.com/search?q=gcc+avr+assembly
http://www.nongnu.org/avr-libc/user-manual/assembler.html



Go Up