components/
crc.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5//! Component for Crc syscall interface.
6//!
7//! This provides one Component, `CrcComponent`, which implements a
8//! userspace syscall interface to the Crc peripheral.
9//!
10//! Usage
11//! -----
12//! ```rust
13//! let crc = components::crc::CrcComponent::new(board_kernel, &sam4l::crccu::CrcCU)
14//!     .finalize(components::crc_component_static!(sam4l::crccu::Crccu));
15//! ```
16
17// Author: Philip Levis <pal@cs.stanford.edu>
18// Author: Leon Schuermann  <leon@is.currently.online>
19// Last modified: 6/2/2021
20
21use 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// Setup static space for the objects.
29#[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}