Skip to content

Commit

Permalink
Introduce RGB/DPI driver
Browse files Browse the repository at this point in the history
  • Loading branch information
Dominic Fischer committed Oct 27, 2024
1 parent f3c5286 commit 9329f23
Show file tree
Hide file tree
Showing 8 changed files with 1,085 additions and 1 deletion.
1 change: 1 addition & 0 deletions esp-hal/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `I2c::with_timeout` (#2361)
- `Spi::half_duplex_read` and `Spi::half_duplex_write` (#2373)
- `Cpu::COUNT` and `Cpu::current()` (#?)
- Add RGB/DPI driver (#2415)

### Changed

Expand Down
86 changes: 85 additions & 1 deletion esp-hal/src/dma/buffers.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use core::ptr::null_mut;
use core::{
ops::{Deref, DerefMut},
ptr::null_mut,
};

use super::*;
use crate::soc::is_slice_in_dram;
Expand Down Expand Up @@ -1000,3 +1003,84 @@ unsafe impl DmaRxBuffer for EmptyBuf {
0
}
}

/// DMA Repeating Buffer
///
/// This consists of a single descriptor that points to itself and points to a
/// single buffer, resulting in the buffer being transmitted over and over
/// again, indefinitely.
pub struct DmaRepeatingBuf {
descriptor: &'static mut DmaDescriptor,
buffer: &'static mut [u8],
}

impl DmaRepeatingBuf {
/// Create a new [DmaRepeatingBuf].
pub fn new(
descriptor: &'static mut DmaDescriptor,
buffer: &'static mut [u8],
) -> Result<DmaRepeatingBuf, DmaBufError> {
if !is_slice_in_dram(buffer) {
return Err(DmaBufError::UnsupportedMemoryRegion);
}
if !is_slice_in_dram(core::slice::from_ref(descriptor)) {
return Err(DmaBufError::UnsupportedMemoryRegion);
}

if buffer.len() > max_chunk_size(None) {
return Err(DmaBufError::InsufficientDescriptors);
}

descriptor.set_owner(Owner::Dma); // Doesn't matter
descriptor.set_suc_eof(false);
descriptor.set_length(buffer.len());
descriptor.set_size(buffer.len());
descriptor.buffer = buffer.as_mut_ptr();
descriptor.next = descriptor;

Ok(Self { descriptor, buffer })
}

/// Consume the buf, returning the descriptor and buffer.
pub fn split(self) -> (&'static mut DmaDescriptor, &'static mut [u8]) {
(self.descriptor, self.buffer)
}
}

unsafe impl DmaTxBuffer for DmaRepeatingBuf {
type View = Self;

fn prepare(&mut self) -> Preparation {
Preparation {
start: self.descriptor,
block_size: None,
is_burstable: true,
}
}

fn into_view(self) -> Self::View {
self
}

fn from_view(view: Self::View) -> Self {
view
}

fn length(&self) -> usize {
panic!("DmaRepeatingBuf does not have a length")
}
}

impl Deref for DmaRepeatingBuf {
type Target = [u8];

fn deref(&self) -> &Self::Target {
self.buffer
}
}

impl DerefMut for DmaRepeatingBuf {
fn deref_mut(&mut self) -> &mut Self::Target {
self.buffer
}
}
24 changes: 24 additions & 0 deletions esp-hal/src/dma/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -761,6 +761,30 @@ macro_rules! dma_rx_stream_buffer {
}};
}

/// Convenience macro to create a [DmaRepeatingBuf] from a buffer size.
///
/// ## Usage
/// ```rust,no_run
#[doc = crate::before_snippet!()]
/// use esp_hal::dma_repeating_buf;
///
/// let buf = dma_repeating_buf!(2000);
/// # }
/// ```
#[macro_export]
macro_rules! dma_repeating_buf {
($size:expr) => {{
const {
::core::assert!($size <= 4095, "size must be <= 4095");
::core::assert!($size > 0, "size must be > 0");
}

let (buffer, descriptors) = $crate::dma_buffers_impl!($size, $size, is_circular = false);

$crate::dma::DmaRepeatingBuf::new(&mut descriptors[0], buffer).unwrap()
}};
}

/// DMA Errors
#[derive(Debug, Clone, Copy, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
Expand Down
Loading

0 comments on commit 9329f23

Please sign in to comment.