0

I would like to concatenate a string and an integer (enum) for addressing a port/pin in an embedded system project. Ports are namend:

M1_MS1_GPIO_Port
M2_MS1_GPIO_Port
M2_MS1_GPIO_Port

... and the pins are named accordingly

M1_MS1_GPIO_Pin
M2_MS1_GPIO_Pin
M2_MS1_GPIO_Pin

...

Now I would like to have a function that gets a number, and calles the GPIO_Write function. I tried something like

#define SETMS1(NUMBER) (HAL_GPIO_WritePin(M##NUMBER##_GPIO_Port ...)

void set_MS1( int M )
{
   SETMS1( M );
}

But M is not resolved as a number. Is there any way to do this?

KR51K
  • 1
  • 1
  • 2
    Does this answer your question? [How to concatenate twice with the C preprocessor and expand a macro as in "arg ## \_ ## MACRO"?](https://stackoverflow.com/questions/1489932/how-to-concatenate-twice-with-the-c-preprocessor-and-expand-a-macro-as-in-arg) – dxiv Jan 28 '21 at 07:51
  • 1
    Almost nobody posting these kind of questions on SO have managed to write a sensible abstraction layer for GPIO. So my advise is just _don't_ - and drop the ST bloatware as well. Just access the port registers directly, that's about as readable as C code gets and most attempts to add abstraction just turns the code worse. – Lundin Jan 28 '21 at 08:51
  • Agree with @Lundin, HW-related abstractions tends to make the code more portable, but also bloat. From my experience, it isn't worth it, code becoming too tricky. – Robert Jan 29 '21 at 01:43

1 Answers1

1

You can not "call" macro functions during run-time. Macros are expanded during compile-time.

Option 1:

You use a switch statement.

void set_MS1(int m)
{
    switch (m)
    {
    case 1:
        HAL_GPIO_WritePin(M1_MS1_GPIO_Port/*...*/);
        break;
    case 2:
        HAL_GPIO_WritePin(M2_MS1_GPIO_Port/*...*/);
        break;
    default:
        // if applicable, error handling
        break;
    }
}

Option 2:

You use an array and index the ports and pins. This is only possible if the port names and pin names are constants.

void set_MS1(int m)
{
    static const int ports[] =
    {
        0,
        M1_MS1_GPIO_Port,
        M2_MS1_GPIO_Port,
    };

    if (m >= 1 && m < sizeof ports / sizeof ports[0])
    {
        HAL_GPIO_WritePin(ports[m]/*...*/);
    }
    else
    {
        // if applicable, error handling
    }
}

Final note:

I'm sure there are more options. Just look at other sources and learn. We all did. Oh, and experiment!

the busybee
  • 10,755
  • 3
  • 13
  • 30