Ver código fonte

Adding control functions (WIP)

Adding useful functions to setup all the configurable options in the
CODEC (not yet finished)
dds
Michele Perla 10 anos atrás
pai
commit
f0b376d3f6
2 arquivos alterados com 170 adições e 42 exclusões
  1. +160
    -39
      control_ak4558.cpp
  2. +10
    -3
      control_ak4558.h

+ 160
- 39
control_ak4558.cpp Ver arquivo

@@ -20,11 +20,15 @@ void AudioControlAK4558::readInitConfig(void)
unsigned int n = 0;
Wire.requestFrom(AK4558_I2C_ADDR, 10);
while(Wire.available()) {
#if AK4558_SERIAL_DEBUG > 0
Serial.print("Register ");
Serial.print(n);
Serial.print(" = ");
#endif
registers[n++] = Wire.read();
#if AK4558_SERIAL_DEBUG > 0
Serial.println(registers[n-1]);
#endif
}
}

@@ -36,11 +40,88 @@ bool AudioControlAK4558::write(unsigned int reg, unsigned int val)
return (Wire.endTransmission()==0);
}

bool AudioControlAK4558::enableIn(void)
{
// ADC setup (datasheet page 74
#if AK4558_SERIAL_DEBUG > 0
Serial.println("AK4558: Enable ADC");
#endif
registers[AK4558_PLL_CTRL] |= AK4558_PLL2;
registers[AK4558_PLL_CTRL] &= ~AK4558_PLL1;
write(AK4558_I2C_ADDR, registers[AK4558_PLL_CTRL]);
#if AK4558_SERIAL_DEBUG > 0
Serial.print("AK4558: PLL_CTRL set to ");
Serial.println(registers[AK4558_PLL_CTRL], BIN);
#endif
delay(10);
// as per table 16, set PLL_CTRL.PLL3-2-1-0 to 0101 for MICK as PLL Reference, 11.2896 MHz
// also, wait 10 ms for PLL lock
// TODO: IS IT NEEDED?
// ignore this, leaving default values - ADC: Set up the de-emphasis filter (Addr = 07H).
registers[AK4558_PWR_MNGT] |= AK4558_PMADR | AK4558_PMADL;
write(AK4558_I2C_ADDR, registers[AK4558_PWR_MNGT]);
#if AK4558_SERIAL_DEBUG > 0
Serial.print("AK4558: PWR_MNGT set to ");
Serial.println(registers[AK4558_PWR_MNGT], BIN);
#endif
delay(300);
// Power up the ADC: PMADL = PMADR bits = “0” → “1”
// Initialization cycle of the ADC is 5200/fs @Normal mode. The SDTO pin outputs “L” during initialization.
#if AK4558_SERIAL_DEBUG > 0
Serial.println("AK4558: Enable ADC - Done");
#endif
return true;
}
bool AudioControlAK4558::enableOut(void)
{
#if AK4558_SERIAL_DEBUG > 0
Serial.println("AK4558: Enable DAC");
#endif
// DAC Output setup (datasheet page 75)

registers[AK4558_MODE_CTRL] |= AK4558_LOPS;
write(AK4558_I2C_ADDR, registers[AK4558_MODE_CTRL]);
#if AK4558_SERIAL_DEBUG > 0
Serial.print("AK4558: MODE_CTRL set to ");
Serial.println(registers[AK4558_MODE_CTRL], BIN);
#endif
// Set the DAC output to power-save mode: LOPS bit “0” → “1”
// ignore this, leaving default values - DAC: Set up the digital filter mode.
// ignore this, leaving default values - Set up the digital output volume (Address = 08H, 09H).
registers[AK4558_PWR_MNGT] |= AK4558_PMDAR | AK4558_PMDAL;
write(AK4558_I2C_ADDR, registers[AK4558_PWR_MNGT]);
#if AK4558_SERIAL_DEBUG > 0
Serial.print("AK4558: PWR_MNGT set to ");
Serial.println(registers[AK4558_PWR_MNGT], BIN);
#endif
delay(300);
// Power up the DAC: PMDAL = PMDAR bits = “0” → “1”
// Outputs of the LOUT and ROUT pins start rising. Rise time is 300ms (max.) when C = 1μF.
registers[AK4558_MODE_CTRL] &= ~AK4558_LOPS;
write(AK4558_I2C_ADDR, registers[AK4558_MODE_CTRL]);
#if AK4558_SERIAL_DEBUG > 0
Serial.print("AK4558: MODE_CTRL set to ");
Serial.println(registers[AK4558_MODE_CTRL], BIN);
#endif
// Release power-save mode of the DAC output: LOPS bit = “1” → “0”
// Set LOPS bit to “0” after the LOUT and ROUT pins output “H”. Sound data will be output from the
// LOUT and ROUT pins after this setting.
#if AK4558_SERIAL_DEBUG > 0
Serial.println("AK4558: Enable DAC - Done");
#endif
return true;
}

