#include "device/supercap.h"

/* 全局变量 */
CAN_SuperCapRXDataTypeDef CAN_SuperCapRXData = {0};

uint8_t PowerOffset =0;

uint32_t LastCapTick = 0; //上一次收到超电信号的时间戳
uint32_t NowCapTick = 0;  //现在收到超电信号的时间戳

uint32_t chassis_energy_in_gamming =0;

/* 静态变量 - 用于CAN接收管理 */
static bool supercap_inited = false;
static osMessageQueueId_t supercap_rx_queue = NULL;

/**
  * @brief          获取超级电容在线状态，1在线，0离线
  */
uint8_t get_supercap_online_state(void){

  NowCapTick = HAL_GetTick(); //更新时间戳

  uint32_t DeltaCapTick = 0;
  DeltaCapTick = NowCapTick - LastCapTick; //计算时间差

//	if(get_game_progress() == 4){
//		//比赛开始的时候，开始统计消耗的能量

		chassis_energy_in_gamming += CAN_SuperCapRXData.BatPower * DeltaCapTick *0.001f;
    // 因为STM32的系统定时器是1ms的周期，所以*0.001，单位化为秒（S），能量单位才是焦耳（J）
//	}

  if(DeltaCapTick > 1000){
    //如果时间差大于1s，说明超电信号丢失，返回超电离线的标志
    return 0;
  }else {
    //如果时间差小于1s，说明超电信号正常，返回超电在线的标志
    return 1;
  }
}

/**
  * @brief          获取根据超级电容功率统计的底盘消耗能量，单位：焦耳（J）
  */
uint32_t get_chassis_energy_from_supercap(void){
	
  return chassis_energy_in_gamming;
	
}

/******************超级电容数据从CAN传到结构体******************/
int8_t SuperCap_Init(void)
{
    if (supercap_inited) {
        return DEVICE_OK;  // 已经初始化过
    }

    if (BSP_CAN_RegisterId( SUPERCAP_CAN , SUPERCAP_RX_ID, 3) != BSP_OK) {
        return DEVICE_ERR;
    }
    
    supercap_inited = true;
    return DEVICE_OK;
}

int8_t SuperCap_Update(void)
{
    if (!supercap_inited) {
        return DEVICE_ERR;
    }
    
    BSP_CAN_Message_t rx_msg;

    // 从CAN队列获取数据
    if (BSP_CAN_GetMessage( SUPERCAP_CAN , SUPERCAP_RX_ID, &rx_msg, BSP_CAN_TIMEOUT_IMMEDIATE) == BSP_OK) {
        // 处理接收到的数据
        transfer_SuperCap_measure(rx_msg.data);
        return DEVICE_OK;
    }
    
    return DEVICE_ERR;  // 没有新数据
}

void transfer_SuperCap_measure(uint8_t *data)
{
  LastCapTick = HAL_GetTick();
  CAN_SuperCapRXData.SuperCapReady = (SuperCap_Status_t)data[0];
  CAN_SuperCapRXData.SuperCapState = (SuperCap_Status_t)data[1];
  CAN_SuperCapRXData.SuperCapEnergy = data[2];
  CAN_SuperCapRXData.ChassisPower = data[3] << 1; //左移一位是为了扩大范围，超电发出来的的时候右移了一位
  CAN_SuperCapRXData.BatVoltage = data[4];
  CAN_SuperCapRXData.BatPower = data[5];
}

/**
  * @brief          获取超级电容的运行状态，具体查看枚举SuperCapStateEnum
  * @retval         none
  */
SuperCapStateEnum get_supercap_state(void){
  return (SuperCapStateEnum)CAN_SuperCapRXData.SuperCapState;
}

/**
  * @brief          获取超级电容读到的电池电压，单位伏（V）
  * @retval         none
  */
float get_battery_voltage_from_supercap(void){
  return (float)CAN_SuperCapRXData.BatVoltage * 0.1f;
}

/**
  * @brief          获取超级电容可用能量，范围：0-100%
  * @retval         none
  */
uint8_t get_supercap_energy(void){
  return CAN_SuperCapRXData.SuperCapEnergy;
}

/**
  * @brief          设置超级电容功率补偿
  * @retval         none
  */
void set_supercap_power_offset(uint8_t offset){
  PowerOffset = offset;
}

/**
  * @brief          发送超级电容数据
  * @param[in]      Enable: 超级电容使能
  * @param[in]      Charge: 超级电容充电，在PLUS版本中无效
  * @param[in]      PowerLimit: 裁判系统功率限制
  * @param[in]      Chargepower: 超级电容充电功率，在PLUS版本中无效
  * @retval         none
  */
int8_t CAN_TX_SuperCapData(CAN_SuperCapTXDataTypeDef * TX_Temp)
{
		if (TX_Temp == NULL) return DEVICE_ERR_NULL;
	
		BSP_CAN_StdDataFrame_t tx_frame;	
	
		tx_frame.id = SUPERCAP_TX_ID;
    tx_frame.dlc = 0x08;
	
    tx_frame.data[0] = TX_Temp-> Enable;
    tx_frame.data[1] = TX_Temp-> Charge;//PLUS disabled
    tx_frame.data[2] = TX_Temp-> Powerlimit - PowerOffset;
    tx_frame.data[3] = TX_Temp-> ChargePower;//PLUS disabled
	
		tx_frame.data[4] = 0;
		tx_frame.data[5] = 0;
		tx_frame.data[6] = 0;
		tx_frame.data[7] = 0;
		
		return BSP_CAN_TransmitStdDataFrame( SUPERCAP_CAN , &tx_frame) == BSP_OK ? DEVICE_OK : DEVICE_ERR;
}


