
#include <stdint.h>
#include <stdio.h>
#include "xil_printf.h"
#include "ff.h"
#include "platform.h"

#include "tiAfe79_afeGlobalConstants.h"
#include "tiAfe79_afeLibGlobals.h"
#include "tiAfe79_afeCommonMacros.h"
#include "tiAfe79_baseFunc.h"
#include "tiAfe79_afeParameters.h"
#include "tiAfe79_basicFunctions.h"
#include "tiAfe79_macro.h"
#include "tiAfe79_controls.h"
#include "tiAfe79_calibrations.h"
#include "tiAfe79_dsaAndNco.h"
#include "tiAfe79_jesd.h"
#include "tiAfe79_serDes.h"
#include "tiAfe79_pap.h"
#include "tiAfe79_agc.h"
#include "tiAfe79_init.h"
#include "tiAfe79_paramsSetterGetter.h"


//#define SD_FILE_NAME	"Afe79xxPg1.hex"

int		g_nExecSertUp;
void init_tiAfe79DeviceInfo_t();
extern afe79InstDeviceInfo tiAfe79DeviceInfo_t[2];

#define FPGA_ADDR_BASE          ((long)0x80000000)          // FPGA base address

int afe_setup( int no )
{
	char	fname[32];
	FIL		fil;

	sprintf( fname, "Afe79xxPg%d.hex", no );
	if( f_open( &fil, fname, FA_READ ) )
    {
		xil_printf( "file not found\r\n" );
        return -1;
    }
	g_nExecSertUp = 1;

	init_tiAfe79DeviceInfo_t();
    AFE79FNP(setAfeLogLvl)( &tiAfe79DeviceInfo_t[0], 2 );
    AFE79FNP(overrideTdd)( &tiAfe79DeviceInfo_t[0], 0, 0, 0, 0 );
	tiAfe79DeviceInfo_t[0].afeSystemParams.enableRxDsaCalibration = 2;
    AFE79FNP(afeDeviceBringup)( &tiAfe79DeviceInfo_t[0],  fname, 0, 0 );

/*
    AFE79FNP(SetSerdesTxCursor)( &tiAfe79DeviceInfo_t[0], 0, 0,0,1);
    AFE79FNP(SetSerdesTxCursor)( &tiAfe79DeviceInfo_t[0], 1, 0,0,2);
	AFE79FNP(SetSerdesTxCursor)( &tiAfe79DeviceInfo_t[0], 2, 0,0,3);
	AFE79FNP(SetSerdesTxCursor)( &tiAfe79DeviceInfo_t[0], 3, 0,0,4);
	AFE79FNP(SetSerdesTxCursor)( &tiAfe79DeviceInfo_t[0], 4, 0,0,5);
	AFE79FNP(SetSerdesTxCursor)( &tiAfe79DeviceInfo_t[0], 5, 0,0,6);
	AFE79FNP(SetSerdesTxCursor)( &tiAfe79DeviceInfo_t[0], 6, 0,0,7);
	AFE79FNP(SetSerdesTxCursor)( &tiAfe79DeviceInfo_t[0], 7, 0,0,0);
*/
/*
    AFE79FNP(sendSerdesTxPrbs)( &tiAfe79DeviceInfo_t[0],0,0,1);
	AFE79FNP(sendSerdesTxPrbs)( &tiAfe79DeviceInfo_t[0],1,0,1);
	AFE79FNP(sendSerdesTxPrbs)( &tiAfe79DeviceInfo_t[0],2,0,1);
	AFE79FNP(sendSerdesTxPrbs)( &tiAfe79DeviceInfo_t[0],3,0,1);
	AFE79FNP(sendSerdesTxPrbs)( &tiAfe79DeviceInfo_t[0],4,0,1);
	AFE79FNP(sendSerdesTxPrbs)( &tiAfe79DeviceInfo_t[0],5,0,1);
	AFE79FNP(sendSerdesTxPrbs)( &tiAfe79DeviceInfo_t[0],6,0,1);
	AFE79FNP(sendSerdesTxPrbs)( &tiAfe79DeviceInfo_t[0],7,0,1);
*/
/*
    AFE79FNP(setJesdTxSyncOverride)(&tiAfe79DeviceInfo_t[0] , 0, 1, 1);
    AFE79FNP(setJesdTxSyncOverride)(&tiAfe79DeviceInfo_t[0] , 1, 1, 1);
    AFE79FNP(setJesdTxSyncOverride)(&tiAfe79DeviceInfo_t[0] , 2, 1, 1);
    AFE79FNP(setJesdTxSyncOverride)(&tiAfe79DeviceInfo_t[0] , 3, 1, 1);
    AFE79FNP(setJesdTxSyncOverride)(&tiAfe79DeviceInfo_t[0] , 4, 1, 1);
    AFE79FNP(setJesdTxSyncOverride)(&tiAfe79DeviceInfo_t[0] , 5, 1, 1);
 */
    g_nExecSertUp = 0;
	return 0;
}

