Bavo Van Achte / Mbed 2 deprecated MLX90418_I2C_master

Dependencies:   mbed libscpi

i2c_mbed_fpga.cpp

Committer:
wuliqunyy
Date:
2021-03-24
Revision:
12:9f8c7f4da5f6
Parent:
11:b86aea372744
Child:
14:062850afdf38

File content as of revision 12:9f8c7f4da5f6:

#include "mbed.h"
#include "i2c_mbed_fpga.h"
DigitalOut led3(LED3);

/** i2c read from slave DUT
*  retun 0 on success, otherwise fails
*
*  @param i2c_master specifies the i2c interface
*  @param word is 4byte, first 2bytes as addr, the rest 2bytes to store data
*/
int i2c_mbed_fpga::i2c_word_read(char *word){
    int ack = 0;
    ack = i2c_master.write(I2C_SLAVE_ADDR, word, 2, true);  //restart
    ack += i2c_master.read(I2C_SLAVE_ADDR, word+2, 2, false); //stop bit
    wait_us(100); 
    return (ack == 0) ? 0 : 1; 
}

//I2C read even NAK happens
int i2c_mbed_fpga::i2c_word_read_by_byte(char *word){
    int ack = 0;
    i2c_master.start();
    ack = i2c_master.write(I2C_SLAVE_ADDR);
    ack = i2c_master.write(*word);
    ack = i2c_master.write(*(word+1));
    i2c_master.start();
    *(word+2) = i2c_master.read(1);
    *(word+3) = i2c_master.read(1);
    i2c_master.stop();
    return ack; 
}


/** i2c write to slave DUT
*   ==> one time write, not read back check
*
*  @param i2c_master specifies the i2c interface
*  @param word is considered as 4byte char data
*/
int i2c_mbed_fpga::i2c_word_write(char *word){
    int ack = 0;
    ack = i2c_master.write(I2C_SLAVE_ADDR, word, 4, false);
    return ack; 
}
//I2C write even NAK happens
int i2c_mbed_fpga::i2c_word_write_by_byte(char *word){
    int ack = 0;
    i2c_master.start();
    ack = i2c_master.write(I2C_SLAVE_ADDR);
    ack = i2c_master.write(*word);
    ack = i2c_master.write(*(word+1));
    ack = i2c_master.write(*(word+2));
    ack = i2c_master.write(*(word+3));
    i2c_master.stop();
    return ack; 
}


/** i2c write to slave DUT
*   ==> Safe write with 3 times read back check
*
*  @param i2c_master specifies the i2c interface
*  @param word is considered as 4byte char data
*/
int i2c_mbed_fpga::i2c_word_safe_write(char *word){
    int ack = 0;
    char readBuff[4];
    std::copy(word, word+4, readBuff);
    int i = 0;
    do{
        ack = i2c_master.write(I2C_SLAVE_ADDR, word, 4, false);
        wait_us(100);
        ack +=i2c_word_read(readBuff);
        wait_us(100);
        if( *(readBuff+2) == *(word+2) && *(readBuff+3) == *(word+3) ){
            ack++;
            }
        i++;
    }while ( ack!=0 && i<3 );
    return ack; 
}


/** i2c enter key to open I2C window
*/
int i2c_mbed_fpga::i2c_window_open(){
    char i2cMessage[4];
    *(i2cMessage+0) = (char)(NVADDR_CUST_ID3 >> 8)& 0xff;
    *(i2cMessage+1) = (char)(NVADDR_CUST_ID3 >> 0)& 0xff;
    *(i2cMessage+2) = (char)(0xD0)& 0xff;
    *(i2cMessage+3) = (char)(0xD0)& 0xff;  
    return i2c_word_write_by_byte(i2cMessage);
}

/** i2c enter key to Start the motor
*/
int i2c_mbed_fpga::i2c_motor_start(){
    char i2cMessage[4];
    *(i2cMessage+0) = (char)(NVADDR_CUST_ID3 >> 8)& 0xff;
    *(i2cMessage+1) = (char)(NVADDR_CUST_ID3 >> 0)& 0xff;
    *(i2cMessage+2) = (char)(0xCA)& 0xff;
    *(i2cMessage+3) = (char)(0xFE)& 0xff;  
    return i2c_word_write_by_byte(i2cMessage);
}

