TEST_CODE_ApplyTo2V1_API

Dependencies:   SDFileSystem max32630fthr USBDevice

DUT_RegConfig.cpp

Committer:
china_sn0w
Date:
2020-07-28
Revision:
4:217334c3a5b2
Parent:
3:35b05d91568d

File content as of revision 4:217334c3a5b2:

#include "mbed.h"
#include "cmsis_os.h"
#include "max32630fthr.h"
#include "USBSerial.h"
#include "CmdHandler.h"
#include "DUT_RegConfig.h"
#include "ServoRun.h"
#include "SDFileSystem.h"
#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;

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)
{
    WriteOneReg(0x37, rco);
    WriteOneReg(0xE4, tdc);
    WriteOneReg(0xC0, dcr);
}

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);
    }

    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());
}

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();
      
    
    DUT_RegTableInit();
    wait_ms(100);
}

void Enable_DUT_Interrupt(void)
{
    int_enable = 1;
}

void Disable_DUT_Interrupt(void)
{
    int_enable = 0;
}

void InterruptHandle(void)
{
    if(int_enable == 0)
        return;

    if(int_mark == 1) {
        int_mark = 0;
    } else if(int_mark == 2) {
        chip_int_semph.release();
        //发送信号量
    }
}



void HistogramReport()
{
    uint8_t ret = 0;
    uint16_t lsb, mili, ref_lsb, ref_mili, noise_level;
    uint32_t peak;


    uint16_t histogram_pos = 0;
    uint16_t histogram_num = 0;
    uint16_t range_step = 0;
    while(1) {
        if(histogram_mode == 1) {
            //ReadOneReg(REG_SYS_CFG, &sys_cfg_save);
            //WriteOneReg(REG_SYS_CFG, 0x00);
            ret = OneTimeMeasure(&lsb, &mili, &peak, &noise_level, &ref_lsb, &ref_mili);//////
            if(ret != 0) {
                histogram_mode = 0;
            } else {
                ret = vangogh_ram_rd(histogram_tdc);
                if(ret != 0) {
                    histogram_mode = 0;
                } else {
                    HandleReadHistogram(histogram_tdc);
                }
            }
            //WriteOneReg(REG_SYS_CFG, sys_cfg_save);
        } else if(histogram_mode == 2) {
            //ReadOneReg(REG_SYS_CFG, &sys_cfg_save);
            //WriteOneReg(REG_SYS_CFG, 0x00);
            ret = OneTimeMeasure(&lsb, &mili, &peak, &noise_level, &ref_lsb, &ref_mili);//////
            if(ret != 0) {
                histogram_mode = 0;
            } else {
                ret = vangogh_ram_rd_ma();
                if(ret != 0) {
                    histogram_mode = 0;
                } else {
                    HandleReadHistogram(0xF1);
                }
            }
            //WriteOneReg(REG_SYS_CFG, sys_cfg_save);
        } else if(histogram_mode == 3) {


            if(histogram_num >= histogram_per_pos) {
                histogram_num = 0;
                histogram_pos++;
                if(histogram_pos >= histogram_pos_num) {
                    histogram_mode = 0;
                }
                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, &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 {
                        StoreHistogram(histogram_pos, histogram_num, i);
                        wait_ms(100);
                    }
                }
            }
            //WriteOneReg(REG_SYS_CFG, sys_cfg_save);
            histogram_num++;
        } else if(histogram_mode == 4) {
            //ReadOneReg(REG_SYS_CFG, &sys_cfg_save);
            //WriteOneReg(REG_SYS_CFG, 0x00);
            ret = OneTimeMeasure(&lsb, &mili, &peak, &noise_level, &ref_lsb, &ref_mili);
            if(ret != 0) {
                histogram_mode = 0;
            } else {
                for(uint8_t i = 0; i < 9; i++) {
                    ret = vangogh_ram_rd(i);
                    if(ret != 0) {
                        histogram_mode = 0;
                        break;
                    } else {
                        HandleReadHistogram(i);
                        wait_ms(1);
                    }
                }
            }
            //WriteOneReg(REG_SYS_CFG, sys_cfg_save);
        } else if(histogram_mode == 5) {

            if(range_per_step == 0) {
                range_step++;
                if(range_step >= range_step_num) {
                    histogram_mode = 0;
                }
                //ServoRun(1, 10);
                //while(CheckUntil()) wait_ms(100);

                range_per_step = 0;
                single_measure_times = 256;                
                //ret = ContinuousMeasure();
                if(ret != 0) {
                    histogram_mode = 0;
                } else {
                    while(range_per_step<256 && histogram_mode == 5) {
                        wait_ms(100);
                    }
                    StoreHistogram(range_step, 0, 0);
                    wait_ms(5);
                    StoreHistogram(range_step, 0, 1);
                    wait_ms(5);
                    StoreHistogram(range_step, 0, 2);
                    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);
            }



        } else {
            histogram_num = 0;
            histogram_pos = 0;
            range_step = 0;
            histogram_pos_num = 0;
            histogram_per_pos = 0;
        }
        wait_ms(100);
    }
}

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, ref_lsb, ref_milimeter, noise_level;
    uint32_t peak;

    uint8_t ret = 0;
    
    Van_Dist_TypeDef result;
    Van_Status status;


    while(1) {
        
        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];
    buf[0] = addr;
    buf[1] = data;

    i2c_v.write(DUT_DEV_ADDR, (char*)buf, 2);

    return 0;
}

