use onerom_metadata::{
FireFreq, FireVreg as OneromFireVreg, OneromFirmwareConfig, OneromFirmwareOverrides,
};
use crate::{Config, FirmwareConfig};
pub fn build_firmware_config(config: &Config) -> OneromFirmwareConfig {
OneromFirmwareConfig {
name: config.instance_name.clone(),
serial_number: config.serial_override.clone(),
}
}
const PRESENT_FIRE_CPU_FREQ: u8 = 1 << 2;
const PRESENT_FIRE_OVERCLOCK: u8 = 1 << 3;
const PRESENT_FIRE_VREG: u8 = 1 << 4;
const PRESENT_LED: u8 = 1 << 5;
const PRESENT_SWD: u8 = 1 << 6;
const VALUE_FIRE_OVERCLOCK: u8 = 1 << 1;
const VALUE_LED_ENABLED: u8 = 1 << 2;
const VALUE_SWD_ENABLED: u8 = 1 << 3;
pub fn build_firmware_overrides(overrides: &FirmwareConfig) -> OneromFirmwareOverrides {
let mut override_present = [0u8; 8];
let mut override_value = [0u8; 8];
let mut fire_freq: FireFreq = 0; let mut fire_vreg = OneromFireVreg::FireVregNone;
if let Some(fire) = &overrides.fire {
if let Some(cpu_freq) = fire.cpu_freq {
override_present[0] |= PRESENT_FIRE_CPU_FREQ;
fire_freq = cpu_freq.get();
}
if let Some(overclock) = fire.overclock {
override_present[0] |= PRESENT_FIRE_OVERCLOCK;
if overclock {
override_value[0] |= VALUE_FIRE_OVERCLOCK;
}
}
if let Some(vreg) = &fire.vreg {
override_present[0] |= PRESENT_FIRE_VREG;
fire_vreg = OneromFireVreg::try_from(vreg.clone() as u8)
.expect("onerom_config::FireVreg values are a subset of onerom_metadata::FireVreg");
}
}
if let Some(led) = &overrides.led {
override_present[0] |= PRESENT_LED;
if led.enabled {
override_value[0] |= VALUE_LED_ENABLED;
}
}
if let Some(swd) = &overrides.swd {
override_present[0] |= PRESENT_SWD;
if swd.swd_enabled {
override_value[0] |= VALUE_SWD_ENABLED;
}
}
OneromFirmwareOverrides {
override_present,
ice_freq: 0, fire_freq,
fire_vreg,
override_value,
}
}
#[cfg(test)]
mod tests {
use super::*;
use alloc::string::ToString;
use alloc::vec;
use crate::{DebugConfig, FireConfig, FireCpuFreq, FireVreg, LedConfig};
#[test]
fn firmware_config_name_and_serial() {
let config = Config {
version: 1,
name: None,
description: "test".to_string(),
detail: None,
chip_sets: vec![],
notes: None,
categories: None,
instance_name: Some("My One ROM".to_string()),
serial_override: Some("ABC123".to_string()),
boot_logging: false,
swd_enabled: true,
turbo_boot: false,
};
let fw = build_firmware_config(&config);
assert_eq!(fw.name, Some("My One ROM".to_string()));
assert_eq!(fw.serial_number, Some("ABC123".to_string()));
}
#[test]
fn firmware_overrides_empty() {
let overrides = FirmwareConfig {
ice: None,
fire: None,
led: None,
swd: None,
serve_alg_params: None,
};
let result = build_firmware_overrides(&overrides);
assert_eq!(result.override_present, [0u8; 8]);
assert_eq!(result.ice_freq, 0);
assert_eq!(result.fire_freq, 0);
assert_eq!(result.fire_vreg, OneromFireVreg::FireVregNone);
assert_eq!(result.override_value, [0u8; 8]);
}
#[test]
fn firmware_overrides_fire_led_swd() {
let overrides = FirmwareConfig {
ice: None,
fire: Some(FireConfig {
cpu_freq: Some(FireCpuFreq::mhz(200).unwrap()),
overclock: Some(true),
vreg: Some(FireVreg::V1_10),
serve_mode: None,
rom_dma_preload: true,
force_16_bit: false,
}),
led: Some(LedConfig { enabled: true }),
swd: Some(DebugConfig { swd_enabled: true }),
serve_alg_params: None,
};
let result = build_firmware_overrides(&overrides);
assert_eq!(
result.override_present[0],
PRESENT_FIRE_CPU_FREQ
| PRESENT_FIRE_OVERCLOCK
| PRESENT_FIRE_VREG
| PRESENT_LED
| PRESENT_SWD
);
assert_eq!(result.override_present[1..], [0u8; 7]);
assert_eq!(result.ice_freq, 0);
assert_eq!(result.fire_freq, 200);
assert_eq!(result.fire_vreg, OneromFireVreg::FireVreg110v);
assert_eq!(
result.override_value[0],
VALUE_FIRE_OVERCLOCK | VALUE_LED_ENABLED | VALUE_SWD_ENABLED
);
assert_eq!(result.override_value[1..], [0u8; 7]);
}
}