int set_afe_enable( int rx, int tx )
{
	return AFE79FNP(overrideTdd)( &tiAfe79DeviceInfo_t[0], rx, 0, tx, 1 );

/*
	AFE79FNP(afeSpiWriteWrapper)( &tiAfe79DeviceInfo_t[0], 0xec,       1, 0, 7 );
	AFE79FNP(afeSpiWriteWrapper)( &tiAfe79DeviceInfo_t[0], 0xf4,       1, 0, 7 );
	AFE79FNP(afeSpiWriteWrapper)( &tiAfe79DeviceInfo_t[0], 0xe4,       1, 0, 7 );
	AFE79FNP(afeSpiWriteWrapper)( &tiAfe79DeviceInfo_t[0], 0xed,       0, 0, 7 );
	AFE79FNP(afeSpiWriteWrapper)( &tiAfe79DeviceInfo_t[0], 0xf5,       0, 0, 7 );
	AFE79FNP(afeSpiWriteWrapper)( &tiAfe79DeviceInfo_t[0], 0xe5,       0, 0, 7 );
	AFE79FNP(afeSpiWriteWrapper)( &tiAfe79DeviceInfo_t[0], 0xed, g_nRxCh, 0, 7 );
	AFE79FNP(afeSpiWriteWrapper)( &tiAfe79DeviceInfo_t[0], 0xf5,       0, 0, 7 );
	AFE79FNP(afeSpiWriteWrapper)( &tiAfe79DeviceInfo_t[0], 0xe5, g_nTxCh, 0, 7 );
*/
}

void set_afe_reg( int addr, unsigned int reg )
{
	AFE79FNP(afeSpiRawWrite)( &tiAfe79DeviceInfo_t[0], addr, reg );
}

void get_afe_reg( int addr, unsigned int *reg )
{
	unsigned char	val;

	AFE79FNP(afeSpiRawRead)( &tiAfe79DeviceInfo_t[0], addr, &val );
	*reg = val;
}

int set_adc_nco( int ch, int nco, unsigned int mixer )
{
	int		i, rtn = 0;

	if( ch == 4 )
	{
		for( i=0; i<4; i++ )	rtn |= AFE79FNP(updateRxNco)( &tiAfe79DeviceInfo_t[0], i, mixer, 0, nco );
	}
	else
		rtn = AFE79FNP(updateRxNco)( &tiAfe79DeviceInfo_t[0], ch, mixer, 0, nco );

	return rtn;
}

int set_adc_dsa( int ch, unsigned int dsa )
{
    return AFE79FNP(setRxDsa)( &tiAfe79DeviceInfo_t[0], ch, dsa );
}

void get_adc_nco( int ch, unsigned int *freq1 )
{
	int		reg;

	reg = *((volatile unsigned int *)(FPGA_ADDR_BASE + 0x11210)) & 0x01;
	*freq1 = tiAfe79DeviceInfo_t[0].afeSystemParams.rxNco[reg][ch][0];
}

