Przeglądaj źródła

Merge pull request #147 from MickMad/master

Add AK4558 CODEC support / Merge branch 'master' of https://github.com/MickMad/Audio
dds
Paul Stoffregen 9 lat temu
rodzic
commit
f43ba4ce51
7 zmienionych plików z 702 dodań i 0 usunięć
  1. +1
    -0
      Audio.h
  2. +301
    -0
      control_ak4558.cpp
  3. +255
    -0
      control_ak4558.h
  4. +32
    -0
      examples/HardwareTesting/AK4558/PassthroughTest/PassthroughTest.ino
  5. +47
    -0
      examples/HardwareTesting/AK4558/SineOutTest/SineOutTest.ino
  6. +59
    -0
      gui/index.html
  7. +7
    -0
      keywords.txt

+ 1
- 0
Audio.h Wyświetl plik

@@ -66,6 +66,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"

+ 301
- 0
control_ak4558.cpp Wyświetl plik

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

void AudioControlAK4558::initConfig(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
uint8_t 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], BIN);
#endif
}
}

void AudioControlAK4558::readConfig(void)
{
// reads registers values
uint8_t n = 0;
uint8_t c = 0;
Wire.requestFrom(AK4558_I2C_ADDR, 10);
while(Wire.available()) {
Serial.print("Register ");
Serial.print(n++);
Serial.print(" = ");
c = Wire.read();
Serial.println(c, BIN);
}
}

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

