Created
October 31, 2019 15:57
-
-
Save gitlarryf/51ce859b9cc4616b54690daf2536a7d9 to your computer and use it in GitHub Desktop.
Default MVI69E-LDM Backplane sample source code
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
///////////////////////////////////////////////////////////////////////////// | |
// backplane_sample.c | |
// | |
// This file contains sample code for the MVI69E-LDM module. | |
// | |
// (c) 2013, Prosoft Technology , All Rights Reserved | |
// | |
// MODIFIED : | |
// 4/18/2013 -- PJB | |
// | |
///////////////////////////////////////////////////////////////////////////// | |
#include <stdlib.h> | |
#include <sys/time.h> | |
#include <time.h> | |
#include <unistd.h> | |
#include <stdio.h> | |
#include <string.h> | |
#include <signal.h> | |
#include "mvi69api.h" | |
MVI69HANDLE MVI69_Handle = (MVI69HANDLE) NULL; | |
MVI69MODULEINFO Module_Info; | |
MVI69IOCONFIG IO_Config; | |
int Last_Run_Mode = -1; | |
#define MODE( m ) ((m == MVI69_RUN_MODE ) ? "RUN" : ((m == MVI69_PROGRAM_MODE) ? "Program" : "unknown" )) | |
WORD Read_Buffer[MVI69_MAX_OUTPUT_WORDS]; | |
WORD Write_Buffer[MVI69_MAX_INPUT_WORDS]; | |
// offset into the read buffer | |
#define OFFSET 0 | |
// timeout to wait for scan (in milliseconds ) | |
#define TIMEOUT 1000L | |
///////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
// | |
// open_backplane( void ) | |
// Input: | |
// none | |
// | |
// Output: | |
// The global MVI69_Handle is set if successful. | |
// | |
// Description: | |
// Opens a connection to the backplane driver, allow access to some of the module hardware | |
// including backplane communication | |
// | |
///////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
void open_backplane( void ) | |
{ | |
int result; | |
// set module information object | |
Module_Info.VendorID = 309; // prosoft | |
Module_Info.DeviceType = 12; // communications adapter | |
Module_Info.ProductCode = 6112; // EDS product code LDM | |
Module_Info.MajorRevision = 1; // major revision 1 | |
Module_Info.MinorRevision = 1; // minor revision 1 | |
strcpy((char *)Module_Info.Name, "MVI69E-LDM" ); | |
result = MVI69_SetModuleInfo( MVI69_Handle, &Module_Info ); | |
if ( result != MVI69_SUCCESS ) | |
{ | |
printf( "mvi69 Set Module info failed: %d\n", result ); | |
exit( -1 ); | |
} | |
// open access to backplane/hardware driver | |
result = MVI69_Open( &MVI69_Handle ); | |
if ( result != MVI69_SUCCESS ) | |
{ | |
printf( "MVI69 open failed: %d\n", result ); | |
exit( -1 ); | |
} | |
result = MVI69_GetIOConfig( MVI69_Handle, &IO_Config ); | |
if ( result != MVI69_SUCCESS ) | |
{ | |
printf( "MVI69 Get IO config failed: %d\n", result ); | |
exit( -1 ); | |
} | |
printf( "IO Config: Input (Mapped words) %d\n", IO_Config.MappedInputWords ); | |
printf( "IO Config: Output (Mapped words) %d\n", IO_Config.MappedOutputWords ); | |
printf( "IO Config: Received msg size(words) %d\n", IO_Config.MsgRcvBufSize ); | |
printf( "IO Config: Sent Msg Size(words) %d\n", IO_Config.MsgSndBufSize ); | |
// make sure that the input and output sizes are not bigger than our buffer. | |
if ( IO_Config.MappedInputWords > MVI69_MAX_INPUT_WORDS ) | |
IO_Config.MappedInputWords = MVI69_MAX_INPUT_WORDS; | |
if ( IO_Config.MappedOutputWords > MVI69_MAX_OUTPUT_WORDS ) | |
IO_Config.MappedOutputWords = MVI69_MAX_OUTPUT_WORDS; | |
// Read the Module information | |
result = MVI69_GetModuleInfo( MVI69_Handle, &Module_Info ); | |
if ( result != MVI69_SUCCESS ) | |
{ | |
printf( "MVI69 Get Module Info failed: %d\n", result ); | |
exit( -1 ); | |
} | |
else | |
{ | |
printf("\nModule Information:\n"); | |
printf("::Vendor ID : %d\n", Module_Info.VendorID ); | |
printf("::Device Type : %d\n", Module_Info.DeviceType ); | |
printf("::Product Code : %d\n", Module_Info.ProductCode ); | |
printf("::Major Rev. : %d\n", Module_Info.MajorRevision ); | |
printf("::Minor Rev. : %d\n", Module_Info.MinorRevision ); | |
printf("::Serial No. : %lu (0x%04lX)\n", Module_Info.SerialNo, Module_Info.SerialNo ); | |
printf("::Name : %s\n", Module_Info.Name ); | |
} | |
} | |
///////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
// | |
// sigquit_handler( int sig ) | |
// | |
// sig - is the signal that caused the invocation. | |
// | |
// This is the normal exit routine for the application. It is called when the program exits and | |
// when the following signals are received: SIGSEGV, SIGQUIT, SIGINT or SIGTERM. This function will cause | |
// the module to exit(not reboot) after the application closes all the resources. | |
// | |
///////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
void sigquit_handler( int sig ) | |
{ | |
// close backplane | |
MVI69_Close( MVI69_Handle ); | |
printf( "ERROR: Killed by signal %d!\n", sig ); | |
exit( 2 ); | |
} | |
///////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
// | |
// main program | |
// Input: | |
// argc - argument count. | |
// argv - list of arguments. | |
// | |
// Description: This program | |
// - establishes communication with the Control Logix Controller. | |
// - reads the Controller's Clock and displays | |
// - Reads a block of data from the controller, | |
// and writes that block back to the controller. | |
// | |
///////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
int main( int argc, char * argv[] ) | |
{ | |
int result; | |
int run_mode; | |
DWORD scan_count; | |
static WORD Last_Read_Data_Sample = -1; | |
int i; | |
int transfer_size; | |
printf("\nProgram Initialization....\n"); | |
// set up special event handlers. | |
signal( SIGSEGV, sigquit_handler ); | |
signal( SIGQUIT, sigquit_handler ); | |
signal( SIGINT, sigquit_handler ); | |
signal( SIGTERM, sigquit_handler ); | |
// print version info and exit if requested. | |
if ( argc > 1 ) | |
{ | |
if ( argv[1][0] == '-' && ( argv[1][1] == 'h' || argv[1][1] == 'H' )) | |
{ | |
printf( "\n Usage:\n BackPlane\n Communicates over the backplane transfering the output" ); | |
printf( "\n block back to the input block.\n There are no params\n" ); | |
exit( -1 ); | |
} | |
} | |
// open access to backplane and hardware | |
open_backplane(); | |
// echo back copy is limited by the smaller of the input or output image size | |
if ( IO_Config.MappedInputWords > IO_Config.MappedOutputWords ) | |
transfer_size = IO_Config.MappedOutputWords; | |
else | |
transfer_size = IO_Config.MappedInputWords; | |
// initialize LED | |
MVI69_SetLED( MVI69_Handle, MVI69_LEDID_OK, MVI69_LED_STATE_GREEN ); | |
MVI69_SetLED( MVI69_Handle, MVI69_LEDID_CFG, MVI69_LED_STATE_GREEN ); | |
MVI69_SetLED( MVI69_Handle, MVI69_LEDID_P1, MVI69_LED_STATE_OFF ); | |
MVI69_SetLED( MVI69_Handle, MVI69_LEDID_P2, MVI69_LED_STATE_OFF ); | |
MVI69_SetLED( MVI69_Handle, MVI69_LEDID_BP, MVI69_LED_STATE_OFF ); | |
MVI69_SetLED( MVI69_Handle, MVI69_LEDID_NET, MVI69_LED_STATE_GREEN ); | |
printf( "\nProgram Running....\n" ); | |
// main task loop, stay here forever | |
while ( 1 ) | |
{ | |
// read the scan mode from the backplane. | |
result = MVI69_GetScanMode( MVI69_Handle, &run_mode ); | |
if ( result != MVI69_SUCCESS ) | |
{ | |
printf( "MVI69 Get Scan Mode failed: %d\n", result ); | |
exit( -1 ); | |
} | |
if ( run_mode != Last_Run_Mode ) | |
{ | |
printf( "\nRun mode changed from %s to %s \n", MODE( Last_Run_Mode ), MODE( run_mode )); | |
Last_Run_Mode = run_mode; | |
} | |
// wait for the the next input (output does exactly the same thing) scan. | |
result = MVI69_WaitForInputScan( MVI69_Handle, TIMEOUT ); | |
// result = MVI69_WaitForOutputScan( MVI69_Handle, TIMEOUT ); | |
if ( result != MVI69_ERR_TIMEOUT ) | |
{ | |
if ( result != MVI69_SUCCESS ) | |
{ | |
printf( "MVI69 wait for scan failed: %d\n", result ); | |
exit( -1 ); | |
} | |
// read the current scan count | |
result = MVI69_GetScanCounter( MVI69_Handle, &scan_count ); | |
if ( result != MVI69_SUCCESS ) | |
{ | |
printf( "MVI69 Get Scan Counter failed: %d\n", result ); | |
exit( -1 ); | |
} | |
//read connected data from module | |
result = MVI69_ReadOutputImage( MVI69_Handle, | |
OFFSET, | |
IO_Config.MappedOutputWords, | |
Read_Buffer ); | |
if ( result != MVI69_SUCCESS ) | |
{ | |
printf( "MVI69 Read Output Image failed: %d\n", result ); | |
exit( -1 ); | |
} | |
// play with data block | |
// if the data changed in the output from controller, copy it back to the controller. | |
// otherwise decrement it down to zero | |
if ( Read_Buffer[2] != Last_Read_Data_Sample ) | |
{ | |
// there is new output data, so just copy the new output data to the input area. | |
memcpy( Write_Buffer, Read_Buffer, transfer_size * 2 ); | |
Last_Read_Data_Sample = Read_Buffer[2]; | |
} | |
else | |
{ | |
// decrement the input (ie write) data | |
for ( i = 1; i < transfer_size; i++ ) | |
{ | |
if ( Write_Buffer[i] > 0 ) | |
Write_Buffer[i]--; | |
} | |
} | |
// put the scan count in the first element of the buffer | |
Write_Buffer[0] = scan_count % 5000; | |
// print the scan count every 5000 scans, just so we can see things are working. | |
//if ( Write_Buffer[0] == 0 ) | |
// printf("Scan count is %ld\n", scan_count ); | |
// write data back to controller input image | |
result = MVI69_WriteInputImage( MVI69_Handle, | |
OFFSET, | |
IO_Config.MappedInputWords, | |
Write_Buffer ); | |
if ( result != MVI69_SUCCESS ) | |
{ | |
printf( "MVI69 Write Input Image failed: %d\n", result ); | |
exit( -1 ); | |
} | |
} // if not timeout | |
} // main program loop | |
// this exit should never be executed, since the main loop is never ending. | |
exit( 1 ); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment