/* * @Author: shenghao.xu * @Date: 2023-04-06 09:33:45 * @LastEditors: shenghao.xu * @LastEditTime: 2023-06-19 23:46:16 * @Description: * email:545403892@qq.com * Copyright (c) 2023 by shenghao.xu, All Rights Reserved. */ #include "agreement_slave.h" // 查询IP输入电流 static bool command_req_query_ip_input_current(const command_req_t *const data, command_resp_t *resp) { slave_request_done_t rsp; uint8_t offset = 0; resp->pbuf = pbuf_allocz(SMALL_PBUF_BUFFER_SIZE __PLINE1); if (!DBG_ASSERT(resp->pbuf != NULL __DBG_LINE)) return false; if (handle.slave_request_done_call != NULL) { rsp = handle.slave_request_done_call((command_e)data->command, NULL); rsp.data.current.c = S2B_UINT32(rsp.data.current.c); rsp.default_value.c = S2B_UINT32(rsp.default_value.c); osel_memcpy(resp->pbuf->data_p, (uint8_t *)&rsp.default_value.c, sizeof(uint32_t)); offset += sizeof(uint32_t); osel_memcpy(resp->pbuf->data_p + offset, (uint8_t *)&rsp.data.current.c, sizeof(uint32_t)); offset += sizeof(uint32_t); resp->pbuf->data_len = offset; } return true; } // 调节IP输入电流 static bool command_req_adjust_ip_input_current(const command_req_t *const data, command_resp_t *resp) { slave_request_done_t rsp; uint8_t offset = 0; resp->pbuf = pbuf_allocz(SMALL_PBUF_BUFFER_SIZE __PLINE1); if (!DBG_ASSERT(resp->pbuf != NULL __DBG_LINE)) return false; if (handle.slave_request_done_call != NULL) { float32_t f; osel_memcpy((uint8_t *)&f, (uint8_t *)&data->data.adjust_ip_input_current.value, sizeof(float32_t)); f.c = B2S_UINT32(f.c); rsp = handle.slave_request_done_call((command_e)data->command, &f); rsp.data.current.c = S2B_UINT32(rsp.data.current.c); osel_memcpy(resp->pbuf->data_p, (uint8_t *)&rsp.data.current.f, sizeof(float32)); offset += sizeof(float32); resp->pbuf->data_len = offset; } return true; } // 查询状态 static bool command_req_query_state(const command_req_t *const data, command_resp_t *resp) { slave_request_done_t rsp; uint8_t offset = 0; resp->pbuf = pbuf_allocz(SMALL_PBUF_BUFFER_SIZE __PLINE1); if (!DBG_ASSERT(resp->pbuf != NULL __DBG_LINE)) return false; if (handle.slave_request_done_call != NULL) { rsp = handle.slave_request_done_call((command_e)data->command, NULL); osel_memcpy(resp->pbuf->data_p, (uint8_t *)&rsp.data.query_state, sizeof(slave_req_query_state_t)); offset += sizeof(slave_req_query_state_t); resp->pbuf->data_len = offset; } return true; } // 查询流程 static bool command_req_query_process(const command_req_t *const data, command_resp_t *resp) { slave_request_done_t rsp; uint8_t sum; uint16_t crc; uint16_t offset = 0; resp->pbuf = pbuf_allocz(LARGE_PBUF_BUFFER_SIZE __PLINE1); if (!DBG_ASSERT(resp->pbuf != NULL __DBG_LINE)) return false; if (handle.slave_request_done_call != NULL) { rsp = handle.slave_request_done_call((command_e)data->command, NULL); config_convert_pbuf(rsp.data.config, &resp->pbuf); offset = resp->pbuf->data_len; // 填充异或校验 sum = xor_compute(resp->pbuf->data_p, offset); crc = crc16_compute(resp->pbuf->data_p, offset); resp->pbuf->data_p[offset] = sum; offset++; crc = S2B_UINT16(crc); osel_memcpy(&resp->pbuf->data_p[offset], (uint8_t *)&crc, sizeof(uint16_t)); offset += sizeof(uint16_t); resp->pbuf->data_len = offset; } return true; } // 配置流程 static bool command_req_config_process(const command_req_t *const data, command_resp_t *resp) { slave_request_done_t rsp; uint8_t sum; uint16_t crc; uint16_t offset = 0; resp->pbuf = pbuf_allocz(LARGE_PBUF_BUFFER_SIZE __PLINE1); if (!DBG_ASSERT(resp->pbuf != NULL __DBG_LINE)) return false; if (handle.slave_request_done_call != NULL) { rsp = handle.slave_request_done_call((command_e)data->command, data->data.config); config_convert_pbuf(rsp.data.config, &resp->pbuf); offset = resp->pbuf->data_len; // 填充异或校验 sum = xor_compute(resp->pbuf->data_p, offset); crc = crc16_compute(resp->pbuf->data_p, offset); resp->pbuf->data_p[offset] = sum; offset++; crc = S2B_UINT16(crc); osel_memcpy(&resp->pbuf->data_p[offset], (uint8_t *)&crc, sizeof(uint16_t)); offset += sizeof(uint16_t); resp->pbuf->data_len = offset; } return true; } // 执行流程 static bool command_req_execute_process(const command_req_t *const data, command_resp_t *resp) { slave_request_done_t rsp; uint8_t offset = 0; resp->pbuf = pbuf_allocz(SMALL_PBUF_BUFFER_SIZE __PLINE1); if (!DBG_ASSERT(resp->pbuf != NULL __DBG_LINE)) return false; if (handle.slave_request_done_call != NULL) { osel_memcpy((uint8_t *)&g_execute_process, (uint8_t *)&data->data.execute_process, sizeof(execute_process_t)); rsp = handle.slave_request_done_call((command_e)data->command, &g_execute_process); osel_memcpy(resp->pbuf->data_p, (uint8_t *)&rsp.data.query_state, sizeof(execute_process_t)); offset += sizeof(execute_process_t); resp->pbuf->data_len = offset; } return true; } // 停止流程 static bool command_req_stop_process(const command_req_t *const data, command_resp_t *resp) { // slave_request_done_t rsp; resp->pbuf = pbuf_allocz(SMALL_PBUF_BUFFER_SIZE __PLINE1); if (!DBG_ASSERT(resp->pbuf != NULL __DBG_LINE)) return false; if (handle.slave_request_done_call != NULL) { handle.slave_request_done_call((command_e)data->command, NULL); } return true; } // 查询数据 static bool command_req_query_data(const command_req_t *const data, command_resp_t *resp) { slave_request_done_t rsp; resp->pbuf = pbuf_allocz(LARGE_PBUF_BUFFER_SIZE __PLINE1); if (!DBG_ASSERT(resp->pbuf != NULL __DBG_LINE)) return false; if (handle.slave_request_done_call != NULL) { query_data_t d; osel_memcpy((uint8_t *)&d, (uint8_t *)&data->data.query_data, sizeof(query_data_t)); if (d.count > 0) { rsp = handle.slave_request_done_call((command_e)data->command, &d); query_data_convert_pbuf(rsp.data.query_data_rsp, d.count, &resp->pbuf); } } return true; } // 配置地址 static bool command_req_config_address(const command_req_t *const data, command_resp_t *resp) { slave_request_done_t rsp; uint8_t offset = 0; resp->pbuf = pbuf_allocz(SMALL_PBUF_BUFFER_SIZE __PLINE1); if (!DBG_ASSERT(resp->pbuf != NULL __DBG_LINE)) return false; if (handle.slave_request_done_call != NULL) { config_address_t d; osel_memcpy((uint8_t *)&d, (uint8_t *)&data->data.config_address, sizeof(config_address_t)); rsp = handle.slave_request_done_call((command_e)data->command, &d); osel_memcpy(resp->pbuf->data_p, (uint8_t *)&rsp.data.config_address, sizeof(config_address_t)); offset += sizeof(config_address_t); resp->pbuf->data_len = offset; } return true; } // 查询地址 static bool command_req_query_address(const command_req_t *const data, command_resp_t *resp) { slave_request_done_t rsp; uint8_t offset = 0; resp->pbuf = pbuf_allocz(SMALL_PBUF_BUFFER_SIZE __PLINE1); if (!DBG_ASSERT(resp->pbuf != NULL __DBG_LINE)) return false; if (handle.slave_request_done_call != NULL) { rsp = handle.slave_request_done_call((command_e)data->command, NULL); osel_memcpy(resp->pbuf->data_p, (uint8_t *)&rsp.data.query_address, sizeof(query_address_t)); offset += sizeof(query_address_t); resp->pbuf->data_len = offset; } return true; } // 标定传感器 static bool command_req_calibration_sensor(const command_req_t *const data, command_resp_t *resp) { slave_request_done_t rsp; resp->pbuf = pbuf_allocz(MEDIUM_PBUF_BUFFER_SIZE __PLINE1); if (!DBG_ASSERT(resp->pbuf != NULL __DBG_LINE)) return false; if (handle.slave_request_done_call != NULL) { calibration_sensor_t d; osel_memcpy((uint8_t *)&d, (uint8_t *)&data->data.calibration_sensor, sizeof(calibration_sensor_t)); rsp = handle.slave_request_done_call((command_e)data->command, &d); calibration_sensor_convert_pbuf(rsp.data.calibration_sensor, &resp->pbuf); } return true; } // 设置阀门状态 static bool command_req_set_valve(const command_req_t *const data, command_resp_t *resp) { slave_request_done_t rsp; uint8_t offset = 0; resp->pbuf = pbuf_allocz(SMALL_PBUF_BUFFER_SIZE __PLINE1); if (!DBG_ASSERT(resp->pbuf != NULL __DBG_LINE)) return false; if (handle.slave_request_done_call != NULL) { set_valve_t d; osel_memcpy((uint8_t *)&d, (uint8_t *)&data->data.set_valve, sizeof(set_valve_t)); rsp = handle.slave_request_done_call((command_e)data->command, &d); osel_memcpy(resp->pbuf->data_p, (uint8_t *)&rsp.data.set_valve, sizeof(set_valve_t)); offset += sizeof(set_valve_t); resp->pbuf->data_len = offset; } return true; } // 查询比例阀 static bool command_req_query_valve(const command_req_t *const data, command_resp_t *resp) { slave_request_done_t rsp; uint8_t offset = 0; resp->pbuf = pbuf_allocz(SMALL_PBUF_BUFFER_SIZE __PLINE1); if (!DBG_ASSERT(resp->pbuf != NULL __DBG_LINE)) return false; if (handle.slave_request_done_call != NULL) { rsp = handle.slave_request_done_call((command_e)data->command, NULL); rsp.data.valve_ratio.value.c = S2B_UINT32(rsp.data.valve_ratio.value.c); rsp.default_value.c = S2B_UINT32(rsp.default_value.c); osel_memcpy(resp->pbuf->data_p, (uint8_t *)&rsp.default_value.c, sizeof(uint32_t)); offset += sizeof(uint32_t); osel_memcpy(resp->pbuf->data_p + offset, (uint8_t *)&rsp.data.valve_ratio, sizeof(set_valve_ratio_t)); offset += sizeof(set_valve_ratio_t); resp->pbuf->data_len = offset; } return true; } // 设置比例阀 static bool command_req_set_valve_ratio(const command_req_t *const data, command_resp_t *resp) { slave_request_done_t rsp; uint8_t offset = 0; resp->pbuf = pbuf_allocz(SMALL_PBUF_BUFFER_SIZE __PLINE1); if (!DBG_ASSERT(resp->pbuf != NULL __DBG_LINE)) return false; if (handle.slave_request_done_call != NULL) { set_valve_ratio_t d; osel_memcpy((uint8_t *)&d, (uint8_t *)&data->data.valve_ratio, sizeof(set_valve_ratio_t)); d.value.c = B2S_UINT32(d.value.c); rsp = handle.slave_request_done_call((command_e)data->command, &d); rsp.data.valve_ratio.value.c = S2B_UINT32(rsp.data.valve_ratio.value.c); osel_memcpy(resp->pbuf->data_p, (uint8_t *)&rsp.data.valve_ratio, sizeof(set_valve_ratio_t)); offset += sizeof(set_valve_ratio_t); resp->pbuf->data_len = offset; } return true; } static bool command_req_set_stepper_motor(const command_req_t *const data, command_resp_t *resp) { slave_request_done_t rsp; uint8_t offset = 0; stepper_motor_t d; float32_t f; resp->pbuf = pbuf_allocz(SMALL_PBUF_BUFFER_SIZE __PLINE1); if (!DBG_ASSERT(resp->pbuf != NULL __DBG_LINE)) return false; if (handle.slave_request_done_call != NULL) { osel_memcpy((uint8_t *)&d, (uint8_t *)&data->data.stepper_motor, sizeof(stepper_motor_t)); d.angle = B2S_UINT32(d.angle); d.dir = data->data.stepper_motor.dir; f.f = data->data.stepper_motor.angle; f.c = B2S_UINT32(f.c); d.angle = f.f; rsp = handle.slave_request_done_call((command_e)data->command, &d); f.f = rsp.data.stepper_motor.angle; f.c = S2B_UINT32(f.c); rsp.data.stepper_motor.angle = f.f; osel_memcpy(resp->pbuf->data_p, (uint8_t *)&rsp.data.stepper_motor, sizeof(stepper_motor_t)); offset += sizeof(stepper_motor_t); resp->pbuf->data_len = offset; } return true; } // 查询I/P 输入PWM占空比 static bool command_req_query_ip_pwm_duty(const command_req_t *const data, command_resp_t *resp) { slave_request_done_t rsp; uint8_t offset = 0; resp->pbuf = pbuf_allocz(SMALL_PBUF_BUFFER_SIZE __PLINE1); if (!DBG_ASSERT(resp->pbuf != NULL __DBG_LINE)) return false; if (handle.slave_request_done_call != NULL) { rsp = handle.slave_request_done_call((command_e)data->command, NULL); osel_memcpy(resp->pbuf->data_p, (uint8_t *)&rsp.data.query_ip_pwm_duty, sizeof(query_ip_pwm_duty_t)); offset += sizeof(query_ip_pwm_duty_t); resp->pbuf->data_len = offset; } return true; } // 调节I/P 输入PWM占空比 static bool command_req_set_ip_pwm_duty(const command_req_t *const data, command_resp_t *resp) { uint8_t offset = 0; float32_t f; resp->pbuf = pbuf_allocz(SMALL_PBUF_BUFFER_SIZE __PLINE1); if (!DBG_ASSERT(resp->pbuf != NULL __DBG_LINE)) return false; if (handle.slave_request_done_call != NULL) { adjust_ip_pwm_duty_t d; osel_memcpy((uint8_t *)&d, (uint8_t *)&data->data.adjust_ip_input_current, sizeof(adjust_ip_pwm_duty_t)); f.f = d.percent; f.c = B2S_UINT32(f.c); d.percent = f.f; handle.slave_request_done_call((command_e)data->command, &d); osel_memcpy(resp->pbuf->data_p, (uint8_t *)&data->data.adjust_ip_input_current, sizeof(adjust_ip_pwm_duty_t)); offset += sizeof(adjust_ip_pwm_duty_t); resp->pbuf->data_len = offset; } return true; } // 设置I/P 模式 static bool command_req_set_ip_mode(const command_req_t *const data, command_resp_t *resp) { slave_request_done_t rsp; uint8_t offset = 0; resp->pbuf = pbuf_allocz(SMALL_PBUF_BUFFER_SIZE __PLINE1); if (!DBG_ASSERT(resp->pbuf != NULL __DBG_LINE)) return false; if (handle.slave_request_done_call != NULL) { set_ip_mode_t d; osel_memcpy((uint8_t *)&d, (uint8_t *)&data->data.set_ip_mode, sizeof(set_ip_mode_t)); rsp = handle.slave_request_done_call((command_e)data->command, &d); osel_memcpy(resp->pbuf->data_p, (uint8_t *)&rsp.data.set_ip_mode, sizeof(set_ip_mode_t)); offset += 2 + rsp.data.set_ip_mode.data_length; resp->pbuf->data_len = offset; } return true; } // 查询I/P 模式 static bool command_req_query_ip_mode(const command_req_t *const data, command_resp_t *resp) { slave_request_done_t rsp; uint8_t offset = 0; resp->pbuf = pbuf_allocz(SMALL_PBUF_BUFFER_SIZE __PLINE1); if (!DBG_ASSERT(resp->pbuf != NULL __DBG_LINE)) return false; if (handle.slave_request_done_call != NULL) { rsp = handle.slave_request_done_call((command_e)data->command, NULL); osel_memcpy(resp->pbuf->data_p, (uint8_t *)&rsp.data.query_ip_mode, sizeof(query_ip_mode_t)); offset += 2 + rsp.data.set_ip_mode.data_length; resp->pbuf->data_len = offset; } return true; } // 复位设备 static bool command_req_reset_device(const command_req_t *const data, command_resp_t *resp) { // slave_request_done_t rsp; resp->pbuf = pbuf_allocz(SMALL_PBUF_BUFFER_SIZE __PLINE1); if (!DBG_ASSERT(resp->pbuf != NULL __DBG_LINE)) return false; if (handle.slave_request_done_call != NULL) { handle.slave_request_done_call((command_e)data->command, NULL); } return true; } bool agreement_slave_init(void) { command_req_ptr_arr[COMMAND_RESET_DEVICE] = command_req_reset_device; command_req_ptr_arr[COMMAND_QUERY_IP_INPUT_CURRENT] = command_req_query_ip_input_current; command_req_ptr_arr[COMMAND_ADJUST_IP_INPUT_CURRENT] = command_req_adjust_ip_input_current; command_req_ptr_arr[COMMAND_QUERY_STATE] = command_req_query_state; command_req_ptr_arr[COMMAND_QUERY_PROCESS] = command_req_query_process; command_req_ptr_arr[COMMAND_CONFIG_PROCESS] = command_req_config_process; command_req_ptr_arr[COMMAND_EXECUTE_PROCESS] = command_req_execute_process; command_req_ptr_arr[COMMAND_STOP_PROCESS] = command_req_stop_process; command_req_ptr_arr[COMMAND_QUERY_DATA] = command_req_query_data; command_req_ptr_arr[COMMAND_CONFIG_ADDRESS] = command_req_config_address; command_req_ptr_arr[COMMAND_QUERY_ADDRESS] = command_req_query_address; command_req_ptr_arr[COMMAND_CALIBRATE_SENSOR] = command_req_calibration_sensor; command_req_ptr_arr[COMMAND_SET_VALVE] = command_req_set_valve; command_req_ptr_arr[COMMAND_QUERY_VALVE] = command_req_query_valve; command_req_ptr_arr[COMMAND_SET_VALVE_RATIO] = command_req_set_valve_ratio; command_req_ptr_arr[COMMAND_SET_STEPPER_MOTOR] = command_req_set_stepper_motor; command_req_ptr_arr[COMMAND_QUERY_IP_INPUT_PWM_DUTY] = command_req_query_ip_pwm_duty; command_req_ptr_arr[COMMAND_ADJUST_IP_INPUT_PWM_DUTY] = command_req_set_ip_pwm_duty; command_req_ptr_arr[COMMAND_SET_IP_MODE] = command_req_set_ip_mode; command_req_ptr_arr[COMMAND_QUERY_IP_MODE] = command_req_query_ip_mode; return true; } void agreement_slave_req(uint8_t *data, uint16_t len) { agreement_response_fill_t rsp; command_resp_t resp; command_req_t req; pbuf_t *pbuf; uint16_t offset = 0, surplus = 0; // LOG_HEX(data, len); osel_memset((uint8_t *)&req, 0, sizeof(command_req_t)); osel_memset((uint8_t *)&resp, 0, sizeof(command_resp_t)); osel_memcpy((uint8_t *)&req.src, data, sizeof(uint16_t)); offset += sizeof(uint16_t); osel_memcpy((uint8_t *)&req.dst, data + offset, sizeof(uint16_t)); offset += sizeof(uint16_t); req.src = S2B_UINT16(req.src); req.dst = S2B_UINT16(req.dst); // TODO 判断目标地址是否是自己 req.command = data[offset++]; if (!DBG_ASSERT(handle.response_call != NULL __DBG_LINE)) return; if (!DBG_ASSERT(req.command < COMMAND_MAX __DBG_LINE)) return; if (command_req_ptr_arr[req.command] == NULL) { return; } surplus = len - offset; if (surplus > 0) { if (req.command == COMMAND_CONFIG_PROCESS) { // 配置流程指令,数据结构中有指针,需要单独处理 req.data.config = data_convert_config(data + offset, surplus); // req.data.config 中的指针是全局变量,不需要释放 } else if (req.command == COMMAND_CALIBRATE_SENSOR) { // 标定传感器指令,数据结构中有指针,需要单独处理 calibration_sensor_t *calibration_sensor = NULL; calibration_sensor = data_convert_calibration_sensor(data + offset, surplus); if (!DBG_ASSERT(calibration_sensor != NULL __DBG_LINE)) { return; } else { // req.data.calibration_sensor 中的指针是全局变量,不需要释放 req.data.calibration_sensor.state = calibration_sensor->state; req.data.calibration_sensor.sensor_data.count = calibration_sensor->sensor_data.count; req.data.calibration_sensor.sensor_data.sensors = calibration_sensor->sensor_data.sensors; } } else if (req.command == COMMAND_QUERY_DATA) { // 查询数据指令,数据结构中有指针,需要单独处理 query_data_t *query_data = NULL; query_data = data_convert_query_data(data + offset, surplus); if (!DBG_ASSERT(query_data != NULL __DBG_LINE)) { return; } else { // req.data.query_data 中的指针是全局变量,不需要释放 req.data.query_data.count = query_data->count; req.data.query_data.sensors = query_data->sensors; } } else { osel_memcpy((uint8_t *)&req.data, data + offset, surplus); } } if (!command_req_ptr_arr[req.command](&req, &resp)) { return; } rsp.dst = S2B_UINT16(req.src); rsp.src = S2B_UINT16(req.dst); rsp.command = req.command + 0x80; rsp.data = resp.pbuf->data_p; rsp.data_len = resp.pbuf->data_len; pbuf = agreement_response_fill(&rsp); pbuf_freez(&resp.pbuf __PLINE2); handle.response_call(pbuf->data_p, pbuf->data_len); pbuf_freez(&pbuf __PLINE2); LOG_PRINT("mem used:%d%%\r\n", my_mem_perused(0)); return; } bool mock_config_query_data(void) { g_config = mock_commond_req_config(); return true; }