/*
 * VEML6031X00_ALS.c
 *
 * Created  : 20 August 2021
 * Modified : 13 June 2023
 * Author   : HWanyusof
 * Version	: 1.2
 */

#include "VEML6031X00_Prototypes.h"
#include "VEML6031X00.h"
#include "I2C_Functions.h"
#include "VEML6031X00_Application_Library.h"

extern int I2C_Bus;

//****************************************************************************************************
//*****************************************Sensor API*************************************************

/*Turn On/Off the Bandgap and LDO
 *VEML6031X00_SET_SD(Byte SD_Bit)
 *Byte SD_Bit - Input Parameter:
 *
 * VEML6031X00_SD_ON
 * VEML6031X00_SD_OFF
 *
 */
void VEML6031X00_SET_SD(Byte SD_Bit)
{
	struct TransferData VEML6031X00_Data;
	VEML6031X00_Data.Slave_Address = VEML6031X00_Slave_Address;
	VEML6031X00_Data.RegisterAddress = VEML6031X00_ALS_CONF_0;
	VEML6031X00_Data.Select_I2C_Bus = I2C_Bus;
	ReadI2C_Bus(&VEML6031X00_Data);
	VEML6031X00_Data.WData[0] = (VEML6031X00_Data.RData[0]&~(VEML6031X00_SD_ON|VEML6031X00_SD_OFF))|SD_Bit;
	VEML6031X00_Data.WData[1] = VEML6031X00_Data.RData[1];
	WriteI2C_Bus(&VEML6031X00_Data);
}

/*Turn On/Off the ALS IR Channel
 *VEML6031X00_SET_ALS_IR_SD(Byte SD_Bit)
 *Byte SD_Bit - Input Parameter:
 *
 * VEML6031X00_ALS_IR_SD_ON
 * VEML6031X00_ALS_IR_SD_OFF
 *
 */
void VEML6031X00_SET_ALS_IR_SD(Byte SD_Bit)
{
	struct TransferData VEML6031X00_Data;
	VEML6031X00_Data.Slave_Address = VEML6031X00_Slave_Address;
	VEML6031X00_Data.RegisterAddress = VEML6031X00_ALS_CONF_0;
	VEML6031X00_Data.Select_I2C_Bus = I2C_Bus;
	ReadI2C_Bus(&VEML6031X00_Data);
	VEML6031X00_Data.WData[0] = VEML6031X00_Data.RData[0];
	VEML6031X00_Data.WData[1] = (VEML6031X00_Data.RData[1]&~(VEML6031X00_ALS_IR_SD_ON|VEML6031X00_ALS_IR_SD_OFF))|SD_Bit;
	WriteI2C_Bus(&VEML6031X00_Data);
}

/*Set the Integration Time
 *VEML6031X00_SET_ALS_IT(Byte IntTime)
 *Byte IntTime - Input Parameter:
 *
 * VEML6031X00_ALS_IT_3_125ms
 * VEML6031X00_ALS_IT_6_25ms
 * VEML6031X00_ALS_IT_12_5ms
 * VEML6031X00_ALS_IT_25ms
 * VEML6031X00_ALS_IT_50ms
 * VEML6031X00_ALS_IT_100ms
 * VEML6031X00_ALS_IT_200ms
 * VEML6031X00_ALS_IT_400ms
 */
void VEML6031X00_SET_ALS_IT(Byte IntTime)
{
	struct TransferData VEML6031X00_Data;
	VEML6031X00_Data.Slave_Address = VEML6031X00_Slave_Address;
	VEML6031X00_Data.RegisterAddress = VEML6031X00_ALS_CONF_0;
	VEML6031X00_Data.Select_I2C_Bus = I2C_Bus;
	ReadI2C_Bus(&VEML6031X00_Data);
	VEML6031X00_Data.WData[0] = (VEML6031X00_Data.RData[0]&~(VEML6031X00_ALS_IT_3_125ms|VEML6031X00_ALS_IT_6_25ms|VEML6031X00_ALS_IT_12_5ms|VEML6031X00_ALS_IT_25ms|VEML6031X00_ALS_IT_50ms|VEML6031X00_ALS_IT_100ms|VEML6031X00_ALS_IT_200ms|VEML6031X00_ALS_IT_400ms))|IntTime;
	VEML6031X00_Data.WData[1] = VEML6031X00_Data.RData[1];
	WriteI2C_Bus(&VEML6031X00_Data);
}

