Condensed Version of Public VL53L0X

Dependents:   ToF-Only-Tryout

Revision:
12:aa177f0e4c10
Parent:
11:c6f95a42d4d7
--- a/VL53L0X.cpp	Mon Apr 08 16:26:19 2019 +0000
+++ b/VL53L0X.cpp	Wed Apr 10 19:03:16 2019 +0000
@@ -49,6 +49,12 @@
 #include "VL53L0X.h"
 #include "VL53L0X_tuning.h"
 
+/******************************************************************************/
+/******************************************************************************/
+/****************** All initialization functions      *************************/
+/******************************************************************************/
+/******************************************************************************/
+
 // Function Data_init and Init_Sensor is united into Start_Sensor
 VL53L0X_Error VL53L0X::Start_Sensor(uint8_t new_addr)
 {	ErrState = VL53L0X_OK;
@@ -81,11 +87,15 @@
     
     /* Set Default static parameters
     *set first temporary values 9.44MHz * 65536 = 618660 */
-    DevSpecParams.OscFrequencyMHz = 618660;
- 	DevSpecParams.RefSPADSInitialised = 0;
-    DevSpecParams.ReadDataFromDeviceDone = 0;
+    OscFrequencyMHz = 618660;
+ 	RefSPADSInitialised = 0;
+ 	
+ 	// Read All NVM from device
+    ReadNVMDataFromDeviceDone = 0;
+	Get_all_NVM_info_from_device();
 
 #ifdef USE_IQC_STATION
+	// must make sure that first your read all NVM info used by the API */
     VL53L0X_Apply_Offset_Cal();
 #endif
 
@@ -163,6 +173,7 @@
     uint8_t vhv_settings;
     uint8_t phase_cal;
 
+	// make sure the Get_all_NVM_info_from_device was called before calling static init
     if (ErrState == VL53L0X_OK) { Static_init(); } // Device Initialization
 
     if (ErrState == VL53L0X_OK) {  // Device Calibration
@@ -177,15 +188,13 @@
 void VL53L0X::Fill_device_info()
 {   uint8_t revision;
 
-    Get_info_from_device(2);
-
     if (ErrState == VL53L0X_OK) 
-      { if (DevSpecParams.ModuleId == 0) 
+      { if (ModuleId == 0) 
             { revision = 0;
               strcpy(Device_Info.ProductId,""); }
           else 
-            { revision = DevSpecParams.Revision; 
-              strcpy(Device_Info.ProductId,DevSpecParams.ProductId); 
+            { revision = Revision; 
+              strcpy(Device_Info.ProductId,ProductId); 
             }
         if (revision == 0) 
             { strcpy(Device_Info.Name,VL53L0X_STRING_DEVICE_INFO_NAME_TS0); } 
@@ -202,6 +211,116 @@
 	             (Read_Byte(REG_IDENTIFICATION_REVISION_ID) & 0xF0) >> 4;
 }
  
+/* That was 'Get_info_from_device( unit8_t option)' where option was composed of 
+  1, 2, 4 depending what info was requested.
+  It was decided to combine all that into a single Get ALL infos from the device
+  that is called once at Sensor Init so all the job is done. 
+  In addition, originally values would first be read into local variables and then
+  only copied to class fields if no errors. 
+  However, if at device initialization an error is raised the whole class instance
+  cannot be used anyway, so decided that we directly read into class fields.  */
+
+void VL53L0X::Get_all_NVM_info_from_device()
+{   uint32_t tmp_dword;
+    uint32_t offset_fixed1104_mm = 0;
+    int16_t  offset_um = 0;
+    uint32_t dist_meas_tgt_fixed1104_mm = 400 << 4;
+    uint32_t dist_meas_fixed1104_400_mm = 0;
+    uint32_t signal_rate_meas_fixed1104_400_mm = 0;
+    int i;
+
+    /* This access is done only once after that a GetDeviceInfo or datainit is done*/
+    if (ReadNVMDataFromDeviceDone == 7) { return ; }
+    
+    Write_Byte(0x80,0x01);
+    Write_Byte(0xFF,0x01);
+    Write_Byte(0x00,0x00);
+    Write_Byte(0xFF,0x06);
+    Register_BitMask(0x83,0xFF,0x04)
+    Write_Byte(0xFF,0x07);
+    Write_Byte(0x81,0x01);
+    Polling_delay(); // warning, does nothing!!
+    Write_Byte(0x80,0x01);
+
+	/*  *************    First Block of NVM data is read:   ************/
+    tmp_dword = Get_NVM_DWord(0x6b); 
+    ReferenceSPADCount = (uint8_t)((tmp_dword >>  8) & 0x7f);
+    ReferenceSPADType  = (uint8_t)((tmp_dword >> 15) & 0x01);
+
+    tmp_dword = Get_NVM_DWord(0x24); 
+    SPADData.RefGoodSPADMap[0] = (uint8_t)((tmp_dword >> 24)& 0xff);
+    SPADData.RefGoodSPADMap[1] = (uint8_t)((tmp_dword >> 16)& 0xff);
+    SPADData.RefGoodSPADMap[2] = (uint8_t)((tmp_dword >>  8)& 0xff);
+    SPADData.RefGoodSPADMap[3] = (uint8_t)(tmp_dword & 0xff);
+
+    tmp_dword = Get_NVM_DWord(0x25); 
+    SPADData.RefGoodSPADMap[4] = (uint8_t)((tmp_dword >> 24)& 0xff);
+    SPADData.RefGoodSPADMap[5] = (uint8_t)((tmp_dword >> 16)& 0xff);
+
+	/*  *************    Second Block of NVM data is read:   ************/
+    ModuleId = Get_NVM_Byte(0x02); 
+    Revision  = Get_NVM_Byte(0x02); 
+
+	tmp_dword = Get_NVM_DWord(0x77); 
+    ProductId[0] = (char)((tmp_dword >> 25) & 0x07f);
+    ProductId[1] = (char)((tmp_dword >> 18) & 0x07f);
+    ProductId[2] = (char)((tmp_dword >> 11) & 0x07f);
+    ProductId[3] = (char)((tmp_dword >>  4) & 0x07f);
+    ProductId[4] = (char)((tmp_dword <<  3) & 0x07f);
+
+	tmp_dword = Get_NVM_DWord(0x78); 
+    ProductId[4] = ProductId[4] | 
+                    (char)((tmp_dword >> 29) & 0x07f));
+    ProductId[5] = (char)((tmp_dword >> 22) & 0x07f);
+    ProductId[6] = (char)((tmp_dword >> 15) & 0x07f);
+    ProductId[7] = (char)((tmp_dword >>  8) & 0x07f);
+    ProductId[8] = (char)((tmp_dword >>  1) & 0x07f);
+    ProductId[9] = (char)((tmp_dword <<  6) & 0x07f);
+
+	tmp_dword = Get_NVM_DWord(0x79); 
+    ProductId[9]  = ProductId[9] | 
+         			 (char)((tmp_dword >> 26) & 0x07f);
+    ProductId[10] = (char)((tmp_dword >> 19) & 0x07f);
+    ProductId[11] = (char)((tmp_dword >> 12) & 0x07f);
+    ProductId[12] = (char)((tmp_dword >>  5) & 0x07f);
+    ProductId[13] = (char)((tmp_dword <<  2) & 0x07f);
+
+	tmp_dword = Get_NVM_DWord(0x7A); 
+    ProductId[13] = ProductId[13] |
+           			 (char)((tmp_dword >> 30) & 0x07f));
+    ProductId[14] = (char)((tmp_dword >> 23) & 0x07f);
+    ProductId[15] = (char)((tmp_dword >> 16) & 0x07f);
+    ProductId[16] = (char)((tmp_dword >>  9) & 0x07f);
+    ProductId[17] = (char)((tmp_dword >>  2) & 0x07f);
+    ProductId[18] = '\0';
+
+	/*  *************    Third Block of NVM data is read:   ************/
+    PartUIDUpper = Get_NVM_DWord(0x7B); 
+	PartUIDLower = Get_NVM_DWord(0x7C); 
+    SignalRateMeasFixed400mm =  // convert from FP97_TO_FP1616
+       ( (( Get_NVM_DWord(0x73) << 17) & 0x1fE0000) | 
+         (( Get_NVM_DWord(0x74) >> 15) & 0x001fE00) ) ; 
+
+    dist_meas_fixed1104_400_mm = 
+        (( Get_NVM_DWord(0x75) <<  8) & 0xff00) | 
+        (( Get_NVM_DWord(0x76) >> 24) & 0x00ff);
+    
+    if (dist_meas_fixed1104_400_mm != 0) {
+        offset_fixed1104_mm = dist_meas_fixed1104_400_mm -
+            dist_meas_tgt_fixed1104_mm;
+        NVM_Offset_Cal_um = (offset_fixed1104_mm * 1000) >> 4;
+        NVM_Offset_Cal_um *= -1; }
+      else { NVM_Offset_Cal_um = 0; }
+
+    Write_Byte(0x81,0x00);
+    Write_Byte(0xFF,0x06);
+    Register_BitMask(0x83,0xfb,0x00)
+    Write_Byte(0xFF,0x01);
+    Write_Byte(0x00,0x01);
+    Write_Byte(0xFF,0x00);
+    Write_Byte(0x80,0x00);
+	ReadNVMDataFromDeviceDone = 7;
+}
 
 uint32_t VL53L0X::Get_distance()
 {   ErrState = VL53L0X_OK;
@@ -219,6 +338,12 @@
        { ErrState = VL53L0X_ERROR_RANGE_ERROR; return 0;}
 }
 
+/******************************************************************************/
+/******************************************************************************/
+/****************** Actual Measurement functions      *************************/
+/******************************************************************************/
+/******************************************************************************/
+
 TRangeResults VL53L0X::Get_Measurement(TOperatingMode operating_mode)
 { 	TRangeResults p_data;
 
@@ -284,9 +409,6 @@
 void VL53L0X::VL53L0X_Apply_Offset_Cal()
 {   int32_t Summed_Offset_Cal_um;
 
-    /* read all NVM info used by the API */
-    Get_info_from_device(7);
-
     /* Read back current device offset, and remember in case later someone wants to use it */
     if (ErrState == VL53L0X_OK) { Last_Offset_Cal_um = Get_Offset_Cal_um(); }
 
@@ -510,7 +632,7 @@
             if (ErrState == VL53L0X_OK)
                 Set_Sequence_Step_Timeout(VL53L0X_SEQUENCESTEP_MSRC,msrc_timeout_us);
 
-            DevSpecParams.PreRangeVcselPPeriod = vcsel_PPeriod_pclk;
+            PreRangeVcselPPeriod = vcsel_PPeriod_pclk;
             break;
             
           case VL53L0X_VCSEL_FINAL_RANGE:
@@ -521,7 +643,7 @@
             if (ErrState == VL53L0X_OK)
                 Set_Sequence_Step_Timeout(VL53L0X_SEQUENCESTEP_FINAL_RANGE,final_range_timeout_us);
 
-            DevSpecParams.FinalRangeVcselPPeriod = vcsel_PPeriod_pclk;
+            FinalRangeVcselPPeriod = vcsel_PPeriod_pclk;
             break;
           default: ErrState = VL53L0X_ERROR_INVALID_PARAMS;
         }
@@ -758,7 +880,7 @@
 {   uint8_t sys_range_status_register;
     uint32_t interrupt_mask;
 
-    if (DevSpecParams.GpioFunctionality == REG_SYSINT_GPIO_NEW_SAMPLE_READY) 
+    if (GpioFunctionality == REG_SYSINT_GPIO_NEW_SAMPLE_READY) 
 	  { Get_interrupt_mask_status(&interrupt_mask);
         if (interrupt_mask ==  REG_SYSINT_GPIO_NEW_SAMPLE_READY) 
 		   { return 1; } else { return 0; }
@@ -1147,7 +1269,7 @@
     
     if (ErrState != VL53L0X_OK) { return; } // Do nothing if not Cleared error
 
-    interrupt_config = DevSpecParams.GpioFunctionality; 
+    interrupt_config = GpioFunctionality; 
 
     if ((interrupt_config == GPIO_FUNC_THRESHOLD_CROSSED_LOW ) ||
         (interrupt_config == GPIO_FUNC_THRESHOLD_CROSSED_HIGH) ||
@@ -1545,13 +1667,13 @@
 
     if (ErrState == VL53L0X_OK) {
         /* Calculate final range macro periods */
-        final_range_timeout_micro_secs = DevSpecParams.FinalRangeTimeoutMicroSecs; 
-        final_range_vcsel_pclks = DevSpecParams.FinalRangeVcselPPeriod; 
+        final_range_timeout_micro_secs = FinalRangeTimeoutMicroSecs; 
+        final_range_vcsel_pclks = FinalRangeVcselPPeriod; 
         final_range_macro_pclks = Calc_timeout_mclks(final_range_timeout_micro_secs,final_range_vcsel_pclks);
 
         /* Calculate pre-range macro periods */
-        pre_range_timeout_micro_secs = DevSpecParams.PreRangeTimeoutMicroSecs; 
-        pre_range_vcsel_pclks = DevSpecParams.PreRangeVcselPPeriod; 
+        pre_range_timeout_micro_secs = PreRangeTimeoutMicroSecs; 
+        pre_range_vcsel_pclks = PreRangeVcselPPeriod; 
         pre_range_macro_pclks = Calc_timeout_mclks(pre_range_timeout_micro_secs,pre_range_vcsel_pclks);
         vcsel_width = 3;
         if (final_range_vcsel_pclks == 8) {  vcsel_width = 2; }
@@ -2037,7 +2159,7 @@
     uint16_t peak_SIG_rate_Ref;
     uint32_t need_apt_SPADS = 0;
     uint32_t index = 0;
-    uint32_t SPAD_array_size = 6;
+    uint32_t REF_SPAD_ARRAY_SIZE = 6;
     uint32_t signal_rate_diff = 0;
     uint32_t last_SIG_rate_diff = 0;
     uint8_t complete = 0;
@@ -2074,7 +2196,7 @@
      * provided as an input.
      * Note that there are 6 bytes. Only the first 44 bits will be used to
      * represent SPADS. */
-    for (index = 0; index < SPAD_array_size; index++) {
+    for (index = 0; index < REF_SPAD_ARRAY_SIZE; index++) {
         SPADData.RefSPADEnables[index] = 0; }
 
     Write_Byte(0xFF,0x01);
@@ -2096,7 +2218,7 @@
         Enable_Ref_SPADS(need_apt_SPADS,
                                   SPADData.RefGoodSPADMap,
                                   SPADData.RefSPADEnables,
-                                  SPAD_array_size,
+                                  REF_SPAD_ARRAY_SIZE,
                                   start_select,
                                   current_SPAD_index,
                                   minimum_SPAD_count,
@@ -2109,7 +2231,7 @@
         peak_SIG_rate_Ref = Get_Perf_Ref_SIG_measurement();
         if ((ErrState == VL53L0X_OK) && (peak_SIG_rate_Ref > target_Ref_rate)) 
          {  /* Signal rate measurement too high, switch to APERTURE SPADS */
-            for (index = 0; index < SPAD_array_size; index++) 
+            for (index = 0; index < REF_SPAD_ARRAY_SIZE; index++) 
               {  SPADData.RefSPADEnables[index] = 0; }
 
             /* Increment to the first APERTURE SPAD */
@@ -2122,7 +2244,7 @@
             Enable_Ref_SPADS(need_apt_SPADS,
                                       SPADData.RefGoodSPADMap,
                                       SPADData.RefSPADEnables,
-                                      SPAD_array_size,
+                                      REF_SPAD_ARRAY_SIZE,
                                       start_select,
                                       current_SPAD_index,
                                       minimum_SPAD_count,
@@ -2150,13 +2272,13 @@
         is_aperture_SPADS_int = need_apt_SPADS;
         ref_SPAD_count_int	= minimum_SPAD_count;
 
-        memcpy(last_SPAD_array,SPADData.RefSPADEnables, SPAD_array_size);
+        memcpy(last_SPAD_array,SPADData.RefSPADEnables, REF_SPAD_ARRAY_SIZE);
         last_SIG_rate_diff = abs(peak_SIG_rate_Ref - target_Ref_rate);
         complete = 0;
 
         while (!complete) {
             Get_Next_Good_SPAD(SPADData.RefGoodSPADMap,
-                SPAD_array_size,current_SPAD_index, &next_good_SPAD);
+                REF_SPAD_ARRAY_SIZE,current_SPAD_index, &next_good_SPAD);
 
             if (next_good_SPAD == -1) {
                 ErrState = VL53L0X_ERROR_REF_SPAD_INIT;
@@ -2176,7 +2298,7 @@
 
             current_SPAD_index = next_good_SPAD;
             Enable_SPAD_bit(SPADData.RefSPADEnables,
-                         SPAD_array_size,current_SPAD_index);
+                         REF_SPAD_ARRAY_SIZE,current_SPAD_index);
 
             if (ErrState == VL53L0X_OK) {
                 current_SPAD_index++;
@@ -2199,14 +2321,14 @@
                 if (signal_rate_diff > last_SIG_rate_diff) {
                     /* Previous SPAD map produced a closer measurement,so choose this. */
                     I2c_Write(REG_GLOBAL_CONFIG_SPAD_ENABLES_REF_0, last_SPAD_array,6); // Set_Ref_SPAD_map();
-                    memcpy(SPADData.RefSPADEnables,last_SPAD_array,SPAD_array_size);
+                    memcpy(SPADData.RefSPADEnables,last_SPAD_array,REF_SPAD_ARRAY_SIZE);
                     (ref_SPAD_count_int)--;
                 }
                 complete = 1;
             } else {
                 /* Continue to add SPADS */
                 last_SIG_rate_diff = signal_rate_diff;
-                memcpy(last_SPAD_array, SPADData.RefSPADEnables,SPAD_array_size);
+                memcpy(last_SPAD_array, SPADData.RefSPADEnables,REF_SPAD_ARRAY_SIZE);
             }
         } /* while */
     }
@@ -2214,16 +2336,15 @@
     if (ErrState == VL53L0X_OK) {
         *ref_SPAD_count = ref_SPAD_count_int;
         *is_aperture_SPADS = is_aperture_SPADS_int;
-        DevSpecParams.RefSPADSInitialised = 1;
-        DevSpecParams.ReferenceSPADCount = (uint8_t)(*ref_SPAD_count);
-        DevSpecParams.ReferenceSPADType = *is_aperture_SPADS;
+        RefSPADSInitialised = 1;
+        ReferenceSPADCount = (uint8_t)(*ref_SPAD_count);
+        ReferenceSPADType = *is_aperture_SPADS;
     }
 }
 
 void VL53L0X::Set_Reference_SPADS(uint32_t count,uint8_t is_aperture_SPADS)
 {   uint32_t current_SPAD_index = 0;
     uint8_t  start_select    = 0xB4;
-    uint32_t SPAD_array_size = 6;
     uint32_t max_SPAD_count  = 44;
     uint32_t last_SPAD_index;
     uint32_t index;
@@ -2236,7 +2357,7 @@
     Write_Byte(0xFF,0x00); 
     Write_Byte(REG_GLOBAL_CONFIG_REF_EN_START_SELECT, start_select);
 
-    for (index = 0; index < SPAD_array_size; index++) {
+    for (index = 0; index < REF_SPAD_ARRAY_SIZE; index++) {
         SPADData.RefSPADEnables[index] = 0; }
 
     if (is_aperture_SPADS) {
@@ -2246,19 +2367,18 @@
             current_SPAD_index++;
         }
     }
-    Enable_Ref_SPADS(is_aperture_SPADS,
-                              SPADData.RefGoodSPADMap,
+    Enable_Ref_SPADS(is_aperture_SPADS,  SPADData.RefGoodSPADMap,
                               SPADData.RefSPADEnables,
-                              SPAD_array_size,
+                              REF_SPAD_ARRAY_SIZE,
                               start_select,
                               current_SPAD_index,
                               count,
                               &last_SPAD_index);
 
     if (ErrState == VL53L0X_OK) {
-        DevSpecParams.RefSPADSInitialised = 1;
-        DevSpecParams.ReferenceSPADCount = (uint8_t)(count);
-        DevSpecParams.ReferenceSPADType = is_aperture_SPADS;
+        RefSPADSInitialised = 1;
+        ReferenceSPADCount = (uint8_t)(count);
+        ReferenceSPADType = is_aperture_SPADS;
     }
 }
 
@@ -2299,7 +2419,7 @@
                { Register_BitMask(REG_GPIO_HV_MUX_ACTIVE_HIGH,0xEF,pol_data); }
 
             if (ErrState == VL53L0X_OK) 
-               {DevSpecParams.GpioFunctionality = functionality; }
+               {GpioFunctionality = functionality; }
 
             Clear_interrupt_mask(0);
      } // switch 
@@ -2346,7 +2466,7 @@
             if (msrc_range_time_out_m_clks > 256) { msrc_encoded_time_out = 255;} 
                else {msrc_encoded_time_out = (uint8_t)msrc_range_time_out_m_clks - 1; }
 
-            DevSpecParams.LastEncodedTimeout = msrc_encoded_time_out;
+            LastEncodedTimeout = msrc_encoded_time_out;
           }
         Write_Byte(REG_MSRC_CONFIG_TIMEOUT_MACROP,msrc_encoded_time_out);
         break; 
@@ -2359,12 +2479,12 @@
                                            (uint8_t)current_vcsel_PPeriod_p_clk);
             pre_range_encoded_time_out = Encode_timeout(pre_range_time_out_m_clks);
 
-            DevSpecParams.LastEncodedTimeout = pre_range_encoded_time_out;
+            LastEncodedTimeout = pre_range_encoded_time_out;
         
             Write_Word(REG_PRE_RANGE_CONFIG_TIMEOUT_MACROP_HI,pre_range_encoded_time_out);
 
             if (ErrState == VL53L0X_OK) 
-               {DevSpecParams.PreRangeTimeoutMicroSecs=timeout_micro_secs; }
+               {PreRangeTimeoutMicroSecs=timeout_micro_secs; }
             break;
             
       case VL53L0X_SEQUENCESTEP_FINAL_RANGE:
@@ -2402,7 +2522,7 @@
               }
 
             if (ErrState == VL53L0X_OK) 
-              { DevSpecParams.FinalRangeTimeoutMicroSecs = timeout_micro_secs; }
+              { FinalRangeTimeoutMicroSecs = timeout_micro_secs; }
           	break;
           
         default: ErrState = VL53L0X_ERROR_INVALID_PARAMS;
@@ -2580,11 +2700,9 @@
     uint8_t  vcsel_PPeriod_pclk;
     uint32_t seq_timeout_micro_secs;
 
-    Get_info_from_device(1);
-
     /* set the ref SPAD from NVM */
-    count	= (uint32_t)DevSpecParams.ReferenceSPADCount; 
-    aperture_SPADS = DevSpecParams.ReferenceSPADType; 
+    count	= (uint32_t)ReferenceSPADCount; 
+    aperture_SPADS = ReferenceSPADType; 
 
     /* NVM value invalid */
     if ((aperture_SPADS > 1) || ((aperture_SPADS == 1) && (count > 32)) ||
@@ -2615,7 +2733,7 @@
     Write_Byte(0xFF,0x00);
 
     if (ErrState == VL53L0X_OK) 
-      { DevSpecParams.OscFrequencyMHz=FP412_TO_FP1616(tempword); }
+      { OscFrequencyMHz=FP412_TO_FP1616(tempword); }
 
     /* After static init,some device parameters may be changed, so update them */
     new_curr_parameters = Get_device_parameters(); 
@@ -2642,7 +2760,7 @@
        { vcsel_PPeriod_pclk = (Read_Byte(REG_PRE_RANGE_CONFIG_VCSEL_PERIOD) + 1) << 1; }
 
     if ( ErrState == VL53L0X_OK) 
-       { DevSpecParams.PreRangeVcselPPeriod = vcsel_PPeriod_pclk; }
+       { PreRangeVcselPPeriod = vcsel_PPeriod_pclk; }
 
     /* Store final-range vcsel period */
     if (ErrState == VL53L0X_OK)
@@ -2650,7 +2768,7 @@
 		    = ( Read_Byte(REG_FINAL_RANGE_CONFIG_VCSEL_PERIOD) + 1) << 1; }
 
     if (ErrState == VL53L0X_OK) 
-       { DevSpecParams.FinalRangeVcselPPeriod = vcsel_PPeriod_pclk; }
+       { FinalRangeVcselPPeriod = vcsel_PPeriod_pclk; }
 
     /* Store pre-range timeout */
     if (ErrState == VL53L0X_OK) 
@@ -2658,7 +2776,7 @@
                                                      &seq_timeout_micro_secs); }
 
     if (ErrState == VL53L0X_OK) 
-       { DevSpecParams.PreRangeTimeoutMicroSecs = seq_timeout_micro_secs; }
+       { PreRangeTimeoutMicroSecs = seq_timeout_micro_secs; }
 
     /* Store final-range timeout */
     if (ErrState == VL53L0X_OK) 
@@ -2666,7 +2784,7 @@
                                                       &seq_timeout_micro_secs);}
 
     if (ErrState == VL53L0X_OK) 
-       { DevSpecParams.FinalRangeTimeoutMicroSecs = seq_timeout_micro_secs; }
+       { FinalRangeTimeoutMicroSecs = seq_timeout_micro_secs; }
 }
 
 void VL53L0X::Stop_Measurement()
@@ -2870,191 +2988,6 @@
     Write_Byte(0x83,0x01); // set strobe register back to 1 'manually'
 }
 
