yincheng.zhong
2 天以前 2ebb8217f43b69f491620423ea4d5d5944d1f91d
keil/include/drivers/dps310.c
@@ -19,362 +19,362 @@
static dps310_scaling_coeffs_e
dps310_get_scaling_coef (dps310_osr_e osr)
{
        dps310_scaling_coeffs_e scaling_coeff;
    dps310_scaling_coeffs_e scaling_coeff;
        switch (osr){
    switch (osr) {
              case OSR_1:
                    scaling_coeff = OSR_SF_1;
                    break;
              case OSR_2:
                    scaling_coeff = OSR_SF_2;
                    break;
              case OSR_4:
                    scaling_coeff = OSR_SF_4;
                    break;
              case OSR_8:
                    scaling_coeff = OSR_SF_8;
                    break;
              case OSR_16:
                    scaling_coeff = OSR_SF_16;
                    break;
              case OSR_32:
                    scaling_coeff = OSR_SF_32;
                    break;
              case OSR_64:
                    scaling_coeff = OSR_SF_64;
                    break;
              case OSR_128:
                    scaling_coeff = OSR_SF_128;
                    break;
              default:
                     scaling_coeff = OSR_SF_1;
                     break;
        }
        return scaling_coeff;
    case OSR_1:
        scaling_coeff = OSR_SF_1;
        break;
    case OSR_2:
        scaling_coeff = OSR_SF_2;
        break;
    case OSR_4:
        scaling_coeff = OSR_SF_4;
        break;
    case OSR_8:
        scaling_coeff = OSR_SF_8;
        break;
    case OSR_16:
        scaling_coeff = OSR_SF_16;
        break;
    case OSR_32:
        scaling_coeff = OSR_SF_32;
        break;
    case OSR_64:
        scaling_coeff = OSR_SF_64;
        break;
    case OSR_128:
        scaling_coeff = OSR_SF_128;
        break;
    default:
        scaling_coeff = OSR_SF_1;
        break;
    }
    return scaling_coeff;
}
static int dps310_read_calib_coeffs(struct dps310_state *drv_state)
{
        s32 ret;
        u8 read_buffer[IFX_DPS310_COEF_LEN] = {0};
    s32 ret;
    u8 read_buffer[IFX_DPS310_COEF_LEN] = {0};
        if (drv_state == NULL)
            return -EINVAL;
    if (drv_state == NULL)
        return -EINVAL;
        ret =  drv_state->io->read_block((u8)IFX_DPS310_COEF_REG_ADDR,
                                 (u8)IFX_DPS310_COEF_LEN, read_buffer);
    ret =  drv_state->io->read_block((u8)IFX_DPS310_COEF_REG_ADDR,
                                     (u8)IFX_DPS310_COEF_LEN, read_buffer);
        if ( ret != IFX_DPS310_COEF_LEN )
            return ret;
    if ( ret != IFX_DPS310_COEF_LEN )
        return ret;
        drv_state->calib_coeffs.C0 = (read_buffer[0] << 4) + ((read_buffer[1] >>4) & 0x0F);
    drv_state->calib_coeffs.C0 = (read_buffer[0] << 4) + ((read_buffer[1] >>4) & 0x0F);
        if(drv_state->calib_coeffs.C0 > POW_2_11_MINUS_1)
            drv_state->calib_coeffs.C0 = drv_state->calib_coeffs.C0 - POW_2_12;
    if(drv_state->calib_coeffs.C0 > POW_2_11_MINUS_1)
        drv_state->calib_coeffs.C0 = drv_state->calib_coeffs.C0 - POW_2_12;
        drv_state->calib_coeffs.C1 = (read_buffer[2] + ((read_buffer[1] & 0x0F)<<8));
    drv_state->calib_coeffs.C1 = (read_buffer[2] + ((read_buffer[1] & 0x0F)<<8));
        if(drv_state->calib_coeffs.C1 > POW_2_11_MINUS_1)
            drv_state->calib_coeffs.C1 = drv_state->calib_coeffs.C1 - POW_2_12;
    if(drv_state->calib_coeffs.C1 > POW_2_11_MINUS_1)
        drv_state->calib_coeffs.C1 = drv_state->calib_coeffs.C1 - POW_2_12;
        drv_state->calib_coeffs.C00 = ((read_buffer[4]<<4) + (read_buffer[3]<<12)) + ((read_buffer[5]>>4) & 0x0F);
    drv_state->calib_coeffs.C00 = ((read_buffer[4]<<4) + (read_buffer[3]<<12)) + ((read_buffer[5]>>4) & 0x0F);
        if(drv_state->calib_coeffs.C00 > POW_2_19_MINUS_1)
            drv_state->calib_coeffs.C00 = drv_state->calib_coeffs.C00 -POW_2_20;
    if(drv_state->calib_coeffs.C00 > POW_2_19_MINUS_1)
        drv_state->calib_coeffs.C00 = drv_state->calib_coeffs.C00 -POW_2_20;
        drv_state->calib_coeffs.C10 = ((read_buffer[5] & 0x0F)<<16) + read_buffer[7] + (read_buffer[6]<<8);
    drv_state->calib_coeffs.C10 = ((read_buffer[5] & 0x0F)<<16) + read_buffer[7] + (read_buffer[6]<<8);
        if(drv_state->calib_coeffs.C10 > POW_2_19_MINUS_1)
            drv_state->calib_coeffs.C10 = drv_state->calib_coeffs.C10 - POW_2_20;
    if(drv_state->calib_coeffs.C10 > POW_2_19_MINUS_1)
        drv_state->calib_coeffs.C10 = drv_state->calib_coeffs.C10 - POW_2_20;
        drv_state->calib_coeffs.C01 = (read_buffer[9] + (read_buffer[8]<<8));
    drv_state->calib_coeffs.C01 = (read_buffer[9] + (read_buffer[8]<<8));
        if(drv_state->calib_coeffs.C01 > POW_2_15_MINUS_1)
            drv_state->calib_coeffs.C01 = drv_state->calib_coeffs.C01 - POW_2_16;
    if(drv_state->calib_coeffs.C01 > POW_2_15_MINUS_1)
        drv_state->calib_coeffs.C01 = drv_state->calib_coeffs.C01 - POW_2_16;
        drv_state->calib_coeffs.C11 = (read_buffer[11] + (read_buffer[10]<<8));
    drv_state->calib_coeffs.C11 = (read_buffer[11] + (read_buffer[10]<<8));
        if(drv_state->calib_coeffs.C11 > POW_2_15_MINUS_1)
            drv_state->calib_coeffs.C11 = drv_state->calib_coeffs.C11 - POW_2_16;
    if(drv_state->calib_coeffs.C11 > POW_2_15_MINUS_1)
        drv_state->calib_coeffs.C11 = drv_state->calib_coeffs.C11 - POW_2_16;
        drv_state->calib_coeffs.C20 = (read_buffer[13] + (read_buffer[12]<<8));
    drv_state->calib_coeffs.C20 = (read_buffer[13] + (read_buffer[12]<<8));
        if(drv_state->calib_coeffs.C20 > POW_2_15_MINUS_1)
            drv_state->calib_coeffs.C20 = drv_state->calib_coeffs.C20 - POW_2_16;
    if(drv_state->calib_coeffs.C20 > POW_2_15_MINUS_1)
        drv_state->calib_coeffs.C20 = drv_state->calib_coeffs.C20 - POW_2_16;
        drv_state->calib_coeffs.C21 = (read_buffer[15] + (read_buffer[14]<<8));
    drv_state->calib_coeffs.C21 = (read_buffer[15] + (read_buffer[14]<<8));
        if(drv_state->calib_coeffs.C21 > POW_2_15_MINUS_1)
            drv_state->calib_coeffs.C21 = drv_state->calib_coeffs.C21 - POW_2_16;
    if(drv_state->calib_coeffs.C21 > POW_2_15_MINUS_1)
        drv_state->calib_coeffs.C21 = drv_state->calib_coeffs.C21 - POW_2_16;
        drv_state->calib_coeffs.C30 = (read_buffer[17] + (read_buffer[16]<<8));
    drv_state->calib_coeffs.C30 = (read_buffer[17] + (read_buffer[16]<<8));
        if(drv_state->calib_coeffs.C30 > POW_2_15_MINUS_1)
            drv_state->calib_coeffs.C30 = drv_state->calib_coeffs.C30 - POW_2_16;
    if(drv_state->calib_coeffs.C30 > POW_2_15_MINUS_1)
        drv_state->calib_coeffs.C30 = drv_state->calib_coeffs.C30 - POW_2_16;
        /* lets see which temperature diode is used for calibration and update state accordingly*/
        ret = drv_state->io->read_byte(IFX_DPS310_TMP_COEF_SRCE_REG_ADDR);
    /* lets see which temperature diode is used for calibration and update state accordingly*/
    ret = drv_state->io->read_byte(IFX_DPS310_TMP_COEF_SRCE_REG_ADDR);
        if (ret < 0){
                return -EIO;
        }
        if ((ret >> IFX_DPS310_TMP_COEF_SRCE_REG_POS_MASK) & 1 ){
            drv_state->tmp_ext = TMP_EXT_MEMS;
      }
      else{
            drv_state->tmp_ext = TMP_EXT_ASIC;
      }
        return 0;
    if (ret < 0) {
        return -EIO;
    }
    if ((ret >> IFX_DPS310_TMP_COEF_SRCE_REG_POS_MASK) & 1 ) {
        drv_state->tmp_ext = TMP_EXT_MEMS;
    }
    else {
        drv_state->tmp_ext = TMP_EXT_ASIC;
    }
    return 0;
}
int dps310_resume(struct dps310_state *drv_state)
{
        s32 ret;
        if (drv_state == NULL)
            return -EINVAL;
    s32 ret;
    if (drv_state == NULL)
        return -EINVAL;
        ret = drv_state->io->write_byte(IFX_DPS310_MEAS_CFG_REG_ADDR,
                                        (u8)DPS310_MODE_BACKGROUND_ALL);
        if (ret < 0)
                return -EIO;
    ret = drv_state->io->write_byte(IFX_DPS310_MEAS_CFG_REG_ADDR,
                                    (u8)DPS310_MODE_BACKGROUND_ALL);
    if (ret < 0)
        return -EIO;
        drv_state->dev_mode = DPS310_MODE_BACKGROUND_ALL;
    drv_state->dev_mode = DPS310_MODE_BACKGROUND_ALL;
        return 0;
    return 0;
}
int dps310_standby(struct dps310_state *drv_state)
{
        s32 ret;
        if (drv_state == NULL)
          return -EINVAL;
    s32 ret;
    if (drv_state == NULL)
        return -EINVAL;
        ret = drv_state->io->write_byte(IFX_DPS310_MEAS_CFG_REG_ADDR,
                                       (u8)DPS310_MODE_IDLE);
        if (ret < 0)
                return -EIO;
    ret = drv_state->io->write_byte(IFX_DPS310_MEAS_CFG_REG_ADDR,
                                    (u8)DPS310_MODE_IDLE);
    if (ret < 0)
        return -EIO;
        drv_state->dev_mode = DPS310_MODE_IDLE;
    drv_state->dev_mode = DPS310_MODE_IDLE;
        return 0;
    return 0;
}
int dps310_config(struct dps310_state *drv_state,
                            dps310_osr_e osr_temp,
                            dps310_tmp_rate_e mr_temp,
                            dps310_osr_e osr_press,
                            dps310_pm_rate_e mr_press,
                            dps310_temperature_src_e temp_src)
                  dps310_osr_e osr_temp,
                  dps310_tmp_rate_e mr_temp,
                  dps310_osr_e osr_press,
                  dps310_pm_rate_e mr_press,
                  dps310_temperature_src_e temp_src)
{
        s32 ret;
        u8  config;
    s32 ret;
    u8  config;
        if (drv_state == NULL)
         return -EINVAL;
    if (drv_state == NULL)
        return -EINVAL;
       /* configure temperature measurements first*/
       /*Prepare a configuration word for TMP_CFG register*/
        config = (u8) temp_src;
    /* configure temperature measurements first*/
    /*Prepare a configuration word for TMP_CFG register*/
    config = (u8) temp_src;
        /*First Set the TMP_RATE[2:0] -> 6:4 */
        config |= ((u8)mr_temp);
    /*First Set the TMP_RATE[2:0] -> 6:4 */
    config |= ((u8)mr_temp);
       /*Set the TMP_PRC[3:0] -> 2:0 */
        config |= ((u8)osr_temp);
    /*Set the TMP_PRC[3:0] -> 2:0 */
    config |= ((u8)osr_temp);
        ret = drv_state->io->write_byte(IFX_DPS310_TMP_CFG_REG_ADDR,
                                  config);
        if (ret < 0)
            return -EIO;
    ret = drv_state->io->write_byte(IFX_DPS310_TMP_CFG_REG_ADDR,
                                    config);
    if (ret < 0)
        return -EIO;
        /*Prepare a configuration word for PRS_CFG register*/
        /*First Set the PM_RATE[2:0] -> 6:4 */
        config = (u8) ( 0x00 ) | ((u8)mr_press);
    /*Prepare a configuration word for PRS_CFG register*/
    /*First Set the PM_RATE[2:0] -> 6:4 */
    config = (u8) ( 0x00 ) | ((u8)mr_press);
        /*Set the PM_PRC[3:0] -> 3:0 */
        config |= ((u8)osr_press);
    /*Set the PM_PRC[3:0] -> 3:0 */
    config |= ((u8)osr_press);
        ret = drv_state->io->write_byte(IFX_DPS310_PRS_CFG_REG_ADDR,
                                  config);
        if (ret < 0)
            return -EIO;
    ret = drv_state->io->write_byte(IFX_DPS310_PRS_CFG_REG_ADDR,
                                    config);
    if (ret < 0)
        return -EIO;
        /* always take configuration word from state*/
        config = drv_state->cfg_word;
    /* always take configuration word from state*/
    config = drv_state->cfg_word;
        /*If oversampling rate for temperature is greater than 8 times, then set TMP_SHIFT bit in CFG_REG */
        if ((u8)osr_temp > (u8) OSR_8){
                config |= (u8) IFX_DPS310_CFG_TMP_SHIFT_EN_SET_VAL;
        }
    /*If oversampling rate for temperature is greater than 8 times, then set TMP_SHIFT bit in CFG_REG */
    if ((u8)osr_temp > (u8) OSR_8) {
        config |= (u8) IFX_DPS310_CFG_TMP_SHIFT_EN_SET_VAL;
    }
        /*If oversampling rate for pressure is greater than 8 times, then set P_SHIFT bit in CFG_REG */
        if ((u8)osr_press > (u8) OSR_8){
                config |= (u8) IFX_DPS310_CFG_PRS_SHIFT_EN_SET_VAL;
        }
    /*If oversampling rate for pressure is greater than 8 times, then set P_SHIFT bit in CFG_REG */
    if ((u8)osr_press > (u8) OSR_8) {
        config |= (u8) IFX_DPS310_CFG_PRS_SHIFT_EN_SET_VAL;
    }
        /* write CFG_REG */
        ret =  drv_state->io->write_byte(IFX_DPS310_CFG_REG_ADDR,
                                  config);
        if (ret < 0)
            return -EIO;
    /* write CFG_REG */
    ret =  drv_state->io->write_byte(IFX_DPS310_CFG_REG_ADDR,
                                     config);
    if (ret < 0)
        return -EIO;
       /*Update state accordingly with proper scaling factors based on oversampling rates*/
        drv_state->tmp_osr_scale_coeff = dps310_get_scaling_coef(osr_temp);
    /*Update state accordingly with proper scaling factors based on oversampling rates*/
    drv_state->tmp_osr_scale_coeff = dps310_get_scaling_coef(osr_temp);
        drv_state->prs_osr_scale_coeff = dps310_get_scaling_coef(osr_press);
    drv_state->prs_osr_scale_coeff = dps310_get_scaling_coef(osr_press);
        drv_state->press_mr = mr_press;
    drv_state->press_mr = mr_press;
        drv_state->temp_mr  = mr_temp;
    drv_state->temp_mr  = mr_temp;
        drv_state->temp_osr = osr_temp;
    drv_state->temp_osr = osr_temp;
        drv_state->press_osr = osr_press;
    drv_state->press_osr = osr_press;
        drv_state->tmp_ext  = temp_src;
    drv_state->tmp_ext  = temp_src;
        return 0;
    return 0;
}
int dps310_get_processed_data (struct dps310_state *drv_state,
                                      f64 *pressure,
                                      f64 *temperature)
                               f64 *pressure,
                               f64 *temperature)
{
        s32    ret;
        u8     read_buffer[IFX_DPS310_PSR_TMP_READ_LEN] = {0};
        f64    press_raw;
        f64    temp_raw;
    s32    ret;
    u8     read_buffer[IFX_DPS310_PSR_TMP_READ_LEN] = {0};
    f64    press_raw;
    f64    temp_raw;
        f64 temp_scaled;
        f64 temp_final;
        f64 press_scaled;
        f64 press_final;
    f64 temp_scaled;
    f64 temp_final;
    f64 press_scaled;
    f64 press_final;
        if (drv_state == NULL)
            return -EINVAL;
    if (drv_state == NULL)
        return -EINVAL;
        ret = test_read_block(IFX_DPS310_PSR_TMP_READ_REG_ADDR,
                              IFX_DPS310_PSR_TMP_READ_LEN,
                              read_buffer);
    ret = test_read_block(IFX_DPS310_PSR_TMP_READ_REG_ADDR,
                          IFX_DPS310_PSR_TMP_READ_LEN,
                          read_buffer);
        if (ret < IFX_DPS310_PSR_TMP_READ_LEN)
            return -EINVAL;
    if (ret < IFX_DPS310_PSR_TMP_READ_LEN)
        return -EINVAL;
        press_raw = (read_buffer[2]) + (read_buffer[1]<<8) + (read_buffer[0] <<16);
        temp_raw  = (read_buffer[5]) + (read_buffer[4]<<8) + (read_buffer[3] <<16);
    press_raw = (read_buffer[2]) + (read_buffer[1]<<8) + (read_buffer[0] <<16);
    temp_raw  = (read_buffer[5]) + (read_buffer[4]<<8) + (read_buffer[3] <<16);
        if(temp_raw > POW_2_23_MINUS_1){
            temp_raw = temp_raw - POW_2_24;
        }
    if(temp_raw > POW_2_23_MINUS_1) {
        temp_raw = temp_raw - POW_2_24;
    }
        if(press_raw > POW_2_23_MINUS_1){
            press_raw = press_raw - POW_2_24;
        }
    if(press_raw > POW_2_23_MINUS_1) {
        press_raw = press_raw - POW_2_24;
    }
        temp_scaled = (double)temp_raw / (double) (drv_state->tmp_osr_scale_coeff);
    temp_scaled = (double)temp_raw / (double) (drv_state->tmp_osr_scale_coeff);
        temp_final =  (drv_state->calib_coeffs.C0 /2.0f) + drv_state->calib_coeffs.C1 * temp_scaled ;
    temp_final =  (drv_state->calib_coeffs.C0 /2.0f) + drv_state->calib_coeffs.C1 * temp_scaled ;
        press_scaled = (double) press_raw / drv_state->prs_osr_scale_coeff;
    press_scaled = (double) press_raw / drv_state->prs_osr_scale_coeff;
        press_final = drv_state->calib_coeffs.C00 +
                      press_scaled *  (  drv_state->calib_coeffs.C10 + press_scaled *
                      ( drv_state->calib_coeffs.C20 + press_scaled * drv_state->calib_coeffs.C30 )  ) +
                      temp_scaled * drv_state->calib_coeffs.C01 +
                      temp_scaled * press_scaled * ( drv_state->calib_coeffs.C11 +
                                                      press_scaled * drv_state->calib_coeffs.C21 );
    press_final = drv_state->calib_coeffs.C00 +
                  press_scaled *  (  drv_state->calib_coeffs.C10 + press_scaled *
                                     ( drv_state->calib_coeffs.C20 + press_scaled * drv_state->calib_coeffs.C30 )  ) +
                  temp_scaled * drv_state->calib_coeffs.C01 +
                  temp_scaled * press_scaled * ( drv_state->calib_coeffs.C11 +
                          press_scaled * drv_state->calib_coeffs.C21 );
        press_final = press_final * 0.01f;   //to convert it into mBar
    press_final = press_final * 0.01f;   //to convert it into mBar
        *temperature = temp_final;
        *pressure    = press_final;  //press_final;
    *temperature = temp_final;
    *pressure    = press_final;  //press_final;
        return 0;
    return 0;
}
int dps310_init(struct dps310_state *drv_state, dps310_bus_connection *io)
{
        s32 ret;
    s32 ret;
        if (!drv_state){
            return -EINVAL;
        }
    if (!drv_state) {
        return -EINVAL;
    }
        if (!io){
            return -EINVAL;
        }
    if (!io) {
        return -EINVAL;
    }
        drv_state->cfg_word = 0;
        drv_state->enable = 0;
        /*first verify chip by reading product and rev id*/
        ret = io->read_byte(IFX_DPS310_PROD_REV_ID_REG_ADDR);
    drv_state->cfg_word = 0;
    drv_state->enable = 0;
        if (ret < 0){
            ret = -EIO;
            goto err_handler_iio;
        }
    /*first verify chip by reading product and rev id*/
    ret = io->read_byte(IFX_DPS310_PROD_REV_ID_REG_ADDR);
        if (ret != IFX_DSPS310_PROD_REV_ID_VAL){
            ret = -EINVAL;
         goto err_handler_iio;
        }
    if (ret < 0) {
        ret = -EIO;
        goto err_handler_iio;
    }
        /* attach bus connection instance to state*/
        drv_state->io = io;
    if (ret != IFX_DSPS310_PROD_REV_ID_VAL) {
        ret = -EINVAL;
        goto err_handler_iio;
    }
        /* from here wait for about 40ms till calibration coefficients become available*/
        if (drv_state->io->delayms != NULL)
            drv_state->io->delayms(40);
    /* attach bus connection instance to state*/
    drv_state->io = io;
        /* read now the calibration coeffs, temperature coef source and store in driver state*/
        ret = dps310_read_calib_coeffs(drv_state);
    /* from here wait for about 40ms till calibration coefficients become available*/
    if (drv_state->io->delayms != NULL)
        drv_state->io->delayms(40);
        if (ret < 0){
            goto err_handler_iio;
        }
    /* read now the calibration coeffs, temperature coef source and store in driver state*/
    ret = dps310_read_calib_coeffs(drv_state);
        /* Now apply ADC Temperature gain settings*/
        /* First write valid signature on 0x0e and 0x0f
         * to unlock address 0x62 */
        drv_state->io->write_byte((u8)0x0e,(u8)0xa5);
        drv_state->io->write_byte((u8)0x0f,(u8)0x96);
        /*Then update high gain value for Temperature*/
        drv_state->io->write_byte((u8)0x62,(u8)0x02);
    if (ret < 0) {
        goto err_handler_iio;
    }
        /*Finally lock back the location 0x62*/
        drv_state->io->write_byte((u8)0x0e,(u8)0x00);
        drv_state->io->write_byte((u8)0x0f,(u8)0x00);
    /* Now apply ADC Temperature gain settings*/
    /* First write valid signature on 0x0e and 0x0f
     * to unlock address 0x62 */
    drv_state->io->write_byte((u8)0x0e,(u8)0xa5);
    drv_state->io->write_byte((u8)0x0f,(u8)0x96);
    /*Then update high gain value for Temperature*/
    drv_state->io->write_byte((u8)0x62,(u8)0x02);
    /*Finally lock back the location 0x62*/
    drv_state->io->write_byte((u8)0x0e,(u8)0x00);
    drv_state->io->write_byte((u8)0x0f,(u8)0x00);
        /* configure sensor for default ODR settings*/
        ret = dps310_config(drv_state,
                            IFX_DPS310_TEMPERATURE_OSR,
                            IFX_DPS310_TEMPERATURE_MR,
                            IFX_DPS310_PRESSURE_OSR,
                            IFX_DPS310_PRESSURE_MR,
                            drv_state->tmp_ext);
        if (ret < 0){
            goto err_handler_iio;
        }
    /* configure sensor for default ODR settings*/
    ret = dps310_config(drv_state,
                        IFX_DPS310_TEMPERATURE_OSR,
                        IFX_DPS310_TEMPERATURE_MR,
                        IFX_DPS310_PRESSURE_OSR,
                        IFX_DPS310_PRESSURE_MR,
                        drv_state->tmp_ext);
    if (ret < 0) {
        goto err_handler_iio;
    }
        /* activate sensor*/
        ret = dps310_resume(drv_state);
        if (ret < 0){
            goto err_handler_iio;
        }
    /* activate sensor*/
    ret = dps310_resume(drv_state);
    if (ret < 0) {
        goto err_handler_iio;
    }
        return 0;
    return 0;
err_handler_iio:
      return ret;
    return ret;
}