/** i2c to set the 50k PWM
*/
int i2c_mbed_fpga::i2c_set_50k_pwm(unsigned int pwm50k){
    nv_gen_ctrl_val &= ~NV_PWM_36K_MASK;
    nv_gen_ctrl_val |= pwm50k << NV_PWM_36K_OFFSET;
    char i2cMessage[4];
    *(i2cMessage+0) = (char)(NVADDR_NV_GEN_CTRL >> 8)& 0xff;
    *(i2cMessage+1) = (char)(NVADDR_NV_GEN_CTRL >> 0)& 0xff;
    *(i2cMessage+2) = (char)(nv_gen_ctrl_val >> 8)& 0xff;
    *(i2cMessage+3) = (char)(nv_gen_ctrl_val >> 0)& 0xff;          
    return i2c_word_safe_write(i2cMessage);
}



/** i2c to set the Postion Pulse width
*/
int i2c_mbed_fpga::i2c_set_position_pulse_width(unsigned int mantisaa_2b, unsigned int exponent_3b){
    nv_positin_val &= ~NV_POSITION_PULSE_TIME_MASK;
    nv_positin_val |= ((exponent_3b << 2) | mantisaa_2b) << NV_POSITION_PULSE_TIME_OFFSET;
    char i2cMessage[4];
    *(i2cMessage+0) = (char)(NVADDR_NV_POSITION >> 8)& 0xff;
    *(i2cMessage+1) = (char)(NVADDR_NV_POSITION >> 0)& 0xff;
    *(i2cMessage+2) = (char)(nv_positin_val >> 8)& 0xff;
    *(i2cMessage+3) = (char)(nv_positin_val >> 0)& 0xff;          
    return i2c_word_safe_write(i2cMessage);
}

/** i2c to set the Postion Pulse duty cycle
*/
int i2c_mbed_fpga::i2c_set_position_duty(unsigned int duty_2b){
    nv_positin_val &= ~NV_POSITION_DUTY_MASK;
    nv_positin_val |= duty_2b << NV_POSITION_DUTY_OFFSET;
    char i2cMessage[4];
    *(i2cMessage+0) = (char)(NVADDR_NV_POSITION >> 8)& 0xff;
    *(i2cMessage+1) = (char)(NVADDR_NV_POSITION >> 0)& 0xff;
    *(i2cMessage+2) = (char)(nv_positin_val >> 8)& 0xff;
    *(i2cMessage+3) = (char)(nv_positin_val >> 0)& 0xff;          
    return i2c_word_safe_write(i2cMessage);
}

/** i2c to enable the Postion Pulse majority volting
*/
int i2c_mbed_fpga::i2c_set_position_maj_vote(unsigned int maj_1b){
    nv_positin_val &= ~NV_POSI_MAJO_VOTE_MASK;
    nv_positin_val |= maj_1b << NV_POSI_MAJO_VOTE_OFFSET;
    char i2cMessage[4];
    *(i2cMessage+0) = (char)(NVADDR_NV_POSITION >> 8)& 0xff;
    *(i2cMessage+1) = (char)(NVADDR_NV_POSITION >> 0)& 0xff;
    *(i2cMessage+2) = (char)(nv_positin_val >> 8)& 0xff;
    *(i2cMessage+3) = (char)(nv_positin_val >> 0)& 0xff;          
    return i2c_word_safe_write(i2cMessage);
}

/** i2c to set the anti-cogging rotation direction
*/
int i2c_mbed_fpga::i2c_set_position_anti_cog(unsigned int cog_1b){
    nv_positin_val &= ~NV_ANTI_COG_MASK;
    nv_positin_val |= cog_1b << NV_ANTI_COG_OFFSET;
    char i2cMessage[4];
    *(i2cMessage+0) = (char)(NVADDR_NV_POSITION >> 8)& 0xff;
    *(i2cMessage+1) = (char)(NVADDR_NV_POSITION >> 0)& 0xff;
    *(i2cMessage+2) = (char)(nv_positin_val >> 8)& 0xff;
    *(i2cMessage+3) = (char)(nv_positin_val >> 0)& 0xff;          
    return i2c_word_safe_write(i2cMessage);
}


