Skip to content

Commit

Permalink
Complete Gd32f103 Support (#203)
Browse files Browse the repository at this point in the history
* Implement gpio hal like to the stm32f103.
* Add blinky test
  • Loading branch information
asterix24 authored Jun 9, 2024
1 parent 301ac94 commit 43b2a53
Show file tree
Hide file tree
Showing 7 changed files with 493 additions and 2 deletions.
2 changes: 1 addition & 1 deletion bsp/gigadevice/gd32/build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ fn path(comptime suffix: []const u8) std.Build.LazyPath {
}

const hal = .{
.root_source_file = path("/src/hals/GD32VF103.zig"),
.root_source_file = path("/src/hals/GD32VF103/hal.zig"),
};

pub const chips = struct {
Expand Down
158 changes: 158 additions & 0 deletions bsp/gigadevice/gd32/src/hals/GD32VF103/gpio.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
const std = @import("std");
const assert = std.debug.assert;

const microzig = @import("microzig");
pub const peripherals = microzig.chip.peripherals;

const GPIOA = peripherals.GPIOA;
const GPIOB = peripherals.GPIOB;
const GPIOC = peripherals.GPIOC;
const GPIOD = peripherals.GPIOD;
const GPIOE = peripherals.GPIOE;

const GPIO = @TypeOf(GPIOA);

const log = std.log.scoped(.gpio);

pub const Function = enum {};

pub const Mode = union(enum) {
input: InputMode,
output: OutputMode,
};

pub const InputMode = enum(u2) {
analog,
floating,
pull,
reserved,
};

pub const OutputMode = enum(u2) {
general_purpose_push_pull,
general_purpose_open_drain,
alternate_function_push_pull,
alternate_function_open_drain,
};

pub const Speed = enum(u2) {
reserved,
max_10MHz,
max_2MHz,
max_50MHz,
};

pub const IrqLevel = enum(u2) {
low,
high,
fall,
rise,
};

pub const IrqCallback = fn (gpio: u32, events: u32) callconv(.C) void;

pub const Enabled = enum {
disabled,
enabled,
};

pub const Pull = enum {
up,
down,
};

// NOTE: With this current setup, every time we want to do anythting we go through a switch
// Do we want this?
pub const Pin = packed struct(u8) {
number: u4,
port: u3,
padding: u1,

pub fn init(port: u3, number: u4) Pin {
return Pin{
.number = number,
.port = port,
.padding = 0,
};
}
inline fn write_pin_config(gpio: Pin, config: u32) void {
const port = gpio.get_port();
if (gpio.number <= 7) {
const offset = @as(u5, gpio.number) << 2;
port.CTL0.raw &= ~(@as(u32, 0b1111) << offset);
port.CTL0.raw |= config << offset;
} else {
const offset = (@as(u5, gpio.number) - 8) << 2;
port.CTL1.raw &= ~(@as(u32, 0b1111) << offset);
port.CTL1.raw |= config << offset;
}
}

fn mask(gpio: Pin) u16 {
return @as(u16, 1) << gpio.number;
}

// NOTE: Im not sure I like this
// We could probably calculate an offset from GPIOA?
pub fn get_port(gpio: Pin) GPIO {
return switch (gpio.port) {
0 => GPIOA,
1 => GPIOB,
2 => GPIOC,
3 => GPIOD,
4 => GPIOE,
5 => @panic("The STM32 only has ports 0..6 (A..G)"),
6 => @panic("The STM32 only has ports 0..6 (A..G)"),
7 => @panic("The STM32 only has ports 0..6 (A..G)"),
};
}

pub inline fn set_mode(gpio: Pin, mode: Mode) void {
switch (mode) {
.input => |in| gpio.set_input_mode(in),
.output => |out| gpio.set_output_mode(out, .max_2MHz),
}
}

pub inline fn set_input_mode(gpio: Pin, mode: InputMode) void {
const m_mode = @as(u32, @intFromEnum(mode));
const config: u32 = m_mode << 2;
gpio.write_pin_config(config);
}

pub inline fn set_output_mode(gpio: Pin, mode: OutputMode, speed: Speed) void {
const s_speed = @as(u32, @intFromEnum(speed));
const m_mode = @as(u32, @intFromEnum(mode));
const config: u32 = s_speed + (m_mode << 2);
gpio.write_pin_config(config);
}

pub inline fn set_pull(gpio: Pin, pull: Pull) void {
var port = gpio.get_port();
switch (pull) {
.up => port.BOP.raw = gpio.mask(),
.down => port.BC.raw = gpio.mask(),
}
}

pub inline fn read(gpio: Pin) u1 {
const port = gpio.get_port();
return if (port.ISTAT.raw & gpio.mask() != 0)
1
else
0;
}

pub inline fn put(gpio: Pin, value: u1) void {
var port = gpio.get_port();
switch (value) {
0 => port.OCTL.raw &= ~gpio.mask(),
1 => port.OCTL.raw |= gpio.mask(),
}
}

pub inline fn toggle(gpio: Pin) void {
var port = gpio.get_port();
port.OCTL.raw ^= gpio.mask();
}
};
7 changes: 7 additions & 0 deletions bsp/gigadevice/gd32/src/hals/GD32VF103/hal.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
pub const pins = @import("pins.zig");

pub const clock_frequencies = .{
.cpu = 8_000_000, // 8 MHz
};

pub fn init() void {}
Loading

0 comments on commit 43b2a53

Please sign in to comment.