137 lines
4.2 KiB
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);
|
|
}
|