/** i2c to set the Start Up Pulse width (pulse train)
*/
int i2c_mbed_fpga::i2c_set_start_up_pulse_width(unsigned int mantisaa_3b, unsigned int exponent_3b){
    nv_start_up_val &= ~NV_START_UP_TIME_MASK;
    nv_start_up_val |= ((exponent_3b << 3) | mantisaa_3b) << NV_START_UP_TIME_OFFSET;
    char i2cMessage[4];
    *(i2cMessage+0) = (char)(NVADDR_NV_START_UP >> 8)& 0xff;
    *(i2cMessage+1) = (char)(NVADDR_NV_START_UP >> 0)& 0xff;
    *(i2cMessage+2) = (char)(nv_start_up_val >> 8)& 0xff;
    *(i2cMessage+3) = (char)(nv_start_up_val >> 0)& 0xff;          
    return i2c_word_safe_write(i2cMessage);
}

/** i2c to set the Start up Pulse duty cycle (pulse train)
*/
int i2c_mbed_fpga::i2c_set_start_up_duty(unsigned int duty_2b){
    nv_start_up_val &= ~NV_START_DUTY_MASK;
    nv_start_up_val |= duty_2b << NV_START_DUTY_OFFSET;
    char i2cMessage[4];
    *(i2cMessage+0) = (char)(NVADDR_NV_START_UP >> 8)& 0xff;
    *(i2cMessage+1) = (char)(NVADDR_NV_START_UP >> 0)& 0xff;
    *(i2cMessage+2) = (char)(nv_start_up_val >> 8)& 0xff;
    *(i2cMessage+3) = (char)(nv_start_up_val >> 0)& 0xff;          
    return i2c_word_safe_write(i2cMessage);
}

/** i2c to set the Start up commutation number of EHPs (pulse train)
*/
int i2c_mbed_fpga::i2c_set_start_up_num_comm(unsigned int comm){
    nv_start_up_val &= ~NV_COMM_START_NUM_MASK;
    nv_start_up_val |= comm << NV_COMM_START_NUM_OFFSET;
    char i2cMessage[4];
    *(i2cMessage+0) = (char)(NVADDR_NV_START_UP >> 8)& 0xff;
    *(i2cMessage+1) = (char)(NVADDR_NV_START_UP >> 0)& 0xff;
    *(i2cMessage+2) = (char)(nv_start_up_val >> 8)& 0xff;
    *(i2cMessage+3) = (char)(nv_start_up_val >> 0)& 0xff;          
    return i2c_word_safe_write(i2cMessage);
}

/** i2c to set the Soft Start Up (pulse train)
*/
int i2c_mbed_fpga::i2c_set_soft_start_up(unsigned int enbale, unsigned int mantisaa_3b, unsigned int exponent_3b, unsigned int step_size, unsigned int num_steps){
    int ack = 0;
    nv_start_up_val &= ~NV_SOFT_START_MASK;
    nv_start_up_val |= enbale << NV_SOFT_START_OFFSET;
    nv_positin_val &= ~NV_FIRST_NON_FLAT_TIME_MASK;
    nv_positin_val |= ((exponent_3b << 3) | mantisaa_3b) << NV_FIRST_NON_FLAT_TIME_OFFSET;
    nv_start_up_val &= ~NV_SOFT_STEP_SIZE_MASK;
    nv_start_up_val |= step_size << NV_SOFT_STEP_SIZE_OFFSET;
    nv_wind_brake_val &= ~NV_SOFT_NUM_STEP_MASK;
    nv_wind_brake_val |= num_steps << NV_SOFT_NUM_STEP_OFFSET;
    char i2cMessage[4];
    *(i2cMessage+0) = (char)(NVADDR_NV_POSITION >> 8)& 0xff;
    *(i2cMessage+1) = (char)(NVADDR_NV_POSITION >> 0)& 0xff;
    *(i2cMessage+2) = (char)(nv_positin_val >> 8)& 0xff;
    *(i2cMessage+3) = (char)(nv_positin_val >> 0)& 0xff;  
    ack += i2c_word_safe_write(i2cMessage);
    
    *(i2cMessage+0) = (char)(NVADDR_NV_START_UP >> 8)& 0xff;
    *(i2cMessage+1) = (char)(NVADDR_NV_START_UP >> 0)& 0xff;
    *(i2cMessage+2) = (char)(nv_start_up_val >> 8)& 0xff;
    *(i2cMessage+3) = (char)(nv_start_up_val >> 0)& 0xff;          
    ack += i2c_word_safe_write(i2cMessage);
    
    *(i2cMessage+0) = (char)(NVADDR_NV_WIND_BRAKE >> 8)& 0xff;
    *(i2cMessage+1) = (char)(NVADDR_NV_WIND_BRAKE >> 0)& 0xff;
    *(i2cMessage+2) = (char)(nv_wind_brake_val >> 8)& 0xff;
    *(i2cMessage+3) = (char)(nv_wind_brake_val >> 0)& 0xff;          
    ack += i2c_word_safe_write(i2cMessage);
    
    return ack; 
}

