package m9z import ( "encoding/binary" "fmt" "github.com/gogf/gf/v2/errors/gerror" "tgk-touch/internal/global" ) // 定义任务指令结构 type TaskInstruction struct { Type uint32 `json:"type"` // 指令类型 (ISA_CMP, ISA_GOTO, etc.) Param uint32 `json:"param"` Value uint32 `json:"value"` // 指令参数 } // 定义任务结构 type TaskProgram struct { Index uint8 `json:"index"` // 任务索引 (0~2) Size uint8 `json:"size"` // 指令数量 Instructions []TaskInstruction `json:"instructions"` // 指令列表 } // StartTaskRead 读取开始任务 (优化指令 CMD=0x13) func StartTaskRead(deviceId string, idx uint8) (*TaskProgram, error) { return taskRead(deviceId, startTask, idx, "读取开始任务") } // MiddleTaskRead 读取中间任务 (优化指令 CMD=0x14) func MiddleTaskRead(deviceId string, idx uint8) (*TaskProgram, error) { // 实现与StartTaskRead相同,仅CMD不同 return taskRead(deviceId, middleTask, idx, "读取中间任务") } // StopTaskRead 读取结束任务 (优化指令 CMD=0x15) func StopTaskRead(deviceId string, idx uint8) (*TaskProgram, error) { // 实现与StartTaskRead相同,仅CMD不同 return taskRead(deviceId, stopTask, idx, "读取结束任务") } // 通用任务读取函数 func taskRead(deviceId string, cmd M9zCtrl, idx uint8, detail string) (*TaskProgram, error) { readResp, err := ReadCmd(deviceId, cmd, detail, uint(idx)) if err != nil { return nil, err } data := readResp.Data // 解析逻辑与StartTaskRead相同 if idx < 0 || idx > 2 { idx = 0 } task := &TaskProgram{Index: idx} if len(data) < 1 { return nil, fmt.Errorf("invalid task data length") } task.Size = data[0] task.Instructions = make([]TaskInstruction, 0, task.Size) for i := 1; i+3 < len(data) && len(task.Instructions) < int(task.Size); i += 4 { instruction := binary.LittleEndian.Uint32(data[i : i+4]) g.Log().Debugf("% X", instruction) insType := uint32(instruction >> 28) ins := TaskInstruction{Type: insType} // 根据指令类型解析参数 switch insType { case 0x01: // ISA_CMP // 参数: 源类型 + 比较值 ins.Param = (instruction >> 24) & 0x0F ins.Value = instruction & 0x0000FFFF case 0x02: // ISA_GOTO // 参数: 跳转类型 + 跳转地址 + 最大次数 + 索引值 ins.Param = (instruction >> 24) & 0x0F ins.Value = ((instruction >> 16) & 0xFF) | ((instruction >> 8) & 0xFF) | (instruction & 0xFF) case 0x03: // ISA_DLY // 参数: 延迟单位 + 延迟值 ins.Param = (instruction >> 24) & 0x0F ins.Value = instruction & 0x00FFFFFF case 0x04: // ISA_OUTPUT // 参数: 输出类型 + 输出值 ins.Param = (instruction >> 24) & 0x0F ins.Value = instruction & 0x00FFFFFF // 输出值 default: // 未知指令类型 ins.Param = instruction } task.Instructions = append(task.Instructions, ins) } return task, nil } // StartTaskWrite 写入开始任务 (优化指令 CMD=0x13) func StartTaskWrite(deviceId string, task *TaskProgram) error { return taskWrite(deviceId, startTask, task, "写入开始任务") } // MiddleTaskWrite 写入中间任务 (优化指令 CMD=0x14) func MiddleTaskWrite(deviceId string, task *TaskProgram) error { return taskWrite(deviceId, middleTask, task, "写入中间任务") } // StopTaskWrite 写入结束任务 (优化指令 CMD=0x15) func StopTaskWrite(deviceId string, task *TaskProgram) error { return taskWrite(deviceId, stopTask, task, "写入结束任务") } // 通用任务写入函数 func taskWrite(deviceId string, cmd M9zCtrl, task *TaskProgram, detail string) error { if task.Size > 23 { return fmt.Errorf("任务数量 %+v 太多,超过了上限,请删除一些后重试}", task.Size) } // 构造数据缓冲区 (1字节大小 + 每个指令4字节) buf := make([]byte, 1+4*len(task.Instructions)) buf[0] = byte(len(task.Instructions)) offset := 1 for _, ins := range task.Instructions { // 组合指令 (类型在高4位) instruction := ins.Type | ins.Param | ins.Value // 写入小端序 binary.LittleEndian.PutUint32(buf[offset:offset+4], instruction) offset += 4 } writeResp, err := WriteCmd(deviceId, M9zCtrl(cmd), buf, detail, task.Index) if err != nil { return err } if !writeResp.Success { return gerror.New("设置失败") } // 发送写入命令 return nil }