capsules_core/
i2c_master_slave_combo.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//! Combines two hardware devices into a single I2C master/slave device.
6//!
7//! If a chip provides a separate hardware implementation for a I2C master and
8//! slave device, like the Apollo3 for example, this capsule can be used to
9//! combine them into a single `I2CMasterSlave` compatible implementation.
10//!
11//! This allows the `I2CMasterSlaveDriver` capsule to be implemented on more
12//! types of hardware.
13
14use kernel::hil::i2c::{
15    Error, I2CHwMasterClient, I2CHwSlaveClient, I2CMaster, I2CMasterSlave, I2CSlave,
16};
17
18pub struct I2CMasterSlaveCombo<'a, M: I2CMaster<'a>, S: I2CSlave<'a>> {
19    i2c_master: &'a M,
20    i2c_slave: &'a S,
21}
22
23impl<'a, M: I2CMaster<'a>, S: I2CSlave<'a>> I2CMasterSlaveCombo<'a, M, S> {
24    pub fn new(i2c_master: &'a M, i2c_slave: &'a S) -> I2CMasterSlaveCombo<'a, M, S> {
25        I2CMasterSlaveCombo {
26            i2c_master,
27            i2c_slave,
28        }
29    }
30}
31
32impl<'a, M: I2CMaster<'a>, S: I2CSlave<'a>> I2CMaster<'a> for I2CMasterSlaveCombo<'a, M, S> {
33    fn set_master_client(&self, master_client: &'a dyn I2CHwMasterClient) {
34        self.i2c_master.set_master_client(master_client)
35    }
36
37    fn enable(&self) {
38        self.i2c_master.enable()
39    }
40
41    fn disable(&self) {
42        self.i2c_master.disable()
43    }
44
45    fn write_read(
46        &self,
47        addr: u8,
48        data: &'static mut [u8],
49        write_len: usize,
50        read_len: usize,
51    ) -> Result<(), (Error, &'static mut [u8])> {
52        self.i2c_master.write_read(addr, data, write_len, read_len)
53    }
54
55    fn write(
56        &self,
57        addr: u8,
58        data: &'static mut [u8],
59        len: usize,
60    ) -> Result<(), (Error, &'static mut [u8])> {
61        self.i2c_master.write(addr, data, len)
62    }
63
64    fn read(
65        &self,
66        addr: u8,
67        buffer: &'static mut [u8],
68        len: usize,
69    ) -> Result<(), (Error, &'static mut [u8])> {
70        self.i2c_master.read(addr, buffer, len)
71    }
72}
73
74impl<'a, M: I2CMaster<'a>, S: I2CSlave<'a>> I2CSlave<'a> for I2CMasterSlaveCombo<'a, M, S> {
75    fn set_slave_client(&self, slave_client: &'a dyn I2CHwSlaveClient) {
76        self.i2c_slave.set_slave_client(slave_client);
77    }
78
79    fn enable(&self) {
80        self.i2c_slave.enable()
81    }
82
83    fn disable(&self) {
84        self.i2c_slave.disable()
85    }
86
87    fn set_address(&self, addr: u8) -> Result<(), Error> {
88        self.i2c_slave.set_address(addr)
89    }
90
91    fn write_receive(
92        &self,
93        data: &'static mut [u8],
94        max_len: usize,
95    ) -> Result<(), (Error, &'static mut [u8])> {
96        self.i2c_slave.write_receive(data, max_len)
97    }
98
99    fn read_send(
100        &self,
101        data: &'static mut [u8],
102        max_len: usize,
103    ) -> Result<(), (Error, &'static mut [u8])> {
104        self.i2c_slave.read_send(data, max_len)
105    }
106
107    fn listen(&self) {
108        self.i2c_slave.listen()
109    }
110}
111
112impl<'a, M: I2CMaster<'a>, S: I2CSlave<'a>> I2CMasterSlave<'a> for I2CMasterSlaveCombo<'a, M, S> {}