|
|
package m9z
|
|
|
|
|
|
import (
|
|
|
"encoding/binary"
|
|
|
"fmt"
|
|
|
"github.com/towgo/towgo/errors/terror"
|
|
|
"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 terror.New("设置失败")
|
|
|
}
|
|
|
// 发送写入命令
|
|
|
return nil
|
|
|
}
|