bool AudioControlAK4558::enableIn(void)
{
// ADC setup (datasheet page 74
#if AK4558_SERIAL_DEBUG > 0
Serial.println("AK4558: Enable ADC");
#endif

// ignore this, leaving default values - ADC: Set up the de-emphasis filter (Addr = 07H).
registers[AK4558_PWR_MNGT] |= AK4558_PMADR | AK4558_PMADL;
write(AK4558_PWR_MNGT, 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_MODE_CTRL, 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_PWR_MNGT, 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_MODE_CTRL, 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)
{
#if AK4558_SERIAL_DEBUG > 0
Serial.println("AK4558: Enable device");
#endif
// Power Up and Reset
// Clock Setup (datasheet page 72)
pinMode(PIN_PDN, OUTPUT);
digitalWrite(0, LOW);
delay(1);
digitalWrite(0, HIGH);
// After Power Up: PDN pin “L” → “H”
// “L” time of 150ns or more is needed to reset the AK4558.
delay(20);
#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();
initConfig();
// 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;
#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)
registers[AK4558_CTRL_2] &= ~AK4558_MCKS1;
#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;
// 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
// 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.
#if AK4558_SERIAL_DEBUG > 0
Serial.println("AK4558: Enable device - Done");
#endif
return true;
}

bool AudioControlAK4558::disableIn(void)
{
// ADC power-down (datasheet page 74
registers[AK4558_PWR_MNGT] &= ~AK4558_PMADR | ~AK4558_PMADL;
write(AK4558_PWR_MNGT, 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_MODE_CTRL, 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”
registers[AK4558_PWR_MNGT] &= ~AK4558_PMDAR | ~AK4558_PMDAL;
write(AK4558_PWR_MNGT, 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 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_MODE_CTRL, 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 outputs of the LOUT and ROUT pins fall to “L”.
#if AK4558_SERIAL_DEBUG > 0
Serial.println("AK4558: Disable DAC - Done");
#endif
return true;
}

uint8_t AudioControlAK4558::convertVolume(float vol)
{
// Convert float (range 0.0-1.0) to unsigned char (range 0x00-0xFF)
uint8_t temp = ((uint32_t)vol)>>22;
return temp;
}

bool AudioControlAK4558::volume(float n)
{
// Set DAC output volume
uint8_t vol = convertVolume(n);
registers[AK4558_LOUT_VOL] = vol;
registers[AK4558_ROUT_VOL] = vol;
Wire.beginTransmission(AK4558_I2C_ADDR);
Wire.write(AK4558_LOUT_VOL);
Wire.write(registers[AK4558_LOUT_VOL]);
Wire.write(registers[AK4558_ROUT_VOL]);
#if AK4558_SERIAL_DEBUG > 0
Serial.print("AK4558: LOUT_VOL set to ");
Serial.println(registers[AK4558_LOUT_VOL], BIN);
Serial.print("AK4558: ROUT_VOL set to ");
Serial.println(registers[AK4558_ROUT_VOL], BIN);
#endif
return (Wire.endTransmission(true)==0);
}

bool AudioControlAK4558::volumeLeft(float n)
{
// Set DAC left output volume
uint8_t vol = convertVolume(n);
registers[AK4558_LOUT_VOL] = vol;
bool ret = write(AK4558_LOUT_VOL, registers[AK4558_LOUT_VOL]);
#if AK4558_SERIAL_DEBUG > 0
Serial.print("AK4558: LOUT_VOL set to ");
Serial.println(registers[AK4558_LOUT_VOL], BIN);
#endif
return ret;
}

bool AudioControlAK4558::volumeRight(float n)
{
// Set DAC right output volume
uint8_t vol = convertVolume(n);
registers[AK4558_ROUT_VOL] = vol;
bool ret = write(AK4558_ROUT_VOL, registers[AK4558_ROUT_VOL]);
#if AK4558_SERIAL_DEBUG > 0
Serial.print("AK4558: ROUT_VOL set to ");
Serial.println(registers[AK4558_ROUT_VOL], BIN);
#endif
return ret;
}

+ 255
- 0
control_ak4558.h Wyświetl plik

@@ -0,0 +1,255 @@
/*
* 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"

#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
// 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); //enables the CODEC, does not power up ADC nor DAC (use enableIn() and enableOut() for selective power up)
bool enableIn(void); //powers up ADC
bool enableOut(void); //powers up DAC
bool disable(void) { return (disableIn()&&disableOut()); } //powers down ADC/DAC
bool disableIn(void); //powers down ADC
bool disableOut(void); //powers down DAC
bool volume(float n); //sets LOUT/ROUT volume to n (range 0.0 - 1.0)
bool volumeLeft(float n); //sets LOUT volume to n (range 0.0 - 1.0)
bool volumeRight(float n); //sets ROUT volume to n (range 0.0 - 1.0)
bool inputLevel(float n) { return false; } //not supported by AK4558
bool inputSelect(int n) { return false; } //sets inputs to mono left, mono right, stereo (default stereo), not yet implemented
private:
uint8_t registers[10];
void initConfig(void);
void readConfig(void);
bool write(unsigned int reg, unsigned int val);
uint8_t convertVolume(float vol);
};

#endif

+ 32
- 0
examples/HardwareTesting/AK4558/PassthroughTest/PassthroughTest.ino Wyświetl plik

@@ -0,0 +1,32 @@
/*
* AK4558 Passthrough Test
* 2015 by Michele Perla
*
* A simple hardware test which receives audio from the HiFi Audio CODEC Module
* LIN/RIN pins and send it to the LOUT/ROUT pins
*
*/

#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

AudioInputI2S i2s1;
AudioOutputI2S i2s2;
AudioConnection patchCord1(i2s1, 0, i2s2, 0);
AudioConnection patchCord2(i2s1, 1, i2s2, 1);
AudioControlAK4558 ak4558;

void setup() {
// put your setup code here, to run once:
AudioMemory(12);
while (!Serial);
ak4558.enable();
ak4558.enableIn();
ak4558.enableOut();
}

void loop() {
}

+ 47
- 0
examples/HardwareTesting/AK4558/SineOutTest/SineOutTest.ino Wyświetl plik

@@ -0,0 +1,47 @@
/*
* AK4558 Sine Out Test
* 2015 by Michele Perla
*
* A simple hardware test which sends two 440 Hz sinewaves to the
* LOUT/ROUT pins of the HiFi Audio CODEC Module. One of the waves
* is out-of-phase by 90° with the other.
*
*/

#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

AudioSynthWaveformSine sine2;
AudioSynthWaveformSine sine1;
AudioOutputI2S i2s1;
AudioConnection patchCord1(sine2, 0, i2s1, 0);
AudioConnection patchCord2(sine1, 0, i2s1, 1);
AudioControlAK4558 ak4558;

int phase = 0;

void setup() {
// put your setup code here, to run once:
AudioMemory(12);
while (!Serial);
ak4558.enable();
ak4558.enableOut();
AudioNoInterrupts();
sine1.frequency(440);
sine2.frequency(440);
sine1.amplitude(1.0);
sine2.amplitude(1.0);
AudioInterrupts();
}

void loop() {
phase+=10;
if (phase==360) phase=0;
AudioNoInterrupts();
sine2.phase(phase);
AudioInterrupts();
delay(250);
}

+ 59
- 0
gui/index.html Wyświetl plik

@@ -2792,5 +2792,64 @@ value frequency
</div>
</script>

<script type="text/x-red" data-help-name="AudioControlAK4558">
<h3>Summary</h3>
<p>Control the AK4558 chip on the <a href="https://hackaday.io/project/8567-hifi-audio-codec-module" target="_blank">HiFi Audio CODEC Module</a>
in slave mode, where the Teensy controls all I2S timing.</p>
<h3>Audio Connections</h3>
<p>This object has no audio inputs or outputs. Separate I2S objects
are used to send and receive audio data.
</p>
<h3>Functions</h3>
<p class=func><span class=keyword>enable</span>();</p>
<p class=desc>Enables the CODEC to work with 44.1 KHz - 16 bit data. This function does not enable the ADC/DAC modules.
</p>
<p class=func><span class=keyword>enableIn</span>();</p>
<p class=desc>Enables the ADC module.
</p>
<p class=func><span class=keyword>enableOut</span>();</p>
<p class=desc>Enables the DAC module.
</p>
<p class=func><span class=keyword>disable</span>();</p>
<p class=desc>Disables the ADC and the DAC modules.
</p>
<p class=func><span class=keyword>disableIn</span>();</p>
<p class=desc>Disable the ADC module.
</p>
<p class=func><span class=keyword>disableOut</span>();</p>
<p class=desc>Disable the DAC module.
</p>
<p class=func><span class=keyword>volume</span>(level);</p>
<p class=desc>Accepts a float in range 0.0-1.0 and sets the line output volume accordingly.
</p>
<p class=func><span class=keyword>volumeLeft</span>(level);</p>
<p class=desc>Accepts a float in range 0.0-1.0 and sets the left line output volume accordingly.
</p>
<p class=func><span class=keyword>volumeRight</span>(level);</p>
<p class=desc>Accepts a float in range 0.0-1.0 and sets the right line output volume accordingly.
</p>
<p class=func><span class=keyword>inputLevel</span>(level);</p>
<p class=desc>NOT SUPPORTED BY THE AK4558
</p>
<p class=func><span class=keyword>inputSelect</span>(input);</p>
<p class=desc>not implemented yet
</p>
<h3>Examples</h3>
<p class=exam>File &gt; Examples &gt; Audio &gt; HardwareTesting &gt; AK4558 &gt; PassthroughTest
</p>
<p class=exam>File &gt; Examples &gt; Audio &gt; HardwareTesting &gt; AK4558 &gt; SineOutTest
</p>
<h3>Notes</h3>
<p>TODO: Implement inputSelect() function to enable mono left, mono right, stereo operation.</p>
<p>TODO: Implement ADC and DAC filters control.</p>
<p>TODO: Implement DAC level attenuator attack rate modifier.</p>
</script>
<script type="text/x-red" data-template-name="AudioControlWM8731master">
<div class="form-row">
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
<input type="text" id="node-input-name" placeholder="Name">
</div>
</script>

</body>
</html>

+ 7
- 0
keywords.txt Wyświetl plik

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

AudioAnalyzeFFT256 KEYWORD2
@@ -74,8 +75,14 @@ trigger KEYWORD2
length KEYWORD2
threshold KEYWORD2
enable KEYWORD2
enableIn KEYWORD2
enableOut KEYWORD2
disable KEYWORD2
disableIn KEYWORD2
disableOut KEYWORD2
volume KEYWORD2
volumeLeft KEYWORD2
volumeRight KEYWORD2
attack KEYWORD2
hold KEYWORD2
decay KEYWORD2

Ładowanie…
Anuluj
Zapisz