/** i2c to set the High Torque Start Up (pulse train)
*/
int i2c_mbed_fpga::i2c_set_high_torque_start_up(unsigned int enbale, unsigned int mantisaa_3b, unsigned int exponent_3b){
    int ack = 0;
    nv_start_up_val &= ~NV_LONG_START_MASK;
    nv_start_up_val |= enbale << NV_LONG_START_OFFSET;
    nv_positin_val &= ~NV_FIRST_NON_FLAT_TIME_MASK;
    nv_positin_val |= ((exponent_3b << 3) | mantisaa_3b) << NV_FIRST_NON_FLAT_TIME_OFFSET;
    char i2cMessage[4];
    *(i2cMessage+0) = (char)(NVADDR_NV_POSITION >> 8)& 0xff;
    *(i2cMessage+1) = (char)(NVADDR_NV_POSITION >> 0)& 0xff;
    *(i2cMessage+2) = (char)(nv_positin_val >> 8)& 0xff;
    *(i2cMessage+3) = (char)(nv_positin_val >> 0)& 0xff;  
    ack += i2c_word_safe_write(i2cMessage);
    
    *(i2cMessage+0) = (char)(NVADDR_NV_START_UP >> 8)& 0xff;
    *(i2cMessage+1) = (char)(NVADDR_NV_START_UP >> 0)& 0xff;
    *(i2cMessage+2) = (char)(nv_start_up_val >> 8)& 0xff;
    *(i2cMessage+3) = (char)(nv_start_up_val >> 0)& 0xff;          
    ack += i2c_word_safe_write(i2cMessage);
        
    return ack; 
}

/** i2c to set the Single Pulse Start Up (pulse train)
*/
int i2c_mbed_fpga::i2c_set_single_pulse_start_up(unsigned int enbale, unsigned int mantisaa_3b, unsigned int exponent_3b){
    int ack = 0;
    nv_start_up_val &= ~NV_SINGLE_PULSE_START_MASK;
    nv_start_up_val |= enbale << NV_SINGLE_PULSE_START_OFFSET;
    nv_positin_val &= ~NV_FIRST_NON_FLAT_TIME_MASK;
    nv_positin_val |= ((exponent_3b << 3) | mantisaa_3b) << NV_FIRST_NON_FLAT_TIME_OFFSET;
    char i2cMessage[4];
    *(i2cMessage+0) = (char)(NVADDR_NV_POSITION >> 8)& 0xff;
    *(i2cMessage+1) = (char)(NVADDR_NV_POSITION >> 0)& 0xff;
    *(i2cMessage+2) = (char)(nv_positin_val >> 8)& 0xff;
    *(i2cMessage+3) = (char)(nv_positin_val >> 0)& 0xff;  
    ack += i2c_word_safe_write(i2cMessage);
    
    *(i2cMessage+0) = (char)(NVADDR_NV_START_UP >> 8)& 0xff;
    *(i2cMessage+1) = (char)(NVADDR_NV_START_UP >> 0)& 0xff;
    *(i2cMessage+2) = (char)(nv_start_up_val >> 8)& 0xff;
    *(i2cMessage+3) = (char)(nv_start_up_val >> 0)& 0xff;          
    ack += i2c_word_safe_write(i2cMessage);
        
    return ack; 
}

