1pub mod debug;
8
9#[allow(unused_imports)]
10use self::debug::{HexBuf, UdintFlags, UeconFlags, UestaFlags};
11use crate::pm;
12use crate::pm::{Clock, HSBClock, PBBClock, disable_clock, enable_clock};
13use crate::scif;
14use core::cell::Cell;
15use core::slice;
16use kernel::debug as debugln;
17use kernel::hil;
18use kernel::hil::usb::TransferType;
19use kernel::utilities::StaticRef;
20use kernel::utilities::cells::OptionalCell;
21use kernel::utilities::registers::interfaces::{ReadWriteable, Readable, Writeable};
22use kernel::utilities::registers::{
23 FieldValue, InMemoryRegister, LocalRegisterCopy, ReadOnly, ReadWrite, WriteOnly,
24 register_bitfields, register_structs,
25};
26
27macro_rules! client_warn {
32 [ $( $arg:expr ),+ ] => {
33 debugln!($( $arg ),+)
34 };
35}
36
37macro_rules! client_err {
38 [ $( $arg:expr ),+ ] => {
39 panic!($( $arg ),+)
40 };
41}
42
43macro_rules! debug1 {
44 [ $( $arg:expr ),+ ] => {
45 {} };
47}
48
49macro_rules! internal_err {
50 [ $( $arg:expr ),+ ] => {
51 panic!($( $arg ),+)
52 };
53}
54
55register_structs! {
56 UsbcRegisters {
57 (0x000 => udcon: ReadWrite<u32, DeviceControl::Register>),
58 (0x004 => udint: ReadOnly<u32, DeviceInterrupt::Register>),
59 (0x008 => udintclr: WriteOnly<u32, DeviceInterrupt::Register>),
60 (0x00C => udintset: WriteOnly<u32, DeviceInterrupt::Register>),
61 (0x010 => udinte: ReadOnly<u32, DeviceInterrupt::Register>),
62 (0x014 => udinteclr: WriteOnly<u32, DeviceInterrupt::Register>),
63 (0x018 => udinteset: WriteOnly<u32, DeviceInterrupt::Register>),
64 (0x01C => uerst: ReadWrite<u32>),
65 (0x020 => udfnum: ReadOnly<u32>),
66 (0x024 => _reserved0: [u8; 0xdc]),
67 (0x100 => uecfg: [ReadWrite<u32, EndpointConfig::Register>; 12]),
68 (0x130 => uesta: [ReadOnly<u32, EndpointStatus::Register>; 12]),
69 (0x160 => uestaclr: [WriteOnly<u32, EndpointStatus::Register>; 12]),
70 (0x190 => uestaset: [WriteOnly<u32, EndpointStatus::Register>; 12]),
71 (0x1C0 => uecon: [ReadOnly<u32, EndpointControl::Register>; 12]),
72 (0x1F0 => ueconset: [WriteOnly<u32, EndpointControl::Register>; 12]),
73 (0x220 => ueconclr: [WriteOnly<u32, EndpointControl::Register>; 12]),
74 (0x250 => _reserved1: [u8; 0x1b0]),
75 (0x400 => uhcon: ReadWrite<u32>),
76 (0x404 => uhint: ReadOnly<u32>),
77 (0x408 => uhintclr: WriteOnly<u32>),
78 (0x40C => uhintset: WriteOnly<u32>),
79 (0x410 => uhinte: ReadOnly<u32>),
80 (0x414 => uhinteclr: WriteOnly<u32>),
81 (0x418 => uhinteset: WriteOnly<u32>),
82 (0x41C => uprst: ReadWrite<u32>),
83 (0x420 => uhfnum: ReadWrite<u32>),
84 (0x424 => uhsofc: ReadWrite<u32>),
85 (0x428 => _reserved2: [u8; 0xd8]),
86 (0x500 => upcfg: [ReadWrite<u32>; 12]),
87 (0x530 => upsta: [ReadOnly<u32>; 12]),
88 (0x560 => upstaclr: [WriteOnly<u32>; 12]),
89 (0x590 => upstaset: [WriteOnly<u32>; 12]),
90 (0x5C0 => upcon: [ReadOnly<u32>; 12]),
91 (0x5F0 => upconset: [WriteOnly<u32>; 12]),
92 (0x620 => upconclr: [WriteOnly<u32>; 12]),
93 (0x650 => upinrq: [ReadWrite<u32>; 12]),
94 (0x680 => _reserved3: [u8; 0x180]),
95 (0x800 => usbcon: ReadWrite<u32, Control::Register>),
96 (0x804 => usbsta: ReadOnly<u32, Status::Register>),
97 (0x808 => usbstaclr: WriteOnly<u32>),
98 (0x80C => usbstaset: WriteOnly<u32>),
99 (0x810 => _reserved4: [u8; 8]),
100 (0x818 => uvers: ReadOnly<u32>),
101 (0x81C => ufeatures: ReadOnly<u32>),
102 (0x820 => uaddrsize: ReadOnly<u32>),
103 (0x824 => uname1: ReadOnly<u32>),
104 (0x828 => uname2: ReadOnly<u32>),
105 (0x82C => usbfsm: ReadOnly<u32>),
106 (0x830 => udesc: ReadWrite<u32>),
107 (0x834 => @END),
108 }
109}
110
111register_bitfields![u32,
112 Control [
113 UIMOD OFFSET(25) NUMBITS(1) [
114 HostMode = 0,
115 DeviceMode = 1
116 ],
117 USBE OFFSET(15) NUMBITS(1) [],
118 FRZCLK OFFSET(14) NUMBITS(1) []
119 ],
120 Status [
121 SUSPEND OFFSET(16) NUMBITS(1) [],
122 CLKUSABLE OFFSET(14) NUMBITS(1) [],
123 SPEED OFFSET(12) NUMBITS(2) [
124 SpeedFull = 0b00,
125 SpeedLow = 0b10
126 ],
127 VBUSRQ OFFSET(9) NUMBITS(1) []
128 ],
129 DeviceControl [
130 GNAK OFFSET(17) NUMBITS(1) [],
131 LS OFFSET(12) NUMBITS(1) [
132 FullSpeed = 0,
133 LowSpeed = 1
134 ],
135 RMWKUP OFFSET(9) NUMBITS(1) [],
136 DETACH OFFSET(8) NUMBITS(1) [],
137 ADDEN OFFSET(7) NUMBITS(1) [],
138 UADD OFFSET(0) NUMBITS(7) []
139 ],
140 DeviceInterrupt [
141 EPINT OFFSET(12) NUMBITS(8),
142 UPRSM OFFSET(6) NUMBITS(1),
143 EORSM OFFSET(5) NUMBITS(1),
144 WAKEUP OFFSET(4) NUMBITS(1),
145 EORST OFFSET(3) NUMBITS(1),
146 SOF OFFSET(2) NUMBITS(1),
147 SUSP OFFSET(0) NUMBITS(1)
148 ],
149 EndpointConfig [
150 REPNB OFFSET(16) NUMBITS(4) [
151 NotRedirected = 0
152 ],
153 EPTYPE OFFSET(11) NUMBITS(2) [
154 Control = 0,
155 Isochronous = 1,
156 Bulk = 2,
157 Interrupt = 3
158 ],
159 EPDIR OFFSET(8) NUMBITS(1) [
160 Out = 0,
161 In = 1
162 ],
163 EPSIZE OFFSET(4) NUMBITS(3) [
164 Bytes8 = 0,
165 Bytes16 = 1,
166 Bytes32 = 2,
167 Bytes64 = 3,
168 Bytes128 = 4,
169 Bytes256 = 5,
170 Bytes512 = 6,
171 Bytes1024 = 7
172 ],
173 EPBK OFFSET(2) NUMBITS(1) [
174 Single = 0,
175 Double = 1
176 ]
177 ],
178 EndpointStatus [
179 CTRLDIR OFFSET(17) NUMBITS(1) [
180 Out = 0,
181 In = 1
182 ],
183 CURRBK OFFSET(14) NUMBITS(2) [
184 Bank0 = 0,
185 Bank1 = 1
186 ],
187 NBUSYBK OFFSET(12) NUMBITS(2) [],
188 RAMACER OFFSET(11) NUMBITS(1) [],
189 DTSEQ OFFSET(8) NUMBITS(2) [
190 Data0 = 0,
191 Data1 = 1
192 ],
193 STALLED OFFSET(6) NUMBITS(1) [],
194 CRCERR OFFSET(6) NUMBITS(1) [],
195 NAKIN OFFSET(4) NUMBITS(1) [],
196 NAKOUT OFFSET(3) NUMBITS(1) [],
197 ERRORF OFFSET(2) NUMBITS(1) [],
198 RXSTP OFFSET(2) NUMBITS(1) [],
199 RXOUT OFFSET(1) NUMBITS(1) [],
200 TXIN OFFSET(0) NUMBITS(1) []
201 ],
202 EndpointControl [
203 BUSY1E 25,
204 BUSY0E 24,
205 STALLRQ 19,
206 RSTDT 18,
207 FIFOCON 14,
208 KILLBK 13,
209 NBUSYBKE 12,
210 RAMACERE 11,
211 NREPLY 8,
212 STALLEDE 6,
213 CRCERRE 6,
214 NAKINE 4,
215 NAKOUTE 3,
216 RXSTPE 2,
217 ERRORFE 2,
218 RXOUTE 1,
219 TXINE 0
220 ]
221];
222
223const USBC_BASE: StaticRef<UsbcRegisters> =
224 unsafe { StaticRef::new(0x400A5000 as *const UsbcRegisters) };
225
226#[inline]
227fn usbc_regs() -> &'static UsbcRegisters {
228 &USBC_BASE
229}
230
231pub const N_ENDPOINTS: usize = 8;
234
235#[repr(C)]
237#[repr(align(8))]
239pub struct Usbc<'a> {
240 descriptors: [Endpoint; N_ENDPOINTS],
241 state: OptionalCell<State>,
242 requests: [Cell<Requests>; N_ENDPOINTS],
243 client: OptionalCell<&'a dyn hil::usb::Client<'a>>,
244 pm: &'a pm::PowerManager,
245}
246
247#[derive(Copy, Clone, Default, Debug)]
248pub struct Requests {
249 pub resume_in: bool,
250 pub resume_out: bool,
251}
252
253impl Requests {
254 pub const fn new() -> Self {
255 Requests {
256 resume_in: false,
257 resume_out: false,
258 }
259 }
260}
261
262#[derive(Copy, Clone, Debug)]
263pub enum State {
264 Reset,
266
267 Idle(Mode),
271
272 Active(Mode),
274}
275
276#[derive(Copy, Clone, Debug)]
277pub enum Mode {
278 Host,
279 Device {
280 speed: Speed,
281 config: DeviceConfig,
282 state: DeviceState,
283 },
284}
285
286type EndpointConfigValue = LocalRegisterCopy<u32, EndpointConfig::Register>;
287type EndpointStatusValue = LocalRegisterCopy<u32, EndpointStatus::Register>;
288
289#[derive(Copy, Clone, Debug, Default)]
290pub struct DeviceConfig {
291 pub endpoint_configs: [Option<EndpointConfigValue>; N_ENDPOINTS],
292}
293
294#[derive(Copy, Clone, Debug, Default)]
295pub struct DeviceState {
296 pub endpoint_states: [EndpointState; N_ENDPOINTS],
297}
298
299#[derive(Copy, Clone, Debug, Default)]
300pub enum EndpointState {
301 #[default]
302 Disabled,
303 Ctrl(CtrlState),
304 BulkIn(BulkInState),
305 BulkOut(BulkOutState),
306}
307
308#[derive(Copy, Clone, PartialEq, Debug)]
309pub enum CtrlState {
310 Init,
311 ReadIn,
312 ReadStatus,
313 WriteOut,
314 WriteStatus,
315 WriteStatusWait,
316 InDelay,
317}
318
319#[derive(Copy, Clone, PartialEq, Debug)]
320pub enum BulkInState {
321 Init,
322 Delay,
323}
324
325#[derive(Copy, Clone, PartialEq, Debug)]
326pub enum BulkOutState {
327 Init,
328 Delay,
329}
330
331#[derive(Copy, Clone, PartialEq, Debug)]
332pub enum Speed {
333 Full,
334 Low,
335}
336
337pub enum BankIndex {
338 Bank0,
339 Bank1,
340}
341
342impl From<BankIndex> for usize {
343 fn from(bi: BankIndex) -> usize {
344 match bi {
345 BankIndex::Bank0 => 0,
346 BankIndex::Bank1 => 1,
347 }
348 }
349}
350
351pub struct EndpointIndex(u8);
352
353impl EndpointIndex {
354 pub fn new(index: usize) -> EndpointIndex {
355 EndpointIndex(index as u8 & 0xf)
356 }
357
358 pub fn to_u32(self) -> u32 {
359 self.0 as u32
360 }
361}
362
363impl From<EndpointIndex> for usize {
364 fn from(ei: EndpointIndex) -> usize {
365 ei.0 as usize
366 }
367}
368
369pub type Endpoint = [Bank; 2];
370
371pub const fn new_endpoint() -> Endpoint {
372 [Bank::new(), Bank::new()]
373}
374
375#[repr(C)]
376pub struct Bank {
377 addr: InMemoryRegister<u32>,
378
379 pub packet_size: InMemoryRegister<u32, PacketSize::Register>,
384 pub control_status: InMemoryRegister<u32, ControlStatus::Register>,
385
386 _reserved: u32,
387}
388
389impl Bank {
390 pub const fn new() -> Bank {
391 Bank {
392 addr: InMemoryRegister::new(0),
393 packet_size: InMemoryRegister::new(0),
394 control_status: InMemoryRegister::new(0),
395 _reserved: 0,
396 }
397 }
398
399 pub fn set_addr(&self, addr: *mut u8) {
400 self.addr.set(addr as u32);
401 }
402}
403
404register_bitfields![u32,
405 PacketSize [
406 AUTO_ZLP OFFSET(31) NUMBITS(1) [
407 No = 0,
408 Yes = 1
409 ],
410 MULTI_PACKET_SIZE OFFSET(16) NUMBITS(15) [],
411 BYTE_COUNT OFFSET(0) NUMBITS(15) []
412 ],
413 ControlStatus [
414 UNDERF 18,
415 OVERF 17,
416 CRCERR 16,
417 STALLRQ_NEXT 0
418 ]
419];
420
421impl<'a> Usbc<'a> {
422 pub const fn new(pm: &'a pm::PowerManager) -> Self {
423 Usbc {
424 client: OptionalCell::empty(),
425 state: OptionalCell::new(State::Reset),
426 descriptors: [
427 new_endpoint(),
428 new_endpoint(),
429 new_endpoint(),
430 new_endpoint(),
431 new_endpoint(),
432 new_endpoint(),
433 new_endpoint(),
434 new_endpoint(),
435 ],
436 requests: [
437 Cell::new(Requests::new()),
438 Cell::new(Requests::new()),
439 Cell::new(Requests::new()),
440 Cell::new(Requests::new()),
441 Cell::new(Requests::new()),
442 Cell::new(Requests::new()),
443 Cell::new(Requests::new()),
444 Cell::new(Requests::new()),
445 ],
446 pm,
447 }
448 }
449
450 fn map_state<F, R>(&self, closure: F) -> R
451 where
452 F: FnOnce(&mut State) -> R,
453 {
454 let mut state = self.state.take().unwrap(); let result = closure(&mut state);
456 self.state.set(state);
457 result
458 }
459
460 fn get_state(&self) -> State {
461 self.state.unwrap_or_panic() }
463
464 fn set_state(&self, state: State) {
465 self.state.set(state);
466 }
467
468 fn endpoint_bank_set_buffer(
471 &self,
472 endpoint: EndpointIndex,
473 bank: BankIndex,
474 buf: &[InMemoryRegister<u8>],
475 ) {
476 let e: usize = From::from(endpoint);
477 let b: usize = From::from(bank);
478 let p: *const InMemoryRegister<u8> = buf.as_ptr();
479 let p: *mut u8 = p.cast_mut().cast();
480
481 debug1!("Set Endpoint{}/Bank{} addr={:8?}", e, b, p);
482 self.descriptors[e][b].set_addr(p);
483 self.descriptors[e][b].packet_size.write(
484 PacketSize::BYTE_COUNT.val(0)
485 + PacketSize::MULTI_PACKET_SIZE.val(0)
486 + PacketSize::AUTO_ZLP::No,
487 );
488 }
489
490 fn enable(&self, mode: Mode) {
492 match self.get_state() {
493 State::Reset => {
494 enable_clock(Clock::HSB(HSBClock::USBC));
499 enable_clock(Clock::PBB(PBBClock::USBC));
500
501 if let Mode::Device { speed, .. } = mode {
506 usbc_regs().udcon.modify(match speed {
507 Speed::Full => DeviceControl::LS::FullSpeed,
508 Speed::Low => DeviceControl::LS::LowSpeed,
509 });
510 }
511
512 usbc_regs().usbcon.modify(Control::UIMOD::DeviceMode);
514 usbc_regs().usbcon.modify(Control::FRZCLK::CLEAR);
515 usbc_regs().usbcon.modify(Control::USBE::SET);
516
517 usbc_regs()
519 .udesc
520 .set(core::ptr::addr_of!(self.descriptors) as u32);
521
522 usbc_regs().udintclr.write(
524 DeviceInterrupt::SUSP::SET
525 + DeviceInterrupt::SOF::SET
526 + DeviceInterrupt::EORST::SET
527 + DeviceInterrupt::EORSM::SET
528 + DeviceInterrupt::UPRSM::SET,
529 );
530
531 usbc_regs().udinteset.write(
538 DeviceInterrupt::EORST::SET
539 + DeviceInterrupt::EORSM::SET
540 + DeviceInterrupt::UPRSM::SET,
541 );
542
543 debug1!("Enabled");
544
545 self.set_state(State::Idle(mode));
546 }
547 _ => internal_err!("Already enabled"),
548 }
549 }
550
551 fn _disable(&self) {
553 if let State::Active(_) = self.get_state() {
555 self.detach();
556 }
557
558 match self.get_state() {
560 State::Idle(..) => {
561 usbc_regs().usbcon.modify(Control::USBE::CLEAR);
562
563 disable_clock(Clock::PBB(PBBClock::USBC));
564 disable_clock(Clock::HSB(HSBClock::USBC));
565
566 self.set_state(State::Reset);
567 }
568 _ => internal_err!("Disable called from wrong state"),
569 }
570 }
571
572 fn attach(&self) {
574 match self.get_state() {
575 State::Idle(mode) => {
576 if self.pm.get_system_frequency() != 48000000 {
577 internal_err!("The system clock does not support USB");
578 }
579
580 scif::generic_clock_enable(scif::GenericClock::GCLK7, scif::ClockSource::CLK_HSB);
582
583 while !usbc_regs().usbsta.is_set(Status::CLKUSABLE) {}
584
585 usbc_regs().udcon.modify(DeviceControl::DETACH::CLEAR);
586
587 debug1!("Attached");
588
589 self.set_state(State::Active(mode));
590 }
591 _ => internal_err!("Attach called in wrong state"),
592 }
593 }
594
595 fn detach(&self) {
597 if let State::Active(mode) = self.get_state() {
598 usbc_regs().udcon.modify(DeviceControl::DETACH::SET);
599
600 scif::generic_clock_disable(scif::GenericClock::GCLK7);
601
602 self.set_state(State::Idle(mode));
603 }
604 }
605
606 fn endpoint_enable(&self, endpoint: usize, endpoint_config: EndpointConfigValue) {
608 self.endpoint_record_config(endpoint, endpoint_config);
609 self.endpoint_write_config(endpoint, endpoint_config);
610
611 usbc_regs()
614 .uerst
615 .set(usbc_regs().uerst.get() | (1 << endpoint));
616
617 self.endpoint_init(endpoint, endpoint_config);
618
619 usbc_regs().udinteset.set(1 << (12 + endpoint));
621
622 debug1!("Enabled endpoint {}", endpoint);
623 }
624
625 fn endpoint_record_config(&self, endpoint: usize, endpoint_config: EndpointConfigValue) {
626 self.map_state(|state| match *state {
628 State::Reset => {
629 client_err!("Not enabled");
630 }
631 State::Idle(Mode::Device { ref mut config, .. }) => {
632 config.endpoint_configs[endpoint] = Some(endpoint_config);
634 }
635 State::Active(Mode::Device { ref mut config, .. }) => {
636 config.endpoint_configs[endpoint] = Some(endpoint_config);
638 }
639 _ => client_err!("Not in Device mode"),
640 });
641 }
642
643 fn endpoint_write_config(&self, endpoint: usize, config: EndpointConfigValue) {
644 usbc_regs().uecfg[endpoint].set(From::from(config));
648
649 debug1!("Configured endpoint {}", endpoint);
650 }
651
652 fn endpoint_init(&self, endpoint: usize, config: EndpointConfigValue) {
653 self.map_state(|state| match *state {
654 State::Idle(Mode::Device { ref mut state, .. }) => {
655 self.endpoint_init_with_device_state(state, endpoint, config);
656 }
657 State::Active(Mode::Device { ref mut state, .. }) => {
658 self.endpoint_init_with_device_state(state, endpoint, config);
659 }
660 _ => internal_err!("Not reached"),
661 });
662 }
663
664 fn endpoint_init_with_device_state(
665 &self,
666 state: &mut DeviceState,
667 endpoint: usize,
668 config: EndpointConfigValue,
669 ) {
670 endpoint_enable_interrupts(
673 endpoint,
674 EndpointControl::RAMACERE::SET + EndpointControl::STALLEDE::SET,
675 );
676
677 if config.matches_all(EndpointConfig::EPTYPE::Control) {
678 endpoint_enable_interrupts(endpoint, EndpointControl::RXSTPE::SET);
679 state.endpoint_states[endpoint] = EndpointState::Ctrl(CtrlState::Init);
680 } else if config.matches_all(EndpointConfig::EPTYPE::Bulk + EndpointConfig::EPDIR::In) {
681 endpoint_enable_interrupts(endpoint, EndpointControl::TXINE::SET);
682 state.endpoint_states[endpoint] = EndpointState::BulkIn(BulkInState::Init);
683 } else if config.matches_all(EndpointConfig::EPTYPE::Bulk + EndpointConfig::EPDIR::Out) {
684 endpoint_enable_interrupts(endpoint, EndpointControl::RXOUTE::SET);
685 state.endpoint_states[endpoint] = EndpointState::BulkOut(BulkOutState::Init);
686 } else {
687 }
689
690 debug1!("Initialized endpoint {}", endpoint);
691 }
692
693 fn endpoint_resume_in(&self, endpoint: usize) {
694 self.map_state(|state| match *state {
695 State::Active(Mode::Device { ref mut state, .. }) => {
696 let endpoint_state = &mut state.endpoint_states[endpoint];
697 match *endpoint_state {
698 EndpointState::BulkIn(BulkInState::Delay) => {
699 endpoint_enable_interrupts(endpoint, EndpointControl::TXINE::SET);
701 *endpoint_state = EndpointState::BulkIn(BulkInState::Init);
702 }
703 _ => debugln!("Ignoring superfluous resume_in"),
705 }
706 }
707 _ => debugln!("Ignoring inappropriate resume_in"),
708 });
709 }
710
711 fn endpoint_resume_out(&self, endpoint: usize) {
712 self.map_state(|state| match *state {
713 State::Active(Mode::Device { ref mut state, .. }) => {
714 let endpoint_state = &mut state.endpoint_states[endpoint];
715 match *endpoint_state {
716 EndpointState::BulkOut(BulkOutState::Delay) => {
717 endpoint_enable_interrupts(endpoint, EndpointControl::RXOUTE::SET);
719 *endpoint_state = EndpointState::BulkOut(BulkOutState::Init);
720 }
721 _ => debugln!("Ignoring superfluous resume_out"),
723 }
724 }
725 _ => debugln!("Ignoring inappropriate resume_out"),
726 });
727 }
728
729 fn handle_requests(&self) {
730 for endpoint in 0..N_ENDPOINTS {
731 let mut requests = self.requests[endpoint].get();
732
733 if requests.resume_in {
734 self.endpoint_resume_in(endpoint);
735 requests.resume_in = false;
736 }
737 if requests.resume_out {
738 self.endpoint_resume_out(endpoint);
739 requests.resume_out = false;
740 }
741
742 self.requests[endpoint].set(requests);
743 }
744 }
745
746 pub fn handle_interrupt(&self) {
748 self.map_state(|state| match *state {
749 State::Reset => internal_err!("Received interrupt in Reset"),
750 State::Idle(_) => {
751 debug1!("Received interrupt in Idle");
753 }
754 State::Active(ref mut mode) => match *mode {
755 Mode::Device {
756 speed,
757 ref config,
758 ref mut state,
759 } => self.handle_device_interrupt(speed, config, state),
760 Mode::Host => internal_err!("Host mode unimplemented"),
761 },
762 });
763
764 self.handle_requests();
766 }
767
768 fn handle_device_interrupt(
770 &self,
771 speed: Speed,
772 device_config: &DeviceConfig,
773 device_state: &mut DeviceState,
774 ) {
775 let udint = usbc_regs().udint.extract();
776
777 debug1!("--> UDINT={:?}", UdintFlags(udint.get()));
778
779 if udint.is_set(DeviceInterrupt::EORST) {
780 debug1!("USB Bus Reset");
782
783 usbc_regs().udcon.modify(match speed {
785 Speed::Full => DeviceControl::LS::FullSpeed,
786 Speed::Low => DeviceControl::LS::LowSpeed,
787 });
788
789 *device_state = DeviceState::default();
791
792 for i in 0..N_ENDPOINTS {
794 if let Some(endpoint_config) = device_config.endpoint_configs[i] {
795 self.endpoint_write_config(i, endpoint_config);
796 self.endpoint_init_with_device_state(device_state, i, endpoint_config);
797 }
798 }
799
800 self.client.map(|client| {
802 client.bus_reset();
803 });
804
805 usbc_regs().udintclr.write(DeviceInterrupt::EORST::SET);
807
808 return;
810 }
811
812 if udint.is_set(DeviceInterrupt::SUSP) {
813 usbc_regs().udinteset.write(DeviceInterrupt::WAKEUP::SET);
830
831 usbc_regs().udintclr.write(DeviceInterrupt::SUSP::SET);
833 }
834
835 if udint.is_set(DeviceInterrupt::WAKEUP) {
836 usbc_regs().udinteclr.write(DeviceInterrupt::WAKEUP::SET);
840
841 usbc_regs().udintclr.write(DeviceInterrupt::WAKEUP::SET);
843
844 }
846
847 if udint.is_set(DeviceInterrupt::SOF) {
848 usbc_regs().udintclr.write(DeviceInterrupt::SOF::SET);
850 }
851
852 if udint.is_set(DeviceInterrupt::EORSM) {
853 debug1!("UDINT EORSM");
855 }
856
857 if udint.is_set(DeviceInterrupt::UPRSM) {
858 debug1!("UDINT UPRSM");
860 }
861
862 for endpoint in 0..N_ENDPOINTS {
864 if udint.get() & (1 << (12 + endpoint)) == 0 {
865 continue;
867 }
868
869 self.handle_endpoint_interrupt(endpoint, &mut device_state.endpoint_states[endpoint]);
870 }
871 }
872
873 fn handle_endpoint_interrupt(&self, endpoint: usize, endpoint_state: &mut EndpointState) {
874 let status = usbc_regs().uesta[endpoint].extract();
875 debug1!(" UESTA{}={:?}", endpoint, UestaFlags(status.get()));
876
877 if status.is_set(EndpointStatus::STALLED) {
878 debug1!("\tep{}: STALLED/CRCERR", endpoint);
879
880 usbc_regs().uestaclr[endpoint].write(EndpointStatus::STALLED::SET);
882 }
883
884 if status.is_set(EndpointStatus::RAMACER) {
885 debug1!("\tep{}: RAMACER", endpoint);
886
887 usbc_regs().uestaclr[endpoint].write(EndpointStatus::RAMACER::SET);
889 }
890
891 match *endpoint_state {
892 EndpointState::Ctrl(ref mut ctrl_state) => {
893 self.handle_ctrl_endpoint_interrupt(endpoint, ctrl_state, status)
894 }
895 EndpointState::BulkIn(ref mut bulk_in_state) => {
896 self.handle_bulk_in_endpoint_interrupt(endpoint, bulk_in_state, status)
897 }
898 EndpointState::BulkOut(ref mut bulk_out_state) => {
899 self.handle_bulk_out_endpoint_interrupt(endpoint, bulk_out_state, status)
900 }
901 EndpointState::Disabled => {
902 debug1!("Ignoring interrupt for disabled endpoint {}", endpoint);
903 }
904 }
905 }
906
907 fn handle_ctrl_endpoint_interrupt(
908 &self,
909 endpoint: usize,
910 ctrl_state: &mut CtrlState,
911 status: EndpointStatusValue,
912 ) {
913 let mut again = true;
914 while again {
915 again = false;
916 debug1!(
921 " ep{}: Ctrl({:?}) UECON={:?}",
922 endpoint,
923 *ctrl_state,
924 UeconFlags(usbc_regs().uecon[endpoint].get())
925 );
926
927 match *ctrl_state {
928 CtrlState::Init => {
929 if status.is_set(EndpointStatus::RXSTP) {
930 debug1!("\tep{}: RXSTP", endpoint);
933 let bank = 0;
936 let packet_bytes = self.descriptors[endpoint][bank]
937 .packet_size
938 .read(PacketSize::BYTE_COUNT);
939 let result = if packet_bytes == 8 {
940 self.client.map(|c| c.ctrl_setup(endpoint))
941 } else {
942 Some(hil::usb::CtrlSetupResult::ErrBadLength)
943 };
944
945 match result {
946 Some(hil::usb::CtrlSetupResult::Ok)
947 | Some(hil::usb::CtrlSetupResult::OkSetAddress) => {
948 endpoint_disable_interrupts(endpoint, EndpointControl::RXSTPE::SET);
950
951 if status.matches_all(EndpointStatus::CTRLDIR::In) {
952 usbc_regs().uestaclr[endpoint]
959 .write(EndpointStatus::NAKOUT::SET);
960 endpoint_enable_interrupts(
961 endpoint,
962 EndpointControl::TXINE::SET + EndpointControl::NAKOUTE::SET,
963 );
964 *ctrl_state = CtrlState::ReadIn;
965 } else {
966 usbc_regs().uestaclr[endpoint]
971 .write(EndpointStatus::NAKIN::SET);
972 endpoint_enable_interrupts(
973 endpoint,
974 EndpointControl::RXOUTE::SET + EndpointControl::NAKINE::SET,
975 );
976 *ctrl_state = CtrlState::WriteOut;
977 }
978 }
979 failure => {
980 usbc_regs().ueconset[endpoint].write(EndpointControl::STALLRQ::SET);
983
984 match failure {
985 None => debug1!("\tep{}: No client to handle Setup", endpoint),
986 Some(_err) => {
987 debug1!("\tep{}: Client err on Setup: {:?}", endpoint, _err)
988 }
989 }
990
991 }
993 }
994
995 usbc_regs().uestaclr[endpoint].write(EndpointStatus::RXSTP::SET);
997 }
998 }
999 CtrlState::ReadIn => {
1000 if status.is_set(EndpointStatus::NAKOUT) {
1004 endpoint_disable_interrupts(
1007 endpoint,
1008 EndpointControl::TXINE::SET + EndpointControl::NAKOUTE::SET,
1009 );
1010
1011 debug1!("\tep{}: NAKOUT", endpoint);
1012 self.client.map(|c| c.ctrl_status(endpoint));
1013
1014 endpoint_enable_interrupts(endpoint, EndpointControl::RXOUTE::SET);
1016
1017 usbc_regs().uestaclr[endpoint].write(EndpointStatus::NAKOUT::SET);
1019
1020 *ctrl_state = CtrlState::ReadStatus;
1021
1022 again = true;
1024 } else if status.is_set(EndpointStatus::TXIN) {
1025 debug1!("\tep{}: TXIN", endpoint);
1027
1028 let result = self.client.map(|c| {
1029 c.ctrl_in(endpoint)
1031 });
1032 match result {
1033 Some(hil::usb::CtrlInResult::Packet(
1034 packet_bytes,
1035 transfer_complete,
1036 )) => {
1037 let packet_size = if packet_bytes == 64 && transfer_complete {
1042 PacketSize::BYTE_COUNT.val(64) + PacketSize::AUTO_ZLP::Yes
1046 } else {
1047 PacketSize::BYTE_COUNT.val(packet_bytes as u32)
1051 };
1052 let bank = 0;
1053 self.descriptors[endpoint][bank]
1054 .packet_size
1055 .write(packet_size);
1056
1057 debug1!(
1058 "\tep{}: Send CTRL IN packet ({} bytes)",
1059 endpoint,
1060 packet_bytes
1061 );
1062 if transfer_complete {
1065 endpoint_disable_interrupts(
1068 endpoint,
1069 EndpointControl::TXINE::SET,
1070 );
1071 } else {
1072 }
1074
1075 usbc_regs().uestaclr[endpoint].write(EndpointStatus::TXIN::SET);
1078 }
1079 Some(hil::usb::CtrlInResult::Delay) => {
1080 endpoint_disable_interrupts(endpoint, EndpointControl::TXINE::SET);
1081
1082 debug1!("*** Client NAK");
1083
1084 *ctrl_state = CtrlState::InDelay;
1087 }
1088 _ => {
1089 usbc_regs().ueconset[endpoint].write(EndpointControl::STALLRQ::SET);
1091
1092 debug1!("\tep{}: Client IN err => STALL", endpoint);
1093
1094 endpoint_disable_interrupts(
1096 endpoint,
1097 EndpointControl::NAKOUTE::SET,
1098 );
1099 endpoint_enable_interrupts(endpoint, EndpointControl::RXSTPE::SET);
1100 *ctrl_state = CtrlState::Init;
1101 }
1102 }
1103 }
1104 }
1105 CtrlState::ReadStatus => {
1106 if status.is_set(EndpointStatus::RXOUT) {
1107 debug1!("\tep{}: RXOUT: End of Control Read transaction", endpoint);
1110
1111 endpoint_disable_interrupts(endpoint, EndpointControl::RXOUTE::SET);
1113 endpoint_enable_interrupts(endpoint, EndpointControl::RXSTPE::SET);
1114 *ctrl_state = CtrlState::Init;
1115
1116 usbc_regs().uestaclr[endpoint].write(EndpointStatus::RXOUT::SET);
1118
1119 self.client.map(|c| c.ctrl_status_complete(endpoint));
1120 }
1121 }
1122 CtrlState::WriteOut => {
1123 if status.is_set(EndpointStatus::RXOUT) {
1124 debug1!("\tep{}: RXOUT: Received Control Write data", endpoint);
1127 let bank = 0;
1131 let result = self.client.map(|c| {
1132 c.ctrl_out(
1133 endpoint,
1134 self.descriptors[endpoint][bank]
1135 .packet_size
1136 .read(PacketSize::BYTE_COUNT),
1137 )
1138 });
1139 match result {
1140 Some(hil::usb::CtrlOutResult::Ok) => {
1141 usbc_regs().uestaclr[endpoint].write(EndpointStatus::RXOUT::SET);
1143 }
1144 Some(hil::usb::CtrlOutResult::Delay) => {
1145 endpoint_disable_interrupts(endpoint, EndpointControl::RXOUTE::SET);
1150 }
1151 _ => {
1152 usbc_regs().ueconset[endpoint].write(EndpointControl::STALLRQ::SET);
1155
1156 debug1!("\tep{}: Client OUT err => STALL", endpoint);
1157
1158 endpoint_disable_interrupts(
1160 endpoint,
1161 EndpointControl::RXOUTE::SET + EndpointControl::NAKINE::SET,
1162 );
1163 endpoint_enable_interrupts(endpoint, EndpointControl::RXSTPE::SET);
1164 *ctrl_state = CtrlState::Init;
1165 }
1166 }
1167 }
1168 if status.is_set(EndpointStatus::NAKIN) {
1169 debug1!("\tep{}: NAKIN: Control Write -> Status stage", endpoint);
1171
1172 usbc_regs().uestaclr[endpoint].write(EndpointStatus::NAKIN::SET);
1174
1175 endpoint_disable_interrupts(
1177 endpoint,
1178 EndpointControl::RXOUTE::SET + EndpointControl::NAKINE::SET,
1179 );
1180 endpoint_enable_interrupts(endpoint, EndpointControl::TXINE::SET);
1181 *ctrl_state = CtrlState::WriteStatus;
1182
1183 again = true;
1185 }
1186 }
1187 CtrlState::WriteStatus => {
1188 if status.is_set(EndpointStatus::TXIN) {
1189 debug1!(
1190 "\tep{}: TXIN for Control Write Status (will send ZLP)",
1191 endpoint
1192 );
1193
1194 self.client.map(|c| c.ctrl_status(endpoint));
1195
1196 let bank = 0;
1198 self.descriptors[endpoint][bank]
1199 .packet_size
1200 .write(PacketSize::BYTE_COUNT.val(0));
1201
1202 usbc_regs().uestaclr[endpoint].write(EndpointStatus::TXIN::SET);
1204
1205 *ctrl_state = CtrlState::WriteStatusWait;
1207 }
1208 }
1209 CtrlState::WriteStatusWait => {
1210 if status.is_set(EndpointStatus::TXIN) {
1211 debug1!("\tep{}: TXIN: Control Write Status Complete", endpoint);
1212
1213 endpoint_disable_interrupts(endpoint, EndpointControl::TXINE::SET);
1215 endpoint_enable_interrupts(endpoint, EndpointControl::RXSTPE::SET);
1216 *ctrl_state = CtrlState::Init;
1217
1218 self.client.map(|c| c.ctrl_status_complete(endpoint));
1220 }
1221 }
1222 CtrlState::InDelay => internal_err!("Not reached"),
1223 }
1224
1225 }
1230 }
1231
1232 fn handle_bulk_out_endpoint_interrupt(
1233 &self,
1234 endpoint: usize,
1235 bulk_out_state: &mut BulkOutState,
1236 status: EndpointStatusValue,
1237 ) {
1238 match *bulk_out_state {
1239 BulkOutState::Init => {
1240 if status.is_set(EndpointStatus::RXOUT) {
1241 debug1!("\tep{}: RXOUT", endpoint);
1244
1245 if !usbc_regs().uecon[endpoint].is_set(EndpointControl::FIFOCON) {
1246 debugln!("Got RXOUT but not FIFOCON");
1247 return;
1248 }
1249 let bank = 0;
1252 let packet_bytes = self.descriptors[endpoint][bank]
1253 .packet_size
1254 .read(PacketSize::BYTE_COUNT);
1255
1256 let result = self.client.map(|c| {
1257 c.packet_out(TransferType::Bulk, endpoint, packet_bytes)
1259 });
1260 match result {
1261 Some(hil::usb::OutResult::Ok) => {
1262 usbc_regs().uestaclr[endpoint].write(EndpointStatus::RXOUT::SET);
1264
1265 usbc_regs().ueconclr[endpoint].write(EndpointControl::FIFOCON::SET);
1267
1268 debug1!(
1269 "\tep{}: Recv BULK OUT packet ({} bytes)",
1270 endpoint,
1271 packet_bytes
1272 );
1273
1274 }
1276 Some(hil::usb::OutResult::Delay) => {
1277 endpoint_disable_interrupts(endpoint, EndpointControl::RXOUTE::SET);
1280
1281 *bulk_out_state = BulkOutState::Delay;
1282 }
1283 _ => {
1284 debug1!("\tep{}: Client OUT err => STALL", endpoint);
1285
1286 usbc_regs().ueconset[endpoint].write(EndpointControl::STALLRQ::SET);
1288
1289 }
1293 }
1294 }
1295 }
1296 BulkOutState::Delay => internal_err!("Not reached"),
1297 }
1298 }
1299
1300 fn handle_bulk_in_endpoint_interrupt(
1301 &self,
1302 endpoint: usize,
1303 bulk_in_state: &mut BulkInState,
1304 status: EndpointStatusValue,
1305 ) {
1306 match *bulk_in_state {
1307 BulkInState::Init => {
1308 if status.is_set(EndpointStatus::TXIN) {
1309 debug1!("\tep{}: TXIN", endpoint);
1312
1313 if !usbc_regs().uecon[endpoint].is_set(EndpointControl::FIFOCON) {
1314 debugln!("Got TXIN but not FIFOCON");
1315 return;
1316 }
1317 let result = self.client.map(|c| {
1320 c.packet_in(TransferType::Bulk, endpoint)
1322 });
1323 match result {
1324 Some(hil::usb::InResult::Packet(packet_bytes)) => {
1325 usbc_regs().uestaclr[endpoint].write(EndpointStatus::TXIN::SET);
1327
1328 let bank = 0;
1330 self.descriptors[endpoint][bank]
1331 .packet_size
1332 .write(PacketSize::BYTE_COUNT.val(packet_bytes as u32));
1333
1334 usbc_regs().ueconclr[endpoint].write(EndpointControl::FIFOCON::SET);
1336
1337 debug1!(
1338 "\tep{}: Send BULK IN packet ({} bytes)",
1339 endpoint,
1340 packet_bytes
1341 );
1342
1343 }
1345 Some(hil::usb::InResult::Delay) => {
1346 endpoint_disable_interrupts(endpoint, EndpointControl::TXINE::SET);
1349
1350 *bulk_in_state = BulkInState::Delay;
1351 }
1352 _ => {
1353 debug1!("\tep{}: Client IN err => STALL", endpoint);
1354
1355 usbc_regs().ueconset[endpoint].write(EndpointControl::STALLRQ::SET);
1357
1358 }
1362 }
1363 }
1364 }
1365 BulkInState::Delay => {
1366 internal_err!("Not reached");
1368 }
1369 }
1370 }
1371
1372 #[allow(dead_code)]
1373 fn debug_show_d0(&self) {
1374 for bi in 0..1 {
1375 let b = &self.descriptors[0][bi];
1376 let addr = b.addr.get() as *const u8;
1377 let _buf = if addr.is_null() {
1378 None
1379 } else {
1380 unsafe {
1381 Some(slice::from_raw_parts(
1382 addr,
1383 b.packet_size.read(PacketSize::BYTE_COUNT) as usize,
1384 ))
1385 }
1386 };
1387
1388 debug1!(
1389 "B_0_{} \
1390 \n {:?}\
1391 \n {:?}\
1392 \n {:?}",
1393 bi, b.packet_size.get(),
1395 b.control_status.get(),
1396 _buf.map(HexBuf)
1397 );
1398 }
1399 }
1400
1401 pub fn mode(&self) -> Option<Mode> {
1402 match self.get_state() {
1403 State::Idle(mode) => Some(mode),
1404 State::Active(mode) => Some(mode),
1405 _ => None,
1406 }
1407 }
1408
1409 pub fn speed(&self) -> Option<Speed> {
1410 match self.mode() {
1411 Some(mode) => {
1412 match mode {
1413 Mode::Device { speed, .. } => Some(speed),
1414 Mode::Host => {
1415 None }
1417 }
1418 }
1419 _ => None,
1420 }
1421 }
1422
1423 }
1425
1426#[inline]
1427fn endpoint_disable_interrupts(endpoint: usize, mask: FieldValue<u32, EndpointControl::Register>) {
1428 usbc_regs().ueconclr[endpoint].write(mask);
1429}
1430
1431#[inline]
1432fn endpoint_enable_interrupts(endpoint: usize, mask: FieldValue<u32, EndpointControl::Register>) {
1433 usbc_regs().ueconset[endpoint].write(mask);
1434}
1435
1436impl<'a> hil::usb::UsbController<'a> for Usbc<'a> {
1437 fn set_client(&self, client: &'a dyn hil::usb::Client<'a>) {
1438 self.client.set(client);
1439 }
1440
1441 fn endpoint_set_ctrl_buffer(&self, buf: &'a [InMemoryRegister<u8>]) {
1442 if buf.len() < 8 {
1443 client_err!("Bad endpoint buffer size");
1444 }
1445
1446 self.endpoint_bank_set_buffer(EndpointIndex::new(0), BankIndex::Bank0, buf);
1447 }
1448
1449 fn endpoint_set_in_buffer(&self, endpoint: usize, buf: &'a [InMemoryRegister<u8>]) {
1450 if buf.len() < 8 {
1451 client_err!("Bad endpoint buffer size");
1452 }
1453
1454 self.endpoint_bank_set_buffer(EndpointIndex::new(endpoint), BankIndex::Bank0, buf);
1455 }
1456
1457 fn endpoint_set_out_buffer(&self, endpoint: usize, buf: &'a [InMemoryRegister<u8>]) {
1458 if buf.len() < 8 {
1459 client_err!("Bad endpoint buffer size");
1460 }
1461
1462 self.endpoint_bank_set_buffer(EndpointIndex::new(endpoint), BankIndex::Bank0, buf);
1464 }
1465
1466 fn enable_as_device(&self, speed: hil::usb::DeviceSpeed) {
1467 let speed = match speed {
1468 hil::usb::DeviceSpeed::Full => Speed::Full,
1469 hil::usb::DeviceSpeed::Low => Speed::Low,
1470 };
1471
1472 match self.get_state() {
1473 State::Reset => self.enable(Mode::Device {
1474 speed,
1475 config: DeviceConfig::default(),
1476 state: DeviceState::default(),
1477 }),
1478 _ => client_err!("Already enabled"),
1479 }
1480 }
1481
1482 fn attach(&self) {
1483 match self.get_state() {
1484 State::Reset => client_warn!("Not enabled"),
1485 State::Active(_) => client_warn!("Already attached"),
1486 State::Idle(_) => self.attach(),
1487 }
1488 }
1489
1490 fn detach(&self) {
1491 match self.get_state() {
1492 State::Reset => client_warn!("Not enabled"),
1493 State::Idle(_) => client_warn!("Not attached"),
1494 State::Active(_) => self.detach(),
1495 }
1496 }
1497
1498 fn set_address(&self, addr: u16) {
1499 usbc_regs()
1500 .udcon
1501 .modify(DeviceControl::UADD.val(addr as u32));
1502
1503 debug1!("Set Address = {}", addr);
1504 }
1505
1506 fn enable_address(&self) {
1507 usbc_regs().udcon.modify(DeviceControl::ADDEN::SET);
1508
1509 debug1!(
1510 "Enable Address = {}",
1511 usbc_regs().udcon.read(DeviceControl::UADD)
1512 );
1513 }
1514
1515 fn endpoint_in_enable(&self, transfer_type: TransferType, endpoint: usize) {
1516 let endpoint_cfg = match transfer_type {
1517 TransferType::Control => {
1518 panic!("There is no IN control endpoint");
1519 }
1520 TransferType::Bulk => LocalRegisterCopy::new(From::from(
1521 EndpointConfig::EPTYPE::Bulk
1522 + EndpointConfig::EPDIR::In
1523 + EndpointConfig::EPSIZE::Bytes8
1524 + EndpointConfig::EPBK::Single,
1525 )),
1526 TransferType::Interrupt | TransferType::Isochronous => unimplemented!(),
1527 };
1528
1529 self.endpoint_enable(endpoint, endpoint_cfg)
1530 }
1531
1532 fn endpoint_out_enable(&self, transfer_type: TransferType, endpoint: usize) {
1533 let endpoint_cfg = match transfer_type {
1534 TransferType::Control => LocalRegisterCopy::new(From::from(
1535 EndpointConfig::EPTYPE::Control
1536 + EndpointConfig::EPDIR::Out
1537 + EndpointConfig::EPSIZE::Bytes8
1538 + EndpointConfig::EPBK::Single,
1539 )),
1540 TransferType::Bulk => LocalRegisterCopy::new(From::from(
1541 EndpointConfig::EPTYPE::Bulk
1542 + EndpointConfig::EPDIR::Out
1543 + EndpointConfig::EPSIZE::Bytes8
1544 + EndpointConfig::EPBK::Single,
1545 )),
1546 TransferType::Interrupt | TransferType::Isochronous => unimplemented!(),
1547 };
1548
1549 self.endpoint_enable(endpoint, endpoint_cfg)
1550 }
1551
1552 fn endpoint_in_out_enable(&self, _transfer_type: TransferType, _endpoint: usize) {
1553 unimplemented!()
1554 }
1555
1556 fn endpoint_resume_in(&self, endpoint: usize) {
1557 let mut requests = self.requests[endpoint].get();
1558 requests.resume_in = true;
1559 self.requests[endpoint].set(requests);
1560
1561 self.handle_requests();
1563 }
1564
1565 fn endpoint_resume_out(&self, endpoint: usize) {
1566 let mut requests = self.requests[endpoint].get();
1567 requests.resume_out = true;
1568 self.requests[endpoint].set(requests);
1569
1570 self.handle_requests();
1572 }
1573}