Overview: I'm trying to trigger an Overrun error indication, by issuing long delays between each byte read from the serial port. To make long story short - I don't get this event.
The test: The DTE is configured to work at 920000BPS 8N1, no flow control. The DTE is connected to my Windows10 host via "Silicon Labs CP210x USB to UART Bridge" device.
The provided code fragment opens the port, calls the SetCommMask function. A delay of 10 seconds was inserted between each call to ReadFile within a loop. The DTE continuously sends data at a stable rate.
The problem: I don't get any Overrun signal from WaitCommEvent.
Question: Is there a problem with my code? is there some known limitation with the USB driver? Do I need to use flow control to get noticed about overrun events?
#include <Windows.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
HANDLE hComm; // Handle to the Serial port
BOOL Status; // Status
DCB dcbSerialParams = { 0 }; // Initializing DCB structure
COMMTIMEOUTS timeouts = { 0 }; //Initializing timeouts structure
char SerialBuffer[64] = { 0 }; //Buffer to send and receive data
DWORD BytesWritten = 0; // No of bytes written to the port
DWORD dwEventMask; // Event mask to trigger
char ReadData; //temperory Character
DWORD NoBytesRead; // Bytes read by ReadFile()
unsigned char loop = 0;
wchar_t pszPortName[10] = { 0 }; //com port id
wchar_t PortNo[20] = { 0 }; //contain friendly name
//Enter the com port id
do
{
printf_s("Enter the Com Port: ");
wscanf_s(L"%s", pszPortName, (unsigned)_countof(pszPortName));
swprintf_s(PortNo, 20, L"\\\\.\\%s", pszPortName);
//Open the serial com port
hComm = CreateFile(PortNo, //friendly name
GENERIC_READ | GENERIC_WRITE, // Read/Write Access
0, // No Sharing, ports cant be shared
NULL, // No Security
OPEN_EXISTING, // Open existing port only
0, // Non Overlapped I/O
NULL); // Null for Comm Devices
if (hComm == INVALID_HANDLE_VALUE)
{
printf_s("\n Port can't be opened\n\n");
break;
}
//Setting the Parameters for the SerialPort
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
Status = GetCommState(hComm, &dcbSerialParams); //retreives the current settings
if (Status == FALSE)
{
printf_s("\nError to Get the Com state\n\n");
break;
}
dcbSerialParams.BaudRate = 920000;//CBR_9600; //BaudRate = 9600
dcbSerialParams.ByteSize = 8; //ByteSize = 8
dcbSerialParams.StopBits = ONESTOPBIT; //StopBits = 1
dcbSerialParams.Parity = NOPARITY; //Parity = None
Status = SetCommState(hComm, &dcbSerialParams);
if (Status == FALSE)
{
printf_s("\nError to Setting DCB Structure\n\n");
break;
}
//Setting Timeouts
timeouts.ReadIntervalTimeout = 50;
timeouts.ReadTotalTimeoutConstant = 50;
timeouts.ReadTotalTimeoutMultiplier = 10;
timeouts.WriteTotalTimeoutConstant = 50;
timeouts.WriteTotalTimeoutMultiplier = 10;
if (SetCommTimeouts(hComm, &timeouts) == FALSE)
{
printf_s("\nError to Setting Time outs");
break;
}
//Setting Receive Mask
Status = SetCommMask(hComm, EV_ERR| EV_RX80FULL| EV_BREAK/*EV_RXCHAR*/);
if (Status == FALSE)
{
printf_s("\nError to in Setting CommMask\n\n");
break;
}
//Read data and store in a buffer
do
{
Status = ReadFile(hComm, &ReadData, sizeof(ReadData), &NoBytesRead, NULL);
//Setting WaitComm() Event
Sleep(10000); /* Ten seconds */
Status = WaitCommEvent(hComm, &dwEventMask, NULL); //Wait for the character to be received
if (Status == FALSE)
{
printf_s("\nError! in Setting WaitCommEvent()\n\n");
break;
}
SerialBuffer[loop] = ReadData;
++loop;
} while (NoBytesRead > 0);
--loop; //Get Actual length of received data
printf_s("\nNumber of bytes received = %d\n\n", loop);
//print receive data on console
printf_s("\n\n");
int index = 0;
for (index = 0; index < loop; ++index)
{
printf_s("%c", SerialBuffer[index]);
}
printf_s("\n\n");
} while (0);
CloseHandle(hComm);//Closing the Serial Port
system("pause");
return 0;
}