/** i2c to set the open loop mode
*/
int i2c_mbed_fpga::i2c_set_rough_gain(unsigned int rough_gain){
    int ack = 0;
    nv_gen_ctrl_val &= ~NV_ROUGH_GAIN_MASK;
    nv_gen_ctrl_val |= rough_gain << NV_ROUGH_GAIN_OFFSET;
    char i2cMessage[4];
    *(i2cMessage+0) = (char)(NVADDR_NV_GEN_CTRL >> 8)& 0xff;
    *(i2cMessage+1) = (char)(NVADDR_NV_GEN_CTRL >> 0)& 0xff;
    *(i2cMessage+2) = (char)(nv_gen_ctrl_val >> 8)& 0xff;
    *(i2cMessage+3) = (char)(nv_gen_ctrl_val >> 0)& 0xff;  
    ack += i2c_word_safe_write(i2cMessage);
    
    return ack; 
}



/** i2c to set the current threshold for I_didt
*/
int i2c_mbed_fpga::i2c_set_comm_i_thres(unsigned int i_thr_low, unsigned int i_thr_high){
    int ack = 0;
    nv_comm_ctrl_val &= ~NV_I_ZC_TH_LOW_MASK;
    nv_comm_ctrl_val |= i_thr_low << NV_I_ZC_TH_LOW_OFFSET;
    nv_comm_ctrl_val &= ~NV_I_ZC_TH_HIGH_MASK;
    nv_comm_ctrl_val |= i_thr_high << NV_I_ZC_TH_HIGH_OFFSET;
    char i2cMessage[4];
    *(i2cMessage+0) = (char)(NVADDR_NV_COMM >> 8)& 0xff;
    *(i2cMessage+1) = (char)(NVADDR_NV_COMM >> 0)& 0xff;
    *(i2cMessage+2) = (char)(nv_comm_ctrl_val >> 8)& 0xff;
    *(i2cMessage+3) = (char)(nv_comm_ctrl_val >> 0)& 0xff;  
    ack += i2c_word_safe_write(i2cMessage);
    
    return ack; 
}

/** i2c to set the di current threshold for didt
*/
int i2c_mbed_fpga::i2c_set_comm_di_thres(unsigned int di_1st, unsigned int di_2nd){
    int ack = 0;
    nv_comm_ctrl_val &= ~NV_DI_TH_1ST_MASK;
    nv_comm_ctrl_val |= di_1st << NV_DI_TH_1ST_OFFSET;
    nv_comm_ctrl_val &= ~NV_DI_TH_2ND_MASK;
    nv_comm_ctrl_val |= di_2nd << NV_DI_TH_2ND_OFFSET;
    char i2cMessage[4];
    *(i2cMessage+0) = (char)(NVADDR_NV_COMM >> 8)& 0xff;
    *(i2cMessage+1) = (char)(NVADDR_NV_COMM >> 0)& 0xff;
    *(i2cMessage+2) = (char)(nv_comm_ctrl_val >> 8)& 0xff;
    *(i2cMessage+3) = (char)(nv_comm_ctrl_val >> 0)& 0xff;  
    ack += i2c_word_safe_write(i2cMessage);
    
    return ack; 
}




/** i2c to clean the I2C controller settins
*/
int i2c_mbed_fpga::i2c_clear_spd_ctrl(){
    int ack = 0;
    nv_spd_control_1_val = 0;
    nv_spd_control_2_val = 0;
    char i2cMessage[4];
    *(i2cMessage+0) = (char)(NVADDR_NV_SPD_CTRL_1 >> 8)& 0xff;
    *(i2cMessage+1) = (char)(NVADDR_NV_SPD_CTRL_1 >> 0)& 0xff;
    *(i2cMessage+2) = (char)(nv_spd_control_1_val >> 8)& 0xff;
    *(i2cMessage+3) = (char)(nv_spd_control_1_val >> 0)& 0xff;  
    ack += i2c_word_safe_write(i2cMessage);
    
    *(i2cMessage+0) = (char)(NVADDR_NV_SPD_CTRL_2 >> 8)& 0xff;
    *(i2cMessage+1) = (char)(NVADDR_NV_SPD_CTRL_2 >> 0)& 0xff;
    *(i2cMessage+2) = (char)(nv_spd_control_2_val >> 8)& 0xff;
    *(i2cMessage+3) = (char)(nv_spd_control_2_val >> 0)& 0xff;  
    ack += i2c_word_safe_write(i2cMessage);
    
    return ack; 
}


