from htra_api import *
from math import *

###Open Device###
Status = 0          #Function return status.
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 mode, etc.
BootInfo = BootInfo_TypeDef()       #Boot information structure, including device details, USB speed, etc.

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

#Configure ETH interface for Ethernet devices
#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 the device.
if(Status == 0):
    print("Device is opened successfully")
else:
    print("Return other errors Status = {:d}".format(Status))

###Configuration Delivery###
DET_ProfileIn = DET_Profile_TypeDef()  #DET input configuration, including center frequency, decimation factor, reference level, etc.
DET_ProfileOut = DET_Profile_TypeDef() #DET output configuration.
StreamInfo = DET_StreamInfo_TypeDef()  #DET data-related information under the current configuration, including DET data points, bytes, etc.

dll.DET_ProfileDeInit(pointer(Device),pointer(DET_ProfileIn)) #Initialize parameters related to DET mode.

DET_ProfileIn.CenterFreq_Hz = 1e9                           #Set center frequency.
DET_ProfileIn.RefLevel_dBm = 0                              #Set reference level.
DET_ProfileIn.DecimateFactor = 2                            #Set decimation factor.
DET_ProfileIn.TriggerSource = DET_TriggerSource_TypeDef.Bus #Set trigger source to internal bus trigger.

#Configure trigger mode. FixedPoints mode samples from the rising edge of the trigger signal and ends after TriggerLength points.
#Adaptive mode samples from the rising edge to the falling edge of the trigger signal.
DET_ProfileIn.TriggerMode = TriggerMode_TypeDef.Adaptive
#DET_ProfileIn.TriggerMode = TriggerMode_TypeDef.FixedPoints
#DET_ProfileIn.TriggerLength = 16242 #Set the number of points collected per trigger. Effective only when TriggerMode is FixedPoints.

Status = dll.DET_Configuration(pointer(Device),pointer(DET_ProfileIn),pointer(DET_ProfileOut),pointer(StreamInfo)) #Deliver DET mode configuration.

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

###Data Acquisition###
NormalizedPowerPacket = (c_float * StreamInfo.PacketSamples)() #Create power array (pre-unit conversion data).
NormalizedPowerStream = (c_float * StreamInfo.PacketSamples)() #Create power array (post-unit conversion data).
ScaleToV = c_float()                                           #Absolute amplitude (V unit) scaling factor.
TriggerInfo = DET_TriggerInfo_TypeDef()                        #Structure to store trigger information in DET mode.
MeasAuxInfo = MeasAuxInfo_TypeDef()                            #Structure to store auxiliary measurement data.

#In Adaptive mode (DET_ProfileOut.TriggerMode.value == 1), sampling starts at the rising edge and ends at the falling edge of the trigger signal.
#In FixedPoints mode, sampling starts at the rising edge and ends after TriggerLength points. Data acquisition continues upon the next trigger.
#In actual development, use one of these modes.
if(DET_ProfileOut.TriggerMode.value==1):
    Status = dll.DET_BusTriggerStart(pointer(Device)) #Call DET_BusTriggerStart to trigger the device. If the trigger source is external, this function is not needed.
    while True:
        Status = dll.DET_GetPowerStream(pointer(Device),NormalizedPowerPacket,pointer(ScaleToV),
                                        pointer(TriggerInfo),pointer(MeasAuxInfo)) #Retrieve DET data and trigger information.
        for i in range(0,StreamInfo.PacketSamples):                                #Unit conversion.
            NormalizedPowerStream[i] = 10 * log10(20 * pow(NormalizedPowerPacket[i] * ScaleToV.value, 2))
        print(NormalizedPowerStream[:])

else:
    while True:
        Status = dll.DET_BusTriggerStart(pointer(Device))  #Call DET_BusTriggerStart to trigger the device. If the trigger source is external, this function is not needed.
        for i in range(0, StreamInfo.PacketCount):         #Retrieve DET data and trigger information.
            Status = dll.DET_GetPowerStream(pointer(Device), NormalizedPowerPacket, pointer(ScaleToV),
                                            pointer(TriggerInfo), pointer(MeasAuxInfo))
            if (i == StreamInfo.PacketCount - 1 and StreamInfo.StreamSamples % StreamInfo.PacketSamples != 0):
                NormalizedPowerStream[i * StreamInfo.PacketSamples:] = NormalizedPowerPacket[
                                                                       0:StreamInfo.StreamSamples % StreamInfo.PacketSamples]
            else:
                NormalizedPowerStream[
                i * StreamInfo.PacketSamples:(i + 1) * StreamInfo.PacketSamples] = NormalizedPowerPacket[:]
        for i in range(0, StreamInfo.PacketSamples):
            NormalizedPowerStream[i] = 10 * log10(20 * pow(NormalizedPowerStream[i] * ScaleToV.value, 2))
        print(NormalizedPowerStream[:])

Status = dll.DET_BusTriggerStop(pointer(Device)) #Call DET_BusTriggerStop to stop triggering the device.

###Close Device###
Status = dll.Device_Close(pointer(Device))