////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2020, 2022-2023 Qualcomm Technologies, Inc.
// All Rights Reserved.
// Confidential and Proprietary - Qualcomm Technologies, Inc.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @file  camxspectralsensorinterface.h
/// @brief CamX Non-Camera Sensor Interface Spectral Sensor definitions
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


// NOWHINE FILE GR016: Typedefs must not be used for structs, classes, and enumerations
#ifndef CAMXSPECTRALSENSORINTERFACE_H
#define CAMXSPECTRALSENSORINTERFACE_H

#include "camxncsdefs.h"

#ifdef __cplusplus
extern "C"
{
#endif // __cplusplus

CAMX_NAMESPACE_BEGIN

/// @brief Data structures that are exposed to OEM must be packed to have the expected layout.
#pragma pack(push, CDK_PACK_SIZE)

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// NCS SS Constant Definitions
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

const UINT32 NCS_SS_PROVIDER_DATA_VERSION          = 1;    ///< data structure version of SS

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// NCS Sensor Capability & Config Definitions
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

const UINT16 MaxStringSize           = 256;  ///< MAX String Size

// @brief Range structure in float
struct RangeFloat
{
    FLOAT min;    ///< Minimum
    FLOAT max;    ///< Maximum
};
// @brief Single Sensor Attribute
struct Attribute
{
    const CHAR attributeName[MaxStringSize];  ///< Lux, Frequency, CCT, Channel Strength, power, samplingRate etc
    union
    {
        RangeFloat  range;       ///< Range of the attribute. Min=Max for an attribute with no range
    } data;
};

// @breif Sensor Attribute array
struct SensorAttribute
{
    UINT8            length;             ///< length of array
    Attribute*       pAttributes;        ///< Array of quantities
};

// @breif Driver Info
struct DriverInformation
{
    CHAR            name[MaxStringSize];               ///< Name of this sensor
    CHAR            vendor[MaxStringSize];             ///< Vendor of this sensor
    CHAR            hardwareVersion[MaxStringSize];    ///< Hardware Versions e.g VD6282, VD6283
    UINT16          driverVersion;                     ///< Software Driver version
};

/// @brief SS Sensor capabilites structure
struct SSSensorCap : public NCSProviderCap
{
    DriverInformation driverInfo;   ///< Driver Information
    SensorAttribute   attributes;   ///< All Sensor Attributes
};

/// @brief SS Sensor Config
struct SSSensorConfig : public NCSSensorConfig
{
    UINT64      cctLuxSamplingTime;         ///< Sampling Time in microsecond for CCT/Lux
    UINT64      flickerSamplingFrequency;   ///< Sampling Frequency for Flicker Channel
};

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// NCS Sensor Data Structures
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// @brief Spectral Channels' strength
struct RawChannelStrength
{
    UINT32    rChannel;      ///< Red Channel
    UINT32    gChannel;      ///< Green Channel
    UINT32    bChannel;      ///< Blue Channel
    UINT32    clearChannel1; ///< Clear Channel 1 with No Filter
    UINT32    clearChannel2; ///< Clear Channel 2 with No Filter
    UINT32    irChannel;     ///< Infrared Channel
};

// @brief Spectral Channels' strength
struct SpectralChannelInfo
{
    BOOL               isValid;                      ///< Data is Valid or Not
    RawChannelStrength rawChannelData;               ///< Raw value from the spectral sensor channels
    UINT16             cctValue;                     ///< Correlated Color Temperature
    FLOAT              luxValue;                     ///< Lux
    FLOAT              expGainOfNonFlickerChannels;  ///< Exposure Gain of the  All channels except the selected flicker channel
    FLOAT              expTimeOfNonFlickerChannels;  ///< Exposure Time of the  All channels except the selected flicker channel
    UINT64             samplingTime;                 ///< sampling time in microseconds for CCT and Lux
};


// @brief Given Flicker Frequency and Amplitude in FFT
struct SpectralFrequencyInfo
{
    FLOAT amplitude;     ///< Amplitude from Fast Fourier Transform (FFT) on Sensor Flicker Data
    FLOAT frequency;     ///< Flicker frequency peak value
};

// @brief Flicker Channel Configured by Sensor
enum FlickerChannel
{
    InvalidChannel = -1,   ///< Invalid
    RedChannel     = 0,    ///< Red
    GreenChannel,          ///< Green
    BlueChannel,           ///< Blue
    ClearChannel1,         ///< Clear
    ClearChannel2,         ///< Clear
    InfraredChannel,       ///< IR
    MaxChannel = 0xFFFF    ///< Max Value
};

// @brief Flicker Frequencies related inforamtion
struct SpectralFlickerFrequencyInfo
{
    BOOL                  isValid;                      ///< Data is Valid or Not
    FlickerChannel        channel;                      ///< Primary Flicker Channel Configured
    SpectralFrequencyInfo firstMaximaPeak;              ///< First maximum freq amplitude in FFT
    SpectralFrequencyInfo secondMaximaPeak;             ///< Second maximum freq amplitude in FFT
    UINT16                configuredSamplingFlickerFreq; ///< Sampling Flicker Frequency configured by the sensor
    UINT16                avgRawFlickerData;            ///< The average value for the raw of flicker channel
    UINT16                maxRawFlickerData;            ///< The max value for the raw of flicker channel
    UINT16                minRawFlickerData;            ///< The min value for the raw of flicker channel
    UINT16                avgFlickerFreqAmplitude;      ///< Avg. of 5 different flicker frequency amplitude calculated by FFT
    FLOAT                 expGainOfFlickerChannel;      ///< Exposure Gain of the flicker channel
    FLOAT                 expTimeOfFlickerChannel;      ///< Exposure Time of the flicker channel if available otherwise -1.0
};


// @brief Main Data Structure that contains Spectral Sensor Data
struct NCSDataMultiSpectralSensor
{
    UINT64                        timestamp;      ///< Time Stamp of the data
    SpectralChannelInfo           channelsInfo;   ///< 6 channels information
    SpectralFlickerFrequencyInfo  flickerInfo;    ///< Flicker Information
};

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// NCS Interface Structures
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// @brief Configuration Type Enum
enum QueryPayloadType
{
    DriverInfo,         ///< Sensor Type and Vendor Information.
                        ///  Payload: DriverInformation
    SensorAttributes,   ///< List of sensor attributes
                        ///  Payload: SensorAttribute
    MaxPayloadTypeCount ///<  Maximum
};

// To@Do Generalize
// @brief Configuration Type Enum
enum ConfigurationType
{
    SamplingFrequency, ///< Configure Sampling Frequency of the flicker Channel in Hertz
                       ///  Payload: UINT32
    SamplingTime,      ///< Configure Sampling time of CCT and Lux on non-flicker channels in micro sec
                       ///  Payload: UINT32
    QTimeStamp,        ///< Sets the QTimer timestamp to the driver to synchronize clocks and reduce clock drift.
                       ///  Camera runs w.r.t Qtimer. CamX will call it after regular intervals.
                       ///  Payload: uint64_t Qtimer timestamp
    MaxConfigType      ///<  Maximum
};

// @brief QueryInfo structure to query into any Sensor Driver supporting this Spectral Sensor Interface
struct QueryInfo
{
   QueryPayloadType queryType;   ///< Type of query
   VOID*            pData;       ///< Payload will be typecasted w.r.t queryType
   UINT16           size;        ///< Size of the structure pData. Needs to be written by Vendor driver
};

// @brief Parameters to be configuredinto any Sensor Driver supporting this Spectral Sensor Interface

struct ConfigureParameters
{
    ConfigurationType configType;   ///< Type Of Configuration
    union
    {
        UINT32            samplingTime;       ///< Sampling Time of the spectral sensor for CCT/LUX
        UINT32            samplingFrequency;  ///< Sampling Frequency of the flicker channel
        UINT64            timestamp;          ///< Qtimer Time Stamp
    } configPayload;
};

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Interface for Exeternal Sensor
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
typedef struct SpectralSensorInterface
{
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// QuerySensorInfo
    ///
    /// @brief  This method can be called to query sensor's characteristics
    ///
    /// @param  pCaps  Pointer to SensorCapability to be filled by OEM
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    VOID (*QuerySensorInfo)(
        QueryInfo* pQuery);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// OpenSensor
    ///
    /// @brief  Opens a link to the Spectral sensor if it is present. SpectralSensorInterface operations
    ///         can be performed if 1 returned
    ///
    /// @return -1 for error.  -2 for sensor not present . 0 for success
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    INT (*OpenSensor)();

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// Configure
    ///
    /// @brief  Send Configurations to be applied
    ///
    /// @param  pConfig             pointer to config structure
    /// @param  numOfConfigParams   Number of configuration parameters. pConfig array length
    ///
    /// @return success is 0
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    INT (*Configure)(
        const ConfigureParameters* pConfig,
        const UINT                 numOfConfigParams);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// StartSensor
    ///
    /// @brief  Once the link is open. And the configurations are applied, Start sensor.
    ///
    /// @return success is 0
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    INT (*StartSensor)();

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// PollSensorData
    ///
    /// @brief  Blocking Call to poll sensor data.
    ///
    /// @param  numSamples   Number of samples requested. 1 for single smaple. > 1 for Batched sample
    /// @param  pSensorData  Pointer to Sensor Data. Can be typecasted to expected sensor data structure based on
    ///                      NCSSensorType enum defined and Queried from sensor
    ///
    /// @return -1 if failed OR number of samples returned
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    INT (*PollSensorData)(
        const UINT8   numSamples,
        VOID*         pSensorData);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// StopSensor
    ///
    /// @brief  Stop the sensor streaming
    ///
    /// @return success is 0
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    INT (*StopSensor)();

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// CloseSensor
    ///
    /// @brief  Turn off sensor
    ///
    /// @return success is 0
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    INT (*CloseSensor)();

} SpectralSensorInterface;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// GetSpectralSensorInterface
///
/// @brief  This function is the entry point to the Spectral sensor driver. CamX will call into OEM's sensor driver lib using
///         "GetSpectralSensorInterface" string. Sensor will be then operated using
///         SpectralSensorInterface structure as defined above.
///
/// @param  ppInterfaceObject    Double Pointer to structure. Pointer from camx will be passed by reference to the OEM driver
///
/// @return None
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CAMX_VISIBILITY_PUBLIC void GetSpectralSensorInterface(
    SpectralSensorInterface** ppInterfaceObject);

#pragma pack(pop)

CAMX_NAMESPACE_END

#ifdef __cplusplus
}
#endif // __cplusplus
#endif // CAMXSPECTRALSENSORINTERFACE_H
