/* Example of Timer pacer trigger with DMA (ASYNC, double buffer) for PCI-D64HU

   Author: Moki

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */

/* File level history (record changes for this file here.)

   v 0.0.0 12 Aug 2016 by Moki
     create, blah blah... */


#define _10MHz_BASE_CLOCK_

#include "PlxApi.h"

#if defined(PLX_LINUX)
    #include "ConsFunc.h"
    #include "PlxInit.h"
#endif

#include "PLX_Inc/Reg9054.h"
#include "D64HDLL.h"
#include "d64h_private.h"
#include "d64h_cpld.h"

/******************************************************************************
 *
 * Function   :  main
 *
 * Description:  The main entry point
 *
 *****************************************************************************/
int main(void)
{
	PLX_STATUS              rc;
	U16                     u16Val;
	U32                     u32Val;
	U32                     count;
	short                   wCardNum, nErrCode;
	BYTE                    bCardID;
	int			i,j,k;
	U32			u32DIBuf[4096];
	U32			u32DOBuf[4096];
	F64			SampleRate = 10;
	U16                     fifoStatus;
	BOOLEAN                 bStopped, bReady;

	nErrCode = initLib();
	if( nErrCode != SUCCESS_NO_ERROR )
	{
		ConsoleEnd();
		exit(0);
	}

	nErrCode = d64h_scan( &wCardNum, NULL );
	if( nErrCode == SUCCESS_NO_ERROR )
	{
		Cons_printf("found %d cards, ", wCardNum);
	}

	nErrCode = d64h_cardinfo_get( 0, &bCardID );
	if( nErrCode == SUCCESS_NO_ERROR )
	{
		Cons_printf("first card id = %d\n\n", bCardID);
	} else {
		Cons_printf("\n\n");
		ConsoleEnd();
		exit(0);
	}
	rc = d64h_open( bCardID );

	if (rc != ApiSuccess)
	{
		Cons_printf("\n   ERROR: Unable to find or select a PLX device\n");
		PlxSdkErrorDisplay(rc);
		_Pause;
		ConsoleEnd();
		exit(-1);
	}
//	memcpy(&DeviceKey, &(D64H_CPLD[bCardID].DevKey_DMA), sizeof(PLX_DEVICE_KEY));
//	memcpy(&Device, &(D64H_CPLD[bCardID].Device), sizeof(PLX_DEVICE_OBJECT));

	for(i=0; i<4096; i++) {
		u32DOBuf[i] = i;
	}

	Cons_printf("Demo timer_dma_double_buff : Timer pacer trigger with DMA (ASYNC, double buffer)\n");

	        nErrCode = d64h_do_config( bCardID, TRIG_SOURCE_INT_PACER, OREQ_DISABLE, IREQ_FALLING);
        nErrCode = d64h_di_config( bCardID, TRIG_SOURCE_INT_PACER, DI_NOWAITING, DI_TRIG_RISING, IREQ_FALLING);
        nErrCode = d64h_continue_writeport(bCardID, u32DOBuf, 0x12, 0, &SampleRate, ASYNCH_OP);
        //nErrCode = d64h_continue_writeport(bCardID, u32DOBuf, 512, 0, &SampleRate, ASYNCH_OP);
        nErrCode = d64h_continue_readport(bCardID, u32DIBuf, 0x20, &SampleRate, ASYNCH_OP);
        k = 0;
        while(1) {
                nErrCode = d64h_do_async_dblbuf_halfready(bCardID, &bReady);
                //nErrCode = d64h_do_async_dblbuf_halfready(bCardID, &bReady, &count );
                if(bReady == TRUE) {
                        nErrCode = d64h_do_async_dblbuf_transfer(bCardID, u32DOBuf);
                }
                nErrCode = d64h_di_async_dblbuf_halfready( bCardID, &bReady);
                //nErrCode = d64h_di_async_dblbuf_halfready( bCardID, &bReady, &count );
                if(bReady == TRUE) {
                        nErrCode = d64h_di_async_dblbuf_transfer(bCardID, u32DIBuf);
                        for(i=0; i<0x20; i++) {
                                if(i%0x8 == 0) Cons_printf("\n%d:%02X : ",k ,i);
                                Cons_printf("0x%08X ", u32DIBuf[i]);
                        }
                        Cons_printf("\n");
                        k++;
                        if(k>8) break;
                }
        }
        nErrCode = d64h_di_async_clear( bCardID, &count );
        Cons_printf("DI async clear with Count = %d\n", count);
        nErrCode = d64h_do_async_clear( bCardID, &count );
        Cons_printf("DO async clear with Count = %d\n", count);
        if( nErrCode != SUCCESS_NO_ERROR )
        {
        }
        for(i=0; i<0x20; i++) {
                if(i%0x8 == 0) Cons_printf("\n%d:%02X : ",k ,i);
                Cons_printf("0x%08X ", u32DIBuf[i]);
        }

	Cons_printf("\n\n");

	d64h_close(bCardID);

	return 0;
}

