#include "app/sox/soc.h" #include "app/sox/measure.h" #include "app/sox/measure_task.h" #include "app/sox/health.h" #include "app/sox/state.h" #include "bsp/gpio.h" #include "bsp/ml5238.h" #include "libs/logger.h" #include "protocol.h" #include "bms_message.h" static uint8_t bms_insert = 0; static uint8_t bms_insert_ack = 0; //主要用来告知PSxxx是否刚插入,PSxxx答复后需要清除 void bms_message_update_insert(int is_hall_detect){ if (!is_hall_detect){ bms_insert = 0; bms_insert_ack = 0; }else { if (!bms_insert_ack) { bms_insert = 1; } } } void process_bms_message(can_frame_t *frame, int len){ int result = 0; uint8_t *data = NULL; int data_len = 0; switch(frame->key) { case CAN_KEY_BMS_SET_POWER: if (len != sizeof(pwr_cmd_t)){ result = 1; }else { pwr_cmd_t *cmd = (pwr_cmd_t *)frame->data; uint32_t user_request = USER_REQUEST_PENDING; if (cmd->charger_fet){ user_request |= USER_REQUEST_CHARGER; } if (cmd->discharger_fet){ user_request |= USER_REQUEST_DISCHARGER; } if (cmd->small_power){ user_request |= USER_REQUEST_SMALLCURRENT; } bms_state_get()->user_request = user_request; } protocol_send_ack(frame->head.can_addr, frame->key, result); break; case CAN_KEY_BMS_BASE_INFO:{ binfo_cmd_resp_t bresp; bresp.capacity = get_soc()->capacity; bresp.energy = get_soc()->energy; bresp.pack_current = measure_value()->load_current; bresp.pack_voltage = bms_state_get()->pack_voltage; bresp.max_temp = 0; for (int i = 0; i < PACK_TEMPS_NUM; i ++){ if (bresp.max_temp < measure_value()->pack_temp[i]){ bresp.max_temp = measure_value()->pack_temp[i]; } } data = (uint8_t *)&bresp; data_len = sizeof(bresp); break; } case CAN_KEY_BMS_CHARG_INFO:{ cinfo_cmd_resp_t cresp; cresp.charge_current = measure_value()->load_current; cresp.charge_remain_time = 0; data = (uint8_t *)&cresp; data_len = sizeof(cresp); break; } case CAN_KEY_BMS_CLEAR: bms_insert_ack = 1; bms_insert = 0; protocol_send_ack(frame->head.can_addr, frame->key, result); break; case CAN_KEY_BMS_GET_TIME:{ uint32_t time = shark_get_seconds(); data = (uint8_t *)&time; data_len = sizeof(time); break; } case CAN_KEY_BMS_GET_STAT: { stat_cmd_resp_t sresp; sresp.insert = bms_insert; sresp.is_charging = bms_state_get()->charging; sresp.discharger_fet = ml5238_is_discharging(); sresp.charger_fet = ml5238_is_charging(); sresp.small_power = AUX_VOL_IS_OPEN(); sresp.is_balancing = bms_state_get()->pack_balancing; uint32_t *h = (uint32_t *)(bms_health()); sresp.health = (*h != 0); data = (uint8_t *)&sresp; data_len = sizeof(sresp); break; } case CAN_KEY_BMS_TEMPS: data = (uint8_t *)measure_value()->pack_temp; data_len = sizeof(measure_value()->pack_temp); break; case CAN_KEY_BMS_GET_CELLS: data = (uint8_t *)measure_value()->cell_vol; data_len = sizeof(measure_value()->cell_vol); break; case CAN_KEY_BMS_GET_HEALTH_STAT: data = (uint8_t *)bms_health(); data_len = sizeof(*bms_health()); case CAN_KEY_SET_SN: protocol_send_ack(frame->head.can_addr, frame->key, result); break; case CAN_KEY_GET_SN: break; case CAN_KEY_GET_VERSION: break; case CAN_KEY_SET_LOGGER: if (len != 2) { result = 1; }else { set_log_level(frame->data[0], frame->data[1]); } protocol_send_ack(frame->head.can_addr, frame->key, result); break; } if (data != NULL && data_len > 0){ protocol_send_bms_info(frame->head.can_addr, frame->key, data, data_len); } }