I am using an STM32F303RE Nucleo board connected to my own PCB to do RS-232 serial communications, and I can't figure out why this code doesn't work in certain circumstances.
I'm using HAL functions (HAL_UART_Transmit and HAL_UART_Receive) for my communications, using the USB connector on the Nucleo for usart2 and a 9-pin RS-232 serial port on my own PCB for usart1. Both usart configurations have been set up by HAL.
When I communicate (using a Putty terminal) using only the USB connection (usart2), the code works perfectly. When I use usart1 for Tx and usart2 for Rx, still no problems. When I use usart2 for Tx and usart1 for Rx, it also works fine.
The problem is when I try to use usart1 (which is my RS-232 cable) for both Tx and Rx. My processor transmits the initial data fine, but when it's time to receive the data, nothing makes it into the received data register. I have some code to simply echo back any received data on the transmit line, and nothing comes through in this configuration. Once again - the code works fine in every other configuration of usart1 and usart2 for both sending and receiving, but no Rx when I try to do it all on usart1 (RS-232)
Here is the relevant section of code I'm using. COMTYPE is set to either &huart1 or &huart2 (in the problem case, it's set to &huart1)
Main loop (received data used for switch statement in menu system):
HAL_UART_Transmit(COMTYPE, prompt, sizeof(prompt), TIMEOUT);
cmd_size = UART_getstr(command);
cmd_num = parse_menu_input(command, cmd_size);
converted = (uint8_t)cmd_num + '0';
// error parsing command for menu selection
if(cmd_num == -1){
HAL_UART_Transmit(COMTYPE, parse_error, sizeof(parse_error), TIMEOUT);
}
else{
menu_switch(cmd_num);
}
}
Function containing Rx function and echo back (Tx) function:
int UART_getstr(uint8_t* command){
int x = 0; // tracker for buffer pointer
int chars = 0;
uint8_t buffer; // single char storage for UART receive
while(1){
// get single char from UART_Receive
HAL_UART_Receive(COMTYPE, &buffer, 1, HAL_MAX_DELAY);
// echo back function
HAL_UART_Transmit(COMTYPE, &buffer, sizeof(char), TIMEOUT);
// write value of received char to "command" array
command[x] = buffer;
// increment the number of valid chars
chars++;
// stop adding chars to command after [Enter] pressed
if(command[x] == '\r'){
chars--;
break;
}
// correct for storing DELETE as char in buffer
if(command[x] == 0x7F){
command -= 1;
chars -= 2;
}
else{
x++;
}
}
command[x] = '\0';
// return length of command buffer
return chars; }
I don't understand why the exact same code would work in 3 out of 4 circumstances, but not the 4th. I've checked the serial cable, and the rest of the RS-232 hardware functions fine when being used ONLY for Tx or ONLY for Rx. But the Rx seems blocked by something when trying to use RS-232 for both.
EDIT: Adding UART initialization code (generated by HAL):
/* USART1 init function */
static void MX_USART1_UART_Init(void)
{
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
/* USART2 init function */
static void MX_USART2_UART_Init(void)
{
huart2.Instance = USART2;
huart2.Init.BaudRate = 115200;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart2) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}