rts-sim-testing-service/third_party/message/can_atp_req.go
2023-11-21 17:20:03 +08:00

205 lines
4.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package message
import "log/slog"
//应答器传输模块BTM与车载ATP通信协议定义
const (
CAN_ADDR_REQ_BTM = byte(0x62) //设备地址
CAN_ADDR_REQ_ATP = byte(0x81) //设备地址
CAN_ADDR_RSP_BTM = byte(0x02) //设备地址
CAN_ADDR_RSP_ATP = byte(0x01) //设备地址
CAN_FRAME_ATP_REQ = byte(0x02) //帧类型-查询请求帧
CAN_FRAME_STATUS_RSP = byte(0x01) //状态应答帧
CAN_FRAME_TIME_SYNC_RSP = byte(0x02) //时间同步应答帧
CAN_FRAME_DATA_RSP = byte(0x80) //数据应答帧
CAN_FRAME_DATA_END_RSP = byte(0xff) //数据结束应答帧
)
////////////////////////////////////////////////////////////////////////////////////
// CanFrameId CAN串行总线帧ID定义,29bits
type CanFrameId struct {
//ID1 8bits
ID1 byte
//ID2 8bits
ID2 byte
//ID3 8bits
ID3 byte
//ID4 5bits ,有效位[bit4,bit0],无效位[bit7,bit5]
ID4 byte
}
// NewCanFrameId 创建CAN串行总线帧ID
// dstAddr 目的设备地址
// srcAddr 源设备地址
// frameType 帧类型
// sn 序列号
func NewCanFrameId(dstAddr byte, srcAddr byte, frameType byte, sn byte) *CanFrameId {
return &CanFrameId{
ID1: dstAddr,
ID2: srcAddr,
ID3: frameType,
ID4: sn,
}
}
////////////////////////////////////////////////////////////////
// AtpRequestFrame ATP查询帧
type AtpRequestFrame struct {
//帧ID
FId CanFrameId
//功率放大器命令false-0关闭功率放大器true-1s开启功率放大器
PowerAmplifierTurnOn bool
//功率放大器控制者false-0BTM控制true-1ATP控制
PowerAmplifierControlledByAtp bool
//重发请求
ResendRequest byte
//速度,1=0.1km/h
Speed uint16
//当前ATP系统时间1=1ms
Time uint32
//crc 校验码,从数据流中接收到的
Crc16 uint16
//解码时CRC16校验结果,true-校验通过
Crc16CheckOk bool
}
// NewAtpRequestFrame 创建ATP查询帧
func NewAtpRequestFrame(sn byte) *AtpRequestFrame {
return &AtpRequestFrame{
FId: *NewCanFrameId(CAN_ADDR_REQ_BTM, CAN_ADDR_REQ_ATP, CAN_FRAME_ATP_REQ, sn),
}
}
func (f *AtpRequestFrame) Decode(cf *CanetFrame) bool {
f.FId = cf.CanId
//
bits := NewCanBitsReader(cf.CanData, 8)
//
if d, ok := bits.ReadBits(1); ok {
f.PowerAmplifierTurnOn = d == 1
} else {
return false
}
if d, ok := bits.ReadBits(1); ok {
f.PowerAmplifierControlledByAtp = d == 1
} else {
return false
}
if d, ok := bits.ReadBits(2); ok {
f.ResendRequest = d
} else {
return false
}
//speed
f.Speed = 0x0000
if d, ok := bits.ReadBits(4); ok {
f.Speed = uint16(d)
f.Speed <<= 8
} else {
return false
}
if d, ok := bits.ReadByte(); ok {
f.Speed |= uint16(d)
} else {
return false
}
//time
f.Time = 0
timeArr := make([]byte, 4, 4)
if d, ok := bits.ReadByte(); ok {
timeArr[0] = d
} else {
return false
}
if d, ok := bits.ReadByte(); ok {
timeArr[1] = d
} else {
return false
}
if d, ok := bits.ReadByte(); ok {
timeArr[2] = d
} else {
return false
}
if d, ok := bits.ReadByte(); ok {
timeArr[3] = d
} else {
return false
}
crc16 := calculateAtpReqCrc16(timeArr)
t1 := uint32(timeArr[0])
t2 := uint32(timeArr[1])
t3 := uint32(timeArr[2])
t4 := uint32(timeArr[3])
f.Time |= t1 << 24
f.Time |= t2 << 16
f.Time |= t3 << 8
f.Time |= t4
//crc
f.Crc16 = 0
if d, ok := bits.ReadByte(); ok {
crc1 := uint16(d)
f.Crc16 |= crc1 << 8
} else {
return false
}
if d, ok := bits.ReadByte(); ok {
crc2 := uint16(d)
f.Crc16 |= crc2
} else {
return false
}
//crc校验
f.Crc16CheckOk = f.Crc16 == crc16
if !f.Crc16CheckOk {
slog.Debug("解码AtpRequestFrameCRC16校验未通过")
}
//
return true
}
func (f *AtpRequestFrame) Encode() *CanetFrame {
cf := &CanetFrame{}
cf.CanId = f.FId
cf.CanLen = 8
cf.FF = true
cf.RTR = false
//
bits := NewCanBitsWriter(8)
//
if f.PowerAmplifierTurnOn {
bits.AddBits(1, 1)
} else {
bits.AddBits(0, 1)
}
//
if f.PowerAmplifierControlledByAtp {
bits.AddBits(1, 1)
} else {
bits.AddBits(0, 1)
}
//
bits.AddBits(f.ResendRequest, 2)
//速度
bits.AddBits(byte(f.Speed>>8), 4)
bits.AddByte(byte(f.Speed))
//时间
timeArr := make([]byte, 4, 4)
timeArr[0] = byte(f.Time >> 24)
timeArr[1] = byte(f.Time >> 16)
timeArr[2] = byte(f.Time >> 8)
timeArr[3] = byte(f.Time)
for _, timeByte := range timeArr {
bits.AddByte(timeByte)
}
//crc
crc16 := calculateAtpReqCrc16(timeArr)
bits.AddByte(byte(crc16 >> 8))
bits.AddByte(byte(crc16))
//
cf.CanData = bits.(CanBusData).GetData()
//
return cf
}