/**** Some of the code has been modified from the Example Code in  ******/
/**** the PSoC Creator. The copyright is owned by Cypress (Infineon). ***/
/**** The use of the code here is for the use as example when designing */
/**** with the PSoC MCU only. Please contact Cypress for any question ***/
/**** with regards to the copyright for redistribution.               ***/
/*
 * Main.c
 *
 * Created  : 2 February 2023
 * Modified : 31 May 2023
 * Author   : HWanyusof
 * Version	: 1.2
 */

#include "VCNL36828P.h"
#include "VCNL36828P_Prototypes.h"
#include "typedefinition.h"
#include "VCNL36828P_Application_Library.h" 
#include "project.h"

//Global Variables

/* Set the default slave address
 * VCNL36828P has 2 slave addresses depending on the Pin 5/Pin 6 (SCL/SDA) configuration.
 * Please refer to Table 1 on the datasheet
 * 1. 0x60
 * 2. 0x51
 */
int VCNL36828P_SlaveAddress = 0x60;

//Switch the I2C Bus number here (Currently only tested with Teensy3.5 with possibility to use multiple i2c channels)
// I2C_Bus = 1 for Wire 1 (Pin 18-SDA, 19-SCL)
// I2C_Bus = 2 for Wire 2 (Pin 37-SCL, 38-SDA)
//Other Arduino family boards-please use I2C_Bus = 1
//Other platforms will not be affected
int I2C_Bus = 2;

//Variables for Offset Value
int CalibValue = 0;
int AverageCount = 10; //Change the average count to the needed number of offset measurement

/* Function Prototypes */
void AF_Mode();
void Auto_Mode();
void Basic_Initialization_Auto_Mode();

int main(void)
{
    /* Enable global interrupts. */
    CyGlobalIntEnable;
    
    /* Place your initialization/startup code here (e.g. MyInst_Start()) */
    I2C_1_Start();
    CDC_Start(0,CDC_5V_OPERATION);
    CDC_CDC_Init();
    
    /* Reset Sensor to default value */
	//1. Reset for sensor 1 with slave address of 0x60
	VCNL36828P_SlaveAddress = 0x60;
	Reset_Sensor();
	//2. Reset for sensor 2 with slave address of 0x51
	VCNL36828P_SlaveAddress = 0x51;
	Reset_Sensor();

	/****************************************************************************/
	/****************************Basic  Initialization***************************/
	/*
     *Basic_Initialization_Auto_Mode() uses the most basic steps to turn on the Proximity Sensor.
     *Very useful when first working with the sensor.
     *For the more advanced settings, you can use the Auto_Mode() or AF_Mode()
     */

	//1. Initialization for sensor 1 with slave address of 0x60
	VCNL36828P_SlaveAddress = 0x60;
	Basic_Initialization_Auto_Mode();

	//2. Initialization for sensor 2 with slave address of 0x51
	VCNL36828P_SlaveAddress = 0x51;
	Basic_Initialization_Auto_Mode();


	/***************************End of Initialization****************************/
    /****************************************************************************/
    for(;;)
    {
        /* Print the sensor output */
    	//Print Sensor 1 with slave address of 0x60
    	VCNL36828P_SlaveAddress = 0x60;
    	Print_Data_Only();

    	//Print Sensor 2 with slave address of 0x60
    	VCNL36828P_SlaveAddress = 0x51;
    	Print_Data_Only();

    	CyDelay(500);
        /* Place your application code here. */
    }
}

//Auto/Self-Timed Mode Basic Initialization Function
void Basic_Initialization_Auto_Mode()
{
	//1.) Initialization
	//Switch the sensor off
	VCNL36828P_SET_PS_ON(VCNL36828P_PS_ON_DIS);

	//2.) Setting up PS
	//PS_CONF1_H
	//Enable/disable high dynamic range (12 bit/16 bit) ADC output setting
	VCNL36828P_SET_PS_HD(VCNL36828P_PS_HD_16Bits);

	//PS_CONF2_L
	//Set the integration time for one measurement; the pulse length “T” is determined by PS_ITB
	VCNL36828P_SET_PS_IT(VCNL36828P_PS_IT_8T);
	//Set the pulse length “T” for PS_IT
	VCNL36828P_SET_PS_ITB(VCNL36828P_PS_ITB_50us);
	//PS_CONF2_H
	//Set the VCSEL driving current
	VCNL36828P_SET_I_VCSEL(VCNL36828P_I_VCSEL_20mA);

	//PS_CONF3_L
	//Set the measurement mode of the sensor
	VCNL36828P_SET_PS_MODE(VCNL36828P_PS_MODE_AUTO_MODE);

	//3.) Switch On the sensor
	//Enable the internal calibration
	VCNL36828P_SET_PS_CAL(VCNL36828P_PS_CAL_EN);
	//Switch the sensor on
	VCNL36828P_SET_PS_ON(VCNL36828P_PS_ON_EN);

    //Delay needs to be changed depending on the API of the µ-controller
	CyDelay(1000);
}


