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

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @file  camxtofsensordefs.h
/// @brief CamX Non-Camera Sensor ToF Sensor definitions
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


#ifndef CAMXTOFSENSORDEFS_H
#define CAMXTOFSENSORDEFS_H

#include "camxncsdefs.h"
#include <sensors.h>

CAMX_NAMESPACE_BEGIN


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

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// NCS ToF Constant Definitions
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

const UINT32 NCS_TOF_PROVIDER_DATA_VERSION          = 1;    ///< data structure version of ToF

static const INT    TOFMaxSamples                 = 3;    ///< Maximum samples to be stored for TOF

/*  Packet Format: We can either have a Single Point Laser Sensor (L1/L0)
    or a MultiPoint (L5) laser sensor having 8*8 data points.
    "data[16]" field in sensors_event_t structure will have the following format depending on sensor type.
    data[0] : Bits 0 - 7  : Version Number  -> "0" for L0/L1 sensor and "1" for L5 sensor type. Depending on that
    we have different interpretation for "data[16]" array.

    For Version number 0 we have L1 sensor:
    data[0] ->  Version
    data[1] ->  type
    data[2] ->  distance
    data[3] ->  confidence
    data[4] ->  nearLimit
    data[5] ->  farLimit
    data[12] ->  ambientRate

    Rest of the field we do not care for single point sensor

    For Version number 1, we have L5 sensor:
              Bits  Interpretation
    data[0]:
               0-3    Version
               4-5    No.of targets per zone
               6-11   Reserved
               12-17   Width
               18-23  Height
               24     Last Event
               25-31  Reserved

    data[1]    0-15   Depth Distance
    to         16-31  Depth Distance
    data[15]
               OR (For two target distances per zone)

               0-15  Depth Distance for 1st target per zone
               16-31 Depth Distance for 2nd target per zone

               OR
               0-31  IR Ambient Rate per zone
*/



/// MASK Definitions according to proposed API to Sensor Vendor for L5 sensor
static const UINT VersionNumberMask                 = 0x0000000F;   ///< Version number
static const UINT WidthOfGridMask                   = 0x0003F000;   ///< Width of Laser Sensor Grid
static const UINT HeightOfGridMask                  = 0x00FC0000;   ///< Height of Laser Sensor Grid
static const UINT TargetsPerZoneMask                = 0x00000030;   ///< Number of targets per zone from Sensor packet
static const UINT LastEventMask                     = 0x01000000;   ///< "Last event" bit packet from sensor
static const UINT TotalNumOfDepthPointsMask         = 0xFFFF0000;   ///< Deprecate this
static const UINT Lower16BitsDepthPointMask         = 0x0000FFFF;   ///< Each 32 bit data point contains two depth samples.
static const UINT Upper16BitsDepthPointMask         = 0xFFFF0000;   ///< Second Sample point
static const UINT MaxDepthPointsInSingleEvent       = 30;           ///< Acc. to agreed upon format
static const UINT MaxAmbientRatePointsInSingleEvent = 15;           ///< Acc. to agreed upon format
static const UINT MaxDataPacketLength               = 16;           ///< max "data" array length as specified in sensors.h API
static const UINT NumSensorEventsToRead             = 10;           ///< Number of sensor events to read in poll call
static const UINT   MaxGridWidth                    = 8;            ///< Grid points are arranged in 8*8 or 4*4
static const UINT   MaxGridHeight                   = 8;            ///< We can use 8*8 for AF or 4*4
static const UINT   MaxNumOfTargetDistancesPerZone  = 2;            ///< Max Number of distances per grid of TOF sensor
static const UINT32 OneTargetPerZoneMask            = 0x10000;      ///< Mask for 1 target per zone of sensor
static const UINT32 TwoTargetsPerZoneMask           = 0x20000;      ///< Mask for 2 targets per zone of sensor

/// @brief NCS Depth sensor type
enum DepthSensorType
{
    SinglePointToFSensor = 0,    ///< Single point TOF sensor
    MultiPointToFSensor  = 1,    ///< 4*4 or 8*8 TOF sensor
    DepthSensor          = 2,    ///< Depth sensor
    MaxDepthSensorType   = 3,    ///< Max depth sensor type
};

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

