#include #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 "app/sox/iostate.h" #include "bsp/gpio.h" #include "bsp/ml5238.h" #include "app/nv_storage.h" #include "libs/logger.h" #include "bsp/uart.h" #include "protocol_old.h" #include "pcba_test.h" static uart_enum_t current_uart = SHARK_UART0; extern char* bsp_get_fversion(void); uint16_t _checksum(uint8_t *data, uint16_t size) { uint32_t checksum; if((NULL == data) || (0 == size)) { return 0; } checksum = 0; while(size>1) { checksum += *(uint16_t*)data; data += 2; size -= 2; } if(size>0) { checksum += *data; } while(checksum>>16) { checksum = (checksum&0xFFFF)+(checksum>>16); } return (uint16_t)~checksum; } static int get_response_data(uint8_t *data, uint8_t operate, uint8_t result){ comm_head_t *head = (comm_head_t *)data; head->size = sizeof(comm_head_t); head->type = bms_state_get()->bms_addr; head->dir = 0x16; head->bStatus = 1; head->cmd = 0x10; head->protocol = 'C'; head->checksum = 0; comm_response_t *response = (comm_response_t *)head->data; response->remain_miles= 0; //剩余里程 response->capacity = get_soc()->capacity; response->remain_charger_time= soc_get_charger_remain_time()/6; //10分之1小时单位 response->is_chargering = bms_state_get()->charging; response->load_current = measure_value()->load_current; response->pack_voltage = bms_state_get()->pack_voltage; response->max_temp = -100; for (int i = 0; i < PACK_TEMPS_NUM; i++){ if (response->max_temp < measure_value()->pack_temp[i]){ response->max_temp = measure_value()->pack_temp[i]; } } response->health_state = *((uint16_t *)bms_health()) | (bms_health()->sigle_cell_lower_voltage << 1); response->balance_mask = 0x0; response->misc_status = (ml5238_is_discharging() << 1) | (ml5238_is_charging() << 2); response->misc_status |= (AUX_VOL_IS_OPEN() << 3) |(io_state()->aux_lock_detect << 5); response->misc_status |= ((get_soc()->capacity==100) << 4) | (((get_soc()->flags & SOC_FLAG_CALIBRATED) == 0) << 6); response->misc_status |= io_state()->charger_detect_irq; response->result = (operate << 4) | result; head->size += sizeof(comm_response_t); if (operate == OP_READ_INFO){ uint8_t sn[32]; int sn_len = nv_read_sn(sn, sizeof(sn)); if (sn_len <= 0){ sn[0] = 'B'; memset(sn + 1, '0', sizeof(sn) - 1); sn_len = 18; } memcpy(&data[head->size], sn, sn_len); head->size += sn_len; strcpy((char *)&data[head->size], bsp_get_fversion()); head->size += strlen(bsp_get_fversion()); }else if (operate == OP_ALARM_TIMES){ memset(&data[head->size], 0, sizeof(times_response_t)); times_response_t *resp = (times_response_t *)&data[head->size]; resp->charger_cycle = soc_get_cycle(); head->size += sizeof(times_response_t); }else if (operate == OP_CELL_VOL){ data[head->size ++] = CELLS_NUM; for (int i = 0; i size ++] = (uint8_t)measure_value()->cell_vol[i]; data[head->size ++] = (uint8_t)(measure_value()->cell_vol[i] >> 8); } }else if (operate == OP_TEMP_OTHER){ for (int i = 0; i < PACK_TEMPS_NUM; i++){ data[head->size ++] = measure_value()->pack_temp[i]; } data[head->size ++] = (ml5238_is_charging() << 0) | (ml5238_is_discharging() << 1); } head->checksum = _checksum(data, head->size); return head->size; } static int protocol_old_process_binary(uart_enum_t uart_no, uint8_t *data, int len){ current_uart = uart_no; comm_head_t *head = (comm_head_t *)data; if (head->type != bms_state_get()->bms_addr || head->dir != 0x16 || head->bStatus == 1 || head->size < sizeof(comm_head_t)){ return -1; } uint16_t checksum = head->checksum; head->checksum = 0; if (checksum != _checksum(data, len)){ return -1; } data = head->data; data += 6; uint8_t operate = data[0]; uint8_t ps_charger = data[1]; bms_set_ps_charger_in(1, (ps_charger == CW_CHE_SHANG_CHARGER || ps_charger == CW_CHONG_DIAN_ZUO)); data += 1; uint8_t result = 1; if (operate == OP_OPEN_FET){ if (data[8] == 0x01) { bms_state_get()->user_request = USER_REQUEST_PENDING | USER_REQUEST_DISCHARGER_ON|USER_REQUEST_CHARGER_OFF; }else if (data[8] == 0x02) { bms_state_get()->user_request = USER_REQUEST_PENDING | USER_REQUEST_DISCHARGER_OFF|USER_REQUEST_CHARGER_ON; }else if (data[8] == 0x03) { bms_state_get()->user_request = USER_REQUEST_PENDING | USER_REQUEST_DISCHARGER_ON|USER_REQUEST_CHARGER_ON; }else if (data[8] == 0x0){ bms_state_get()->user_request = USER_REQUEST_PENDING | USER_REQUEST_SMALLCURRENT_OFF|USER_REQUEST_DISCHARGER_OFF|USER_REQUEST_CHARGER_OFF; }else if (data[8] == 0x04) { bms_state_get()->user_request = USER_REQUEST_PENDING | USER_REQUEST_SMALLCURRENT_ON; }else { result = 0; } }else if (operate == OP_WRITE_SN){ if (data[8] == 1) { result = nv_save_sn(&data[9], 18) <= 0?1:0; } } uint8_t response_data[256]; uint16_t response_len = get_response_data(response_data, operate, result); if (response_len <= 0){ return -1; } set_log_all(L_disable); shark_uart_write_bytes(current_uart, response_data, response_len); return 0; } void protocol_old_recv_frame(uart_enum_t uart_no, uint8_t *data, int len){ if (protocol_old_process_binary(uart_no, data, len) == 0){ return; } if (memcmp(data, "mode", 4) == 0){ set_log_all(L_disable); if (memcmp(data + 4, "laohua", 6) == 0){ bms_work_mode_set(WORK_MODE_AGING_TEST, 1); bms_state_get()->user_request = USER_REQUEST_PENDING | USER_REQUEST_SMALLCURRENT_OFF | USER_REQUEST_DISCHARGER_ON|USER_REQUEST_CHARGER_ON; printf("laohua OK!\n"); }else if (memcmp(data + 4, "tuichu", 6) == 0){ if (bms_work_is_aging_test()){ bms_work_mode_set(WORK_MODE_AGING_TEST, 0); bms_state_get()->user_request = USER_REQUEST_PENDING | USER_REQUEST_SMALLCURRENT_ON | USER_REQUEST_DISCHARGER_OFF | USER_REQUEST_CHARGER_OFF; printf("tuichu OK!\n"); } }else if (memcmp(data + 4, "ceshi", 5) == 0) { bms_work_mode_set(WORK_MODE_PCBA_TEST, 1); printf("pcba ceshi OK!\n"); } }else if (bms_work_is_pcba_test() && data[0] == 0xFE && data[1] == 0xFE){ uint8_t response[16]; int resp_len = pcba_test(data, len, response); if (resp_len > 0) { shark_uart_write_bytes(current_uart, response, resp_len); } } }