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