int set_adc_do_calibration( int no )
{
	unsigned short	num = 0;
	unsigned char	data[2048+OVERHEAD_SIZE];
	
	AFE79FNP(doRxDsaCalib)( &tiAfe79DeviceInfo_t[0], 0x0f, 0x00, 0, 0, &data[OVERHEAD_SIZE+sizeof(short)], &num );

	if( !num )	return -1;

	*((unsigned short *)&data[OVERHEAD_SIZE]) = num;
	spi_eeprom_write( EEP_ADC_CALIB_ADR(no), sizeof(short) + num, data );

	return 0;
}

int set_adc_load_calibration( int no )
{
	unsigned short	num;
	unsigned char	data[2048+READ_DATA_OFFSET];
	
	spi_eeprom_read( EEP_ADC_CALIB_ADR(no), 2048, data );
	num = *((unsigned short *)&data[READ_DATA_OFFSET]);

	return AFE79FNP(loadRxDsaPacket)( &tiAfe79DeviceInfo_t[0], &data[READ_DATA_OFFSET+sizeof(short)], num );
}

int set_dac_nco( int ch, int nco, unsigned int mixer )
{
	int		i, rtn = 0;

	if( ch == 4 )
	{
		for( i=0; i<4; i++ )	rtn = AFE79FNP(updateTxNco)( &tiAfe79DeviceInfo_t[0], i, mixer, nco );
	}
	else
		rtn = AFE79FNP(updateTxNco)( &tiAfe79DeviceInfo_t[0], ch, mixer, nco );

	return	rtn;
}

int set_dac_dsa( int ch, unsigned int dsa )
{
    return AFE79FNP(setTxDsa)( &tiAfe79DeviceInfo_t[0], ch, dsa );
}

int set_dac_do_calibration( int no )
{
	unsigned short	num = 0;
	unsigned char	data[2048+OVERHEAD_SIZE];

	AFE79FNP(doTxDsaCalib)( &tiAfe79DeviceInfo_t[0], 0x0f, 2, 0, &data[OVERHEAD_SIZE+sizeof(short)], &num );
	if( !num )	return -1;

	*((unsigned short *)&data[OVERHEAD_SIZE]) = num;
	spi_eeprom_write( EEP_DAC_CALIB_ADR(no), sizeof(short) + num, data );

	return 0;
}

int set_dac_load_calibration( int no )
{
	unsigned short	num;
	unsigned char	data[2048+READ_DATA_OFFSET];
	
	spi_eeprom_read( EEP_DAC_CALIB_ADR(no), 2048, data );
	num = *((unsigned short *)&data[READ_DATA_OFFSET]);

	return AFE79FNP(loadTxDsaPacket)( &tiAfe79DeviceInfo_t[0], &data[READ_DATA_OFFSET+sizeof(short)], num );
}


int set_dac_prbs( int no, int mode, int enable )
{
	return AFE79FNP(enableSerdesRxPrbsCheck)( &tiAfe79DeviceInfo_t[0], no, mode, enable );
}

void get_dac_prbs( int no, unsigned int *ber )
{
	AFE79FNP(getSerdesRxPrbsError)( &tiAfe79DeviceInfo_t[0], no, ber );
}

int set_dac_prbs_clear( int no )
{
	return AFE79FNP(clearSerdesRxPrbsErrorCounter)( &tiAfe79DeviceInfo_t[0], no );
}


void get_dac_ber( int no, unsigned int *extent, unsigned short *ber )
{
	unsigned short	stat;

    AFE79FNP(getSerdesEye)( &tiAfe79DeviceInfo_t[0], no, ber, &stat );
    *extent = stat;
}

void get_jesd_link( unsigned int *link )
{
	unsigned short	stat;

    AFE79FNP(getJesdRxLinkStatus)( &tiAfe79DeviceInfo_t[0], &stat );
    *link = stat;
}

