components/
mx25r6435f.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 the MX25R6435F flash chip.
6//!
7//! Usage
8//! -----
9//! ```rust
10//! let mx25r6435f = components::mx25r6435f::Mx25r6435fComponent::new(
11//!     &gpio_port[driver.write_protect_pin],
12//!     &gpio_port[driver.hold_pin],
13//!     &gpio_port[driver.chip_select] as &dyn kernel::hil::gpio::Pin,
14//!     mux_alarm,
15//!     mux_spi,
16//! )
17//! .finalize(components::mx25r6435f_component_static!(
18//!     nrf52::spi::SPIM,
19//!     nrf52::gpio::GPIOPin,
20//!     nrf52::rtc::Rtc
21//! ));
22//! ```
23
24use capsules_core::virtualizers::virtual_alarm::{MuxAlarm, VirtualMuxAlarm};
25use capsules_core::virtualizers::virtual_spi::{MuxSpiMaster, VirtualSpiMasterDevice};
26use capsules_extra::mx25r6435f::MX25R6435F;
27use core::mem::MaybeUninit;
28use kernel::component::Component;
29use kernel::hil;
30use kernel::hil::spi::SpiMasterDevice;
31use kernel::hil::time::Alarm;
32
33// Setup static space for the objects.
34#[macro_export]
35macro_rules! mx25r6435f_component_static {
36    ($S:ty, $P:ty, $A:ty $(,)?) => {{
37        let spi_device = kernel::static_buf!(
38            capsules_core::virtualizers::virtual_spi::VirtualSpiMasterDevice<'static, $S>
39        );
40        let alarm = kernel::static_buf!(
41            capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<'static, $A>
42        );
43        let mx25r6435f = kernel::static_buf!(
44            capsules_extra::mx25r6435f::MX25R6435F<
45                'static,
46                capsules_core::virtualizers::virtual_spi::VirtualSpiMasterDevice<'static, $S>,
47                $P,
48                capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<'static, $A>,
49            >
50        );
51
52        let tx_buf = kernel::static_buf!([u8; capsules_extra::mx25r6435f::TX_BUF_LEN]);
53        let rx_buf = kernel::static_buf!([u8; capsules_extra::mx25r6435f::RX_BUF_LEN]);
54
55        (spi_device, alarm, mx25r6435f, tx_buf, rx_buf)
56    };};
57}
58
59pub type Mx25r6435fComponentType<S, P, A> = capsules_extra::mx25r6435f::MX25R6435F<
60    'static,
61    capsules_core::virtualizers::virtual_spi::VirtualSpiMasterDevice<'static, S>,
62    P,
63    VirtualMuxAlarm<'static, A>,
64>;
65
66pub struct Mx25r6435fComponent<
67    S: 'static + hil::spi::SpiMaster<'static>,
68    P: 'static + hil::gpio::Pin,
69    A: 'static + hil::time::Alarm<'static>,
70> {
71    write_protect_pin: Option<&'static P>,
72    hold_pin: Option<&'static P>,
73    chip_select: S::ChipSelect,
74    mux_alarm: &'static MuxAlarm<'static, A>,
75    mux_spi: &'static MuxSpiMaster<'static, S>,
76}
77
78impl<
79        S: 'static + hil::spi::SpiMaster<'static>,
80        P: 'static + hil::gpio::Pin,
81        A: 'static + hil::time::Alarm<'static>,
82    > Mx25r6435fComponent<S, P, A>
83{
84    pub fn new<CS: kernel::hil::spi::cs::IntoChipSelect<S::ChipSelect, hil::spi::cs::ActiveLow>>(
85        write_protect_pin: Option<&'static P>,
86        hold_pin: Option<&'static P>,
87        chip_select: CS,
88        mux_alarm: &'static MuxAlarm<'static, A>,
89        mux_spi: &'static MuxSpiMaster<'static, S>,
90    ) -> Mx25r6435fComponent<S, P, A> {
91        Mx25r6435fComponent {
92            write_protect_pin,
93            hold_pin,
94            chip_select: chip_select.into_cs(),
95            mux_alarm,
96            mux_spi,
97        }
98    }
99}
100
101impl<
102        S: 'static + hil::spi::SpiMaster<'static>,
103        P: 'static + hil::gpio::Pin,
104        A: 'static + hil::time::Alarm<'static>,
105    > Component for Mx25r6435fComponent<S, P, A>
106{
107    type StaticInput = (
108        &'static mut MaybeUninit<VirtualSpiMasterDevice<'static, S>>,
109        &'static mut MaybeUninit<VirtualMuxAlarm<'static, A>>,
110        &'static mut MaybeUninit<
111            MX25R6435F<'static, VirtualSpiMasterDevice<'static, S>, P, VirtualMuxAlarm<'static, A>>,
112        >,
113        &'static mut MaybeUninit<[u8; capsules_extra::mx25r6435f::TX_BUF_LEN]>,
114        &'static mut MaybeUninit<[u8; capsules_extra::mx25r6435f::RX_BUF_LEN]>,
115    );
116    type Output = &'static MX25R6435F<
117        'static,
118        VirtualSpiMasterDevice<'static, S>,
119        P,
120        VirtualMuxAlarm<'static, A>,
121    >;
122
123    fn finalize(self, static_buffer: Self::StaticInput) -> Self::Output {
124        let mx25r6435f_spi = static_buffer
125            .0
126            .write(VirtualSpiMasterDevice::new(self.mux_spi, self.chip_select));
127        // Create an alarm for this chip.
128        let mx25r6435f_virtual_alarm = static_buffer.1.write(VirtualMuxAlarm::new(self.mux_alarm));
129        mx25r6435f_virtual_alarm.setup();
130
131        let tx_buf = static_buffer
132            .3
133            .write([0; capsules_extra::mx25r6435f::TX_BUF_LEN]);
134        let rx_buf = static_buffer
135            .4
136            .write([0; capsules_extra::mx25r6435f::RX_BUF_LEN]);
137
138        let mx25r6435f = static_buffer
139            .2
140            .write(capsules_extra::mx25r6435f::MX25R6435F::new(
141                mx25r6435f_spi,
142                mx25r6435f_virtual_alarm,
143                tx_buf,
144                rx_buf,
145                self.write_protect_pin,
146                self.hold_pin,
147            ));
148        mx25r6435f_spi.setup();
149        mx25r6435f_spi.set_client(mx25r6435f);
150        mx25r6435f_virtual_alarm.set_alarm_client(mx25r6435f);
151        mx25r6435f
152    }
153}