8 years ago.

Nucleo - i2c buffer limits?

Hello, I am trying to make two stm32 nucleo board communicate with each other using the i2c protocol and the related mbed libraries. Unfortunately it seems that only a few bytes (2 or 3 depending on the board) can be sent during a write operation from master to the slave. Is it due to a limited buffer capability of the nucleo boards or it is maybe caused by a bug in the library?

I already checked the pull up resistor of the scl and sda lines and tried different resistor many times already, the result is always the same.

1 Answer

8 years ago.

Can you post up your code? I have several Nucleos I could experiment with but don't feel like developing the code to test! :) With Nucleo to external I2C there is not a limit I have discovered but I don't currently go beyond 8 data bytes

Sure, here is the code:

Master

#include "mbed.h"
//MASTER NUCLEO-L476RG
I2C i2c(PB_9,PB_8);        // sda, scl
Serial pc(PA_2, PA_3);
 
const int addr = 0x78; // define the I2C Address
 
int main() {
    char cmd[2];
    pc.printf("INIZIO\n");
    i2c.frequency(400000);
    while(1)
    {
        char str[] = "stringa";
        cmd[0] = 0x0;            // pointer to command register
        cmd[1] = 0x51;           // Start ranging, results in cm
        int x =i2c.write(addr, "abcde", 5); // Send command string
        pc.printf("%d\n",x);
        wait(1);
    }
}

Slave

//SLAVE NUCLEO-F446RE
#include "mbed.h"
 
I2CSlave slave(PB_9,PB_8);
Serial pc(PA_2, PA_3);
DigitalOut led1(LED1);
 
int main()
{
    pc.printf("Welcome\n");
    char buf[8] = {""};
    int val;
    uint16_t * controlregister = 0x0000;
    uint16_t content = *controlregister;
    *controlregister=0x0001;
    pc.printf("control register content: %x\n",content);
    slave.frequency(400000);
    slave.address(0x78);
    pc.printf("Starting program");
    while (1)
    {
        int i = slave.receive();
        if(i == 0) continue;
        pc.printf("Slave Receive: %d: \n", i);
        switch (i)
        {
            case I2CSlave::ReadAddressed:
                val = slave.write(buf, 4); // Includes null char
                pc.printf("ReadAddressed: %d\n\r", val);
                break;
            case I2CSlave::WriteGeneral:
                val = slave.read(buf, 4);
                pc.printf("WriteGeneral: %d\n\r", val);
                break;
            case I2CSlave::WriteAddressed:
                val = slave.read(buf, 5);
                pc.printf("WriteAdressed: %s return %d\n\r", buf,val);
                for(int i = 0; i < 5; i ++)
                {
                    pc.printf(" %d \t ", buf[i]);
                }
                break;
        }
    }
}

Only the first two bytes are actually received. From the oscylloscope it seems that the slave does not return an ack at the second byte

posted by Vincenzo Comito 17 Apr 2016

Just letting you know I am looking at this and am not happy with the behavior of the slave. Still too early to give results so I will keep plugging away when I have time.

posted by Bill Bellis 18 Apr 2016

Did you get the same problem? I still think this is due to a bug in the mbed's slave implementation

posted by Vincenzo Comito 21 Apr 2016

Any updates on this issue? I'm running into the same problem...

posted by Manny Gonzalez 16 Sep 2016