//AF/Continuous Forced Mode Initialization Function
void AF_Mode()
{
	//1.) Initialization
		//Switch the sensor off
		VCNL36828P_SET_PS_ON(VCNL36828P_PS_ON_DIS);

		//2.) Setting up PS
		//PS_CONF1_H
		//Enable/disable high dynamic range (12 bit/16 bit) ADC output setting
		VCNL36828P_SET_PS_HD(VCNL36828P_PS_HD_16Bits);
		//Enable/disable the sunlight protection mode interrupt setting
		VCNL36828P_SET_PS_SP_INT(VCNL36828P_PS_SP_INT_EN);
		//Enable/disable the smart persistence setting when the interrupt event is triggered
		VCNL36828P_SET_PS_SMART_PERS(VCNL36828P_PS_SMART_PERS_DIS);
		//Set the amount of consecutive threshold crossing events necessary to trigger interrupt
		VCNL36828P_SET_PS_PERS(VCNL36828P_PS_PERS_1);
		//Set the interrupt mode setting
		VCNL36828P_SET_PS_INT(VCNL36828P_PS_INT_LOGIC_MODE);

		//PS_CONF2_L
		//Set the measurement period
		VCNL36828P_SET_PS_PERIOD(VCNL36828P_PS_PERIOD_50ms);
		//Set the integration time for one measurement; the pulse length “T” is determined by PS_ITB
		VCNL36828P_SET_PS_IT(VCNL36828P_PS_IT_8T);
		//Set the number of infrared signal pulses per measurement
		VCNL36828P_SET_PS_MPS(VCNL36828P_PS_MPS_1);
		//Set the pulse length “T” for PS_IT
		VCNL36828P_SET_PS_ITB(VCNL36828P_PS_ITB_50us);
		//Set the gain of the ADC
		VCNL36828P_SET_PS_GAIN(VCNL36828P_PS_GAIN_x1);

		//PS_CONF2_H
		//Set the sensitivity of the ADC
		VCNL36828P_SET_PS_SENS(VCNL36828P_PS_SENS_NORMAL);
		//Enable/disable the internal crosstalk cancellation
		VCNL36828P_SET_PS_OFFSET(VCNL36828P_PS_OFFSET_EN);
		//Set the VCSEL driving current
		VCNL36828P_SET_I_VCSEL(VCNL36828P_I_VCSEL_20mA);

		//PS_CONF3_L
		//Set the measurement mode of the sensor
		VCNL36828P_SET_PS_MODE(VCNL36828P_PS_MODE_AF_MODE);

		//PS_CONF3_H
		//Set the short measurement period
		VCNL36828P_SET_PS_SHORT_PERIOD(VCNL36828P_PS_SHORT_PERIOD_DIS);
		//Enable/disable the sunlight cancellation
		VCNL36828P_SET_PS_SC(VCNL36828P_PS_SC_EN);

		//3.) Switch On the sensor
		//Enable the internal calibration
		VCNL36828P_SET_PS_CAL(VCNL36828P_PS_CAL_EN);
		//Switch the sensor on
		VCNL36828P_SET_PS_ON(VCNL36828P_PS_ON_EN);

		//Delay of 10 ms needs to be changed depending on the API of the µ-controller of use
		CyDelay(10);

		//Clear Initial Interrupt
		VCNL36828P_GET_INT_FLAG();
		CyDelay(10);

		//4.) Threshold Setting and Offset Measurement
		for(int i=0;i<AverageCount;i++)
		{
			//Set trigger to start a measurement
		    VCNL36828P_SET_PS_TRIG(VCNL36828P_PS_TRIG_EN);
			//Delay of 10 ms needs to be changed depending on the API of the µ-controller of use
			CyDelay(10);
			CalibValue += VCNL36828P_GET_PS_DATA();
			//Delay of 10 ms needs to be changed depending on the API of the µ-controller of use
			CyDelay(10);
		}

		//Calculate the average of the offset measurement
		CalibValue /= AverageCount;

		//Set the offset count cancellation value
		VCNL36828P_SET_PS_CANC(CalibValue);
		//Set the low threshold interrupt value
		VCNL36828P_SET_PS_THDL(3000);
		//Set the high threshold interrupt value
		VCNL36828P_SET_PS_THDH(4000);

		CyDelay(1000);
}

