1use capsules_extra::can::CanCapsule;
27use core::mem::MaybeUninit;
28use kernel::component::Component;
29use kernel::hil::can;
30use kernel::{capabilities, create_capability};
31
32#[macro_export]
33macro_rules! can_component_static {
34 ($C:ty $(,)?) => {{
35 use capsules_extra::can::CanCapsule;
36 use core::mem::MaybeUninit;
37 use kernel::hil::can;
38 use kernel::static_buf;
39
40 let CAN_TX_BUF = static_buf!([u8; can::STANDARD_CAN_PACKET_SIZE]);
41 let CAN_RX_BUF = static_buf!([u8; can::STANDARD_CAN_PACKET_SIZE]);
42 let can = static_buf!(capsules_extra::can::CanCapsule<'static, $C>);
43 (can, CAN_TX_BUF, CAN_RX_BUF)
44 };};
45}
46
47pub struct CanComponent<A: 'static + can::Can> {
48 board_kernel: &'static kernel::Kernel,
49 driver_num: usize,
50 can: &'static A,
51}
52
53impl<A: 'static + can::Can> CanComponent<A> {
54 pub fn new(
55 board_kernel: &'static kernel::Kernel,
56 driver_num: usize,
57 can: &'static A,
58 ) -> CanComponent<A> {
59 CanComponent {
60 board_kernel,
61 driver_num,
62 can,
63 }
64 }
65}
66
67impl<A: 'static + can::Can> Component for CanComponent<A> {
68 type StaticInput = (
69 &'static mut MaybeUninit<CanCapsule<'static, A>>,
70 &'static mut MaybeUninit<[u8; can::STANDARD_CAN_PACKET_SIZE]>,
71 &'static mut MaybeUninit<[u8; can::STANDARD_CAN_PACKET_SIZE]>,
72 );
73 type Output = &'static CanCapsule<'static, A>;
74
75 fn finalize(self, static_buffer: Self::StaticInput) -> Self::Output {
76 let grant_cap = create_capability!(capabilities::MemoryAllocationCapability);
77 let grant_can = self.board_kernel.create_grant(self.driver_num, &grant_cap);
78
79 let can = static_buffer.0.write(capsules_extra::can::CanCapsule::new(
80 self.can,
81 grant_can,
82 static_buffer.1.write([0; can::STANDARD_CAN_PACKET_SIZE]),
83 static_buffer.2.write([0; can::STANDARD_CAN_PACKET_SIZE]),
84 ));
85 can::Controller::set_client(self.can, Some(can));
86 can::Transmit::set_client(self.can, Some(can));
87 can::Receive::set_client(self.can, Some(can));
88
89 can
90 }
91}