Skip to content

Commit

Permalink
checkpoint: brutal circular dma hack
Browse files Browse the repository at this point in the history
  • Loading branch information
antoinevg committed Aug 12, 2022
1 parent 8db8e48 commit 2d32589
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 27 deletions.
49 changes: 34 additions & 15 deletions examples/audio_testsignal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ fn main() -> ! {
}

if counter % 5 == 0 {
println!("counter: {}", counter);
//println!("counter: {}", counter);
}

counter += 1;
Expand Down Expand Up @@ -110,21 +110,39 @@ extern "C" fn MachineExternal() {
pac::Interrupt::DMAC_NS => {
let dmac = unsafe { &*pac::DMAC::PTR };

// clear pending interrupts
dmac.dmac_irq_pend_reg0.write(|w| w.dma2_hlaf_irq_pend().set_bit());
while dmac.dmac_irq_pend_reg0.read().dma2_hlaf_irq_pend().bit_is_set() {}
dmac.dmac_irq_pend_reg0.write(|w| w.dma2_pkg_irq_pend().set_bit());
while dmac.dmac_irq_pend_reg0.read().dma2_pkg_irq_pend().bit_is_set() {}
//dmac.dmac_irq_pend_reg0.write(|w| w.dma2_queue_irq_pend().set_bit());
//while dmac.dmac_irq_pend_reg0.read().dma2_queue_irq_pend().bit_is_set() {}

// get some stats
let packages = dmac.dmac_pkg_num_reg2.read().bits();
println!("DMAC_NS {}", packages);
let left = dmac.dmac_bcnt_left_reg2.read().bits();
//let bits = dmac.dmac_sta_reg.read().bits();
//let mbus = twiddle::bit(bits, 31);
//let chans = twiddle::range(bits, 0..15);

// get pending bits
let bits = dmac.dmac_irq_pend_reg0.read().bits();
let pending = twiddle::range(bits, 8..10);

// clear pending interrupts
if twiddle::bit(pending, 0) { // half package
dmac.dmac_irq_pend_reg0.write(|w| w.dma2_hlaf_irq_pend().set_bit());
while dmac.dmac_irq_pend_reg0.read().dma2_hlaf_irq_pend().bit_is_set() {}
}
if twiddle::bit(pending, 1) { // end of package
dmac.dmac_irq_pend_reg0.write(|w| w.dma2_pkg_irq_pend().set_bit());
while dmac.dmac_irq_pend_reg0.read().dma2_pkg_irq_pend().bit_is_set() {}
}
if twiddle::bit(pending, 2) { // end of queue
dmac.dmac_irq_pend_reg0.write(|w| w.dma2_queue_irq_pend().set_bit());
while dmac.dmac_irq_pend_reg0.read().dma2_queue_irq_pend().bit_is_set() {}
}

let bits = dmac.dmac_sta_reg.read().bits();
let mbus = twiddle::bit(bits, 31);
let chans = twiddle::range(bits, 0..15);
println!("DMAC_NS mbus:{} chans:{:#018b}", mbus, chans); // 0: idle, 1: busy
// dump some debug info
let counter = unsafe { COUNTER };
if counter % 1000 == 0 {
println!("DMAC_NS pend:{:#05b}", pending); // 0: idle, 1: busy
println!("DMAC_NS pkg:{}", packages);
println!("DMAC_NS left:{}\n", left);
//println!("DMAC_NS mbus:{} chans:{:#018b}", mbus, chans); // 0: idle, 1: busy
}
}
pac::Interrupt::AUDIO_CODEC => {
let audio_codec = unsafe { &*pac::AUDIOCODEC::PTR };
Expand All @@ -140,7 +158,6 @@ extern "C" fn MachineExternal() {
//let mut ac_dac_txdata = unsafe { &*AUDIOCODEC::PTR }.ac_dac_txdata;
const AC_DAC_TXDATA: *mut u32 = (audio_codec::SUNXI_AUDIO_CODEC + 0x0020) as *mut u32;
let sample = audio_codec::TX_BUFFER[COUNTER];
COUNTER += 1;
if COUNTER == audio_codec::TX_BUFFER.len() {
COUNTER = 0;
}
Expand Down Expand Up @@ -191,6 +208,8 @@ extern "C" fn MachineExternal() {
}
}

unsafe { COUNTER += 1 };

// Release claim
plic.complete(claim);
}
50 changes: 41 additions & 9 deletions src/audio_codec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ use core::ptr::NonNull;
use d1_pac as pac;
use pac::{AUDIOCODEC, CCU};

use crate::dmac::descriptor::Descriptor;
use crate::dmac::{self, descriptor, descriptor::DescriptorConfig, Dmac};
use twiddle;
use crate::println;
Expand Down Expand Up @@ -439,10 +440,11 @@ fn configure_dac(codec: &AUDIOCODEC) {
// .modify(|r, w| unsafe { w.bits(r.bits() | (0 << PB12)) });
}

pub const BLOCK_LENGTH: usize = 128;
pub const BLOCK_LENGTH: usize = 64;
pub const STEREO_BLOCK_LENGTH: usize = BLOCK_LENGTH * 2; // 2 channels
pub const TX_BUFFER_LENGTH:usize = STEREO_BLOCK_LENGTH * 2; // 2 half-blocks
pub static mut TX_BUFFER: [u32; TX_BUFFER_LENGTH] = [0; TX_BUFFER_LENGTH];
pub static mut TX_BUFFER_1: [u32; TX_BUFFER_LENGTH] = [0; TX_BUFFER_LENGTH];
pub static mut TX_BUFFER_2: [u32; TX_BUFFER_LENGTH] = [0; TX_BUFFER_LENGTH];

/// 8.4.4.2 Playback Process, page 769-770
///
Expand All @@ -461,8 +463,15 @@ fn enable_dac_drq_dma(codec: &AUDIOCODEC, dmac: &mut Dmac) {
// generate some test noise
unsafe {
let mut counter = 0;
for byte in &mut TX_BUFFER {
*byte = ((u32::MAX / TX_BUFFER.len() as u32) * counter) as u32;
for byte in &mut TX_BUFFER_1 {
*byte = ((u32::MAX / TX_BUFFER_1.len() as u32) * counter) as u32;
counter += 1;
}
}
unsafe {
let mut counter = 0;
for byte in &mut TX_BUFFER_2 {
*byte = ((u32::MAX / TX_BUFFER_2.len() as u32) * counter) as u32;
counter += 1;
}
}
Expand All @@ -473,29 +482,52 @@ fn enable_dac_drq_dma(codec: &AUDIOCODEC, dmac: &mut Dmac) {
let bits = twiddle::set(bits, 3, true); // DAC_IRQ_EN
codec.ac_dac_fifoc.write(|w| unsafe { w.bits(bits) });

// TODO pg. 225 make sure that TX_BUFFER_1 is word-aligned

// enable dma
let ac_dac_txdata = &unsafe { &*AUDIOCODEC::PTR }.ac_dac_txdata as *const _ as *mut ();
let descriptor_config = descriptor::DescriptorConfig {
source: unsafe { TX_BUFFER.as_ptr().cast() },
// memory
source: unsafe { TX_BUFFER_1.as_ptr().cast() },
destination: ac_dac_txdata,
byte_counter: unsafe { TX_BUFFER.len() },
byte_counter: unsafe { TX_BUFFER_1.len() }, // ???
// byte_counter: unsafe { TX_BUFFER_LENGTH * 4 }, // ???
// config
link: None,
wait_clock_cycles: 0,
bmode: descriptor::BModeSel::Normal,
// destination
dest_width: descriptor::DataWidth::Bit32,
dest_addr_mode: descriptor::AddressMode::IoMode,
dest_block_size: descriptor::BlockSize::Byte4,
dest_drq_type: descriptor::DestDrqType::AudioCodec,
// source
src_data_width: descriptor::DataWidth::Bit32,
src_addr_mode: descriptor::AddressMode::LinearMode,
src_block_size: descriptor::BlockSize::Byte1,
src_block_size: descriptor::BlockSize::Byte4,
src_drq_type: descriptor::SrcDrqType::Dram,
};
let descriptor = descriptor_config.try_into().unwrap();
let mut descriptor_config_2 = descriptor_config.clone();;

let mut descriptor_1: Descriptor = descriptor_config.try_into().unwrap();

// link descriptor_1 to descriptor_2
let descriptor_1_ptr = &descriptor_1 as* const Descriptor as *const ();
descriptor_config_2.source = unsafe { TX_BUFFER_2.as_ptr().cast() };
descriptor_config_2.link = Some(descriptor_1_ptr);
let descriptor_2: Descriptor = descriptor_config_2.try_into().unwrap();

// link descriptor_2 to descriptor_1
let descriptor_2_ptr = &descriptor_2 as* const Descriptor as *const ();
descriptor_1.link = descriptor_2_ptr as u32;
descriptor_1.link |= ((descriptor_2_ptr as usize >> 32) as u32) & 0b11;

unsafe {
dmac.channels[2].set_channel_modes(dmac::ChannelMode::Wait, dmac::ChannelMode::Handshake);
dmac.channels[2].start_descriptor(NonNull::from(&descriptor));
//dmac.channels[2].set_channel_modes(dmac::ChannelMode::Handshake, dmac::ChannelMode::Handshake);
//dmac.channels[2].set_channel_modes(dmac::ChannelMode::Wait, dmac::ChannelMode::Wait);
//dmac.channels[2].set_channel_modes(dmac::ChannelMode::Handshake, dmac::ChannelMode::Wait);
dmac.channels[2].start_descriptor(NonNull::from(&descriptor_1));
}
}

Expand Down
10 changes: 8 additions & 2 deletions src/dmac.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ pub struct Dmac {
impl Dmac {
pub fn new(dmac: DMAC, ccu: &mut CCU) -> Self {
ccu.dma_bgr.write(|w| w.gating().pass().rst().deassert());
// disable auto-gating, probably not needed?
dmac.dmac_auto_gate_reg.write(
|w| w.dma_chan_circuit().set_bit()
.dma_common_circuit().set_bit()
.dma_mclk_circuit().set_bit()
);
Self {
dmac,
channels: [
Expand Down Expand Up @@ -179,9 +185,9 @@ impl Channel {

// TODO only handles channel 0
self.irq_en_reg0().write(
|w| w.dma2_hlaf_irq_en().set_bit()
|w| w//.dma2_hlaf_irq_en().set_bit()
.dma2_pkg_irq_en().set_bit()
//.dma2_queue_irq_en().set_bit()
.dma2_queue_irq_en().set_bit()
);

let desc_addr = desc.as_ptr() as usize;
Expand Down
3 changes: 2 additions & 1 deletion src/dmac/descriptor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ pub struct Descriptor {
destination_address: u32,
byte_counter: u32,
parameter: u32,
link: u32,
pub link: u32,
}

// TODO: THIS COULD PROBABLY BE A BITFIELD LIBRARY
#[derive(Clone)]
pub struct DescriptorConfig {
pub source: *const (),
pub destination: *mut (),
Expand Down

0 comments on commit 2d32589

Please sign in to comment.