Przeglądaj źródła

Added AK4558 CODEC support

dds
Michele Perla 9 lat temu
rodzic
commit
a602a17dca
4 zmienionych plików z 361 dodań i 0 usunięć
  1. +1
    -0
      Audio.h
  2. +115
    -0
      control_ak4558.cpp
  3. +244
    -0
      control_ak4558.h
  4. +1
    -0
      keywords.txt

+ 1
- 0
Audio.h Wyświetl plik

@@ -65,6 +65,7 @@
#include "analyze_peak.h"
#include "control_sgtl5000.h"
#include "control_wm8731.h"
#include "control_ak4558.h"
#include "effect_bitcrusher.h"
#include "effect_chorus.h"
#include "effect_fade.h"

+ 115
- 0
control_ak4558.cpp Wyświetl plik

@@ -0,0 +1,115 @@
/*
* HiFi Audio Codec Module support library for Teensy 3.x
*
* Copyright 2015, Michele Perla
*
*/
#include "control_ak4558.h"
#include "Wire.h"

void AudioControlAK4558::readInitConfig(void)
{
// puts all default registers values inside an array
// this allows us to modify registers locally using annotation like follows:
//
// registers[AK4558_CTRL_1] &= ~AK4558_DIF2;
// registers[AK4558_CTRL_1] |= AK4558_DIF1 | AK4558_DIF0;
//
// after manipulation, we can write the entire register value on the CODEC
unsigned int n = 0;
Wire.requestFrom(AK4558_I2C_ADDR, 10);
while(Wire.available()) {
Serial.print("Register ");
Serial.print(n);
Serial.print(" = ");
registers[n++] = Wire.read();
Serial.println(registers[n-1]);
}
}

bool AudioControlAK4558::write(unsigned int reg, unsigned int val)
{
Wire.beginTransmission(AK4558_I2C_ADDR);
Wire.write(reg);
Wire.write(val);
return (Wire.endTransmission()==0);
}

bool AudioControlAK4558::enable(void)
{
// Power Up and Reset
// Clock Setup (datasheet page 72)
digitalWrite(PIN_PDN, LOW);
delay(1);
digitalWrite(PIN_PDN, HIGH);
// 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");
// Control register settings become available in 10ms (min.) when LDOE pin = “H”
Wire.begin();
readInitConfig();
// access all registers to store locally their default values
// DIF2-0, DFS1-0 and ACKS bits must be set before MCKI, LRCK and BICK are supplied
// PMPLL = 0 (EXT Slave Mode; disables internal PLL and uses ext. clock) (by DEFAULT)
// ACKS = 0 (Manual Setting Mode; disables automatic clock selection) (by DEFAULT)
// DFS1-0 = 00 (Sampling Speed = Normal Speed Mode) (by DEFAULT)
// TDM1-0 = 00 (Time Division Multiplexing mode OFF) (by DEFAULT)
registers[AK4558_CTRL_1] &= ~AK4558_DIF2;
registers[AK4558_CTRL_1] |= AK4558_DIF1 | AK4558_DIF0;
// DIF2-1-0 = 011 ( 16 bit I2S compatible when BICK = 32fs)
registers[AK4558_CTRL_2] &= ~AK4558_MCKS1;
// MCKS1-0 = 00 (Master Clock Input Frequency Select, set 256fs for Normal Speed Mode -> 11.2896 MHz)
registers[AK4558_MODE_CTRL] &= ~AK4558_BCKO0;
// BCKO1-0 = 00 (BICK Output Frequency at Master Mode = 32fs = 1.4112 MHz)
Wire.beginTransmission(AK4558_I2C_ADDR);
Wire.write(AK4558_CTRL_1);
Wire.write(registers[AK4558_CTRL_1]);
Wire.write(registers[AK4558_CTRL_2]);
Wire.write(registers[AK4558_MODE_CTRL]);
Wire.endTransmission();
// Write configuration registers in a single write operation (datasheet page 81):
// The AK4558 can perform more than one byte write operation per sequence. After receipt of the third byte
// the AK4558 generates an acknowledge and awaits the next data. The master can transmit more than
// 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.
// 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]);
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;
write(AK4558_I2C_ADDR, registers[AK4558_MODE_CTRL]);
// 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).
registers[AK4558_PWR_MNGT] |= AK4558_PMADR | AK4558_PMADL | AK4558_PMDAR | AK4558_PMDAL;
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.
registers[AK4558_MODE_CTRL] &= ~AK4558_LOPS;
write(AK4558_I2C_ADDR, registers[AK4558_MODE_CTRL]);
// 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");
return true;
}

