[Solved] Incompatible codec register settings in control_cs4272.cpp

WeTec

Member
I have a custom board with a CS4272 codec which is configured as clock master. A 24.576 MHz crystal is connected to generate the master clock signal.
No problem for now because the Teensy Audio Library provides AudioOutputI2Sslave and AudioInputI2Sslave objects to work as I2S slave.
The AudioControlCS4272 object from the library is supposed to configure the codec as clock master with 48 kHz sample rate. The Teensy Audio Library uses 44.1 kHz by default. To use 48 kHz sample rate I set the following line (58) in AudioStreaming.h:
C++:
#define AUDIO_SAMPLE_RATE_EXACT 48000.0f

I had trouble to get the codec running with the AudioControlCS4272 object from the library. There was no autput signal at all and the LRCLK signal was 32kHz instead of the expected 48kHz.

A closer look in control_cs4272.cpp reveals the following:
  • The Ratio Select bits in the Mode Control 1 register are set to 0x3. This seems correct according to table 8 in the CS4272 Datasheet.
    External Crystal Used, MCLK=Output; MCLK/LRCK = 512; 24.576 MHz / 512 = 48 kHz. Ratio0 Bit is 1 but "d indicates that any value may written", so 0x3 should be equal to 0x2 in this case.
    But the measured 32 kHz at LRCLK pin leads to MCLK/LRCK = 768 as in table 9.
    I'm not sure why the divider is set to 768 because I used an external crystal and the values in table 8 should be used.
  • The DAC Digital Interface Format bits in the Mode Control 1 register are set to 0. This is the default setting of the codec and selects the Left Justified format for the DAC. The Teensy Audio Library uses the I2S format (according to register settings in control_sgtl5000.cpp).
  • The ADC Digital Interface Format bit in the ADC Control register is untouched and this also selects the Left Justified format for the ADC.
However, I got my board up and running with the following changes in the control_cs4272.cpp file (lines 116 and following):

C++:
    // Set ratio select for MCLK=512*LRCLK (BCLK = 64*LRCLK), master mode and I2S format
    write(CS4272_MODE_CONTROL, CS4272_MC_RATIO_SEL(2) | CS4272_MC_MASTER_SLAVE | CS4272_MC_SERIAL_FORMAT(1));
    
    // Set ADC I2S format
    write(CS4272_ADC_CTRL, CS4272_ADC_CTRL_SER_FORMAT);

This is a simple test program to confirm my changes in the library:
C++:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

// GUItool: begin automatically generated code
AudioSynthWaveformSine   sine1;          //xy=376,266
AudioOutputI2Sslave      i2sslave2;      //xy=562,283
AudioConnection          patchCord1(sine1, 0, i2sslave2, 0);
AudioControlCS4272       CS4272;         //xy=580,165
// GUItool: end automatically generated code

void setup() {
  AudioMemory(20);
  CS4272.enable();
  sine1.frequency(1000.0);
  sine1.amplitude(0.8);
}

void loop() {
  // put your main code here, to run repeatedly:
}

Teensy Version 1.58 and 0.59.3
 
Back
Top