Variant.h pin definitions unclear?

Post here all questions related to STM32 core if you can't find a relevant section!
Post Reply
MGeo
Posts: 38
Joined: Thu Dec 19, 2019 10:29 am
Answers: 2

Variant.h pin definitions unclear?

Post by MGeo »

I'm running into trouble with invalid digital pin definition values from variant.h on a Nucleo-F401RE. I am using PA4 as a digital output pin. PA4 is returned as a uint value of 55, when I am expecting some value below NUM_DIGITAL_PINS of 52. Looking at variant.h it is now defined as A2. It is a mystery to me and my search as to where A2 is being defined. For the life of me I can not locate where A2 is being defined. Could anyone help in understanding where A2 definition is coming from?

Also, this level of multiple #define redirection is new and somewhat confusing to to me, I'm left wondering if this is a good and more importantly maintainable implementation for variant files?

Thanks,
George

Nucleo-F401RE variant.h https://github.com/stm32duino/Arduino_C ... iant.h#L83

Code: Select all

/*----------------------------------------------------------------------------
 *        Pins
 *----------------------------------------------------------------------------*/

#define PA3   0
#define PA2   1
#define PA10  2
#define PB3   3
#define PB5   4
#define PB4   5
#define PB10  6
#define PA8   7
#define PA9   8
#define PC7   9
#define PB6   10
#define PA7   A6
#define PA6   A7
#define PA5   A8 // LD2
#define PB9   14
#define PB8   15
// ST Morpho
// CN7 Left Side
#define PC10  16
#define PC12  17
// 18 is NC - BOOT0
#define PA13  19 // SWD
#define PA14  20 // SWD
#define PA15  21
#define PB7   22
#define PC13  23 // USER_BTN
#define PC14  24 // NC by default SB49 opened
#define PC15  25 // NC by default SB48 opened
#define PH0   26 // NC by default SB55 opened
#define PH1   27
#define PC2   A9
#define PC3   A10
// CN7 Right Side
#define PC11  30
#define PD2   31
// CN10 Left Side
#define PC9   32
// CN10 Right side
#define PC8   33
#define PC6   34
#define PC5   A11
#define PA12  36
#define PA11  37
#define PB12  38
// 39 is NC
#define PB2   40
#define PB1   A12
#define PB15  42
#define PB14  43
#define PB13  44
#define PC4   A13
#define PA0   A0
#define PA1   A1
#define PA4   A2
#define PB0   A3
#define PC1   A4
#define PC0   A5
mrburnette
Posts: 633
Joined: Thu Dec 19, 2019 1:23 am
Answers: 7

Re: Variant.h pin definitions unclear?

Post by mrburnette »

The variant file you linked to defines A2

Code: Select all

#define PA4  A2
... which just means if someone codes A2 (Arduino-centric) as a pin_name the preprocessor translates that to PA4 (proper name)
STM-401.png
STM-401.png (71.65 KiB) Viewed 5451 times


Have you followed the wiki on building a variant? It is a good guide to how files are "glued" together.

https://github.com/stm32duino/wiki/wiki ... nt-(board)

As far as maintainability, STM is going a (IMO) fantastic job ... it is a huge effort and occasionally a bug does get into the soup.
MGeo
Posts: 38
Joined: Thu Dec 19, 2019 10:29 am
Answers: 2

Re: Variant.h pin definitions unclear?

Post by MGeo »

mrburnette wrote: Sat Oct 24, 2020 11:39 pm The variant file you linked to defines A2

Code: Select all

#define PA4  A2
Umm, thanks. I think you got it backwards. The variant file defines PA4 as A2. The definition of A2 is the item in question. Also, this is regarding an existing Nucleo variant.

Thanks,
George
mrburnette
Posts: 633
Joined: Thu Dec 19, 2019 1:23 am
Answers: 7

Re: Variant.h pin definitions unclear?

Post by mrburnette »

:oops:
MGeo
Posts: 38
Joined: Thu Dec 19, 2019 10:29 am
Answers: 2

Re: Variant.h pin definitions unclear?

Post by MGeo »

Apologies, I should have clarified why I am raising the question. I am working with an SPI device with CS pin as PA4. I call to SPI.begin with (optional) PA4 pin as a parameter.

Code: Select all

  // initialize SPI:
  SPI.begin(PA4);

