Click here to show toolbars of the Web Online Help System: show toolbars |
/******************************************************************************/ /* * File name: MsysIo.cpp * Location: See Matrox Example Launcher in the MIL Control Center * * * Synopsis: This example shows how to use the hardware command list and * the timers to achieve real-time and determinist control of * the auxiliary I/Os. * * The example can be configured to do a rotary encoder based * distance delay or a time based delay on an auxiliary * output. * * Copyright (C) Matrox Electronic Systems Ltd., 1992-2016. * All Rights Reserved */ #include <mil.h> #define PULSE_WIDTH 1000000000 /* 1 second pulse width. */ /* Auxiliary I/O change callback structure. */ typedef struct _HOOK_PARAM { MIL_ID MilSystem; MIL_ID CmdListId; MIL_INT64 Operation; MIL_DOUBLE Delay; } HOOK_PARAM, *PHOOK_PARAM; /* Example functions declarations. */ void RotaryEncoderDelayExample(MIL_ID MilSystem); void TimeDelayExample(MIL_ID MilSystem); MIL_INT MFTYPE IoHookFunction(MIL_INT HookType, MIL_ID EventId, void *UserDataPtr); /***************************************************************************** Main. *****************************************************************************/ int MosMain(void) { MIL_ID MilApplication, /* Application identifier. */ MilSystem; /* System identifier. */ MIL_INT Selection=1; /* Allocate a MIL application. */ MappAlloc(M_DEFAULT, &MilApplication); /* Allocate a host system. */ MsysAlloc(M_SYSTEM_HOST, M_DEFAULT, M_DEFAULT, &MilSystem); MosPrintf(MIL_TEXT("MsysIo example on 4Sight GPm:\n")); MosPrintf(MIL_TEXT("----------------------------------\n\n")); MosPrintf(MIL_TEXT("This example shows how to register a timed pulse after a specifed\n")); MosPrintf(MIL_TEXT("number of rotary encoder ticks or after a specified time when\n")); MosPrintf(MIL_TEXT("a trigger is received.\n")); MosPrintf(MIL_TEXT("Choose the type of delay:\n")); MosPrintf(MIL_TEXT("1) The delay is based on rotary encoder ticks.\n") ); MosPrintf(MIL_TEXT("2) The delay is based on time.\n")); Selection = MosGetch(); switch(Selection) { case '1': case '\r': RotaryEncoderDelayExample(MilSystem); break; case '2': TimeDelayExample(MilSystem); break; default: MosPrintf(MIL_TEXT("\nInvalid selection !.\n\nUsing delay based on time.\n\n")); TimeDelayExample(MilSystem); break; } MsysFree(MilSystem); MappFree(MilApplication); return 0; } /***************************************************************************** Delay in number of rotary encoder ticks example. *****************************************************************************/ void RotaryEncoderDelayExample(MIL_ID MilSystem) { MIL_ID MilCmdList; /* I/O Command List identifier. */ HOOK_PARAM HookParam; /* Input 1 on 4Sight GPm corresponds to M_AUX_IO8 in MIL. */ /* Input 2 on 4Sight GPm corresponds to M_AUX_IO9 in MIL. */ /* Input 3 on 4Sight GPm corresponds to M_AUX_IO10 in MIL. */ /* Output 8 on 4Sight GPm corresponds to M_AUX_IO7 in MIL. */ MosPrintf(MIL_TEXT("The delay will be based on rotary encoder ticks.\n\n")); MosPrintf(MIL_TEXT("Do the following connection:\n")); MosPrintf(MIL_TEXT("1- Connect a trigger signal or switch on Input 1 of 4Sight GPm.\n")); MosPrintf(MIL_TEXT("2- Connect Line A of rotary encoder to Input 2 of 4Sight GPm.\n")); MosPrintf(MIL_TEXT("3- Connect Line B of rotary encoder to Input 3 of 4Sight GPm.\n")); MosPrintf(MIL_TEXT("4- Verify or probe Output 8 of 4Sight GPm.\n")); MosPrintf(MIL_TEXT("Press <Enter> when ready.\n\n")); MosGetch(); /* Setup Rotary encoder input (ex: positional information). */ MsysControl(MilSystem, M_ROTARY_ENCODER_BIT0_SOURCE + M_ROTARY_ENCODER1, M_AUX_IO9); /* Connector's Input 2. */ MsysControl(MilSystem, M_ROTARY_ENCODER_BIT1_SOURCE + M_ROTARY_ENCODER1, M_AUX_IO10); /* Connector's Input 3. */ MsysControl(MilSystem, M_ROTARY_ENCODER_OUTPUT_MODE + M_ROTARY_ENCODER1, M_STEP_FORWARD); MsysControl(MilSystem, M_ROTARY_ENCODER_STATE + M_ROTARY_ENCODER1, M_ENABLE); /* Setup I/O Output (Ex: ejector pulse). */ MsysControl(MilSystem, M_IO_SOURCE + M_AUX_IO7, M_TIMER1); /* Connector's Output 8. */ MsysControl(MilSystem, M_TIMER_TRIGGER_ACTIVATION+M_TIMER1, M_DEFAULT); /* Edge rising. */ MsysControl(MilSystem, M_TIMER_DELAY+M_TIMER1, 0); MsysControl(MilSystem, M_TIMER_DURATION+M_TIMER1, PULSE_WIDTH); MsysControl(MilSystem, M_TIMER_TRIGGER_SOURCE + M_TIMER1, M_IO_COMMAND_LIST1 + M_IO_COMMAND_BIT0); MsysControl(MilSystem, M_TIMER_STATE + M_TIMER1, M_ENABLE); /* Allocate a command list based on Rotary Encoder 1. */ MilCmdList = MsysIoAlloc(MilSystem, M_IO_COMMAND_LIST1, M_IO_COMMAND_LIST, M_ROTARY_ENCODER1, M_NULL); if (MilCmdList!= M_NULL) { /* We will latch counter upon reception of a trigger on connector's Input 1 */ /* (M_AUX_IO8). */ MsysIoControl(MilCmdList, M_REFERENCE_LATCH_TRIGGER_SOURCE+M_LATCH1, M_AUX_IO8); MsysIoControl(MilCmdList, M_REFERENCE_LATCH_ACTIVATION+M_LATCH1, M_EDGE_RISING); MsysIoControl(MilCmdList, M_REFERENCE_LATCH_STATE+M_LATCH1, M_ENABLE); /* Debounce Input 1 during 25 ms. */ MsysControl(MilSystem, M_IO_DEBOUNCE_TIME+M_AUX_IO8, 25000000); /* Enable interrupt generation on reception of a trigger on M_AUX_IO8 */ /* (ex: object detection) and hook a callback function to it. */ MsysControl(MilSystem, M_IO_INTERRUPT_ACTIVATION+M_AUX_IO8, M_EDGE_RISING); HookParam.MilSystem = MilSystem; HookParam.CmdListId = MilCmdList; HookParam.Operation = M_IMPULSE; HookParam.Delay = 100; /* 100 rotary encoder ticks after trigger */ MsysHookFunction(MilSystem, M_IO_CHANGE, IoHookFunction, &HookParam); MsysControl(MilSystem, M_IO_INTERRUPT_STATE+M_AUX_IO8, M_ENABLE); MosPrintf(MIL_TEXT("Activate your rotary encoder.\n")); MosPrintf(MIL_TEXT("Send a rising edge trigger to Input 1.\n")); MosPrintf(MIL_TEXT("Verify 1 second pulse (100 ticks after trigger) on Output 8.\n")); MosPrintf(MIL_TEXT("Press <Enter> when you are ready to end.\n\n")); MosGetch(); /* Put back important controls to default value. */ MsysControl(MilSystem, M_TIMER_STATE + M_TIMER1, M_DEFAULT); MsysControl(MilSystem, M_IO_SOURCE+M_AUX_IO0, M_USER_BIT0); MsysIoControl(MilCmdList, M_REFERENCE_LATCH_STATE+M_LATCH1, M_DEFAULT); MsysControl(MilSystem, M_IO_INTERRUPT_STATE+M_AUX_IO8, M_DEFAULT); MsysControl(MilSystem, M_IO_DEBOUNCE_TIME+M_AUX_IO8, 0); /* Unhook the callback function. */ MsysHookFunction(MilSystem, M_IO_CHANGE+M_UNHOOK, IoHookFunction, &HookParam); /* Free the I/O command list. */ MsysIoFree(MilCmdList); } else { MosPrintf(MIL_TEXT("MIL was unable to allocate an I/O command list.\n")); MosPrintf(MIL_TEXT("Press <Enter> to end.\n")); MosGetch(); } } /***************************************************************************** Delay in time example. *****************************************************************************/ void TimeDelayExample(MIL_ID MilSystem) { MIL_ID MilCmdList; /* I/O Command List identifier. */ HOOK_PARAM HookParam; /* Input 1 on 4Sight GPm corresponds to M_AUX_IO8 in MIL. */ /* Output 8 on 4Sight GPm corresponds to M_AUX_IO7 in MIL. */ MosPrintf(MIL_TEXT("The delay will be based on time.\n\n")); MosPrintf(MIL_TEXT("Do the following connection:\n")); MosPrintf(MIL_TEXT("1- Connect a trigger signal or switch on Input 1 of 4Sight GPm.\n")); MosPrintf(MIL_TEXT("2- Verify or probe Output 8 of 4Sight GPm.\n")); MosPrintf(MIL_TEXT("Press <Enter> when ready.\n\n")); MosGetch(); MsysControl(MilSystem, M_IO_SOURCE + M_AUX_IO7, M_IO_COMMAND_LIST1 + M_IO_COMMAND_BIT0); /* Connector's Output 8. */ /* Allocate a command list based on time. */ MilCmdList = MsysIoAlloc(MilSystem, M_IO_COMMAND_LIST1, M_IO_COMMAND_LIST, M_CLOCK, M_NULL); if (MilCmdList!= M_NULL) { /* We will latch counter upon reception of a trigger on connector's Input 1 */ /* (M_AUX_IO8). */ MsysIoControl(MilCmdList, M_REFERENCE_LATCH_TRIGGER_SOURCE+M_LATCH1, M_AUX_IO8); MsysIoControl(MilCmdList, M_REFERENCE_LATCH_ACTIVATION+M_LATCH1, M_EDGE_RISING); MsysIoControl(MilCmdList, M_REFERENCE_LATCH_STATE+M_LATCH1, M_ENABLE); /* Debounce INPUT 1 during 25 ms. */ MsysControl(MilSystem, M_IO_DEBOUNCE_TIME+M_AUX_IO8, 25000000); /* Enable interrupt generation on reception of a trigger on M_AUX_IO8 */ /* (ex: object detection) and hook a callback function to it. */ MsysControl(MilSystem, M_IO_INTERRUPT_ACTIVATION+M_AUX_IO8, M_EDGE_RISING); HookParam.MilSystem = MilSystem; HookParam.CmdListId = MilCmdList; HookParam.Operation = M_EDGE_RISING; HookParam.Delay = 2; /* 2 seconds after trigger. */ MsysHookFunction(MilSystem, M_IO_CHANGE, IoHookFunction, &HookParam); MsysControl(MilSystem, M_IO_INTERRUPT_STATE+M_AUX_IO8, M_ENABLE); MosPrintf(MIL_TEXT("Send a rising edge trigger to Input 1.\n")); MosPrintf(MIL_TEXT("Verify toggle of Output 8, 2 seconds after trigger.\n")); MosPrintf(MIL_TEXT("Press <Enter> when you are ready to end.\n\n")); MosGetch(); /* Put back important controls to default value. */ MsysControl(MilSystem, M_IO_SOURCE+M_AUX_IO0, M_USER_BIT0); MsysIoControl(MilCmdList, M_REFERENCE_LATCH_STATE+M_LATCH1, M_DEFAULT); MsysControl(MilSystem, M_IO_INTERRUPT_STATE+M_AUX_IO8, M_DEFAULT); MsysControl(MilSystem, M_IO_DEBOUNCE_TIME+M_AUX_IO8, 0); /* Unhook the callback function. */ MsysHookFunction(MilSystem, M_IO_CHANGE+M_UNHOOK, IoHookFunction, &HookParam); /* Free the I/O command list. */ MsysIoFree(MilCmdList); } else { MosPrintf(MIL_TEXT("MIL was unable to allocate an I/O command list.\n")); MosPrintf(MIL_TEXT("Press <Enter> to end.\n")); MosGetch(); } } /* Interrupt hook function. */ MIL_INT MFTYPE IoHookFunction(MIL_INT HookType, MIL_ID EventId, void *UserDataPtr) { PHOOK_PARAM pHookParam = (PHOOK_PARAM)UserDataPtr; MIL_INT PinNb = 0; MIL_INT Status; MIL_INT64 RefStamp; /* If the callback is for M_AUX_IO8. */ MsysGetHookInfo(pHookParam->MilSystem, EventId, M_IO_INTERRUPT_SOURCE, &PinNb); if (PinNb == M_AUX_IO8) { MsysGetHookInfo(pHookParam->MilSystem, EventId, M_REFERENCE_LATCH_VALUE+M_IO_COMMAND_LIST1+M_LATCH1, &RefStamp); MsysIoCommandRegister(pHookParam->CmdListId, pHookParam->Operation, RefStamp, pHookParam->Delay, M_DEFAULT, M_IO_COMMAND_BIT0, &Status); if (pHookParam->Operation == M_EDGE_RISING) pHookParam->Operation = M_EDGE_FALLING; else if (pHookParam->Operation == M_EDGE_FALLING) pHookParam->Operation = M_EDGE_RISING; if (Status == M_NULL) MosPrintf(MIL_TEXT("MIL successfully registered an I/O event.\n")); else if (Status == M_INVALID) MosPrintf(MIL_TEXT( "MIL determined that the position where to register an I/O is passed.\n")); } return M_NULL; }