B3CHXNO7SSVZE7CC7SDDTTFU4KSWZCE64UCVN6WP6NZZVOKNH7ZAC
IPLSYOCQIAQLB6HXL6YBJ5ZKKESCSRO7S7P5SF6I367M6HEJJRNQC
TXSGLYOVYQ77EG23PAVW62MBJRHS2WTVAVNQ3NYVBDGKNMSYS7DAC
6GJR2V3AYCEJWLBP2KMTWUNO332MG5OFEUNPCNSSNF5BJKXA3VTQC
UAB3QWX6I6PF4BRKRV6C7QKQMEYESRIALOFSOP3P5NAX2SHXABTQC
TKNYDMLX6VQSCEFDUY6VTMJPSOEOSWVC3YLDHHD7R4K4RVP3I7KAC
KIS6Z2AJQC7NOS2NAATBHNSM5G336VCPQKAZ6O5ALPNL7SSCBWDQC
AIK3NJJOAMB2QEYWLVK7B3E4ZMVGPBPPPZD2TGEBZCNM4Y6KI2XQC
JSTD3P3TDPAT7RZHMEJREQA3I5O37TZHYIRJV37IG6II3XCQM44AC
fn emf(self: anytype, dir: dcc.Direction, level: u16) !u12 {
defer rp2xxx.adc.set_enabled(false);
rp2xxx.adc.set_enabled(true);
const emf_config = main.cv.manufacturer.emf;
self.freerun();
rp2xxx.time.sleep_us(emf_config.delay_us);
rp2xxx.adc.start(.free_running);
var results: [std.math.maxInt(u8)]u12 = undefined;
for (0..emf_config.iterations) |i| {
while (rp2xxx.adc.fifo.is_empty()) {
asm volatile ("" ::: "memory");
}
results[i] = try rp2xxx.adc.fifo.pop();
// TODO: check if we should sort right here
}
switch (dir) {
.forward => self.forward(level),
.backward => self.backward(level),
}
std.sort.pdq(u12, results[0..emf_config.iterations], {}, less);
// Calculate average EMF
var sum: usize = 0;
for (emf_config.low_cutoff..emf_config.iterations - emf_config.high_cutoff) |i| {
sum += results[i];
}
const aemf = sum / (emf_config.iterations - emf_config.low_cutoff - emf_config.high_cutoff);
return @truncate(aemf);
}
// Switch to free running mode
md.freerun();
rp2xxx.time.sleep_us(100);
// Actual measurring
const emf = main.cv.manufacturer.emf;
rp2xxx.adc.start(.free_running);
var emfs: [std.math.maxInt(u8)]u12 = undefined;
for (0..emf.iterations) |i| {
if (rp2xxx.adc.fifo.has_overflowed()) {
std.log.debug("ADC overflow, clearing...", .{});
rp2xxx.adc.fifo.clear_overflowed();
}
while (rp2xxx.adc.fifo.is_empty()) {
asm volatile ("" ::: "memory");
}
emfs[i] = try rp2xxx.adc.fifo.pop();
// TODO: check if we should sort right here
}
// std.log.debug("Raw EMF values: {any}", .{emfs});
// Sort results, so we can cut out the low and high part
std.sort.pdq(u12, emfs[0..emf.iterations], {}, less);
// Calculate average EMF
var sum: u32 = 0;
for (emf.low_cutoff..emf.iterations - emf.high_cutoff) |i| {
sum += emfs[i];
}
const m1emf = sum / (emf.iterations - emf.low_cutoff - emf.high_cutoff);
// init uart logging
if (board.uart) |uart| {
uart.apply(.{
.baud_rate = 115200,
.clock_config = rp2xxx.clock_config,
});
rp2xxx.uart.init_logger(uart);
{ // UART log setup
if (board.uart) |uart| {
uart.apply(.{
.baud_rate = 115200,
.clock_config = rp2xxx.clock_config,
});
rp2xxx.uart.init_logger(uart);
}
// PWM setup
// TODO: minimum: core1.c: get_initial_level
{ // PWM setup
// 125MHz -> 25kHz
pins.speed.slice().set_wrap(@intCast(125_000_000 / (@as(u32, cv.PWM_period) * 100 + 10_000) - 1));
pins.speed.slice().enable();
pins.speed.slice().set_phase_correct(false);
pins.speed.slice().set_clk_div(1, 0);
}
// 125MHz -> 25kHz
pins.speed.slice().set_wrap(@intCast(125_000_000 / (@as(u32, cv.PWM_period) * 100 + 10_000) - 1));
pins.speed.slice().enable();
pins.speed.slice().set_phase_correct(false);
pins.speed.slice().set_clk_div(1, 0);
{ // ADC setup
rp2xxx.adc.apply(.{
.sample_frequency = null,
.round_robin = null,
.temp_sensor_enabled = false,
.fifo = .{ .dreq_enabled = false, .irq_enabled = false, .shift = false },
}); // apply calls enable too
}