bool AudioControlAK4558::enable(void)
{
Serial.println("Starting setup...");
delay(1000);
Serial.println("Setup start");
#if AK4558_SERIAL_DEBUG > 0
Serial.println("AK4558: Enable device");
#endif
// Power Up and Reset
// Clock Setup (datasheet page 72)
pinMode(PIN_PDN, OUTPUT);
@@ -50,7 +131,9 @@ bool AudioControlAK4558::enable(void)
// After Power Up: PDN pin “L” → “H”
// “L” time of 150ns or more is needed to reset the AK4558.
delay(20);
Serial.println("PDN is HIGH");
#if AK4558_SERIAL_DEBUG > 0
Serial.println("AK4558: PDN is HIGH (device reset)");
#endif
// Control register settings become available in 10ms (min.) when LDOE pin = “H”
Wire.begin();
readInitConfig();
@@ -65,17 +148,27 @@ bool AudioControlAK4558::enable(void)
registers[AK4558_CTRL_1] &= ~AK4558_DIF2;
registers[AK4558_CTRL_1] |= AK4558_DIF1 | AK4558_DIF0;
Serial.print("CTRL_1 set to ");
#if AK4558_SERIAL_DEBUG > 0
Serial.print("AK4558: CTRL_1 set to ");
Serial.println(registers[AK4558_CTRL_1], BIN);
#endif
// DIF2-1-0 = 011 ( 16 bit I2S compatible when BICK = 32fs)
// Set up the audio format (Addr=03H). (in this case: TDM1-0 = 00 (Time Division Multiplexing mode OFF) by default)
registers[AK4558_CTRL_2] &= ~AK4558_MCKS1;
Serial.print("CTRL_2 set to ");
#if AK4558_SERIAL_DEBUG > 0
Serial.print("AK4558: CTRL_2 set to ");
Serial.println(registers[AK4558_CTRL_2], BIN);
#endif
// MCKS1-0 = 00 (Master Clock Input Frequency Select, set 256fs for Normal Speed Mode -> 11.2896 MHz)
registers[AK4558_MODE_CTRL] &= ~AK4558_BCKO0;
Serial.print("MODE_CTRL set to ");
Serial.println(registers[AK4558_MODE_CTRL], BIN);
// BCKO1-0 = 00 (BICK Output Frequency at Master Mode = 32fs = 1.4112 MHz)
registers[AK4558_MODE_CTRL] |= AK4558_FS1;
// Set up the sampling frequency (FS3-0 bits). The ADC must be powered-up in consideration of PLL
// lock time. (in this case (ref. table 17): Set clock to mode 5 / 44.100 KHz)
#if AK4558_SERIAL_DEBUG > 0
Serial.print("AK4558: MODE_CTRL set to ");
Serial.println(registers[AK4558_MODE_CTRL], BIN);
#endif
Wire.beginTransmission(AK4558_I2C_ADDR);
Wire.write(AK4558_CTRL_1);
Wire.write(registers[AK4558_CTRL_1]);
@@ -88,48 +181,76 @@ bool AudioControlAK4558::enable(void)
// one byte instead of terminating the write cycle after the first data byte is transferred. After receiving each
// data packet the internal address counter is incremented by one, and the next data is automatically taken
// into the next address.
#if AK4558_SERIAL_DEBUG > 0
Serial.println("AK4558: Enable device - Done");
#endif
return true;
}

bool AudioControlAK4558::disableIn(void)
{
// ADC power-down (datasheet page 74
// ADC/DAC Output setup (datasheet pages 74, 75)
registers[AK4558_PLL_CTRL] |= AK4558_PLL2;
registers[AK4558_PLL_CTRL] &= ~AK4558_PLL1;
write(AK4558_I2C_ADDR, registers[AK4558_PLL_CTRL]);
Serial.print("PLL_CTRL set to ");
Serial.println(registers[AK4558_PLL_CTRL], BIN);
delay(10);
// as per table 16, set PLL_CTRL.PLL3-2-1-0 to 0101 for MICK as PLL Reference, 11.2896 MHz
// also, wait 10 ms for PLL lock
// TODO: IS IT NEEDED?
// Set the DAC output to power-save mode: LOPS bit “0” → “1”
registers[AK4558_MODE_CTRL] |= AK4558_FS1 | AK4558_LOPS;
registers[AK4558_PWR_MNGT] &= ~AK4558_PMADR | ~AK4558_PMADL;
write(AK4558_I2C_ADDR, registers[AK4558_PWR_MNGT]);
#if AK4558_SERIAL_DEBUG > 0
Serial.print("AK4558: PWR_MNGT set to ");
Serial.println(registers[AK4558_PWR_MNGT], BIN);
#endif
// Power down ADC: PMADL = PMADR bits = “1” → “0”
#if AK4558_SERIAL_DEBUG > 0
Serial.println("AK4558: Enable ADC - Done");
#endif
return true;
}

