Ruud Vlaming schreef:
Hi,
There are a couple of ways to use i/o address in assymbly.
Below i used a some:
#define _EEARL_ "0x1E"
uint8_t portFSReadByte(unsigned char * pAddress)
{ uint8_t result;
asm volatile ( \
"in r26, __SREG__ \n\t"
"cli \n\t"
"out %2, %A0 \n\t"
"out "_EEARL_", %B0 \n\t"
"sbi __EECR__, 0 \n\t"
"in %A0, 0x1D \n\t"
"out __SREG__, r26 \n\t"
"" :"=r" (result) :"0" (pAddress), "I" (_SFR_IO_ADDR(EEARH)) : "r26" );
return result; }
(1) You can define a constant, like i did for _EEARL_
This is nice but no so portable.
(2) You can use the asm paramter list, like for EEARH
Also nice, but errorprone, since i keep making mistakes in
numbering, especially when you have many parameters and
have to change something.
(3) The best thing to have would be something like __EECR__,
resembling the definition for __SREG__, but that does not
compile right now.
Is the latter possible somehow? Or are there other solutions?
You could go for option 2 if you use syntax like this (took this from
eeprom.h)
__asm__ __volatile__ (
"/* START EEPROM WRITE CRITICAL SECTION */\n\t"
"in r0, %[__sreg] \n\t"
"cli \n\t"
"sbi %[__eecr], %[__eemwe] \n\t"
"sbi %[__eecr], %[__eewe] \n\t"
"out %[__sreg], r0 \n\t"
"/* END EEPROM WRITE CRITICAL SECTION */"
:
: [__eecr] "i" (_SFR_IO_ADDR(EECR)),
[__sreg] "i" (_SFR_IO_ADDR(SREG)),
[__eemwe] "i" (EEMWE),
[__eewe] "i" (EEWE)
: "r0"
);
This makes the code far more readable IMHO. For more info on the %[ ]
notation take look at:
http://gcc.gnu.org/onlinedocs/gcc-4.3.0/gcc/Extended-Asm.html
HTH
Wouter
_______________________________________________
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list