Move lpc1768 to new generated SVD

wch-ch32v003
Vesim 3 years ago
parent 74641abbf0
commit eedc689738

@ -145,11 +145,11 @@ fn addEmbeddedExecutable(builder: *std.build.Builder, name: []const u8, source:
writer.print("pub const has_board = {};\n", .{has_board}) catch unreachable; writer.print("pub const has_board = {};\n", .{has_board}) catch unreachable;
if (has_board) { if (has_board) {
writer.print("pub const board_name = \"{}\";\n", .{std.fmt.fmtSliceEscapeUpper(backing.board.name)}) catch unreachable; writer.print("pub const board_name = .@\"{}\";\n", .{std.fmt.fmtSliceEscapeUpper(backing.board.name)}) catch unreachable;
} }
writer.print("pub const chip_name = \"{}\";\n", .{std.fmt.fmtSliceEscapeUpper(chip.name)}) catch unreachable; writer.print("pub const chip_name = .@\"{}\";\n", .{std.fmt.fmtSliceEscapeUpper(chip.name)}) catch unreachable;
writer.print("pub const cpu_name = \"{}\";\n", .{std.fmt.fmtSliceEscapeUpper(chip.cpu.name)}) catch unreachable; writer.print("pub const cpu_name = .@\"{}\";\n", .{std.fmt.fmtSliceEscapeUpper(chip.cpu.name)}) catch unreachable;
} }
const config_pkg = Pkg{ const config_pkg = Pkg{

@ -56,27 +56,15 @@ pub fn Uart(comptime index: usize) type {
pub const Config = struct { pub const Config = struct {
baud_rate: u32, baud_rate: u32,
stop_bits: StopBits = .one, stop_bits: StopBits = .one,
parity: Parity = .none, parity: ?Parity = null,
data_bits: DataBits = .@"8", data_bits: DataBits = .eight,
}; };
pub const DataBits = enum { // TODO: comptime verify that the enums are valid
@"5", pub const DataBits = chip.uart.DataBits;
@"6", pub const StopBits = chip.uart.StopBits;
@"7", pub const Parity = chip.uart.Parity;
@"8",
@"9",
};
pub const StopBits = enum { one, two };
pub const Parity = enum {
none,
even,
odd,
mark,
space,
};
pub const InitError = error{ pub const InitError = error{
UnsupportedWordSize, UnsupportedWordSize,
UnsupportedParity, UnsupportedParity,

@ -55,7 +55,7 @@ pub fn parsePin(comptime spec: []const u8) type {
pub fn routePin(comptime pin: type, function: PinTarget) void { pub fn routePin(comptime pin: type, function: PinTarget) void {
var val = pin.regs.pinsel_reg.read(); var val = pin.regs.pinsel_reg.read();
@field(val, pin.regs.pinsel_field) = @enumToInt(function); @field(val, pin.regs.pinsel_field) = @intToEnum(@TypeOf(@field(val, pin.regs.pinsel_field)), @enumToInt(function));
pin.regs.pinsel_reg.write(val); pin.regs.pinsel_reg.write(val);
} }
@ -83,6 +83,30 @@ pub const gpio = struct {
} }
}; };
pub const uart = struct {
const RegisterDataBitsEnum = std.meta.fieldInfo(@TypeOf(registers.UART0.LCR.*).underlying_type, .WLS).field_type;
pub const DataBits = enum(u2) {
five = @enumToInt(RegisterDataBitsEnum.@"5_BIT_CHARACTER_LENG"),
six = @enumToInt(RegisterDataBitsEnum.@"6_BIT_CHARACTER_LENG"),
seven = @enumToInt(RegisterDataBitsEnum.@"7_BIT_CHARACTER_LENG"),
eight = @enumToInt(RegisterDataBitsEnum.@"8_BIT_CHARACTER_LENG"),
};
const RegisterStopBitEnum = std.meta.fieldInfo(@TypeOf(registers.UART0.LCR.*).underlying_type, .SBS).field_type;
pub const StopBits = enum(u1) {
one = @enumToInt(RegisterStopBitEnum.@"1_STOP_BIT_"),
two = @enumToInt(RegisterStopBitEnum.@"2_STOP_BITS_1_5_IF_"),
};
const RegisterParityEnum = std.meta.fieldInfo(@TypeOf(registers.UART0.LCR.*).underlying_type, .PS).field_type;
pub const Parity = enum(u2) {
odd = @enumToInt(RegisterParityEnum.@"ODD_PARITY_NUMBER_O"),
even = @enumToInt(RegisterParityEnum.@"EVEN_PARITY_NUMBER_"),
mark = @enumToInt(RegisterParityEnum.@"FORCED_1_STICK_PARIT"),
space = @enumToInt(RegisterParityEnum.@"FORCED_0_STICK_PARIT"),
};
};
pub fn Uart(comptime index: usize) type { pub fn Uart(comptime index: usize) type {
return struct { return struct {
const UARTn = switch (index) { const UARTn = switch (index) {
@ -98,20 +122,20 @@ pub fn Uart(comptime index: usize) type {
micro.debug.write("0"); micro.debug.write("0");
switch (index) { switch (index) {
0 => { 0 => {
registers.SYSCON.PCONP.modify(.{ .PCUART0 = true }); registers.SYSCON.PCONP.modify(.{ .PCUART0 = 1 });
registers.SYSCON.PCLKSEL0.modify(.{ .PCLK_UART0 = 0 }); registers.SYSCON.PCLKSEL0.modify(.{ .PCLK_UART0 = .CCLK_DIV_4 });
}, },
1 => { 1 => {
registers.SYSCON.PCONP.modify(.{ .PCUART1 = true }); registers.SYSCON.PCONP.modify(.{ .PCUART1 = 1 });
registers.SYSCON.PCLKSEL0.modify(.{ .PCLK_UART1 = 0 }); registers.SYSCON.PCLKSEL0.modify(.{ .PCLK_UART1 = .CCLK_DIV_4 });
}, },
2 => { 2 => {
registers.SYSCON.PCONP.modify(.{ .PCUART2 = true }); registers.SYSCON.PCONP.modify(.{ .PCUART2 = 1 });
registers.SYSCON.PCLKSEL0.modify(.{ .PCLK_UART2 = 0 }); registers.SYSCON.PCLKSEL0.modify(.{ .PCLK_UART2 = .CCLK_DIV_4 });
}, },
3 => { 3 => {
registers.SYSCON.PCONP.modify(.{ .PCUART3 = true }); registers.SYSCON.PCONP.modify(.{ .PCUART3 = 1 });
registers.SYSCON.PCLKSEL0.modify(.{ .PCLK_UART3 = 0 }); registers.SYSCON.PCLKSEL0.modify(.{ .PCLK_UART3 = .CCLK_DIV_4 });
}, },
else => unreachable, else => unreachable,
} }
@ -119,29 +143,17 @@ pub fn Uart(comptime index: usize) type {
UARTn.LCR.write(.{ UARTn.LCR.write(.{
// 8N1 // 8N1
.WLS = switch (config.data_bits) { .WLS = @intToEnum(std.meta.fieldInfo(@TypeOf(UARTn.LCR.*).underlying_type, .WLS).field_type, @enumToInt(config.data_bits)),
.@"5" => 0b00, .SBS = @intToEnum(std.meta.fieldInfo(@TypeOf(UARTn.LCR.*).underlying_type, .SBS).field_type, @enumToInt(config.stop_bits)),
.@"6" => 0b01, .PE = if (config.parity) |_| .ENABLE_PARITY_GENERA else .DISABLE_PARITY_GENER,
.@"7" => 0b10, .PS = if (config.parity) |p| @intToEnum(std.meta.fieldInfo(@TypeOf(UARTn.LCR.*).underlying_type, .PS).field_type, @enumToInt(p)) else .ODD_PARITY_NUMBER_O,
.@"8" => 0b11, .BC = .DISABLE_BREAK_TRANSM,
.@"9" => return error.UnsupportedWordSize, .DLAB = .ENABLE_ACCESS_TO_DIV,
},
.SBS = switch (config.stop_bits) {
.one => false,
.two => true,
},
.PE = (config.parity != .none),
.PS = switch (config.parity) {
.none, .odd => @as(u2, 0b00),
.even => 0b01,
.mark => 0b10,
.space => 0b11,
},
.BC = false,
.DLAB = true,
}); });
micro.debug.write("2"); micro.debug.write("2");
UARTn.FCR.modify(.{ .FIFOEN = false });
// TODO: UARTN_FIFOS_ARE_DISA is not available in all uarts
//UARTn.FCR.modify(.{ .FIFOEN = .UARTN_FIFOS_ARE_DISA });
micro.debug.writer().print("clock: {} baud: {} ", .{ micro.debug.writer().print("clock: {} baud: {} ", .{
micro.clock.get(), micro.clock.get(),
@ -156,13 +168,16 @@ pub fn Uart(comptime index: usize) type {
UARTn.DLL.write(.{ .DLLSB = @truncate(u8, regval >> 0x00) }); UARTn.DLL.write(.{ .DLLSB = @truncate(u8, regval >> 0x00) });
UARTn.DLM.write(.{ .DLMSB = @truncate(u8, regval >> 0x08) }); UARTn.DLM.write(.{ .DLMSB = @truncate(u8, regval >> 0x08) });
UARTn.LCR.modify(.{ .DLAB = false }); UARTn.LCR.modify(.{ .DLAB = .DISABLE_ACCESS_TO_DI });
return Self{}; return Self{};
} }
pub fn canWrite(self: Self) bool { pub fn canWrite(self: Self) bool {
return UARTn.LSR.read().THRE; return switch (UARTn.LSR.read().THRE) {
.VALID => true,
.THR_IS_EMPTY_ => false,
};
} }
pub fn tx(self: Self, ch: u8) void { pub fn tx(self: Self, ch: u8) void {
while (!self.canWrite()) {} // Wait for Previous transmission while (!self.canWrite()) {} // Wait for Previous transmission
@ -170,7 +185,10 @@ pub fn Uart(comptime index: usize) type {
} }
pub fn canRead(self: Self) bool { pub fn canRead(self: Self) bool {
return UARTn.LSR.read().RDR; return switch (UARTn.LSR.read().RDR) {
.EMPTY => false,
.NOTEMPTY => true,
};
} }
pub fn rx(self: Self) u8 { pub fn rx(self: Self) u8 {
while (!self.canRead()) {} // Wait till the data is received while (!self.canRead()) {} // Wait till the data is received

File diff suppressed because it is too large Load Diff

@ -45,7 +45,7 @@ class MMIOFileGenerator:
total_fields_with_values = 0 total_fields_with_values = 0
for e in field.enumerated_values: for e in field.enumerated_values:
e.description = cleanup_description(e.description) e.description = cleanup_description(e.description)
if e.value is None: if e.value is None or e.name == "RESERVED":
# reserved fields doesn't have a value so we have to comment them out # reserved fields doesn't have a value so we have to comment them out
self.write_line(f"// @\"{e.name}\", // desc: {e.description}") self.write_line(f"// @\"{e.name}\", // desc: {e.description}")
else: else:
@ -84,9 +84,16 @@ class MMIOFileGenerator:
last_offset = 0 last_offset = 0
reserved_index = 0 reserved_index = 0
for field in sorted(register.fields, key=lambda f: f.bit_offset): for field in sorted(register.fields, key=lambda f: f.bit_offset):
# workaround for NXP SVD which has overleaping reserved fields
if field.name == "RESERVED":
self.write_line(f"// RESERVED: u{field.bit_width}, // bit offset: {field.bit_offset} desc: {field.description}")
continue
if last_offset != field.bit_offset: if last_offset != field.bit_offset:
self.generate_padding(field.bit_offset - last_offset, "reserved", reserved_index) reserved_size = field.bit_offset - last_offset
reserved_index = reserved_index + field.bit_width self.generate_padding(reserved_size, "reserved", reserved_index)
reserved_index = reserved_index + reserved_size
if field.is_enumerated_type: if field.is_enumerated_type:
last_offset = self.generate_enumerated_field(field) last_offset = self.generate_enumerated_field(field)
else: else:
@ -98,7 +105,6 @@ class MMIOFileGenerator:
else: else:
self.generate_padding(size - last_offset, "padding", 0) self.generate_padding(size - last_offset, "padding", 0)
self.write_line("});") self.write_line("});")
def generate_peripherial_declaration(self, peripherial): def generate_peripherial_declaration(self, peripherial):

@ -4,16 +4,16 @@ const micro = @import("microzig");
pub const panic = micro.panic; pub const panic = micro.panic;
// Configures the led_pin to a hardware pin // Configures the led_pin to a hardware pin
const led_pin = switch (@import("builtin").cpu.arch) { const led_pin = if (micro.config.has_board)
.avr => if (micro.config.has_board) switch (micro.config.board_name) {
micro.Pin("D13") // Use D13 from Arduino Nano .@"Arduino Nano" => micro.Pin("D13"),
else .@"mbed LPC1768" => micro.Pin("LED-1"),
micro.Pin("PB5"), // Use PB5 on raw ATmega328p else => @compileError("unknown board"),
.arm => if (micro.config.has_board) }
micro.Pin("LED-1") // Use LED-1 from mbed LPC1768 else switch (micro.config.chip_name) {
else .@"ATmega328p" => micro.Pin("PB5"),
micro.Pin("P1.18"), // Use P1.18 on raw LPC1768 .@"NXP LPC1768" => micro.Pin("P1.18"),
else => @compileError("Unsupported platform!"), else => @compileError("unknown chip"),
}; };
pub fn main() void { pub fn main() void {

@ -28,7 +28,7 @@ const PLL = struct {
fn overclock_flash(timing: u5) void { fn overclock_flash(timing: u5) void {
micro.chip.registers.SYSCON.FLASHCFG.write(.{ micro.chip.registers.SYSCON.FLASHCFG.write(.{
.FLASHTIM = @intCast(u4, timing - 1), .FLASHTIM = @intToEnum(@TypeOf(micro.chip.registers.SYSCON.FLASHCFG.read().FLASHTIM), @intCast(u4, timing - 1)),
}); });
} }
fn feed_pll() callconv(.Inline) void { fn feed_pll() callconv(.Inline) void {
@ -39,12 +39,12 @@ const PLL = struct {
fn overclock_pll(divider: u8) void { fn overclock_pll(divider: u8) void {
// PLL einrichten für RC // PLL einrichten für RC
micro.chip.registers.SYSCON.PLL0CON.write(.{ micro.chip.registers.SYSCON.PLL0CON.write(.{
.PLLE0 = false, .PLLE0 = 0,
.PLLC0 = false, .PLLC0 = 0,
}); });
feed_pll(); feed_pll();
micro.chip.registers.SYSCON.CLKSRCSEL.write(.{ .CLKSRC = 0 }); // RC-Oszillator als Quelle micro.chip.registers.SYSCON.CLKSRCSEL.write(.{ .CLKSRC = .SELECTS_THE_INTERNAL }); // RC-Oszillator als Quelle
micro.chip.registers.SYSCON.PLL0CFG.write(.{ micro.chip.registers.SYSCON.PLL0CFG.write(.{
// SysClk = (4MHz / 2) * (2 * 75) = 300 MHz // SysClk = (4MHz / 2) * (2 * 75) = 300 MHz
.MSEL0 = 74, .MSEL0 = 74,
@ -55,7 +55,7 @@ const PLL = struct {
feed_pll(); feed_pll();
micro.chip.registers.SYSCON.PLL0CON.modify(.{ .PLLE0 = true }); // PLL einschalten micro.chip.registers.SYSCON.PLL0CON.modify(.{ .PLLE0 = 1 }); // PLL einschalten
feed_pll(); feed_pll();
var i: usize = 0; var i: usize = 0;
@ -63,7 +63,7 @@ const PLL = struct {
micro.cpu.nop(); micro.cpu.nop();
} }
micro.chip.registers.SYSCON.PLL0CON.modify(.{ .PLLC0 = true }); micro.chip.registers.SYSCON.PLL0CON.modify(.{ .PLLC0 = 1 });
feed_pll(); feed_pll();
} }
}; };
@ -95,8 +95,8 @@ pub fn main() !void {
var debug_port = micro.Uart(1).init(.{ var debug_port = micro.Uart(1).init(.{
.baud_rate = 9600, .baud_rate = 9600,
.stop_bits = .one, .stop_bits = .one,
.parity = .none, // { none, even, odd, mark, space } .parity = null,
.data_bits = .@"8", // 5, 6, 7, 8, or 9 data bits .data_bits = .eight,
}) catch |err| { }) catch |err| {
led1.write(if (err == error.UnsupportedBaudRate) micro.gpio.State.low else .high); led1.write(if (err == error.UnsupportedBaudRate) micro.gpio.State.low else .high);
led2.write(if (err == error.UnsupportedParity) micro.gpio.State.low else .high); led2.write(if (err == error.UnsupportedParity) micro.gpio.State.low else .high);

Loading…
Cancel
Save