SRC4392 + ESP32

Hi All,

I am working on a DSP based on ADAU1466 + SRC4392, controlled by an ESP32 through SPI interface.

My programming skills are not so great, so i where wondering if anyone have a sketch they would be willing to share with me?

Currently i have tried this code which does not seem to do the trick;
Code:
#include <Arduino.h>
#include "PCF8575.h"
#include "SPI.h"

unsigned char audioSRCCom(unsigned char address, unsigned char data, bool read = false);
void audioSRCWrite(unsigned char address, unsigned char data);

unsigned char errorCode;

#define SPI_SRC   4
#define SPI_ADAU  5

#define AUDIO_SRC_R14_INTMASK	0xF4	// CRC, parity, validity, bip encoding, and dir unlock unmasked
#define AUDIO_SRC_R18_INTMODE	0xAA	// interrupt mode to level change
#define AUDIO_SRC_R19_INTMODE	0xAA

PCF8575 exp1(0x21);
PCF8575 rexp(0x22);

const SPISettings settingsA(1000000, MSBFIRST, SPI_MODE3); // Store SPI transaction information to settingsA

uint8_t audioSRCCom(unsigned char address, unsigned char data, bool read) {
  uint8_t Response = 0x00; // Set response to 0
	digitalWrite(SPI_SRC, LOW);
  SPI.beginTransaction(settingsA);
  SPI.transfer(address);
  SPI.transfer(0);
  SPI.transfer(data);
  SPI.endTransaction(); 
  digitalWrite(SPI_SRC, HIGH);
  if (!read) return Response; // End if only write session
  delay(1);
  digitalWrite(SPI_SRC, LOW);
  SPI.beginTransaction(settingsA);
  Response = SPI.transfer(0xFF);
  SPI.endTransaction(); 
  digitalWrite(SPI_SRC, HIGH);
  return Response;
}

void src_statuses () {
  Serial.print("SRC Interupt Status: ");
  Serial.println(audioSRCCom(0x02, 0x01, true));
  Serial.print("SRC Ready Status: ");
  Serial.println(audioSRCCom(0x0A, 0x10, true));
  Serial.print("SRC Ratio Status: ");
  Serial.println(audioSRCCom(0x0A, 0x20, true));
}

void initiate_src4392 () {
  src_statuses();
  audioSRCCom(0x7f, 0x00); // Initial write to page register, selecting page 0
  audioSRCCom(0x01, 0x80); // Software reset
  audioSRCCom(0x03, 0x31); // Port A format I2S, slave mode, src->porta
  audioSRCCom(0x04, 0x01); // Port A clock to MCLK/256 (48k)
  audioSRCCom(0x05, 0x41); // Port B format I2S, slave mode, mute output (port is not used)
  audioSRCCom(0x06, 0x01); // Port B clock to MCLK/256 (48k)
  audioSRCCom(0x08, 0x31); // Bypass Mux RX1, AESMUX BYMUX, LDMUX BPMUX, Enable AES and TX
  audioSRCCom(0x0D, 0x08); // DIR reference clock = MCLK
  audioSRCCom(0x0E, 0x08); // Automatic DIR-mute for loss of lock
  audioSRCCom(0x0F, 0x12); // Registers 0F, 10 and 11; PLL1 configuration. Values from datasheet: P=1, J=8, D=0
  audioSRCCom(0x10, 0); // Registers 0F, 10 and 11; PLL1 configuration. Values from datasheet: P=1, J=8, D=0
  audioSRCCom(0x11, 0); // Registers 0F, 10 and 11; PLL1 configuration. Values from datasheet: P=1, J=8, D=0
  audioSRCCom(0x16, 0xF4); // CRC, parity, validity, bip encoding, and dir unlock unmasked
  audioSRCCom(0x18, 0xAA);	// interrupt mode to level change
  audioSRCCom(0x19, 0xAA);	// interrupt mode to level change
  audioSRCCom(0x2d, 0x42); // Port B as input, MCLK as Ref, Mute Disabled, Volume tracking leftch.
  audioSRCCom(0x30, 0x07); // Set left channel volume -3.5dB
  audioSRCCom(0x31, 0x07); // Set right channel volume -3.5dB
  audioSRCCom(0x01, 0x3f); // Activates the chip, remove soft RST, Enable all.
  delay(10);
  src_statuses();
}

void setup() {
  delay(1000);              // 1 second startup delay
  Serial.begin(9600);    // Initialize the USB serial port for debug
  pinMode(SPI_SRC, OUTPUT); // src4392 CS pin
  pinMode(SPI_ADAU, OUTPUT); // adau1466 CS pin
  digitalWrite(SPI_SRC, HIGH); // Pull SRC4392 CS pin HIGH
  digitalWrite(SPI_ADAU, HIGH); // Pull ADAU1466 CS pin HIGH
  exp1.pinMode(P5, OUTPUT); // ADAU1466 Reset pin
  exp1.pinMode(P6, OUTPUT); // SRC4392 Reset pin - H/W Linked to ADAU1466 Reset, if ADAU1466 RST is low, SRC4392 will be low for atleast 300ms after ADAU1466 turns high
  exp1.begin();
  exp1.digitalWrite(P5, HIGH);
  exp1.digitalWrite(P6, HIGH);
  delay(10);
  SPI.begin();
}

void loop() {
  initiate_src4392();
  delay(5000);
}

Serial response from the sketch is:
SRC Interupt Status: 0
SRC Ready Status: 0
SRC Ratio Status: 0
SRC Interupt Status: 0
SRC Ready Status: 0
SRC Ratio Status: 0

Physically checked that hardware rst pin is 3.3v, and i am can program ADAU1466 through same spi interface

Schematic for the SRC chip:
Screenshot by Lightshot
 
Last edited:
Can you write the registers while the SRC4392 is in software reset? I've checked what I do in my Verilog code and the only suspicious difference I found is that I first switch off the software reset and then write the registers.

parameter [511:0] src4392spidata = 512'h0100390031004100000000000000081821CB02000000000000000000000000000000000000000000000000000000010400000000000000000000000000000000;
// These bits have to be shifted into the SRC4392 from high to low!
// Address 01, value 39: Sample rate converter on, DIR off, DIT off,
// port B on, port A on, general enable on, reset off.
// address 03, value 31: port A in slave mode, outputs signal from SRC,
// sound not muted, 24 bits I2S
// address 05, value 41: port B in slave mode, output off, 24 bits I2S
// addresses 0B and 0C, value 00: interrupts off
// address 0D, value 08: RXCLK set to MCLK, input 0 to DIR. Hardly relevant,
// as I don't use the DIR anyway.
// address 0E, value 18: DIR muted when DIR gets unlocked,
// clock of PLL2 not divided, RXCKO-output off, PLL2 free running
// when not locked
// addresses 0F...11, values 21CB02: PLL1 to P = 2, J = 7, D = 2818, as
// recommended for a 27 MHz reference clock
// address 1B, value 00: GPO1 off
// address 1C, value 00: GPO2 off
// address 1D, value 00: GPO3 off
// address 1E, value 00: GPO4 off
// adresses 1F...2C: read only, so written values get ignored.
// address 2D, value 01: SRC converts data from port B, uses the MCLK as
// reference, sound not muted, left and right volumes separately controllable
// address 2E, value 04: de-emphasis off, no decimation filtering, FIFO
// length of 64 words
// address 2F, value 00: 24 bits output words
// adresses 30 and 31, values 00: output attenuators set to 0 dB
// Rest is nonsense.
 
Last edited: