Inline assembly with xmega

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

Hi,

I have a problem with inline assembly

I have a naked isr that works fine with a AT90USB646

ISR(USART1_RX_vect, ISR_NAKED)
{
asm (
....
"	lds	r17,%[udr1]							\n\t"
....
"	reti									\n\t"
:
 :
[udr1] "M" (_SFR_MEM_ADDR(UDR1))
:
"memory"
);
}

Then I have to port it to an xmega device ATxmega128A1

ISR(USARTC0_RXC_vect, ISR_NAKED)
{
asm (
....
"	lds r17,%[udr]						\n\t"
....
"	reti									\n\t"
:
 :
[udr] "M" (_SFR_MEM_ADDR(USARTC0_DATA))
:
"memory"
);
}

But studio 4 give me this error :

warning: asm operand 0 probably doesn't match constraints

when I try to replace the LDS line by :

"	lds		r17,USARTC0_DATA 				\n\t"

I have this error

undefined reference to `USARTC0_DATA'

USARTC0_DATA and UDR1 is defined as this in their respected io.h

#define USARTC0_DATA  _SFR_MEM8(0x08A0)
#define UDR1    _SFR_MEM8(0XCE)

This works :

"	lds		r17,0x08A0 						\n\t"

But not this :

#define USARTC0_DATA_addr	0x08A0
...
"lds		r17,USARTC0_DATA_addr 				\n\t"

Sometimes in my tests he said me :

lvalue required as unary '&' operand

Do someone know what I have to write in my interrupt code to make it run ?
I have read the avrlibc manual, but it is not very clear. And there is no sts lds example with xmega.

Best Regards.

Doom

AVR inside

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

Don't use conatraint "M". Use "n" instead.

USARTC0_DATA is just a define to an integer (address), thus you have no symbol you can refer from asm.

#define replaces text in the source file but not inside of strings, therefore define does not work is you intend it.

Because all addresses in avr/io.g are RAM addresses, you can use the neat &USARTC0_DATA instead of _SFR_MEM_ADDR(USARTC0_DATA).

avrfreaks does not support Opera. Profile inactive.

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

If you are writing a complete ISR() then what's the advantage of using inline asm() in C? Why not put the whole ISR in a .S file and write clean Asm source like God intended?

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

clawson wrote:
If you are writing a complete ISR() then what's the advantage of using inline asm() in C?

Simply accessing C variables from my asm ?

AVR inside

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

SprinterSB wrote:
Don't use conatraint "M". Use "n" instead.

Good job, it compiles well !!!

But how can I find this as it seems not to be in the documentation (http://savannah.nongnu.org/download/avr-libc/avr-libc-user-manual-1.8.0.pdf.bz2).

In the inline assembly cookbook p42, the little 'n' constraint does not exist.

And on the next page, the LDS instruction is defined like this :

lds r, label

Hard to find the 'n' constraint !

So, big big thanks for you.

(if you know a documentation that explains all inline assembly, 'Je suis preneur' as we say in french)

Best regards

AVR inside

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

Quote:

Simply accessing C variables from my asm ?

Eh? It's just as easy to access C variables from Asm as it is in C.

// file1.c
#include 
uint16_t var = 12345;

void asm_func(void);

int main(void) {
  DDRB = 0xFF;
  DDRD = 0xFF;
  asm_func();
}
// file2.S
#define __SFR_OFFSET 0
#include 
.global asm_func
.extern var
asm_func:
  lds R24,var
  lds R25,var+1
  out PORTB, R24
  out PORTD, R25
  ret

This writes 0x39 to PORTB and 0x30 to PORTD.

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

clawson wrote:

Eh? It's just as easy to access C variables from Asm as it is in C.

When I wrote this code years ago, I have just find this example with the BEER-WARE licence

And in this example, the variables are in registers. Has I am using all possibly register in an other hyper fast interrupt, I can't waste register for this, and so I use inline assembly.

Next time, if I can, I will use the S way as it seems to be more simple.
Thanks for your example.

This example is not in the documentation avrlibc. Why ? Is it possible to add it ?

Best Regards

AVR inside

Last Edited: Fri. Aug 31, 2012 - 07:03 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I tried to write some inline assembly once.

my head hurt a lot and the code would not compile.

Using the info in avr-libc I was able to write a .S file that worked and was readable.

regards
Greg

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

Quote:

This example is not in the documentation avrlibc. Why ? Is it possible to add it ?

Not that example but AVR-LibC docs have this:

http://www.nongnu.org/avr-libc/u...

The point I was making above was how a C variable could be accessed by .S code. In the manual example you see 'pwm_incoming' and 'intbits' shared between the C (where they are defined) and the .S

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

It is the link I give you, but you are right.

I have read to quickly...

AVR inside

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

n is documented in the GCC manuals just like other machine independent constraints like s, i, r, or m.

avrfreaks does not support Opera. Profile inactive.