chore: HERV 통합 저장소 초기 커밋
- 펌웨어(program), C# 대시보드(TestProgram), 시뮬레이터(Simulator), 프로토콜/문서(Protocol, doc) 전체를 단일 저장소로 통합 - program 폴더의 별도 git 저장소를 제거하고 통합 저장소에 흡수 - 빌드 산출물(program/build, bin/obj, *.o/.elf/.bin/.hex 등) .gitignore 처리 - 사내 Synology NAS Git 원격 연결 예정 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
namespace ErvProtocol
|
||||
{
|
||||
// 고정패킷 파서 (PC_ERV_Protocol.md Rev2.0)
|
||||
// 0xAA | CMD | DATA[240] | CRC16-MODBUS(LE) = 244B 고정
|
||||
// 연결(소켓/시리얼)마다 1개 인스턴스. CRC 통과 프레임만 OnFrame 으로 전달.
|
||||
public sealed class FrameParser
|
||||
{
|
||||
public const byte STX = 0xAA;
|
||||
public const int DataLen = CtrlFrame.DataLen; // 240
|
||||
|
||||
public event Action<byte, byte[]>? OnFrame; // (cmd, data[240])
|
||||
public event Action<string>? OnError;
|
||||
|
||||
enum Step { Stx, Cmd, Data, CrcLo, CrcHi }
|
||||
Step _step = Step.Stx;
|
||||
byte _cmd, _crcLo;
|
||||
readonly byte[] _data = new byte[DataLen];
|
||||
int _dataPos;
|
||||
|
||||
public void Feed(ReadOnlySpan<byte> data)
|
||||
{
|
||||
foreach (var b in data) FeedByte(b);
|
||||
}
|
||||
|
||||
public void FeedByte(byte b)
|
||||
{
|
||||
switch (_step)
|
||||
{
|
||||
case Step.Stx:
|
||||
if (b == STX) _step = Step.Cmd;
|
||||
break;
|
||||
case Step.Cmd:
|
||||
_cmd = b; _dataPos = 0; _step = Step.Data;
|
||||
break;
|
||||
case Step.Data:
|
||||
_data[_dataPos++] = b;
|
||||
if (_dataPos >= DataLen) _step = Step.CrcLo;
|
||||
break;
|
||||
case Step.CrcLo:
|
||||
_crcLo = b; _step = Step.CrcHi;
|
||||
break;
|
||||
case Step.CrcHi:
|
||||
ushort rxCrc = (ushort)(_crcLo | (b << 8));
|
||||
_step = Step.Stx;
|
||||
Verify(rxCrc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 프레임 동기 리셋 (시리얼 프레임 갭 발생 시 등)
|
||||
public void Reset() => _step = Step.Stx;
|
||||
|
||||
void Verify(ushort rxCrc)
|
||||
{
|
||||
var buf = new byte[1 + DataLen]; // CMD + DATA[240]
|
||||
buf[0] = _cmd;
|
||||
Array.Copy(_data, 0, buf, 1, DataLen);
|
||||
ushort calc = Crc16.Modbus(buf, 0, buf.Length);
|
||||
if (calc != rxCrc)
|
||||
{
|
||||
OnError?.Invoke($"CRC ERR cmd=0x{_cmd:X2} calc=0x{calc:X4} rx=0x{rxCrc:X4}");
|
||||
return;
|
||||
}
|
||||
var data = new byte[DataLen];
|
||||
Array.Copy(_data, data, DataLen);
|
||||
OnFrame?.Invoke(_cmd, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user