//***************************************************************************** // // serial_pic.cpp : Defines the entry point for the Win32 console application. // // Author: Reed Bement 04/09/2004 // // Note: // ---- // // Application tests the simple serial data communications library by // transfering data over the command line specified serial port. // //***************************************************************************** #include #include #include #include #include "serial.h" // Structure that holds parsed command line parameters. typedef struct { DWORD dwComPort; DWORD dwBaudRate; char szInFile[MAX_PATH]; char szOutFile[MAX_PATH]; } CMD_PARAMS, *PCMD_PARAMS; // Structure that holds receive and transmit thread parameters. typedef struct { FILE *fp; PSERIAL_CONTEXT psc; } THRD_PARAMS, *PTHRD_PARAMS; //***************************************************************************** // // Global Variables // //***************************************************************************** BOOL g_bTransmitRunning; BOOL g_bReceiveRunning; DWORD g_dwBytesSent; //***************************************************************************** // // Usage - Prints commandline syntax at console. // // Paramaters - None. // // Returns - None. // //***************************************************************************** void Usage(void) { printf("\nUsage:\n"); printf("serial_pic COMm[:] [-bBaudRate] -iInFile -oOutFile\n\n"); } //***************************************************************************** // // ParseCmdLineParams - Parse the command line parameters. // // Paramaters - // argc - See SDK. // argv - See SDK. // pcp - Pointer to parsed command line parameters structure. // // Returns - TRUE on success. // //***************************************************************************** BOOL ParseCmdLineParams(int argc, char* argv[], PCMD_PARAMS pcp) { char *psz; bool bInputSpecDone = FALSE; // Process command line arguments if ((argc < 4) || (argc > 5)) { if (argc < 4) { printf("\nNot enough parameters\n"); } else { printf("\nToo many parameters\n"); } return FALSE; } // Loop through arguments, skip arg zero. for (int i = 1; i < argc; i++) { psz = argv[i]; if (*psz == '-') { // Handle prefixed parameter. psz++; switch (*psz++) { case 'b': case 'B': if (sscanf(psz, "%d", &pcp->dwBaudRate) != 1) { printf("\nError converting baud rate number: %s\n", psz); return FALSE; } break; case 'i': case 'I': strncpy(pcp->szInFile, psz, MAX_PATH); break; case 'o': case 'O': strncpy(pcp->szOutFile, psz, MAX_PATH); break; default: psz--; printf("\nUnknown parameter: %c%c\n", *(argv[i]), *psz); return FALSE; } } else { // Handle unprefixed COM port specification. char szTmp[4]; strncpy(szTmp, psz, 3); szTmp[3] = '\0'; psz+= 3; _strupr(szTmp); if (strcmp(szTmp, "COM")) { printf("\nUnknown parameter: %s\n", psz); return FALSE; } if (sscanf(psz, "%d", &pcp->dwComPort) != 1) { printf("\nError converting port number: %s\n", psz); return FALSE; } } } return TRUE; } //***************************************************************************** // // RecieveThread - Receive characters and write them to an open file. // // Paramaters // vp - FIle handle to receive file. // // Returns - Nothing. // //***************************************************************************** void RecieveThread(void *vp) { DWORD dwByteCount = 0; PTHRD_PARAMS ptp = (PTHRD_PARAMS) vp; while (g_bReceiveRunning) { BYTE b; if (RecvSerialByte(ptp->psc, &b)) { fputc(b, ptp->fp); dwByteCount++; if (g_dwBytesSent) { if (dwByteCount >= g_dwBytesSent) { printf("Received all sent bytes.\n"); break; } } } else { printf("Error while receiving bytes. Count: %d\n", dwByteCount); printf("%s\n\n", ptp->psc->szError); break; } } g_bReceiveRunning = FALSE; printf("\nTotal bytes received: %d\n", dwByteCount); _endthread(); } //***************************************************************************** // // TransmitThread - Send characters read from an open file. // // Paramaters // vp - FIle handle to send file. // // Returns - Nothing. // //***************************************************************************** void TransmitThread(void *vp) { DWORD dwByteCount = 0; PTHRD_PARAMS ptp = (PTHRD_PARAMS) vp; while (g_bTransmitRunning) { char ch = fgetc(ptp->fp); if (!feof(ptp->fp)) { if (SendSerialByte(ptp->psc, ch)) { dwByteCount++; } else { printf("Error while sending byte: 0x%X, count: %d\n", ch, dwByteCount); printf("%s\n\n", ptp->psc->szError); break; } } else { break; } } printf("\nTotal bytes transmitted: %d\n", dwByteCount); g_dwBytesSent = dwByteCount; g_bTransmitRunning = false; _endthread(); } //***************************************************************************** // // Main - Entry point for serial_pic.exe application. // // Paramaters - See SDK. // // Returns - Zero on success, else error code. // //***************************************************************************** int main(int argc, char* argv[]) { printf("Skeleton Win32 to PIC serial data communications test.\n"); CMD_PARAMS cp; // Default to 9600 baud. cp.dwBaudRate = CBR_9600; if (ParseCmdLineParams(argc, argv, &cp)) { SERIAL_CONTEXT sc; if (InitSerial(&sc, cp.dwComPort, cp.dwBaudRate)) { printf("Opened COM%d at %d baud\n", cp.dwComPort, cp.dwBaudRate); FILE *fpInFile, *fpOutFile; // Open input file. fpInFile = fopen(cp.szInFile,"rb"); if (fpInFile) { printf("Sending from: %s\n", cp.szInFile); // Create output file. fpOutFile = fopen(cp.szOutFile,"wb"); if (fpOutFile) { printf("Receiving to: %s\n", cp.szOutFile); // Start recieve data thread. THRD_PARAMS rtp; rtp.fp = fpOutFile; rtp.psc = ≻ g_bReceiveRunning = TRUE; _beginthread(RecieveThread, 0, &rtp); // Start send data thread. THRD_PARAMS ttp; ttp.fp = fpInFile; ttp.psc = ≻ g_bTransmitRunning = TRUE; _beginthread(TransmitThread, 0, &ttp); // Loop until finished or interrupted. printf("Hit anykey to abort...\n"); while (g_bTransmitRunning || g_bReceiveRunning) { if (_kbhit()) { _getch(); g_bTransmitRunning = g_bReceiveRunning = FALSE; printf("\nUser abort.\n"); break; } } fclose(fpOutFile); } else { printf("Unable to create: %s\n", cp.szOutFile); printf("Last error: %d\n", GetLastError()); } fclose(fpInFile); } else { printf("Unable to open: %s\n", cp.szInFile); printf("Last error: %d\n", GetLastError()); } CloseSerial(&sc); } else { printf("Error while initializing COM%d at %d baud\n", cp.dwComPort, cp.dwBaudRate); printf("%s\n\n", sc.szError); } } else { Usage(); } return 0; }