Alistair Gadd schrieb:
Hi Guys,
I'm trying to use GCC-AVR to set up the clock prescale on an ATmega32U4,
using the clock_prescale_set() function as outlined in the "avr/power.h
" header file.
If I call:
clock_prescale_set(clock_div_1)
or
clock_prescale_set(0);
where clock_prescale_set is defined in "avr/power.h" as follows:
typedef enum
{
clock_div_1 = 0,
clock_div_2 = 1,
clock_div_4 = 2,
clock_div_8 = 3,
clock_div_16 = 4,
clock_div_32 = 5,
clock_div_64 = 6,
clock_div_128 = 7,
clock_div_256 = 8
#if defined(__AVR_ATmega128RFA1__) \
|| defined(__AVR_ATmega256RFR2__) \
|| defined(__AVR_ATmega2564RFR2__) \
|| defined(__AVR_ATmega128RFR2__) \
|| defined(__AVR_ATmega1284RFR2__) \
|| defined(__AVR_ATmega64RFR2__) \
|| defined(__AVR_ATmega644RFR2__)
, clock_div_1_rc = 15
#endif
} clock_div_t;
void clock_prescale_set(clock_div_t __x)
{
uint8_t __tmp = _BV(CLKPCE);
__asm__ __volatile__ (
"in __tmp_reg__,__SREG__" "\n\t"
"cli" "\n\t"
"sts %1, %0" "\n\t"
"sts %1, %2" "\n\t"
"out __SREG__, __tmp_reg__"
: /* no outputs */
: "d" (__tmp),
"M" (_SFR_MEM_ADDR(CLKPR)),
"d" (__x)
: "r0");
}
I get the following in-line assembler generated (.lss file extract):
void clock_prescale_set(clock_div_t __x)
{
uint8_t __tmp = _BV(CLKPCE);
__asm__ __volatile__ (
12a: 90 e0 ldi r25, 0x00 ; 0
12c: 80 e8 ldi r24, 0x80 ; 128
12e: 0f b6 in r0, 0x3f ; 63
130: f8 94 cli
132: 80 93 61 00 sts 0x0061, r24
136: 90 93 61 00 sts 0x0061, r25
13a: 0f be out 0x3f, r0 ; 63
This is obviously not the code as generated by the cited inline
assembler sequence. Hence either the dump is basing on a wrong or
outdated file, or the dump is just sloppy and misleading (LDI is not
part of the inline asm for example).
Apart from being suboptimal, that inline assembler sequence is not fully
correct.
which I can understand, but if I call:
clock_prescale_set(clock_div_4);
or:
clock_prescale_set(2);
I get exactly the same code generated, in other words:
void clock_prescale_set(clock_div_t __x)
{
uint8_t __tmp = _BV(CLKPCE);
__asm__ __volatile__ (
12a: 90 e0 ldi r25, *0x00* ; 0
12c: 80 e8 ldi r24, 0x80 ; 128
12e: 0f b6 in r0, 0x3f ; 63
130: f8 94 cli
132: 80 93 61 00 sts 0x0061, r24
136: 90 93 61 00 sts 0x0061, r25
13a: 0f be out 0x3f, r0 ; 63
where I would expect to get this:
If you want to see the exact assembler sequence, add -save-temps to the
command options and inspect the assembler (.s) file.
If you want to see the exact preprocessed code, i.e. the input to the
compiler proper, add -save-temps to the command options and inspect the
preprocessed code (.i or .ii) file.
void clock_prescale_set(clock_div_t __x)
{
uint8_t __tmp = _BV(CLKPCE);
__asm__ __volatile__ (
12a: 90 e0 ldi r25, *0x02* ; 0
12c: 80 e8 ldi r24, 0x80 ; 128
12e: 0f b6 in r0, 0x3f ; 63
130: f8 94 cli
132: 80 93 61 00 sts 0x0061, r24
136: 90 93 61 00 sts 0x0061, r25
13a: 0f be out 0x3f, r0 ; 63
I don't get any compilation errors, so I think it sees the enum okay and
the assembly listing is fresh each time I try. I'm sure I must be doing
something simplisticly crazy, but I think I need help, because this is
You snipped out / left out any information that would enable one to
reproduce what you did...
Johann
_______________________________________________
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list