Condensed Version of Public VL53L0X

Dependents:   ToF-Only-Tryout

Files at this revision

API Documentation at this revision

Comitter:
sepp_nepp
Date:
Wed Apr 10 19:03:16 2019 +0000
Parent:
11:c6f95a42d4d7
Commit message:
Troy a gain

Changed in this revision

VL53L0X.cpp Show annotated file Show diff for this revision Revisions of this file
VL53L0X.h Show annotated file Show diff for this revision Revisions of this file
VL53L0X_def.h Show annotated file Show diff for this revision Revisions of this file
--- 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);   }
 
--- a/VL53L0X.h	Mon Apr 08 16:26:19 2019 +0000
+++ b/VL53L0X.h	Wed Apr 10 19:03:16 2019 +0000
@@ -44,6 +44,37 @@
     /* Device data made accessible for further usage */
     TVL53L0X_DeviceInfo Device_Info;
 
+	/* all the fields previously hidden under DevSpecParams 
+	   of type struct VL53L0X_DeviceSpecificParameters_t   */
+    TFP1616 OscFrequencyMHz; 
+    /* Frequency used */
+    uint16_t LastEncodedTimeout;
+    /* last encoded Time out used for timing budget*/
+    TGPIO_Func GpioFunctionality;
+    /* store the functionality of the GPIO: pin0 */
+    uint32_t FinalRangeTimeoutMicroSecs;
+    /*!< Execution time of the final range*/
+    uint8_t FinalRangeVcselPPeriod;
+    /*!< Vcsel pulse period (pll clocks) for the final range measurement*/
+    uint32_t PreRangeTimeoutMicroSecs;
+    /*!< Execution time of the final range*/
+    uint8_t PreRangeVcselPPeriod;
+    /*!< Vcsel pulse period (pll clocks) for the pre-range measurement*/
+    uint16_t SigmaEstRefArray;
+    /*!< Reference array sigma value in 1/100th of [mm] e.g. 100 = 1mm */
+    uint16_t SigmaEstEffPulseWidth;
+    /*!< Effective Pulse width for sigma estimate in 1/100th of ns e.g. 900 = 9.0ns */
+    uint16_t SigmaEstEffAmbWidth;
+    /*!< Effective Ambient width for sigma estimate in 1/100th of ns e.g. 500 = 5.0ns */
+    uint8_t ModuleId; /* Module ID */
+    uint8_t Revision; /* test Revision */
+    char ProductId[VL53L0X_MAX_STRING_LENGTH]; /* Product Identifier String  */
+    uint8_t ReferenceSPADType;	/* used for ref SPAD management */
+    uint8_t RefSPADSInitialised; /* reports if ref SPADS are initialised. */
+    uint32_t PartUIDUpper; /*!< Unique Part ID Upper */
+    uint32_t PartUIDLower; /*!< Unique Part ID Lower */
+    TFP1616 SignalRateMeasFixed400mm; /*!< Peek Signal rate at 400 mm*/
+
 public: 
 	/******************************************************************************/
 	/****************** Public Initialization Methods     *************************/
@@ -107,8 +138,6 @@
      * This function will change the VL53L0X_State from VL53L0X_STATE_POWERDOWN to
      * VL53L0X_STATE_WAIT_STATICINIT.
      *
-     * @note This function accesses to the device
-     * 
      * @return  None; instead check class Field "ErrState"
      */
     void Data_init();
@@ -123,6 +152,13 @@
      *           Also check and fix errors reported Field "ErrState"   */
     void Fill_device_info();
     
