add TTC driver
This commit is contained in:
parent
198e17c134
commit
90423f6fee
@ -23,6 +23,7 @@ pub mod slcr;
|
||||
pub mod spi;
|
||||
pub mod time;
|
||||
pub mod uart;
|
||||
pub mod ttc;
|
||||
|
||||
/// This enumeration encodes the various boot sources.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
|
45
zynq7000-hal/src/ttc.rs
Normal file
45
zynq7000-hal/src/ttc.rs
Normal file
@ -0,0 +1,45 @@
|
||||
//! Triple-timer counter (TTC) high-level driver.
|
||||
|
||||
use arbitrary_int::u3;
|
||||
|
||||
use crate::gpio::{IoPeriph, Mio30, Mio31, MioPin, MuxConf, PinMode};
|
||||
#[cfg(not(feature = "7z010-7z007s-clg225"))]
|
||||
use crate::gpio::{Mio18, Mio19, Mio42, Mio43};
|
||||
|
||||
/// Each TTC consists of three independent timers/counters.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum TtcId {
|
||||
Ttc0 = 0,
|
||||
Ttc1 = 1,
|
||||
}
|
||||
|
||||
pub const TTC_MUX_CONF: MuxConf = MuxConf::new_with_l3(u3::new(0b110));
|
||||
|
||||
pub trait ClockInPin {
|
||||
const ID: TtcId;
|
||||
}
|
||||
|
||||
pub trait WaveOutPin {
|
||||
const ID: TtcId;
|
||||
}
|
||||
|
||||
macro_rules! into_ttc {
|
||||
($($Mio:ident),+) => {
|
||||
$(
|
||||
impl <M: PinMode> MioPin<$Mio, M> {
|
||||
/// Convert the pin into a TTC pin by configuring the pin routing via the
|
||||
/// MIO multiplexer bits.
|
||||
pub fn into_ttck(self) -> MioPin<$Mio, IoPeriph> {
|
||||
// Enable pull-ups for the I2C pins.
|
||||
self.into_io_periph(TTC_MUX_CONF, None)
|
||||
}
|
||||
}
|
||||
)+
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "7z010-7z007s-clg225"))]
|
||||
into_ttc!(Mio18, Mio19, Mio42, Mio43);
|
||||
into_ttc!(Mio30, Mio31);
|
||||
|
||||
pub struct Pwm {}
|
@ -1,3 +1,4 @@
|
||||
//! SPI register module.
|
||||
use arbitrary_int::{u2, u6, u10};
|
||||
|
||||
pub const I2C_0_BASE_ADDR: usize = 0xE000_4000;
|
||||
|
@ -23,6 +23,7 @@ pub mod mpcore;
|
||||
pub mod slcr;
|
||||
pub mod spi;
|
||||
pub mod uart;
|
||||
pub mod ttc;
|
||||
|
||||
static PERIPHERALS_TAKEN: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
//! SPI register module.
|
||||
use arbitrary_int::u4;
|
||||
|
||||
pub const SPI_0_BASE_ADDR: usize = 0xE000_6000;
|
||||
|
153
zynq7000/src/ttc.rs
Normal file
153
zynq7000/src/ttc.rs
Normal file
@ -0,0 +1,153 @@
|
||||
//! Triple-timer counter (TTC) register module.
|
||||
use arbitrary_int::u4;
|
||||
|
||||
#[bitbybit::bitenum(u1, exhaustive = true)]
|
||||
pub enum ClockSource {
|
||||
Pclk = 0b0,
|
||||
Extewrnal = 0b1,
|
||||
}
|
||||
|
||||
#[bitbybit::bitfield(u32)]
|
||||
pub struct ClockControl {
|
||||
/// When this bit is set and the external clock is selected, the counter clocks on the
|
||||
/// negative edge of the external clock input.
|
||||
#[bit(6, rw)]
|
||||
ext_clk_edge: bool,
|
||||
#[bit(5, rw)]
|
||||
clk_src: ClockSource,
|
||||
#[bits(1..=4, rw)]
|
||||
prescaler: u4,
|
||||
#[bit(0, rw)]
|
||||
prescale_enable: bool,
|
||||
}
|
||||
|
||||
#[bitbybit::bitenum(u1, exhaustive = true)]
|
||||
pub enum Mode {
|
||||
Overflow = 0b0,
|
||||
Interval = 0b1,
|
||||
}
|
||||
|
||||
#[bitbybit::bitenum(u1, exhaustive = true)]
|
||||
pub enum WavePolarity {
|
||||
/// The waveform output goes from high to low on a match 0 interrupt and returns high on
|
||||
/// overflow or interval interrupt.
|
||||
HighToLowOnMatch1 = 0b0,
|
||||
/// The waveform output goes from low to high on a match 0 interrupt and returns low on
|
||||
/// overflow or interval interrupt.
|
||||
LowToHighOnMatch1 = 0b1,
|
||||
}
|
||||
|
||||
#[bitbybit::bitenum(u1, exhaustive = true)]
|
||||
pub enum WaveEnable {
|
||||
Enable = 0b0,
|
||||
Disable = 0b1,
|
||||
}
|
||||
|
||||
#[bitbybit::bitfield(u32)]
|
||||
pub struct CountControl {
|
||||
#[bit(6, rw)]
|
||||
wave_polarity: WavePolarity,
|
||||
/// Output waveform enable, active low. Reset value 1.
|
||||
#[bit(5, rw)]
|
||||
wave_enable_n: WaveEnable,
|
||||
/// Resets the counter and restarts counting. Automatically cleared on restart.
|
||||
#[bit(4, rw)]
|
||||
reset: bool,
|
||||
/// When this bit is set, an interrupt is generated when the count value matches one of the
|
||||
/// three match registers and the corresponding bit is set in the IER register.
|
||||
#[bit(3, rw)]
|
||||
match_enable: bool,
|
||||
/// When this bit is high, the timer counts down.
|
||||
#[bit(2, rw)]
|
||||
decrementing: bool,
|
||||
#[bit(1, rw)]
|
||||
mode: Mode,
|
||||
#[bit(0, rw)]
|
||||
disable: bool,
|
||||
}
|
||||
|
||||
#[bitbybit::bitfield(u32)]
|
||||
pub struct Counter {
|
||||
#[bits(0..=15, r)]
|
||||
count: u16,
|
||||
}
|
||||
|
||||
#[bitbybit::bitfield(u32)]
|
||||
pub struct RwValue {
|
||||
#[bits(0..=15, rw)]
|
||||
value: u16,
|
||||
}
|
||||
|
||||
#[bitbybit::bitfield(u32)]
|
||||
pub struct InterruptStatus {
|
||||
/// Even timer overflow interrupt.
|
||||
#[bit(5, r)]
|
||||
event: bool,
|
||||
#[bit(4, r)]
|
||||
counter_overflow: bool,
|
||||
#[bit(3, r)]
|
||||
match_2: bool,
|
||||
#[bit(2, r)]
|
||||
match_1: bool,
|
||||
#[bit(1, r)]
|
||||
match_0: bool,
|
||||
#[bit(0, r)]
|
||||
interval: bool,
|
||||
}
|
||||
|
||||
#[bitbybit::bitfield(u32)]
|
||||
pub struct InterruptControl {
|
||||
/// Even timer overflow interrupt.
|
||||
#[bit(5, rw)]
|
||||
event: bool,
|
||||
#[bit(4, rw)]
|
||||
counter_overflow: bool,
|
||||
#[bit(3, rw)]
|
||||
match_2: bool,
|
||||
#[bit(2, rw)]
|
||||
match_1: bool,
|
||||
#[bit(1, rw)]
|
||||
match_0: bool,
|
||||
#[bit(0, rw)]
|
||||
interval: bool,
|
||||
}
|
||||
|
||||
#[bitbybit::bitfield(u32)]
|
||||
pub struct EventControl {
|
||||
/// E_Ov bit. When set to 0, the event timer is disabled and set to 0 when an event timer
|
||||
/// register overflow occurs. Otherwise, continue counting on overflow.
|
||||
#[bit(2, rw)]
|
||||
continuous_mode: bool,
|
||||
/// E_Lo bit. When set to 1, counts PCLK cycles during low level duration of the external
|
||||
/// clock. Otherwise, counts it during high level duration.
|
||||
#[bit(1, rw)]
|
||||
count_low_level_of_ext_clk: bool,
|
||||
#[bit(0, rw)]
|
||||
enable: bool,
|
||||
}
|
||||
|
||||
#[bitbybit::bitfield(u32)]
|
||||
pub struct EventCount {
|
||||
#[bits(0..=15, r)]
|
||||
count: u16,
|
||||
}
|
||||
|
||||
/// Triple-timer counter
|
||||
#[derive(derive_mmio::Mmio)]
|
||||
#[repr(C)]
|
||||
pub struct Ttc {
|
||||
clk_cntr: [ClockControl; 3],
|
||||
cnt_ctrl: [CountControl; 3],
|
||||
#[mmio(PureRead)]
|
||||
current_counter: [Counter; 3],
|
||||
interval_value: [RwValue; 3],
|
||||
match_value_0: [RwValue; 3],
|
||||
match_value_1: [RwValue; 3],
|
||||
match_value_2: [RwValue; 3],
|
||||
#[mmio(Read)]
|
||||
isr: [InterruptStatus; 3],
|
||||
ier: [InterruptControl; 3],
|
||||
event_cntrl: [EventControl; 3],
|
||||
#[mmio(PureRead)]
|
||||
event_reg: [EventCount; 3],
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
//! UART register module.
|
||||
//! PS UART register module.
|
||||
use arbitrary_int::u6;
|
||||
|
||||
pub const UART_0_BASE: usize = 0xE000_0000;
|
||||
|
Loading…
x
Reference in New Issue
Block a user