Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
daurnimator committed Jan 27, 2020
1 parent d3e5050 commit e55f7a0
Show file tree
Hide file tree
Showing 3 changed files with 204 additions and 10 deletions.
1 change: 1 addition & 0 deletions riscv-zig-blink/build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub fn build(b: *Builder) void {
});
elf.setLinkerScriptPath("ld/linker.ld");
elf.setBuildMode(mode);
elf.setOutputDir(".");

const binary = b.addSystemCommand(&[_][]const u8{
"llvm-objcopy",
Expand Down
85 changes: 85 additions & 0 deletions riscv-zig-blink/src/fomu/rgb.zig
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,85 @@ pub const RGB = struct {
/// Writing to this register has no immediate effect – data isn’t written until the DAT register is written.
pub const ADDR = @intToPtr(*volatile u4, base + 0x4);

pub const Register = enum {
PWRR = 1,
PWRG = 2,
PWRB = 3,

BCRR = 5,
BCFR = 6,

CR0 = 8,
BR = 9,
ONR = 10,
OFR = 11,
};

pub fn setRegister(reg: Register, value: u8) void {
ADDR.* = @enumToInt(reg);
DAT.* = value;
}

const CR0 = packed struct {
BRMSBEXT: u2,

pwm_mode: enum(u1) {
linear = 0,

/// The Polynomial for the LFSR is X^(8) + X^(5) + X^3 + X + 1
LFSR = 1,
},

quick_stop: bool,

outskew: bool,

/// PWM output polarity
output_polarity: enum(u1) {
active_high = 0,
active_low = 1,
},

/// Flick rate for PWM (in Hz)
fr: enum(u1) {
@"125" = 0,
@"250" = 1,
},

/// LED Driver enabled?
enable: bool,
};

pub fn setControlRegister(value: CR0) void {
setRegister(.CR0, @bitCast(u8, value));
}

pub const Breathe = packed struct {
/// Breathe rate is in 128 ms increments
rate: u4,

_pad: u1 = 0,

mode: enum(u1) {
fixed = 0,
modulate = 1,
},

pwm_range_extend: bool,

enable: bool,
};

pub fn setBreatheRegister(reg: enum {
On,
Off,
}, value: Breathe) void {
setRegister(switch (reg) {
.On => .BCRR,
.Off => .BCFR,
}, @bitCast(u8, value));
}

/// Control logic for the RGB LED and LEDDA hardware PWM LED block.
pub const CTRL = @intToPtr(*volatile packed struct {
/// Enable the fading pattern?
Expand Down Expand Up @@ -52,4 +131,10 @@ pub const RGB = struct {
/// Blue
B: bool,
}, base + 0xc);

pub fn setColour(r: u8, g: u8, b: u8) void {
setRegister(.PWRR, r);
setRegister(.PWRG, g);
setRegister(.PWRB, b);
}
};
128 changes: 118 additions & 10 deletions riscv-zig-blink/src/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,131 @@ pub fn panic(message: []const u8, stack_trace: ?*builtin.StackTrace) noreturn {

fomu.messibleOutstream.print("PANIC: {}\r\n", .{message}) catch void;

// // Get LED to flash red

// // Put LED into fading mode
// fomu.RGB.CTRL.* = .{
// .EXE = true,
// .CURREN = true,
// .RGBLEDEN = true,
// .RRAW = false,
// .GRAW = false,
// .BRAW = false,
// };

// // Enable the LED driver, and set 250 Hz mode.
// fomu.RGB.setControlRegister(.{
// .enable = true,
// .fr = .@"250",
// .quick_stop = false,
// .outskew = false,
// .output_polarity = .active_high,
// .pwm_mode = .linear,
// .BRMSBEXT = 0,
// });

while (true) {}
}

pub fn main() noreturn {
// Turn on the green LED
// Turn on the RGB block and current enable, as well as enabling led control
fomu.RGB.CTRL.* = .{
.EXE = false,
.EXE = true,
.CURREN = true,
.RGBLEDEN = true,
.RRAW = true,
.GRAW = true,
.BRAW = true,
};
fomu.RGB.RAW.* = .{
.R = false,
.G = true,
.B = false,
.RRAW = false,
.GRAW = false,
.BRAW = false,
};

// Enable the LED driver, and set 250 Hz mode.
// Also set quick stop, which we'll use to switch patterns quickly.
fomu.RGB.setControlRegister(.{
.enable = true,
.fr = .@"250",
.quick_stop = true,
.outskew = false,
.output_polarity = .active_high,
.pwm_mode = .linear,
.BRMSBEXT = 0,
});

// Set clock register to 12 MHz / 64 kHz - 1
fomu.RGB.setRegister(.BR, (12000000 / 64000) - 1);

// Blink on/off time is in 32 ms increments
fomu.RGB.setRegister(.ONR, 1); // Amount of time to stay "on"
fomu.RGB.setRegister(.OFR, 1); // Amount of time to stay "off"

fomu.RGB.setBreatheRegister(.On, .{
.enable = true,
.pwm_range_extend = false,
.mode = .fixed,
.rate = 1,
});
fomu.RGB.setBreatheRegister(.Off, .{
.enable = true,
.pwm_range_extend = false,
.mode = .fixed,
.rate = 1,
});

var i: u8 = 0;
while (true) : (i +%= 1) {
colorWheel(i);
msleep(80);
}
while (true) {}
}

const Color = struct {
r: u8,
g: u8,
b: u8,
};

/// Input a value 0 to 255 to get a color value.
/// The colours are a transition r - g - b - back to r.
fn colorWheel(wheelPos: u8) void {
var c: Color = undefined;
var wp = 255 - wheelPos;
switch (wp) {
0...84 => {
c = .{
.r = 255 - wp * 3,
.g = 0,
.b = wp * 3,
};
},
85...169 => {
wp -= 85;
c = .{
.r = 0,
.g = wp * 3,
.b = 255 - wp * 3,
};
},
170...255 => {
wp -= 170;
c = .{
.r = wp * 3,
.g = 255 - wp * 3,
.b = 0,
};
},
}
fomu.RGB.setColour(c.r, c.g, c.b);
}

const SYSTEM_CLOCK_FREQUENCY = 12000000;

fn msleep(comptime ms: usize) void {
fomu.TIMER0.EN.* = false;
fomu.TIMER0.RELOAD.* = 0;
fomu.TIMER0.LOAD.* = SYSTEM_CLOCK_FREQUENCY / 1000 * ms;
fomu.TIMER0.EN.* = true;
while (true) {
fomu.TIMER0.UPDATE_VALUE.* = true;
if (fomu.TIMER0.VALUE.* == 0) break;
}
}

0 comments on commit e55f7a0

Please sign in to comment.