cancel
Showing results for 
Search instead for 
Did you mean: 

STM32G031F6P UART TX DMA Problem.

ABURM
Associate III

Hi guys.

I am using STM32G031F6P MCU and i want to use UART TX with DMA in slave mode. But it is not working. RS485 line is always busy. I am using RS485 transceiver (SN65HVD37DR). If i use normal (not DMA) transmit mode, it is working. Code and cubemx project as follows;

0693W00000WITAJQA5.jpg0693W00000WITATQA5.jpg0693W00000WITCZQA5.jpg 

6 REPLIES 6
gbm
Lead III

ENABLE the request event!

ABURM
Associate III

It didn't work. Definitely not working.

Bob S
Principal

What does "RS485 line is always busy" mean? Is your CPU continuously transmitting? The more details you can provide the easier it is for people who don't know your system to help. Is your 485 bus 4-wire or 2-wire? If it is 2 wire, you will receive back what you transmit and I don't see your code accounting for that.

Which MAY explain your "always busy". HAL_UART_Transmit() returns AFTER the data has been sent. HAL_UART_Transmit_IT() and HAL_UART_Transmit_DMA() return as soon as the data has started to be sent. So with HAL_UART_Transmit_DMA() you are starting your receive before the TX data has been sent. If you have 2-wire RS485 then you WILL receive the same data you sent.

Karl Yamashita
Lead II

I wrote this whole post and lost it so re-writting it again, sigh...

What I find it people having issues with HAL_UART_Receive_xx() and HAL_UART_Transmit_xx() don't take into consideration of the HAL return status.

You'll have to re-write your code so that you can re-try receiving and transmitting if HAL returns busy.

Below code snippets should show you how I'm using error flags so I can re-try to enable interrupts or re-transmit again.

bool UART_Receive_IT_errorFlag = false;
bool UART_Transmit_IT_errorFlag = false;
 
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	Battery_Address = RX_Buff[0];
	Charge_Start = RX_Buff[1];
	// toggle pin
	RS485_Counter++;
	
	EnableUART_Receive_IT();
}
 
void EnableUART_Receive_IT(void)
{
	if(HAL_UART_Receive_IT(&huart1, RX_Buff, 2) != HAL_OK)
	{
		UART_Receive_IT_errorFlag = true; // failed to enable interrupt so need to re-enable in polling routine.
	}
}
 
void UART_Transmit(void)
{
	if(HAL_UART_Transmit_IT(&huart, TX_Buff, 1) != HAL_OK)
	{
		UART_Transmit_IT_errorFlag = true;
	}
}
 
// main loop, usually called from main while loop
void PollingRoutine(void)
{
	CheckBatteryStatus();
	CheckUART_Receive_IT_errorFlag();
	CheckUART_Transmit_IT_ErrorFlag();
}
 
// polling for battery message
void CheckBatteryStatus(void)
{
	if(Battery_Address == BATTERY_BUS_ADDRESS)
	{
		Battery_Address == 0; // do we need to clear? 
		TX_Buff[0] = RS485_Counter;
		UART_Transmit();
	}
}
 
void CheckUART_Receive_IT_errorFlag(void)
{
	if(UART_Receive_IT_errorFlag)
	{
		UART_Receive_IT_errorFlag = 0;
		EnableUART_Receive_IT(); // try again to enable interrupt
	}
}
 
void CheckUART_Transmit_IT_ErrorFlag(void)
{
	if(UART_Transmit_IT_errorFlag)
	{
		UART_Transmit_IT_errorFlag = 0;
		UART_Transmit(); // previous transmit failed, so re-transmit again
	}
}

If you find my answers useful, click the accept button so that way others can see the solution.
ABURM
Associate III

Hi guys.

Bob S., I am using 2 MCU. STM32G431 (master) and STM32G031 (slave). I am using 4 wire bus RS485. Master is sending data every 10ms and slave responds. I don't continuously transmitting. But "HAL_UART_Transmit_DMA" keeps returning with "HAL_BUSY". I've watched a lot of videos, all basically doing the same inits. The configuration is not too complicated. Enable UART, set baud rate, activate DMA for TX, activate RX interrupt, write RX callback program and start. Thats all. But i still don't understand why it's not working.

Karl Yamashita, thanks mate. I dont use "HAL_UART_Transmit_IT" but i will try this.

ABURM
Associate III

Hi Guys.

I still haven't been able to solve the problem. "HAL_UART_Transmit_DMA" is not working in "Normal" DMA mode. When I start the system, it sends only 1 byte of data. Then "if (huart->gState == HAL_UART_STATE_READY)" gState keeps getting 0x21 and returns with busy without sending.

0693W00000WJL8gQAH.jpgI am doing everything right. Could it be a problem with Cubemx?