cancel
Showing results for 
Search instead for 
Did you mean: 

Data Format I2S PCM5102A DAC Synthesizer

Stipe
Associate II

Hi guys,

I have successfully connected a PCM5102 DAC to my STM32F401CCU6 black pill board. The CubeMX Setup with DMA and I2C works fine. I have interrupt routines and a double buffer which create samples. Electrically, I connected 3.3V supply (from STM32 VCC 3.3 Pin). I configured the 4 config pins so that the DAC works correctly. There is a STLinkV2 connected to the STM32 board, which is also the power supply.

My Problem is that the sine wave is completely "swapped", if I try to set a signed value.

My settings (CUBE IDE):

 hi2s2.Instance = SPI2;
hi2s2.Init.Mode = I2S_MODE_MASTER_TX;
hi2s2.Init.Standard = I2S_STANDARD_PHILIPS;
hi2s2.Init.DataFormat = I2S_DATAFORMAT_16B;
hi2s2.Init.MCLKOutput = I2S_MCLKOUTPUT_DISABLE;
hi2s2.Init.AudioFreq = I2S_AUDIOFREQ_48K;
hi2s2.Init.CPOL = I2S_CPOL_LOW;
hi2s2.Init.ClockSource = I2S_CLOCK_PLL;
hi2s2.Init.FullDuplexMode = I2S_FULLDUPLEXMODE_DISABLE;

My synth code looks like this:

int32_t sample = s * 0.6 * 0x7FFF - 0x10000;
uint16_t sampleL = (uint16_t) sample;
outBufPtr[i++] = sampleL;
outBufPtr[i++] = sampleL;

 

I have tried several things, scaling to signed int16 and unsigned int16. Only the above scaling is working for me:

s * 0x7FFF - 0x10000

I wonder, how the data format really should look like? Endianness seems ok. Everybody say. it should be unsigned 16 Bit, but why doesn't this work?

There is another problem. The output is strongly clipping, when the volume is near 1. So I have to scale it down, for ex. 0.6 like in the example. The output peak to peak voltage also seems to exceed the 3.3 V power supply in this case. How is this possible?

Cheers, Stipe

1 REPLY 1
Stipe
Associate II

Edit: The clipping problem seems to have the cause of the shitty bread board connections, thats all. The 5102 wants a really stable power supply.

I also recognized that I exceeded the I2C Clock limit of 50MHz like issued in the datasheet, so I divided my clock by 2 which is now 38.4 MHz, which results in high accuracy 48kHz.

The numeric issue is still unclear to me. I thought I simple send an unsigned short (uint16) to the dac, but it is not satisfied. Setting an other standard as I2S_STANDARD_PHILIPS dows not work at all.