1use capsules_extra::crc::CrcDriver;
22use core::mem::MaybeUninit;
23use kernel::capabilities;
24use kernel::component::Component;
25use kernel::create_capability;
26use kernel::hil::crc::Crc;
27
28#[macro_export]
30macro_rules! crc_component_static {
31    ($C:ty $(,)?) => {{
32        let buffer = kernel::static_buf!([u8; capsules_extra::crc::DEFAULT_CRC_BUF_LENGTH]);
33        let crc = kernel::static_buf!(capsules_extra::crc::CrcDriver<'static, $C>);
34
35        (crc, buffer)
36    };};
37}
38
39pub struct CrcComponent<C: 'static + Crc<'static>> {
40    board_kernel: &'static kernel::Kernel,
41    driver_num: usize,
42    crc: &'static C,
43}
44
45impl<C: 'static + Crc<'static>> CrcComponent<C> {
46    pub fn new(
47        board_kernel: &'static kernel::Kernel,
48        driver_num: usize,
49        crc: &'static C,
50    ) -> CrcComponent<C> {
51        CrcComponent {
52            board_kernel,
53            driver_num,
54            crc,
55        }
56    }
57}
58
59impl<C: 'static + Crc<'static>> Component for CrcComponent<C> {
60    type StaticInput = (
61        &'static mut MaybeUninit<CrcDriver<'static, C>>,
62        &'static mut MaybeUninit<[u8; capsules_extra::crc::DEFAULT_CRC_BUF_LENGTH]>,
63    );
64    type Output = &'static CrcDriver<'static, C>;
65
66    fn finalize(self, static_buffer: Self::StaticInput) -> Self::Output {
67        let grant_cap = create_capability!(capabilities::MemoryAllocationCapability);
68        let crc_buf = static_buffer
69            .1
70            .write([0; capsules_extra::crc::DEFAULT_CRC_BUF_LENGTH]);
71
72        let crc = static_buffer.0.write(CrcDriver::new(
73            self.crc,
74            crc_buf,
75            self.board_kernel.create_grant(self.driver_num, &grant_cap),
76        ));
77
78        self.crc.set_client(crc);
79
80        crc
81    }
82}