+ 244
- 0
control_ak4558.h Wyświetl plik

@@ -0,0 +1,244 @@
/*
* HiFi Audio Codec Module support library for Teensy 3.x
*
* Copyright 2015, Michele Perla
*
*/
#ifndef control_ak4558_h_
#define control_ak4558_h_

#include "AudioControl.h"

// for Teensy audio lib operation the following settings are needed
// 1fs = 44.1 KHz
// sample size = 16 bits
// MCKI : 11.2896 MHz
// BICK : 1.4112 MHz
// LRCK : 44.100 KHz
// to do so we need to set the following bits:
// PMPLL = 0 (EXT Slave Mode; disables internal PLL and uses ext. clock) (by DEFAULT)
// ACKS = 0 (Manual Setting Mode; disables automatic clock selection) (by DEFAULT)
// DFS1-0 = 00 (Sampling Speed = Normal Speed Mode, default)
// MCKS1-0 = 00 (Master Clock Input Frequency Select, set 256fs for Normal Speed Mode -> 11.2896 MHz)
// BCKO1-0 = 00 (BICK Output Frequency at Master Mode = 32fs = 1.4112 MHz)
// TDM1-0 = 00 (Time Division Multiplexing mode OFF) (by DEFAULT)
// DIF2-1-0 = 011 ( 16 bit I2S compatible when BICK = 32fs)

#ifndef PIN_PDN
#define PIN_PDN 1
#endif
// Power-Down & Reset Mode Pin
// “L”: Power-down and Reset, “H”: Normal operation
// The AK4558 should be reset once by bringing PDN pin = “L”

#ifndef AK4558_CAD1
#define AK4558_CAD1 1
#endif
// Chip Address 1 pin
// set to 'H' by default, configurable to 'L' via a jumper on bottom side of the board

#ifndef AK4558_CAD0
#define AK4558_CAD0 1
#endif
// Chip Address 0 pin
// set to 'H' by default, configurable to 'L' via a jumper on bottom side of the board

#define AK4558_I2C_ADDR (0x10 + (AK4558_CAD1<<1) + AK4558_CAD0)
// datasheet page 81:
// This address is 7 bits long followed by the eighth bit that is a data direction bit (R/W).
// The most significant five bits of the slave address are fixed as “00100”. The next bits are
// CAD1 and CAD0 (device address bit). These bits identify the specific device on the bus.
// The hard-wired input pins (CAD1 and CAD0) set these device address bits (Figure 69)

// Power Management register
#define AK4558_PWR_MNGT 0x00
// D4 D3 D2 D1 D0
// PMADR PMADL PMDAR PMDAL RSTN
#define AK4558_PMADR (1u<<4)
#define AK4558_PMADL (1u<<3)
// PMADL/R: ADC L/Rch Power Management
// 0: ADC L/Rch Power Down (default)
// 1: Normal Operation
#define AK4558_PMDAR (1u<<2)
#define AK4558_PMDAL (1u<<1)
// PMDAL/R: DAC L/Rch Power Management
// 0: DAC L/Rch Power Down (default)
// 1: Normal Operation
#define AK4558_RSTN (1u)
// RSTN: Internal Timing Reset
// 0: Reset Register values are not reset.
// 1: Normal Operation (default)


