Home > Back-end >  Unusual syntax for a #define directive
Unusual syntax for a #define directive

Time:11-22

In a sketch I found the following instruction:

#define USB_CONFIG_POWER_MA(mA)                ((mA)/2)

And I want to be sure not to make any mistake: why are there two "mA"?

Which one should I replace by a value given that in a previous version of this code one just needed this line:

#define USB_CONFIG_POWER_MA(20)

to set the max to 20mA but now it gives a compilation error:

/home/henry/arduino-1.8.16/hardware/arduino/avr/cores/arduino/USBCore.h:99:29: error: "20" may not appear in macro parameter list

This seems to be the solution as it gives me no compilation error

#define USB_CONFIG_POWER_MA(mA) ((40)/2)

but again i want to be sure!

CodePudding user response:

With

#define USB_CONFIG_POWER_MA(mA)                ((mA)/2)

you define a function-like macro, where mA is the argument to the macro.

You can use it like:

printf("USB power for 20 mA is %d\n", USB_CONFIG_POWER_MA(20));

The preprocessor will replace the macro as such:

printf("USB power for 20 mA is %d\n", ((20)/2));

If you always want the macro to be replaced by the value 20 then either define a function-like macro where you ignore the argument (this will be backward compatible):

#define USB_CONFIG_POWER_MA(mA)                20

Or define a macro without arguments (this will require you to change all macro invocations):

#define USB_CONFIG_POWER_MA                    20

The latter, without arguments, is often used in C as a way to define symbolic constants, and as such makes more sense in your use-case.


Another possible solution is to use the original macro definition, but use a second macro to define the value to pass as argument:

#define USB_CONFIG_POWER_MA(mA)                ((mA)/2)
#define USB_CONFIG_DEFAULT_POWER               40

// ...

printf("USB power for 20 mA is %d\n",
       USB_CONFIG_POWER_MA(USB_CONFIG_DEFAULT_POWER));

This will both be backward compatible and allow other values to be used together with the original USB_CONFIG_POWER_MA macro.

CodePudding user response:

to set the max to 20mA

You shouldn't change the definition of the USB_CONFIG_POWER_MA macro, you should change the value that's passed to it where it's used. The macro you're talking about comes from USBCore.h:

#define D_CONFIG(_totalLength,_interfaces) \
    { 9, 2, _totalLength,_interfaces, 1, 0, \
      USB_CONFIG_BUS_POWERED | USB_CONFIG_REMOTE_WAKEUP, \
      USB_CONFIG_POWER_MA(USB_CONFIG_POWER) }

You can see the macro being used to set the configured power here. Looking deeper, the definition of USB_CONFIG_POWER is:

#ifndef USB_CONFIG_POWER
  #define USB_CONFIG_POWER      (500)
#endif

So USB_CONFIG_POWER only gets defined if it isn't already defined. That means that all you need to do to set the power that your Arduino sketch requests is to make sure that you define USB_CONFIG_POWER yourself before you include the USBCore.h file. Put a line like:

#define USB_CONFIG_POWER        (20)

in your code before you include that file, and you should be good to go.

  • Related