use tock_registers::{
interfaces::{ReadWriteable, Readable, Writeable},
register_bitfields, register_structs,
registers::ReadWrite,
};
register_bitfields! [
u32,
pub IOBLK_REG [
PU OFFSET(2) NUMBITS(1) [],
PD OFFSET(3) NUMBITS(1) [],
DS0 OFFSET(5) NUMBITS(1) [],
DS1 OFFSET(6) NUMBITS(1) [],
DS2 OFFSET(7) NUMBITS(1) [],
ST0 OFFSET(8) NUMBITS(1) [],
ST1 OFFSET(9) NUMBITS(1) [],
HE OFFSET(10) NUMBITS(1) [],
SL OFFSET(11) NUMBITS(1) []
],
pub IOBLK_DS2 [
DS OFFSET(5) NUMBITS(2) []
],
pub IOBLK_DS3 [
DS OFFSET(5) NUMBITS(3) []
],
pub IOBLK_ST [
ST OFFSET(8) NUMBITS(2) []
]
];
register_structs! {
pub IoblkG1Registers {
(0x000 => _reserved0),
(0x004 => pub pwm0_buck: ReadWrite<u32, IOBLK_REG::Register>),
(0x008 => _reserved1),
(0x010 => pub adc1: ReadWrite<u32, IOBLK_REG::Register>),
(0x014 => _reserved2),
(0x01C => pub pkg_type0: ReadWrite<u32, IOBLK_REG::Register>),
(0x020 => pub usb_vbus_det: ReadWrite<u32, IOBLK_REG::Register>),
(0x024 => pub pkg_type1: ReadWrite<u32, IOBLK_REG::Register>),
(0x028 => pub pkg_type2: ReadWrite<u32, IOBLK_REG::Register>),
(0x02C => @END),
}
}
register_structs! {
pub IoblkG7Registers {
(0x000 => pub sd0_cd: ReadWrite<u32, IOBLK_REG::Register>),
(0x004 => pub sd0_pwr_en: ReadWrite<u32, IOBLK_REG::Register>),
(0x008 => pub spk_en: ReadWrite<u32, IOBLK_REG::Register>),
(0x00C => pub uart0_tx: ReadWrite<u32, IOBLK_REG::Register>),
(0x010 => pub uart0_rx: ReadWrite<u32, IOBLK_REG::Register>),
(0x014 => _reserved0),
(0x018 => pub emmc_dat2: ReadWrite<u32, IOBLK_REG::Register>),
(0x01C => pub emmc_clk: ReadWrite<u32, IOBLK_REG::Register>),
(0x020 => pub emmc_dat0: ReadWrite<u32, IOBLK_REG::Register>),
(0x024 => pub emmc_dat3: ReadWrite<u32, IOBLK_REG::Register>),
(0x028 => pub emmc_cmd: ReadWrite<u32, IOBLK_REG::Register>),
(0x02C => pub emmc_dat1: ReadWrite<u32, IOBLK_REG::Register>),
(0x030 => pub jtag_cpu_tms: ReadWrite<u32, IOBLK_REG::Register>),
(0x034 => pub jtag_cpu_tck: ReadWrite<u32, IOBLK_REG::Register>),
(0x038 => _reserved1),
(0x03C => pub iic0_scl: ReadWrite<u32, IOBLK_REG::Register>),
(0x040 => pub iic0_sda: ReadWrite<u32, IOBLK_REG::Register>),
(0x044 => pub aux0: ReadWrite<u32, IOBLK_REG::Register>),
(0x048 => @END),
}
}
register_structs! {
pub IoblkG10Registers {
(0x000 => pub sd0_clk: ReadWrite<u32, IOBLK_REG::Register>),
(0x004 => pub sd0_cmd: ReadWrite<u32, IOBLK_REG::Register>),
(0x008 => pub sd0_d0: ReadWrite<u32, IOBLK_REG::Register>),
(0x00C => pub sd0_d1: ReadWrite<u32, IOBLK_REG::Register>),
(0x010 => pub sd0_d2: ReadWrite<u32, IOBLK_REG::Register>),
(0x014 => pub sd0_d3: ReadWrite<u32, IOBLK_REG::Register>),
(0x018 => @END),
}
}
register_structs! {
pub IoblkG12Registers {
(0x000 => _reserved0),
(0x038 => pub pad_mipirx4n: ReadWrite<u32, IOBLK_REG::Register>),
(0x03C => pub pad_mipirx4p: ReadWrite<u32, IOBLK_REG::Register>),
(0x040 => pub pad_mipirx3n: ReadWrite<u32, IOBLK_REG::Register>),
(0x044 => pub pad_mipirx3p: ReadWrite<u32, IOBLK_REG::Register>),
(0x048 => pub pad_mipirx2n: ReadWrite<u32, IOBLK_REG::Register>),
(0x04C => pub pad_mipirx2p: ReadWrite<u32, IOBLK_REG::Register>),
(0x050 => pub pad_mipirx1n: ReadWrite<u32, IOBLK_REG::Register>),
(0x054 => pub pad_mipirx1p: ReadWrite<u32, IOBLK_REG::Register>),
(0x058 => pub pad_mipirx0n: ReadWrite<u32, IOBLK_REG::Register>),
(0x05C => pub pad_mipirx0p: ReadWrite<u32, IOBLK_REG::Register>),
(0x060 => _reserved1),
(0x070 => pub pad_mipi_txm2: ReadWrite<u32, IOBLK_REG::Register>),
(0x074 => pub pad_mipi_txp2: ReadWrite<u32, IOBLK_REG::Register>),
(0x078 => pub pad_mipi_txm1: ReadWrite<u32, IOBLK_REG::Register>),
(0x07C => pub pad_mipi_txp1: ReadWrite<u32, IOBLK_REG::Register>),
(0x080 => pub pad_mipi_txm0: ReadWrite<u32, IOBLK_REG::Register>),
(0x084 => pub pad_mipi_txp0: ReadWrite<u32, IOBLK_REG::Register>),
(0x088 => _reserved2),
(0x08C => pub gpio_rtx: ReadWrite<u32, IOBLK_REG::Register>),
(0x090 => @END),
}
}
register_structs! {
pub IoblkGrtcRegisters {
(0x000 => pub pwr_vbat_det: ReadWrite<u32, IOBLK_REG::Register>),
(0x004 => pub pwr_rstn: ReadWrite<u32, IOBLK_REG::Register>),
(0x008 => pub pwr_seq1: ReadWrite<u32, IOBLK_REG::Register>),
(0x00C => pub pwr_seq2: ReadWrite<u32, IOBLK_REG::Register>),
(0x010 => _reserved0),
(0x018 => pub pwr_wakeup0: ReadWrite<u32, IOBLK_REG::Register>),
(0x01C => _reserved1),
(0x020 => pub pwr_button1: ReadWrite<u32, IOBLK_REG::Register>),
(0x024 => _reserved2),
(0x028 => pub xtal_xin: ReadWrite<u32, IOBLK_REG::Register>),
(0x02C => pub pwr_gpio0: ReadWrite<u32, IOBLK_REG::Register>),
(0x030 => pub pwr_gpio1: ReadWrite<u32, IOBLK_REG::Register>),
(0x034 => pub pwr_gpio2: ReadWrite<u32, IOBLK_REG::Register>),
(0x038 => _reserved3),
(0x0E0 => pub gpio_zq: ReadWrite<u32, IOBLK_REG::Register>),
(0x0E4 => @END),
}
}
pub trait IoConfig {
fn set_pull_up(&self, enable: bool);
fn set_pull_down(&self, enable: bool);
fn set_drive_strength(&self, strength: u8);
fn get_drive_strength(&self) -> u8;
fn set_schmitt_trigger(&self, level: u8);
fn set_bus_holder(&self, enable: bool);
fn set_slew_rate_limit(&self, enable: bool);
}
impl IoConfig for ReadWrite<u32, IOBLK_REG::Register> {
fn set_pull_up(&self, enable: bool) {
if enable {
self.modify(IOBLK_REG::PU::SET);
} else {
self.modify(IOBLK_REG::PU::CLEAR);
}
}
fn set_pull_down(&self, enable: bool) {
if enable {
self.modify(IOBLK_REG::PD::SET);
} else {
self.modify(IOBLK_REG::PD::CLEAR);
}
}
fn set_drive_strength(&self, strength: u8) {
let ds0 = (strength & 0x1) != 0;
let ds1 = (strength & 0x2) != 0;
let ds2 = (strength & 0x4) != 0;
let mut val = self.get();
if ds0 {
val |= 1 << 5;
} else {
val &= !(1 << 5);
}
if ds1 {
val |= 1 << 6;
} else {
val &= !(1 << 6);
}
if ds2 {
val |= 1 << 7;
} else {
val &= !(1 << 7);
}
self.set(val);
}
fn get_drive_strength(&self) -> u8 {
let val = self.get();
let ds0 = ((val >> 5) & 1) as u8;
let ds1 = ((val >> 6) & 1) as u8;
let ds2 = ((val >> 7) & 1) as u8;
ds0 | (ds1 << 1) | (ds2 << 2)
}
fn set_schmitt_trigger(&self, level: u8) {
let st0 = (level & 0x1) != 0;
let st1 = (level & 0x2) != 0;
let mut val = self.get();
if st0 {
val |= 1 << 8;
} else {
val &= !(1 << 8);
}
if st1 {
val |= 1 << 9;
} else {
val &= !(1 << 9);
}
self.set(val);
}
fn set_bus_holder(&self, enable: bool) {
if enable {
self.modify(IOBLK_REG::HE::SET);
} else {
self.modify(IOBLK_REG::HE::CLEAR);
}
}
fn set_slew_rate_limit(&self, enable: bool) {
if enable {
self.modify(IOBLK_REG::SL::SET);
} else {
self.modify(IOBLK_REG::SL::CLEAR);
}
}
}