Check if two #defines define same register

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

Hi,

I am using #defines for pin manipulation to make change of used pin easier such as 

#define MyPin (1<<PB1)
#define PORTMyPin PORTB

...

PORTMyPin|=MyPin;

It works well but sometimes I don't want manipulate just one pin. For example I want to write all pins LOW except for one pin. I can do either

PORTA=0;
PORTB=MyPin;

or

PORTA=0;
PORTMyPin=MyPin;

but either will fail when I decide to move MyPin from port B to port A. I wanted to add something like

#if (PORTMyPin!=PORTB)
#error
#endif

to get error when I move the pin to another port without updating this location depends on original location. But sadly it does not work and Google did not help me. How would you solve this?

This topic has a solution.
Last Edited: Mon. Aug 27, 2018 - 07:46 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Try taking the address of the ports:

#if ((&PORTB) != (&PORTMyPin))

This should remove the * dereference in the macros.

 

--Mike

 

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

avr-mike wrote:

Try taking the address of the ports:

#if ((&PORTB) != (&PORTMyPin))

This should remove the * dereference in the macros.

 

--Mike

 

The preprocessor doesn't know anything about pointers, so this won't work.

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

Either I don't understand what you are asking or you are making it more complicated than it needs to be.

 

#define MyPIN   (1<<PB1)
#define MyPORT  PORTB

void some_func(void)
{
    // set MyPIN on MyPORT
    MyPORT |= MyPIN;

    // clear MyPIN on MyPORT
    MyPORT &= ~MyPIN;
}

 

EDIT: I'm pretty sure I don't understand what you're asking, but to change to PORTA, change the MyPORT definition from PORTB to PORTA in the example above.

Greg Muth

Portland, OR, US

Xplained/Pro/Mini Boards mostly

 

Make Xmega Great Again!

 

Last Edited: Fri. Aug 24, 2018 - 10:15 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

@avr-mike: I have also tried to stringify the result of macro expansion. But preprocessor is unable to compare strings.

 

@Greg_Muth: I want to write all pins on all ports to LOW except for MyPin which should stay HIGH. Either code in OP will work as long as MyPin stays in PORTB. But if I later decide it needs to be in PORTA and "simply change PORTMyPin definition" both will fail.

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

I use this macro to get the address of a register:

#define LOCATION_OF(r) ((uint16_t)&(r))

The compiler knows what to do with it, so instead of using the preprocessor,

you can create normal if-else statements which will likely be optimized to one

or the other branch.

 

--Mike

 

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

I thought about it. I wanted the macro as a warning that the location depends on the pin being in a specific port. It looks like it is not possible. But is it possible to do something like

if (LOCATION_OF(PORTB)!=LOCATION_OF(PORTMyPin)) {
    someFunctonGeneratingError();
}

in such way that the function get optimized away when the locations are same before generating the error? Maybe allocating 10GB of RAM/program memory would work?

My desired outcome is nothing when the locations match and compile time error when they are different.

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

If you're up for a challenge, you can probably use the C++

enable_if template for this since it inserts code only when

a boolean condition is true.

 

--Mike

 

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1
_Static_assert(&PORTB == &PORTMyPin, "Oops");

 

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

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

joeymorin wrote:

_Static_assert(&PORTB == &PORTMyPin, "Oops");

 

Thanks a lot - it led me to the solution. It did not work as written but after a bit of Googling I ended up with:

 

static_assert(&PORTB == &PORTMyPin, "Oops");

For it to work I needed to enable C++11 via "-std=c++11" flag but now it does exactly as I want!

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

Nope.  C uses _Static_assert(), not static_assert().  That's for C++.  You'll need -std=c11 or -std=gnu11.

 

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

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

I don't know pros and cons of C++ vs C so I use C++ because it is more "modern".

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

Smajdalf wrote:

I don't know pros and cons of C++ vs C so I use C++ because it is more "modern".

C and C++ are >>very<< different animals. C is not a subset of C++. Arguably C++ is worth learning for a great many reasons which I will let others expound upon. However, you should specify the standard for the language you are writing in. Don't specify c++11 and then compile as C.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]