Tool/software:
Hello,
I am using Uart2 for communication.
I am facing issue while sending the data form dl_uart_transmitdatablocking function.
Sometimes the data from the buffer is not send completly on the uart.
The data from buffer is also seen in UART2_TXDATA register and FIFOs are also enabled. (Uart Baudrate 9600)
following is the code for your reference. I have also attached screenshot of TX data available in the buffer to send and data received in the external terminal(docklight).
void UartSendSlave(UARTFIFODATA * uart) {
Uint16 TxPtr = 0;
datacntptr=0;
do {
/*if (MAP_UARTSpaceAvail(uart->base)) {
MAP_UARTCharPutNonBlocking(uart->base, uart->buff[TxPtr]);
TxPtr++;
} else {
// sleep the task for a while
OS_DELAY(1);
*/
/* DL_UART_transmitData(uart->base, uart->buff[TxPtr]);
TxPtr++;*/
// TxPtr=uart->buff[datacntptr];
DL_UART_transmitDataBlocking(uart->base,uart->buff[datacntptr]);
datacntptr++;
} while (datacntptr < uart->txcnt);
}
/****************************************************
* FUNCTION: UartSlaveExecute
*
* PARAMETERS:UARTFIFODATA * uart
*
* DESCRIPTION: called in loop by process when slave is active
*
****************************************************/
void UartSlaveExecute(UARTFIFODATA *uart)
{
if (uart->mode != U_SLAVE)
return;
switch (uart->status)
{
case U_TX:
case U_WAIT:
uart->status = U_WAIT;
uart->rxcnt = 0;
//Wait forever here for a new message
if (OS_SEMAPHORE_TAKE( uart->SemUartRXstart, OS_MAX_DELAY ) != pdTRUE)
{
//OS_DELAY(1);
return;
}
case U_RX:
//Loop until packet complete ( no more chars for some time )
//Packet complete , analyze
uart->status = U_TX;
uart->protocol_func(uart);
//If there is a response , send it
if (uart->txcnt)
{
// OS_DELAY(1);
//Set 485 direction (only if defined, for half/duplex)
if (uart->tx_en_port != 0)
{
if (uart->base == (unsigned long) MB_SLV_B_INST)
{
TxEnable(uart);
}
else
{
TxEnable2(uart);
}
}
//Fifo mode for transmit
DL_UART_enableFIFOs(uart->base);
//Send packet and wait for transmission to complete ( sem given by TX interrupt)
UartSendSlave(uart);
if (OS_SEMAPHORE_TAKE( uart->SemUartTXend, 30 ) == pdFALSE)
{
}
while (DL_UART_isBusy(uart->base));
// while (DL_UART_isBusy(uart->base));
// it's now safe to put the transceiver back in RX mode . N.B.: now done in TX interrupt
}
uart->status = U_WAIT;
uart->txcnt = 0;
break;
case U_ERR:
uart->rxcnt = 0;
uart->txcnt = 0;
uart->status = U_WAIT;
OS_DELAY(1);
break;
}
}
Please try this example code to send the same frame to PC:
C:\ti\mspm0_sdk_2_04_00_06\examples\nortos\LP_MSPM0G3507\driverlib\uart_rw_multibyte_fifo_poll
Please try to capture the hardware UART Tx line waveform, to confirm that there are data lost from MSPM0 UART Tx.
1) > // it's now safe to put the transceiver back in RX mode . N.B.: now done in TX interrupt
Can you show how this is done?
2) > f (OS_SEMAPHORE_TAKE( uart->SemUartTXend, 30 ) == pdFALSE)
I'm guessing that the "30" is 30 msec, which is 30 bytes at 9600bps. Many of your packets appear to be longer than this. You should consider what a (spurious) timeout here would do -- or maybe just increase the timeout.
3) > DL_UART_enableFIFOs(uart->base);
Are you enabling/disabling the FIFOs on every transmission? I know of no reason this wouldn't work, but it seems unusual. I expect that you lose any FIFO contents when you disable them.
4) > case U_WAIT:
It appears that this case falls through to case U_RX. Was this intentional? [I don't really understand your state machine, but it looks odd.]
Hi,
We have tried the suggested Example code. And no loss of data was found from MSPM0 UART Tx.
But When we trying the same function as per the example code in our code we can see the dataloss in the receiving port.
So please suggest anything else that can resolve our issue.
In your packet trace, it appeared that in the one (?) case of "[RX]" data loss it occurred at the end of the packet, so I suspected you were stopping the transmission too early. Thus my questions above.
Yes, there are UART state register can be check make sure all data in UART Tx buffer is send out.
TRM: 18.3.10 RIS (Offset = 1030h) [Reset = 00000000h] : EOT bit, is CPU interrupt.
I suspect an isBusy() test would suffice, but the isBusy call we see takes place (per the comment) after the RS-485 has been switched back to RX in the ISR (not shown).
It seemed to me that the TX could be cut off (prematurely) by (a) disabling the FIFOs or (b) switching the transceiver too early, but we can't see that.