from htra_api import *

###Open Device###
Status = 0          #Function return value.
Device = c_void_p() #Memory address of the current device.
DevNum = c_int(0)   #Specify device number.

BootProfile = BootProfile_TypeDef() #Boot configuration structure, including physical interface, power supply method, etc.
BootInfo = BootInfo_TypeDef()       #Boot information structure, including device information, USB rate, etc.

BootProfile.DevicePowerSupply = DevicePowerSupply_TypeDef.USBPortAndPowerPort #Use both USB data port and independent power port for dual power supply.
BootProfile.PhysicalInterface = PhysicalInterface_TypeDef.USB                 #Use USB interface for data transmission.

#Configure ETH interface for Ethernet device
#BootProfile.PhysicalInterface = PhysicalInterface_TypeDef.ETH #Use Ethernet for data transmission
#BootProfile.ETH_IPVersion = IPVersion_TypeDef.IPv4
#BootProfile.ETH_RemotePort = 5000
#BootProfile.ETH_ReadTimeOut = 10000
#BootProfile.ETH_IPAddress[0] = 192
#BootProfile.ETH_IPAddress[1] = 168
#BootProfile.ETH_IPAddress[2] = 1
#BootProfile.ETH_IPAddress[3] = 100

Status = dll.Device_Open(pointer(Device),DevNum,pointer(BootProfile),pointer(BootInfo)) #Open device.
if(Status == 0):
    print("Device is opened successfully")
else:
    print("Return other errors Status = {:d}".format(Status))

###Configuration Delivery###
IQS_ProfileIn = IQS_Profile_TypeDef()  #IQS input configuration, including start frequency, stop frequency, RBW, reference level, etc.
IQS_ProfileOut = IQS_Profile_TypeDef() #IQS output configuration.
StreamInfo = IQS_StreamInfo_TypeDef()  #IQ data information under the current configuration, including bandwidth, single-channel IQ sampling rate, etc.

dll.IQS_ProfileDeInit(pointer(Device),pointer(IQS_ProfileIn)) #Initialize configuration parameters for IQS mode.

IQS_ProfileIn.CenterFreq_Hz = 1e9                           #Configure center frequency.
IQS_ProfileIn.RefLevel_dBm = 0                              #Configure reference level.
IQS_ProfileIn.DecimateFactor = 2                            #Configure decimation factor.
IQS_ProfileIn.DataFormat = DataFormat_TypeDef.Complex16bit  #Configure IQ data format.
IQS_ProfileIn.TriggerSource = IQS_TriggerSource_TypeDef.Bus #Configure trigger source as internal bus trigger.

#Configure trigger mode.
#In Adaptive mode, run directly; in FixedPoints mode, set TriggerMode to FixedPoints and configure the number of sampling points TriggerLength.
IQS_ProfileIn.TriggerMode = TriggerMode_TypeDef.Adaptive
#IQS_ProfileIn.TriggerMode = TriggerMode_TypeDef.FixedPoints
#IQS_ProfileIn.TriggerLength = 16242 #Configure the number of points per trigger acquisition, effective only when TriggerMode is set to FixedPoints.

Status = dll.IQS_Configuration(pointer(Device),pointer(IQS_ProfileIn),pointer(IQS_ProfileOut),pointer(StreamInfo))  #Apply IQS mode configuration.

if(Status == 0):
    print("configuration delievery succeeded")
else:
    print("SWP_Configuration call is incorrect Status = {:d}".format(Status))

### Get Data###
IQ_Data = (c_int16 * (StreamInfo.StreamSamples*2))() #Store IQ data.
I_Data = (c_int16 * (StreamInfo.PacketSamples))()    #Store I data.
Q_Data = (c_int16 * (StreamInfo.PacketSamples))()    #Store Q data.
AlternIQPacket = c_int16_p()                         #Pointer to temporary storage address for IQ data (library function).
ScaleToV = c_float()                                 #Scaling factor to restore amplitude to voltage.
TriggerInfo = IQS_TriggerInfo_TypeDef()              #Trace information structure.
MeasAuxInfo = MeasAuxInfo_TypeDef()                  #Measurement auxiliary information structure.

#When using Adaptive mode (i.e., IQS_ProfileOut.TriggerMode.value == 1), sampling starts at the rising edge of the trigger signal and ends at the falling edge.
#In FixedPoints mode, sampling starts at the rising edge of the trigger signal and stops after collecting TriggerLength points, then re-triggers for data acquisition.
if (IQS_ProfileOut.TriggerMode.value==1):
    Status = dll.IQS_BusTriggerStart(pointer(Device)) #Call IQS_BusTriggerStart to trigger the device. If the trigger source is external, this function is not needed.
    while(True):
        dll.IQS_GetIQStream(pointer(Device),pointer(AlternIQPacket),pointer(ScaleToV),pointer(TriggerInfo),pointer(MeasAuxInfo)) #Get IQ data packet, trigger info, I-channel max value, and max value array index.
        I_Data[0:StreamInfo.PacketSamples] = AlternIQPacket[0:StreamInfo.PacketSamples*2:2]
        Q_Data[0:StreamInfo.PacketSamples] = AlternIQPacket[1:StreamInfo.PacketSamples*2:2]
        print(I_Data[:])
        print(Q_Data[:])

else:
    while(True):
        Status = dll.IQS_BusTriggerStart(pointer(Device)) #Call IQS_BusTriggerStart to trigger the device. If the trigger source is external, this function is not needed.
        for i in range(0,StreamInfo.PacketCount):
            dll.IQS_GetIQStream(pointer(Device),pointer(AlternIQPacket),pointer(ScaleToV),pointer(TriggerInfo),pointer(MeasAuxInfo)) #Get IQ data packet, trigger info, I-channel max value, and max value array index.
            if(i == StreamInfo.PacketCount - 1 and StreamInfo.StreamSamples % StreamInfo.PacketSamples != 0):                        #The last packet may not be full (16242 points); so only the remaining points are needed.
                IQ_Data[(i*StreamInfo.PacketSamples*2):] = AlternIQPacket[0:(2*(StreamInfo.StreamSamples % StreamInfo.PacketSamples))]
                break
            else:
                IQ_Data[(i*StreamInfo.PacketSamples*2):((i+1)*StreamInfo.PacketSamples*2)] = AlternIQPacket[0:(StreamInfo.PacketSamples*2)]
        I_DATA = IQ_Data[0::2] #Separate I data.
        Q_DATA = IQ_Data[1::2] #Separate Q data.
        print(I_DATA[:])
        print(Q_DATA[:])

Status = dll.IQS_BusTriggerStop(pointer(Device)) #Call IQS_BusTriggerStop to stop triggering the device.
###Close Device###
Status = dll.Device_Close(pointer(Device))
if(Status == 0):
    print("Device closed successfully")
else:
    print("Device closure failed")




