I am working on a project in which I am transmitting incoming CAN data to PC via USB.
CAN data will receive in every 1ms from an external hardware.This data I will copy into USB ring Buffer. Every 20ms data in the USB buffer will transmit to PC.I am using Bulk transfer mode. I developed my USB application based on the bulk transfer sample program.I am using the TI's PC tool(usb_bulk_example) to check the amount of data received at the PC.
My communication link is like this fig
CANDATASOURCE(1) ------------can------------->TM4C123(2)--------usb------------->PC(3)
Here I am facing 2 problems
1) Data loss between CANDATASOURCE and TM4C123(CAN bus)
Ex: An average loss of 300 messages for every 500000 messages when transmission happens at 1000msgs/second.
Loss is very less(less than 5 messages instead of 300) if the message transmission frequency is less(ex 200msgs/second).
Both transmitter and receiver are at the same sampling point (80%) and baud rate (1mbps).
Values I used to calculate sampling point(80%) and baud rate(1mbps) is given below
Clock = 80MHz
GetBittime.ui32SyncPropPhase1Seg=15;
GetBittime.ui32Phase2Seg=4;
GetBittime.ui32SJW=3;
GetBittime.ui32QuantumPrescaler=4;
What should I do to achieve zero data loss at this rate(1000 msgs/second)?
2) Received CAN data I will copy inside a message object structure (tCANMsgObject).
CANMessageGet(CAN0_BASE, 2, &sMsgObjectRx, 0);
Then this object structure I will copy into USB ring buffer using DMA.Gven below is the function which does that.
void UsbcopyDataToUSB(uint8_t *pui8Data, uint32_t ui32NumBytes) // This function is called inside the CAN RX ISR
{
uint32_t ui32Loop, ui32Space;
uint32_t ui32WriteIndex;
tUSBRingBufObject sTxRing;
//
// Get the current buffer information to allow us to write directly to
// the transmit buffer (we already have enough information from the
// parameters to access the receive buffer directly).
//
USBBufferInfoGet(&g_sTxBuffer, &sTxRing);
//
// How much space is there in the transmit buffer?
//
ui32Space = USBBufferSpaceAvailable(&g_sTxBuffer);
//
// How many characters can we process this time round?
//
ui32Loop = (ui32Space < ui32NumBytes) ? ui32Space : ui32NumBytes;
UsbDataTxBufferCount += ui32Loop;
ui32WriteIndex = sTxRing.ui32WriteIndex;
uDmaInitSWTransfer((void*)pui8Data,(void*)g_pui8USBTxBuffer[ui32WriteIndex],ui32Loop);
}
Everything mentioned above are happening inside the CAN receiver interrupt.
Every 20ms, I will transmit the data to PC(at this time 20 CAN messages can be present inside the ring buffer). TX ring buffer size is 2K.
I have a counter to track how many bytes of data I have transmitted over USB.The function which transmits data over USB is given below.
void UsbTransmitDataIfAny() // This function is called every 20ms
{
if (UsbDataTxBufferCount)
{
USBBufferDataWritten(&g_sTxBuffer, UsbDataTxBufferCount);
UsbDataTransmitCount += UsbDataTxBufferCount; //ToTal Data tramsmitted over USB in Bytes
UsbDataTxBufferCount = 0;
}
}
In PC side, I am running usb_bulk_example with -e option.I also did some edit in that application to check how much data received.
At lower frequencies (CAN message transmission frequency is 200msgs/second) there used to be a small difference between the total data transmitted count
in the MCU side and total data received count in the PC side.
Ex: total Data transmitted(MCU side) = 100050B
Total Data received(PC side) = 100000B now the PC counter is less than 50B.
At this point if I sent one more packet of data from MCU to PC (consider 1packet = 10Byte),
then total Data transmitted(MCU side) become 100060B ie incremet of new packet size.
but total Data received(PC side) become 100060B ie incremet of 60B(old difference + new packet size).
Why this is happening ?
At higher frequencies(CAN message transmission frequency is 1000msgs/second) these 2 counts are showing a difference around 250B.Unlike the previous case after sending a single packet the difference is still same.MCU is connected to PC directly so If I call USBBufferDataWritten() can I assume that USB library will sent that data? If so, why it is not reaching to PC.
Or is there any problem in the PC side?Please help me?