kea_hal/system/
sim.rs

1//! # SIM - System Integration Module
2//!
3//! ## SIM_SCGC - System Clock Gating Control Register
4//!
5//! This module controls whether or not a module is connected to the bus clock.
6//! This register is controlled by each peripherals respective (software)
7//! module.
8//!
9//! ## SIM_BUSDIV
10//!
11//! This contains a single bit field that controls whether the bus divider is
12//! equal to or half that of the system clock. Because the maximum allowed
13//! speed of the bus clock is 20MHz compared to the 40MHz allowed for the
14//! system clock, the bus clock divider must be set appropriately if the system
15//! clock exceeds 20MHz. By default the system clock is 16MHz.
16//!
17//!
18//! ## SIM_SOPT - System Options Register
19//!
20//! The SIM holds system configuration options, such as trigger sources, RESET
21//! pin usage, etc. All of the options will be implemented in their respective
22//! (software) modules. For example reset pin usage is handled by [crate::gpio]
23//! , and the bus divider is handled by [crate::clocks].
24//!
25//! ## UUID
26//!
27//! the MCU's 64bit UUID.
28//!
29//! ## SIM_PINSEL - Pin Selection Register
30//!
31//! The SIM also holds the Pin Selection Register (SIM_PINSEL) which configures
32//! the pins that certain peripherals use for inputs and outputs. This
33//! functionality is not controlled by this (software) module, but is instead
34//! implemented by their repsective modules. For example SIM_PINSEL\[UART0\] is
35//! handled within the UART (software) module.
36
37use crate::{pac::SIM, HALExt};
38
39impl HALExt for SIM {
40    type T = Sim;
41    /// Split the SIM peripheral into useful chunks
42    fn split(self) -> Sim {
43        Sim {
44            id: Id { _0: () },
45            status: Status { _0: () },
46            uuid: UUID,
47        }
48    }
49}
50
51/// Struct containings type structs for the Sim interface.
52pub struct Sim {
53    /// Getters for the ID portion of the Status and ID register
54    pub id: Id,
55    /// Getters for the Status portion of the Status and ID register
56    pub status: Status,
57    /// Getters for the UUID register
58    pub uuid: UUID,
59}
60
61/// Status type
62pub struct Status {
63    _0: (),
64}
65
66/// ID type
67pub struct Id {
68    _0: (),
69}
70
71/// Enumeration for the number of pins on the device.
72///
73/// returned by status_id.pinout()
74#[repr(u8)]
75pub enum DevicePinOuts {
76    /// 8 Pin device
77    Pin8 = 0,
78    /// 16 Pin device
79    Pin16 = 1,
80    /// 20 Pin device
81    Pin20 = 2,
82    /// 24 Pin device
83    Pin24 = 3,
84    /// 32 Pin device
85    Pin32 = 4,
86    /// 44 Pin device
87    Pin44 = 5,
88    /// 48 Pin device
89    Pin48 = 6,
90    /// 64 Pin device
91    Pin64 = 7,
92    /// 80 Pin device
93    Pin80 = 8,
94    /// 100 Pin device
95    Pin100 = 10,
96    /// Effectively Invalid
97    Reserved,
98}
99
100impl Id {
101    /// Return the Kinetis Family ID (4 bits)
102    pub fn family(&self) -> u8 {
103        unsafe { &(*SIM::ptr()) }.srsid.read().famid().bits()
104    }
105
106    /// Return the Kinetis sub-family ID (4 bits)
107    pub fn subfamily(&self) -> u8 {
108        unsafe { &(*SIM::ptr()) }.srsid.read().subfamid().bits()
109    }
110
111    /// Return the device revision number (4 bits)
112    pub fn revision(&self) -> u8 {
113        unsafe { &(*SIM::ptr()) }.srsid.read().rev_id().bits()
114    }
115
116    /// Device pin id
117    pub fn pinout(&self) -> DevicePinOuts {
118        let sim = unsafe { &(*SIM::ptr()) };
119
120        match sim.srsid.read().pinid().bits() {
121            0 => DevicePinOuts::Pin8,
122            1 => DevicePinOuts::Pin16,
123            2 => DevicePinOuts::Pin20,
124            3 => DevicePinOuts::Pin24,
125            4 => DevicePinOuts::Pin32,
126            5 => DevicePinOuts::Pin44,
127            6 => DevicePinOuts::Pin48,
128            7 => DevicePinOuts::Pin64,
129            8 => DevicePinOuts::Pin80,
130            10 => DevicePinOuts::Pin100,
131            _ => DevicePinOuts::Reserved,
132        }
133    }
134}
135
136impl Status {
137    /// A reset was caused by a module failing to acknowledge entering Stop
138    /// mode
139    pub fn stop_error_reset(&self) -> bool {
140        unsafe { &(*SIM::ptr()) }.srsid.read().sackerr().bit()
141    }
142
143    /// A reset was caused by debugger request
144    ///
145    /// The request is made in the MDM-AP register, this is called MDMAP in
146    /// SIM_SRSID (section 12.2.1 of KEA64RM).
147    pub fn debugger_reset(&self) -> bool {
148        unsafe { &(*SIM::ptr()) }.srsid.read().mdmap().bit()
149    }
150
151    /// A reset was caused by software request
152    pub fn software_reset(&self) -> bool {
153        unsafe { &(*SIM::ptr()) }.srsid.read().sw().bit()
154    }
155
156    /// A reset was caused by a core lockup event
157    pub fn lockup_reset(&self) -> bool {
158        unsafe { &(*SIM::ptr()) }.srsid.read().lockup().bit()
159    }
160
161    /// A reset was caused by power-on
162    ///
163    /// For normal startup, this is set, if there was some other reason for
164    /// reseting, this is cleared.
165    pub fn power_on_reset(&self) -> bool {
166        unsafe { &(*SIM::ptr()) }.srsid.read().por().bit()
167    }
168
169    /// A reset was caused by the reset Pin
170    pub fn pin_reset(&self) -> bool {
171        unsafe { &(*SIM::ptr()) }.srsid.read().pin().bit()
172    }
173
174    /// A reset was caused by the watchdog.
175    pub fn watchdog_reset(&self) -> bool {
176        unsafe { &(*SIM::ptr()) }.srsid.read().wdog().bit()
177    }
178
179    /// A reset was caused by the Internal Clock Source Peripheral
180    ///
181    /// This is called LOC (Loss Of Clock?) rest in KEA64RM (sect 12.2.1)
182    pub fn ics_reset(&self) -> bool {
183        unsafe { &(*SIM::ptr()) }.srsid.read().loc().bit()
184    }
185
186    /// A reset was caused by low voltage (brown out)
187    ///
188    /// Brown out detection is controlled by the Power Mangement Controller
189    /// (PMC) Peripheral
190    pub fn lv_reset(&self) -> bool {
191        unsafe { &(*SIM::ptr()) }.srsid.read().lvd().bit()
192    }
193}
194
195/// Universally Unique IDentifier
196pub struct UUID;
197
198impl UUID {
199    /// Returns the UUID as a u64
200    pub fn uuid(&self) -> u64 {
201        ((self.uuid_h() as u64) << 32) | (self.uuid_l() as u64)
202    }
203
204    /// Returns lower 32bits of UUID as u32
205    pub fn uuid_l(&self) -> u32 {
206        unsafe { &(*SIM::ptr()) }.uuidh.read().bits()
207    }
208
209    /// Returns upper 32bits of UUID as u32
210    pub fn uuid_h(&self) -> u32 {
211        unsafe { &(*SIM::ptr()) }.uuidl.read().bits()
212    }
213}