Error while trying to create macro for GPIO configuration

Go To Last Post
10 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So I wanted to create some easier to read functions for assigning pins and then setting and clearing them. I tried this:

 

#define GPIO_CONFIGURE_PIN(name, port, bit) \
__inline void make_##name##_input()        {DDR##port## &= ~(1 << bit)} \
__inline void make_##name##_output()       {DDR##port## |= (1 << bit);} \
__inline void ##name##_set()               {PORT##port## |= (1 << bit);} \
__inline void ##name##_clr()               {PORT##port## &= ~(1 << bit);} \
__inline uint8_t ##name##_get()            {return(PIN##port## & (1 << bit));}

but it doesn't work. I saw at some places that setting optimization at something OTHER than -O0 solved this issue for them, but it doesn't work for me in Atmel Studio 7. I've set the optimization to -Os, -O1 but I get the same following error:

 

pasting "DDRD" and = does not give a valid preprocessing token

I'm sure I'm doing something quite stupid here but I can't put my finger on it.

 

I tried doing straight up:

 

#define GPIO_CONFIGURE_PIN(name, port, bit) \
inline void make_##name##_input()        {DDRD = 0x00;}

and this works! However, using the 'port' variable by doing ##port## is failing.

 

I'd appreciate your help, thank you!

This topic has a solution.
Last Edited: Wed. Jan 3, 2018 - 11:33 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Show how you are invoking these macros.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Later in the same file, I'm calling

 

GPIO_CONFIGURE_PIN(ECHO_PIN, D, 3);

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok so now you need to show what ECHO_PIN is. This would go easier if you simply post a complete, standalone test program.

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think you are using ##var## in places where you should just be using ##var
https://gcc.gnu.org/onlinedocs/cpp/Concatenation.html

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well ECHO_PIN is just the name, so that macro should result in 5 methods with names

 

void make_ECHO_PIN_input(){...}
void make_ECHO_PIN_output(){...}
...

etc. getting created when it's called, yes? Regardless, here's the standalone:

 

#include <avr/io.h>
#include <util/delay.h>
#include <inttypes.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>

#define GPIO_CONFIGURE_PIN(name, port, bit) \
__inline void make_##name##_input()        {DDR##port## &= ~(1 << bit);} \
__inline void make_##name##_output()       {DDR##port## |= (1 << bit);} \
__inline void ##name##_set()               {PORT##port## |= (1 << bit);} \
__inline void ##name##_clr()               {PORT##port## &= ~(1 << bit);} \
__inline uint8_t ##name##_get()            {return(PIN##port## & (1 << bit));}

GPIO_CONFIGURE_PIN(ECHO_PIN, D, 3);

int main(void){
    make_ECHO_PIN_output();
    ECHO_PIN_set();
    while(1){
        // Do nothing
    }
return(0);
}

I realized that after pasting DDRD, it's not searching avr/iom8a.h for definition of DDRD though, which is weird.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

THIS HELPS!

 

#define GPIO_CONFIGURE_PIN(name, port, bit) \
__inline void make_##name##_input()        {DDR##port &= ~(1 << bit);} \
__inline void make_##name##_output()       {DDR##port |= (1 << bit);} \
__inline void ##name##_set()               {PORT##port |= (1 << bit);} \
__inline void ##name##_clr()               {PORT##port &= ~(1 << bit);} \
__inline uint8_t ##name##_get()            {return(PIN##port & (1 << bit));}

has done away with the compilation errors, though the macro isn't working as expected, but this helps a lot. Thanks!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Whenever you're getting trouble with preprocessor stuff, the thing to do is to look at the preprocessor output.

 

http://www.8052.com/forum/read/2...

 

For GCC, use -E or -save-temps

 

https://gcc.gnu.org/onlinedocs/gcc/Overall-Options.html#Overall-Options

 

https://gcc.gnu.org/onlinedocs/gcc/Developer-Options.html#Developer-Options

 

https://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html

 

#PreprocessorDebugging

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yeah, I was using the concat operator (**) incorrectly, as was correctly pointed out, everything is hunky dory now, thread can be marked solved, thanks a lot guys!

Last Edited: Wed. Jan 3, 2018 - 11:42 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

lemonickous wrote:
thread can be marked solved

That's something that you have to do yourself: http://www.avrfreaks.net/comment...

 

EDIT

 

never mind - it's done.

Last Edited: Wed. Jan 3, 2018 - 11:52 AM