Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: Check_VL6180XA1_ToF
Fork of X_NUCLEO_6180XA1 by
Diff: Components/VL6180X/vl6180x_class.cpp
- Revision:
- 4:a5abf7757947
- Parent:
- 3:454541a079f4
- Child:
- 7:2dc81120c917
--- a/Components/VL6180X/vl6180x_class.cpp Fri Sep 11 14:39:00 2015 +0200
+++ b/Components/VL6180X/vl6180x_class.cpp Thu Sep 17 10:41:21 2015 +0200
@@ -38,8 +38,104 @@
/* Includes ------------------------------------------------------------------*/
#include "vl6180x_class.h"
+/* define for inizialization -------------------------------------------------*/
+
+#if VL6180x_UPSCALE_SUPPORT == 1
+ #define _GetUpscale(dev, ... ) 1
+ #define _SetUpscale(...) -1
+ #define DEF_UPSCALE 1
+#elif VL6180x_UPSCALE_SUPPORT == 2
+ #define _GetUpscale(dev, ... ) 2
+ #define _SetUpscale(...)
+ #define DEF_UPSCALE 2
+#elif VL6180x_UPSCALE_SUPPORT == 3
+ #define _GetUpscale(dev, ... ) 3
+ #define _SetUpscale(...)
+ #define DEF_UPSCALE 3
+#else
+ #define DEF_UPSCALE (-(VL6180x_UPSCALE_SUPPORT))
+ #define _GetUpscale(dev, ... ) VL6180xDevDataGet(dev, UpscaleFactor)
+ #define _SetUpscale(dev, Scaling ) VL6180xDevDataSet(dev, UpscaleFactor, Scaling)
+#endif
+
+
+#if VL6180x_SINGLE_DEVICE_DRIVER
+extern struct VL6180xDevData_t SingleVL6180xDevData;
+#define VL6180xDevDataGet(dev, field) (SingleVL6180xDevData.field)
+#define VL6180xDevDataSet(dev, field, data) SingleVL6180xDevData.field=(data)
+#endif
+
+
+#if VL6180x_UPSCALE_SUPPORT == 1
+ #define _GetUpscale(dev, ... ) 1
+ #define _SetUpscale(...) -1
+ #define DEF_UPSCALE 1
+#elif VL6180x_UPSCALE_SUPPORT == 2
+ #define _GetUpscale(dev, ... ) 2
+ #define _SetUpscale(...)
+ #define DEF_UPSCALE 2
+#elif VL6180x_UPSCALE_SUPPORT == 3
+ #define _GetUpscale(dev, ... ) 3
+ #define _SetUpscale(...)
+ #define DEF_UPSCALE 3
+#else
+ #define DEF_UPSCALE (-(VL6180x_UPSCALE_SUPPORT))
+ #define _GetUpscale(dev, ... ) VL6180xDevDataGet(dev, UpscaleFactor)
+ #define _SetUpscale(dev, Scaling ) VL6180xDevDataSet(dev, UpscaleFactor, Scaling)
+#endif
+
+
+struct VL6180xDevData_t VL6180x_DEV_DATA_ATTR SingleVL6180xDevData={
+ .EceFactorM = DEF_ECE_FACTOR_M,
+ .EceFactorD = DEF_ECE_FACTOR_D,
+#ifdef VL6180x_HAVE_UPSCALE_DATA
+ .UpscaleFactor = DEF_UPSCALE,
+#endif
+#ifdef VL6180x_HAVE_ALS_DATA
+ .IntegrationPeriod = DEF_INT_PEFRIOD,
+ .AlsGainCode = DEF_ALS_GAIN,
+ .AlsScaler = DEF_ALS_SCALER,
+#endif
+#ifdef VL6180x_HAVE_DMAX_RANGING
+ .DMaxEnable = DEF_DMAX_ENABLE,
+#endif
+};
+
+
#define Fix7_2_KCPs(x) ((((uint32_t)(x))*1000)>>7)
+/* define for i2c configuration ----------------------------------------------*/
+
+#define I2C_BUFFER_CONFIG 1
+#define VL6180x_I2C_USER_VAR
+#define TEMP_BUF_SIZE 32
+
+#ifndef I2C_BUFFER_CONFIG
+#error "I2C_BUFFER_CONFIG not defined"
+/* TODO you must define value for I2C_BUFFER_CONFIG in configuration or platform h */
+#endif
+
+
+#if I2C_BUFFER_CONFIG == 0
+ /* GLOBAL config buffer */
+ uint8_t i2c_global_buffer[VL6180x_MAX_I2C_XFER_SIZE];
+
+ #define DECL_I2C_BUFFER
+ #define VL6180x_GetI2cBuffer(dev, n_byte) i2c_global_buffer
+
+#elif I2C_BUFFER_CONFIG == 1
+ /* ON STACK */
+ #define DECL_I2C_BUFFER uint8_t LocBuffer[VL6180x_MAX_I2C_XFER_SIZE];
+ #define VL6180x_GetI2cBuffer(dev, n_byte) LocBuffer
+#elif I2C_BUFFER_CONFIG == 2
+ /* user define buffer type declare DECL_I2C_BUFFER as access via VL6180x_GetI2cBuffer */
+ #define DECL_I2C_BUFFER
+#else
+#error "invalid I2C_BUFFER_CONFIG "
+#endif
+
+/* Initialization functions --------------------------------------------------*/
+
int VL6180X::VL6180x_InitData(VL6180xDev_t dev)
{
int status, dmax_status ;
@@ -73,14 +169,14 @@
do{
/* backup offset initial value from nvm these must be done prior any over call that use offset */
- status = VL6180x_RdByte(dev,SYSRANGE_PART_TO_PART_RANGE_OFFSET, (uint8_t*)&offset);
+ status = VL6180x_RdByte(MyDevice,SYSRANGE_PART_TO_PART_RANGE_OFFSET, (uint8_t*)&offset);
if( status ){
VL6180x_ErrLog("SYSRANGE_PART_TO_PART_RANGE_OFFSET rd fail");
break;
}
VL6180xDevDataSet(dev, Part2PartOffsetNVM, offset);
- status=VL6180x_RdDWord( dev, SYSRANGE_RANGE_IGNORE_THRESHOLD, &CalValue);
+ status=VL6180x_RdDWord(MyDevice, SYSRANGE_RANGE_IGNORE_THRESHOLD, &CalValue);
if( status ){
VL6180x_ErrLog("Part2PartAmbNVM rd fail");
break;
@@ -90,7 +186,7 @@
}
VL6180xDevDataSet(dev, Part2PartAmbNVM, CalValue);
- status = VL6180x_RdWord(dev, SYSRANGE_CROSSTALK_COMPENSATION_RATE ,&u16);
+ status = VL6180x_RdWord(MyDevice, SYSRANGE_CROSSTALK_COMPENSATION_RATE ,&u16);
if( status){
VL6180x_ErrLog("SYSRANGE_CROSSTALK_COMPENSATION_RATE rd fail ");
break;
@@ -105,7 +201,7 @@
}
/* Read or wait for fresh out of reset */
- status = VL6180x_RdByte(dev,SYSTEM_FRESH_OUT_OF_RESET, &FreshOutReset);
+ status = VL6180x_RdByte(MyDevice,SYSTEM_FRESH_OUT_OF_RESET, &FreshOutReset);
if( status ) {
VL6180x_ErrLog("SYSTEM_FRESH_OUT_OF_RESET rd fail");
break;
@@ -121,34 +217,73 @@
}
-int VL6180X::VL6180XReadID(uint8_t *rl_id)
-{
- if(!rl_id)
- {
- return API_ERROR;
- }
- return VL6180X_IO_Read(rl_id, IDENTIFICATION_MODEL_ID, 1);
-}
+#define _DMaxData(field) VL6180xDevDataGet(dev, DMaxData.field)
+
+
+#ifndef VL6180x_PLATFORM_PROVIDE_SQRT
+
+uint32_t VL6180X::VL6180x_SqrtUint32(uint32_t num) {
+ uint32_t res = 0;
+ uint32_t bit = 1 << 30; /* The second-to-top bit is set: 1 << 30 for 32 bits */
+
+ /* "bit" starts at the highest power of four <= the argument. */
+ while (bit > num)
+ bit >>= 2;
-int VL6180X::VL6180X_IO_Read(uint8_t *pBuffer, uint8_t RegisterAddress, uint16 NumByteToRead)
-{
- int lecture
-
- lecture=dev_i2c.i2c_read(pBuffer, DevAddress, RegisterAddress, NumByteToRead);
- if(lecture!=0)
- {
- return API_ERROR;
+ while (bit != 0) {
+ if (num >= res + bit) {
+ num -= res + bit;
+ res = (res >> 1) + bit;
+ }
+ else
+ res >>= 1;
+ bit >>= 2;
}
- return API_NO_ERROR;
+ return res;
+}
+#endif
+
+
+void VL6180X::_DMax_OneTimeInit(VL6180xDev_t dev){
+ _DMaxData(ambTuningWindowFactor_K)=DEF_AMBIENT_TUNING;
}
-
+uint32_t VL6180X::_DMax_RawValueAtRateKCps(VL6180xDev_t dev, int32_t rate){
+ uint32_t snrLimit_K;
+ int32_t DMaxSq;
+ uint32_t RawDMax;
+ DMaxFix_t retSignalAt400mm;
+ uint32_t ambTuningWindowFactor_K;
+ ambTuningWindowFactor_K = _DMaxData(ambTuningWindowFactor_K);
+ snrLimit_K = _DMaxData(snrLimit_K);
+ retSignalAt400mm = _DMaxData(retSignalAt400mm); /* 12 to 18 bits Kcps */
+ if( rate > 0 ){
+ DMaxSq = 400*400*1000 / rate -(400*400/330); /* K of (1/RtnAmb -1/330 )=> 30bit- (12-18)bit => 12-18 bits*/
+ if( DMaxSq<= 0){
+ RawDMax = 0;
+ }
+ else{
+ /* value can be more 32 bit so base on raneg apply *retSignalAt400mm before or after division to presevr accuracy */
+ if( DMaxSq< (2<<12) ){
+ DMaxSq = DMaxSq*retSignalAt400mm/(snrLimit_K+ambTuningWindowFactor_K); /* max 12 + 12 to 18 -10 => 12-26 bit */
+ }else{
+ DMaxSq = DMaxSq/(snrLimit_K+ambTuningWindowFactor_K)*retSignalAt400mm; /* 12 to 18 -10 + 12 to 18 *=> 12-26 bit */
+ }
+ RawDMax=VL6180x_SqrtUint32(DMaxSq);
+ }
+ }
+ else{
+ RawDMax = 0x7FFFFFFF; /* bigest possibmle 32bit signed value */
+ }
+ return RawDMax;
+}
-static int _DMax_InitData(VL6180xDev_t dev){
+int VL6180X::_DMax_InitData(VL6180xDev_t dev)
+{
int status, warning;
uint8_t u8;
uint16_t u16;
@@ -167,7 +302,7 @@
LOG_FUNCTION_START("");
do{
- status = VL6180x_RdByte(dev, 0x02A ,&u8);
+ status = VL6180x_RdByte(MyDevice, 0x02A ,&u8);
if( status ){
VL6180x_ErrLog("Reg 0x02A rd fail");
break;
@@ -179,25 +314,25 @@
}
Reg2A_KCps = Fix7_2_KCPs(u8); /* convert to KCPs */
- status = VL6180x_RdByte(dev, SYSRANGE_RANGE_CHECK_ENABLES, &SysRangeCheckEn);
+ status = VL6180x_RdByte(MyDevice, SYSRANGE_RANGE_CHECK_ENABLES, &SysRangeCheckEn);
if (status) {
VL6180x_ErrLog("SYSRANGE_RANGE_CHECK_ENABLES rd fail ");
break;
}
- status = VL6180x_RdByte(dev, SYSRANGE_MAX_CONVERGENCE_TIME, &MaxConvTime);
+ status = VL6180x_RdByte(MyDevice, SYSRANGE_MAX_CONVERGENCE_TIME, &MaxConvTime);
if( status){
VL6180x_ErrLog("SYSRANGE_MAX_CONVERGENCE_TIME rd fail ");
break;
}
- status = VL6180x_RdDWord(dev, 0x0B8, &RegB8);
+ status = VL6180x_RdDWord(MyDevice, 0x0B8, &RegB8);
if( status ){
VL6180x_ErrLog("reg 0x0B8 rd fail ");
break;
}
- status = VL6180x_RdByte(dev, SYSRANGE_MAX_AMBIENT_LEVEL_MULT, &snrLimit);
+ status = VL6180x_RdByte(MyDevice, SYSRANGE_MAX_AMBIENT_LEVEL_MULT, &snrLimit);
if( status){
VL6180x_ErrLog("SYSRANGE_MAX_AMBIENT_LEVEL_MULT rd fail ");
break;
@@ -214,7 +349,7 @@
/* if xtalk range check is off omit it in snr clipping */
if( SysRangeCheckEn&RANGE_CHECK_RANGE_ENABLE_MASK ){
- status = VL6180x_RdWord(dev, SYSRANGE_RANGE_IGNORE_THRESHOLD, &u16);
+ status = VL6180x_RdWord(MyDevice, SYSRANGE_RANGE_IGNORE_THRESHOLD, &u16);
if( status){
VL6180x_ErrLog("SYSRANGE_RANGE_IGNORE_THRESHOLD rd fail ");
break;
@@ -240,6 +375,160 @@
return status;
}
+
#undef Fix7_2_KCPs
+/* Write and read functions from I2C -----------------------------------------*/
+
+int VL6180X::VL6180x_WrByte(VL6180xDev_t dev, uint16_t index, uint8_t data)
+{
+ int status;
+ DECL_I2C_BUFFER
+ VL6180x_I2C_USER_VAR
+
+ status=VL6180x_I2CWrite(dev, index, &data,(uint8_t)3);
+ return status;
+}
+
+int VL6180X::VL6180x_WrWord(VL6180xDev_t dev, uint16_t index, uint16_t data)
+{
+ int status;
+ DECL_I2C_BUFFER
+ VL6180x_I2C_USER_VAR
+
+ status=VL6180x_I2CWrite(dev, index, (uint8_t *)&data,(uint8_t)4);
+ return status;
+}
+
+int VL6180X::VL6180x_WrDWord(VL6180xDev_t dev, uint16_t index, uint32_t data)
+{
+ VL6180x_I2C_USER_VAR
+ DECL_I2C_BUFFER
+ int status;
+
+ status=VL6180x_I2CWrite(dev, index, (uint8_t *)&data,(uint8_t)6);
+ return status;
+}
+
+int VL6180X::VL6180x_RdByte(VL6180xDev_t dev, uint16_t index, uint8_t *data)
+{
+ VL6180x_I2C_USER_VAR
+ int status;
+ uint8_t buffer;
+ DECL_I2C_BUFFER
+
+ status=VL6180x_I2CRead(dev, index, &buffer,1);
+ if( !status ){
+ *data=buffer;
+ }
+ return status;
+}
+
+int VL6180X::VL6180x_RdWord(VL6180xDev_t dev, uint16_t index, uint16_t *data)
+{
+ VL6180x_I2C_USER_VAR
+ int status;
+ uint8_t *buffer;
+ DECL_I2C_BUFFER
+
+ status=VL6180x_I2CRead(dev, index, buffer,2);
+ if( !status ){
+ /* VL6180x register are Big endian if cpu is be direct read direct into *data is possible */
+ *data=((uint16_t)buffer[0]<<8)|(uint16_t)buffer[1];
+ }
+ return status;
+}
+
+int VL6180X::VL6180x_RdDWord(VL6180xDev_t dev, uint16_t index, uint32_t *data)
+{
+ VL6180x_I2C_USER_VAR
+ int status;
+ uint8_t *buffer;
+ DECL_I2C_BUFFER
+
+
+ status=VL6180x_I2CRead(dev, index, buffer,4);
+ if( !status ){
+ /* VL6180x register are Big endian if cpu is be direct read direct into data is possible */
+ *data=((uint32_t)buffer[0]<<24)|((uint32_t)buffer[1]<<16)|((uint32_t)buffer[2]<<8)|((uint32_t)buffer[3]);
+ }
+ return status;
+}
+
+int VL6180X::VL6180x_I2CWrite(uint8_t DeviceAddr, uint16_t RegisterAddr, uint8_t* pBuffer, uint16_t NumByteToWrite)
+{
+ int ret;
+ int i;
+ uint8_t tmp[TEMP_BUF_SIZE];
+ uint16_t myRegisterAddr = RegisterAddr;
+ uint8_t *array;
+
+ if(NumByteToWrite >= TEMP_BUF_SIZE) return -2;
+
+ /* First, send 8 bits device address and 16 bits register address in BE format. Then, send data and STOP condition */
+ tmp[0] = *(((uint8_t*)&myRegisterAddr)+1);
+ tmp[1] = (uint8_t)RegisterAddr;
+
+ if(NumByteToWrite>1)
+ {
+ array=new uint8_t[NumByteToWrite];
+ for(i=0;i<NumByteToWrite;i++)
+ {
+ array[NumByteToWrite-1-i]=pBuffer[i];
+ }
+ }
+
+ memcpy(tmp+2, array, NumByteToWrite);
+
+ ret = dev_i2c.write(DeviceAddr, (const char*)tmp, NumByteToWrite+sizeof(RegisterAddr), false);
+
+ if(ret) return -1;
+ return 0;
+}
+
+int VL6180X::VL6180x_I2CRead(uint8_t DeviceAddr, uint16_t RegisterAddr, uint8_t* pBuffer, uint16_t NumByteToRead)
+{
+ int ret;
+ uint16_t myRegisterAddr = RegisterAddr;
+ uint16_t myRegisterAddrBE;
+
+ myRegisterAddrBE = *(((uint8_t*)&myRegisterAddr)+1);
+ *(((uint8_t*)&myRegisterAddrBE)+1) = (uint8_t)myRegisterAddr;
+
+ /* Send 8 bits device address and 16 bits register address in BE format, with no STOP condition */
+ ret = dev_i2c.write(DeviceAddr, (const char*)&myRegisterAddrBE, sizeof(RegisterAddr), true);
+ if(!ret) {
+ /* Read data, with STOP condition */
+ ret = dev_i2c.read(DeviceAddr, (char*)pBuffer, NumByteToRead, false);
+ }
+
+ if(ret) return -1;
+ return 0;
+}
+
+/* IO read funcitons ---------------------------------------------------------*/
+
+int VL6180X::VL6180X_ReadID(uint8_t *rl_id)
+{
+ if(!rl_id)
+ {
+ return API_ERROR; // DA DEFINIRE IL TIPO DI ERRORE!!
+ }
+ return VL6180X_IO_Read(rl_id, IDENTIFICATION_MODEL_ID, 1);
+}
+
+
+int VL6180X::VL6180X_IO_Read(uint8_t *pBuffer, uint8_t RegisterAddress, uint16_t NumByteToRead)
+{
+ int lecture;
+
+ lecture=dev_i2c.i2c_read(pBuffer, MyDeviceAddress, RegisterAddress, NumByteToRead);
+ if(lecture!=0)
+ {
+ return INVALID_PARAMS; // DA DEFINIRE IL TIPO DI ERRORE!!
+ }
+ return API_NO_ERROR; // DA DEFINIRE IL TIPO DI ERRORE!!
+}
+
+
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