/*Enable/Disable Active Force or Auto Mode
 *VEML6031X00_SET_ALS_AF(Byte AF_Bit)
 *Byte AF_Bit - Input Parameter:
 *
 * VEML6031X00_ALS_AUTO
 * VEML6031X00_ALS_AF_EN
 */
void VEML6031X00_SET_ALS_AF(Byte AF_Bit)
{
	struct TransferData VEML6031X00_Data;
	VEML6031X00_Data.Slave_Address = VEML6031X00_Slave_Address;
	VEML6031X00_Data.RegisterAddress =  VEML6031X00_ALS_CONF_0;
	VEML6031X00_Data.Select_I2C_Bus = I2C_Bus;
    ReadI2C_Bus(&VEML6031X00_Data);
	VEML6031X00_Data.WData[0] =(VEML6031X00_Data.RData[0]&~(VEML6031X00_ALS_AUTO|VEML6031X00_ALS_AF_EN))|AF_Bit;
	VEML6031X00_Data.WData[1] = VEML6031X00_Data.RData[1];
	WriteI2C_Bus(&VEML6031X00_Data);
}

/*Enable/Disable Trigger for AF Mode
 *VEML6031X00_SET_ALS_TRIG(Byte TriggerBit)
 *Byte TriggerBit - Input Parameter:
 *
 * VEML6031X00_ALS_TRIG_EN
 * VEML6031X00_ALS_TRIG_DIS
 */
void VEML6031X00_SET_ALS_TRIG(Byte TriggerBit)
{
	struct TransferData VEML6031X00_Data;
	VEML6031X00_Data.Slave_Address = VEML6031X00_Slave_Address;
	VEML6031X00_Data.RegisterAddress =  VEML6031X00_ALS_CONF_0;
	VEML6031X00_Data.Select_I2C_Bus = I2C_Bus;
    ReadI2C_Bus(&VEML6031X00_Data);
	VEML6031X00_Data.WData[0] =(VEML6031X00_Data.RData[0]&~(VEML6031X00_ALS_TRIG_EN|VEML6031X00_ALS_TRIG_DIS))|TriggerBit;
	VEML6031X00_Data.WData[1] = VEML6031X00_Data.RData[1];
	WriteI2C_Bus(&VEML6031X00_Data);
}

/*Enable/Disable Interrupt
 *VEML6031X00_SET_ALS_INT_EN(Byte Interrupt)
 *Byte Interrupt - Input Parameter:
 *
 * VEML6031X00_ALS_INT_EN
 * VEML6031X00_ALS_INT_DIS
 */
void VEML6031X00_SET_ALS_INT_EN(Byte Interrupt)
{
	struct TransferData VEML6031X00_Data;
	VEML6031X00_Data.Slave_Address = VEML6031X00_Slave_Address;
	VEML6031X00_Data.RegisterAddress = VEML6031X00_ALS_CONF_0;
	VEML6031X00_Data.Select_I2C_Bus = I2C_Bus;
	ReadI2C_Bus(&VEML6031X00_Data);
	VEML6031X00_Data.WData[0] = (VEML6031X00_Data.RData[0]&~(VEML6031X00_ALS_INT_EN | VEML6031X00_ALS_INT_DIS))|Interrupt;
	VEML6031X00_Data.WData[1] = VEML6031X00_Data.RData[1];
	WriteI2C_Bus(&VEML6031X00_Data);
}

