I2C issues with STM32F303K8

Hey!

I’ve run into an issue with getting I2C working on my Nucleo STM32F303K8. No matter what I try, I just cannot get my board to output a clock pulse.

I don’t have it connected to a device just yet, I wanted to see if I could first see the clock pulses on my oscilloscope. All I see is the both the SCL and the SDA lines pulled low. I have a serial decoder on my scope and was hoping to see the data being output.

Here is what I’ve tried so far:

  • Made a clean build
  • Tried different version of Mbed OS. Versions 6.5 and 6.6
  • I built a small project in STM32CubeIDE and managed to get the device working using that code. This proves that it’s not something broken inside the chip, that I had the rights pins connected and could see it on my scope. Using that code isn’t an option, I’m trying to add something to an existing project.
  • In the Nucleo board docs (Link here), it mentions two jumpers - SB16 and SB18 which are by default bridged. These connect D5 to A5 and D4 and A4 so that the board can be Arduino Nano compatible. It mentions that you need to set the PA5 and PA6 (D5 and D4) as input floating. I tried this by setting them up as DigitalIn pins and setting the mode a few different ways - PullUp, NoPullUp, default.
  • Tried the Transfer() function instead of Write()
  • Tried just Read() ing to see if I could just see clock pulses
  • Tried both Start->Write->Stop methods and the Write with address method (See this post for more info)
  • Tried adding 10K pullups to both SCL and SDA lines. Also tried 4.7K pull ups
  • Tried probing A4/A5 instead of D4/D5. I noticed that when the board is unplugged I can probe these pins and notice that A4->D4 and A5->D5 are shorted (See the point about about jumpers)
  • Tried running this at different speeds
  • Had a look at known Limitations on MBed site, nothing listed there under known limitations for this board

Here is the code:
// #define DEVICE_I2C_ASYNCH false // I was curious about this one, set to both true and false to see what it would do

#include "mbed.h"

I2C my_i2c_device(I2C_SDA, I2C_SCL);

const int addr7bit = 0x48;      // 7 bit I2C address

const int addr8bit = 0x48 << 1; // 8bit I2C address, 0x90

int main()

{

    char cmd[2];

    int result;

    my_i2c_device.frequency(400000);  // have tested 100Khz, 400Khz and 1Mhz

    while (1) {

        cmd[0] = 0x01;

        cmd[1] = 0x00;

        my_i2c_device.write(addr8bit, cmd, 2);

        // also tried this method, which I can see in the source code is implemented differently

        // my_i2c_device.start();

        // my_i2c_device.write(0xFF);

        // my_i2c_device.stop();

        ThisThread::sleep_for(1000ms);

        cmd[0] = 0x00;

        my_i2c_device.write(addr8bit, cmd, 1);

        result = my_i2c_device.read(addr8bit, cmd, 2);

        printf("Read result: %d\r\n", result);

        ThisThread::sleep_for(500ms);

        // float tmp = (float((cmd[0] << 8) | cmd[1]) / 256.0); // commenting out, we don't have this sensor connected

        // printf("Temp = %.2f\n", tmp);

    }

}

Details about my setup:

  • Target board: STM32F303K8
  • Machine: Windows 10 Pro
  • Mbed Studio version: 1.3.1, reporting that everything is up to date
  • ST Link firmware was recently updated to latest version
  • Mbed OS version: 6.6
  • Scope: Rigol DS1074 - plenty of bandwidth to view this sort of signal.
  • Device under test: No device, just trying to view the resulting clock pulses on my scope.

It seems there are a few others who have had similar issues in the past, while looking at their post helped me understand the problem a bit better, I couldn’t fully resolve the issue.

Hey guys, I actually figured this out and thought it might be good to share in case anyone else comes across this same issue and needs help. I was stuck on this issue for quite some time today.

Firstly, I made a silly mistake. I had my scope ground hooked up to my breadboard ground line, but didn’t connect the ground of the Nucleo to the breadboard. D’oh!

Secondly, I was on to something about those jumpers but when I tried it I didn’t have the ground hooked up, so naturally this caused a false negative. This STM32 board (and perhaps more/all of the Nucleo-32 boards) have a note in the datasheet about this. If your jumpers SB16 and SB18 are on:

D4 and PA5 must be configured as input floating. D5 and PA6 must be configured as input floating.

Here is some example code of what worked for me. It would be great if a future release of Mbed could maybe somehow get around this issue. Or at least list under board limitations that you can’t use D4/D5 at the same time as A4/A5 - this is the case regardless if you are using the I2C peripheral or not…

// As per STM32303K8 manual page 20 (https://www.st.com/resource/en/user_manual/dm00231744-stm32-nucleo32-boards-mb1180-stmicroelectronics.pdf), we need to do something with these pins. 

        DigitalIn Floating_PA5(PA_5);

        DigitalIn Floating_PA6(PA_6);

        Floating_PA5.mode(PullUp);

        Floating_PA6.mode(PullUp);

        I2C my_i2c_device(I2C_SDA, I2C_SCL);

        my_i2c_device.frequency(400000);  // have tested 100Khz, 400Khz and 1Mhz