1use crate::pac::CHIPID;
2
3#[derive(Clone, Copy, Debug, defmt::Format)]
4pub enum EmbeddedProcessor {
5 Arm946Es,
6 Arm7Tdmi,
7 CortexM3,
8 Arm920T,
9 Arm926Ejs,
10 CortexA5,
11 CortexM4,
12}
13
14#[derive(Clone, Copy, Debug, defmt::Format)]
15pub enum Family {
16 AtSam4e,
17 AtSam4n,
18 AtSam4s,
19}
20
21#[derive(Clone, Copy, Debug, defmt::Format)]
22pub enum Model {
23 AtSam4e8c,
24 AtSam4e8e,
25 AtSam4e16c,
26 AtSam4e16e,
27
28 AtSam4n8a,
29 AtSam4n8b,
30 AtSam4n8c,
31 AtSam4n16b,
32 AtSam4n16c,
33
34 AtSam4s2a,
35 AtSam4s2b,
36 AtSam4s2c,
37 AtSam4s4a,
38 AtSam4s4b,
39 AtSam4s4c,
40 AtSam4s8b,
41 AtSam4s8c,
42 AtSam4s16b,
43 AtSam4s16c,
44 AtSam4sa16b,
45 AtSam4sa16c,
46 AtSam4sd16b,
47 AtSam4sd16c,
48 AtSam4sd32b,
49 AtSam4sd32c,
50}
51
52#[derive(Clone, Copy, Debug, defmt::Format)]
53pub enum FlashMemoryType {
54 Rom,
55 Romless,
56 Sram,
57 Flash,
58 RomFlash, }
60
61#[derive(Debug, defmt::Format)]
62pub struct ChipId {
63 version: u8,
64 embedded_processor: Option<EmbeddedProcessor>,
65 flash1_byte_size: Option<usize>,
66 flash2_byte_size: Option<usize>,
67 internal_sram_byte_size: Option<usize>,
68 family: Option<Family>,
69 model: Option<Model>,
70 flash_memory_type: Option<FlashMemoryType>,
71}
72
73impl ChipId {
74 pub fn new(chip_id: CHIPID) -> Self {
75 let cidr = chip_id.cidr.read();
76 let version = cidr.version().bits();
77 let embedded_processor = match cidr.eproc().bits() {
78 1 => Some(EmbeddedProcessor::Arm946Es),
79 2 => Some(EmbeddedProcessor::Arm7Tdmi),
80 3 => Some(EmbeddedProcessor::CortexM3),
81 4 => Some(EmbeddedProcessor::Arm920T),
82 5 => Some(EmbeddedProcessor::Arm926Ejs),
83 6 => Some(EmbeddedProcessor::CortexA5),
84 7 => Some(EmbeddedProcessor::CortexM4),
85 _ => None,
86 };
87 let flash1_byte_size = Self::decode_flash_size_from_register(cidr.nvpsiz().bits());
88 let flash2_byte_size = Self::decode_flash_size_from_register(cidr.nvpsiz2().bits());
89 let internal_sram_byte_size = match cidr.sramsiz().bits() {
90 0 => Some(48 * 1024),
91 1 => Some(192 * 1024),
92 2 => Some(2 * 1024),
93 3 => Some(6 * 1024),
94 4 => Some(24 * 1024),
95 5 => Some(4 * 1024),
96 6 => Some(80 * 1024),
97 7 => Some(160 * 1024),
98 8 => Some(8 * 1024),
99 9 => Some(16 * 1024),
100 10 => Some(32 * 1024),
101 11 => Some(64 * 1024),
102 12 => Some(128 * 1024),
103 13 => Some(256 * 1024),
104 14 => Some(96 * 1024),
105 15 => Some(512 * 1024),
106 _ => None,
107 };
108 let (family, model) = Self::decode_family_and_model(&chip_id);
109 let flash_memory_type = match cidr.nvptyp().bits() {
110 0 => Some(FlashMemoryType::Rom),
111 1 => Some(FlashMemoryType::Romless),
112 2 => Some(FlashMemoryType::Flash),
113 3 => Some(FlashMemoryType::RomFlash),
114 4 => Some(FlashMemoryType::Sram),
115 _ => None,
116 };
117
118 ChipId {
119 version,
120 embedded_processor,
121 flash1_byte_size,
122 flash2_byte_size,
123 internal_sram_byte_size,
124 family,
125 model,
126 flash_memory_type,
127 }
128 }
129
130 pub fn version(&self) -> u8 {
131 self.version
132 }
133
134 pub fn embedded_processor(&self) -> Option<EmbeddedProcessor> {
135 self.embedded_processor
136 }
137
138 pub fn flash1_byte_size(&self) -> Option<usize> {
139 self.flash1_byte_size
140 }
141
142 pub fn flash2_byte_size(&self) -> Option<usize> {
143 self.flash2_byte_size
144 }
145
146 pub fn internal_sram_size(&self) -> Option<usize> {
147 self.internal_sram_byte_size
148 }
149
150 pub fn family(&self) -> Option<Family> {
151 self.family
152 }
153
154 pub fn model(&self) -> Option<Model> {
155 self.model
156 }
157
158 pub fn flash_memory_type(&self) -> Option<FlashMemoryType> {
159 self.flash_memory_type
160 }
161
162 fn decode_flash_size_from_register(register_value: u8) -> Option<usize> {
163 match register_value {
164 1 => Some(8 * 1024),
165 2 => Some(16 * 1024),
166 3 => Some(32 * 1024),
167 5 => Some(64 * 1024),
168 7 => Some(128 * 1024),
169 9 => Some(256 * 1024),
170 10 => Some(512 * 1024),
171 12 => Some(1024 * 1024),
172 14 => Some(2048 * 1024),
173 _ => None,
174 }
175 }
176
177 fn decode_family_and_model(chip_id: &CHIPID) -> (Option<Family>, Option<Model>) {
178 match chip_id.cidr.read().bits() {
179 0x288B_07E0 => (Some(Family::AtSam4s), Some(Model::AtSam4s2a)),
180 0x289B_07E0 => (Some(Family::AtSam4s), Some(Model::AtSam4s2b)),
181 0x28AB_07E0 => (Some(Family::AtSam4s), Some(Model::AtSam4s2c)),
182
183 0x288B_09E0 => (Some(Family::AtSam4s), Some(Model::AtSam4s4a)),
184 0x289B_09E0 => (Some(Family::AtSam4s), Some(Model::AtSam4s4b)),
185 0x28AB_09E0 => (Some(Family::AtSam4s), Some(Model::AtSam4s4c)),
186
187 0x289C_0AE0 => (Some(Family::AtSam4s), Some(Model::AtSam4s8b)),
188 0x28AC_0AE0 => (Some(Family::AtSam4s), Some(Model::AtSam4s8c)),
189
190 0x289C_0CE0 => (Some(Family::AtSam4s), Some(Model::AtSam4s16b)),
191 0x28AC_0CE0 => (Some(Family::AtSam4s), Some(Model::AtSam4s16c)),
192
193 0x2897_0CE0 => (Some(Family::AtSam4s), Some(Model::AtSam4sa16b)),
194 0x28A7_0CE0 => (Some(Family::AtSam4s), Some(Model::AtSam4sa16c)),
195
196 0x2997_0CE0 => (Some(Family::AtSam4s), Some(Model::AtSam4sd16b)),
197 0x29A7_0CE0 => (Some(Family::AtSam4s), Some(Model::AtSam4sd16c)),
198
199 0x2997_0EE0 => (Some(Family::AtSam4s), Some(Model::AtSam4sd32b)),
200 0x29A7_0EE0 => (Some(Family::AtSam4s), Some(Model::AtSam4sd32c)),
201
202 0x293B_0AE0 => (Some(Family::AtSam4n), Some(Model::AtSam4n8a)),
203 0x294B_0AE0 => (Some(Family::AtSam4n), Some(Model::AtSam4n8b)),
204 0x295B_0AE0 => (Some(Family::AtSam4n), Some(Model::AtSam4n8c)),
205
206 0x2946_0CE0 => (Some(Family::AtSam4n), Some(Model::AtSam4n16b)),
207 0x2956_0CE0 => (Some(Family::AtSam4n), Some(Model::AtSam4n16c)),
208
209 0xA3CC_0CE0 => match chip_id.exid.read().bits() {
210 0x0012_0209 => (Some(Family::AtSam4e), Some(Model::AtSam4e8c)),
211 0x0012_0208 => (Some(Family::AtSam4e), Some(Model::AtSam4e8e)),
212
213 0x0012_0201 => (Some(Family::AtSam4e), Some(Model::AtSam4e16c)),
214 0x0012_0200 => (Some(Family::AtSam4e), Some(Model::AtSam4e16e)),
215 _ => (Some(Family::AtSam4e), None),
216 },
217
218 _ => (None, None),
219 }
220 }
221}