+    /* api_core.h functions */
+    void Get_all_NVM_info_from_device( uint8_t option);
+
+	/* All the data that is read from the NVM and stored internally */
+    uint8_t ReadNVMDataFromDeviceDone; /* Indicate if read from device has been done (==1-4-7) or not (==0) */
+    uint8_t ReferenceSPADCount; /* used for ref SPAD management */
+
 public:
     /**
      * @brief       Start the measure indicated by operating mode
@@ -1157,9 +1193,6 @@
 
     void Check_and_load_interrupt_settings( uint8_t start_not_stopflag);
 
-    /* api_core.h functions */
-    void Get_info_from_device( uint8_t option);
-
     uint32_t Decode_timeout(uint16_t encoded_timeout);
 
     uint32_t Calc_timeout_us(uint16_t timeout_period_mclks,
@@ -1789,12 +1822,15 @@
 /******************************************************************************/
 /****************** Write and read functions from I2C *************************/
 /******************************************************************************/
+	uint32_t Get_NVM_DWord(uint8_t NVM_Address)
+	uint16_t Get_NVM_Word (uint8_t NVM_Address)
+	uint8_t  Get_NVM_Byte (uint8_t NVM_Address)
+
     /**
      * Thread safe Update (read/modify/write) single byte register
      *
      * Final_reg = (Initial_reg & and_mask) | or_mask
      *
-     * 
      * @param   index      The register index
      * @param   and_mask    8 bit and data
      * @param   or_mask     8 bit or data
@@ -1936,8 +1972,6 @@
     /*!< Ranging Data */
     VL53L0X_HistogramMeasurementData_t LastHistogramMeasure;
     /*!< Histogram Data */
-    VL53L0X_DeviceSpecificParameters_t DevSpecParams;
-    /*!< Parameters specific to the device */
     VL53L0X_SPADData_t SPADData;
     /*!< SPAD Data */
     uint8_t SequenceConfig;
--- a/VL53L0X_def.h	Mon Apr 08 16:26:19 2019 +0000
+++ b/VL53L0X_def.h	Wed Apr 10 19:03:16 2019 +0000
@@ -586,8 +586,6 @@
     see @a ::TDevError @a VL53L0X_GetStatusErrorString() */
 } VL53L0X_HistogramMeasurementData_t;
 
-#define REF_SPAD_BUFFER_SIZE 6
-
 #define VL53L0X_PLL_PERIOD_PS = 1655;
 #define VL53L0X_MACRO_PERIOD_VCLKS = 2304;
 
@@ -595,46 +593,15 @@
  * @struct VL53L0X_SPADData_t
  * @brief SPAD Configuration Data.
  */
+ #define REF_SPAD_ARRAY_SIZE 6
+
 typedef struct {
-    uint8_t RefSPADEnables[REF_SPAD_BUFFER_SIZE];
+    uint8_t RefSPADEnables[REF_SPAD_ARRAY_SIZE];
     /*!< Reference SPAD Enables */
-    uint8_t RefGoodSPADMap[REF_SPAD_BUFFER_SIZE];
+    uint8_t RefGoodSPADMap[REF_SPAD_ARRAY_SIZE];
     /*!< Reference SPAD Good SPAD Map */
 } VL53L0X_SPADData_t;
 
-typedef struct {
-    TFP1616 OscFrequencyMHz; 
-    /* Frequency used */
-    uint16_t LastEncodedTimeout;
-    /* last encoded Time out used for timing budget*/
-    TGPIO_Func GpioFunctionality;
-    /* store the functionality of the GPIO: pin0 */
-    uint32_t FinalRangeTimeoutMicroSecs;
-    /*!< Execution time of the final range*/
-    uint8_t FinalRangeVcselPPeriod;
-    /*!< Vcsel pulse period (pll clocks) for the final range measurement*/
-    uint32_t PreRangeTimeoutMicroSecs;
-    /*!< Execution time of the final range*/
-    uint8_t PreRangeVcselPPeriod;
-    /*!< Vcsel pulse period (pll clocks) for the pre-range measurement*/
-    uint16_t SigmaEstRefArray;
-    /*!< Reference array sigma value in 1/100th of [mm] e.g. 100 = 1mm */
-    uint16_t SigmaEstEffPulseWidth;
-    /*!< Effective Pulse width for sigma estimate in 1/100th of ns e.g. 900 = 9.0ns */
-    uint16_t SigmaEstEffAmbWidth;
-    /*!< Effective Ambient width for sigma estimate in 1/100th of ns e.g. 500 = 5.0ns */
-    uint8_t ReadDataFromDeviceDone; /* Indicate if read from device has
-	been done (==1) or not (==0) */
-    uint8_t ModuleId; /* Module ID */
-    uint8_t Revision; /* test Revision */
-    char ProductId[VL53L0X_MAX_STRING_LENGTH]; /* Product Identifier String  */
-    uint8_t ReferenceSPADCount; /* used for ref SPAD management */
-    uint8_t ReferenceSPADType;	/* used for ref SPAD management */
-    uint8_t RefSPADSInitialised; /* reports if ref SPADS are initialised. */
-    uint32_t PartUIDUpper; /*!< Unique Part ID Upper */
-    uint32_t PartUIDLower; /*!< Unique Part ID Lower */
-    TFP1616 SignalRateMeasFixed400mm; /*!< Peek Signal rate at 400 mm*/
-} VL53L0X_DeviceSpecificParameters_t;
 
 /** @defgroup VL53L0X_define_InterruptPolarity_group Defines the Polarity
  * of the Interrupt