/** i2c to set the open loop mode
*/
int i2c_mbed_fpga::i2c_set_loop_mode(unsigned int openloop){
    int ack = 0;
    nv_spd_control_1_val &= ~NV_SPD_LOOP_MODE_MASK;
    nv_spd_control_1_val |= openloop << NV_SPD_LOOP_MODE_OFFSET;
    char i2cMessage[4];
    *(i2cMessage+0) = (char)(NVADDR_NV_SPD_CTRL_1 >> 8)& 0xff;
    *(i2cMessage+1) = (char)(NVADDR_NV_SPD_CTRL_1 >> 0)& 0xff;
    *(i2cMessage+2) = (char)(nv_spd_control_1_val >> 8)& 0xff;
    *(i2cMessage+3) = (char)(nv_spd_control_1_val >> 0)& 0xff;  
    ack += i2c_word_safe_write(i2cMessage);
    
    return ack; 
}

/** i2c to set the Single Pulse Start Up (pulse train)
*/
int i2c_mbed_fpga::i2c_set_open_loop_duty(unsigned int duty){
    int ack = 0;
    ram_open_duty_val = duty;
    char i2cMessage[4];
    *(i2cMessage+0) = (char)(0x10)& 0xff;
    *(i2cMessage+1) = (char)(0x00)& 0xff;
    *(i2cMessage+2) = (char)(ram_open_duty_val >> 8)& 0xff;
    *(i2cMessage+3) = (char)(ram_open_duty_val >> 0)& 0xff;  
    ack += i2c_word_safe_write(i2cMessage);
        
    return ack; 
}

/** i2c to set the speed curve type
*/
int i2c_mbed_fpga::i2c_set_curve_type(unsigned int curvetype){
    int ack = 0;
    nv_spd_control_1_val &= ~NV_CURVE_MODE_MASK;
    nv_spd_control_1_val |= curvetype << NV_CURVE_MODE_OFFSET;
    char i2cMessage[4];
    *(i2cMessage+0) = (char)(NVADDR_NV_SPD_CTRL_1 >> 8)& 0xff;
    *(i2cMessage+1) = (char)(NVADDR_NV_SPD_CTRL_1 >> 0)& 0xff;
    *(i2cMessage+2) = (char)(nv_spd_control_1_val >> 8)& 0xff;
    *(i2cMessage+3) = (char)(nv_spd_control_1_val >> 0)& 0xff;  
    ack += i2c_word_safe_write(i2cMessage);
    
    return ack; 
}

/** i2c to set the open dc ini
*/
int i2c_mbed_fpga::i2c_set_dc_ini(unsigned int ini){
    int ack = 0;
    nv_spd_control_2_val &= ~NV_DC_OPENLOOP_INI_MASK;
    nv_spd_control_2_val |= ini << NV_DC_OPENLOOP_INI_OFFSET;
    char i2cMessage[4];
    *(i2cMessage+0) = (char)(NVADDR_NV_SPD_CTRL_2 >> 8)& 0xff;
    *(i2cMessage+1) = (char)(NVADDR_NV_SPD_CTRL_2 >> 0)& 0xff;
    *(i2cMessage+2) = (char)(nv_spd_control_2_val >> 8)& 0xff;
    *(i2cMessage+3) = (char)(nv_spd_control_2_val >> 0)& 0xff;  
    ack += i2c_word_safe_write(i2cMessage);
    
    return ack; 
}

/** i2c to set the open dc slew rate
*/
int i2c_mbed_fpga::i2c_set_dc_sr(unsigned int sr){
    int ack = 0;
    nv_spd_control_2_val &= ~NV_DC_OPENLOOP_SR_MASK;
    nv_spd_control_2_val |= sr << NV_DC_OPENLOOP_SR_OFFSET;
    char i2cMessage[4];
    *(i2cMessage+0) = (char)(NVADDR_NV_SPD_CTRL_2 >> 8)& 0xff;
    *(i2cMessage+1) = (char)(NVADDR_NV_SPD_CTRL_2 >> 0)& 0xff;
    *(i2cMessage+2) = (char)(nv_spd_control_2_val >> 8)& 0xff;
    *(i2cMessage+3) = (char)(nv_spd_control_2_val >> 0)& 0xff;  
    ack += i2c_word_safe_write(i2cMessage);
    
    return ack; 
}