[Top][All Lists]
[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
- [avr-gcc-list] Should this code work? 4.1.1, Bob Paddock, 2007/03/02
- Re: [avr-gcc-list] Should this code work? 4.1.1, Francesco Sacchi, 2007/03/02
- Re: [avr-gcc-list] Should this code work? 4.1.1, Bob Paddock, 2007/03/02
- Re: [avr-gcc-list] Should this code work? 4.1.1, Graham Davies, 2007/03/02
- Re: [avr-gcc-list] Should this code work? 4.1.1, Bob Paddock, 2007/03/03
- Re: [avr-gcc-list] Should this code work? 4.1.1, Francesco Sacchi, 2007/03/03
- Re: [avr-gcc-list] Should this code work? 4.1.1, Graham Davies, 2007/03/03
- Re: [avr-gcc-list] Should this code work? 4.1.1, Dave Hansen, 2007/03/05