#include "weight_init.h"
#include "chipflash.h"
#include "crc.h"
#include "soft_can.h"
#include "tim.h"
#include "math.h"


_WS_INFO ws_info = {
    ._app_bin_size = 0xFFFFFFFF,
    ._compAddr = COMP_ADDR,
    ._hardVer = HARDVER,
    ._softVer = SOFT_VER,
    ._moduleID = MODULE_ID,
    ._bootFlag = BOOT_FLAG,
};

/*软重启判断*/
//static void Soft_Reset_Judge(void) {
//  static uint8_t buf[8] = {0};
//  flash_ops->Read_Flash(RESET_FLASH_BASE, buf, sizeof(buf));

//  if (buf[0] == 0xFE) // 判断是否是软件重启
//  {
//    flash_ops->Erase_Flash(RESET_FLASH_BASE, RESET_FLASH_END);
//  }
//}

/* 读取FLASH波特率设置，0x1F4 = 500K,0x3E8 = 1000K */
//static void Set_Can_Baud(void) {
//  uint8_t BaudBuf[2] = {0};
//  uint16_t setbaudflag = 0;
//  flash_ops->Read_Flash(CAN_FLASH_BASE, BaudBuf, sizeof(BaudBuf));

//  setbaudflag = BaudBuf[1];
//  setbaudflag = (setbaudflag << 8) + BaudBuf[0];
//  if (0x1F4 == setbaudflag) {
//    MX_CAN_Init(8);
//  } else if (0x3E8 == setbaudflag) {
//    MX_CAN_Init(4);
//  } else {
//    setbaudflag = 0x3E8;
//    BaudBuf[0] = setbaudflag & 0xff;
//    BaudBuf[1] = (setbaudflag & 0xff00) >> 8;
//    flash_ops->Erase_Flash(CAN_FLASH_BASE, CAN_FLASH_END); // 默认重写0x3E8
//    flash_ops->Write_Flash(CAN_FLASH_BASE, BaudBuf, sizeof(BaudBuf));
//    MX_CAN_Init(4);
//  }
//}

/*需要升级*/
void Write_Upgrade_Flag(void) {
  ws_info._bootFlag = BOOT_FLAG;

  flash_ops->Erase_Flash(PAR_FLASH_BASE_ADDR, PAR_FLASH_END_ADDR);

  flash_ops->Write_Flash(PAR_FLASH_BASE_ADDR, (uint8_t *)&ws_info,
                         sizeof(ws_info));
}

/*重置升级标志位*/
static void Reset_Upgrade(void) {
//  flash_ops->Read_Flash(PAR_FLASH_BASE_ADDR, (uint8_t *)&ws_info,
//                        sizeof(ws_info));
  /*merge的时候合并冲突把这个标志位覆盖成了不存在升级！！引以为戒！*/
//#if OFF_SEL == 1
//  if (ws_info._bootFlag != NOEXIST_UPGRADE_FLAG)
//#elif OFF_SEL == 2
//  if (ws_info._bootFlag != UNUPGRADE)
//#else
//  if (ws_info._bootFlag != UNUPGRADE)
//#endif
//  {
//#if OFF_SEL == 1
//    ws_info._bootFlag = NOEXIST_UPGRADE_FLAG;
//#elif OFF_SEL == 2
//    ws_info._bootFlag = UNUPGRADE;
//#else
//    ws_info._bootFlag = UNUPGRADE;
//#endif
	ws_info._bootFlag = UNUPGRADE;
    ws_info._app_bin_size = 0xFFFFFFFF, ws_info._compAddr = COMP_ADDR,
    ws_info._hardVer = HARDVER, ws_info._softVer = SOFT_VER,
    ws_info._moduleID = MODULE_ID,

    //flash_ops->Erase_Flash(PAR_FLASH_BASE_ADDR, PAR_FLASH_END_ADDR);
    ws_info._crcCheck = Get_Crc16((uint8_t *)&ws_info, sizeof(ws_info) - 2);
//    flash_ops->Write_Flash(PAR_FLASH_BASE_ADDR, (uint8_t *)&ws_info,
//                           sizeof(ws_info));
  //}
}

