#include "sht30.h"
#include "i2c.h"
#include "pdebug.h"
#include "assertions.h"
#include  "filter.h"
#include "cmsis_os.h"

#if 0
stTempHumiSensor g_stTempHumiSensor={
  .i2c_reg_addr   = 0x44<<1,
  .cmd_init_mode  = 0x2320,  //repeat medium_4
  .cmd_read_data  = 0xe000,  
};
#endif

stTempHumiSensor g_stTempHumiSensor={
  .i2c_reg_addr   = 0x44<<1,
  .cmd_init_mode  = 0x2c06,  
  .cmd_read_data  = 0x2c06,  
};

stTempHumiData g_stTempHumiData;

/**
  * @brief  写命令,(两个命令时间间隔至少1ms)
  * @param  
  * @retval 
  */
static u_int8_t i2c_write_cmd(u_int8_t addr,u_int16_t cmd)
{
    u_int8_t cmd_buff[2]={0x00};
    
    cmd_buff[0] = cmd>>8;
    cmd_buff[1] = cmd;
    
    u_int8_t ret = HAL_I2C_Master_Transmit(&hi2c1,addr,cmd_buff,2,0xffff);
    return ret;
}

/**
  * @brief  CRC校验
  * @param  
  * @retval 
  */
#define CRC8_POLYNOMIAL 0x31
u_int8_t CheckCrc8(u_int8_t* message, u_int8_t initial_value)
{
    u_int8_t  remainder;    
    u_int8_t  i = 0, j = 0;  

    remainder = initial_value;

    for(j = 0; j < 2;j++){
      remainder ^= message[j];
      for (i = 0; i < 8; i++){
        if (remainder & 0x80){
            remainder = (remainder << 1)^CRC8_POLYNOMIAL;
         } else {
                remainder = (remainder << 1);
         }
      }
    }
    return remainder;
}

/**
  * @brief  初始化代码
  * @param  
  * @retval 
  */
u_int8_t sht30_init()
{   
    float temp,humi;
    uint8_t ret;
    // soft reset
    // i2c_write_cmd(0x30a2);
    // HAL_Delay(25);
    HAL_GPIO_WritePin(GPIOB, GPIO_SHT_PWR_EN_Pin, GPIO_PIN_SET);
    HAL_Delay(1); 
    //u_int8_t ret = i2c_write_cmd(g_stTempHumiSensor.i2c_reg_addr, g_stTempHumiSensor.cmd_init_mode); 
    
    ret =  get_temp_humi_data(&temp, &humi);
    if(ret ==  TRUE)
      term_printf("Sensor Sht30 Check OK.\r\n Temp:%.2f,Humi:%.2f\r\n", temp,humi);
    else
      term_printf("Sensor Sht30 Check Err.\r\n");
    return 0;
}

/**
  * @brief  温湿度数据采集
  * @param  
  * @retval 
  */
u_int8_t sht30_collect_data(stTempHumiSensor stSensorDev, float *temp, float *humi)
{
    u_int8_t read_buff[6] = {0};

    u_int16_t temp_value;
    u_int16_t humi_value;

    i2c_write_cmd(stSensorDev.i2c_reg_addr,stSensorDev.cmd_read_data);

    if(HAL_I2C_Master_Receive(&hi2c1,stSensorDev.i2c_reg_addr,read_buff,6,0xffff) != HAL_OK){
        return HAL_ERROR;
    }
       
    if(CheckCrc8(read_buff, 0xFF) != read_buff[2] && CheckCrc8(&read_buff[3], 0xFF) != read_buff[5]){
        return HAL_ERROR;
    }

     temp_value = ((u_int16_t)read_buff[0]<<8)|read_buff[1];
     *temp = -45 + 175*((float)temp_value/65535);

     humi_value = ((u_int16_t)read_buff[3]<<8)|read_buff[4];
     *humi = 100 * ((float)humi_value / 65535);

    return HAL_OK;
}


/**
  * @brief  获取温湿度数据
  * @param  
  * @retval 
  */
#define COLLECT_DATA_NUM  10
BOOL get_temp_humi_data(float* temdata, float* humidata)
{   
    U_DataType collect_temdata[30]={0x00};
    U_DataType collect_humidata[30]={0x00};
    U_DataType tmp_temdata,tmp_humidata;
   
    for(int i=0; i<COLLECT_DATA_NUM; i++){
        int ret = sht30_collect_data(g_stTempHumiSensor,&collect_temdata[i].fValue, &collect_humidata[i].fValue);
       // AssertError(ret == HAL_OK, return FALSE, "sht30采样失败");
        if(ret == HAL_ERROR) 
          return FALSE;
        osDelay(1);
    }
    
    tmp_temdata = filter_middle(collect_temdata,COLLECT_DATA_NUM, FILTER_DATA_TYPE_FLOAT);
    tmp_humidata = filter_middle(collect_humidata,COLLECT_DATA_NUM, FILTER_DATA_TYPE_FLOAT);
    
//    断言有问题
//    AssertError((tmp_temdata.fValue >= -40) && (tmp_temdata.fValue <= 85), return FALSE, "sht30温度值校验失败");
//    AssertError((tmp_humidata.fValue >= 0) && (tmp_humidata.fValue <= 100), return FALSE, "sht30湿度值校验失败");
    if(tmp_temdata.fValue < -40)
    {
        tmp_temdata.fValue = -40;
//        term_printf("sht30温度值校验失败");
        return FALSE;
    }
    if(tmp_temdata.fValue > 125)
    {
        tmp_temdata.fValue = 125;
//        term_printf("sht30温度值校验失败");
        return FALSE;
    }
    if(tmp_humidata.fValue < 0)
    {
        tmp_humidata.fValue = 0;
//        term_printf("sht30湿度值校验失败");
        return FALSE;
    }
    if(tmp_humidata.fValue > 100)
    {
        tmp_humidata.fValue = 100;
//        term_printf("sht3湿度值校验失败");
        return FALSE;
    }
    
    *temdata = tmp_temdata.fValue;
    *humidata = tmp_humidata.fValue;
    
    //g_stTempHumiData.temp =  tmp_temdata.fValue;
    //g_stTempHumiData.humi =  tmp_humidata.fValue;
    return TRUE;
}

#if 0
/**
  * @brief  测试用例
  * @param  
  * @retval 
  */
void TEST_read_sht30_value()
{
    float temp,humi;
  
    AssertError(get_temp_humi_data(&temp, &humi),return,"采集sht30温湿度数据失败" );

    term_printf("temp:%.2f, humi:%.2f\r\n", temp, humi);
}

#endif