2018-08-30 07:58 AM
I want to make a streaming from MCU to PC over USB and write as a binary file. Now I have some real problems with USB speed. I tried to measure it and
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
if ((dmaFlag != 0)) {
for(int i = 0; i < DMA_BUFFER_SIZE/4096; ++i) {
CDC_Transmit_FS(buffer + 4096*i, 4096*sizeof(unsigned int));
while(strcmp(string, "copy") != 0);
string[0] = 0;
//printf("roger\r\n");
}
//printArray();
CDC_Transmit_FS(endstring, strlen(endstring));
dmaFlag = 0;
}
}
where
#define DMA_BUFFER_SIZE 65536
and PC listener code
#include <windows.h>
#include <stdio.h>
#include <stdint.h>
int64_t GlobalCounterFrequency;
inline float Win32GetSecondsElapsed(LARGE_INTEGER Start, LARGE_INTEGER End)
{
float Result = (float)(End.QuadPart - Start.QuadPart) /
(float)GlobalCounterFrequency;
return(Result);
}
LARGE_INTEGER startCounter, endCounter;
float time = 0;
int main()
{
// Define the five bytes to send ("hello")
char* bytes_to_send = "send_data";
// Declare variables and structures
HANDLE hSerial;
DCB dcbSerialParams = {0};
COMMTIMEOUTS timeouts = {0};
// Open the highest available serial port number
fprintf(stderr, "Opening serial port...");
hSerial = CreateFile(
"\\\\.\\COM6", GENERIC_READ|GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
if (hSerial == INVALID_HANDLE_VALUE)
{
fprintf(stderr, "Error\n");
return 1;
}
else fprintf(stderr, "OK\n");
//SetupComm(hSerial, 1200, 1200);
// Set device parameters (38400 baud, 1 start bit,
// 1 stop bit, no parity)
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
if (GetCommState(hSerial, &dcbSerialParams) == 0)
{
fprintf(stderr, "Error getting device state\n");
CloseHandle(hSerial);
return 1;
}
/*
dcbSerialParams.BaudRate = CBR_38400;
dcbSerialParams.ByteSize = 8;
dcbSerialParams.StopBits = ONESTOPBIT;
dcbSerialParams.Parity = NOPARITY;
if(SetCommState(hSerial, &dcbSerialParams) == 0)
{
fprintf(stderr, "Error setting device parameters\n");
DWORD lastError = GetLastError();
CloseHandle(hSerial);
return 1;
}
*/
// Set COM port timeout settings
timeouts.ReadIntervalTimeout = 50;
timeouts.ReadTotalTimeoutConstant = 50;
timeouts.ReadTotalTimeoutMultiplier = 10;
timeouts.WriteTotalTimeoutConstant = 50;
timeouts.WriteTotalTimeoutMultiplier = 10;
if(SetCommTimeouts(hSerial, &timeouts) == 0)
{
fprintf(stderr, "Error setting timeouts\n");
CloseHandle(hSerial);
return 1;
}
// Send specified text (remaining command line arguments)
#if 1
DWORD bytes_written, total_bytes_written = 0;
fprintf(stderr, "Sending bytes...");
if(!WriteFile(hSerial, bytes_to_send, strlen(bytes_to_send), &bytes_written, NULL))
{
fprintf(stderr, "Error\n");
CloseHandle(hSerial);
return 1;
}
fprintf(stderr, "%d bytes written\n", bytes_written);
#endif
char *Filename = "orbita_data.bin";
// this should always create new file data be written into
HANDLE FileHandle = CreateFile(Filename, GENERIC_WRITE, 0, 0,
CREATE_ALWAYS, 0, 0);
if(FileHandle != INVALID_HANDLE_VALUE) {
// NOTE(Egor): succeed
}
else {
// NOTE(Egor); fail
}
LARGE_INTEGER CounterFrequencyResult;
QueryPerformanceFrequency(&CounterFrequencyResult);
GlobalCounterFrequency = CounterFrequencyResult.QuadPart;
QueryPerformanceCounter(&startCounter);
for(;;) {
#define number_of_ccr 4096
unsigned int lpBuffer[number_of_ccr] = {0};
unsigned long nNumberOfBytesToRead = number_of_ccr*4;
unsigned long lpNumberOfBytesRead;
ReadFile(
hSerial,
lpBuffer,
nNumberOfBytesToRead,
&lpNumberOfBytesRead,
NULL
);
if(!strcmp(lpBuffer, "end\r\n")) {
CloseHandle(FileHandle);
fprintf(stderr, "end flag was received\n");
break;
}
else if(lpNumberOfBytesRead > 0) {
// NOTE(Egor): succeed
char *copyString = "copy";
WriteFile(hSerial, copyString , strlen(copyString), &bytes_written, NULL);
DWORD BytesWritten;
// write data to file
WriteFile(FileHandle, lpBuffer, nNumberOfBytesToRead, &BytesWritten, 0);
}
}
QueryPerformanceCounter(&endCounter);
time = Win32GetSecondsElapsed(startCounter, endCounter);
char DebugBuffer[256];
sprintf(DebugBuffer, "time: %f \n", time);
OutputDebugStringA(DebugBuffer);
// Close serial port
fprintf(stderr, "Closing serial port...");
if (CloseHandle(hSerial) == 0)
{
fprintf(stderr, "Error\n");
return 1;
}
fprintf(stderr, "OK\n");
// exit normally
return 0;
}
give me no more that 256kb over 2.5(!!!) seconds if QPC doesn't lying to me.
Is something ridiculously wrong with my setup? Or it's a common speed for USB-OTG-FS configured as virtual com port? Could someone provide an exmaple or advice about USB streaming?
Thanks in advance, any help will be highly apreciated, actully I run out of ideas already.