Arduino core for STM32 inconsistent serial port behaviour

I have a simple test project that interfaces with an UART device through the hardware serial port 2 of my STM32 Nucleo32 development kit (STM32L432).
Here is my platformio.ini:

[env:nucleo_l432kc]
platform = ststm32
board = nucleo_l432kc
framework = arduino
build_flags = 
    -D SERIAL_UART_INSTANCE=2

And here is my code:

void setup() {
  pinMode(PA3, INPUT_PULLUP);
  Serial2.begin(9600);
}

void loop() {
    Serial2.print("AT\r");
    delay(500);
    while (Serial2.available()) {
        char c = Serial2.read();
        Serial.print(c);  // Print received character
    }
  delay(5000);
}

However, I’ve run into some inconsistencies with Serial.available() between the STM32 Nucleo32 platform and Arduino AVR platforms.
I’ve hooked up my UART to ports: PA2 and PA3 on my nucleo board, alongside a logic analyzer.

The logic analyzer shows a correct response (OK\r) from the peripheral device connected to my development board. However, unlike on Arduino platforms, the incoming serial response doesn’t seem to affect the Serial2.available() return value in any way. The return value always remains 0, and so the code never reaches the loop where it’s supposed to print out the response from the serial buffer.

This same code works fine on Arduino AVR platforms.
What difference is there with this call between these two platforms?

You’re setting up your serial ports wrongly.

First of all, the default for the Nucleo L432KC is

Using USART 2 with RX = PA15 and TX = PA2 (alternate function 1). This serial is then available as the Serial object. Note that this already doesn’t match your expectation of

Further we have the list of possible UART TX/RX pins as a whole:

So, let’s step back a bit:

  1. The serial connection to the ST-Link on the board is at RX=PA15 and TX=PA2.
  2. You seem to also want to connect and external serial device with RX = PA3 and TX = PA2

This conflicts. I think you want to use the serial connection to the ST-Link indepedently to the serial connection to your external device? Then you need to choose distinct pins and UART perpiherals for this.

If you leave the original Serial in place, you can e.g. use the default pins for USART1, which is TX = PA9 and RX = PA10, with the regular Serial1 object. The pins for Serial1 can be compile-time configured as

[env:nucleo_l432kc]
platform = ststm32
board = nucleo_l432kc
framework = arduino
build_flags = 
    -D PIN_SERIAL1_TX=PA9
    -D PIN_SERIAL1_RX=PA10

and use Serial to communicate with your serial monitor (ST-Link), and Serial1 to communicate with your external serial device (an ESP8266 modem or whatever), completely independently.

void setup() {
  Serial.begin(9600); // UART connection to serial monitor
  Serial1.begin(9600); // UART connection to modem
}

void loop() {
  Serial1.print("AT\r");
  delay(500);
  while (Serial1.available()) {
      char c = Serial1.read();
      Serial.print(c);  // Print received character
  }
  delay(5000);
}

How do I ensure Serial1 is enabled in platformio.ini? Just adding the pin definitions for Serial1 doesn’t define the Serial1 object.

Right, I thought it would be enabled automatically, but you indeed have to do

build_flags = 
  -D ENABLE_HWSERIAL1
  -D PIN_SERIAL1_TX=PA9
  -D PIN_SERIAL1_RX=PA10

because of