#include <stdio.h>
#include <unistd.h>
#include "i8094_dll.h"

#define MAX_INTERP_SEGMENT		8

typedef struct _CONTI_INTERP_SEGMENT_
{
	long MainAxisFinishPoint;	/* Finish point of MainAxis */
	long SlaveAxisFinishPoint;	/* Finish point of SlaveAxis */
	
	long MainAxisCenterPoint;	/* Center point of MainAxis */
	long SlaveAxisCenterPoint;	/* Center point of SlaveAxis */
}CONTI_INTERP_SEGMENT;

BYTE bCardID = 0; //bCardID=(bSlotNum-1), if the I-8094 plug-in Slot 2 of LinPAC, bCardID=2-1=1 


CONTI_INTERP_SEGMENT ContiInterpSeg[MAX_INTERP_SEGMENT] = {
	{ 45000,     0,       0,      0},   // Continue-Interpolation Segment 1
	{ 15000,  15000,      0,  15000},   // Continue-Interpolation Segment 2
	{     0,  15000,      0,      0},   // Continue-Interpolation Segment 3
	{-15000,  15000, -15000,      0},   // Continue-Interpolation Segment 4
	{-45000,      0,      0,      0},   // Continue-Interpolation Segment 5
	{-15000, -15000,      0, -15000},   // Continue-Interpolation Segment 6
	{     0, -15000,      0,      0},   // Continue-Interpolation Segment 7
	{ 15000, -15000,  15000,      0} }; // Continue-Interpolation Segment 8

int main( void )
{

   short nRet;
   BYTE bDone, bReady;
   WORD wStopStatus;
   long nCmdCntX, nCmdCntY;
   DWORD dwSpeedX;
   int SegIndex, DispCnt;

   nRet = i8094_open( bCardID ); 
   if( nRet == SUCCESS_NO_ERROR )
   {
	nRet = i8094_set_pls_cfg( bCardID, AXIS_X, PULSE_MODE_CW_CCW, PULSE_LOGIC_ACTIVE_HIGH, PARAMETER_IGNORED );
	printf(" [AXIS-X] i8094_set_pls_cfg returns = %d\n", nRet );
			
	nRet = i8094_set_enc_cfg( bCardID, AXIS_X, ENCODER_MODE_CW_CCW, 0 );
	printf(" [AXIS-X] i8094_set_enc_cfg returns = %d\n", nRet );

	nRet = i8094_set_limit( bCardID, AXIS_X, LIMIT_LOGIC_ACTIVE_LOW, LIMIT_STOP_SUDDEN );
	printf(" [AXIS-X] i8094_set_limit returns = %d\n", nRet );

	nRet = i8094_set_cmdcounter( bCardID, AXIS_X, 0);
	printf(" [AXIS-X] i8094_set_cmdcounter returns = %d\n", nRet );

	nRet = i8094_set_pls_cfg( bCardID, AXIS_Y, PULSE_MODE_CW_CCW, PULSE_LOGIC_ACTIVE_HIGH, PARAMETER_IGNORED );
	printf(" [AXIS-Y] i8094_set_pls_cfg returns = %d\n", nRet );
			
	nRet = i8094_set_enc_cfg( bCardID, AXIS_Y, ENCODER_MODE_CW_CCW, 0 );
	printf(" [AXIS-Y] i8094_set_enc_cfg returns = %d\n", nRet );

	nRet = i8094_set_limit( bCardID, AXIS_Y, LIMIT_LOGIC_ACTIVE_LOW, LIMIT_STOP_SUDDEN );
	printf(" [AXIS-Y] i8094_set_limit returns = %d\n", nRet );

	nRet = i8094_set_cmdcounter( bCardID, AXIS_Y, 0);
	printf(" [AXIS-Y] i8094_set_cmdcounter returns = %d\n", nRet );


	nRet = i8094_conti_interp_begin( bCardID, AXIS_X, AXIS_Y, 0x00, 5000 );
	printf(" i8094_conti_interp_begin returns = %d\n", nRet );

	if( nRet != SUCCESS_NO_ERROR )
	    goto Close_Device;


	SegIndex = 0; 

	nRet = i8094_conti_line2_move( bCardID, ContiInterpSeg[SegIndex].MainAxisFinishPoint, ContiInterpSeg[SegIndex].SlaveAxisFinishPoint, INTERP_CONTINUE_START );
	printf(" i8094_conti_line2_move returns = %d\n", nRet );
	if( nRet != SUCCESS_NO_ERROR )
	    goto Close_Device;

	SegIndex ++;

	DispCnt = 0;
	do{

	    if( SegIndex < MAX_INTERP_SEGMENT ) // completion of Continue-Interpolation
	    {
		    nRet = i8094_conti_interp_next_ready( bCardID, &bReady );
		    if( nRet != SUCCESS_NO_ERROR )
		    break;

		    if( bReady == CONTINUE_INTERPOLATION_NEXT_READY )
		    {
		        if( (SegIndex % 2) == 0 )  // Segment 1, 3, 5, 7 - Linear Interpolation
		        {
			         nRet = i8094_conti_line2_move( bCardID, ContiInterpSeg[SegIndex].MainAxisFinishPoint, ContiInterpSeg[SegIndex].SlaveAxisFinishPoint, INTERP_NEXT_CONTINUOUS_MOTION );
			         printf(" i8094_conti_line2_move returns = %d\n", nRet );

			         if( nRet != SUCCESS_NO_ERROR )
			             break;
			         else
			             SegIndex ++;
		        }
		        else // Segment 2, 4, 6, 8 - Arc Interpolation
		        {
			         nRet = i8094_conti_arc2_move( bCardID, INTERP_ARC_DIRECTION_COUNTER_CLOCKWISE, ContiInterpSeg[SegIndex].MainAxisCenterPoint, ContiInterpSeg[SegIndex].SlaveAxisCenterPoint, ContiInterpSeg[SegIndex].MainAxisFinishPoint, ContiInterpSeg[SegIndex].SlaveAxisFinishPoint, INTERP_NEXT_CONTINUOUS_MOTION );
			         printf(" i8094_conti_arc2_move returns = %d\n", nRet );

			         if( nRet != SUCCESS_NO_ERROR )
			           break;
			         else
			           SegIndex ++;
		        } // if( (m_SegIndex % 2) == 0 ) 	

		    } // if( bReady == CONTINUE_INTERPOLATION_NEXT_READY )

	    } // if( SegIndex < MAX_INTERP_SEGMENT )

	    nRet = i8094_motion_done( bCardID, AXIS_X, &bDone, &wStopStatus );

	    if( (DispCnt % 20) == 0 ) // display command-counters every 1 sec.
	    {
		    i8094_get_cmdcounter( bCardID, AXIS_X, &nCmdCntX);
		    i8094_get_cmdcounter( bCardID, AXIS_Y, &nCmdCntY);
		    i8094_get_speed( bCardID, AXIS_X, &dwSpeedX );

		    printf(" [Speed-X = %ld]  [CmdCounter-X = %ld]  [CmdCounter-Y = %ld]\n", dwSpeedX, nCmdCntX, nCmdCntY );
	    }

	    DispCnt ++;
				
	    usleep( 50000 ); // sleep 50ms

	}while( bDone == MOTION_NOT_DONE );

	printf(" nRet = %d  bDone = %d  wStopStatus = 0x%X\n", nRet, bDone, wStopStatus );


Close_Device:
	i8094_conti_interp_end( bCardID );
	i8094_close( bCardID );
  }
  else
	   printf(" i8094_open() return %d !\n", nRet ); 

   return 0;
}

