Re: Saving & retreiving a structure in eeprom

2020-06-09 Thread Dave Hansen
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?

2011-08-29 Thread Dave Hansen



 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

2010-02-05 Thread Dave Hansen

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

2009-03-30 Thread Dave Hansen

 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

2009-03-30 Thread Dave Hansen

 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

2009-03-30 Thread Dave Hansen

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.

2009-03-11 Thread Dave Hansen

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

2009-02-11 Thread Dave Hansen

 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 ?

2009-02-05 Thread Dave Hansen



 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 ?

2009-02-05 Thread Dave Hansen

 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 ?!)

2009-01-06 Thread Dave Hansen

 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

2008-07-30 Thread Dave Hansen

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

2008-07-30 Thread Dave Hansen

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

2008-01-11 Thread Dave Hansen




 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

2007-11-13 Thread Dave Hansen

  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

2007-10-02 Thread Dave Hansen

 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

2007-09-28 Thread Dave Hansen

 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

2007-09-06 Thread Dave Hansen




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

2007-08-11 Thread Dave Hansen

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?

2007-04-09 Thread Dave Hansen

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

2007-03-26 Thread Dave Hansen

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

2007-03-05 Thread Dave Hansen

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...

2006-12-15 Thread Dave Hansen

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...

2006-12-15 Thread Dave Hansen

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

2006-03-07 Thread Dave Hansen

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)

2006-01-30 Thread Dave Hansen

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

2005-12-14 Thread Dave Hansen

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

2005-11-16 Thread Dave Hansen

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

2005-11-10 Thread Dave Hansen

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

2005-11-09 Thread Dave Hansen

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

2005-11-07 Thread Dave Hansen

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

2005-11-04 Thread Dave Hansen

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

2005-10-07 Thread Dave Hansen

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 ?!

2005-09-30 Thread Dave Hansen

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 ?

2005-09-29 Thread Dave Hansen

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 ?

2005-09-28 Thread Dave Hansen

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 ?

2005-09-28 Thread Dave Hansen

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

2005-09-26 Thread Dave Hansen

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]

2005-09-23 Thread Dave Hansen

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

2005-09-20 Thread Dave Hansen

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 ?

2005-09-19 Thread Dave Hansen

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

2005-09-14 Thread Dave Hansen

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

2005-09-14 Thread Dave Hansen

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

2005-09-12 Thread Dave Hansen

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

2005-08-09 Thread Dave Hansen

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