/// @brief TOF Sensor capabilites structure
struct TOFSensorCap : public NCSProviderCap
{
    sensor_t sensorCap;     ///< Sensor attribure
};

/// @brief TOF Sensor config structure
struct TOFSensorConfig : public NCSSensorConfig
{
    FLOAT                   samplingRate;           ///< Sampling rate in hertz.
    UINT                    reportRate;             ///< Reporting rate in micorseconds.
    INT                     configurationFlags;    ///< In case of depth TOF sensor this field is used to set default config
};

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

/// @brief TOF data structure for Single Point TOF sensor
struct TOFData
{
    FLOAT  version;     ///< Sensor version.
    FLOAT  type;        ///< Sensor specific type.
    FLOAT  distance;    ///< Estimated distance.
    FLOAT  confidence;  ///< Data confidence.
    FLOAT  nearLimit;   ///< Near limit of the sensor.
    FLOAT  farLimit;    ///< Far limit of the sensor.
    UINT64 timestamp;   ///< Timestamp of the sample.
    INT32  maxRange;    ///< Max range of the sensor.
    FLOAT  ambientRate; ///< ambient rate from sensor.
};

/// @brief TOF Depth data structure for Multi Point TOF Sensor. Distance is returned in Depth16 format
///        and buffer format depends on num of targets per zone configured.
struct Depth16TOFData
{
    UINT16  stride;                                     ///< Horizontal stride multiple of 16 pixels, this is per Android API
    UINT16  numOfTargetsPerGrid;                        ///< Number of target distance per grid of TOF sensor
    UINT16  depthBuffer[MaxGridWidth * MaxGridHeight * MaxNumOfTargetDistancesPerZone]; ///< depth buffer
};

/// @brief TOF Ambient data structure for Multi Point TOF Sensor. Ambient Rate is returned for configured number of
///        zones. Ambientrate = (photons detected in the zone) / sum(aperture of the enabled SPADS (SinglePhotonArrayDiodes))
///        In 64 zones mode Each zone is 16 SPAD that have different apertures. If there is a lot of IR ambient light the
///        SPADS with high aperture are automatically disabled in order to prevent these spads from saturating. But in low light
///        conditions all the SPADS are enabled. The provided IR is the sum of all the number of detected photons in the zone,
///        divided by the number of SPAD weighted with their apertures
struct InfraredTOFData
{
    UINT16  stride;         ///< Stride of data
    UINT32  ambientRate[MaxGridWidth * MaxGridHeight];   ///< Pointer to Ambient rate of IR from configured grids
};


/// @brief This structure represents the information returned by a multipoint TOF sensor.
struct MultipointTOFData
{
    UINT64              timestamp;          ///< Timestamp of the sample.
    UINT16              width;              ///< Width and height of the  data from sensor
    UINT16              height;             ///< Width and height are same for both Depth16 data and ambient rate data
    Depth16TOFData      m_depthBuffer;      ///< Depth16 data Buffer in an Array
    InfraredTOFData     m_infraredBuffer;   ///< Ambient rate of IR from configured grids
};

/// @brief This structure for unify alloc single/multi-point laser data
struct NCSDataTOFData
{
    union{
        TOFData           singleTOFData;
        MultipointTOFData multiTOFData;
    };
};

/// @brief TOF Depth Sensor Mode Configuration Enum
enum TOFModeConfiguration
{
    _8by8_15FPS = 1,        ///< 8*8 @ 15 FPS
    _8by8_7FPS,             ///< 8*8 @ 7 FPS
    _4by4_30FPS,            ///< 4*4 @ 30 FPS
    _4by4_15FPS,            ///< 4*4 @ 15 FPS
    _4by4_7FPS,             ///< 4*4 @ 7 FPS
    MaxMode = 0xFFFF        ///< max mode
};

CAMX_NAMESPACE_END

#ifdef __cplusplus
}
#endif // __cplusplus
#endif // CAMXTOFSENSORDEFS_H
