Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions esp-hal-common/src/dma/gdma.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,9 @@ pub(crate) mod private {
use crate::dma::{private::*, *};

ImplChannel!(0);
#[cfg(not(esp32c2))]
ImplChannel!(1);
#[cfg(not(esp32c2))]
ImplChannel!(2);
}

Expand All @@ -230,7 +232,9 @@ pub(crate) mod private {
pub struct Gdma {
_inner: crate::pac::DMA,
pub channel0: ChannelCreator0,
#[cfg(not(esp32c2))]
pub channel1: ChannelCreator1,
#[cfg(not(esp32c2))]
pub channel2: ChannelCreator2,
}

Expand All @@ -248,7 +252,9 @@ impl Gdma {
Gdma {
_inner: dma,
channel0: ChannelCreator0 {},
#[cfg(not(esp32c2))]
channel1: ChannelCreator1 {},
#[cfg(not(esp32c2))]
channel2: ChannelCreator2 {},
}
}
Expand Down
15 changes: 13 additions & 2 deletions esp-hal-common/src/dma/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use core::{marker::PhantomData, sync::atomic::compiler_fence};

use private::*;

#[cfg(esp32c3)]
#[cfg(any(esp32c2, esp32c3))]
pub mod gdma;

#[cfg(any(esp32, esp32s2))]
Expand All @@ -20,7 +20,7 @@ pub enum DmaError {
}

/// DMA Priorities
#[cfg(any(esp32c3, esp32s3))]
#[cfg(any(esp32c2, esp32c3, esp32s3))]
#[derive(Clone, Copy)]
pub enum DmaPriority {
Priority0 = 0,
Expand All @@ -42,12 +42,22 @@ pub enum DmaPriority {
}

/// DMA Priorities
/// The values need to match the TRM
#[cfg(any(esp32, esp32s2))]
#[derive(Clone, Copy)]
pub enum DmaPriority {
Priority0 = 0,
}

/// DMA capable peripherals
/// The values need to match the TRM
#[cfg(esp32c2)]
#[derive(Clone, Copy)]
pub enum DmaPeripheral {
Spi2 = 0,
Sha = 7,
}

/// DMA capable peripherals
/// The values need to match the TRM
#[cfg(esp32c3)]
Expand All @@ -62,6 +72,7 @@ pub enum DmaPeripheral {
}

/// DMA capable peripherals
/// The values need to match the TRM
#[cfg(any(esp32, esp32s2))]
#[derive(Clone, Copy)]
pub enum DmaPeripheral {
Expand Down
5 changes: 2 additions & 3 deletions esp-hal-common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ pub use self::{
pub mod analog;
pub mod clock;
pub mod delay;
#[cfg(any(esp32, esp32c2, esp32c3, esp32s2))]
pub mod dma;
pub mod gpio;
pub mod i2c;
// FIXME: While the ESP32-C2 *does* have LEDC, it is not currently available in
Expand Down Expand Up @@ -90,9 +92,6 @@ pub mod efuse;
#[cfg_attr(xtensa, path = "interrupt/xtensa.rs")]
pub mod interrupt;

#[cfg(any(esp32c3, esp32, esp32s2))]
pub mod dma;

/// Enumeration of CPU cores
/// The actual number of available cores depends on the target.
pub enum Cpu {
Expand Down
24 changes: 13 additions & 11 deletions esp-hal-common/src/spi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,12 @@

use fugit::HertzU32;

#[cfg(any(esp32c3, esp32, esp32s2))]
use crate::dma::private::{Rx, Tx};
#[cfg(any(esp32c3, esp32, esp32s2))]
use crate::dma::{DmaError, DmaPeripheral};
#[cfg(any(esp32, esp32c2, esp32c3, esp32s2))]
use crate::dma::{
private::{Rx, Tx},
DmaError,
DmaPeripheral,
};
use crate::{
clock::Clocks,
pac::spi2::RegisterBlock,
Expand All @@ -76,13 +78,13 @@ const MAX_DMA_SIZE: usize = 32736;

#[derive(Debug, Clone, Copy)]
pub enum Error {
#[cfg(any(esp32c3, esp32, esp32s2))]
#[cfg(any(esp32, esp32c2, esp32c3, esp32s2))]
DmaError(DmaError),
MaxDmaTransferSizeExceeded,
Unknown,
}

#[cfg(any(esp32c3, esp32, esp32s2))]
#[cfg(any(esp32, esp32c2, esp32c3, esp32s2))]
impl From<DmaError> for Error {
fn from(value: DmaError) -> Self {
Error::DmaError(value)
Expand Down Expand Up @@ -262,7 +264,7 @@ where
}
}

#[cfg(any(esp32c3, esp32, esp32s2))]
#[cfg(any(esp32, esp32c2, esp32c3, esp32s2))]
pub mod dma {
use core::mem;

Expand Down Expand Up @@ -916,7 +918,7 @@ mod ehal1 {
}
}

#[cfg(any(esp32c3, esp32, esp32s2))]
#[cfg(any(esp32, esp32c2, esp32c3, esp32s2))]
pub trait InstanceDma<TX, RX>: Instance
where
TX: Tx,
Expand Down Expand Up @@ -1071,7 +1073,7 @@ where
}
}

#[cfg(esp32c3)]
#[cfg(any(esp32c2, esp32c3))]
fn enable_dma(&self) {
let reg_block = self.register_block();
reg_block.dma_conf.modify(|_, w| w.dma_tx_ena().set_bit());
Expand All @@ -1083,7 +1085,7 @@ where
// for non GDMA this is done in `assign_tx_device` / `assign_rx_device`
}

#[cfg(esp32c3)]
#[cfg(any(esp32c2, esp32c3))]
fn clear_dma_interrupts(&self) {
let reg_block = self.register_block();
reg_block.dma_int_clr.write(|w| {
Expand Down Expand Up @@ -1126,7 +1128,7 @@ where
}
}

#[cfg(any(esp32c3, esp32, esp32s2))]
#[cfg(any(esp32, esp32c2, esp32c3, esp32s2))]
impl<TX, RX> InstanceDma<TX, RX> for crate::pac::SPI2
where
TX: Tx,
Expand Down
6 changes: 3 additions & 3 deletions esp-hal-common/src/system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub enum Peripheral {
Ledc,
#[cfg(any(esp32c2, esp32c3))]
ApbSarAdc,
#[cfg(esp32c3)]
#[cfg(any(esp32c2, esp32c3))]
Gdma,
#[cfg(any(esp32, esp32s2))]
Dma,
Expand All @@ -47,7 +47,7 @@ impl PeripheralClockControl {
#[cfg(esp32)]
let (perip_clk_en0, perip_rst_en0) = { (&system.perip_clk_en, &system.perip_rst_en) };

#[cfg(esp32c3)]
#[cfg(any(esp32c2, esp32c3))]
let (perip_clk_en1, perip_rst_en1) = { (&system.perip_clk_en1, &system.perip_rst_en1) };

match peripheral {
Expand Down Expand Up @@ -89,7 +89,7 @@ impl PeripheralClockControl {
perip_clk_en0.modify(|_, w| w.apb_saradc_clk_en().set_bit());
perip_rst_en0.modify(|_, w| w.apb_saradc_rst().clear_bit());
}
#[cfg(esp32c3)]
#[cfg(any(any(esp32c2, esp32c3)))]
Peripheral::Gdma => {
perip_clk_en1.modify(|_, w| w.dma_clk_en().set_bit());
perip_rst_en1.modify(|_, w| w.dma_rst().clear_bit());
Expand Down
120 changes: 120 additions & 0 deletions esp32c2-hal/examples/spi_loopback_dma.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
//! SPI loopback test using DMA
//!
//! Folowing pins are used:
//! SCLK GPIO6
//! MISO GPIO2
//! MOSI GPIO7
//! CS GPIO10
//!
//! Depending on your target and the board you are using you have to change the
//! pins.
//!
//! This example transfers data via SPI.
//! Connect MISO and MOSI pins to see the outgoing data is read as incoming
//! data.

#![no_std]
#![no_main]

use esp32c2_hal::{
clock::ClockControl,
dma::{DmaPriority, DmaTransferRxTx},
gdma::Gdma,
gpio::IO,
pac::Peripherals,
prelude::*,
spi::{dma::WithDmaSpi2, Spi, SpiMode},
timer::TimerGroup,
Delay,
Rtc,
};
use esp_backtrace as _;
use esp_println::println;
use riscv_rt::entry;

#[entry]
fn main() -> ! {
let peripherals = Peripherals::take().unwrap();
let mut system = peripherals.SYSTEM.split();
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();

// Disable the watchdog timers. For the ESP32-C2, this includes the Super WDT,
// the RTC WDT, and the TIMG WDT.
let mut rtc = Rtc::new(peripherals.RTC_CNTL);
let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks);
let mut wdt0 = timer_group0.wdt;

rtc.swd.disable();
rtc.rwdt.disable();
wdt0.disable();

let io = IO::new(peripherals.GPIO, peripherals.IO_MUX);
let sclk = io.pins.gpio6;
let miso = io.pins.gpio2;
let mosi = io.pins.gpio7;
let cs = io.pins.gpio10;

let dma = Gdma::new(peripherals.DMA, &mut system.peripheral_clock_control);
let dma_channel = dma.channel0;

let mut descriptors = [0u32; 8 * 3];
let mut rx_descriptors = [0u32; 8 * 3];

let mut spi = Spi::new(
peripherals.SPI2,
sclk,
mosi,
miso,
cs,
100u32.kHz(),
SpiMode::Mode0,
&mut system.peripheral_clock_control,
&clocks,
)
.with_dma(dma_channel.configure(
false,
&mut descriptors,
&mut rx_descriptors,
DmaPriority::Priority0,
));

let mut delay = Delay::new(&clocks);

// DMA buffer require a static life-time
let mut send = buffer1();
let mut receive = buffer2();
let mut i = 0;

for (i, v) in send.iter_mut().enumerate() {
*v = (i % 255) as u8;
}

loop {
send[0] = i;
send[send.len() - 1] = i;
i = i.wrapping_add(1);

let transfer = spi.dma_transfer(send, receive).unwrap();
// here we could do something else while DMA transfer is in progress
// the buffers and spi is moved into the transfer and we can get it back via
// `wait`
(receive, send, spi) = transfer.wait();
println!(
"{:x?} .. {:x?}",
&receive[..10],
&receive[receive.len() - 10..]
);

delay.delay_ms(250u32);
}
}

fn buffer1() -> &'static mut [u8; 32000] {
static mut BUFFER: [u8; 32000] = [0u8; 32000];
unsafe { &mut BUFFER }
}

fn buffer2() -> &'static mut [u8; 32000] {
static mut BUFFER: [u8; 32000] = [0u8; 32000];
unsafe { &mut BUFFER }
}
1 change: 1 addition & 0 deletions esp32c2-hal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use core::arch::global_asm;
pub use embedded_hal as ehal;
pub use esp_hal_common::{
clock,
dma::{self, gdma},
efuse,
gpio as gpio_types,
i2c,
Expand Down