Code:#include <windows.h> #include <stddef.h> #include <stdio.h> #include <stdlib.h> #include <winioctl.h> #include <conio.h> #include <stdlib.h> #include <signal.h> #include "QuaDef.h" #include "QuaDLL.h" #define TIMEOUT_SEC 10 // Counter elements to count frames transmitted. long counter; char digits[15]; // This is the string we will transmit. char *pMsgString = "Jim's Chicago Style Pizza and German Beer Stand "; // configuration array pointer. PMPA_CONFIG pMPA_cfg, pMPA_cfgOut; // Buffer length, including space for the counter bytes. short BufferLen; // Receive buffer pointer. PUCHAR pRxBuffer; // Transmit buffer pointer. PUCHAR pTxBuffer; // Other miscellaneous variables. MPA_HANDLE Handle1, Handle2; ULONG SentbufferLen; void ResetFrames(PMPA_HANDLE pHandle, BOOLEAN tx, BOOLEAN rx); void init_config_array(int channel) { // Set up all initial values in the configuration array. pMPA_cfg->set.all = 0; pMPA_cfg->InternalLoopback = FALSE; pMPA_cfg->set.bits.InternalLoopback = TRUE; pMPA_cfg->CRCPreset = 0; pMPA_cfg->set.bits.CRCPreset = TRUE; pMPA_cfg->structLen = sizeof(MPA_CONFIG); if(channel == 0) { pMPA_cfg->TxClockSource = BAUD_RATE_GEN; pMPA_cfg->set.bits.TxClockSource = TRUE; pMPA_cfg->RxClockSource = BAUD_RATE_GEN; pMPA_cfg->set.bits.RxClockSource = TRUE; } else { pMPA_cfg->TxClockSource = TRXC; pMPA_cfg->set.bits.TxClockSource = TRUE; pMPA_cfg->RxClockSource = RTXC; pMPA_cfg->set.bits.RxClockSource = TRUE; } pMPA_cfg->Encoding = NRZ; pMPA_cfg->set.bits.Encoding = TRUE; pMPA_cfg->set.bits.BaudRate = TRUE; pMPA_cfg->BaudRate = 9600; pMPA_cfg->set.bits.ClockMode = TRUE; pMPA_cfg->ClockMode = 1; pMPA_cfg->set.bits.ClockRate = TRUE; pMPA_cfg->ClockRate = 9830400; pMPA_cfg->IdleLineControl = IDLE_LINE_FLAGS; pMPA_cfg->set.bits.IdleLineControl = TRUE; pMPA_cfg->set.bits.FrameBufferSizeRx = TRUE; pMPA_cfg->FrameBufferSizeRx = BufferLen; pMPA_cfgOut->structLen = sizeof(MPA_CONFIG); } // Convert ascii hex to unsigned int. USHORT hextoui(char *numbertext) { return((USHORT)strtol(numbertext, (char **)NULL, 16)); } // Convert ascii decimal to unsigned int. USHORT atoui(char *numbertext) { return((USHORT)strtol(numbertext, (char **)NULL, 10)); } // Convert ascii decimal to unsigned char. UCHAR atouc(char *numbertext) { return((UCHAR)strtol(numbertext, (char **)NULL, 10)); } // Convert ascii decimal to unsigned long. ULONG atoul(char *numbertext) { return((ULONG)strtol(numbertext, (char **)NULL, 10)); } void process_options(int argc, char *argv[]) { int index; char *charptr; // Loop through all command line parameters, skipping the program name. for (index = 1; index <= (argc-1); index++) { charptr = argv[index]; // First character of parameter must be a slash. if (*charptr == '/') { charptr++; // The switch type follows the slash. Decode the type and // pass a pointer to the variable data to the conversion // routine. switch (*charptr) { // Change baud rate. case 'b': case 'B': pMPA_cfg->BaudRate = atoul(++charptr); break; default: printf("\nLPBCKBI (options)\n"); printf("\nOptions:\n"); printf("/B<BaudRateTimeConst>\n"); exit(-1); break; } } } } short transmit(void) { ULONG bytesWritten; MPA_ERROR_CODE result; counter++; ltoa(counter, digits, 10); strcpy (pTxBuffer,pMsgString); strcat(pTxBuffer, digits); SentbufferLen = strlen(pTxBuffer); // Transmit data result = MPA_PutData(&Handle1, pTxBuffer, SentbufferLen, &bytesWritten, NULL); if (result != ERR_NO_ERROR) { printf("Error starting frame transmission %x", result); return(1); } return 0; } void SyncDriveExit(void) { // This exit routine takes care of required cleanup. // It's important not to exit with any locked memory lying around! MPA_ERROR_CODE result; if ((result = MPA_Close(&Handle1)) != ERR_NO_ERROR) { printf("ERROR: Unable to close device. Error code %d\n", result); } if ((result = MPA_Close(&Handle2)) != ERR_NO_ERROR) { printf("ERROR: Unable to close device. Error code %d\n", result); } free(pRxBuffer); free(pTxBuffer); free(pMPA_cfg); free(pMPA_cfgOut); printf("Closed device. Handle =\n"); // Print current buffer statuses. } void AbnormalExit(int signal) { // This function ensures that the exit handler gets // called if Ctrl-C, Ctrl-Break, etc. occurs. exit(0); } void main(int argc, char *argv[]) { MPA_ERROR_CODE err; UCHAR deviceNumber1 = 0, deviceNumber2 = 1; //just for one device BOOLEAN overlapped = 0; UCHAR timeout; ULONG frameCnt; ULONG bytesWritten; MPA_DRIVER_VERSION ver; MPA_ERROR_CODE result; // Setup handlers for Ctrl-C, Ctrl-Break, etc. signal(SIGINT, AbnormalExit); signal(SIGTERM, AbnormalExit); atexit(SyncDriveExit); // Initialize the counter to "00000". counter = 0; // Open first device Handle1.structLen = sizeof(MPA_HANDLE); err = MPA_Open(&Handle1, deviceNumber1, overlapped); if(err != ERR_NO_ERROR) { printf("ERROR: Unable to open first device. Error code %d.\n", err); exit(-1); } // Open second Handle2.structLen = sizeof(MPA_HANDLE); err = MPA_Open(&Handle2, deviceNumber2, overlapped); if(err != ERR_NO_ERROR) { printf("ERROR: Unable to open second device. Error code %d.\n", err); exit(-1); } // Allocate memory for the channel configuration array. // For Windows, it should be locked memory. if ((pMPA_cfg = malloc(sizeof(MPA_CONFIG))) == NULL) { printf("Cannot allocate config array!\n"); exit(-1); } if ((pMPA_cfgOut = malloc(sizeof(MPA_CONFIG))) == NULL) { printf("Cannot allocate config array!\n"); exit(-1); } printf("\n*** Quatech MPA-series adapter feedback example program ***\n\n"); printf("Bit synchronous transfer between two boards (one if MPAC-100).\n"); printf("Press Ctrl-Break to stop the program.\n\n"); // Initialize the channel configuration array. // Buffer length is the string, and // some extra space for the counter bytes. BufferLen = strlen(pMsgString ) + 0x10; pRxBuffer = (PUCHAR)(malloc(BufferLen)); if(pRxBuffer == NULL) { printf("Cannot allocate Rx_Buffer!\n"); exit(-1); } pTxBuffer = (char *)(malloc(BufferLen)); if(pTxBuffer == NULL) { printf("Cannot allocate TxBuffer!\n"); exit(-1); } // Check the SyncDrive version. ver.structLen = sizeof(MPA_DRIVER_VERSION); err = MPA_GetDriverVersion(&Handle1, &ver); if(err != ERR_NO_ERROR) { printf("Syncdrive release level error!\n\n"); } printf("Driver release level is %d.%d\n", ver.major, ver.minor); init_config_array(0); // Now process any options that override the defaults for first device. if (argc > 1) process_options(argc, argv); err = MPA_SetConfig(&Handle1, pMPA_cfg, pMPA_cfgOut); if(err != ERR_NO_ERROR) { printf("ERROR: Unable to configure first device. Error code %d.\n", err); exit(-1); } //You must close and reopen for configuration values to take effect err = MPA_Close(&Handle1); if(err != ERR_NO_ERROR) { printf("ERROR: Unable to close device. Error code %d.\n", err); SyncDriveExit(); } err = MPA_Open(&Handle1, deviceNumber1, overlapped); if(err != ERR_NO_ERROR) { printf("ERROR: Unable to open device. Error code %d.\n", err); SyncDriveExit(); } printf("First channel configuration status = %d \n",err); // Now process any options that override the defaults for second device. init_config_array(1); // Now process any options that override the defaults for first device. if (argc > 1) process_options(argc, argv); err = MPA_SetConfig(&Handle2, pMPA_cfg, pMPA_cfgOut); if(err != ERR_NO_ERROR) { printf("ERROR: Unable to configure second device. Error code %d.\n", err); exit(-1); } //You must close and reopen for configuration values to take effect err = MPA_Close(&Handle2); if(err != ERR_NO_ERROR) { printf("ERROR: Unable to close device. Error code %d.\n", err); SyncDriveExit(); } err = MPA_Open(&Handle2, deviceNumber2, overlapped); if(err != ERR_NO_ERROR) { printf("ERROR: Unable to open device. Error code %d.\n", err); SyncDriveExit(); } printf("Second channel configuration status = %d \n",err); // Reset frames ResetFrames(&Handle1, TRUE, TRUE); ResetFrames(&Handle2, TRUE, TRUE); printf("Press any key to start.\n"); while(!kbhit()); getch(); while(1) { transmit(); // initialize and transmit buffer timeout = 0; do { Sleep(100); MPA_GetFrameCount(&Handle2, &frameCnt); } while (frameCnt == 0 && ++timeout < TIMEOUT_SEC*10); if (timeout >= TIMEOUT_SEC*10) { printf("ERROR: Did not receive frame!\n"); break; } if ((result = MPA_GetData(&Handle2, pRxBuffer, SentbufferLen, &bytesWritten, NULL)) != ERR_NO_ERROR) { printf("ERROR: Unable to get data. Error code %d\n", result); } // put terminator in buffer to accommodate the printf statement *(pRxBuffer + SentbufferLen) = 0; // print received buffer printf("%s \n", pRxBuffer); // Compare the received buffer against transmitted buffer. if (strncmp(pRxBuffer, pTxBuffer, strlen(pTxBuffer)) != 0) { printf("Strings not the same. Rx Length = %i.\n", strlen(pRxBuffer)); } }//End while(1) } void ResetFrames(PMPA_HANDLE pHandle, BOOLEAN tx, BOOLEAN rx) { MPA_ERROR_CODE result; MPA_RESET_FRAMES reset; if (tx && rx) printf("Resetting Tx and Rx frame buffers.\n"); else if (tx) printf("Resetting Tx frame buffer.\n"); else if (rx) printf("Resetting Rx frame buffer.\n"); else printf("ERROR: Resetting neither frame buffer.\n"); reset.structLen = sizeof(MPA_RESET_FRAMES); reset.tx = tx; reset.rx = rx; if ((result = MPA_ResetFrames(pHandle, &reset)) != ERR_NO_ERROR) { printf("ERROR: Unable to reset Tx and Rx frame buffers. Error code %d\n", result); } }