I'm currently working on a problem with RS485 communication where my Modbus RTU slave device is only able to process every other command due to corruption in the UART's Rx buffer. I am using UART0 on a K22F under KDS 3.0, KSDK 1.2, and I am also using Processor Expert.
I am not using the Rx or Tx callback functions. I handle incoming serial data with a task that waits for a byte to arrive on UART0 like this:
uint8_t rxbuff[256];
UART_DRV_ReceiveDataBlocking( _0, rxbuff, 1, MODBUS_RECEIVE_WAITFOREVER);
// process each incoming byte now that we know data is coming
Every byte that comes in after this one is stuffed into rxbuff, and rxbuff is evaluated on the fly to determine whether or not it is a valid modbus packet. Generally speaking, the RTU slave will accept all of the incoming data and then throw out the packet if it is not the intended recipient, or if the function code or CRC is invalid. Before exiting, I do flush the Rx buffer, which might actually not be necessary, since UART_DRV_ReceiveDataBlocking removes data from rxbuff anyway. However, I've run my code with and without flushing the Rx buffer, and the result is the same. Here's how I flush the buffer:
UART_Type *base = g_uartBase[instance];
UART_HAL_DisableReceiver( base);
UART_HAL_FlushRxFifo( base);
UART_HAL_EnableReceiver( base);
The problem? I can only process every other command.
The reason? The response from the modbus slave is sent back to the host, but because the RS485 transceiver is still listening, it picks up this data as well. Once the command handler executes, there's data in the FIFO again. Although I flush the RX buffer after the slave sends its response, this problem with "data corruption" will still occur if the slave's response packet > 8 bytes. If I send anything <= 8 bytes, I don't see this problem.
The response I am testing right now is 9 bytes. For example, let's say the following takes place:
Host sends: <0x02> <0x04> <0x0> <0x0A> <0x00> <0x02> <0x51> <0xFA>
Slave responds: <0x02> <0x04> <0x04> <0x1D> <0x00> <0x00> <0x00> <0xCE> <0xE8>
The response is 9 bytes. I flush the RX FIFO, which let's assume for now leaves <0xE8> in there the next time around. The modbus command listener loops around again and waits for more incoming data. First, it's interesting that it sits at
UART_DRV_ReceiveDataBlocking( _0, rxbuff, 1, MODBUS_RECEIVE_WAITFOREVER);
and waits. Shouldn't it think there's a byte still in the FIFO?
Now the host sends the same command again. At this time, the listening task gets past the receive data call, but the first byte it reads in is wrong. It's not 0xE8, it's usually null. The next byte it reads in is usually correct or shifted by one. I haven't established the exact pattern yet. The problem is that now the packet gets thrown out because the identifying information in it is wrong and the slave thinks it's garbled or for a different slave.
Message was edited by: Dave Matsumoto. I found out a lot more new information, so I wanted to make this question even more focused to hopefully get more help with this issue.
So far, I have tried increasing the interrupt priority of the UART component and also set the RTU task priority in MQX to 1. Doesn't help with the lost data in the buffer. I'm going to drop the transmission speed next.
EDIT -- I tried dropping the speed, but that did not help.