capsules_extra/
bus.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//! Abstraction Interface for several busses.
6//! Useful for devices that support multiple protocols
7//!
8//! Usage
9//! -----
10//!
11//! I2C example
12//! ```rust,ignore
13//! let bus = components::bus::I2CMasterBusComponent::new(i2c_mux, address)
14//!     .finalize(components::spi_bus_component_helper!());
15//! ```
16//!
17//! SPI example
18//! ```rust,ignore
19//! let bus =
20//!     components::bus::SpiMasterBusComponent::new().finalize(components::spi_bus_component_helper!(
21//!         // spi type
22//!         nrf52840::spi::SPIM,
23//!         // chip select
24//!         &nrf52840::gpio::PORT[GPIO_D4],
25//!          // spi mux
26//!         spi_mux
27//!     ));
28//! ```
29
30use core::cell::Cell;
31use kernel::debug;
32use kernel::hil::bus8080::{self, Bus8080, BusAddr8080};
33use kernel::hil::i2c::{Error, I2CClient, I2CDevice};
34use kernel::hil::spi::{ClockPhase, ClockPolarity, SpiMasterClient, SpiMasterDevice};
35use kernel::utilities::cells::OptionalCell;
36use kernel::utilities::leasable_buffer::SubSliceMut;
37use kernel::ErrorCode;
38
39// Buses, such as I2C or SPI, are generally serial and transmit data byte by byte,
40// without taking endianness into account. The receiving device—in this case,
41// the screen—interprets the data and determines the endianness.
42// In Tock, the lower-level screen driver sets the address endianness.
43// For most buses, with the exception of the parallel 8080 bus, endianness
44// is largely transparent.
45// We store addresses using primitive data types like `u8`, `u16`, `u32`, and `u64`.
46
47/// The `DataWidth` enum and associated `BusAddr` structs define the width
48/// of the data transmitted over a bus.
49///
50/// The `BusAddr::bytes`` function transforms the address into the
51/// specified endianness and returns an iterator.
52pub enum DataWidth {
53    Bits8,
54    Bits16LE,
55    Bits16BE,
56    Bits32LE,
57    Bits32BE,
58    Bits64LE,
59    Bits64BE,
60}
61
62/// Each `BusAddr` struct represents a specific data width and endianness.
63
64/// 8 bit Bus Address
65pub struct BusAddr8(u8);
66
67/// 16 bit Big Endian Bus Address
68pub struct BusAddr16BE(u16);
69
70/// 16 bit Little Endian Bus Address
71pub struct BusAddr16LE(u16);
72
73/// 32 bit Big Endian Bus Address
74pub struct BusAddr32BE(u32);
75
76/// 32 bit Little Endian Bus Address
77pub struct BusAddr32LE(u32);
78
79/// 64 bit Big Endian Bus Address
80pub struct BusAddr64BE(u64);
81
82/// 64 bit Little Endian Bus Address
83pub struct BusAddr64LE(u64);
84
85impl From<BusAddr8> for BusAddr8080 {
86    fn from(value: BusAddr8) -> Self {
87        BusAddr8080::BusAddr8(value.0)
88    }
89}
90impl From<BusAddr16BE> for BusAddr8080 {
91    fn from(value: BusAddr16BE) -> Self {
92        BusAddr8080::BusAddr16BE(value.0)
93    }
94}
95impl From<BusAddr16LE> for BusAddr8080 {
96    fn from(value: BusAddr16LE) -> Self {
97        BusAddr8080::BusAddr16LE(value.0)
98    }
99}
100
101impl From<u8> for BusAddr8 {
102    fn from(value: u8) -> Self {
103        Self(value)
104    }
105}
106impl From<u16> for BusAddr16BE {
107    fn from(value: u16) -> Self {
108        Self(value)
109    }
110}
111impl From<u16> for BusAddr16LE {
112    fn from(value: u16) -> Self {
113        Self(value)
114    }
115}
116impl From<u32> for BusAddr32BE {
117    fn from(value: u32) -> Self {
118        Self(value)
119    }
120}
121impl From<u32> for BusAddr32LE {
122    fn from(value: u32) -> Self {
123        Self(value)
124    }
125}
126impl From<u64> for BusAddr64BE {
127    fn from(value: u64) -> Self {
128        Self(value)
129    }
130}
131impl From<u64> for BusAddr64LE {
132    fn from(value: u64) -> Self {
133        Self(value)
134    }
135}
136
137/// The `BusAddr` trait is implemented for each BusAddr struct.
138/// It provides information about the data width and a way
139/// to access the underlying byte representation.
140pub trait BusAddr {
141    const DATA_WIDTH: DataWidth;
142    fn len(&self) -> usize {
143        Self::DATA_WIDTH.width_in_bytes()
144    }
145    fn bytes(&self) -> impl Iterator<Item = u8>;
146}
147impl BusAddr for BusAddr8 {
148    const DATA_WIDTH: DataWidth = DataWidth::Bits8;
149    fn bytes(&self) -> impl Iterator<Item = u8> {
150        self.0.to_be_bytes().into_iter()
151    }
152}
153impl BusAddr for BusAddr16BE {
154    const DATA_WIDTH: DataWidth = DataWidth::Bits16BE;
155    fn bytes(&self) -> impl Iterator<Item = u8> {
156        self.0.to_be_bytes().into_iter()
157    }
158}
159impl BusAddr for BusAddr16LE {
160    const DATA_WIDTH: DataWidth = DataWidth::Bits16LE;
161    fn bytes(&self) -> impl Iterator<Item = u8> {
162        self.0.to_le_bytes().into_iter()
163    }
164}
165impl BusAddr for BusAddr32BE {
166    const DATA_WIDTH: DataWidth = DataWidth::Bits32BE;
167    fn bytes(&self) -> impl Iterator<Item = u8> {
168        self.0.to_be_bytes().into_iter()
169    }
170}
171impl BusAddr for BusAddr32LE {
172    const DATA_WIDTH: DataWidth = DataWidth::Bits32LE;
173    fn bytes(&self) -> impl Iterator<Item = u8> {
174        self.0.to_le_bytes().into_iter()
175    }
176}
177impl BusAddr for BusAddr64BE {
178    const DATA_WIDTH: DataWidth = DataWidth::Bits64BE;
179    fn bytes(&self) -> impl Iterator<Item = u8> {
180        self.0.to_be_bytes().into_iter()
181    }
182}
183impl BusAddr for BusAddr64LE {
184    const DATA_WIDTH: DataWidth = DataWidth::Bits64LE;
185    fn bytes(&self) -> impl Iterator<Item = u8> {
186        self.0.to_le_bytes().into_iter()
187    }
188}
189
190impl DataWidth {
191    pub fn width_in_bytes(&self) -> usize {
192        match self {
193            DataWidth::Bits8 => 1,
194            DataWidth::Bits16BE | DataWidth::Bits16LE => 2,
195            DataWidth::Bits32BE | DataWidth::Bits32LE => 4,
196            DataWidth::Bits64BE | DataWidth::Bits64LE => 8,
197        }
198    }
199}
200
201pub trait Bus<'a, A: BusAddr> {
202    /// Set the address to write to
203    ///
204    /// If the underlying bus does not support addresses (eg UART)
205    /// this function returns ENOSUPPORT
206    fn set_addr(&self, addr: A) -> Result<(), ErrorCode>;
207    /// Write data items to the previously set address
208    ///
209    /// data_width specifies the encoding of the data items placed in the buffer
210    /// len specifies the number of data items (the number of bytes is len * data_width.width_in_bytes)
211    fn write(
212        &self,
213        data_width: DataWidth,
214        buffer: &'static mut [u8],
215        len: usize,
216    ) -> Result<(), (ErrorCode, &'static mut [u8])>;
217
218    /// Read data items from the previously set address
219    ///
220    /// data_width specifies the encoding of the data items placed in the buffer
221    /// len specifies the number of data items (the number of bytes is len * data_width.width_in_bytes)
222    fn read(
223        &self,
224        data_width: DataWidth,
225        buffer: &'static mut [u8],
226        len: usize,
227    ) -> Result<(), (ErrorCode, &'static mut [u8])>;
228
229    fn set_client(&self, client: &'a dyn Client);
230}
231
232pub trait Client {
233    /// Called when set_addr, write or read are complete
234    ///
235    /// set_address does not return a buffer
236    /// write and read return a buffer
237    /// len should be set to the number of data elements written
238    fn command_complete(
239        &self,
240        buffer: Option<&'static mut [u8]>,
241        len: usize,
242        status: Result<(), ErrorCode>,
243    );
244}
245
246#[derive(Copy, Clone)]
247enum BusStatus {
248    Idle,
249    SetAddress,
250    Write,
251    Read,
252}
253
254/*********** SPI ************/
255
256pub struct SpiMasterBus<'a, S: SpiMasterDevice<'a>> {
257    spi: &'a S,
258    read_write_buffer: OptionalCell<SubSliceMut<'static, u8>>,
259    bus_width: Cell<usize>,
260    client: OptionalCell<&'a dyn Client>,
261    addr_buffer: OptionalCell<SubSliceMut<'static, u8>>,
262    status: Cell<BusStatus>,
263}
264
265impl<'a, S: SpiMasterDevice<'a>> SpiMasterBus<'a, S> {
266    pub fn new(spi: &'a S, addr_buffer: &'static mut [u8]) -> SpiMasterBus<'a, S> {
267        SpiMasterBus {
268            spi,
269            read_write_buffer: OptionalCell::empty(),
270            bus_width: Cell::new(1),
271            client: OptionalCell::empty(),
272            addr_buffer: OptionalCell::new(addr_buffer.into()),
273            status: Cell::new(BusStatus::Idle),
274        }
275    }
276
277    pub fn set_read_write_buffer(&self, buffer: &'static mut [u8]) {
278        self.read_write_buffer.replace(buffer.into());
279    }
280
281    pub fn configure(
282        &self,
283        cpol: ClockPolarity,
284        cpal: ClockPhase,
285        rate: u32,
286    ) -> Result<(), ErrorCode> {
287        self.spi.configure(cpol, cpal, rate)
288    }
289}
290
291impl<'a, A: BusAddr, S: SpiMasterDevice<'a>> Bus<'a, A> for SpiMasterBus<'a, S> {
292    fn set_addr(&self, addr: A) -> Result<(), ErrorCode> {
293        self.addr_buffer
294            .take()
295            .map_or(Err(ErrorCode::NOMEM), |mut buffer| {
296                let bytes = addr.bytes();
297                if buffer.len() >= addr.len() {
298                    buffer.reset();
299                    buffer.slice(0..addr.len());
300                    self.status.set(BusStatus::SetAddress);
301                    buffer
302                        .as_slice()
303                        .iter_mut()
304                        .zip(bytes)
305                        .for_each(|(d, s)| *d = s);
306                    if let Err((error, buffer, _)) = self.spi.read_write_bytes(buffer, None) {
307                        self.status.set(BusStatus::Idle);
308                        self.addr_buffer.replace(buffer);
309                        Err(error)
310                    } else {
311                        Ok(())
312                    }
313                } else {
314                    self.addr_buffer.replace(buffer);
315                    Err(ErrorCode::SIZE)
316                }
317            })
318    }
319
320    fn write(
321        &self,
322        data_width: DataWidth,
323        buffer: &'static mut [u8],
324        len: usize,
325    ) -> Result<(), (ErrorCode, &'static mut [u8])> {
326        // endianess does not matter as the buffer is sent as is
327        let bytes = data_width.width_in_bytes();
328        self.bus_width.set(bytes);
329        if buffer.len() >= len * bytes {
330            let mut buffer_slice: SubSliceMut<'static, u8> = buffer.into();
331            buffer_slice.slice(0..(len * bytes));
332            self.status.set(BusStatus::Write);
333            if let Err((error, buffer, _)) = self.spi.read_write_bytes(buffer_slice, None) {
334                self.status.set(BusStatus::Idle);
335                Err((error, buffer.take()))
336            } else {
337                Ok(())
338            }
339        } else {
340            Err((ErrorCode::NOMEM, buffer))
341        }
342    }
343
344    fn read(
345        &self,
346        data_width: DataWidth,
347        buffer: &'static mut [u8],
348        len: usize,
349    ) -> Result<(), (ErrorCode, &'static mut [u8])> {
350        // endianess does not matter as the buffer is read as is
351        let bytes = data_width.width_in_bytes();
352        self.bus_width.set(bytes);
353        self.read_write_buffer.take().map_or_else(
354            || panic!("bus::read: spi did not return the read write buffer"),
355            move |write_buffer| {
356                if write_buffer.len() >= len * bytes
357                    && write_buffer.len() > 0
358                    && buffer.len() > len * bytes
359                {
360                    let mut buffer_slice: SubSliceMut<'static, u8> = buffer.into();
361                    buffer_slice.slice(0..(len * bytes));
362                    self.status.set(BusStatus::Read);
363                    if let Err((error, write_buffer, buffer)) =
364                        self.spi.read_write_bytes(write_buffer, Some(buffer_slice))
365                    {
366                        self.status.set(BusStatus::Idle);
367                        self.read_write_buffer.replace(write_buffer);
368                        Err((error, buffer.map_or(&mut [] as &mut [u8], |b| b.take())))
369                    } else {
370                        Ok(())
371                    }
372                } else {
373                    Err((ErrorCode::NOMEM, buffer))
374                }
375            },
376        )
377    }
378
379    fn set_client(&self, client: &'a dyn Client) {
380        self.client.replace(client);
381    }
382}
383
384impl<'a, S: SpiMasterDevice<'a>> SpiMasterClient for SpiMasterBus<'a, S> {
385    fn read_write_done(
386        &self,
387        write_buffer: SubSliceMut<'static, u8>,
388        read_buffer: Option<SubSliceMut<'static, u8>>,
389        status: Result<usize, ErrorCode>,
390    ) {
391        match self.status.get() {
392            BusStatus::SetAddress => {
393                self.addr_buffer.replace(write_buffer);
394                self.client.map(move |client| {
395                    client.command_complete(None, status.unwrap_or(0), status.map(|_| ()))
396                });
397            }
398            BusStatus::Write | BusStatus::Read => {
399                let mut buffer = write_buffer;
400                if let Some(buf) = read_buffer {
401                    self.read_write_buffer.replace(buffer);
402                    buffer = buf;
403                }
404                self.client.map(move |client| {
405                    client.command_complete(
406                        Some(buffer.take()),
407                        status.unwrap_or(0) / self.bus_width.get(),
408                        status.map(|_| ()),
409                    )
410                });
411            }
412            _ => {
413                panic!("spi sent an extra read_write_done");
414            }
415        }
416    }
417}
418
419/*********** I2C ************/
420
421pub struct I2CMasterBus<'a, I: I2CDevice> {
422    i2c: &'a I,
423    len: Cell<usize>,
424    client: OptionalCell<&'a dyn Client>,
425    addr_buffer: OptionalCell<&'static mut [u8]>,
426    status: Cell<BusStatus>,
427}
428
429impl<'a, I: I2CDevice> I2CMasterBus<'a, I> {
430    pub fn new(i2c: &'a I, addr_buffer: &'static mut [u8]) -> I2CMasterBus<'a, I> {
431        I2CMasterBus {
432            i2c,
433            len: Cell::new(0),
434            client: OptionalCell::empty(),
435            addr_buffer: OptionalCell::new(addr_buffer),
436            status: Cell::new(BusStatus::Idle),
437        }
438    }
439}
440
441impl<'a, A: BusAddr, I: I2CDevice> Bus<'a, A> for I2CMasterBus<'a, I> {
442    fn set_addr(&self, addr: A) -> Result<(), ErrorCode> {
443        self.addr_buffer
444            .take()
445            .map_or(Err(ErrorCode::NOMEM), |buffer| {
446                self.status.set(BusStatus::SetAddress);
447                let bytes = addr.bytes();
448                if buffer.len() >= addr.len() {
449                    let () = buffer.iter_mut().zip(bytes).for_each(|(d, s)| *d = s);
450                    match self.i2c.write(buffer, addr.len()) {
451                        Ok(()) => Ok(()),
452                        Err((error, buffer)) => {
453                            self.addr_buffer.replace(buffer);
454                            Err(error.into())
455                        }
456                    }
457                } else {
458                    self.addr_buffer.replace(buffer);
459                    Err(ErrorCode::SIZE)
460                }
461            })
462    }
463
464    fn write(
465        &self,
466        data_width: DataWidth,
467        buffer: &'static mut [u8],
468        len: usize,
469    ) -> Result<(), (ErrorCode, &'static mut [u8])> {
470        // endianess does not matter as the buffer is sent as is
471        let bytes = data_width.width_in_bytes();
472        self.len.set(len * bytes);
473        if len * bytes < 255 && buffer.len() >= len * bytes {
474            debug!("write len {}", len);
475            self.len.set(len);
476            self.status.set(BusStatus::Write);
477            match self.i2c.write(buffer, len * bytes) {
478                Ok(()) => Ok(()),
479                Err((error, buffer)) => Err((error.into(), buffer)),
480            }
481        } else {
482            Err((ErrorCode::NOMEM, buffer))
483        }
484    }
485
486    fn read(
487        &self,
488        data_width: DataWidth,
489        buffer: &'static mut [u8],
490        len: usize,
491    ) -> Result<(), (ErrorCode, &'static mut [u8])> {
492        // endianess does not matter as the buffer is read as is
493        let bytes = data_width.width_in_bytes();
494        self.len.set(len * bytes);
495        if len & bytes < 255 && buffer.len() >= len * bytes {
496            self.len.set(len);
497            self.status.set(BusStatus::Read);
498            match self.i2c.read(buffer, len * bytes) {
499                Ok(()) => Ok(()),
500                Err((error, buffer)) => Err((error.into(), buffer)),
501            }
502        } else {
503            Err((ErrorCode::NOMEM, buffer))
504        }
505    }
506
507    fn set_client(&self, client: &'a dyn Client) {
508        self.client.replace(client);
509    }
510}
511
512impl<I: I2CDevice> I2CClient for I2CMasterBus<'_, I> {
513    fn command_complete(&self, buffer: &'static mut [u8], status: Result<(), Error>) {
514        let len = match status {
515            Ok(()) => self.len.get(),
516            _ => 0,
517        };
518        let report_status = match status {
519            Ok(()) => Ok(()),
520            Err(error) => Err(error.into()),
521        };
522        match self.status.get() {
523            BusStatus::SetAddress => {
524                self.addr_buffer.replace(buffer);
525                self.client
526                    .map(move |client| client.command_complete(None, 0, report_status));
527            }
528            BusStatus::Write | BusStatus::Read => {
529                self.client
530                    .map(move |client| client.command_complete(Some(buffer), len, report_status));
531            }
532            _ => {
533                panic!("i2c sent an extra read_write_done");
534            }
535        }
536    }
537}
538
539/*************** Bus 8080  ***************/
540pub struct Bus8080Bus<'a, B: Bus8080<'static>> {
541    bus: &'a B,
542    client: OptionalCell<&'a dyn Client>,
543    status: Cell<BusStatus>,
544}
545
546impl<'a, B: Bus8080<'static>> Bus8080Bus<'a, B> {
547    pub fn new(bus: &'a B) -> Bus8080Bus<'a, B> {
548        Bus8080Bus {
549            bus,
550            client: OptionalCell::empty(),
551            status: Cell::new(BusStatus::Idle),
552        }
553    }
554
555    fn to_bus8080_width(bus_width: DataWidth) -> Option<bus8080::BusWidth> {
556        match bus_width {
557            DataWidth::Bits8 => Some(bus8080::BusWidth::Bits8),
558            DataWidth::Bits16LE => Some(bus8080::BusWidth::Bits16LE),
559            DataWidth::Bits16BE => Some(bus8080::BusWidth::Bits16BE),
560            _ => None,
561        }
562    }
563}
564
565impl<'a, A: BusAddr + Into<BusAddr8080>, B: Bus8080<'static>> Bus<'a, A> for Bus8080Bus<'a, B> {
566    fn set_addr(&self, addr: A) -> Result<(), ErrorCode> {
567        let _ = self.bus.set_addr(addr.into());
568        Ok(())
569    }
570
571    fn write(
572        &self,
573        data_width: DataWidth,
574        buffer: &'static mut [u8],
575        len: usize,
576    ) -> Result<(), (ErrorCode, &'static mut [u8])> {
577        if let Some(bus_width) = Self::to_bus8080_width(data_width) {
578            self.bus.write(bus_width, buffer, len)
579        } else {
580            Err((ErrorCode::INVAL, buffer))
581        }
582    }
583
584    fn read(
585        &self,
586        data_width: DataWidth,
587        buffer: &'static mut [u8],
588        len: usize,
589    ) -> Result<(), (ErrorCode, &'static mut [u8])> {
590        if let Some(bus_width) = Self::to_bus8080_width(data_width) {
591            self.bus.read(bus_width, buffer, len)
592        } else {
593            Err((ErrorCode::INVAL, buffer))
594        }
595    }
596
597    fn set_client(&self, client: &'a dyn Client) {
598        self.client.replace(client);
599    }
600}
601
602impl<B: Bus8080<'static>> bus8080::Client for Bus8080Bus<'_, B> {
603    fn command_complete(
604        &self,
605        buffer: Option<&'static mut [u8]>,
606        len: usize,
607        status: Result<(), ErrorCode>,
608    ) {
609        self.status.set(BusStatus::Idle);
610        self.client.map(|client| {
611            client.command_complete(buffer, len, status);
612        });
613    }
614}