use crate::ral;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u32)]
pub enum Mode {
OneShot = 0,
Repeat = 1,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u32)]
pub enum Instance {
Gpt0,
Gpt1,
}
pub struct Gpt<'a> {
usb: &'a mut ral::AnyUsbInstance,
gpt: Instance,
}
impl<'a> Gpt<'a> {
pub(crate) fn new(usb: &'a mut ral::AnyUsbInstance, gpt: Instance) -> Self {
Self { usb, gpt }
}
pub fn instance(&self) -> Instance {
self.gpt
}
pub fn run(&mut self) {
match self.gpt {
Instance::Gpt0 => ral::modify_reg!(ral::usb, self.usb, GPTIMER0CTRL, GPTRUN: 1),
Instance::Gpt1 => ral::modify_reg!(ral::usb, self.usb, GPTIMER1CTRL, GPTRUN: 1),
}
}
pub fn is_running(&self) -> bool {
match self.gpt {
Instance::Gpt0 => ral::read_reg!(ral::usb, self.usb, GPTIMER0CTRL, GPTRUN == 1),
Instance::Gpt1 => ral::read_reg!(ral::usb, self.usb, GPTIMER1CTRL, GPTRUN == 1),
}
}
pub fn stop(&mut self) {
match self.gpt {
Instance::Gpt0 => ral::modify_reg!(ral::usb, self.usb, GPTIMER0CTRL, GPTRUN: 0),
Instance::Gpt1 => ral::modify_reg!(ral::usb, self.usb, GPTIMER1CTRL, GPTRUN: 0),
}
}
pub fn reset(&mut self) {
match self.gpt {
Instance::Gpt0 => ral::modify_reg!(ral::usb, self.usb, GPTIMER0CTRL, GPTRST: 1),
Instance::Gpt1 => ral::modify_reg!(ral::usb, self.usb, GPTIMER1CTRL, GPTRST: 1),
}
}
pub fn set_mode(&mut self, mode: Mode) {
match self.gpt {
Instance::Gpt0 => {
ral::modify_reg!(ral::usb, self.usb, GPTIMER0CTRL, GPTMODE: mode as u32)
}
Instance::Gpt1 => {
ral::modify_reg!(ral::usb, self.usb, GPTIMER1CTRL, GPTMODE: mode as u32)
}
}
}
pub fn mode(&self) -> Mode {
let mode: u32 = match self.gpt {
Instance::Gpt0 => {
ral::read_reg!(ral::usb, self.usb, GPTIMER0CTRL, GPTMODE)
}
Instance::Gpt1 => {
ral::read_reg!(ral::usb, self.usb, GPTIMER1CTRL, GPTMODE)
}
};
if mode == (Mode::Repeat as u32) {
Mode::Repeat
} else if mode == (Mode::OneShot as u32) {
Mode::OneShot
} else {
unreachable!()
}
}
pub fn set_load(&mut self, us: u32) {
let count = us.clamp(1, 0xFF_FFFF).saturating_sub(1);
match self.gpt {
Instance::Gpt0 => ral::write_reg!(ral::usb, self.usb, GPTIMER0LD, count),
Instance::Gpt1 => ral::write_reg!(ral::usb, self.usb, GPTIMER1LD, count),
}
}
pub fn load(&self) -> u32 {
match self.gpt {
Instance::Gpt0 => ral::read_reg!(ral::usb, self.usb, GPTIMER0LD),
Instance::Gpt1 => ral::read_reg!(ral::usb, self.usb, GPTIMER1LD),
}
}
pub fn is_elapsed(&self) -> bool {
match self.gpt {
Instance::Gpt0 => ral::read_reg!(ral::usb, self.usb, USBSTS, TI0 == 1),
Instance::Gpt1 => ral::read_reg!(ral::usb, self.usb, USBSTS, TI1 == 1),
}
}
pub fn clear_elapsed(&mut self) {
match self.gpt {
Instance::Gpt0 => ral::write_reg!(ral::usb, self.usb, USBSTS, TI0: 1),
Instance::Gpt1 => ral::write_reg!(ral::usb, self.usb, USBSTS, TI1: 1),
}
}
pub fn set_interrupt_enabled(&mut self, enable: bool) {
match self.gpt {
Instance::Gpt0 => ral::modify_reg!(ral::usb, self.usb, USBINTR, TIE0: enable as u32),
Instance::Gpt1 => ral::modify_reg!(ral::usb, self.usb, USBINTR, TIE1: enable as u32),
}
}
pub fn is_interrupt_enabled(&self) -> bool {
match self.gpt {
Instance::Gpt0 => ral::read_reg!(ral::usb, self.usb, USBINTR, TIE0 == 1),
Instance::Gpt1 => ral::read_reg!(ral::usb, self.usb, USBINTR, TIE1 == 1),
}
}
}