cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H753: Can't receive the data the controller is sending

jhi
Senior

I'm using the UART (USART5) with RS485 and I have enabled the read to be on also when sending. I need to read back the data that was sent to see if it is correct. The problem is, that I do not receive what was sent. But if I send the same data from other device (without changing any code), I will receive the data. So the receive works, but not the same time with sending.

Initialization - FIFO is also enabled.

 

BaudRate = PARALLEL_BAUD_RATE;
DataWidth = LL_USART_DATAWIDTH_8B;
Parity = LL_USART_PARITY_NONE;
StopBits = LL_USART_STOPBITS_1;
HardwareFlowControl = LL_USART_HWCONTROL_NONE;
OverSampling = LL_USART_OVERSAMPLING_16;
PrescalerValue = LL_USART_PRESCALER_DIV1;
TransferDirection = LL_USART_DIRECTION_TX_RX;

 

And data sending is done with LL_USART_TransmitData8. The half-duplex is not enabled.

What could block the receive when sending?

1 ACCEPTED SOLUTION

Accepted Solutions
TDK
Guru

It sounds like your transmission code is getting in the way of your reception code. You haven't shown much code so it's difficult to determine what is going on exactly.

If you think it's a hardware issue, post a short compilable code which reproduces the issue.

If you feel a post has answered your question, please click "Accept as Solution".

View solution in original post

38 REPLIES 38
AScha.3
Chief II

for rs485 yo use a symm driver chip, that has rx/tx switch input - right?

read manual of this rs485 driver chip, usually they switch off rx, when you set it to transmit tx.

If you feel a post has answered your question, please click "Accept as Solution".

I guess you didn’t read what I wrote. I said that I enabled the read path when sending. I can also see that data on RX-pin with logic analyzer, so the data is there. It just doesn’t end up to FIFO-buffer or to RDR. But if the same data is sent from outside then the data is received.

TDK
Guru

Are we just guessing? Probably a bug in the code. Perhaps using blocking mode incorrectly or making incorrect assumptions or a logic flow error.

If you feel a post has answered your question, please click "Accept as Solution".
jhi
Senior

Yes, probably a bug in the code. I would like to know which bug could cause this behavior. UART with FIFO mode with interrupts. Even if it was in blocking mode, I would see the bytes in FIFO afterwards or RDR would change. I'm  only sending 4 bytes, so those will fit in FIFO. And as I wrote, the receive (and sending) works when communicating with second device.  Only that I can't receive own bytes. For this test, the device is only one sending and the TX and RX are monitored with logic analyzer. Following is a simplified code for initialization + send/receive.

RXFNE stays 0 the whole time.

Configuration

// Initialize UART.
    LL_USART_Init(UART5, &ptConfiguration->tUartConfiguration);
    LL_USART_ConfigAsyncMode(UART5);
    LL_USART_EnableIT_IDLE(UART5);
    LL_USART_EnableIT_ERROR(UART5);
    LL_USART_EnableIT_PE(UART5);

    // Enable FIFO.
    LL_USART_SetTXFIFOThreshold(UART5, LL_USART_FIFOTHRESHOLD_1_8);
    LL_USART_SetRXFIFOThreshold(UART5, LL_USART_FIFOTHRESHOLD_1_2);
    LL_USART_EnableFIFO(UART5);
    LL_USART_EnableIT_RXFT(UART5);  // Enable RX FIFO threshold interrupt.

    HAL_NVIC_SetPriority(UART5_IRQn, 9, 0);
    HAL_NVIC_EnableIRQ(UART5_IRQn);

    LL_USART_Enable(UART5);  // Enable UART.

Sending:

// Send Data
LL_USART_TransmitData8(UART5, 0xAA);
LL_USART_TransmitData8(UART5, 0x55);
LL_USART_TransmitData8(UART5, 0xAA);
LL_USART_TransmitData8(UART5, 0x55);

Receive:

void UART5_IRQHandler(void)
{
     if ((LL_USART_IsActiveFlag_IDLE(UART5) > 0) || (LL_USART_IsActiveFlag_RXFT(UART5) > 0))
    {
        LL_USART_ClearFlag_IDLE(UART5);  // Clear IDLE line flag.

        while (LL_USART_IsActiveFlag_RXNE_RXFNE(UART5) > 0)
        {
            -- Parse data.
        }
    }
}

 

We use the THVD1410DR 485 chip to interface to our USART. In this setup(there are both Rx and Tx control lines to the chip) you can only Receive or Transmit, not both at the same time. So our driver code will have the Rx on and wait for data to come in. When we want to transmit we will turn off the Rx and turn on the Tx.

TDK
Guru

Be aware reading RDR in the debugger will actually remove the byte from the FIFO. So if that's what you're doing, that is the problem.

> LL_USART_SetRXFIFOThreshold(UART5, LL_USART_FIFOTHRESHOLD_1_2);

> LL_USART_EnableIT_RXFT(UART5);

You enable the RXFT interrupt, so the code won't interrupt until the FIFO has filled enough to reach the threshold. This allows the possibility of bytes in the buffer, but interrupt not triggering. Perhaps what you want, perhaps not. Also introduces the possibility of reading x+1 bytes if one happens to come in during the interrupt handler.

If you feel a post has answered your question, please click "Accept as Solution".

The idle interrupt should handle the case when I sent only 4 or less bytes. Also I don’t actively read the RDR register. The RXFN (Rx fifo not empty) stays also 0, so not receiving any bytes when I stop the debugger.

We have separate TX/RX enable pins and as I wrote I can see the bytes on RX pin with logic analyzer.

When you say "I said that I enabled the read path when sending", this confuses me. Does your 485 chip allow that? On our 485 interface chip you can only do one direction at a time. So if we enabled the read line(active low) while transmitting, the data would be lost. I did not think 485 interfaces could be synchronous.

Capture2.JPG