Skip to content

Commit

Permalink
checkpoint: ac_dac_cnt is incrementing and interrupts are clearing
Browse files Browse the repository at this point in the history
  • Loading branch information
antoinevg committed Aug 12, 2022
1 parent 2d32589 commit c42078e
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 100 deletions.
69 changes: 36 additions & 33 deletions examples/audio_testsignal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,31 +25,28 @@ fn main() -> ! {
// trim bandgap reference voltage ???
audio_codec::trim_bandgap_ref_voltage();

// gpio - PE8
let gpio = &p.GPIO;
const PE8: u32 = 8;
gpio.pe_cfg1.modify(|_, w| w.pe8_select().pe_eint8());
gpio.pe_pull0.write(|w| w.pe8_pull().pull_up());
gpio.pe_eint_cfg1.modify(|_, w| w.eint8_cfg().double_edge());
gpio.pe_eint_ctl.modify(|_, w| w.eint8_ctl().enable());

// gpio - led
let gpio = &p.GPIO;
const PC1: u32 = 1;
gpio.pc_cfg0.write(|w| w.pc1_select().output());

// ccu
let mut ccu = p.CCU;

// dmac
let mut dmac = dmac::Dmac::new(p.DMAC, &mut ccu);

// audio_codec
let audio_codec = audio_codec::AudioCodec::new(p.AUDIOCODEC, &mut ccu, &mut dmac);

// plic
let plic = plic::Plic::new(p.PLIC);
unsafe {
//plic.set_priority(pac::Interrupt::GPIOE_NS, plic::Priority::P1);
plic.set_priority(pac::Interrupt::DMAC_NS, plic::Priority::P10);
//plic.set_priority(pac::Interrupt::AUDIO_CODEC, plic::Priority::P1);
plic.set_priority(pac::Interrupt::AUDIO_CODEC, plic::Priority::P1);

//plic.unmask(pac::Interrupt::GPIOE_NS);
plic.unmask(pac::Interrupt::DMAC_NS);
//plic.unmask(pac::Interrupt::AUDIO_CODEC);
plic.unmask(pac::Interrupt::AUDIO_CODEC);
}

// enable interrupts
Expand All @@ -58,15 +55,9 @@ fn main() -> ! {
riscv::register::mie::set_mext();
}

// dmac
let mut dmac = dmac::Dmac::new(p.DMAC, &mut ccu);

// audio_codec
let audio_codec = audio_codec::AudioCodec::new(p.AUDIOCODEC, &mut ccu, &mut dmac);
// audio_codec - start
audio_codec.start(&mut dmac);

let mut counter = 0;

// blinky
loop {
gpio.pc_dat
Expand All @@ -79,12 +70,6 @@ fn main() -> ! {
unsafe {
riscv::asm::delay(100_000_000);
}

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

counter += 1;
}
}

Expand Down Expand Up @@ -147,9 +132,27 @@ extern "C" fn MachineExternal() {
pac::Interrupt::AUDIO_CODEC => {
let audio_codec = unsafe { &*pac::AUDIOCODEC::PTR };

let count = audio_codec.ac_adc_cnt.read().bits();
if count != 0 {
println!("ac_adc_cnt: {:#034b}", count);
// clear all pending interrupts
let bits = audio_codec.ac_dac_fifos.read().bits();
let bits = twiddle::set_range(bits, 1..3, 0b111);
audio_codec.ac_dac_fifos.write(|w| unsafe { w.bits(bits) });
loop {
let bits = audio_codec.ac_dac_fifos.read().bits();
if twiddle::range(bits, 1..3) == 0 {
break;
}
}

//let bits = audio_codec.ac_dac_fifos.read().bits();
//let bits = twiddle::range(bits, 1..3);
//println!("ac_dac_fifos: {:#05b}", bits);

// dump some debug info
let counter = unsafe { COUNTER };
if counter % 30000 == 0 {
let count = audio_codec.ac_dac_cnt.read().bits();
//println!("ac_dac_cnt: {:#034b} -> {}", count, counter);
println!("ac_dac_cnt: {}", count);
}

/*unsafe {
Expand All @@ -176,9 +179,9 @@ extern "C" fn MachineExternal() {
/*for _ in 0..10 {
let bits = audio_codec.ac_dac_fifos.read().bits();
println!("1 {:#05b}", twiddle::range(bits, 1..3));
let bits = twiddle::set(bits, 3, true);
//let bits = twiddle::set(bits, 2, true);
//let bits = twiddle::set(bits, 1, true);
let bits = twiddle::set(bits, 2, true);
let bits = twiddle::set(bits, 1, true);
let bits = twiddle::set(bits, 0, true);
audio_codec.ac_dac_fifos.write(|w| unsafe { w.bits(bits) });
unsafe { riscv::asm::delay(50); }
//audio_codec.ac_dac_fifos.write(|w| unsafe { w.bits(0b1000) });
Expand All @@ -189,7 +192,7 @@ extern "C" fn MachineExternal() {
}
panic!();*/

let bits = audio_codec.ac_dac_fifos.read().bits();
/*let bits = audio_codec.ac_dac_fifos.read().bits();
if twiddle::bit(bits, 3) {
let bits = twiddle::set(bits, 3, true);
}
Expand All @@ -199,7 +202,7 @@ extern "C" fn MachineExternal() {
if twiddle::bit(bits, 1) {
let bits = twiddle::set(bits, 1, true);
}
audio_codec.ac_dac_fifos.write(|w| unsafe { w.bits(bits) });
audio_codec.ac_dac_fifos.write(|w| unsafe { w.bits(bits) });*/

}
x => {
Expand Down
137 changes: 70 additions & 67 deletions src/audio_codec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ impl AudioCodec {
twiddle::set_range(bits, 0..2, 0b000); // ADDA_LOOP_MODE (0b000: Disabled, 0b001: ADC1/ADC2, 0b010: ADC3)
audio_codec.ac_dac_dg.write(|w| unsafe { w.bits(bits) });
*/
//init_codec_ccu(ccu); // 1
//configure_dac(&audio_codec); // 2
init_codec_ccu(ccu); // 1
configure_dac(&audio_codec); // 2

Self { audio_codec }
}
Expand Down Expand Up @@ -139,8 +139,7 @@ impl AudioCodec {
/// sunxi_codec_init()
///
fn init_codec_ccu(ccu: &CCU) {
// configure PLL_Audio0 frequency and enable PLL_Audio1
// TODO Shouldn't this be PLL_Audio1 ??? (see pg. 769 Playback Process)
// configure PLL_Audio0 frequency and enable PLL_Audio0
//
// pg. 64 3.2.6.7 PLL_AUDIO0_CTRL_REG
// 0x0078 PLL_AUDIO0 Control Register (Default Value: 0x4814_5500)
Expand Down Expand Up @@ -211,15 +210,15 @@ fn init_codec_ccu(ccu: &CCU) {
ccu.audio_codec_bgr
.write(|w| unsafe { w.bits(0x0001_0001) });

// configure PLL_Audio0 frequency and enable PLL_Audio1
// configure PLL_Audio0 frequency and select PLL_Audio0
//
// pg. 117 3.2.6.84 AUDIO_CODEC_DAC_CLK_REG
// 0x0A50 AUDIO_CODEC_DAC Clock Register (Default Value: 0x0000_0000)
// Example: 1000_0000_0000_0000_0000_0000_0000_0000
//
// 31 Gating Clock = 1 (0: off, 1: on)
// 30:27 ---
// 26:24 Clock Source Select = 000 (00: PLL_AUDIO0(1x), 01: PLL_AUDIO1(DIV2), 10: PLL_AUDIO1(DIV5))
// 26:24 Clock Source Select = 000 (00: PLL_AUDIO0 (1x), 01: PLL_AUDIO1 (DIV2), 10: PLL_AUDIO1 (DIV5))
// 23:10 ---
// 09:08 Factor N = 00 (00: /1, 01: /2, 10: /4, 11: /8)
// 07:05 ---
Expand Down Expand Up @@ -266,9 +265,9 @@ fn configure_dac(codec: &AUDIOCODEC) {
// 06 DAC_MONO_EN = 00 (00: Stereo, 64 levels fifo, 01: 128 levels fifo)
// 05 TX_SAMPLE_BITS = 0 (0: 16 bits, 1: 20 bits)
// 04 DAC_DRQ_EN = 0
// 03 DAC_IRQ_EN = 0
// 02 FIFO_UNDERRUN_IRQ_EN = 0
// 01 FIFO_OVERRUN_IRQ_EN = 9
// 03 DAC_IRQ_EN = 1
// 02 FIFO_UNDERRUN_IRQ_EN = 1
// 01 FIFO_OVERRUN_IRQ_EN = 1
// 00 FIFO_FLUSH = 0 (0: self clear, 1: flush TX FIFO)

// - sunxi_codec_hw_params() --
Expand All @@ -277,7 +276,8 @@ fn configure_dac(codec: &AUDIOCODEC) {

// set DAC sample resolution
let bits = twiddle::set_range(bits, 24..25, 0b01); // FIFO Mode = [15:0] (little-endian)
let bits = twiddle::set(bits, 5, false); // Sample Resolution = 16 bits
//let bits = twiddle::set(bits, 5, false); // Sample Resolution = 16 bits
let bits = twiddle::set(bits, 5, true); // Sample Resolution = 20 bits

// set DAC sample rate
//codec.ac_dac_fifoc.modify(|_r, w| w.sample_rate(SampleRate::R48K));
Expand All @@ -288,15 +288,18 @@ fn configure_dac(codec: &AUDIOCODEC) {
// set DAC channels
let bits = twiddle::set(bits, 6, false); // DAC Mono Enable = false

// enable DAC_IRQ - deleteme
//let bits = twiddle::set(bits, 3, true); // DAC_IRQ_EN

// Write to register
codec.ac_dac_fifoc.write(|w| unsafe { w.bits(bits) });

// - sunxi_codec_playback_prepare --

// FIFO flush
let bits = codec.ac_dac_fifoc.read().bits();
let bits = twiddle::set(bits, 0, true);
codec.ac_dac_fifoc.write(|w| unsafe { w.bits(bits) });
//let bits = codec.ac_dac_fifoc.read().bits();
//let bits = twiddle::set(bits, 0, true);
//codec.ac_dac_fifoc.write(|w| unsafe { w.bits(bits) });

// FIFO clear pending interrupts
//
Expand All @@ -311,23 +314,35 @@ fn configure_dac(codec: &AUDIOCODEC) {
// 02 TXU_INT Underrun Pending Interrupt
// 01 TXO_INT Overrun Pending Interrupt
// 00 ---
codec.ac_dac_fifos.write(|w| unsafe { w.bits(0b1110) });
//codec.ac_dac_fifos.write(|w| unsafe { w.bits(0b1110) });

// enable FIFO_UNDERRUN & FIFO_OVERRUN IRQ's
//let bits = codec.ac_dac_fifoc.read().bits();
//let bits = twiddle::set(bits, 3, true); // DAC_IRQ_EN
//let bits = twiddle::set(bits, 2, true); // FIFO_UNDERRUN_IRQ_EN
//let bits = twiddle::set(bits, 1, true); // FIFO_OVERRUN_IRQ_EN
//codec.ac_dac_fifoc.write(|w| unsafe { w.bits(bits) });

// FIFO clear sample counter
//
// pg. 780 8.4.6. AC_DAC_CNT6
// pg. 780 8.4.6. AC_DAC_CNT
// 0x0024 DAC TX Counter Register (Default Value: 0x0000_0000)
//
// 31:00 TX_CNT TX Sample Counter
codec.ac_dac_cnt.write(|w| unsafe { w.bits(0b1110) });
let bits = codec.ac_dac_fifoc.read().bits();
let bits = twiddle::set(bits, 0, true);
codec.ac_dac_fifoc.write(|w| unsafe { w.bits(bits) });
codec.ac_dac_cnt.write(|w| unsafe { w.bits(0) });
//codec.ac_dac_cnt.write(|w| unsafe { w.bits(0b1110) }); ????? WTF ?????

// Flush FIFO
//let bits = codec.ac_dac_fifoc.read().bits();
//let bits = twiddle::set(bits, 0, true);
//codec.ac_dac_fifoc.write(|w| unsafe { w.bits(bits) });

// FIFO enable empty DRQ - happens in enable_dac_drq_dma
//let bits = codec.ac_dac_fifoc.read().bits();
//let bits = twiddle::set(bits, 4, true);
//codec.ac_dac_fifoc.write(|w| unsafe { w.bits(bits) });


// FIFO enable empty DRQ
let bits = codec.ac_dac_fifoc.read().bits();
let bits = twiddle::set(bits, 4, true);
codec.ac_dac_fifoc.write(|w| unsafe { w.bits(bits) });
/*
// Enable ADC analog channels
//
Expand Down Expand Up @@ -421,10 +436,15 @@ fn configure_dac(codec: &AUDIOCODEC) {
//
// 31 EN_DAC DAC Digital Part Enable
// ...
// 00 HUB_EN Audio Hub Enable ?????
let bits = codec.ac_dac_dpc.read().bits();
let bits = twiddle::set(bits, 31, true);
codec.ac_dac_dpc.write(|w| unsafe { w.bits(bits) });

let bits = codec.ac_dac_dpc.read().bits();
let bits = twiddle::set(bits, 0, true);
codec.ac_dac_dpc.write(|w| unsafe { w.bits(bits) });

// Turn on speaker ???
unsafe {
riscv::asm::delay(1000);
Expand All @@ -442,7 +462,8 @@ fn configure_dac(codec: &AUDIOCODEC) {

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 const TX_BUFFER_LENGTH:usize = STEREO_BLOCK_LENGTH * 2; // 2 half-blocks
pub const TX_BUFFER_LENGTH:usize = STEREO_BLOCK_LENGTH * 1; // 2 buffers
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];

Expand Down Expand Up @@ -476,12 +497,6 @@ fn enable_dac_drq_dma(codec: &AUDIOCODEC, dmac: &mut Dmac) {
}
}

// enable dac drq
let bits = codec.ac_dac_fifoc.read().bits();
let bits = twiddle::set(bits, 4, true); // DAC_DRQ_EN
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
Expand All @@ -490,8 +505,8 @@ fn enable_dac_drq_dma(codec: &AUDIOCODEC, dmac: &mut Dmac) {
// memory
source: unsafe { TX_BUFFER_1.as_ptr().cast() },
destination: ac_dac_txdata,
byte_counter: unsafe { TX_BUFFER_1.len() }, // ???
// byte_counter: unsafe { TX_BUFFER_LENGTH * 4 }, // ???
//byte_counter: unsafe { TX_BUFFER_1.len() }, // ???
byte_counter: (unsafe { TX_BUFFER_LENGTH } * 4), // ???
// config
link: None,
wait_clock_cycles: 0,
Expand Down Expand Up @@ -529,6 +544,23 @@ fn enable_dac_drq_dma(codec: &AUDIOCODEC, dmac: &mut Dmac) {
//dmac.channels[2].set_channel_modes(dmac::ChannelMode::Handshake, dmac::ChannelMode::Wait);
dmac.channels[2].start_descriptor(NonNull::from(&descriptor_1));
}

// clear pending interrupts
//let bits = codec.ac_dac_fifos.read().bits();
//let bits = twiddle::set_range(bits, 1..3, 0b111);
//codec.ac_dac_fifos.write(|w| unsafe { w.bits(bits) });

// enable dac interrupts - all of them here ?
let bits = codec.ac_dac_fifoc.read().bits();
let bits = twiddle::set(bits, 4, true); // DAC_DRQ_EN
let bits = twiddle::set(bits, 3, true); // DAC_IRQ_EN
//let bits = twiddle::set(bits, 2, true); // FIFO_UNDERRUN_IRQ_EN
//let bits = twiddle::set(bits, 1, true); // FIFO_OVERRUN_IRQ_EN
codec.ac_dac_fifoc.write(|w| unsafe { w.bits(bits) });

// clear pending interrupts
//let bits = codec.ac_dac_fifos.read().bits();
//let bits = twiddle::set_range(bits, 1..3, 0b111);
}

// - --------------------------------------------------------------------------
Expand Down Expand Up @@ -586,49 +618,20 @@ pub(crate) fn configure_mixer(codec: &AUDIOCODEC) {
.adc2_reg
.modify(|r, w| unsafe { w.bits(r.bits() | (0x01 << lineout_ctl0)) }); // TODO check
}
pub(crate) fn prepare_playback(p: &pac::Peripherals) {
// - sunxi_codec_playback_prepare -----------------------------------------
// flush fifo
// clear pending
// clear sample counter
// enable fifo empty drq
// enable dac analog left channel
// enable dac digital part
// enable left, right lineout
}
pub(crate) fn init_dma(p: &pac::Peripherals) {
// - sunxi_dma_start ------------------------------------------------------
// configure dma
}
pub(crate) fn start_audio(p: &pac::Peripherals) {
}
*/

// - interrupts ---------------------------------------------------------------

//use d1_pac::interrupt::Interrupt::AUDIO_CODEC;

//#[export_name = "AUDIO_CODEC"]
//fn AUDIO_CODEC() {
//}
//use d1_pac::Interrupt::AUDIO_CODEC;

/*use d1_pac::Interrupt::AUDIO_CODEC;
#[export_name = "AUDIO_CODEC"]
fn AUDIO_CODEC() {
}
*/


// - example code -------------------------------------------------------------
//
// https://github.com/Tina-Linux/tina-v83x-u-boot-2018/blob/master/drivers/sound/sun8iw18-codec.c
Expand Down

0 comments on commit c42078e

Please sign in to comment.