What type to pass to _delay_ms

I’m using Studio 7 ver 7.0.1006 and I come up with the error

__build_avr_delay_cycles expects a compile time integer constant.

Snippet works when I inline _delay_ms (), but as soon as I put it in a function, it won’t build.

#define F_CPU 16000000L
#define LED (1 << PINB4)

#include "avr/io.h"
#include "util/delay.h"

void Wait ( uint32_t mSec) {
	_delay_ms( mSec );
}

int main (void) {
	int Count = 10;
	
	DDRB = (1 << PINB4) | (1 << PINB5);
	PORTB = ~(1 << PINB5);
	
	while (Count) {
		PORTB = LED;
		Wait(  350 );		
		PORTB = ~LED;
		Wait( 500 );
		Count--;
	}
}

I don't know what else to say except to echo the error message at you, it tells you exactly what the problem is. The parameter to _delay_ms() must be a constant value that can be calculated at compile time. When you have it wrapped with a function, you're passing it a variable, not a constant. When you inlines it, you were passing it the literal values 350 and 500, which satisfy its requirements.

Arduino IDE 1.6.10...

Sketch uses 198 bytes (0%) of program storage space. Maximum is 32,256 bytes.
Global variables use 0 bytes (0%) of dynamic memory, leaving 2,048 bytes for local variables. Maximum is 2,048 bytes.

...has no problem with your code.

Arduino IDE 1.6.9...

__build_avr_delay_cycles expects a compile time integer constant

...has a problem with your code.

OldSteve: Arduino IDE 1.6.9... ...has a problem with your code.

This was the behavior I was expecting

Maybe it's because Arduino uses gcc and Atmel Studio uses M$. Not sure if I'm right about that, but I do remember the dozens of #pragmas I had to use with Visual Studio. In either case what I was attempting to learn was how to code the most efficient way to get the smallest object file and realized each instance of _delay_ms used 12 bytes of code (inline).

Thanks for the input guys.

Jiggy-Ninja: I don't know what else to say except to echo the error message at you, it tells you exactly what the problem is.

Now that I've had time to think about it, DUH. Maybe I was assuming what the error was instead of actually reading the message.

From the documentation:

Note: The new implementation of _delay_ms(double __ms) with
__builtin_avr_delay_cycles(unsigned long) support is not backward compatible.
User can define DELAY_BACKWARD_COMPATIBLE to get a backward compatible delay.
Also, the backward compatible
algorithm will be chosen if the code is compiled in a freestanding
environment
(GCC option \c -ffreestanding), as the math functions
required for rounding are not available to the compiler then.

Try defining the DELAY_BACKWARD_COMPATIBLE symbol above the #include line, the function will compile with to use _delay_loop_2() instead of __builtin_avr_delay_cycles().

Yes, that definitely solved the problem, but the whole point of a function was to reduce the 12 bytes / inline, but that definitely didn’t happen.

[color=green]	   text	   data	    bss	    dec	    hex	filename
	   1048	      0	      0	   1048	    418	TestApp.elf[/color]

Nothing else in my design is going to depend upon floating point, which is what DELAY_BACKWARD_COMPATIBLE did, so that’s 954 bytes of wasted overhead. Think maybe I’m going to stick to a paradigm where I know exactly what the result is going to be.

Ah, I missed that the parameter for that was a double instead of an integral type.

TightCoderEx: Yes, that definitely solved the problem, but the whole point of a function was to reduce the 12 bytes / inline, but that definitely didn't happen.

Image size is the least of your concerns in that situation...

[url=http://www.nongnu.org/avr-libc/user-manual/group__util__delay.html]Delay Functions[/url]: In order for these functions to work as intended, compiler optimizations must be enabled, and the delay time must be an expression that is a known constant at compile-time. If these requirements are not met, the resulting delay will be much longer (and basically unpredictable), and applications that otherwise do not use floating-point calculations will experience severe code bloat by the floating-point library routines linked into the application.

Think maybe I'm going to stick to a paradigm where I know exactly what the result is going to be.

That or read the documentation.

[quote author=Coding Badly date=1471280867 link=msg=2882758] That or read the documentation. [/quote] Since I started with AVR a couple of weeks ago, I knew there had to be something like this ([u]library reference[/u]), but as my focus was more toward architecture, I hadn't seriously start looking for documents on the library. This will definitely make development much less frustrating.