lpc55_hal/peripherals/
usbfs.rs1use crate::peripherals::{anactrl, pmc, syscon};
2use crate::raw;
3use crate::typestates::{
4 init_state,
5 usbfs_mode,
6 ClocksSupportUsbfsToken,
9};
10use core::ops::Deref;
11
12use crate::traits::usb::{Usb, UsbSpeed};
13
14pub struct Usbfs<
16 State: init_state::InitState = init_state::Unknown,
17 Mode: usbfs_mode::UsbfsMode = usbfs_mode::Unknown,
18> {
19 pub(crate) raw_fsd: raw::USB0,
20 pub(crate) raw_fsh: raw::USBFSH,
21 _state: State,
22 _mode: Mode,
23}
24
25pub type EnabledUsbfsDevice = Usbfs<init_state::Enabled, usbfs_mode::Device>;
26pub type EnabledUsbfsHost = Usbfs<init_state::Enabled, usbfs_mode::Host>;
27
28impl Deref for EnabledUsbfsDevice {
29 type Target = raw::usb1::RegisterBlock;
30 fn deref(&self) -> &Self::Target {
31 &self.raw_fsd
32 }
33}
34
35unsafe impl Sync for EnabledUsbfsDevice {}
36
37impl Usb<init_state::Enabled> for EnabledUsbfsDevice {
38 const SPEED: UsbSpeed = UsbSpeed::FullSpeed;
39 }
41
42impl Usbfs {
43 pub fn new(raw_fsd: raw::USB0, raw_fsh: raw::USBFSH) -> Self {
44 Usbfs {
45 raw_fsd,
46 raw_fsh,
47 _state: init_state::Unknown,
48 _mode: usbfs_mode::Unknown,
49 }
50 }
51}
52
53impl<State: init_state::InitState, Mode: usbfs_mode::UsbfsMode> Usbfs<State, Mode> {
54 pub fn release(self) -> (raw::USB0, raw::USBFSH) {
55 (self.raw_fsd, self.raw_fsh)
56 }
57
58 pub fn enabled_as_device(
59 mut self,
60 anactrl: &mut anactrl::Anactrl,
61 pmc: &mut pmc::Pmc,
62 syscon: &mut syscon::Syscon,
63 _clocks_token: ClocksSupportUsbfsToken,
65 ) -> EnabledUsbfsDevice {
66 unsafe { syscon.raw.usb0clkdiv.modify(|_, w| w.div().bits(1)) };
69 syscon.raw.usb0clkdiv.modify(|_, w| w.halt().run());
70 syscon.raw.usb0clksel.modify(|_, w| w.sel().enum_0x3()); while syscon.raw.usb0clkdiv.read().reqflag().is_ongoing() {}
72
73 pmc.power_on(&mut self.raw_fsd);
75
76 syscon.reset(&mut self.raw_fsd);
78 syscon.enable_clock(&mut self.raw_fsd);
79
80 syscon.enable_clock(&mut self.raw_fsh);
82 self.raw_fsh
84 .portmode
85 .modify(|_, w| w.dev_enable().set_bit());
86 syscon.disable_clock(&mut self.raw_fsh);
87
88 syscon.raw.ahbclkctrl2.modify(|_, w| w.usb1_ram().enable());
93
94 anactrl
97 .raw
98 .fro192m_ctrl
99 .modify(|_, w| w.usbclkadj().set_bit());
100 while anactrl.raw.fro192m_ctrl.read().usbmodchg().bit_is_set() {}
101 Usbfs {
104 raw_fsd: self.raw_fsd,
105 raw_fsh: self.raw_fsh,
106 _state: init_state::Enabled(()),
107 _mode: usbfs_mode::Device,
108 }
109 }
110}
111
112#[derive(Debug)]
113pub struct UsbFsDevInfo {
114 pub maj_rev: u8,
115 pub min_rev: u8,
116 pub err_code: u8,
117 pub frame_nr: u16,
118}
119
120impl EnabledUsbfsDevice {
121 pub fn info(&self) -> UsbFsDevInfo {
122 UsbFsDevInfo {
124 maj_rev: self.raw_fsd.info.read().majrev().bits(),
125 min_rev: self.raw_fsd.info.read().minrev().bits(),
126 err_code: self.raw_fsd.info.read().err_code().bits(),
127 frame_nr: self.raw_fsd.info.read().frame_nr().bits(),
128 }
129 }
130}
131
132impl<State: init_state::InitState> Usbfs<State, usbfs_mode::Device> {
133 pub fn disabled(
135 mut self,
136 pmc: &mut pmc::Pmc,
137 syscon: &mut syscon::Syscon,
138 ) -> Usbfs<init_state::Disabled, usbfs_mode::Device> {
139 pmc.power_off(&mut self.raw_fsd);
140 syscon.disable_clock(&mut self.raw_fsd);
141
142 Usbfs {
143 raw_fsd: self.raw_fsd,
144 raw_fsh: self.raw_fsh,
145 _state: init_state::Disabled,
146 _mode: usbfs_mode::Device,
147 }
148 }
149}
150
151impl From<(raw::USB0, raw::USBFSH)> for Usbfs {
152 fn from(raw: (raw::USB0, raw::USBFSH)) -> Self {
153 Usbfs::new(raw.0, raw.1)
154 }
155}