//Auto/Self-Timed Mode Initialization Function
void Auto_Mode()
{
	//1.) Initialization
	//Switch the sensor off
	VCNL36828P_SET_PS_ON(VCNL36828P_PS_ON_DIS);

	//2.) Setting up PS
	//PS_CONF1_H
	//Enable/disable high dynamic range (12 bit/16 bit) ADC output setting
	VCNL36828P_SET_PS_HD(VCNL36828P_PS_HD_16Bits);
	//Enable/disable the sunlight protection mode interrupt setting
	VCNL36828P_SET_PS_SP_INT(VCNL36828P_PS_SP_INT_EN);
	//Enable/disable the smart persistence setting when the interrupt event is triggered
	VCNL36828P_SET_PS_SMART_PERS(VCNL36828P_PS_SMART_PERS_DIS);
	//Set the amount of consecutive threshold crossing events necessary to trigger interrupt
	VCNL36828P_SET_PS_PERS(VCNL36828P_PS_PERS_1);
	//Set the interrupt mode setting
	VCNL36828P_SET_PS_INT(VCNL36828P_PS_INT_LOGIC_MODE);

	//PS_CONF2_L
	//Set the measurement period
	VCNL36828P_SET_PS_PERIOD(VCNL36828P_PS_PERIOD_50ms);
	//Set the integration time for one measurement; the pulse length “T” is determined by PS_ITB
	VCNL36828P_SET_PS_IT(VCNL36828P_PS_IT_8T);
	//Set the number of infrared signal pulses per measurement
	VCNL36828P_SET_PS_MPS(VCNL36828P_PS_MPS_1);
	//Set the pulse length “T” for PS_IT
	VCNL36828P_SET_PS_ITB(VCNL36828P_PS_ITB_50us);
	//Set the gain of the ADC
	VCNL36828P_SET_PS_GAIN(VCNL36828P_PS_GAIN_x1);

	//PS_CONF2_H
	//Set the sensitivity of the ADC
	VCNL36828P_SET_PS_SENS(VCNL36828P_PS_SENS_NORMAL);
	//Enable/disable the internal crosstalk cancellation
	VCNL36828P_SET_PS_OFFSET(VCNL36828P_PS_OFFSET_EN);
	//Set the VCSEL driving current
	VCNL36828P_SET_I_VCSEL(VCNL36828P_I_VCSEL_20mA);

	//PS_CONF3_L
	//Set the measurement mode of the sensor
	VCNL36828P_SET_PS_MODE(VCNL36828P_PS_MODE_AUTO_MODE);

	//PS_CONF3_H
	//Set the short measurement period
	VCNL36828P_SET_PS_SHORT_PERIOD(VCNL36828P_PS_SHORT_PERIOD_DIS);
	//Enable/disable the sunlight cancellation
	VCNL36828P_SET_PS_SC(VCNL36828P_PS_SC_EN);

	//3.) Switch On the sensor
	//Enable the internal calibration
	VCNL36828P_SET_PS_CAL(VCNL36828P_PS_CAL_EN);
	//Switch the sensor on
	VCNL36828P_SET_PS_ON(VCNL36828P_PS_ON_EN);

	//Delay of 10 ms needs to be changed depending on the API of the µ-controller of use
	CyDelay(10);

	//Clear Initial Interrupt
	VCNL36828P_GET_INT_FLAG();
	CyDelay(10);

	//4.) Threshold Setting and Offset Measurement
	for(int i=0;i<AverageCount;i++)
	{
		//Delay of 10 ms needs to be changed depending on the API of the µ-controller of use
		CyDelay(10);
		CalibValue += VCNL36828P_GET_PS_DATA();
		//Delay of 10 ms needs to be changed depending on the API of the µ-controller of use
		CyDelay(10);
	}

	//Calculate the average of the offset measurement
	CalibValue /= AverageCount;

	//Set the offset count cancellation value
	VCNL36828P_SET_PS_CANC(CalibValue);
	//Set the low threshold interrupt value
	VCNL36828P_SET_PS_THDL(3000);
	//Set the high threshold interrupt value
	VCNL36828P_SET_PS_THDH(4000);

	CyDelay(1000);
}



/* [] END OF FILE */
