Skip to main content

atsam4_hal/
chipid.rs

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, // flash1_byte_size = ROM size, flash2_byte_size = Flash size
59}
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}