uint8_t ReadOneReg(uint8_t addr, uint8_t *data)
{
    uint8_t buf[2];
    buf[0] = addr;

    i2c_v.write(DUT_DEV_ADDR, (char*)buf,  1);
    i2c_v.read (DUT_DEV_ADDR, (char*)data, 1);

    return 0;
}

*/

uint8_t ReadAllRegToTable(void)
{
    for(uint16_t i = 0; i < DUT_REG_NUM; i++) {
        ReadOneReg(dut_reg[i].addr, &(dut_reg[i].value));
    }

    return 0;
}

uint8_t WriteFW(uint16_t size)
{
    DownloadFirmware(Firmware, size);
    
    wait_ms(30);
    Van_Config_TypeDef cfg;
    uint8_t cg_para[20];
    cfg.preSetMode = VAN_HIGH_PRECISION;    
    InitRanging(&cfg, cg_para);

    return 0;
}

uint8_t vangogh_ram_rd(uint8_t tdc)       //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 tdc_index = tdc;
    uint16_t ram_addr_base = 0x1000 + 0x0400 * tdc_index;

    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[tdc_index][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 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;    
    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;
   
    Van_Dist_TypeDef result;

    int_mark = 1;//One Time Measure

    StartRanging();   

    timeout = 1000;
    while(int_mark == 1 && timeout != 0) {
        timeout--;
        wait_ms(5);       
    }

    if(timeout == 0) {
        return 1;

    } else {

        ReadRangingResult(&result);
        
        ret = ReadOneReg(0x0d, (uint8_t*)lsb);
        ret = ReadOneReg(0x0e, (uint8_t*)lsb + 1);
        
        *milimeter = result.millimeter;
        *peak = result.peak;
        *noise_level = result.noise;
        
        //*ref_lsb = result.confidence;
        *ref_lsb = result.histcnt;
        *ref_milimeter = result.dmax;       

    }   

    return ret;
}

uint8_t ContinuousMeasure(void)
{
    uint8_t ret = 0;
    
    StartRanging();   
    continus_ranging = 1; 

    return ret;
}

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;   

    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(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);  

    return ret;
}

uint8_t StopContinuousMeasure()
{
    uint8_t ret = 0;
   
    continus_ranging = 0;

    return ret;
}

void StoreHistogram(uint16_t histogram_pos, uint16_t histogram_num, uint8_t tdc)
{
    _uart_send_pbuff[0] = histogram_pos;
    _uart_send_pbuff[1] = histogram_pos >> 8;

    _uart_send_pbuff[2] = tdc;

    _uart_send_pbuff[3] = histogram_num;
    _uart_send_pbuff[4] = histogram_num >> 8;

    memcpy(&_uart_send_pbuff[5], histogram[tdc], 1024);

    UART_CmdAckSend(READ_CMD | 0x80, VAN_STEP_HISTOGRAM_CMD, _uart_send_pbuff, 1024 + 1 + 2 + 2);
    //return 0;
}

