use core::fmt;
use deku::prelude::*;
#[cfg(not(feature = "std"))]
use alloc::string::String;
use crate::SdrrInfo;
pub enum Source {
Flash,
Ram,
}
#[derive(
Debug, Clone, Copy, PartialEq, Eq, DekuRead, DekuWrite, serde::Serialize, serde::Deserialize,
)]
#[deku(id_type = "u16", ctx = "endian: deku::ctx::Endian")]
pub enum McuLine {
#[deku(id = "0x0000")]
F401DE,
#[deku(id = "0x0001")]
F405,
#[deku(id = "0x0002")]
F411,
#[deku(id = "0x0003")]
F446,
#[deku(id = "0x0004")]
F401BC,
#[deku(id = "0x0005")]
Rp2350,
}
impl fmt::Display for McuLine {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
McuLine::F401DE => write!(f, "STM32F401DE"),
McuLine::F405 => write!(f, "STM32F405"),
McuLine::F411 => write!(f, "STM32F411"),
McuLine::F446 => write!(f, "STM32F446"),
McuLine::F401BC => write!(f, "STM32F401BC"),
McuLine::Rp2350 => write!(f, "RP2350"),
}
}
}
impl McuLine {
pub fn ram_kb(&self) -> &str {
match self {
McuLine::F401DE => "96",
McuLine::F401BC => "64",
McuLine::F405 | McuLine::F411 | McuLine::F446 => "128",
McuLine::Rp2350 => "520",
}
}
pub fn chip_suffix(&self) -> &str {
match self {
McuLine::F401DE => "f401",
McuLine::F401BC => "f401",
McuLine::F405 => "f405",
McuLine::F411 => "f411",
McuLine::F446 => "f446",
McuLine::Rp2350 => "rp2350",
}
}
}
#[derive(
Debug, Clone, Copy, PartialEq, Eq, DekuRead, DekuWrite, serde::Serialize, serde::Deserialize,
)]
#[deku(id_type = "u16", ctx = "endian: deku::ctx::Endian")]
pub enum McuStorage {
#[deku(id = "0")]
Storage8,
#[deku(id = "1")]
StorageB,
#[deku(id = "2")]
StorageC,
#[deku(id = "3")]
StorageD,
#[deku(id = "4")]
StorageE,
#[deku(id = "5")]
StorageF,
#[deku(id = "6")]
StorageG,
#[deku(id = "7")]
Storage2MB,
}
impl McuStorage {
pub fn size_kb(&self) -> usize {
match self {
McuStorage::Storage8 => 64,
McuStorage::StorageB => 128,
McuStorage::StorageC => 256,
McuStorage::StorageD => 384,
McuStorage::StorageE => 512,
McuStorage::StorageF => 768,
McuStorage::StorageG => 1024,
McuStorage::Storage2MB => 2048,
}
}
pub fn kb(&self) -> &str {
match self {
McuStorage::Storage8 => "64",
McuStorage::StorageB => "128",
McuStorage::StorageC => "256",
McuStorage::StorageD => "384",
McuStorage::StorageE => "512",
McuStorage::StorageF => "768",
McuStorage::StorageG => "1024",
McuStorage::Storage2MB => "2048",
}
}
pub fn package_code(&self) -> &str {
match self {
McuStorage::Storage8 => "8",
McuStorage::StorageB => "B",
McuStorage::StorageC => "C",
McuStorage::StorageD => "D",
McuStorage::StorageE => "E",
McuStorage::StorageF => "F",
McuStorage::StorageG => "G",
McuStorage::Storage2MB => "2MB",
}
}
pub fn stm32_suffix(&self) -> &str {
match self {
McuStorage::Storage8 => "R8",
McuStorage::StorageB => "RB",
McuStorage::StorageC => "RC",
McuStorage::StorageD => "RD",
McuStorage::StorageE => "RE",
McuStorage::StorageF => "RF",
McuStorage::StorageG => "RG",
McuStorage::Storage2MB => "",
}
}
}
impl fmt::Display for McuStorage {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.package_code())
}
}
#[derive(
Debug, Clone, Copy, PartialEq, Eq, DekuRead, DekuWrite, serde::Serialize, serde::Deserialize,
)]
#[deku(id_type = "u8")]
pub enum SdrrRomType {
#[deku(id = "0")]
Rom2316,
#[deku(id = "1")]
Rom2332,
#[deku(id = "2")]
Rom2364,
#[deku(id = "3")]
Rom23128,
#[deku(id = "4")]
Rom23256,
#[deku(id = "5")]
Rom23512,
#[deku(id = "6")]
Rom2704,
#[deku(id = "7")]
Rom2708,
#[deku(id = "8")]
Rom2716,
#[deku(id = "9")]
Rom2732,
#[deku(id = "10")]
Rom2764,
#[deku(id = "11")]
Rom27128,
#[deku(id = "12")]
Rom27256,
#[deku(id = "13")]
Rom27512,
#[deku(id = "14")]
Rom231024,
#[deku(id = "15")]
Rom27C010,
#[deku(id = "16")]
Rom27C020,
#[deku(id = "17")]
Rom27C040,
#[deku(id = "18")]
Rom27C080,
#[deku(id = "19")]
Rom27C400,
#[deku(id = "20")]
Ram6116,
#[deku(id = "21")]
Rom27C301,
#[deku(id = "22")]
SystemPlugin,
#[deku(id = "23")]
UserPlugin,
#[deku(id = "24")]
PioPlugin,
#[deku(id = "25")]
RomSst39sf040,
}
impl fmt::Display for SdrrRomType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
SdrrRomType::Rom2316 => write!(f, "2316"),
SdrrRomType::Rom2332 => write!(f, "2332"),
SdrrRomType::Rom2364 => write!(f, "2364"),
SdrrRomType::Rom23128 => write!(f, "23128"),
SdrrRomType::Rom23256 => write!(f, "23256"),
SdrrRomType::Rom23512 => write!(f, "23512"),
SdrrRomType::Rom2704 => write!(f, "2704"),
SdrrRomType::Rom2708 => write!(f, "2708"),
SdrrRomType::Rom2716 => write!(f, "2716"),
SdrrRomType::Rom2732 => write!(f, "2732"),
SdrrRomType::Rom2764 => write!(f, "2764"),
SdrrRomType::Rom27128 => write!(f, "27128"),
SdrrRomType::Rom27256 => write!(f, "27256"),
SdrrRomType::Rom27512 => write!(f, "27512"),
SdrrRomType::Rom231024 => write!(f, "231024"),
SdrrRomType::Rom27C010 => write!(f, "27C010"),
SdrrRomType::Rom27C020 => write!(f, "27C020"),
SdrrRomType::Rom27C040 => write!(f, "27C040"),
SdrrRomType::Rom27C080 => write!(f, "27C080"),
SdrrRomType::Rom27C400 => write!(f, "27C400"),
SdrrRomType::Ram6116 => write!(f, "6116 (RAM)"),
SdrrRomType::Rom27C301 => write!(f, "27C301"),
SdrrRomType::SystemPlugin => write!(f, "System Plugin"),
SdrrRomType::UserPlugin => write!(f, "User Plugin"),
SdrrRomType::PioPlugin => write!(f, "PIO Plugin"),
SdrrRomType::RomSst39sf040 => write!(f, "SST39SF040"),
}
}
}
impl SdrrRomType {
pub fn rom_size(&self) -> usize {
if self == &SdrrRomType::Rom2704 {
return 512;
}
self.rom_size_kb() * 1024
}
pub fn rom_size_kb(&self) -> usize {
match self {
SdrrRomType::Rom2316 => 2,
SdrrRomType::Rom2332 => 4,
SdrrRomType::Rom2364 => 8,
SdrrRomType::Rom23128 => 16,
SdrrRomType::Rom23256 => 32,
SdrrRomType::Rom23512 => 64,
SdrrRomType::Rom2704 => 0,
SdrrRomType::Rom2708 => 1,
SdrrRomType::Rom2716 => 2,
SdrrRomType::Rom2732 => 4,
SdrrRomType::Rom2764 => 8,
SdrrRomType::Rom27128 => 16,
SdrrRomType::Rom27256 => 32,
SdrrRomType::Rom27512 => 64,
SdrrRomType::Rom231024 => 128,
SdrrRomType::Rom27C010 => 128,
SdrrRomType::Rom27C020 => 256,
SdrrRomType::Rom27C040 => 512,
SdrrRomType::Rom27C080 => 1024,
SdrrRomType::Rom27C400 => 512,
SdrrRomType::Ram6116 => 2,
SdrrRomType::Rom27C301 => 128,
SdrrRomType::SystemPlugin => 64,
SdrrRomType::UserPlugin => 64,
SdrrRomType::PioPlugin => 64,
SdrrRomType::RomSst39sf040 => 512,
}
}
pub fn rom_pins(&self) -> usize {
match self {
SdrrRomType::Rom2316 => 24,
SdrrRomType::Rom2332 => 24,
SdrrRomType::Rom2364 => 24,
SdrrRomType::Rom23128 => 28,
SdrrRomType::Rom23256 => 28,
SdrrRomType::Rom23512 => 28,
SdrrRomType::Rom2704 => 24,
SdrrRomType::Rom2708 => 24,
SdrrRomType::Rom2716 => 24,
SdrrRomType::Rom2732 => 24,
SdrrRomType::Rom2764 => 28,
SdrrRomType::Rom27128 => 28,
SdrrRomType::Rom27256 => 28,
SdrrRomType::Rom27512 => 28,
SdrrRomType::Rom231024 => 28,
SdrrRomType::Rom27C010 => 32,
SdrrRomType::Rom27C020 => 32,
SdrrRomType::Rom27C040 => 32,
SdrrRomType::Rom27C080 => 32,
SdrrRomType::Rom27C400 => 40,
SdrrRomType::Ram6116 => 24,
SdrrRomType::Rom27C301 => 32,
SdrrRomType::SystemPlugin => 0,
SdrrRomType::UserPlugin => 0,
SdrrRomType::PioPlugin => 0,
SdrrRomType::RomSst39sf040 => 512,
}
}
pub fn max_addr(&self) -> u32 {
(self.rom_size() - 1) as u32
}
pub fn supports_cs2(&self) -> bool {
match self {
SdrrRomType::Rom2316 => true,
SdrrRomType::Rom2332 => true,
SdrrRomType::Rom2364 => false,
SdrrRomType::Rom23128 => true,
SdrrRomType::Rom23256 => true,
SdrrRomType::Rom23512 => false,
SdrrRomType::Rom2704 => false,
SdrrRomType::Rom2708 => false,
SdrrRomType::Rom2716 => false,
SdrrRomType::Rom2732 => false,
SdrrRomType::Rom2764 => false,
SdrrRomType::Rom27128 => false,
SdrrRomType::Rom27256 => false,
SdrrRomType::Rom27512 => false,
SdrrRomType::Rom231024 => false,
SdrrRomType::Rom27C010 => false,
SdrrRomType::Rom27C020 => false,
SdrrRomType::Rom27C040 => false,
SdrrRomType::Rom27C080 => false,
SdrrRomType::Rom27C400 => false,
SdrrRomType::Ram6116 => false,
SdrrRomType::Rom27C301 => false,
SdrrRomType::SystemPlugin => false,
SdrrRomType::UserPlugin => false,
SdrrRomType::PioPlugin => false,
SdrrRomType::RomSst39sf040 => false,
}
}
pub fn supports_cs3(&self) -> bool {
match self {
SdrrRomType::Rom2316 => true,
SdrrRomType::Rom2332 => false,
SdrrRomType::Rom2364 => false,
SdrrRomType::Rom23128 => true,
SdrrRomType::Rom23256 => false,
SdrrRomType::Rom23512 => false,
SdrrRomType::Rom2704 => false,
SdrrRomType::Rom2708 => false,
SdrrRomType::Rom2716 => false,
SdrrRomType::Rom2732 => false,
SdrrRomType::Rom2764 => false,
SdrrRomType::Rom27128 => false,
SdrrRomType::Rom27256 => false,
SdrrRomType::Rom27512 => false,
SdrrRomType::Rom231024 => false,
SdrrRomType::Rom27C010 => false,
SdrrRomType::Rom27C020 => false,
SdrrRomType::Rom27C040 => false,
SdrrRomType::Rom27C080 => false,
SdrrRomType::Rom27C400 => false,
SdrrRomType::Ram6116 => false,
SdrrRomType::Rom27C301 => false,
SdrrRomType::SystemPlugin => false,
SdrrRomType::UserPlugin => false,
SdrrRomType::PioPlugin => false,
SdrrRomType::RomSst39sf040 => false,
}
}
}
#[derive(
Debug, Clone, Copy, PartialEq, Eq, DekuRead, DekuWrite, serde::Serialize, serde::Deserialize,
)]
#[deku(id_type = "u8")]
pub enum SdrrCsState {
#[deku(id = "0")]
ActiveLow,
#[deku(id = "1")]
ActiveHigh,
#[deku(id = "2")]
NotUsed,
}
impl fmt::Display for SdrrCsState {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
SdrrCsState::ActiveLow => write!(f, "Active Low"),
SdrrCsState::ActiveHigh => write!(f, "Active High"),
SdrrCsState::NotUsed => write!(f, "Not Used"),
}
}
}
#[derive(
Debug, Clone, Copy, PartialEq, Eq, DekuRead, DekuWrite, serde::Serialize, serde::Deserialize,
)]
#[deku(id_type = "u8")]
pub enum SdrrServe {
#[deku(id = "0")]
TwoCsOneAddr,
#[deku(id = "1")]
AddrOnCs,
#[deku(id = "2")]
AddrOnAnyCs,
}
impl fmt::Display for SdrrServe {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
SdrrServe::TwoCsOneAddr => write!(f, "A = Two CS checks for every address check"),
SdrrServe::AddrOnCs => write!(f, "B = Check address only when CS active"),
SdrrServe::AddrOnAnyCs => write!(f, "C = Check address on any CS active"),
}
}
}
#[derive(
Debug, Clone, Copy, PartialEq, Eq, DekuRead, DekuWrite, serde::Serialize, serde::Deserialize,
)]
#[deku(id_type = "u8")]
pub enum SdrrMcuPort {
#[deku(id = "0x00")]
None,
#[deku(id = "0x01")]
PortA,
#[deku(id = "0x02")]
PortB,
#[deku(id = "0x03")]
PortC,
#[deku(id = "0x04")]
PortD,
#[deku(id = "0x05")]
Port0,
}
impl fmt::Display for SdrrMcuPort {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
SdrrMcuPort::None => write!(f, "None"),
SdrrMcuPort::PortA => write!(f, "A"),
SdrrMcuPort::PortB => write!(f, "B"),
SdrrMcuPort::PortC => write!(f, "C"),
SdrrMcuPort::PortD => write!(f, "D"),
SdrrMcuPort::Port0 => write!(f, "0"),
}
}
}
impl From<u8> for SdrrMcuPort {
fn from(value: u8) -> Self {
match value {
0x00 => SdrrMcuPort::None,
0x01 => SdrrMcuPort::PortA,
0x02 => SdrrMcuPort::PortB,
0x03 => SdrrMcuPort::PortC,
0x04 => SdrrMcuPort::PortD,
0x05 => SdrrMcuPort::Port0,
_ => SdrrMcuPort::None,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct SdrrCsSet {
cs1: bool,
cs2: Option<bool>,
cs3: Option<bool>,
x1: Option<bool>,
x2: Option<bool>,
}
impl SdrrCsSet {
pub fn new(
cs1: bool,
cs2: Option<bool>,
cs3: Option<bool>,
x1: Option<bool>,
x2: Option<bool>,
) -> Self {
Self {
cs1,
cs2,
cs3,
x1,
x2,
}
}
pub fn cs1(&self) -> bool {
self.cs1
}
pub fn cs2(&self) -> Option<bool> {
self.cs2
}
pub fn cs3(&self) -> Option<bool> {
self.cs3
}
pub fn x1(&self) -> Option<bool> {
self.x1
}
pub fn x2(&self) -> Option<bool> {
self.x2
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct SdrrLogicalAddress {
addr: u32,
cs_set: SdrrCsSet,
}
impl SdrrLogicalAddress {
pub fn new(addr: u32, cs_set: SdrrCsSet) -> Self {
Self { addr, cs_set }
}
pub fn mangle(&self, info: &SdrrInfo) -> Result<u32, String> {
info.mangle_address(self)
}
pub fn addr(&self) -> u32 {
self.addr
}
pub fn cs_set(&self) -> &SdrrCsSet {
&self.cs_set
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SdrrAddress {
Raw(u32),
Logical(SdrrLogicalAddress),
}
impl SdrrAddress {
pub fn from_raw(addr: u32) -> Self {
Self::Raw(addr)
}
pub fn from_logical(addr: u32, cs_set: &SdrrCsSet) -> Self {
Self::Logical(SdrrLogicalAddress::new(addr, *cs_set))
}
}
impl fmt::Display for SdrrAddress {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if f.alternate() {
match self {
SdrrAddress::Raw(addr) => write!(f, "Raw address: 0x{:04X}", addr),
SdrrAddress::Logical(logical) => write!(
f,
"Logical address: 0x{:04X} (CS1: {}, CS2: {:?}, CS3: {:?}, X1: {:?}, X2: {:?})",
logical.addr,
logical.cs_set.cs1(),
logical.cs_set.cs2(),
logical.cs_set.cs3(),
logical.cs_set.x1(),
logical.cs_set.x2()
),
}
} else {
match self {
SdrrAddress::Raw(addr) => write!(f, "0x{:04X}", addr),
SdrrAddress::Logical(logical) => write!(f, "0x{:04X}", logical.addr),
}
}
}
}
#[repr(u8)]
#[derive(
Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize, DekuRead, DekuWrite,
)]
#[deku(id_type = "u8")]
pub enum FireVreg {
#[deku(id = "0x00")]
V0_55 = 0x00,
#[deku(id = "0x01")]
V0_60 = 0x01,
#[deku(id = "0x02")]
V0_65 = 0x02,
#[deku(id = "0x03")]
V0_70 = 0x03,
#[deku(id = "0x04")]
V0_75 = 0x04,
#[deku(id = "0x05")]
V0_80 = 0x05,
#[deku(id = "0x06")]
V0_85 = 0x06,
#[deku(id = "0x07")]
V0_90 = 0x07,
#[deku(id = "0x08")]
V0_95 = 0x08,
#[deku(id = "0x09")]
V1_00 = 0x09,
#[deku(id = "0x0A")]
V1_05 = 0x0A,
#[deku(id = "0x0B")]
V1_10 = 0x0B,
#[deku(id = "0x0C")]
V1_15 = 0x0C,
#[deku(id = "0x0D")]
V1_20 = 0x0D,
#[deku(id = "0x0E")]
V1_25 = 0x0E,
#[deku(id = "0x0F")]
V1_30 = 0x0F,
#[deku(id = "0x10")]
V1_35 = 0x10,
#[deku(id = "0x11")]
V1_40 = 0x11,
#[deku(id = "0x12")]
V1_50 = 0x12,
#[deku(id = "0x13")]
V1_60 = 0x13,
#[deku(id = "0x14")]
V1_65 = 0x14,
#[deku(id = "0x15")]
V1_70 = 0x15,
#[deku(id = "0x16")]
V1_80 = 0x16,
#[deku(id = "0x17")]
V1_90 = 0x17,
#[deku(id = "0x18")]
V2_00 = 0x18,
#[deku(id = "0x19")]
V2_35 = 0x19,
#[deku(id = "0x1A")]
V2_50 = 0x1A,
#[deku(id = "0x1B")]
V2_65 = 0x1B,
#[deku(id = "0x1C")]
V2_80 = 0x1C,
#[deku(id = "0x1D")]
V3_00 = 0x1D,
#[deku(id = "0x1E")]
V3_15 = 0x1E,
#[deku(id = "0x1F")]
V3_30 = 0x1F,
#[deku(id = "0xFE")]
None = 0xFE,
#[deku(id = "0xFF")]
Stock = 0xFF,
}
#[repr(u8)]
#[derive(
Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, Eq, DekuRead, DekuWrite,
)]
#[deku(id_type = "u8")]
pub enum BitMode {
#[deku(id = "0x01")]
Mode8 = 0x01,
#[deku(id = "0x02")]
Mode16 = 0x02,
}
#[repr(u8)]
#[derive(
Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, Eq, DekuRead, DekuWrite,
)]
#[deku(id_type = "u8")]
pub enum FireServeMode {
#[deku(id = "0x00")]
Cpu = 0x00,
#[deku(id = "0x01")]
Pio = 0x01,
}
#[repr(u8)]
#[derive(
Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, Eq, DekuRead, DekuWrite,
)]
#[deku(id_type = "u8")]
pub enum LimpMode {
#[deku(id = "0x00")]
None = 0x00,
#[deku(id = "0x01")]
NoRoms = 0x01,
#[deku(id = "0x02")]
InvalidConfig = 0x02,
#[deku(id = "0x03")]
InvalidBuild = 0x03,
}