components/
sh1106.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 2024.
4
5//! Components for the SH1106 OLED screen.
6//!
7//! Usage
8//! -----
9//! ```rust
10//!
11//! let oled_i2c = components::i2c::I2CComponent::new(i2c_bus, 0x3c)
12//!     .finalize(components::i2c_component_static!(nrf52840::i2c::TWI));
13//!
14//! let sh1106 = components::sh1106::Sh1106Component::new(oled_i2c, true)
15//!     .finalize(components::sh1106_component_static!(nrf52840::i2c::TWI));
16//! ```
17
18use core::mem::MaybeUninit;
19use kernel::component::Component;
20use kernel::hil;
21
22// Setup static space for the objects.
23#[macro_export]
24macro_rules! sh1106_component_static {
25    ($I: ty $(,)?) => {{
26        let buffer = kernel::static_buf!([u8; capsules_extra::sh1106::BUFFER_SIZE]);
27        let sh1106 = kernel::static_buf!(
28            capsules_extra::sh1106::Sh1106<
29                'static,
30                capsules_core::virtualizers::virtual_i2c::I2CDevice<'static, $I>,
31            >
32        );
33
34        (buffer, sh1106)
35    };};
36}
37
38pub type Sh1106ComponentType<I> = capsules_extra::sh1106::Sh1106<
39    'static,
40    capsules_core::virtualizers::virtual_i2c::I2CDevice<'static, I>,
41>;
42
43pub struct Sh1106Component<I: hil::i2c::I2CMaster<'static> + 'static> {
44    i2c_device: &'static capsules_core::virtualizers::virtual_i2c::I2CDevice<'static, I>,
45    use_charge_pump: bool,
46}
47
48impl<I: hil::i2c::I2CMaster<'static> + 'static> Sh1106Component<I> {
49    pub fn new(
50        i2c_device: &'static capsules_core::virtualizers::virtual_i2c::I2CDevice<'static, I>,
51        use_charge_pump: bool,
52    ) -> Sh1106Component<I> {
53        Sh1106Component {
54            i2c_device,
55            use_charge_pump,
56        }
57    }
58}
59
60impl<I: hil::i2c::I2CMaster<'static> + 'static> Component for Sh1106Component<I> {
61    type StaticInput = (
62        &'static mut MaybeUninit<[u8; capsules_extra::sh1106::BUFFER_SIZE]>,
63        &'static mut MaybeUninit<
64            capsules_extra::sh1106::Sh1106<
65                'static,
66                capsules_core::virtualizers::virtual_i2c::I2CDevice<'static, I>,
67            >,
68        >,
69    );
70    type Output = &'static capsules_extra::sh1106::Sh1106<
71        'static,
72        capsules_core::virtualizers::virtual_i2c::I2CDevice<'static, I>,
73    >;
74
75    fn finalize(self, static_buffer: Self::StaticInput) -> Self::Output {
76        let buffer = static_buffer
77            .0
78            .write([0; capsules_extra::sh1106::BUFFER_SIZE]);
79
80        let sh1106 = static_buffer.1.write(capsules_extra::sh1106::Sh1106::new(
81            self.i2c_device,
82            buffer,
83            self.use_charge_pump,
84        ));
85        self.i2c_device.set_client(sh1106);
86
87        sh1106
88    }
89}