use crate::pac::CHIPID;
#[derive(Clone, Copy, Debug)]
pub enum EmbeddedProcessor {
Arm946Es,
Arm7Tdmi,
CortexM3,
Arm920T,
Arm926Ejs,
CortexA5,
CortexM4,
}
#[derive(Clone, Copy, Debug)]
pub enum Family {
AtSam4e,
AtSam4n,
AtSam4s,
}
#[derive(Clone, Copy, Debug)]
pub enum Model {
AtSam4e8c,
AtSam4e8e,
AtSam4e16c,
AtSam4e16e,
AtSam4n8a,
AtSam4n8b,
AtSam4n8c,
AtSam4n16b,
AtSam4n16c,
AtSam4s2a,
AtSam4s2b,
AtSam4s2c,
AtSam4s4a,
AtSam4s4b,
AtSam4s4c,
AtSam4s8b,
AtSam4s8c,
AtSam4s16b,
AtSam4s16c,
AtSam4sa16b,
AtSam4sa16c,
AtSam4sd16b,
AtSam4sd16c,
AtSam4sd32b,
AtSam4sd32c,
}
#[derive(Clone, Copy, Debug)]
pub enum FlashMemoryType {
Rom,
Romless,
Sram,
Flash,
RomFlash, }
#[derive(Debug)]
pub struct ChipId {
version: u8,
embedded_processor: Option<EmbeddedProcessor>,
flash1_byte_size: Option<usize>,
flash2_byte_size: Option<usize>,
internal_sram_byte_size: Option<usize>,
family: Option<Family>,
model: Option<Model>,
flash_memory_type: Option<FlashMemoryType>,
}
impl ChipId {
pub fn new(chip_id: CHIPID) -> Self {
let cidr = chip_id.cidr.read();
let version = cidr.version().bits();
let embedded_processor = match cidr.eproc().bits() {
1 => Some(EmbeddedProcessor::Arm946Es),
2 => Some(EmbeddedProcessor::Arm7Tdmi),
3 => Some(EmbeddedProcessor::CortexM3),
4 => Some(EmbeddedProcessor::Arm920T),
5 => Some(EmbeddedProcessor::Arm926Ejs),
6 => Some(EmbeddedProcessor::CortexA5),
7 => Some(EmbeddedProcessor::CortexM4),
_ => None,
};
let flash1_byte_size = Self::decode_flash_size_from_register(cidr.nvpsiz().bits());
let flash2_byte_size = Self::decode_flash_size_from_register(cidr.nvpsiz2().bits());
let internal_sram_byte_size = match cidr.sramsiz().bits() {
0 => Some(48 * 1024),
1 => Some(192 * 1024),
2 => Some(2 * 1024),
3 => Some(6 * 1024),
4 => Some(24 * 1024),
5 => Some(4 * 1024),
6 => Some(80 * 1024),
7 => Some(160 * 1024),
8 => Some(8 * 1024),
9 => Some(16 * 1024),
10 => Some(32 * 1024),
11 => Some(64 * 1024),
12 => Some(128 * 1024),
13 => Some(256 * 1024),
14 => Some(96 * 1024),
15 => Some(512 * 1024),
_ => None,
};
let (family, model) = Self::decode_family_and_model(&chip_id);
let flash_memory_type = match cidr.nvptyp().bits() {
0 => Some(FlashMemoryType::Rom),
1 => Some(FlashMemoryType::Romless),
2 => Some(FlashMemoryType::Flash),
3 => Some(FlashMemoryType::RomFlash),
4 => Some(FlashMemoryType::Sram),
_ => None,
};
ChipId {
version,
embedded_processor,
flash1_byte_size,
flash2_byte_size,
internal_sram_byte_size,
family,
model,
flash_memory_type,
}
}
pub fn version(&self) -> u8 {
self.version
}
pub fn embedded_processor(&self) -> Option<EmbeddedProcessor> {
self.embedded_processor
}
pub fn flash1_byte_size(&self) -> Option<usize> {
self.flash1_byte_size
}
pub fn flash2_byte_size(&self) -> Option<usize> {
self.flash2_byte_size
}
pub fn internal_sram_size(&self) -> Option<usize> {
self.internal_sram_byte_size
}
pub fn family(&self) -> Option<Family> {
self.family
}
pub fn model(&self) -> Option<Model> {
self.model
}
pub fn flash_memory_type(&self) -> Option<FlashMemoryType> {
self.flash_memory_type
}
fn decode_flash_size_from_register(register_value: u8) -> Option<usize> {
match register_value {
1 => Some(8 * 1024),
2 => Some(16 * 1024),
3 => Some(32 * 1024),
5 => Some(64 * 1024),
7 => Some(128 * 1024),
9 => Some(256 * 1024),
10 => Some(512 * 1024),
12 => Some(1024 * 1024),
14 => Some(2048 * 1024),
_ => None,
}
}
fn decode_family_and_model(chip_id: &CHIPID) -> (Option<Family>, Option<Model>) {
match chip_id.cidr.read().bits() {
0x288B_07E0 => (Some(Family::AtSam4s), Some(Model::AtSam4s2a)),
0x289B_07E0 => (Some(Family::AtSam4s), Some(Model::AtSam4s2b)),
0x28AB_07E0 => (Some(Family::AtSam4s), Some(Model::AtSam4s2c)),
0x288B_09E0 => (Some(Family::AtSam4s), Some(Model::AtSam4s4a)),
0x289B_09E0 => (Some(Family::AtSam4s), Some(Model::AtSam4s4b)),
0x28AB_09E0 => (Some(Family::AtSam4s), Some(Model::AtSam4s4c)),
0x289C_0AE0 => (Some(Family::AtSam4s), Some(Model::AtSam4s8b)),
0x28AC_0AE0 => (Some(Family::AtSam4s), Some(Model::AtSam4s8c)),
0x289C_0CE0 => (Some(Family::AtSam4s), Some(Model::AtSam4s16b)),
0x28AC_0CE0 => (Some(Family::AtSam4s), Some(Model::AtSam4s16c)),
0x2897_0CE0 => (Some(Family::AtSam4s), Some(Model::AtSam4sa16b)),
0x28A7_0CE0 => (Some(Family::AtSam4s), Some(Model::AtSam4sa16c)),
0x2997_0CE0 => (Some(Family::AtSam4s), Some(Model::AtSam4sd16b)),
0x29A7_0CE0 => (Some(Family::AtSam4s), Some(Model::AtSam4sd16c)),
0x2997_0EE0 => (Some(Family::AtSam4s), Some(Model::AtSam4sd32b)),
0x29A7_0EE0 => (Some(Family::AtSam4s), Some(Model::AtSam4sd32c)),
0x293B_0AE0 => (Some(Family::AtSam4n), Some(Model::AtSam4n8a)),
0x294B_0AE0 => (Some(Family::AtSam4n), Some(Model::AtSam4n8b)),
0x295B_0AE0 => (Some(Family::AtSam4n), Some(Model::AtSam4n8c)),
0x2946_0CE0 => (Some(Family::AtSam4n), Some(Model::AtSam4n16b)),
0x2956_0CE0 => (Some(Family::AtSam4n), Some(Model::AtSam4n16c)),
0xA3CC_0CE0 => match chip_id.exid.read().bits() {
0x0012_0209 => (Some(Family::AtSam4e), Some(Model::AtSam4e8c)),
0x0012_0208 => (Some(Family::AtSam4e), Some(Model::AtSam4e8e)),
0x0012_0201 => (Some(Family::AtSam4e), Some(Model::AtSam4e16c)),
0x0012_0200 => (Some(Family::AtSam4e), Some(Model::AtSam4e16e)),
_ => (Some(Family::AtSam4e), None),
},
_ => (None, None),
}
}
}