WIP + get DAC config running

This commit is contained in:
Ed Clarke
2018-10-26 11:25:39 +01:00
parent 770c11b3f0
commit 161b934b8f
8 changed files with 198 additions and 165 deletions

View File

@@ -3,6 +3,7 @@
#include <platform.h>
#include <print.h>
#include <stdio.h>
#include "i2c.h"
@@ -51,168 +52,156 @@
// 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)
#define DAC3101_REGWRITE(reg, val) {i_i2c.write_reg(DAC3101_I2C_DEVICE_ADDR, reg, val);}
void AudioHwConfigure(unsigned samFreq)
void AudioHwConfigure(unsigned samFreq, client i2c_master_if i_i2c)
{
// Take DAC out of reset.
//p_gpio <: 1;
par
// Wait for 1ms
delay_milliseconds(1);
// Set register page to 0
DAC3101_REGWRITE(DAC3101_PAGE_CTRL, 0x00);
// Initiate SW reset (PLL is powered off as part of reset)
DAC3101_REGWRITE(DAC3101_SW_RST, 0x01);
// so I've got 24MHz in to PLL, I want 24.576MHz or 22.5792MHz out.
// I will always be using fractional-N (D != 0) so we must set R = 1
// PLL_CLKIN/P must be between 10 and 20MHz so we must set P = 2
// PLL_CLK = CLKIN * ((RxJ.D)/P)
// We know R = 1, P = 2.
// PLL_CLK = CLKIN * (J.D / 2)
// For 24.576MHz:
// J = 8
// D = 1920
// So PLL_CLK = 24 * (8.192/2) = 24 x 4.096 = 98.304MHz
// Then:
// NDAC = 4
// MDAC = 4
// DOSR = 128
// So:
// DAC_CLK = PLL_CLK / 4 = 24.576MHz.
// DAC_MOD_CLK = DAC_CLK / 4 = 6.144MHz.
// DAC_FS = DAC_MOD_CLK / 128 = 48kHz.
// For 22.5792MHz:
// J = 7
// D = 5264
// So PLL_CLK = 24 * (7.5264/2) = 24 x 3.7632 = 90.3168MHz
// Then:
// NDAC = 4
// MDAC = 4
// DOSR = 128
// So:
// DAC_CLK = PLL_CLK / 4 = 22.5792MHz.
// DAC_MOD_CLK = DAC_CLK / 4 = 5.6448MHz.
// DAC_FS = DAC_MOD_CLK / 128 = 44.1kHz.
/* Sample frequency dependent register settings */
if ((samFreq % 11025) == 0)
{
{
unsigned char data[1] = {0};
// MCLK = 22.5792MHz (44.1,88.2,176.4kHz)
// Set PLL J Value to 7
DAC3101_REGWRITE(DAC3101_PLL_J, 0x07);
// Set PLL D to 5264 ... (0x1490)
// Set PLL D MSB Value to 0x14
DAC3101_REGWRITE(DAC3101_PLL_D_MSB, 0x14);
// Set PLL D LSB Value to 0x90
DAC3101_REGWRITE(DAC3101_PLL_D_LSB, 0x90);
// Wait for 1ms
delay_milliseconds(1);
// Set register page to 0
DAC3101_REGWRITE(DAC3101_PAGE_CTRL, 0x00);
// Initiate SW reset (PLL is powered off as part of reset)
DAC3101_REGWRITE(DAC3101_SW_RST, 0x01);
// so I've got 24MHz in to PLL, I want 24.576MHz or 22.5792MHz out.
// I will always be using fractional-N (D != 0) so we must set R = 1
// PLL_CLKIN/P must be between 10 and 20MHz so we must set P = 2
// PLL_CLK = CLKIN * ((RxJ.D)/P)
// We know R = 1, P = 2.
// PLL_CLK = CLKIN * (J.D / 2)
// For 24.576MHz:
// J = 8
// D = 1920
// So PLL_CLK = 24 * (8.192/2) = 24 x 4.096 = 98.304MHz
// Then:
// NDAC = 4
// MDAC = 4
// DOSR = 128
// So:
// DAC_CLK = PLL_CLK / 4 = 24.576MHz.
// DAC_MOD_CLK = DAC_CLK / 4 = 6.144MHz.
// DAC_FS = DAC_MOD_CLK / 128 = 48kHz.
// For 22.5792MHz:
// J = 7
// D = 5264
// So PLL_CLK = 24 * (7.5264/2) = 24 x 3.7632 = 90.3168MHz
// Then:
// NDAC = 4
// MDAC = 4
// DOSR = 128
// So:
// DAC_CLK = PLL_CLK / 4 = 22.5792MHz.
// DAC_MOD_CLK = DAC_CLK / 4 = 5.6448MHz.
// DAC_FS = DAC_MOD_CLK / 128 = 44.1kHz.
}
else if ((samFreq % 8000) == 0)
{
// MCLK = 24.576MHz (48,96,192kHz)
// Set PLL J Value to 8
DAC3101_REGWRITE(DAC3101_PLL_J, 0x08);
// Set PLL D to 1920 ... (0x780)
// Set PLL D MSB Value to 0x07
DAC3101_REGWRITE(DAC3101_PLL_D_MSB, 0x07);
// Set PLL D LSB Value to 0x80
DAC3101_REGWRITE(DAC3101_PLL_D_LSB, 0x80);
}
else
{
//debug_printf("Unrecognised sample freq of %d in ConfigCodec\n", samFreq);
}
/* Sample frequency dependent register settings */
if ((samFreq % 11025) == 0)
{
// MCLK = 22.5792MHz (44.1,88.2,176.4kHz)
// Set PLL J Value to 7
DAC3101_REGWRITE(DAC3101_PLL_J, 0x07);
// Set PLL D to 5264 ... (0x1490)
// Set PLL D MSB Value to 0x14
DAC3101_REGWRITE(DAC3101_PLL_D_MSB, 0x14);
// Set PLL D LSB Value to 0x90
DAC3101_REGWRITE(DAC3101_PLL_D_LSB, 0x90);
delay_milliseconds(1);
// Set PLL_CLKIN = MCLK (device pin), CODEC_CLKIN = PLL_CLK (generated on-chip)
DAC3101_REGWRITE(DAC3101_CLK_GEN_MUX, 0x03);
// Set PLL P and R values and power up.
DAC3101_REGWRITE(DAC3101_PLL_P_R, 0xA1);
// Set NDAC clock divider to 4 and power up.
DAC3101_REGWRITE(DAC3101_NDAC_VAL, 0x84);
// Set MDAC clock divider to 4 and power up.
DAC3101_REGWRITE(DAC3101_MDAC_VAL, 0x84);
// Set OSR clock divider to 128.
DAC3101_REGWRITE(DAC3101_DOSR_VAL_LSB, 0x80);
// Set CLKOUT Mux to DAC_CLK
DAC3101_REGWRITE(DAC3101_CLKOUT_MUX, 0x04);
// Set CLKOUT M divider to 1 and power up.
DAC3101_REGWRITE(DAC3101_CLKOUT_M_VAL, 0x81);
// Set GPIO1 output to come from CLKOUT output.
DAC3101_REGWRITE(DAC3101_GPIO1_IO, 0x10);
// Set CODEC interface mode: I2S, 24 bit, slave mode (BCLK, WCLK both inputs).
DAC3101_REGWRITE(DAC3101_CODEC_IF, 0x20);
// Set register page to 1
DAC3101_REGWRITE(DAC3101_PAGE_CTRL, 0x01);
// Program common-mode voltage to mid scale 1.65V.
DAC3101_REGWRITE(DAC3101_HP_DRVR, 0x14);
// Program headphone-specific depop settings.
// De-pop, Power on = 800 ms, Step time = 4 ms
DAC3101_REGWRITE(DAC3101_HP_DEPOP, 0x4E);
// Program routing of DAC output to the output amplifier (headphone/lineout or speaker)
// LDAC routed to left channel mixer amp, RDAC routed to right channel mixer amp
DAC3101_REGWRITE(DAC3101_DAC_OP_MIX, 0x44);
// Unmute and set gain of output driver
// Unmute HPL, set gain = 0 db
DAC3101_REGWRITE(DAC3101_HPL_DRVR, 0x06);
// Unmute HPR, set gain = 0 dB
DAC3101_REGWRITE(DAC3101_HPR_DRVR, 0x06);
// Unmute Left Class-D, set gain = 12 dB
DAC3101_REGWRITE(DAC3101_SPKL_DRVR, 0x0C);
// Unmute Right Class-D, set gain = 12 dB
DAC3101_REGWRITE(DAC3101_SPKR_DRVR, 0x0C);
// Power up output drivers
// HPL and HPR powered up
DAC3101_REGWRITE(DAC3101_HP_DRVR, 0xD4);
// Power-up L and R Class-D drivers
DAC3101_REGWRITE(DAC3101_SPK_AMP, 0xC6);
// Enable HPL output analog volume, set = -9 dB
DAC3101_REGWRITE(DAC3101_HPL_VOL_A, 0x92);
// Enable HPR output analog volume, set = -9 dB
DAC3101_REGWRITE(DAC3101_HPR_VOL_A, 0x92);
// Enable Left Class-D output analog volume, set = -9 dB
DAC3101_REGWRITE(DAC3101_SPKL_VOL_A, 0x92);
// Enable Right Class-D output analog volume, set = -9 dB
DAC3101_REGWRITE(DAC3101_SPKR_VOL_A, 0x92);
delay_milliseconds(100);
}
else if ((samFreq % 8000) == 0)
{
// MCLK = 24.576MHz (48,96,192kHz)
// Set PLL J Value to 8
DAC3101_REGWRITE(DAC3101_PLL_J, 0x08);
// Set PLL D to 1920 ... (0x780)
// Set PLL D MSB Value to 0x07
DAC3101_REGWRITE(DAC3101_PLL_D_MSB, 0x07);
// Set PLL D LSB Value to 0x80
DAC3101_REGWRITE(DAC3101_PLL_D_LSB, 0x80);
}
else
{
//debug_printf("Unrecognised sample freq of %d in ConfigCodec\n", samFreq);
}
// Power up DAC
// Set register page to 0
DAC3101_REGWRITE(DAC3101_PAGE_CTRL, 0x00);
// Power up DAC channels and set digital gain
// Powerup DAC left and right channels (soft step enabled)
DAC3101_REGWRITE(DAC3101_DAC_DAT_PATH, 0xD4);
// DAC Left gain = 0dB
DAC3101_REGWRITE(DAC3101_DACL_VOL_D, 0x00);
// DAC Right gain = 0dB
DAC3101_REGWRITE(DAC3101_DACR_VOL_D, 0x00);
// Unmute digital volume control
// Unmute DAC left and right channels
DAC3101_REGWRITE(DAC3101_DAC_VOL, 0x00);
delay_milliseconds(1);
// Set PLL_CLKIN = MCLK (device pin), CODEC_CLKIN = PLL_CLK (generated on-chip)
DAC3101_REGWRITE(DAC3101_CLK_GEN_MUX, 0x03);
// Set PLL P and R values and power up.
DAC3101_REGWRITE(DAC3101_PLL_P_R, 0xA1);
// Set NDAC clock divider to 4 and power up.
DAC3101_REGWRITE(DAC3101_NDAC_VAL, 0x84);
// Set MDAC clock divider to 4 and power up.
DAC3101_REGWRITE(DAC3101_MDAC_VAL, 0x84);
// Set OSR clock divider to 128.
DAC3101_REGWRITE(DAC3101_DOSR_VAL_LSB, 0x80);
// Set CLKOUT Mux to DAC_CLK
DAC3101_REGWRITE(DAC3101_CLKOUT_MUX, 0x04);
// Set CLKOUT M divider to 1 and power up.
DAC3101_REGWRITE(DAC3101_CLKOUT_M_VAL, 0x81);
// Set GPIO1 output to come from CLKOUT output.
DAC3101_REGWRITE(DAC3101_GPIO1_IO, 0x10);
// Set CODEC interface mode: I2S, 24 bit, slave mode (BCLK, WCLK both inputs).
DAC3101_REGWRITE(DAC3101_CODEC_IF, 0x20);
// Set register page to 1
DAC3101_REGWRITE(DAC3101_PAGE_CTRL, 0x01);
// Program common-mode voltage to mid scale 1.65V.
DAC3101_REGWRITE(DAC3101_HP_DRVR, 0x14);
// Program headphone-specific depop settings.
// De-pop, Power on = 800 ms, Step time = 4 ms
DAC3101_REGWRITE(DAC3101_HP_DEPOP, 0x4E);
// Program routing of DAC output to the output amplifier (headphone/lineout or speaker)
// LDAC routed to left channel mixer amp, RDAC routed to right channel mixer amp
DAC3101_REGWRITE(DAC3101_DAC_OP_MIX, 0x44);
// Unmute and set gain of output driver
// Unmute HPL, set gain = 0 db
DAC3101_REGWRITE(DAC3101_HPL_DRVR, 0x06);
// Unmute HPR, set gain = 0 dB
DAC3101_REGWRITE(DAC3101_HPR_DRVR, 0x06);
// Unmute Left Class-D, set gain = 12 dB
DAC3101_REGWRITE(DAC3101_SPKL_DRVR, 0x0C);
// Unmute Right Class-D, set gain = 12 dB
DAC3101_REGWRITE(DAC3101_SPKR_DRVR, 0x0C);
// Power up output drivers
// HPL and HPR powered up
DAC3101_REGWRITE(DAC3101_HP_DRVR, 0xD4);
// Power-up L and R Class-D drivers
DAC3101_REGWRITE(DAC3101_SPK_AMP, 0xC6);
// Enable HPL output analog volume, set = -9 dB
DAC3101_REGWRITE(DAC3101_HPL_VOL_A, 0x92);
// Enable HPR output analog volume, set = -9 dB
DAC3101_REGWRITE(DAC3101_HPR_VOL_A, 0x92);
// Enable Left Class-D output analog volume, set = -9 dB
DAC3101_REGWRITE(DAC3101_SPKL_VOL_A, 0x92);
// Enable Right Class-D output analog volume, set = -9 dB
DAC3101_REGWRITE(DAC3101_SPKR_VOL_A, 0x92);
delay_milliseconds(100);
// Power up DAC
// Set register page to 0
DAC3101_REGWRITE(DAC3101_PAGE_CTRL, 0x00);
// Power up DAC channels and set digital gain
// Powerup DAC left and right channels (soft step enabled)
DAC3101_REGWRITE(DAC3101_DAC_DAT_PATH, 0xD4);
// DAC Left gain = 0dB
DAC3101_REGWRITE(DAC3101_DACL_VOL_D, 0x00);
// DAC Right gain = 0dB
DAC3101_REGWRITE(DAC3101_DACR_VOL_D, 0x00);
// Unmute digital volume control
// Unmute DAC left and right channels
DAC3101_REGWRITE(DAC3101_DAC_VOL, 0x00);
// Shutdown
//i_i2c[0].shutdown();
}
} /* par */
}
//These are here just to silence compiler warnings