-void VL53L0X::Get_info_from_device(uint8_t option)
-{   uint8_t byte;
-    uint32_t tmp_dword;
-    uint8_t module_id;
-    uint8_t revision;
-    uint8_t reference_SPAD_count = 0;
-    uint8_t reference_SPAD_type = 0;
-    uint32_t part_uid_upper = 0;
-    uint32_t part_uid_lower = 0;
-    uint32_t offset_fixed1104_mm = 0;
-    int16_t offset_um = 0;
-    uint32_t dist_meas_tgt_fixed1104_mm = 400 << 4;
-    uint32_t dist_meas_fixed1104_400_mm = 0;
-    uint32_t signal_rate_meas_fixed1104_400_mm = 0;
-    char product_id[19];
-    uint8_t read_data_from_device_done;
-    TFP1616 signal_rate_meas_fixed400_mm_fix = 0;
-    uint8_t nvm_Ref_good_SPAD_map[REF_SPAD_BUFFER_SIZE];
-    int i;
-
-	read_data_from_device_done = DevSpecParams.ReadDataFromDeviceDone; 
-
-    /* This access is done only once after that a GetDeviceInfo or datainit is done*/
-    if (read_data_from_device_done != 7) {
-        Write_Byte(0x80,0x01);
-        Write_Byte(0xFF,0x01);
-        Write_Byte(0x00,0x00);
-        Write_Byte(0xFF,0x06);
-        byte = Read_Byte(0x83); 
-        Write_Byte(0x83,byte | 4);
-        Write_Byte(0xFF,0x07);
-        Write_Byte(0x81,0x01);
-        Polling_delay(); // warning, does nothing!!
-        Write_Byte(0x80,0x01);
-
-        if (((option & 1) == 1) &&
-            ((read_data_from_device_done & 1) == 0)) {
-            Write_Byte(0x94,0x6b);
-            Wait_read_strobe();
-            tmp_dword = Read_DWord(0x90); 
-            reference_SPAD_count = (uint8_t)((tmp_dword >>  8) & 0x7f);
-            reference_SPAD_type  = (uint8_t)((tmp_dword >> 15) & 0x01);
-
-            Write_Byte(0x94,0x24);
-            Wait_read_strobe();
-            tmp_dword = Read_DWord(0x90); 
-            nvm_Ref_good_SPAD_map[0] = (uint8_t)((tmp_dword >> 24)& 0xff);
-            nvm_Ref_good_SPAD_map[1] = (uint8_t)((tmp_dword >> 16)& 0xff);
-            nvm_Ref_good_SPAD_map[2] = (uint8_t)((tmp_dword >>  8)& 0xff);
-            nvm_Ref_good_SPAD_map[3] = (uint8_t)(tmp_dword & 0xff);
-
-            Write_Byte(0x94,0x25);
-            Wait_read_strobe();
-            tmp_dword = Read_DWord(0x90); 
-            nvm_Ref_good_SPAD_map[4] = (uint8_t)((tmp_dword >> 24)& 0xff);
-            nvm_Ref_good_SPAD_map[5] = (uint8_t)((tmp_dword >> 16)& 0xff);
-        }
-
-        if (((option & 2) == 2) && ((read_data_from_device_done & 2) == 0)) {
-            Write_Byte(0x94,0x02);
-            Wait_read_strobe();
-            module_id = Read_Byte(0x90); 
-
-            Write_Byte(0x94,0x7B);
-            Wait_read_strobe();
-            revision = Read_Byte(0x90); 
-
-            Write_Byte(0x94,0x77);
-            Wait_read_strobe();
-            tmp_dword = Read_DWord(0x90); 
-            product_id[0] = (char)((tmp_dword >> 25) & 0x07f);
-            product_id[1] = (char)((tmp_dword >> 18) & 0x07f);
-            product_id[2] = (char)((tmp_dword >> 11) & 0x07f);
-            product_id[3] = (char)((tmp_dword >>  4) & 0x07f);
-
-            byte = (uint8_t)((tmp_dword & 0x00f) << 3);
-
-            Write_Byte(0x94,0x78);
-            Wait_read_strobe();
-            tmp_dword = Read_DWord(0x90); 
-            product_id[4] = (char)(byte +((tmp_dword >> 29) & 0x07f));
-            product_id[5] = (char)((tmp_dword >> 22) & 0x07f);
-            product_id[6] = (char)((tmp_dword >> 15) & 0x07f);
-            product_id[7] = (char)((tmp_dword >> 8) & 0x07f);
-            product_id[8] = (char)((tmp_dword >> 1) & 0x07f);
-            byte = (uint8_t)((tmp_dword & 0x001) << 6);
-
-            Write_Byte(0x94,0x79);
-            Wait_read_strobe();
-            tmp_dword = Read_DWord(0x90); 
-            product_id[9] = (char)(byte +((tmp_dword >> 26) & 0x07f));
-            product_id[10] = (char)((tmp_dword >> 19) & 0x07f);
-            product_id[11] = (char)((tmp_dword >> 12) & 0x07f);
-            product_id[12] = (char)((tmp_dword >> 5) & 0x07f);
-
-            byte = (uint8_t)((tmp_dword & 0x01f) << 2);
-
-            Write_Byte(0x94,0x7A);
-            Wait_read_strobe();
-            tmp_dword = Read_DWord(0x90); 
-            product_id[13] = (char)(byte +((tmp_dword >> 30) & 0x07f));
-            product_id[14] = (char)((tmp_dword >> 23) & 0x07f);
-            product_id[15] = (char)((tmp_dword >> 16) & 0x07f);
-            product_id[16] = (char)((tmp_dword >> 9) & 0x07f);
-            product_id[17] = (char)((tmp_dword >> 2) & 0x07f);
-            product_id[18] = '\0';
-        }
-
-        if (((option & 4) == 4) && ((read_data_from_device_done & 4) == 0)) 
-          { Write_Byte(0x94,0x7B);
-            Wait_read_strobe();
-            part_uid_upper = Read_DWord(0x90); 
-
-            Write_Byte(0x94,0x7C);
-            Wait_read_strobe();
-            part_uid_lower = Read_DWord(0x90); 
-
-            Write_Byte(0x94,0x73);
-            Wait_read_strobe();
-            tmp_dword = Read_DWord(0x90); 
-            signal_rate_meas_fixed1104_400_mm = (tmp_dword & 0x0000000ff) << 8;
-
-            Write_Byte(0x94,0x74);
-            Wait_read_strobe();
-            tmp_dword = Read_DWord(0x90); 
-            signal_rate_meas_fixed1104_400_mm |= ((tmp_dword &
-                                                   0xff000000) >> 24);
-
-            Write_Byte(0x94,0x75);
-            Wait_read_strobe();
-            tmp_dword = Read_DWord(0x90); 
-            dist_meas_fixed1104_400_mm = (tmp_dword & 0x0000000ff)<< 8;
-
-            Write_Byte(0x94,0x76);
-            Wait_read_strobe();
-            tmp_dword = Read_DWord(0x90); 
-            dist_meas_fixed1104_400_mm |= ((tmp_dword & 0xff000000) >> 24);
-        }
-
-        Write_Byte(0x81,0x00);
-        Write_Byte(0xFF,0x06);
-        Write_Byte(0x83,Read_Byte(0x83) & 0xfb);
-        Write_Byte(0xFF,0x01);
-        Write_Byte(0x00,0x01);
-        Write_Byte(0xFF,0x00);
-        Write_Byte(0x80,0x00);
-    }
-
-    if ((ErrState == VL53L0X_OK) && (read_data_from_device_done != 7)) {
-        /* Assign to variable if ErrState is ok */
-        if (((option & 1) == 1) && ((read_data_from_device_done & 1) == 0)) 
-          { DevSpecParams.ReferenceSPADCount=reference_SPAD_count;
-            DevSpecParams.ReferenceSPADType =reference_SPAD_type;
-            for (i = 0; i < REF_SPAD_BUFFER_SIZE; i++) 
-              { SPADData.RefGoodSPADMap[i] =  nvm_Ref_good_SPAD_map[i]; }
-          }
-
-        if (((option & 2) == 2) &&((read_data_from_device_done & 2) == 0)) 
-          { DevSpecParams.ModuleId = module_id;
-            DevSpecParams.Revision = revision;
-            strcpy(DevSpecParams.ProductId, product_id);
-          }
-
-        if (((option & 4) == 4) && ((read_data_from_device_done & 4) == 0)) {
-            DevSpecParams.PartUIDUpper = part_uid_upper;
-            DevSpecParams.PartUIDLower = part_uid_lower;
-            signal_rate_meas_fixed400_mm_fix =
-                FP97_TO_FP1616(signal_rate_meas_fixed1104_400_mm);
-            DevSpecParams.SignalRateMeasFixed400mm = signal_rate_meas_fixed400_mm_fix;
-            DevSpecParams.SignalRateMeasFixed400mm = signal_rate_meas_fixed400_mm_fix;
-
-            offset_um = 0;
-            if (dist_meas_fixed1104_400_mm != 0) {
-                offset_fixed1104_mm = dist_meas_fixed1104_400_mm -
-                    dist_meas_tgt_fixed1104_mm;
-                offset_um = (offset_fixed1104_mm * 1000) >> 4;
-                offset_um *= -1;
-            }
-            NVM_Offset_Cal_um = offset_um; 
-        }
-        byte = (uint8_t)(read_data_from_device_done | option);
-        DevSpecParams.ReadDataFromDeviceDone = byte;
-    }
-}
-
 /******************************************************************************/
 /****************** Small Service and wrapper functions  **********************/
 /******************************************************************************/
@@ -3079,6 +3012,22 @@
 /****************** Write and read functions from I2C *************************/
 /******************************************************************************/
 
+
+uint32_t VL53L0X::Get_NVM_DWord(uint8_t NVM_Address)
+{	Write_Byte(0x94,NVM_Address);
+	Wait_read_strobe();
+	return Read_DWord(0x90); 
+}
+uint16_t VL53L0X::Get_NVM_Word(uint8_t NVM_Address)
+{	Write_Byte(0x94,NVM_Address);
+	Wait_read_strobe();
+	return Read_Word(0x90); 
+}
+uint8_t VL53L0X::Get_NVM_Byte(uint8_t NVM_Address)
+{	Write_Byte(0x94,NVM_Address);
+	Wait_read_strobe();
+	return Read_Byte(0x90); 
+}
 void VL53L0X::Write_Byte(uint8_t index, uint8_t data)
 {   I2c_Write(index,&data,1);   }