WIP Adaptive with PLL nudge (demo working)
This commit is contained in:
@@ -1,15 +1,8 @@
|
||||
#ifndef _AUDIO_CONFIG_
|
||||
#define _AUDIO_CONFIG_
|
||||
|
||||
void ConfigAudioPorts(unsigned divide);
|
||||
void AudioHwConfigure(unsigned samFreq, client i2c_master_if i_i2c);
|
||||
void pll_nudge(int nudge);
|
||||
|
||||
void AudioHwInit();
|
||||
|
||||
void PLL_Init(void);
|
||||
|
||||
/* Configures master clock and codc for passed sample freq */
|
||||
void AudioHwConfig(unsigned samFreq);
|
||||
|
||||
void ConfigCodec24576(unsigned samFeq);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -4,7 +4,10 @@
|
||||
#include <print.h>
|
||||
#include <stdio.h>
|
||||
#include "i2c.h"
|
||||
|
||||
#include "xua.h"
|
||||
#define DEBUG_UNIT AUDIO_CFG
|
||||
#define DEBUG_PRINT_ENABLE_AUDIO_CFG 1
|
||||
#include "debug_print.h"
|
||||
|
||||
|
||||
// TLV320DAC3101 Device I2C Address
|
||||
@@ -45,16 +48,39 @@
|
||||
#define DAC3101_SPKR_DRVR 0x2B // Register 43 - Right Class-D Speaker Driver
|
||||
|
||||
// TLV320DAC3101 easy register access defines
|
||||
//#define DAC3101_REGREAD(reg, data) {data[0] = 0xAA; i2c_master_read_reg(DAC3101_I2C_DEVICE_ADDR, reg, data, 1, i2c);}
|
||||
//#define DAC3101_REGWRITE(reg, val) {data[0] = val; i2c_master_write_reg(DAC3101_I2C_DEVICE_ADDR, reg, data, 1, i2c);}
|
||||
|
||||
//#define DAC3101_REGWRITE(reg, val) {i_i2c[0].write_reg(DAC3101_I2C_DEVICE_ADDR, reg, val);}
|
||||
|
||||
// TLV320DAC3101 easy register access defines
|
||||
//#define DAC3101_REGWRITE(reg, val) {data[0] = val; i2c_master_write_reg(DAC3101_I2C_DEVICE_ADDR, reg, data, 1, i2c);}
|
||||
#define DAC3101_REGWRITE(reg, val) {i_i2c.write_reg(DAC3101_I2C_DEVICE_ADDR, reg, val);}
|
||||
|
||||
|
||||
|
||||
static void set_node_pll_reg(tileref tile_ref, unsigned reg_val){
|
||||
write_sswitch_reg(get_tile_id(tile_ref), XS1_SSWITCH_PLL_CTL_NUM, reg_val);
|
||||
}
|
||||
|
||||
// Nominal setting is ref div = 25, fb_div = 1024, op_div = 2
|
||||
// PCF Freq 0.96MHz
|
||||
|
||||
enum clock_nudge{
|
||||
PLL_SLOWER = -1,
|
||||
PLL_NOMINAL = 0,
|
||||
PLL_FASTER = 1
|
||||
};
|
||||
|
||||
#define PLL_LOW 0xC003FE18 // This is 3.069MHz
|
||||
#define PLL_NOM 0xC003FF18 // This is 3.072MHz
|
||||
#define PLL_HIGH 0xC0040018 // This is 3.075MHz
|
||||
|
||||
int old_nudge = 0;
|
||||
void pll_nudge(int nudge) {
|
||||
if (nudge > 0){
|
||||
set_node_pll_reg(tile[0], PLL_HIGH);
|
||||
}
|
||||
else if (nudge < 0){
|
||||
set_node_pll_reg(tile[0], PLL_LOW);
|
||||
}
|
||||
set_node_pll_reg(tile[0], PLL_NOM);
|
||||
if(nudge != old_nudge && nudge){debug_printf("nudge: %d\n", nudge); }old_nudge = nudge;
|
||||
}
|
||||
|
||||
void AudioHwConfigure(unsigned samFreq, client i2c_master_if i_i2c)
|
||||
{
|
||||
|
||||
@@ -101,6 +127,34 @@ void AudioHwConfigure(unsigned samFreq, client i2c_master_if i_i2c)
|
||||
// DAC_MOD_CLK = DAC_CLK / 4 = 5.6448MHz.
|
||||
// DAC_FS = DAC_MOD_CLK / 128 = 44.1kHz.
|
||||
|
||||
#if XUA_ADAPTIVE
|
||||
//Set nominal clock speed on PLL
|
||||
write_sswitch_reg(get_tile_id(tile[0]), XS1_SSWITCH_PLL_CTL_NUM, PLL_NOM);
|
||||
|
||||
// We are assuming 48kHz family only and we generate MCLK
|
||||
// Set PLL J Value to 7
|
||||
DAC3101_REGWRITE(DAC3101_PLL_J, 0x07);
|
||||
// Set PLL D to 0 ...
|
||||
// Set PLL D MSB Value to 0x00
|
||||
DAC3101_REGWRITE(DAC3101_PLL_D_MSB, 0x07);
|
||||
// Set PLL D LSB Value to 0x00
|
||||
DAC3101_REGWRITE(DAC3101_PLL_D_LSB, 0x80);
|
||||
|
||||
delay_milliseconds(1);
|
||||
|
||||
// Set PLL_CLKIN = BCLK (device pin), CODEC_CLKIN = PLL_CLK (generated on-chip)
|
||||
DAC3101_REGWRITE(DAC3101_CLK_GEN_MUX, 0x07);
|
||||
|
||||
// Set PLL P and R values and power up.
|
||||
DAC3101_REGWRITE(DAC3101_PLL_P_R, 0x94);
|
||||
// Set NDAC clock divider to 2 and power up.
|
||||
DAC3101_REGWRITE(DAC3101_NDAC_VAL, 0x82);
|
||||
// Set MDAC clock divider to 7 and power up.
|
||||
DAC3101_REGWRITE(DAC3101_MDAC_VAL, 0x87);
|
||||
// Set OSR clock divider to 128.
|
||||
DAC3101_REGWRITE(DAC3101_DOSR_VAL_LSB, 0x80);
|
||||
|
||||
#else
|
||||
/* Sample frequency dependent register settings */
|
||||
if ((samFreq % 11025) == 0)
|
||||
{
|
||||
@@ -143,7 +197,9 @@ void AudioHwConfigure(unsigned samFreq, client i2c_master_if i_i2c)
|
||||
DAC3101_REGWRITE(DAC3101_MDAC_VAL, 0x84);
|
||||
// Set OSR clock divider to 128.
|
||||
DAC3101_REGWRITE(DAC3101_DOSR_VAL_LSB, 0x80);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
// Set CLKOUT Mux to DAC_CLK
|
||||
DAC3101_REGWRITE(DAC3101_CLKOUT_MUX, 0x04);
|
||||
// Set CLKOUT M divider to 1 and power up.
|
||||
@@ -205,6 +261,7 @@ void AudioHwConfigure(unsigned samFreq, client i2c_master_if i_i2c)
|
||||
i_i2c.shutdown();
|
||||
}
|
||||
|
||||
|
||||
//These are here just to silence compiler warnings
|
||||
void AudioHwInit(){}
|
||||
void AudioHwConfig(unsigned samFreq, unsigned mClk, unsigned dsdMode, unsigned sampRes_DAC, unsigned sampRes_ADC){}
|
||||
@@ -64,6 +64,7 @@ void AudioHwConfigure(unsigned samFreq, client i2c_master_if i_i2c);
|
||||
void XUA_Endpoint0_select(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl,
|
||||
chanend ?c_mix_ctl, chanend ?c_clk_ctl, chanend ?c_EANativeTransport_ctrl, CLIENT_INTERFACE(i_dfu, ?dfuInterface) VENDOR_REQUESTS_PARAMS_DEC_);
|
||||
void pdm_mic(streaming chanend c_ds_output, in buffered port:32 p_pdm_mics);
|
||||
void mic_array_setup_ddr_xcore(clock pdmclk, clock pdmclk6, out port p_pdm_clk, buffered in port:32 p_pdm_data, int divide);
|
||||
|
||||
void burn_normal_priority(void){
|
||||
while(1);
|
||||
@@ -98,7 +99,8 @@ int main()
|
||||
c_audio :> int _; //Now wait until i2c has finished mclk setup
|
||||
|
||||
const unsigned micDiv = MCLK_48/3072000;
|
||||
mic_array_setup_ddr(pdmclk, pdmclk6, p_mclk_in, p_pdm_clk, p_pdm_mics, micDiv);
|
||||
if (XUA_ADAPTIVE) mic_array_setup_ddr_xcore(pdmclk, pdmclk6, p_pdm_clk, p_pdm_mics, micDiv);
|
||||
else mic_array_setup_ddr(pdmclk, pdmclk6, p_mclk_in, p_pdm_clk, p_pdm_mics, micDiv);
|
||||
|
||||
par {
|
||||
i2s_frame_master(i_i2s, p_i2s_dac, 1, p_i2s_adc, 1, p_bclk, p_lrclk, p_mclk_in, clk_audio_bclk);
|
||||
@@ -110,7 +112,7 @@ int main()
|
||||
}
|
||||
}
|
||||
on tile[1]:{
|
||||
// Connect master-clock input clock-block to clock-block pin
|
||||
// Connect master-clock input clock-block to clock-block pin for asnch feedback calculation
|
||||
set_clock_src(clk_usb_mclk, p_mclk_in_usb); // Clock clock-block from mclk pin
|
||||
set_port_clock(p_for_mclk_count, clk_usb_mclk); // Clock the "count" port from the clock block
|
||||
start_clock(clk_usb_mclk); // Set the clock off running
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#define DEBUG_PRINT_ENABLE_XUA_AUDIO_HUB 1
|
||||
#include "debug_print.h"
|
||||
#include "mic_array.h"
|
||||
#include "AudioConfig.h"
|
||||
|
||||
|
||||
void mic_array_decimator_set_samprate(const unsigned samplerate, int mic_decimator_fir_data_array[], mic_array_decimator_conf_common_t *dcc, mic_array_decimator_config_t dc[]);
|
||||
@@ -31,6 +32,8 @@ void AudioHub(server i2s_frame_callback_if i2s,
|
||||
int32_t samples_out[NUM_USB_CHAN_OUT] = {0};
|
||||
int32_t samples_in[NUM_USB_CHAN_IN] = {0};
|
||||
|
||||
int32_t clock_nudge = 0;
|
||||
|
||||
#if XUA_NUM_PDM_MICS > 0
|
||||
unsigned buffer;
|
||||
int raw_mics[XUA_NUM_PDM_MICS] = {0};
|
||||
@@ -66,8 +69,9 @@ void AudioHub(server i2s_frame_callback_if i2s,
|
||||
case i2s.restart_check() -> i2s_restart_t restart:
|
||||
restart = I2S_NO_RESTART; // Keep on looping
|
||||
timer tmr; int t0, t1; tmr :> t0;
|
||||
for (int i = 0; i < NUM_USB_CHAN_OUT; i++) c_audio :> samples_out[i];
|
||||
for (int i = 0; i < NUM_USB_CHAN_IN; i++) c_audio <: raw_mics[i];
|
||||
for (int i = 0; i < NUM_USB_CHAN_OUT; i++) c_audio :> samples_out[i];
|
||||
if (XUA_ADAPTIVE) c_audio :> clock_nudge;
|
||||
for (int i = 0; i < NUM_USB_CHAN_IN; i++) c_audio <: raw_mics[i];
|
||||
|
||||
//Grab mics
|
||||
current = mic_array_get_next_time_domain_frame(c_ds_output, decimatorCount, buffer, mic_audio_frame, dc);
|
||||
@@ -75,8 +79,10 @@ void AudioHub(server i2s_frame_callback_if i2s,
|
||||
raw_mics[0] = current->data[0][0];
|
||||
raw_mics[1] = current->data[1][0];
|
||||
}
|
||||
|
||||
pll_nudge(clock_nudge);
|
||||
//tmr :> t1; debug_printf("%d\n", t1 - t0);
|
||||
delay_microseconds(15); //Test backpressure tolerance
|
||||
//delay_microseconds(10); //Test backpressure tolerance
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,4 +74,36 @@ void pdm_mic(streaming chanend c_ds_output, in buffered port:32 p_pdm_mics)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void mic_array_setup_ddr_xcore(clock pdmclk,
|
||||
clock pdmclk6,
|
||||
out port p_pdm_clk,
|
||||
buffered in port:32 p_pdm_data,
|
||||
int divide) {
|
||||
configure_clock_xcore(pdmclk, 80);
|
||||
//configure_clock_src_divide(pdmclk, p_mclk, divide/2);
|
||||
|
||||
configure_clock_xcore(pdmclk6, 40);
|
||||
//configure_clock_src_divide(pdmclk6, p_mclk, divide/4);
|
||||
|
||||
configure_port_clock_output(p_pdm_clk, pdmclk);
|
||||
configure_in_port(p_pdm_data, pdmclk6);
|
||||
|
||||
/* start the faster capture clock */
|
||||
start_clock(pdmclk6);
|
||||
/* wait for a rising edge on the capture clock */
|
||||
partin(p_pdm_data, 4);
|
||||
/* start the slower output clock */
|
||||
start_clock(pdmclk);
|
||||
|
||||
/*
|
||||
* this results in the rising edge of the capture clock
|
||||
* leading the rising edge of the output clock by one period
|
||||
* of p_mclk, which is about 40.7 ns for the typical frequency
|
||||
* of 24.576 megahertz.
|
||||
* This should fall within the data valid window.
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -155,6 +155,27 @@ void do_feedback_calculation(unsigned &sof_count
|
||||
}
|
||||
}
|
||||
|
||||
void fill_level_process(int fill_level, int &clock_nudge){
|
||||
const int trigger_high_upper = 6;
|
||||
const int trigger_high_lower = 8;
|
||||
|
||||
const int trigger_low_upper = -6;
|
||||
const int trigger_low_lower = -8;
|
||||
|
||||
if (fill_level >= trigger_high_upper){
|
||||
clock_nudge = 1;
|
||||
//debug_printf("Nudge down\n");
|
||||
}
|
||||
else if (fill_level <= trigger_low_upper){
|
||||
//debug_printf("Nudge up\n");
|
||||
clock_nudge = -1;
|
||||
}
|
||||
else clock_nudge = 0;
|
||||
//debug_printf("%d\n", clock_nudge);
|
||||
|
||||
static unsigned counter; counter++; if (counter>SOF_FREQ_HZ){counter = 0; debug_printf("f: %d\n",fill_level);}
|
||||
}
|
||||
|
||||
|
||||
extern "C"{
|
||||
void XUA_Endpoint0_lite_init(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl,
|
||||
@@ -187,7 +208,10 @@ void XUA_Buffer_lite(chanend c_ep0_out, chanend c_ep0_in, chanend c_aud_out, cha
|
||||
const unsigned mclk_hz = MCLK_48;
|
||||
unsigned int fb_clocks[1] = {0};
|
||||
|
||||
|
||||
//Adapative device clock control
|
||||
int clock_nudge = 0;
|
||||
|
||||
//Endpoints
|
||||
XUD_ep ep_aud_out = XUD_InitEp(c_aud_out);
|
||||
XUD_ep ep_aud_in = XUD_InitEp(c_aud_in);
|
||||
XUD_ep ep_feedback = 0;
|
||||
@@ -270,6 +294,9 @@ void XUA_Buffer_lite(chanend c_ep0_out, chanend c_ep0_in, chanend c_aud_out, cha
|
||||
if (ret != FIFO_SUCCESS) debug_printf("h2d full\n");
|
||||
num_samples_to_send_to_host = num_samples_received_from_host;
|
||||
|
||||
int fill_level = fifo_get_fill_relative_half(host_to_device_fifo_ptr);
|
||||
fill_level_process(fill_level, clock_nudge);
|
||||
|
||||
//Mark EP as ready for next frame from host
|
||||
XUD_SetReady_OutPtr(ep_aud_out, (unsigned)buffer_aud_out);
|
||||
//tmr :> t1; debug_printf("o%d\n", t1 - t0);
|
||||
@@ -314,10 +341,11 @@ void XUA_Buffer_lite(chanend c_ep0_out, chanend c_ep0_in, chanend c_aud_out, cha
|
||||
c_audio_hub :> samples_in[i];
|
||||
}
|
||||
fifo_ret_t ret = fifo_block_pop(host_to_device_fifo_ptr, samples_out, NUM_USB_CHAN_OUT);
|
||||
if (ret != FIFO_SUCCESS && output_interface_num) debug_printf("h2s empty\n");
|
||||
if (ret != FIFO_SUCCESS && output_interface_num != 0) debug_printf("h2d empty\n");
|
||||
for (int i = 0; i < NUM_USB_CHAN_OUT; i++) c_audio_hub <: samples_out[i];
|
||||
if (XUA_ADAPTIVE) c_audio_hub <: clock_nudge;
|
||||
ret = fifo_block_push(device_to_host_fifo_ptr, samples_in, NUM_USB_CHAN_IN);
|
||||
if (ret != FIFO_SUCCESS && input_interface_num) debug_printf("d2h full\n");
|
||||
if (ret != FIFO_SUCCESS && input_interface_num != 0) debug_printf("d2h full\n");
|
||||
//tmr :> t1; debug_printf("a%d\n", t1 - t0);
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user