// PLL Control register
#define AK4558_PLL_CTRL 0X01
// D4 D3 D2 D1 D0
// PLL3 PLL2 PLL1 PLL0 PMPLL
#define AK4558_PLL3 (1u<<4)
#define AK4558_PLL2 (1u<<3)
#define AK4558_PLL1 (1u<<2)
#define AK4558_PLL0 (1u<<1)
// PLL3-0: PLL Reference Clock Select (Table 16)
// Default: “0010” (BICK pin=64fs)
#define AK4558_PMPLL (1u)
// PMPLL: PLL Power Management
// 0: EXT Mode and Power down (default)
// 1: PLL Mode and Power up


// DAC TDM register
#define AK4558_DAC_TDM 0X02
// D1 D0
// SDS1 SDS0
#define AK4558_SDS1 (1u<<1)
#define AK4558_SDS0 (1u)
// SDS1-0: DAC TDM Data Select (Table 24)
// Default: “00”


// Control 1 register
#define AK4558_CTRL_1 0X03
// D7 D6 D5 D4 D3 D2 D1 D0
// TDM1 TDM0 DIF2 DIF1 DIF0 ATS1 ATS0 SMUTE
#define AK4558_TDM1 (1u<<7)
#define AK4558_TDM0 (1u<<6)
// TDM1-0: TDM Format Select (Table 23, Table 25, Table 26)
// Default: “00” (Stereo Mode)
#define AK4558_DIF2 (1u<<5)
#define AK4558_DIF1 (1u<<4)
#define AK4558_DIF0 (1u<<3)
// DIF2-0: Audio Interface Format Mode Select (Table 23)
// Default: “111” (32bit I2S)
#define AK4558_ATS1 (1u<<2)
#define AK4558_ATS0 (1u<<1)
// ATS1-0: Transition Time Setting of Digital Attenuator (Table 31)
// Default: “00”
#define AK4558_SMUTE (1u)
// SMUTE: Soft Mute Enable
// 0: Normal Operation (default)
// 1: All DAC outputs are soft muted.


// Control 2 register
#define AK4558_CTRL_2 0X04
// D4 D3 D2 D1 D0
// MCKS1 MCKS0 DFS1 DFS0 ACKS
#define AK4558_MCKS1 (1u<<4)
#define AK4558_MCKS0 (1u<<3)
// MCKS1-0: Master Clock Input Frequency Select (Table 9, follows):
// MCKS1 MCKS0 NSM DSM QSM
// 0 0 256fs 256fs 128fs
// 0 1 384fs 256fs 128fs
// 1 0 512fs 256fs 128fs (default)
// 1 1 768fs 256fs 128fs
#define AK4558_DFS1 (1u<<2)
#define AK4558_DFS0 (1u<<1)
// DFS1-0: Sampling Speed Control (Table 8)
// The setting of DFS1-0 bits is ignored when ACKS bit =“1”.
#define AK4558_ACKS (1u)
// ACKS: Automatic Clock Recognition Mode
// 0: Disable, Manual Setting Mode (default)
// 1: Enable, Auto Setting Mode
// When ACKS bit = “1”, master clock frequency is detected automatically. In this case, the setting of
// DFS1-0 bits is ignored. When ACKS bit = “0”, DFS1-0 bits set the sampling speed mode. The MCKI
// frequency of each mode is detected automatically.


// Mode Control register
#define AK4558_MODE_CTRL 0X05
// D6 D5 D4 D3 D2 D1 D0
// FS3 FS2 FS1 FS0 BCKO1 BCKO0 LOPS
#define AK4558_FS3 (1u<<6)
#define AK4558_FS2 (1u<<5)
#define AK4558_FS1 (1u<<4)
#define AK4558_FS0 (1u<<3)
// FS3-0: Sampling Frequency (Table 17, Table 18)
// Default: “0101”
#define AK4558_BCKO1 (1u<<2)
#define AK4558_BCKO0 (1u<<1)
// BCKO1-0: BICK Output Frequency Setting in Master Mode (Table 21)
// Default: “01” (64fs)
#define AK4558_LOPS (1u<<0)
// LOPS: Power-save Mode of LOUT/ROUT
// 0: Normal Operation (default)
// 1: Power-save Mode


