Why doesn't my SGTL5000 respond to I2C write commands from FRDM-K22F?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Why doesn't my SGTL5000 respond to I2C write commands from FRDM-K22F?

Jump to solution
2,241 Views
donturner
Contributor III

I have a FRDM-K22F wired to a Teensy Audio Shield which is essentially an SGTL5000.

 

Whenever I attempt an I2C write I get a strange result - instead of getting an ACK I get a NACK. Checking with a logic analyser I can see that the I2C SDA line is pulled down only halfway. See the attached screenshot showing the analog output of Channel 2 which is I2C SDA - the problem point is marked at 1.902 V. What could be causing this strange behaviour?

 

158183_158183.pngScreen Shot 2016-08-09 at 22.22.16.png

I'm pretty sure it has to do with my K22F board configuration - perhaps I need to disable a pull up resistor somewhere?

Labels (1)
Tags (3)
1 Solution
1,480 Views
michael_galda
NXP Employee
NXP Employee

No, if you see the MCLK clock output, you are OK.

Regarding the I2C signal levels.

What i2C port/pins are used, are there external pull-ups used?. Is the Port PCR set to Open Drain mode?

View solution in original post

6 Replies
1,480 Views
michael_galda
NXP Employee
NXP Employee

Hi Don,

One of the reasons why the SGTL5000 is not responding to I2C commands may that the SGTL5000 is not running, i.e it doesn't have master clock present (MCLK). Are you generating the MCLK signal (lets say 12.288MHz) by K22. This signal provides a main clocking reference for codec.

- I don't see any crystal on the teense board (please check) so the clock must be provided externally.

This is just one of the reasons,

THanks,

Michael

0 Kudos
1,480 Views
donturner
Contributor III

Thanks Michael. You might be on to something there. I am generating a MCLK signal at 12.288MHz but the analog output looks strange:

Screen Shot 2016-08-10 at 09.41.16.png

See how it alternates between 2 ranges: 1.38V-1.62V and 1.63V-1.89V.  I wonder if that could cause the SGTL5000 to behave erratically.

Here's the code I'm using to generate MCLK:

// Initialise the SAI/I2S module

  g_sai_tx_config.protocol = kSAI_BusI2S;

  g_sai_tx_config.syncMode = kSAI_ModeAsync;

  g_sai_tx_config.mclkOutputEnable = true;

  g_sai_tx_config.mclkSource = kSAI_MclkSourceSysclk;

  g_sai_tx_config.bclkSource = kSAI_BclkSourceMclkDiv;

  g_sai_tx_config.masterSlave = kSAI_Master;

  SAI_TxInit(I2S0, &g_sai_tx_config);

// Set the format of the data

  g_sai_tx_format.bitWidth = kSAI_WordWidth16bits;

  g_sai_tx_format.channel = 0; // Taken from Kinetis Serial Audio Training P17

  g_sai_tx_format.sampleRate_Hz = kSAI_SampleRate48KHz;

  g_sai_tx_format.masterClockHz = 256 * kSAI_SampleRate48KHz; //12.288MHz

  g_sai_tx_format.stereo = kSAI_Stereo;

  g_sai_tx_format.protocol = kSAI_BusI2S;

  SAI_TxSetFormat(I2S0, &g_sai_tx_format, CLOCK_GetCoreSysClkFreq(), CLOCK_GetCoreSysClkFreq());

Am I doing something wrong in the MCLK generation?

0 Kudos
1,481 Views
michael_galda
NXP Employee
NXP Employee

No, if you see the MCLK clock output, you are OK.

Regarding the I2C signal levels.

What i2C port/pins are used, are there external pull-ups used?. Is the Port PCR set to Open Drain mode?

1,480 Views
donturner
Contributor III

"Is the Port PCR set to Open Drain mode?" I don't think so, and I think this is the problem.

I'm using PTB0 and PTB1 for SCL and SDA respectively. Here's my initialisation code:

// Initialise the pins used for I2C

  CLOCK_EnableClock(kCLOCK_PortB);

// I2C0_SCL - I2C Clock on PTB0

  PORT_SetPinMux(PORTB, 0u, kPORT_MuxAlt2);

// I2C0_SDA - I2C Data on PTB1

  PORT_SetPinMux(PORTB, 1u, kPORT_MuxAlt2);

I think I just need to add the following:

PORT_HAL_SetOpenDrainCmd(PORTB, 0u, true);

PORT_HAL_SetOpenDrainCmd(PORTB, 1u, true);

I'll test this in a few hours when I'm back with my MCU to verify. This is probably a stupid question but without open drain enabled, why isn't the SGTL5000 able to pull the SDA line to 0V (GND)?

Thanks very much for your help - really appreciate it!

0 Kudos
1,480 Views
donturner
Contributor III

It's working now. Here's the full code I used (I'm using KSDK 2.0 so some functions had to be updated):

  #include "fsl_i2c.h"

  // Configure I2C GPIO pins: SCL on PTB0, SDA on PTB1

  #define I2C_PORT PORTB

  #define I2C_SCL_PIN 0U

  #define I2C_SDA_PIN 1U

  port_pin_config_t pinConfig = {0};

  pinConfig.pullSelect = kPORT_PullUp;

  pinConfig.openDrainEnable = kPORT_OpenDrainEnable;

  PORT_SetPinConfig(I2C_PORT, I2C_SCL_PIN, &pinConfig);

  PORT_SetPinConfig(I2C_PORT, I2C_SDA_PIN, &pinConfig);

Thanks very much for your help.

0 Kudos
1,480 Views
michael_galda
NXP Employee
NXP Employee

OK, thanks for that update. / welcome!

To your question, why the I2C slave device (SGTL) is unable to pull the line low to 0V is easy answer:

- Where the pin is in normal (push-pull) configuration, It actively drives both 1/0 on the output, so if there is a log.1 on the pin output, there is a strong 3V3 signal driven - so the external device is unable to pull it down, and two outputs are fighting resulting to the middle levels.

In the Open drain mode, only 0 is actively driven onto the output, while the 1 (3V3) is managed by external pull-up, which represents very weak signal, which can be pulled low easily by the external device.

So this is it.

/MG