/*Set effective PD size of ALS and IR channel
 *VEML6031X00_SET_PD_DIV4(Byte PD_Size)
 *Byte PD_Size - Input Parameter:
 *
 * VEML6031X00_PD_DIV4_FULL
 * VEML6031X00_PD_DIV4_QUARTER
 */
void VEML6031X00_SET_PD_DIV4(Byte PD_Size)
{
	struct TransferData VEML6031X00_Data;
	VEML6031X00_Data.Slave_Address = VEML6031X00_Slave_Address;
	VEML6031X00_Data.RegisterAddress = VEML6031X00_ALS_CONF_0;
	VEML6031X00_Data.Select_I2C_Bus = I2C_Bus;
	ReadI2C_Bus(&VEML6031X00_Data);
	VEML6031X00_Data.WData[0] = (VEML6031X00_Data.RData[0]);
	VEML6031X00_Data.WData[1] = (VEML6031X00_Data.RData[1]&~(VEML6031X00_PD_DIV4_FULL|VEML6031X00_PD_DIV4_QUARTER))|PD_Size;
	WriteI2C_Bus(&VEML6031X00_Data);
}

/*Set the Analog Gain
 *VEML6031X00_SET_ALS_GAIN(Byte Gain)
 *Byte Gain - Input Parameter:
 *
 * VEML6031X00_ALS_GAIN_x0_5
 * VEML6031X00_ALS_GAIN_x0_66
 * VEML6031X00_ALS_GAIN_x1
 * VEML6031X00_ALS_GAIN_x2
 */
void VEML6031X00_SET_ALS_GAIN(Byte Gain)
{
	struct TransferData VEML6031X00_Data;
	VEML6031X00_Data.Slave_Address = VEML6031X00_Slave_Address;
	VEML6031X00_Data.RegisterAddress = VEML6031X00_ALS_CONF_0;
	VEML6031X00_Data.Select_I2C_Bus = I2C_Bus;
	ReadI2C_Bus(&VEML6031X00_Data);
	VEML6031X00_Data.WData[0] = VEML6031X00_Data.RData[0];
	VEML6031X00_Data.WData[1] = (VEML6031X00_Data.RData[1]&~(VEML6031X00_ALS_GAIN_x1|VEML6031X00_ALS_GAIN_x2|VEML6031X00_ALS_GAIN_x0_66|VEML6031X00_ALS_GAIN_x0_5))|(Gain);
	WriteI2C_Bus(&VEML6031X00_Data);
}

/*Set the Persistence
 *VEML6031X00_SET_PERS(Byte Pers)
 *Byte Pers - Input Parameter:
 *
 * VEML6031X00_ALS_PERS_1
 * VEML6031X00_ALS_PERS_2
 * VEML6031X00_ALS_PERS_4
 * VEML6031X00_ALS_PERS_8
 */
void VEML6031X00_SET_PERS(Byte Pers)
{
	struct TransferData VEML6031X00_Data;
	VEML6031X00_Data.Slave_Address = VEML6031X00_Slave_Address;
	VEML6031X00_Data.RegisterAddress = VEML6031X00_ALS_CONF_0;
	VEML6031X00_Data.Select_I2C_Bus = I2C_Bus;
	ReadI2C_Bus(&VEML6031X00_Data);
	VEML6031X00_Data.WData[0] = (VEML6031X00_Data.RData[0]);
	VEML6031X00_Data.WData[1] = (VEML6031X00_Data.RData[1]&~(VEML6031X00_ALS_PERS_1|VEML6031X00_ALS_PERS_2|VEML6031X00_ALS_PERS_4|VEML6031X00_ALS_PERS_8))|Pers;
	WriteI2C_Bus(&VEML6031X00_Data);
}

/*Set the ALS internal calibration (OTP Trigger)
 *VEML6031X00_SET_ALS_CAL(Byte als_cal)
 *Byte als_cal - Input Parameter:
 *
 * VEML6031X00_ALS_CAL_ON
 * VEML6031X00_ALS_CAL_OFF
 */
