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: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Bob Paddock Sent: Friday, March 02, 2007 3:59 PM To: avr-gcc-list@nongnu.org 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 AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list _______________________________________________ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list