TEST_CODE_ApplyTo2V1_API

Dependencies:   SDFileSystem max32630fthr USBDevice

Revision:
4:217334c3a5b2
Parent:
3:35b05d91568d
--- a/DUT_RegConfig.cpp	Mon Jun 22 05:27:48 2020 +0000
+++ b/DUT_RegConfig.cpp	Tue Jul 28 01:40:05 2020 +0000
@@ -9,21 +9,48 @@
 #include "Firmware.h"
 #include "RegTable.h"
 #include "CmdHandler.h"
+#include "Van_API.h"
 
 DUTREG dut_reg[DUT_REG_NUM];
 uint8_t Firmware[8192];
 uint8_t histogram[10][1024];
+//uint8_t hist_ma[2048];
 uint8_t dcr_matrix[17][9*2];
 
+uint8_t pixel_map[16][18] = {
+    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+    0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00,
+    0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00,
+    
+    0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00,
+    0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00,
+    0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00,
+    0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00,
+    
+    0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
+    0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02,
+    0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04,
+    0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08,
+    
+    0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10,
+    0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20,
+    0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40,
+    0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80
+    };
+
+uint8_t work_mode = 0;
 uint8_t int_mark = 0;
 uint8_t int_enable = 1;
 uint8_t histogram_mode = 0;
 uint8_t histogram_tdc = 0;
+uint8_t continus_ranging = 0;
 
 Semaphore chip_int_semph(1);
 extern DigitalOut xSHUT;
 extern I2C i2c_v;
 extern DigitalOut TRIM_EN;
+extern DigitalOut HIGH_EN;
 
 uint16_t histogram_pos_num = 0;
 uint16_t histogram_per_pos = 0;
@@ -31,16 +58,53 @@
 uint16_t range_step_num = 0;
 uint16_t range_per_step = 0;
 
+uint16_t single_measure_times = 0;
+
 extern const uint8_t reg_table[];
 extern const uint8_t Firmware_Ranging[];
 extern uint8_t  _uart_send_pbuff[CMD_BUF_LEN] ;
 
+
+void ECO_ByPassROM(void)
+{
+    uint8_t tmp = 0;   
+    
+    WriteOneReg(0x00, 0x00);
+    WriteOneReg(0x01, 0x00);
+    ReadOneReg(0x07, &tmp);
+    WriteOneReg(0x07, tmp & 0xFE);    
+}
+
+void ECO_DefaultRegInit(void)
+{
+    WriteOneReg(0x00, 0x03);
+    WriteOneReg(0x01, 0x00);
+    WriteOneReg(0x02, 0x00);
+    WriteOneReg(0x37, 0x61);
+    WriteOneReg(0x38, 0x00);
+    WriteOneReg(0x39, 0x00);
+    WriteOneReg(0x3A, 0x1F);
+    WriteOneReg(0x41, 0x04);
+    WriteOneReg(0x48, 0x7F);
+    WriteOneReg(0x49, 0x01);
+    WriteOneReg(0x4C, 0xFF);
+    WriteOneReg(0x4D, 0x00);
+    WriteOneReg(0x51, 0x0E);
+    WriteOneReg(0xE4, 0xD1);
+    WriteOneReg(0xE8, 0x00);
+    WriteOneReg(0xF7, 0xFF);
+    WriteOneReg(0xF8, 0x8B);
+}
+
 void ChipInitReset(void)
 {
     xSHUT = 0;
     wait_ms(30);
     xSHUT = 1;
     wait_ms(30);
+    //ECO_ByPassROM();
+    //wait_ms(30);
+    //ECO_DefaultRegInit();
 }
 
 void SetBitThree(uint8_t rco, uint8_t tdc, uint8_t dcr)
