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); }