#pragma once

#include "fdcan.h"
#include "weight_read.h"
#include "rkfifo.h"

//称重canid
#define CANTX_ID 0x81320
#define CANRX_ID 0x81321
#define CANRX_MASTK 0x80000
#define CAN_ACK_ID 0x81322

#define CANTX_ID2 0x81326

#define CAN_REQ_UPGRADE_ID 0x381400

#define HIGH_MASK 0xFFFF0000
#define LOW_MASK 0x0000FFFF

#define ONE_PARAM_SIZE (8 * 1024)
#define ONE_WORD_SIZE (1 * 64)

#define RESET_FLASH_BASE ((uint32_t)FLASH_BASE + 64 * 1024) // 存放重启标志位
#define RESET_FLASH_END RESET_FLASH_BASE + ONE_PARAM_SIZE

#define CAN_FLASH_BASE RESET_FLASH_END // 存放CAN波特率标志位
#define CAN_FLASH_END CAN_FLASH_BASE + ONE_PARAM_SIZE

#define VALUE_FLASH_Check_Addr CAN_FLASH_END // 存放默认K值信息,前四个字节为数据有效位
#define VALUE_FLASH_Check_End VALUE_FLASH_Check_Addr + ONE_PARAM_SIZE
/*基本上只用第一个的地址*/
#define K1_VALUE_FLASH_BASE VALUE_FLASH_Check_End //测量K值
#define K1_VALUE_FLASH_END K1_VALUE_FLASH_BASE + ONE_PARAM_SIZE
//#define K2_VALUE_FLASH_BASE K1_VALUE_FLASH_END
//#define K2_VALUE_FLASH_END K2_VALUE_FLASH_BASE + ONE_PARAM_SIZE
//#define K3_VALUE_FLASH_BASE K2_VALUE_FLASH_END
//#define K3_VALUE_FLASH_END K3_VALUE_FLASH_BASE + ONE_PARAM_SIZE
//#define K4_VALUE_FLASH_BASE K3_VALUE_FLASH_END
//#define K4_VALUE_FLASH_END K4_VALUE_FLASH_BASE + ONE_PARAM_SIZE

/*基本上只用第一个的地址*/
#define GROSSWEIGHT1_FLASH_BASE K1_VALUE_FLASH_END    //毛重
#define GROSSWEIGHT1_FLASH_END GROSSWEIGHT1_FLASH_BASE + ONE_PARAM_SIZE
//#define GROSSWEIGHT2_FLASH_BASE GROSSWEIGHT1_FLASH_END
//#define GROSSWEIGHT2_FLASH_END GROSSWEIGHT2_FLASH_BASE + ONE_WORD_SIZE
//#define GROSSWEIGHT3_FLASH_BASE GROSSWEIGHT2_FLASH_END
//#define GROSSWEIGHT3_FLASH_END GROSSWEIGHT3_FLASH_BASE + ONE_WORD_SIZE
//#define GROSSWEIGHT4_FLASH_BASE GROSSWEIGHT3_FLASH_END
//#define GROSSWEIGHT4_FLASH_END GROSSWEIGHT4_FLASH_BASE + ONE_WORD_SIZE

#define SENSOR1_INIT_VALUE_BASE GROSSWEIGHT1_FLASH_END  //基础K值
#define SENSOR1_INIT_VALUE_END SENSOR1_INIT_VALUE_BASE + ONE_PARAM_SIZE
#define SENSOR2_INIT_VALUE_BASE SENSOR1_INIT_VALUE_END
#define SENSOR2_INIT_VALUE_END SENSOR2_INIT_VALUE_BASE + ONE_PARAM_SIZE
#define SENSOR3_INIT_VALUE_BASE SENSOR2_INIT_VALUE_END
#define SENSOR3_INIT_VALUE_END SENSOR3_INIT_VALUE_BASE + ONE_PARAM_SIZE
#define SENSOR4_INIT_VALUE_BASE SENSOR3_INIT_VALUE_END
#define SENSOR4_INIT_VALUE_END SENSOR4_INIT_VALUE_BASE + ONE_PARAM_SIZE

#define SENSOR_NUM_RECORD_BASE SENSOR4_INIT_VALUE_END + ONE_PARAM_SIZE
#define SENSOR_NUM_RECORD_END SENSOR_NUM_RECORD_BASE + ONE_PARAM_SIZE

// 配置起始地址
#define PARAM_FLASH_BASE RESET_FLASH_BASE
// 配置结束地址
#define PARAM_FLASH_END GROSSWEIGHT4_FLASH_END

#define Value_Check 0x33336666

#define MAX_FRAME_DATA 8

typedef struct
{
    FDCAN_TxHeaderTypeDef Txheader;
    uint8_t Txdata[MAX_FRAME_DATA];
} Can_Tx;

typedef struct
{
    FDCAN_RxHeaderTypeDef Rxheader;
    uint8_t Rxdata[MAX_FRAME_DATA];
} Can_Rx;

typedef struct
{
    uint8_t Code;
    uint8_t Data[4];
    uint8_t CRCH;
    uint8_t CRCL;
    uint8_t Num;
} FORMAT_RXMSG, FORMAT_ACKMSG;

typedef struct
{
    uint8_t WorkStatus;
    uint8_t AlarmStatus;
    uint16_t WeightRate;
    uint8_t Weight[4];
} FORMAT_CAN2PMU;



typedef enum
{
    no_ack = 0,
    ack_f1 = 0xF1,
    ack_f2 = 0xF2,
    ack_f3 = 0xF3,
    ack_f4 = 0xF4,
    ack_f5 = 0xF5,
    ack_f6 = 0xF6,
    ack_f7 = 0xF7,
    ack_e1 = 0xE1,
    ack_e2 = 0xE2,
    ack_e3 = 0xE3,
    ack_e4 = 0xE4,
    ack_e5 = 0xE5,
    ack_e6 = 0xE6,
    ack_e7 = 0xE7,
} ACK_STATUS;

// struct FITTED_DATA
// {
// 	uint8_t Fitted_Count;
// 	uint32_t Real_Variation[4][8];
// 	float RealWeight[4][8];
// };

// extern struct FITTED_DATA fitted_data;

extern rkfifo_t can_tx_kfifo;
extern rkfifo_t can_rx_kfifo;

extern bool factory_calibration;
void Set_Ack_Status(ACK_STATUS status);

FORMAT_CAN2PMU *Get_Tx_Msg(void);

extern void MY_CAN_INIT();

void Write_To_Flash(uint32_t first_flash, uint32_t end_flash, uint8_t *data, uint8_t size);

void CAN_Init(uint32_t ExtId);

void CAN2PMU_Send(void);
extern void Can_Rx_Decode(void);

void Can_Ack_Pmu(void);

extern void can2Pmu_3hz_info();

void CAN_Tx_Empty_Callback(FDCAN_HandleTypeDef *hcan);
extern void Can_Txmsg_Target_Init(uint32_t can_id, uint8_t *data);
extern void Can_Txmsg_Init(void);
extern bool can_send(FDCAN_HandleTypeDef *hfdcan);