SPI.cpp has numerous checks to test if _pin argument is greater than NUM_DIGITAL_PINS such as:
https://github.com/stm32duino/Arduino_C ... PI.cpp#L64
and
https://github.com/stm32duino/Arduino_C ... I.cpp#L263
If this test fails the begin method simply returns with no action or warning, not really the best of practice.

Nucleo-F401RE variant.h defines NUM_DIGITAL_PINS as 52. So far so good.
https://github.com/stm32duino/Arduino_C ... iant.h#L89

Also in variant.h, PA4 gets defined as A2. I've so far been unable to track down where A2 is actually defined, but in a debugger PA4 is assigned 55, which makes sense if we start counting Analog up from NUM_DIGITAL_PINS. Defining PA4 as A2 instead of as a number (was 48) appears to be a recent change (https://github.com/stm32duino/Arduino_C ... f2e3496390).

SPI library also uses NUM_DIGITAL_PINS to signal that the CS pin will be controlled by the library user in software, here:
https://github.com/stm32duino/Arduino_C ... /SPI.h#L57

I'm thinking the change might have broken the SPI implementation? I'm left wondering what else may be affected by this change.

Separately, MISRA C suggests that macros used in preprocessor directives should be defined before use. It is not clear from the unit file if and where A2 is previously defined, hence my maintainability comment.


Thanks,
George
MGeo
Posts: 38
Joined: Thu Dec 19, 2019 10:29 am
Answers: 2

Re: Variant.h pin definitions unclear?

Post by MGeo »

A quick test sketch:

Code: Select all

  uint32_t PA_4_PinNum = pinNametoDigitalPin(PA_4);
  PinName A2_PinName = analogInputToPinName(A2);
  PinName PA4_PinName = analogInputToPinName(PA4);
  
  Serial.println(PA_4_PinNum);
  Serial.println(A2_PinName);
  Serial.println(PA4_PinName);
Prints out:

Code: Select all

48
4
4
PA_4 then gives 48, not 55.
User avatar
fpiSTM
Posts: 1738
Joined: Wed Dec 11, 2019 7:11 pm
Answers: 91
Location: Le Mans
Contact:

Re: Variant.h pin definitions unclear?

Post by fpiSTM »

Hi @MGeo

You're right there is an issue with SPI using the PYn pin number notation when it is an analog pin.

It is part of the rework done to be able to define the analog pins in a non contiguous way.
The pin number PA4 is well defined as A2 as it is an analog pin.
And A2 is well defined as 55. This way it is possible to recover the digital pin index thanks the analogInputPin array.
Using analogInputToDigitalPin() will give 48 as expected.

As a warkaround simply use the number or the analogInputToDigitalPin() macro
User avatar
fpiSTM
Posts: 1738
Joined: Wed Dec 11, 2019 7:11 pm
Answers: 91
Location: Le Mans
Contact:

Re: Variant.h pin definitions unclear?

Post by fpiSTM »

PR to fix this issue available here https://github.com/stm32duino/Arduino_C ... /pull/1219

If you can test it, thanks.
MGeo
Posts: 38
Joined: Thu Dec 19, 2019 10:29 am
Answers: 2

Re: Variant.h pin definitions unclear?

Post by MGeo »

Wow, that was fast! Seems to be working for me.

I sounds like I need to study up on pin number (PA4) vs PinName (PA_4) form to better understand which to use when. Up until now I've always been using pin number form and things have worked as expected, but I can see advantages of PinName enum.

Thanks again,
George
User avatar
fpiSTM
Posts: 1738
Joined: Wed Dec 11, 2019 7:11 pm
Answers: 91
Location: Le Mans
Contact:

Re: Variant.h pin definitions unclear?

Post by fpiSTM »

Arduino API use pin number Dx, x, Ax or PYn then it is converted to PinName which are a combination of GPIO port and GPIO pin for HAL/LL.
Some advanced API uses PinName to be faster (avoid the conversion from pin number to PinName).

I'm curently, reworking all the variants and also manage the remap pins(G0) and dual pads pin (H7). I also remove the need to comment alternative pins in the peripheralPins.cpp and user will be able to use the one he want using an PYn_ALTx name.

Finally I will also document all of this (as it is done for MBed: https://os.mbed.com/teams/ST/wiki/pinout_labels)
Post Reply

Return to “General discussion”