1use core::mem::MaybeUninit;
35use kernel::capabilities;
36use kernel::component::Component;
37use kernel::create_capability;
38use kernel::hil;
39
40#[macro_export]
42macro_rules! ctap_component_static {
43 ($U:ty $(,)?) => {{
44 let hid = kernel::static_buf!(capsules_extra::usb::ctap::CtapHid<'static, $U>);
45 let driver = kernel::static_buf!(
46 capsules_extra::usb_hid_driver::UsbHidDriver<
47 'static,
48 capsules_extra::usb::usb_hid_driver::UsbHidDriver<'static, $U>,
49 >
50 );
51 let send_buffer = kernel::static_buf!([u8; 64]);
52 let recv_buffer = kernel::static_buf!([u8; 64]);
53
54 (hid, driver, send_buffer, recv_buffer)
55 };};
56}
57
58pub struct CtapComponent<U: 'static + hil::usb::UsbController<'static>> {
59 board_kernel: &'static kernel::Kernel,
60 driver_num: usize,
61 usb: &'static U,
62 vendor_id: u16,
63 product_id: u16,
64 strings: &'static [&'static str; 3],
65}
66
67impl<U: 'static + hil::usb::UsbController<'static>> CtapComponent<U> {
68 pub fn new(
69 board_kernel: &'static kernel::Kernel,
70 driver_num: usize,
71 usb: &'static U,
72 vendor_id: u16,
73 product_id: u16,
74 strings: &'static [&'static str; 3],
75 ) -> CtapComponent<U> {
76 CtapComponent {
77 board_kernel,
78 driver_num,
79 usb,
80 vendor_id,
81 product_id,
82 strings,
83 }
84 }
85}
86
87impl<U: 'static + hil::usb::UsbController<'static>> Component for CtapComponent<U> {
88 type StaticInput = (
89 &'static mut MaybeUninit<capsules_extra::usb::ctap::CtapHid<'static, U>>,
90 &'static mut MaybeUninit<
91 capsules_extra::usb_hid_driver::UsbHidDriver<
92 'static,
93 capsules_extra::usb::ctap::CtapHid<'static, U>,
94 >,
95 >,
96 &'static mut MaybeUninit<[u8; 64]>,
97 &'static mut MaybeUninit<[u8; 64]>,
98 );
99 type Output = (
100 &'static capsules_extra::usb::ctap::CtapHid<'static, U>,
101 &'static capsules_extra::usb_hid_driver::UsbHidDriver<
102 'static,
103 capsules_extra::usb::ctap::CtapHid<'static, U>,
104 >,
105 );
106
107 fn finalize(self, s: Self::StaticInput) -> Self::Output {
108 let ctap = s.0.write(capsules_extra::usb::ctap::CtapHid::new(
109 self.usb,
110 self.vendor_id,
111 self.product_id,
112 self.strings,
113 ));
114 self.usb.set_client(ctap);
115
116 let grant_cap = create_capability!(capabilities::MemoryAllocationCapability);
117
118 let send_buffer = s.2.write([0; 64]);
119 let recv_buffer = s.3.write([0; 64]);
120
121 let ctap_driver = s.1.write(capsules_extra::usb_hid_driver::UsbHidDriver::new(
122 ctap,
123 send_buffer,
124 recv_buffer,
125 self.board_kernel.create_grant(self.driver_num, &grant_cap),
126 ));
127
128 ctap.set_client(ctap_driver);
129
130 (ctap, ctap_driver)
131 }
132}