I have a microcontroller TM4C123GXL Launchpad, that has 8 serial UART ports. I am using Keil uVision5 with Tiva Ware for programming.
I wanted to interface 3 UART devices with the microcontroller without any loss of bytes. The baud rate has been set to 115200 bits/sec with no parity as shown in the figure below. All devices sent data frame periodically every 5ms.
TX and RX time are calculated using No_0f_bytes*10/BaudRate
I have successfully interfaced the devices with the UART of µC. The problem in the communication is that that I am losing the bytes. If I do a communication with a single device (Device 2) I am still losing the bytes from the whole frame (20 bytes).
Is it due to the 16 byte FIFO limitation of Tm4c123 or anything else?
I have also implemented the µDMA feature of TM4C123. But still, bytes are lost. What can I do to improve the system for lossless transmission and reception of data frames?
Edit:
Here is the Software Architecture:
I am using Periodic Timer Interrupt of 5ms to receive and transmit the frame. All frame has first 2 bytes header and a counter byte as the last byte.
void Timer1IntHandler(void) // Periodic Service Routine every 5ms
{
DisableIntrupts();
bool Correct=ReadJoystick(); //10 bytes Device 1
if(Correct)
{
GenerateServoCardsFrame();
SendServo1Frame(); //20 bytes Device 2
SendServo2Frame(); //17 bytes Device 3
ReadServo1Frame(); //15 bytes Device 2
ReadServo2Frame(); //20 bytes Device 3
GenerateJoystickFrame();
SendJoystickFrame(); //10 bytes Device 1
EnableIntrupts();
}
}
main()
{
SetupClock() ; //Setup 16 MHz Clock
SetupJoystick(); //Initalize uart1 port for Device1
SetupServoCard1(); //Initalize uart2 port for Device2
SetupServoCard2(); //Initalize uart3 port for Device3
InitalizePeriodicTimerHandler(5); //Periodic Service Routine every 5ms (Timer1IntHandler)
while(1)
{
}
}
bool ReadJoystick(void)
{
int BytePos=0;
int CountInvalid=0;
int LoopoutTime=0;
while(1)
{
if (ROM_UARTCharsAvail(UART1))
{
ByteRX = ROM_UARTCharGetNonBlocking(UART1);
if (BytePos==0)
{
if (ByteRX== 0xA1) //Header1 found
{
KArray[0] = Bytebuf ;
BytePos ++;
}
else
{
CountInvalid++;
if (CountInvalid>5)
return 0;
}
}
else if (BytePos ==1)
{
if (ByteRX == 0x66) //Header2 found
{
KArray[1] = ByteRX;
BytePos ++;
}
else
BytePos=0;
}
else
{
KArray[BytePos++] = ByteRX;
if (BytePos==10)
return 1; //Frame Recived
}
}
else
{
SysCtlDelay(0.25*SysCtlClockGet()/3 / 1000); // 0.25ms delay
LoopoutTime++;
if (LoopoutTime > 10)
return 0;
}
}
}
According to my calculation, 1 byte requires 10/115200=0.08680ms and to read a FIFO of 16 bytes requires 1.38ms. The table in the figure shows total Tx time of 4.08ms and Rx time of 3.91 ms which sums to 8ms. This is greater than my Periodic Interrupt Service Routine.
Do I have to increase the Periodic Interrupt Timing?
volatile
bugs all over. The form ofmain
used is from the dinosaur era, which suggests that a bad compiler is used. And so on. \$\endgroup\$