full implementation if anyone comes back to this
pub const SMPDOBitLength = struct {
/// index of this sync manager
sm_idx: u8,
/// start address in esc memory
start_addr: u32,
pdo_byte_length: u16,
/// total bit length of PDOs assigned to this sync manager.
pdo_bit_length: u16,
direction: PDODirection,
};
pub const SMPDOBitLengths = struct {
pdo_bit_lengths: std.BoundedArray(SMPDOBitLength, max_sm) = .{},
fn lessThan(context: void, a: SMPDOBitLength, b: SMPDOBitLength) bool {
_ = context;
return a.start_addr < b.start_addr;
}
pub fn sortAndVerifyNonOverlapping(self: *SMPDOBitLengths) !void {
if (self.pdo_bit_lengths.len <= 1) return;
std.sort.insertion(SMPDOBitLength, self.pdo_bit_lengths.slice(), {}, SMPDOBitLengths.lessThan);
assert(std.sort.isSorted(SMPDOBitLength, self.pdo_bit_lengths.slice(), {}, SMPDOBitLengths.lessThan));
for (1..self.pdo_bit_lengths.len) |i| {
const this_sm = self.pdo_bit_lengths.slice()[i];
const last_sm = self.pdo_bit_lengths.slice()[i - 1];
if (last_sm.start_addr + last_sm.pdo_byte_length > this_sm.start_addr or
last_sm.start_addr == this_sm.start_addr)
{
std.log.warn("overlapping sync managers: {}, {}", .{ this_sm, last_sm });
return error.OverlappingSM;
}
}
}
};
test "sort and verfiy non overlapping SMPDOBitLengths" {
var pdo_bit_lengths = SMPDOBitLengths{};
try pdo_bit_lengths.pdo_bit_lengths.append(SMPDOBitLength{ .direction = .tx, .pdo_bit_length = 12, .pdo_byte_length = 2, .start_addr = 1000, .sm_idx = 2 });
try pdo_bit_lengths.pdo_bit_lengths.append(SMPDOBitLength{ .direction = .tx, .pdo_bit_length = 12, .pdo_byte_length = 2, .start_addr = 998, .sm_idx = 4 });
try pdo_bit_lengths.pdo_bit_lengths.append(SMPDOBitLength{ .direction = .tx, .pdo_bit_length = 12, .pdo_byte_length = 2, .start_addr = 1002, .sm_idx = 1 });
try pdo_bit_lengths.sortAndVerifyNonOverlapping();
try std.testing.expectEqual(@as(u32, 998), pdo_bit_lengths.pdo_bit_lengths.slice()[0].start_addr);
try std.testing.expectEqual(@as(u32, 1000), pdo_bit_lengths.pdo_bit_lengths.slice()[1].start_addr);
try std.testing.expectEqual(@as(u32, 1002), pdo_bit_lengths.pdo_bit_lengths.slice()[2].start_addr);
}
test "overlapping sync managers" {
var pdo_bit_lengths = SMPDOBitLengths{};
try pdo_bit_lengths.pdo_bit_lengths.append(SMPDOBitLength{ .direction = .tx, .pdo_bit_length = 12, .pdo_byte_length = 2, .start_addr = 1000, .sm_idx = 3 });
try pdo_bit_lengths.pdo_bit_lengths.append(SMPDOBitLength{ .direction = .tx, .pdo_bit_length = 12, .pdo_byte_length = 3, .start_addr = 998, .sm_idx = 3 });
try pdo_bit_lengths.pdo_bit_lengths.append(SMPDOBitLength{ .direction = .tx, .pdo_bit_length = 12, .pdo_byte_length = 2, .start_addr = 1002, .sm_idx = 3 });
try std.testing.expectError(error.OverlappingSM, pdo_bit_lengths.sortAndVerifyNonOverlapping());
}
test "overlapping sync managers non unique start addr" {
var pdo_bit_lengths = SMPDOBitLengths{};
try pdo_bit_lengths.pdo_bit_lengths.append(SMPDOBitLength{ .direction = .tx, .pdo_bit_length = 12, .pdo_byte_length = 2, .start_addr = 1000, .sm_idx = 3 });
try pdo_bit_lengths.pdo_bit_lengths.append(SMPDOBitLength{ .direction = .tx, .pdo_bit_length = 12, .pdo_byte_length = 2, .start_addr = 1000, .sm_idx = 3 });
try pdo_bit_lengths.pdo_bit_lengths.append(SMPDOBitLength{ .direction = .tx, .pdo_bit_length = 12, .pdo_byte_length = 2, .start_addr = 1002, .sm_idx = 3 });
try std.testing.expectError(error.OverlappingSM, pdo_bit_lengths.sortAndVerifyNonOverlapping());
}