/* File name: Muart.c * Synopsis: This program allows you to test all the UART features * to read and write data. The user must physically link * the UART connector on the Matrox Board to the specified * COM port on the same computer. * * Note : This example will only run with Matrox boards that support * the UART features. These boards are: * Matrox Morphis, Matrox Helios and Matrox Solios. */ #include #include #include #include #define IMAGE_FILE M_IMAGE_PATH MIL_TEXT("Bird.mim") /* Uart configuration parameters. */ /* See board specific notes for a complete list of available baud rates. */ #define CONFIG_SPEED 38400 /* Only 1 or 2 stop bits are allowed. */ #define CONFIG_STOP_BITS 1 /* Only 7 or 8 data bits are allowed. */ #define CONFIG_DATA_LENGTH 8 /* Parity can be set to M_DISABLE, M_ODD or M_EVEN. */ #define CONFIG_PARITY M_DISABLE /* SystemInfo Struct. */ #define MAX_PORTS 50 typedef struct { MIL_TEXT_CHAR ComPortName[1][MAX_PATH]; MIL_TEXT_CHAR System[1][MAX_PATH]; unsigned long Device; unsigned long UartNumber; }SystemInfo; /* Hooked Data Struct. */ typedef struct { MIL_ID SystemId; MIL_ID ReceiveBufferId; MIL_TEXT_PTR ReceiveBuffer; unsigned long ReadSize; unsigned long ReadPosition; SystemInfo *Matrox; }UartHook; /* Function prototypes. */ long MFTYPE ReadHook(long , MIL_ID , void MPTYPE *); long InitializeComPort(HANDLE *hCom, long InterfaceType, SystemInfo *SysInfo); void InitializeMatroxUart(MIL_ID *MilSystem, SystemInfo *SysInfo, unsigned long *UartInterfaceType); void ReadFromComPort(HANDLE hCom, char *Buffer, unsigned long SizeToRead, OVERLAPPED *Overlapped); void WriteToComPort(HANDLE hCom, char *Buffer, unsigned long SizeToWrite, OVERLAPPED *Overlapped); void EnumerateComPorts(SystemInfo *SysInfo); int main(void) { MIL_ID MilApplication, /* MIL Application identifier. */ MilSystem, /* MIL System identifier. */ MilDisplaySource, /* MIL Display identifier. */ MilDisplayReceive, /* MIL Display identifier. */ MilSourceImage, /* MIL Source image identifier. */ MilReceivedImage; /* MIL Received image through UART. */ BUFATTRTYPE SourceFormat; /* Buffer format of source image. */ OVERLAPPED Overlapped; /* Windows overlapped structure. */ HANDLE hCom; /* Windows COM port handle. */ char *SourceBuffer, /* Pointer to address of source buffer. */ *ReceiveBuffer; /* Pointer to address of receive buffer. */ unsigned long SourceImageSize, /* Size of source image. */ UartInterfaceType, /* Type of UART interface being used. */ SentSize, /* Number of bytes written. */ lNumBytesTransferred; /* Number of bytes transferred. */ long volatile DoSomething = 0; /* Dummy variable. */ volatile UartHook UserStruct; /* UartHook structure object. */ /* Initialize SystemInfo structure and enumerate COM ports. */ SystemInfo Matrox; EnumerateComPorts(&Matrox); /* Initialize overlapped structure. */ memset(&Overlapped, 0, sizeof(Overlapped)); Overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); /* MIL allocations. */ MappAlloc(M_DEFAULT, &MilApplication ); MsysAlloc(Matrox.System[0], Matrox.Device, M_SETUP, &MilSystem); MdispAlloc(MilSystem, M_DEF_DISPLAY_NUM, M_DEF_DISPLAY_FORMAT, M_DEF_DISPLAY_INIT, &MilDisplaySource); MdispAlloc(MilSystem, M_DEF_DISPLAY_NUM, M_DEF_DISPLAY_FORMAT, M_DEF_DISPLAY_INIT, &MilDisplayReceive); /* Allocate MilSourceImage and load an image in it. */ MbufRestore(IMAGE_FILE, MilSystem, &MilSourceImage); /* Allocate the receive buffer with the same attributes as the source image. */ MbufInquire(MilSourceImage, M_EXTENDED_ATTRIBUTE, &SourceFormat); MbufAllocColor(MilSystem, (long)MbufInquire(MilSourceImage, M_SIZE_BAND, M_NULL), (long)MbufInquire(MilSourceImage, M_SIZE_X, M_NULL), (long)MbufInquire(MilSourceImage, M_SIZE_Y, M_NULL), (long)MbufInquire(MilSourceImage, M_TYPE, M_NULL), SourceFormat, &MilReceivedImage); MbufClear(MilReceivedImage, M_BLACK); /* Inquire the size in bytes of the source image. */ MbufInquire(MilSourceImage, M_SIZE_BYTE, &SourceImageSize); /* Inquire the virtual address of the source buffer. */ MbufInquire(MilSourceImage, M_HOST_ADDRESS, &SourceBuffer); /* Inquire the virtual address of the receive buffer. */ MbufInquire(MilReceivedImage, M_HOST_ADDRESS, &ReceiveBuffer); /* Print text on the displays and associate buffers. */ MdispControl(MilDisplaySource, M_TITLE, M_PTR_TO_DOUBLE(MIL_TEXT("MIL Source Image"))); MdispControl(MilDisplayReceive, M_TITLE, M_PTR_TO_DOUBLE(MIL_TEXT("MIL Received Image through UART."))); MdispSelect(MilDisplaySource, MilSourceImage); MdispSelect(MilDisplayReceive, MilReceivedImage); /* Initialize Matrox UART */ InitializeMatroxUart(&MilSystem, &Matrox, &UartInterfaceType); /* Initialize the OS mapped COM port as the other UART. */ if(!InitializeComPort(&hCom, UartInterfaceType, &Matrox)) return 0; /* Test to send data from the Matrox UART. */ MOs_printf(MIL_TEXT("The program will now send data from your Matrox board to your com port.\n")); MOs_printf(MIL_TEXT("%d bytes will be sent, this may take some time.\n"), SourceImageSize); MOs_printf(MIL_TEXT("Press to send data.\n")); getchar(); /* Setting the number of bytes to transfer. */ MsysControl(MilSystem, M_UART_WRITE_STRING_LENGTH + M_UART_NB(Matrox.UartNumber), SourceImageSize); /* Sending data through the Matrox UART. This call is asynchronous. */ MsysControl(MilSystem, M_UART_WRITE_STRING + M_UART_NB(Matrox.UartNumber), (unsigned long)SourceBuffer); /* Read the data from the COM port. */ ReadFromComPort(hCom, ReceiveBuffer, SourceImageSize, &Overlapped); /* Wait for the asynchronous write operation to finish and retrieve the actual number of bytes transferred. */ lNumBytesTransferred = 0; MsysInquire(MilSystem, M_UART_BYTES_WRITTEN + M_UART_NB(Matrox.UartNumber), &lNumBytesTransferred); /* Display the result. */ MOs_printf(MIL_TEXT("\n\nImage received through COM port\n\n")); /* Let the MIL image buffer know that it has been updated. */ MbufControl(MilReceivedImage, M_MODIFIED, M_DEFAULT); /* Test reading data from the Matrox board UART with M_UART_READ_STRING. */ MOs_printf(MIL_TEXT("The program will now send data from your com port to your Matrox board.\n")); MOs_printf(MIL_TEXT("%d bytes will be sent, this may take some time.\n"), SourceImageSize); MOs_printf(MIL_TEXT("Press to send data.\n")); getchar(); MbufClear(MilReceivedImage, M_BLACK); /* Setting the delimiter to the standard '\0' character. */ MsysControl(MilSystem, M_UART_STRING_DELIMITER + M_UART_NB(Matrox.UartNumber), M_DEFAULT ); /* This control is useful only if M_UART_READ_STRING_LENGTH is set to M_DEFAULT. */ MsysControl(MilSystem, M_UART_READ_STRING_MAXIMUM_LENGTH + M_UART_NB(Matrox.UartNumber), SourceImageSize); /* Setting the receive buffer size to the source buffer size. Setting M_UART_READ_STRING_LENGTH to M_DEFAULT would result in reading until the delimiter character is received or until M_UART_READ_STRING_MAXIMUM_LENGTH is reached, whichever happens first. Note that this mode of operation (using M_DEFAULT) will result in a loss of performance. Performance is improved if the actual number of characters to read is specified. */ MsysControl(MilSystem, M_UART_READ_STRING_LENGTH + M_UART_NB(Matrox.UartNumber), SourceImageSize); /* Reading incoming data through the Matrox board UART. This call is asynchronous. */ MsysControl(MilSystem, M_UART_READ_STRING + M_UART_NB(Matrox.UartNumber), (long)ReceiveBuffer); /* Write the data with the COM port. */ WriteToComPort(hCom, SourceBuffer, SourceImageSize, &Overlapped); /* Wait for the asynchronous read operation to finish and retrieve the actual number of bytes received. */ lNumBytesTransferred = 0; MsysInquire(MilSystem, M_UART_BYTES_READ + M_UART_NB(Matrox.UartNumber), &lNumBytesTransferred); /* Display the result. */ MOs_printf(MIL_TEXT("\n\nImage received through MIL Uart: \n\n")); /* Let the MIL image buffer know that it has been updated. */ MbufControl(MilReceivedImage, M_MODIFIED, M_DEFAULT); /* Test to read data from the Matrox board UART with a hook function. */ MOs_printf(MIL_TEXT("The program will now send data from your COM port to your Matrox board\n")); MOs_printf(MIL_TEXT("and read the data through a MIL hook function.\n")); MOs_printf(MIL_TEXT("%d bytes will be sent, this may take some time.\n"), SourceImageSize); MOs_printf(MIL_TEXT("Press to send data.\n")); getchar(); MbufClear(MilReceivedImage, M_BLACK); /* Initialize UART hook structure. */ UserStruct.SystemId = MilSystem; UserStruct.ReceiveBufferId = MilReceivedImage; UserStruct.ReceiveBuffer = ReceiveBuffer; UserStruct.ReadSize = SourceImageSize; UserStruct.ReadPosition = 0; UserStruct.Matrox = &Matrox; /* Hook the function to M_UART_DATA_RECEIVED. */ MsysHookFunction(MilSystem, M_UART_DATA_RECEIVED + M_UART_NB(Matrox.UartNumber), ReadHook, (void *)(&UserStruct)); /* Send data through the Windows COM port. */ ResetEvent(Overlapped.hEvent); WriteFile(hCom, SourceBuffer, SourceImageSize, &SentSize, &Overlapped); /* At this point the CPU is free to do other tasks and the incoming data */ /* will be read during this time. Here, the CPU will only wait for the */ /* end of the data receive function. */ while(UserStruct.ReadPosition < SourceImageSize) { DoSomething = DoSomething; Sleep(1); } /* Wait for the COM port to finish writing. */ GetOverlappedResult(hCom, &Overlapped, &SentSize, TRUE); /* Display the result. */ MOs_printf(MIL_TEXT("\n\nFinished reading data from hook function.\n")); MOs_printf(MIL_TEXT("Press to end.\n")); getchar(); /* Unhook functions. */ MsysHookFunction(MilSystem, M_UART_DATA_RECEIVED + M_UNHOOK + M_UART_NB(Matrox.UartNumber), ReadHook, (void *)(&UserStruct)); /* Free allocations. */ CloseHandle(hCom); CloseHandle(Overlapped.hEvent); MbufFree(MilReceivedImage); MbufFree(MilSourceImage); MdispFree(MilDisplaySource); MdispFree(MilDisplayReceive); MsysFree(MilSystem); MappFree(MilApplication); return 0; } void InitializeMatroxUart(MIL_ID *MilSystem, SystemInfo *SysInfo, unsigned long *UartInterfaceType) { SystemInfo *Matrox = (SystemInfo *) SysInfo; /* Changing UART configuration on Matrox board. */ /* M_UART_NB(M_DEVn) accesses the n UART number on this system. */ MsysControl(*MilSystem, M_UART_PARITY + M_UART_NB(Matrox->UartNumber), CONFIG_PARITY ); MsysControl(*MilSystem, M_UART_SPEED + M_UART_NB(Matrox->UartNumber), CONFIG_SPEED ); MsysControl(*MilSystem, M_UART_DATA_LENGTH + M_UART_NB(Matrox->UartNumber), CONFIG_DATA_LENGTH); MsysControl(*MilSystem, M_UART_STOP_BITS + M_UART_NB(Matrox->UartNumber), CONFIG_STOP_BITS ); MsysInquire(*MilSystem, M_UART_INTERFACE_TYPE + M_UART_NB(Matrox->UartNumber), UartInterfaceType); } long InitializeComPort(HANDLE *hCom, long InterfaceType, SystemInfo *SysInfo) { SECURITY_ATTRIBUTES SecAttr; /* Windows security attributes struct. */ COMMTIMEOUTS Timeouts; /* Windows COM port timeouts struct. */ DCB dcb; /* Windows COM port configuration struct. */ SecAttr.lpSecurityDescriptor = NULL; SecAttr.bInheritHandle = TRUE; SecAttr.nLength = sizeof(SecAttr); /* Opening Windows COM port handle. */ *hCom = CreateFile (SysInfo->ComPortName[0], GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, &SecAttr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); if(*hCom == INVALID_HANDLE_VALUE) { MOs_printf(MIL_TEXT(" Unable to open com port.\n")); return M_FALSE; } if(!GetCommState(*hCom, &dcb)) { MOs_printf(MIL_TEXT(" Unable to get com port state.\n")); return M_FALSE; } if(!GetCommTimeouts(*hCom, &Timeouts)) { MOs_printf(MIL_TEXT(" Unable to get com port timeouts.\n")); return M_FALSE; } /* Changing Windows COM port configuration. */ dcb.BaudRate = CONFIG_SPEED; dcb.ByteSize = CONFIG_DATA_LENGTH; if(CONFIG_STOP_BITS == 1) dcb.StopBits = ONESTOPBIT; else if(CONFIG_STOP_BITS == 2) dcb.StopBits = TWOSTOPBITS; if(CONFIG_PARITY == M_DISABLE) dcb.Parity = NOPARITY; else if (CONFIG_PARITY == M_EVEN) dcb.Parity = EVENPARITY; else if (CONFIG_PARITY == M_ODD) dcb.Parity = ODDPARITY; if(InterfaceType == M_RS232) dcb.fRtsControl = RTS_CONTROL_HANDSHAKE; else if(InterfaceType == M_RS485) /* Specifies that the RTS line will be high if bytes are available for transmission. After all buffered bytes have been sent, the RTS line will be low. This is required for RS485 interfaces. */ dcb.fRtsControl = RTS_CONTROL_TOGGLE; if (!SetCommState(*hCom, &dcb)) { MOs_printf(MIL_TEXT("Unable to set com port to desired configuration.\n")); return M_FALSE; } /* Set default read and write timeouts (in ms.). */ Timeouts.ReadIntervalTimeout = 50; Timeouts.ReadTotalTimeoutConstant = 0; Timeouts.ReadTotalTimeoutMultiplier = 0; Timeouts.WriteTotalTimeoutConstant = 0; Timeouts.WriteTotalTimeoutMultiplier = 50; if(!SetCommTimeouts(*hCom, &Timeouts)) { MOs_printf(MIL_TEXT("Unable to set com port timeouts.\n")); return M_FALSE; } return M_TRUE; } void ReadFromComPort(HANDLE hCom, char *Buffer, unsigned long SizeToRead, OVERLAPPED *Overlapped) { unsigned long ReadSize = 0; unsigned long TransferSize = 0; ResetEvent(Overlapped->hEvent); while(TransferSize < SizeToRead) { /* Reading in 1KB blocks from the COM port. */ ReadFile(hCom, Buffer+TransferSize, 1024, &ReadSize, Overlapped); GetOverlappedResult(hCom, Overlapped, &ReadSize, TRUE); TransferSize += ReadSize; MOs_printf(MIL_TEXT("%d bytes read. (%.2f%% completed.)\r"), TransferSize, (float)TransferSize/(float)SizeToRead * 100.0); } } void WriteToComPort(HANDLE hCom, char *Buffer, unsigned long SizeToWrite, OVERLAPPED *Overlapped) { unsigned long WriteSize = 0; unsigned long TransferSize = 0; unsigned long TransactionSize = 1024; ResetEvent(Overlapped->hEvent); while(TransferSize < SizeToWrite) { /* Writing in 1KB blocks with the COM port. */ WriteFile(hCom, Buffer+TransferSize, TransactionSize, &WriteSize, Overlapped); GetOverlappedResult(hCom, Overlapped, &WriteSize, TRUE); TransferSize += WriteSize; MOs_printf(MIL_TEXT("%d bytes written. (%.2f%% completed.)\r"), TransferSize, (float)TransferSize/(float)SizeToWrite * 100.0); if(SizeToWrite - TransferSize < TransactionSize) TransactionSize = SizeToWrite - TransferSize; } } /* UART read hook function. */ long MFTYPE ReadHook(long HookType, MIL_ID EventId, void MPTYPE *UserStructPtr) { UartHook *Params = (UartHook*) UserStructPtr; unsigned long Pending = 0; unsigned long lNumBytesTransferred = 0; /* Inquire the number of bytes pending in the UART receive buffer. */ MsysInquire(Params->SystemId, M_UART_DATA_PENDING + M_UART_NB(Params->Matrox->UartNumber), &Pending); while(Pending) { /* Read the data that is pending in the UART receive buffer. */ MsysControl(Params->SystemId, M_UART_READ_STRING_LENGTH + M_UART_NB(Params->Matrox->UartNumber), Pending); MsysControl(Params->SystemId, M_UART_READ_STRING + M_UART_NB(Params->Matrox->UartNumber), (unsigned long)(Params->ReceiveBuffer + Params->ReadPosition)); lNumBytesTransferred = 0; MsysInquire(Params->SystemId, M_UART_BYTES_READ + M_UART_NB(Params->Matrox->UartNumber), &lNumBytesTransferred); /* Notify buffer that it has been modified. */ MbufControl(Params->ReceiveBufferId, M_MODIFIED, M_DEFAULT); /* Adjust read position and continue. */ Params->ReadPosition += lNumBytesTransferred; MOs_printf(MIL_TEXT("%d bytes read. (%.2f%% completed.)\r"), Params->ReadPosition, (float)Params->ReadPosition / (float)Params->ReadSize * 100.0); MsysInquire(Params->SystemId, M_UART_DATA_PENDING + M_UART_NB(Params->Matrox->UartNumber), &Pending); } return 0; } void EnumerateComPorts(SystemInfo *SysInfo) { SystemInfo *Matrox = (SystemInfo *) SysInfo; /* Pointer to SysInfo structure. */ MIL_ID MilApplication, /* MIL Application identifier. */ MilSystem; /* MIL System identifier. */ long ComPortNumber = 0, /* Inquired COM port number. */ MaxPortNumber = 0, /* Remember the highest port. */ MinPortNumber = MAX_PORTS, /* Remember the lowest port. */ MatroxDevice[MAX_PORTS], /* Storage for device numbers. */ MatroxUartNumber[MAX_PORTS]; /* Storage for UART numbers. */ int SystemType, /* System to allocate. */ DeviceNumber, /* Device number to allocate. */ UartNumber, /* UART number. */ NumberOfPortsFound = 0, /* Remember number of ports found. */ PortNumberExists[MAX_PORTS] = {0}, /* Remember which ports were found. */ EntryCount = 0, /* Used to enumerate Windows ports. */ nIndex[2], /* Used in for loops. */ UserChoice = 0, /* Used to store user input. */ MatroxPortIndex = -1, /* Used as an index pointer. */ WindowsPortIndex = -1, /* Used as an index pointer. */ SelectedMatroxPort = -1, /* Used to store user selection. */ SelectedWindowsPort = -1; /* Used to store user selection. */ /* Registry specific variables. */ const HKEY MAIN_KEY = HKEY_LOCAL_MACHINE; const char SUB_KEY[30] = "HARDWARE\\DEVICEMAP\\SERIALCOMM"; const REGSAM KEY_PERMISSIONS = KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE; FILETIME DummyFileTime; DWORD DummyLength = MAX_PATH; HKEY CurKey; /* Enumeration specific variables. */ MIL_TEXT_CHAR EntryName[MAX_PORTS][MAX_PATH] = {""}; MIL_TEXT_CHAR EntryData[MAX_PORTS][MAX_PATH] = {""}; MIL_TEXT_CHAR TempSignalFormat[1][MAX_PATH] = {""}; MIL_TEXT_CHAR MilSystemNames[3][25] = {{M_SYSTEM_MORPHIS}, {M_SYSTEM_SOLIOS}, {M_SYSTEM_HELIOS}}; MIL_TEXT_CHAR SystemNames[3][25] = {{MIL_TEXT("Matrox Morphis")}, {MIL_TEXT("Matrox Solios")}, {MIL_TEXT("Matrox Helios")}}; MIL_TEXT_CHAR MatroxPorts[MAX_PORTS][MAX_PATH]; MIL_TEXT_CHAR WindowsPorts[MAX_PORTS][MAX_PATH]; MIL_TEXT_CHAR MatroxSignalFormat[MAX_PORTS][MAX_PATH]; MIL_TEXT_CHAR MatroxBoardName[MAX_PORTS][MAX_PATH]; MIL_TEXT_CHAR MatroxSystem[MAX_PORTS][MAX_PATH]; /* Enumerating Matrox COM ports. */ MappAlloc(M_DEFAULT, &MilApplication); MappControl(M_ERROR, M_PRINT_DISABLE); MOs_printf(MIL_TEXT("Enumerating Matrox COM ports.\n")); MOs_printf(MIL_TEXT("-----------------------------------------------------\n")); for(SystemType=0; SystemType<3; SystemType++) { for(DeviceNumber=0; DeviceNumber MaxPortNumber) MaxPortNumber = ComPortNumber; if (ComPortNumber < MinPortNumber) MinPortNumber = ComPortNumber; } else break; } MsysFree(MilSystem); MilSystem = M_NULL; } else break; } } MOs_printf(MIL_TEXT("\n")); MappControl(M_ERROR, M_PRINT_ENABLE); MappFree(MilApplication); /* Enumerating Windows COM ports. */ MOs_printf(MIL_TEXT("Enumerating Windows COM ports.\n")); MOs_printf(MIL_TEXT("-------------------------------\n")); RegOpenKeyEx(MAIN_KEY, SUB_KEY, 0, KEY_PERMISSIONS, &CurKey); while (RegEnumValue(CurKey, EntryCount, EntryName[EntryCount], &DummyLength, NULL, NULL, NULL, (unsigned long *) &DummyFileTime ) != ERROR_NO_MORE_ITEMS) { EntryCount++; DummyLength = MAX_PATH; } /* Get data from the entries. */ for (nIndex[0] = 0; nIndex[0] < EntryCount; nIndex[0]++) { int nEntryExists = 0; RegQueryValueEx(CurKey, EntryName[nIndex[0]], NULL, NULL, EntryData[nIndex[0]], &DummyLength); for (nIndex[1] = 0; nIndex[1] <= (int) MatroxPortIndex; nIndex[1]++) { if (strcmp(EntryData[nIndex[0]], MatroxPorts[nIndex[1]]) == 0) nEntryExists = 1; } if (!nEntryExists) { WindowsPortIndex++; MOs_strcpy(WindowsPorts[WindowsPortIndex], EntryData[nIndex[0]]); MOs_printf(MIL_TEXT("%2d) "), MatroxPortIndex + WindowsPortIndex + 2); MOs_printf(MIL_TEXT("%s "), EntryName[nIndex[0]]); MOs_printf(MIL_TEXT(" \t= %s\n"), EntryData[nIndex[0]]); } DummyLength = MAX_PATH; } MOs_printf(MIL_TEXT("\n")); RegCloseKey(CurKey); /* Get the desired Matrox COM port number for the source. */ MOs_printf(MIL_TEXT("Please specify the Matrox COM Port index to use.\n")); do { MOs_printf(MIL_TEXT("Valid entries are from 1 to %d: "), (MatroxPortIndex + 1)); scanf("%d", &UserChoice); if (UserChoice >= 1 && UserChoice <= (int)MatroxPortIndex + 1) { MOs_printf(MIL_TEXT("\n%d) %s, DEV%d, %s selected.\n"), UserChoice, MatroxBoardName[UserChoice - 1], MatroxDevice[UserChoice - 1], MatroxPorts[UserChoice - 1]); SelectedMatroxPort = UserChoice - 1; } else { MOs_printf(MIL_TEXT("Invalid selection. ")); UserChoice = 0; } }while (UserChoice == 0); /* Get the second COM port to complete the transfer. */ MOs_printf(MIL_TEXT("\nPlease specify the other COM Port index to use.\n")); UserChoice = 0; do { MOs_printf(MIL_TEXT("Valid entries are from 1 to %d: "), (MatroxPortIndex + 1) + (WindowsPortIndex + 1)); scanf("%d", &UserChoice); if ((UserChoice >= 1) && (UserChoice <= (int)MatroxPortIndex + 1 + (int)WindowsPortIndex + 1)) { if ((UserChoice - 1) > (int)MatroxPortIndex) MOs_printf(MIL_TEXT("\n%d) Windows %s selected.\n"), UserChoice, WindowsPorts[(UserChoice - 1) - (MatroxPortIndex) - 1]); else MOs_printf(MIL_TEXT("\n%d) %s, DEV%d, %s selected.\n"), UserChoice, MatroxBoardName[UserChoice - 1], MatroxDevice[UserChoice - 1], MatroxPorts[UserChoice - 1]); /* Make sure that a different COM port was selected. */ if (UserChoice == (int)SelectedMatroxPort + 1) { MOs_printf(MIL_TEXT("\nYou can not select the same port twice. Select a different COM port.\n")); UserChoice = 0; } /* Make sure signal formats are the same. */ else { MIL_TEXT_CHAR TempSignalFormat[1][MAX_PATH]; if ((UserChoice - 1) > (int)MatroxPortIndex) MOs_strcpy(TempSignalFormat[0], MIL_TEXT("RS232")); else MOs_strcpy(TempSignalFormat[0], MatroxSignalFormat[UserChoice - 1]); if (strcmp(TempSignalFormat[0], MatroxSignalFormat[SelectedMatroxPort]) != 0) { MOs_printf(MIL_TEXT("\nIncompatible formats. \n")); if ((UserChoice - 1) > (int)MatroxPortIndex) MOs_printf(MIL_TEXT("The Windows %s uses the RS232 format.\nThe %s uses the %s format. \n"), WindowsPorts[(UserChoice - 1) - (MatroxPortIndex)], MatroxBoardName[SelectedMatroxPort], MatroxSignalFormat[SelectedMatroxPort]); else MOs_printf(MIL_TEXT("The %s uses the %s format.\nThe %s uses the %s format. \n"), MatroxBoardName[UserChoice - 1], MatroxSignalFormat[UserChoice - 1], MatroxBoardName[SelectedMatroxPort], MatroxSignalFormat[SelectedMatroxPort]); MOs_printf(MIL_TEXT("Select a compatible board.\n\n")); UserChoice = 0; } else { if ((UserChoice - 1) > (int)MatroxPortIndex) { SelectedWindowsPort = (UserChoice - 1) - (MatroxPortIndex) - 1; MOs_sprintf(Matrox->ComPortName[0], MIL_TEXT("\\\\.\\%s"), WindowsPorts[SelectedWindowsPort]); } else { SelectedWindowsPort = (UserChoice - 1) + (MatroxPortIndex); MOs_sprintf(Matrox->ComPortName[0], MIL_TEXT("\\\\.\\%s"), MatroxPorts[SelectedWindowsPort - MatroxPortIndex]); } } } } else { MOs_printf(MIL_TEXT("Invalid selection. ")); UserChoice = 0; } }while (UserChoice == 0); getchar(); MOs_printf(MIL_TEXT("\n")); /* Fill structure with user's entries. */ MOs_strcpy(Matrox->System[0], MatroxSystem[SelectedMatroxPort]); Matrox->Device = MatroxDevice[SelectedMatroxPort]; Matrox->UartNumber = MatroxUartNumber[SelectedMatroxPort]; }