@@ -53,14 +117,21 @@
 void DUT_RegInit(uint8_t rco, uint8_t tdc, uint8_t dcr)
 {
     LoadRegTable();
-    for(uint16_t i = 0; i < 256; i++) 
-    {
-        WriteOneReg(dut_reg[i].addr, dut_reg[i].value);        
+    for(uint16_t i = 0; i < 256; i++) {
+        WriteOneReg(dut_reg[i].addr, dut_reg[i].value);
     }
 
     SetBitThree(rco, tdc, dcr);
 }
 
+void DUT_RegTableInit(void)
+{
+    for(uint16_t i = 0; i < 256; i++) {
+        dut_reg[i].addr = i;
+        dut_reg[i].value = i;
+    }
+}
+
 void DUT_FirmwareInit(void)
 {
     WriteFW(LoadFirmware());
@@ -69,10 +140,13 @@
 void DeviceAllInit(uint8_t rco, uint8_t tdc, uint8_t dcr)
 {
     ChipInitReset();
-    wait_ms(100);
-    DUT_RegInit(rco, tdc, dcr);
-    wait_ms(100);
-    DUT_FirmwareInit();
+    //wait_ms(100);
+    //DUT_RegInit(rco, tdc, dcr);
+    //wait_ms(100);
+    //DUT_FirmwareInit();
+      
+    
+    DUT_RegTableInit();
     wait_ms(100);
 }
 
@@ -104,7 +178,7 @@
 void HistogramReport()
 {
     uint8_t ret = 0;
-    uint16_t lsb, mili, noise_level;
+    uint16_t lsb, mili, ref_lsb, ref_mili, noise_level;
     uint32_t peak;
 
 
@@ -115,7 +189,7 @@
         if(histogram_mode == 1) {
             //ReadOneReg(REG_SYS_CFG, &sys_cfg_save);
             //WriteOneReg(REG_SYS_CFG, 0x00);
-            ret = OneTimeMeasure(&lsb, &mili, &peak, &noise_level);
+            ret = OneTimeMeasure(&lsb, &mili, &peak, &noise_level, &ref_lsb, &ref_mili);//////
             if(ret != 0) {
                 histogram_mode = 0;
             } else {
@@ -130,19 +204,15 @@
         } else if(histogram_mode == 2) {
             //ReadOneReg(REG_SYS_CFG, &sys_cfg_save);
             //WriteOneReg(REG_SYS_CFG, 0x00);
-            ret = OneTimeMeasure(&lsb, &mili, &peak, &noise_level);
+            ret = OneTimeMeasure(&lsb, &mili, &peak, &noise_level, &ref_lsb, &ref_mili);//////
             if(ret != 0) {
                 histogram_mode = 0;
             } else {
-                for(uint8_t i = 0; i < 10; i++) {
-                    ret = vangogh_ram_rd(i);
-                    if(ret != 0) {
-                        histogram_mode = 0;
-                        break;
-                    } else {
-                        HandleReadHistogram(i);
-                        wait_ms(1);
-                    }
+                ret = vangogh_ram_rd_ma();
+                if(ret != 0) {
+                    histogram_mode = 0;
+                } else {
+                    HandleReadHistogram(0xF1);
                 }
             }
             //WriteOneReg(REG_SYS_CFG, sys_cfg_save);
@@ -155,12 +225,12 @@
                 if(histogram_pos >= histogram_pos_num) {
                     histogram_mode = 0;
                 }
-                ServoRun(1, 10);
+                ServoRun(1, 20);
                 while(CheckUntil()) wait_ms(100);
             }
             //ReadOneReg(REG_SYS_CFG, &sys_cfg_save);
             //WriteOneReg(REG_SYS_CFG, 0x00);
-            ret = OneTimeMeasure(&lsb, &mili, &peak, &noise_level);
+            ret = OneTimeMeasure(&lsb, &mili, &peak, &noise_level, &ref_lsb, &ref_mili);
             if(ret != 0) {
                 histogram_mode = 0;
             } else {
@@ -180,7 +250,7 @@
         } else if(histogram_mode == 4) {
             //ReadOneReg(REG_SYS_CFG, &sys_cfg_save);
             //WriteOneReg(REG_SYS_CFG, 0x00);
-            ret = OneTimeMeasure(&lsb, &mili, &peak, &noise_level);
+            ret = OneTimeMeasure(&lsb, &mili, &peak, &noise_level, &ref_lsb, &ref_mili);
             if(ret != 0) {
                 histogram_mode = 0;
             } else {
@@ -203,11 +273,12 @@
                 if(range_step >= range_step_num) {
                     histogram_mode = 0;
                 }
-                ServoRun(1, 10);
-                while(CheckUntil()) wait_ms(100);
+                //ServoRun(1, 10);
+                //while(CheckUntil()) wait_ms(100);
 
                 range_per_step = 0;
-                ret = ContinuousMeasure();
+                single_measure_times = 256;                
+                //ret = ContinuousMeasure();
                 if(ret != 0) {
                     histogram_mode = 0;
                 } else {
@@ -222,9 +293,16 @@
                     wait_ms(5);
                     StoreHistogram(range_step, 0, 3);
                     wait_ms(5);
+                    StoreHistogram(range_step, 0, 4);
+                    wait_ms(5);
+                    StoreHistogram(range_step, 0, 5);
+                    wait_ms(5);
                     range_per_step = 0;
 
                 }
+                
+                ServoRun(1, 10);
+                while(CheckUntil()) wait_ms(100);
             }
 
 
@@ -236,60 +314,104 @@
             histogram_pos_num = 0;
             histogram_per_pos = 0;
         }
-        wait(1);
+        wait_ms(100);
     }
 }
 
-void StoreMeasureData(uint16_t lsb, uint16_t milimeter, uint32_t peak, uint16_t noise_level, uint16_t i)
+void StoreMeasureData(uint16_t lsb, uint16_t milimeter, uint32_t peak, uint16_t noise_level, uint16_t ref_lsb, uint16_t ref_milimeter, uint16_t i)
 {
     histogram[0][4*i] = 0;
     histogram[0][4*i+1] = 0;
     histogram[0][4*i+2] = lsb >> 8;
     histogram[0][4*i+3] = lsb ;
-    
+
     histogram[1][4*i] = 0;
     histogram[1][4*i+1] = 0;
     histogram[1][4*i+2] = milimeter >> 8;
     histogram[1][4*i+3] = milimeter ;
-    
+
     histogram[2][4*i]   = peak >> 24;
     histogram[2][4*i+1] = peak >> 16;
     histogram[2][4*i+2] = peak >> 8;
     histogram[2][4*i+3] = peak ;
-    
+
     histogram[3][4*i]   = 0;
     histogram[3][4*i+1] = 0;
     histogram[3][4*i+2] = noise_level >> 8;
     histogram[3][4*i+3] = noise_level ;
     
+    histogram[4][4*i]   = 0;
+    histogram[4][4*i+1] = 0;
+    histogram[4][4*i+2] = ref_lsb >> 8;
+    histogram[4][4*i+3] = ref_lsb ;
+    
+    histogram[5][4*i]   = 0;
+    histogram[5][4*i+1] = 0;
+    histogram[5][4*i+2] = ref_milimeter >> 8;
+    histogram[5][4*i+3] = ref_milimeter ;
 }
 
 void ContinuousMeasureReport()
 {
-    uint16_t lsb, milimeter, noise_level;
+    uint16_t lsb, milimeter, ref_lsb, ref_milimeter, noise_level;
     uint32_t peak;
-    uint8_t int_flag = 0;
-    uint16_t time_out = 0;
+
+    uint8_t ret = 0;
+    
+    Van_Dist_TypeDef result;
+    Van_Status status;
+
 
     while(1) {
-
-        chip_int_semph.wait();
-        if(histogram_mode == 5) {
-            if(RaadContinuousMeasure(&lsb, &milimeter, &peak, &noise_level) == 0) {
-                StoreMeasureData(lsb, milimeter, peak, noise_level, range_per_step++);
-                if(range_per_step == 256) {
-                    StopContinuousMeasure();
-                }
-            }
-        } else {
-            if(RaadContinuousMeasure(&lsb, &milimeter, &peak, &noise_level) == 0) {
-                HandleContinuousMeasureReport(lsb, milimeter, peak, noise_level);
+        
+        if(continus_ranging == 1)
+        {
+            
+    
+            status = PollingGetRangingResult(&result, VAN_GO_ON);
+            if(status == VAN_OK)
+            {
+                lsb = 0;
+                milimeter = result.millimeter;
+                peak = result.peak;
+                noise_level = result.noise;
+                //ref_lsb = result.confidence;
+                ref_lsb = result.histcnt;
+                ref_milimeter = result.dmax;    
+                
+                ret = ReadOneReg(0x0d, (uint8_t*)&lsb);
+                ret = ReadOneReg(0x0e, (uint8_t*)&lsb + 1);   
+            
+                HandleContinuousMeasureReport(lsb, milimeter, peak, noise_level, ref_lsb, ref_milimeter);
             }
         }
+        wait_ms(25);
+       }
+}
 
+void AutoSingleMeasurment()
+{
+    uint16_t lsb, milimeter, ref_lsb, ref_milimeter, noise_level;
+    uint32_t peak;
+    
+    
+    while(1)
+    {
+        if(single_measure_times > 0)
+        {
+            if(OneTimeMeasure(&lsb, &milimeter, &peak, &noise_level, &ref_lsb, &ref_milimeter) == 0)
+            {
+                StoreMeasureData(lsb, milimeter, peak, noise_level, ref_lsb, ref_milimeter, range_per_step++);
+            }
+            single_measure_times--;
+        }
+        
+        wait_ms(30);
     }
 }
 
+/*
+
 uint8_t WriteOneReg(uint8_t addr, uint8_t data)
 {
     uint8_t buf[2];
@@ -312,6 +434,7 @@
     return 0;
 }
 
+*/
 
 uint8_t ReadAllRegToTable(void)
 {
@@ -324,48 +447,15 @@
 
 uint8_t WriteFW(uint16_t size)
 {
-    uint8_t  ret = 0;
-    uint8_t  i;
-    uint8_t  reg_sys_cfg;
-    uint8_t  uart_rx_data;
-    uint16_t fw_size = size;
-    uint16_t fw_send = 0;
-
-    ret = WriteOneReg(REG_PW_CTRL, 0x08);
-    ret = WriteOneReg(REG_PW_CTRL, 0x0a);
-    ret = WriteOneReg(REG_MCU_CFG, 0x02);
-    ret = ReadOneReg (REG_SYS_CFG, &reg_sys_cfg);
-    ret = WriteOneReg(REG_SYS_CFG, reg_sys_cfg | (0x01<<0));
-    ret = WriteOneReg(REG_CMD, 0x01);
-    ret = WriteOneReg(REG_SIZE, 0x02);
-    ret = WriteOneReg(REG_SCRATCH_PAD_BASE+0x00, 0x00);
-    ret = WriteOneReg(REG_SCRATCH_PAD_BASE+0x01, 0x00);
+    DownloadFirmware(Firmware, size);
+    
+    wait_ms(30);
+    Van_Config_TypeDef cfg;
+    uint8_t cg_para[20];
+    cfg.preSetMode = VAN_HIGH_PRECISION;    
+    InitRanging(&cfg, cg_para);
 
-    while(fw_size >= 32) {
-        ret = WriteOneReg(REG_CMD,0x03);
-        ret = WriteOneReg(REG_SIZE,0x20);
-        for(i=0; i<32; i++) {
-            uart_rx_data = Firmware[fw_send++];
-            ret = WriteOneReg(REG_SCRATCH_PAD_BASE+i, uart_rx_data);
-            wait_us(5);
-        }
-        fw_size -= 32;
-    }
-    if(fw_size > 0) {
-        ret = WriteOneReg(REG_CMD,0x03);
-        ret = WriteOneReg(REG_SIZE,(uint8_t)fw_size);
-        for(i=0; i<fw_size; i++) {
-            uart_rx_data = Firmware[fw_send++];
-            ret = WriteOneReg(REG_SCRATCH_PAD_BASE+i, uart_rx_data);
-            wait_us(5);
-        }
-    }
-    ret = WriteOneReg(REG_SYS_CFG, reg_sys_cfg & ~(0x01<<0));
-    ret = WriteOneReg(REG_MCU_CFG, 0x03);
-    ret = WriteOneReg(REG_PW_CTRL, 0x02); //reset r_otp_ld_done, is a must
-    ret = WriteOneReg(REG_PW_CTRL, 0x00); //reset r_otp_ld_done, exit low power mode
-
-    return ret;
+    return 0;
 }
 
 uint8_t vangogh_ram_rd(uint8_t tdc)       //UART CMD foramt: CMD-1-byte|TDC-index-1-byte
@@ -401,38 +491,62 @@
     ret = WriteOneReg(REG_SYS_CFG, reg_sys_cfg & ~(0x01<<0)); //clear sc_en
     ret = WriteOneReg(REG_PW_CTRL, reg_pw_ctrl | (0x01<<1)); //restore power         control register
     ret = WriteOneReg(REG_PW_CTRL, reg_pw_ctrl); //clear pw_ctrl_lp
+      
 
     return ret;
 }
 
-uint8_t OneTimeMeasure(uint16_t *lsb, uint16_t *milimeter, uint32_t *peak, uint16_t *noise_level)
+uint8_t vangogh_ram_rd_ma(void)       //UART CMD foramt: CMD-1-byte|TDC-index-1-byte
 {
     uint8_t ret = 0;
+    uint8_t i;
+    uint8_t j;
     uint8_t reg_pw_ctrl;
-    uint8_t reg_sys_cfg;
+    uint8_t reg_sys_cfg;    
+    uint16_t ram_addr_base = 0x0800;
+
+    ret = ReadOneReg (REG_SYS_CFG, &reg_sys_cfg           );
+    ret = WriteOneReg(REG_SYS_CFG, reg_sys_cfg | (0x01<<0));
+    ret = ReadOneReg (REG_PW_CTRL, &reg_pw_ctrl);
+    ret = WriteOneReg(REG_PW_CTRL, reg_pw_ctrl | (0x01<<3)); //set otp_ld_done
+    ret = WriteOneReg(REG_PW_CTRL, reg_pw_ctrl | (0x01<<3) | (0x01<<1)); //set otp_ld_done, pw_ctrl_lp
+    ret = WriteOneReg(REG_MCU_CFG, 0x01);
+    ret = WriteOneReg(REG_CMD, 0x01);
+    ret = WriteOneReg(REG_SIZE, 0x02);
+    ret = WriteOneReg(REG_SCRATCH_PAD_BASE+0x00, *((uint8_t*)(&ram_addr_base)  ));
+    ret = WriteOneReg(REG_SCRATCH_PAD_BASE+0x01, *((uint8_t*)(&ram_addr_base)+1));
+    wait_us(100);
+    for(j=0; j<32; j++) {
+        ret = WriteOneReg(REG_CMD,0x05);  //Issue RAM read command
+        ret = WriteOneReg(REG_SIZE,0x20); //Issue RAM read command
+        wait_us(100);
+        for(i=0; i<32; i++) {
+            ret = ReadOneReg(0x0c+i, &histogram[0][32*j + i]);
+        }
+    }
+    ret = WriteOneReg(REG_MCU_CFG, 0x03);
+    ret = WriteOneReg(REG_SYS_CFG, reg_sys_cfg & ~(0x01<<0)); //clear sc_en
+    ret = WriteOneReg(REG_PW_CTRL, reg_pw_ctrl | (0x01<<1)); //restore power         control register
+    ret = WriteOneReg(REG_PW_CTRL, reg_pw_ctrl); //clear pw_ctrl_lp
+
+    return ret;
+}
+
+uint8_t OneTimeMeasure(uint16_t *lsb, uint16_t *milimeter, uint32_t *peak, uint16_t *noise_level, uint16_t *ref_lsb, uint16_t *ref_milimeter)
+{
+    uint8_t ret = 0;   
     uint32_t timeout = 0;
-    uint8_t flag = 0;
+   
+    Van_Dist_TypeDef result;
 
     int_mark = 1;//One Time Measure
 
-    //ret = ReadOneReg (REG_SYS_CFG, &reg_sys_cfg           );
-    //ret = WriteOneReg(REG_SYS_CFG, reg_sys_cfg | (0x01<<0));
-    //ret = ReadOneReg (REG_PW_CTRL, &reg_pw_ctrl);
-    //ret = WriteOneReg(REG_PW_CTRL, reg_pw_ctrl | (0x01<<3)); //set otp_ld_done
-    //ret = WriteOneReg(REG_PW_CTRL, (reg_pw_ctrl | (0x01<<3)) & ~(0x01<<1)); //set otp_ld_done, clear pw_ctrl_lp
-    //ret = WriteOneReg(0x08, 0x00);
-    ret = WriteOneReg(REG_CMD, 0x0E);
-    //ret = WriteOneReg(REG_SIZE, 0x00);
+    StartRanging();   
 
     timeout = 1000;
     while(int_mark == 1 && timeout != 0) {
         timeout--;
-        wait_ms(5);
-        //ReadOneReg(0x08, &flag);
-        // if(flag == 0xFF)
-        //{
-        //     int_mark = 0;
-        //  }
+        wait_ms(5);       
     }
 
     if(timeout == 0) {
@@ -440,25 +554,20 @@
 
     } else {
 
+        ReadRangingResult(&result);
+        
         ret = ReadOneReg(0x0d, (uint8_t*)lsb);
         ret = ReadOneReg(0x0e, (uint8_t*)lsb + 1);
-
-        ret = ReadOneReg(0x18, (uint8_t*)milimeter);
-        ret = ReadOneReg(0x19, (uint8_t*)milimeter + 1);
-
-        ret = ReadOneReg(0x26, (uint8_t*)noise_level);
-        ret = ReadOneReg(0x27, (uint8_t*)noise_level + 1);
+        
+        *milimeter = result.millimeter;
+        *peak = result.peak;
+        *noise_level = result.noise;
+        
+        //*ref_lsb = result.confidence;
+        *ref_lsb = result.histcnt;
+        *ref_milimeter = result.dmax;       
 
-        ret = ReadOneReg(0x28, (uint8_t*)peak );
-        ret = ReadOneReg(0x29, (uint8_t*)peak + 1);
-        ret = ReadOneReg(0x2a, (uint8_t*)peak + 2);
-        ret = ReadOneReg(0x2b, (uint8_t*)peak + 3);
-
-    }
-
-    //ret = WriteOneReg(REG_SYS_CFG, reg_sys_cfg & ~(0x01<<0)); //clear sc_en
-    //ret = WriteOneReg(REG_PW_CTRL, reg_pw_ctrl | (0x01<<1)); //restore power         control register
-    //ret = WriteOneReg(REG_PW_CTRL, reg_pw_ctrl & ~(0x01<<1)); //clear pw_ctrl_lp
+    }   
 
     return ret;
 }
@@ -466,37 +575,16 @@
 uint8_t ContinuousMeasure(void)
 {
     uint8_t ret = 0;
-    uint8_t reg_pw_ctrl;
-    uint8_t reg_sys_cfg;
-
-    int_mark = 2;//Continuous Time Measure
-
-    //ret = ReadOneReg (REG_SYS_CFG, &reg_sys_cfg           );
-    //ret = WriteOneReg(REG_SYS_CFG, reg_sys_cfg | (0x01<<0));
-    //ret = ReadOneReg (REG_PW_CTRL, &reg_pw_ctrl);
-    //ret = WriteOneReg(REG_PW_CTRL, reg_pw_ctrl | (0x01<<3)); //set otp_ld_done
-    //ret = WriteOneReg(REG_PW_CTRL, (reg_pw_ctrl | (0x01<<3)) & ~(0x01<<1)); //set otp_ld_done, clear pw_ctrl_lp
-    ret = WriteOneReg(REG_CMD, 0x0F);
-    //ret = WriteOneReg(REG_SIZE, 0x00);
-
-    //ret = WriteOneReg(REG_SYS_CFG, reg_sys_cfg & ~(0x01<<0)); //clear sc_en
+    
+    StartRanging();   
+    continus_ranging = 1; 
 
     return ret;
 }
 
-uint8_t RaadContinuousMeasure(uint16_t *lsb, uint16_t *milimeter, uint32_t *peak, uint16_t *noise_level)
+uint8_t RaadContinuousMeasure(uint16_t *lsb, uint16_t *milimeter, uint32_t *peak, uint16_t *noise_level, uint16_t *ref_lsb, uint16_t *ref_milimeter)
 {
-    uint8_t ret = 0;
-    uint8_t reg_pw_ctrl;
-    uint8_t reg_sys_cfg;
-
-    int_mark = 2;//Continuous Time Measure
-
-    //ret = ReadOneReg (REG_SYS_CFG, &reg_sys_cfg           );
-    //ret = WriteOneReg(REG_SYS_CFG, reg_sys_cfg | (0x01<<0));
-    //ret = ReadOneReg (REG_PW_CTRL, &reg_pw_ctrl);
-    //ret = WriteOneReg(REG_PW_CTRL, reg_pw_ctrl | (0x01<<3)); //set otp_ld_done
-    //ret = WriteOneReg(REG_PW_CTRL, (reg_pw_ctrl | (0x01<<3)) & ~(0x01<<1)); //set otp_ld_done, clear pw_ctrl_lp
+    uint8_t ret = 0;   
 
     ret = ReadOneReg(0x0d, (uint8_t*)lsb);
     ret = ReadOneReg(0x0e, (uint8_t*)lsb + 1);
@@ -504,15 +592,19 @@
     ret = ReadOneReg(0x18, (uint8_t*)milimeter);
     ret = ReadOneReg(0x19, (uint8_t*)milimeter + 1);
 
+    ret = ReadOneReg(0x20, (uint8_t*)ref_lsb);
+    ret = ReadOneReg(0x21, (uint8_t*)ref_lsb + 1);
+
+    ret = ReadOneReg(0x22, (uint8_t*)ref_milimeter);
+    ret = ReadOneReg(0x23, (uint8_t*)ref_milimeter+1);
+
     ret = ReadOneReg(0x26, (uint8_t*)noise_level);
     ret = ReadOneReg(0x27, (uint8_t*)noise_level + 1);
 
     ret = ReadOneReg(0x28, (uint8_t*)peak );
     ret = ReadOneReg(0x29, (uint8_t*)peak + 1);
     ret = ReadOneReg(0x2a, (uint8_t*)peak + 2);
-    ret = ReadOneReg(0x2b, (uint8_t*)peak + 3);
-
-    //ret = WriteOneReg(REG_SYS_CFG, reg_sys_cfg & ~(0x01<<0)); //clear sc_en
+    ret = ReadOneReg(0x2b, (uint8_t*)peak + 3);  
 
     return ret;
 }
@@ -520,45 +612,14 @@
 uint8_t StopContinuousMeasure()
 {
     uint8_t ret = 0;
-    uint8_t reg_pw_ctrl;
-    uint8_t reg_sys_cfg;
-
-    int_mark = 0;//Continuous Time Measure
-
-    //ret = ReadOneReg (REG_SYS_CFG, &reg_sys_cfg           );
-    //ret = WriteOneReg(REG_SYS_CFG, reg_sys_cfg | (0x01<<0));
-    //ret = ReadOneReg (REG_PW_CTRL, &reg_pw_ctrl);
-    //ret = WriteOneReg(REG_PW_CTRL, reg_pw_ctrl | (0x01<<3)); //set otp_ld_done
-    //ret = WriteOneReg(REG_PW_CTRL, (reg_pw_ctrl | (0x01<<3)) & ~(0x01<<1)); //set otp_ld_done, clear pw_ctrl_lp
-    ret = WriteOneReg(REG_CMD, 0x00);
-    ret = WriteOneReg(REG_SIZE, 0x00);
-
-    //ret = WriteOneReg(REG_SYS_CFG, reg_sys_cfg & ~(0x01<<0)); //clear sc_en
-    //ret = WriteOneReg(REG_PW_CTRL, reg_pw_ctrl | (0x01<<1)); //restore power         control register
-    //ret = WriteOneReg(REG_PW_CTRL, reg_pw_ctrl & ~(0x01<<1)); //clear pw_ctrl_lp
+   
+    continus_ranging = 0;
 
     return ret;
 }
 
 void StoreHistogram(uint16_t histogram_pos, uint16_t histogram_num, uint8_t tdc)
 {
-    /*
-    char file_name[20];
-
-    //sprintf(file_name, "/sd/hist_%d_%d_tdc%d", histogram_pos, histogram_num, tdc);
-    sprintf(file_name, "/sd/hello.txt");
-
-    FILE *fp = fopen(file_name, "w");
-    //for(uint32_t i = 0; i < 1024; i++) {
-    //    fseek(fp,0,SEEK_END);
-    //    fprintf(fp, "%02X ", histogram[tdc][i]);
-    //}
-    fprintf(fp, "hello ");
-
-    fflush(fp);
-    fclose(fp);
-    */
-
     _uart_send_pbuff[0] = histogram_pos;
     _uart_send_pbuff[1] = histogram_pos >> 8;
 
@@ -613,9 +674,7 @@
 
 uint8_t DelayLineTest(uint8_t phase, uint8_t* buf)
 {
-    uint8_t ret = 0;
-    uint32_t timeout = 0;
-
+    
     WriteOneReg(0xE4, phase);
     wait_ms(10);
 
@@ -623,21 +682,22 @@
         WriteOneReg(0xE1, 0x61 | (step << 1));
         wait_ms(10);
 
-        timeout = 50;
-        int_mark = 1;
+        //timeout = 50;
+        //int_mark = 1;
         WriteOneReg(0x0A, 0x0B);
-        wait_ms(10);
-        while(int_mark == 1 && timeout != 0) {
-            timeout--;
-            wait_ms(100);
+        wait_ms(100);
+        //while(int_mark == 1 && timeout != 0) {
+        //    timeout--;
+        //   wait_ms(100);
+        //}
+        //wait_ms(100);
+        for(uint8_t tdc = 0; tdc < 9; tdc++) {
+            ReadOneReg(0x0c + tdc*2, buf + step*18 + tdc*2 + 1);
+            //wait_ms(1);
+            ReadOneReg(0x0c + tdc*2 + 1, buf + step*18 + tdc*2);
+            //wait_ms(1);
         }
-        for(uint8_t tdc = 0; tdc < 9; tdc++) {
-            ret = ReadOneReg(0x0c + tdc*2, buf + step*18 + tdc*2 + 1);
-            wait_ms(1);
-            ret = ReadOneReg(0x0c + tdc*2 + 1, buf + step*18 + tdc*2);
-            wait_ms(1);
-        }
-
+        //wait_ms(100);
     }
 
     return 0;
@@ -649,20 +709,20 @@
     uint32_t timeout = 0;
     memset(buf, 0x00, 10);
 
-    WriteOneReg(0x0C, 0x0C);
-    WriteOneReg(0x0A, 0x0A);
+    //WriteOneReg(0x0C, 0x0C);
+    //WriteOneReg(0x0A, 0x0A);
     wait_ms(1);
 
-    timeout = 10;
+    timeout = 20;
     int_mark = 1;
-    WriteOneReg(0x0A, 0x0B);
+    WriteOneReg(0x0A, 0x0A);
     while(int_mark == 1 && timeout != 0) {
         timeout--;
         wait_ms(100);
     }
     //osDelay(80);
 
-    ret = ReadOneReg(0x0D, buf);
+    ret = ReadOneReg(0x0C, buf);
     ret = ReadOneReg(0xE4, buf + 1);
 
     if(ret != 0)
@@ -675,51 +735,50 @@
 {
     uint8_t ret = 0;
     uint8_t buf[14];
-    
+
     memset(buf, 0x00, 14);
-    
+
     buf[0] |= (pd[5]&0xF);
     buf[0] |= ((pd[6] << 4)&0xF0);
-    
+
     buf[1] |= (pd[7]&0xF);
     buf[1] |= ((pd[8] << 4)&0xF0);
-    
+
     buf[2] |= (pd[9]&0xF);
     buf[2] |= ((pd[10] << 4)&0xF0);
-    
+
     buf[3] |= (pd[11]&0xF);
     buf[3] |= ((pd[12] << 4)&0xF0);
-    
+
     buf[4] |= (pd[13]&0xF);
     buf[4] |= ((pd[14] << 4)&0xF0);
-    
+
     buf[5] |= (pd[15]&0xF);
     buf[5] |= ((pd[16] << 4)&0xF0);
-    
+
     buf[6] |= (pd[17]&0xF);
     buf[6] |= ((pd[18] << 4)&0xF0);
-    
+
     buf[7] |= (pd[19]&0xF);
     buf[7] |= ((pd[20] << 4)&0xF0);
-    
+
     buf[8] = 0x00;// Fisrt 16LSB cut off
     buf[9] = 0xFF;
-    
+
     buf[10] = 0x01;// Ref PAD switch
-    
+
     buf[11] = 0x1F;// TDC Resolution 1F = 31
-    
+
     buf[12] = 0x0C;// Length
     buf[13] = 0x09;//CMD
-    
-    for(uint8_t i = 0; i < 12; i++)
-    {
+
+    for(uint8_t i = 0; i < 12; i++) {
         WriteOneReg(0x0C + i, buf[i]);
     }
-    
+
     WriteOneReg(0x0B, 0x0C);
     WriteOneReg(0x0A, 0x09);
-    
+
     return 0;
 }
 
@@ -727,103 +786,99 @@
 {
     uint8_t ret = 0;
     uint8_t value = 0, result = 0;
-    
+
     TRIM_EN = 1;
 
     //==================First BAND=====================//
     ChipInitReset();
-    ret = WriteOneReg(0xED    , 0x03);
-    ret = WriteOneReg(0xEC    , 0x36);
-    ret = WriteOneReg(0x3D    , 0xC0);
-    ret = WriteOneReg(0xE8    , 0x00);
-    ret = WriteOneReg(0xEA    , 0x3F);
-    ret = WriteOneReg(0x3D    , 0xC8);
-    ret = WriteOneReg(0xED    , 0x83);
+    ret = WriteOneReg(0xED, 0x03);
+    ret = WriteOneReg(0xEC, 0x36);
+    ret = WriteOneReg(0x3D, 0xC0);
+    ret = WriteOneReg(0xE8, 0x00);
+    ret = WriteOneReg(0xEA, 0x3F);
+    ret = WriteOneReg(0x3D, 0xC8);
+    ret = WriteOneReg(0xED, 0x83);
 
     wait_ms(1000);
 
     ret = ReadOneReg(0xFA, &value);
     ret = ReadOneReg(0xFB, &result);
 
-    if((result&0xC0) == 0xC0)
-    {
+    if((result&0xC0) == 0xC0) {
         *rco = value;
-         ChipInitReset();
-         TRIM_EN = 0;
+        ChipInitReset();
+        TRIM_EN = 0;
         return 0;
     }
 
     //==================Second BAND=====================//
     ChipInitReset();
-    ret = WriteOneReg(0xED    , 0x03);
-    ret = WriteOneReg(0xEC    , 0x36);
-    ret = WriteOneReg(0x3D    , 0xC0);
-    ret = WriteOneReg(0xE8    , 0x00);
-    ret = WriteOneReg(0xEA    , 0x7F);
-    ret = WriteOneReg(0xEB    , 0x40);
-    ret = WriteOneReg(0x3D    , 0xC8);
-    ret = WriteOneReg(0xED    , 0x83);
+    ret = WriteOneReg(0xED, 0x03);
+    ret = WriteOneReg(0xEC, 0x36);
+    ret = WriteOneReg(0x3D, 0xC0);
+    ret = WriteOneReg(0xE8, 0x00);
+    ret = WriteOneReg(0xEA, 0x7F);
+    ret = WriteOneReg(0xEB, 0x40);
+    ret = WriteOneReg(0x3D, 0xC8);
+    ret = WriteOneReg(0xED, 0x83);
 
     wait_ms(1000);
 
     ret = ReadOneReg(0xFA, &value);
     ret = ReadOneReg(0xFB, &result);
 
-    if((result&0xC0) == 0xC0)
-    {
+    if((result&0xC0) == 0xC0) {
         *rco = value;
-         ChipInitReset();
-         TRIM_EN = 0;
+        ChipInitReset();
+        TRIM_EN = 0;
         return 0;
-    }    
+    }
 
     //==================Third BAND=====================//
     ChipInitReset();
-    ret = WriteOneReg(0xED    , 0x03);
-    ret = WriteOneReg(0xEC    , 0x36);
-    ret = WriteOneReg(0x3D    , 0xC0);
-    ret = WriteOneReg(0xE8    , 0x00);
-    ret = WriteOneReg(0xEA    , 0xBF);
-    ret = WriteOneReg(0xEB    , 0x80);
-    ret = WriteOneReg(0x3D    , 0xC8);
-    ret = WriteOneReg(0xED    , 0x83);
+    ret = WriteOneReg(0xED, 0x03);
+    ret = WriteOneReg(0xEC, 0x36);
+    ret = WriteOneReg(0x3D, 0xC0);
+    ret = WriteOneReg(0xE8, 0x00);
+    ret = WriteOneReg(0xEA, 0xBF);
+    ret = WriteOneReg(0xEB, 0x80);
+    ret = WriteOneReg(0x3D, 0xC8);
+    ret = WriteOneReg(0xED, 0x83);
 
     wait_ms(1000);
 
     ret = ReadOneReg(0xFA, &value);
     ret = ReadOneReg(0xFB, &result);
 
-    if((result&0xC0) == 0xC0)
-    {
+    if((result&0xC0) == 0xC0) {
         *rco = value;
-         ChipInitReset();
-         TRIM_EN = 0;
+        ChipInitReset();
+        TRIM_EN = 0;
         return 0;
-    }    
+    }
 
     //==================Fourth BAND=====================//
     ChipInitReset();
-    ret = WriteOneReg(0xED    , 0x03);
-    ret = WriteOneReg(0xEC    , 0x36);
-    ret = WriteOneReg(0x3D    , 0xC0);
-    ret = WriteOneReg(0xE8    , 0x00);
-    ret = WriteOneReg(0xEA    , 0xFF);
-    ret = WriteOneReg(0xEB    , 0xC0);
-    ret = WriteOneReg(0x3D    , 0xC8);
-    ret = WriteOneReg(0xED    , 0x83);
+    ret = WriteOneReg(0xED, 0x03);
+    ret = WriteOneReg(0xEC, 0x36);
+    ret = WriteOneReg(0x3D, 0xC0);
+    ret = WriteOneReg(0xE8, 0x00);
+    ret = WriteOneReg(0xEA, 0xFF);
+    ret = WriteOneReg(0xEB, 0xC0);
+    ret = WriteOneReg(0x3D, 0xC8);
+    ret = WriteOneReg(0xED, 0x83);
 
     wait_ms(1000);
 
     ret = ReadOneReg(0xFA, &value);
     ret = ReadOneReg(0xFB, &result);
 
-    if((result&0xC0) == 0xC0)
-    {
+    if((result&0xC0) == 0xC0) {
         *rco = value;
-         ChipInitReset();
-         TRIM_EN = 0;
+        ChipInitReset();
+        TRIM_EN = 0;
         return 0;
-    }    
+    }
 
     ChipInitReset();
     TRIM_EN = 0;
@@ -834,8 +889,8 @@
 {
     uint8_t ret = 0;
     uint32_t timeout = 0;
-        
-    WriteOneReg(0xC0, 0x00);    
+
+    WriteOneReg(0xC0, 0x00);
     wait_ms(1);
 
     timeout = 600;
@@ -845,8 +900,8 @@
         timeout--;
         wait_ms(100);
     }
-    //osDelay(80);   
-    
+    //osDelay(80);
+
     ret = ReadOneReg(0xC0, bvd);
 
     if(timeout == 0)
@@ -857,12 +912,301 @@
 
 uint8_t Pixel_Enable(uint8_t *buf)
 {
-    for(uint8_t i = 0; i < 18; i++)
+    for(uint8_t i = 0; i < 18; i++) {
+        WriteOneReg(0xC2 + i, buf[i]);
+    }
+
+    return 0;
+}
+
+uint8_t MP_Measure(uint8_t mp, uint16_t *mp_tof, uint32_t* mp_peak)
+{
+    uint8_t ret = 0;
+    uint16_t lsb, mili, ref_lsb, ref_mili, noise_level;
+    uint32_t peak;
+    
+    uint32_t total_peak = 0, total_tof = 0;    
+    
+    switch(mp)   
     {
-        WriteOneReg(0xC2 + i, buf[i]);  
+        case 0:
+        case 1:
+        case 4:
+        case 5:
+            WriteOneReg(0xD7, 0x00); 
+            Pixel_Enable(pixel_map[mp]);
+            for(uint8_t j = 0; j < 16; j++)   
+            {
+                ret = OneTimeMeasure(&lsb, &mili, &peak, &noise_level, &ref_lsb, &ref_mili);//////
+                if(ret != 0)
+                {
+                    return 1;
+                }
+                
+                total_peak += peak;
+                total_tof += mili;
+            }
+            
+            *mp_tof = total_tof / 16;
+            *mp_peak = total_peak / 16;            
+        break;
+        
+        case 2:
+        case 3:
+        case 6:
+        case 7:
+            WriteOneReg(0xD7, 0x01); 
+            Pixel_Enable(pixel_map[mp]);
+            for(uint8_t j = 0; j < 16; j++)   
+            {
+                ret = OneTimeMeasure(&lsb, &mili, &peak, &noise_level, &ref_lsb, &ref_mili);//////
+                if(ret != 0)
+                {
+                    return 1;
+                }
+                
+                total_peak += peak;
+                total_tof += mili;
+            }
+            
+            *mp_tof = total_tof / 16;
+            *mp_peak = total_peak / 16;            
+        break;
+        
+        case 8:
+        case 9:
+        case 12:
+        case 13:
+            WriteOneReg(0xD7, 0x02); 
+            Pixel_Enable(pixel_map[mp]);
+            for(uint8_t j = 0; j < 16; j++)   
+            {
+                ret = OneTimeMeasure(&lsb, &mili, &peak, &noise_level, &ref_lsb, &ref_mili);//////
+                if(ret != 0)
+                {
+                    return 1;
+                }
+                
+                total_peak += peak;
+                total_tof += mili;
+            }
+            
+            *mp_tof = total_tof / 16;
+            *mp_peak = total_peak / 16;            
+        break;
+        
+        case 10:
+        case 11:
+        case 14:
+        case 15:
+            WriteOneReg(0xD7, 0x03); 
+            Pixel_Enable(pixel_map[mp]);
+            for(uint8_t j = 0; j < 16; j++)   
+            {
+                ret = OneTimeMeasure(&lsb, &mili, &peak, &noise_level, &ref_lsb, &ref_mili);//////
+                if(ret != 0)
+                {
+                    return 1;
+                }
+                
+                total_peak += peak;
+                total_tof += mili;
+            }
+            
+            *mp_tof = total_tof / 16;
+            *mp_peak = total_peak / 16;            
+        break;
     }
     
     return 0;
 }
 
+uint8_t MP_Slect(uint8_t *buf)
+{
+    uint32_t sum3x3[4];
+    uint32_t tmp = 0;
+    
+    uint16_t tof;
+    uint32_t peak;
+    
+    uint32_t tof_buf[16], peak_buf[16];
+        
+    for(uint8_t i = 0; i < 16; i++)
+    {
+        MP_Measure(i, &tof, &peak);
+        tof_buf[i] = tof;
+        peak_buf[i] = peak;
+    }    
+    
+    sum3x3[0] = peak_buf[0] + peak_buf[1] + peak_buf[2]
+              + peak_buf[4] + peak_buf[5] + peak_buf[6]
+              + peak_buf[8] + peak_buf[9] + peak_buf[10];
+              
+    sum3x3[1] = peak_buf[1] + peak_buf[2] + peak_buf[3]
+              + peak_buf[5] + peak_buf[6] + peak_buf[7]
+              + peak_buf[9] + peak_buf[10] + peak_buf[11];
+              
+    sum3x3[2] = peak_buf[4] + peak_buf[5] + peak_buf[6]
+              + peak_buf[8] + peak_buf[9] + peak_buf[10]
+              + peak_buf[12] + peak_buf[13] + peak_buf[14];
+              
+    sum3x3[3] = peak_buf[5] + peak_buf[6] + peak_buf[7]
+              + peak_buf[9] + peak_buf[10] + peak_buf[11]
+              + peak_buf[13] + peak_buf[14] + peak_buf[15];          
+              
+    for(uint8_t j = 0; j < 4; j++)
+    {
+        if(sum3x3[j] >= tmp)
+        {
+            tmp = sum3x3[j];
+            buf[0] = j;
+        }
+    }
+    
+    for(uint8_t k = 0; k < 16; k++)
+    {
+        memcpy(&buf[1+k*8], &tof_buf[k], 4);
+        memcpy(&buf[1+k*8 + 4], &peak_buf[k], 4);
+    }
+    
+    return 0;
+}
 
+uint8_t OTP_WritePart(uint8_t base, uint8_t len, uint8_t *buf)
+{
+    uint32_t timeout = 0;
+    uint8_t flag = 0;    
+    
+    if(len > 29)
+        return 2;
+    
+    WriteOneReg(0x0C, 0x02); 
+    WriteOneReg(0x0D, len); 
+    WriteOneReg(0x0E, base); 
+    
+    for(uint8_t i = 0; i < len; i++)
+    {
+        WriteOneReg(0x0F + i, buf[i]); 
+    }
+    
+    timeout = 2000;
+    WriteOneReg(0x08, 0x00); 
+    WriteOneReg(0x0A, 0x09);     
+    while(timeout != 0) {
+        timeout--;
+        wait_ms(1);
+        ReadOneReg(0x08, &flag);
+        if(flag == 0xFF)
+        {
+            break;
+        }
+    }
+    if(timeout == 0)
+    {
+        return 1;
+    }
+    
+    HIGH_EN = 1;
+    timeout = 1000;
+    while(timeout != 0) {
+        timeout--;
+        wait_ms(1);
+        ReadOneReg(0x08, &flag);
+        if(flag == 0x00)
+        {
+            break;
+        }
+    }
+    HIGH_EN = 0;
+    if(timeout == 0)
+    {
+        return 1;
+    }
+    
+    return 0;
+}
+
+uint8_t OTP_Write(uint8_t *buf)
+{    
+    uint8_t i = 0;
+    uint8_t ret = 0;
+    uint8_t base = buf[0];
+    uint8_t len = buf[1];   
+    
+    while(len > 29) 
+    {
+        ret = OTP_WritePart(base + i*29, 29, &buf[2 + i*29]);
+        if(ret != 0)
+        {
+            return ret;
+        }
+        len -= 29;
+        i++;
+        
+        wait_ms(1000);
+    }
+    if(len > 0)
+    {
+        ret = OTP_WritePart(base + i*29, len, &buf[2 + i*29]);
+        if(ret != 0)
+        {
+            return ret;
+        }
+    }
+    
+    return 0;
+}
+
+uint8_t OTP_ReadPart(uint8_t base, uint8_t len, uint8_t* out)
+{
+    if(len > 29)
+        return 2;    
+
+    WriteOneReg(0x0C, 0x03); 
+    WriteOneReg(0x0D, len); 
+    WriteOneReg(0x0E, base); 
+    WriteOneReg(0x0A, 0x09);     
+    
+    wait_ms(100);
+    
+    for(uint8_t i = 0; i < len; i++)
+    {
+        ReadOneReg(0x0F + i, &out[i]); 
+    }  
+    
+    return 0;
+}
+
+uint8_t OTP_Read(uint8_t* in, uint8_t* out)
+{
+    uint8_t ret = 0;
+    uint8_t i = 0;
+    
+    uint8_t base = in[0];
+    uint8_t len = in[1];   
+    
+    while(len > 29) 
+    {
+        ret = OTP_ReadPart(base + i*29, 29, &out[2 + i*29]);
+        if(ret != 0)
+        {
+            return ret;
+        }
+        len -= 29;
+        i++;
+    }
+    if(len > 0)
+    {
+        ret = OTP_ReadPart(base + i*29, len, &out[2 + i*29]);
+        if(ret != 0)
+        {
+            return ret;
+        }
+    }
+    
+    out[0] = base;
+    out[1] = len;
+    
+    return 0;
+}
+