make distinct types for peripherals always (#69)

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

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

@ -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 base_address = node.getValue("baseAddress") orelse return error.PeripheralMissingBaseAddress;
const offset = try std.fmt.parseInt(u64, base_address, 0); 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); errdefer db.destroyEntity(type_id);
const instance_id = try db.createPeripheralInstance(device_id, 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); 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| if (node.findChild("interrupt")) |interrupt_node|
try loadInterrupt(db, interrupt_node, device_id); 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 // - any dimElementGroup values are set
log.debug("{}: created peripheral instance", .{instance_id}); 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); try db.addDescription(instance_id, description);
}
if (node.getValue("version")) |version| if (node.getValue("version")) |version|
try db.addVersion(instance_id, 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. // 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.device", "TEST_DEVICE");
_ = try db.getEntityIdByName("instance.peripheral", "TEST_PERIPHERAL"); _ = try db.getEntityIdByName("instance.peripheral", "TEST_PERIPHERAL");
_ = try db.getEntityIdByName("type.peripheral", "TEST_PERIPHERAL");
const register_id = try db.getEntityIdByName("type.register", "TEST_REGISTER"); const register_id = try db.getEntityIdByName("type.register", "TEST_REGISTER");
try expectAttr(db, "size", 32, register_id); try expectAttr(db, "size", 32, register_id);

Loading…
Cancel
Save