// Filter Setting register
#define AK4558_FLTR_SET 0x06
// D7 D6 D5 D4 D3 D2 D1 D0
// FIRDA2 FIRDA1 FIRDA0 SLDA SDDA SSLOW DEM1 DEM0
#define AK4558_FIRDA2 (1u<<7)
#define AK4558_FIRDA1 (1u<<6)
#define AK4558_FIRDA0 (1u<<5)
// FIRDA2-0: Out band noise eliminating Filters Setting (Table 32)
// default: “001” (48kHz)
#define AK4558_SLDA (1u<<4)
// SLDA: DAC Slow Roll-off Filter Enable (Table 28)
// 0: Sharp Roll-off filter (default)
// 1: Slow Roll-off Filter
#define AK4558_SDDA (1u<<3)
// SDDA: DAC Short delay Filter Enable (Table 28)
// 0: Normal filter
// 1: Short delay Filter (default)
#define AK4558_SSLOW (1u<<2)
// SSLOW: Digital Filter Bypass Mode Enable
// 0: Roll-off filter (default)
// 1: Super Slow Roll-off Mode
#define AK4558_DEM1 (1u<<1)
#define AK4558_DEM0 (1u)
// DEM1-0: De-emphasis response control for DAC (Table 22)
// Default: “01”, OFF


// HPF Enable, Filter Setting
#define AK4558_HPF_EN_FLTR_SET 0x07
// D3 D2 D1 D0
// SLAD SDAD HPFER HPFEL
#define AK4558_SLAD (1u<<3)
// SLAD: ADC Slow Roll-off Filter Enable (Table 27)
// 0: Sharp Roll-off filter (default)
// 1: Slow Roll-off Filter
#define AK4558_SDAD (1u<<2)
// SDAD: ADC Short delay Filter Enable (Table 27)
// 0: Normal filter
// 1: Short delay Filter (default)
#define AK4558_HPFER (1u<<1)
#define AK4558_HPFEL (1u)
// HPFEL/R: ADC HPF L/Rch Setting
// 0: HPF L/Rch OFF
// 1: HPF L/Rch ON (default)


// LOUT Volume Control register
#define AK4558_LOUT_VOL 0X08
// D7 D6 D5 D4 D3 D2 D1 D0
// ATL7 ATL6 ATL5 ATL4 ATL3 ATL2 ATL1 ATL0
//
// ATL 7-0: Attenuation Level (Table 30)
// Default:FF(0dB)


// ROUT Volume Control register
#define AK4558_ROUT_VOL 0X09
// D7 D6 D5 D4 D3 D2 D1 D0
// ATR7 ATR6 ATR5 ATR4 ATR3 ATR2 ATR1 ATR0
//
// ATR 7-0: Attenuation Level (Table 30)
// Default:FF(0dB)

class AudioControlAK4558 : public AudioControl
{
public:
bool enable(void);
bool disable(void) { return false; }
bool volume(float n) { return false; }
bool inputLevel(float n) { return false; }
bool inputSelect(int n) { return false; }
protected:
unsigned int registers[10];
void readInitConfig(void);
bool write(unsigned int reg, unsigned int val);
};

#endif

+ 1
- 0
keywords.txt Wyświetl plik

@@ -9,6 +9,7 @@ AudioOutputPWM KEYWORD2
AudioControlSGTL5000 KEYWORD2
AudioControlWM8731 KEYWORD2
AudioControlWM8731master KEYWORD2
AudioControlAK4558 KEYWORD2
AudioMemory KEYWORD2

AudioAnalyzeFFT256 KEYWORD2

Ładowanie…
Anuluj
Zapisz