1use core::fmt;
8
9use crate::arm::Cortex;
10use crate::arm::ap::{IDR_AHB_AP_CORTEX_M0, IDR_AHB_AP_CORTEX_M33, Idr};
11use crate::arm::dp::IdCode;
12
13const RP2040_FLASH_BASE: u32 = 0x1000_0000;
15
16const RP2040_RAM_BASE: u32 = 0x2000_0000;
18
19const RP2350_FLASH_BASE: u32 = 0x1000_0000;
21
22const RP2350_RAM_BASE: u32 = 0x2000_0000;
24
25pub const RP2040_CHIP_ID: u32 = 0x10002927;
27pub const RP2040_CHIP_ID_ADDR: u32 = 0x40000000;
28
29pub const RP2040_CPU_ID: u32 = 0x410CC601;
31pub const RP2040_CPU_ID_ADDR: u32 = 0xE000ED00;
32
33#[derive(Debug, Clone, Copy, PartialEq, Eq)]
34pub enum RpLine {
35 Rp2040,
36 Rp2350,
37 Unknown,
38}
39
40impl RpLine {
41 pub fn known(&self) -> bool {
43 !matches!(self, RpLine::Unknown)
44 }
45
46 pub fn ram_size_bytes(&self) -> Option<u32> {
48 self.ram_size_kb().map(|size| size * 1024)
49 }
50
51 pub fn ram_size_kb(&self) -> Option<u32> {
53 match self {
54 RpLine::Rp2040 => Some(264),
55 RpLine::Rp2350 => Some(512),
56 RpLine::Unknown => None,
57 }
58 }
59
60 pub fn expected_idr(&self) -> Option<Idr> {
62 match self {
63 RpLine::Rp2040 => Some(IDR_AHB_AP_CORTEX_M0),
64 RpLine::Rp2350 => Some(IDR_AHB_AP_CORTEX_M33),
65 RpLine::Unknown => None,
66 }
67 }
68}
69
70impl fmt::Display for RpLine {
71 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
72 match self {
73 RpLine::Rp2040 => write!(f, "RP2040"),
74 RpLine::Rp2350 => write!(f, "RP2350"),
75 RpLine::Unknown => write!(f, "Unknown"),
76 }
77 }
78}
79
80#[derive(Debug, Clone, Copy)]
82pub struct RpDetails {
83 line: RpLine,
84}
85
86impl RpDetails {
87 pub fn from_line(line: RpLine) -> Self {
89 Self { line }
90 }
91
92 pub fn line(&self) -> RpLine {
94 self.line
95 }
96
97 pub fn from_idcode(idcode: IdCode) -> Option<Self> {
99 match idcode {
100 Cortex::IDCODE_M0 => Some(RpDetails {
101 line: RpLine::Rp2040,
102 }),
103 Cortex::IDCODE_M33 => Some(RpDetails {
104 line: RpLine::Rp2350,
105 }),
106 _ => None,
107 }
108 }
109
110 pub fn flash_base(&self) -> Option<u32> {
112 match self.line {
113 RpLine::Rp2040 => Some(RP2040_FLASH_BASE),
114 RpLine::Rp2350 => Some(RP2350_FLASH_BASE),
115 RpLine::Unknown => None,
116 }
117 }
118
119 pub fn ram_base(&self) -> Option<u32> {
121 match self.line {
122 RpLine::Rp2040 => Some(RP2040_RAM_BASE),
123 RpLine::Rp2350 => Some(RP2350_RAM_BASE),
124 RpLine::Unknown => None,
125 }
126 }
127
128 pub fn expected_idr(&self) -> Option<Idr> {
134 self.line.expected_idr()
135 }
136}
137
138impl fmt::Display for RpDetails {
139 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
140 write!(f, "{}", self.line)
141 }
142}