bool AudioControlAK4558::disableOut(void)
{
#if AK4558_SERIAL_DEBUG > 0
Serial.println("AK4558: Disable DAC");
#endif
// DAC Output power-down (datasheet page 75)

registers[AK4558_MODE_CTRL] |= AK4558_LOPS;
write(AK4558_I2C_ADDR, registers[AK4558_MODE_CTRL]);
Serial.print("MODE_CTRL set to ");
#if AK4558_SERIAL_DEBUG > 0
Serial.print("AK4558: MODE_CTRL set to ");
Serial.println(registers[AK4558_MODE_CTRL], BIN);
// Set up the sampling frequency (FS3-0 bits). The ADC must be powered-up in consideration of PLL
// lock time. (in this case (ref. table 17): Set clock to mode 5 / 44.100 KHz)
// Set up the audio format (Addr=03H). (in this case: TDM1-0 = 00 (Time Division Multiplexing mode OFF) by default)
// ignore this, leaving default values - ADC: Set up the de-emphasis filter (Addr = 07H).
// ignore this, leaving default values - DAC: Set up the digital filter mode.
// ignore this, leaving default values - Set up the digital output volume (Address = 08H, 09H).
#endif
// Set the DAC output to power-save mode: LOPS bit “0” → “1”
registers[AK4558_PWR_MNGT] |= AK4558_PMADR | AK4558_PMADL | AK4558_PMDAR | AK4558_PMDAL;
registers[AK4558_PWR_MNGT] &= ~AK4558_PMDAR | ~AK4558_PMDAL;
write(AK4558_I2C_ADDR, registers[AK4558_PWR_MNGT]);
Serial.print("PWR_MNGT set to ");
#if AK4558_SERIAL_DEBUG > 0
Serial.print("AK4558: PWR_MNGT set to ");
Serial.println(registers[AK4558_PWR_MNGT], BIN);
#endif
delay(300);
// Power up the ADC: PMADL = PMADR bits = “0” → “1”
// Initialization cycle of the ADC is 5200/fs @Normal mode. The SDTO pin outputs “L” during initialization.
// Power up the DAC: PMDAL = PMDAR bits = “0” → “1”
// Outputs of the LOUT and ROUT pins start rising. Rise time is 300ms (max.) when C = 1μF.
// Power down the DAC: PMDAL = PMDAR bits = “1” → “0”
// Outputs of the LOUT and ROUT pins start falling. Rise time is 300ms (max.) when C = 1μF.
registers[AK4558_MODE_CTRL] &= ~AK4558_LOPS;
write(AK4558_I2C_ADDR, registers[AK4558_MODE_CTRL]);
write(AK4558_I2C_ADDR, registers[AK4558_MODE_CTRL]);
Serial.print("MODE_CTRL set to ");
#if AK4558_SERIAL_DEBUG > 0
Serial.print("AK4558: MODE_CTRL set to ");
Serial.println(registers[AK4558_MODE_CTRL], BIN);
#endif
// Release power-save mode of the DAC output: LOPS bit = “1” → “0”
// Set LOPS bit to “0” after the LOUT and ROUT pins output “H”. Sound data will be output from the
// LOUT and ROUT pins after this setting.
Serial.println("Setup ended");
// Set LOPS bit to “0” after outputs of the LOUT and ROUT pins fall to “L”.
#if AK4558_SERIAL_DEBUG > 0
Serial.println("AK4558: Disable DAC - Done");
#endif
return true;
}

bool AudioControlAK4558:volume(float n)
{
// Set DAC output volume
registers[AK4558_LOUT_VOL] &= ~AK4558_LOPS;
write(AK4558_I2C_ADDR, registers[AK4558_LOUT_VOL]);
#if AK4558_SERIAL_DEBUG > 0
Serial.print("AK4558: LOUT_VOL set to ");
Serial.println(registers[AK4558_LOUT_VOL], BIN);
#endif
}

+ 10
- 3
control_ak4558.h Ver arquivo

@@ -9,6 +9,9 @@

#include "AudioControl.h"

#define AK4558_SERIAL_DEBUG 1
//if 1, then Serial Monitor will show debug information about configuration of the AK4558

// for Teensy audio lib operation the following settings are needed
// 1fs = 44.1 KHz
// sample size = 16 bits
@@ -230,9 +233,13 @@
class AudioControlAK4558 : public AudioControl
{
public:
bool enable(void);
bool disable(void) { return false; }
bool volume(float n) { return false; }
bool enable(void); //enables the CODEC, does not power up ADC nor DAC (use enableIn() and enableOut() for selective power up)
bool enableIn(void);
bool enableOut(void);
bool disable(void) { return (disableIn()&&disableOut()); }
bool disableIn(void);
bool disableOut(void);
bool volume(float n);
bool inputLevel(float n) { return false; }
bool inputSelect(int n) { return false; }
protected:

Carregando…
Cancelar
Salvar