Re: Saving & retreiving a structure in eeprom
You wrote >>> eeprom_read_block((void *), (const void *)eepLoc, num) ; What is num? -=Dave From: AVR-GCC-list on behalf of Royce Pereira Sent: Tuesday, June 9, 2020 8:18 AM To: avr-gcc-list@nongnu.org Subject: Saving & retreiving a structure in eeprom Hi, The MPU is ATMega8. AVR-GCC version is 9.1.0 I have a structure that I'm trying to save (& retrieve in eeprom). Furthermore, it is to be saved in an indexed location in the eeprom from 0 to 29. The structure is 4 bytes in size. So total 127 bytes are used in EEPROM //- #define EEP_START7 //offset in EEPROM where my structure storage starts. typedef struct { int temp ; unsigned int time ; } _pgm ; #define STRU_SIZE(sizeof(_pgm)) _pgm setPgm ; //create struct in RAM. uint16_teepLoc ; //holds address of EEPROM uint8_t index ; //index to read from in EEPROM... //-- //save struct from RAM to an indexed location in EEPROM... void savPgm(char idx) { eepLoc = EEP_START + ((uint16_t)idx * STRU_SIZE) ; eeprom_write_block((const void *), (void *)eepLoc, STRU_SIZE) ; return ; } //--- //Retreive struct from an indexed location in EEPROM void getPgm(char idx) { eepLoc = EEP_START + ((uint16_t)idx * STRU_SIZE) ; eeprom_read_block((void *), (const void *)eepLoc, num) ; return ; } //-- int main(void) { index = 5 ; setPgm.temp = 50 ; setPgm.time = 10 ; savPgm(index) ;//example .. save in 6th location in EEPROM; //Now read the saved struct back from eeprom... // this reads back correctly.:- setPgm.temp = eeprom_read_word((const uint16_t *)eepLoc) ; //eepLoc was set before. setPgm.time = eeprom_read_word((const uint16_t *)eepLoc + 1) ; //But this reads 0x for both elementss. (Why?):- getPgm(index) ; //uses block-read function return 0 ; } //--- The getPgm function uses the read block api but retreives garbage(0x); What am I doing wrong ? Thank you! -- Best Regards, -- Royce Pereira -- Best Regards, -- Royce Pereira
Re: [avr-gcc-list] Can enumerator values be used in a #if preprocessordirective?
From: graceindustr...@gmail.com [...] So that explains the difference. Seems like there could be a better error message for this case, 'don't use enum here', alas The preprocessor does not know anything about types in the language... Here's a cute/ugly little macro that might help you find the errors you're looking for: #define ctassert(n,e) extern unsigned char n[(e)?0:-1] Here's an example of how you might use it: enum{a,b,c,d,last}; #define MAX 2 ctassert(big_enough,(last = MAX)); Note that the macro does not need to be invoked from within a function. If the test fails, the error message is almost pretty good, depending on what you choose for the array name (sztest.c:6: error: size of array `big_enough' is negative). Refinements of the concept left as an exercise for the reader. Regards, -=Dave ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org https://lists.nongnu.org/mailman/listinfo/avr-gcc-list
RE: [avr-gcc-list] Rounded integral division in preprocessor
From: jb@gmx.de: I'm trying to do rounded (opposed to truncated) integer division with avr-gcc with using only preprocessor magic. This proves to be difficult: The current code I'm using is #define __IDIV(x, y) (long)(((long)x + ((long)y / 2L)) / (long)y) #define IDIV(x, y) (__IDIV((x), (y))) I'm not sure why you're getting the error message, but the above seems unnecessarily complex. For what it's worth, the following should have equivalent functionality, and does not generate the error: #define IDIV(x,y) ( ((x)+(y)/2L)/(y) ) Regards, -=Dave _ Your E-mail and More On-the-Go. Get Windows Live Hotmail Free. http://clk.atdmt.com/GBL/go/201469229/direct/01/ ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
RE: [avr-gcc-list] Re: Passing a string variable to lcd_puts
From: david.br...@hesbynett.no [...char vs. signed cahr vs. unsigned char...] Don't look it up - if you learn the compiler's default behaviour, you risk writing incorrect code. If it is in any way relevant whether a char is signed or not, write signed char or unsigned char explicitly in the code. The only reason one would ever use a plain char is to hole a true character - a letter - such as in strings. Since it is (in general) meaningless to do arithmetic on characters, it does not matter if the compiler considers them to be signed or unsigned. All true, but you need to be careful all the same. Consider the case I ran into about 20 years ago, a custom terminal with Function keys (e.g., F1, F2, etc) that returned values outside the standard ASCII range (0xF1, 0xF2, etc.). Consider the following code, stubbed out for illustration purposes: #define EXIT_KEY 0xF1 extern void process_key(char key); char get_key(void) {return EXIT_KEY} void handle_input(void) { char key; do { key = get_key(); process_key(key); } while (key != EXIT_KEY); } In this code, the handle_input function falls into an infinite loop if plain char is signed. This is because key gets promoted (to signed int) before the comparison with EXIT_KEY (which is already signed int). If plain char is signed, and key is 0xF1, the sign is extended for key, but not EXIT_KEY. There are numerous solutions, but I post it here as a warning to the wise. Sometimes math is performed on character types implicitly. Regards, -=Dave _ Express your personality in color! Preview and select themes for Hotmail®. http://www.windowslive-hotmail.com/LearnMore/personalize.aspx?ocid=TXT_MSGTX_WL_HM_express_032009#colortheme___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
RE: [avr-gcc-list] Re: Passing a string variable to lcd_puts
From: j...@uriah.heep.sax.de Dave Hansen i...@hotmail.com wrote: In this code=2C the handle_input function falls into an infinite loop if pl= ain char is signed. This is because key gets promoted (to signed int) befo= re the comparison with EXIT_KEY (which is already signed int). If plain c= har is signed=2C and key is 0xF1=2C the sign is extended for key=2C but not= EXIT_KEY. I didn't try it, but wouldn't the correct solution be to declare #define EXIT_KEY ((char)0xF1) That way, EXIT_KEY must be promoted by the same rules, and the comparison ought to work again. That would work. Another way is to have get_key return int. Regards, -=Dave _ Express your personality in color! Preview and select themes for Hotmail®. http://www.windowslive-hotmail.com/LearnMore/personalize.aspx?ocid=TXT_MSGTX_WL_HM_express_032009#colortheme___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
RE: [avr-gcc-list] Re: Passing a string variable to lcd_puts
From: i...@hotmail.com That would work. Another way is to have get_key return int. Oops. I mean, of course, make key an int. Having get_key return an int that is then stored into a char would accomplish... nothing. Regards, -=Dave Express your personality in color! Preview and select themes for Hotmail®. See how. _ Express your personality in color! Preview and select themes for Hotmail®. http://www.windowslive-hotmail.com/LearnMore/personalize.aspx?ocid=TXT_MSGTX_WL_HM_express_032009#colortheme___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
RE: [avr-gcc-list] Re: Wierd Calls.
From: d...@mobilefusioninc.com [...] I'm still puzzled as to why the compiler didn't change: // This takes 53uS at 4 MHz Bin = ( A / Data_Divisor ) // Data_Divisor is a constant, 32. into // This takes 8.9uS at 4 MHz Bin = ( A 5) Just guessing, but it may be trying to preserve truncation toward zero (required by C99) if the expression is signed. Regards, -=Dave _ Windows Live™ Groups: Create an online spot for your favorite groups to meet. http://windowslive.com/online/groups?ocid=TXT_TAGLM_WL_groups_032009___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
RE: [avr-gcc-list] memcpy() : problem when passing destination pointer
From: bernard.fou...@kuantic.com [...re: volatile use cases...] fourth case: nasty situations where 'volatile' is only a part of the solution but does not insure a correct result: For instance if ISR1 and ISR2 are *nested* ISRs, IsrCounter does not correctly hold the count of interrupts: volatile uint8_t IsrCounter; ISR1() { IsrCounter++; } ISR2() { IsrCounter++; } Consider also memory locations larger than the MCU data processing unit size (8 bits for AVR). The following code gives bad results on an AVR but works on a i386: volatile uint32_t MilliSeconds; ISR() { MilliSeconds++; } main() { while(MilliSeconds SOME_LIMIT) ... } In both of these cases, volatile is insufficient because it does not imply atomic. In the first case, you need an atomic read-modify-write, and in the second you need an atomic read of a wide value. In both cases you can achieve that by enclosing the the variable access in a cli-sei pair. For example, the latter case can be fixed by changing the routine to something like main() // or int main(void), yada yada { uint32_t ms; // does not need to be volatile do{ cli(); ms = Milliseconds; sei(); } while (ms SOME_LIMIT); } Regards, -=Dave _ Stay up to date on your PC, the Web, and your mobile phone with Windows Live. http://clk.atdmt.com/MRT/go/msnnkwxp1020093185mrt/direct/01/___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
RE: [avr-gcc-list] Re: Strings: escape sequence to insert arbitrary hex value ?
From: dke...@hiwaay.net On Thu, Feb 05, 2009 at 12:13:37AM -0700, Chris Kuethe wrote: On Thu, Feb 5, 2009 at 12:10 AM, Schwichtenberg, Knut wrote: As far as I know hex values won't work as expected but octal does! I used: static char s46[] __attribute__ ((progmem)) = Hei\342gas; /* 46 */ which is written as Hei?gas on an LCD. As far as I know, hex values do work... because I tried that program before pasting it. But some people prefer octal escapes... Odds are that is an avr-gcc patch and not standard gcc. Am more certain the support of entering binary values is an avr-gcc enhancement because I see the patch file in the FreeBSD port. ISO C99, section 6.4.4.4, p3: The single-quote ', the double-quote , the question-mark ?, the backslash \, and arbitrary integer values are representable according to the following table of escape sequences: single quote' \' double quote \ question mark? \? backslash\ \\ octal character \octal digits hexadecimal character \x hexadecimal digits Same section, p6: The hexadecimal digits that follow the backslash and the letter x in a hexadecimal escape sequence are taken to be part of the construction of a single character for an integer character constant or of a single wide character for a wide character constant. The numerical value of the hexadecimal integer so formed specifies the value of the desired character or wide character. Regards, -=Dave _ Windows Live™: E-mail. Chat. Share. Get more ways to connect. http://windowslive.com/explore?ocid=TXT_TAGLM_WL_t2_allup_explore_022009 ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
RE: [avr-gcc-list] Re: Strings: escape sequence to insert arbitrary hex value ?
From: vincent.trouill...@modulonet.fr [...] ISO C99, section 6.4.4.4, p3: the question-mark ?, [..] is representable according to the following table of escape sequences: question mark? \? Interesting. I wonder why the standard deeemd it necessary to provide an escape sequence for the question mark ? As other have mentioned, it's to prevent the substitution of trigraphs. Trigraphs are a way to express characters that either do not appear is the source character set, or are handled poorly by the development environment. If trigraphs are enabled, then puts(Trigraphs??!); will output Trigraphs| (IIRC). To prevent this, you can use puts(Trigraphs?\?!); Regards, -=Dave _ Windows Live™: E-mail. Chat. Share. Get more ways to connect. http://windowslive.com/howitworks?ocid=TXT_TAGLM_WL_t2_allup_howitworks_022009 ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Slightly OT: AVR EEPROM Location 0 (was RE: [avr-gcc-list] address@hidden ... what is it for ?!)
From: dke...@hiwaay.net[...] Notice the starting address of eeprom is 1 byte above the physical address of start of eeprom because there was some rumor stating some models of AVR would accidentally trash the first byte under some circumstances. Perhaps when the rest of the device was wiped for a code reload or something? Anyway, it was cheaper to do without the first byte than to worry about it. More than a rumor. If you cut power to certain AVR parts during a write to EEPROM, location 0 would be corrupted. Documented in various AVR Errata sheets. Limited primarily to the AT90S parts IIRC. But it was a long while before I started using EEPROM address 0 again... Regards, -=Dave _ It’s the same Hotmail®. If by “same” you mean up to 70% faster. http://windowslive.com/online/hotmail?ocid=TXT_TAGLM_WL_hotmail_acq_broad1_122008___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
RE: [avr-gcc-list] 24 bit Integer
From: [EMAIL PROTECTED] 2008/7/14 Weddington, Eric [EMAIL PROTECTED]: A 24-bit integer is not supported by the C language. In theory, support could be added to GCC, but then it would be considered an extension to the C language. And it would also be difficult and/or time-consuming to add to GCC. The C standard doesn't dictate the size of any integer type, except that char must be large enough to hold the environments standard character set and the size of any larger types is ordered as you'd expect. char = short = int = long Also that short and int must be able to represent at least -32767 to +32767, and long must be able to represent +/-2,147,483,647. So int24_t would have to be a special type outside the standard types. And I think (though I'm not certain) that it would have to be promoted to long before any operator could be applied. Some of that would be mitigated by the as-if rule, of course... int is typically the natural word size for the architecture, but often on 8 bit micros it will be larger (since char typically provides an 8 bit int anyway.) It's larger because an 8 bits can't represent the required range of values. Regards, -=Dave _ Time for vacation? WIN what you need- enter now! http://www.gowindowslive.com/summergiveaway/?ocid=tag_jlyhm___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
RE: [avr-gcc-list] 24 bit Integer
For a PDP-8, CHAR_BIT would be 12, int could have 24 bits, and long could have 36 or 48, whatever is most convenient/efficient/desired. For a PDP-15, char and int could be the same 18-bit type, and long could be 36 bits. On further reflection, you might be able to replace the standard 16 bit int on AVR with a 24 bit int. The required ranges are minimums. That makes int16_t a special type outside the normal hierarchy, however, and I'm not certain that's allowed. Regards, -=Dave From: [EMAIL PROTECTED] [...] what about a PDP 8 or PDP 15, could we not code for it? being 12 and 18 bit machines? From: [EMAIL PROTECTED] 2008/7/14 Weddington, Eric [EMAIL PROTECTED]: A 24-bit integer is not supported by the C language. In theory, support could be added to GCC, but then it would be considered an extension to the C language. And it would also be difficult and/or time-consuming to add to GCC. The C standard doesn't dictate the size of any integer type, except that char must be large enough to hold the environments standard character set and the size of any larger types is ordered as you'd expect. char = short = int = long Also that short and int must be able to represent at least -32767 to +32767, and long must be able to represent +/-2,147,483,647. So int24_t would have to be a special type outside the standard types. And I think (though I'm not certain) that it would have to be promoted to long before any operator could be applied. Some of that would be mitigated by the as-if rule, of course... int is typically the natural word size for the architecture, but often on 8 bit micros it will be larger (since char typically provides an 8 bit int anyway.) It's larger because an 8 bits can't represent the required range of values. Regards, -=Dave Time for vacation? WIN what you need. Enter Now! ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list _ With Windows Live for mobile, your contacts travel with you. http://www.windowslive.com/mobile/overview.html?ocid=TXT_TAGLM_WL_mobile_072008 ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
RE: [avr-gcc-list] Tip: handling volatile operands
From: [EMAIL PROTECTED] The point I was trying to make (poorly) was that io (and other variables) that may universally declared volatile, may in fact have values that need to be used in a non-volatile fashion. You have same problem with unrollable operations such as: if (ioport == 1) else if (ioport == 2) else if (ioport == 99) So, copy to temporary seems a more general solution - if non volatile access is required. In cases such as these, a copy to a temporary would be required -- the value of the port could change between tests. If you fail to use a temporary, not only are you generating multiple reads to the port, but you are also opening a window where all the tests could fail when at least one of them should succeed. Another solution in this particular case would be to replace the if-else cascade with a switch. switch (ioport) { case 1: ... case 2: ... case 99: ... } This is (IMHO) a closer abstraction of what you actually want done. Though you have to be clever if you're going to mask bits like the original example. In which case an if-else cascade using a temporary would be better. Regards, -=Dave _ Put your friends on the big screen with Windows Vista® + Windows Live™. http://www.microsoft.com/windows/shop/specialoffers.mspx?ocid=TXT_TAGLM_CPC_MediaCtr_bigscreen_012008___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
RE: [avr-gcc-list] ATMega32 fuse bit problem
From: [EMAIL PROTECTED] For instance I recovered chips sometimes by using UART traffic because I had no other hardware at hand: I took a RS232-UART converter, sent a big file from a terminal emulator (with no particular protocol, just raw byte sending) and I tried a few times to erase the chip until it worked ;-) I did a device controller that way once, sending nulls out on the data line as clock and toggling the handshake line for data. :) The intended use is only a suggestion! Clever! If you just want a clean clock signal from a UART, set up to transmit 8N1 and send a continuous string of ASCII 'U' (0x55). Assuming your application can keep the shift register full, you'll get a nice clean square wave whose frequency is 1/2 the baud rate (stop bit is 1, start bit is 0, and the data is transmitted LSB to MSB). Regards, -=Dave _ Windows Live Hotmail and Microsoft Office Outlook – together at last. Get it now. http://office.microsoft.com/en-us/outlook/HA102225181033.aspx?pid=CL100626971033___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
RE: [avr-gcc-list] Problem with delay loop
From: [EMAIL PROTECTED] Hi, On Mon, 01 Oct 2007 13:02:32 +0530, David Brown [EMAIL PROTECTED] wrote: Royce Pereira wrote: So I have to write more 'C' code :) to get the same stuff done, in the 'new smarter' compiler! Interesting. Doesn't seem right, some how. Regards, --Royce. It might not seem right, but that's the way it is. The compiler only has to generate code that has the same effect as the source you've written, and a simple ret has that effect. Why then was the empty 'ret' function retained? I would think such a case would be the prime candidate for optimisation. The compiler should eliminate such a funtion, as well as all calls to that function. That would really make a difference in size/speed of the code. I don't remember the code. Was the function declared static? If not, the compiler must generate at least the ret since functions external to the file could potentially call it as well. If the function was static, the code for it (and the calls to it) could indeed be removed entirely. Years ago, I ran a simple test on a compiler for the 80386. The code static int square(int n) { return n*n; } int test(void) { return square(3); } generated _test: mov ax,9 ret So in that case, no code was generated for the static function. (Instead, the compiler destroys a perfectly good delay loop I've used for the last 2 years -yes, I'm still sore) Sorry, I must disagree. It was not perfectly good. As the fact that the compiler was able to legally destroy it demonstrates. [...] I've always maintained - good software is one that does what you *want* it to do, *not* what you tell it to do. ;) Sorry, I must again disagree. All too often, software that attempts to DWIM (Do What I Mean) guesses wrong, and I have to clean up a mess. E.g., try entering acronyms in Microsoft Word, and watch it correct them for you. Regards, -=Dave _ Windows Live Hotmail and Microsoft Office Outlook – together at last. Get it now. http://office.microsoft.com/en-us/outlook/HA102225181033.aspx?pid=CL100626971033___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
RE: [avr-gcc-list] Problem with delay loop
Date: Fri, 28 Sep 2007 14:21:38 +0530 To: [EMAIL PROTECTED] Subject: Re: [avr-gcc-list] Problem with delay loop From: [EMAIL PROTECTED] CC: AVR-GCC-list@nongnu.org Hi, On Fri, 28 Sep 2007 13:42:18 +0530, Klaus Rudolph [EMAIL PROTECTED] wrote: The code has been optimized. Well done! If you need the variable access use 'volatile' Why does it get optimised? Because it is allowed, and gcc is sophisticated enough to do so. I understand the meaning of 'volatile', but why is it required here ? What is the meaning of volatile? Hint: it has nothing to do with sharing. It is clear that the variable is changing in the code itself (not outside it). Precisely. The optimizer recognized that neither the intermediate values nor even the final value of the variable had any effect on the outcome of the program, and therefore removed the calculation of those values from the code. Again- it worked in the older avr-gcc. Was that a bug(the fact that it worked)? No. It was a missed opportunity for optimization. The program produced the same result, it just took longer to do so. Again, you would do well to investigate the library's delay.h header and the facilities it provides. These work very well. HTH, -=Dave _ Explore the seven wonders of the world http://search.msn.com/results.aspx?q=7+wonders+worldmkt=en-USform=QBRE___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] avr-g++ local variable constructor / block body/destructor ex
From: Graham Davies [EMAIL PROTECTED] David Brown wrote: I believe [the compiler] can [change order of ... volatile objects access]. Obviously it is only legal if such moves do not affect the volatile accesses themselves. Perhaps someone here who has a better knowledge of the standards ... I wouldn't claim better knowledge, but this is a sore spot for me so I'm going to chime in anyway. I think that the compiler is not permitted to change the order in which volatile objects are accessed. This would undermine the intent of volatile, which is to give the user exactly what he asks for. My impression is that the C language is defined in terms of the behavior of an abstract machine, which lacks all optimization and operates in a very simplistic but easy-to-describe manner. An actual compiler is allowed to deviate from this, in order to perform optimization, on condition that the resulting behavior is indistinguishable from the abstract machine at certain places called sequence points. In addition, when manipulating volatile objects, it is not allowed to deviate at all from the abstract machine. This is all true, but I think the key is that the volatile qualifier only affects what it qualifies. For example, given the following code x = 1; y = 2; x = 3; y = 4; If none of the variables is volatile, only the last three lines need generate any code, and they may be reordered any way the compiler likes. If both variables ar volatile, each line must be executed in exactly the order shown. If only x is volatile, the generated code must write a 1 to x, then a 3. The write of 2 to y can be elided, and the write of 4 to y can occur before, between, or after the writes to x. As long as the final result is as-if the code had been performed by the abstract machine, and any volatile value is handled exactly as the abstract machine would have. HTH, -=Dave _ Test your celebrity IQ. Play Red Carpet Reveal and earn great prizes! http://club.live.com/red_carpet_reveal.aspx?icid=redcarpet_hotmailtextlink2 ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] Operation problem
From: Gerard Marull Paretas [EMAIL PROTECTED] Paulo Marques: I think you just answered your own question: if all the variables involved are uint16_t, then that is the precision used for all he expression and it will overflow on the multiplication. The same happens whether if currentsong.length is uint32_t or uint16_t. Yes. The target of the assignment plays no part in the calculation. Let's simplify some things. Consider the the following code: uint16_t w1=4, w2=4; uint32_t dw1=4, dw2=4; uint32_t r1, r2, r3, r4; r1 = w1 + w2; r2 = dw1 + dw2; r3 = dw1 + w2; r4 = (uint32_t)w1 + w2; I haven't tried it, but I have a prediction: r1 will be 14464, but r2, r3, and r4 will all be 8. The reason is simple: the calculation in each statement is separate from the assignment. The calculation occurs first, and the result is then assigned to the target. The first expression (w1+w2) is the addition of 2 uint16_t values, the result of which is a uint16_t. Since the addition overflows, only the lowest 16 bits are kept. That result is stored in r1. The second expression is the addition of two uint32_t values. The result is a uint32_t, and no overflow occurs. The third expression involves a uint32_t and a uint16_t. The promotion rules of C require the uint16_t value be promoted to uint32_t before the addition takes place. After that, it's just like the second expression. The third expression has an explicit cast of a uint16_t (w1) to uint32_t. The conversion of w1 takes place before the addition, and the integer promotions then require that w2 be converted to uint32_t as well before the addition takes place. After that, it's just like the third expression. If this is still fuzzy, try compiling the code above (or something like it), and look at the generated assembly. Regards, -=Dave _ Find a local pizza place, movie theater, and more .then map the best route! http://maps.live.com/default.aspx?v=2ss=yp.bars~yp.pizza~yp.movie%20theatercp=42.358996~-71.056691style=rlvl=13tilt=-90dir=0alt=-1000scene=950607encType=1FORM=MGAC01 ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] New GCC warning - how to silence?
From: Bob Paddock [EMAIL PROTECTED] [...] What I've never understood at all is why are characters signed in any case?What exactly is the meaning of a negative-letter-A? It's all hysterical raisins. The earliest C compilers made char signed by default because ASCII only requires 7 bits, and signed operations on 8-bit values on the target platforms were less expensive than unsigned. As C proliferated before there was a standard, many compilers followed the practice, even if there was no difference between signed and unsigned operations. However, if unsigned operations were less expensive, many compilers made char unsigned by default. When the C standards committee met, one of their charters was to codify existing practice. Since both signed and unsigned plain char were in common use at the time, the committee allowed either, so long as an implementation defined which it used. IMHO this was an error on the committee's part. As it is, the plain char type is almost useless, but you're essentially required to use it, since, for example, string literals point to arrays of plain char. Furthermore, combined with the new (with the original standard) value preserving automatic promotion rules, signed char types are the source of many confusing promotion errors. As it is, we're stuck with it, and since avrgcc has used signed chars by default for many years, the only reason to change to unsigned would be code efficiency gains, i.e., if operations on unsigned char were much less expensive than operations on signed char. I haven't looked into it deeply, but I don't think that's the case for the AVR architecture. It would be better to code to stdint.h, than rely on any ambiguous compiler switches/standard-C 'undefined' issues. For applications written for an 8-bit micro, such as the AVR, where you want tight control on such things, this is true. It is not true for all applications that might be written in C, however. And you really have no choice when it comes to using the standard library or string literals: you're stuck with plain char for those. Regards, -=Dave _ MSN is giving away a trip to Vegas to see Elton John. Enter to win today. http://msnconcertcontest.com?icid-nceltontagline ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
RE: [avr-gcc-list] Inconsisten behaviour of switch statement
From: Eric Weddington [EMAIL PROTECTED] From: Schwichtenberg, Knut [mailto:[EMAIL PROTECTED] [...] Eric, the point is not that I don't like the output, but the case to be selected should be deterministic. I always thought that a switch statement would lead to identical results if the input value is identical. This is currently not true. The table jump for a volatile variable is identical to an if-then-else structure of a non-volatile variable and the current if-then-else implementation for a volatile variable can not be simulated by a table jump. This is one of many reasons why I personally don't like switch statements in embedded code. I still suggest coding your algorithm as a dispatch table. Give it a try. I think Knut has a point. At least, if I understand what's going on. Given code like switch (var) { etc. } If var is volatile, it should be read only once, regarless of the number of cases. Consider code like switch (fn()) { etc. } How many times would you expect fn to be called? Of course, a simple workaround would be to read the value of var into a non-volatile local variable, and switch on that, e.g., local = var; switch (local) { etc. } But he shouldn't _have_ to do that. Bug in gcc? Regards, -=Dave _ Get a FREE Web site, company branded e-mail and more from Microsoft Office Live! http://clk.atdmt.com/MRT/go/mcrssaub0050001411mrt/direct/01/ ___ 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] volatile...
From: Paulo Marques [EMAIL PROTECTED] Graham Davies wrote: David Brown wrote: You are missing a number of points ... Well, I think we're getting close to complete coverage now! Well, since we are going for complete coverage, I'll add my 2 cents, then. You've opened some new cans of worms here, but I'll only make one small comment [...] static uint16_t atomic_read_16(uint16_t *ptr) { uint16_t ret; cli(); ret = (volatile)(*ptr); Your cast to volatile here is not only unnecessary, it's wrong. You are actually casting the uint16_t intermediate value to signed int, which is then converted (back) to uint16_t. If you tried to model an atomic_read_32 on this function, you might not like the results. On newer conmpilers (with C99 compliance) it shouldn't even compile (implied int no longer allowed). sei(); OK, a second comment: I like to save SREG before the CLI, then restore SREG rather than blindly enabling interupts with SEI. That way, if I happen to call the function with interrupts disabled, they aren't unintentionally enabled early. return ret; } Regards, -=Dave _ WIN up to $10,000 in cash or prizes enter the Microsoft Office Live Sweepstakes http://clk.atdmt.com/MRT/go/aub0050001581mrt/direct/01/ ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] volatile...
From: Paulo Marques [EMAIL PROTECTED] Dave Hansen wrote: [...] You've opened some new cans of worms here, but I'll only make one small comment I was afraid of that (the cans of worms, not your comment) ;) Thanks for noticing the implied smiley. Looking at what I wrote, I'm not sure it has the tone that was intended... [...] static uint16_t atomic_read_16(uint16_t *ptr) { uint16_t ret; cli(); ret = (volatile)(*ptr); Your cast to volatile here is not only unnecessary, it's wrong. [...] But you're actually wrong about the volatile not being needed. Because the sei instruction doesn't claim anything about memory clobbers, without volatile the compiler would be free to re-order instructions and do the sei before the assignment. Ouch. I would have thought the volatile int the sei macro would have taken care of this. This is no theoretical scenario. Just search the archives for previous threads over this. I didn't find anything in a quick search, but I believe you. Would declaring the variable (ret) 'volatile' let us remove the cast? Regards, -=Dave _ Get the latest Windows Live Messenger 8.1 Beta version. Join now. http://ideas.live.com ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
RE: [avr-gcc-list] query please help
From: rajeev joshi [EMAIL PROTECTED] [...] 4.While working on windows which compiler, simulator shpuld use ,right now i m having codevision AVR ,AVR studio . 5. But i m not gettin how to work on WINAVR . What is your goal? If you have to get a project out, and you have a paid license for CodeVisionAVR, it's probably easiest just to use that. CVAVR takes you by the hand and leads you through the process. Support on the Yahoo group and from HPInfotech is quite good. It's not necessarily a better tool than WinAVR, but its learning curve is easier to overcome, and it's certainly better than acceptable. If your goal is to develop software under WinAVR, and you're not familiar with the GNU tools or comfortable with the edit-compile-debug cycle outside a completely integrated IDE, you might want to check out avrfreaks.net articles on the tools. Personally, I have a much harder time navigating avrfreaks than using the tools, but there is helpful information there if you're willing to dig for it. If you want to develop under both UN*X and Windoze, gcc is a much better option. It is difficult, but possible, to write code that compiles and runs under both WinAVR and CVAVR (I've done it many times), but it involves becoming quite familiar with both tools, and giving up some of the simplifying assumptions of CVAVR, as well as hiding syntax differences behind macros. HTH, -=Dave ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
RE: [avr-gcc-list] (no subject)
From: MuRaT KaRaDeNiZ [EMAIL PROTECTED] So U08 RX485_oldbyte1; is uninitialized data, but compiler also initialize it to zero, why is it different from inline initialization during declaration, I expect the compiler just replace the zero with the initial value i provide? Because reality is different than what you expect. In C, there are really two kinds of declarations, those that define the object, and those that reference it. Rule number 1: There may be only 1 defining declaration in a program. How do you tell the difference? If a declaration includes an initializer, it is a (the) defining declaration. If none of the declarations of an object include an initializer, then all referencing declarations must be declared with the extern storage class. A top-level declaration without extern and without an initializer is called a tentative definition. It is treated as a referencing declaration, but if no other declaration of the variable in the file includes an initializer, then the tentative definition becomes a defining declaration. If an implementation permits tentative declarations in multiple translation units without issuing a diagnostic, it is non-conforming, but supports a common extension. Avoid taking advantage of this extensionif you want your code to be portable. HTH, -=Dave ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
RE: [avr-gcc-list] Program Space String optimization
From: bolet (sent by Nabble.com) [EMAIL PROTECTED] [...] The program works OK without optimization. It doesn't work with optimization (-o1). The code is: ...includes... const char P_Txt[] PROGMEM = Just a test..; volatile PGM_P txt= P_Txt; int main (void) { ...Init code ... (reg setup enable int) do{} while( (a=pgm_read_byte(txt)) ); // Wait for null char cli(); //Disable int for (;;); // Do nothing return(0); } SIGNAL (SIG_USART_DATA) { UDR0=pgm_read_byte(txt++); //Send a byte and increment pointer } The 'do while' assembler code generated (with -o1) : +0041: 91E00100LDS R30,0x0100 +0043: 91F00101LDS R31,0x0101 +0045: 9184 LPM R24,Z 51: do{} while( (a=pgm_read_byte(txt)) ); // Wait for null char +0046: 2388 TST R24 +0047: F7F1 BRNEPC-0x01 Branch if not equal 52: cli(); //Disable int As you can see, the LPM instruction is outside the loop, so this is an infinite loop. -What's wrong with this code? Seems to be a strange corner case. I'm not sure the compiler is misbehaving, but it might be. There should be a simple fix. You've declared 'txt' to be volatile, which is good, but you don't show the declaration of 'a'. And I suspect it's not volatile. Since 'a' is not volatile, subsequent writes to the value may be optimized out. But the LPM should always happen because txt is volatile. In any case, changing the declaration of 'a' to something like unsigned char volatile a; should do it. Removing 'a' entirely should fix it as well, but I'm assuming you're using it for other reasons. -Which is this the correct way to work with flash data? You don't seem to be handling flash wrong. Any suggestion would be greatly appreciated. HTH, -=Dave ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
RE: [avr-gcc-list] Problem with debbuggin with AVRStudio, WinAvr and JtagIce mkII
From: [EMAIL PROTECTED] [...] #include avr/io.h int somma(int a, int b) { return a+b; } int main () { int e = 10; int r = 1; r = somma(e,r); r=r+1; return r; } it's a stupid program. When debbugging it step by step the main regularly calls somma(e,r). After somma(e,r) finished, the control flow does not return in main at r=r+1 but in a part of memory without code (after the exit() of the main). Can you help me with this problem? Just a guess: Try making 'r' volatile, i.e., change the declaration of r to int volatile r = 1; Because r is not used other than as the return value, the compiler might be optimizing out accesses to the variable itself. The 'volatile' declaration forces the compiler to retain these accesses. HTH, -=Dave ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
RE: [avr-gcc-list] sdram adress/length
From: varsha [EMAIL PROTECTED] hello all, i am using avr-gcc (GCC) 3.4.3, and using ATmega16 , and writng the code for copying sdram data int flash, in c language. There are three address bytes and three length bytes for sdram. At a time i can read 16 bytes from sdram, then i want to decerment the length and incerement the address value bye 16. how to increment address value(or decrement the length), by using a single variable. i dont want use three different bytes, because then propogating carry becomes a problem.. is there any way , by which we can define a data type which takes three bytes of memory...? Obviously, you could use unsigned long, which solves all your problems at the cost of one unused byte. Each. unsigned long sdram_adr = 0; unsigned long sdram_len = 0x100; while (sdram_len 0) { process_16_sdram_bytes(sdram_adr); sdram_len -= 16; sdram_adr += 16; } However, access to unsigned long is not atomic. If you are going to be accessing these values in interrupt service routines, you'll have to protect access in mainline code so they aren't interrupted. Hope this helps, -=Dave ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] AVR assembly for fast bit bang
From: David Kelly [EMAIL PROTECTED] [...] People keep saying C isn't fast enough. I don't belive it. First attempt: #include avr/io.h #define CLOCK_B (10) #define BIT_B (11) void myjunk(uint8_t byte) { uint8_t i; for( i = 0 ; i 8 ; i++ ) { PORTA |= CLOCK_B; // rising edge of clock if( byte (17) ) PORTA |= BIT_B; // set else PORTA = ~BIT_B;// clear byte = 1; PORTA = ~CLOCK_B; // falling edge of clock } } [...snip assembly...] It might be tough to do better on AVR. My standard SPI routine uses a do-while loop, which might save an instruction or two, but made about a 30% difference on the PIC compiler I used. Something like void output_spi_byte(uint8_t byte) { uint8_t bit_ctr = 8; do { output_low(SPI_DATA); // Set data bit low... if (byte 0x80) output_high(SPI_DATA); // ...or high, as required output_high(SPI_CLK); byte = 1; // Shift acts as clock dwell delay output_low(SPI_CLK); } while (--bit_ctr); } I don't have avr-gcc handy to see if it's any better than your code. I was more concerned with size than speed, as you may be able to tell. If speed is the ultimate object, unrolling the loop will help. Regards, -=Dave ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] How to (efficeiently !!!) testabitwithinamulti-byte intege
From: Vincent Trouilliez [EMAIL PROTECTED] FWIW, I always had good luck with the delay functions in delay.h for short hardcoded (usec) delays. Lucky you ! Other than wanting to avoid all this in-line stuff, the reason I replaced _delay_us(40) in my lcd routine, by an empty for loop, is that I accidentally realised that _delay_us(40) produced a 1,500us delay somehow !!! Couldn't figure out why, I set the F_CPU #define properly, and _delay_ms() works perfectly, but _delay_us clearly doesn't. Might be a bug with the particular delay of 40us, don't know, as don't use us delays anywhere else in my program. Well, as I said earlier, I wrote my own delay_us routine from _delay_loop_2 rather than using the supplied _delay_us. I'm not sure why, it was so long ago. Perhaps it didn't exist back then. My longest delay (i.e. parameter supplied to the macro) was 10 usec, but I never measured to see how close it was. It couldn't have been over about 100 usec, or the system would not have performed.. I did measure a couple of 1 usec delays, and those were very close to exact. Regards, -=Dave ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] How to (efficeiently !!!) test abitwithinamulti-byte intege
From: David Brown [EMAIL PROTECTED] [...] The bug is almost certainly a delay loop variable that is not declared volatile. The delay function is probably something like: void shortDelay(void) { uint8_t n = 50; while (n--); } That (might) work fine with little or no optomisation, but when optomisation is on, it fails. The solution is simply to make n volatile. Note that it will not give you precise control of your delay - different optomisations or different compiler versions might give slightly different code, and may or may not inline the function. But in a case like this it doesn't matter - all you are looking for is a slight delay, and it doesn't matter if it is too long. I've done exactly this sort of thing (with volatile, naturally) myself for LCD routines. FWIW, I always had good luck with the delay functions in delay.h for short hardcoded (usec) delays. I don't have access to the code now, but I had a macro that calculated the minimum number of trips through the four-cycle loop that would guarantee the specified delay. Something like #define usec_count_(x) ((OSC_FREQ*(x))/400) #define delay_us(x) _delay_loop_2(usec_count_(x)) It looks like the library also provides _delay_us, which might be better, though I've never tried it. Requires you to #define F_CPU before #including avr/delay.h. Regards, -=Dave ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] Compile problem
From: Patrick Blanchard [EMAIL PROTECTED] On Fri, 2005-10-07 at 08:24 -0700, Razvan Turiac wrote: I think I have a compile problem. I am using WinAVR 20050214 and I've got one problem when compiling some code. OK, but you need to show us the compiler errors received... You have to scan the attachments. It probably would have been better for the OP to simply include the code in-line with his message. From what I see, there were no error messages, but it appears the compiler generated incorrect code. also, avr/io.h header does not define wait(), nor does avr/delay.h It was his function, in the attached (to his message) C file. The assembler code is all wrong. how? It appears the TIFR register is not acting volatile. Perhaps it's incorrectly declared in the header? The wait function is: --- void wait(unsigned char time) { TCCR0 = 0x02; //set prescaler to 2 while(time--) //wait time * 100us increments @ XTAL = 16MHz { TCNT0 = 56; TIFR |= (1 TOV0); while(!(TIFR TOV0)); } } --- Note: the TIFR |= (1 TOV0); should more properly be TIFR = (1 TOV0); due to the way TIFR works. But I digress. The generated code is: --- wait: .LFB3: .LM1: /* prologue: frame size=0 */ /* prologue end (size=0) */ .LM2: ldi r25,lo8(2) out 83-0x20,r25 .LM3: tst r24 breq .L9 .LM4: ldi r24,lo8(56) out 82-0x20,r24 .LM5: in r24,88-0x20 ori r24,lo8(1) out 88-0x20,r24 .L4: .LM6: in r24,88-0x20 rjmp .L4 .L9: ret --- Note the inner loop is optimized out, apparently on the assumption that the low bit in TIFR has just been set, so it remains set. Regards, -=Dave ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
RE: [avr-gcc-list] CVS or SVN ?!
From: Vincent Trouilliez [EMAIL PROTECTED] Hi list, I have been advised to use CVS when developing programs, but it seems awkward to set up the server side. While asking around for help, I have been suggested to give up CVS and use SVN, subversion, instead, and that it was meant to supplant CVS. Now CVS seems difficult enough, so I don't fancy spending time on it, only to have to change to something else soon after... I would like your opinions on this... what do everyone use at work ? Most of my career I used PVCS. At various places of employment, I've used Continuus, Visual Source Safe, and RCS. That last is the closest I've ever come to CVS or SVN. Does it make any difference what system I use, as long as I use one !? The difference between using one and not using one is far greater than the differences between any two particular systems. And that's why (IMHO), especially for individuals or groups who've not used version control in the past, ease-of-use is by far the most important feature. If it's hard to use, people will find a way to avoid using it, at least until it's saved their butts a few times and they can see the true value. Kind of like lint... Say I find a job in this field, what would my boss be most likely to ask me to use, CVS or SVN ? Or do the bosses not care, and the engineer can use and setup whatever system he prefers or is familiar with ? You will generally use what the company has chosen. Unless they haven't chosen. Which is why I'm using RCS at the moment -- it's better simple to set up, easy to use, low overhead, and _far_ better than nothing. If you're on a Windoze box, Component Software makes it almost trivial to set up and use (www.componentsoftware.com). The personal version is free (as in beer). But it's only me using it. I'd want something fuller-featured if there were group dynamics to contend with. Component software has a CVS-based system that's not free, but reasonably priced, and I'd certainly give that a look based on my experience with the RCS tool. HTH, -=Dave ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] calling function pointers via pointers ?
From: Vincent Trouilliez [EMAIL PROTECTED] [...] What more could I possibly want ? Well, there is one thing actually: the pointer points to a function, any function. However if the item is actually a sub-menu, then the 'menu_item' structure needs to store a pointer to a 'menu' structure, so that I know what sub-menu to run. So it would like this: typedef struct { charname[21]; void(*fp) (uint8_t); menu *sub_menu; // I need to know what sub-menu to run ! }menu_item; typedef struct menu { char title[21]; uint8_t nb; menu_item items[]; }menu; But it's a bit strange no ? :-/ How can I declare a pointer of 'menu' type... even before said type has been declared ! The two structures would be interdependent... no solution in sight ! :o I guess this is crap code again... heeelp... Not strange. No crap. You're just missing a feature. C allows you to forward-declare a structure with a tag. What you need is something like struct menu;// Forward declaration typedef struct { char name[21]; void (*fp) (uint8_t); struct menu *sub_menu; // can't use typedef here }menu_item; typedef struct menu { char title[21]; uint8_tnb; menu_item items[]; }menu; Warning: untested code, but it should be close. HTH, -=Dave ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
RE: [avr-gcc-list] calling function pointers via pointers ?
From: Vincent Trouilliez [EMAIL PROTECTED] [...] Problem: my function pointers are in an array, within a structure, which itself is accessed via pointers... oh dear. [...] //data type for a menu struct menu { .; .; int (*fp)()[]; //table to store all the pointers Err... Read it from the inside-out: fp is a pointer to a function that returns an array of pointers to int. I don't think that works, let alone is what you want. And you need to specify the size, and it's a good idea to specify the formal parameters needed by the function. I think you mean something like int (*fp[3])(void); fp is an array of 3 pointers to function taking void and returning int. }; //definition for a menu const struct menu __ATTR_PROGMEM__ menu_foo = { ., ., {fn1, fn2, ... } }; Note: menu_foo is PROGMEM. //run the specified menu using the structure passed as argument void menu_run(const struct menu * p) Do you have to make p point to PROGMEM? I'm not sure, but I do know that... { int r; . r = (p-fp[0])();//call the first function ...this won't work if you call menu_run with menu_foo as the parameter. You need to read the pointer out of PROGMEM first, then call using that: int (*fp)(void); fp = pgm_read_word(p-fp[0]); fp(); Warning: untested code. You might need a cast in there. HTH, -=Dave ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] calling function pointers via pointers ?
From: Vincent Trouilliez [EMAIL PROTECTED] [...] However, something still causes me trouble apparently The actual/complete declaration of my menu data type / structure is : struct menu { uint8_t options; //options to control the operation of the menu uint8_t nb; //number of options present in this menu chardesc[][21]; //table to store the strings for each menu entry void (*fp[])(void); //table to store the pointers to the functions }; The compiler complains that : ui.h:29: error: flexible array member not at end of struct make: *** [main.o] Error 1 I got around this by giving a fixed size to 'desc', which worked fine for debugging the pointer part of things, but it's otherwise no good of course. What's the trick ? Sounds like you're in deep yogurt. Do you know what a flexible array member is? Did you know you defined two of them? Did you reserve space for the function pointers? You probably need to seperate the tables from the structure. Something like this: struct menu_entry { char desc[21]; // or perhaps simply char * desc void (*fp)(void); }; struct menu { uint8_t options; //options to control the operation of the menu uint8_t nb; //number of options present in this menu struct menu_entry * entries; }; Then use them something like struct menu_entry menu_x_entries[] = { { opt 1, fn_x1}, { opt 2, fn_x2}, { opt 3, fn_x3} }; struct menu menu_x = {0, 3, menu_x_entries}; Hopefully this is enough to get you started. You'll have to work out the pgmspace details out yourself. Regards, -=Dave ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
RE: [avr-gcc-list] Lint and avr-gcc
From: Jonathan Goldberg [EMAIL PROTECTED] Anyone have a good lint configuration file for avr-gcc? You don't say which lint. Here's the one I'm using for a current project under Ginpel's PC-lint. --- begin included file --- // Compiler definitions // c:\lint\lnt\co-gnu3.lnt // 2.95.3 and later (3.3.1) -si2// Change int and ptr sizes for AVR -sp2 -d__GNUC__ +rw(inline) // Header file locations // -iC:\WinAVR\avr\include -iC:\WinAVR\lib\gcc\avr\3.4.1\include // Project definitions -d__AVR_ATmega32__ // Compiler does this from MCU definition -dOSC_FREQ=1200 // Make file derives this from HZ -dDBUG=0 -dHIGH_CAP=0 -dDISABLE_VBATT_TEST=0 // Error reporting suspension // // Some GNU macros return a value from bracketed expressions. -emacro(155,__LPM) // lint doesn't understand extern inline -esym(14,timer_enable_int) // in avr/interrupt.h // Interrupt vectors must be extern but aren't referenced // -esym(714,__vector_*) -esym(765,__vector_*) --- end included file --- HTH, -=Dave ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] Trick for creating WYSIWYG bitmaps in C [was: howto specifiy a binary constant]
From: Bob Paddock [EMAIL PROTECTED] I thought I'd try this bitmap 'trick' via copypaste of the #defines and code into the file I was working on, this is what I get: Name/name.c:692: error: `sXX__' undeclared here (not in a function) Name/name.c:692: error: initializer element is not constant Name/name.c:692: error: (near initialization for `lcd_char_P[0]') Name/name.c:693: error: `sX_X_' undeclared here (not in a function) Name/name.c:693: error: initializer element is not constant [snip rest of the bitmap erros] Is this 'trick' compiler or compiler option dependent? [...] #define X )*2+1 #define _ )*2 #define s 0 /* 8 parens for 8 bit, 16 for 16, etc) */ Then you just draw your bitmap as such: uint8_t lcd_char_P[] = { sXX__, sX_X_, sX__X, sX_X_, sXX__, sX___, sX___, sX___ } I think it will work if you change the above to uint8_t lcd_char_P[] = { s XX__, s X_X_, s X__X, s X_X_, s XX__, s X___, s X___, s X___ } But I haven't tried it myself. Regards, -=Dave ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] OT Generic C question
From: David Brown [EMAIL PROTECTED] - Original Message - From: Trampas [EMAIL PROTECTED] I was helping a friend debug some code, he is new to C, using the Keil version of GCC for ARM. Anyway I found the following: int i; i=0; i=i++; //i was still zero that [...] I'd agree with you that i should be 1 after i = i++, despite the sillyness Actually, I think the naive interpretation would be that i should be zero after the above is executed: The statement implies three operations: 1) read the variable on the RHS (i) and save the value 2) increment the variable on the RHS (i). 3) store the value preserved in step 1 (0) in the variable on the LHS (i) The logical order of the operations is given above. In reality, the operations can occur in just about any order. The only guarantees the C standard makes about the order of execution involves a concept called sequence points. Sequence point occur in several places, but the most common is at the end of each full expression (as a first estimation, you can think of it as being at each semicolon). The standard says that the value of a variable should only be modified once between sequence points. The expression i = i++; attempts to modify i twice: once with the ++ operator and once with the = operator. Modifying a variable twice between sequence points is undefined behavior -- there is no correct answer. After the expression is executed, i could be 0, 1, 42, or the system might format your hard drive. All of the above and many other results are legal as far as the standard is concerned. As other have pointed out, the correct way to get the desired effect is one of ++i; i++; i += 1; i = i + 1; Each of which should result in identical code. Google on C sequence points for more information than you probably want. HTH, -=Dave ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] Initilizing complex const arrays : syntax ?
From: David Kelly [EMAIL PROTECTED] [...] char buffer[4]; uint8_t i; strncpy_P( buffer, PGM_P(000), 3 ); i = 2; while(x) { buffer[i--] = x%10 + '0'; x = x/10; } putchar(buffer[0]); putchar('.'); putchar(buffer[1]); putchar(buffer[2]); In the above I find myself wishing for the FORTH /mod operator. Avr- gcc calls exactly the same routine for division or modulo and stores the desired result. In assembly we could store both but I don't see how to get at both from C. Is possible the compiler could optimize it but plain -O didn't in recent tests. Try something like #include stdlib.h ... div_t qr; while(x) { qr = div(x,10); buffer[i--] = qr.rem + '0'; x = qr.quot; } I'm not certain this is optimal. I haven't looked closely, but it looks like it should be. It certainly has the opportunity to be. Regards, -=Dave ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] Code version timestamp
From: [EMAIL PROTECTED] (Joerg Wunsch) [EMAIL PROTECTED] wrote: I would like to display a code version (date/time or incremental number) during init on an LCD display. If you're using CVS, you can get the date of the last checkin of a particular module by const char foo[] = $Date$; And whether you're using CVS or not, you should be able to do something like const char foo_2[] PROGMEM = Compiled on __DATE__; to get the date the file was actually compiled. Won't tell you (by itself) which version of the file was compiled, though... Regards, ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] Code version timestamp
From: Anton Erasmus [EMAIL PROTECTED] On 14 Sep 2005 at 6:21, John Altstadt wrote: [...] %.elf: $(OBJ) @echo @echo $(MSG_LINKING) $@ $(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS) rm version.o There is a better way to force the recompile of version.c Add the following at the end of your makefile # Always compile version.c to get correct compilation date and time .PHONY: version.c ITYM .PHONY: version.o Another method that works with make utilities besides GNU's (and is perhaps more self-documenting) is version.o: FORCE FORCE: IOW, make version.o depend on FORCE, and make FORCE a phony target (no prerequisites and no commands). As long as you don't make a file named FORCE, version.o will always be made (compiled from version.c) Of course, if you are using GNU make, it's good to add .PHONY: FORCE so FORCEd commands are executed even if a file named FORCE is created... Regards, -=Dave ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Re: [avr-gcc-list] Small program for UART not working
From: Anton Erasmus [EMAIL PROTECTED] [...] I tried to calculate the baud rate on scope, I found I can't get a exactly number, I can only get an estimate. Do you know if there's way to set the baud rate accurately? Send 0xAA continiously. That way you get a nice square wave at the baud rate frequency. If you drop I thought it was 0x55 (or ASCII 'U') that you wanted, rather than 0xAA. An idle RS-232 line is in the Mark state. Start bit is Mark to Space transition. Data bits are then sent LSB first, with Mark == 1, Space == 0, so the LSB has to be a '1'. After the last databit (bit 7 is zero, or Space), the stop bit puts the line back into idle (Mark) for 1 bit time. This should work for 8N1. Regards, -=Dave ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
RE: AW: [avr-gcc-list] Pgmspace.h Use
From: Haase Bjoern (PT-BEU/EMT) * [EMAIL PROTECTED] [EMAIL PROTECTED] wrote: Hello, for code portability reasons, I would like to avoid to call explicity the function pgm_read_byte() like in the following example : const prog_char array[7] = {0x10,0x20,0x30,0x40,0x50,0x60,0x70}; y = pgm_read_byte(array[2]); // I would like to to keep the syntax y = array[2]; without having the array copied in the SRAM Is there a way to do it ? No. The declaration you give above *is* how you put the array in Flash, and how you access the array in Flash. GCC requires a new feature patch for it to know that the expression, y = array[2], means that array is in Flash and to use the correct assembly sequence. There is a person working on such a feature, however, it is very non-trivial to implement in GCC. And currently there is not a deadline when this work will be completed as it being written by a volunteer. Eric Weddington IMO, it is not a problem of gcc, it is a problem of the C programming language that lacks support for Harvard architectures. In order to add support, you are forced to leave the ANSI standard, IIUC. There is ISO/IEC WDTR 18037, which addresses multiple memory spaces (Harvard architectures), fixed-point arithemetic, and hardware IO addressing. I'm not sure of what the status is, but you should (soon? now?) be able to support this stuff without leaving the standard. FWIW, to maintain portability between the two compilers I use, my current code has a common.h file that all the .c files #include. One of the fetures of common.h is a set of preprocessor directives something like #if defined(__GNUC__) # include avr/pgmspace.h # define flash const #else # define pgm_read_byte(p) (*((unsigned char flash *)(p))) # define pgm_read_word(p) (*((unsigned short flash *)(p))) # define PROGMEM #endif So I can define data like unsigned char flash array[2] PROGMEM = {3,5}; and access it with something like x = pgm_read_byte(array+idx); Maybe the syntax isn't as pretty, but it works. Regards, -=Dave ___ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list