void VEML6031X00_SET_ALS_CAL(Byte als_cal)
{
	struct TransferData VEML6031X00_Data;
	VEML6031X00_Data.Slave_Address = VEML6031X00_Slave_Address;
	VEML6031X00_Data.RegisterAddress = VEML6031X00_ALS_CONF_0;
	VEML6031X00_Data.Select_I2C_Bus = I2C_Bus;
	ReadI2C_Bus(&VEML6031X00_Data);
	VEML6031X00_Data.WData[0] = (VEML6031X00_Data.RData[0]);
	VEML6031X00_Data.WData[1] = (VEML6031X00_Data.RData[1]&~(VEML6031X00_ALS_CAL_ON|VEML6031X00_ALS_CAL_OFF))|als_cal;
	WriteI2C_Bus(&VEML6031X00_Data);
}

/*Set the High Threshold
 *VEML6031X00_SET_ALS_HighThreshold(Word HighThreshold)
 *Word HighThreshold - Input Parameter:
 *
 * Value between 0d0 and 0d65535
 */
void VEML6031X00_SET_ALS_HighThreshold(Word HighThreshold)
{
 	struct TransferData VEML6031X00_Data;
	VEML6031X00_Data.Slave_Address = VEML6031X00_Slave_Address;
	VEML6031X00_Data.RegisterAddress = VEML6031X00_ALS_WH_L;
	VEML6031X00_Data.Select_I2C_Bus = I2C_Bus;
	VEML6031X00_Data.WData[0] = HighThreshold;
	VEML6031X00_Data.WData[1] = (HighThreshold>>8);
	WriteI2C_Bus(&VEML6031X00_Data);
}

/*Set the Low threshold
 *VEML6031X00_SET_ALS_LowThreshold(Word LowThreshold)
 *Word LowThreshold - Input Parameter:
 *
 * Value between 0d0 and 0d65535
 */
void VEML6031X00_SET_ALS_LowThreshold(Word LowThreshold)
{
	struct TransferData VEML6031X00_Data;
	VEML6031X00_Data.Slave_Address = VEML6031X00_Slave_Address;
	VEML6031X00_Data.RegisterAddress = VEML6031X00_ALS_WL_L;
	VEML6031X00_Data.Select_I2C_Bus = I2C_Bus;
	VEML6031X00_Data.WData[0] = LowThreshold;
	VEML6031X00_Data.WData[1] = (LowThreshold>>8);
	WriteI2C_Bus(&VEML6031X00_Data);
}

/*Read the ALS Data
 *VEML6031X00_GET_ALS_DATA() returns ALS Data between 0d0 and 0d65535
 */
Word VEML6031X00_GET_ALS_DATA()
{
	int RData=0;
	struct TransferData VEML6031X00_Data;
	VEML6031X00_Data.Slave_Address = VEML6031X00_Slave_Address;
	VEML6031X00_Data.RegisterAddress = VEML6031X00_ALS_DATA_L;
	VEML6031X00_Data.Select_I2C_Bus = I2C_Bus;
	ReadI2C_Bus(&VEML6031X00_Data);
	RData=((VEML6031X00_Data.RData[1]<<8)|VEML6031X00_Data.RData[0]);
	return RData;
}

/*Read the IR Channel Data
 *VEML6031X00_GET_IR_DATA() returns IR Data between 0d0 and 0d65535
 */
Word VEML6031X00_GET_IR_DATA()
{
	int RData=0;
	struct TransferData VEML6031X00_Data;
	VEML6031X00_Data.Slave_Address = VEML6031X00_Slave_Address;
	VEML6031X00_Data.RegisterAddress = VEML6031X00_IR_DATA_L;
	VEML6031X00_Data.Select_I2C_Bus = I2C_Bus;
	ReadI2C_Bus(&VEML6031X00_Data);
	RData = ((VEML6031X00_Data.RData[1]<<8)|VEML6031X00_Data.RData[0]);
	return RData;
}


