components/
fm25cl.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//! Components for the FM25CL FRAM chip.
6//!
7//! Uses a SPI Interface.
8//!
9//! Usage
10//! -----
11//! ```rust
12//! let fm25cl = components::fm25cl::Fm25clComponent::new(spi_mux, stm32f429zi::gpio::PinId::PE03)
13//!     .finalize(components::fm25cl_component_static!(stm32f429zi::spi::Spi));
14//! ```
15
16use capsules_core::virtualizers::virtual_spi::{MuxSpiMaster, VirtualSpiMasterDevice};
17use capsules_extra::fm25cl::FM25CL;
18use core::mem::MaybeUninit;
19use kernel::component::Component;
20use kernel::hil::spi;
21use kernel::hil::spi::SpiMasterDevice;
22
23#[macro_export]
24macro_rules! fm25cl_component_static {
25    ($S:ty $(,)?) => {{
26        let txbuffer = kernel::static_buf!([u8; capsules_extra::fm25cl::BUF_LEN]);
27        let rxbuffer = kernel::static_buf!([u8; capsules_extra::fm25cl::BUF_LEN]);
28
29        let spi = kernel::static_buf!(
30            capsules_core::virtualizers::virtual_spi::VirtualSpiMasterDevice<'static, $S>
31        );
32        let fm25cl = kernel::static_buf!(
33            capsules_extra::fm25cl::FM25CL<
34                'static,
35                capsules_core::virtualizers::virtual_spi::VirtualSpiMasterDevice<'static, $S>,
36            >
37        );
38
39        (spi, fm25cl, txbuffer, rxbuffer)
40    };};
41}
42
43pub struct Fm25clComponent<
44    S: 'static + spi::SpiMaster<'static>,
45    CS: spi::cs::IntoChipSelect<S::ChipSelect, spi::cs::ActiveLow>,
46> {
47    spi_mux: &'static MuxSpiMaster<'static, S>,
48    chip_select: CS,
49}
50
51impl<
52        S: 'static + spi::SpiMaster<'static>,
53        CS: spi::cs::IntoChipSelect<S::ChipSelect, spi::cs::ActiveLow>,
54    > Fm25clComponent<S, CS>
55{
56    pub fn new(spi_mux: &'static MuxSpiMaster<'static, S>, chip_select: CS) -> Self {
57        Self {
58            spi_mux,
59            chip_select,
60        }
61    }
62}
63
64impl<
65        S: 'static + spi::SpiMaster<'static>,
66        CS: spi::cs::IntoChipSelect<S::ChipSelect, spi::cs::ActiveLow>,
67    > Component for Fm25clComponent<S, CS>
68{
69    type StaticInput = (
70        &'static mut MaybeUninit<VirtualSpiMasterDevice<'static, S>>,
71        &'static mut MaybeUninit<FM25CL<'static, VirtualSpiMasterDevice<'static, S>>>,
72        &'static mut MaybeUninit<[u8; capsules_extra::fm25cl::BUF_LEN]>,
73        &'static mut MaybeUninit<[u8; capsules_extra::fm25cl::BUF_LEN]>,
74    );
75    type Output = &'static FM25CL<'static, VirtualSpiMasterDevice<'static, S>>;
76
77    fn finalize(self, static_buffer: Self::StaticInput) -> Self::Output {
78        let spi_device = static_buffer.0.write(VirtualSpiMasterDevice::new(
79            self.spi_mux,
80            self.chip_select.into_cs(),
81        ));
82        spi_device.setup();
83
84        let txbuffer = static_buffer.2.write([0; capsules_extra::fm25cl::BUF_LEN]);
85        let rxbuffer = static_buffer.3.write([0; capsules_extra::fm25cl::BUF_LEN]);
86
87        let fm25cl = static_buffer
88            .1
89            .write(FM25CL::new(spi_device, txbuffer, rxbuffer));
90        spi_device.set_client(fm25cl);
91
92        fm25cl
93    }
94}