components/
hd44780.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 HD447880 LCD controller.
6//!
7//! Usage
8//! -----
9//! ```rust
10//! let height: u8 = 2;
11//! let width: u8 = 16;
12//! let lcd = components::hd44780::HD44780Component::new(mux_alarm,
13//!                                                      width,
14//!                                                      height,
15//!                                                      // rs pin
16//!                                                      gpio_ports.pins[5][13].as_ref().unwrap(),
17//!                                                      // en pin
18//!                                                      gpio_ports.pins[4][11].as_ref().unwrap(),
19//!                                                      // data 4 pin
20//!                                                      gpio_ports.pins[5][14].as_ref().unwrap(),
21//!                                                      // data 5 pin
22//!                                                      gpio_ports.pins[4][13].as_ref().unwrap(),
23//!                                                      // data 6 pin
24//!                                                      gpio_ports.pins[5][15].as_ref().unwrap(),
25//!                                                      // data 7 pin
26//!                                                      gpio_ports.pins[6][14].as_ref().unwrap())
27//!     .finalize(
28//!     components::hd44780_component_static!(
29//!         stm32f429zi::tim2::Tim2,
30//!
31//!
32//!     )
33//! );
34//! ```
35
36use capsules_core::virtualizers::virtual_alarm::{MuxAlarm, VirtualMuxAlarm};
37use capsules_extra::hd44780::HD44780;
38use core::mem::MaybeUninit;
39use kernel::component::Component;
40use kernel::hil::time;
41use kernel::hil::time::Alarm;
42
43// Setup static space for the objects.
44#[macro_export]
45macro_rules! hd44780_component_static {
46    ($A:ty $(,)?) => {{
47        let alarm = kernel::static_buf!(
48            capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<'static, $A>
49        );
50        let hd44780 = kernel::static_buf!(
51            capsules_extra::hd44780::HD44780<
52                'static,
53                capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<'static, $A>,
54            >
55        );
56        let buffer = kernel::static_buf!([u8; capsules_extra::hd44780::BUF_LEN]);
57
58        (alarm, hd44780, buffer)
59    };};
60}
61
62pub struct HD44780Component<A: 'static + time::Alarm<'static>> {
63    alarm_mux: &'static MuxAlarm<'static, A>,
64    width: u8,
65    height: u8,
66    rs: &'static dyn kernel::hil::gpio::Pin,
67    en: &'static dyn kernel::hil::gpio::Pin,
68    data_4_pin: &'static dyn kernel::hil::gpio::Pin,
69    data_5_pin: &'static dyn kernel::hil::gpio::Pin,
70    data_6_pin: &'static dyn kernel::hil::gpio::Pin,
71    data_7_pin: &'static dyn kernel::hil::gpio::Pin,
72}
73
74impl<A: 'static + time::Alarm<'static>> HD44780Component<A> {
75    pub fn new(
76        alarm_mux: &'static MuxAlarm<'static, A>,
77        width: u8,
78        height: u8,
79        rs: &'static dyn kernel::hil::gpio::Pin,
80        en: &'static dyn kernel::hil::gpio::Pin,
81        data_4_pin: &'static dyn kernel::hil::gpio::Pin,
82        data_5_pin: &'static dyn kernel::hil::gpio::Pin,
83        data_6_pin: &'static dyn kernel::hil::gpio::Pin,
84        data_7_pin: &'static dyn kernel::hil::gpio::Pin,
85    ) -> HD44780Component<A> {
86        HD44780Component {
87            alarm_mux,
88            width,
89            height,
90            rs,
91            en,
92            data_4_pin,
93            data_5_pin,
94            data_6_pin,
95            data_7_pin,
96        }
97    }
98}
99
100impl<A: 'static + time::Alarm<'static>> Component for HD44780Component<A> {
101    type StaticInput = (
102        &'static mut MaybeUninit<VirtualMuxAlarm<'static, A>>,
103        &'static mut MaybeUninit<HD44780<'static, VirtualMuxAlarm<'static, A>>>,
104        &'static mut MaybeUninit<[u8; capsules_extra::hd44780::BUF_LEN]>,
105    );
106    type Output = &'static HD44780<'static, VirtualMuxAlarm<'static, A>>;
107
108    fn finalize(self, static_buffer: Self::StaticInput) -> Self::Output {
109        let lcd_alarm = static_buffer.0.write(VirtualMuxAlarm::new(self.alarm_mux));
110        lcd_alarm.setup();
111
112        let buffer = static_buffer.2.write([0; capsules_extra::hd44780::BUF_LEN]);
113
114        let hd44780 = static_buffer.1.write(capsules_extra::hd44780::HD44780::new(
115            self.rs,
116            self.en,
117            self.data_4_pin,
118            self.data_5_pin,
119            self.data_6_pin,
120            self.data_7_pin,
121            buffer,
122            lcd_alarm,
123            self.width,
124            self.height,
125        ));
126        lcd_alarm.set_alarm_client(hd44780);
127
128        hd44780
129    }
130}