2021-11-11 06:26 AM
Hi ,
I am working on STM32L0 series controller with VD6283TX ALS on I2C interface.
Though code is available for the sensor, my requirement is to write own code that will control the sensor. Sometimes it reads the RAW data from sensor and sometimes it gives 0 values from sensor. I am confused why this is happening. Please suggest the way to get consistent output from the sensor. Here is my code-i am using ReadChannelValue(uint8_t channel)to read the output of particular channel
#define SLAVE_READ_ADDR (0x41)
#define SLAVE_WRITE_ADDR (0x40)
#define I2C_TIMEOUT (100)
#define INTERRUPT_CTRL_REG (0x02)
#define ALS_CTRL_REG (0x03)
/*config param*/
#define ALS_EN (0x01)
#define ALS_CONT (0x06)
#define ALS_PERIOD_REG (0x04)
/*config param*/
#define ALS_IM_PER (0x32)/*1 corresponds to 20.5ms->255*20.5 =5.22s max period*/
#define CHANNEL6_ENABLE_REG (0x2D)
/*config param*/
#define CH6_EN (0x01)
#define ALS_CHANNEL_ENABLE_REG (0x2E)
/*config param*/
#define ALS_CH_EN (0x1F)/*enable all channels*/
#define AC_MODE_CTRL_RED (0x31)
/*config param*/
#define PEDESTAL_DIS (0x40)
#define AC_OUT_SEL (0X00)
#define AC_CH_SEL (0x00)
#define AC_FREQEXT_EN (0x01)
#define PEDESTAL_VALUE_REG (0x32)
/*config param*/
#define PDST_VAL (0x03)/*recommended in datasheet*/
#define ALS_GAIN_CH1_REG (0x25)
#define ALS_GAIN_CH2_REG (0x26)
#define ALS_GAIN_CH3_REG (0x27)
#define ALS_GAIN_CH4_REG (0x28)
#define ALS_GAIN_CH5_REG (0x29)
#define ALS_GAIN_CH6_REG (0x2A)
#define SDA_DRV_CFG_REG (0x3C)
#define CHANNEL_1_DATA_REG_SA (0x06U)
#define CHANNEL_2_DATA_REG_SA (0x0AU)
#define CHANNEL_3_DATA_REG_SA (0x0EU)
#define CHANNEL_4_DATA_REG_SA (0x12U)
#define CHANNEL_5_DATA_REG_SA (0x16U)
#define CHANNEL_6_DATA_REG_SA (0x1AU)
////////////////////////////////////////////////////////////////////
void VD6283_Init(void)
{
VD6283_WriteRegister(ALS_CTRL_REG,(ALS_EN | ALS_CONT));
VD6283_WriteRegister(ALS_PERIOD_REG,ALS_IM_PER);
VD6283_WriteRegister(CHANNEL6_ENABLE_REG,CH6_EN);
VD6283_WriteRegister(ALS_CHANNEL_ENABLE_REG,ALS_CH_EN);
VD6283_WriteRegister(AC_MODE_CTRL_RED,(PEDESTAL_DIS | AC_OUT_SEL | AC_CH_SEL | AC_FREQEXT_EN));
VD6283_WriteRegister(PEDESTAL_VALUE_REG,PDST_VAL);
VD6283_WriteRegister(INTERRUPT_CTRL_REG,1);
VD6283_WriteRegister(INTERRUPT_CTRL_REG,0);
}
//////////////////////////////////////////////////////////////////
uint8_t VD6283_ReadRegister(uint8_t address)
{
uint8_t data =0;
HAL_I2C_Master_Transmit(&hi2c1, SLAVE_WRITE_ADDR, &address, sizeof(address), I2C_TIMEOUT);
HAL_I2C_Master_Receive(&hi2c1, SLAVE_READ_ADDR, &data, sizeof(uint8_t), I2C_TIMEOUT);
VD6283_WriteRegister(INTERRUPT_CTRL_REG,1);
VD6283_WriteRegister(INTERRUPT_CTRL_REG,0);
return data;
}
////////////////////////////////////////////////////////////////////////
void VD6283_WriteRegister(uint8_t address,uint8_t data)
{
uint8_t databuff[2];
databuff[0] = address;
databuff[1] = data;
HAL_I2C_Master_Transmit(&hi2c1, SLAVE_WRITE_ADDR, databuff, (uint16_t)sizeof(databuff), I2C_TIMEOUT);
}
////////////////////////////////////////////////////////////////////////////
uint32_t ReadChannelValue(uint8_t channel)
{
uint32_t val = 0;
HAL_StatusTypeDef retVal;
uint8_t tempBuff = 0;
switch(channel)
{
case CHANNEL_1:
tempBuff = CHANNEL_1_DATA_REG_SA;
retVal = HAL_I2C_Master_Transmit(&hi2c1, SLAVE_WRITE_ADDR,&tempBuff, 1, I2C_TIMEOUT);
retVal = HAL_I2C_Master_Receive(&hi2c1, SLAVE_READ_ADDR, (uint8_t *)&val,CHANNEL_OUTPUT_SIZE, I2C_TIMEOUT);
allchannelData.channel_1 = val;
break;
case CHANNEL_2:
tempBuff = CHANNEL_2_DATA_REG_SA;
retVal = HAL_I2C_Master_Transmit(&hi2c1, SLAVE_WRITE_ADDR, &tempBuff, 1, I2C_TIMEOUT);
retVal = HAL_I2C_Master_Receive(&hi2c1, SLAVE_READ_ADDR, (uint8_t*)&val,CHANNEL_OUTPUT_SIZE, I2C_TIMEOUT);
allchannelData.channel_2 = val;
break;
case CHANNEL_3:
tempBuff = CHANNEL_3_DATA_REG_SA;
retVal = HAL_I2C_Master_Transmit(&hi2c1, SLAVE_WRITE_ADDR, &tempBuff, 1, I2C_TIMEOUT);
retVal = HAL_I2C_Master_Receive(&hi2c1, SLAVE_READ_ADDR, (uint8_t*)&val,CHANNEL_OUTPUT_SIZE, I2C_TIMEOUT);
allchannelData.channel_3 = val;
break;
case CHANNEL_4:
tempBuff = CHANNEL_4_DATA_REG_SA;
retVal = HAL_I2C_Master_Transmit(&hi2c1, SLAVE_WRITE_ADDR, &tempBuff, 1, I2C_TIMEOUT);
retVal = HAL_I2C_Master_Receive(&hi2c1, SLAVE_READ_ADDR, (uint8_t*)&val,CHANNEL_OUTPUT_SIZE, I2C_TIMEOUT);
allchannelData.channel_4 = val;
break;
case CHANNEL_5:
tempBuff = CHANNEL_5_DATA_REG_SA;
retVal = HAL_I2C_Master_Transmit(&hi2c1, SLAVE_WRITE_ADDR, &tempBuff, 1, I2C_TIMEOUT);
retVal = HAL_I2C_Master_Receive(&hi2c1, SLAVE_READ_ADDR, (uint8_t*)&val,CHANNEL_OUTPUT_SIZE, I2C_TIMEOUT);
allchannelData.channel_5 = val;
break;
case CHANNEL_6:
tempBuff = CHANNEL_6_DATA_REG_SA;
retVal = HAL_I2C_Master_Transmit(&hi2c1, SLAVE_WRITE_ADDR, &tempBuff, 1, I2C_TIMEOUT);
retVal = HAL_I2C_Master_Receive(&hi2c1, SLAVE_READ_ADDR, (uint8_t*)&val, CHANNEL_OUTPUT_SIZE, I2C_TIMEOUT);
allchannelData.channel_6 = val;
break;
}
VD6283_WriteRegister(INTERRUPT_CTRL_REG,1);
VD6283_WriteRegister(INTERRUPT_CTRL_REG,0);
return val;
}
TIA,
Bipin
2021-11-11 07:05 AM
Dear,
I believe you should also read the validity bit to check the channel data consistency.
I suggest to look for it in the VD6283 driver (in STSW-IMG302 or X-CUBE-ALS from st.com)
Regards,
Elio
2021-11-12 08:02 AM
Hi Elio,
Thanks for the response! i just noticed in datasheet that "the VD6283 registers should be accessed only through the VD6283 software driver provided by STMicroelectronics" so i am dropping the idea to use my driver. Can you / anyone help to understand how to use the available driver as i was able to read the device id and revision id of the device from the driver but the data ready flag is not in a state to read the data,and hence there is no data when i call "VD6283TX_GetValues()".
any reference document i should refer?
Here is the sequence of API's i am using:
VD6283TX_Object_t LSstruct;
uint32_t data[6];
LSstruct.handle = &hi2c1;
uint8_t ret = VD6283TX_Init(&LSstruct);
VD6283TX_Start(&LSstruct,0);
ret = VD6283TX_GetValues(&LSstruct,data);
Thanks
2023-08-08 04:58 AM
Hello
Sorry for the late answer.
If you are always interested, please check this UM.
Regards
Anne