Re: [avr-gcc-list] Should this code work? 4.1.1
On Sunday 04 March 2007 14:21, Gavin Jackson wrote: Another thing you may want to take a look at is the SPIF flag on page 174 of the datasheet. It states that: From what the datasheet says, your SPIF bit is never cleared so you'll be overwriting the SPI data register contents before they've been transmitted. That code was copypasted verbatim right out of the CAN128 data sheet, I would not normally write code in that style. I was doing a test on some hardware for a new board that I just powered up for the first time and was looking for something quick. I should know better than to trust Atmel supplied code. Sometimes I wonder if they even bother to compile it; such as their old battery charger code when you use something besides a Lithium battery for example. Thanks for bring that to my attention. ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] Should this code work? 4.1.1
From: Graham Davies [EMAIL PROTECTED] Bob Paddock wrote: [...] I don't see while(true){} being any different than for(;;){} in this context, and while(true){} causes the Lint error of evaluation of constant value boolean. [...] I can't see why Lint would consider this an error and for ( ; ; ) not. Even so, isn't there some markup you can add in a comment to reassure Lint that this is what you intend? FWIW, assuming you're discussing PC-lint... PC-lint considers for (;;) to be the traditional or conventional way to express an endless loop, and therefore does not comment on it. Personally, I use while (1) or while(TRUE) more often, and indeed, PC-lint warns about that, perhaps to catch mistakes of the form of while (Flag) where Flag is a preprocessor macro that expands into a constant. To suppress that warning for your entire program, use -e716, or disable on the line you use it with a lint comment like /*lint !e716 */. Regards, -=Dave _ With tax season right around the corner, make sure to follow these few simple tips. http://articles.moneycentral.msn.com/Taxes/PreparationTips/PreparationTips.aspx?icid=HMFebtagline ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] Should this code work? 4.1.1
On Friday 02 March 2007 21:29, Graham Davies wrote: Bob Paddock wrote: for(;;){} is a endless loop, how is until execution of that block ends in any way. being fulfilled here? The block begins with the open brace and ends with the close brace. The block ends when control falls out of the bottom The falls out is the issue with me, as I see the {} as being contained within, the } was never crossed, so to me it was still the same {} block. I could not find this reinitialize issue in my old KR book? and for ( ; ; ) If instead you write while ( true ) it is easier to see where control goes when it leaves the block at the bottom. I don't see while(true){} being any different than for(;;){} in this context, and while(true){} causes the Lint error of evaluation of constant value boolean. ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
RE: [avr-gcc-list] Should this code work? 4.1.1
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 = (1SPE)|(1MSTR)|(1SPR0); } void SPI_MasterTransmit(char cData); void SPI_MasterTransmit(char cData) { /* Start transmission */ SPDR = cData; /* Wait for transmission complete */ while(!(SPSR (1SPIF))) ; } 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) (shift8) ); 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
Re: [avr-gcc-list] Should this code work? 4.1.1
On Friday 02 March 2007 18:42, Francesco Sacchi wrote: Bob Paddock ha scritto: 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? Nothing is broken. If you declare shift inside the for block, every time block is executed shift is recreated. ISO/IEC 9899:TC2 Committee Draft — May 6, 2005 WG14/N1124 6.2.4 Storage durations of objects ... 4 An object whose identifier is declared with no linkage and without the storage-class specifier static has automatic storage duration. 5 For such an object that does not have a variable length array type, its lifetime extends from entry into the block with which it is associated until execution of that block ends in any way. (Entering an enclosed block or calling a function suspends, but does not end, execution of the current block.) If the block is entered recursively, a new instance of the object is created each time. The initial value of the object is indeterminate. If an initialization is specified for the object, it is performed each time the declaration is reached in the execution of the block; otherwise, the value becomes indeterminate each time the declaration is reached. for(;;){} is a endless loop, how is until execution of that block ends in any way. being fulfilled here? I my mind the {} block should not have ended, nor is this a case of recursion, to cause 'shift' to be recreated and reinitialized. Apparently it is the last paragraph that got me: If an initialization is specified for the object, it is performed each time the declaration is reached in the execution of the block; otherwise, the value becomes indeterminate each time the declaration is reached. ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] Should this code work? 4.1.1
Bob Paddock wrote: for(;;){} is a endless loop, how is until execution of that block ends in any way. being fulfilled here? The block begins with the open brace and ends with the close brace. The block ends when control falls out of the bottom and for ( ; ; ) takes over for the next iteration. Personally, I never write for ( ; ; ), pretty much becase it leads to this kind of confusion. You can't *see* what is being executed. If instead you write while ( true ) it is easier to see where control goes when it leaves the block at the bottom. Graham. ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list