Skip to content

Commit 7821968

Browse files
authored
Introduce RGB/DPI driver (#2415)
* Introduce RGB/DPI driver * Choose different pin for HIL test * fail * Use official devkit * merge update * non_exhaustive --------- Co-authored-by: Dominic Fischer <[email protected]>
1 parent 26fd1a4 commit 7821968

File tree

8 files changed

+1483
-1
lines changed

8 files changed

+1483
-1
lines changed

esp-hal/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2020
- `Pins::steal()` to unsafely obtain GPIO. (#2335)
2121
- `I2c::with_timeout` (#2361)
2222
- `Spi::half_duplex_read` and `Spi::half_duplex_write` (#2373)
23+
- Add RGB/DPI driver (#2415)
24+
- Add `DmaLoopBuf` (#2415)
2325
- `Cpu::COUNT` and `Cpu::current()` (#2411)
2426
- `UartInterrupt` and related functions (#2406)
2527
- I2S Parallel output driver for ESP32. (#2348, #2436, #2472)

esp-hal/src/dma/buffers.rs

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
use core::ptr::null_mut;
1+
use core::{
2+
ops::{Deref, DerefMut},
3+
ptr::null_mut,
4+
};
25

36
use super::*;
47
use crate::soc::is_slice_in_dram;
@@ -1046,3 +1049,91 @@ unsafe impl DmaRxBuffer for EmptyBuf {
10461049
0
10471050
}
10481051
}
1052+
1053+
/// DMA Loop Buffer
1054+
///
1055+
/// This consists of a single descriptor that points to itself and points to a
1056+
/// single buffer, resulting in the buffer being transmitted over and over
1057+
/// again, indefinitely.
1058+
///
1059+
/// Note: A DMA descriptor is 12 bytes. If your buffer is significantly shorter
1060+
/// than this, the DMA channel will spend more time reading the descriptor than
1061+
/// it does reading the buffer, which may leave it unable to keep up with the
1062+
/// bandwidth requirements of some peripherals at high frequencies.
1063+
pub struct DmaLoopBuf {
1064+
descriptor: &'static mut DmaDescriptor,
1065+
buffer: &'static mut [u8],
1066+
}
1067+
1068+
impl DmaLoopBuf {
1069+
/// Create a new [DmaLoopBuf].
1070+
pub fn new(
1071+
descriptor: &'static mut DmaDescriptor,
1072+
buffer: &'static mut [u8],
1073+
) -> Result<DmaLoopBuf, DmaBufError> {
1074+
if !is_slice_in_dram(buffer) {
1075+
return Err(DmaBufError::UnsupportedMemoryRegion);
1076+
}
1077+
if !is_slice_in_dram(core::slice::from_ref(descriptor)) {
1078+
return Err(DmaBufError::UnsupportedMemoryRegion);
1079+
}
1080+
1081+
if buffer.len() > max_chunk_size(None) {
1082+
return Err(DmaBufError::InsufficientDescriptors);
1083+
}
1084+
1085+
descriptor.set_owner(Owner::Dma); // Doesn't matter
1086+
descriptor.set_suc_eof(false);
1087+
descriptor.set_length(buffer.len());
1088+
descriptor.set_size(buffer.len());
1089+
descriptor.buffer = buffer.as_mut_ptr();
1090+
descriptor.next = descriptor;
1091+
1092+
Ok(Self { descriptor, buffer })
1093+
}
1094+
1095+
/// Consume the buf, returning the descriptor and buffer.
1096+
pub fn split(self) -> (&'static mut DmaDescriptor, &'static mut [u8]) {
1097+
(self.descriptor, self.buffer)
1098+
}
1099+
}
1100+
1101+
unsafe impl DmaTxBuffer for DmaLoopBuf {
1102+
type View = Self;
1103+
1104+
fn prepare(&mut self) -> Preparation {
1105+
Preparation {
1106+
start: self.descriptor,
1107+
block_size: None,
1108+
is_burstable: true,
1109+
// The DMA must not check the owner bit, as it is never set.
1110+
check_owner: Some(false),
1111+
}
1112+
}
1113+
1114+
fn into_view(self) -> Self::View {
1115+
self
1116+
}
1117+
1118+
fn from_view(view: Self::View) -> Self {
1119+
view
1120+
}
1121+
1122+
fn length(&self) -> usize {
1123+
panic!("DmaLoopBuf does not have a length")
1124+
}
1125+
}
1126+
1127+
impl Deref for DmaLoopBuf {
1128+
type Target = [u8];
1129+
1130+
fn deref(&self) -> &Self::Target {
1131+
self.buffer
1132+
}
1133+
}
1134+
1135+
impl DerefMut for DmaLoopBuf {
1136+
fn deref_mut(&mut self) -> &mut Self::Target {
1137+
self.buffer
1138+
}
1139+
}

esp-hal/src/dma/mod.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -775,6 +775,30 @@ macro_rules! dma_rx_stream_buffer {
775775
}};
776776
}
777777

778+
/// Convenience macro to create a [DmaLoopBuf] from a buffer size.
779+
///
780+
/// ## Usage
781+
/// ```rust,no_run
782+
#[doc = crate::before_snippet!()]
783+
/// use esp_hal::dma_loop_buffer;
784+
///
785+
/// let buf = dma_loop_buffer!(2000);
786+
/// # }
787+
/// ```
788+
#[macro_export]
789+
macro_rules! dma_loop_buffer {
790+
($size:expr) => {{
791+
const {
792+
::core::assert!($size <= 4095, "size must be <= 4095");
793+
::core::assert!($size > 0, "size must be > 0");
794+
}
795+
796+
let (buffer, descriptors) = $crate::dma_buffers_impl!($size, $size, is_circular = false);
797+
798+
$crate::dma::DmaLoopBuf::new(&mut descriptors[0], buffer).unwrap()
799+
}};
800+
}
801+
778802
/// DMA Errors
779803
#[derive(Debug, Clone, Copy, PartialEq)]
780804
#[cfg_attr(feature = "defmt", derive(defmt::Format))]

0 commit comments

Comments
 (0)