avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[avr-gcc-list] possible compiler bug?


From: Brian Dean
Subject: [avr-gcc-list] possible compiler bug?
Date: Wed, 28 Aug 2002 15:44:38 -0400
User-agent: Mutt/1.4i

Hi,

I think there may be a bug in the code generation for writing 16 bit
values via a pointer.  Consider the following code:

        #include <inttypes.h>
        #include <io.h>

        void set_pwm(volatile uint16_t * pwmreg, uint16_t pwm)
        {
          *pwmreg = pwm;
        }


        int main(void)
        {
          volatile uint16_t * pwmreg, pwmval;
          
          pwmval = 512;
          pwmreg = (uint16_t *)_SFR_ADDR(OCR1AL);
        
          set_pwm(pwmreg, pwmval);
        }

The generated assembler (below) appears to load the low byte first and
then the high byte.  However, the AVR data sheets state that when
accessing 16 bit registers such as the output compare registers, that
the high byte must be loaded first followed by the low byte.  I had an
elusive bug in a recent project that turned out to be due to this.
After I forced the high byte be written first, followed by the low
byte, my problems disappeared.

While this shouldn't make any difference for writing to real RAM
locations, it makes a big difference when writing to memory mapped I/O
ports.

The compiler version is:

        Reading specs from /usr/local/lib/gcc-lib/avr/3.3/specs
        Configured with: ./configure --target=avr --prefix=/usr/local 
i386-portbld-freebsd4.6
        Thread model: single
        gcc version 3.3 20020812 (experimental)

Thanks,
-Brian
-- 
Brian Dean                                      address@hidden

        .file   "bug.c"
        .arch atmega163
__SREG__ = 0x3f
__SP_H__ = 0x3e
__SP_L__ = 0x3d
__tmp_reg__ = 0
__zero_reg__ = 1
_PC_ = 2
        .global __do_copy_data
        .global __do_clear_bss
        .text
.global set_pwm
        .type   set_pwm, @function
set_pwm:
/* prologue: frame size=0 */
/* prologue end (size=0) */
        movw r30,r24
        st Z,r22
        std Z+1,r23
/* epilogue: frame size=0 */
        ret
/* epilogue end (size=1) */
/* function set_pwm size 4 (3) */
        .size   set_pwm, .-set_pwm
.global main
        .type   main, @function
main:
/* prologue: frame size=2 */
        ldi r28,lo8(__stack - 2)
        ldi r29,hi8(__stack - 2)
        out __SP_H__,r29
        out __SP_L__,r28
/* prologue end (size=4) */
        ldi r24,lo8(512)
        ldi r25,hi8(512)
        std Y+1,r24
        std Y+2,r25
        ldd r22,Y+1
        ldd r23,Y+2
        ldi r24,lo8(74)
        ldi r25,hi8(74)
        call set_pwm
/* epilogue: frame size=2 */
        jmp exit
/* epilogue end (size=2) */
/* function main size 16 (10) */
        .size   main, .-main
/* File "bug.c": code   20 = 0x0014 (  13), prologues   4, epilogues   3 */
avr-gcc-list at http://avr1.org



reply via email to

[Prev in Thread] Current Thread [Next in Thread]