uint8_t DCRTest(uint8_t vspad, uint8_t test_time)
{
    uint8_t ret = 0;
    uint32_t timeout = 0;
    memset(dcr_matrix, 0x00, 17*9*2);
    //WriteOneReg(0x50, 0x01);
    //WriteOneReg(0xBD, 0x01);
    //wait_ms(100);
    //WriteOneReg(0xD8, 0xF0);
    WriteOneReg(0xC0, vspad);

    for(uint8_t group = 0; group < 9; group++) {
        WriteOneReg(0x0C, group);
        wait_ms(1);
        WriteOneReg(0x0D, test_time);
        wait_ms(1);

        timeout = 25;
        int_mark = 1;
        WriteOneReg(0x0A, 0x0C);
        while(int_mark == 1 && timeout != 0) {
            timeout--;
            wait_ms(100);
        }
        //osDelay(80);
        for(uint8_t pix = 0; pix < 17; pix++) {
            ret = ReadOneReg(0x82 + pix*2, &dcr_matrix[pix][group*2 + 1]);
            ret = ReadOneReg(0x82 + pix*2 + 1, &dcr_matrix[pix][group*2]);
            //osDelay(1);
            if(ret != 0)
                return ret;
        }

    }

    return 0;
}

uint8_t DelayLineTest(uint8_t phase, uint8_t* buf)
{
    
    WriteOneReg(0xE4, phase);
    wait_ms(10);

    for(uint8_t step = 0; step < 8; step++) {
        WriteOneReg(0xE1, 0x61 | (step << 1));
        wait_ms(10);

        //timeout = 50;
        //int_mark = 1;
        WriteOneReg(0x0A, 0x0B);
        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);
        }
        //wait_ms(100);
    }

    return 0;
}

uint8_t GetTdcPhase(uint8_t* buf)
{
    uint8_t ret = 0;
    uint32_t timeout = 0;
    memset(buf, 0x00, 10);

    //WriteOneReg(0x0C, 0x0C);
    //WriteOneReg(0x0A, 0x0A);
    wait_ms(1);

    timeout = 20;
    int_mark = 1;
    WriteOneReg(0x0A, 0x0A);
    while(int_mark == 1 && timeout != 0) {
        timeout--;
        wait_ms(100);
    }
    //osDelay(80);

    ret = ReadOneReg(0x0C, buf);
    ret = ReadOneReg(0xE4, buf + 1);

    if(ret != 0)
        return ret;

    return 0;
}

uint8_t SetWindow(uint8_t* pd)
{
    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++) {
        WriteOneReg(0x0C + i, buf[i]);
    }

    WriteOneReg(0x0B, 0x0C);
    WriteOneReg(0x0A, 0x09);

    return 0;
}

uint8_t RCO_Trim(uint8_t *rco)
{
    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);

    wait_ms(1000);

    ret = ReadOneReg(0xFA, &value);
    ret = ReadOneReg(0xFB, &result);

    if((result&0xC0) == 0xC0) {
        *rco = value;
        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);

    wait_ms(1000);

    ret = ReadOneReg(0xFA, &value);
    ret = ReadOneReg(0xFB, &result);

    if((result&0xC0) == 0xC0) {
        *rco = value;
        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);

    wait_ms(1000);

    ret = ReadOneReg(0xFA, &value);
    ret = ReadOneReg(0xFB, &result);

    if((result&0xC0) == 0xC0) {
        *rco = value;
        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);

    wait_ms(1000);

    ret = ReadOneReg(0xFA, &value);
    ret = ReadOneReg(0xFB, &result);

    if((result&0xC0) == 0xC0) {
        *rco = value;
        ChipInitReset();
        TRIM_EN = 0;
        return 0;
    }

    ChipInitReset();
    TRIM_EN = 0;
    return 1;
}

uint8_t BVD_Trim(uint8_t *bvd)
{
    uint8_t ret = 0;
    uint32_t timeout = 0;

    WriteOneReg(0xC0, 0x00);
    wait_ms(1);

    timeout = 600;
    int_mark = 1;
    WriteOneReg(0x0A, 0x08);
    while(int_mark == 1 && timeout != 0) {
        timeout--;
        wait_ms(100);
    }
    //osDelay(80);

    ret = ReadOneReg(0xC0, bvd);

    if(timeout == 0)
        return 1;

    return 0;
}

uint8_t Pixel_Enable(uint8_t *buf)
{
    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)   
    {
        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;
}