2026-05-11 7:19 AM
The STM32F415 transmit and receive lines are connected to the MAX3232 chip. The board also contains chips to control LEDs and read tokens, which are controlled by the STM32F415, and those functionalities work, but I am having issues with the RS-232 communication. I get nothing on the receiving end. When I hook up a scope to the transmit line for UART4 (pin 51) on the STM32 chip, it is always high (3.3 V) and nothing is transmitted. What could cause this issue?
Solved! Go to Solution.
2026-05-11 8:49 AM - edited 2026-05-11 8:50 AM
@mƎALLEm wrote:I suggest you at first to use HAL/CubeMx to start your project and validate your hardware.
+1
@tgomulin As suggested earlier, start with something that just validates the UART - nothing else.
TX and RX here match the datasheet:
https://www.st.com/resource/en/datasheet/stm32f415rg.pdf#page=59
But this is wrong:
RX is an input to the STM32 - so should be driven by receiver R1OUT;
TX is an output from the STM32 - so should drive transmitter T1IN.
2026-05-11 7:26 AM
Welcome to the forum.
Please see How to write your question to maximize your chances to find a solution for best results.
Have you used a debugger to see if your UART code is actually being executed?
Is this a custom board? If so, please post the schematic.
If it is, have you tried your software on an ST board?
Please post a minimal but complete code example which illustrates the example - just a simple UART transmit.
2026-05-11 8:32 AM
I have used STM32CubeIDE to step through the code, and the UART transmit code seems to be executed and returns HAL_OK when I had it returning a value.
This is a custom board. It has not been tried on an ST board. Below is the subset of the schematic with the STM32 and MAX3232 chips.
Parts of this code including the SystemClockConfig are reused from another group. I didn't do the individual bit setting in that function. I'm wondering if something is missing from that, or if the Tx/Rx lines are swapped somewhere, or there is something else wrong. I ended up with this board, and both hardware people who took the old design and modified it to this have left the company.
#include <dev_lofo.h>
#include <dev_lp5024.h>
#include <dev_tca9548.h>
#include <dev_eeprom.h>
#include <stdint.h>
#include "main.h"
#include "stm32f4_Config.h"
#include "CommandManager.h"
#include "rs232_driver.h"
#include "RS232Manager.h"
#include "stm32f4xx_hal_rcc.h"
#include "TokenIndicator.h"
EEPROM_Config eepromConfig;
Command cmdT;
unsigned char buff[64];
void SystemClockConfig();
void ConfigureGPIO(void);
UART_HandleTypeDef huart1;
// Token status change function
void LOFO_OnChange(unsigned char channel, unsigned char stateOld, unsigned char stateNew);
int main(void)
{
// Setup mcu clock configuration
SystemClockConfig();
SystemInit();
// Configure system GPIO
ConfigureGPIO();
// Configure I2C2 Bus
I2C2_Init(GPIO_PORT_B, GPIO_P11, GPIO_PORT_B, GPIO_P10, I2C_CLOCK_100KHZ);
// Configure LED control modules
LP5024_Init(LP5024_ID | (LP5024_ADDRESS));
LP5024_Init(LP5024_ID | (LP5024_ADDRESS +1));
// Configure I2C Multiplexer
TCA9548_Init();
// Initialize the LOFO pin monitor.
LOFO_Init();
// The following config initializes the reader to read IST 64K tokens. This can be reconfigured via a command to the command manager.
eepromConfig.PageBuffer = 32;
eepromConfig.Device_ID = 0x50;
eepromConfig.Device_Address = 0x00;
eepromConfig.Address_Length = 2;
eepromConfig.Capacity = 8192;
// Initialize the EEPROM module.
EEPROM_Init(eepromConfig);
TokenIndicatorInitialize();
// Register the callback function for Token Change events
LOFO_RegisterCallback(LOFO_OnChange);
// Initialize the RS232 device
RS232_Init(&huart1);
STATUS_LED = 1;
SysTick_Delay(1000);
STATUS_LED = 0;
SysTick_Delay(1000);
STATUS_LED = 1;
SysTick_Delay(1000);
STATUS_LED = 0;
SysTick_Delay(1000);
int startAddr = LP5024_ID | (LP5024_ADDRESS);
// Turn all LEDS on and off to start with
for (int chip = 0; chip < 2; ++chip)
{
for (int i = 0; i < 8; i++)
{
(void) LP5024_LED_Color_Set((startAddr+chip), i, 0, 255, 0);
SysTick_Delay(1000);
(void) LP5024_LED_Color_Set((startAddr+chip), i, 0, 0, 0);
SysTick_Delay(1000);
}
}
uint8_t msg[] = "Hello RS232!\r\n";
HAL_UART_Transmit(&huart1, msg, sizeof(msg)-1, HAL_MAX_DELAY);
SysTick_Delay(1000);
}
void SystemClockConfig()
{
RCC_CTL->CR.HSEON = 1;
while(!RCC_CTL->CR.HSERDY){}
// Turn on APB1ENR power
RCC_CTL->APB1ENR.PWREN = 1;
while(RCC_CTL->APB1ENR.PWREN != 1){}
PWR_CTL->CR.Bits.VOS = 0b11;
// Enable Instruction Cache
FLASH_CTL->ACR.Bits.ICEN = 1;
// Enable Data Cache
FLASH_CTL->ACR.Bits.DCEN = 1;
// Enable Prefetch Cache
FLASH_CTL->ACR.Bits.PRFTEN = 1;
// Configure flash to 5 wait states
FLASH_CTL->ACR.Bits.LATENCY = 5;
// Configure AHB Prescaler
RCC_CTL->CFGR.HPRE = RCC_CFGR_HPRE_DIV1;
// Configure APB1 Prescaler
RCC_CTL->CFGR.PPRE1 = 0b101;
// Configure APB2 Prescaler
RCC_CTL->CFGR.PPRE2 = 0b100;
// Configure PLLM
RCC_CTL->PLLCFGR.PLLM = 16;
// Configure PLLN
RCC_CTL->PLLCFGR.PLLN = 336;
// Configure PLLP
RCC_CTL->PLLCFGR.PLLP = RCC_PLLCFGR_PLLP_DIV2;
// Configure PLLQ
RCC_CTL->PLLCFGR.PLLQ = 7;
// Configure PLL Source Select
RCC_CTL->PLLCFGR.PLLsrc=1;
while(RCC_CTL->PLLCFGR.PLLSRC != 1){}
RCC_CTL->CR.PLLON = 1;
while(!RCC_CTL->CR.PLLRDY){}
// Configure System clock switch
RCC_CTL->CFGR.SW = RCC_CFGR_SW_PLL;
while(!(RCC_CTL->CFGR.SWS == 2)){}
}
void ConfigureGPIO(void)
{
// Configure Port A
GPIO_Port_Config(GpioPort.A, Enable);
GPIOA_MODE->B0 = GpioMode.INPUT; // LOFO Port 1
GPIOA_MODE->B1 = GpioMode.INPUT; // LOFO Port 2
GPIOA_MODE->B2 = GpioMode.INPUT; // LOFO Port 3
GPIOA_MODE->B3 = GpioMode.INPUT; // LOFO Port 4
GPIOA_MODE->B4 = GpioMode.INPUT; // LOFO Port 5
GPIOA_MODE->B5 = GpioMode.INPUT; // LOFO Port 6
GPIOA_MODE->B6 = GpioMode.INPUT; // LOFO Port 7
GPIOA_MODE->B7 = GpioMode.INPUT; // LOFO Port 8
GPIOA_MODE->B8 = GpioMode.INPUT; // LOFO Port 9
// Configure Port B
GPIO_Port_Config(GpioPort.B, Enable);
GPIOB_MODE->B1 = GpioMode.INPUT; // LOFO Port 10
GPIOB_MODE->B2 = GpioMode.INPUT; // LOFO Port 11
GPIOB_MODE->B5 = GpioMode.INPUT; // LOFO Port 12
GPIOB_MODE->B6 = GpioMode.INPUT; // LOFO Port 13
GPIOB_MODE->B7 = GpioMode.INPUT; // LOFO Port 14
GPIOB_MODE->B8 = GpioMode.INPUT; // LOFO Port 15
GPIOB_MODE->B9 = GpioMode.INPUT; // LOFO Port 16
// Configure Port C
GPIO_Port_Config(GpioPort.C, Enable);
GPIOC_MODE->B12 = GpioMode.OUTPUT; // Enable Status LED pin
GPIOC_MODE->B13 = GpioMode.OUTPUT; // Enable Link LED pin
/* Clock Enables */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_UART4_CLK_ENABLE();
}
// Hopefully we never end up here but if we do then it means the device had an unrecoverable error.
void Error_Handler(void)
{
//__disable_irq();
while (1)
{
STATUS_LED = 1;
SysTick_Delay(1000);
STATUS_LED = 0;
SysTick_Delay(1000);
}
}
void LOFO_OnChange(unsigned char channel, unsigned char stateOld, unsigned char stateNew)
{
CommandReset(&cmdT);
cmdT.commandID = 0xFF;
cmdT.requestID[0] = 0xFF;
cmdT.requestID[1] = 0xFF;
cmdT.requestID[2] = 0xFF;
cmdT.action = 0x01;
cmdT.status = 0x01;
cmdT.position = channel;
cmdT.packetLen = 0x02;
cmdT.packetLenHighByte = 0x00;
cmdT.packetLenLowByte = 0x02;
cmdT.packetData[0] = stateNew; /* This is the new state of the token at position {channel}*/
cmdT.packetData[1] = LOFO_GetInsertionStatus(); /* This is the state of all channels */
CommandEnqueue(cmdT);
}
2026-05-11 8:40 AM
Hello,
I suggest you at first to use HAL/CubeMx to start your project and validate your hardware.
If all is ok you can move forward with the direct access to the registers.
Starting with direct access to the registers spreads confusion.
So please validate your hardware first and inspire from the HAL implementation for the direct access to the registers..
2026-05-11 8:49 AM - edited 2026-05-11 8:50 AM
@mƎALLEm wrote:I suggest you at first to use HAL/CubeMx to start your project and validate your hardware.
+1
@tgomulin As suggested earlier, start with something that just validates the UART - nothing else.
TX and RX here match the datasheet:
https://www.st.com/resource/en/datasheet/stm32f415rg.pdf#page=59
But this is wrong:
RX is an input to the STM32 - so should be driven by receiver R1OUT;
TX is an output from the STM32 - so should drive transmitter T1IN.
2026-05-11 10:32 AM
Thanks for identifying that. We'll work on getting a new board. Thanks!
2026-05-11 11:20 AM
Meanwhile, I suggest that you prototype this on an ST board.
Then you will have something known to work when the new board arrives.
Also something that others can reproduce if you run into issues.
2026-05-11 11:33 AM
What ST board would you recommend? This is not really my realm. Thanks!