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
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:
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