-
Notifications
You must be signed in to change notification settings - Fork 163
MSP430 Support #828
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
MSP430 Support #828
Changes from all commits
Commits
Show all changes
18 commits
Select commit
Hold shift + click to select a range
b71847a
init
mattnite 7c77604
WIP
mattnite 96a910f
WIP
mattnite 0f0cc7a
Compiling blinky
mattnite 2b86da4
Cleanup
mattnite d760f35
Format
mattnite 355ed75
Targetdb file
mattnite dce30f5
Add MSP430 examples
mattnite 7ded007
Set up stack, create declarations for external crystals on board
mattnite 62ffd69
Minimize manual linkerscript code
mattnite a507c70
Fix default interrupt handlers
mattnite c59a480
Renamed boards
mattnite e33a863
Fix watchdog disable
mattnite f947f23
more improvements
mattnite d35e234
Devlog entry
mattnite 4a8f4e8
Devlog link
mattnite de7572d
gif
mattnite 749e360
Add TODO
mattnite File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,186 @@ | ||
| const std = @import("std"); | ||
| const microzig = @import("microzig"); | ||
| const config = microzig.config; | ||
|
|
||
| const Interrupt = if (std.mem.eql(u8, config.chip_name, "MSP430G2553")) enum(u4) { | ||
| TRAPINT = 0, | ||
| PORT1 = 2, | ||
| PORT2 = 3, | ||
| ADC10 = 5, | ||
| USCIAB0TX = 6, | ||
| USCIAB0RX = 7, | ||
| TIMER0_A1 = 8, | ||
| TIMER0_A0 = 9, | ||
| WDT = 10, | ||
| COMPARATORA = 11, | ||
| TIMER1_A1 = 12, | ||
| TIMER1_A0 = 13, | ||
| NMI = 14, | ||
| } else if (std.mem.eql(u8, config.chip_name, "MSP430F5529")) enum(u6) { | ||
| RTC = 41, | ||
| PORT2 = 42, | ||
| TIMER2_A1 = 43, | ||
| TIMER2_A0 = 44, | ||
| USCI_B1 = 45, | ||
| USCI_A1 = 46, | ||
| PORT1 = 47, | ||
| TIMER1_A1 = 48, | ||
| TIMER1_A0 = 49, | ||
| DMA = 50, | ||
| USB_UBM = 51, | ||
| TIMER0_A1 = 52, | ||
| TIMER0_A0 = 53, | ||
| ADC12 = 54, | ||
| USCI_B0 = 55, | ||
| USCI_A0 = 56, | ||
| WDT = 57, | ||
| TIMER0_B1 = 58, | ||
| TIMER0_B0 = 59, | ||
| COMP_B = 60, | ||
| UNMI = 61, | ||
| SYSNMI = 62, | ||
| }; | ||
|
|
||
| pub const InterruptOptions = microzig.utilities.GenerateInterruptOptions(&.{ | ||
| .{ .InterruptEnum = Interrupt, .HandlerFn = interrupt.Handler }, | ||
| }); | ||
|
|
||
| // A placeholder for now | ||
| const VectorTable = if (std.mem.eql(u8, config.cpu_name, "MSP430X")) | ||
| extern struct { | ||
| table: [63]interrupt.Handler = [_]interrupt.Handler{.{ .c = interrupt.unhandled }} ** 63, | ||
| RESET: interrupt.Handler, | ||
| } | ||
| else if (std.mem.eql(u8, config.cpu_name, "MSP430")) | ||
| extern struct { | ||
| table: [15]interrupt.Handler = [_]interrupt.Handler{.{ .c = interrupt.unhandled }} ** 15, | ||
| RESET: interrupt.Handler, | ||
| } | ||
| else | ||
| @compileError("Invalid CPU, there are only MSP430 and MSP430X: " ++ config.cpu_name); | ||
|
|
||
| const vector_table: VectorTable = vector_table: { | ||
| var tmp: VectorTable = .{ | ||
| .RESET = .{ .c = startup_logic._start }, | ||
| }; | ||
|
|
||
| // Apply interrupts | ||
| for (@typeInfo(@TypeOf(microzig.options.interrupts)).@"struct".fields) |field| { | ||
| const maybe_handler = @field(microzig.options.interrupts, field.name); | ||
| tmp.table[@intFromEnum(@field(Interrupt, field.name))] = | ||
| maybe_handler orelse .{ .c = interrupt.unhandled }; | ||
| } | ||
|
|
||
| break :vector_table tmp; | ||
| }; | ||
|
|
||
| pub const interrupt = struct { | ||
| // NOTE: We do not have an msp430 interrupt calling convention yet. This | ||
| // means that you need to exit the ISR with RETI | ||
| pub const Handler = extern union { | ||
| naked: *const fn () callconv(.naked) void, | ||
| c: *const fn () callconv(.c) void, | ||
| }; | ||
|
|
||
| pub fn unhandled() callconv(.c) void { | ||
| while (true) {} | ||
| } | ||
|
|
||
| pub inline fn disable_interrupts() void { | ||
| // including a nop because it's suggested in literature | ||
| asm volatile ( | ||
| \\DINT | ||
| \\NOP | ||
| ::: .{}); | ||
| } | ||
|
|
||
| pub inline fn enable_interrupts() void { | ||
| // including a nop because it's suggested in literature | ||
| asm volatile ( | ||
| \\NOP | ||
| \\EINT | ||
| ::: .{}); | ||
| } | ||
| }; | ||
|
|
||
| pub const startup_logic = struct { | ||
| extern fn microzig_main() noreturn; | ||
|
|
||
| pub fn _start() callconv(.c) noreturn { | ||
| const stack_init = comptime microzig.utilities.get_end_of_stack(); | ||
| asm volatile ( | ||
| \\MOV %[stack_init], SP | ||
| : | ||
| : [stack_init] "i" (@as(u32, @intFromPtr(stack_init))), | ||
| ); | ||
|
|
||
| microzig.utilities.initialize_system_memories(.auto); | ||
| @call(.never_inline, microzig_main, .{}); | ||
| } | ||
| }; | ||
|
|
||
| pub fn export_startup_logic() void { | ||
| @export(&vector_table, .{ | ||
| .name = "_vector_table", | ||
| .section = ".isr_vector", | ||
| .linkage = .strong, | ||
| }); | ||
| @export(&startup_logic._start, .{ | ||
| .name = "_start", | ||
| }); | ||
| } | ||
|
|
||
| export fn memset(dest: [*]u8, ch: u8, count: usize) callconv(.c) [*]u8 { | ||
| // dest: R12 | ||
| _ = ch; // R13 | ||
| _ = count; // R14 | ||
| asm volatile ( | ||
| \\ MOV R12, R5 | ||
| \\ ADD R5, R14 | ||
| \\memset_loop: | ||
| \\ CMP R5, R12 | ||
| \\ JEQ memset_done | ||
| \\ MOV.B R13, @R12 | ||
| \\ INC R12 | ||
| \\ JMP memset_loop | ||
| \\memset_done: | ||
| \\ SUB R12, R14 | ||
| ::: .{ | ||
| .r5 = true, | ||
| // r12 doesn't go in the clobbers because it is restored before exiting | ||
| .r13 = true, | ||
| .r14 = true, | ||
| }); | ||
|
|
||
| return dest; | ||
| } | ||
|
|
||
| export fn memcpy(dest: [*]u8, src: [*]const u8, count: usize) callconv(.c) [*]u8 { | ||
| // dest: R12 | ||
| _ = src; // R13 | ||
| _ = count; // R14 | ||
| asm volatile ( | ||
| \\ MOV R5, R12 | ||
| \\ ADD R5, R14 | ||
| \\memcpy_loop: | ||
| \\ CMP R5, R12 | ||
| \\ JEQ memcpy_done | ||
| \\ MOV.B @R13, @R12 | ||
| \\ INC R12 | ||
| \\ INC R13 | ||
| \\memcpy_done: | ||
| \\ SUB R12, R14 | ||
| ::: .{ | ||
| .r5 = true, | ||
| // r12 doesn't go in the clobbers because it is restored before exiting | ||
| .r13 = true, | ||
| .r14 = true, | ||
| }); | ||
|
|
||
| return dest; | ||
| } | ||
|
|
||
| export fn abort() callconv(.c) void { | ||
| @breakpoint(); | ||
| while (true) {} | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| const msp430 = @import("msp430.zig"); | ||
| pub const interrupt = msp430.interrupt; | ||
| pub const export_startup_logic = msp430.export_startup_logic; |
Empty file.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| const std = @import("std"); | ||
| const microzig = @import("microzig"); | ||
|
|
||
| const MicroBuild = microzig.MicroBuild(.{ | ||
| .msp430 = true, | ||
| }); | ||
|
|
||
| pub fn build(b: *std.Build) void { | ||
| const optimize = b.standardOptimizeOption(.{}); | ||
|
|
||
| const mz_dep = b.dependency("microzig", .{}); | ||
| const mb = MicroBuild.init(b, mz_dep) orelse return; | ||
|
|
||
| const targets = &.{ | ||
| mb.ports.msp430.boards.launch_pad_msp430f5529, | ||
| mb.ports.msp430.boards.launch_pad_msp430g2553, | ||
| }; | ||
|
|
||
| inline for (targets) |target| { | ||
| const empty = mb.add_firmware(.{ | ||
| .name = b.fmt("empty_{s}", .{target.chip.name}), | ||
| .target = target, | ||
| .optimize = optimize, | ||
| .root_source_file = b.path("src/empty.zig"), | ||
| }); | ||
|
|
||
| const blinky = mb.add_firmware(.{ | ||
| .name = b.fmt("blinky_{s}", .{target.chip.name}), | ||
| .target = target, | ||
| .optimize = optimize, | ||
| .root_source_file = b.path("src/blinky.zig"), | ||
| }); | ||
|
|
||
| mb.install_firmware(empty, .{}); | ||
| mb.install_firmware(blinky, .{}); | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| .{ | ||
| .name = .msp430, | ||
| .version = "0.0.1", | ||
| .minimum_zig_version = "0.15.2", | ||
| .fingerprint = 0x21359f74332f7448, | ||
| .dependencies = .{ | ||
| .microzig = .{ .path = "../../.." }, | ||
| }, | ||
| .paths = .{ | ||
| "README.md", | ||
| "build.zig", | ||
| "build.zig.zon", | ||
| "src", | ||
| }, | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.