MS2WYW6EVLN6BMH6HS4DYRESUTREVB5LDSVORIX3DR3E5FMMS4YQC
TXSGLYOVYQ77EG23PAVW62MBJRHS2WTVAVNQ3NYVBDGKNMSYS7DAC
UAB3QWX6I6PF4BRKRV6C7QKQMEYESRIALOFSOP3P5NAX2SHXABTQC
WYMZVWFSD2KSORBUMFWEXZFGDE3KV77AFVFJVVYPI7RY4NVDEK6AC
B3CHXNO7SSVZE7CC7SDDTTFU4KSWZCE64UCVN6WP6NZZVOKNH7ZAC
3PHQ7BKOEICZ7E6D76ALDVMZFKI2FXXHZCIWJESFADEQ4YYSZ2AAC
IPLSYOCQIAQLB6HXL6YBJ5ZKKESCSRO7S7P5SF6I367M6HEJJRNQC
// zig fmt: off
const MASK_3BYTES = 0b1111111111_1_00000000_1_00000000_1_00000000_1;
const COMPARE_3BYTES = 0b1111111111_0_00000000_0_00000000_0_00000000_1;
const MASK_4BYTES = 0b1111111111_1_00000000_1_00000000_1_00000000_1_00000000_1;
const COMPARE_4BYTES = 0b1111111111_0_00000000_0_00000000_0_00000000_0_00000000_1;
const MASK_5BYTES = 0b1111111111_1_00000000_1_00000000_1_00000000_1_00000000_1_00000000_1;
const COMPARE_5BYTES = 0b1111111111_0_00000000_0_00000000_0_00000000_0_00000000_0_00000000_1;
// zig fmt: on
const Packet = struct {
address: u8,
instruction: Instruction,
pub fn speed(self: @This()) Speed {
// TODO: Based on CV29 we should add support for 14 step speed control
var ret: u5 = self.instruction.speed << 1;
ret |= self.instruction.headlight;
return @enumFromInt(ret);
}
};
// TODO: extended address byte support (2.3)
pub const Parser = struct {
pub const TIME_ONEMAX_US = 87; // XXX: doble check these!
// zig fmt: off
const MASK_PREAMBLE = 0b1111111111_0;
const MASK_3BYTES = 0b1111111111_1_00000000_1_00000000_1_00000000_1;
const COMPARE_3BYTES = 0b1111111111_0_00000000_0_00000000_0_00000000_1;
const MASK_4BYTES = 0b1111111111_1_00000000_1_00000000_1_00000000_1_00000000_1;
const COMPARE_4BYTES = 0b1111111111_0_00000000_0_00000000_0_00000000_0_00000000_1;
const MASK_5BYTES = 0b1111111111_1_00000000_1_00000000_1_00000000_1_00000000_1_00000000_1;
const COMPARE_5BYTES = 0b1111111111_0_00000000_0_00000000_0_00000000_0_00000000_0_00000000_1;
// zig fmt: on
const bit: BitType = if (diff.less_than(@enumFromInt(TIME_ONEMAX))) .one else .zero;
// XXX: this might be useful...
// if (diff.less_than(@enumFromInt(5))) return;
log.debug("DIFF: {d}", .{diff.to_us()});
const bit: BitType = if (diff.less_than(@enumFromInt(TIME_ONEMAX_US))) .one else .zero;
std.log.debug("3 byte long DCC package detected!", .{});
defer self.reset();
const address: u8 = @truncate(self.buffer >> (2 * (8 + 1) + 1));
const instruction: u8 = @truncate(self.buffer >> (8 + 1) + 1);
const checksum: u8 = @truncate(self.buffer >> 1);
if (address ^ instruction == checksum) {
std.log.debug("DDC packet passed the validation", .{});
const packet = Packet{
.address = @bitCast(address),
.instruction = @bitCast(instruction),
};
self.packets.writeItem(packet) catch {
std.log.err("DDC packet FIFO full, dropping packet", .{});
return;
};
std.log.debug("DCC packet added to FIFO", .{});
} else {
std.log.debug("DDC packet invalid", .{});
}
self.write3bytes();
fn write3bytes(self: *@This()) void {
log.debug("3 byte long DCC package detected!", .{});
defer self.reset();
const address: u8 = @truncate(self.buffer >> (2 * (8 + 1) + 1));
const instruction: u8 = @truncate(self.buffer >> (8 + 1) + 1);
const checksum: u8 = @truncate(self.buffer >> 1);
if (address ^ instruction != checksum) {
log.debug("DDC packet invalid, dropping it", .{});
return;
}
const packet = Packet{
.address = @bitCast(address),
.instruction = @bitCast(instruction),
};
self.packets.writeItem(packet) catch {
log.err("DDC packet FIFO full, dropping packet", .{});
return;
};
log.debug("DCC packet added to FIFO", .{});
}