make distinct types for peripherals always (#69)

wch-ch32v003
Matt Knight 2 years ago committed by Matt Knight
parent 9627d4196c
commit 293f25e6c3

@ -201,30 +201,19 @@ fn writePeripheralInstance(db: Database, instance_id: EntityId, offset: u64, out
const writer = buffer.writer();
const name = db.attrs.name.get(instance_id) orelse return error.MissingPeripheralInstanceName;
const type_id = db.instances.peripherals.get(instance_id).?;
if (db.attrs.name.contains(type_id)) {
const type_ref = try typesReference(db, type_id);
assert(db.attrs.name.contains(type_id));
const type_ref = try typesReference(db, type_id);
if (db.attrs.description.get(instance_id)) |description|
try writeComment(db.arena.allocator(), description, writer)
else if (db.attrs.description.get(type_id)) |description|
try writeComment(db.arena.allocator(), description, writer);
try writer.print("pub const {s} = @ptrCast(*volatile {s}, 0x{x});\n", .{
std.zig.fmtId(name),
type_ref,
offset,
});
} else {
try writer.print("pub const {s} = @ptrCast(*volatile ", .{
std.zig.fmtId(name),
});
try writePeripheralBody(db, type_id, writer);
if (db.attrs.description.get(instance_id)) |description|
try writeComment(db.arena.allocator(), description, writer)
else if (db.attrs.description.get(type_id)) |description|
try writeComment(db.arena.allocator(), description, writer);
try writer.print(", 0x{x});\n", .{
offset,
});
}
try writer.print("pub const {s} = @ptrCast(*volatile {s}, 0x{x});\n", .{
std.zig.fmtId(name),
type_ref,
offset,
});
try out_writer.writeAll(buffer.items);
}
@ -317,8 +306,8 @@ fn writePeripheral(
assert(db.entityIs("type.peripheral", peripheral_id) or
db.entityIs("type.register_group", peripheral_id));
// unnamed peripherals are anonymously defined
const name = db.attrs.name.get(peripheral_id) orelse return;
// peripheral types should always have a name (responsibility of parsing to get this done)
const name = db.attrs.name.get(peripheral_id) orelse unreachable;
// for now only serialize flat peripherals with no register groups
// TODO: expand this
@ -343,24 +332,13 @@ fn writePeripheral(
if (db.attrs.description.get(peripheral_id)) |description|
try writeComment(db.arena.allocator(), description, writer);
try writer.print("pub const {s} = ", .{std.zig.fmtId(name)});
try writePeripheralBody(db, peripheral_id, writer);
try writer.writeAll(";\n");
try out_writer.writeAll(buffer.items);
}
fn writePeripheralBody(
db: Database,
peripheral_id: EntityId,
writer: anytype,
) WritePeripheralError(@TypeOf(writer))!void {
const zero_sized = isPeripheralZeroSized(db, peripheral_id);
const has_modes = db.children.modes.contains(peripheral_id);
try writer.print(
\\{s} {s} {{
\\pub const {s} = {s} {s} {{
\\
, .{
std.zig.fmtId(name),
if (zero_sized) "" else "packed",
if (has_modes) "union" else "struct",
});
@ -393,6 +371,9 @@ fn writePeripheralBody(
try writeRegisters(db, peripheral_id, writer);
try writer.writeAll("\n}");
try writer.writeAll(";\n");
try out_writer.writeAll(buffer.items);
}
fn writeNewlineIfWritten(writer: anytype, written: *bool) !void {
@ -1317,49 +1298,14 @@ test "gen.namespaced register groups" {
, buffer.items);
}
test "gen.peripheral without name" {
test "gen.peripheral with reserved register" {
var db = try Database.init(std.testing.allocator);
defer db.deinit();
const peripheral_id = try db.createPeripheral(.{});
_ = try db.createRegister(peripheral_id, .{ .name = "PORTB", .size = 8, .offset = 0 });
_ = try db.createRegister(peripheral_id, .{ .name = "DDRB", .size = 8, .offset = 1 });
_ = try db.createRegister(peripheral_id, .{ .name = "PINB", .size = 8, .offset = 2 });
const device_id = try db.createDevice(.{
.name = "ATmega328P",
});
_ = try db.createPeripheralInstance(device_id, peripheral_id, .{
const peripheral_id = try db.createPeripheral(.{
.name = "PORTB",
.offset = 0x23,
});
var buffer = std.ArrayList(u8).init(std.testing.allocator);
defer buffer.deinit();
try db.toZig(buffer.writer());
try std.testing.expectEqualStrings(
\\const mmio = @import("mmio");
\\
\\pub const devices = struct {
\\ pub const ATmega328P = struct {
\\ pub const PORTB = @ptrCast(*volatile packed struct {
\\ PORTB: u8,
\\ DDRB: u8,
\\ PINB: u8,
\\ }, 0x23);
\\ };
\\};
\\
, buffer.items);
}
test "gen.peripheral with reserved register" {
var db = try Database.init(std.testing.allocator);
defer db.deinit();
const peripheral_id = try db.createPeripheral(.{});
_ = try db.createRegister(peripheral_id, .{ .name = "PORTB", .size = 32, .offset = 0 });
_ = try db.createRegister(peripheral_id, .{ .name = "PINB", .size = 32, .offset = 8 });
@ -1381,11 +1327,15 @@ test "gen.peripheral with reserved register" {
\\
\\pub const devices = struct {
\\ pub const ATmega328P = struct {
\\ pub const PORTB = @ptrCast(*volatile packed struct {
\\ PORTB: u32,
\\ reserved8: [4]u8,
\\ PINB: u32,
\\ }, 0x23);
\\ pub const PORTB = @ptrCast(*volatile types.PORTB, 0x23);
\\ };
\\};
\\
\\pub const types = struct {
\\ pub const PORTB = packed struct {
\\ PORTB: u32,
\\ reserved8: [4]u8,
\\ PINB: u32,
\\ };
\\};
\\

@ -185,7 +185,14 @@ pub fn loadPeripheral(ctx: *Context, node: xml.Node, device_id: EntityId) !void
const base_address = node.getValue("baseAddress") orelse return error.PeripheralMissingBaseAddress;
const offset = try std.fmt.parseInt(u64, base_address, 0);
const type_id = try db.createPeripheral(.{});
// dim elements before creation as it might require creating multiple instances
const dim_elements = try DimElements.parse(node);
if (dim_elements != null)
return error.TodoDimElements;
const type_id = try db.createPeripheral(.{
.name = name,
});
errdefer db.destroyEntity(type_id);
const instance_id = try db.createPeripheralInstance(device_id, type_id, .{
@ -194,10 +201,6 @@ pub fn loadPeripheral(ctx: *Context, node: xml.Node, device_id: EntityId) !void
});
errdefer db.destroyEntity(instance_id);
const dim_elements = try DimElements.parse(node);
if (dim_elements != null)
return error.TodoDimElements;
if (node.findChild("interrupt")) |interrupt_node|
try loadInterrupt(db, interrupt_node, device_id);
@ -205,10 +208,11 @@ pub fn loadPeripheral(ctx: *Context, node: xml.Node, device_id: EntityId) !void
// - any dimElementGroup values are set
log.debug("{}: created peripheral instance", .{instance_id});
// TODO: what to do with a half baked instance?
if (node.getValue("description")) |description|
if (node.getValue("description")) |description| {
try db.addDescription(type_id, description);
try db.addDescription(instance_id, description);
}
if (node.getValue("version")) |version|
try db.addVersion(instance_id, version);
@ -935,6 +939,7 @@ test "device register properties" {
// these only have names attached, so if these functions fail the test will fail.
_ = try db.getEntityIdByName("instance.device", "TEST_DEVICE");
_ = try db.getEntityIdByName("instance.peripheral", "TEST_PERIPHERAL");
_ = try db.getEntityIdByName("type.peripheral", "TEST_PERIPHERAL");
const register_id = try db.getEntityIdByName("type.register", "TEST_REGISTER");
try expectAttr(db, "size", 32, register_id);

Loading…
Cancel
Save