Multiplexing Serial Input @ Runtime

Working libraries, libraries being ported and related hardware
Post Reply
kscheff
Posts: 2
Joined: Tue Jan 31, 2023 8:17 pm

Multiplexing Serial Input @ Runtime

Post by kscheff »

Hello,

I am working on a STM32F030R8/C8 design implementing 2 serial ports for 2 modbus (RS232) devices. I don't need to access both modbus devices at the same time. The F030R8/C8 has 2 USARTs but I envision to use 1 USART shared resource for the modbuses. The other USART is used for a different interface.

The issue I am facing is that I could not figure out how to switch from one RX/TX pin pair to another location. The setup uses:
1) USART1 PA10/PA9
2) USART1 PB7/PB6 (AF0)

To give you an idea, the project is based on
https://github.com/smarmengol/Modbus-Ma ... or-Arduino
https://github.com/cole8888/SRNE-Solar- ... GLE_CC.ino

I tried to switch AF0, end and re-start serial with different pin definition, using setRx() / setTx(). I either get only data from the first opened device or nothing at all. also re-opening the modbus class with the newly opened HardwareSerial device does not make it working. I can sometimes see that the TX pins starts to send data, but I don't get data back.

I suspect that I am missing some GPIO setup. I am new to the STM32 devices. Arduino experience is a bit rusty from ESP32 programming. Can someone point me to the right direction how to slave this by software? I don't want to spin the hardware.

modbus interface.jpg
modbus interface.jpg (87.77 KiB) Viewed 3105 times
kscheff
Posts: 2
Joined: Tue Jan 31, 2023 8:17 pm

Re: Multiplexing Serial Input @ Runtime

Post by kscheff »

the it thing nowadays is to ask AI for answers... so here it goes, taken from you.com:
How do I change USART Pins on the fly in STM32F030 device?

To change the USART pins on the fly on a STM32F030 device, you will need to use the GPIO Alternate Function (AF) registers. The AF registers allow you to select which pins will be used for the USART functions, and you can use them to switch the pins without having to reset the device. To do this, you will need to configure the AF registers for the required pins and then use the USART_SetPin() function to select the pins you have configured.
AN2606 Application note - STM32 microcontroller system memory ...
https://www.st.com/resource/en/applicat ... ronics.pdf
How to change the UART baud rate after running on STM32 board ...
https://stackoverflow.com/questions/572 ... tm32-board
AN4989 Application note - STM32 microcontroller debug toolbox ...
https://www.st.com/resource/en/applicat ... ronics.pdf
At least a starting point to dig into the IO configuration hell :ugeek:
User avatar
fpiSTM
Posts: 1723
Joined: Wed Dec 11, 2019 7:11 pm
Answers: 91
Location: Le Mans
Contact:

Re: Multiplexing Serial Input @ Runtime

Post by fpiSTM »

Hi,
I've tested with Nucleo F091RC which have same pin for USART1 and it works, note the pinMode() to reset the AF of pins else you will have also the data on the pins ;)
Pressing the user button will switch the pin to use with USART1.

Code: Select all

volatile bool switchUart = false;
static bool selectedPB = false; // false: PA10/PA9, true: PB7/PB6
HardwareSerial Serial1(PA10, PA9);

void switchUsart() {
  switchUart = true;
}

// the setup routine runs once when you press reset:
void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial1.begin(9600);
  while (!Serial1);
  pinMode(USER_BTN, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(USER_BTN), switchUsart, FALLING);
}

// the loop routine runs over and over again forever:
void loop() {
  if (switchUart) {
    // Serial1.flush(); --> end() already call flush
    Serial1.end();
    if (!selectedPB) {
      Serial1.setRx(PB7);
      Serial1.setTx(PB6);
      pinMode(PA10, INPUT);
      pinMode(PA9, INPUT);
    } else {
      Serial1.setRx(PA10);
      Serial1.setTx(PA9);
      pinMode(PB7, INPUT);
      pinMode(PB6, INPUT);
    }
    selectedPB = !selectedPB;
    switchUart = false;
    Serial1.begin(9600);
  }
  Serial1.printf("Hi there from %s at %i\n", selectedPB ? "PBx" : "PAx", millis());
}
Post Reply

Return to “Libraries & Hardware”