static void Load_Param(void) {
  uint32_t v_check;
  uint32_t tmp_g;
  float tmp_k;
  uint8_t sensor_num_c = 0;
  WEIGHING_DEVICE *device = Get_Device_Handle();
  flash_ops->Read_Flash(VALUE_FLASH_Check_Addr, (uint8_t *)&v_check,
                        sizeof(v_check));

  if (Value_Check == v_check) {
    flash_ops->Read_Flash(SENSOR_NUM_RECORD_BASE, (uint8_t *)&sensor_num_c,
                          sizeof(sensor_num_c));
    if (sensor_num_c <= SENSOR_NUM) {
      device->sensor_num_mask = sensor_num_c;
    }

    for (sensor_num_c = 0; sensor_num_c < SENSOR_NUM; sensor_num_c++) {
      struct SENSOR *sensor = device->sensor[sensor_num_c];
      if (sensor_num_c == device->sensor_num_mask) {
        sensor->base_k = 0;
        continue;
      }

      
      flash_ops->Read_Flash(GROSSWEIGHT1_FLASH_BASE +
                                sensor_num_c * ONE_WORD_SIZE,
                            (uint8_t *)&tmp_g, sizeof(tmp_g));

      if (tmp_g != 0xFFFFFFFF && tmp_g != 0) {
        device->sensor[sensor_num_c]->GrossWeight = tmp_g;
      }
    }

    flash_ops->Read_Flash(K1_VALUE_FLASH_BASE,(uint8_t *)&tmp_k, sizeof(tmp_k));
    device->correct_k = tmp_k;
    flash_ops->Read_Flash(K1_VALUE_FLASH_BASE,(uint8_t *)&tmp_g, sizeof(tmp_k));
    if(tmp_g == 0xFFFFFFFF)
    {
      device->correct_k = 1;
    }

  }
}

static void Record_First_InitValue(void) {
  WEIGHING_DEVICE *device = Get_Device_Handle();
  for (uint8_t sensor_num_c = 0; sensor_num_c < SENSOR_NUM; sensor_num_c++) {
    if (sensor_num_c == device->sensor_num_mask) {
      continue;
    }

    struct SENSOR *sensor = device->sensor[sensor_num_c];
    flash_ops->Read_Flash(
        SENSOR1_INIT_VALUE_BASE + sensor_num_c * ONE_WORD_SIZE,
        (uint8_t *)&sensor->raw_init_value, sizeof(sensor->raw_init_value));

    if (sensor->raw_init_value == 0xFFFFFFFF) 
	{
      sensor->raw_init_value = sensor->GrossWeight;
      flash_ops->Write_Flash(
          SENSOR1_INIT_VALUE_BASE + sensor_num_c * ONE_WORD_SIZE,
          (uint8_t *)&sensor->raw_init_value, sizeof(sensor->raw_init_value));
    }
  }
  //flash_ops->Erase_Flash(SENSOR1_INIT_VALUE_BASE , SENSOR1_INIT_VALUE_BASE + ONE_PARAM_SIZE);
  
}

static void Get_Warn_Licence(void) {
  float read_tmp = 0;
  WEIGHING_DEVICE *device = Get_Device_Handle();
  for (uint8_t sensor_num_c = 0; sensor_num_c < SENSOR_NUM; sensor_num_c++) {
    struct SENSOR *sensor = device->sensor[sensor_num_c];
    
    if (sensor_num_c == device->sensor_num_mask) {
      continue;
    }
    
    flash_ops->Read_Flash(SENSOR1_INIT_VALUE_BASE +
                              sensor_num_c * ONE_PARAM_SIZE,
                          (uint8_t *)&read_tmp, sizeof(read_tmp));
    
    if(read_tmp < MIN_K || read_tmp > MAX_K)
        sensor->base_k = 112.0f;
   else
        sensor->base_k = read_tmp;   

    
  }
}

static void Read_Params(void) {
  WEIGHING_DEVICE *device = Get_Device_Handle();
  device->_ops->get_allgrossweight();
  delay_us(200);
  Record_First_InitValue();
  Get_Warn_Licence(); //读基础K
  Load_Param();
  /*防止异常*/
  for (uint8_t sensor_num_c = 0; sensor_num_c < SENSOR_NUM; sensor_num_c++) {
    if (sensor_num_c == device->sensor_num_mask) {
      continue;
    }
    struct SENSOR *sensor = device->sensor[sensor_num_c];
    // if (sensor->K.f < MIN_K || sensor->K.f > MAX_K || sensor->K.i[0] == 0xff) {
    //   sensor->K.f = 112.0f;
    // }
  }
}

void MY_WEIGHT_INIT(void) {
  WEIGHING_DEVICE *device = Get_Device_Handle();

  //Reset_Upgrade();

 // Set_Can_Baud();

  //CAN_Init(CANTX_ID);

  device->_ops->filter_init();

  Read_Params();

  //Soft_Reset_Judge();
  // 主动发送K值
  Set_Ack_Status(ack_e1); 
}
