#ifndef  _CAN_USE_H
#define _CAN_USE_H

#include <cmsis_os2.h>
#include "bsp_can.h"

typedef enum {
  CAN_CHASSIS_M3508_M1_ID = 0x201, /* 1 */
  CAN_CHASSIS_M3508_M2_ID = 0x202, /* 2 */
  CAN_CHASSIS_M3508_M3_ID = 0x203, /* 3 */
  CAN_CHASSIS_M3508_M4_ID = 0x204, /* 4 */
		
	CAN_UP_M3508_M1_ID = 0x201, /* 1 */
  CAN_UP_M3508_M2_ID = 0x202, /* 2 */
  CAN_UP_M3508_M3_ID = 0x203, /* 3 */
  CAN_UP_M3508_M4_ID = 0x204, /* 4 */

  CAN_UP_M3508_M5_ID = 0x205, /* 1 */
  CAN_UP_M3508_M6_ID = 0x206, /* 2 */
	
	CAN_SICK_ID_1=0x301,
	CAN_SICK_ID_2=0x302,
	CAN_SICK_ID_3=0x303,
	CAN_SICK_ID_4=0x304,

	
	CAN_Encoder_ID=0x01,
	
  CAN_VESC5065_M1_MSG1 =0x90b,           //vesc的数据回传使用了扩展id，[0:7]为驱动器id，[8:15]为帧类型
	CAN_VESC5065_M2_MSG1 =0x90c,
	CAN_VESC5065_M3_MSG1 =0x90d,
	CAN_VSEC5065_M4_MSG1 =0x90e,

  CAN_VESC5065_M1_MSG4 =0x1011,
	CAN_VESC5065_M2_MSG4 =0x1012,
	CAN_VESC5065_M3_MSG4 =0x1013,
	CAN_VSEC5065_M4_MSG4 =0x1014,
	
} CAN_MotorId_t;


typedef enum {
  CAN_MOTOR_5065,
	CAN_MOTOR_CHASSIS3508,
	
	CAN_MOTOR_UP3508_SHOOT,
	CAN_MOTOR_UP3508_Dribble,

  CAN_MOTOR_GROUT_NUM,
} CAN_MotorGroup_e;

typedef union {
  float as_array[4];
  struct {
    float m1;
    float m2;
    float m3;
    float m4;
  } named;
} CAN_DJIOutput_t;


typedef union {
  int erpm[4];
  struct {
    int m1;
    int m2;
    int m3;
    int m4;
  } named;
} CAN_VescOutput_t;

typedef union{
		int as_array;
		struct{
		int8_t byte1;
		int8_t byte2;
		int8_t byte3;
		int8_t byte4;
		}byte;
}Vesc_ByteGet;

typedef struct {
  CAN_VescOutput_t chassis5065;
	CAN_DJIOutput_t motor_CHASSIS3508;
	CAN_DJIOutput_t motor_UP3508_shoot;
	CAN_DJIOutput_t motor_UP3508_Dribble;

} CAN_Output_t;


typedef struct {
  CAN_RxHeaderTypeDef rx_header;
  uint8_t rx_data[8];
  CAN_HandleTypeDef *hcan;
	
} CAN_RawRx_t;

typedef struct {
  CAN_TxHeaderTypeDef tx_header;
  uint8_t tx_data[8];
} CAN_RawTx_t;

typedef struct {
  BSP_CAN_t chassis5065;
	BSP_CAN_t motor_CHASSIS3508;
	BSP_CAN_t motor_UP3508_shoot;
	BSP_CAN_t motor_UP3508_Dribble;
	
	
	BSP_CAN_t sick;
	BSP_CAN_t encoder;

} CAN_Params_t;


/* 电机反馈信息 */
typedef struct {
  float rotor_ecd;
  float rotor_speed;
  float torque_current;
  float temp;
} CAN_MotorFeedback_t;

/* sick反馈信息 */
typedef struct {
	 uint16_t raw_dis[4];

}CAN_SickFeedback_t;
/* encoder编码器反馈信息 */
typedef struct {
	 
	uint32_t ecd;
	float angle;
	
}CAN_EncoderFeedback_t;

typedef union {
  CAN_MotorFeedback_t as_array[4];
  struct {
    CAN_MotorFeedback_t m1;
    CAN_MotorFeedback_t m2;
    CAN_MotorFeedback_t m3;
    CAN_MotorFeedback_t m4;
  } named;
} CAN_Data_Motor_t;

typedef union {
  CAN_MotorFeedback_t as_array[4];
  struct {
    CAN_MotorFeedback_t m1;
    CAN_MotorFeedback_t m2;
    CAN_MotorFeedback_t m3;
    CAN_MotorFeedback_t m4;
  } named;
} CAN_VescMotor_t;


typedef struct {
  CAN_Data_Motor_t chassis6020;
  CAN_Data_Motor_t chassis5065;
	/*1是指用来运球的，2用来扳机和俯仰*/
	CAN_Data_Motor_t up_shoot_motor3508;
	CAN_Data_Motor_t up_dribble_motor3508;
	
	CAN_Data_Motor_t chassis_motor3508;
	CAN_Data_Motor_t pit6020;

} CAN_Motor_t;

typedef struct {
  uint32_t recive_flag;

  CAN_Motor_t motor;
	CAN_EncoderFeedback_t Oid;
	CAN_SickFeedback_t sickfed;
  const CAN_Params_t *param;
  struct {
    uint32_t chassis;
    uint32_t up;	
  } mailbox;
  osMessageQueueId_t msgq_raw;
	
} CAN_t;

int8_t CAN_Init(CAN_t *can,const CAN_Params_t *param);

int8_t CAN_StoreMsg(CAN_t *can,CAN_RawRx_t *can_rx);

bool_t CAN_CheckFlag(CAN_t *can,uint32_t flag);

int8_t CAN_ClearFlag(CAN_t *can,uint32_t flag);

int8_t CAN_DJIMotor_Control(CAN_MotorGroup_e group,CAN_Output_t *output,CAN_t *can);

int8_t CAN_VESC_Control(int id,CAN_MotorGroup_e group, CAN_Output_t *output,CAN_t *can);

void CAN_Encoder_Control(CAN_t *can);

void CAN_Encoder_Decode(CAN_EncoderFeedback_t *feedback,
                             const uint8_t *raw) ;
static void CAN_Sick_Receive(CAN_SickFeedback_t *feedback,int id,
	                            const uint8_t *raw) ;
#endif
