MerryChrysler/src/main.zig

137 lines
4.2 KiB
Zig

const std = @import("std");
const microzig = @import("microzig");
const rp2040 = microzig.hal;
const gpio = rp2040.gpio;
const clocks = rp2040.clocks;
const time = rp2040.time;
const regs = microzig.chip.registers;
const multicore = rp2040.multicore;
const pwm = rp2040.pwm;
const pin_config = rp2040.pins.GlobalConfiguration{
.GPIO8 = .{ .name = "channel0", .function = .PWM4_A },
.GPIO9 = .{ .name = "channel1", .function = .PWM4_B },
.GPIO10 = .{ .name = "channel2", .function = .PWM5_A },
.GPIO3 = .{ .name = "channel3", .function = .PWM1_B },
.GPIO4 = .{ .name = "channel4", .function = .PWM2_A },
.GPIO5 = .{ .name = "channel5", .function = .PWM2_B },
.GPIO25 = .{ .name = "channelInt", .function = .PWM4_B },
};
const Channels = enum { Channel0, Channel1, Channel2, Channel3, Channel4, Channel5, ChannelInt };
const Animations = enum { Candle, Pulse };
const ChannelConfig = struct {
channel: Channels,
animation: Animations,
step: u16,
last_value: u16,
rand_src: std.rand.DefaultPrng,
pub fn init(channel: Channels, animation: Animations) ChannelConfig {
return ChannelConfig{ .channel = channel, .animation = animation, .step = 0, .rand_src = std.rand.DefaultPrng.init(0), .last_value = 0 };
}
fn nextLevelPulse(self: *ChannelConfig) u16 {
if (self.step < 127) {
return self.step;
} else {
return 255 - self.step;
}
}
fn nextLevelCandle(self: *ChannelConfig) u16 {
const Levels = enum(u16) { VeryDim = 255 / 8, Dim = 255 / 4, Half = 255 / 2, Bright = 255 * 3 / 4, FullBright = 255 };
if ((self.step % 10) == 0) {
return @enumToInt(self.rand_src.random().enumValue(Levels));
} else {
return self.last_value;
}
}
pub fn nextLevel(self: *ChannelConfig) u16 {
self.step = ((self.step + 1) % 255);
var value = switch (self.animation) {
Animations.Pulse => self.nextLevelPulse(),
Animations.Candle => self.nextLevelCandle(),
};
self.last_value = value;
return value;
}
};
pub fn cfgChannel(pin: anytype) !void {
pin.slice().setWrap(256);
pin.setLevel(0);
pin.slice().enable();
}
pub fn main() !void {
const pins = pin_config.apply();
try cfgChannel(pins.channel0);
try cfgChannel(pins.channel1);
try cfgChannel(pins.channel2);
try cfgChannel(pins.channel3);
try cfgChannel(pins.channel4);
try cfgChannel(pins.channel5);
try cfgChannel(pins.channelInt);
var cfg = [_]ChannelConfig{
ChannelConfig.init(Channels.ChannelInt, Animations.Candle),
ChannelConfig.init(Channels.Channel0, Animations.Candle),
ChannelConfig.init(Channels.Channel1, Animations.Pulse),
ChannelConfig.init(Channels.Channel2, Animations.Candle),
ChannelConfig.init(Channels.Channel3, Animations.Candle),
ChannelConfig.init(Channels.Channel4, Animations.Candle),
ChannelConfig.init(Channels.Channel5, Animations.Candle),
};
while (true) {
for (cfg) |*channel| {
var level = channel.nextLevel();
switch (channel.channel) {
Channels.ChannelInt => {
pins.channelInt.setLevel(level);
},
Channels.Channel0 => {
pins.channel0.setLevel(level);
},
Channels.Channel1 => {
pins.channel1.setLevel(level);
},
Channels.Channel2 => {
pins.channel2.setLevel(level);
},
Channels.Channel3 => {
pins.channel3.setLevel(level);
},
Channels.Channel4 => {
pins.channel4.setLevel(level);
},
Channels.Channel5 => {
pins.channel5.setLevel(level);
},
}
}
time.sleepMs(10);
}
}
test "Test Candle Animations" {
var channel = ChannelConfig.init(Channels.ChannelInt, Animations.Candle);
const val1 = channel.nextLevel();
channel.step = 9;
const val2 = channel.nextLevel();
try std.testing.expect(val1 != val2);
}