/*Read the ALS Interrupt Flag
 *VEML6031X00_GET_ALS_INT() returns interrupt flag status.
 *Please refer to Table 8 in the Datasheet page 10
 */
Byte VEML6031X00_GET_ALS_INT()
{
	uint8_t RData;
	struct TransferData VEML6031X00_Data;
	VEML6031X00_Data.Slave_Address = VEML6031X00_Slave_Address;
	VEML6031X00_Data.RegisterAddress = VEML6031X00_ALS_INT;
	VEML6031X00_Data.Select_I2C_Bus = I2C_Bus;
	ReadI2C_Bus(&VEML6031X00_Data);
    RData = (VEML6031X00_Data.RData[0]);
	return RData;
}

/*Read Register value
 *VEML6031X00_READ_Reg(Byte Reg)
 *Byte Reg - Input Parameter:
 *
 * VEML6031X00_ALS_CONF_0
 * VEML6031X00_ALS_WH_LB
 * VEML6031X00_ALS_WL_LB
 * VEML6031X00_ALS_DATA_LB
 * VEML6031X00_IR_DATA_LB
 * VEML6031X00_ID_CODE1
 * VEML6031X00_ALS_INT
 *
 *returns Register Value between 0d0/0x00 and 0d65535/0xFFFF
 */
Word VEML6031X00_READ_Reg(Byte Reg)
{
	struct TransferData VEML6031X00_Data;
	VEML6031X00_Data.Slave_Address = VEML6031X00_Slave_Address;
	VEML6031X00_Data.RegisterAddress = Reg;
	VEML6031X00_Data.Select_I2C_Bus = I2C_Bus;
	ReadI2C_Bus(&VEML6031X00_Data);
	return (VEML6031X00_Data.RData[1]<<8|VEML6031X00_Data.RData[0]);
}

/*Read the SD bit
 *returns 1 for Shutdown and 0 for Bandgap and LDO On
 */
bool VEML6031X00_GET_SD_Bit()
{
	struct TransferData VEML6031X00_Data;
	VEML6031X00_Data.Slave_Address = VEML6031X00_Slave_Address;
	VEML6031X00_Data.RegisterAddress = VEML6031X00_ALS_CONF_0;
    VEML6031X00_Data.Select_I2C_Bus = I2C_Bus;
	ReadI2C_Bus(&VEML6031X00_Data);
	return (VEML6031X00_Data.RData[0] & 0x01);
}

/*Read the ALS_IR_SD bit
 *returns 0 for ALS IR channel on and 1 for shutdown
 */
bool VEML6031X00_GET_ALS_IR_SD_Bit()
{
	struct TransferData VEML6031X00_Data;
	VEML6031X00_Data.Slave_Address = VEML6031X00_Slave_Address;
	VEML6031X00_Data.RegisterAddress = VEML6031X00_ALS_CONF_0;
    VEML6031X00_Data.Select_I2C_Bus = I2C_Bus;
	ReadI2C_Bus(&VEML6031X00_Data);
	return (VEML6031X00_Data.RData[1] & 0x80);
}

/*Read the ALS_AF bit
 *returns 1 for AF Mode and 0 for Auto Mode
 */
bool VEML6031X00_GET_ALS_AF_Bit()
{
	struct TransferData VEML6031X00_Data;
	VEML6031X00_Data.Slave_Address = VEML6031X00_Slave_Address;
	VEML6031X00_Data.RegisterAddress = VEML6031X00_ALS_CONF_0;
    VEML6031X00_Data.Select_I2C_Bus = I2C_Bus;
	ReadI2C_Bus(&VEML6031X00_Data);
	return (VEML6031X00_Data.RData[0] & 0x08);
}

/*Read the ALS_IT bits
 *returns 0d0 - 0d8 depending on ALS_IT bits
 */
