#include <iostream>
#include <vector>
#include <string>
#include "htra_api.h"
#include "example.h"
using namespace std;

#define IS_USB 1 //默认使用的是USB型设备，若使用的是网口型设备则将IS_USB定义为0。

int IQS_GetIQ_EZStandard()
{
	int Status = 0;      //函数的返回。
	void* Device = NULL; //当前设备的内存地址。
	int DevNum = 0;      //指定设备号。

	BootProfile_TypeDef BootProfile; //启动配置结构体，包括物理接口、供电方式等。
	BootInfo_TypeDef BootInfo;       //启动信息结构体，包括设备信息、USB速率等。

	BootProfile.DevicePowerSupply = USBPortAndPowerPort; //使用USB数据端口及独立电源端口双供电。

#if IS_USB==1
	//配置USB接口。
	BootProfile.PhysicalInterface = USB;
#else 
	//配置ETH接口。
	BootProfile.PhysicalInterface = ETH;
	BootProfile.ETH_IPVersion = IPv4;
	BootProfile.ETH_RemotePort = 5000;
	BootProfile.ETH_ReadTimeOut = 5000;
	BootProfile.ETH_IPAddress[0] = 192;
	BootProfile.ETH_IPAddress[1] = 168;
	BootProfile.ETH_IPAddress[2] = 1;
	BootProfile.ETH_IPAddress[3] = 100;
#endif

	Status = Device_Open(&Device, DevNum, &BootProfile, &BootInfo); //打开设备。

	Device_Open_ErrorHandling(Status, &Device, DevNum, &BootProfile, &BootInfo); //当Status不为0时，根据Status的返回值进行相对应的错误处理。

	IQS_EZProfile_TypeDef IQS_EZProfileIn;  //IQS输入配置，包括起始频率、终止频率、RBW、参考电平等。
	IQS_EZProfile_TypeDef IQS_EZProfileOut; //IQS输出配置。
	IQS_StreamInfo_TypeDef EZStreamInfo;    //当前配置下IQ数据信息，包括带宽,IQ单路采样率等。

	Status = IQS_EZProfileDeInit(&Device, &IQS_EZProfileIn); //初始化IQS模式简洁模式下的相关参数。

	IQS_EZProfileIn.CenterFreq_Hz = 1e9;       //配置中心频率。
	IQS_EZProfileIn.RefLevel_dBm = 0;          //配置参考电平。
	IQS_EZProfileIn.DecimateFactor = 2;		   //配置抽取倍数。
	IQS_EZProfileIn.DataFormat = Complex16bit; //配置IQ数据格式。
	IQS_EZProfileIn.TriggerSource = Bus;       //配置触发源为内部总线触发。
	IQS_EZProfileIn.TriggerMode = FixedPoints; //配置触发模式。
	IQS_EZProfileIn.TriggerLength = 16384;     //配置单次触发采集的点数。

	Status = IQS_EZConfiguration(&Device, &IQS_EZProfileIn, &IQS_EZProfileOut, &EZStreamInfo); //简洁模式下发IQS模式的相关配置。

	if (Status == 0)
	{
		printf("EZConfiguration delievery succeeded.\n");
	}
	else
	{
		printf("Error in IQS_EZConfiguration call. Status = %d\n", Status);
		Device_Close(&Device);
		return 0;
	}

	IQStream_TypeDef IQStream; //存放IQ数据包数据，包括IQ数据、配置信息等。
	bool tag = false;		   //当IQS_EZProfileIn.TriggerMode  = Adaptive时，获取数据之前控制触发1次。

	vector<int16_t> I_Data(EZStreamInfo.StreamSamples); //创建I路数据数组。
	vector<int16_t> Q_Data(EZStreamInfo.StreamSamples); //创建Q路数据数组。

	if (IQS_EZProfileIn.TriggerMode == Adaptive)
	{
		I_Data.resize(EZStreamInfo.PacketSamples); //重新调整I_Data的大小，用于存放Adaptive模式下I路数据。
		Q_Data.resize(EZStreamInfo.PacketSamples); //重新调整Q_Data的大小，用于存放Adaptive模式下Q路数据。
	}

	while (1)
	{
		if (IQS_EZProfileOut.TriggerMode == Adaptive && tag != true) //当IQS_EZProfileOut.TriggerMode = Adaptive时仅触发一次。
		{
			Status = IQS_BusTriggerStart(&Device);                   //调用IQS_BusTriggerStart触发设备。若触发源为外部触发，则不需要调用此函数。
			tag = true;
		}
		if (IQS_EZProfileOut.TriggerMode == FixedPoints)             //当IQS_EZProfileOut.TriggerMode = FixedPoints时每次循环均触发。
		{
			Status = IQS_BusTriggerStart(&Device);                   //若触发源为外部触发，则不需要调用此函数。
		}

		/*获取IQ数据*/
		for (int j = 0; j < EZStreamInfo.PacketCount; j++)	         //仅当TriggerMode为FixedPoints时生效。
		{
			Status = IQS_GetIQStream_PM1(&Device, &IQStream);        //获取IQ数据包、触发信息、I路数据最大值及最大值数组下标。

			if (Status == APIRETVAL_NoError)
			{
				// UserCode here
				//注意：实际使用IQ模式时，建议开一个线程专门调用IQS_GetIQStream获取IQ数据，不能与处理IQ数据放在同一个线程里。

				//int16_t* IQ = (int16_t*)IQStream.AlternIQStream;
				//uint32_t Points = EZStreamInfo.PacketSamples;

				//if (j == EZStreamInfo.PacketCount - 1 && EZStreamInfo.StreamSamples % EZStreamInfo.PacketSamples != 0 && IQS_EZProfileOut.TriggerMode == FixedPoints) //可能最后一包不满一整包（16242个点）；所以只需要循环不满一包的点数
				//{
				//	Points = EZStreamInfo.StreamSamples % EZStreamInfo.PacketSamples;
				//}

				//for (uint32_t i = 0; i < Points; i++)
				//{
				//	I_Data[i + EZStreamInfo.PacketSamples * j] = IQ[i * 2];
				//	Q_Data[i + EZStreamInfo.PacketSamples * j] = IQ[i * 2 + 1];
				//}
			}

			/*获取数据失败时，返回错误提示，发生以下错误时，建议按照提示进行操作*/
			else
			{
				switch (Status)
				{
				case APIRETVAL_WARNING_IFOverflow: 
					printf("Warning - IF saturation detected. Reconfiguration recommended. Reference level <= signal power\n");  //IQS_GetIQStream_PM1如果返回值为-12，建议重新配置参数获取。
					break;
				case APIRETVAL_WARNING_ReconfigurationIsRecommended:
					printf("Warning - Significant temperature change detected on the device. Reconfiguration of temperature is recommended\n"); //IQS_GetIQStream_PM1如果返回值为-14，建议重新配置参数后再获取。
					break;
				default:
					printf("Other error returned. Status = %d\n", Status);
					Device_Close(&Device);
					break;
				}
			}
		}
	}

	Status = IQS_BusTriggerStop(&Device); //调用IQS_BusTriggerStop停止触发设备。

	Device_Close(&Device); //关闭设备。

	return 0;

}

