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

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

RE: [avr-gcc-list] Should this code work? 4.1.1


From: James L. Evans
Subject: RE: [avr-gcc-list] Should this code work? 4.1.1
Date: Fri, 2 Mar 2007 16:27:39 -0500

Shouldn't the declaration of shift be OUTSIDE the for block (or in the
for expression). Otherwize, shift is always 1 and the if (0 == shift)
can be optimized away. 

-----Original Message-----
From: address@hidden
[mailto:address@hidden On Behalf Of
Bob Paddock
Sent: Friday, March 02, 2007 3:59 PM
To: address@hidden
Subject: [avr-gcc-list] Should this code work? 4.1.1


In what many or may not be a continuation of my problems with
out-of-order code execution, with 4.1.1, I'd like to know why this code
does not work (comments below the code):

/* Code for AT90CAN64. */

#include <avr/io.h>
#include <util/delay.h>

void SPI_MasterInit(void);
void SPI_MasterInit(void)
{
   /* Enable SPI, Master, set clock rate fck/16 */
   SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
}

void SPI_MasterTransmit(char cData);
void SPI_MasterTransmit(char cData)
{
   /* Start transmission */
   SPDR = cData;

   /* Wait for transmission complete */
   while(!(SPSR & (1<<SPIF)))
     ;
}

int main( void )
{
   /* Data Direction et.al. setup by the bootloader, before we get to
this
main() */

   SPI_MasterInit();
   PORTB &= (uint8_t) ~_BV(4); /* Display Output enable */

   for(;;)
     {
       /* volatile */ uint16_t shift = 1;

       SPI_MasterTransmit( 0x3F );
       SPI_MasterTransmit( (uint8_t) shift );
       SPI_MasterTransmit( (uint8_t) (shift>>8) );

       shift <<= 1;
       if( 0 == shift )
         {
           shift = 1;
         }
       PORTA |= (uint8_t)  _BV(6); /* Load the data into latch, */
       _delay_us( 5.0 );
       PORTA &= (uint8_t) ~_BV(6); /* return line low */

       _delay_ms( 32.5 );
       _delay_ms( 32.5 );
       _delay_ms( 32.5 );
       _delay_ms( 32.5 );
     }
}

With 'volatile' commented out the variable 'shift'
is no place to be found in 'main.lss'. The fixed values 0x3F,0x01,0x00
are output.  With 'volatile'
present, but I don't understand why it is needed in this context, the
'shift' code is present, but non-functional.

  /* volatile */ uint16_t shift = 1;

What I mean by non-functional is that if you look at the produced
main.lss file, or run the program on the real hardware:

   f8:  21 e0           ldi     r18, 0x01       ; 1
   fa:  30 e0           ldi     r19, 0x00       ; 0
   fc:  5f e3           ldi     r21, 0x3F       ; 63
   fe:  4c e0           ldi     r20, 0x0C       ; 12
  100:  e0 e0           ldi     r30, 0x00       ; 0
  102:  fa ee           ldi     r31, 0xEA       ; 234

   for(;;)
     {
       volatile uint16_t shift = 1;
  104:  3a 83           std     Y+2, r19        ; 0x02
  106:  29 83           std     Y+1, r18        ; 0x01
  ...
  166:  ce cf           rjmp    .-100           ; 0x104 <main+0x26>

you see that the last rjmp is jumping to the point where shift is
reinitialized with '1' (r18/r19).

Moving 'uint16_t shift = 1;' out of the for(;;){} and into the top of
main(){} makes the code work ok.

Is it my understanding, or the compiler that is broken here?





_______________________________________________
AVR-GCC-list mailing list
address@hidden
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list






reply via email to

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