_SFR_ASM_COMPAT

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

Hi There.
If _SFR_ASM_COMPAT is defined. What is the preferred way (from the avr-libc point of view) to access SFR's?

Macros like sbi and cbi seems to have disapperared. Or I can't find them because I'm too tired....

Olof

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

> If _SFR_ASM_COMPAT is defined. What is the preferred way (from the
> avr-libc point of view) to access SFR's?

See the documentation: use _SFR_IO8/_SFR_IO16/_SFR_MEM8/_SFR_MEM16.
That's the preferred way. If you're lazy, you could use __SFR_OFFSET
of 0, and write the reg names directly, but that's at least
discouraged.

> Macros like sbi and cbi seems to have disapperared. Or I can't find
> them because I'm too tired....

SBI and CBI are still valid assembler instructions.

Do you need them in C code? Just review the umpteen threads about bit
manipulation in C.

DDRB |= (1 << 0);

will result in exactly an SBI instruction if optimization is enabled.
(It wouldn't have resulted in an SBI instruction without optimization
enabled even with the old sbi() macro either.)

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

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

Thanks Jörg, but...
If _SFR_ASM_COMPAT is defined DDRB evaluates to a constatant. Take your own advice and read the documentation if you don't understand why. And constants can't be used as
l-values in C-statements (sic!). The macros you advice me to use also will not evaluate
to anything that can be used as an l-value in a C-statement. Right?

So I tried to wrap cbi like:

#define cbi(a, b) (_MMIO_BYTE(a)) &= ~(1 << (b))

But what about the __SFR_OFFSET, will that be needed? I like my define(s) to be safe to use on different (avr)processors?

sbi and cbi are just examples. I don't want to write assembly routines for every possible way to assign data to an l-value. Why should I? As you said the compiler will optimise C-code to
single instuctions when possible.

cheers

Olof

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

> If _SFR_ASM_COMPAT is defined DDRB evaluates to a constatant. Take
> your own advice and read the documentation if you don't understand
> why. And constants can't be used as l-values in C-statements
> (sic!). The macros you advice me to use also will not evaluate to
> anything that can be used as an l-value in a C-statement. Right?

Sure, you wrote about _SFR_ASM_COMPAT so I assumed you were going to
write an assembly file. In inline assembler, it's completely
pointless as the inline assembler doesn't see your preprocessed header
file anyway. For inline asm, you need to pass IO registers using the
proper constraints (so it's the C compiler that evaluates ).

See the FAQ, entry "How do I use a #define'd constant in an asm
statement?"

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

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

I understand that I was not clear about my intentions. If I had wanted to use assembler
I wouldn't have asked in the first place. I do read the documentation see.

I have some legacy code library that was maintained up to avr-gcc 3.2. The code uses
a lot of inline assembler. But also old decrapted macros like cbi, PGM_rb() and so on. I'd like to port the code to the latest version of the compiler.

Though my own coding philosofy is stay with C unless there really is some speed or
size issue that must be done in assembler and that is not the case here.

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

Ah, OK.

Emulating the old macros like sbi and PGM_RB is really simple. sbi
has been (y) |= (1 << (x)) for years already, so just use that.

As for the inline asm code, I guess there's not much chances to use it
verbatim, as the transition from the old IO approach to the one used
now (where direct assignments are possible) was probably about the
biggest API change affecting inline asm. I think the best option is
really to move that code to the I constraint. The only alternative I
could think of is to create a few additional macros for the IO ports
you are interested in, and use them (e.g. change PORTD into asmPORTD,
and assign it a plain number).

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

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

The problem is that this code wont compile,

#define _SFR_ASM_COMPAT 1
#include 

void I_do_not_compile(void)
{
   PORTD = 1;
}

void but_I_do(void)
{
  _MMIO_BYTE(PORTD) = 1;  // But what about __SFR_OFFSET?
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Drop _SFR_ASM_COMPAT, it's really only meant for assembly
source files.

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

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

Will the existing inline assembly still compile properly?.

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

No, but it cannot anyway, no matter what. See above,
you *must* rewrite it using "I" constraints.

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.