// --------------------------------- lmsusb.h ---------------------------------
//
//  Include file for Linux LabBrick LMS signal generator definitions
//
// (c) 2020-2021 by Vaunix Technology Corporation, all rights reserved
//
//  JA  Version 1.0 LMS Digital Signal Generator Device Driver
//	RD	Updated 6/2024
//-----------------------------------------------------------------------------
#ifndef __LMSUSB_H__
#define __LMSUSB_H__

// ---------- Include headers ----------------
#include <libusb-1.0/libusb.h>
#include "lmsdrvr.h"
//*****************************************************************************
//
// If building with a C++ compiler, make all of the definitions in this header
// have a C binding.
//
//*****************************************************************************
#ifdef __cplusplus
extern "C"
{
#endif

/// ---------- Macros ----------------

#define STATUS_PLL_LOCK 	0x80 	// MASK: Pll lock status bit, 1 = locked
#define STATUS_NEW_PARAM 	0x40 	// MASK: A parameter was set since the last "Save Settings" command
#define STATUS_CMD_OK 		0x20 	// MASK: The command was completed by the LMS device without problems
#define STATUS_RF_ON 		0x10 	// MASK: The RF HW is on (moved from 0x08)

// Bit masks and equates for the Sweep command byte (stored in Sweep_mode, and reported also in Status)
#define SWP_BIDIR 			0x08 	// MASK: bit = 0 for ramp style sweep, 1 for triangle style sweep
#define SWP_DIRECTION 		0x04 	// MASK: bit = 0 for sweep up, 1 for sweep down 
#define SWP_CONTINUOUS 		0x02 	// MASK: bit = 1 for continuous sweeping
#define SWP_ONCE 			0x01 	// MASK: bit = 1 for single sweep
#define SWP_CHIRP           0x10    // MASK: bit = 1 for chirping sweeps

// Bit masks and equates for the DSS Pulse mode command byte (stored in Pulse_mode)
#define PM_ACTIVE 			0x01 	// MASK: bit = 0 for normal mode, 1 for pulse mode
#define PM_EXTERNAL 		0x02 	// MASK: bit = 0 for normal mode, 1 for external modulation

// HID report equates
#define HR_BLOCKSIZE 		6 		// size of the block of bytes buffer in our HID report
#define HID_REPORT_LENGTH 	8 		// use an 8 byte report..

// Misc. constants used for the Vaunix devices
#define VNX_MIN_SWEEPTIME 	1 		// 1 ms. minimum sweep time (AO checked 10-25)
#define MAX_ATTEN 			64 		// we've got 64 db max attenuation for most LMS devices 
									// we represent it as 4 * the value, or the attenuation in .25db steps at the API level
#define MAX_ATTEN_LH 		80 		// we've got 80 db max attenuation for LMS-6123LH devices 
									// we represent it as 4 * the value, or the attenuation in .25db steps at the API level
#define VNX_MIN_CHIRPLENGTH 48		// 1 microsecond in our internal 48 MHz units

// Misc commands to send to the device
#define VNX_SET 			0x80
#define VNX_GET 			0x00	// the set and get bits are or'd into the msb of the command byte

// ---- LMS Commands, some used in other devices ----
#define VNX_FREQUENCY 		0x04	// output frequency in 100Khz units
#define VNX_FDWELL 			0x05	// time to dwell at each frequency in the sweep, in 1ms units, minimum of 10ms.
#define VNX_FSTART 			0x06	// frequency lower limit of sweep in 100Khz units 
#define VNX_FSTOP 			0x07	// frequency upper limit of sweep in 100Khz units
#define VNX_FSTEP 			0x08	// frequency step size, in 100Khz units
#define VNX_SWEEP 			0x09	// command to start/stop sweep, data = 01 for single sweep, 00 to stop
									// sweeping, and 02 for continuous sweeping.
									// For the DSS synth, there are more sweep option bits

#define VNX_RFMUTE 			0x0A	// enable or disable RF output, byte = 01 to enable, 00 to disable
#define VNX_ATTEN 			0x0B	// attenuator setting, byte = number of dbm attenuation in .25 db steps
									// 00 is no attenuation, 02 is .5 db, 04 is 1 db

#define VNX_SAVEPAR 		0x0C	// command to save user parameters to flash, data bytes must be
									// set to  0x42, 0x55, 0x31 as a key to enable the flash update
									// all of the above settings are saved (Frequency, sweep params, etc.)

#define VNX_PWR 			0x0D	// power output setting, relative to calibrated value - adds to calibrated
									// attenuator setting. It is a byte, with the attenuation expressed in .25db
									// steps. Thus, 2 = .5 db attenuation, 4 = 1.0db attenuation, etc. 

#define VNX_DEFAULTS 		0x0F	// restore all settings to factory default
									// FSTART = Minimum Frequency, FSTOP = Maximum Frequency

#define VNX_STATUS 			0x0E	// Not really a command, but the status byte value for periodic status reports.
#define VNX_INTOSC 			0x23	// enable/disable internal reference oscillator - Byte == 01 for on, 00 for off

// ---------------------- DSS Specific Commands ----------------------

#define VNX_DSS_STATUS 		0x4E	// Not really a command, but the status byte value for periodic status reports.

#define VNX_DSS_FREQUENCY 	0x44	// output frequency in 10 Hz units
#define VNX_DSS_SWPTIME 	0x45	// sweep time, in 1ms units, minimum of 100ms.
#define VNX_DSS_FSTART 		0x46	// frequency lower limit of sweep in 10 Hz units 
#define VNX_DSS_FSTOP 		0x47	// frequency upper limit of sweep in 10 Hz units
#define VNX_DSS_SWEEP 		0x48	// start/stop sweeps

#define VNX_OFFTIME 		0x49	// length of pulse mode RF off time in microseconds
#define VNX_ONTIME 			0x4A	// length of pulse mode RF on time in microseconds
#define VNX_PULSE_MODE 		0x4B	// start/stop pulse mode

#define VNX_EXTSWP 			0x4C	// enable/disable external sweep trigger

// ----------------------- Chirp commands ----------------------------
#define VNX_CHIRP_LENGTH	0x4F    // set/get the length of the chirp, uses the same encoding as PWM values
									// units of 48MHz, 1MHz, 1KHz
#define VNX_CHIRP_MODE		0x59    // set/get the operating mode of the chirping hardware
#define VNX_CHIRP_RATE		0x51    // set/get the repeat rate for the HW timer in 1MHz units (24 bit max value)

// ---------------------- Misc. commands ---------------------------
#define VNX_MAX_PWR 		0x1B	// get the calibrated power output
#define VNX_GETSERNUM 		0x1F	// get the serial number, value is a DWORD
#define VNX_MINFREQUENCY 	0x20	// get (no set allowed) the minimum frequency
#define VNX_MAXFREQUENCY 	0x21	// get (no set allowed) the maximum frequency

#define VNX_MODELNAME 		0x22	// get (no set allowed) the device's model name string -- last 6 chars only

// ----------- Global Equates ------------
#define MAXDEVICES 			64
#define MAX_MODELNAME 		32

#define PMODE_1US 			0x00	// the top nibble is 0 for pulse mode times in 1 microsecond units
#define PMODE_1MS 			0x20	// the top nibble is 2 for pulse mode times in 1 millisecond units
#define PTIME_MASK 			0x00FFFFFF // only the first 24 bits are used for pulse mode times

// ----------- Mode Bit Masks ------------
#define MODE_CHIRP			0x00000010	// bit is 1 for chirping enabled
#define MODE_INTREF 		0x00000020	// bit is 1 for internal osc., 0 for external reference
#define MODE_RFON			0x00000040	// bit is 1 for RF on, 0 if RF is off (moved from 0x10 by RD 5/23/21)
#define MODE_SWEEP 			0x0000000F	// bottom 4 bits are used to keep the sweep control bits

#define MODE_PWMON 			0x00000100	// we keep a copy of the PWM control bits here, 1 for int PWM on
#define MODE_EXTPWM 		0x00000200	// 1 for ext. PWM input enabled
#define PWM_MASK 			0x00000300

#define MODE_EXTSWEEP 		0x00000400	// bit is 1 for external sweep trigger, 0 for internal sweep control (changed 6/2024)

// ----------- Command Equates -----------
#define STATUS_OK 			0
#define BAD_PARAMETER 		0x80010000	// out of range input -- frequency outside min/max etc.
#define BAD_HID_IO 			0x80020000	// an error was returned by the lower level USB drivers
#define DEVICE_NOT_READY 	0x80030000	// device isn't open, no handle, etc.
#define ERROR_STATUS_MSK 	0x80000000	// the MSB is set for errors

#define F_INVALID_DEVID 	-1.0		// for functions that return a float, STATUS_OK is the same
#define F_BAD_HID_IO 		-2.0
#define F_DEVICE_NOT_READY 	-3.0
#define F_BAD_PARAMETER		-4.0

// Status returns for DevStatus
#define INVALID_DEVID 		0x80000000 // MSB is set if the device ID is invalid
#define DEV_CONNECTED 		0x00000001 // LSB is set if a device is connected
#define DEV_OPENED 			0x00000002 // set if the device is opened
#define SWP_ACTIVE 			0x00000004 // set if the device is sweeping
#define SWP_UP 				0x00000008 // set if the device is sweeping up in frequency
#define SWP_REPEAT 			0x00000010 // set if the device is in continuous sweep mode
#define SWP_BIDIRECTIONAL 	0x00000020 // set if the device is in bi-directional sweep mode
#define PLL_LOCKED 			0x00000040 // set if the PLL lock status is TRUE (both PLL's are locked)
#define FAST_PULSE_OPTION 	0x00000080 // set if the fast pulse mode option is installed
#define EXT_SWEEP_OPTION 	0x00000100 // set if the external sweep option is enabled (HW may not be installed)

// Internal values in DevStatus
#define DEV_LOCKED 			0x00002000 // set if we don't want read thread updates of the device parameters
#define DEV_RDTHREAD 		0x00004000 // set when the read thread is running

// Flags to encode pulse mode time ranges
#define PM48Mhz 			0x10000000 // used to select the 48Mhz pulse mod clock
#define PM1Mhz 				0x00000000 // used to select the 1Mhz pulse mod clock or sw pulsing

// Format of the status report, for the convenience of host side coders

typedef struct {
    char pkt_status;
    char count;
    long frequency;
    char dev_status;
    signed char power;
}
VNX_STATUS_REPORT;

typedef struct {
    char reportid; // an artifact of the Windows HID API
    char status;
    char count;
    char byteblock[HR_BLOCKSIZE];
}
HID_REPORT1;

typedef struct {
    char reportid; // an artifact of the Windows HID API
    char command;
    char count;
    char byteblock[HR_BLOCKSIZE];
}
HID_REPORT_OUT;

typedef struct {
    int DevStatus;
    int Frequency;
    int MinFrequency;
    int MaxFrequency;
    int StartFrequency;
    int EndFrequency;
    int FrequencyStep;
    int SweepTime;
    int Power;
    int MaxPower;
    int MinPower;
    int PowerScale;
    int PulseOnTime;
    int PulseOffTime;
    float PulseOnTimeSeconds;
    float PulseOffTimeSeconds;
	int ChirpLength;
	int ChirpRepeatRate;
	bool SweepChirpOut;
	bool HasChirp;
    int Modebits;
    int SerialNumber;
    char ModelName[MAX_MODELNAME];
    int LMSType;
    
	// Internal variables used to identify and manage the hardware
	unsigned int idVendor;
	unsigned int idProduct;
	unsigned int idType;
	int BusAddress;
	int Endpoint;
	char Serialstr[16];
	volatile char thread_command;
	char sndbuff[8];
	char rcvbuff[24];
	volatile char decodewatch;
	int MyDevID;
	libusb_device_handle *DevHandle;
}
LMSPARAMS;

//*****************************************************************************
//
// Mark the end of the C bindings section for C++ compilers.
//
//*****************************************************************************
#ifdef __cplusplus
}
#endif

#endif // __LMSUSB_H__                             
