INSAT Mini Project

Dependencies:   ST_INTERFACES X_NUCLEO_COMMON

Fork of X_NUCLEO_6180XA1 by ST

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****/