int VEML6031X00_GET_ALS_IT_Bits()
{
	struct TransferData VEML6031X00_Data;
	VEML6031X00_Data.Slave_Address = VEML6031X00_Slave_Address;
	VEML6031X00_Data.RegisterAddress = VEML6031X00_ALS_CONF_0;
    VEML6031X00_Data.Select_I2C_Bus = I2C_Bus;
	ReadI2C_Bus(&VEML6031X00_Data);
	if ((VEML6031X00_Data.RData[0] & 0x70) == 0x00) {return 1;}
	if ((VEML6031X00_Data.RData[0] & 0x70) == 0x10) {return 2;}
	if ((VEML6031X00_Data.RData[0] & 0x70) == 0x20) {return 3;}
	if ((VEML6031X00_Data.RData[0] & 0x70) == 0x30) {return 4;}
	if ((VEML6031X00_Data.RData[0] & 0x70) == 0x40) {return 5;}
	if ((VEML6031X00_Data.RData[0] & 0x70) == 0x50) {return 6;}
	if ((VEML6031X00_Data.RData[0] & 0x70) == 0x60) {return 7;}
	if ((VEML6031X00_Data.RData[0] & 0x70) == 0x70) {return 8;}
	else
	return 0;
}

/*Read the ALS_GAIN bits
 *returns 0d0 - 0d4 depending on ALS_GAIN bits
 */
int VEML6031X00_GET_ALS_GAIN_Bits()
{
	struct TransferData VEML6031X00_Data;
	VEML6031X00_Data.Slave_Address = VEML6031X00_Slave_Address;
	VEML6031X00_Data.RegisterAddress = VEML6031X00_ALS_CONF_0;
    VEML6031X00_Data.Select_I2C_Bus = I2C_Bus;
	ReadI2C_Bus(&VEML6031X00_Data);
	if ((VEML6031X00_Data.RData[1] & 0x18) == 0x00) {return 1;}
	if ((VEML6031X00_Data.RData[1] & 0x18) == 0x08) {return 2;}
	if ((VEML6031X00_Data.RData[1] & 0x18) == 0x10) {return 3;}
	if ((VEML6031X00_Data.RData[1] & 0x18) == 0x18) {return 4;}
	else
	return 0;
}

/*Read the PD_DIV4 bit
 *returns 1 for 1/4 PD size being used and 0 for full (4/4) PD size being used
 */
bool VEML6031X00_GET_PD_DIV4_Bit()
{
	struct TransferData VEML6031X00_Data;
	VEML6031X00_Data.Slave_Address = VEML6031X00_Slave_Address;
	VEML6031X00_Data.RegisterAddress = VEML6031X00_ALS_CONF_0;
    VEML6031X00_Data.Select_I2C_Bus = I2C_Bus;
	ReadI2C_Bus(&VEML6031X00_Data);
	return (VEML6031X00_Data.RData[1] & 0x40);
}

/*Read Device ID
 *Returns ID
 */
Word VEML6031X00_GET_ID()
{
	Word RegValue;
	struct TransferData VEML6031X00_Data;
	VEML6031X00_Data.Slave_Address = VEML6031X00_Slave_Address;
	VEML6031X00_Data.RegisterAddress = VEML6031X00_ID_L;
	VEML6031X00_Data.Select_I2C_Bus = I2C_Bus;
	ReadI2C_Bus(&VEML6031X00_Data);
	RegValue = VEML6031X00_Data.RData[1]<<8|VEML6031X00_Data.RData[0];
	return RegValue;
}

/*Read the AF_DATA_READY flag
 *returns 1 for AF_DATA_READY flag and 0 for no AF_DATA_READY flag
 */
bool VEML6031X00_GET_AF_DATA_READY_FLAG()
{
	struct TransferData VEML6031X00_Data;
	VEML6031X00_Data.Slave_Address = VEML6031X00_Slave_Address;
	VEML6031X00_Data.RegisterAddress = VEML6031X00_ALS_INT;
    VEML6031X00_Data.Select_I2C_Bus = I2C_Bus;
	ReadI2C_Bus(&VEML6031X00_Data);
	return (VEML6031X00_Data.RData[0] & 0x08);
}
